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