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