00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 FILE_LICENCE ( GPL_ANY );
00016
00017 #include "etherboot.h"
00018 #include "nic.h"
00019 #include <errno.h>
00020 #include <gpxe/pci.h>
00021 #include <gpxe/ethernet.h>
00022 #include "string.h"
00023 #include <mii.h>
00024 #include "bnx2.h"
00025 #include "bnx2_fw.h"
00026
00027 #if 0
00028
00029 #define EBUSY 1
00030 #define ENODEV 2
00031 #define EINVAL 3
00032 #define ENOMEM 4
00033 #define EIO 5
00034 #endif
00035
00036
00037
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
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
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
00062
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
00068
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
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
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
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
00089
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
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
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
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
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
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
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
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
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
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
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
00617 case SPEED_100:
00618 val |= BNX2_EMAC_MODE_PORT_MII;
00619 break;
00620 case SPEED_2500:
00621 val |= BNX2_EMAC_MODE_25G;
00622
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
00633 if (bp->duplex == DUPLEX_HALF)
00634 val |= BNX2_EMAC_MODE_HALF_DUPLEX;
00635 REG_WR(bp, BNX2_EMAC_MODE, val);
00636
00637
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
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
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, ®);
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
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
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
00865
00866
00867
00868
00869
00870
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
00941
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
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
00977
00978
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
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
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
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
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
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
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
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
01260
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
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
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
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
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
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
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
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
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
01416 REG_WR_IND(bp, cpu_reg->inst, 0);
01417 REG_WR_IND(bp, cpu_reg->pc, fw->start_addr);
01418
01419
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
01433
01434
01435
01436
01437
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
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
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
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
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
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
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
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
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
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
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
01718 bnx2_enable_nvram_access(bp);
01719
01720
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
01727 bnx2_disable_nvram_access(bp);
01728
01729 break;
01730 }
01731 }
01732 }
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
01759
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
01770 bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1);
01771
01772
01773
01774 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
01775 BNX2_DRV_RESET_SIGNATURE_MAGIC);
01776
01777
01778
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
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
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
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
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
01823
01824 REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
01825
01826
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
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
01894
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
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
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
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);
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
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
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
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
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
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
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
02164
02165
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
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
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
02245
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
02289 bp->flags |= NO_WOL_FLAG;
02290
02291
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
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
02352
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
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);
02378
02379 if (++i > 500) {
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
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
02398 txbd = &bp->tx_desc_ring[ring_prod];
02399 txbd->tx_bd_haddr_hi = 0;
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
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
02431
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
02450
02451
02452
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
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
02479
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
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;
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 if (pdev == 0)
02621 return 0;
02622
02623 memset(bp, 0, sizeof(*bp));
02624
02625 rc = bnx2_init_board(pdev, nic);
02626 if (rc < 0) {
02627 return 0;
02628 }
02629
02630
02631
02632
02633
02634
02635
02636
02637 nic->nic_op = &bnx2_operations;
02638
02639 memcpy(nic->node_addr, bp->mac_addr, ETH_ALEN);
02640 printf("Ethernet addr: %s\n", eth_ntoa( nic->node_addr ) );
02641 printf("Broadcom NetXtreme II (%c%d) PCI%s %s %dMHz\n",
02642 (int) ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
02643 (int) ((CHIP_ID(bp) & 0x0ff0) >> 4),
02644 ((bp->flags & PCIX_FLAG) ? "-X" : ""),
02645 ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
02646 bp->bus_speed_mhz);
02647
02648 bnx2_set_power_state_0(bp);
02649 bnx2_disable_int(bp);
02650
02651 bnx2_alloc_mem(bp);
02652
02653 rc = bnx2_init_nic(bp);
02654 if (rc) {
02655 return 0;
02656 }
02657
02658 bnx2_poll_link(bp);
02659 for(i = 0; !bp->link_up && (i < VALID_LINK_TIMEOUT*100); i++) {
02660 mdelay(1);
02661 bnx2_poll_link(bp);
02662 }
02663 #if 1
02664 if (!bp->link_up){
02665 printf("Valid link not established\n");
02666 goto err_out_disable;
02667 }
02668 #endif
02669
02670 return 1;
02671
02672 err_out_disable:
02673 bnx2_disable(nic);
02674 return 0;
02675 }
02676
02677 static struct pci_device_id bnx2_nics[] = {
02678 PCI_ROM(0x14e4, 0x164a, "bnx2-5706", "Broadcom NetXtreme II BCM5706", 0),
02679 PCI_ROM(0x14e4, 0x164c, "bnx2-5708", "Broadcom NetXtreme II BCM5708", 0),
02680 PCI_ROM(0x14e4, 0x16aa, "bnx2-5706S", "Broadcom NetXtreme II BCM5706S", 0),
02681 PCI_ROM(0x14e4, 0x16ac, "bnx2-5708S", "Broadcom NetXtreme II BCM5708S", 0),
02682 };
02683
02684 PCI_DRIVER ( bnx2_driver, bnx2_nics, PCI_NO_CLASS );
02685
02686 DRIVER ( "BNX2", nic_driver, pci_driver, bnx2_driver, bnx2_probe, bnx2_disable );
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697