xref: /illumos-gate/usr/src/uts/common/io/chxge/com/ch_subr.c (revision d48be21240dfd051b689384ce2b23479d757f2d8)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (C) 2003-2005 Chelsio Communications.  All rights reserved.
24  */
25 
26 #include "common.h"
27 #include "elmer0.h"
28 #include "regs.h"
29 
30 #include "gmac.h"
31 #include "cphy.h"
32 #include "sge.h"
33 #include "tp.h"
34 #include "espi.h"
35 
36 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
37 #include "mc3.h"
38 #include "mc4.h"
39 #include "mc5.h"
40 #include "ulp.h"
41 #endif
42 #ifdef CONFIG_CHELSIO_T1_COUGAR
43 #include "cspi.h"
44 #endif
45 
46 /*
47  * t1_wait_op_done - wait until an operation is completed
48  * @adapter: the adapter performing the operation
49  * @reg: the register to check for completion
50  * @mask: a single-bit field within @reg that indicates completion
51  * @polarity: the value of the field when the operation is completed
52  * @attempts: number of check iterations
53  * @delay: delay in usecs between iterations
54  * @attempts: number of check iterations
55  * @delay: delay in usecs between iterations
56  *
57  * Wait until an operation is completed by checking a bit in a register
58  * up to @attempts times.	Returns %0 if the operation completes and %1
59  * otherwise.
60  */
61 int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
62 		int attempts, int delay)
63 {
64 	while (attempts) {
65 		u32 val = t1_read_reg_4(adapter, reg) & mask;
66 		if (!!val == polarity)
67 			return (0);
68 		if (--attempts == 0)
69 			return (1);
70 		if (delay)
71 			DELAY_US(delay);
72 	}
73 
74 	return (1);
75 }
76 
77 /* #define TPI_ATTEMPTS 50 */
78 #define	TPI_ATTEMPTS 100
79 
80 /*
81  * Write a register over the TPI interface (unlocked and locked versions).
82  */
83 int
84 __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
85 {
86 	int tpi_busy;
87 
88 	t1_write_reg_4(adapter, A_TPI_ADDR, addr);
89 	t1_write_reg_4(adapter, A_TPI_WR_DATA, value);
90 	t1_write_reg_4(adapter, A_TPI_CSR, F_TPIWR);
91 
92 	tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
93 		TPI_ATTEMPTS, 3);
94 	if (tpi_busy)
95 		CH_ALERT("%s: TPI write to 0x%x failed\n",
96 			adapter_name(adapter), addr);
97 	return (tpi_busy);
98 }
99 
100 int
101 t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
102 {
103 	int ret;
104 
105 	TPI_LOCK(adapter);
106 	ret = __t1_tpi_write(adapter, addr, value);
107 	TPI_UNLOCK(adapter);
108 	return (ret);
109 }
110 
111 /*
112  * Read a register over the TPI interface (unlocked and locked versions).
113  */
114 int
115 __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
116 {
117 	int tpi_busy;
118 
119 	t1_write_reg_4(adapter, A_TPI_ADDR, addr);
120 	t1_write_reg_4(adapter, A_TPI_CSR, 0);
121 
122 	tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
123 		TPI_ATTEMPTS, 3);
124 
125 	if (tpi_busy)
126 		CH_ALERT("%s: TPI read from 0x%x failed\n",
127 			adapter_name(adapter), addr);
128 	else
129 		*valp = t1_read_reg_4(adapter, A_TPI_RD_DATA);
130 	return (tpi_busy);
131 }
132 
133 int
134 t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
135 {
136 	int ret;
137 
138 	TPI_LOCK(adapter);
139 	ret = __t1_tpi_read(adapter, addr, valp);
140 	TPI_UNLOCK(adapter);
141 	return (ret);
142 }
143 
144 /*
145  * Set a TPI parameter.
146  */
147 static void t1_tpi_par(adapter_t *adapter, u32 value)
148 {
149 	t1_write_reg_4(adapter, A_TPI_PAR, V_TPIPAR(value));
150 }
151 
152 /*
153  * Called when a port's link settings change to propagate the new values to the
154  * associated PHY and MAC.  After performing the common tasks it invokes an
155  * OS-specific handler.
156  */
157 void
158 link_changed(adapter_t *adapter, int port_id)
159 {
160 	int link_ok, speed, duplex, fc;
161 	struct cphy *phy = adapter->port[port_id].phy;
162 	struct link_config *lc = &adapter->port[port_id].link_config;
163 
164 	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
165 
166 	lc->speed = speed < 0 ? SPEED_INVALID : speed;
167 	lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
168 	if (!(lc->requested_fc & PAUSE_AUTONEG))
169 		fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
170 
171 	if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
172 		/* Set MAC speed, duplex, and flow control to match PHY. */
173 		struct cmac *mac = adapter->port[port_id].mac;
174 
175 		mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc);
176 		lc->fc = (unsigned char)fc;
177 	}
178 	t1_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
179 }
180 
181 static int t1_pci_intr_handler(adapter_t *adapter)
182 {
183 	u32 pcix_cause;
184 
185 	(void) t1_os_pci_read_config_4(adapter, A_PCICFG_INTR_CAUSE,
186 		&pcix_cause);
187 
188 	if (pcix_cause) {
189 		(void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_CAUSE,
190 			pcix_cause);
191 		t1_fatal_err(adapter);    /* PCI errors are fatal */
192 	}
193 	return (0);
194 }
195 
196 #ifdef CONFIG_CHELSIO_T1_1G
197 #include "fpga_defs.h"
198 
199 /*
200  * PHY interrupt handler for FPGA boards.
201  */
202 static int fpga_phy_intr_handler(adapter_t *adapter)
203 {
204 	int p;
205 	u32 cause = t1_read_reg_4(adapter, FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
206 
207 	for_each_port(adapter, p)
208 		if (cause & (1 << p)) {
209 			struct cphy *phy = adapter->port[p].phy;
210 			int phy_cause = phy->ops->interrupt_handler(phy);
211 
212 			if (phy_cause & cphy_cause_link_change)
213 				link_changed(adapter, p);
214 		}
215 	t1_write_reg_4(adapter, FPGA_GMAC_ADDR_INTERRUPT_CAUSE, cause);
216 	return (0);
217 }
218 
219 /*
220  * Slow path interrupt handler for FPGAs.
221  */
222 static int fpga_slow_intr(adapter_t *adapter)
223 {
224 	u32 cause = t1_read_reg_4(adapter, A_PL_CAUSE);
225 
226 	cause &= ~F_PL_INTR_SGE_DATA;
227 	if (cause & F_PL_INTR_SGE_ERR)
228 		(void) t1_sge_intr_error_handler(adapter->sge);
229 
230 	if (cause & FPGA_PCIX_INTERRUPT_GMAC)
231 		(void) fpga_phy_intr_handler(adapter);
232 
233 	if (cause & FPGA_PCIX_INTERRUPT_TP) {
234 		/*
235 		 * FPGA doesn't support MC4 interrupts and it requires
236 		 * this odd layer of indirection for MC5.
237 		 */
238 		u32 tp_cause = t1_read_reg_4(adapter,
239 			FPGA_TP_ADDR_INTERRUPT_CAUSE);
240 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
241 		if (tp_cause & FPGA_TP_INTERRUPT_MC5)
242 			t1_mc5_intr_handler(adapter->mc5);
243 #endif
244 		/* Clear TP interrupt */
245 		t1_write_reg_4(adapter, FPGA_TP_ADDR_INTERRUPT_CAUSE,
246 			tp_cause);
247 	}
248 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
249 	if (cause & FPGA_PCIX_INTERRUPT_MC3)
250 		(void) t1_mc3_intr_handler(adapter->mc3);
251 #endif
252 	if (cause & FPGA_PCIX_INTERRUPT_PCIX)
253 		(void) t1_pci_intr_handler(adapter);
254 
255 	/* Clear the interrupts just processed. */
256 	if (cause)
257 		t1_write_reg_4(adapter, A_PL_CAUSE, cause);
258 
259 	return (cause != 0);
260 }
261 
262 /*
263  * FPGA MDIO initialization.
264  */
265 static void fpga_mdio_init(adapter_t *adapter, const struct board_info *bi)
266 {
267 	(void) bi;	/* avoid warnings */
268 	t1_write_reg_4(adapter, A_MI0_CLK, V_MI0_CLK_DIV(3));
269 }
270 
271 /*
272  * FPGA MDIO read/write operations.
273  */
274 static int fpga_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
275 	int reg_addr, unsigned int *val)
276 {
277 	if (mmd_addr)
278 		return (-EINVAL);
279 
280 	/* Check if MDI is busy; this shouldn't happen. */
281 	if (t1_read_reg_4(adapter, A_MI0_CSR) & F_MI0_BUSY) {
282 		CH_ALERT("%s: MDIO busy at start of read\n",
283 			adapter_name(adapter));
284 		return (-EBUSY);
285 	}
286 	t1_write_reg_4(adapter, A_MI0_ADDR,
287 		V_MI0_PHY_REG_ADDR(reg_addr) | V_MI0_PHY_ADDR(phy_addr));
288 	*val = t1_read_reg_4(adapter, A_MI0_DATA_EXT);
289 
290 	return (0);
291 }
292 
293 static int fpga_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
294 	int reg_addr, unsigned int val)
295 {
296 	if (mmd_addr)
297 		return (-EINVAL);
298 
299 	/* Check if MDI is busy; this shouldn't happen. */
300 	if (t1_read_reg_4(adapter, A_MI0_CSR) & F_MI0_BUSY) {
301 		CH_ALERT("%s: MDIO busy at start of write\n",
302 			adapter_name(adapter));
303 		return (-EBUSY);
304 	}
305 	t1_write_reg_4(adapter, A_MI0_ADDR,
306 		V_MI0_PHY_REG_ADDR(reg_addr) | V_MI0_PHY_ADDR(phy_addr));
307 	t1_write_reg_4(adapter, A_MI0_DATA_EXT, val);
308 	return (0);
309 }
310 
311 static struct mdio_ops fpga_mdio_ops = {
312 	fpga_mdio_init,
313 	fpga_mdio_read,
314 	fpga_mdio_write
315 };
316 #endif
317 
318 /*
319  * Wait until Elmer's MI1 interface is ready for new operations.
320  */
321 static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg)
322 {
323 	int attempts = 100, busy;
324 
325 	do {
326 		u32 val;
327 
328 		(void) __t1_tpi_read(adapter, mi1_reg, &val);
329 		busy = val & F_MI1_OP_BUSY;
330 		if (busy)
331 			DELAY_US(10);
332 	} while (busy && --attempts);
333 	if (busy)
334 		CH_ALERT("%s: MDIO operation timed out\n",
335 			adapter_name(adapter));
336 	return (busy);
337 }
338 
339 /*
340  * MI1 MDIO initialization.
341  */
342 static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
343 {
344 	u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1;
345 	u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) |
346 		V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv);
347 
348 	if (!(bi->caps & SUPPORTED_10000baseT_Full))
349 		val |= V_MI1_SOF(1);
350 	(void) t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val);
351 }
352 
353 #if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
354 /*
355  * Elmer MI1 MDIO read/write operations.
356  */
357 static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
358 	int reg_addr, unsigned int *valp)
359 {
360 	u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
361 
362 	if (mmd_addr)
363 		return (-EINVAL);
364 
365 	TPI_LOCK(adapter);
366 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
367 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
368 		MI1_OP_DIRECT_READ);
369 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
370 	(void) __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
371 	TPI_UNLOCK(adapter);
372 	return (0);
373 }
374 
375 static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
376 	int reg_addr, unsigned int val)
377 {
378 	u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
379 
380 	if (mmd_addr)
381 		return (-EINVAL);
382 
383 	TPI_LOCK(adapter);
384 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
385 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
386 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
387 		MI1_OP_DIRECT_WRITE);
388 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
389 	TPI_UNLOCK(adapter);
390 	return (0);
391 }
392 
393 #if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
394 static struct mdio_ops mi1_mdio_ops = {
395 	mi1_mdio_init,
396 	mi1_mdio_read,
397 	mi1_mdio_write
398 };
399 #endif
400 
401 #endif
402 
403 #if 0
404 static int mi1_mdio_ext_readinc(adapter_t *adapter, int phy_addr, int mmd_addr,
405 				int reg_addr, unsigned int *valp)
406 {
407 	u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
408 
409 	TPI_LOCK(adapter);
410 
411 	/* Write the address we want. */
412 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
413 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
414 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
415 		MI1_OP_INDIRECT_ADDRESS);
416 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
417 
418 	/* Write the operation we want. */
419 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
420 		MI1_OP_INDIRECT_READ_INC);
421 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
422 
423 	/* Read the data. */
424 	(void) __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
425 	TPI_UNLOCK(adapter);
426 	return (0);
427 }
428 #endif
429 
430 static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
431 	int reg_addr, unsigned int *valp)
432 {
433 	u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
434 
435 	TPI_LOCK(adapter);
436 
437 	/* Write the address we want. */
438 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
439 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
440 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
441 		MI1_OP_INDIRECT_ADDRESS);
442 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
443 
444 	/* Write the operation we want. */
445 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
446 		MI1_OP_INDIRECT_READ);
447 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
448 
449 	/* Read the data. */
450 	(void) __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
451 	TPI_UNLOCK(adapter);
452 	return (0);
453 }
454 
455 static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
456 	int reg_addr, unsigned int val)
457 {
458 	u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
459 
460 	TPI_LOCK(adapter);
461 
462 	/* Write the address we want. */
463 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
464 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
465 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
466 		MI1_OP_INDIRECT_ADDRESS);
467 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
468 
469 	/* Write the data. */
470 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
471 	(void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
472 		MI1_OP_INDIRECT_WRITE);
473 	(void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
474 	TPI_UNLOCK(adapter);
475 	return (0);
476 }
477 
478 static struct mdio_ops mi1_mdio_ext_ops = {
479 	mi1_mdio_init,
480 	mi1_mdio_ext_read,
481 	mi1_mdio_ext_write
482 };
483 
484 enum {
485 	CH_BRD_T110_1CU,
486 	CH_BRD_N110_1F,
487 	CH_BRD_N210_1F,
488 	CH_BRD_T210_1F,
489 	CH_BRD_T210_1CU,
490 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
491 #ifdef CONFIG_CHELSIO_T1_1G
492 	CH_BRD_T204_4CU,
493 	CH_BRD_T204V_4CU,
494 	CH_BRD_6800_4CU,
495 	CH_BRD_7500_4CU,
496 	CH_BRD_7500_4F,
497 	CH_BRD_T101_1CU_LB,
498 	CH_BRD_T101_1F_LB,
499 #endif
500 	CH_BRD_8000_1F,
501 	CH_BRD_T110_1F,
502 #ifdef CONFIG_CHELSIO_T1_COUGAR
503 #ifdef CONFIG_CHELSIO_T1_1G
504 	CH_BRD_COUGAR_4CU,
505 #endif
506 	CH_BRD_COUGAR_1F,
507 #endif
508 #ifdef CONFIG_USERMODE
509 	CH_BRD_SIMUL,
510 #endif
511 #endif
512 };
513 
514 static struct board_info t1_board[] = {
515 
516 { CHBT_BOARD_CHT110, 1/*ports#*/,
517   SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T1,
518   CHBT_MAC_PM3393, CHBT_PHY_MY3126,
519   125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/,
520   1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/,
521   1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops,
522   &t1_my3126_ops, &mi1_mdio_ext_ops,
523   "Chelsio T110 1x10GBase-CX4 TOE" },
524 
525 { CHBT_BOARD_N110, 1/*ports#*/,
526   SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
527   CHBT_MAC_PM3393, CHBT_PHY_88X2010,
528   125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
529   1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
530   0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
531   &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
532   "Chelsio N110 1x10GBaseX NIC" },
533 
534 { CHBT_BOARD_N210, 1/*ports#*/,
535   SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2,
536   CHBT_MAC_PM3393, CHBT_PHY_88X2010,
537   125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
538   1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
539   0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
540   &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
541   "Chelsio N210 1x10GBaseX NIC" },
542 
543 { CHBT_BOARD_CHT210, 1/*ports#*/,
544   SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2,
545   CHBT_MAC_PM3393, CHBT_PHY_88X2010,
546   125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/,
547   1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
548   0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
549   &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
550   "Chelsio T210 1x10GBaseX TOE" },
551 
552 { CHBT_BOARD_CHT210, 1/*ports#*/,
553   SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2,
554   CHBT_MAC_PM3393, CHBT_PHY_MY3126,
555   125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/,
556   1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/,
557   1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops,
558   &t1_my3126_ops, &mi1_mdio_ext_ops,
559   "Chelsio T210 1x10GBase-CX4 TOE" },
560 
561 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
562 #ifdef CONFIG_CHELSIO_T1_1G
563 { CHBT_BOARD_CHT204, 4/*ports#*/,
564   SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
565   SUPPORTED_PAUSE | SUPPORTED_TP /*caps*/, CHBT_TERM_T2, CHBT_MAC_IXF1010, CHBT_PHY_88E1111,
566   100000000/*clk-core*/, 133000000/*clk-mc3*/, 100000000/*clk-mc4*/,
567   4/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
568   0/*mdiinv*/, 1/*mdc*/, 4/*phybaseaddr*/, &t1_ixf1010_ops,
569   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
570   "Chelsio T204 4x100/1000BaseT TOE" },
571 { CHBT_BOARD_CHT204V, 4/*ports#*/,
572   SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half |
573   SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
574   SUPPORTED_PAUSE | SUPPORTED_TP /*caps*/, CHBT_TERM_T2, CHBT_MAC_VSC7321, CHBT_PHY_88E1111,
575   100000000/*clk-core*/, 133000000/*clk-mc3*/, 100000000/*clk-mc4*/,
576   4/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
577   0/*mdiinv*/, 1/*mdc*/, 4/*phybaseaddr*/, &t1_vsc7326_ops,
578   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
579   "Chelsio T204V 4x100/1000BaseT TOE" },
580 
581 { CHBT_BOARD_6800, 1/*ports#*/,
582   SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half |
583   SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half |
584   SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP /*caps*/,
585   CHBT_TERM_FPGA, CHBT_MAC_CHELSIO_A, CHBT_PHY_88E1041,
586   16000000/*clk-core*/, 16000000/*clk-mc3*/, 16000000/*clk-mc4*/,
587   0/*espi-ports*/, 0/*clk-cspi*/, 0/*clk-elmer0*/, 0/*mdien*/,
588   0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_chelsio_mac_ops, &t1_mv88e1xxx_ops, &fpga_mdio_ops,
589   "Chelsio FPGA 4x10/100/1000BaseT TOE" },
590 
591 { CHBT_BOARD_7500, 4/*ports#*/,
592   SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
593   SUPPORTED_TP /*caps*/, CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1041,
594   87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/,
595   4/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/,
596   0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_ixf1010_ops,
597   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
598   "Chelsio 7500 4x100/1000BaseT TOE" },
599 
600 { CHBT_BOARD_7500, 4/*ports#*/,
601   SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE /*caps*/,
602   CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1041,
603   87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/,
604   4/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/,
605   0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_ixf1010_ops,
606   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
607   "Chelsio 7500 4x1000BaseX TOE" },
608 
609 { CHBT_BOARD_CHT101, 1/*ports#*/,
610   SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
611   SUPPORTED_TP | SUPPORTED_PAUSE | SUPPORTED_LOOPBACK /*caps*/, CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1111,
612   83300000/*clk-core*/, 83300000/*clk-mc3*/, 83300000/*clk-mc4*/,
613   2/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/,
614   0/*mdiinv*/, 4/*mdc*/, 4/*phybaseaddr*/, &t1_ixf1010_ops,
615   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
616   "Chelsio T101 1x100/1000BaseT TOE" },
617 
618 { CHBT_BOARD_CHT101, 1/*ports#*/,
619   SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE | SUPPORTED_PAUSE | SUPPORTED_LOOPBACK /*caps*/,
620   CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1111,
621   83300000/*clk-core*/, 83300000/*clk-mc3*/, 83300000/*clk-mc4*/,
622   2/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/,
623   0/*mdiinv*/, 4/*mdc*/, 4/*phybaseaddr*/, &t1_ixf1010_ops,
624   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
625   "Chelsio T101 1x1000BaseX TOE" },
626 #endif
627 
628 { CHBT_BOARD_8000, 1/*ports#*/,
629   SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
630   CHBT_MAC_PM3393, CHBT_PHY_XPAK,
631   125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/,
632   1/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 1/*mdien*/,
633   1/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
634   &t1_xpak_ops, &mi1_mdio_ext_ops,
635   "Chelsio 8000 1x10GBaseX TOE" },
636 
637 { CHBT_BOARD_CHT110, 1/*ports#*/,
638   SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
639   CHBT_MAC_PM3393, CHBT_PHY_XPAK,
640   125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/,
641   1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/,
642   1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops,
643   &t1_xpak_ops, &mi1_mdio_ext_ops,
644   "Chelsio T110 1x10GBaseX TOE" },
645 
646 #ifdef CONFIG_CHELSIO_T1_COUGAR
647 #ifdef CONFIG_CHELSIO_T1_1G
648 { CHBT_BOARD_COUGAR, 4/*ports#*/,
649   SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half |
650   SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half |
651   SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP /*caps*/,
652   CHBT_TERM_T1, CHBT_MAC_VSC7321, CHBT_PHY_88E1041,
653   87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/,
654   4/*espi-ports*/, 333300000/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/,
655   0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_vsc7321_ops,
656   &t1_mv88e1xxx_ops, &mi1_mdio_ops,
657   "Chelsio Cougar 4x100/1000BaseT TOE" },
658 #endif
659 
660 { CHBT_BOARD_COUGAR, 1/*ports#*/,
661   SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
662   CHBT_MAC_VSC7321, CHBT_PHY_XPAK,
663   87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/,
664   1/*espi-ports*/, 333300000/*clk-cspi*/, 40/*clk-elmer0*/, 1/*mdien*/,
665   1/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_vsc7321_ops,
666   &t1_xpak_ops, &mi1_mdio_ext_ops,
667   "Chelsio Cougar 1x10GBaseX TOE" },
668 #endif
669 
670 #ifdef CONFIG_USERMODE
671 { CHBT_BOARD_SIMUL, 1/*ports#*/,
672   0/*caps*/, CHBT_TERM_T1, CHBT_MAC_DUMMY, CHBT_PHY_DUMMY,
673   125000000/*clk-core*/, 125000000/*clk-mc3*/, 125000000/*clk-mc4*/,
674   1/*espi-ports*/, 0/*clk-cspi*/, 0/*clk-elmer0*/, 0/*mdien*/,
675   0/*mdiinv*/, 0/*mdc*/, 0/*phybaseaddr*/, &t1_dummy_mac_ops,
676   &t1_dummy_phy_ops, NULL, "Chelsio simulation environment TOE" },
677 #endif
678 #endif
679 };
680 
681 struct pci_device_id t1_pci_tbl[] = {
682 	CH_DEVICE(8, 0, CH_BRD_T110_1CU),
683 	CH_DEVICE(8, 1, CH_BRD_T110_1CU),
684 	CH_DEVICE(7, 0, CH_BRD_N110_1F),
685 	CH_DEVICE(10, 1, CH_BRD_N210_1F),
686 	CH_DEVICE(11, 1, CH_BRD_T210_1F),
687 	CH_DEVICE(14, 1, CH_BRD_T210_1CU),
688 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
689 #ifdef CONFIG_CHELSIO_T1_1G
690 	CH_DEVICE(12, 1, CH_BRD_T204_4CU),
691 	CH_DEVICE(13, 1, CH_BRD_T204V_4CU),
692 	CH_DEVICE(1, 0, CH_BRD_6800_4CU),
693 	CH_DEVICE(2, 1, CH_BRD_7500_4CU),
694 	CH_DEVICE(2, 3, CH_BRD_7500_4F),
695 	CH_DEVICE(4, 0, CH_BRD_T101_1CU_LB),
696 	CH_DEVICE(4, 2, CH_BRD_T101_1F_LB),
697 #endif
698 	CH_DEVICE(3, 0, CH_BRD_8000_1F),
699 	CH_DEVICE(3, 1, CH_BRD_8000_1F),
700 	CH_DEVICE(6, 0, CH_BRD_T110_1F),
701 	CH_DEVICE(6, 1, CH_BRD_T110_1F),
702 #ifdef CONFIG_CHELSIO_T1_COUGAR
703 #ifdef CONFIG_CHELSIO_T1_1G
704 	CH_DEVICE(5, 0, CH_BRD_COUGAR_4CU),
705 #endif
706 	CH_DEVICE(5, 1, CH_BRD_COUGAR_1F),
707 #endif
708 #ifdef CONFIG_USERMODE
709 	CH_DEVICE(0x5000, PCI_ANY_ID, CH_BRD_SIMUL),
710 #endif
711 #endif
712         { 0, }
713 };
714 
715 #ifndef CH_DEVICE_COMMON
716 /*
717  * Return the board_info structure with a given index.  Out-of-range indices
718  * return NULL.
719  */
720 const struct board_info *
721 t1_get_board_info(unsigned int board_id)
722 {
723 	return (board_id < DIMOF(t1_board) ? &t1_board[board_id] : NULL);
724 }
725 #else
726 /*
727  * Return the board_info structure that corresponds to a given PCI devid/ssid
728  * pair.  Return NULL if the id combination is unknown.
729  */
730 const struct board_info *t1_get_board_info_from_ids(unsigned int devid,
731 						    unsigned short ssid)
732 {
733 	struct pci_device_id *p;
734 
735 	for (p = t1_pci_tbl; p->devid; ++p)
736 		if (p->devid == devid && p->ssid == ssid)
737 			return (&t1_board[p->board_info_index]);
738 	return (NULL);
739 }
740 #endif
741 
742 typedef struct {
743 	u32 format_version;
744 	u8 serial_number[16];
745 	u8 mac_base_address[6];
746 	u8 pad[2];	/* make multiple-of-4 size requirement explicit */
747 } chelsio_vpd_t;
748 
749 #define	EEPROMSIZE	(8 * 1024)
750 #define	EEPROM_MAX_POLL	4
751 
752 /*
753  * Read SEEPROM. A zero is written to the flag register when the addres is
754  * written to the Control register. The hardware device will set the flag to a
755  * one when 4B have been transferred to the Data register.
756  */
757 int
758 t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
759 {
760 	int i = EEPROM_MAX_POLL;
761 	u16 val;
762 
763 	if (addr >= EEPROMSIZE || (addr & 3))
764 	return (-EINVAL);
765 
766 	(void) t1_os_pci_write_config_2(adapter, A_PCICFG_VPD_ADDR, (u16)addr);
767 	do {
768 		DELAY_US(50);
769 		(void) t1_os_pci_read_config_2(adapter,
770 			A_PCICFG_VPD_ADDR, &val);
771 	} while (!(val & F_VPD_OP_FLAG) && --i);
772 
773 	if (!(val & F_VPD_OP_FLAG)) {
774 		CH_ERR("%s: reading EEPROM address 0x%x failed\n",
775 			adapter_name(adapter), addr);
776 		return (-EIO);
777 	}
778 	(void) t1_os_pci_read_config_4(adapter, A_PCICFG_VPD_DATA, data);
779 	*data = le32_to_cpu(*data);
780 	return (0);
781 }
782 
783 static int t1_eeprom_vpd_get(adapter_t *adapter, chelsio_vpd_t *vpd)
784 {
785 	int addr, ret = 0;
786 
787 	for (addr = 0; !ret && addr < sizeof (*vpd); addr += sizeof (u32))
788 		ret = t1_seeprom_read(adapter, addr,
789 			(u32 *)((u8 *)vpd + addr));
790 
791 	return (ret);
792 }
793 
794 /*
795  * Read a port's MAC address from the VPD ROM.
796  */
797 static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[])
798 {
799 	chelsio_vpd_t vpd;
800 
801 	if (t1_eeprom_vpd_get(adapter, &vpd))
802 	return (1);
803 	memcpy(mac_addr, vpd.mac_base_address, 5);
804 	mac_addr[5] = vpd.mac_base_address[5] + index;
805 	return (0);
806 }
807 
808 /*
809  * Set up the MAC/PHY according to the requested link settings.
810  *
811  * If the PHY can auto-negotiate first decide what to advertise, then
812  * enable/disable auto-negotiation as desired and reset.
813  *
814  * If the PHY does not auto-negotiate we just reset it.
815  *
816  * If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
817  * otherwise do it later based on the outcome of auto-negotiation.
818  */
819 int
820 t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
821 {
822 	unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
823 
824 	if (lc->supported & SUPPORTED_Autoneg) {
825 		lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE);
826 		if (fc) {
827 			if (fc == ((PAUSE_RX | PAUSE_TX) & !is_T2(mac->adapter)))
828 				lc->advertising |= ADVERTISED_PAUSE;
829 			else {
830 				lc->advertising |= ADVERTISED_ASYM_PAUSE;
831 				if (fc == PAUSE_RX)
832 					lc->advertising |= ADVERTISED_PAUSE;
833 			}
834 		}
835 		phy->ops->advertise(phy, lc->advertising);
836 
837 		if (lc->autoneg == AUTONEG_DISABLE) {
838 			lc->speed = lc->requested_speed;
839 			lc->duplex = lc->requested_duplex;
840 			lc->fc = (unsigned char)fc;
841 			mac->ops->set_speed_duplex_fc(mac, lc->speed,
842 						      lc->duplex, fc);
843 			/* Also disables autoneg */
844 			phy->state = PHY_AUTONEG_RDY;
845 			phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
846 			phy->ops->reset(phy, 0);
847 		} else {
848 			phy->state = PHY_AUTONEG_EN;
849 			phy->ops->autoneg_enable(phy); /* also resets PHY */
850 		}
851 	} else {
852 		phy->state = PHY_AUTONEG_RDY;
853 		mac->ops->set_speed_duplex_fc(mac, -1, -1, fc);
854 		lc->fc = (unsigned char)fc;
855 		phy->ops->reset(phy, 0);
856 	}
857 	return 0;
858 }
859 
860 /*
861  * External interrupt handler for boards using elmer0.
862  */
863 int
864 elmer0_ext_intr_handler(adapter_t *adapter)
865 {
866 	struct cphy *phy;
867 	int phy_cause;
868 	u32 cause;
869 
870 	(void) t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause);
871 
872 	switch (board_info(adapter)->board) {
873 #ifdef CONFIG_CHELSIO_T1_1G
874         case CHBT_BOARD_CHT204:
875         case CHBT_BOARD_CHT204V: {
876                 int i, port_bit;
877 		for_each_port(adapter, i) {
878 			port_bit = i ? i + 1 : 0;
879 			if (!(cause & (1 << port_bit))) continue;
880 
881 			phy = adapter->port[i].phy;
882 			phy_cause = phy->ops->interrupt_handler(phy);
883 			if (phy_cause & cphy_cause_link_change)
884 				link_changed(adapter, i);
885 		}
886 		break;
887 	}
888 	case CHBT_BOARD_CHT101:
889 		if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */
890 			phy = adapter->port[0].phy;
891 			phy_cause = phy->ops->interrupt_handler(phy);
892 			if (phy_cause & cphy_cause_link_change)
893 				link_changed(adapter, 0);
894 		}
895 		break;
896 	case CHBT_BOARD_7500: {
897 		int p;
898 		/*
899 		 * Elmer0's interrupt cause isn't useful here because there is
900 		 * only one bit that can be set for all 4 ports.  This means
901 		 * we are forced to check every PHY's interrupt status
902 		 * register to see who initiated the interrupt.
903 		 */
904 		for_each_port(adapter, p) {
905 			phy = adapter->port[p].phy;
906 			phy_cause = phy->ops->interrupt_handler(phy);
907 			if (phy_cause & cphy_cause_link_change)
908 			    link_changed(adapter, p);
909 		}
910 		break;
911 	}
912 #endif
913 	case CHBT_BOARD_CHT210:
914 	case CHBT_BOARD_N210:
915 	case CHBT_BOARD_N110:
916 		if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */
917 			phy = adapter->port[0].phy;
918 			phy_cause = phy->ops->interrupt_handler(phy);
919 			if (phy_cause & cphy_cause_link_change)
920 				link_changed(adapter, 0);
921 		}
922 		break;
923 	case CHBT_BOARD_8000:
924 	case CHBT_BOARD_CHT110:
925 		CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n",
926 			cause);
927 		if (cause & ELMER0_GP_BIT1) {	/* PMC3393 INTB */
928 			struct cmac *mac = adapter->port[0].mac;
929 
930 			mac->ops->interrupt_handler(mac);
931 		}
932 		if (cause & ELMER0_GP_BIT5) {	/* XPAK MOD_DETECT */
933 			u32 mod_detect;
934 
935 			(void) t1_tpi_read(adapter, A_ELMER0_GPI_STAT,
936 				&mod_detect);
937 			CH_MSG(adapter, INFO, LINK, "XPAK %s\n",
938 				mod_detect ? "removed" : "inserted");
939 		}
940 		break;
941 #ifdef CONFIG_CHELSIO_T1_COUGAR
942 	case CHBT_BOARD_COUGAR:
943 		if (adapter->params.nports == 1) {
944 			if (cause & ELMER0_GP_BIT1) {	/* Vitesse MAC */
945 				struct cmac *mac = adapter->port[0].mac;
946 				mac->ops->interrupt_handler(mac);
947 			}
948 			if (cause & ELMER0_GP_BIT5) {	/* XPAK MOD_DETECT */
949 			}
950 		} else {
951 			int i, port_bit;
952 
953 			for_each_port(adapter, i) {
954 				port_bit = i ? i + 1 : 0;
955 				if (!(cause & (1 << port_bit))) continue;
956 
957 				phy = adapter->port[i].phy;
958 				phy_cause = phy->ops->interrupt_handler(phy);
959 				if (phy_cause & cphy_cause_link_change)
960 					link_changed(adapter, i);
961 			}
962 		}
963 		break;
964 #endif
965 	}
966 	(void) t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause);
967 	return (0);
968 }
969 
970 /* Enables all interrupts. */
971 void
972 t1_interrupts_enable(adapter_t *adapter)
973 {
974 	unsigned int i;
975 
976 	adapter->slow_intr_mask = F_PL_INTR_SGE_ERR | F_PL_INTR_TP;
977 	(void) t1_sge_intr_enable(adapter->sge);
978 	t1_tp_intr_enable(adapter->tp);
979 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
980 	if (adapter->mc4) {
981 		adapter->slow_intr_mask |= F_PL_INTR_MC3 | F_PL_INTR_MC4 |
982 			F_PL_INTR_ULP | F_PL_INTR_MC5;
983 	/*
984 	 * T2 -- Disable interrupts for now b/c we are not clearing
985 	 * correctly yet.
986 	 */
987 		/* t1_ulp_intr_enable(adapter->ulp); */
988 		t1_ulp_intr_disable(adapter->ulp);
989 
990 		t1_mc3_intr_enable(adapter->mc3);
991 		t1_mc4_intr_enable(adapter->mc4);
992 		t1_mc5_intr_enable(adapter->mc5);
993 	}
994 #endif
995 	if (adapter->espi) {
996 		adapter->slow_intr_mask |= F_PL_INTR_ESPI;
997 		t1_espi_intr_enable(adapter->espi);
998 	}
999 
1000 	/* Enable MAC/PHY interrupts for each port. */
1001 	for_each_port(adapter, i) {
1002 		adapter->port[i].mac->ops->interrupt_enable(adapter->
1003 			port[i].mac);
1004 		adapter->port[i].phy->ops->interrupt_enable(adapter->
1005 			port[i].phy);
1006 	}
1007 
1008 	/* Enable PCIX & external chip interrupts on ASIC boards. */
1009 	if (t1_is_asic(adapter)) {
1010 		u32 pl_intr = t1_read_reg_4(adapter, A_PL_ENABLE);
1011 
1012 		/* PCI-X interrupts */
1013 		(void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_ENABLE,
1014 			0xffffffff);
1015 
1016 		adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
1017 		pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
1018 		t1_write_reg_4(adapter, A_PL_ENABLE, pl_intr);
1019 	}
1020 }
1021 
1022 /* Disables all interrupts. */
1023 void
1024 t1_interrupts_disable(adapter_t * adapter)
1025 {
1026 	unsigned int i;
1027 
1028 	(void) t1_sge_intr_disable(adapter->sge);
1029 	t1_tp_intr_disable(adapter->tp);
1030 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1031 	if (adapter->mc4) {
1032 		t1_ulp_intr_disable(adapter->ulp);
1033 		t1_mc3_intr_disable(adapter->mc3);
1034 		t1_mc4_intr_disable(adapter->mc4);
1035 		t1_mc5_intr_disable(adapter->mc5);
1036 	}
1037 #endif
1038 	if (adapter->espi)
1039 		t1_espi_intr_disable(adapter->espi);
1040 
1041 	/* Disable MAC/PHY interrupts for each port. */
1042 	for_each_port(adapter, i) {
1043 		adapter->port[i].mac->ops->interrupt_disable(adapter->
1044 			port[i].mac);
1045 		adapter->port[i].phy->ops->interrupt_disable(adapter->
1046 			port[i].phy);
1047 	}
1048 
1049 	/* Disable PCIX & external chip interrupts. */
1050 	if (t1_is_asic(adapter))
1051 		t1_write_reg_4(adapter, A_PL_ENABLE, 0);
1052 
1053 	/* PCI-X interrupts */
1054 	(void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_ENABLE, 0);
1055 
1056 	adapter->slow_intr_mask = 0;
1057 }
1058 
1059 /* Clears all interrupts */
1060 void
1061 t1_interrupts_clear(adapter_t * adapter)
1062 {
1063 	unsigned int i;
1064 
1065 	(void) t1_sge_intr_clear(adapter->sge);
1066 	t1_tp_intr_clear(adapter->tp);
1067 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1068 	if (adapter->mc4) {
1069 		t1_ulp_intr_clear(adapter->ulp);
1070 		t1_mc3_intr_clear(adapter->mc3);
1071 		t1_mc4_intr_clear(adapter->mc4);
1072 		t1_mc5_intr_clear(adapter->mc5);
1073 	}
1074 #endif
1075 	if (adapter->espi)
1076 		t1_espi_intr_clear(adapter->espi);
1077 
1078 	/* Clear MAC/PHY interrupts for each port. */
1079 	for_each_port(adapter, i) {
1080 		adapter->port[i].mac->ops->interrupt_clear(adapter->
1081 			port[i].mac);
1082 		adapter->port[i].phy->ops->interrupt_clear(adapter->
1083 			port[i].phy);
1084 	}
1085 
1086 	/* Enable interrupts for external devices. */
1087 	if (t1_is_asic(adapter)) {
1088 		u32 pl_intr = t1_read_reg_4(adapter, A_PL_CAUSE);
1089 
1090 		t1_write_reg_4(adapter, A_PL_CAUSE,
1091 			pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX);
1092 	}
1093 
1094 	/* PCI-X interrupts */
1095 	(void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_CAUSE,
1096 		0xffffffff);
1097 }
1098 
1099 /*
1100  * Slow path interrupt handler for ASICs.
1101  */
1102 static int asic_slow_intr(adapter_t *adapter)
1103 {
1104 	u32 cause = t1_read_reg_4(adapter, A_PL_CAUSE);
1105 
1106 	cause &= adapter->slow_intr_mask;
1107 	if (!cause)
1108 		return (0);
1109 	if (cause & F_PL_INTR_SGE_ERR)
1110 		(void) t1_sge_intr_error_handler(adapter->sge);
1111 	if (cause & F_PL_INTR_TP)
1112 		(void) t1_tp_intr_handler(adapter->tp);
1113 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1114 	if (cause & F_PL_INTR_MC3)
1115 		(void) t1_mc3_intr_handler(adapter->mc3);
1116 	if (cause & F_PL_INTR_MC4)
1117 		(void) t1_mc4_intr_handler(adapter->mc4);
1118 	if (cause & F_PL_INTR_ULP)
1119 		(void) t1_ulp_intr_handler(adapter->ulp);
1120 	if (cause & F_PL_INTR_MC5)
1121 		(void) t1_mc5_intr_handler(adapter->mc5);
1122 #endif
1123 	if (cause & F_PL_INTR_ESPI)
1124 		(void) t1_espi_intr_handler(adapter->espi);
1125 	if (cause & F_PL_INTR_PCIX)
1126 		(void) t1_pci_intr_handler(adapter);
1127 	if (cause & F_PL_INTR_EXT)
1128 		t1_os_elmer0_ext_intr(adapter);
1129 
1130 	/* Clear the interrupts just processed. */
1131 	t1_write_reg_4(adapter, A_PL_CAUSE, cause);
1132 	(void) t1_read_reg_4(adapter, A_PL_CAUSE); /* flush writes */
1133 	return (1);
1134 }
1135 
1136 int
1137 t1_slow_intr_handler(adapter_t *adapter)
1138 {
1139 #ifdef CONFIG_CHELSIO_T1_1G
1140 	if (!t1_is_asic(adapter))
1141 		return (fpga_slow_intr(adapter));
1142 #endif
1143 	return (asic_slow_intr(adapter));
1144 }
1145 
1146 /* Power sequencing is a work-around for Intel's XPAKs. */
1147 static void
1148 power_sequence_xpak(adapter_t * adapter)
1149 {
1150 	u32 mod_detect;
1151 	u32 gpo;
1152 
1153 	/* Check for XPAK */
1154 	(void) t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
1155 	if (!(ELMER0_GP_BIT5 & mod_detect)) {
1156 		/* XPAK is present */
1157 		(void) t1_tpi_read(adapter, A_ELMER0_GPO, &gpo);
1158 		gpo |= ELMER0_GP_BIT18;
1159 		(void) t1_tpi_write(adapter, A_ELMER0_GPO, gpo);
1160 	}
1161 }
1162 
1163 int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
1164 	struct adapter_params *p)
1165 {
1166 	p->chip_version = bi->chip_term;
1167 	p->is_asic = (p->chip_version != CHBT_TERM_FPGA);
1168 	if (p->chip_version == CHBT_TERM_T1 ||
1169 	    p->chip_version == CHBT_TERM_T2 ||
1170 	    p->chip_version == CHBT_TERM_FPGA) {
1171 		u32 val = t1_read_reg_4(adapter, A_TP_PC_CONFIG);
1172 
1173 		val = G_TP_PC_REV(val);
1174 		if (val == 2)
1175 			p->chip_revision = TERM_T1B;
1176 		else if (val == 3)
1177 			p->chip_revision = TERM_T2;
1178 		else
1179 			return (-1);
1180 	} else
1181 		return (-1);
1182 	return (0);
1183 }
1184 
1185 /*
1186  * Enable board components other than the Chelsio chip, such as external MAC
1187  * and PHY.
1188  */
1189 static int board_init(adapter_t *adapter, const struct board_info *bi)
1190 {
1191 	switch (bi->board) {
1192 	case CHBT_BOARD_8000:
1193 	case CHBT_BOARD_N110:
1194 	case CHBT_BOARD_N210:
1195 	case CHBT_BOARD_CHT210:
1196 	case CHBT_BOARD_COUGAR:
1197 		t1_tpi_par(adapter, 0xf);
1198 		(void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
1199 		break;
1200 	case CHBT_BOARD_CHT110:
1201 		t1_tpi_par(adapter, 0xf);
1202 		(void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800);
1203 
1204 		/*
1205 		 * TBD XXX Might not need.  This fixes a problem
1206 		 * described in the Intel SR XPAK errata.
1207 		 */
1208 		power_sequence_xpak(adapter);
1209 		break;
1210 #ifdef CONFIG_CHELSIO_T1_1G
1211 	case CHBT_BOARD_CHT204:
1212 	case CHBT_BOARD_CHT204V:
1213                 t1_tpi_par(adapter, 0xf);
1214                 (void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x804);
1215                 break;
1216 	case CHBT_BOARD_CHT101:
1217 	case CHBT_BOARD_7500:
1218 		t1_tpi_par(adapter, 0xf);
1219 		(void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804);
1220 		break;
1221 #endif
1222 	}
1223 	return (0);
1224 }
1225 
1226 /*
1227  * Initialize and configure the Terminator HW modules.  Note that external
1228  * MAC and PHYs are initialized separately.
1229  */
1230 int
1231 t1_init_hw_modules(adapter_t *adapter)
1232 {
1233 	int err = -EIO;
1234 	const struct board_info *bi = board_info(adapter);
1235 
1236 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1237 	if (adapter->mc3 && t1_mc3_init(adapter->mc3, bi->clock_mc3))
1238 		goto out_err;
1239 	if (adapter->mc4 && t1_mc4_init(adapter->mc4, bi->clock_mc4))
1240 		goto out_err;
1241 	if (adapter->mc5 && t1_mc5_init(adapter->mc5,
1242 					adapter->params.mc5.nservers,
1243 					adapter->params.mc5.nroutes, 1, 0))
1244 		goto out_err;
1245 	if (adapter->ulp && t1_ulp_init(adapter->ulp,
1246 					adapter->params.tp.pm_tx_base))
1247 		goto out_err;
1248 #endif
1249 	if (!adapter->mc4) {
1250 		u32 val = t1_read_reg_4(adapter, A_MC4_CFG);
1251 
1252 		t1_write_reg_4(adapter, A_MC4_CFG, val | F_READY | F_MC4_SLOW);
1253 		t1_write_reg_4(adapter, A_MC5_CONFIG,
1254 			F_M_BUS_ENABLE | F_TCAM_RESET);
1255 	}
1256 
1257 #ifdef CONFIG_CHELSIO_T1_COUGAR
1258 	if (adapter->cspi && t1_cspi_init(adapter->cspi))
1259 		goto out_err;
1260 #endif
1261 	if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac,
1262 		bi->espi_nports))
1263 		goto out_err;
1264 
1265 	if (t1_tp_reset(adapter->tp, &adapter->params.tp, bi->clock_core))
1266 		goto out_err;
1267 
1268 	err = t1_sge_configure(adapter->sge, &adapter->params.sge);
1269 	if (err)
1270 		goto out_err;
1271 
1272 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1273 	(void) t1_tp_set_coalescing_size(adapter->tp,
1274 		min(adapter->params.sge.large_buf_capacity,
1275 			TP_MAX_RX_COALESCING_SIZE));
1276 #endif
1277 	err = 0;
1278 out_err:
1279 	return (err);
1280 }
1281 
1282 /*
1283  * Determine a card's PCI mode.
1284  */
1285 static void __devinit get_pci_mode(adapter_t *adapter, struct pci_params *p)
1286 {
1287 	static unsigned short speed_map[] = { 33, 66, 100, 133 };
1288 	u32 pci_mode;
1289 
1290 	(void) t1_os_pci_read_config_4(adapter, A_PCICFG_MODE, &pci_mode);
1291 	p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)];
1292 	p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32;
1293 	p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0;
1294 }
1295 
1296 /*
1297  * Release the structures holding the SW per-Terminator-HW-module state.
1298  */
1299 void
1300 t1_free_sw_modules(adapter_t *adapter)
1301 {
1302 	unsigned int i;
1303 
1304 	for_each_port(adapter, i) {
1305 		struct cmac *mac = adapter->port[i].mac;
1306 		struct cphy *phy = adapter->port[i].phy;
1307 
1308 		if (mac)
1309 			mac->ops->destroy(mac);
1310 		if (phy)
1311 			phy->ops->destroy(phy);
1312 	}
1313 
1314 	if (adapter->sge)
1315 		(void) t1_sge_destroy(adapter->sge);
1316 	if (adapter->tp)
1317 		t1_tp_destroy(adapter->tp);
1318 	if (adapter->espi)
1319 		t1_espi_destroy(adapter->espi);
1320 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1321 	if (adapter->mc5)
1322 		t1_mc5_destroy(adapter->mc5);
1323 	if (adapter->mc3)
1324 		t1_mc3_destroy(adapter->mc3);
1325 	if (adapter->mc4)
1326 		t1_mc4_destroy(adapter->mc4);
1327 	if (adapter->ulp)
1328 		t1_ulp_destroy(adapter->ulp);
1329 #endif
1330 #ifdef CONFIG_CHELSIO_T1_COUGAR
1331 	if (adapter->cspi)
1332 		t1_cspi_destroy(adapter->cspi);
1333 #endif
1334 }
1335 
1336 static void __devinit init_link_config(struct link_config *lc,
1337 	const struct board_info *bi)
1338 {
1339 	lc->supported = bi->caps;
1340 	lc->requested_speed = lc->speed = SPEED_INVALID;
1341 	lc->requested_duplex = lc->duplex = DUPLEX_INVALID;
1342 	lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
1343 	if (lc->supported & SUPPORTED_Autoneg) {
1344 		lc->advertising = lc->supported;
1345 		lc->autoneg = AUTONEG_ENABLE;
1346 		lc->requested_fc |= PAUSE_AUTONEG;
1347 	} else {
1348 		lc->advertising = 0;
1349 		lc->autoneg = AUTONEG_DISABLE;
1350 	}
1351 }
1352 
1353 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1354 void init_mtus(unsigned short mtus[])
1355 {
1356 	mtus[0] = 68;
1357 	mtus[1] = 508;
1358 	mtus[2] = 576;
1359 	mtus[3] = 1492;
1360 	mtus[4] = 1500;
1361 	mtus[5] = 2000;
1362 	mtus[6] = 4000;
1363 	mtus[7] = 9000;
1364 }
1365 #endif
1366 
1367 /*
1368  * Allocate and initialize the data structures that hold the SW state of
1369  * the Terminator HW modules.
1370  */
1371 int __devinit t1_init_sw_modules(adapter_t *adapter,
1372 	const struct board_info *bi)
1373 {
1374 	unsigned int i;
1375 
1376 	adapter->params.brd_info = bi;
1377 	adapter->params.nports = bi->port_number;
1378 	adapter->params.stats_update_period = bi->gmac->stats_update_period;
1379 
1380 	adapter->sge = t1_sge_create(adapter, &adapter->params.sge);
1381 	if (!adapter->sge) {
1382 		CH_ERR("%s: SGE initialization failed\n",
1383 			adapter_name(adapter));
1384 		goto error;
1385 	}
1386 
1387 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1388 	if (bi->clock_mc4) {
1389 		/*
1390 		 * Must wait 200us after power up before touching the
1391 		 * memory controllers.
1392 		 */
1393 		DELAY_US(200);
1394 
1395 		adapter->mc3 = t1_mc3_create(adapter);
1396 		if (!adapter->mc3) {
1397 			CH_ERR("%s: MC3 initialization failed\n",
1398 				adapter_name(adapter));
1399 			goto error;
1400 		}
1401 
1402 		adapter->mc4 = t1_mc4_create(adapter);
1403 		if (!adapter->mc4) {
1404 			CH_ERR("%s: MC4 initialization failed\n",
1405 				adapter_name(adapter));
1406 			goto error;
1407 		}
1408 
1409 		if (!adapter->params.mc5.mode)
1410 			adapter->params.mc5.mode = MC5_MODE_144_BIT;
1411 		adapter->mc5 = t1_mc5_create(adapter,
1412 			adapter->params.mc5.mode);
1413 		if (!adapter->mc5) {
1414 			CH_ERR("%s: MC5 initialization failed\n",
1415 				adapter_name(adapter));
1416 			goto error;
1417 		}
1418 
1419 		adapter->ulp = t1_ulp_create(adapter);
1420 		if (!adapter->ulp) {
1421 			CH_ERR("%s: ULP initialization failed\n",
1422 				adapter_name(adapter));
1423 			goto error;
1424 		}
1425 
1426 		adapter->params.tp.pm_size = t1_mc3_get_size(adapter->mc3);
1427 		adapter->params.tp.cm_size = t1_mc4_get_size(adapter->mc4);
1428 
1429 		adapter->params.mc5.nservers = DEFAULT_SERVER_REGION_LEN;
1430 		adapter->params.mc5.nroutes = DEFAULT_RT_REGION_LEN;
1431 
1432 		init_mtus(adapter->params.mtus);
1433 	}
1434 #endif
1435 
1436 #ifdef CONFIG_CHELSIO_T1_COUGAR
1437 	if (bi->clock_cspi && !(adapter->cspi = t1_cspi_create(adapter))) {
1438 		CH_ERR("%s: CSPI initialization failed\n",
1439 			adapter_name(adapter));
1440 		goto error;
1441 	}
1442 #endif
1443 
1444 	if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) {
1445 		CH_ERR("%s: ESPI initialization failed\n",
1446 			adapter_name(adapter));
1447 		goto error;
1448 	}
1449 
1450 	adapter->tp = t1_tp_create(adapter, &adapter->params.tp);
1451 	if (!adapter->tp) {
1452 		CH_ERR("%s: TP initialization failed\n",
1453 			adapter_name(adapter));
1454 		goto error;
1455 	}
1456 
1457 	(void) board_init(adapter, bi);
1458 	bi->mdio_ops->init(adapter, bi);
1459 	if (bi->gphy->reset)
1460 		bi->gphy->reset(adapter);
1461 	if (bi->gmac->reset)
1462 		bi->gmac->reset(adapter);
1463 
1464 	for_each_port(adapter, i) {
1465 		u8 hw_addr[6];
1466 		struct cmac *mac;
1467 		int phy_addr = bi->mdio_phybaseaddr + i;
1468 
1469 		adapter->port[i].phy = bi->gphy->create(adapter, phy_addr,
1470 							bi->mdio_ops);
1471 		if (!adapter->port[i].phy) {
1472 			CH_ERR("%s: PHY %d initialization failed\n",
1473 				adapter_name(adapter), i);
1474 			goto error;
1475 		}
1476 
1477 		adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
1478 		if (!mac) {
1479 			CH_ERR("%s: MAC %d initialization failed\n",
1480 				adapter_name(adapter), i);
1481 			goto error;
1482 		}
1483 
1484 		/*
1485 		 * Get the port's MAC addresses either from the EEPROM if one
1486 		 * exists or the one hardcoded in the MAC.
1487 		 */
1488 		if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY)
1489 			mac->ops->macaddress_get(mac, hw_addr);
1490 		else if (vpd_macaddress_get(adapter, i, hw_addr)) {
1491 			CH_ERR("%s: could not read MAC address from VPD ROM\n",
1492 				port_name(adapter, i));
1493 			goto error;
1494 		}
1495 		t1_os_set_hw_addr(adapter, i, hw_addr);
1496 		init_link_config(&adapter->port[i].link_config, bi);
1497 	}
1498 
1499 	get_pci_mode(adapter, &adapter->params.pci);
1500 	t1_interrupts_clear(adapter);
1501 	return (0);
1502 
1503 error:
1504 	t1_free_sw_modules(adapter);
1505 	return (-1);
1506 }
1507