Annotation of qemu/roms/ipxe/src/drivers/net/bnx2.c, revision 1.1.1.1

1.1       root        1: /* bnx2.c: Broadcom NX2 network driver.
                      2:  *
                      3:  * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify
                      6:  * it under the terms of the GNU General Public License as published by
                      7:  * the Free Software Foundation.
                      8:  *
                      9:  * Written by: Michael Chan  ([email protected])
                     10:  *
                     11:  * Etherboot port by Ryan Jackson ([email protected]), based on driver
                     12:  * version 1.4.40 from linux 2.6.17
                     13:  */
                     14: 
                     15: FILE_LICENCE ( GPL_ANY );
                     16: 
                     17: #include "etherboot.h"
                     18: #include "nic.h"
                     19: #include <errno.h>
                     20: #include <ipxe/pci.h>
                     21: #include <ipxe/ethernet.h>
                     22: #include "string.h"
                     23: #include <mii.h>
                     24: #include "bnx2.h"
                     25: #include "bnx2_fw.h"
                     26: 
                     27: #if 0
                     28: /* Dummy defines for error handling */
                     29: #define EBUSY  1
                     30: #define ENODEV 2
                     31: #define EINVAL 3
                     32: #define ENOMEM 4
                     33: #define EIO    5
                     34: #endif
                     35: 
                     36: /* The bnx2 seems to be picky about the alignment of the receive buffers
                     37:  * and possibly the status block.
                     38:  */
                     39: static struct bss {
                     40:        struct tx_bd tx_desc_ring[TX_DESC_CNT];
                     41:        struct rx_bd rx_desc_ring[RX_DESC_CNT];
                     42:        unsigned char rx_buf[RX_BUF_CNT][RX_BUF_SIZE];
                     43:        struct status_block status_blk;
                     44:        struct statistics_block stats_blk;
                     45: } bnx2_bss;
                     46: 
                     47: static struct bnx2 bnx2;
                     48: 
                     49: static struct flash_spec flash_table[] =
                     50: {
                     51:        /* Slow EEPROM */
                     52:        {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
                     53:         1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
                     54:         SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
                     55:         "EEPROM - slow"},
                     56:        /* Expansion entry 0001 */
                     57:        {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
                     58:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                     59:         SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
                     60:         "Entry 0001"},
                     61:        /* Saifun SA25F010 (non-buffered flash) */
                     62:        /* strap, cfg1, & write1 need updates */
                     63:        {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
                     64:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                     65:         SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
                     66:         "Non-buffered flash (128kB)"},
                     67:        /* Saifun SA25F020 (non-buffered flash) */
                     68:        /* strap, cfg1, & write1 need updates */
                     69:        {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
                     70:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                     71:         SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
                     72:         "Non-buffered flash (256kB)"},
                     73:        /* Expansion entry 0100 */
                     74:        {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
                     75:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                     76:         SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
                     77:         "Entry 0100"},
                     78:        /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
                     79:        {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,        
                     80:         0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
                     81:         ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
                     82:         "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
                     83:        /* Entry 0110: ST M45PE20 (non-buffered flash)*/
                     84:        {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
                     85:         0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
                     86:         ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
                     87:         "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
                     88:        /* Saifun SA25F005 (non-buffered flash) */
                     89:        /* strap, cfg1, & write1 need updates */
                     90:        {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
                     91:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                     92:         SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
                     93:         "Non-buffered flash (64kB)"},
                     94:        /* Fast EEPROM */
                     95:        {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
                     96:         1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
                     97:         SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
                     98:         "EEPROM - fast"},
                     99:        /* Expansion entry 1001 */
                    100:        {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
                    101:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                    102:         SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
                    103:         "Entry 1001"},
                    104:        /* Expansion entry 1010 */
                    105:        {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
                    106:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                    107:         SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
                    108:         "Entry 1010"},
                    109:        /* ATMEL AT45DB011B (buffered flash) */
                    110:        {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
                    111:         1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
                    112:         BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
                    113:         "Buffered flash (128kB)"},
                    114:        /* Expansion entry 1100 */
                    115:        {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
                    116:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                    117:         SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
                    118:         "Entry 1100"},
                    119:        /* Expansion entry 1101 */
                    120:        {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
                    121:         0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
                    122:         SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
                    123:         "Entry 1101"},
                    124:        /* Ateml Expansion entry 1110 */
                    125:        {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
                    126:         1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
                    127:         BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
                    128:         "Entry 1110 (Atmel)"},
                    129:        /* ATMEL AT45DB021B (buffered flash) */
                    130:        {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
                    131:         1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
                    132:         BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
                    133:         "Buffered flash (256kB)"},
                    134: };
                    135: 
                    136: static u32
                    137: bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
                    138: {
                    139:        REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
                    140:        return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW));
                    141: }
                    142: 
                    143: static void
                    144: bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
                    145: {
                    146:        REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
                    147:        REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
                    148: }
                    149: 
                    150: static void
                    151: bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
                    152: {
                    153:        offset += cid_addr;
                    154:        REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
                    155:        REG_WR(bp, BNX2_CTX_DATA, val);
                    156: }
                    157: 
                    158: static int
                    159: bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
                    160: {
                    161:        u32 val1;
                    162:        int i, ret;
                    163: 
                    164:        if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
                    165:                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    166:                val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
                    167: 
                    168:                REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
                    169:                REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    170: 
                    171:                udelay(40);
                    172:        }
                    173: 
                    174:        val1 = (bp->phy_addr << 21) | (reg << 16) |
                    175:                BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT |
                    176:                BNX2_EMAC_MDIO_COMM_START_BUSY;
                    177:        REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
                    178: 
                    179:        for (i = 0; i < 50; i++) {
                    180:                udelay(10);
                    181: 
                    182:                val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
                    183:                if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
                    184:                        udelay(5);
                    185: 
                    186:                        val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
                    187:                        val1 &= BNX2_EMAC_MDIO_COMM_DATA;
                    188: 
                    189:                        break;
                    190:                }
                    191:        }
                    192: 
                    193:        if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) {
                    194:                *val = 0x0;
                    195:                ret = -EBUSY;
                    196:        }
                    197:        else {
                    198:                *val = val1;
                    199:                ret = 0;
                    200:        }
                    201: 
                    202:        if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
                    203:                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    204:                val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
                    205: 
                    206:                REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
                    207:                REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    208: 
                    209:                udelay(40);
                    210:        }
                    211: 
                    212:        return ret;
                    213: }
                    214: 
                    215: static int
                    216: bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
                    217: {
                    218:        u32 val1;
                    219:        int i, ret;
                    220: 
                    221:        if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
                    222:                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    223:                val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
                    224: 
                    225:                REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
                    226:                REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    227: 
                    228:                udelay(40);
                    229:        }
                    230: 
                    231:        val1 = (bp->phy_addr << 21) | (reg << 16) | val |
                    232:                BNX2_EMAC_MDIO_COMM_COMMAND_WRITE |
                    233:                BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT;
                    234:        REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
                    235:     
                    236:        for (i = 0; i < 50; i++) {
                    237:                udelay(10);
                    238: 
                    239:                val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
                    240:                if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
                    241:                        udelay(5);
                    242:                        break;
                    243:                }
                    244:        }
                    245: 
                    246:        if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)
                    247:                ret = -EBUSY;
                    248:        else
                    249:                ret = 0;
                    250: 
                    251:        if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
                    252:                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    253:                val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
                    254: 
                    255:                REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
                    256:                REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                    257: 
                    258:                udelay(40);
                    259:        }
                    260: 
                    261:        return ret;
                    262: }
                    263: 
                    264: static void
                    265: bnx2_disable_int(struct bnx2 *bp)
                    266: {
                    267:        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                    268:               BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
                    269:        REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
                    270: 
                    271: }
                    272: 
                    273: static int
                    274: bnx2_alloc_mem(struct bnx2 *bp)
                    275: {
                    276:        bp->tx_desc_ring = bnx2_bss.tx_desc_ring;
                    277:        bp->tx_desc_mapping = virt_to_bus(bp->tx_desc_ring);
                    278: 
                    279:        bp->rx_desc_ring = bnx2_bss.rx_desc_ring;
                    280:        memset(bp->rx_desc_ring, 0, sizeof(struct rx_bd) * RX_DESC_CNT);
                    281:        bp->rx_desc_mapping = virt_to_bus(bp->rx_desc_ring);
                    282: 
                    283:        memset(&bnx2_bss.status_blk, 0, sizeof(struct status_block));
                    284:        bp->status_blk = &bnx2_bss.status_blk;
                    285:        bp->status_blk_mapping = virt_to_bus(&bnx2_bss.status_blk);
                    286: 
                    287:        bp->stats_blk = &bnx2_bss.stats_blk;
                    288:        memset(&bnx2_bss.stats_blk, 0, sizeof(struct statistics_block));
                    289:        bp->stats_blk_mapping = virt_to_bus(&bnx2_bss.stats_blk);
                    290: 
                    291:        return 0;
                    292: }
                    293: 
                    294: static void
                    295: bnx2_report_fw_link(struct bnx2 *bp)
                    296: {
                    297:        u32 fw_link_status = 0;
                    298: 
                    299:        if (bp->link_up) {
                    300:                u32 bmsr;
                    301: 
                    302:                switch (bp->line_speed) {
                    303:                case SPEED_10:
                    304:                        if (bp->duplex == DUPLEX_HALF)
                    305:                                fw_link_status = BNX2_LINK_STATUS_10HALF;
                    306:                        else
                    307:                                fw_link_status = BNX2_LINK_STATUS_10FULL;
                    308:                        break;
                    309:                case SPEED_100:
                    310:                        if (bp->duplex == DUPLEX_HALF)
                    311:                                fw_link_status = BNX2_LINK_STATUS_100HALF;
                    312:                        else
                    313:                                fw_link_status = BNX2_LINK_STATUS_100FULL;
                    314:                        break;
                    315:                case SPEED_1000:
                    316:                        if (bp->duplex == DUPLEX_HALF)
                    317:                                fw_link_status = BNX2_LINK_STATUS_1000HALF;
                    318:                        else
                    319:                                fw_link_status = BNX2_LINK_STATUS_1000FULL;
                    320:                        break;
                    321:                case SPEED_2500:
                    322:                        if (bp->duplex == DUPLEX_HALF)
                    323:                                fw_link_status = BNX2_LINK_STATUS_2500HALF;
                    324:                        else
                    325:                                fw_link_status = BNX2_LINK_STATUS_2500FULL;
                    326:                        break;
                    327:                }
                    328: 
                    329:                fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
                    330: 
                    331:                if (bp->autoneg) {
                    332:                        fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
                    333: 
                    334:                        bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    335:                        bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    336: 
                    337:                        if (!(bmsr & BMSR_ANEGCOMPLETE) ||
                    338:                            bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
                    339:                                fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
                    340:                        else
                    341:                                fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
                    342:                }
                    343:        }
                    344:        else
                    345:                fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
                    346: 
                    347:        REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
                    348: }
                    349: 
                    350: static void
                    351: bnx2_report_link(struct bnx2 *bp)
                    352: {
                    353:        if (bp->link_up) {
                    354:                printf("NIC Link is Up, ");
                    355: 
                    356:                printf("%d Mbps ", bp->line_speed);
                    357: 
                    358:                if (bp->duplex == DUPLEX_FULL)
                    359:                        printf("full duplex");
                    360:                else
                    361:                        printf("half duplex");
                    362: 
                    363:                if (bp->flow_ctrl) {
                    364:                        if (bp->flow_ctrl & FLOW_CTRL_RX) {
                    365:                                printf(", receive ");
                    366:                                if (bp->flow_ctrl & FLOW_CTRL_TX)
                    367:                                        printf("& transmit ");
                    368:                        }
                    369:                        else {
                    370:                                printf(", transmit ");
                    371:                        }
                    372:                        printf("flow control ON");
                    373:                }
                    374:                printf("\n");
                    375:        }
                    376:        else {
                    377:                printf("NIC Link is Down\n");
                    378:        }
                    379: 
                    380:        bnx2_report_fw_link(bp);
                    381: }
                    382: 
                    383: static void
                    384: bnx2_resolve_flow_ctrl(struct bnx2 *bp)
                    385: {
                    386:        u32 local_adv, remote_adv;
                    387: 
                    388:        bp->flow_ctrl = 0;
                    389:        if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != 
                    390:                (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) {
                    391: 
                    392:                if (bp->duplex == DUPLEX_FULL) {
                    393:                        bp->flow_ctrl = bp->req_flow_ctrl;
                    394:                }
                    395:                return;
                    396:        }
                    397: 
                    398:        if (bp->duplex != DUPLEX_FULL) {
                    399:                return;
                    400:        }
                    401: 
                    402:        if ((bp->phy_flags & PHY_SERDES_FLAG) &&
                    403:            (CHIP_NUM(bp) == CHIP_NUM_5708)) {
                    404:                u32 val;
                    405: 
                    406:                bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
                    407:                if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
                    408:                        bp->flow_ctrl |= FLOW_CTRL_TX;
                    409:                if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
                    410:                        bp->flow_ctrl |= FLOW_CTRL_RX;
                    411:                return;
                    412:        }
                    413: 
                    414:        bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
                    415:        bnx2_read_phy(bp, MII_LPA, &remote_adv);
                    416: 
                    417:        if (bp->phy_flags & PHY_SERDES_FLAG) {
                    418:                u32 new_local_adv = 0;
                    419:                u32 new_remote_adv = 0;
                    420: 
                    421:                if (local_adv & ADVERTISE_1000XPAUSE)
                    422:                        new_local_adv |= ADVERTISE_PAUSE_CAP;
                    423:                if (local_adv & ADVERTISE_1000XPSE_ASYM)
                    424:                        new_local_adv |= ADVERTISE_PAUSE_ASYM;
                    425:                if (remote_adv & ADVERTISE_1000XPAUSE)
                    426:                        new_remote_adv |= ADVERTISE_PAUSE_CAP;
                    427:                if (remote_adv & ADVERTISE_1000XPSE_ASYM)
                    428:                        new_remote_adv |= ADVERTISE_PAUSE_ASYM;
                    429: 
                    430:                local_adv = new_local_adv;
                    431:                remote_adv = new_remote_adv;
                    432:        }
                    433: 
                    434:        /* See Table 28B-3 of 802.3ab-1999 spec. */
                    435:        if (local_adv & ADVERTISE_PAUSE_CAP) {
                    436:                if(local_adv & ADVERTISE_PAUSE_ASYM) {
                    437:                        if (remote_adv & ADVERTISE_PAUSE_CAP) {
                    438:                                bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
                    439:                        }
                    440:                        else if (remote_adv & ADVERTISE_PAUSE_ASYM) {
                    441:                                bp->flow_ctrl = FLOW_CTRL_RX;
                    442:                        }
                    443:                }
                    444:                else {
                    445:                        if (remote_adv & ADVERTISE_PAUSE_CAP) {
                    446:                                bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
                    447:                        }
                    448:                }
                    449:        }
                    450:        else if (local_adv & ADVERTISE_PAUSE_ASYM) {
                    451:                if ((remote_adv & ADVERTISE_PAUSE_CAP) &&
                    452:                        (remote_adv & ADVERTISE_PAUSE_ASYM)) {
                    453: 
                    454:                        bp->flow_ctrl = FLOW_CTRL_TX;
                    455:                }
                    456:        }
                    457: }
                    458: 
                    459: static int
                    460: bnx2_5708s_linkup(struct bnx2 *bp)
                    461: {
                    462:        u32 val;
                    463: 
                    464:        bp->link_up = 1;
                    465:        bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
                    466:        switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) {
                    467:                case BCM5708S_1000X_STAT1_SPEED_10:
                    468:                        bp->line_speed = SPEED_10;
                    469:                        break;
                    470:                case BCM5708S_1000X_STAT1_SPEED_100:
                    471:                        bp->line_speed = SPEED_100;
                    472:                        break;
                    473:                case BCM5708S_1000X_STAT1_SPEED_1G:
                    474:                        bp->line_speed = SPEED_1000;
                    475:                        break;
                    476:                case BCM5708S_1000X_STAT1_SPEED_2G5:
                    477:                        bp->line_speed = SPEED_2500;
                    478:                        break;
                    479:        }
                    480:        if (val & BCM5708S_1000X_STAT1_FD)
                    481:                bp->duplex = DUPLEX_FULL;
                    482:        else
                    483:                bp->duplex = DUPLEX_HALF;
                    484: 
                    485:        return 0;
                    486: }
                    487: 
                    488: static int
                    489: bnx2_5706s_linkup(struct bnx2 *bp)
                    490: {
                    491:        u32 bmcr, local_adv, remote_adv, common;
                    492: 
                    493:        bp->link_up = 1;
                    494:        bp->line_speed = SPEED_1000;
                    495: 
                    496:        bnx2_read_phy(bp, MII_BMCR, &bmcr);
                    497:        if (bmcr & BMCR_FULLDPLX) {
                    498:                bp->duplex = DUPLEX_FULL;
                    499:        }
                    500:        else {
                    501:                bp->duplex = DUPLEX_HALF;
                    502:        }
                    503: 
                    504:        if (!(bmcr & BMCR_ANENABLE)) {
                    505:                return 0;
                    506:        }
                    507: 
                    508:        bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
                    509:        bnx2_read_phy(bp, MII_LPA, &remote_adv);
                    510: 
                    511:        common = local_adv & remote_adv;
                    512:        if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) {
                    513: 
                    514:                if (common & ADVERTISE_1000XFULL) {
                    515:                        bp->duplex = DUPLEX_FULL;
                    516:                }
                    517:                else {
                    518:                        bp->duplex = DUPLEX_HALF;
                    519:                }
                    520:        }
                    521: 
                    522:        return 0;
                    523: }
                    524: 
                    525: static int
                    526: bnx2_copper_linkup(struct bnx2 *bp)
                    527: {
                    528:        u32 bmcr;
                    529: 
                    530:        bnx2_read_phy(bp, MII_BMCR, &bmcr);
                    531:        if (bmcr & BMCR_ANENABLE) {
                    532:                u32 local_adv, remote_adv, common;
                    533: 
                    534:                bnx2_read_phy(bp, MII_CTRL1000, &local_adv);
                    535:                bnx2_read_phy(bp, MII_STAT1000, &remote_adv);
                    536: 
                    537:                common = local_adv & (remote_adv >> 2);
                    538:                if (common & ADVERTISE_1000FULL) {
                    539:                        bp->line_speed = SPEED_1000;
                    540:                        bp->duplex = DUPLEX_FULL;
                    541:                }
                    542:                else if (common & ADVERTISE_1000HALF) {
                    543:                        bp->line_speed = SPEED_1000;
                    544:                        bp->duplex = DUPLEX_HALF;
                    545:                }
                    546:                else {
                    547:                        bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
                    548:                        bnx2_read_phy(bp, MII_LPA, &remote_adv);
                    549: 
                    550:                        common = local_adv & remote_adv;
                    551:                        if (common & ADVERTISE_100FULL) {
                    552:                                bp->line_speed = SPEED_100;
                    553:                                bp->duplex = DUPLEX_FULL;
                    554:                        }
                    555:                        else if (common & ADVERTISE_100HALF) {
                    556:                                bp->line_speed = SPEED_100;
                    557:                                bp->duplex = DUPLEX_HALF;
                    558:                        }
                    559:                        else if (common & ADVERTISE_10FULL) {
                    560:                                bp->line_speed = SPEED_10;
                    561:                                bp->duplex = DUPLEX_FULL;
                    562:                        }
                    563:                        else if (common & ADVERTISE_10HALF) {
                    564:                                bp->line_speed = SPEED_10;
                    565:                                bp->duplex = DUPLEX_HALF;
                    566:                        }
                    567:                        else {
                    568:                                bp->line_speed = 0;
                    569:                                bp->link_up = 0;
                    570:                        }
                    571:                }
                    572:        }
                    573:        else {
                    574:                if (bmcr & BMCR_SPEED100) {
                    575:                        bp->line_speed = SPEED_100;
                    576:                }
                    577:                else {
                    578:                        bp->line_speed = SPEED_10;
                    579:                }
                    580:                if (bmcr & BMCR_FULLDPLX) {
                    581:                        bp->duplex = DUPLEX_FULL;
                    582:                }
                    583:                else {
                    584:                        bp->duplex = DUPLEX_HALF;
                    585:                }
                    586:        }
                    587: 
                    588:        return 0;
                    589: }
                    590: 
                    591: static int
                    592: bnx2_set_mac_link(struct bnx2 *bp)
                    593: {
                    594:        u32 val;
                    595: 
                    596:        REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620);
                    597:        if (bp->link_up && (bp->line_speed == SPEED_1000) &&
                    598:                (bp->duplex == DUPLEX_HALF)) {
                    599:                REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff);
                    600:        }
                    601: 
                    602:        /* Configure the EMAC mode register. */
                    603:        val = REG_RD(bp, BNX2_EMAC_MODE);
                    604: 
                    605:        val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
                    606:                BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
                    607:                BNX2_EMAC_MODE_25G);
                    608: 
                    609:        if (bp->link_up) {
                    610:                switch (bp->line_speed) {
                    611:                        case SPEED_10:
                    612:                                if (CHIP_NUM(bp) == CHIP_NUM_5708) {
                    613:                                        val |= BNX2_EMAC_MODE_PORT_MII_10;
                    614:                                        break;
                    615:                                }
                    616:                                /* fall through */
                    617:                        case SPEED_100:
                    618:                                val |= BNX2_EMAC_MODE_PORT_MII;
                    619:                                break;
                    620:                        case SPEED_2500:
                    621:                                val |= BNX2_EMAC_MODE_25G;
                    622:                                /* fall through */
                    623:                        case SPEED_1000:
                    624:                                val |= BNX2_EMAC_MODE_PORT_GMII;
                    625:                                break;
                    626:                }
                    627:        }
                    628:        else {
                    629:                val |= BNX2_EMAC_MODE_PORT_GMII;
                    630:        }
                    631: 
                    632:        /* Set the MAC to operate in the appropriate duplex mode. */
                    633:        if (bp->duplex == DUPLEX_HALF)
                    634:                val |= BNX2_EMAC_MODE_HALF_DUPLEX;
                    635:        REG_WR(bp, BNX2_EMAC_MODE, val);
                    636: 
                    637:        /* Enable/disable rx PAUSE. */
                    638:        bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN;
                    639: 
                    640:        if (bp->flow_ctrl & FLOW_CTRL_RX)
                    641:                bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN;
                    642:        REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode);
                    643: 
                    644:        /* Enable/disable tx PAUSE. */
                    645:        val = REG_RD(bp, BNX2_EMAC_TX_MODE);
                    646:        val &= ~BNX2_EMAC_TX_MODE_FLOW_EN;
                    647: 
                    648:        if (bp->flow_ctrl & FLOW_CTRL_TX)
                    649:                val |= BNX2_EMAC_TX_MODE_FLOW_EN;
                    650:        REG_WR(bp, BNX2_EMAC_TX_MODE, val);
                    651: 
                    652:        /* Acknowledge the interrupt. */
                    653:        REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
                    654: 
                    655:        return 0;
                    656: }
                    657: 
                    658: static int
                    659: bnx2_set_link(struct bnx2 *bp)
                    660: {
                    661:        u32 bmsr;
                    662:        u8 link_up;
                    663: 
                    664:        if (bp->loopback == MAC_LOOPBACK) {
                    665:                bp->link_up = 1;
                    666:                return 0;
                    667:        }
                    668: 
                    669:        link_up = bp->link_up;
                    670: 
                    671:        bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    672:        bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    673: 
                    674:        if ((bp->phy_flags & PHY_SERDES_FLAG) &&
                    675:            (CHIP_NUM(bp) == CHIP_NUM_5706)) {
                    676:                u32 val;
                    677: 
                    678:                val = REG_RD(bp, BNX2_EMAC_STATUS);
                    679:                if (val & BNX2_EMAC_STATUS_LINK)
                    680:                        bmsr |= BMSR_LSTATUS;
                    681:                else
                    682:                        bmsr &= ~BMSR_LSTATUS;
                    683:        }
                    684: 
                    685:        if (bmsr & BMSR_LSTATUS) {
                    686:                bp->link_up = 1;
                    687: 
                    688:                if (bp->phy_flags & PHY_SERDES_FLAG) {
                    689:                        if (CHIP_NUM(bp) == CHIP_NUM_5706)
                    690:                                bnx2_5706s_linkup(bp);
                    691:                        else if (CHIP_NUM(bp) == CHIP_NUM_5708)
                    692:                                bnx2_5708s_linkup(bp);
                    693:                }
                    694:                else {
                    695:                        bnx2_copper_linkup(bp);
                    696:                }
                    697:                bnx2_resolve_flow_ctrl(bp);
                    698:        }
                    699:        else {
                    700:                if ((bp->phy_flags & PHY_SERDES_FLAG) &&
                    701:                        (bp->autoneg & AUTONEG_SPEED)) {
                    702: 
                    703:                        u32 bmcr;
                    704: 
                    705:                        bnx2_read_phy(bp, MII_BMCR, &bmcr);
                    706:                        if (!(bmcr & BMCR_ANENABLE)) {
                    707:                                bnx2_write_phy(bp, MII_BMCR, bmcr |
                    708:                                        BMCR_ANENABLE);
                    709:                        }
                    710:                }
                    711:                bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
                    712:                bp->link_up = 0;
                    713:        }
                    714: 
                    715:        if (bp->link_up != link_up) {
                    716:                bnx2_report_link(bp);
                    717:        }
                    718: 
                    719:        bnx2_set_mac_link(bp);
                    720: 
                    721:        return 0;
                    722: }
                    723: 
                    724: static int
                    725: bnx2_reset_phy(struct bnx2 *bp)
                    726: {
                    727:        int i;
                    728:        u32 reg;
                    729: 
                    730:         bnx2_write_phy(bp, MII_BMCR, BMCR_RESET);
                    731: 
                    732: #define PHY_RESET_MAX_WAIT 100
                    733:        for (i = 0; i < PHY_RESET_MAX_WAIT; i++) {
                    734:                udelay(10);
                    735: 
                    736:                bnx2_read_phy(bp, MII_BMCR, &reg);
                    737:                if (!(reg & BMCR_RESET)) {
                    738:                        udelay(20);
                    739:                        break;
                    740:                }
                    741:        }
                    742:        if (i == PHY_RESET_MAX_WAIT) {
                    743:                return -EBUSY;
                    744:        }
                    745:        return 0;
                    746: }
                    747: 
                    748: static u32
                    749: bnx2_phy_get_pause_adv(struct bnx2 *bp)
                    750: {
                    751:        u32 adv = 0;
                    752: 
                    753:        if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) ==
                    754:                (FLOW_CTRL_RX | FLOW_CTRL_TX)) {
                    755: 
                    756:                if (bp->phy_flags & PHY_SERDES_FLAG) {
                    757:                        adv = ADVERTISE_1000XPAUSE;
                    758:                }
                    759:                else {
                    760:                        adv = ADVERTISE_PAUSE_CAP;
                    761:                }
                    762:        }
                    763:        else if (bp->req_flow_ctrl & FLOW_CTRL_TX) {
                    764:                if (bp->phy_flags & PHY_SERDES_FLAG) {
                    765:                        adv = ADVERTISE_1000XPSE_ASYM;
                    766:                }
                    767:                else {
                    768:                        adv = ADVERTISE_PAUSE_ASYM;
                    769:                }
                    770:        }
                    771:        else if (bp->req_flow_ctrl & FLOW_CTRL_RX) {
                    772:                if (bp->phy_flags & PHY_SERDES_FLAG) {
                    773:                        adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
                    774:                }
                    775:                else {
                    776:                        adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
                    777:                }
                    778:        }
                    779:        return adv;
                    780: }
                    781: 
                    782: static int
                    783: bnx2_setup_serdes_phy(struct bnx2 *bp)
                    784: {
                    785:        u32 adv, bmcr, up1;
                    786:        u32 new_adv = 0;
                    787: 
                    788:        if (!(bp->autoneg & AUTONEG_SPEED)) {
                    789:                u32 new_bmcr;
                    790:                int force_link_down = 0;
                    791: 
                    792:                if (CHIP_NUM(bp) == CHIP_NUM_5708) {
                    793:                        bnx2_read_phy(bp, BCM5708S_UP1, &up1);
                    794:                        if (up1 & BCM5708S_UP1_2G5) {
                    795:                                up1 &= ~BCM5708S_UP1_2G5;
                    796:                                bnx2_write_phy(bp, BCM5708S_UP1, up1);
                    797:                                force_link_down = 1;
                    798:                        }
                    799:                }
                    800: 
                    801:                bnx2_read_phy(bp, MII_ADVERTISE, &adv);
                    802:                adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
                    803: 
                    804:                bnx2_read_phy(bp, MII_BMCR, &bmcr);
                    805:                new_bmcr = bmcr & ~BMCR_ANENABLE;
                    806:                new_bmcr |= BMCR_SPEED1000;
                    807:                if (bp->req_duplex == DUPLEX_FULL) {
                    808:                        adv |= ADVERTISE_1000XFULL;
                    809:                        new_bmcr |= BMCR_FULLDPLX;
                    810:                }
                    811:                else {
                    812:                        adv |= ADVERTISE_1000XHALF;
                    813:                        new_bmcr &= ~BMCR_FULLDPLX;
                    814:                }
                    815:                if ((new_bmcr != bmcr) || (force_link_down)) {
                    816:                        /* Force a link down visible on the other side */
                    817:                        if (bp->link_up) {
                    818:                                bnx2_write_phy(bp, MII_ADVERTISE, adv &
                    819:                                               ~(ADVERTISE_1000XFULL |
                    820:                                                 ADVERTISE_1000XHALF));
                    821:                                bnx2_write_phy(bp, MII_BMCR, bmcr |
                    822:                                        BMCR_ANRESTART | BMCR_ANENABLE);
                    823: 
                    824:                                bp->link_up = 0;
                    825:                                bnx2_write_phy(bp, MII_BMCR, new_bmcr);
                    826:                        }
                    827:                        bnx2_write_phy(bp, MII_ADVERTISE, adv);
                    828:                        bnx2_write_phy(bp, MII_BMCR, new_bmcr);
                    829:                }
                    830:                return 0;
                    831:        }
                    832: 
                    833:        if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
                    834:                bnx2_read_phy(bp, BCM5708S_UP1, &up1);
                    835:                up1 |= BCM5708S_UP1_2G5;
                    836:                bnx2_write_phy(bp, BCM5708S_UP1, up1);
                    837:        }
                    838: 
                    839:        if (bp->advertising & ADVERTISED_1000baseT_Full)
                    840:                new_adv |= ADVERTISE_1000XFULL;
                    841: 
                    842:        new_adv |= bnx2_phy_get_pause_adv(bp);
                    843: 
                    844:        bnx2_read_phy(bp, MII_ADVERTISE, &adv);
                    845:        bnx2_read_phy(bp, MII_BMCR, &bmcr);
                    846: 
                    847:        bp->serdes_an_pending = 0;
                    848:        if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) {
                    849:                /* Force a link down visible on the other side */
                    850:                if (bp->link_up) {
                    851:                        int i;
                    852: 
                    853:                        bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
                    854:                        for (i = 0; i < 110; i++) {
                    855:                                udelay(100);
                    856:                        }
                    857:                }
                    858: 
                    859:                bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
                    860:                bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
                    861:                        BMCR_ANENABLE);
                    862: #if 0
                    863:                if (CHIP_NUM(bp) == CHIP_NUM_5706) {
                    864:                        /* Speed up link-up time when the link partner
                    865:                         * does not autonegotiate which is very common
                    866:                         * in blade servers. Some blade servers use
                    867:                         * IPMI for kerboard input and it's important
                    868:                         * to minimize link disruptions. Autoneg. involves
                    869:                         * exchanging base pages plus 3 next pages and
                    870:                         * normally completes in about 120 msec.
                    871:                         */
                    872:                        bp->current_interval = SERDES_AN_TIMEOUT;
                    873:                        bp->serdes_an_pending = 1;
                    874:                        mod_timer(&bp->timer, jiffies + bp->current_interval);
                    875:                }
                    876: #endif
                    877:        }
                    878: 
                    879:        return 0;
                    880: }
                    881: 
                    882: #define ETHTOOL_ALL_FIBRE_SPEED                                                \
                    883:        (ADVERTISED_1000baseT_Full)
                    884: 
                    885: #define ETHTOOL_ALL_COPPER_SPEED                                       \
                    886:        (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |            \
                    887:        ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |           \
                    888:        ADVERTISED_1000baseT_Full)
                    889: 
                    890: #define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \
                    891:        ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA)
                    892:        
                    893: #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
                    894: 
                    895: static int
                    896: bnx2_setup_copper_phy(struct bnx2 *bp)
                    897: {
                    898:        u32 bmcr;
                    899:        u32 new_bmcr;
                    900: 
                    901:        bnx2_read_phy(bp, MII_BMCR, &bmcr);
                    902: 
                    903:        if (bp->autoneg & AUTONEG_SPEED) {
                    904:                u32 adv_reg, adv1000_reg;
                    905:                u32 new_adv_reg = 0;
                    906:                u32 new_adv1000_reg = 0;
                    907: 
                    908:                bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg);
                    909:                adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
                    910:                        ADVERTISE_PAUSE_ASYM);
                    911: 
                    912:                bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
                    913:                adv1000_reg &= PHY_ALL_1000_SPEED;
                    914: 
                    915:                if (bp->advertising & ADVERTISED_10baseT_Half)
                    916:                        new_adv_reg |= ADVERTISE_10HALF;
                    917:                if (bp->advertising & ADVERTISED_10baseT_Full)
                    918:                        new_adv_reg |= ADVERTISE_10FULL;
                    919:                if (bp->advertising & ADVERTISED_100baseT_Half)
                    920:                        new_adv_reg |= ADVERTISE_100HALF;
                    921:                if (bp->advertising & ADVERTISED_100baseT_Full)
                    922:                        new_adv_reg |= ADVERTISE_100FULL;
                    923:                if (bp->advertising & ADVERTISED_1000baseT_Full)
                    924:                        new_adv1000_reg |= ADVERTISE_1000FULL;
                    925:                
                    926:                new_adv_reg |= ADVERTISE_CSMA;
                    927: 
                    928:                new_adv_reg |= bnx2_phy_get_pause_adv(bp);
                    929: 
                    930:                if ((adv1000_reg != new_adv1000_reg) ||
                    931:                        (adv_reg != new_adv_reg) ||
                    932:                        ((bmcr & BMCR_ANENABLE) == 0)) {
                    933: 
                    934:                        bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg);
                    935:                        bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg);
                    936:                        bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART |
                    937:                                BMCR_ANENABLE);
                    938:                }
                    939:                else if (bp->link_up) {
                    940:                        /* Flow ctrl may have changed from auto to forced */
                    941:                        /* or vice-versa. */
                    942: 
                    943:                        bnx2_resolve_flow_ctrl(bp);
                    944:                        bnx2_set_mac_link(bp);
                    945:                }
                    946:                return 0;
                    947:        }
                    948: 
                    949:        new_bmcr = 0;
                    950:        if (bp->req_line_speed == SPEED_100) {
                    951:                new_bmcr |= BMCR_SPEED100;
                    952:        }
                    953:        if (bp->req_duplex == DUPLEX_FULL) {
                    954:                new_bmcr |= BMCR_FULLDPLX;
                    955:        }
                    956:        if (new_bmcr != bmcr) {
                    957:                u32 bmsr;
                    958:                int i = 0;
                    959: 
                    960:                bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    961:                bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    962:                
                    963:                if (bmsr & BMSR_LSTATUS) {
                    964:                        /* Force link down */
                    965:                        bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
                    966:                        do {
                    967:                                udelay(100);
                    968:                                bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    969:                                bnx2_read_phy(bp, MII_BMSR, &bmsr);
                    970:                                i++;
                    971:                        } while ((bmsr & BMSR_LSTATUS) && (i < 620));
                    972:                }
                    973: 
                    974:                bnx2_write_phy(bp, MII_BMCR, new_bmcr);
                    975: 
                    976:                /* Normally, the new speed is setup after the link has
                    977:                 * gone down and up again. In some cases, link will not go
                    978:                 * down so we need to set up the new speed here.
                    979:                 */
                    980:                if (bmsr & BMSR_LSTATUS) {
                    981:                        bp->line_speed = bp->req_line_speed;
                    982:                        bp->duplex = bp->req_duplex;
                    983:                        bnx2_resolve_flow_ctrl(bp);
                    984:                        bnx2_set_mac_link(bp);
                    985:                }
                    986:        }
                    987:        return 0;
                    988: }
                    989: 
                    990: static int
                    991: bnx2_setup_phy(struct bnx2 *bp)
                    992: {
                    993:        if (bp->loopback == MAC_LOOPBACK)
                    994:                return 0;
                    995: 
                    996:        if (bp->phy_flags & PHY_SERDES_FLAG) {
                    997:                return (bnx2_setup_serdes_phy(bp));
                    998:        }
                    999:        else {
                   1000:                return (bnx2_setup_copper_phy(bp));
                   1001:        }
                   1002: }
                   1003: 
                   1004: static int
                   1005: bnx2_init_5708s_phy(struct bnx2 *bp)
                   1006: {
                   1007:        u32 val;
                   1008: 
                   1009:        bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
                   1010:        bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
                   1011:        bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
                   1012: 
                   1013:        bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
                   1014:        val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
                   1015:        bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
                   1016: 
                   1017:        bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
                   1018:        val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
                   1019:        bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
                   1020: 
                   1021:        if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
                   1022:                bnx2_read_phy(bp, BCM5708S_UP1, &val);
                   1023:                val |= BCM5708S_UP1_2G5;
                   1024:                bnx2_write_phy(bp, BCM5708S_UP1, val);
                   1025:        }
                   1026: 
                   1027:        if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
                   1028:            (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
                   1029:            (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
                   1030:                /* increase tx signal amplitude */
                   1031:                bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
                   1032:                               BCM5708S_BLK_ADDR_TX_MISC);
                   1033:                bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
                   1034:                val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
                   1035:                bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
                   1036:                bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
                   1037:        }
                   1038: 
                   1039:        val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
                   1040:              BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
                   1041: 
                   1042:        if (val) {
                   1043:                u32 is_backplane;
                   1044: 
                   1045:                is_backplane = REG_RD_IND(bp, bp->shmem_base +
                   1046:                                          BNX2_SHARED_HW_CFG_CONFIG);
                   1047:                if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
                   1048:                        bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
                   1049:                                       BCM5708S_BLK_ADDR_TX_MISC);
                   1050:                        bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
                   1051:                        bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
                   1052:                                       BCM5708S_BLK_ADDR_DIG);
                   1053:                }
                   1054:        }
                   1055:        return 0;
                   1056: }
                   1057: 
                   1058: static int
                   1059: bnx2_init_5706s_phy(struct bnx2 *bp)
                   1060: {
                   1061:        u32 val;
                   1062: 
                   1063:        bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
                   1064: 
                   1065:        if (CHIP_NUM(bp) == CHIP_NUM_5706) {
                   1066:                REG_WR(bp, BNX2_MISC_UNUSED0, 0x300);
                   1067:        }
                   1068: 
                   1069: 
                   1070:        bnx2_write_phy(bp, 0x18, 0x7);
                   1071:        bnx2_read_phy(bp, 0x18, &val);
                   1072:        bnx2_write_phy(bp, 0x18, val & ~0x4007);
                   1073: 
                   1074:        bnx2_write_phy(bp, 0x1c, 0x6c00);
                   1075:        bnx2_read_phy(bp, 0x1c, &val);
                   1076:        bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00);
                   1077: 
                   1078:        return 0;
                   1079: }
                   1080: 
                   1081: static int
                   1082: bnx2_init_copper_phy(struct bnx2 *bp)
                   1083: {
                   1084:        u32 val;
                   1085: 
                   1086:        bp->phy_flags |= PHY_CRC_FIX_FLAG;
                   1087: 
                   1088:        if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
                   1089:                bnx2_write_phy(bp, 0x18, 0x0c00);
                   1090:                bnx2_write_phy(bp, 0x17, 0x000a);
                   1091:                bnx2_write_phy(bp, 0x15, 0x310b);
                   1092:                bnx2_write_phy(bp, 0x17, 0x201f);
                   1093:                bnx2_write_phy(bp, 0x15, 0x9506);
                   1094:                bnx2_write_phy(bp, 0x17, 0x401f);
                   1095:                bnx2_write_phy(bp, 0x15, 0x14e2);
                   1096:                bnx2_write_phy(bp, 0x18, 0x0400);
                   1097:        }
                   1098: 
                   1099:        bnx2_write_phy(bp, 0x18, 0x7);
                   1100:        bnx2_read_phy(bp, 0x18, &val);
                   1101:        bnx2_write_phy(bp, 0x18, val & ~0x4007);
                   1102: 
                   1103:        bnx2_read_phy(bp, 0x10, &val);
                   1104:        bnx2_write_phy(bp, 0x10, val & ~0x1);
                   1105: 
                   1106:        /* ethernet@wirespeed */
                   1107:        bnx2_write_phy(bp, 0x18, 0x7007);
                   1108:        bnx2_read_phy(bp, 0x18, &val);
                   1109:        bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
                   1110:        return 0;
                   1111: }
                   1112: 
                   1113: static int
                   1114: bnx2_init_phy(struct bnx2 *bp)
                   1115: {
                   1116:        u32 val;
                   1117:        int rc = 0;
                   1118: 
                   1119:        bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG;
                   1120:        bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG;
                   1121: 
                   1122:         REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
                   1123: 
                   1124:        bnx2_reset_phy(bp);
                   1125: 
                   1126:        bnx2_read_phy(bp, MII_PHYSID1, &val);
                   1127:        bp->phy_id = val << 16;
                   1128:        bnx2_read_phy(bp, MII_PHYSID2, &val);
                   1129:        bp->phy_id |= val & 0xffff;
                   1130: 
                   1131:        if (bp->phy_flags & PHY_SERDES_FLAG) {
                   1132:                if (CHIP_NUM(bp) == CHIP_NUM_5706)
                   1133:                        rc = bnx2_init_5706s_phy(bp);
                   1134:                else if (CHIP_NUM(bp) == CHIP_NUM_5708)
                   1135:                        rc = bnx2_init_5708s_phy(bp);
                   1136:        }
                   1137:        else {
                   1138:                rc = bnx2_init_copper_phy(bp);
                   1139:        }
                   1140: 
                   1141:        bnx2_setup_phy(bp);
                   1142: 
                   1143:        return rc;
                   1144: }
                   1145: 
                   1146: static int
                   1147: bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
                   1148: {
                   1149:        int i;
                   1150:        u32 val;
                   1151: 
                   1152:        bp->fw_wr_seq++;
                   1153:        msg_data |= bp->fw_wr_seq;
                   1154: 
                   1155:        REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
                   1156: 
                   1157:        /* wait for an acknowledgement. */
                   1158:        for (i = 0; i < (FW_ACK_TIME_OUT_MS / 50); i++) {
                   1159:                mdelay(50);
                   1160: 
                   1161:                val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
                   1162: 
                   1163:                if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
                   1164:                        break;
                   1165:        }
                   1166:        if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0)
                   1167:                return 0;
                   1168: 
                   1169:        /* If we timed out, inform the firmware that this is the case. */
                   1170:        if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) {
                   1171:                if (!silent)
                   1172:                  printf("fw sync timeout, reset code = %x\n", (unsigned int) msg_data);
                   1173: 
                   1174:                msg_data &= ~BNX2_DRV_MSG_CODE;
                   1175:                msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
                   1176: 
                   1177:                REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
                   1178: 
                   1179:                return -EBUSY;
                   1180:        }
                   1181: 
                   1182:        if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK)
                   1183:                return -EIO;
                   1184: 
                   1185:        return 0;
                   1186: }
                   1187: 
                   1188: static void
                   1189: bnx2_init_context(struct bnx2 *bp)
                   1190: {
                   1191:        u32 vcid;
                   1192: 
                   1193:        vcid = 96;
                   1194:        while (vcid) {
                   1195:                u32 vcid_addr, pcid_addr, offset;
                   1196: 
                   1197:                vcid--;
                   1198: 
                   1199:                if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
                   1200:                        u32 new_vcid;
                   1201: 
                   1202:                        vcid_addr = GET_PCID_ADDR(vcid);
                   1203:                        if (vcid & 0x8) {
                   1204:                                new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7);
                   1205:                        }
                   1206:                        else {
                   1207:                                new_vcid = vcid;
                   1208:                        }
                   1209:                        pcid_addr = GET_PCID_ADDR(new_vcid);
                   1210:                }
                   1211:                else {
                   1212:                        vcid_addr = GET_CID_ADDR(vcid);
                   1213:                        pcid_addr = vcid_addr;
                   1214:                }
                   1215: 
                   1216:                REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
                   1217:                REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
                   1218: 
                   1219:                /* Zero out the context. */
                   1220:                for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
                   1221:                        CTX_WR(bp, 0x00, offset, 0);
                   1222:                }
                   1223: 
                   1224:                REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
                   1225:                REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
                   1226:        }
                   1227: }
                   1228: 
                   1229: static int
                   1230: bnx2_alloc_bad_rbuf(struct bnx2 *bp)
                   1231: {
                   1232:        u16 good_mbuf[512];
                   1233:        u32 good_mbuf_cnt;
                   1234:        u32 val;
                   1235: 
                   1236:        REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
                   1237:                BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
                   1238: 
                   1239:        good_mbuf_cnt = 0;
                   1240: 
                   1241:        /* Allocate a bunch of mbufs and save the good ones in an array. */
                   1242:        val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
                   1243:        while (val & BNX2_RBUF_STATUS1_FREE_COUNT) {
                   1244:                REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ);
                   1245: 
                   1246:                val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC);
                   1247: 
                   1248:                val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE;
                   1249: 
                   1250:                /* The addresses with Bit 9 set are bad memory blocks. */
                   1251:                if (!(val & (1 << 9))) {
                   1252:                        good_mbuf[good_mbuf_cnt] = (u16) val;
                   1253:                        good_mbuf_cnt++;
                   1254:                }
                   1255: 
                   1256:                val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
                   1257:        }
                   1258: 
                   1259:        /* Free the good ones back to the mbuf pool thus discarding
                   1260:         * all the bad ones. */
                   1261:        while (good_mbuf_cnt) {
                   1262:                good_mbuf_cnt--;
                   1263: 
                   1264:                val = good_mbuf[good_mbuf_cnt];
                   1265:                val = (val << 9) | val | 1;
                   1266: 
                   1267:                REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
                   1268:        }
                   1269:        return 0;
                   1270: }
                   1271: 
                   1272: static void
                   1273: bnx2_set_mac_addr(struct bnx2 *bp) 
                   1274: {
                   1275:        u32 val;
                   1276:        u8 *mac_addr = bp->nic->node_addr;
                   1277: 
                   1278:        val = (mac_addr[0] << 8) | mac_addr[1];
                   1279: 
                   1280:        REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val);
                   1281: 
                   1282:        val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 
                   1283:                (mac_addr[4] << 8) | mac_addr[5];
                   1284: 
                   1285:        REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val);
                   1286: }
                   1287: 
                   1288: static void
                   1289: bnx2_set_rx_mode(struct nic *nic __unused)
                   1290: {
                   1291:        struct bnx2 *bp = &bnx2;
                   1292:        u32 rx_mode, sort_mode;
                   1293:        int i;
                   1294: 
                   1295:        rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
                   1296:                                  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
                   1297:        sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
                   1298: 
                   1299:        if (!(bp->flags & ASF_ENABLE_FLAG)) {
                   1300:                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
                   1301:        }
                   1302: 
                   1303:        /* Accept all multicasts */
                   1304:        for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
                   1305:                REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
                   1306:                       0xffffffff);
                   1307:                }
                   1308:        sort_mode |= BNX2_RPM_SORT_USER0_MC_EN;
                   1309: 
                   1310:        if (rx_mode != bp->rx_mode) {
                   1311:                bp->rx_mode = rx_mode;
                   1312:                REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
                   1313:        }
                   1314: 
                   1315:        REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
                   1316:        REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
                   1317:        REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
                   1318: }
                   1319: 
                   1320: static void
                   1321: load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc)
                   1322: {
                   1323:        unsigned int i;
                   1324:        u32 val;
                   1325: 
                   1326: 
                   1327:        for (i = 0; i < rv2p_code_len; i += 8) {
                   1328:                REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code);
                   1329:                rv2p_code++;
                   1330:                REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code);
                   1331:                rv2p_code++;
                   1332: 
                   1333:                if (rv2p_proc == RV2P_PROC1) {
                   1334:                        val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
                   1335:                        REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val);
                   1336:                }
                   1337:                else {
                   1338:                        val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
                   1339:                        REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val);
                   1340:                }
                   1341:        }
                   1342: 
                   1343:        /* Reset the processor, un-stall is done later. */
                   1344:        if (rv2p_proc == RV2P_PROC1) {
                   1345:                REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
                   1346:        }
                   1347:        else {
                   1348:                REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
                   1349:        }
                   1350: }
                   1351: 
                   1352: static void
                   1353: load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                   1354: {
                   1355:        u32 offset;
                   1356:        u32 val;
                   1357: 
                   1358:        /* Halt the CPU. */
                   1359:        val = REG_RD_IND(bp, cpu_reg->mode);
                   1360:        val |= cpu_reg->mode_value_halt;
                   1361:        REG_WR_IND(bp, cpu_reg->mode, val);
                   1362:        REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
                   1363: 
                   1364:        /* Load the Text area. */
                   1365:        offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
                   1366:        if (fw->text) {
                   1367:                unsigned int j;
                   1368: 
                   1369:                for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
                   1370:                        REG_WR_IND(bp, offset, fw->text[j]);
                   1371:                }
                   1372:        }
                   1373: 
                   1374:        /* Load the Data area. */
                   1375:        offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
                   1376:        if (fw->data) {
                   1377:                unsigned int j;
                   1378: 
                   1379:                for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
                   1380:                        REG_WR_IND(bp, offset, fw->data[j]);
                   1381:                }
                   1382:        }
                   1383: 
                   1384:        /* Load the SBSS area. */
                   1385:        offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
                   1386:        if (fw->sbss) {
                   1387:                unsigned int j;
                   1388: 
                   1389:                for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
                   1390:                        REG_WR_IND(bp, offset, fw->sbss[j]);
                   1391:                }
                   1392:        }
                   1393: 
                   1394:        /* Load the BSS area. */
                   1395:        offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
                   1396:        if (fw->bss) {
                   1397:                unsigned int j;
                   1398: 
                   1399:                for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
                   1400:                        REG_WR_IND(bp, offset, fw->bss[j]);
                   1401:                }
                   1402:        }
                   1403: 
                   1404:        /* Load the Read-Only area. */
                   1405:        offset = cpu_reg->spad_base +
                   1406:                (fw->rodata_addr - cpu_reg->mips_view_base);
                   1407:        if (fw->rodata) {
                   1408:                unsigned int j;
                   1409: 
                   1410:                for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
                   1411:                        REG_WR_IND(bp, offset, fw->rodata[j]);
                   1412:                }
                   1413:        }
                   1414: 
                   1415:        /* Clear the pre-fetch instruction. */
                   1416:        REG_WR_IND(bp, cpu_reg->inst, 0);
                   1417:        REG_WR_IND(bp, cpu_reg->pc, fw->start_addr);
                   1418: 
                   1419:        /* Start the CPU. */
                   1420:        val = REG_RD_IND(bp, cpu_reg->mode);
                   1421:        val &= ~cpu_reg->mode_value_halt;
                   1422:        REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
                   1423:        REG_WR_IND(bp, cpu_reg->mode, val);
                   1424: }
                   1425: 
                   1426: static void
                   1427: bnx2_init_cpus(struct bnx2 *bp)
                   1428: {
                   1429:        struct cpu_reg cpu_reg;
                   1430:        struct fw_info fw;
                   1431: 
                   1432:        /* Unfortunately, it looks like we need to load the firmware
                   1433:         * before the card will work properly.  That means this driver
                   1434:         * will be huge by Etherboot standards (approx. 50K compressed).
                   1435:         */
                   1436: 
                   1437:        /* Initialize the RV2P processor. */
                   1438:        load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1);
                   1439:        load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2);
                   1440: 
                   1441:        /* Initialize the RX Processor. */
                   1442:        cpu_reg.mode = BNX2_RXP_CPU_MODE;
                   1443:        cpu_reg.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT;
                   1444:        cpu_reg.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA;
                   1445:        cpu_reg.state = BNX2_RXP_CPU_STATE;
                   1446:        cpu_reg.state_value_clear = 0xffffff;
                   1447:        cpu_reg.gpr0 = BNX2_RXP_CPU_REG_FILE;
                   1448:        cpu_reg.evmask = BNX2_RXP_CPU_EVENT_MASK;
                   1449:        cpu_reg.pc = BNX2_RXP_CPU_PROGRAM_COUNTER;
                   1450:        cpu_reg.inst = BNX2_RXP_CPU_INSTRUCTION;
                   1451:        cpu_reg.bp = BNX2_RXP_CPU_HW_BREAKPOINT;
                   1452:        cpu_reg.spad_base = BNX2_RXP_SCRATCH;
                   1453:        cpu_reg.mips_view_base = 0x8000000;
                   1454: 
                   1455:        fw.ver_major = bnx2_RXP_b06FwReleaseMajor;
                   1456:        fw.ver_minor = bnx2_RXP_b06FwReleaseMinor;
                   1457:        fw.ver_fix = bnx2_RXP_b06FwReleaseFix;
                   1458:        fw.start_addr = bnx2_RXP_b06FwStartAddr;
                   1459: 
                   1460:        fw.text_addr = bnx2_RXP_b06FwTextAddr;
                   1461:        fw.text_len = bnx2_RXP_b06FwTextLen;
                   1462:        fw.text_index = 0;
                   1463:        fw.text = bnx2_RXP_b06FwText;
                   1464: 
                   1465:        fw.data_addr = bnx2_RXP_b06FwDataAddr;
                   1466:        fw.data_len = bnx2_RXP_b06FwDataLen;
                   1467:        fw.data_index = 0;
                   1468:        fw.data = bnx2_RXP_b06FwData;
                   1469: 
                   1470:        fw.sbss_addr = bnx2_RXP_b06FwSbssAddr;
                   1471:        fw.sbss_len = bnx2_RXP_b06FwSbssLen;
                   1472:        fw.sbss_index = 0;
                   1473:        fw.sbss = bnx2_RXP_b06FwSbss;
                   1474: 
                   1475:        fw.bss_addr = bnx2_RXP_b06FwBssAddr;
                   1476:        fw.bss_len = bnx2_RXP_b06FwBssLen;
                   1477:        fw.bss_index = 0;
                   1478:        fw.bss = bnx2_RXP_b06FwBss;
                   1479: 
                   1480:        fw.rodata_addr = bnx2_RXP_b06FwRodataAddr;
                   1481:        fw.rodata_len = bnx2_RXP_b06FwRodataLen;
                   1482:        fw.rodata_index = 0;
                   1483:        fw.rodata = bnx2_RXP_b06FwRodata;
                   1484: 
                   1485:        load_cpu_fw(bp, &cpu_reg, &fw);
                   1486: 
                   1487:        /* Initialize the TX Processor. */
                   1488:        cpu_reg.mode = BNX2_TXP_CPU_MODE;
                   1489:        cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT;
                   1490:        cpu_reg.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA;
                   1491:        cpu_reg.state = BNX2_TXP_CPU_STATE;
                   1492:        cpu_reg.state_value_clear = 0xffffff;
                   1493:        cpu_reg.gpr0 = BNX2_TXP_CPU_REG_FILE;
                   1494:        cpu_reg.evmask = BNX2_TXP_CPU_EVENT_MASK;
                   1495:        cpu_reg.pc = BNX2_TXP_CPU_PROGRAM_COUNTER;
                   1496:        cpu_reg.inst = BNX2_TXP_CPU_INSTRUCTION;
                   1497:        cpu_reg.bp = BNX2_TXP_CPU_HW_BREAKPOINT;
                   1498:        cpu_reg.spad_base = BNX2_TXP_SCRATCH;
                   1499:        cpu_reg.mips_view_base = 0x8000000;
                   1500:     
                   1501:        fw.ver_major = bnx2_TXP_b06FwReleaseMajor;
                   1502:        fw.ver_minor = bnx2_TXP_b06FwReleaseMinor;
                   1503:        fw.ver_fix = bnx2_TXP_b06FwReleaseFix;
                   1504:        fw.start_addr = bnx2_TXP_b06FwStartAddr;
                   1505: 
                   1506:        fw.text_addr = bnx2_TXP_b06FwTextAddr;
                   1507:        fw.text_len = bnx2_TXP_b06FwTextLen;
                   1508:        fw.text_index = 0;
                   1509:        fw.text = bnx2_TXP_b06FwText;
                   1510: 
                   1511:        fw.data_addr = bnx2_TXP_b06FwDataAddr;
                   1512:        fw.data_len = bnx2_TXP_b06FwDataLen;
                   1513:        fw.data_index = 0;
                   1514:        fw.data = bnx2_TXP_b06FwData;
                   1515: 
                   1516:        fw.sbss_addr = bnx2_TXP_b06FwSbssAddr;
                   1517:        fw.sbss_len = bnx2_TXP_b06FwSbssLen;
                   1518:        fw.sbss_index = 0;
                   1519:        fw.sbss = bnx2_TXP_b06FwSbss;
                   1520: 
                   1521:        fw.bss_addr = bnx2_TXP_b06FwBssAddr;
                   1522:        fw.bss_len = bnx2_TXP_b06FwBssLen;
                   1523:        fw.bss_index = 0;
                   1524:        fw.bss = bnx2_TXP_b06FwBss;
                   1525: 
                   1526:        fw.rodata_addr = bnx2_TXP_b06FwRodataAddr;
                   1527:        fw.rodata_len = bnx2_TXP_b06FwRodataLen;
                   1528:        fw.rodata_index = 0;
                   1529:        fw.rodata = bnx2_TXP_b06FwRodata;
                   1530: 
                   1531:        load_cpu_fw(bp, &cpu_reg, &fw);
                   1532: 
                   1533:        /* Initialize the TX Patch-up Processor. */
                   1534:        cpu_reg.mode = BNX2_TPAT_CPU_MODE;
                   1535:        cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT;
                   1536:        cpu_reg.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA;
                   1537:        cpu_reg.state = BNX2_TPAT_CPU_STATE;
                   1538:        cpu_reg.state_value_clear = 0xffffff;
                   1539:        cpu_reg.gpr0 = BNX2_TPAT_CPU_REG_FILE;
                   1540:        cpu_reg.evmask = BNX2_TPAT_CPU_EVENT_MASK;
                   1541:        cpu_reg.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER;
                   1542:        cpu_reg.inst = BNX2_TPAT_CPU_INSTRUCTION;
                   1543:        cpu_reg.bp = BNX2_TPAT_CPU_HW_BREAKPOINT;
                   1544:        cpu_reg.spad_base = BNX2_TPAT_SCRATCH;
                   1545:        cpu_reg.mips_view_base = 0x8000000;
                   1546:     
                   1547:        fw.ver_major = bnx2_TPAT_b06FwReleaseMajor;
                   1548:        fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor;
                   1549:        fw.ver_fix = bnx2_TPAT_b06FwReleaseFix;
                   1550:        fw.start_addr = bnx2_TPAT_b06FwStartAddr;
                   1551: 
                   1552:        fw.text_addr = bnx2_TPAT_b06FwTextAddr;
                   1553:        fw.text_len = bnx2_TPAT_b06FwTextLen;
                   1554:        fw.text_index = 0;
                   1555:        fw.text = bnx2_TPAT_b06FwText;
                   1556: 
                   1557:        fw.data_addr = bnx2_TPAT_b06FwDataAddr;
                   1558:        fw.data_len = bnx2_TPAT_b06FwDataLen;
                   1559:        fw.data_index = 0;
                   1560:        fw.data = bnx2_TPAT_b06FwData;
                   1561: 
                   1562:        fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr;
                   1563:        fw.sbss_len = bnx2_TPAT_b06FwSbssLen;
                   1564:        fw.sbss_index = 0;
                   1565:        fw.sbss = bnx2_TPAT_b06FwSbss;
                   1566: 
                   1567:        fw.bss_addr = bnx2_TPAT_b06FwBssAddr;
                   1568:        fw.bss_len = bnx2_TPAT_b06FwBssLen;
                   1569:        fw.bss_index = 0;
                   1570:        fw.bss = bnx2_TPAT_b06FwBss;
                   1571: 
                   1572:        fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr;
                   1573:        fw.rodata_len = bnx2_TPAT_b06FwRodataLen;
                   1574:        fw.rodata_index = 0;
                   1575:        fw.rodata = bnx2_TPAT_b06FwRodata;
                   1576: 
                   1577:        load_cpu_fw(bp, &cpu_reg, &fw);
                   1578: 
                   1579:        /* Initialize the Completion Processor. */
                   1580:        cpu_reg.mode = BNX2_COM_CPU_MODE;
                   1581:        cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT;
                   1582:        cpu_reg.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA;
                   1583:        cpu_reg.state = BNX2_COM_CPU_STATE;
                   1584:        cpu_reg.state_value_clear = 0xffffff;
                   1585:        cpu_reg.gpr0 = BNX2_COM_CPU_REG_FILE;
                   1586:        cpu_reg.evmask = BNX2_COM_CPU_EVENT_MASK;
                   1587:        cpu_reg.pc = BNX2_COM_CPU_PROGRAM_COUNTER;
                   1588:        cpu_reg.inst = BNX2_COM_CPU_INSTRUCTION;
                   1589:        cpu_reg.bp = BNX2_COM_CPU_HW_BREAKPOINT;
                   1590:        cpu_reg.spad_base = BNX2_COM_SCRATCH;
                   1591:        cpu_reg.mips_view_base = 0x8000000;
                   1592:     
                   1593:        fw.ver_major = bnx2_COM_b06FwReleaseMajor;
                   1594:        fw.ver_minor = bnx2_COM_b06FwReleaseMinor;
                   1595:        fw.ver_fix = bnx2_COM_b06FwReleaseFix;
                   1596:        fw.start_addr = bnx2_COM_b06FwStartAddr;
                   1597: 
                   1598:        fw.text_addr = bnx2_COM_b06FwTextAddr;
                   1599:        fw.text_len = bnx2_COM_b06FwTextLen;
                   1600:        fw.text_index = 0;
                   1601:        fw.text = bnx2_COM_b06FwText;
                   1602: 
                   1603:        fw.data_addr = bnx2_COM_b06FwDataAddr;
                   1604:        fw.data_len = bnx2_COM_b06FwDataLen;
                   1605:        fw.data_index = 0;
                   1606:        fw.data = bnx2_COM_b06FwData;
                   1607: 
                   1608:        fw.sbss_addr = bnx2_COM_b06FwSbssAddr;
                   1609:        fw.sbss_len = bnx2_COM_b06FwSbssLen;
                   1610:        fw.sbss_index = 0;
                   1611:        fw.sbss = bnx2_COM_b06FwSbss;
                   1612: 
                   1613:        fw.bss_addr = bnx2_COM_b06FwBssAddr;
                   1614:        fw.bss_len = bnx2_COM_b06FwBssLen;
                   1615:        fw.bss_index = 0;
                   1616:        fw.bss = bnx2_COM_b06FwBss;
                   1617: 
                   1618:        fw.rodata_addr = bnx2_COM_b06FwRodataAddr;
                   1619:        fw.rodata_len = bnx2_COM_b06FwRodataLen;
                   1620:        fw.rodata_index = 0;
                   1621:        fw.rodata = bnx2_COM_b06FwRodata;
                   1622: 
                   1623:        load_cpu_fw(bp, &cpu_reg, &fw);
                   1624: 
                   1625: }
                   1626: 
                   1627: static int
                   1628: bnx2_set_power_state_0(struct bnx2 *bp)
                   1629: {
                   1630:        u16 pmcsr;
                   1631:        u32 val;
                   1632: 
                   1633:        pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
                   1634: 
                   1635:        pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
                   1636:                (pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
                   1637:                PCI_PM_CTRL_PME_STATUS);
                   1638: 
                   1639:        if (pmcsr & PCI_PM_CTRL_STATE_MASK)
                   1640:                /* delay required during transition out of D3hot */
                   1641:                mdelay(20);
                   1642: 
                   1643:        val = REG_RD(bp, BNX2_EMAC_MODE);
                   1644:        val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD;
                   1645:        val &= ~BNX2_EMAC_MODE_MPKT;
                   1646:        REG_WR(bp, BNX2_EMAC_MODE, val);
                   1647: 
                   1648:        val = REG_RD(bp, BNX2_RPM_CONFIG);
                   1649:        val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
                   1650:        REG_WR(bp, BNX2_RPM_CONFIG, val);
                   1651:                
                   1652:        return 0;
                   1653: }
                   1654: 
                   1655: static void
                   1656: bnx2_enable_nvram_access(struct bnx2 *bp)
                   1657: {
                   1658:        u32 val;
                   1659: 
                   1660:        val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
                   1661:        /* Enable both bits, even on read. */
                   1662:        REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 
                   1663:               val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN);
                   1664: }
                   1665: 
                   1666: static void
                   1667: bnx2_disable_nvram_access(struct bnx2 *bp)
                   1668: {
                   1669:        u32 val;
                   1670: 
                   1671:        val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
                   1672:        /* Disable both bits, even after read. */
                   1673:        REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 
                   1674:                val & ~(BNX2_NVM_ACCESS_ENABLE_EN |
                   1675:                        BNX2_NVM_ACCESS_ENABLE_WR_EN));
                   1676: }
                   1677: 
                   1678: static int
                   1679: bnx2_init_nvram(struct bnx2 *bp)
                   1680: {
                   1681:        u32 val;
                   1682:        int j, entry_count, rc;
                   1683:        struct flash_spec *flash;
                   1684: 
                   1685:        /* Determine the selected interface. */
                   1686:        val = REG_RD(bp, BNX2_NVM_CFG1);
                   1687: 
                   1688:        entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
                   1689: 
                   1690:        rc = 0;
                   1691:        if (val & 0x40000000) {
                   1692:                /* Flash interface has been reconfigured */
                   1693:                for (j = 0, flash = &flash_table[0]; j < entry_count;
                   1694:                     j++, flash++) {
                   1695:                        if ((val & FLASH_BACKUP_STRAP_MASK) ==
                   1696:                            (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
                   1697:                                bp->flash_info = flash;
                   1698:                                break;
                   1699:                        }
                   1700:                }
                   1701:        }
                   1702:        else {
                   1703:                u32 mask;
                   1704:                /* Not yet been reconfigured */
                   1705: 
                   1706:                if (val & (1 << 23))
                   1707:                        mask = FLASH_BACKUP_STRAP_MASK;
                   1708:                else
                   1709:                        mask = FLASH_STRAP_MASK;
                   1710: 
                   1711:                for (j = 0, flash = &flash_table[0]; j < entry_count;
                   1712:                        j++, flash++) {
                   1713: 
                   1714:                        if ((val & mask) == (flash->strapping & mask)) {
                   1715:                                bp->flash_info = flash;
                   1716: 
                   1717:                                /* Enable access to flash interface */
                   1718:                                bnx2_enable_nvram_access(bp);
                   1719: 
                   1720:                                /* Reconfigure the flash interface */
                   1721:                                REG_WR(bp, BNX2_NVM_CFG1, flash->config1);
                   1722:                                REG_WR(bp, BNX2_NVM_CFG2, flash->config2);
                   1723:                                REG_WR(bp, BNX2_NVM_CFG3, flash->config3);
                   1724:                                REG_WR(bp, BNX2_NVM_WRITE1, flash->write1);
                   1725: 
                   1726:                                /* Disable access to flash interface */
                   1727:                                bnx2_disable_nvram_access(bp);
                   1728: 
                   1729:                                break;
                   1730:                        }
                   1731:                }
                   1732:        } /* if (val & 0x40000000) */
                   1733: 
                   1734:        if (j == entry_count) {
                   1735:                bp->flash_info = NULL;
                   1736:                printf("Unknown flash/EEPROM type.\n");
                   1737:                return -ENODEV;
                   1738:        }
                   1739: 
                   1740:        val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2);
                   1741:        val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK;
                   1742:        if (val) {
                   1743:                bp->flash_size = val;
                   1744:        }
                   1745:        else {
                   1746:                bp->flash_size = bp->flash_info->total_size;
                   1747:        }
                   1748: 
                   1749:        return rc;
                   1750: }
                   1751: 
                   1752: static int
                   1753: bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                   1754: {
                   1755:        u32 val;
                   1756:        int i, rc = 0;
                   1757: 
                   1758:        /* Wait for the current PCI transaction to complete before
                   1759:         * issuing a reset. */
                   1760:        REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
                   1761:               BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
                   1762:               BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
                   1763:               BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
                   1764:               BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
                   1765:        val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
                   1766:        udelay(5);
                   1767: 
                   1768: 
                   1769:        /* Wait for the firmware to tell us it is ok to issue a reset. */
                   1770:        bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1);
                   1771: 
                   1772:        /* Deposit a driver reset signature so the firmware knows that
                   1773:         * this is a soft reset. */
                   1774:        REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
                   1775:                   BNX2_DRV_RESET_SIGNATURE_MAGIC);
                   1776: 
                   1777:        /* Do a dummy read to force the chip to complete all current transaction
                   1778:         * before we issue a reset. */
                   1779:        val = REG_RD(bp, BNX2_MISC_ID);
                   1780: 
                   1781:        val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
                   1782:              BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
                   1783:              BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
                   1784: 
                   1785:        /* Chip reset. */
                   1786:        REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
                   1787: 
                   1788:        if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
                   1789:            (CHIP_ID(bp) == CHIP_ID_5706_A1))
                   1790:                mdelay(15);
                   1791: 
                   1792:        /* Reset takes approximate 30 usec */
                   1793:        for (i = 0; i < 10; i++) {
                   1794:                val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
                   1795:                if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
                   1796:                            BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
                   1797:                        break;
                   1798:                }
                   1799:                udelay(10);
                   1800:        }
                   1801: 
                   1802:        if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
                   1803:                   BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
                   1804:                printf("Chip reset did not complete\n");
                   1805:                return -EBUSY;
                   1806:        }
                   1807: 
                   1808:        /* Make sure byte swapping is properly configured. */
                   1809:        val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0);
                   1810:        if (val != 0x01020304) {
                   1811:                printf("Chip not in correct endian mode\n");
                   1812:                return -ENODEV;
                   1813:        }
                   1814: 
                   1815:        /* Wait for the firmware to finish its initialization. */
                   1816:        rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0);
                   1817:        if (rc) {
                   1818:                return rc;
                   1819:        }
                   1820: 
                   1821:        if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
                   1822:                /* Adjust the voltage regular to two steps lower.  The default
                   1823:                 * of this register is 0x0000000e. */
                   1824:                REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
                   1825: 
                   1826:                /* Remove bad rbuf memory from the free pool. */
                   1827:                rc = bnx2_alloc_bad_rbuf(bp);
                   1828:        }
                   1829: 
                   1830:        return rc;
                   1831: }
                   1832: 
                   1833: static void
                   1834: bnx2_disable(struct nic *nic __unused)
                   1835: {
                   1836:        struct bnx2* bp = &bnx2;
                   1837: 
                   1838:        if (bp->regview) {
                   1839:                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_UNLOAD);
                   1840:                iounmap(bp->regview);
                   1841:        }
                   1842: }
                   1843: 
                   1844: static int
                   1845: bnx2_init_chip(struct bnx2 *bp)
                   1846: {
                   1847:        u32 val;
                   1848:        int rc;
                   1849: 
                   1850:        /* Make sure the interrupt is not active. */
                   1851:        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
                   1852: 
                   1853:        val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP |
                   1854:              BNX2_DMA_CONFIG_DATA_WORD_SWAP |
                   1855: #if __BYTE_ORDER ==  __BIG_ENDIAN
                   1856:              BNX2_DMA_CONFIG_CNTL_BYTE_SWAP | 
                   1857: #endif
                   1858:              BNX2_DMA_CONFIG_CNTL_WORD_SWAP | 
                   1859:              DMA_READ_CHANS << 12 |
                   1860:              DMA_WRITE_CHANS << 16;
                   1861: 
                   1862:        val |= (0x2 << 20) | (1 << 11);
                   1863: 
                   1864:        if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133))
                   1865:                val |= (1 << 23);
                   1866: 
                   1867:        if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
                   1868:            (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG))
                   1869:                val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
                   1870: 
                   1871:        REG_WR(bp, BNX2_DMA_CONFIG, val);
                   1872: 
                   1873:        if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
                   1874:                val = REG_RD(bp, BNX2_TDMA_CONFIG);
                   1875:                val |= BNX2_TDMA_CONFIG_ONE_DMA;
                   1876:                REG_WR(bp, BNX2_TDMA_CONFIG, val);
                   1877:        }
                   1878: 
                   1879:        if (bp->flags & PCIX_FLAG) {
                   1880:                u16 val16;
                   1881: 
                   1882:                pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
                   1883:                                     &val16);
                   1884:                pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
                   1885:                                      val16 & ~PCI_X_CMD_ERO);
                   1886:        }
                   1887: 
                   1888:        REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
                   1889:               BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
                   1890:               BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
                   1891:               BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
                   1892: 
                   1893:        /* Initialize context mapping and zero out the quick contexts.  The
                   1894:         * context block must have already been enabled. */
                   1895:        bnx2_init_context(bp);
                   1896: 
                   1897:        bnx2_init_nvram(bp);
                   1898:        bnx2_init_cpus(bp);
                   1899: 
                   1900:        bnx2_set_mac_addr(bp);
                   1901: 
                   1902:        val = REG_RD(bp, BNX2_MQ_CONFIG);
                   1903:        val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
                   1904:        val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
                   1905:        REG_WR(bp, BNX2_MQ_CONFIG, val);
                   1906: 
                   1907:        val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
                   1908:        REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
                   1909:        REG_WR(bp, BNX2_MQ_KNL_WIND_END, val);
                   1910: 
                   1911:        val = (BCM_PAGE_BITS - 8) << 24;
                   1912:        REG_WR(bp, BNX2_RV2P_CONFIG, val);
                   1913: 
                   1914:        /* Configure page size. */
                   1915:        val = REG_RD(bp, BNX2_TBDR_CONFIG);
                   1916:        val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE;
                   1917:        val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
                   1918:        REG_WR(bp, BNX2_TBDR_CONFIG, val);
                   1919: 
                   1920:        val = bp->mac_addr[0] +
                   1921:              (bp->mac_addr[1] << 8) +
                   1922:              (bp->mac_addr[2] << 16) +
                   1923:              bp->mac_addr[3] +
                   1924:              (bp->mac_addr[4] << 8) +
                   1925:              (bp->mac_addr[5] << 16);
                   1926:        REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
                   1927: 
                   1928:        /* Program the MTU.  Also include 4 bytes for CRC32. */
                   1929:        val = ETH_MAX_MTU + ETH_HLEN + 4;
                   1930:        if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
                   1931:                val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
                   1932:        REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
                   1933: 
                   1934:        bp->last_status_idx = 0;
                   1935:        bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
                   1936: 
                   1937:        /* Set up how to generate a link change interrupt. */
                   1938:        REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
                   1939: 
                   1940:        REG_WR(bp, BNX2_HC_STATUS_ADDR_L,
                   1941:               (u64) bp->status_blk_mapping & 0xffffffff);
                   1942:        REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
                   1943: 
                   1944:        REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
                   1945:               (u64) bp->stats_blk_mapping & 0xffffffff);
                   1946:        REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H,
                   1947:               (u64) bp->stats_blk_mapping >> 32);
                   1948: 
                   1949:        REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP, 
                   1950:               (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip);
                   1951: 
                   1952:        REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP,
                   1953:               (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip);
                   1954: 
                   1955:        REG_WR(bp, BNX2_HC_COMP_PROD_TRIP,
                   1956:               (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip);
                   1957: 
                   1958:        REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks);
                   1959: 
                   1960:        REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks);
                   1961: 
                   1962:        REG_WR(bp, BNX2_HC_COM_TICKS,
                   1963:               (bp->com_ticks_int << 16) | bp->com_ticks);
                   1964: 
                   1965:        REG_WR(bp, BNX2_HC_CMD_TICKS,
                   1966:               (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
                   1967: 
                   1968:        REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
                   1969:        REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
                   1970: 
                   1971:        if (CHIP_ID(bp) == CHIP_ID_5706_A1)
                   1972:                REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS);
                   1973:        else {
                   1974:                REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE |
                   1975:                       BNX2_HC_CONFIG_TX_TMR_MODE |
                   1976:                       BNX2_HC_CONFIG_COLLECT_STATS);
                   1977:        }
                   1978: 
                   1979:        /* Clear internal stats counters. */
                   1980:        REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
                   1981: 
                   1982:        REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
                   1983: 
                   1984:        if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) &
                   1985:            BNX2_PORT_FEATURE_ASF_ENABLED)
                   1986:                bp->flags |= ASF_ENABLE_FLAG;
                   1987: 
                   1988:        /* Initialize the receive filter. */
                   1989:        bnx2_set_rx_mode(bp->nic);
                   1990: 
                   1991:        rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
                   1992:                          0);
                   1993: 
                   1994:        REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
                   1995:        REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
                   1996: 
                   1997:        udelay(20);
                   1998: 
                   1999:        bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);
                   2000: 
                   2001:        return rc;
                   2002: }
                   2003: 
                   2004: static void
                   2005: bnx2_init_tx_ring(struct bnx2 *bp)
                   2006: {
                   2007:        struct tx_bd *txbd;
                   2008:        u32 val;
                   2009: 
                   2010:        txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT];
                   2011:                
                   2012:        /* Etherboot lives below 4GB, so hi is always 0 */
                   2013:        txbd->tx_bd_haddr_hi = 0;
                   2014:        txbd->tx_bd_haddr_lo = bp->tx_desc_mapping;
                   2015: 
                   2016:        bp->tx_prod = 0;
                   2017:        bp->tx_cons = 0;
                   2018:        bp->hw_tx_cons = 0;
                   2019:        bp->tx_prod_bseq = 0;
                   2020:        
                   2021:        val = BNX2_L2CTX_TYPE_TYPE_L2;
                   2022:        val |= BNX2_L2CTX_TYPE_SIZE_L2;
                   2023:        CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val);
                   2024: 
                   2025:        val = BNX2_L2CTX_CMD_TYPE_TYPE_L2;
                   2026:        val |= 8 << 16;
                   2027:        CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val);
                   2028: 
                   2029:        /* Etherboot lives below 4GB, so hi is always 0 */
                   2030:        CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, 0);
                   2031: 
                   2032:        val = (u64) bp->tx_desc_mapping & 0xffffffff;
                   2033:        CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val);
                   2034: }
                   2035: 
                   2036: static void
                   2037: bnx2_init_rx_ring(struct bnx2 *bp)
                   2038: {
                   2039:        struct rx_bd *rxbd;
                   2040:        unsigned int i;
                   2041:        u16 prod, ring_prod;
                   2042:        u32 val;
                   2043: 
                   2044:        bp->rx_buf_use_size = RX_BUF_USE_SIZE;
                   2045:        bp->rx_buf_size = RX_BUF_SIZE;
                   2046: 
                   2047:        ring_prod = prod = bp->rx_prod = 0;
                   2048:        bp->rx_cons = 0;
                   2049:        bp->hw_rx_cons = 0;
                   2050:        bp->rx_prod_bseq = 0;
                   2051: 
                   2052:        memset(bnx2_bss.rx_buf, 0, sizeof(bnx2_bss.rx_buf));
                   2053:                
                   2054:        rxbd = &bp->rx_desc_ring[0];
                   2055:        for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) {
                   2056:                rxbd->rx_bd_len = bp->rx_buf_use_size;
                   2057:                rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
                   2058:        }
                   2059:        rxbd->rx_bd_haddr_hi = 0;
                   2060:        rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff;
                   2061: 
                   2062:        val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
                   2063:        val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
                   2064:        val |= 0x02 << 8;
                   2065:        CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val);
                   2066: 
                   2067:        /* Etherboot doesn't use memory above 4GB, so this is always 0 */
                   2068:        CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, 0);
                   2069: 
                   2070:        val = bp->rx_desc_mapping & 0xffffffff;
                   2071:        CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val);
                   2072: 
                   2073:        for (i = 0; (int) i < bp->rx_ring_size; i++) {
                   2074:                rxbd = &bp->rx_desc_ring[RX_RING_IDX(ring_prod)];
                   2075:                rxbd->rx_bd_haddr_hi = 0;
                   2076:                rxbd->rx_bd_haddr_lo = virt_to_bus(&bnx2_bss.rx_buf[ring_prod][0]);
                   2077:                bp->rx_prod_bseq += bp->rx_buf_use_size;
                   2078:                prod = NEXT_RX_BD(prod);
                   2079:                ring_prod = RX_RING_IDX(prod);
                   2080:        }
                   2081:        bp->rx_prod = prod;
                   2082: 
                   2083:        REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod);
                   2084: 
                   2085:        REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
                   2086: }
                   2087: 
                   2088: static int
                   2089: bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
                   2090: {
                   2091:        int rc;
                   2092: 
                   2093:        rc = bnx2_reset_chip(bp, reset_code);
                   2094:        if (rc) {
                   2095:                return rc;
                   2096:        }
                   2097: 
                   2098:        bnx2_init_chip(bp);
                   2099:        bnx2_init_tx_ring(bp);
                   2100:        bnx2_init_rx_ring(bp);
                   2101:        return 0;
                   2102: }
                   2103: 
                   2104: static int
                   2105: bnx2_init_nic(struct bnx2 *bp)
                   2106: {
                   2107:        int rc;
                   2108: 
                   2109:        if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
                   2110:                return rc;
                   2111: 
                   2112:        bnx2_init_phy(bp);
                   2113:        bnx2_set_link(bp);
                   2114:        return 0;
                   2115: }
                   2116: 
                   2117: static int
                   2118: bnx2_init_board(struct pci_device *pdev, struct nic *nic)
                   2119: {
                   2120:        unsigned long bnx2reg_base, bnx2reg_len;
                   2121:        struct bnx2 *bp = &bnx2;
                   2122:        int rc;
                   2123:        u32 reg;
                   2124: 
                   2125:        bp->flags = 0;
                   2126:        bp->phy_flags = 0;
                   2127: 
                   2128:        /* enable device (incl. PCI PM wakeup), and bus-mastering */
                   2129:        adjust_pci_device(pdev);
                   2130: 
                   2131:        nic->ioaddr = pdev->ioaddr & ~3;
                   2132:        nic->irqno = 0;
                   2133: 
                   2134:        rc = 0;
                   2135:        bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
                   2136:        if (bp->pm_cap == 0) {
                   2137:                printf("Cannot find power management capability, aborting.\n");
                   2138:                rc = -EIO;
                   2139:                goto err_out_disable;
                   2140:        }
                   2141: 
                   2142:        bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
                   2143:        if (bp->pcix_cap == 0) {
                   2144:                printf("Cannot find PCIX capability, aborting.\n");
                   2145:                rc = -EIO;
                   2146:                goto err_out_disable;
                   2147:        }
                   2148: 
                   2149:        bp->pdev = pdev;
                   2150:        bp->nic = nic;
                   2151: 
                   2152:        bnx2reg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
                   2153:        bnx2reg_len = MB_GET_CID_ADDR(17);
                   2154: 
                   2155:        bp->regview = ioremap(bnx2reg_base, bnx2reg_len);
                   2156: 
                   2157:        if (!bp->regview) {
                   2158:                printf("Cannot map register space, aborting.\n");
                   2159:                rc = -EIO;
                   2160:                goto err_out_disable;
                   2161:        }
                   2162: 
                   2163:        /* Configure byte swap and enable write to the reg_window registers.
                   2164:         * Rely on CPU to do target byte swapping on big endian systems
                   2165:         * The chip's target access swapping will not swap all accesses
                   2166:         */
                   2167:        pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
                   2168:                               BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
                   2169:                               BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
                   2170: 
                   2171:        bnx2_set_power_state_0(bp);
                   2172: 
                   2173:        bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
                   2174: 
                   2175:        /* Get bus information. */
                   2176:        reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
                   2177:        if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
                   2178:                u32 clkreg;
                   2179: 
                   2180:                bp->flags |= PCIX_FLAG;
                   2181: 
                   2182:                clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
                   2183:                
                   2184:                clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
                   2185:                switch (clkreg) {
                   2186:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
                   2187:                        bp->bus_speed_mhz = 133;
                   2188:                        break;
                   2189: 
                   2190:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
                   2191:                        bp->bus_speed_mhz = 100;
                   2192:                        break;
                   2193: 
                   2194:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
                   2195:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
                   2196:                        bp->bus_speed_mhz = 66;
                   2197:                        break;
                   2198: 
                   2199:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
                   2200:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
                   2201:                        bp->bus_speed_mhz = 50;
                   2202:                        break;
                   2203: 
                   2204:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
                   2205:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
                   2206:                case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
                   2207:                        bp->bus_speed_mhz = 33;
                   2208:                        break;
                   2209:                }
                   2210:        }
                   2211:        else {
                   2212:                if (reg & BNX2_PCICFG_MISC_STATUS_M66EN)
                   2213:                        bp->bus_speed_mhz = 66;
                   2214:                else
                   2215:                        bp->bus_speed_mhz = 33;
                   2216:        }
                   2217: 
                   2218:        if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET)
                   2219:                bp->flags |= PCI_32BIT_FLAG;
                   2220: 
                   2221:        /* 5706A0 may falsely detect SERR and PERR. */
                   2222:        if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
                   2223:                reg = REG_RD(bp, PCI_COMMAND);
                   2224:                reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
                   2225:                REG_WR(bp, PCI_COMMAND, reg);
                   2226:        }
                   2227:        else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
                   2228:                !(bp->flags & PCIX_FLAG)) {
                   2229: 
                   2230:                printf("5706 A1 can only be used in a PCIX bus, aborting.\n");
                   2231:                goto err_out_disable;
                   2232:        }
                   2233: 
                   2234:        bnx2_init_nvram(bp);
                   2235: 
                   2236:        reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
                   2237: 
                   2238:        if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
                   2239:            BNX2_SHM_HDR_SIGNATURE_SIG)
                   2240:                bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
                   2241:        else
                   2242:                bp->shmem_base = HOST_VIEW_SHMEM_BASE;
                   2243: 
                   2244:        /* Get the permanent MAC address.  First we need to make sure the
                   2245:         * firmware is actually running.
                   2246:         */
                   2247:        reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
                   2248: 
                   2249:        if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
                   2250:            BNX2_DEV_INFO_SIGNATURE_MAGIC) {
                   2251:                printf("Firmware not running, aborting.\n");
                   2252:                rc = -ENODEV;
                   2253:                goto err_out_disable;
                   2254:        }
                   2255: 
                   2256:        bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
                   2257: 
                   2258:        reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
                   2259:        bp->mac_addr[0] = (u8) (reg >> 8);
                   2260:        bp->mac_addr[1] = (u8) reg;
                   2261: 
                   2262:        reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
                   2263:        bp->mac_addr[2] = (u8) (reg >> 24);
                   2264:        bp->mac_addr[3] = (u8) (reg >> 16);
                   2265:        bp->mac_addr[4] = (u8) (reg >> 8);
                   2266:        bp->mac_addr[5] = (u8) reg;
                   2267: 
                   2268:        bp->tx_ring_size = MAX_TX_DESC_CNT;
                   2269:        bp->rx_ring_size = RX_BUF_CNT;
                   2270:        bp->rx_max_ring_idx = MAX_RX_DESC_CNT;
                   2271: 
                   2272:        bp->rx_offset = RX_OFFSET;
                   2273: 
                   2274:        bp->tx_quick_cons_trip_int = 20;
                   2275:        bp->tx_quick_cons_trip = 20;
                   2276:        bp->tx_ticks_int = 80;
                   2277:        bp->tx_ticks = 80;
                   2278:                
                   2279:        bp->rx_quick_cons_trip_int = 6;
                   2280:        bp->rx_quick_cons_trip = 6;
                   2281:        bp->rx_ticks_int = 18;
                   2282:        bp->rx_ticks = 18;
                   2283: 
                   2284:        bp->stats_ticks = 1000000 & 0xffff00;
                   2285: 
                   2286:        bp->phy_addr = 1;
                   2287: 
                   2288:        /* No need for WOL support in Etherboot */
                   2289:        bp->flags |= NO_WOL_FLAG;
                   2290: 
                   2291:        /* Disable WOL support if we are running on a SERDES chip. */
                   2292:        if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
                   2293:                bp->phy_flags |= PHY_SERDES_FLAG;
                   2294:                if (CHIP_NUM(bp) == CHIP_NUM_5708) {
                   2295:                        bp->phy_addr = 2;
                   2296:                        reg = REG_RD_IND(bp, bp->shmem_base +
                   2297:                                         BNX2_SHARED_HW_CFG_CONFIG);
                   2298:                        if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
                   2299:                                bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
                   2300:                }
                   2301:        }
                   2302: 
                   2303:        if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
                   2304:                bp->tx_quick_cons_trip_int =
                   2305:                        bp->tx_quick_cons_trip;
                   2306:                bp->tx_ticks_int = bp->tx_ticks;
                   2307:                bp->rx_quick_cons_trip_int =
                   2308:                        bp->rx_quick_cons_trip;
                   2309:                bp->rx_ticks_int = bp->rx_ticks;
                   2310:                bp->comp_prod_trip_int = bp->comp_prod_trip;
                   2311:                bp->com_ticks_int = bp->com_ticks;
                   2312:                bp->cmd_ticks_int = bp->cmd_ticks;
                   2313:        }
                   2314: 
                   2315:        bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
                   2316:        bp->req_line_speed = 0;
                   2317:        if (bp->phy_flags & PHY_SERDES_FLAG) {
                   2318:                bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
                   2319: 
                   2320:                reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
                   2321:                reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
                   2322:                if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
                   2323:                        bp->autoneg = 0;
                   2324:                        bp->req_line_speed = bp->line_speed = SPEED_1000;
                   2325:                        bp->req_duplex = DUPLEX_FULL;
                   2326:                }
                   2327:        }
                   2328:        else {
                   2329:                bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
                   2330:        }
                   2331: 
                   2332:        bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
                   2333: 
                   2334:        /* Disable driver heartbeat checking */
                   2335:        REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB,
                   2336:                        BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE);
                   2337:        REG_RD_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB);
                   2338: 
                   2339:        return 0;
                   2340: 
                   2341: err_out_disable:
                   2342:        bnx2_disable(nic);
                   2343: 
                   2344:        return rc;
                   2345: }
                   2346: 
                   2347: static void
                   2348: bnx2_transmit(struct nic *nic, const char *dst_addr,
                   2349:                unsigned int type, unsigned int size, const char *packet)
                   2350: {
                   2351:        /* Sometimes the nic will be behind by a frame.  Using two transmit
                   2352:         * buffers prevents us from timing out in that case.
                   2353:         */
                   2354:        static struct eth_frame {
                   2355:                uint8_t  dst_addr[ETH_ALEN];
                   2356:                uint8_t  src_addr[ETH_ALEN];
                   2357:                uint16_t type;
                   2358:                uint8_t  data [ETH_FRAME_LEN - ETH_HLEN];
                   2359:        } frame[2];
                   2360:        static int frame_idx = 0;
                   2361:        
                   2362:        /* send the packet to destination */
                   2363:        struct tx_bd *txbd;
                   2364:        struct bnx2 *bp = &bnx2;
                   2365:        u16 prod, ring_prod;
                   2366:        u16 hw_cons;
                   2367:        int i = 0;
                   2368: 
                   2369:        prod = bp->tx_prod;
                   2370:        ring_prod = TX_RING_IDX(prod);
                   2371:        hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
                   2372:        if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
                   2373:                hw_cons++;
                   2374:        }
                   2375: 
                   2376:        while((hw_cons != prod) && (hw_cons != (PREV_TX_BD(prod)))) {
                   2377:                mdelay(10);     /* give the nic a chance */
                   2378:                //poll_interruptions();
                   2379:                if (++i > 500) { /* timeout 5s for transmit */
                   2380:                        printf("transmit timed out\n");
                   2381:                        bnx2_disable(bp->nic);
                   2382:                        bnx2_init_board(bp->pdev, bp->nic);
                   2383:                        return;
                   2384:                }
                   2385:        }
                   2386:        if (i != 0) {
                   2387:                printf("#");
                   2388:        }
                   2389: 
                   2390:        /* Copy the packet to the our local buffer */
                   2391:        memcpy(&frame[frame_idx].dst_addr, dst_addr, ETH_ALEN);
                   2392:        memcpy(&frame[frame_idx].src_addr, nic->node_addr, ETH_ALEN);
                   2393:        frame[frame_idx].type = htons(type);
                   2394:        memset(&frame[frame_idx].data, 0, sizeof(frame[frame_idx].data));
                   2395:        memcpy(&frame[frame_idx].data, packet, size);
                   2396: 
                   2397:        /* Setup the ring buffer entry to transmit */
                   2398:        txbd = &bp->tx_desc_ring[ring_prod];
                   2399:        txbd->tx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */
                   2400:        txbd->tx_bd_haddr_lo = virt_to_bus(&frame[frame_idx]);
                   2401:        txbd->tx_bd_mss_nbytes = (size + ETH_HLEN);
                   2402:        txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
                   2403: 
                   2404:        /* Advance to the next entry */
                   2405:        prod = NEXT_TX_BD(prod);
                   2406:        frame_idx ^= 1;
                   2407: 
                   2408:        bp->tx_prod_bseq += (size + ETH_HLEN);
                   2409: 
                   2410:        REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
                   2411:        REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
                   2412: 
                   2413:        wmb();
                   2414: 
                   2415:        bp->tx_prod = prod;
                   2416: }
                   2417: 
                   2418: static int
                   2419: bnx2_poll_link(struct bnx2 *bp)
                   2420: {
                   2421:        u32 new_link_state, old_link_state, emac_status;
                   2422: 
                   2423:        new_link_state = bp->status_blk->status_attn_bits &
                   2424:                STATUS_ATTN_BITS_LINK_STATE;
                   2425: 
                   2426:        old_link_state = bp->status_blk->status_attn_bits_ack &
                   2427:                STATUS_ATTN_BITS_LINK_STATE;
                   2428: 
                   2429:        if (!new_link_state && !old_link_state) {
                   2430:                /* For some reason the card doesn't always update the link
                   2431:                 * status bits properly.  Kick the stupid thing and try again.
                   2432:                 */
                   2433:                u32 bmsr;
                   2434: 
                   2435:                bnx2_read_phy(bp, MII_BMSR, &bmsr);
                   2436:                bnx2_read_phy(bp, MII_BMSR, &bmsr);
                   2437: 
                   2438:                if ((bp->phy_flags & PHY_SERDES_FLAG) &&
                   2439:                    (CHIP_NUM(bp) == CHIP_NUM_5706)) {
                   2440:                        REG_RD(bp, BNX2_EMAC_STATUS);
                   2441:                }
                   2442: 
                   2443:                new_link_state = bp->status_blk->status_attn_bits &
                   2444:                        STATUS_ATTN_BITS_LINK_STATE;
                   2445: 
                   2446:                old_link_state = bp->status_blk->status_attn_bits_ack &
                   2447:                        STATUS_ATTN_BITS_LINK_STATE;
                   2448: 
                   2449:                /* Okay, for some reason the above doesn't work with some
                   2450:                 * switches (like HP ProCurve). If the above doesn't work,
                   2451:                 * check the MAC directly to see if we have a link.  Perhaps we
                   2452:                 * should always check the MAC instead probing the MII.
                   2453:                 */
                   2454:                if (!new_link_state && !old_link_state) {
                   2455:                        emac_status = REG_RD(bp, BNX2_EMAC_STATUS);
                   2456:                        if (emac_status & BNX2_EMAC_STATUS_LINK_CHANGE) {
                   2457:                                /* Acknowledge the link change */
                   2458:                                REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
                   2459:                        } else if (emac_status & BNX2_EMAC_STATUS_LINK) {
                   2460:                                new_link_state = !old_link_state;
                   2461:                        }
                   2462:                }
                   2463: 
                   2464:        }
                   2465: 
                   2466:        if (new_link_state != old_link_state) {
                   2467:                if (new_link_state) {
                   2468:                        REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD,
                   2469:                                STATUS_ATTN_BITS_LINK_STATE);
                   2470:                }
                   2471:                else {
                   2472:                        REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD,
                   2473:                                STATUS_ATTN_BITS_LINK_STATE);
                   2474:                }
                   2475: 
                   2476:                bnx2_set_link(bp);
                   2477: 
                   2478:                /* This is needed to take care of transient status
                   2479:                 * during link changes.
                   2480:                 */
                   2481: 
                   2482:                REG_WR(bp, BNX2_HC_COMMAND,
                   2483:                       bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
                   2484:                REG_RD(bp, BNX2_HC_COMMAND);
                   2485: 
                   2486:        }
                   2487: 
                   2488:        return bp->link_up;
                   2489: }
                   2490: 
                   2491: static int
                   2492: bnx2_poll(struct nic* nic, int retrieve)
                   2493: {
                   2494:        struct bnx2 *bp = &bnx2;
                   2495:        struct rx_bd *cons_bd, *prod_bd;
                   2496:        u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
                   2497:        struct l2_fhdr *rx_hdr;
                   2498:        int result = 0;
                   2499:        unsigned int len;
                   2500:        unsigned char *data;
                   2501:        u32 status;
                   2502:        
                   2503: #if 0
                   2504:        if ((bp->status_blk->status_idx == bp->last_status_idx) &&
                   2505:            (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
                   2506:             BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) {
                   2507: 
                   2508:                bp->last_status_idx = bp->status_blk->status_idx;
                   2509:                REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                   2510:               BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
                   2511:               BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
                   2512:               bp->last_status_idx);
                   2513:                return 0;
                   2514:        }
                   2515: #endif
                   2516: 
                   2517:        if ((bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) && !retrieve)
                   2518:                return 1;
                   2519: 
                   2520:        if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) {
                   2521: 
                   2522:                hw_cons = bp->hw_rx_cons = bp->status_blk->status_rx_quick_consumer_index0;
                   2523:                if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
                   2524:                        hw_cons++;
                   2525:                }
                   2526:                sw_cons = bp->rx_cons;
                   2527:                sw_prod = bp->rx_prod;
                   2528: 
                   2529:                rmb();
                   2530:                if (sw_cons != hw_cons) {
                   2531: 
                   2532:                        sw_ring_cons = RX_RING_IDX(sw_cons);
                   2533:                        sw_ring_prod = RX_RING_IDX(sw_prod);
                   2534: 
                   2535:                        data = bus_to_virt(bp->rx_desc_ring[sw_ring_cons].rx_bd_haddr_lo);
                   2536: 
                   2537:                        rx_hdr = (struct l2_fhdr *)data;
                   2538:                        len = rx_hdr->l2_fhdr_pkt_len - 4;
                   2539:                        if ((len > (ETH_MAX_MTU + ETH_HLEN)) ||
                   2540:                                ((status = rx_hdr->l2_fhdr_status) &
                   2541:                                (L2_FHDR_ERRORS_BAD_CRC |
                   2542:                                L2_FHDR_ERRORS_PHY_DECODE |
                   2543:                                L2_FHDR_ERRORS_ALIGNMENT |
                   2544:                                L2_FHDR_ERRORS_TOO_SHORT |
                   2545:                                L2_FHDR_ERRORS_GIANT_FRAME))) {
                   2546:                                result = 0;
                   2547:                        }
                   2548:                        else
                   2549:                        {
                   2550:                                nic->packetlen = len;
                   2551:                                memcpy(nic->packet, data + bp->rx_offset, len);
                   2552:                                result = 1;
                   2553:                        }
                   2554: 
                   2555:                        /* Reuse the buffer */
                   2556:                        bp->rx_prod_bseq += bp->rx_buf_use_size;
                   2557:                        if (sw_cons != sw_prod) {
                   2558:                                cons_bd = &bp->rx_desc_ring[sw_ring_cons];
                   2559:                                prod_bd = &bp->rx_desc_ring[sw_ring_prod];
                   2560:                                prod_bd->rx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */
                   2561:                                prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
                   2562:                        }
                   2563: 
                   2564:                        sw_cons = NEXT_RX_BD(sw_cons);
                   2565:                        sw_prod = NEXT_RX_BD(sw_prod);
                   2566: 
                   2567:                }
                   2568: 
                   2569:                bp->rx_cons = sw_cons;
                   2570:                bp->rx_prod = sw_prod;
                   2571: 
                   2572:                REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod);
                   2573: 
                   2574:                REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
                   2575: 
                   2576:                wmb();
                   2577: 
                   2578:        }
                   2579: 
                   2580:        bnx2_poll_link(bp);
                   2581: 
                   2582: #if 0
                   2583:        bp->last_status_idx = bp->status_blk->status_idx;
                   2584:        rmb();
                   2585: 
                   2586:        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                   2587:               BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
                   2588:               BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
                   2589:               bp->last_status_idx);
                   2590: 
                   2591:        REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
                   2592: #endif
                   2593: 
                   2594:        return result;
                   2595: }
                   2596: 
                   2597: static void
                   2598: bnx2_irq(struct nic *nic __unused, irq_action_t action __unused)
                   2599: {
                   2600:        switch ( action ) {
                   2601:                case DISABLE: break;
                   2602:                case ENABLE: break;
                   2603:                case FORCE: break;
                   2604:        }
                   2605: }
                   2606: 
                   2607: static struct nic_operations bnx2_operations = {
                   2608:        .connect        = dummy_connect,
                   2609:        .poll           = bnx2_poll,
                   2610:        .transmit       = bnx2_transmit,
                   2611:        .irq            = bnx2_irq,
                   2612: };
                   2613: 
                   2614: static int
                   2615: bnx2_probe(struct nic *nic, struct pci_device *pdev)
                   2616: {
                   2617:        struct bnx2 *bp = &bnx2;
                   2618:        int i, rc;
                   2619: 
                   2620:        if (pdev == 0)
                   2621:                return 0;
                   2622: 
                   2623:        memset(bp, 0, sizeof(*bp));
                   2624: 
                   2625:        rc = bnx2_init_board(pdev, nic);
                   2626:        if (rc < 0) {
                   2627:                return 0;
                   2628:        }
                   2629: 
                   2630:        /*
                   2631:        nic->disable = bnx2_disable;
                   2632:        nic->transmit = bnx2_transmit;
                   2633:        nic->poll = bnx2_poll;
                   2634:        nic->irq = bnx2_irq;
                   2635:        */
                   2636:        
                   2637:        nic->nic_op     = &bnx2_operations;
                   2638: 
                   2639:        memcpy(nic->node_addr, bp->mac_addr, ETH_ALEN);
                   2640:        printf("Ethernet addr: %s\n", eth_ntoa( nic->node_addr ) );
                   2641:        printf("Broadcom NetXtreme II (%c%d) PCI%s %s %dMHz\n",
                   2642:                (int) ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
                   2643:                (int) ((CHIP_ID(bp) & 0x0ff0) >> 4),
                   2644:                ((bp->flags & PCIX_FLAG) ? "-X" : ""),
                   2645:                ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
                   2646:                bp->bus_speed_mhz);
                   2647: 
                   2648:        bnx2_set_power_state_0(bp);
                   2649:        bnx2_disable_int(bp);
                   2650: 
                   2651:        bnx2_alloc_mem(bp);
                   2652: 
                   2653:        rc = bnx2_init_nic(bp);
                   2654:        if (rc) {
                   2655:                return 0;
                   2656:        }
                   2657: 
                   2658:        bnx2_poll_link(bp);
                   2659:        for(i = 0; !bp->link_up && (i < VALID_LINK_TIMEOUT*100); i++) {
                   2660:                mdelay(1);
                   2661:                bnx2_poll_link(bp);
                   2662:        }
                   2663: #if 1
                   2664:        if (!bp->link_up){
                   2665:                printf("Valid link not established\n");
                   2666:                goto err_out_disable;
                   2667:        }
                   2668: #endif
                   2669:        
                   2670:        return 1;
                   2671: 
                   2672: err_out_disable:
                   2673:        bnx2_disable(nic);
                   2674:        return 0;
                   2675: }
                   2676: 
                   2677: static struct pci_device_id bnx2_nics[] = {
                   2678:        PCI_ROM(0x14e4, 0x164a, "bnx2-5706",        "Broadcom NetXtreme II BCM5706", 0),
                   2679:        PCI_ROM(0x14e4, 0x164c, "bnx2-5708",        "Broadcom NetXtreme II BCM5708", 0),
                   2680:        PCI_ROM(0x14e4, 0x16aa, "bnx2-5706S",       "Broadcom NetXtreme II BCM5706S", 0),
                   2681:        PCI_ROM(0x14e4, 0x16ac, "bnx2-5708S",       "Broadcom NetXtreme II BCM5708S", 0),
                   2682: };
                   2683: 
                   2684: PCI_DRIVER ( bnx2_driver, bnx2_nics, PCI_NO_CLASS );
                   2685: 
                   2686: DRIVER ( "BNX2", nic_driver, pci_driver, bnx2_driver, bnx2_probe, bnx2_disable );
                   2687: 
                   2688: /*
                   2689: static struct pci_driver bnx2_driver __pci_driver = {
                   2690:        .type     = NIC_DRIVER,
                   2691:        .name     = "BNX2",              
                   2692:        .probe    = bnx2_probe,
                   2693:        .ids      = bnx2_nics,                  
                   2694:        .id_count = sizeof(bnx2_nics)/sizeof(bnx2_nics[0]), 
                   2695:        .class    = 0,    
                   2696: };
                   2697: */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.