1 /*****************************************************************************
5 * $Date: 2005/06/22 01:08:36 $ *
7 * Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
22 * http://www.chelsio.com *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
27 * Maintainers: maintainers@chelsio.com *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
38 ****************************************************************************/
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
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
61 static int t1_wait_op_done(adapter_t
*adapter
, int reg
, u32 mask
, int polarity
,
62 int attempts
, int delay
)
65 u32 val
= readl(adapter
->regs
+ reg
) & mask
;
67 if (!!val
== polarity
)
76 #define TPI_ATTEMPTS 50
79 * Write a register over the TPI interface (unlocked and locked versions).
81 static int __t1_tpi_write(adapter_t
*adapter
, u32 addr
, u32 value
)
85 writel(addr
, adapter
->regs
+ A_TPI_ADDR
);
86 writel(value
, adapter
->regs
+ A_TPI_WR_DATA
);
87 writel(F_TPIWR
, adapter
->regs
+ A_TPI_CSR
);
89 tpi_busy
= t1_wait_op_done(adapter
, A_TPI_CSR
, F_TPIRDY
, 1,
92 CH_ALERT("%s: TPI write to 0x%x failed\n",
97 int t1_tpi_write(adapter_t
*adapter
, u32 addr
, u32 value
)
101 spin_lock(&(adapter
)->tpi_lock
);
102 ret
= __t1_tpi_write(adapter
, addr
, value
);
103 spin_unlock(&(adapter
)->tpi_lock
);
108 * Read a register over the TPI interface (unlocked and locked versions).
110 static int __t1_tpi_read(adapter_t
*adapter
, u32 addr
, u32
*valp
)
114 writel(addr
, adapter
->regs
+ A_TPI_ADDR
);
115 writel(0, adapter
->regs
+ A_TPI_CSR
);
117 tpi_busy
= t1_wait_op_done(adapter
, A_TPI_CSR
, F_TPIRDY
, 1,
120 CH_ALERT("%s: TPI read from 0x%x failed\n",
121 adapter
->name
, addr
);
123 *valp
= readl(adapter
->regs
+ A_TPI_RD_DATA
);
127 int t1_tpi_read(adapter_t
*adapter
, u32 addr
, u32
*valp
)
131 spin_lock(&(adapter
)->tpi_lock
);
132 ret
= __t1_tpi_read(adapter
, addr
, valp
);
133 spin_unlock(&(adapter
)->tpi_lock
);
138 * Called when a port's link settings change to propagate the new values to the
139 * associated PHY and MAC. After performing the common tasks it invokes an
140 * OS-specific handler.
142 /* static */ void link_changed(adapter_t
*adapter
, int port_id
)
144 int link_ok
, speed
, duplex
, fc
;
145 struct cphy
*phy
= adapter
->port
[port_id
].phy
;
146 struct link_config
*lc
= &adapter
->port
[port_id
].link_config
;
148 phy
->ops
->get_link_status(phy
, &link_ok
, &speed
, &duplex
, &fc
);
150 lc
->speed
= speed
< 0 ? SPEED_INVALID
: speed
;
151 lc
->duplex
= duplex
< 0 ? DUPLEX_INVALID
: duplex
;
152 if (!(lc
->requested_fc
& PAUSE_AUTONEG
))
153 fc
= lc
->requested_fc
& (PAUSE_RX
| PAUSE_TX
);
155 if (link_ok
&& speed
>= 0 && lc
->autoneg
== AUTONEG_ENABLE
) {
156 /* Set MAC speed, duplex, and flow control to match PHY. */
157 struct cmac
*mac
= adapter
->port
[port_id
].mac
;
159 mac
->ops
->set_speed_duplex_fc(mac
, speed
, duplex
, fc
);
160 lc
->fc
= (unsigned char)fc
;
162 t1_link_changed(adapter
, port_id
, link_ok
, speed
, duplex
, fc
);
165 static int t1_pci_intr_handler(adapter_t
*adapter
)
169 pci_read_config_dword(adapter
->pdev
, A_PCICFG_INTR_CAUSE
, &pcix_cause
);
172 pci_write_config_dword(adapter
->pdev
, A_PCICFG_INTR_CAUSE
,
174 t1_fatal_err(adapter
); /* PCI errors are fatal */
181 * Wait until Elmer's MI1 interface is ready for new operations.
183 static int mi1_wait_until_ready(adapter_t
*adapter
, int mi1_reg
)
185 int attempts
= 100, busy
;
190 __t1_tpi_read(adapter
, mi1_reg
, &val
);
191 busy
= val
& F_MI1_OP_BUSY
;
194 } while (busy
&& --attempts
);
196 CH_ALERT("%s: MDIO operation timed out\n",
202 * MI1 MDIO initialization.
204 static void mi1_mdio_init(adapter_t
*adapter
, const struct board_info
*bi
)
206 u32 clkdiv
= bi
->clock_elmer0
/ (2 * bi
->mdio_mdc
) - 1;
207 u32 val
= F_MI1_PREAMBLE_ENABLE
| V_MI1_MDI_INVERT(bi
->mdio_mdiinv
) |
208 V_MI1_MDI_ENABLE(bi
->mdio_mdien
) | V_MI1_CLK_DIV(clkdiv
);
210 if (!(bi
->caps
& SUPPORTED_10000baseT_Full
))
212 t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_CFG
, val
);
215 static int mi1_mdio_ext_read(adapter_t
*adapter
, int phy_addr
, int mmd_addr
,
216 int reg_addr
, unsigned int *valp
)
218 u32 addr
= V_MI1_REG_ADDR(mmd_addr
) | V_MI1_PHY_ADDR(phy_addr
);
220 spin_lock(&(adapter
)->tpi_lock
);
222 /* Write the address we want. */
223 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_ADDR
, addr
);
224 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_DATA
, reg_addr
);
225 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_OP
,
226 MI1_OP_INDIRECT_ADDRESS
);
227 mi1_wait_until_ready(adapter
, A_ELMER0_PORT0_MI1_OP
);
229 /* Write the operation we want. */
230 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_OP
, MI1_OP_INDIRECT_READ
);
231 mi1_wait_until_ready(adapter
, A_ELMER0_PORT0_MI1_OP
);
234 __t1_tpi_read(adapter
, A_ELMER0_PORT0_MI1_DATA
, valp
);
235 spin_unlock(&(adapter
)->tpi_lock
);
239 static int mi1_mdio_ext_write(adapter_t
*adapter
, int phy_addr
, int mmd_addr
,
240 int reg_addr
, unsigned int val
)
242 u32 addr
= V_MI1_REG_ADDR(mmd_addr
) | V_MI1_PHY_ADDR(phy_addr
);
244 spin_lock(&(adapter
)->tpi_lock
);
246 /* Write the address we want. */
247 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_ADDR
, addr
);
248 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_DATA
, reg_addr
);
249 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_OP
,
250 MI1_OP_INDIRECT_ADDRESS
);
251 mi1_wait_until_ready(adapter
, A_ELMER0_PORT0_MI1_OP
);
253 /* Write the data. */
254 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_DATA
, val
);
255 __t1_tpi_write(adapter
, A_ELMER0_PORT0_MI1_OP
, MI1_OP_INDIRECT_WRITE
);
256 mi1_wait_until_ready(adapter
, A_ELMER0_PORT0_MI1_OP
);
257 spin_unlock(&(adapter
)->tpi_lock
);
261 static struct mdio_ops mi1_mdio_ext_ops
= {
272 static struct board_info t1_board
[] = {
274 { CHBT_BOARD_N110
, 1/*ports#*/,
275 SUPPORTED_10000baseT_Full
| SUPPORTED_FIBRE
/*caps*/, CHBT_TERM_T1
,
276 CHBT_MAC_PM3393
, CHBT_PHY_88X2010
,
277 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
278 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
279 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops
,
280 &t1_mv88x201x_ops
, &mi1_mdio_ext_ops
,
281 "Chelsio N110 1x10GBaseX NIC" },
283 { CHBT_BOARD_N210
, 1/*ports#*/,
284 SUPPORTED_10000baseT_Full
| SUPPORTED_FIBRE
/*caps*/, CHBT_TERM_T2
,
285 CHBT_MAC_PM3393
, CHBT_PHY_88X2010
,
286 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
287 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
288 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops
,
289 &t1_mv88x201x_ops
, &mi1_mdio_ext_ops
,
290 "Chelsio N210 1x10GBaseX NIC" },
294 struct pci_device_id t1_pci_tbl
[] = {
295 CH_DEVICE(7, 0, CH_BRD_N110_1F
),
296 CH_DEVICE(10, 1, CH_BRD_N210_1F
),
300 MODULE_DEVICE_TABLE(pci
, t1_pci_tbl
);
303 * Return the board_info structure with a given index. Out-of-range indices
306 const struct board_info
*t1_get_board_info(unsigned int board_id
)
308 return board_id
< ARRAY_SIZE(t1_board
) ? &t1_board
[board_id
] : NULL
;
311 struct chelsio_vpd_t
{
313 u8 serial_number
[16];
314 u8 mac_base_address
[6];
315 u8 pad
[2]; /* make multiple-of-4 size requirement explicit */
318 #define EEPROMSIZE (8 * 1024)
319 #define EEPROM_MAX_POLL 4
322 * Read SEEPROM. A zero is written to the flag register when the addres is
323 * written to the Control register. The hardware device will set the flag to a
324 * one when 4B have been transferred to the Data register.
326 int t1_seeprom_read(adapter_t
*adapter
, u32 addr
, u32
*data
)
328 int i
= EEPROM_MAX_POLL
;
331 if (addr
>= EEPROMSIZE
|| (addr
& 3))
334 pci_write_config_word(adapter
->pdev
, A_PCICFG_VPD_ADDR
, (u16
)addr
);
337 pci_read_config_word(adapter
->pdev
, A_PCICFG_VPD_ADDR
, &val
);
338 } while (!(val
& F_VPD_OP_FLAG
) && --i
);
340 if (!(val
& F_VPD_OP_FLAG
)) {
341 CH_ERR("%s: reading EEPROM address 0x%x failed\n",
342 adapter
->name
, addr
);
345 pci_read_config_dword(adapter
->pdev
, A_PCICFG_VPD_DATA
, data
);
346 *data
= le32_to_cpu(*data
);
350 static int t1_eeprom_vpd_get(adapter_t
*adapter
, struct chelsio_vpd_t
*vpd
)
354 for (addr
= 0; !ret
&& addr
< sizeof(*vpd
); addr
+= sizeof(u32
))
355 ret
= t1_seeprom_read(adapter
, addr
,
356 (u32
*)((u8
*)vpd
+ addr
));
362 * Read a port's MAC address from the VPD ROM.
364 static int vpd_macaddress_get(adapter_t
*adapter
, int index
, u8 mac_addr
[])
366 struct chelsio_vpd_t vpd
;
368 if (t1_eeprom_vpd_get(adapter
, &vpd
))
370 memcpy(mac_addr
, vpd
.mac_base_address
, 5);
371 mac_addr
[5] = vpd
.mac_base_address
[5] + index
;
376 * Set up the MAC/PHY according to the requested link settings.
378 * If the PHY can auto-negotiate first decide what to advertise, then
379 * enable/disable auto-negotiation as desired and reset.
381 * If the PHY does not auto-negotiate we just reset it.
383 * If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
384 * otherwise do it later based on the outcome of auto-negotiation.
386 int t1_link_start(struct cphy
*phy
, struct cmac
*mac
, struct link_config
*lc
)
388 unsigned int fc
= lc
->requested_fc
& (PAUSE_RX
| PAUSE_TX
);
390 if (lc
->supported
& SUPPORTED_Autoneg
) {
391 lc
->advertising
&= ~(ADVERTISED_ASYM_PAUSE
| ADVERTISED_PAUSE
);
393 lc
->advertising
|= ADVERTISED_ASYM_PAUSE
;
394 if (fc
== (PAUSE_RX
| PAUSE_TX
))
395 lc
->advertising
|= ADVERTISED_PAUSE
;
397 phy
->ops
->advertise(phy
, lc
->advertising
);
399 if (lc
->autoneg
== AUTONEG_DISABLE
) {
400 lc
->speed
= lc
->requested_speed
;
401 lc
->duplex
= lc
->requested_duplex
;
402 lc
->fc
= (unsigned char)fc
;
403 mac
->ops
->set_speed_duplex_fc(mac
, lc
->speed
,
405 /* Also disables autoneg */
406 phy
->ops
->set_speed_duplex(phy
, lc
->speed
, lc
->duplex
);
407 phy
->ops
->reset(phy
, 0);
409 phy
->ops
->autoneg_enable(phy
); /* also resets PHY */
411 mac
->ops
->set_speed_duplex_fc(mac
, -1, -1, fc
);
412 lc
->fc
= (unsigned char)fc
;
413 phy
->ops
->reset(phy
, 0);
419 * External interrupt handler for boards using elmer0.
421 int elmer0_ext_intr_handler(adapter_t
*adapter
)
427 t1_tpi_read(adapter
, A_ELMER0_INT_CAUSE
, &cause
);
429 switch (board_info(adapter
)->board
) {
430 case CHBT_BOARD_N210
:
431 case CHBT_BOARD_N110
:
432 if (cause
& ELMER0_GP_BIT6
) { /* Marvell 88x2010 interrupt */
433 phy
= adapter
->port
[0].phy
;
434 phy_cause
= phy
->ops
->interrupt_handler(phy
);
435 if (phy_cause
& cphy_cause_link_change
)
436 link_changed(adapter
, 0);
440 t1_tpi_write(adapter
, A_ELMER0_INT_CAUSE
, cause
);
444 /* Enables all interrupts. */
445 void t1_interrupts_enable(adapter_t
*adapter
)
450 adapter
->slow_intr_mask
= F_PL_INTR_SGE_ERR
;
452 t1_sge_intr_enable(adapter
->sge
);
454 adapter
->slow_intr_mask
|= F_PL_INTR_ESPI
;
455 t1_espi_intr_enable(adapter
->espi
);
458 /* Enable MAC/PHY interrupts for each port. */
459 for_each_port(adapter
, i
) {
460 adapter
->port
[i
].mac
->ops
->interrupt_enable(adapter
->port
[i
].mac
);
461 adapter
->port
[i
].phy
->ops
->interrupt_enable(adapter
->port
[i
].phy
);
464 /* Enable PCIX & external chip interrupts on ASIC boards. */
465 pl_intr
= readl(adapter
->regs
+ A_PL_ENABLE
);
467 /* PCI-X interrupts */
468 pci_write_config_dword(adapter
->pdev
, A_PCICFG_INTR_ENABLE
,
471 adapter
->slow_intr_mask
|= F_PL_INTR_EXT
| F_PL_INTR_PCIX
;
472 pl_intr
|= F_PL_INTR_EXT
| F_PL_INTR_PCIX
;
473 writel(pl_intr
, adapter
->regs
+ A_PL_ENABLE
);
476 /* Disables all interrupts. */
477 void t1_interrupts_disable(adapter_t
* adapter
)
481 t1_sge_intr_disable(adapter
->sge
);
483 t1_espi_intr_disable(adapter
->espi
);
485 /* Disable MAC/PHY interrupts for each port. */
486 for_each_port(adapter
, i
) {
487 adapter
->port
[i
].mac
->ops
->interrupt_disable(adapter
->port
[i
].mac
);
488 adapter
->port
[i
].phy
->ops
->interrupt_disable(adapter
->port
[i
].phy
);
491 /* Disable PCIX & external chip interrupts. */
492 writel(0, adapter
->regs
+ A_PL_ENABLE
);
494 /* PCI-X interrupts */
495 pci_write_config_dword(adapter
->pdev
, A_PCICFG_INTR_ENABLE
, 0);
497 adapter
->slow_intr_mask
= 0;
500 /* Clears all interrupts */
501 void t1_interrupts_clear(adapter_t
* adapter
)
507 t1_sge_intr_clear(adapter
->sge
);
509 t1_espi_intr_clear(adapter
->espi
);
511 /* Clear MAC/PHY interrupts for each port. */
512 for_each_port(adapter
, i
) {
513 adapter
->port
[i
].mac
->ops
->interrupt_clear(adapter
->port
[i
].mac
);
514 adapter
->port
[i
].phy
->ops
->interrupt_clear(adapter
->port
[i
].phy
);
517 /* Enable interrupts for external devices. */
518 pl_intr
= readl(adapter
->regs
+ A_PL_CAUSE
);
520 writel(pl_intr
| F_PL_INTR_EXT
| F_PL_INTR_PCIX
,
521 adapter
->regs
+ A_PL_CAUSE
);
523 /* PCI-X interrupts */
524 pci_write_config_dword(adapter
->pdev
, A_PCICFG_INTR_CAUSE
, 0xffffffff);
528 * Slow path interrupt handler for ASICs.
530 int t1_slow_intr_handler(adapter_t
*adapter
)
532 u32 cause
= readl(adapter
->regs
+ A_PL_CAUSE
);
534 cause
&= adapter
->slow_intr_mask
;
537 if (cause
& F_PL_INTR_SGE_ERR
)
538 t1_sge_intr_error_handler(adapter
->sge
);
539 if (cause
& F_PL_INTR_ESPI
)
540 t1_espi_intr_handler(adapter
->espi
);
541 if (cause
& F_PL_INTR_PCIX
)
542 t1_pci_intr_handler(adapter
);
543 if (cause
& F_PL_INTR_EXT
)
544 t1_elmer0_ext_intr(adapter
);
546 /* Clear the interrupts just processed. */
547 writel(cause
, adapter
->regs
+ A_PL_CAUSE
);
548 (void)readl(adapter
->regs
+ A_PL_CAUSE
); /* flush writes */
552 /* Pause deadlock avoidance parameters */
554 #define DROP_PKTS_CNT 1
556 static void set_csum_offload(adapter_t
*adapter
, u32 csum_bit
, int enable
)
558 u32 val
= readl(adapter
->regs
+ A_TP_GLOBAL_CONFIG
);
564 writel(val
, adapter
->regs
+ A_TP_GLOBAL_CONFIG
);
567 void t1_tp_set_ip_checksum_offload(adapter_t
*adapter
, int enable
)
569 set_csum_offload(adapter
, F_IP_CSUM
, enable
);
572 void t1_tp_set_udp_checksum_offload(adapter_t
*adapter
, int enable
)
574 set_csum_offload(adapter
, F_UDP_CSUM
, enable
);
577 void t1_tp_set_tcp_checksum_offload(adapter_t
*adapter
, int enable
)
579 set_csum_offload(adapter
, F_TCP_CSUM
, enable
);
582 static void t1_tp_reset(adapter_t
*adapter
, unsigned int tp_clk
)
586 val
= F_TP_IN_CSPI_CPL
| F_TP_IN_CSPI_CHECK_IP_CSUM
|
587 F_TP_IN_CSPI_CHECK_TCP_CSUM
| F_TP_IN_ESPI_ETHERNET
;
588 val
|= F_TP_IN_ESPI_CHECK_IP_CSUM
|
589 F_TP_IN_ESPI_CHECK_TCP_CSUM
;
590 writel(val
, adapter
->regs
+ A_TP_IN_CONFIG
);
591 writel(F_TP_OUT_CSPI_CPL
|
592 F_TP_OUT_ESPI_ETHERNET
|
593 F_TP_OUT_ESPI_GENERATE_IP_CSUM
|
594 F_TP_OUT_ESPI_GENERATE_TCP_CSUM
,
595 adapter
->regs
+ A_TP_OUT_CONFIG
);
597 val
= readl(adapter
->regs
+ A_TP_GLOBAL_CONFIG
);
598 val
&= ~(F_IP_CSUM
| F_UDP_CSUM
| F_TCP_CSUM
);
599 writel(val
, adapter
->regs
+ A_TP_GLOBAL_CONFIG
);
602 * Enable pause frame deadlock prevention.
604 if (is_T2(adapter
)) {
605 u32 drop_ticks
= DROP_MSEC
* (tp_clk
/ 1000);
607 writel(F_ENABLE_TX_DROP
| F_ENABLE_TX_ERROR
|
608 V_DROP_TICKS_CNT(drop_ticks
) |
609 V_NUM_PKTS_DROPPED(DROP_PKTS_CNT
),
610 adapter
->regs
+ A_TP_TX_DROP_CONFIG
);
613 writel(F_TP_RESET
, adapter
->regs
+ A_TP_RESET
);
616 int __devinit
t1_get_board_rev(adapter_t
*adapter
, const struct board_info
*bi
,
617 struct adapter_params
*p
)
619 p
->chip_version
= bi
->chip_term
;
620 if (p
->chip_version
== CHBT_TERM_T1
||
621 p
->chip_version
== CHBT_TERM_T2
) {
622 u32 val
= readl(adapter
->regs
+ A_TP_PC_CONFIG
);
624 val
= G_TP_PC_REV(val
);
626 p
->chip_revision
= TERM_T1B
;
628 p
->chip_revision
= TERM_T2
;
637 * Enable board components other than the Chelsio chip, such as external MAC
640 static int board_init(adapter_t
*adapter
, const struct board_info
*bi
)
643 case CHBT_BOARD_N110
:
644 case CHBT_BOARD_N210
:
645 writel(V_TPIPAR(0xf), adapter
->regs
+ A_TPI_PAR
);
646 t1_tpi_write(adapter
, A_ELMER0_GPO
, 0x800);
653 * Initialize and configure the Terminator HW modules. Note that external
654 * MAC and PHYs are initialized separately.
656 int t1_init_hw_modules(adapter_t
*adapter
)
659 const struct board_info
*bi
= board_info(adapter
);
661 if (!bi
->clock_mc4
) {
662 u32 val
= readl(adapter
->regs
+ A_MC4_CFG
);
664 writel(val
| F_READY
| F_MC4_SLOW
, adapter
->regs
+ A_MC4_CFG
);
665 writel(F_M_BUS_ENABLE
| F_TCAM_RESET
,
666 adapter
->regs
+ A_MC5_CONFIG
);
669 if (adapter
->espi
&& t1_espi_init(adapter
->espi
, bi
->chip_mac
,
673 t1_tp_reset(adapter
, bi
->clock_core
);
675 err
= t1_sge_configure(adapter
->sge
, &adapter
->params
.sge
);
685 * Determine a card's PCI mode.
687 static void __devinit
get_pci_mode(adapter_t
*adapter
, struct chelsio_pci_params
*p
)
689 static unsigned short speed_map
[] = { 33, 66, 100, 133 };
692 pci_read_config_dword(adapter
->pdev
, A_PCICFG_MODE
, &pci_mode
);
693 p
->speed
= speed_map
[G_PCI_MODE_CLK(pci_mode
)];
694 p
->width
= (pci_mode
& F_PCI_MODE_64BIT
) ? 64 : 32;
695 p
->is_pcix
= (pci_mode
& F_PCI_MODE_PCIX
) != 0;
699 * Release the structures holding the SW per-Terminator-HW-module state.
701 void t1_free_sw_modules(adapter_t
*adapter
)
705 for_each_port(adapter
, i
) {
706 struct cmac
*mac
= adapter
->port
[i
].mac
;
707 struct cphy
*phy
= adapter
->port
[i
].phy
;
710 mac
->ops
->destroy(mac
);
712 phy
->ops
->destroy(phy
);
716 t1_sge_destroy(adapter
->sge
);
718 t1_espi_destroy(adapter
->espi
);
721 static void __devinit
init_link_config(struct link_config
*lc
,
722 const struct board_info
*bi
)
724 lc
->supported
= bi
->caps
;
725 lc
->requested_speed
= lc
->speed
= SPEED_INVALID
;
726 lc
->requested_duplex
= lc
->duplex
= DUPLEX_INVALID
;
727 lc
->requested_fc
= lc
->fc
= PAUSE_RX
| PAUSE_TX
;
728 if (lc
->supported
& SUPPORTED_Autoneg
) {
729 lc
->advertising
= lc
->supported
;
730 lc
->autoneg
= AUTONEG_ENABLE
;
731 lc
->requested_fc
|= PAUSE_AUTONEG
;
734 lc
->autoneg
= AUTONEG_DISABLE
;
740 * Allocate and initialize the data structures that hold the SW state of
741 * the Terminator HW modules.
743 int __devinit
t1_init_sw_modules(adapter_t
*adapter
,
744 const struct board_info
*bi
)
748 adapter
->params
.brd_info
= bi
;
749 adapter
->params
.nports
= bi
->port_number
;
750 adapter
->params
.stats_update_period
= bi
->gmac
->stats_update_period
;
752 adapter
->sge
= t1_sge_create(adapter
, &adapter
->params
.sge
);
754 CH_ERR("%s: SGE initialization failed\n",
759 if (bi
->espi_nports
&& !(adapter
->espi
= t1_espi_create(adapter
))) {
760 CH_ERR("%s: ESPI initialization failed\n",
765 board_init(adapter
, bi
);
766 bi
->mdio_ops
->init(adapter
, bi
);
768 bi
->gphy
->reset(adapter
);
770 bi
->gmac
->reset(adapter
);
772 for_each_port(adapter
, i
) {
775 int phy_addr
= bi
->mdio_phybaseaddr
+ i
;
777 adapter
->port
[i
].phy
= bi
->gphy
->create(adapter
, phy_addr
,
779 if (!adapter
->port
[i
].phy
) {
780 CH_ERR("%s: PHY %d initialization failed\n",
785 adapter
->port
[i
].mac
= mac
= bi
->gmac
->create(adapter
, i
);
787 CH_ERR("%s: MAC %d initialization failed\n",
793 * Get the port's MAC addresses either from the EEPROM if one
794 * exists or the one hardcoded in the MAC.
796 if (vpd_macaddress_get(adapter
, i
, hw_addr
)) {
797 CH_ERR("%s: could not read MAC address from VPD ROM\n",
798 adapter
->port
[i
].dev
->name
);
801 memcpy(adapter
->port
[i
].dev
->dev_addr
, hw_addr
, ETH_ALEN
);
802 init_link_config(&adapter
->port
[i
].link_config
, bi
);
805 get_pci_mode(adapter
, &adapter
->params
.pci
);
806 t1_interrupts_clear(adapter
);
810 t1_free_sw_modules(adapter
);