#include "etherboot.h"#include "nic.h"#include <errno.h>#include <gpxe/pci.h>#include <gpxe/ethernet.h>#include "string.h"#include <mii.h>#include "bnx2.h"#include "bnx2_fw.h"Go to the source code of this file.
Data Structures | |
| struct | bss |
Defines | |
| #define | PHY_RESET_MAX_WAIT 100 |
| #define | ETHTOOL_ALL_FIBRE_SPEED (ADVERTISED_1000baseT_Full) |
| #define | ETHTOOL_ALL_COPPER_SPEED |
| #define | PHY_ALL_10_100_SPEED |
| #define | PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL) |
Functions | |
| FILE_LICENCE (GPL_ANY) | |
| static u32 | bnx2_reg_rd_ind (struct bnx2 *bp, u32 offset) |
| static void | bnx2_reg_wr_ind (struct bnx2 *bp, u32 offset, u32 val) |
| static void | bnx2_ctx_wr (struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) |
| static int | bnx2_read_phy (struct bnx2 *bp, u32 reg, u32 *val) |
| static int | bnx2_write_phy (struct bnx2 *bp, u32 reg, u32 val) |
| static void | bnx2_disable_int (struct bnx2 *bp) |
| static int | bnx2_alloc_mem (struct bnx2 *bp) |
| static void | bnx2_report_fw_link (struct bnx2 *bp) |
| static void | bnx2_report_link (struct bnx2 *bp) |
| static void | bnx2_resolve_flow_ctrl (struct bnx2 *bp) |
| static int | bnx2_5708s_linkup (struct bnx2 *bp) |
| static int | bnx2_5706s_linkup (struct bnx2 *bp) |
| static int | bnx2_copper_linkup (struct bnx2 *bp) |
| static int | bnx2_set_mac_link (struct bnx2 *bp) |
| static int | bnx2_set_link (struct bnx2 *bp) |
| static int | bnx2_reset_phy (struct bnx2 *bp) |
| static u32 | bnx2_phy_get_pause_adv (struct bnx2 *bp) |
| static int | bnx2_setup_serdes_phy (struct bnx2 *bp) |
| static int | bnx2_setup_copper_phy (struct bnx2 *bp) |
| static int | bnx2_setup_phy (struct bnx2 *bp) |
| static int | bnx2_init_5708s_phy (struct bnx2 *bp) |
| static int | bnx2_init_5706s_phy (struct bnx2 *bp) |
| static int | bnx2_init_copper_phy (struct bnx2 *bp) |
| static int | bnx2_init_phy (struct bnx2 *bp) |
| static int | bnx2_fw_sync (struct bnx2 *bp, u32 msg_data, int silent) |
| static void | bnx2_init_context (struct bnx2 *bp) |
| static int | bnx2_alloc_bad_rbuf (struct bnx2 *bp) |
| static void | bnx2_set_mac_addr (struct bnx2 *bp) |
| static void | bnx2_set_rx_mode (struct nic *nic __unused) |
| static void | load_rv2p_fw (struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc) |
| static void | load_cpu_fw (struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) |
| static void | bnx2_init_cpus (struct bnx2 *bp) |
| static int | bnx2_set_power_state_0 (struct bnx2 *bp) |
| static void | bnx2_enable_nvram_access (struct bnx2 *bp) |
| static void | bnx2_disable_nvram_access (struct bnx2 *bp) |
| static int | bnx2_init_nvram (struct bnx2 *bp) |
| static int | bnx2_reset_chip (struct bnx2 *bp, u32 reset_code) |
| static void | bnx2_disable (struct nic *nic __unused) |
| static int | bnx2_init_chip (struct bnx2 *bp) |
| static void | bnx2_init_tx_ring (struct bnx2 *bp) |
| static void | bnx2_init_rx_ring (struct bnx2 *bp) |
| static int | bnx2_reset_nic (struct bnx2 *bp, u32 reset_code) |
| static int | bnx2_init_nic (struct bnx2 *bp) |
| static int | bnx2_init_board (struct pci_device *pdev, struct nic *nic) |
| static void | bnx2_transmit (struct nic *nic, const char *dst_addr, unsigned int type, unsigned int size, const char *packet) |
| static int | bnx2_poll_link (struct bnx2 *bp) |
| static int | bnx2_poll (struct nic *nic, int retrieve) |
| static void | bnx2_irq (struct nic *nic __unused, irq_action_t action __unused) |
| static int | bnx2_probe (struct nic *nic, struct pci_device *pdev) |
| PCI_DRIVER (bnx2_driver, bnx2_nics, PCI_NO_CLASS) | |
| DRIVER ("BNX2", nic_driver, pci_driver, bnx2_driver, bnx2_probe, bnx2_disable) | |
Variables | |
| static struct bss | bnx2_bss |
| static struct bnx2 | bnx2 |
| static struct flash_spec | flash_table [] |
| static struct nic_operations | bnx2_operations |
| static struct pci_device_id | bnx2_nics [] |
| #define PHY_RESET_MAX_WAIT 100 |
Referenced by bnx2_reset_phy().
| #define ETHTOOL_ALL_FIBRE_SPEED (ADVERTISED_1000baseT_Full) |
| #define ETHTOOL_ALL_COPPER_SPEED |
Value:
(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ ADVERTISED_1000baseT_Full)
Definition at line 885 of file bnx2.c.
Referenced by bnx2_init_board().
| #define PHY_ALL_10_100_SPEED |
| #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL) |
| FILE_LICENCE | ( | GPL_ANY | ) |
Definition at line 137 of file bnx2.c.
References BNX2_PCICFG_REG_WINDOW, BNX2_PCICFG_REG_WINDOW_ADDRESS, REG_RD, and REG_WR.
00138 { 00139 REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); 00140 return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW)); 00141 }
Definition at line 144 of file bnx2.c.
References BNX2_PCICFG_REG_WINDOW, BNX2_PCICFG_REG_WINDOW_ADDRESS, and REG_WR.
00145 { 00146 REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); 00147 REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val); 00148 }
Definition at line 151 of file bnx2.c.
References BNX2_CTX_DATA, BNX2_CTX_DATA_ADR, and REG_WR.
00152 { 00153 offset += cid_addr; 00154 REG_WR(bp, BNX2_CTX_DATA_ADR, offset); 00155 REG_WR(bp, BNX2_CTX_DATA, val); 00156 }
Definition at line 159 of file bnx2.c.
References BNX2_EMAC_MDIO_COMM, BNX2_EMAC_MDIO_COMM_COMMAND_READ, BNX2_EMAC_MDIO_COMM_DATA, BNX2_EMAC_MDIO_COMM_DISEXT, BNX2_EMAC_MDIO_COMM_START_BUSY, BNX2_EMAC_MDIO_MODE, BNX2_EMAC_MDIO_MODE_AUTO_POLL, EBUSY, bnx2::phy_addr, bnx2::phy_flags, PHY_INT_MODE_AUTO_POLLING_FLAG, REG_RD, REG_WR, u32, and udelay().
Referenced by bnx2_5706s_linkup(), bnx2_5708s_linkup(), bnx2_copper_linkup(), bnx2_init_5706s_phy(), bnx2_init_5708s_phy(), bnx2_init_copper_phy(), bnx2_init_phy(), bnx2_poll_link(), bnx2_report_fw_link(), bnx2_reset_phy(), bnx2_resolve_flow_ctrl(), bnx2_set_link(), bnx2_setup_copper_phy(), and bnx2_setup_serdes_phy().
00160 { 00161 u32 val1; 00162 int i, ret; 00163 00164 if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { 00165 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00166 val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL; 00167 00168 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); 00169 REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00170 00171 udelay(40); 00172 } 00173 00174 val1 = (bp->phy_addr << 21) | (reg << 16) | 00175 BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT | 00176 BNX2_EMAC_MDIO_COMM_START_BUSY; 00177 REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1); 00178 00179 for (i = 0; i < 50; i++) { 00180 udelay(10); 00181 00182 val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); 00183 if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) { 00184 udelay(5); 00185 00186 val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); 00187 val1 &= BNX2_EMAC_MDIO_COMM_DATA; 00188 00189 break; 00190 } 00191 } 00192 00193 if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) { 00194 *val = 0x0; 00195 ret = -EBUSY; 00196 } 00197 else { 00198 *val = val1; 00199 ret = 0; 00200 } 00201 00202 if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { 00203 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00204 val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL; 00205 00206 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); 00207 REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00208 00209 udelay(40); 00210 } 00211 00212 return ret; 00213 }
Definition at line 216 of file bnx2.c.
References BNX2_EMAC_MDIO_COMM, BNX2_EMAC_MDIO_COMM_COMMAND_WRITE, BNX2_EMAC_MDIO_COMM_DISEXT, BNX2_EMAC_MDIO_COMM_START_BUSY, BNX2_EMAC_MDIO_MODE, BNX2_EMAC_MDIO_MODE_AUTO_POLL, EBUSY, bnx2::phy_addr, bnx2::phy_flags, PHY_INT_MODE_AUTO_POLLING_FLAG, REG_RD, REG_WR, u32, and udelay().
Referenced by bnx2_init_5706s_phy(), bnx2_init_5708s_phy(), bnx2_init_copper_phy(), bnx2_reset_phy(), bnx2_set_link(), bnx2_setup_copper_phy(), and bnx2_setup_serdes_phy().
00217 { 00218 u32 val1; 00219 int i, ret; 00220 00221 if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { 00222 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00223 val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL; 00224 00225 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); 00226 REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00227 00228 udelay(40); 00229 } 00230 00231 val1 = (bp->phy_addr << 21) | (reg << 16) | val | 00232 BNX2_EMAC_MDIO_COMM_COMMAND_WRITE | 00233 BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT; 00234 REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1); 00235 00236 for (i = 0; i < 50; i++) { 00237 udelay(10); 00238 00239 val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); 00240 if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) { 00241 udelay(5); 00242 break; 00243 } 00244 } 00245 00246 if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) 00247 ret = -EBUSY; 00248 else 00249 ret = 0; 00250 00251 if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { 00252 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00253 val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL; 00254 00255 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); 00256 REG_RD(bp, BNX2_EMAC_MDIO_MODE); 00257 00258 udelay(40); 00259 } 00260 00261 return ret; 00262 }
| static void bnx2_disable_int | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 265 of file bnx2.c.
References BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT, REG_RD, and REG_WR.
Referenced by bnx2_probe().
00266 { 00267 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 00268 BNX2_PCICFG_INT_ACK_CMD_MASK_INT); 00269 REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD); 00270 00271 }
| static int bnx2_alloc_mem | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 274 of file bnx2.c.
References bnx2_bss, memset(), RX_DESC_CNT, bnx2::rx_desc_mapping, bss::rx_desc_ring, bnx2::rx_desc_ring, bss::stats_blk, bnx2::stats_blk, bnx2::stats_blk_mapping, bnx2::status_blk, bss::status_blk, bnx2::status_blk_mapping, bnx2::tx_desc_mapping, bss::tx_desc_ring, bnx2::tx_desc_ring, and virt_to_bus().
Referenced by bnx2_probe().
00275 { 00276 bp->tx_desc_ring = bnx2_bss.tx_desc_ring; 00277 bp->tx_desc_mapping = virt_to_bus(bp->tx_desc_ring); 00278 00279 bp->rx_desc_ring = bnx2_bss.rx_desc_ring; 00280 memset(bp->rx_desc_ring, 0, sizeof(struct rx_bd) * RX_DESC_CNT); 00281 bp->rx_desc_mapping = virt_to_bus(bp->rx_desc_ring); 00282 00283 memset(&bnx2_bss.status_blk, 0, sizeof(struct status_block)); 00284 bp->status_blk = &bnx2_bss.status_blk; 00285 bp->status_blk_mapping = virt_to_bus(&bnx2_bss.status_blk); 00286 00287 bp->stats_blk = &bnx2_bss.stats_blk; 00288 memset(&bnx2_bss.stats_blk, 0, sizeof(struct statistics_block)); 00289 bp->stats_blk_mapping = virt_to_bus(&bnx2_bss.stats_blk); 00290 00291 return 0; 00292 }
| static void bnx2_report_fw_link | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 295 of file bnx2.c.
References bnx2::autoneg, BMSR_ANEGCOMPLETE, BNX2_LINK_STATUS, BNX2_LINK_STATUS_1000FULL, BNX2_LINK_STATUS_1000HALF, BNX2_LINK_STATUS_100FULL, BNX2_LINK_STATUS_100HALF, BNX2_LINK_STATUS_10FULL, BNX2_LINK_STATUS_10HALF, BNX2_LINK_STATUS_2500FULL, BNX2_LINK_STATUS_2500HALF, BNX2_LINK_STATUS_AN_COMPLETE, BNX2_LINK_STATUS_AN_ENABLED, BNX2_LINK_STATUS_LINK_DOWN, BNX2_LINK_STATUS_LINK_UP, BNX2_LINK_STATUS_PARALLEL_DET, bnx2_read_phy(), bnx2::duplex, DUPLEX_HALF, bnx2::line_speed, bnx2::link_up, MII_BMSR, bnx2::phy_flags, PHY_PARALLEL_DETECT_FLAG, REG_WR_IND, bnx2::shmem_base, SPEED_10, SPEED_100, SPEED_1000, SPEED_2500, and u32.
Referenced by bnx2_report_link().
00296 { 00297 u32 fw_link_status = 0; 00298 00299 if (bp->link_up) { 00300 u32 bmsr; 00301 00302 switch (bp->line_speed) { 00303 case SPEED_10: 00304 if (bp->duplex == DUPLEX_HALF) 00305 fw_link_status = BNX2_LINK_STATUS_10HALF; 00306 else 00307 fw_link_status = BNX2_LINK_STATUS_10FULL; 00308 break; 00309 case SPEED_100: 00310 if (bp->duplex == DUPLEX_HALF) 00311 fw_link_status = BNX2_LINK_STATUS_100HALF; 00312 else 00313 fw_link_status = BNX2_LINK_STATUS_100FULL; 00314 break; 00315 case SPEED_1000: 00316 if (bp->duplex == DUPLEX_HALF) 00317 fw_link_status = BNX2_LINK_STATUS_1000HALF; 00318 else 00319 fw_link_status = BNX2_LINK_STATUS_1000FULL; 00320 break; 00321 case SPEED_2500: 00322 if (bp->duplex == DUPLEX_HALF) 00323 fw_link_status = BNX2_LINK_STATUS_2500HALF; 00324 else 00325 fw_link_status = BNX2_LINK_STATUS_2500FULL; 00326 break; 00327 } 00328 00329 fw_link_status |= BNX2_LINK_STATUS_LINK_UP; 00330 00331 if (bp->autoneg) { 00332 fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED; 00333 00334 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00335 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00336 00337 if (!(bmsr & BMSR_ANEGCOMPLETE) || 00338 bp->phy_flags & PHY_PARALLEL_DETECT_FLAG) 00339 fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET; 00340 else 00341 fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE; 00342 } 00343 } 00344 else 00345 fw_link_status = BNX2_LINK_STATUS_LINK_DOWN; 00346 00347 REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status); 00348 }
| static void bnx2_report_link | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 351 of file bnx2.c.
References bnx2_report_fw_link(), bnx2::duplex, DUPLEX_FULL, bnx2::flow_ctrl, FLOW_CTRL_RX, FLOW_CTRL_TX, bnx2::line_speed, bnx2::link_up, and printf().
Referenced by bnx2_set_link().
00352 { 00353 if (bp->link_up) { 00354 printf("NIC Link is Up, "); 00355 00356 printf("%d Mbps ", bp->line_speed); 00357 00358 if (bp->duplex == DUPLEX_FULL) 00359 printf("full duplex"); 00360 else 00361 printf("half duplex"); 00362 00363 if (bp->flow_ctrl) { 00364 if (bp->flow_ctrl & FLOW_CTRL_RX) { 00365 printf(", receive "); 00366 if (bp->flow_ctrl & FLOW_CTRL_TX) 00367 printf("& transmit "); 00368 } 00369 else { 00370 printf(", transmit "); 00371 } 00372 printf("flow control ON"); 00373 } 00374 printf("\n"); 00375 } 00376 else { 00377 printf("NIC Link is Down\n"); 00378 } 00379 00380 bnx2_report_fw_link(bp); 00381 }
| static void bnx2_resolve_flow_ctrl | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 384 of file bnx2.c.
References ADVERTISE_1000XPAUSE, ADVERTISE_1000XPSE_ASYM, ADVERTISE_PAUSE_ASYM, ADVERTISE_PAUSE_CAP, bnx2::autoneg, AUTONEG_FLOW_CTRL, AUTONEG_SPEED, BCM5708S_1000X_STAT1, BCM5708S_1000X_STAT1_RX_PAUSE, BCM5708S_1000X_STAT1_TX_PAUSE, bnx2_read_phy(), CHIP_NUM, CHIP_NUM_5708, bnx2::duplex, DUPLEX_FULL, bnx2::flow_ctrl, FLOW_CTRL_RX, FLOW_CTRL_TX, MII_ADVERTISE, MII_LPA, bnx2::phy_flags, PHY_SERDES_FLAG, bnx2::req_flow_ctrl, and u32.
Referenced by bnx2_set_link(), and bnx2_setup_copper_phy().
00385 { 00386 u32 local_adv, remote_adv; 00387 00388 bp->flow_ctrl = 0; 00389 if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != 00390 (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) { 00391 00392 if (bp->duplex == DUPLEX_FULL) { 00393 bp->flow_ctrl = bp->req_flow_ctrl; 00394 } 00395 return; 00396 } 00397 00398 if (bp->duplex != DUPLEX_FULL) { 00399 return; 00400 } 00401 00402 if ((bp->phy_flags & PHY_SERDES_FLAG) && 00403 (CHIP_NUM(bp) == CHIP_NUM_5708)) { 00404 u32 val; 00405 00406 bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val); 00407 if (val & BCM5708S_1000X_STAT1_TX_PAUSE) 00408 bp->flow_ctrl |= FLOW_CTRL_TX; 00409 if (val & BCM5708S_1000X_STAT1_RX_PAUSE) 00410 bp->flow_ctrl |= FLOW_CTRL_RX; 00411 return; 00412 } 00413 00414 bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); 00415 bnx2_read_phy(bp, MII_LPA, &remote_adv); 00416 00417 if (bp->phy_flags & PHY_SERDES_FLAG) { 00418 u32 new_local_adv = 0; 00419 u32 new_remote_adv = 0; 00420 00421 if (local_adv & ADVERTISE_1000XPAUSE) 00422 new_local_adv |= ADVERTISE_PAUSE_CAP; 00423 if (local_adv & ADVERTISE_1000XPSE_ASYM) 00424 new_local_adv |= ADVERTISE_PAUSE_ASYM; 00425 if (remote_adv & ADVERTISE_1000XPAUSE) 00426 new_remote_adv |= ADVERTISE_PAUSE_CAP; 00427 if (remote_adv & ADVERTISE_1000XPSE_ASYM) 00428 new_remote_adv |= ADVERTISE_PAUSE_ASYM; 00429 00430 local_adv = new_local_adv; 00431 remote_adv = new_remote_adv; 00432 } 00433 00434 /* See Table 28B-3 of 802.3ab-1999 spec. */ 00435 if (local_adv & ADVERTISE_PAUSE_CAP) { 00436 if(local_adv & ADVERTISE_PAUSE_ASYM) { 00437 if (remote_adv & ADVERTISE_PAUSE_CAP) { 00438 bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; 00439 } 00440 else if (remote_adv & ADVERTISE_PAUSE_ASYM) { 00441 bp->flow_ctrl = FLOW_CTRL_RX; 00442 } 00443 } 00444 else { 00445 if (remote_adv & ADVERTISE_PAUSE_CAP) { 00446 bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; 00447 } 00448 } 00449 } 00450 else if (local_adv & ADVERTISE_PAUSE_ASYM) { 00451 if ((remote_adv & ADVERTISE_PAUSE_CAP) && 00452 (remote_adv & ADVERTISE_PAUSE_ASYM)) { 00453 00454 bp->flow_ctrl = FLOW_CTRL_TX; 00455 } 00456 } 00457 }
| static int bnx2_5708s_linkup | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 460 of file bnx2.c.
References BCM5708S_1000X_STAT1, BCM5708S_1000X_STAT1_FD, BCM5708S_1000X_STAT1_SPEED_10, BCM5708S_1000X_STAT1_SPEED_100, BCM5708S_1000X_STAT1_SPEED_1G, BCM5708S_1000X_STAT1_SPEED_2G5, BCM5708S_1000X_STAT1_SPEED_MASK, bnx2_read_phy(), bnx2::duplex, DUPLEX_FULL, DUPLEX_HALF, bnx2::line_speed, bnx2::link_up, SPEED_10, SPEED_100, SPEED_1000, SPEED_2500, and u32.
Referenced by bnx2_set_link().
00461 { 00462 u32 val; 00463 00464 bp->link_up = 1; 00465 bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val); 00466 switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) { 00467 case BCM5708S_1000X_STAT1_SPEED_10: 00468 bp->line_speed = SPEED_10; 00469 break; 00470 case BCM5708S_1000X_STAT1_SPEED_100: 00471 bp->line_speed = SPEED_100; 00472 break; 00473 case BCM5708S_1000X_STAT1_SPEED_1G: 00474 bp->line_speed = SPEED_1000; 00475 break; 00476 case BCM5708S_1000X_STAT1_SPEED_2G5: 00477 bp->line_speed = SPEED_2500; 00478 break; 00479 } 00480 if (val & BCM5708S_1000X_STAT1_FD) 00481 bp->duplex = DUPLEX_FULL; 00482 else 00483 bp->duplex = DUPLEX_HALF; 00484 00485 return 0; 00486 }
| static int bnx2_5706s_linkup | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 489 of file bnx2.c.
References ADVERTISE_1000XFULL, ADVERTISE_1000XHALF, BMCR_ANENABLE, BMCR_FULLDPLX, bnx2_read_phy(), bnx2::duplex, DUPLEX_FULL, DUPLEX_HALF, bnx2::line_speed, bnx2::link_up, MII_ADVERTISE, MII_BMCR, MII_LPA, SPEED_1000, and u32.
Referenced by bnx2_set_link().
00490 { 00491 u32 bmcr, local_adv, remote_adv, common; 00492 00493 bp->link_up = 1; 00494 bp->line_speed = SPEED_1000; 00495 00496 bnx2_read_phy(bp, MII_BMCR, &bmcr); 00497 if (bmcr & BMCR_FULLDPLX) { 00498 bp->duplex = DUPLEX_FULL; 00499 } 00500 else { 00501 bp->duplex = DUPLEX_HALF; 00502 } 00503 00504 if (!(bmcr & BMCR_ANENABLE)) { 00505 return 0; 00506 } 00507 00508 bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); 00509 bnx2_read_phy(bp, MII_LPA, &remote_adv); 00510 00511 common = local_adv & remote_adv; 00512 if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) { 00513 00514 if (common & ADVERTISE_1000XFULL) { 00515 bp->duplex = DUPLEX_FULL; 00516 } 00517 else { 00518 bp->duplex = DUPLEX_HALF; 00519 } 00520 } 00521 00522 return 0; 00523 }
| static int bnx2_copper_linkup | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 526 of file bnx2.c.
References ADVERTISE_1000FULL, ADVERTISE_1000HALF, ADVERTISE_100FULL, ADVERTISE_100HALF, ADVERTISE_10FULL, ADVERTISE_10HALF, BMCR_ANENABLE, BMCR_FULLDPLX, BMCR_SPEED100, bnx2_read_phy(), bnx2::duplex, DUPLEX_FULL, DUPLEX_HALF, bnx2::line_speed, bnx2::link_up, MII_ADVERTISE, MII_BMCR, MII_CTRL1000, MII_LPA, MII_STAT1000, SPEED_10, SPEED_100, SPEED_1000, and u32.
Referenced by bnx2_set_link().
00527 { 00528 u32 bmcr; 00529 00530 bnx2_read_phy(bp, MII_BMCR, &bmcr); 00531 if (bmcr & BMCR_ANENABLE) { 00532 u32 local_adv, remote_adv, common; 00533 00534 bnx2_read_phy(bp, MII_CTRL1000, &local_adv); 00535 bnx2_read_phy(bp, MII_STAT1000, &remote_adv); 00536 00537 common = local_adv & (remote_adv >> 2); 00538 if (common & ADVERTISE_1000FULL) { 00539 bp->line_speed = SPEED_1000; 00540 bp->duplex = DUPLEX_FULL; 00541 } 00542 else if (common & ADVERTISE_1000HALF) { 00543 bp->line_speed = SPEED_1000; 00544 bp->duplex = DUPLEX_HALF; 00545 } 00546 else { 00547 bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); 00548 bnx2_read_phy(bp, MII_LPA, &remote_adv); 00549 00550 common = local_adv & remote_adv; 00551 if (common & ADVERTISE_100FULL) { 00552 bp->line_speed = SPEED_100; 00553 bp->duplex = DUPLEX_FULL; 00554 } 00555 else if (common & ADVERTISE_100HALF) { 00556 bp->line_speed = SPEED_100; 00557 bp->duplex = DUPLEX_HALF; 00558 } 00559 else if (common & ADVERTISE_10FULL) { 00560 bp->line_speed = SPEED_10; 00561 bp->duplex = DUPLEX_FULL; 00562 } 00563 else if (common & ADVERTISE_10HALF) { 00564 bp->line_speed = SPEED_10; 00565 bp->duplex = DUPLEX_HALF; 00566 } 00567 else { 00568 bp->line_speed = 0; 00569 bp->link_up = 0; 00570 } 00571 } 00572 } 00573 else { 00574 if (bmcr & BMCR_SPEED100) { 00575 bp->line_speed = SPEED_100; 00576 } 00577 else { 00578 bp->line_speed = SPEED_10; 00579 } 00580 if (bmcr & BMCR_FULLDPLX) { 00581 bp->duplex = DUPLEX_FULL; 00582 } 00583 else { 00584 bp->duplex = DUPLEX_HALF; 00585 } 00586 } 00587 00588 return 0; 00589 }
| static int bnx2_set_mac_link | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 592 of file bnx2.c.
References BNX2_EMAC_MODE, BNX2_EMAC_MODE_25G, BNX2_EMAC_MODE_FORCE_LINK, BNX2_EMAC_MODE_HALF_DUPLEX, BNX2_EMAC_MODE_MAC_LOOP, BNX2_EMAC_MODE_PORT, BNX2_EMAC_MODE_PORT_GMII, BNX2_EMAC_MODE_PORT_MII, BNX2_EMAC_MODE_PORT_MII_10, BNX2_EMAC_RX_MODE, BNX2_EMAC_RX_MODE_FLOW_EN, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE, BNX2_EMAC_TX_LENGTHS, BNX2_EMAC_TX_MODE, BNX2_EMAC_TX_MODE_FLOW_EN, CHIP_NUM, CHIP_NUM_5708, bnx2::duplex, DUPLEX_HALF, bnx2::flow_ctrl, FLOW_CTRL_RX, FLOW_CTRL_TX, bnx2::line_speed, bnx2::link_up, REG_RD, REG_WR, bnx2::rx_mode, SPEED_10, SPEED_100, SPEED_1000, SPEED_2500, and u32.
Referenced by bnx2_set_link(), and bnx2_setup_copper_phy().
00593 { 00594 u32 val; 00595 00596 REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620); 00597 if (bp->link_up && (bp->line_speed == SPEED_1000) && 00598 (bp->duplex == DUPLEX_HALF)) { 00599 REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff); 00600 } 00601 00602 /* Configure the EMAC mode register. */ 00603 val = REG_RD(bp, BNX2_EMAC_MODE); 00604 00605 val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | 00606 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | 00607 BNX2_EMAC_MODE_25G); 00608 00609 if (bp->link_up) { 00610 switch (bp->line_speed) { 00611 case SPEED_10: 00612 if (CHIP_NUM(bp) == CHIP_NUM_5708) { 00613 val |= BNX2_EMAC_MODE_PORT_MII_10; 00614 break; 00615 } 00616 /* fall through */ 00617 case SPEED_100: 00618 val |= BNX2_EMAC_MODE_PORT_MII; 00619 break; 00620 case SPEED_2500: 00621 val |= BNX2_EMAC_MODE_25G; 00622 /* fall through */ 00623 case SPEED_1000: 00624 val |= BNX2_EMAC_MODE_PORT_GMII; 00625 break; 00626 } 00627 } 00628 else { 00629 val |= BNX2_EMAC_MODE_PORT_GMII; 00630 } 00631 00632 /* Set the MAC to operate in the appropriate duplex mode. */ 00633 if (bp->duplex == DUPLEX_HALF) 00634 val |= BNX2_EMAC_MODE_HALF_DUPLEX; 00635 REG_WR(bp, BNX2_EMAC_MODE, val); 00636 00637 /* Enable/disable rx PAUSE. */ 00638 bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN; 00639 00640 if (bp->flow_ctrl & FLOW_CTRL_RX) 00641 bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN; 00642 REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode); 00643 00644 /* Enable/disable tx PAUSE. */ 00645 val = REG_RD(bp, BNX2_EMAC_TX_MODE); 00646 val &= ~BNX2_EMAC_TX_MODE_FLOW_EN; 00647 00648 if (bp->flow_ctrl & FLOW_CTRL_TX) 00649 val |= BNX2_EMAC_TX_MODE_FLOW_EN; 00650 REG_WR(bp, BNX2_EMAC_TX_MODE, val); 00651 00652 /* Acknowledge the interrupt. */ 00653 REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); 00654 00655 return 0; 00656 }
| static int bnx2_set_link | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 659 of file bnx2.c.
References bnx2::autoneg, AUTONEG_SPEED, BMCR_ANENABLE, BMSR_LSTATUS, bnx2_5706s_linkup(), bnx2_5708s_linkup(), bnx2_copper_linkup(), BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK, bnx2_read_phy(), bnx2_report_link(), bnx2_resolve_flow_ctrl(), bnx2_set_mac_link(), bnx2_write_phy(), CHIP_NUM, CHIP_NUM_5706, CHIP_NUM_5708, bnx2::link_up, bnx2::loopback, MAC_LOOPBACK, MII_BMCR, MII_BMSR, bnx2::phy_flags, PHY_PARALLEL_DETECT_FLAG, PHY_SERDES_FLAG, REG_RD, u32, and u8.
Referenced by bnx2_init_nic(), and bnx2_poll_link().
00660 { 00661 u32 bmsr; 00662 u8 link_up; 00663 00664 if (bp->loopback == MAC_LOOPBACK) { 00665 bp->link_up = 1; 00666 return 0; 00667 } 00668 00669 link_up = bp->link_up; 00670 00671 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00672 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00673 00674 if ((bp->phy_flags & PHY_SERDES_FLAG) && 00675 (CHIP_NUM(bp) == CHIP_NUM_5706)) { 00676 u32 val; 00677 00678 val = REG_RD(bp, BNX2_EMAC_STATUS); 00679 if (val & BNX2_EMAC_STATUS_LINK) 00680 bmsr |= BMSR_LSTATUS; 00681 else 00682 bmsr &= ~BMSR_LSTATUS; 00683 } 00684 00685 if (bmsr & BMSR_LSTATUS) { 00686 bp->link_up = 1; 00687 00688 if (bp->phy_flags & PHY_SERDES_FLAG) { 00689 if (CHIP_NUM(bp) == CHIP_NUM_5706) 00690 bnx2_5706s_linkup(bp); 00691 else if (CHIP_NUM(bp) == CHIP_NUM_5708) 00692 bnx2_5708s_linkup(bp); 00693 } 00694 else { 00695 bnx2_copper_linkup(bp); 00696 } 00697 bnx2_resolve_flow_ctrl(bp); 00698 } 00699 else { 00700 if ((bp->phy_flags & PHY_SERDES_FLAG) && 00701 (bp->autoneg & AUTONEG_SPEED)) { 00702 00703 u32 bmcr; 00704 00705 bnx2_read_phy(bp, MII_BMCR, &bmcr); 00706 if (!(bmcr & BMCR_ANENABLE)) { 00707 bnx2_write_phy(bp, MII_BMCR, bmcr | 00708 BMCR_ANENABLE); 00709 } 00710 } 00711 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; 00712 bp->link_up = 0; 00713 } 00714 00715 if (bp->link_up != link_up) { 00716 bnx2_report_link(bp); 00717 } 00718 00719 bnx2_set_mac_link(bp); 00720 00721 return 0; 00722 }
| static int bnx2_reset_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 725 of file bnx2.c.
References BMCR_RESET, bnx2_read_phy(), bnx2_write_phy(), EBUSY, MII_BMCR, PHY_RESET_MAX_WAIT, u32, and udelay().
Referenced by bnx2_init_phy().
00726 { 00727 int i; 00728 u32 reg; 00729 00730 bnx2_write_phy(bp, MII_BMCR, BMCR_RESET); 00731 00732 #define PHY_RESET_MAX_WAIT 100 00733 for (i = 0; i < PHY_RESET_MAX_WAIT; i++) { 00734 udelay(10); 00735 00736 bnx2_read_phy(bp, MII_BMCR, ®); 00737 if (!(reg & BMCR_RESET)) { 00738 udelay(20); 00739 break; 00740 } 00741 } 00742 if (i == PHY_RESET_MAX_WAIT) { 00743 return -EBUSY; 00744 } 00745 return 0; 00746 }
Definition at line 749 of file bnx2.c.
References ADVERTISE_1000XPAUSE, ADVERTISE_1000XPSE_ASYM, ADVERTISE_PAUSE_ASYM, ADVERTISE_PAUSE_CAP, FLOW_CTRL_RX, FLOW_CTRL_TX, bnx2::phy_flags, PHY_SERDES_FLAG, bnx2::req_flow_ctrl, and u32.
Referenced by bnx2_setup_copper_phy(), and bnx2_setup_serdes_phy().
00750 { 00751 u32 adv = 0; 00752 00753 if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) == 00754 (FLOW_CTRL_RX | FLOW_CTRL_TX)) { 00755 00756 if (bp->phy_flags & PHY_SERDES_FLAG) { 00757 adv = ADVERTISE_1000XPAUSE; 00758 } 00759 else { 00760 adv = ADVERTISE_PAUSE_CAP; 00761 } 00762 } 00763 else if (bp->req_flow_ctrl & FLOW_CTRL_TX) { 00764 if (bp->phy_flags & PHY_SERDES_FLAG) { 00765 adv = ADVERTISE_1000XPSE_ASYM; 00766 } 00767 else { 00768 adv = ADVERTISE_PAUSE_ASYM; 00769 } 00770 } 00771 else if (bp->req_flow_ctrl & FLOW_CTRL_RX) { 00772 if (bp->phy_flags & PHY_SERDES_FLAG) { 00773 adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM; 00774 } 00775 else { 00776 adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; 00777 } 00778 } 00779 return adv; 00780 }
| static int bnx2_setup_serdes_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 783 of file bnx2.c.
References ADVERTISE_1000XFULL, ADVERTISE_1000XHALF, ADVERTISED_1000baseT_Full, bnx2::advertising, bnx2::autoneg, AUTONEG_SPEED, BCM5708S_UP1, BCM5708S_UP1_2G5, BMCR_ANENABLE, BMCR_ANRESTART, BMCR_FULLDPLX, BMCR_LOOPBACK, BMCR_SPEED1000, bnx2_phy_get_pause_adv(), bnx2_read_phy(), bnx2_write_phy(), CHIP_NUM, CHIP_NUM_5706, CHIP_NUM_5708, DUPLEX_FULL, bnx2::link_up, MII_ADVERTISE, MII_BMCR, PHY_2_5G_CAPABLE_FLAG, bnx2::phy_flags, bnx2::req_duplex, bnx2::serdes_an_pending, SERDES_AN_TIMEOUT, u32, and udelay().
Referenced by bnx2_setup_phy().
00784 { 00785 u32 adv, bmcr, up1; 00786 u32 new_adv = 0; 00787 00788 if (!(bp->autoneg & AUTONEG_SPEED)) { 00789 u32 new_bmcr; 00790 int force_link_down = 0; 00791 00792 if (CHIP_NUM(bp) == CHIP_NUM_5708) { 00793 bnx2_read_phy(bp, BCM5708S_UP1, &up1); 00794 if (up1 & BCM5708S_UP1_2G5) { 00795 up1 &= ~BCM5708S_UP1_2G5; 00796 bnx2_write_phy(bp, BCM5708S_UP1, up1); 00797 force_link_down = 1; 00798 } 00799 } 00800 00801 bnx2_read_phy(bp, MII_ADVERTISE, &adv); 00802 adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF); 00803 00804 bnx2_read_phy(bp, MII_BMCR, &bmcr); 00805 new_bmcr = bmcr & ~BMCR_ANENABLE; 00806 new_bmcr |= BMCR_SPEED1000; 00807 if (bp->req_duplex == DUPLEX_FULL) { 00808 adv |= ADVERTISE_1000XFULL; 00809 new_bmcr |= BMCR_FULLDPLX; 00810 } 00811 else { 00812 adv |= ADVERTISE_1000XHALF; 00813 new_bmcr &= ~BMCR_FULLDPLX; 00814 } 00815 if ((new_bmcr != bmcr) || (force_link_down)) { 00816 /* Force a link down visible on the other side */ 00817 if (bp->link_up) { 00818 bnx2_write_phy(bp, MII_ADVERTISE, adv & 00819 ~(ADVERTISE_1000XFULL | 00820 ADVERTISE_1000XHALF)); 00821 bnx2_write_phy(bp, MII_BMCR, bmcr | 00822 BMCR_ANRESTART | BMCR_ANENABLE); 00823 00824 bp->link_up = 0; 00825 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 00826 } 00827 bnx2_write_phy(bp, MII_ADVERTISE, adv); 00828 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 00829 } 00830 return 0; 00831 } 00832 00833 if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { 00834 bnx2_read_phy(bp, BCM5708S_UP1, &up1); 00835 up1 |= BCM5708S_UP1_2G5; 00836 bnx2_write_phy(bp, BCM5708S_UP1, up1); 00837 } 00838 00839 if (bp->advertising & ADVERTISED_1000baseT_Full) 00840 new_adv |= ADVERTISE_1000XFULL; 00841 00842 new_adv |= bnx2_phy_get_pause_adv(bp); 00843 00844 bnx2_read_phy(bp, MII_ADVERTISE, &adv); 00845 bnx2_read_phy(bp, MII_BMCR, &bmcr); 00846 00847 bp->serdes_an_pending = 0; 00848 if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) { 00849 /* Force a link down visible on the other side */ 00850 if (bp->link_up) { 00851 int i; 00852 00853 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); 00854 for (i = 0; i < 110; i++) { 00855 udelay(100); 00856 } 00857 } 00858 00859 bnx2_write_phy(bp, MII_ADVERTISE, new_adv); 00860 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | 00861 BMCR_ANENABLE); 00862 #if 0 00863 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 00864 /* Speed up link-up time when the link partner 00865 * does not autonegotiate which is very common 00866 * in blade servers. Some blade servers use 00867 * IPMI for kerboard input and it's important 00868 * to minimize link disruptions. Autoneg. involves 00869 * exchanging base pages plus 3 next pages and 00870 * normally completes in about 120 msec. 00871 */ 00872 bp->current_interval = SERDES_AN_TIMEOUT; 00873 bp->serdes_an_pending = 1; 00874 mod_timer(&bp->timer, jiffies + bp->current_interval); 00875 } 00876 #endif 00877 } 00878 00879 return 0; 00880 }
| static int bnx2_setup_copper_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 896 of file bnx2.c.
References ADVERTISE_1000FULL, ADVERTISE_100FULL, ADVERTISE_100HALF, ADVERTISE_10FULL, ADVERTISE_10HALF, ADVERTISE_CSMA, ADVERTISE_PAUSE_ASYM, ADVERTISE_PAUSE_CAP, ADVERTISED_1000baseT_Full, ADVERTISED_100baseT_Full, ADVERTISED_100baseT_Half, ADVERTISED_10baseT_Full, ADVERTISED_10baseT_Half, bnx2::advertising, bnx2::autoneg, AUTONEG_SPEED, BMCR_ANENABLE, BMCR_ANRESTART, BMCR_FULLDPLX, BMCR_LOOPBACK, BMCR_SPEED100, BMSR_LSTATUS, bnx2_phy_get_pause_adv(), bnx2_read_phy(), bnx2_resolve_flow_ctrl(), bnx2_set_mac_link(), bnx2_write_phy(), bnx2::duplex, DUPLEX_FULL, bnx2::line_speed, bnx2::link_up, MII_ADVERTISE, MII_BMCR, MII_BMSR, MII_CTRL1000, PHY_ALL_1000_SPEED, PHY_ALL_10_100_SPEED, bnx2::req_duplex, bnx2::req_line_speed, SPEED_100, u32, and udelay().
Referenced by bnx2_setup_phy().
00897 { 00898 u32 bmcr; 00899 u32 new_bmcr; 00900 00901 bnx2_read_phy(bp, MII_BMCR, &bmcr); 00902 00903 if (bp->autoneg & AUTONEG_SPEED) { 00904 u32 adv_reg, adv1000_reg; 00905 u32 new_adv_reg = 0; 00906 u32 new_adv1000_reg = 0; 00907 00908 bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg); 00909 adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | 00910 ADVERTISE_PAUSE_ASYM); 00911 00912 bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg); 00913 adv1000_reg &= PHY_ALL_1000_SPEED; 00914 00915 if (bp->advertising & ADVERTISED_10baseT_Half) 00916 new_adv_reg |= ADVERTISE_10HALF; 00917 if (bp->advertising & ADVERTISED_10baseT_Full) 00918 new_adv_reg |= ADVERTISE_10FULL; 00919 if (bp->advertising & ADVERTISED_100baseT_Half) 00920 new_adv_reg |= ADVERTISE_100HALF; 00921 if (bp->advertising & ADVERTISED_100baseT_Full) 00922 new_adv_reg |= ADVERTISE_100FULL; 00923 if (bp->advertising & ADVERTISED_1000baseT_Full) 00924 new_adv1000_reg |= ADVERTISE_1000FULL; 00925 00926 new_adv_reg |= ADVERTISE_CSMA; 00927 00928 new_adv_reg |= bnx2_phy_get_pause_adv(bp); 00929 00930 if ((adv1000_reg != new_adv1000_reg) || 00931 (adv_reg != new_adv_reg) || 00932 ((bmcr & BMCR_ANENABLE) == 0)) { 00933 00934 bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg); 00935 bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg); 00936 bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART | 00937 BMCR_ANENABLE); 00938 } 00939 else if (bp->link_up) { 00940 /* Flow ctrl may have changed from auto to forced */ 00941 /* or vice-versa. */ 00942 00943 bnx2_resolve_flow_ctrl(bp); 00944 bnx2_set_mac_link(bp); 00945 } 00946 return 0; 00947 } 00948 00949 new_bmcr = 0; 00950 if (bp->req_line_speed == SPEED_100) { 00951 new_bmcr |= BMCR_SPEED100; 00952 } 00953 if (bp->req_duplex == DUPLEX_FULL) { 00954 new_bmcr |= BMCR_FULLDPLX; 00955 } 00956 if (new_bmcr != bmcr) { 00957 u32 bmsr; 00958 int i = 0; 00959 00960 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00961 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00962 00963 if (bmsr & BMSR_LSTATUS) { 00964 /* Force link down */ 00965 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); 00966 do { 00967 udelay(100); 00968 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00969 bnx2_read_phy(bp, MII_BMSR, &bmsr); 00970 i++; 00971 } while ((bmsr & BMSR_LSTATUS) && (i < 620)); 00972 } 00973 00974 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 00975 00976 /* Normally, the new speed is setup after the link has 00977 * gone down and up again. In some cases, link will not go 00978 * down so we need to set up the new speed here. 00979 */ 00980 if (bmsr & BMSR_LSTATUS) { 00981 bp->line_speed = bp->req_line_speed; 00982 bp->duplex = bp->req_duplex; 00983 bnx2_resolve_flow_ctrl(bp); 00984 bnx2_set_mac_link(bp); 00985 } 00986 } 00987 return 0; 00988 }
| static int bnx2_setup_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 991 of file bnx2.c.
References bnx2_setup_copper_phy(), bnx2_setup_serdes_phy(), bnx2::loopback, MAC_LOOPBACK, bnx2::phy_flags, and PHY_SERDES_FLAG.
Referenced by bnx2_init_phy().
00992 { 00993 if (bp->loopback == MAC_LOOPBACK) 00994 return 0; 00995 00996 if (bp->phy_flags & PHY_SERDES_FLAG) { 00997 return (bnx2_setup_serdes_phy(bp)); 00998 } 00999 else { 01000 return (bnx2_setup_copper_phy(bp)); 01001 } 01002 }
| static int bnx2_init_5708s_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1005 of file bnx2.c.
References BCM5708S_1000X_CTL1, BCM5708S_1000X_CTL1_AUTODET_EN, BCM5708S_1000X_CTL1_FIBER_MODE, BCM5708S_1000X_CTL2, BCM5708S_1000X_CTL2_PLLEL_DET_EN, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG, BCM5708S_BLK_ADDR_DIG3, BCM5708S_BLK_ADDR_TX_MISC, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE, BCM5708S_TX_ACTL1, BCM5708S_TX_ACTL1_DRIVER_VCM, BCM5708S_TX_ACTL3, BCM5708S_UP1, BCM5708S_UP1_2G5, BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK, BNX2_PORT_HW_CFG_CONFIG, bnx2_read_phy(), BNX2_SHARED_HW_CFG_CONFIG, BNX2_SHARED_HW_CFG_PHY_BACKPLANE, bnx2_write_phy(), CHIP_ID, CHIP_ID_5708_A0, CHIP_ID_5708_B0, CHIP_ID_5708_B1, PHY_2_5G_CAPABLE_FLAG, bnx2::phy_flags, REG_RD_IND, bnx2::shmem_base, and u32.
Referenced by bnx2_init_phy().
01006 { 01007 u32 val; 01008 01009 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3); 01010 bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE); 01011 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); 01012 01013 bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val); 01014 val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN; 01015 bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val); 01016 01017 bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val); 01018 val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN; 01019 bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val); 01020 01021 if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { 01022 bnx2_read_phy(bp, BCM5708S_UP1, &val); 01023 val |= BCM5708S_UP1_2G5; 01024 bnx2_write_phy(bp, BCM5708S_UP1, val); 01025 } 01026 01027 if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || 01028 (CHIP_ID(bp) == CHIP_ID_5708_B0) || 01029 (CHIP_ID(bp) == CHIP_ID_5708_B1)) { 01030 /* increase tx signal amplitude */ 01031 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, 01032 BCM5708S_BLK_ADDR_TX_MISC); 01033 bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val); 01034 val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM; 01035 bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val); 01036 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); 01037 } 01038 01039 val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) & 01040 BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK; 01041 01042 if (val) { 01043 u32 is_backplane; 01044 01045 is_backplane = REG_RD_IND(bp, bp->shmem_base + 01046 BNX2_SHARED_HW_CFG_CONFIG); 01047 if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) { 01048 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, 01049 BCM5708S_BLK_ADDR_TX_MISC); 01050 bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val); 01051 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, 01052 BCM5708S_BLK_ADDR_DIG); 01053 } 01054 } 01055 return 0; 01056 }
| static int bnx2_init_5706s_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1059 of file bnx2.c.
References BNX2_MISC_UNUSED0, bnx2_read_phy(), bnx2_write_phy(), CHIP_NUM, CHIP_NUM_5706, bnx2::phy_flags, PHY_PARALLEL_DETECT_FLAG, REG_WR, and u32.
Referenced by bnx2_init_phy().
01060 { 01061 u32 val; 01062 01063 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; 01064 01065 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 01066 REG_WR(bp, BNX2_MISC_UNUSED0, 0x300); 01067 } 01068 01069 01070 bnx2_write_phy(bp, 0x18, 0x7); 01071 bnx2_read_phy(bp, 0x18, &val); 01072 bnx2_write_phy(bp, 0x18, val & ~0x4007); 01073 01074 bnx2_write_phy(bp, 0x1c, 0x6c00); 01075 bnx2_read_phy(bp, 0x1c, &val); 01076 bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00); 01077 01078 return 0; 01079 }
| static int bnx2_init_copper_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1082 of file bnx2.c.
References bnx2_read_phy(), bnx2_write_phy(), PHY_CRC_FIX_FLAG, bnx2::phy_flags, and u32.
Referenced by bnx2_init_phy().
01083 { 01084 u32 val; 01085 01086 bp->phy_flags |= PHY_CRC_FIX_FLAG; 01087 01088 if (bp->phy_flags & PHY_CRC_FIX_FLAG) { 01089 bnx2_write_phy(bp, 0x18, 0x0c00); 01090 bnx2_write_phy(bp, 0x17, 0x000a); 01091 bnx2_write_phy(bp, 0x15, 0x310b); 01092 bnx2_write_phy(bp, 0x17, 0x201f); 01093 bnx2_write_phy(bp, 0x15, 0x9506); 01094 bnx2_write_phy(bp, 0x17, 0x401f); 01095 bnx2_write_phy(bp, 0x15, 0x14e2); 01096 bnx2_write_phy(bp, 0x18, 0x0400); 01097 } 01098 01099 bnx2_write_phy(bp, 0x18, 0x7); 01100 bnx2_read_phy(bp, 0x18, &val); 01101 bnx2_write_phy(bp, 0x18, val & ~0x4007); 01102 01103 bnx2_read_phy(bp, 0x10, &val); 01104 bnx2_write_phy(bp, 0x10, val & ~0x1); 01105 01106 /* ethernet@wirespeed */ 01107 bnx2_write_phy(bp, 0x18, 0x7007); 01108 bnx2_read_phy(bp, 0x18, &val); 01109 bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4)); 01110 return 0; 01111 }
| static int bnx2_init_phy | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1114 of file bnx2.c.
References BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK, bnx2_init_5706s_phy(), bnx2_init_5708s_phy(), bnx2_init_copper_phy(), bnx2_read_phy(), bnx2_reset_phy(), bnx2_setup_phy(), CHIP_NUM, CHIP_NUM_5706, CHIP_NUM_5708, MII_PHYSID1, MII_PHYSID2, bnx2::phy_flags, bnx2::phy_id, PHY_INT_MODE_LINK_READY_FLAG, PHY_INT_MODE_MASK_FLAG, PHY_SERDES_FLAG, REG_WR, and u32.
Referenced by bnx2_init_nic().
01115 { 01116 u32 val; 01117 int rc = 0; 01118 01119 bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG; 01120 bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG; 01121 01122 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); 01123 01124 bnx2_reset_phy(bp); 01125 01126 bnx2_read_phy(bp, MII_PHYSID1, &val); 01127 bp->phy_id = val << 16; 01128 bnx2_read_phy(bp, MII_PHYSID2, &val); 01129 bp->phy_id |= val & 0xffff; 01130 01131 if (bp->phy_flags & PHY_SERDES_FLAG) { 01132 if (CHIP_NUM(bp) == CHIP_NUM_5706) 01133 rc = bnx2_init_5706s_phy(bp); 01134 else if (CHIP_NUM(bp) == CHIP_NUM_5708) 01135 rc = bnx2_init_5708s_phy(bp); 01136 } 01137 else { 01138 rc = bnx2_init_copper_phy(bp); 01139 } 01140 01141 bnx2_setup_phy(bp); 01142 01143 return rc; 01144 }
Definition at line 1147 of file bnx2.c.
References BNX2_DRV_MB, BNX2_DRV_MSG_CODE, BNX2_DRV_MSG_CODE_FW_TIMEOUT, BNX2_DRV_MSG_DATA, BNX2_DRV_MSG_DATA_WAIT0, BNX2_DRV_MSG_SEQ, BNX2_FW_MB, BNX2_FW_MSG_ACK, BNX2_FW_MSG_STATUS_MASK, BNX2_FW_MSG_STATUS_OK, EBUSY, EIO, FW_ACK_TIME_OUT_MS, bnx2::fw_wr_seq, mdelay(), printf(), REG_RD_IND, REG_WR_IND, bnx2::shmem_base, and u32.
Referenced by bnx2_init_chip(), and bnx2_reset_chip().
01148 { 01149 int i; 01150 u32 val; 01151 01152 bp->fw_wr_seq++; 01153 msg_data |= bp->fw_wr_seq; 01154 01155 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); 01156 01157 /* wait for an acknowledgement. */ 01158 for (i = 0; i < (FW_ACK_TIME_OUT_MS / 50); i++) { 01159 mdelay(50); 01160 01161 val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB); 01162 01163 if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) 01164 break; 01165 } 01166 if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0) 01167 return 0; 01168 01169 /* If we timed out, inform the firmware that this is the case. */ 01170 if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) { 01171 if (!silent) 01172 printf("fw sync timeout, reset code = %x\n", (unsigned int) msg_data); 01173 01174 msg_data &= ~BNX2_DRV_MSG_CODE; 01175 msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; 01176 01177 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); 01178 01179 return -EBUSY; 01180 } 01181 01182 if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK) 01183 return -EIO; 01184 01185 return 0; 01186 }
| static void bnx2_init_context | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1189 of file bnx2.c.
References BNX2_CTX_PAGE_TBL, BNX2_CTX_VIRT_ADDR, CHIP_ID, CHIP_ID_5706_A0, CTX_WR, GET_CID_ADDR, GET_PCID_ADDR, offset, PHY_CTX_SIZE, REG_WR, and u32.
Referenced by bnx2_init_chip().
01190 { 01191 u32 vcid; 01192 01193 vcid = 96; 01194 while (vcid) { 01195 u32 vcid_addr, pcid_addr, offset; 01196 01197 vcid--; 01198 01199 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 01200 u32 new_vcid; 01201 01202 vcid_addr = GET_PCID_ADDR(vcid); 01203 if (vcid & 0x8) { 01204 new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7); 01205 } 01206 else { 01207 new_vcid = vcid; 01208 } 01209 pcid_addr = GET_PCID_ADDR(new_vcid); 01210 } 01211 else { 01212 vcid_addr = GET_CID_ADDR(vcid); 01213 pcid_addr = vcid_addr; 01214 } 01215 01216 REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00); 01217 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); 01218 01219 /* Zero out the context. */ 01220 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) { 01221 CTX_WR(bp, 0x00, offset, 0); 01222 } 01223 01224 REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr); 01225 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); 01226 } 01227 }
| static int bnx2_alloc_bad_rbuf | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1230 of file bnx2.c.
References BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ, BNX2_RBUF_FW_BUF_ALLOC, BNX2_RBUF_FW_BUF_ALLOC_VALUE, BNX2_RBUF_FW_BUF_FREE, BNX2_RBUF_STATUS1, BNX2_RBUF_STATUS1_FREE_COUNT, REG_RD_IND, REG_WR, REG_WR_IND, u16, and u32.
Referenced by bnx2_reset_chip().
01231 { 01232 u16 good_mbuf[512]; 01233 u32 good_mbuf_cnt; 01234 u32 val; 01235 01236 REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 01237 BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE); 01238 01239 good_mbuf_cnt = 0; 01240 01241 /* Allocate a bunch of mbufs and save the good ones in an array. */ 01242 val = REG_RD_IND(bp, BNX2_RBUF_STATUS1); 01243 while (val & BNX2_RBUF_STATUS1_FREE_COUNT) { 01244 REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ); 01245 01246 val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC); 01247 01248 val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE; 01249 01250 /* The addresses with Bit 9 set are bad memory blocks. */ 01251 if (!(val & (1 << 9))) { 01252 good_mbuf[good_mbuf_cnt] = (u16) val; 01253 good_mbuf_cnt++; 01254 } 01255 01256 val = REG_RD_IND(bp, BNX2_RBUF_STATUS1); 01257 } 01258 01259 /* Free the good ones back to the mbuf pool thus discarding 01260 * all the bad ones. */ 01261 while (good_mbuf_cnt) { 01262 good_mbuf_cnt--; 01263 01264 val = good_mbuf[good_mbuf_cnt]; 01265 val = (val << 9) | val | 1; 01266 01267 REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val); 01268 } 01269 return 0; 01270 }
| static void bnx2_set_mac_addr | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1273 of file bnx2.c.
References BNX2_EMAC_MAC_MATCH0, BNX2_EMAC_MAC_MATCH1, bnx2::nic, nic::node_addr, REG_WR, u32, and u8.
Referenced by bnx2_init_chip().
01274 { 01275 u32 val; 01276 u8 *mac_addr = bp->nic->node_addr; 01277 01278 val = (mac_addr[0] << 8) | mac_addr[1]; 01279 01280 REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val); 01281 01282 val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 01283 (mac_addr[4] << 8) | mac_addr[5]; 01284 01285 REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val); 01286 }
Definition at line 1289 of file bnx2.c.
References ASF_ENABLE_FLAG, BNX2_EMAC_MULTICAST_HASH0, BNX2_EMAC_RX_MODE, BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG, BNX2_EMAC_RX_MODE_PROMISCUOUS, BNX2_RPM_SORT_USER0, BNX2_RPM_SORT_USER0_BC_EN, BNX2_RPM_SORT_USER0_ENA, BNX2_RPM_SORT_USER0_MC_EN, bnx2::flags, NUM_MC_HASH_REGISTERS, REG_WR, bnx2::rx_mode, and u32.
Referenced by bnx2_init_chip().
01290 { 01291 struct bnx2 *bp = &bnx2; 01292 u32 rx_mode, sort_mode; 01293 int i; 01294 01295 rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | 01296 BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); 01297 sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; 01298 01299 if (!(bp->flags & ASF_ENABLE_FLAG)) { 01300 rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; 01301 } 01302 01303 /* Accept all multicasts */ 01304 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { 01305 REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4), 01306 0xffffffff); 01307 } 01308 sort_mode |= BNX2_RPM_SORT_USER0_MC_EN; 01309 01310 if (rx_mode != bp->rx_mode) { 01311 bp->rx_mode = rx_mode; 01312 REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode); 01313 } 01314 01315 REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0); 01316 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode); 01317 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA); 01318 }
| static void load_rv2p_fw | ( | struct bnx2 * | bp, | |
| u32 * | rv2p_code, | |||
| u32 | rv2p_code_len, | |||
| u32 | rv2p_proc | |||
| ) | [static] |
Definition at line 1321 of file bnx2.c.
References BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET, BNX2_RV2P_COMMAND_PROC2_RESET, BNX2_RV2P_INSTR_HIGH, BNX2_RV2P_INSTR_LOW, BNX2_RV2P_PROC1_ADDR_CMD, BNX2_RV2P_PROC1_ADDR_CMD_RDWR, BNX2_RV2P_PROC2_ADDR_CMD, BNX2_RV2P_PROC2_ADDR_CMD_RDWR, REG_WR, RV2P_PROC1, and u32.
Referenced by bnx2_init_cpus().
01322 { 01323 unsigned int i; 01324 u32 val; 01325 01326 01327 for (i = 0; i < rv2p_code_len; i += 8) { 01328 REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code); 01329 rv2p_code++; 01330 REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code); 01331 rv2p_code++; 01332 01333 if (rv2p_proc == RV2P_PROC1) { 01334 val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR; 01335 REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val); 01336 } 01337 else { 01338 val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR; 01339 REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val); 01340 } 01341 } 01342 01343 /* Reset the processor, un-stall is done later. */ 01344 if (rv2p_proc == RV2P_PROC1) { 01345 REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET); 01346 } 01347 else { 01348 REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET); 01349 } 01350 }
| static void load_cpu_fw | ( | struct bnx2 * | bp, | |
| struct cpu_reg * | cpu_reg, | |||
| struct fw_info * | fw | |||
| ) | [static] |
Definition at line 1353 of file bnx2.c.
References fw_info::bss, fw_info::bss_addr, fw_info::bss_len, fw_info::data, fw_info::data_addr, fw_info::data_len, cpu_reg::inst, cpu_reg::mips_view_base, cpu_reg::mode, cpu_reg::mode_value_halt, offset, cpu_reg::pc, REG_RD_IND, REG_WR_IND, fw_info::rodata, fw_info::rodata_addr, fw_info::rodata_len, fw_info::sbss, fw_info::sbss_addr, fw_info::sbss_len, cpu_reg::spad_base, fw_info::start_addr, cpu_reg::state, cpu_reg::state_value_clear, fw_info::text, fw_info::text_addr, fw_info::text_len, and u32.
Referenced by bnx2_init_cpus().
01354 { 01355 u32 offset; 01356 u32 val; 01357 01358 /* Halt the CPU. */ 01359 val = REG_RD_IND(bp, cpu_reg->mode); 01360 val |= cpu_reg->mode_value_halt; 01361 REG_WR_IND(bp, cpu_reg->mode, val); 01362 REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); 01363 01364 /* Load the Text area. */ 01365 offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base); 01366 if (fw->text) { 01367 unsigned int j; 01368 01369 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) { 01370 REG_WR_IND(bp, offset, fw->text[j]); 01371 } 01372 } 01373 01374 /* Load the Data area. */ 01375 offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base); 01376 if (fw->data) { 01377 unsigned int j; 01378 01379 for (j = 0; j < (fw->data_len / 4); j++, offset += 4) { 01380 REG_WR_IND(bp, offset, fw->data[j]); 01381 } 01382 } 01383 01384 /* Load the SBSS area. */ 01385 offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base); 01386 if (fw->sbss) { 01387 unsigned int j; 01388 01389 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) { 01390 REG_WR_IND(bp, offset, fw->sbss[j]); 01391 } 01392 } 01393 01394 /* Load the BSS area. */ 01395 offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base); 01396 if (fw->bss) { 01397 unsigned int j; 01398 01399 for (j = 0; j < (fw->bss_len/4); j++, offset += 4) { 01400 REG_WR_IND(bp, offset, fw->bss[j]); 01401 } 01402 } 01403 01404 /* Load the Read-Only area. */ 01405 offset = cpu_reg->spad_base + 01406 (fw->rodata_addr - cpu_reg->mips_view_base); 01407 if (fw->rodata) { 01408 unsigned int j; 01409 01410 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) { 01411 REG_WR_IND(bp, offset, fw->rodata[j]); 01412 } 01413 } 01414 01415 /* Clear the pre-fetch instruction. */ 01416 REG_WR_IND(bp, cpu_reg->inst, 0); 01417 REG_WR_IND(bp, cpu_reg->pc, fw->start_addr); 01418 01419 /* Start the CPU. */ 01420 val = REG_RD_IND(bp, cpu_reg->mode); 01421 val &= ~cpu_reg->mode_value_halt; 01422 REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); 01423 REG_WR_IND(bp, cpu_reg->mode, val); 01424 }
| static void bnx2_init_cpus | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1427 of file bnx2.c.
References bnx2_COM_b06FwBss, bnx2_COM_b06FwBssAddr, bnx2_COM_b06FwBssLen, bnx2_COM_b06FwData, bnx2_COM_b06FwDataAddr, bnx2_COM_b06FwDataLen, bnx2_COM_b06FwReleaseFix, bnx2_COM_b06FwReleaseMajor, bnx2_COM_b06FwReleaseMinor, bnx2_COM_b06FwRodata, bnx2_COM_b06FwRodataAddr, bnx2_COM_b06FwRodataLen, bnx2_COM_b06FwSbss, bnx2_COM_b06FwSbssAddr, bnx2_COM_b06FwSbssLen, bnx2_COM_b06FwStartAddr, bnx2_COM_b06FwText, bnx2_COM_b06FwTextAddr, bnx2_COM_b06FwTextLen, BNX2_COM_CPU_EVENT_MASK, BNX2_COM_CPU_HW_BREAKPOINT, BNX2_COM_CPU_INSTRUCTION, BNX2_COM_CPU_MODE, BNX2_COM_CPU_MODE_SOFT_HALT, BNX2_COM_CPU_MODE_STEP_ENA, BNX2_COM_CPU_PROGRAM_COUNTER, BNX2_COM_CPU_REG_FILE, BNX2_COM_CPU_STATE, BNX2_COM_SCRATCH, bnx2_rv2p_proc1, bnx2_rv2p_proc2, bnx2_RXP_b06FwBss, bnx2_RXP_b06FwBssAddr, bnx2_RXP_b06FwBssLen, bnx2_RXP_b06FwData, bnx2_RXP_b06FwDataAddr, bnx2_RXP_b06FwDataLen, bnx2_RXP_b06FwReleaseFix, bnx2_RXP_b06FwReleaseMajor, bnx2_RXP_b06FwReleaseMinor, bnx2_RXP_b06FwRodata, bnx2_RXP_b06FwRodataAddr, bnx2_RXP_b06FwRodataLen, bnx2_RXP_b06FwSbss, bnx2_RXP_b06FwSbssAddr, bnx2_RXP_b06FwSbssLen, bnx2_RXP_b06FwStartAddr, bnx2_RXP_b06FwText, bnx2_RXP_b06FwTextAddr, bnx2_RXP_b06FwTextLen, BNX2_RXP_CPU_EVENT_MASK, BNX2_RXP_CPU_HW_BREAKPOINT, BNX2_RXP_CPU_INSTRUCTION, BNX2_RXP_CPU_MODE, BNX2_RXP_CPU_MODE_SOFT_HALT, BNX2_RXP_CPU_MODE_STEP_ENA, BNX2_RXP_CPU_PROGRAM_COUNTER, BNX2_RXP_CPU_REG_FILE, BNX2_RXP_CPU_STATE, BNX2_RXP_SCRATCH, bnx2_TPAT_b06FwBss, bnx2_TPAT_b06FwBssAddr, bnx2_TPAT_b06FwBssLen, bnx2_TPAT_b06FwData, bnx2_TPAT_b06FwDataAddr, bnx2_TPAT_b06FwDataLen, bnx2_TPAT_b06FwReleaseFix, bnx2_TPAT_b06FwReleaseMajor, bnx2_TPAT_b06FwReleaseMinor, bnx2_TPAT_b06FwRodata, bnx2_TPAT_b06FwRodataAddr, bnx2_TPAT_b06FwRodataLen, bnx2_TPAT_b06FwSbss, bnx2_TPAT_b06FwSbssAddr, bnx2_TPAT_b06FwSbssLen, bnx2_TPAT_b06FwStartAddr, bnx2_TPAT_b06FwText, bnx2_TPAT_b06FwTextAddr, bnx2_TPAT_b06FwTextLen, BNX2_TPAT_CPU_EVENT_MASK, BNX2_TPAT_CPU_HW_BREAKPOINT, BNX2_TPAT_CPU_INSTRUCTION, BNX2_TPAT_CPU_MODE, BNX2_TPAT_CPU_MODE_SOFT_HALT, BNX2_TPAT_CPU_MODE_STEP_ENA, BNX2_TPAT_CPU_PROGRAM_COUNTER, BNX2_TPAT_CPU_REG_FILE, BNX2_TPAT_CPU_STATE, BNX2_TPAT_SCRATCH, bnx2_TXP_b06FwBss, bnx2_TXP_b06FwBssAddr, bnx2_TXP_b06FwBssLen, bnx2_TXP_b06FwData, bnx2_TXP_b06FwDataAddr, bnx2_TXP_b06FwDataLen, bnx2_TXP_b06FwReleaseFix, bnx2_TXP_b06FwReleaseMajor, bnx2_TXP_b06FwReleaseMinor, bnx2_TXP_b06FwRodata, bnx2_TXP_b06FwRodataAddr, bnx2_TXP_b06FwRodataLen, bnx2_TXP_b06FwSbss, bnx2_TXP_b06FwSbssAddr, bnx2_TXP_b06FwSbssLen, bnx2_TXP_b06FwStartAddr, bnx2_TXP_b06FwText, bnx2_TXP_b06FwTextAddr, bnx2_TXP_b06FwTextLen, BNX2_TXP_CPU_EVENT_MASK, BNX2_TXP_CPU_HW_BREAKPOINT, BNX2_TXP_CPU_INSTRUCTION, BNX2_TXP_CPU_MODE, BNX2_TXP_CPU_MODE_SOFT_HALT, BNX2_TXP_CPU_MODE_STEP_ENA, BNX2_TXP_CPU_PROGRAM_COUNTER, BNX2_TXP_CPU_REG_FILE, BNX2_TXP_CPU_STATE, BNX2_TXP_SCRATCH, cpu_reg::bp, fw_info::bss, fw_info::bss_addr, fw_info::bss_index, fw_info::bss_len, fw_info::data, fw_info::data_addr, fw_info::data_index, fw_info::data_len, cpu_reg::evmask, cpu_reg::gpr0, cpu_reg::inst, load_cpu_fw(), load_rv2p_fw(), cpu_reg::mips_view_base, cpu_reg::mode, cpu_reg::mode_value_halt, cpu_reg::mode_value_sstep, cpu_reg::pc, fw_info::rodata, fw_info::rodata_addr, fw_info::rodata_index, fw_info::rodata_len, RV2P_PROC1, RV2P_PROC2, fw_info::sbss, fw_info::sbss_addr, fw_info::sbss_index, fw_info::sbss_len, cpu_reg::spad_base, fw_info::start_addr, cpu_reg::state, cpu_reg::state_value_clear, fw_info::text, fw_info::text_addr, fw_info::text_index, fw_info::text_len, fw_info::ver_fix, fw_info::ver_major, and fw_info::ver_minor.
Referenced by bnx2_init_chip().
01428 { 01429 struct cpu_reg cpu_reg; 01430 struct fw_info fw; 01431 01432 /* Unfortunately, it looks like we need to load the firmware 01433 * before the card will work properly. That means this driver 01434 * will be huge by Etherboot standards (approx. 50K compressed). 01435 */ 01436 01437 /* Initialize the RV2P processor. */ 01438 load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1); 01439 load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2); 01440 01441 /* Initialize the RX Processor. */ 01442 cpu_reg.mode = BNX2_RXP_CPU_MODE; 01443 cpu_reg.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT; 01444 cpu_reg.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA; 01445 cpu_reg.state = BNX2_RXP_CPU_STATE; 01446 cpu_reg.state_value_clear = 0xffffff; 01447 cpu_reg.gpr0 = BNX2_RXP_CPU_REG_FILE; 01448 cpu_reg.evmask = BNX2_RXP_CPU_EVENT_MASK; 01449 cpu_reg.pc = BNX2_RXP_CPU_PROGRAM_COUNTER; 01450 cpu_reg.inst = BNX2_RXP_CPU_INSTRUCTION; 01451 cpu_reg.bp = BNX2_RXP_CPU_HW_BREAKPOINT; 01452 cpu_reg.spad_base = BNX2_RXP_SCRATCH; 01453 cpu_reg.mips_view_base = 0x8000000; 01454 01455 fw.ver_major = bnx2_RXP_b06FwReleaseMajor; 01456 fw.ver_minor = bnx2_RXP_b06FwReleaseMinor; 01457 fw.ver_fix = bnx2_RXP_b06FwReleaseFix; 01458 fw.start_addr = bnx2_RXP_b06FwStartAddr; 01459 01460 fw.text_addr = bnx2_RXP_b06FwTextAddr; 01461 fw.text_len = bnx2_RXP_b06FwTextLen; 01462 fw.text_index = 0; 01463 fw.text = bnx2_RXP_b06FwText; 01464 01465 fw.data_addr = bnx2_RXP_b06FwDataAddr; 01466 fw.data_len = bnx2_RXP_b06FwDataLen; 01467 fw.data_index = 0; 01468 fw.data = bnx2_RXP_b06FwData; 01469 01470 fw.sbss_addr = bnx2_RXP_b06FwSbssAddr; 01471 fw.sbss_len = bnx2_RXP_b06FwSbssLen; 01472 fw.sbss_index = 0; 01473 fw.sbss = bnx2_RXP_b06FwSbss; 01474 01475 fw.bss_addr = bnx2_RXP_b06FwBssAddr; 01476 fw.bss_len = bnx2_RXP_b06FwBssLen; 01477 fw.bss_index = 0; 01478 fw.bss = bnx2_RXP_b06FwBss; 01479 01480 fw.rodata_addr = bnx2_RXP_b06FwRodataAddr; 01481 fw.rodata_len = bnx2_RXP_b06FwRodataLen; 01482 fw.rodata_index = 0; 01483 fw.rodata = bnx2_RXP_b06FwRodata; 01484 01485 load_cpu_fw(bp, &cpu_reg, &fw); 01486 01487 /* Initialize the TX Processor. */ 01488 cpu_reg.mode = BNX2_TXP_CPU_MODE; 01489 cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT; 01490 cpu_reg.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA; 01491 cpu_reg.state = BNX2_TXP_CPU_STATE; 01492 cpu_reg.state_value_clear = 0xffffff; 01493 cpu_reg.gpr0 = BNX2_TXP_CPU_REG_FILE; 01494 cpu_reg.evmask = BNX2_TXP_CPU_EVENT_MASK; 01495 cpu_reg.pc = BNX2_TXP_CPU_PROGRAM_COUNTER; 01496 cpu_reg.inst = BNX2_TXP_CPU_INSTRUCTION; 01497 cpu_reg.bp = BNX2_TXP_CPU_HW_BREAKPOINT; 01498 cpu_reg.spad_base = BNX2_TXP_SCRATCH; 01499 cpu_reg.mips_view_base = 0x8000000; 01500 01501 fw.ver_major = bnx2_TXP_b06FwReleaseMajor; 01502 fw.ver_minor = bnx2_TXP_b06FwReleaseMinor; 01503 fw.ver_fix = bnx2_TXP_b06FwReleaseFix; 01504 fw.start_addr = bnx2_TXP_b06FwStartAddr; 01505 01506 fw.text_addr = bnx2_TXP_b06FwTextAddr; 01507 fw.text_len = bnx2_TXP_b06FwTextLen; 01508 fw.text_index = 0; 01509 fw.text = bnx2_TXP_b06FwText; 01510 01511 fw.data_addr = bnx2_TXP_b06FwDataAddr; 01512 fw.data_len = bnx2_TXP_b06FwDataLen; 01513 fw.data_index = 0; 01514 fw.data = bnx2_TXP_b06FwData; 01515 01516 fw.sbss_addr = bnx2_TXP_b06FwSbssAddr; 01517 fw.sbss_len = bnx2_TXP_b06FwSbssLen; 01518 fw.sbss_index = 0; 01519 fw.sbss = bnx2_TXP_b06FwSbss; 01520 01521 fw.bss_addr = bnx2_TXP_b06FwBssAddr; 01522 fw.bss_len = bnx2_TXP_b06FwBssLen; 01523 fw.bss_index = 0; 01524 fw.bss = bnx2_TXP_b06FwBss; 01525 01526 fw.rodata_addr = bnx2_TXP_b06FwRodataAddr; 01527 fw.rodata_len = bnx2_TXP_b06FwRodataLen; 01528 fw.rodata_index = 0; 01529 fw.rodata = bnx2_TXP_b06FwRodata; 01530 01531 load_cpu_fw(bp, &cpu_reg, &fw); 01532 01533 /* Initialize the TX Patch-up Processor. */ 01534 cpu_reg.mode = BNX2_TPAT_CPU_MODE; 01535 cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT; 01536 cpu_reg.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA; 01537 cpu_reg.state = BNX2_TPAT_CPU_STATE; 01538 cpu_reg.state_value_clear = 0xffffff; 01539 cpu_reg.gpr0 = BNX2_TPAT_CPU_REG_FILE; 01540 cpu_reg.evmask = BNX2_TPAT_CPU_EVENT_MASK; 01541 cpu_reg.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER; 01542 cpu_reg.inst = BNX2_TPAT_CPU_INSTRUCTION; 01543 cpu_reg.bp = BNX2_TPAT_CPU_HW_BREAKPOINT; 01544 cpu_reg.spad_base = BNX2_TPAT_SCRATCH; 01545 cpu_reg.mips_view_base = 0x8000000; 01546 01547 fw.ver_major = bnx2_TPAT_b06FwReleaseMajor; 01548 fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor; 01549 fw.ver_fix = bnx2_TPAT_b06FwReleaseFix; 01550 fw.start_addr = bnx2_TPAT_b06FwStartAddr; 01551 01552 fw.text_addr = bnx2_TPAT_b06FwTextAddr; 01553 fw.text_len = bnx2_TPAT_b06FwTextLen; 01554 fw.text_index = 0; 01555 fw.text = bnx2_TPAT_b06FwText; 01556 01557 fw.data_addr = bnx2_TPAT_b06FwDataAddr; 01558 fw.data_len = bnx2_TPAT_b06FwDataLen; 01559 fw.data_index = 0; 01560 fw.data = bnx2_TPAT_b06FwData; 01561 01562 fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr; 01563 fw.sbss_len = bnx2_TPAT_b06FwSbssLen; 01564 fw.sbss_index = 0; 01565 fw.sbss = bnx2_TPAT_b06FwSbss; 01566 01567 fw.bss_addr = bnx2_TPAT_b06FwBssAddr; 01568 fw.bss_len = bnx2_TPAT_b06FwBssLen; 01569 fw.bss_index = 0; 01570 fw.bss = bnx2_TPAT_b06FwBss; 01571 01572 fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr; 01573 fw.rodata_len = bnx2_TPAT_b06FwRodataLen; 01574 fw.rodata_index = 0; 01575 fw.rodata = bnx2_TPAT_b06FwRodata; 01576 01577 load_cpu_fw(bp, &cpu_reg, &fw); 01578 01579 /* Initialize the Completion Processor. */ 01580 cpu_reg.mode = BNX2_COM_CPU_MODE; 01581 cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT; 01582 cpu_reg.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA; 01583 cpu_reg.state = BNX2_COM_CPU_STATE; 01584 cpu_reg.state_value_clear = 0xffffff; 01585 cpu_reg.gpr0 = BNX2_COM_CPU_REG_FILE; 01586 cpu_reg.evmask = BNX2_COM_CPU_EVENT_MASK; 01587 cpu_reg.pc = BNX2_COM_CPU_PROGRAM_COUNTER; 01588 cpu_reg.inst = BNX2_COM_CPU_INSTRUCTION; 01589 cpu_reg.bp = BNX2_COM_CPU_HW_BREAKPOINT; 01590 cpu_reg.spad_base = BNX2_COM_SCRATCH; 01591 cpu_reg.mips_view_base = 0x8000000; 01592 01593 fw.ver_major = bnx2_COM_b06FwReleaseMajor; 01594 fw.ver_minor = bnx2_COM_b06FwReleaseMinor; 01595 fw.ver_fix = bnx2_COM_b06FwReleaseFix; 01596 fw.start_addr = bnx2_COM_b06FwStartAddr; 01597 01598 fw.text_addr = bnx2_COM_b06FwTextAddr; 01599 fw.text_len = bnx2_COM_b06FwTextLen; 01600 fw.text_index = 0; 01601 fw.text = bnx2_COM_b06FwText; 01602 01603 fw.data_addr = bnx2_COM_b06FwDataAddr; 01604 fw.data_len = bnx2_COM_b06FwDataLen; 01605 fw.data_index = 0; 01606 fw.data = bnx2_COM_b06FwData; 01607 01608 fw.sbss_addr = bnx2_COM_b06FwSbssAddr; 01609 fw.sbss_len = bnx2_COM_b06FwSbssLen; 01610 fw.sbss_index = 0; 01611 fw.sbss = bnx2_COM_b06FwSbss; 01612 01613 fw.bss_addr = bnx2_COM_b06FwBssAddr; 01614 fw.bss_len = bnx2_COM_b06FwBssLen; 01615 fw.bss_index = 0; 01616 fw.bss = bnx2_COM_b06FwBss; 01617 01618 fw.rodata_addr = bnx2_COM_b06FwRodataAddr; 01619 fw.rodata_len = bnx2_COM_b06FwRodataLen; 01620 fw.rodata_index = 0; 01621 fw.rodata = bnx2_COM_b06FwRodata; 01622 01623 load_cpu_fw(bp, &cpu_reg, &fw); 01624 01625 }
| static int bnx2_set_power_state_0 | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1628 of file bnx2.c.
References BNX2_EMAC_MODE, BNX2_EMAC_MODE_ACPI_RCVD, BNX2_EMAC_MODE_MPKT, BNX2_EMAC_MODE_MPKT_RCVD, BNX2_RPM_CONFIG, BNX2_RPM_CONFIG_ACPI_ENA, mdelay(), PCI_PM_CTRL, PCI_PM_CTRL_PME_STATUS, PCI_PM_CTRL_STATE_MASK, pci_read_config_word(), pci_write_config_word(), bnx2::pdev, bnx2::pm_cap, REG_RD, REG_WR, u16, and u32.
Referenced by bnx2_init_board(), and bnx2_probe().
01629 { 01630 u16 pmcsr; 01631 u32 val; 01632 01633 pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); 01634 01635 pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, 01636 (pmcsr & ~PCI_PM_CTRL_STATE_MASK) | 01637 PCI_PM_CTRL_PME_STATUS); 01638 01639 if (pmcsr & PCI_PM_CTRL_STATE_MASK) 01640 /* delay required during transition out of D3hot */ 01641 mdelay(20); 01642 01643 val = REG_RD(bp, BNX2_EMAC_MODE); 01644 val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD; 01645 val &= ~BNX2_EMAC_MODE_MPKT; 01646 REG_WR(bp, BNX2_EMAC_MODE, val); 01647 01648 val = REG_RD(bp, BNX2_RPM_CONFIG); 01649 val &= ~BNX2_RPM_CONFIG_ACPI_ENA; 01650 REG_WR(bp, BNX2_RPM_CONFIG, val); 01651 01652 return 0; 01653 }
| static void bnx2_enable_nvram_access | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1656 of file bnx2.c.
References BNX2_NVM_ACCESS_ENABLE, BNX2_NVM_ACCESS_ENABLE_EN, BNX2_NVM_ACCESS_ENABLE_WR_EN, REG_RD, REG_WR, and u32.
Referenced by bnx2_init_nvram().
01657 { 01658 u32 val; 01659 01660 val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE); 01661 /* Enable both bits, even on read. */ 01662 REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 01663 val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN); 01664 }
| static void bnx2_disable_nvram_access | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1667 of file bnx2.c.
References BNX2_NVM_ACCESS_ENABLE, BNX2_NVM_ACCESS_ENABLE_EN, BNX2_NVM_ACCESS_ENABLE_WR_EN, REG_RD, REG_WR, and u32.
Referenced by bnx2_init_nvram().
01668 { 01669 u32 val; 01670 01671 val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE); 01672 /* Disable both bits, even after read. */ 01673 REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 01674 val & ~(BNX2_NVM_ACCESS_ENABLE_EN | 01675 BNX2_NVM_ACCESS_ENABLE_WR_EN)); 01676 }
| static int bnx2_init_nvram | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1679 of file bnx2.c.
References bnx2_disable_nvram_access(), bnx2_enable_nvram_access(), BNX2_NVM_CFG1, BNX2_NVM_CFG2, BNX2_NVM_CFG3, BNX2_NVM_WRITE1, BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK, BNX2_SHARED_HW_CFG_CONFIG2, flash_spec::config1, flash_spec::config2, flash_spec::config3, ENODEV, flash(), FLASH_BACKUP_STRAP_MASK, bnx2::flash_info, bnx2::flash_size, FLASH_STRAP_MASK, NULL, printf(), REG_RD, REG_RD_IND, REG_WR, bnx2::shmem_base, flash_spec::strapping, flash_spec::total_size, u32, and flash_spec::write1.
Referenced by bnx2_init_board(), and bnx2_init_chip().
01680 { 01681 u32 val; 01682 int j, entry_count, rc; 01683 struct flash_spec *flash; 01684 01685 /* Determine the selected interface. */ 01686 val = REG_RD(bp, BNX2_NVM_CFG1); 01687 01688 entry_count = sizeof(flash_table) / sizeof(struct flash_spec); 01689 01690 rc = 0; 01691 if (val & 0x40000000) { 01692 /* Flash interface has been reconfigured */ 01693 for (j = 0, flash = &flash_table[0]; j < entry_count; 01694 j++, flash++) { 01695 if ((val & FLASH_BACKUP_STRAP_MASK) == 01696 (flash->config1 & FLASH_BACKUP_STRAP_MASK)) { 01697 bp->flash_info = flash; 01698 break; 01699 } 01700 } 01701 } 01702 else { 01703 u32 mask; 01704 /* Not yet been reconfigured */ 01705 01706 if (val & (1 << 23)) 01707 mask = FLASH_BACKUP_STRAP_MASK; 01708 else 01709 mask = FLASH_STRAP_MASK; 01710 01711 for (j = 0, flash = &flash_table[0]; j < entry_count; 01712 j++, flash++) { 01713 01714 if ((val & mask) == (flash->strapping & mask)) { 01715 bp->flash_info = flash; 01716 01717 /* Enable access to flash interface */ 01718 bnx2_enable_nvram_access(bp); 01719 01720 /* Reconfigure the flash interface */ 01721 REG_WR(bp, BNX2_NVM_CFG1, flash->config1); 01722 REG_WR(bp, BNX2_NVM_CFG2, flash->config2); 01723 REG_WR(bp, BNX2_NVM_CFG3, flash->config3); 01724 REG_WR(bp, BNX2_NVM_WRITE1, flash->write1); 01725 01726 /* Disable access to flash interface */ 01727 bnx2_disable_nvram_access(bp); 01728 01729 break; 01730 } 01731 } 01732 } /* if (val & 0x40000000) */ 01733 01734 if (j == entry_count) { 01735 bp->flash_info = NULL; 01736 printf("Unknown flash/EEPROM type.\n"); 01737 return -ENODEV; 01738 } 01739 01740 val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2); 01741 val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK; 01742 if (val) { 01743 bp->flash_size = val; 01744 } 01745 else { 01746 bp->flash_size = bp->flash_info->total_size; 01747 } 01748 01749 return rc; 01750 }
Definition at line 1753 of file bnx2.c.
References bnx2_alloc_bad_rbuf(), BNX2_DRV_MSG_DATA_WAIT0, BNX2_DRV_MSG_DATA_WAIT1, BNX2_DRV_RESET_SIGNATURE, BNX2_DRV_RESET_SIGNATURE_MAGIC, bnx2_fw_sync(), BNX2_MISC_ENABLE_CLR_BITS, BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE, BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE, BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE, BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE, BNX2_MISC_ID, BNX2_MISC_VREG_CONTROL, BNX2_PCI_SWAP_DIAG0, BNX2_PCICFG_MISC_CONFIG, BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY, BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ, BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA, BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, CHIP_ID, CHIP_ID_5706_A0, CHIP_ID_5706_A1, EBUSY, ENODEV, mdelay(), printf(), REG_RD, REG_WR, REG_WR_IND, bnx2::shmem_base, u32, and udelay().
Referenced by bnx2_disable(), and bnx2_reset_nic().
01754 { 01755 u32 val; 01756 int i, rc = 0; 01757 01758 /* Wait for the current PCI transaction to complete before 01759 * issuing a reset. */ 01760 REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, 01761 BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | 01762 BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | 01763 BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | 01764 BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); 01765 val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); 01766 udelay(5); 01767 01768 01769 /* Wait for the firmware to tell us it is ok to issue a reset. */ 01770 bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1); 01771 01772 /* Deposit a driver reset signature so the firmware knows that 01773 * this is a soft reset. */ 01774 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE, 01775 BNX2_DRV_RESET_SIGNATURE_MAGIC); 01776 01777 /* Do a dummy read to force the chip to complete all current transaction 01778 * before we issue a reset. */ 01779 val = REG_RD(bp, BNX2_MISC_ID); 01780 01781 val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | 01782 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 01783 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; 01784 01785 /* Chip reset. */ 01786 REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); 01787 01788 if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || 01789 (CHIP_ID(bp) == CHIP_ID_5706_A1)) 01790 mdelay(15); 01791 01792 /* Reset takes approximate 30 usec */ 01793 for (i = 0; i < 10; i++) { 01794 val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG); 01795 if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | 01796 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) { 01797 break; 01798 } 01799 udelay(10); 01800 } 01801 01802 if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | 01803 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) { 01804 printf("Chip reset did not complete\n"); 01805 return -EBUSY; 01806 } 01807 01808 /* Make sure byte swapping is properly configured. */ 01809 val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0); 01810 if (val != 0x01020304) { 01811 printf("Chip not in correct endian mode\n"); 01812 return -ENODEV; 01813 } 01814 01815 /* Wait for the firmware to finish its initialization. */ 01816 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0); 01817 if (rc) { 01818 return rc; 01819 } 01820 01821 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 01822 /* Adjust the voltage regular to two steps lower. The default 01823 * of this register is 0x0000000e. */ 01824 REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa); 01825 01826 /* Remove bad rbuf memory from the free pool. */ 01827 rc = bnx2_alloc_bad_rbuf(bp); 01828 } 01829 01830 return rc; 01831 }
Definition at line 1834 of file bnx2.c.
References BNX2_DRV_MSG_CODE_UNLOAD, bnx2_reset_chip(), iounmap(), and bnx2::regview.
Referenced by bnx2_init_board(), bnx2_probe(), and bnx2_transmit().
01835 { 01836 struct bnx2* bp = &bnx2; 01837 01838 if (bp->regview) { 01839 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_UNLOAD); 01840 iounmap(bp->regview); 01841 } 01842 }
| static int bnx2_init_chip | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 1845 of file bnx2.c.
References ASF_ENABLE_FLAG, BCM_PAGE_BITS, BNX2_DMA_CONFIG, BNX2_DMA_CONFIG_CNTL_BYTE_SWAP, BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA, BNX2_DMA_CONFIG_CNTL_WORD_SWAP, BNX2_DMA_CONFIG_DATA_BYTE_SWAP, BNX2_DMA_CONFIG_DATA_WORD_SWAP, BNX2_DRV_MSG_CODE_RESET, BNX2_DRV_MSG_DATA_WAIT2, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK, BNX2_EMAC_BACKOFF_SEED, BNX2_EMAC_RX_MODE_SORT_MODE, BNX2_EMAC_RX_MTU_SIZE, BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA, bnx2_fw_sync(), BNX2_HC_ATTN_BITS_ENABLE, BNX2_HC_CMD_TICKS, BNX2_HC_COM_TICKS, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW, BNX2_HC_COMP_PROD_TRIP, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS, BNX2_HC_CONFIG_RX_TMR_MODE, BNX2_HC_CONFIG_TX_TMR_MODE, BNX2_HC_RX_QUICK_CONS_TRIP, BNX2_HC_RX_TICKS, BNX2_HC_STAT_COLLECT_TICKS, BNX2_HC_STATISTICS_ADDR_H, BNX2_HC_STATISTICS_ADDR_L, BNX2_HC_STATS_TICKS, BNX2_HC_STATUS_ADDR_H, BNX2_HC_STATUS_ADDR_L, BNX2_HC_TX_QUICK_CONS_TRIP, BNX2_HC_TX_TICKS, bnx2_init_context(), bnx2_init_cpus(), bnx2_init_nvram(), BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE, BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE, BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE, BNX2_MQ_CONFIG, BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE, BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256, BNX2_MQ_KNL_BYP_WIND_START, BNX2_MQ_KNL_WIND_END, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT, BNX2_PORT_FEATURE, BNX2_PORT_FEATURE_ASF_ENABLED, BNX2_RV2P_CONFIG, bnx2_set_mac_addr(), bnx2_set_rx_mode(), BNX2_TBDR_CONFIG, BNX2_TBDR_CONFIG_PAGE_SIZE, BNX2_TDMA_CONFIG, BNX2_TDMA_CONFIG_ONE_DMA, bnx2::bus_speed_mhz, CHIP_ID, CHIP_ID_5706_A0, CHIP_ID_5706_A1, CHIP_NUM, CHIP_NUM_5706, bnx2::cmd_ticks, bnx2::cmd_ticks_int, bnx2::com_ticks, bnx2::com_ticks_int, bnx2::comp_prod_trip, bnx2::comp_prod_trip_int, DMA_READ_CHANS, DMA_WRITE_CHANS, ETH_HLEN, ETH_MAX_MTU, bnx2::flags, bnx2::hc_cmd, bnx2::last_status_idx, bnx2::mac_addr, MAX_CID_CNT, MAX_ETHERNET_PACKET_SIZE, MB_KERNEL_CTX_SIZE, bnx2::nic, pci_read_config_word(), pci_write_config_word(), PCI_X_CMD, PCI_X_CMD_ERO, bnx2::pcix_cap, PCIX_FLAG, bnx2::pdev, REG_RD, REG_RD_IND, REG_WR, bnx2::rx_mode, bnx2::rx_quick_cons_trip, bnx2::rx_quick_cons_trip_int, bnx2::rx_ticks, bnx2::rx_ticks_int, bnx2::shmem_base, bnx2::stats_blk_mapping, bnx2::stats_ticks, STATUS_ATTN_BITS_LINK_STATE, bnx2::status_blk_mapping, bnx2::tx_quick_cons_trip, bnx2::tx_quick_cons_trip_int, bnx2::tx_ticks, bnx2::tx_ticks_int, u16, u32, and udelay().
Referenced by bnx2_reset_nic().
01846 { 01847 u32 val; 01848 int rc; 01849 01850 /* Make sure the interrupt is not active. */ 01851 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); 01852 01853 val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP | 01854 BNX2_DMA_CONFIG_DATA_WORD_SWAP | 01855 #if __BYTE_ORDER == __BIG_ENDIAN 01856 BNX2_DMA_CONFIG_CNTL_BYTE_SWAP | 01857 #endif 01858 BNX2_DMA_CONFIG_CNTL_WORD_SWAP | 01859 DMA_READ_CHANS << 12 | 01860 DMA_WRITE_CHANS << 16; 01861 01862 val |= (0x2 << 20) | (1 << 11); 01863 01864 if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133)) 01865 val |= (1 << 23); 01866 01867 if ((CHIP_NUM(bp) == CHIP_NUM_5706) && 01868 (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG)) 01869 val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA; 01870 01871 REG_WR(bp, BNX2_DMA_CONFIG, val); 01872 01873 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 01874 val = REG_RD(bp, BNX2_TDMA_CONFIG); 01875 val |= BNX2_TDMA_CONFIG_ONE_DMA; 01876 REG_WR(bp, BNX2_TDMA_CONFIG, val); 01877 } 01878 01879 if (bp->flags & PCIX_FLAG) { 01880 u16 val16; 01881 01882 pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD, 01883 &val16); 01884 pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD, 01885 val16 & ~PCI_X_CMD_ERO); 01886 } 01887 01888 REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 01889 BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE | 01890 BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE | 01891 BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE); 01892 01893 /* Initialize context mapping and zero out the quick contexts. The 01894 * context block must have already been enabled. */ 01895 bnx2_init_context(bp); 01896 01897 bnx2_init_nvram(bp); 01898 bnx2_init_cpus(bp); 01899 01900 bnx2_set_mac_addr(bp); 01901 01902 val = REG_RD(bp, BNX2_MQ_CONFIG); 01903 val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; 01904 val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256; 01905 REG_WR(bp, BNX2_MQ_CONFIG, val); 01906 01907 val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE); 01908 REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val); 01909 REG_WR(bp, BNX2_MQ_KNL_WIND_END, val); 01910 01911 val = (BCM_PAGE_BITS - 8) << 24; 01912 REG_WR(bp, BNX2_RV2P_CONFIG, val); 01913 01914 /* Configure page size. */ 01915 val = REG_RD(bp, BNX2_TBDR_CONFIG); 01916 val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE; 01917 val |= (BCM_PAGE_BITS - 8) << 24 | 0x40; 01918 REG_WR(bp, BNX2_TBDR_CONFIG, val); 01919 01920 val = bp->mac_addr[0] + 01921 (bp->mac_addr[1] << 8) + 01922 (bp->mac_addr[2] << 16) + 01923 bp->mac_addr[3] + 01924 (bp->mac_addr[4] << 8) + 01925 (bp->mac_addr[5] << 16); 01926 REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val); 01927 01928 /* Program the MTU. Also include 4 bytes for CRC32. */ 01929 val = ETH_MAX_MTU + ETH_HLEN + 4; 01930 if (val > (MAX_ETHERNET_PACKET_SIZE + 4)) 01931 val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA; 01932 REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val); 01933 01934 bp->last_status_idx = 0; 01935 bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; 01936 01937 /* Set up how to generate a link change interrupt. */ 01938 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); 01939 01940 REG_WR(bp, BNX2_HC_STATUS_ADDR_L, 01941 (u64) bp->status_blk_mapping & 0xffffffff); 01942 REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32); 01943 01944 REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L, 01945 (u64) bp->stats_blk_mapping & 0xffffffff); 01946 REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H, 01947 (u64) bp->stats_blk_mapping >> 32); 01948 01949 REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP, 01950 (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip); 01951 01952 REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP, 01953 (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip); 01954 01955 REG_WR(bp, BNX2_HC_COMP_PROD_TRIP, 01956 (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip); 01957 01958 REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks); 01959 01960 REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks); 01961 01962 REG_WR(bp, BNX2_HC_COM_TICKS, 01963 (bp->com_ticks_int << 16) | bp->com_ticks); 01964 01965 REG_WR(bp, BNX2_HC_CMD_TICKS, 01966 (bp->cmd_ticks_int << 16) | bp->cmd_ticks); 01967 01968 REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); 01969 REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ 01970 01971 if (CHIP_ID(bp) == CHIP_ID_5706_A1) 01972 REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS); 01973 else { 01974 REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE | 01975 BNX2_HC_CONFIG_TX_TMR_MODE | 01976 BNX2_HC_CONFIG_COLLECT_STATS); 01977 } 01978 01979 /* Clear internal stats counters. */ 01980 REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); 01981 01982 REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE); 01983 01984 if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) & 01985 BNX2_PORT_FEATURE_ASF_ENABLED) 01986 bp->flags |= ASF_ENABLE_FLAG; 01987 01988 /* Initialize the receive filter. */ 01989 bnx2_set_rx_mode(bp->nic); 01990 01991 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, 01992 0); 01993 01994 REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff); 01995 REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS); 01996 01997 udelay(20); 01998 01999 bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND); 02000 02001 return rc; 02002 }
| static void bnx2_init_tx_ring | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 2005 of file bnx2.c.
References BNX2_L2CTX_CMD_TYPE, BNX2_L2CTX_CMD_TYPE_TYPE_L2, BNX2_L2CTX_TBDR_BHADDR_HI, BNX2_L2CTX_TBDR_BHADDR_LO, BNX2_L2CTX_TYPE, BNX2_L2CTX_TYPE_SIZE_L2, BNX2_L2CTX_TYPE_TYPE_L2, CTX_WR, GET_CID_ADDR, bnx2::hw_tx_cons, MAX_TX_DESC_CNT, tx_bd::tx_bd_haddr_hi, tx_bd::tx_bd_haddr_lo, TX_CID, bnx2::tx_desc_mapping, bnx2::tx_desc_ring, bnx2::tx_prod, and u32.
Referenced by bnx2_reset_nic().
02006 { 02007 struct tx_bd *txbd; 02008 u32 val; 02009 02010 txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT]; 02011 02012 /* Etherboot lives below 4GB, so hi is always 0 */ 02013 txbd->tx_bd_haddr_hi = 0; 02014 txbd->tx_bd_haddr_lo = bp->tx_desc_mapping; 02015 02016 bp->tx_prod = 0; 02017 bp->tx_cons = 0; 02018 bp->hw_tx_cons = 0; 02019 bp->tx_prod_bseq = 0; 02020 02021 val = BNX2_L2CTX_TYPE_TYPE_L2; 02022 val |= BNX2_L2CTX_TYPE_SIZE_L2; 02023 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val); 02024 02025 val = BNX2_L2CTX_CMD_TYPE_TYPE_L2; 02026 val |= 8 << 16; 02027 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val); 02028 02029 /* Etherboot lives below 4GB, so hi is always 0 */ 02030 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, 0); 02031 02032 val = (u64) bp->tx_desc_mapping & 0xffffffff; 02033 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val); 02034 }
| static void bnx2_init_rx_ring | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 2037 of file bnx2.c.
References bnx2_bss, BNX2_L2CTX_CTX_TYPE, BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE, BNX2_L2CTX_CTX_TYPE_SIZE_L2, BNX2_L2CTX_HOST_BDIDX, BNX2_L2CTX_HOST_BSEQ, BNX2_L2CTX_NX_BDHADDR_HI, BNX2_L2CTX_NX_BDHADDR_LO, CTX_WR, GET_CID_ADDR, bnx2::hw_rx_cons, MAX_RX_DESC_CNT, MB_RX_CID_ADDR, memset(), NEXT_RX_BD, REG_WR, REG_WR16, rx_bd::rx_bd_flags, RX_BD_FLAGS_END, RX_BD_FLAGS_START, rx_bd::rx_bd_haddr_hi, rx_bd::rx_bd_haddr_lo, rx_bd::rx_bd_len, bss::rx_buf, RX_BUF_SIZE, bnx2::rx_buf_size, RX_BUF_USE_SIZE, bnx2::rx_buf_use_size, RX_CID, bnx2::rx_cons, bnx2::rx_desc_mapping, bnx2::rx_desc_ring, bnx2::rx_prod, bnx2::rx_prod_bseq, RX_RING_IDX, u16, u32, and virt_to_bus().
Referenced by bnx2_reset_nic().
02038 { 02039 struct rx_bd *rxbd; 02040 unsigned int i; 02041 u16 prod, ring_prod; 02042 u32 val; 02043 02044 bp->rx_buf_use_size = RX_BUF_USE_SIZE; 02045 bp->rx_buf_size = RX_BUF_SIZE; 02046 02047 ring_prod = prod = bp->rx_prod = 0; 02048 bp->rx_cons = 0; 02049 bp->hw_rx_cons = 0; 02050 bp->rx_prod_bseq = 0; 02051 02052 memset(bnx2_bss.rx_buf, 0, sizeof(bnx2_bss.rx_buf)); 02053 02054 rxbd = &bp->rx_desc_ring[0]; 02055 for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { 02056 rxbd->rx_bd_len = bp->rx_buf_use_size; 02057 rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; 02058 } 02059 rxbd->rx_bd_haddr_hi = 0; 02060 rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff; 02061 02062 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; 02063 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; 02064 val |= 0x02 << 8; 02065 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); 02066 02067 /* Etherboot doesn't use memory above 4GB, so this is always 0 */ 02068 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, 0); 02069 02070 val = bp->rx_desc_mapping & 0xffffffff; 02071 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); 02072 02073 for (i = 0; (int) i < bp->rx_ring_size; i++) { 02074 rxbd = &bp->rx_desc_ring[RX_RING_IDX(ring_prod)]; 02075 rxbd->rx_bd_haddr_hi = 0; 02076 rxbd->rx_bd_haddr_lo = virt_to_bus(&bnx2_bss.rx_buf[ring_prod][0]); 02077 bp->rx_prod_bseq += bp->rx_buf_use_size; 02078 prod = NEXT_RX_BD(prod); 02079 ring_prod = RX_RING_IDX(prod); 02080 } 02081 bp->rx_prod = prod; 02082 02083 REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod); 02084 02085 REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); 02086 }
Definition at line 2089 of file bnx2.c.
References bnx2_init_chip(), bnx2_init_rx_ring(), bnx2_init_tx_ring(), and bnx2_reset_chip().
Referenced by bnx2_init_nic().
02090 { 02091 int rc; 02092 02093 rc = bnx2_reset_chip(bp, reset_code); 02094 if (rc) { 02095 return rc; 02096 } 02097 02098 bnx2_init_chip(bp); 02099 bnx2_init_tx_ring(bp); 02100 bnx2_init_rx_ring(bp); 02101 return 0; 02102 }
| static int bnx2_init_nic | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 2105 of file bnx2.c.
References BNX2_DRV_MSG_CODE_RESET, bnx2_init_phy(), bnx2_reset_nic(), and bnx2_set_link().
Referenced by bnx2_probe().
02106 { 02107 int rc; 02108 02109 if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0) 02110 return rc; 02111 02112 bnx2_init_phy(bp); 02113 bnx2_set_link(bp); 02114 return 0; 02115 }
| static int bnx2_init_board | ( | struct pci_device * | pdev, | |
| struct nic * | nic | |||
| ) | [static] |
Definition at line 2118 of file bnx2.c.
References adjust_pci_device(), ADVERTISED_Autoneg, bnx2::advertising, bnx2::autoneg, AUTONEG_FLOW_CTRL, AUTONEG_SPEED, BNX2_DEV_INFO_BC_REV, BNX2_DEV_INFO_SIGNATURE, BNX2_DEV_INFO_SIGNATURE_MAGIC, BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK, bnx2_disable(), BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE, BNX2_DRV_PULSE_MB, bnx2_init_nvram(), BNX2_MISC_ID, BNX2_PCICFG_MISC_CONFIG, BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA, BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, BNX2_PCICFG_MISC_STATUS, BNX2_PCICFG_MISC_STATUS_32BIT_DET, BNX2_PCICFG_MISC_STATUS_M66EN, BNX2_PCICFG_MISC_STATUS_PCIX_DET, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW, BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G, BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK, BNX2_PORT_HW_CFG_CONFIG, BNX2_PORT_HW_CFG_MAC_LOWER, BNX2_PORT_HW_CFG_MAC_UPPER, bnx2_set_power_state_0(), BNX2_SHARED_HW_CFG_CONFIG, BNX2_SHARED_HW_CFG_PHY_2_5G, BNX2_SHM_HDR_ADDR_0, BNX2_SHM_HDR_SIGNATURE, BNX2_SHM_HDR_SIGNATURE_SIG, BNX2_SHM_HDR_SIGNATURE_SIG_MASK, bnx2::bus_speed_mhz, CHIP_BOND_ID, CHIP_BOND_ID_SERDES_BIT, CHIP_ID, bnx2::chip_id, CHIP_ID_5706_A0, CHIP_ID_5706_A1, CHIP_NUM, CHIP_NUM_5708, bnx2::cmd_ticks, bnx2::cmd_ticks_int, bnx2::com_ticks, bnx2::com_ticks_int, bnx2::comp_prod_trip, bnx2::comp_prod_trip_int, DUPLEX_FULL, EIO, ENODEV, ETHTOOL_ALL_COPPER_SPEED, ETHTOOL_ALL_FIBRE_SPEED, bnx2::flags, FLOW_CTRL_RX, FLOW_CTRL_TX, bnx2::fw_ver, HOST_VIEW_SHMEM_BASE, pci_device::ioaddr, nic::ioaddr, ioremap(), nic::irqno, bnx2::line_speed, bnx2::mac_addr, MAX_RX_DESC_CNT, MAX_TX_DESC_CNT, MB_GET_CID_ADDR, bnx2::nic, NO_WOL_FLAG, PCI_32BIT_FLAG, pci_bar_start(), PCI_BASE_ADDRESS_0, PCI_CAP_ID_PCIX, PCI_CAP_ID_PM, PCI_COMMAND, PCI_COMMAND_PARITY, PCI_COMMAND_SERR, pci_find_capability(), pci_write_config_dword(), bnx2::pcix_cap, PCIX_FLAG, bnx2::pdev, PHY_2_5G_CAPABLE_FLAG, bnx2::phy_addr, bnx2::phy_flags, PHY_SERDES_FLAG, bnx2::pm_cap, printf(), REG_RD, REG_RD_IND, REG_WR, REG_WR_IND, bnx2::regview, bnx2::req_duplex, bnx2::req_flow_ctrl, bnx2::req_line_speed, RX_BUF_CNT, bnx2::rx_max_ring_idx, RX_OFFSET, bnx2::rx_offset, bnx2::rx_quick_cons_trip, bnx2::rx_quick_cons_trip_int, bnx2::rx_ring_size, bnx2::rx_ticks, bnx2::rx_ticks_int, bnx2::shmem_base, SPEED_1000, bnx2::stats_ticks, bnx2::tx_quick_cons_trip, bnx2::tx_quick_cons_trip_int, bnx2::tx_ring_size, bnx2::tx_ticks, bnx2::tx_ticks_int, u32, and u8.
Referenced by bnx2_probe(), and bnx2_transmit().
02119 { 02120 unsigned long bnx2reg_base, bnx2reg_len; 02121 struct bnx2 *bp = &bnx2; 02122 int rc; 02123 u32 reg; 02124 02125 bp->flags = 0; 02126 bp->phy_flags = 0; 02127 02128 /* enable device (incl. PCI PM wakeup), and bus-mastering */ 02129 adjust_pci_device(pdev); 02130 02131 nic->ioaddr = pdev->ioaddr & ~3; 02132 nic->irqno = 0; 02133 02134 rc = 0; 02135 bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); 02136 if (bp->pm_cap == 0) { 02137 printf("Cannot find power management capability, aborting.\n"); 02138 rc = -EIO; 02139 goto err_out_disable; 02140 } 02141 02142 bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); 02143 if (bp->pcix_cap == 0) { 02144 printf("Cannot find PCIX capability, aborting.\n"); 02145 rc = -EIO; 02146 goto err_out_disable; 02147 } 02148 02149 bp->pdev = pdev; 02150 bp->nic = nic; 02151 02152 bnx2reg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_0); 02153 bnx2reg_len = MB_GET_CID_ADDR(17); 02154 02155 bp->regview = ioremap(bnx2reg_base, bnx2reg_len); 02156 02157 if (!bp->regview) { 02158 printf("Cannot map register space, aborting.\n"); 02159 rc = -EIO; 02160 goto err_out_disable; 02161 } 02162 02163 /* Configure byte swap and enable write to the reg_window registers. 02164 * Rely on CPU to do target byte swapping on big endian systems 02165 * The chip's target access swapping will not swap all accesses 02166 */ 02167 pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, 02168 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 02169 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); 02170 02171 bnx2_set_power_state_0(bp); 02172 02173 bp->chip_id = REG_RD(bp, BNX2_MISC_ID); 02174 02175 /* Get bus information. */ 02176 reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); 02177 if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { 02178 u32 clkreg; 02179 02180 bp->flags |= PCIX_FLAG; 02181 02182 clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS); 02183 02184 clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET; 02185 switch (clkreg) { 02186 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: 02187 bp->bus_speed_mhz = 133; 02188 break; 02189 02190 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: 02191 bp->bus_speed_mhz = 100; 02192 break; 02193 02194 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: 02195 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: 02196 bp->bus_speed_mhz = 66; 02197 break; 02198 02199 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: 02200 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: 02201 bp->bus_speed_mhz = 50; 02202 break; 02203 02204 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW: 02205 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: 02206 case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: 02207 bp->bus_speed_mhz = 33; 02208 break; 02209 } 02210 } 02211 else { 02212 if (reg & BNX2_PCICFG_MISC_STATUS_M66EN) 02213 bp->bus_speed_mhz = 66; 02214 else 02215 bp->bus_speed_mhz = 33; 02216 } 02217 02218 if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET) 02219 bp->flags |= PCI_32BIT_FLAG; 02220 02221 /* 5706A0 may falsely detect SERR and PERR. */ 02222 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 02223 reg = REG_RD(bp, PCI_COMMAND); 02224 reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); 02225 REG_WR(bp, PCI_COMMAND, reg); 02226 } 02227 else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) && 02228 !(bp->flags & PCIX_FLAG)) { 02229 02230 printf("5706 A1 can only be used in a PCIX bus, aborting.\n"); 02231 goto err_out_disable; 02232 } 02233 02234 bnx2_init_nvram(bp); 02235 02236 reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); 02237 02238 if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == 02239 BNX2_SHM_HDR_SIGNATURE_SIG) 02240 bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); 02241 else 02242 bp->shmem_base = HOST_VIEW_SHMEM_BASE; 02243 02244 /* Get the permanent MAC address. First we need to make sure the 02245 * firmware is actually running. 02246 */ 02247 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE); 02248 02249 if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != 02250 BNX2_DEV_INFO_SIGNATURE_MAGIC) { 02251 printf("Firmware not running, aborting.\n"); 02252 rc = -ENODEV; 02253 goto err_out_disable; 02254 } 02255 02256 bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV); 02257 02258 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER); 02259 bp->mac_addr[0] = (u8) (reg >> 8); 02260 bp->mac_addr[1] = (u8) reg; 02261 02262 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER); 02263 bp->mac_addr[2] = (u8) (reg >> 24); 02264 bp->mac_addr[3] = (u8) (reg >> 16); 02265 bp->mac_addr[4] = (u8) (reg >> 8); 02266 bp->mac_addr[5] = (u8) reg; 02267 02268 bp->tx_ring_size = MAX_TX_DESC_CNT; 02269 bp->rx_ring_size = RX_BUF_CNT; 02270 bp->rx_max_ring_idx = MAX_RX_DESC_CNT; 02271 02272 bp->rx_offset = RX_OFFSET; 02273 02274 bp->tx_quick_cons_trip_int = 20; 02275 bp->tx_quick_cons_trip = 20; 02276 bp->tx_ticks_int = 80; 02277 bp->tx_ticks = 80; 02278 02279 bp->rx_quick_cons_trip_int = 6; 02280 bp->rx_quick_cons_trip = 6; 02281 bp->rx_ticks_int = 18; 02282 bp->rx_ticks = 18; 02283 02284 bp->stats_ticks = 1000000 & 0xffff00; 02285 02286 bp->phy_addr = 1; 02287 02288 /* No need for WOL support in Etherboot */ 02289 bp->flags |= NO_WOL_FLAG; 02290 02291 /* Disable WOL support if we are running on a SERDES chip. */ 02292 if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { 02293 bp->phy_flags |= PHY_SERDES_FLAG; 02294 if (CHIP_NUM(bp) == CHIP_NUM_5708) { 02295 bp->phy_addr = 2; 02296 reg = REG_RD_IND(bp, bp->shmem_base + 02297 BNX2_SHARED_HW_CFG_CONFIG); 02298 if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) 02299 bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; 02300 } 02301 } 02302 02303 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 02304 bp->tx_quick_cons_trip_int = 02305 bp->tx_quick_cons_trip; 02306 bp->tx_ticks_int = bp->tx_ticks; 02307 bp->rx_quick_cons_trip_int = 02308 bp->rx_quick_cons_trip; 02309 bp->rx_ticks_int = bp->rx_ticks; 02310 bp->comp_prod_trip_int = bp->comp_prod_trip; 02311 bp->com_ticks_int = bp->com_ticks; 02312 bp->cmd_ticks_int = bp->cmd_ticks; 02313 } 02314 02315 bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; 02316 bp->req_line_speed = 0; 02317 if (bp->phy_flags & PHY_SERDES_FLAG) { 02318 bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; 02319 02320 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG); 02321 reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; 02322 if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { 02323 bp->autoneg = 0; 02324 bp->req_line_speed = bp->line_speed = SPEED_1000; 02325 bp->req_duplex = DUPLEX_FULL; 02326 } 02327 } 02328 else { 02329 bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; 02330 } 02331 02332 bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; 02333 02334 /* Disable driver heartbeat checking */ 02335 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, 02336 BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE); 02337 REG_RD_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB); 02338 02339 return 0; 02340 02341 err_out_disable: 02342 bnx2_disable(nic); 02343 02344 return rc; 02345 }
| static void bnx2_transmit | ( | struct nic * | nic, | |
| const char * | dst_addr, | |||
| unsigned int | type, | |||
| unsigned int | size, | |||
| const char * | packet | |||
| ) | [static] |
Definition at line 2348 of file bnx2.c.
References bnx2_disable(), bnx2_init_board(), BNX2_L2CTX_TX_HOST_BIDX, BNX2_L2CTX_TX_HOST_BSEQ, eth_frame::data, ETH_ALEN, ETH_FRAME_LEN, ETH_HLEN, htons, MAX_TX_DESC_CNT, MB_TX_CID_ADDR, mdelay(), memcpy, memset(), NEXT_TX_BD, bnx2::nic, nic::node_addr, bnx2::pdev, PREV_TX_BD, printf(), REG_WR, REG_WR16, eth_frame::src_addr, bnx2::status_blk, status_block::status_tx_quick_consumer_index0, TX_BD_FLAGS_END, TX_BD_FLAGS_START, tx_bd::tx_bd_haddr_hi, tx_bd::tx_bd_haddr_lo, tx_bd::tx_bd_mss_nbytes, tx_bd::tx_bd_vlan_tag_flags, bnx2::tx_desc_ring, bnx2::tx_prod, TX_RING_IDX, u16, virt_to_bus(), and wmb.
02350 { 02351 /* Sometimes the nic will be behind by a frame. Using two transmit 02352 * buffers prevents us from timing out in that case. 02353 */ 02354 static struct eth_frame { 02355 uint8_t dst_addr[ETH_ALEN]; 02356 uint8_t src_addr[ETH_ALEN]; 02357 uint16_t type; 02358 uint8_t data [ETH_FRAME_LEN - ETH_HLEN]; 02359 } frame[2]; 02360 static int frame_idx = 0; 02361 02362 /* send the packet to destination */ 02363 struct tx_bd *txbd; 02364 struct bnx2 *bp = &bnx2; 02365 u16 prod, ring_prod; 02366 u16 hw_cons; 02367 int i = 0; 02368 02369 prod = bp->tx_prod; 02370 ring_prod = TX_RING_IDX(prod); 02371 hw_cons = bp->status_blk->status_tx_quick_consumer_index0; 02372 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { 02373 hw_cons++; 02374 } 02375 02376 while((hw_cons != prod) && (hw_cons != (PREV_TX_BD(prod)))) { 02377 mdelay(10); /* give the nic a chance */ 02378 //poll_interruptions(); 02379 if (++i > 500) { /* timeout 5s for transmit */ 02380 printf("transmit timed out\n"); 02381 bnx2_disable(bp->nic); 02382 bnx2_init_board(bp->pdev, bp->nic); 02383 return; 02384 } 02385 } 02386 if (i != 0) { 02387 printf("#"); 02388 } 02389 02390 /* Copy the packet to the our local buffer */ 02391 memcpy(&frame[frame_idx].dst_addr, dst_addr, ETH_ALEN); 02392 memcpy(&frame[frame_idx].src_addr, nic->node_addr, ETH_ALEN); 02393 frame[frame_idx].type = htons(type); 02394 memset(&frame[frame_idx].data, 0, sizeof(frame[frame_idx].data)); 02395 memcpy(&frame[frame_idx].data, packet, size); 02396 02397 /* Setup the ring buffer entry to transmit */ 02398 txbd = &bp->tx_desc_ring[ring_prod]; 02399 txbd->tx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */ 02400 txbd->tx_bd_haddr_lo = virt_to_bus(&frame[frame_idx]); 02401 txbd->tx_bd_mss_nbytes = (size + ETH_HLEN); 02402 txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; 02403 02404 /* Advance to the next entry */ 02405 prod = NEXT_TX_BD(prod); 02406 frame_idx ^= 1; 02407 02408 bp->tx_prod_bseq += (size + ETH_HLEN); 02409 02410 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); 02411 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); 02412 02413 wmb(); 02414 02415 bp->tx_prod = prod; 02416 }
| static int bnx2_poll_link | ( | struct bnx2 * | bp | ) | [static] |
Definition at line 2419 of file bnx2.c.
References BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK, BNX2_EMAC_STATUS_LINK_CHANGE, BNX2_HC_COMMAND, BNX2_HC_COMMAND_COAL_NOW_WO_INT, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, BNX2_PCICFG_STATUS_BIT_SET_CMD, bnx2_read_phy(), bnx2_set_link(), CHIP_NUM, CHIP_NUM_5706, bnx2::hc_cmd, bnx2::link_up, MII_BMSR, bnx2::phy_flags, PHY_SERDES_FLAG, REG_RD, REG_WR, status_block::status_attn_bits, status_block::status_attn_bits_ack, STATUS_ATTN_BITS_LINK_STATE, bnx2::status_blk, and u32.
Referenced by bnx2_poll(), and bnx2_probe().
02420 { 02421 u32 new_link_state, old_link_state, emac_status; 02422 02423 new_link_state = bp->status_blk->status_attn_bits & 02424 STATUS_ATTN_BITS_LINK_STATE; 02425 02426 old_link_state = bp->status_blk->status_attn_bits_ack & 02427 STATUS_ATTN_BITS_LINK_STATE; 02428 02429 if (!new_link_state && !old_link_state) { 02430 /* For some reason the card doesn't always update the link 02431 * status bits properly. Kick the stupid thing and try again. 02432 */ 02433 u32 bmsr; 02434 02435 bnx2_read_phy(bp, MII_BMSR, &bmsr); 02436 bnx2_read_phy(bp, MII_BMSR, &bmsr); 02437 02438 if ((bp->phy_flags & PHY_SERDES_FLAG) && 02439 (CHIP_NUM(bp) == CHIP_NUM_5706)) { 02440 REG_RD(bp, BNX2_EMAC_STATUS); 02441 } 02442 02443 new_link_state = bp->status_blk->status_attn_bits & 02444 STATUS_ATTN_BITS_LINK_STATE; 02445 02446 old_link_state = bp->status_blk->status_attn_bits_ack & 02447 STATUS_ATTN_BITS_LINK_STATE; 02448 02449 /* Okay, for some reason the above doesn't work with some 02450 * switches (like HP ProCurve). If the above doesn't work, 02451 * check the MAC directly to see if we have a link. Perhaps we 02452 * should always check the MAC instead probing the MII. 02453 */ 02454 if (!new_link_state && !old_link_state) { 02455 emac_status = REG_RD(bp, BNX2_EMAC_STATUS); 02456 if (emac_status & BNX2_EMAC_STATUS_LINK_CHANGE) { 02457 /* Acknowledge the link change */ 02458 REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); 02459 } else if (emac_status & BNX2_EMAC_STATUS_LINK) { 02460 new_link_state = !old_link_state; 02461 } 02462 } 02463 02464 } 02465 02466 if (new_link_state != old_link_state) { 02467 if (new_link_state) { 02468 REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, 02469 STATUS_ATTN_BITS_LINK_STATE); 02470 } 02471 else { 02472 REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, 02473 STATUS_ATTN_BITS_LINK_STATE); 02474 } 02475 02476 bnx2_set_link(bp); 02477 02478 /* This is needed to take care of transient status 02479 * during link changes. 02480 */ 02481 02482 REG_WR(bp, BNX2_HC_COMMAND, 02483 bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); 02484 REG_RD(bp, BNX2_HC_COMMAND); 02485 02486 } 02487 02488 return bp->link_up; 02489 }
| static int bnx2_poll | ( | struct nic * | nic, | |
| int | retrieve | |||
| ) | [static] |
Definition at line 2492 of file bnx2.c.
References BNX2_HC_COMMAND, BNX2_HC_COMMAND_COAL_NOW_WO_INT, BNX2_L2CTX_HOST_BDIDX, BNX2_L2CTX_HOST_BSEQ, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID, BNX2_PCICFG_INT_ACK_CMD_MASK_INT, BNX2_PCICFG_MISC_STATUS, BNX2_PCICFG_MISC_STATUS_INTA_VALUE, bnx2_poll_link(), bus_to_virt(), ETH_HLEN, ETH_MAX_MTU, bnx2::hc_cmd, bnx2::hw_rx_cons, L2_FHDR_ERRORS_ALIGNMENT, L2_FHDR_ERRORS_BAD_CRC, L2_FHDR_ERRORS_GIANT_FRAME, L2_FHDR_ERRORS_PHY_DECODE, L2_FHDR_ERRORS_TOO_SHORT, l2_fhdr::l2_fhdr_pkt_len, l2_fhdr::l2_fhdr_status, bnx2::last_status_idx, MAX_RX_DESC_CNT, MB_RX_CID_ADDR, memcpy, NEXT_RX_BD, nic::packet, nic::packetlen, REG_RD, REG_WR, REG_WR16, rmb, rx_bd::rx_bd_haddr_hi, rx_bd::rx_bd_haddr_lo, bnx2::rx_buf_use_size, bnx2::rx_cons, bnx2::rx_desc_ring, rx_hdr, bnx2::rx_offset, bnx2::rx_prod, bnx2::rx_prod_bseq, RX_RING_IDX, bnx2::status_blk, status_block::status_idx, status_block::status_rx_quick_consumer_index0, u16, u32, and wmb.
02493 { 02494 struct bnx2 *bp = &bnx2; 02495 struct rx_bd *cons_bd, *prod_bd; 02496 u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; 02497 struct l2_fhdr *rx_hdr; 02498 int result = 0; 02499 unsigned int len; 02500 unsigned char *data; 02501 u32 status; 02502 02503 #if 0 02504 if ((bp->status_blk->status_idx == bp->last_status_idx) && 02505 (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & 02506 BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) { 02507 02508 bp->last_status_idx = bp->status_blk->status_idx; 02509 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 02510 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | 02511 BNX2_PCICFG_INT_ACK_CMD_MASK_INT | 02512 bp->last_status_idx); 02513 return 0; 02514 } 02515 #endif 02516 02517 if ((bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) && !retrieve) 02518 return 1; 02519 02520 if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) { 02521 02522 hw_cons = bp->hw_rx_cons = bp->status_blk->status_rx_quick_consumer_index0; 02523 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { 02524 hw_cons++; 02525 } 02526 sw_cons = bp->rx_cons; 02527 sw_prod = bp->rx_prod; 02528 02529 rmb(); 02530 if (sw_cons != hw_cons) { 02531 02532 sw_ring_cons = RX_RING_IDX(sw_cons); 02533 sw_ring_prod = RX_RING_IDX(sw_prod); 02534 02535 data = bus_to_virt(bp->rx_desc_ring[sw_ring_cons].rx_bd_haddr_lo); 02536 02537 rx_hdr = (struct l2_fhdr *)data; 02538 len = rx_hdr->l2_fhdr_pkt_len - 4; 02539 if ((len > (ETH_MAX_MTU + ETH_HLEN)) || 02540 ((status = rx_hdr->l2_fhdr_status) & 02541 (L2_FHDR_ERRORS_BAD_CRC | 02542 L2_FHDR_ERRORS_PHY_DECODE | 02543 L2_FHDR_ERRORS_ALIGNMENT | 02544 L2_FHDR_ERRORS_TOO_SHORT | 02545 L2_FHDR_ERRORS_GIANT_FRAME))) { 02546 result = 0; 02547 } 02548 else 02549 { 02550 nic->packetlen = len; 02551 memcpy(nic->packet, data + bp->rx_offset, len); 02552 result = 1; 02553 } 02554 02555 /* Reuse the buffer */ 02556 bp->rx_prod_bseq += bp->rx_buf_use_size; 02557 if (sw_cons != sw_prod) { 02558 cons_bd = &bp->rx_desc_ring[sw_ring_cons]; 02559 prod_bd = &bp->rx_desc_ring[sw_ring_prod]; 02560 prod_bd->rx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */ 02561 prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; 02562 } 02563 02564 sw_cons = NEXT_RX_BD(sw_cons); 02565 sw_prod = NEXT_RX_BD(sw_prod); 02566 02567 } 02568 02569 bp->rx_cons = sw_cons; 02570 bp->rx_prod = sw_prod; 02571 02572 REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod); 02573 02574 REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); 02575 02576 wmb(); 02577 02578 } 02579 02580 bnx2_poll_link(bp); 02581 02582 #if 0 02583 bp->last_status_idx = bp->status_blk->status_idx; 02584 rmb(); 02585 02586 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 02587 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | 02588 BNX2_PCICFG_INT_ACK_CMD_MASK_INT | 02589 bp->last_status_idx); 02590 02591 REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); 02592 #endif 02593 02594 return result; 02595 }
| static void bnx2_irq | ( | struct nic *nic | __unused, | |
| irq_action_t action | __unused | |||
| ) | [static] |
| static int bnx2_probe | ( | struct nic * | nic, | |
| struct pci_device * | pdev | |||
| ) | [static] |
Definition at line 2615 of file bnx2.c.
References bnx2_alloc_mem(), bnx2_disable(), bnx2_disable_int(), bnx2_init_board(), bnx2_init_nic(), bnx2_poll_link(), bnx2_set_power_state_0(), bnx2::bus_speed_mhz, CHIP_ID, ETH_ALEN, eth_ntoa(), bnx2::flags, bnx2::link_up, bnx2::mac_addr, mdelay(), memcpy, memset(), nic::nic_op, nic::node_addr, PCI_32BIT_FLAG, PCIX_FLAG, printf(), and VALID_LINK_TIMEOUT.
02616 { 02617 struct bnx2 *bp = &bnx2; 02618 int i, rc; 02619 02620 if (pdev == 0) 02621 return 0; 02622 02623 memset(bp, 0, sizeof(*bp)); 02624 02625 rc = bnx2_init_board(pdev, nic); 02626 if (rc < 0) { 02627 return 0; 02628 } 02629 02630 /* 02631 nic->disable = bnx2_disable; 02632 nic->transmit = bnx2_transmit; 02633 nic->poll = bnx2_poll; 02634 nic->irq = bnx2_irq; 02635 */ 02636 02637 nic->nic_op = &bnx2_operations; 02638 02639 memcpy(nic->node_addr, bp->mac_addr, ETH_ALEN); 02640 printf("Ethernet addr: %s\n", eth_ntoa( nic->node_addr ) ); 02641 printf("Broadcom NetXtreme II (%c%d) PCI%s %s %dMHz\n", 02642 (int) ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', 02643 (int) ((CHIP_ID(bp) & 0x0ff0) >> 4), 02644 ((bp->flags & PCIX_FLAG) ? "-X" : ""), 02645 ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), 02646 bp->bus_speed_mhz); 02647 02648 bnx2_set_power_state_0(bp); 02649 bnx2_disable_int(bp); 02650 02651 bnx2_alloc_mem(bp); 02652 02653 rc = bnx2_init_nic(bp); 02654 if (rc) { 02655 return 0; 02656 } 02657 02658 bnx2_poll_link(bp); 02659 for(i = 0; !bp->link_up && (i < VALID_LINK_TIMEOUT*100); i++) { 02660 mdelay(1); 02661 bnx2_poll_link(bp); 02662 } 02663 #if 1 02664 if (!bp->link_up){ 02665 printf("Valid link not established\n"); 02666 goto err_out_disable; 02667 } 02668 #endif 02669 02670 return 1; 02671 02672 err_out_disable: 02673 bnx2_disable(nic); 02674 return 0; 02675 }
| PCI_DRIVER | ( | bnx2_driver | , | |
| bnx2_nics | , | |||
| PCI_NO_CLASS | ||||
| ) |
| DRIVER | ( | "BNX2" | , | |
| nic_driver | , | |||
| pci_driver | , | |||
| bnx2_driver | , | |||
| bnx2_probe | , | |||
| bnx2_disable | ||||
| ) |
Referenced by bnx2_alloc_mem(), and bnx2_init_rx_ring().
struct flash_spec flash_table[] [static] |
struct nic_operations bnx2_operations [static] |
Initial value:
{
.connect = dummy_connect,
.poll = bnx2_poll,
.transmit = bnx2_transmit,
.irq = bnx2_irq,
}
struct pci_device_id bnx2_nics[] [static] |
Initial value:
{
PCI_ROM(0x14e4, 0x164a, "bnx2-5706", "Broadcom NetXtreme II BCM5706", 0),
PCI_ROM(0x14e4, 0x164c, "bnx2-5708", "Broadcom NetXtreme II BCM5708", 0),
PCI_ROM(0x14e4, 0x16aa, "bnx2-5706S", "Broadcom NetXtreme II BCM5706S", 0),
PCI_ROM(0x14e4, 0x16ac, "bnx2-5708S", "Broadcom NetXtreme II BCM5708S", 0),
}
1.5.7.1