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