iPXE
bnx2.c
Go to the documentation of this file.
00001 /* bnx2.c: Broadcom NX2 network driver.
00002  *
00003  * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation.
00008  *
00009  * Written by: Michael Chan  (mchan@broadcom.com)
00010  *
00011  * Etherboot port by Ryan Jackson (rjackson@lnxi.com), based on driver
00012  * version 1.4.40 from linux 2.6.17
00013  */
00014 
00015 FILE_LICENCE ( GPL_ANY );
00016 
00017 #include "etherboot.h"
00018 #include "nic.h"
00019 #include <errno.h>
00020 #include <ipxe/pci.h>
00021 #include <ipxe/ethernet.h>
00022 #include "string.h"
00023 #include <mii.h>
00024 #include "bnx2.h"
00025 #include "bnx2_fw.h"
00026 
00027 #if 0
00028 /* Dummy defines for error handling */
00029 #define EBUSY  1
00030 #define ENODEV 2
00031 #define EINVAL 3
00032 #define ENOMEM 4
00033 #define EIO    5
00034 #endif
00035 
00036 /* The bnx2 seems to be picky about the alignment of the receive buffers
00037  * and possibly the status block.
00038  */
00039 static struct bss {
00040         struct tx_bd tx_desc_ring[TX_DESC_CNT];
00041         struct rx_bd rx_desc_ring[RX_DESC_CNT];
00042         unsigned char rx_buf[RX_BUF_CNT][RX_BUF_SIZE];
00043         struct status_block status_blk;
00044         struct statistics_block stats_blk;
00045 } bnx2_bss;
00046 
00047 static struct bnx2 bnx2;
00048 
00049 static struct flash_spec flash_table[] =
00050 {
00051         /* Slow EEPROM */
00052         {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
00053          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
00054          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
00055          "EEPROM - slow"},
00056         /* Expansion entry 0001 */
00057         {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
00058          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00059          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
00060          "Entry 0001"},
00061         /* Saifun SA25F010 (non-buffered flash) */
00062         /* strap, cfg1, & write1 need updates */
00063         {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
00064          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00065          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
00066          "Non-buffered flash (128kB)"},
00067         /* Saifun SA25F020 (non-buffered flash) */
00068         /* strap, cfg1, & write1 need updates */
00069         {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
00070          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00071          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
00072          "Non-buffered flash (256kB)"},
00073         /* Expansion entry 0100 */
00074         {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
00075          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00076          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
00077          "Entry 0100"},
00078         /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
00079         {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,        
00080          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
00081          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
00082          "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
00083         /* Entry 0110: ST M45PE20 (non-buffered flash)*/
00084         {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
00085          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
00086          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
00087          "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
00088         /* Saifun SA25F005 (non-buffered flash) */
00089         /* strap, cfg1, & write1 need updates */
00090         {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
00091          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00092          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
00093          "Non-buffered flash (64kB)"},
00094         /* Fast EEPROM */
00095         {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
00096          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
00097          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
00098          "EEPROM - fast"},
00099         /* Expansion entry 1001 */
00100         {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
00101          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00102          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
00103          "Entry 1001"},
00104         /* Expansion entry 1010 */
00105         {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
00106          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00107          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
00108          "Entry 1010"},
00109         /* ATMEL AT45DB011B (buffered flash) */
00110         {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
00111          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
00112          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
00113          "Buffered flash (128kB)"},
00114         /* Expansion entry 1100 */
00115         {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
00116          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00117          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
00118          "Entry 1100"},
00119         /* Expansion entry 1101 */
00120         {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
00121          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
00122          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
00123          "Entry 1101"},
00124         /* Ateml Expansion entry 1110 */
00125         {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
00126          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
00127          BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
00128          "Entry 1110 (Atmel)"},
00129         /* ATMEL AT45DB021B (buffered flash) */
00130         {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
00131          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
00132          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
00133          "Buffered flash (256kB)"},
00134 };
00135 
00136 static u32
00137 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
00138 {
00139         REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
00140         return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW));
00141 }
00142 
00143 static void
00144 bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
00145 {
00146         REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
00147         REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
00148 }
00149 
00150 static void
00151 bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
00152 {
00153         offset += cid_addr;
00154         REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
00155         REG_WR(bp, BNX2_CTX_DATA, val);
00156 }
00157 
00158 static int
00159 bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
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 }
00214 
00215 static int
00216 bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
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 }
00263 
00264 static void
00265 bnx2_disable_int(struct bnx2 *bp)
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 }
00272 
00273 static int
00274 bnx2_alloc_mem(struct bnx2 *bp)
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 }
00293 
00294 static void
00295 bnx2_report_fw_link(struct bnx2 *bp)
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 }
00349 
00350 static void
00351 bnx2_report_link(struct bnx2 *bp)
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 }
00382 
00383 static void
00384 bnx2_resolve_flow_ctrl(struct bnx2 *bp)
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 }
00458 
00459 static int
00460 bnx2_5708s_linkup(struct bnx2 *bp)
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 }
00487 
00488 static int
00489 bnx2_5706s_linkup(struct bnx2 *bp)
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 }
00524 
00525 static int
00526 bnx2_copper_linkup(struct bnx2 *bp)
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 }
00590 
00591 static int
00592 bnx2_set_mac_link(struct bnx2 *bp)
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 }
00657 
00658 static int
00659 bnx2_set_link(struct bnx2 *bp)
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 }
00723 
00724 static int
00725 bnx2_reset_phy(struct bnx2 *bp)
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, &reg);
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 }
00747 
00748 static u32
00749 bnx2_phy_get_pause_adv(struct bnx2 *bp)
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 }
00781 
00782 static int
00783 bnx2_setup_serdes_phy(struct bnx2 *bp)
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 }
00881 
00882 #define ETHTOOL_ALL_FIBRE_SPEED                                         \
00883         (ADVERTISED_1000baseT_Full)
00884 
00885 #define ETHTOOL_ALL_COPPER_SPEED                                        \
00886         (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |            \
00887         ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |           \
00888         ADVERTISED_1000baseT_Full)
00889 
00890 #define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \
00891         ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA)
00892         
00893 #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
00894 
00895 static int
00896 bnx2_setup_copper_phy(struct bnx2 *bp)
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 }
00989 
00990 static int
00991 bnx2_setup_phy(struct bnx2 *bp)
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 }
01003 
01004 static int
01005 bnx2_init_5708s_phy(struct bnx2 *bp)
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 }
01057 
01058 static int
01059 bnx2_init_5706s_phy(struct bnx2 *bp)
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 }
01080 
01081 static int
01082 bnx2_init_copper_phy(struct bnx2 *bp)
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 }
01112 
01113 static int
01114 bnx2_init_phy(struct bnx2 *bp)
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 }
01145 
01146 static int
01147 bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
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 }
01187 
01188 static void
01189 bnx2_init_context(struct bnx2 *bp)
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 }
01228 
01229 static int
01230 bnx2_alloc_bad_rbuf(struct bnx2 *bp)
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 }
01271 
01272 static void
01273 bnx2_set_mac_addr(struct bnx2 *bp) 
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 }
01287 
01288 static void
01289 bnx2_set_rx_mode(struct nic *nic __unused)
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 }
01319 
01320 static void
01321 load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc)
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 }
01351 
01352 static void
01353 load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
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 }
01425 
01426 static void
01427 bnx2_init_cpus(struct bnx2 *bp)
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 }
01626 
01627 static int
01628 bnx2_set_power_state_0(struct bnx2 *bp)
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 }
01654 
01655 static void
01656 bnx2_enable_nvram_access(struct bnx2 *bp)
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 }
01665 
01666 static void
01667 bnx2_disable_nvram_access(struct bnx2 *bp)
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 }
01677 
01678 static int
01679 bnx2_init_nvram(struct bnx2 *bp)
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 }
01751 
01752 static int
01753 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
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 }
01832 
01833 static void
01834 bnx2_disable(struct nic *nic __unused)
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 }
01843 
01844 static int
01845 bnx2_init_chip(struct bnx2 *bp)
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 }
02003 
02004 static void
02005 bnx2_init_tx_ring(struct bnx2 *bp)
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 }
02035 
02036 static void
02037 bnx2_init_rx_ring(struct bnx2 *bp)
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 }
02087 
02088 static int
02089 bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
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 }
02103 
02104 static int
02105 bnx2_init_nic(struct bnx2 *bp)
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 }
02116 
02117 static int
02118 bnx2_init_board(struct pci_device *pdev, struct nic *nic)
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 }
02346 
02347 static void
02348 bnx2_transmit(struct nic *nic, const char *dst_addr,
02349                 unsigned int type, unsigned int size, const char *packet)
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 }
02417 
02418 static int
02419 bnx2_poll_link(struct bnx2 *bp)
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 }
02490 
02491 static int
02492 bnx2_poll(struct nic* nic, int retrieve)
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 }
02596 
02597 static void
02598 bnx2_irq(struct nic *nic __unused, irq_action_t action __unused)
02599 {
02600         switch ( action ) {
02601                 case DISABLE: break;
02602                 case ENABLE: break;
02603                 case FORCE: break;
02604         }
02605 }
02606 
02607 static struct nic_operations bnx2_operations = {
02608         .connect        = dummy_connect,
02609         .poll           = bnx2_poll,
02610         .transmit       = bnx2_transmit,
02611         .irq            = bnx2_irq,
02612 };
02613 
02614 static int
02615 bnx2_probe(struct nic *nic, struct pci_device *pdev)
02616 {
02617         struct bnx2 *bp = &bnx2;
02618         int i, rc;
02619 
02620         memset(bp, 0, sizeof(*bp));
02621 
02622         rc = bnx2_init_board(pdev, nic);
02623         if (rc < 0) {
02624                 return 0;
02625         }
02626 
02627         /*
02628         nic->disable = bnx2_disable;
02629         nic->transmit = bnx2_transmit;
02630         nic->poll = bnx2_poll;
02631         nic->irq = bnx2_irq;
02632         */
02633         
02634         nic->nic_op     = &bnx2_operations;
02635 
02636         memcpy(nic->node_addr, bp->mac_addr, ETH_ALEN);
02637         printf("Ethernet addr: %s\n", eth_ntoa( nic->node_addr ) );
02638         printf("Broadcom NetXtreme II (%c%d) PCI%s %s %dMHz\n",
02639                 (int) ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
02640                 (int) ((CHIP_ID(bp) & 0x0ff0) >> 4),
02641                 ((bp->flags & PCIX_FLAG) ? "-X" : ""),
02642                 ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
02643                 bp->bus_speed_mhz);
02644 
02645         bnx2_set_power_state_0(bp);
02646         bnx2_disable_int(bp);
02647 
02648         bnx2_alloc_mem(bp);
02649 
02650         rc = bnx2_init_nic(bp);
02651         if (rc) {
02652                 return 0;
02653         }
02654 
02655         bnx2_poll_link(bp);
02656         for(i = 0; !bp->link_up && (i < VALID_LINK_TIMEOUT*100); i++) {
02657                 mdelay(1);
02658                 bnx2_poll_link(bp);
02659         }
02660 #if 1
02661         if (!bp->link_up){
02662                 printf("Valid link not established\n");
02663                 goto err_out_disable;
02664         }
02665 #endif
02666         
02667         return 1;
02668 
02669 err_out_disable:
02670         bnx2_disable(nic);
02671         return 0;
02672 }
02673 
02674 static struct pci_device_id bnx2_nics[] = {
02675         PCI_ROM(0x14e4, 0x164a, "bnx2-5706",        "Broadcom NetXtreme II BCM5706", 0),
02676         PCI_ROM(0x14e4, 0x164c, "bnx2-5708",        "Broadcom NetXtreme II BCM5708", 0),
02677         PCI_ROM(0x14e4, 0x16aa, "bnx2-5706S",       "Broadcom NetXtreme II BCM5706S", 0),
02678         PCI_ROM(0x14e4, 0x16ac, "bnx2-5708S",       "Broadcom NetXtreme II BCM5708S", 0),
02679 };
02680 
02681 PCI_DRIVER ( bnx2_driver, bnx2_nics, PCI_NO_CLASS );
02682 
02683 DRIVER ( "BNX2", nic_driver, pci_driver, bnx2_driver, bnx2_probe, bnx2_disable );
02684 
02685 /*
02686 static struct pci_driver bnx2_driver __pci_driver = {
02687         .type     = NIC_DRIVER,
02688         .name     = "BNX2",              
02689         .probe    = bnx2_probe,
02690         .ids      = bnx2_nics,                  
02691         .id_count = sizeof(bnx2_nics)/sizeof(bnx2_nics[0]), 
02692         .class    = 0,    
02693 };
02694 */