Warning, cross-references for /kernel/drivers/net/bnx2.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "drivers/pci/pci.h"
0023 #include "drivers/net/ethernet.h"
0024 #include "arch/i386.h"
0025 #include "util/printf.h"
0026 #include "smp/smp.h"
0027 #include "smp/apic.h"
0028 #include "mem/physical.h"
0029 #include "mem/virtual.h"
0030 #include "mem/pow2.h"
0031 #include "kernel.h"
0032 #include "sched/vcpu.h"
0033
0034 #define __LITTLE_ENDIAN
0035
0036 #include "bnx2.h"
0037 #include "bnx2_uncompressed_fw.h"
0038
0039 #define DEBUG_BNX2
0040
0041 #ifdef DEBUG_BNX2
0042 #define DLOG(fmt,...) DLOG_PREFIX("bnx2",fmt,##__VA_ARGS__)
0043 #else
0044 #define DLOG(fmt,...) ;
0045 #endif
0046
0047 #define MIN_ETHERNET_PACKET_SIZE 60
0048 #define MAX_ETHERNET_PACKET_SIZE 1514
0049 #define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
0050 #define ETHERNET_FCS_SIZE 4
0051 #define ETHERNET_VLAN_TAG_SIZE 4
0052 #define ETH_HLEN 14
0053
0054 typedef enum {
0055 BCM5706 = 0,
0056 NC370T,
0057 NC370I,
0058 BCM5706S,
0059 NC370F,
0060 BCM5708,
0061 BCM5708S,
0062 BCM5709,
0063 BCM5709S,
0064 BCM5716,
0065 BCM5716S,
0066 } board_t;
0067
0068
0069 static struct {
0070 char *name;
0071 } board_info[] = {
0072 { "Broadcom NetXtreme II BCM5706 1000Base-T" },
0073 { "HP NC370T Multifunction Gigabit Server Adapter" },
0074 { "HP NC370i Multifunction Gigabit Server Adapter" },
0075 { "Broadcom NetXtreme II BCM5706 1000Base-SX" },
0076 { "HP NC370F Multifunction Gigabit Server Adapter" },
0077 { "Broadcom NetXtreme II BCM5708 1000Base-T" },
0078 { "Broadcom NetXtreme II BCM5708 1000Base-SX" },
0079 { "Broadcom NetXtreme II BCM5709 1000Base-T" },
0080 { "Broadcom NetXtreme II BCM5709 1000Base-SX" },
0081 { "Broadcom NetXtreme II BCM5716 1000Base-T" },
0082 { "Broadcom NetXtreme II BCM5716 1000Base-SX" },
0083 };
0084
0085
0086 static struct {
0087 uint16 vendor, device, subvendor, subdevice, class, classmask, index;
0088 } compatible_ids[] = {
0089 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
0090 PCI_VENDOR_ID_HP, 0x3101, 0, 0, NC370T },
0091 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
0092 PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I },
0093 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
0094 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 },
0095 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708,
0096 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708 },
0097 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
0098 PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F },
0099 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
0100 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
0101 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
0102 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
0103 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709,
0104 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709 },
0105 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709S,
0106 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709S },
0107 { PCI_VENDOR_ID_BROADCOM, 0x163b,
0108 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
0109 { PCI_VENDOR_ID_BROADCOM, 0x163c,
0110 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716S },
0111 { 0xFFFF, 0xFFFF }
0112 };
0113
0114 static const struct flash_spec flash_table[] =
0115 {
0116 #define BUFFERED_FLAGS (BNX2_NV_BUFFERED | BNX2_NV_TRANSLATE)
0117 #define NONBUFFERED_FLAGS (BNX2_NV_WREN)
0118
0119 {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
0120 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
0121 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
0122 "EEPROM - slow"},
0123
0124 {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
0125 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0126 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
0127 "Entry 0001"},
0128
0129
0130 {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
0131 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0132 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
0133 "Non-buffered flash (128kB)"},
0134
0135
0136 {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
0137 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0138 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
0139 "Non-buffered flash (256kB)"},
0140
0141 {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
0142 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0143 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
0144 "Entry 0100"},
0145
0146 {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
0147 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
0148 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
0149 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
0150
0151 {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
0152 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
0153 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
0154 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
0155
0156
0157 {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
0158 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0159 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
0160 "Non-buffered flash (64kB)"},
0161
0162 {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
0163 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
0164 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
0165 "EEPROM - fast"},
0166
0167 {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
0168 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0169 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
0170 "Entry 1001"},
0171
0172 {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
0173 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0174 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
0175 "Entry 1010"},
0176
0177 {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
0178 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
0179 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
0180 "Buffered flash (128kB)"},
0181
0182 {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
0183 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0184 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
0185 "Entry 1100"},
0186
0187 {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
0188 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
0189 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
0190 "Entry 1101"},
0191
0192 {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
0193 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
0194 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
0195 "Entry 1110 (Atmel)"},
0196
0197 {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
0198 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
0199 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
0200 "Buffered flash (256kB)"},
0201 };
0202
0203 static const struct flash_spec flash_5709 = {
0204 .flags = BNX2_NV_BUFFERED,
0205 .page_bits = BCM5709_FLASH_PAGE_BITS,
0206 .page_size = BCM5709_FLASH_PAGE_SIZE,
0207 .addr_mask = BCM5709_FLASH_BYTE_ADDR_MASK,
0208 .total_size = BUFFERED_FLASH_TOTAL_SIZE*2,
0209 .name = "5709 Buffered flash (256kB)",
0210 };
0211
0212 static void
0213 pci_write_config_dword (pci_device *p, u32 offset, u32 val)
0214 {
0215 pci_write_dword (pci_addr (p->bus, p->slot, p->func, offset), val);
0216 }
0217
0218 static void
0219 pci_write_config_word (pci_device *p, u32 offset, u16 val)
0220 {
0221 pci_write_word (pci_addr (p->bus, p->slot, p->func, offset), val);
0222 }
0223
0224 static void
0225 pci_read_config_word (pci_device *p, u32 offset, u16 *val)
0226 {
0227 *val = pci_read_word (pci_addr (p->bus, p->slot, p->func, offset));
0228 }
0229
0230 #define udelay tsc_delay_usec
0231 #define EBUSY 1
0232 #define ENODEV 2
0233 #define EIO 3
0234
0235 static u32
0236 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
0237 {
0238 u32 val;
0239
0240 spinlock_lock(&bp->indirect_lock);
0241 REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
0242 val = REG_RD(bp, BNX2_PCICFG_REG_WINDOW);
0243 spinlock_unlock(&bp->indirect_lock);
0244 return val;
0245 }
0246
0247 static void
0248 bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
0249 {
0250 spinlock_lock(&bp->indirect_lock);
0251 REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
0252 REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
0253 spinlock_unlock(&bp->indirect_lock);
0254 }
0255
0256 static u32
0257 bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
0258 {
0259 return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset));
0260 }
0261
0262 static void
0263 bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val)
0264 {
0265 bnx2_reg_wr_ind(bp, bp->shmem_base + offset, val);
0266 }
0267
0268 static void
0269 bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
0270 {
0271 offset += cid_addr;
0272 spinlock_lock(&bp->indirect_lock);
0273 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
0274 int i;
0275
0276 REG_WR(bp, BNX2_CTX_CTX_DATA, val);
0277 REG_WR(bp, BNX2_CTX_CTX_CTRL,
0278 offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
0279 for (i = 0; i < 5; i++) {
0280 val = REG_RD(bp, BNX2_CTX_CTX_CTRL);
0281 if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0)
0282 break;
0283 udelay(5);
0284 }
0285 } else {
0286 REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
0287 REG_WR(bp, BNX2_CTX_DATA, val);
0288 }
0289 spinlock_unlock(&bp->indirect_lock);
0290 }
0291
0292 static int
0293 bnx2_acquire_nvram_lock(struct bnx2 *bp)
0294 {
0295 u32 val;
0296 int j;
0297
0298
0299 REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_SET2);
0300 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
0301 val = REG_RD(bp, BNX2_NVM_SW_ARB);
0302 if (val & BNX2_NVM_SW_ARB_ARB_ARB2)
0303 break;
0304
0305 udelay(5);
0306 }
0307
0308 if (j >= NVRAM_TIMEOUT_COUNT)
0309 return -EBUSY;
0310
0311 return 0;
0312 }
0313
0314 static int
0315 bnx2_release_nvram_lock(struct bnx2 *bp)
0316 {
0317 int j;
0318 u32 val;
0319
0320
0321 REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_CLR2);
0322
0323 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
0324 val = REG_RD(bp, BNX2_NVM_SW_ARB);
0325 if (!(val & BNX2_NVM_SW_ARB_ARB_ARB2))
0326 break;
0327
0328 udelay(5);
0329 }
0330
0331 if (j >= NVRAM_TIMEOUT_COUNT)
0332 return -EBUSY;
0333
0334 return 0;
0335 }
0336
0337 static void
0338 bnx2_enable_nvram_access(struct bnx2 *bp)
0339 {
0340 u32 val;
0341
0342 val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
0343
0344 REG_WR(bp, BNX2_NVM_ACCESS_ENABLE,
0345 val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN);
0346 }
0347
0348 static void
0349 bnx2_disable_nvram_access(struct bnx2 *bp)
0350 {
0351 u32 val;
0352
0353 val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
0354
0355 REG_WR(bp, BNX2_NVM_ACCESS_ENABLE,
0356 val & ~(BNX2_NVM_ACCESS_ENABLE_EN |
0357 BNX2_NVM_ACCESS_ENABLE_WR_EN));
0358 }
0359
0360 static int
0361 bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags)
0362 {
0363 u32 cmd;
0364 int j;
0365
0366
0367 cmd = BNX2_NVM_COMMAND_DOIT | cmd_flags;
0368
0369
0370 if (bp->flash_info->flags & BNX2_NV_TRANSLATE) {
0371 offset = ((offset / bp->flash_info->page_size) <<
0372 bp->flash_info->page_bits) +
0373 (offset % bp->flash_info->page_size);
0374 }
0375
0376
0377 REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
0378
0379
0380 REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
0381
0382
0383 REG_WR(bp, BNX2_NVM_COMMAND, cmd);
0384
0385
0386 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
0387 u32 val;
0388
0389 udelay(5);
0390
0391 val = REG_RD(bp, BNX2_NVM_COMMAND);
0392 if (val & BNX2_NVM_COMMAND_DONE) {
0393 __be32 v = __cpu_to_be32(REG_RD(bp, BNX2_NVM_READ));
0394 memcpy(ret_val, &v, 4);
0395 break;
0396 }
0397 }
0398 if (j >= NVRAM_TIMEOUT_COUNT)
0399 return -EBUSY;
0400
0401 return 0;
0402 }
0403
0404 static int
0405 bnx2_nvram_read(struct bnx2 *bp, u32 offset, u8 *ret_buf,
0406 int buf_size)
0407 {
0408 int rc = 0;
0409 u32 cmd_flags, offset32, len32, extra;
0410
0411 if (buf_size == 0)
0412 return 0;
0413
0414
0415 if ((rc = bnx2_acquire_nvram_lock(bp)) != 0)
0416 return rc;
0417
0418
0419 bnx2_enable_nvram_access(bp);
0420
0421 len32 = buf_size;
0422 offset32 = offset;
0423 extra = 0;
0424
0425 cmd_flags = 0;
0426
0427 if (offset32 & 3) {
0428 u8 buf[4];
0429 u32 pre_len;
0430
0431 offset32 &= ~3;
0432 pre_len = 4 - (offset & 3);
0433
0434 if (pre_len >= len32) {
0435 pre_len = len32;
0436 cmd_flags = BNX2_NVM_COMMAND_FIRST |
0437 BNX2_NVM_COMMAND_LAST;
0438 }
0439 else {
0440 cmd_flags = BNX2_NVM_COMMAND_FIRST;
0441 }
0442
0443 rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags);
0444
0445 if (rc)
0446 return rc;
0447
0448 memcpy(ret_buf, buf + (offset & 3), pre_len);
0449
0450 offset32 += 4;
0451 ret_buf += pre_len;
0452 len32 -= pre_len;
0453 }
0454 if (len32 & 3) {
0455 extra = 4 - (len32 & 3);
0456 len32 = (len32 + 4) & ~3;
0457 }
0458
0459 if (len32 == 4) {
0460 u8 buf[4];
0461
0462 if (cmd_flags)
0463 cmd_flags = BNX2_NVM_COMMAND_LAST;
0464 else
0465 cmd_flags = BNX2_NVM_COMMAND_FIRST |
0466 BNX2_NVM_COMMAND_LAST;
0467
0468 rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags);
0469
0470 memcpy(ret_buf, buf, 4 - extra);
0471 }
0472 else if (len32 > 0) {
0473 u8 buf[4];
0474
0475
0476 if (cmd_flags)
0477 cmd_flags = 0;
0478 else
0479 cmd_flags = BNX2_NVM_COMMAND_FIRST;
0480
0481 rc = bnx2_nvram_read_dword(bp, offset32, ret_buf, cmd_flags);
0482
0483
0484 offset32 += 4;
0485 ret_buf += 4;
0486 len32 -= 4;
0487
0488 while (len32 > 4 && rc == 0) {
0489 rc = bnx2_nvram_read_dword(bp, offset32, ret_buf, 0);
0490
0491
0492 offset32 += 4;
0493 ret_buf += 4;
0494 len32 -= 4;
0495 }
0496
0497 if (rc)
0498 return rc;
0499
0500 cmd_flags = BNX2_NVM_COMMAND_LAST;
0501 rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags);
0502
0503 memcpy(ret_buf, buf, 4 - extra);
0504 }
0505
0506
0507 bnx2_disable_nvram_access(bp);
0508
0509 bnx2_release_nvram_lock(bp);
0510
0511 return rc;
0512 }
0513
0514 static int
0515 bnx2_init_nvram(struct bnx2 *bp)
0516 {
0517 u32 val;
0518 int j, entry_count, rc = 0;
0519 const struct flash_spec *flash;
0520
0521 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
0522 bp->flash_info = &flash_5709;
0523 goto get_flash_size;
0524 }
0525
0526
0527 val = REG_RD(bp, BNX2_NVM_CFG1);
0528
0529 entry_count = ARRAY_SIZE(flash_table);
0530
0531 if (val & 0x40000000) {
0532
0533
0534 for (j = 0, flash = &flash_table[0]; j < entry_count;
0535 j++, flash++) {
0536 if ((val & FLASH_BACKUP_STRAP_MASK) ==
0537 (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
0538 bp->flash_info = flash;
0539 break;
0540 }
0541 }
0542 }
0543 else {
0544 u32 mask;
0545
0546
0547 if (val & (1 << 23))
0548 mask = FLASH_BACKUP_STRAP_MASK;
0549 else
0550 mask = FLASH_STRAP_MASK;
0551
0552 for (j = 0, flash = &flash_table[0]; j < entry_count;
0553 j++, flash++) {
0554
0555 if ((val & mask) == (flash->strapping & mask)) {
0556 bp->flash_info = flash;
0557
0558
0559 if ((rc = bnx2_acquire_nvram_lock(bp)) != 0)
0560 return rc;
0561
0562
0563 bnx2_enable_nvram_access(bp);
0564
0565
0566 REG_WR(bp, BNX2_NVM_CFG1, flash->config1);
0567 REG_WR(bp, BNX2_NVM_CFG2, flash->config2);
0568 REG_WR(bp, BNX2_NVM_CFG3, flash->config3);
0569 REG_WR(bp, BNX2_NVM_WRITE1, flash->write1);
0570
0571
0572 bnx2_disable_nvram_access(bp);
0573 bnx2_release_nvram_lock(bp);
0574
0575 break;
0576 }
0577 }
0578 }
0579
0580 if (j == entry_count) {
0581 bp->flash_info = NULL;
0582 DLOG ("Unknown flash/EEPROM type");
0583 return -ENODEV;
0584 }
0585
0586 get_flash_size:
0587 val = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG2);
0588 val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK;
0589 if (val)
0590 bp->flash_size = val;
0591 else
0592 bp->flash_size = bp->flash_info->total_size;
0593
0594 return rc;
0595 }
0596
0597 #if 0
0598 static void
0599 bnx2_read_vpd_fw_ver(struct bnx2 *bp)
0600 {
0601 int rc, i, j;
0602 u8 *data;
0603 unsigned int block_end, rosize, len;
0604
0605 #define BNX2_VPD_NVRAM_OFFSET 0x300
0606 #define BNX2_VPD_LEN 128
0607 #define BNX2_MAX_VER_SLEN 30
0608
0609
0610 u8 _data[256];
0611 data = _data;
0612
0613 if (!data)
0614 return;
0615
0616 rc = bnx2_nvram_read(bp, BNX2_VPD_NVRAM_OFFSET, data + BNX2_VPD_LEN,
0617 BNX2_VPD_LEN);
0618 if (rc)
0619 goto vpd_done;
0620
0621 for (i = 0; i < BNX2_VPD_LEN; i += 4) {
0622 data[i] = data[i + BNX2_VPD_LEN + 3];
0623 data[i + 1] = data[i + BNX2_VPD_LEN + 2];
0624 data[i + 2] = data[i + BNX2_VPD_LEN + 1];
0625 data[i + 3] = data[i + BNX2_VPD_LEN];
0626 }
0627
0628 i = pci_vpd_find_tag(data, 0, BNX2_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
0629 if (i < 0)
0630 goto vpd_done;
0631
0632 rosize = pci_vpd_lrdt_size(&data[i]);
0633 i += PCI_VPD_LRDT_TAG_SIZE;
0634 block_end = i + rosize;
0635
0636 if (block_end > BNX2_VPD_LEN)
0637 goto vpd_done;
0638
0639 j = pci_vpd_find_info_keyword(data, i, rosize,
0640 PCI_VPD_RO_KEYWORD_MFR_ID);
0641 if (j < 0)
0642 goto vpd_done;
0643
0644 len = pci_vpd_info_field_size(&data[j]);
0645
0646 j += PCI_VPD_INFO_FLD_HDR_SIZE;
0647 if (j + len > block_end || len != 4 ||
0648 memcmp(&data[j], "1028", 4))
0649 goto vpd_done;
0650
0651 j = pci_vpd_find_info_keyword(data, i, rosize,
0652 PCI_VPD_RO_KEYWORD_VENDOR0);
0653 if (j < 0)
0654 goto vpd_done;
0655
0656 len = pci_vpd_info_field_size(&data[j]);
0657
0658 j += PCI_VPD_INFO_FLD_HDR_SIZE;
0659 if (j + len > block_end || len > BNX2_MAX_VER_SLEN)
0660 goto vpd_done;
0661
0662 memcpy(bp->fw_version, &data[j], len);
0663 bp->fw_version[len] = ' ';
0664
0665 vpd_done:
0666
0667 }
0668 #endif
0669
0670 static void
0671 bnx2_get_5709_media(struct bnx2 *bp)
0672 {
0673 u32 val = REG_RD(bp, BNX2_MISC_DUAL_MEDIA_CTRL);
0674 u32 bond_id = val & BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID;
0675 u32 strap;
0676
0677 if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C)
0678 return;
0679 else if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
0680 bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
0681 return;
0682 }
0683
0684 if (val & BNX2_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
0685 strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
0686 else
0687 strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
0688
0689 if (bp->pdev->func == 0) {
0690 switch (strap) {
0691 case 0x4:
0692 case 0x5:
0693 case 0x6:
0694 bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
0695 return;
0696 }
0697 } else {
0698 switch (strap) {
0699 case 0x1:
0700 case 0x2:
0701 case 0x4:
0702 bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
0703 return;
0704 }
0705 }
0706 }
0707
0708 static void
0709 bnx2_init_fw_cap(struct bnx2 *bp)
0710 {
0711 u32 val, sig = 0;
0712
0713 bp->phy_flags &= ~BNX2_PHY_FLAG_REMOTE_PHY_CAP;
0714 bp->flags &= ~BNX2_FLAG_CAN_KEEP_VLAN;
0715
0716 if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
0717 bp->flags |= BNX2_FLAG_CAN_KEEP_VLAN;
0718
0719 val = bnx2_shmem_rd(bp, BNX2_FW_CAP_MB);
0720 if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
0721 return;
0722
0723 if ((val & BNX2_FW_CAP_CAN_KEEP_VLAN) == BNX2_FW_CAP_CAN_KEEP_VLAN) {
0724 bp->flags |= BNX2_FLAG_CAN_KEEP_VLAN;
0725 sig |= BNX2_DRV_ACK_CAP_SIGNATURE | BNX2_FW_CAP_CAN_KEEP_VLAN;
0726 }
0727
0728 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
0729 (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE)) {
0730 u32 link;
0731
0732 bp->phy_flags |= BNX2_PHY_FLAG_REMOTE_PHY_CAP;
0733
0734 link = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
0735 if (link & BNX2_LINK_STATUS_SERDES_LINK)
0736 bp->phy_port = PORT_FIBRE;
0737 else
0738 bp->phy_port = PORT_TP;
0739
0740 sig |= BNX2_DRV_ACK_CAP_SIGNATURE |
0741 BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
0742 }
0743
0744 #if 0
0745 if (netif_running(bp->dev) && sig)
0746 bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig);
0747 #endif
0748 }
0749
0750
0751
0752 #define SPEED_10 10
0753 #define SPEED_100 100
0754 #define SPEED_1000 1000
0755 #define SPEED_2500 2500
0756 #define SPEED_10000 10000
0757
0758
0759 #define DUPLEX_HALF 0x00
0760 #define DUPLEX_FULL 0x01
0761
0762
0763 #define ADVERTISED_10baseT_Half (1 << 0)
0764 #define ADVERTISED_10baseT_Full (1 << 1)
0765 #define ADVERTISED_100baseT_Half (1 << 2)
0766 #define ADVERTISED_100baseT_Full (1 << 3)
0767 #define ADVERTISED_1000baseT_Half (1 << 4)
0768 #define ADVERTISED_1000baseT_Full (1 << 5)
0769 #define ADVERTISED_Autoneg (1 << 6)
0770 #define ADVERTISED_TP (1 << 7)
0771 #define ADVERTISED_AUI (1 << 8)
0772 #define ADVERTISED_MII (1 << 9)
0773 #define ADVERTISED_FIBRE (1 << 10)
0774 #define ADVERTISED_BNC (1 << 11)
0775 #define ADVERTISED_10000baseT_Full (1 << 12)
0776 #define ADVERTISED_Pause (1 << 13)
0777 #define ADVERTISED_Asym_Pause (1 << 14)
0778 #define ADVERTISED_2500baseX_Full (1 << 15)
0779 #define ADVERTISED_Backplane (1 << 16)
0780 #define ADVERTISED_1000baseKX_Full (1 << 17)
0781 #define ADVERTISED_10000baseKX4_Full (1 << 18)
0782 #define ADVERTISED_10000baseKR_Full (1 << 19)
0783 #define ADVERTISED_10000baseR_FEC (1 << 20)
0784
0785 #define ETHTOOL_ALL_FIBRE_SPEED \
0786 (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) ? \
0787 (ADVERTISED_2500baseX_Full | ADVERTISED_1000baseT_Full) : \
0788 (ADVERTISED_1000baseT_Full)
0789
0790 #define ETHTOOL_ALL_COPPER_SPEED \
0791 (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
0792 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
0793 ADVERTISED_1000baseT_Full)
0794
0795 #define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \
0796 ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA)
0797
0798 #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
0799
0800 static void
0801 bnx2_set_default_remote_link(struct bnx2 *bp)
0802 {
0803 u32 link;
0804
0805 if (bp->phy_port == PORT_TP)
0806 link = bnx2_shmem_rd(bp, BNX2_RPHY_COPPER_LINK);
0807 else
0808 link = bnx2_shmem_rd(bp, BNX2_RPHY_SERDES_LINK);
0809
0810 if (link & BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG) {
0811 bp->req_line_speed = 0;
0812 bp->autoneg |= AUTONEG_SPEED;
0813 bp->advertising = ADVERTISED_Autoneg;
0814 if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
0815 bp->advertising |= ADVERTISED_10baseT_Half;
0816 if (link & BNX2_NETLINK_SET_LINK_SPEED_10FULL)
0817 bp->advertising |= ADVERTISED_10baseT_Full;
0818 if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
0819 bp->advertising |= ADVERTISED_100baseT_Half;
0820 if (link & BNX2_NETLINK_SET_LINK_SPEED_100FULL)
0821 bp->advertising |= ADVERTISED_100baseT_Full;
0822 if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
0823 bp->advertising |= ADVERTISED_1000baseT_Full;
0824 if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
0825 bp->advertising |= ADVERTISED_2500baseX_Full;
0826 } else {
0827 bp->autoneg = 0;
0828 bp->advertising = 0;
0829 bp->req_duplex = DUPLEX_FULL;
0830 if (link & BNX2_NETLINK_SET_LINK_SPEED_10) {
0831 bp->req_line_speed = SPEED_10;
0832 if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
0833 bp->req_duplex = DUPLEX_HALF;
0834 }
0835 if (link & BNX2_NETLINK_SET_LINK_SPEED_100) {
0836 bp->req_line_speed = SPEED_100;
0837 if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
0838 bp->req_duplex = DUPLEX_HALF;
0839 }
0840 if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
0841 bp->req_line_speed = SPEED_1000;
0842 if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
0843 bp->req_line_speed = SPEED_2500;
0844 }
0845 }
0846
0847 static void
0848 bnx2_set_default_link(struct bnx2 *bp)
0849 {
0850 if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) {
0851 bnx2_set_default_remote_link(bp);
0852 return;
0853 }
0854
0855 bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
0856 bp->req_line_speed = 0;
0857 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
0858 u32 reg;
0859
0860 bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
0861
0862 reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_CONFIG);
0863 reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
0864 if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
0865 bp->autoneg = 0;
0866 bp->req_line_speed = bp->line_speed = SPEED_1000;
0867 bp->req_duplex = DUPLEX_FULL;
0868 }
0869 } else
0870 bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
0871 }
0872
0873 static ethernet_device bnx2_ethdev;
0874
0875 static inline u16
0876 bnx2_get_hw_rx_cons(struct bnx2 *bp)
0877 {
0878 volatile u16 *ptr;
0879 u16 cons;
0880
0881 ptr = &bp->status_blk->status_rx_quick_consumer_index0;
0882 cons = *ptr;
0883 if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
0884 cons++;
0885 return cons;
0886 }
0887
0888 static u32
0889 bnx2_irq_handler (u8 vec)
0890 {
0891 int i;
0892 struct bnx2 *bp = bnx2_ethdev.drvdata;
0893 struct bnx2_rx_ring_info *rxr = &bp->rx_ring;
0894 u16 hw_cons = bnx2_get_hw_rx_cons (bp), sw_cons = rxr->rx_cons, sw_prod = rxr->rx_prod;
0895 struct sw_bd *rx_buf, *next_rx_buf;
0896 struct l2_fhdr *rx_hdr;
0897 struct rx_bd *rx_desc;
0898
0899 DLOG ("***IRQ*** hw_cons=%d (%d) sw_cons=%d (%d) sw_prod=%d (%d)",
0900 hw_cons, RX_RING_IDX (hw_cons),
0901 sw_cons, RX_RING_IDX (sw_cons),
0902 sw_prod, RX_RING_IDX (sw_prod));
0903
0904
0905 rx_buf = &rxr->rx_buf_ring[RX_RING_IDX (sw_cons)];
0906 rx_hdr = rx_buf->desc;
0907
0908 if (!rx_hdr) {
0909 DLOG ("rx_hdr=NULL %d %d", sw_cons, RX_RING_IDX (sw_cons));
0910 sw_prod = NEXT_RX_BD (sw_prod);
0911 }
0912
0913 while (rx_hdr && rx_hdr->l2_fhdr_status && hw_cons != sw_cons) {
0914 rx_buf = &rxr->rx_buf_ring[RX_RING_IDX (sw_cons)];
0915 rx_desc = &rxr->rx_desc_ring[0][RX_RING_IDX (sw_cons)];
0916 rx_hdr = rx_buf->desc;
0917
0918 DLOG ("rx_buf[%d (%d)] len=%d status=0x%.08X",
0919 RX_RING_IDX (sw_cons),
0920 sw_cons,
0921 rx_hdr->l2_fhdr_pkt_len,
0922 rx_hdr->l2_fhdr_status);
0923 u8 *p = rx_buf->skb->data + BNX2_RX_OFFSET;
0924 DLOG (" %.02X %.02X %.02X %.02X %.02X %.02X",
0925 p[0], p[1], p[2], p[3], p[4], p[5]);
0926 p+=6;
0927 DLOG (" %.02X %.02X %.02X %.02X %.02X %.02X",
0928 p[0], p[1], p[2], p[3], p[4], p[5]);
0929
0930 DLOG ("rx_desc[%d (%d)] len=%d flags=0x%X haddr=0x%.08X%.08X",
0931 RX_RING_IDX (sw_cons),
0932 sw_cons,
0933 rx_desc->rx_bd_len,
0934 rx_desc->rx_bd_flags,
0935 rx_desc->rx_bd_haddr_hi,
0936 rx_desc->rx_bd_haddr_lo);
0937
0938 memset (rx_buf->skb->data, 0, rx_buf->skb->len);
0939 rxr->rx_prod_bseq += bp->rx_buf_use_size;
0940
0941 sw_cons = NEXT_RX_BD (sw_cons);
0942 sw_prod = NEXT_RX_BD (sw_prod);
0943 hw_cons = bnx2_get_hw_rx_cons (bp);
0944
0945 DLOG ("hw_cons=%d (%d) sw_cons=%d (%d) sw_prod=%d (%d)",
0946 hw_cons, RX_RING_IDX (hw_cons),
0947 sw_cons, RX_RING_IDX (sw_cons),
0948 sw_prod, RX_RING_IDX (sw_prod));
0949 }
0950
0951 rxr->rx_cons = sw_cons;
0952 rxr->rx_prod = sw_prod;
0953
0954 u32 repstat, ctxstat;
0955 if ((repstat = REG_RD (bp, BNX2_CTX_REP_STATUS))) {
0956 ctxstat = REG_RD (bp, BNX2_CTX_STATUS);
0957 DLOG (" CTX status (0x%.08X):%s%s",
0958 ctxstat,
0959 ctxstat & BNX2_CTX_STATUS_USAGE_CNT_ERR ? " usage_cnt_err" : "",
0960 ctxstat & BNX2_CTX_STATUS_INVALID_PAGE ? " invalid_page" : "");
0961 DLOG (" CTX rep status (0x%.08X): entry=0x%X client=0x%X:%s%s%s",
0962 repstat,
0963 repstat & BNX2_CTX_REP_STATUS_ERROR_ENTRY,
0964 (repstat & BNX2_CTX_REP_STATUS_ERROR_CLIENT_ID) >> 10,
0965 repstat & BNX2_CTX_REP_STATUS_USAGE_CNT_MAX_ERR ? " usage_cnt_max_err" : "",
0966 repstat & BNX2_CTX_REP_STATUS_USAGE_CNT_MIN_ERR ? " usage_cnt_min_err" : "",
0967 repstat & BNX2_CTX_REP_STATUS_USAGE_CNT_MISS_ERR ? " usage_cnt_miss_err" : "");
0968 REG_WR (bp, BNX2_CTX_REP_STATUS, repstat & (BNX2_CTX_REP_STATUS_USAGE_CNT_MIN_ERR |
0969 BNX2_CTX_REP_STATUS_USAGE_CNT_MAX_ERR |
0970 BNX2_CTX_REP_STATUS_USAGE_CNT_MISS_ERR));
0971 }
0972
0973 DLOG ("---EOI--- bidx <- %d (%d); prod_bseq = %d",
0974 sw_prod, RX_RING_IDX (sw_prod),
0975 rxr->rx_prod_bseq);
0976 DLOG (" csv: %d, %d", sw_prod, rxr->rx_prod_bseq);
0977
0978 REG_WR16(bp, rxr->rx_bidx_addr, sw_prod);
0979 REG_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
0980
0981
0982 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, (0 << 24) |
0983 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
0984 bp->status_blk->status_idx);
0985 REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
0986
0987 return 0;
0988 }
0989
0990 static void
0991 bnx2_send_heart_beat(struct bnx2 *bp)
0992 {
0993 u32 msg;
0994 u32 addr;
0995
0996 spinlock_lock(&bp->indirect_lock);
0997 msg = (u32) (++bp->fw_drv_pulse_wr_seq & BNX2_DRV_PULSE_SEQ_MASK);
0998 addr = bp->shmem_base + BNX2_DRV_PULSE_MB;
0999 REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, addr);
1000 REG_WR(bp, BNX2_PCICFG_REG_WINDOW, msg);
1001 spinlock_unlock(&bp->indirect_lock);
1002 }
1003
1004 static int
1005 bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
1006 {
1007 int i;
1008 u32 val;
1009
1010 bp->fw_wr_seq++;
1011 msg_data |= bp->fw_wr_seq;
1012
1013 bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
1014
1015 if (!ack)
1016 return 0;
1017
1018
1019 for (i = 0; i < (BNX2_FW_ACK_TIME_OUT_MS / 10); i++) {
1020 udelay(10*1000);
1021
1022 val = bnx2_shmem_rd(bp, BNX2_FW_MB);
1023
1024 if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
1025 break;
1026 }
1027 if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0)
1028 return 0;
1029
1030
1031 if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) {
1032
1033 DLOG ("fw sync timeout, reset code = %x\n", msg_data);
1034
1035 msg_data &= ~BNX2_DRV_MSG_CODE;
1036 msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
1037
1038 bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
1039
1040 return -EBUSY;
1041 }
1042
1043 if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK)
1044 return -EIO;
1045
1046 return 0;
1047 }
1048
1049 #if 0
1050 static int
1051 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
1052 {
1053 u32 val;
1054 int i, rc = 0;
1055 u8 old_port;
1056
1057
1058
1059 REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
1060 BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
1061 BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
1062 BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
1063 BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
1064 val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
1065 udelay(5);
1066
1067
1068 bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
1069
1070
1071
1072 bnx2_shmem_wr(bp, BNX2_DRV_RESET_SIGNATURE,
1073 BNX2_DRV_RESET_SIGNATURE_MAGIC);
1074
1075
1076
1077 val = REG_RD(bp, BNX2_MISC_ID);
1078
1079 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1080 REG_WR(bp, BNX2_MISC_COMMAND, BNX2_MISC_COMMAND_SW_RESET);
1081 REG_RD(bp, BNX2_MISC_COMMAND);
1082 udelay(5);
1083
1084 val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
1085 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
1086
1087 pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
1088
1089 } else {
1090 val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
1091 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
1092 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
1093
1094
1095 REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
1096
1097
1098
1099
1100
1101 if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
1102 (CHIP_ID(bp) == CHIP_ID_5706_A1))
1103 udelay(20*1000);
1104
1105
1106 for (i = 0; i < 10; i++) {
1107 val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
1108 if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
1109 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
1110 break;
1111 udelay(10);
1112 }
1113
1114 if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
1115 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
1116 pr_err("Chip reset did not complete\n");
1117 return -EBUSY;
1118 }
1119 }
1120
1121
1122 val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0);
1123 if (val != 0x01020304) {
1124 pr_err("Chip not in correct endian mode\n");
1125 return -ENODEV;
1126 }
1127
1128
1129 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 1, 0);
1130 if (rc)
1131 return rc;
1132
1133 spin_lock_bh(&bp->phy_lock);
1134 old_port = bp->phy_port;
1135 bnx2_init_fw_cap(bp);
1136 if ((bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) &&
1137 old_port != bp->phy_port)
1138 bnx2_set_default_remote_link(bp);
1139 spin_unlock_bh(&bp->phy_lock);
1140
1141 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
1142
1143
1144 REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
1145
1146
1147 rc = bnx2_alloc_bad_rbuf(bp);
1148 }
1149
1150 if (bp->flags & BNX2_FLAG_USING_MSIX) {
1151 bnx2_setup_msix_tbl(bp);
1152
1153 REG_WR(bp, BNX2_MISC_ECO_HW_CTL,
1154 BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
1155 }
1156
1157 return rc;
1158 }
1159
1160 static int
1161 bnx2_init_chip(struct bnx2 *bp)
1162 {
1163 u32 val, mtu;
1164 int rc, i;
1165
1166
1167 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
1168
1169 val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP |
1170 BNX2_DMA_CONFIG_DATA_WORD_SWAP |
1171 #ifdef __BIG_ENDIAN
1172 BNX2_DMA_CONFIG_CNTL_BYTE_SWAP |
1173 #endif
1174 BNX2_DMA_CONFIG_CNTL_WORD_SWAP |
1175 DMA_READ_CHANS << 12 |
1176 DMA_WRITE_CHANS << 16;
1177
1178 val |= (0x2 << 20) | (1 << 11);
1179
1180 if ((bp->flags & BNX2_FLAG_PCIX) && (bp->bus_speed_mhz == 133))
1181 val |= (1 << 23);
1182
1183 if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
1184 (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & BNX2_FLAG_PCIX))
1185 val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
1186
1187 REG_WR(bp, BNX2_DMA_CONFIG, val);
1188
1189 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
1190 val = REG_RD(bp, BNX2_TDMA_CONFIG);
1191 val |= BNX2_TDMA_CONFIG_ONE_DMA;
1192 REG_WR(bp, BNX2_TDMA_CONFIG, val);
1193 }
1194
1195 if (bp->flags & BNX2_FLAG_PCIX) {
1196 u16 val16;
1197
1198 pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
1199 &val16);
1200 pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
1201 val16 & ~PCI_X_CMD_ERO);
1202 }
1203
1204 REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
1205 BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
1206 BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
1207 BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
1208
1209
1210
1211 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1212 rc = bnx2_init_5709_context(bp);
1213 if (rc)
1214 return rc;
1215 } else
1216 bnx2_init_context(bp);
1217
1218 if ((rc = bnx2_init_cpus(bp)) != 0)
1219 return rc;
1220
1221 bnx2_init_nvram(bp);
1222
1223 bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
1224
1225 val = REG_RD(bp, BNX2_MQ_CONFIG);
1226 val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
1227 val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
1228 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1229 val |= BNX2_MQ_CONFIG_BIN_MQ_MODE;
1230 if (CHIP_REV(bp) == CHIP_REV_Ax)
1231 val |= BNX2_MQ_CONFIG_HALT_DIS;
1232 }
1233
1234 REG_WR(bp, BNX2_MQ_CONFIG, val);
1235
1236 val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
1237 REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
1238 REG_WR(bp, BNX2_MQ_KNL_WIND_END, val);
1239
1240 val = (BCM_PAGE_BITS - 8) << 24;
1241 REG_WR(bp, BNX2_RV2P_CONFIG, val);
1242
1243
1244 val = REG_RD(bp, BNX2_TBDR_CONFIG);
1245 val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE;
1246 val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
1247 REG_WR(bp, BNX2_TBDR_CONFIG, val);
1248
1249 val = bp->mac_addr[0] +
1250 (bp->mac_addr[1] << 8) +
1251 (bp->mac_addr[2] << 16) +
1252 bp->mac_addr[3] +
1253 (bp->mac_addr[4] << 8) +
1254 (bp->mac_addr[5] << 16);
1255 REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
1256
1257
1258 mtu = bp->dev->mtu;
1259 val = mtu + ETH_HLEN + ETH_FCS_LEN;
1260 if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
1261 val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
1262 REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
1263
1264 if (mtu < 1500)
1265 mtu = 1500;
1266
1267 bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG, BNX2_RBUF_CONFIG_VAL(mtu));
1268 bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG2, BNX2_RBUF_CONFIG2_VAL(mtu));
1269 bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
1270
1271 memset(bp->bnx2_napi[0].status_blk.msi, 0, bp->status_stats_size);
1272 for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
1273 bp->bnx2_napi[i].last_status_idx = 0;
1274
1275 bp->idle_chk_status_idx = 0xffff;
1276
1277 bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
1278
1279
1280 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
1281
1282 REG_WR(bp, BNX2_HC_STATUS_ADDR_L,
1283 (u64) bp->status_blk_mapping & 0xffffffff);
1284 REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
1285
1286 REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
1287 (u64) bp->stats_blk_mapping & 0xffffffff);
1288 REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H,
1289 (u64) bp->stats_blk_mapping >> 32);
1290
1291 REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP,
1292 (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip);
1293
1294 REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP,
1295 (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip);
1296
1297 REG_WR(bp, BNX2_HC_COMP_PROD_TRIP,
1298 (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip);
1299
1300 REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks);
1301
1302 REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks);
1303
1304 REG_WR(bp, BNX2_HC_COM_TICKS,
1305 (bp->com_ticks_int << 16) | bp->com_ticks);
1306
1307 REG_WR(bp, BNX2_HC_CMD_TICKS,
1308 (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
1309
1310 if (bp->flags & BNX2_FLAG_BROKEN_STATS)
1311 REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
1312 else
1313 REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks);
1314 REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8);
1315
1316 if (CHIP_ID(bp) == CHIP_ID_5706_A1)
1317 val = BNX2_HC_CONFIG_COLLECT_STATS;
1318 else {
1319 val = BNX2_HC_CONFIG_RX_TMR_MODE | BNX2_HC_CONFIG_TX_TMR_MODE |
1320 BNX2_HC_CONFIG_COLLECT_STATS;
1321 }
1322
1323 if (bp->flags & BNX2_FLAG_USING_MSIX) {
1324 REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
1325 BNX2_HC_MSIX_BIT_VECTOR_VAL);
1326
1327 val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
1328 }
1329
1330 if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
1331 val |= BNX2_HC_CONFIG_ONE_SHOT | BNX2_HC_CONFIG_USE_INT_PARAM;
1332
1333 REG_WR(bp, BNX2_HC_CONFIG, val);
1334
1335 for (i = 1; i < bp->irq_nvecs; i++) {
1336 u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) +
1337 BNX2_HC_SB_CONFIG_1;
1338
1339 REG_WR(bp, base,
1340 BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
1341 BNX2_HC_SB_CONFIG_1_RX_TMR_MODE |
1342 BNX2_HC_SB_CONFIG_1_ONE_SHOT);
1343
1344 REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
1345 (bp->tx_quick_cons_trip_int << 16) |
1346 bp->tx_quick_cons_trip);
1347
1348 REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
1349 (bp->tx_ticks_int << 16) | bp->tx_ticks);
1350
1351 REG_WR(bp, base + BNX2_HC_RX_QUICK_CONS_TRIP_OFF,
1352 (bp->rx_quick_cons_trip_int << 16) |
1353 bp->rx_quick_cons_trip);
1354
1355 REG_WR(bp, base + BNX2_HC_RX_TICKS_OFF,
1356 (bp->rx_ticks_int << 16) | bp->rx_ticks);
1357 }
1358
1359
1360 REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
1361
1362 REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_EVENTS);
1363
1364
1365 bnx2_set_rx_mode(bp->dev);
1366
1367 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1368 val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
1369 val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
1370 REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
1371 }
1372 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
1373 1, 0);
1374
1375 REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT);
1376 REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
1377
1378 udelay(20);
1379
1380 bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);
1381
1382 return rc;
1383 }
1384
1385 static void
1386 bnx2_clear_ring_states(struct bnx2 *bp)
1387 {
1388 struct bnx2_napi *bnapi;
1389 struct bnx2_tx_ring_info *txr;
1390 struct bnx2_rx_ring_info *rxr;
1391 int i;
1392
1393 for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
1394 bnapi = &bp->bnx2_napi[i];
1395 txr = &bnapi->tx_ring;
1396 rxr = &bnapi->rx_ring;
1397
1398 txr->tx_cons = 0;
1399 txr->hw_tx_cons = 0;
1400 rxr->rx_prod_bseq = 0;
1401 rxr->rx_prod = 0;
1402 rxr->rx_cons = 0;
1403 rxr->rx_pg_prod = 0;
1404 rxr->rx_pg_cons = 0;
1405 }
1406 }
1407
1408 static void
1409 bnx2_init_tx_context(struct bnx2 *bp, u32 cid, struct bnx2_tx_ring_info *txr)
1410 {
1411 u32 val, offset0, offset1, offset2, offset3;
1412 u32 cid_addr = GET_CID_ADDR(cid);
1413
1414 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1415 offset0 = BNX2_L2CTX_TYPE_XI;
1416 offset1 = BNX2_L2CTX_CMD_TYPE_XI;
1417 offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI;
1418 offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI;
1419 } else {
1420 offset0 = BNX2_L2CTX_TYPE;
1421 offset1 = BNX2_L2CTX_CMD_TYPE;
1422 offset2 = BNX2_L2CTX_TBDR_BHADDR_HI;
1423 offset3 = BNX2_L2CTX_TBDR_BHADDR_LO;
1424 }
1425 val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2;
1426 bnx2_ctx_wr(bp, cid_addr, offset0, val);
1427
1428 val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
1429 bnx2_ctx_wr(bp, cid_addr, offset1, val);
1430
1431 val = (u64) txr->tx_desc_mapping >> 32;
1432 bnx2_ctx_wr(bp, cid_addr, offset2, val);
1433
1434 val = (u64) txr->tx_desc_mapping & 0xffffffff;
1435 bnx2_ctx_wr(bp, cid_addr, offset3, val);
1436 }
1437
1438 static void
1439 bnx2_init_tx_ring(struct bnx2 *bp, int ring_num)
1440 {
1441 struct tx_bd *txbd;
1442 u32 cid = TX_CID;
1443 struct bnx2_napi *bnapi;
1444 struct bnx2_tx_ring_info *txr;
1445
1446 bnapi = &bp->bnx2_napi[ring_num];
1447 txr = &bnapi->tx_ring;
1448
1449 if (ring_num == 0)
1450 cid = TX_CID;
1451 else
1452 cid = TX_TSS_CID + ring_num - 1;
1453
1454 bp->tx_wake_thresh = bp->tx_ring_size / 2;
1455
1456 txbd = &txr->tx_desc_ring[MAX_TX_DESC_CNT];
1457
1458 txbd->tx_bd_haddr_hi = (u64) txr->tx_desc_mapping >> 32;
1459 txbd->tx_bd_haddr_lo = (u64) txr->tx_desc_mapping & 0xffffffff;
1460
1461 txr->tx_prod = 0;
1462 txr->tx_prod_bseq = 0;
1463
1464 txr->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
1465 txr->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;
1466
1467 bnx2_init_tx_context(bp, cid, txr);
1468 }
1469
1470 #endif
1471
1472 static inline struct sk_buff *
1473 alloc_skb (u32 size)
1474 {
1475 struct sk_buff *skb;
1476 pow2_alloc (sizeof (struct sk_buff), (u8 **) &skb);
1477 if (!skb) return NULL;
1478 skb->len = size;
1479 pow2_alloc (size, (u8 **) &skb->data);
1480 if (!skb->data) return NULL;
1481 memset (skb->data, 0, size);
1482 return skb;
1483 }
1484
1485 static bool
1486 bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
1487 {
1488 struct sk_buff *skb;
1489 struct sw_bd *rx_buf = &rxr->rx_buf_ring[index];
1490 dma_addr_t mapping;
1491 struct rx_bd *rxbd = &rxr->rx_desc_ring[RX_RING(index)][RX_IDX(index)];
1492
1493 skb = alloc_skb(bp->rx_buf_size);
1494 if (skb == NULL) {
1495 return FALSE;
1496 }
1497
1498 mapping = (dma_addr_t) get_phys_addr (skb->data);
1499
1500 rx_buf->skb = skb;
1501 rx_buf->desc = (struct l2_fhdr *) skb->data;
1502
1503 rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
1504 rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
1505
1506 rxr->rx_prod_bseq += bp->rx_buf_use_size;
1507
1508 #if 0
1509 DLOG ("alloc_rx_skb: i=%d: skb=%p mapping=%p desc=%p",
1510 index, skb, mapping, rx_buf->desc);
1511 #endif
1512
1513 return TRUE;
1514 }
1515
1516 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1517 static void
1518 bnx2_init_rx_context(struct bnx2 *bp, u32 cid)
1519 {
1520 u32 val, rx_cid_addr = GET_CID_ADDR(cid);
1521
1522 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
1523 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
1524 val |= 0x02 << 8;
1525
1526 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1527 u32 lo_water, hi_water;
1528
1529 if (bp->flow_ctrl & FLOW_CTRL_TX)
1530 lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT;
1531 else
1532 lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS;
1533 if (lo_water >= bp->rx_ring_size)
1534 lo_water = 0;
1535
1536 hi_water = MIN (bp->rx_ring_size / 4, (int) lo_water + 16);
1537
1538 if (hi_water <= lo_water)
1539 lo_water = 0;
1540
1541 hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE;
1542 lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE;
1543
1544 if (hi_water > 0xf)
1545 hi_water = 0xf;
1546 else if (hi_water == 0)
1547 lo_water = 0;
1548 val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT);
1549 }
1550 DLOG ("init_rx_context: L2CTX_CTX_TYPE(%d) <- 0x%.08X",
1551 rx_cid_addr, val);
1552 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
1553 }
1554
1555 static void
1556 bnx2_init_rxbd_rings(struct rx_bd *rx_ring[], dma_addr_t dma[], u32 buf_size,
1557 int num_rings)
1558 {
1559 int i;
1560 struct rx_bd *rxbd;
1561
1562 for (i = 0; i < num_rings; i++) {
1563 int j;
1564
1565 rxbd = &rx_ring[i][0];
1566 for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) {
1567 rxbd->rx_bd_len = buf_size;
1568 rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
1569 }
1570 if (i == (num_rings - 1))
1571 j = 0;
1572 else
1573 j = i + 1;
1574 rxbd->rx_bd_haddr_hi = (u64) dma[j] >> 32;
1575 rxbd->rx_bd_haddr_lo = (u64) dma[j] & 0xffffffff;
1576 }
1577 }
1578
1579 static struct rx_bd *backup_rx_desc;
1580 static void
1581 bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
1582 {
1583 int i;
1584 u16 prod, ring_prod;
1585 u32 cid, rx_cid_addr, val;
1586 struct bnx2_rx_ring_info *rxr = &bp->rx_ring;
1587
1588 if (ring_num == 0)
1589 cid = RX_CID;
1590 else {
1591 return;
1592
1593 }
1594
1595 rx_cid_addr = GET_CID_ADDR(cid);
1596
1597 bnx2_init_rxbd_rings(rxr->rx_desc_ring, rxr->rx_desc_mapping,
1598 bp->rx_buf_use_size, bp->rx_max_ring);
1599
1600 bnx2_init_rx_context(bp, cid);
1601
1602 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1603 val = REG_RD(bp, BNX2_MQ_MAP_L2_5);
1604 REG_WR(bp, BNX2_MQ_MAP_L2_5, val | BNX2_MQ_MAP_L2_5_ARM);
1605 }
1606
1607 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
1608
1609 #if 0
1610 if (bp->rx_pg_ring_size) {
1611 bnx2_init_rxbd_rings(rxr->rx_pg_desc_ring,
1612 rxr->rx_pg_desc_mapping,
1613 PAGE_SIZE, bp->rx_max_pg_ring);
1614 val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
1615 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
1616 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
1617 BNX2_L2CTX_RBDC_JUMBO_KEY - ring_num);
1618
1619 val = (u64) rxr->rx_pg_desc_mapping[0] >> 32;
1620 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
1621
1622 val = (u64) rxr->rx_pg_desc_mapping[0] & 0xffffffff;
1623 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
1624
1625 if (CHIP_NUM(bp) == CHIP_NUM_5709)
1626 REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
1627 }
1628 #endif
1629
1630 val = (u64) rxr->rx_desc_mapping[0] >> 32;
1631 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
1632
1633 val = (u64) rxr->rx_desc_mapping[0] & 0xffffffff;
1634 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
1635
1636 #if 0
1637 ring_prod = prod = rxr->rx_pg_prod;
1638 for (i = 0; i < bp->rx_pg_ring_size; i++) {
1639 if (bnx2_alloc_rx_page(bp, rxr, ring_prod, GFP_KERNEL) < 0) {
1640 netdev_warn(bp->dev, "init'ed rx page ring %d with %d/%d pages only\n",
1641 ring_num, i, bp->rx_pg_ring_size);
1642 break;
1643 }
1644 prod = NEXT_RX_BD(prod);
1645 ring_prod = RX_PG_RING_IDX(prod);
1646 }
1647 rxr->rx_pg_prod = prod;
1648 #endif
1649
1650 ring_prod = prod = rxr->rx_prod;
1651 for (i = 0; i < bp->rx_ring_size; i++) {
1652 if (!bnx2_alloc_rx_skb(bp, rxr, ring_prod)) {
1653 DLOG ("init'ed rx ring %d with %d/%d skbs only",
1654 ring_num, i, bp->rx_ring_size);
1655 break;
1656 }
1657 prod = NEXT_RX_BD(prod);
1658 ring_prod = RX_RING_IDX(prod);
1659 }
1660
1661 rxr->rx_prod = prod;
1662 rxr->rx_prod_bseq = (prod - 1) * bp->rx_buf_use_size;
1663
1664 rxr->rx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_BDIDX;
1665 rxr->rx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_BSEQ;
1666 rxr->rx_pg_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_PG_BDIDX;
1667
1668
1669 REG_WR16(bp, rxr->rx_bidx_addr, prod);
1670
1671 REG_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
1672
1673 DLOG ("rx_prod=%d rx_bidx_addr=0x%x rx_prod_bseq=0x%x rx_cid_addr=%p",
1674 rxr->rx_prod, rxr->rx_bidx_addr, rxr->rx_prod_bseq, rx_cid_addr);
1675 DLOG (" csv: %d, %d", rxr->rx_prod, rxr->rx_prod_bseq);
1676
1677 pow2_alloc (RXBD_RING_SIZE, (u8 **) &backup_rx_desc);
1678 memcpy (backup_rx_desc, &rxr->rx_desc_ring[0][0], RXBD_RING_SIZE);
1679
1680
1681
1682
1683
1684
1685 }
1686
1687 static void
1688 bnx2_init_all_rings(struct bnx2 *bp)
1689 {
1690 int i;
1691 u32 val;
1692
1693
1694
1695
1696 #if 0
1697 REG_WR(bp, BNX2_TSCH_TSS_CFG, 0);
1698 for (i = 0; i < bp->num_tx_rings; i++)
1699 bnx2_init_tx_ring(bp, i);
1700
1701 if (bp->num_tx_rings > 1)
1702 REG_WR(bp, BNX2_TSCH_TSS_CFG, ((bp->num_tx_rings - 1) << 24) |
1703 (TX_TSS_CID << 7));
1704 #endif
1705
1706 REG_WR(bp, BNX2_RLUP_RSS_CONFIG, 0);
1707 bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, 0);
1708
1709 for (i = 0; i < bp->num_rx_rings; i++)
1710 bnx2_init_rx_ring(bp, i);
1711
1712 if (bp->num_rx_rings > 1) {
1713 u32 tbl_32;
1714 u8 *tbl = (u8 *) &tbl_32;
1715
1716 bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ,
1717 BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES);
1718
1719 for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) {
1720 tbl[i % 4] = i % (bp->num_rx_rings - 1);
1721 if ((i % 4) == 3)
1722 bnx2_reg_wr_ind(bp,
1723 BNX2_RXP_SCRATCH_RSS_TBL + i,
1724 __cpu_to_be32(tbl_32));
1725 }
1726
1727 val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI |
1728 BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_ALL_XI;
1729
1730 REG_WR(bp, BNX2_RLUP_RSS_CONFIG, val);
1731
1732 }
1733 }
1734
1735 #if 0
1736
1737 static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size)
1738 {
1739 u32 max, num_rings = 1;
1740
1741 while (ring_size > MAX_RX_DESC_CNT) {
1742 ring_size -= MAX_RX_DESC_CNT;
1743 num_rings++;
1744 }
1745
1746 max = max_size;
1747 while ((max & num_rings) == 0)
1748 max >>= 1;
1749
1750 if (num_rings != max)
1751 max <<= 1;
1752
1753 return max;
1754 }
1755
1756 static void
1757 bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
1758 {
1759 u32 rx_size, rx_space, jumbo_size;
1760
1761
1762 rx_size = bp->dev->mtu + ETH_HLEN + BNX2_RX_OFFSET + 8;
1763
1764 rx_space = SKB_DATA_ALIGN(rx_size + BNX2_RX_ALIGN) + NET_SKB_PAD +
1765 sizeof(struct skb_shared_info);
1766
1767 bp->rx_copy_thresh = BNX2_RX_COPY_THRESH;
1768 bp->rx_pg_ring_size = 0;
1769 bp->rx_max_pg_ring = 0;
1770 bp->rx_max_pg_ring_idx = 0;
1771 if ((rx_space > PAGE_SIZE) && !(bp->flags & BNX2_FLAG_JUMBO_BROKEN)) {
1772 int pages = PAGE_ALIGN(bp->dev->mtu - 40) >> PAGE_SHIFT;
1773
1774 jumbo_size = size * pages;
1775 if (jumbo_size > MAX_TOTAL_RX_PG_DESC_CNT)
1776 jumbo_size = MAX_TOTAL_RX_PG_DESC_CNT;
1777
1778 bp->rx_pg_ring_size = jumbo_size;
1779 bp->rx_max_pg_ring = bnx2_find_max_ring(jumbo_size,
1780 MAX_RX_PG_RINGS);
1781 bp->rx_max_pg_ring_idx = (bp->rx_max_pg_ring * RX_DESC_CNT) - 1;
1782 rx_size = BNX2_RX_COPY_THRESH + BNX2_RX_OFFSET;
1783 bp->rx_copy_thresh = 0;
1784 }
1785
1786 bp->rx_buf_use_size = rx_size;
1787
1788 bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
1789 bp->rx_jumbo_thresh = rx_size - BNX2_RX_OFFSET;
1790 bp->rx_ring_size = size;
1791 bp->rx_max_ring = bnx2_find_max_ring(size, MAX_RX_RINGS);
1792 bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
1793 }
1794
1795 static void
1796 bnx2_free_tx_skbs(struct bnx2 *bp)
1797 {
1798 int i;
1799
1800 for (i = 0; i < bp->num_tx_rings; i++) {
1801 struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
1802 struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
1803 int j;
1804
1805 if (txr->tx_buf_ring == NULL)
1806 continue;
1807
1808 for (j = 0; j < TX_DESC_CNT; ) {
1809 struct sw_tx_bd *tx_buf = &txr->tx_buf_ring[j];
1810 struct sk_buff *skb = tx_buf->skb;
1811 int k, last;
1812
1813 if (skb == NULL) {
1814 j++;
1815 continue;
1816 }
1817
1818 dma_unmap_single(&bp->pdev->dev,
1819 dma_unmap_addr(tx_buf, mapping),
1820 skb_headlen(skb),
1821 PCI_DMA_TODEVICE);
1822
1823 tx_buf->skb = NULL;
1824
1825 last = tx_buf->nr_frags;
1826 j++;
1827 for (k = 0; k < last; k++, j++) {
1828 tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)];
1829 dma_unmap_page(&bp->pdev->dev,
1830 dma_unmap_addr(tx_buf, mapping),
1831 skb_shinfo(skb)->frags[k].size,
1832 PCI_DMA_TODEVICE);
1833 }
1834 dev_kfree_skb(skb);
1835 }
1836 }
1837 }
1838
1839 static void
1840 bnx2_free_rx_skbs(struct bnx2 *bp)
1841 {
1842 int i;
1843
1844 for (i = 0; i < bp->num_rx_rings; i++) {
1845 struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
1846 struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
1847 int j;
1848
1849 if (rxr->rx_buf_ring == NULL)
1850 return;
1851
1852 for (j = 0; j < bp->rx_max_ring_idx; j++) {
1853 struct sw_bd *rx_buf = &rxr->rx_buf_ring[j];
1854 struct sk_buff *skb = rx_buf->skb;
1855
1856 if (skb == NULL)
1857 continue;
1858
1859 dma_unmap_single(&bp->pdev->dev,
1860 dma_unmap_addr(rx_buf, mapping),
1861 bp->rx_buf_use_size,
1862 PCI_DMA_FROMDEVICE);
1863
1864 rx_buf->skb = NULL;
1865
1866 dev_kfree_skb(skb);
1867 }
1868 for (j = 0; j < bp->rx_max_pg_ring_idx; j++)
1869 bnx2_free_rx_page(bp, rxr, j);
1870 }
1871 }
1872
1873 static void
1874 bnx2_free_skbs(struct bnx2 *bp)
1875 {
1876 bnx2_free_tx_skbs(bp);
1877 bnx2_free_rx_skbs(bp);
1878 }
1879
1880 static int
1881 bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
1882 {
1883 int rc;
1884
1885 rc = bnx2_reset_chip(bp, reset_code);
1886 bnx2_free_skbs(bp);
1887 if (rc)
1888 return rc;
1889
1890 if ((rc = bnx2_init_chip(bp)) != 0)
1891 return rc;
1892
1893 bnx2_init_all_rings(bp);
1894 return 0;
1895 }
1896
1897 static int
1898 bnx2_init_nic(struct bnx2 *bp, int reset_phy)
1899 {
1900 int rc;
1901
1902 if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
1903 return rc;
1904
1905 spinlock_lock(&bp->phy_lock);
1906
1907
1908
1909
1910
1911
1912
1913
1914 spinlock_unlock(&bp->phy_lock);
1915 return 0;
1916 }
1917 #endif
1918
1919 static inline void *
1920 vmalloc_pages (uint pages)
1921 {
1922 u32 phys = alloc_phys_frames (pages);
1923 if (phys == (u32) -1) return NULL;
1924 void *virt = map_contiguous_virtual_pages (phys | 3, pages);
1925 if (virt) return virt;
1926 free_phys_frames (phys, pages);
1927 return NULL;
1928 }
1929
1930 static inline void
1931 vfree_pages (void *m, uint pages)
1932 {
1933 u32 frame = (u32) get_phys_addr (m);
1934 unmap_virtual_pages (m, pages);
1935 free_phys_frames (frame, pages);
1936 }
1937
1938 #define PAGE_ALIGN(x) (((x) + (1<<PAGE_SHIFT) - 1) & ~((1<<PAGE_SHIFT) - 1))
1939 static bool
1940 bnx2_alloc_rx_mem (struct bnx2 *bp)
1941 {
1942 struct bnx2_rx_ring_info *rxr = &bp->rx_ring;
1943 int j;
1944
1945 DLOG ("RX_DESC_CNT=%d", RX_DESC_CNT);
1946 bp->rx_max_ring = 1;
1947 bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
1948 DLOG ("rx_max_ring_idx=%d", bp->rx_max_ring_idx);
1949 rxr->rx_buf_ring = vmalloc_pages (PAGE_ALIGN (SW_RXBD_RING_SIZE * bp->rx_max_ring) >> PAGE_SHIFT);
1950 if (!rxr->rx_buf_ring)
1951 goto abort;
1952 memset (rxr->rx_buf_ring, 0, (SW_RXBD_RING_SIZE * bp->rx_max_ring));
1953 DLOG ("rx_buf_ring=%p", rxr->rx_buf_ring);
1954
1955 for (j = 0; j < bp->rx_max_ring; j++)
1956 rxr->rx_desc_ring[j]=0;
1957 for (j = 0; j < bp->rx_max_ring; j++) {
1958 pow2_alloc (RXBD_RING_SIZE, (u8 **) &rxr->rx_desc_ring[j]);
1959 if (rxr->rx_desc_ring[j] == NULL)
1960 goto abort_rx_desc;
1961 rxr->rx_desc_mapping[j] = (u32) get_phys_addr (rxr->rx_desc_ring[j]);
1962 }
1963 DLOG ("rx_desc_ring[0]=%p", rxr->rx_desc_ring[0]);
1964
1965 bp->rx_pg_ring_size = 0;
1966 u32 rx_size = MAX_ETHERNET_PACKET_SIZE + ETH_HLEN + BNX2_RX_OFFSET + 8;
1967 bp->rx_buf_use_size = 2048;
1968
1969 bp->rx_buf_size = 2048;
1970 DLOG ("rx_buf_use_size=%d rx_buf_size=%d", bp->rx_buf_use_size, bp->rx_buf_size);
1971 bp->rx_jumbo_thresh = rx_size - BNX2_RX_OFFSET;
1972 rxr->rx_prod = 0;
1973 rxr->rx_prod_bseq = 0;
1974
1975 return TRUE;
1976 abort_rx_desc:
1977 for (j = 0; j < bp->rx_max_ring; j++) {
1978 if (rxr->rx_desc_ring[j])
1979 pow2_free ((u8 *) rxr->rx_desc_ring[j]);
1980 }
1981 vfree_pages (rxr->rx_buf_ring, (SW_RXBD_RING_SIZE * bp->rx_max_ring) >> PAGE_SHIFT);
1982 abort:
1983 return FALSE;
1984 }
1985
1986 static void
1987 bnx2_mac_reset (struct bnx2 *bp)
1988 {
1989 int i;
1990
1991 REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
1992 BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
1993 BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
1994 BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
1995 BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
1996 u32 val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
1997 udelay(5);
1998
1999 #define DRV_RESET_SIGNATURE 0x4841564b
2000 bnx2_reg_wr_ind(bp, HOST_VIEW_SHMEM_BASE +
2001
2002 0,
2003 DRV_RESET_SIGNATURE);
2004
2005 bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | BNX2_DRV_MSG_CODE_RESET, 1, 1);
2006
2007 val = REG_RD(bp, BNX2_MISC_ID);
2008 val =
2009 BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2010 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
2011 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
2012 REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
2013
2014 if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || (CHIP_ID(bp) == CHIP_ID_5706_A1)) {
2015 for (i = 0; i < 500; i++) {
2016 udelay(30);
2017 }
2018 }
2019
2020 for (i = 0; i < 10; i++) {
2021 val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
2022 if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2023 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
2024 break;
2025 }
2026 udelay(10);
2027 }
2028
2029 bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | BNX2_DRV_MSG_CODE_RESET, 1, 0);
2030 }
2031
2032 static u32
2033 rv2p_fw_fixup(u32 rv2p_proc, int idx, u32 loc, u32 rv2p_code)
2034 {
2035 switch (idx) {
2036 case RV2P_P1_FIXUP_PAGE_SIZE_IDX:
2037 rv2p_code &= ~RV2P_BD_PAGE_SIZE_MSK;
2038 rv2p_code |= RV2P_BD_PAGE_SIZE;
2039 break;
2040 }
2041 return rv2p_code;
2042 }
2043
2044 #define RV2P_PROC1 0
2045 #define RV2P_PROC2 1
2046 static void
2047 load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len,
2048 u32 rv2p_proc, u32 fixup_loc)
2049 {
2050 __le32 *rv2p_code_start = rv2p_code;
2051 int i;
2052 u32 val, cmd, addr;
2053
2054 if (rv2p_proc == RV2P_PROC1) {
2055 cmd = BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
2056 addr = BNX2_RV2P_PROC1_ADDR_CMD;
2057 } else {
2058 cmd = BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
2059 addr = BNX2_RV2P_PROC2_ADDR_CMD;
2060 }
2061
2062 for (i = 0; i < rv2p_code_len; i += 8) {
2063 REG_WR(bp, BNX2_RV2P_INSTR_HIGH, __le32_to_cpu(*rv2p_code));
2064 rv2p_code++;
2065 REG_WR(bp, BNX2_RV2P_INSTR_LOW, __le32_to_cpu(*rv2p_code));
2066 rv2p_code++;
2067
2068 val = (i / 8) | cmd;
2069 REG_WR(bp, addr, val);
2070 }
2071
2072 rv2p_code = rv2p_code_start;
2073 if (fixup_loc && ((fixup_loc * 4) < rv2p_code_len)) {
2074 u32 code;
2075
2076 code = __le32_to_cpu(*(rv2p_code + fixup_loc - 1));
2077 REG_WR(bp, BNX2_RV2P_INSTR_HIGH, code);
2078 code = __le32_to_cpu(*(rv2p_code + fixup_loc));
2079 code = rv2p_fw_fixup(rv2p_proc, 0, fixup_loc, code);
2080 REG_WR(bp, BNX2_RV2P_INSTR_LOW, code);
2081
2082 val = (fixup_loc / 2) | cmd;
2083 REG_WR(bp, addr, val);
2084 }
2085
2086
2087 if (rv2p_proc == RV2P_PROC1) {
2088 REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
2089 }
2090 else {
2091 REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
2092 }
2093 }
2094 #define RV2P_PROC1_MAX_BD_PAGE_LOC 9
2095 #define RV2P_PROC1_BD_PAGE_SIZE_MSK 0xffff
2096 #define RV2P_PROC1_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
2097 #define RV2P_PROC2_MAX_BD_PAGE_LOC 5
2098 #define RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
2099 #define RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
2100 #define XI_RV2P_PROC1_MAX_BD_PAGE_LOC 9
2101 #define XI_RV2P_PROC1_BD_PAGE_SIZE_MSK 0xffff
2102 #define XI_RV2P_PROC1_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
2103 #define XI90_RV2P_PROC1_MAX_BD_PAGE_LOC 9
2104 #define XI90_RV2P_PROC1_BD_PAGE_SIZE_MSK 0xffff
2105 #define XI90_RV2P_PROC1_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
2106 #define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5
2107 #define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
2108 #define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
2109 #define XI90_RV2P_PROC2_MAX_BD_PAGE_LOC 5
2110 #define XI90_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
2111 #define XI90_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
2112
2113 static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
2114 static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = {
2115 0x08000d98, 0x08000de0, 0x08000e20, 0x08000e6c, 0x08000ea0, 0x00000000
2116 };
2117 static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
2118 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
2119 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
2120 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
2121 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
2122 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
2123 0x00000001, 0x00000001, 0x00000001, 0x00000000 };
2124 static const u32 bnx2_CP_b06FwRodata[(0x154/4) + 1] = {
2125 0x08000f58, 0x08000db0, 0x08000fec, 0x08001094, 0x08000f80, 0x08000fc0,
2126 0x080011cc, 0x08000dcc, 0x080011f0, 0x08000e1c, 0x08001634, 0x080015dc,
2127 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x0800127c, 0x0800127c, 0x08000dcc,
2128 0x08000dcc, 0x08001580, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc,
2129 0x080013f0, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc,
2130 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc,
2131 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000fe0, 0x08000dcc, 0x08000dcc,
2132 0x08001530, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc,
2133 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc,
2134 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc, 0x08000dcc,
2135 0x0800145c, 0x08000dcc, 0x08000dcc, 0x08001370, 0x080012e0, 0x08002e94,
2136 0x08002e9c, 0x08002e64, 0x08002e70, 0x08002e7c, 0x08002e88, 0x080046b4,
2137 0x08003f00, 0x08004634, 0x080046b4, 0x080046b4, 0x080044b4, 0x080046b4,
2138 0x080046fc, 0x08005524, 0x080054e4, 0x080054b0, 0x08005484, 0x08005460,
2139 0x0800541c, 0x00000000 };
2140 static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
2141 static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
2142 0x080033f8, 0x080033f8, 0x08003370, 0x080033a8, 0x080033dc, 0x08003400,
2143 0x08003400, 0x08003400, 0x080032e0, 0x00000000 };
2144 static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
2145 static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
2146 static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
2147 static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
2148
2149 static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
2150 static const u32 bnx2_COM_b09FwRodata[(0x38/4) + 1] = {
2151 0x80080100, 0x80080080, 0x80080000, 0x00000c80, 0x00003200, 0x80080240,
2152 0x08000f10, 0x08000f68, 0x08000fac, 0x08001044, 0x08001084, 0x80080100,
2153 0x80080080, 0x80080000, 0x00000000 };
2154 static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
2155 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
2156 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
2157 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
2158 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
2159 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
2160 0x00000001, 0x00000001, 0x00000001, 0x00000000 };
2161 static const u32 bnx2_CP_b09FwRodata[(0x1c0/4) + 1] = {
2162 0x80080100, 0x80080080, 0x80080000, 0x00000c00, 0x00003080, 0x08001020,
2163 0x080010cc, 0x080010e4, 0x080010f8, 0x0800110c, 0x08001020, 0x08001020,
2164 0x08001140, 0x08001178, 0x08001188, 0x080011b0, 0x080018a0, 0x080018a0,
2165 0x080018d8, 0x080018d8, 0x080018ec, 0x080018bc, 0x08001b14, 0x08001ae0,
2166 0x08001b6c, 0x08001b6c, 0x08001bf4, 0x08001b24, 0x80080240, 0x08002280,
2167 0x080020cc, 0x080022a8, 0x08002340, 0x08002490, 0x080024dc, 0x08002600,
2168 0x08002508, 0x0800258c, 0x0800213c, 0x08002aa8, 0x08002a4c, 0x080020e8,
2169 0x080020e8, 0x080020e8, 0x08002674, 0x08002674, 0x080020e8, 0x080020e8,
2170 0x08002924, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x08002984,
2171 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8,
2172 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8,
2173 0x080020e8, 0x080020e8, 0x080024fc, 0x080020e8, 0x080020e8, 0x080029f4,
2174 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8,
2175 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8,
2176 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x080020e8, 0x08002848,
2177 0x080020e8, 0x080020e8, 0x080027bc, 0x08002718, 0x08003860, 0x08003834,
2178 0x08003800, 0x080037d4, 0x080037b4, 0x08003768, 0x80080100, 0x80080080,
2179 0x80080000, 0x80080080, 0x080047c8, 0x08004800, 0x08004748, 0x080047c8,
2180 0x080047c8, 0x08004528, 0x080047c8, 0x08004b9c, 0x00000000 };
2181 static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
2182 static const u32 bnx2_RXP_b09FwRodata[(0x124/4) + 1] = {
2183 0x0800330c, 0x0800330c, 0x080033e8, 0x080033bc, 0x080033a0, 0x080032f0,
2184 0x080032f0, 0x080032f0, 0x08003314, 0x80080100, 0x80080080, 0x80080000,
2185 0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e,
2186 0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x08007a88, 0x08007ab4,
2187 0x08007a94, 0x080079d0, 0x08007a94, 0x08007ad4, 0x08007a94, 0x080079d0,
2188 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0,
2189 0x080079d0, 0x080079d0, 0x080079d0, 0x08007ac4, 0x08007aa4, 0x080079d0,
2190 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0,
2191 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0, 0x080079d0, 0x08007aa4,
2192 0x08008090, 0x08007f38, 0x08008058, 0x08007f38, 0x08008028, 0x08007e20,
2193 0x08007f38, 0x08007f38, 0x08007f38, 0x08007f38, 0x08007f38, 0x08007f38,
2194 0x08007f38, 0x08007f38, 0x08007f38, 0x08007f38, 0x08007f38, 0x08007f38,
2195 0x08007f60, 0x00000000 };
2196 static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
2197 static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
2198 0x00000001, 0x00000000 };
2199 static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
2200 static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
2201 0x80000940, 0x80000900, 0x80080100, 0x80080080, 0x80080000, 0x800e0000,
2202 0x80080080, 0x80080000, 0x80000a80, 0x80000a00, 0x80000980, 0x80000900,
2203 0x00000000 };
2204
2205 struct fw_info {
2206 const u32 ver_major;
2207 const u32 ver_minor;
2208 const u32 ver_fix;
2209
2210 const u32 start_addr;
2211
2212
2213 const u32 text_addr;
2214 const u32 text_len;
2215 const u32 text_index;
2216 __le32 *text;
2217 const u8 *gz_text;
2218 const u32 gz_text_len;
2219
2220
2221 const u32 data_addr;
2222 const u32 data_len;
2223 const u32 data_index;
2224 const u32 *data;
2225
2226
2227 const u32 sbss_addr;
2228 const u32 sbss_len;
2229 const u32 sbss_index;
2230
2231
2232 const u32 bss_addr;
2233 const u32 bss_len;
2234 const u32 bss_index;
2235
2236
2237 const u32 rodata_addr;
2238 const u32 rodata_len;
2239 const u32 rodata_index;
2240 const u32 *rodata;
2241 };
2242
2243 struct cpu_reg {
2244 u32 mode;
2245 u32 mode_value_halt;
2246 u32 mode_value_sstep;
2247
2248 u32 state;
2249 u32 state_value_clear;
2250
2251 u32 gpr0;
2252 u32 evmask;
2253 u32 pc;
2254 u32 inst;
2255 u32 bp;
2256
2257 u32 spad_base;
2258
2259 u32 mips_view_base;
2260 };
2261
2262
2263 static const struct cpu_reg cpu_reg_com = {
2264 .mode = BNX2_COM_CPU_MODE,
2265 .mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT,
2266 .mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA,
2267 .state = BNX2_COM_CPU_STATE,
2268 .state_value_clear = 0xffffff,
2269 .gpr0 = BNX2_COM_CPU_REG_FILE,
2270 .evmask = BNX2_COM_CPU_EVENT_MASK,
2271 .pc = BNX2_COM_CPU_PROGRAM_COUNTER,
2272 .inst = BNX2_COM_CPU_INSTRUCTION,
2273 .bp = BNX2_COM_CPU_HW_BREAKPOINT,
2274 .spad_base = BNX2_COM_SCRATCH,
2275 .mips_view_base = 0x8000000,
2276 };
2277
2278
2279 static const struct cpu_reg cpu_reg_cp = {
2280 .mode = BNX2_CP_CPU_MODE,
2281 .mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT,
2282 .mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA,
2283 .state = BNX2_CP_CPU_STATE,
2284 .state_value_clear = 0xffffff,
2285 .gpr0 = BNX2_CP_CPU_REG_FILE,
2286 .evmask = BNX2_CP_CPU_EVENT_MASK,
2287 .pc = BNX2_CP_CPU_PROGRAM_COUNTER,
2288 .inst = BNX2_CP_CPU_INSTRUCTION,
2289 .bp = BNX2_CP_CPU_HW_BREAKPOINT,
2290 .spad_base = BNX2_CP_SCRATCH,
2291 .mips_view_base = 0x8000000,
2292 };
2293
2294
2295 static const struct cpu_reg cpu_reg_rxp = {
2296 .mode = BNX2_RXP_CPU_MODE,
2297 .mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT,
2298 .mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA,
2299 .state = BNX2_RXP_CPU_STATE,
2300 .state_value_clear = 0xffffff,
2301 .gpr0 = BNX2_RXP_CPU_REG_FILE,
2302 .evmask = BNX2_RXP_CPU_EVENT_MASK,
2303 .pc = BNX2_RXP_CPU_PROGRAM_COUNTER,
2304 .inst = BNX2_RXP_CPU_INSTRUCTION,
2305 .bp = BNX2_RXP_CPU_HW_BREAKPOINT,
2306 .spad_base = BNX2_RXP_SCRATCH,
2307 .mips_view_base = 0x8000000,
2308 };
2309
2310
2311 static const struct cpu_reg cpu_reg_tpat = {
2312 .mode = BNX2_TPAT_CPU_MODE,
2313 .mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT,
2314 .mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA,
2315 .state = BNX2_TPAT_CPU_STATE,
2316 .state_value_clear = 0xffffff,
2317 .gpr0 = BNX2_TPAT_CPU_REG_FILE,
2318 .evmask = BNX2_TPAT_CPU_EVENT_MASK,
2319 .pc = BNX2_TPAT_CPU_PROGRAM_COUNTER,
2320 .inst = BNX2_TPAT_CPU_INSTRUCTION,
2321 .bp = BNX2_TPAT_CPU_HW_BREAKPOINT,
2322 .spad_base = BNX2_TPAT_SCRATCH,
2323 .mips_view_base = 0x8000000,
2324 };
2325
2326
2327 static const struct cpu_reg cpu_reg_txp = {
2328 .mode = BNX2_TXP_CPU_MODE,
2329 .mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT,
2330 .mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA,
2331 .state = BNX2_TXP_CPU_STATE,
2332 .state_value_clear = 0xffffff,
2333 .gpr0 = BNX2_TXP_CPU_REG_FILE,
2334 .evmask = BNX2_TXP_CPU_EVENT_MASK,
2335 .pc = BNX2_TXP_CPU_PROGRAM_COUNTER,
2336 .inst = BNX2_TXP_CPU_INSTRUCTION,
2337 .bp = BNX2_TXP_CPU_HW_BREAKPOINT,
2338 .spad_base = BNX2_TXP_SCRATCH,
2339 .mips_view_base = 0x8000000,
2340 };
2341
2342 CASSERT (0x7534 == sizeof (bnx2_RXP_b06FwText), bnx2_RXP_b06FwText);
2343 static struct fw_info bnx2_rxp_fw_06 = {
2344
2345 .ver_major = 0x5,
2346 .ver_minor = 0x0,
2347 .ver_fix = 0x0,
2348
2349 .start_addr = 0x080031d8,
2350
2351 .text_addr = 0x08000000,
2352
2353 .text_index = 0x0,
2354 .text = (__le32 *) bnx2_RXP_b06FwText,
2355 .text_len = sizeof(bnx2_RXP_b06FwText),
2356
2357 .data_addr = 0x00000000,
2358 .data_len = 0x0,
2359 .data_index = 0x0,
2360 .data = bnx2_RXP_b06FwData,
2361
2362 .sbss_addr = 0x08007580,
2363 .sbss_len = 0x54,
2364 .sbss_index = 0x0,
2365
2366 .bss_addr = 0x080075d8,
2367 .bss_len = 0x450,
2368 .bss_index = 0x0,
2369
2370 .rodata_addr = 0x08007534,
2371 .rodata_len = 0x24,
2372 .rodata_index = 0x0,
2373 .rodata = bnx2_RXP_b06FwRodata,
2374 };
2375
2376 CASSERT (0x175c == sizeof (bnx2_TPAT_b06FwText), bnx2_TPAT_b06FwText);
2377 static struct fw_info bnx2_tpat_fw_06 = {
2378
2379 .ver_major = 0x5,
2380 .ver_minor = 0x0,
2381 .ver_fix = 0x0,
2382
2383 .start_addr = 0x08000488,
2384
2385 .text_addr = 0x08000400,
2386
2387 .text_index = 0x0,
2388 .text = (__le32 *) bnx2_TPAT_b06FwText,
2389 .text_len = sizeof(bnx2_TPAT_b06FwText),
2390
2391 .data_addr = 0x00000000,
2392 .data_len = 0x0,
2393 .data_index = 0x0,
2394 .data = bnx2_TPAT_b06FwData,
2395
2396 .sbss_addr = 0x08001b80,
2397 .sbss_len = 0x44,
2398 .sbss_index = 0x0,
2399
2400 .bss_addr = 0x08001bc4,
2401 .bss_len = 0x450,
2402 .bss_index = 0x0,
2403
2404 .rodata_addr = 0x00000000,
2405 .rodata_len = 0x0,
2406 .rodata_index = 0x0,
2407 .rodata = bnx2_TPAT_b06FwRodata,
2408 };
2409
2410 CASSERT (0x3b38 == sizeof (bnx2_TXP_b06FwText), bnx2_TXP_b06FwText);
2411 static struct fw_info bnx2_txp_fw_06 = {
2412
2413 .ver_major = 0x5,
2414 .ver_minor = 0x0,
2415 .ver_fix = 0x0,
2416
2417 .start_addr = 0x080000a8,
2418
2419 .text_addr = 0x08000000,
2420
2421 .text_index = 0x0,
2422 .text = (__le32 *) bnx2_TXP_b06FwText,
2423 .text_len = sizeof(bnx2_TXP_b06FwText),
2424
2425 .data_addr = 0x00000000,
2426 .data_len = 0x0,
2427 .data_index = 0x0,
2428 .data = bnx2_TXP_b06FwData,
2429
2430 .sbss_addr = 0x08003b60,
2431 .sbss_len = 0x68,
2432 .sbss_index = 0x0,
2433
2434 .bss_addr = 0x08003bc8,
2435 .bss_len = 0x14c,
2436 .bss_index = 0x0,
2437
2438 .rodata_addr = 0x00000000,
2439 .rodata_len = 0x0,
2440 .rodata_index = 0x0,
2441 .rodata = bnx2_TXP_b06FwRodata,
2442 };
2443
2444 CASSERT (0x4cc8 == sizeof (bnx2_COM_b06FwText), bnx2_COM_b06FwText);
2445 static struct fw_info bnx2_com_fw_06 = {
2446
2447 .ver_major = 0x5,
2448 .ver_minor = 0x0,
2449 .ver_fix = 0x0,
2450
2451 .start_addr = 0x08000110,
2452
2453 .text_addr = 0x08000000,
2454
2455 .text_index = 0x0,
2456 .text = (__le32 *) bnx2_COM_b06FwText,
2457 .text_len = sizeof(bnx2_COM_b06FwText),
2458
2459 .data_addr = 0x00000000,
2460 .data_len = 0x0,
2461 .data_index = 0x0,
2462 .data = bnx2_COM_b06FwData,
2463
2464 .sbss_addr = 0x08004d00,
2465 .sbss_len = 0x38,
2466 .sbss_index = 0x0,
2467
2468 .bss_addr = 0x08004d38,
2469 .bss_len = 0xc4,
2470 .bss_index = 0x0,
2471
2472 .rodata_addr = 0x08004cc8,
2473 .rodata_len = 0x14,
2474 .rodata_index = 0x0,
2475 .rodata = bnx2_COM_b06FwRodata,
2476 };
2477
2478 CASSERT (0x58c4 == sizeof (bnx2_CP_b06FwText), bnx2_CP_b06FwText);
2479 static struct fw_info bnx2_cp_fw_06 = {
2480
2481 .ver_major = 0x5,
2482 .ver_minor = 0x0,
2483 .ver_fix = 0x0,
2484
2485 .start_addr = 0x08000088,
2486
2487 .text_addr = 0x08000000,
2488
2489 .text_index = 0x0,
2490 .text = (__le32 *) bnx2_CP_b06FwText,
2491 .text_len = sizeof(bnx2_CP_b06FwText),
2492
2493 .data_addr = 0x08005a40,
2494 .data_len = 0x84,
2495 .data_index = 0x0,
2496 .data = bnx2_CP_b06FwData,
2497
2498 .sbss_addr = 0x08005ac4,
2499 .sbss_len = 0xf1,
2500 .sbss_index = 0x0,
2501
2502 .bss_addr = 0x08005bb8,
2503 .bss_len = 0x5d8,
2504 .bss_index = 0x0,
2505
2506 .rodata_addr = 0x080058c4,
2507 .rodata_len = 0x154,
2508 .rodata_index = 0x0,
2509 .rodata = bnx2_CP_b06FwRodata,
2510 };
2511
2512 CASSERT (0x51f8 == sizeof (bnx2_COM_b09FwText), bnx2_COM_b09FwText);
2513 static struct fw_info bnx2_com_fw_09 = {
2514
2515 .ver_major = 0x5,
2516 .ver_minor = 0x0,
2517 .ver_fix = 0x0,
2518
2519 .start_addr = 0x08000110,
2520
2521 .text_addr = 0x08000000,
2522
2523 .text_index = 0x0,
2524 .text = (__le32 *) bnx2_COM_b09FwText,
2525 .text_len = sizeof(bnx2_COM_b09FwText),
2526
2527 .data_addr = 0x00000000,
2528 .data_len = 0x0,
2529 .data_index = 0x0,
2530 .data = bnx2_COM_b09FwData,
2531
2532 .sbss_addr = 0x08005260,
2533 .sbss_len = 0x30,
2534 .sbss_index = 0x0,
2535
2536 .bss_addr = 0x08005290,
2537 .bss_len = 0x10c,
2538 .bss_index = 0x0,
2539
2540 .rodata_addr = 0x080051f8,
2541 .rodata_len = 0x38,
2542 .rodata_index = 0x0,
2543 .rodata = bnx2_COM_b09FwRodata,
2544 };
2545
2546 CASSERT (0x528c == sizeof (bnx2_CP_b09FwText), bnx2_CP_b09FwText);
2547 static struct fw_info bnx2_cp_fw_09 = {
2548
2549 .ver_major = 0x5,
2550 .ver_minor = 0x0,
2551 .ver_fix = 0x0,
2552
2553 .start_addr = 0x08000088,
2554
2555 .text_addr = 0x08000000,
2556
2557 .text_index = 0x0,
2558 .text = (__le32 *) bnx2_CP_b09FwText,
2559 .text_len = sizeof(bnx2_CP_b09FwText),
2560
2561 .data_addr = 0x08005480,
2562 .data_len = 0x84,
2563 .data_index = 0x0,
2564 .data = bnx2_CP_b09FwData,
2565
2566 .sbss_addr = 0x08005508,
2567 .sbss_len = 0x9d,
2568 .sbss_index = 0x0,
2569
2570 .bss_addr = 0x080055a8,
2571 .bss_len = 0x19c,
2572 .bss_index = 0x0,
2573
2574 .rodata_addr = 0x0800528c,
2575 .rodata_len = 0x1c0,
2576 .rodata_index = 0x0,
2577 .rodata = bnx2_CP_b09FwRodata,
2578 };
2579
2580 CASSERT (0x8108 == sizeof (bnx2_RXP_b09FwText), bnx2_RXP_b09FwText);
2581 static struct fw_info bnx2_rxp_fw_09 = {
2582
2583 .ver_major = 0x5,
2584 .ver_minor = 0x0,
2585 .ver_fix = 0x0,
2586
2587 .start_addr = 0x080031d8,
2588
2589 .text_addr = 0x08000000,
2590
2591 .text_index = 0x0,
2592 .text = (__le32 *) bnx2_RXP_b09FwText,
2593 .text_len = sizeof(bnx2_RXP_b09FwText),
2594
2595 .data_addr = 0x00000000,
2596 .data_len = 0x0,
2597 .data_index = 0x0,
2598 .data = bnx2_RXP_b09FwData,
2599
2600 .sbss_addr = 0x08008260,
2601 .sbss_len = 0x60,
2602 .sbss_index = 0x0,
2603
2604 .bss_addr = 0x080082c0,
2605 .bss_len = 0x60,
2606 .bss_index = 0x0,
2607
2608 .rodata_addr = 0x08008108,
2609 .rodata_len = 0x124,
2610 .rodata_index = 0x0,
2611 .rodata = bnx2_RXP_b09FwRodata,
2612 };
2613
2614 CASSERT (0x17ec == sizeof (bnx2_TPAT_b09FwText), bnx2_TPAT_b09FwText);
2615 static struct fw_info bnx2_tpat_fw_09 = {
2616
2617 .ver_major = 0x5,
2618 .ver_minor = 0x0,
2619 .ver_fix = 0x0,
2620
2621 .start_addr = 0x08000488,
2622
2623 .text_addr = 0x08000400,
2624
2625 .text_index = 0x0,
2626 .text = (__le32 *) bnx2_TPAT_b09FwText,
2627 .text_len = sizeof(bnx2_TPAT_b09FwText),
2628
2629 .data_addr = 0x00000000,
2630 .data_len = 0x0,
2631 .data_index = 0x0,
2632 .data = bnx2_TPAT_b09FwData,
2633
2634 .sbss_addr = 0x08001c20,
2635 .sbss_len = 0x3c,
2636 .sbss_index = 0x0,
2637
2638 .bss_addr = 0x08001c5c,
2639 .bss_len = 0x344,
2640 .bss_index = 0x0,
2641
2642 .rodata_addr = 0x08001bec,
2643 .rodata_len = 0x4,
2644 .rodata_index = 0x0,
2645 .rodata = bnx2_TPAT_b09FwRodata,
2646 };
2647
2648 CASSERT (0x38d0 == sizeof (bnx2_TXP_b09FwText), bnx2_TXP_b09FwText);
2649 static struct fw_info bnx2_txp_fw_09 = {
2650
2651 .ver_major = 0x5,
2652 .ver_minor = 0x0,
2653 .ver_fix = 0x0,
2654
2655 .start_addr = 0x080000a8,
2656
2657 .text_addr = 0x08000000,
2658
2659 .text_index = 0x0,
2660 .text = (__le32 *) bnx2_TXP_b09FwText,
2661 .text_len = sizeof(bnx2_TXP_b09FwText),
2662
2663 .data_addr = 0x00000000,
2664 .data_len = 0x0,
2665 .data_index = 0x0,
2666 .data = bnx2_TXP_b09FwData,
2667
2668 .sbss_addr = 0x08003920,
2669 .sbss_len = 0x64,
2670 .sbss_index = 0x0,
2671
2672 .bss_addr = 0x08003988,
2673 .bss_len = 0x24c,
2674 .bss_index = 0x0,
2675
2676 .rodata_addr = 0x080038d0,
2677 .rodata_len = 0x30,
2678 .rodata_index = 0x0,
2679 .rodata = bnx2_TXP_b09FwRodata,
2680 };
2681
2682 static int
2683 load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
2684 {
2685 u32 offset;
2686 u32 val;
2687 int rc;
2688
2689
2690 val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
2691 val |= cpu_reg->mode_value_halt;
2692 bnx2_reg_wr_ind(bp, cpu_reg->mode, val);
2693 bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
2694
2695
2696 offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
2697
2698 if (fw->text) {
2699 int j;
2700 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
2701 bnx2_reg_wr_ind(bp, offset, __le32_to_cpu(fw->text[j]));
2702 }
2703 }
2704
2705
2706 offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
2707 if (fw->data) {
2708 int j;
2709
2710 for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
2711 bnx2_reg_wr_ind(bp, offset, fw->data[j]);
2712 }
2713 }
2714
2715
2716 offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
2717 if (fw->sbss_len) {
2718 int j;
2719
2720 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
2721 bnx2_reg_wr_ind(bp, offset, 0);
2722 }
2723 }
2724
2725
2726 offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
2727 if (fw->bss_len) {
2728 int j;
2729
2730 for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
2731 bnx2_reg_wr_ind(bp, offset, 0);
2732 }
2733 }
2734
2735
2736 offset = cpu_reg->spad_base +
2737 (fw->rodata_addr - cpu_reg->mips_view_base);
2738 if (fw->rodata) {
2739 int j;
2740
2741 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
2742 bnx2_reg_wr_ind(bp, offset, fw->rodata[j]);
2743 }
2744 }
2745
2746
2747 bnx2_reg_wr_ind(bp, cpu_reg->inst, 0);
2748 bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr);
2749
2750
2751 val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
2752 val &= ~cpu_reg->mode_value_halt;
2753 bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
2754 bnx2_reg_wr_ind(bp, cpu_reg->mode, val);
2755
2756 return 0;
2757 }
2758
2759 static bool
2760 bnx2_init_cpus(struct bnx2 *bp)
2761 {
2762 struct fw_info *fw;
2763 int rc = 0, rv2p_len;
2764 const void *rv2p;
2765 u32 fixup_loc;
2766
2767
2768 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
2769 if ((CHIP_ID(bp) == CHIP_ID_5709_A0) ||
2770 (CHIP_ID(bp) == CHIP_ID_5709_A1)) {
2771 rv2p = bnx2_xi90_rv2p_proc1;
2772 rv2p_len = sizeof(bnx2_xi90_rv2p_proc1);
2773 fixup_loc = XI90_RV2P_PROC1_MAX_BD_PAGE_LOC;
2774 } else {
2775 rv2p = bnx2_xi_rv2p_proc1;
2776 rv2p_len = sizeof(bnx2_xi_rv2p_proc1);
2777 fixup_loc = XI_RV2P_PROC1_MAX_BD_PAGE_LOC;
2778 }
2779 } else {
2780 rv2p = bnx2_rv2p_proc1;
2781 rv2p_len = sizeof(bnx2_rv2p_proc1);
2782 fixup_loc = RV2P_PROC1_MAX_BD_PAGE_LOC;
2783 }
2784
2785 load_rv2p_fw(bp, (__le32 *) rv2p, rv2p_len, RV2P_PROC1, fixup_loc);
2786
2787 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
2788 if ((CHIP_ID(bp) == CHIP_ID_5709_A0) ||
2789 (CHIP_ID(bp) == CHIP_ID_5709_A1)) {
2790 rv2p = bnx2_xi90_rv2p_proc2;
2791 rv2p_len = sizeof(bnx2_xi90_rv2p_proc2);
2792 fixup_loc = XI90_RV2P_PROC2_MAX_BD_PAGE_LOC;
2793 } else {
2794 rv2p = bnx2_xi_rv2p_proc2;
2795 rv2p_len = sizeof(bnx2_xi_rv2p_proc2);
2796 fixup_loc = XI_RV2P_PROC2_MAX_BD_PAGE_LOC;
2797 }
2798 } else {
2799 rv2p = bnx2_rv2p_proc2;
2800 rv2p_len = sizeof(bnx2_rv2p_proc2);
2801 fixup_loc = RV2P_PROC2_MAX_BD_PAGE_LOC;
2802 }
2803
2804 load_rv2p_fw(bp, (__le32 *) rv2p, rv2p_len, RV2P_PROC2, fixup_loc);
2805
2806
2807 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2808 fw = &bnx2_rxp_fw_09;
2809 else
2810 fw = &bnx2_rxp_fw_06;
2811
2812 rc = load_cpu_fw(bp, &cpu_reg_rxp, fw);
2813 if (rc)
2814 goto init_cpu_err;
2815
2816
2817 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2818 fw = &bnx2_txp_fw_09;
2819 else
2820 fw = &bnx2_txp_fw_06;
2821
2822 rc = load_cpu_fw(bp, &cpu_reg_txp, fw);
2823 if (rc)
2824 goto init_cpu_err;
2825
2826
2827 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2828 fw = &bnx2_tpat_fw_09;
2829 else
2830 fw = &bnx2_tpat_fw_06;
2831
2832 rc = load_cpu_fw(bp, &cpu_reg_tpat, fw);
2833 if (rc)
2834 goto init_cpu_err;
2835
2836
2837 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2838 fw = &bnx2_com_fw_09;
2839 else
2840 fw = &bnx2_com_fw_06;
2841
2842 rc = load_cpu_fw(bp, &cpu_reg_com, fw);
2843 if (rc)
2844 goto init_cpu_err;
2845
2846
2847 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2848 fw = &bnx2_cp_fw_09;
2849 else
2850 fw = &bnx2_cp_fw_06;
2851
2852 rc = load_cpu_fw(bp, &cpu_reg_cp, fw);
2853 if (rc)
2854 goto init_cpu_err;
2855
2856 return TRUE;
2857
2858 init_cpu_err:
2859 DLOG ("init_cpu_err rc=%d", rc);
2860 return FALSE;
2861 }
2862
2863 struct bnx2_cpus_scratch_debug {
2864 u32 offset;
2865 char *name;
2866 };
2867
2868 #define BNX2_SCRATCH_FW_VERSION_OFFSET 0x10
2869 #define BNX2_TPAT_SCRATCH_FW_VERSION_OFFSET 0x410
2870
2871 static void
2872 bnx2_print_fw_versions(struct bnx2 *bp)
2873 {
2874
2875 const struct bnx2_cpus_scratch_debug cpus_scratch[] = {
2876 { .offset = BNX2_TXP_SCRATCH + BNX2_SCRATCH_FW_VERSION_OFFSET,
2877 .name = "TXP" },
2878 { .offset = BNX2_TPAT_SCRATCH +
2879 BNX2_TPAT_SCRATCH_FW_VERSION_OFFSET,
2880 .name = "TPAT" },
2881 { .offset = BNX2_RXP_SCRATCH + BNX2_SCRATCH_FW_VERSION_OFFSET,
2882 .name = "RXP" },
2883 { .offset = BNX2_COM_SCRATCH + BNX2_SCRATCH_FW_VERSION_OFFSET,
2884 .name = "COM" },
2885 { .offset = BNX2_CP_SCRATCH + BNX2_SCRATCH_FW_VERSION_OFFSET,
2886 .name = "CP" },
2887
2888 };
2889 int i;
2890
2891 logger_printf("bnx2: CPU fw versions: ");
2892 for (i = 0; i < ARRAY_SIZE(cpus_scratch); i++) {
2893
2894
2895 char version[12];
2896 int j;
2897
2898
2899 for (j = 0; j < sizeof(version); j += 4) {
2900 u32 val;
2901
2902 val = bnx2_reg_rd_ind(bp, cpus_scratch[i].offset + j);
2903 val = __be32_to_cpu(val);
2904 memcpy(&version[j], &val, sizeof(val));
2905 }
2906
2907
2908 version[11] = '\0';
2909
2910 logger_printf("%s: '%s' ", cpus_scratch[i].name, version);
2911 }
2912 logger_printf("\n");
2913 }
2914
2915 static void
2916 bnx2_mac_init (struct bnx2 *bp)
2917 {
2918 int rc;
2919
2920
2921 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
2922
2923
2924 u32 val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP | BNX2_DMA_CONFIG_DATA_WORD_SWAP |
2925 BNX2_DMA_CONFIG_CNTL_WORD_SWAP;
2926
2927 val |= (5 << 12) | (3 << 16);
2928
2929 val |= (0x2 << 20) | (1 << 11);
2930
2931 if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
2932 (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & BNX2_FLAG_PCIX)) {
2933 val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
2934 }
2935 REG_WR(bp, BNX2_DMA_CONFIG, val);
2936
2937 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
2938 val = REG_RD(bp, BNX2_TDMA_CONFIG);
2939 val |= BNX2_TDMA_CONFIG_ONE_DMA;
2940 REG_WR(bp, BNX2_TDMA_CONFIG, val);
2941 }
2942
2943 if (bp->flags & BNX2_FLAG_PCIX) {
2944 u16 val16;
2945
2946 #define PCI_X_CMD 2
2947 #define PCI_X_CMD_ERO 0x0002
2948
2949 pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
2950 &val16);
2951 pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
2952 val16 & ~PCI_X_CMD_ERO);
2953 }
2954
2955
2956 REG_WR(bp,
2957 BNX2_MISC_ENABLE_SET_BITS,
2958 BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
2959 BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
2960 BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
2961
2962
2963 u32 vcid;
2964 vcid = 96;
2965 while (vcid) {
2966 u32 vcid_addr, pcid_addr, offset;
2967 vcid--;
2968 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
2969 u32 new_vcid;
2970 vcid_addr = GET_PCID_ADDR(vcid);
2971 if (vcid & 0x8) {
2972 new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7);
2973 }
2974 else {
2975 new_vcid = vcid;
2976 }
2977 pcid_addr = GET_PCID_ADDR(new_vcid);
2978 }
2979 else {
2980 vcid_addr = GET_CID_ADDR(vcid);
2981 pcid_addr = vcid_addr;
2982 }
2983 vcid_addr = GET_CID_ADDR(vcid);
2984 pcid_addr = vcid_addr;
2985 REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
2986 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
2987
2988 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
2989 bnx2_ctx_wr(bp, 0x00, offset, 0);
2990 }
2991 REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
2992 REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
2993 }
2994
2995 if (!bnx2_init_cpus (bp)) {
2996 DLOG ("bnx2_init_cpus failed");
2997 return;
2998 }
2999 DLOG ("Initialized onboard CPUs");
3000 bnx2_print_fw_versions (bp);
3001
3002
3003
3004 u8 *mac_addr = bp->mac_addr;
3005 val = (mac_addr[0] << 8) | mac_addr[1];
3006 REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val);
3007 val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | (mac_addr[4] << 8) | mac_addr[5];
3008 REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val);
3009
3010
3011 val = REG_RD(bp, BNX2_MQ_CONFIG);
3012 val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
3013 val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
3014 REG_WR(bp, BNX2_MQ_CONFIG, val);
3015
3016
3017 val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
3018 REG_WR(bp, BNX2_MQ_KNL_WIND_END, val);
3019 REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
3020
3021
3022 val = (BCM_PAGE_BITS - 8) << 24;
3023 REG_WR(bp, BNX2_RV2P_CONFIG, val);
3024 val = REG_RD(bp, BNX2_TBDR_CONFIG);
3025 val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE;
3026 val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
3027 REG_WR(bp, BNX2_TBDR_CONFIG, val);
3028
3029
3030 val = mac_addr[0] + (mac_addr[1] << 8) + (mac_addr[2] << 16) +
3031 mac_addr[3] + (mac_addr[4] << 8) + (mac_addr[5] << 16);
3032 REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
3033
3034
3035 val = MAX_ETHERNET_PACKET_SIZE + ETH_HLEN + ETHERNET_FCS_SIZE;
3036 REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
3037
3038
3039 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
3040
3041
3042 REG_WR(bp, BNX2_HC_STATUS_ADDR_L,
3043 (u64) bp->status_blk_mapping & 0xffffffff);
3044 REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
3045
3046
3047 REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
3048 (u64) bp->stats_blk_mapping & 0xffffffff);
3049 REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H, (u64) bp->stats_blk_mapping >> 32);
3050
3051
3052
3053 if (CHIP_ID(bp) == CHIP_ID_5706_A1) {
3054 REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS);
3055 }
3056 else {
3057 REG_WR(bp, BNX2_HC_CONFIG,
3058 BNX2_HC_CONFIG_RX_TMR_MODE |
3059 BNX2_HC_CONFIG_TX_TMR_MODE |
3060 BNX2_HC_CONFIG_COLLECT_STATS);
3061 }
3062 REG_WR(bp, BNX2_HC_CONFIG,
3063 BNX2_HC_CONFIG_RX_TMR_MODE |
3064 BNX2_HC_CONFIG_TX_TMR_MODE |
3065 BNX2_HC_CONFIG_COLLECT_STATS);
3066
3067
3068 REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
3069
3070
3071 REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
3072
3073
3074 u32 rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
3075 u32 sort_mode = BNX2_RPM_SORT_USER0_MC_EN | BNX2_RPM_SORT_USER0_BC_EN | 1;
3076 REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
3077 REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
3078 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
3079 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
3080
3081
3082 rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
3083 1, 0);
3084
3085
3086
3087
3088
3089
3090 REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
3091 REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
3092 udelay(20);
3093
3094 bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);
3095 }
3096
3097 static void
3098 bnx2_enable_int(struct bnx2 *bp)
3099 {
3100 int i;
3101
3102 #if 0
3103 for (i = 0; i < bp->irq_nvecs; i++) {
3104 struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
3105
3106 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
3107 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
3108 BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
3109 bnapi->last_status_idx);
3110
3111 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
3112 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
3113 bnapi->last_status_idx);
3114 }
3115 #else
3116 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, (0 << 24) |
3117 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
3118 BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
3119 bp->status_blk->status_idx);
3120
3121 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, (0 << 24) |
3122 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
3123 bp->status_blk->status_idx);
3124 #endif
3125
3126 REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
3127 }
3128
3129 #define subsystem_vendor(pdev) ((pdev)->data[11] & 0x0000FFFF)
3130 #define subsystem_device(pdev) (((pdev)->data[11] & 0xFFFF0000) >> 16)
3131
3132 static bool
3133 bnx2_init_board (pci_device *pdev)
3134 {
3135 struct bnx2 *bp = pdev->drvdata;
3136 int rc, i, j;
3137 pci_irq_t irq;
3138 uint irq_line, irq_pin;
3139
3140 bp->flags = bp->phy_flags = 0;
3141
3142 pow2_alloc (sizeof(struct statistics_block), (u8 **) &bp->temp_stats_blk);
3143
3144
3145
3146
3147 u32 phys_addr; void *base_addr;
3148 pci_decode_bar (pdev->index, 0, &phys_addr, NULL, NULL);
3149
3150 if (!pci_get_interrupt (pdev->index, &irq_line, &irq_pin)) {
3151 DLOG ("Unable to get IRQ");
3152 goto err_out_free_stats;
3153 }
3154
3155 if (pci_irq_find (pdev->bus, pdev->slot, irq_pin, &irq)) {
3156
3157 DLOG ("Found PCI routing entry irq.gsi=0x%x", irq.gsi);
3158 if (!pci_irq_map_handler (&irq, bnx2_irq_handler, 0x01,
3159 IOAPIC_DESTINATION_LOGICAL,
3160 IOAPIC_DELIVERY_FIXED))
3161 goto err_out_free_stats;
3162 irq_line = irq.gsi;
3163 } else {
3164 DLOG ("Unable to find PCI routing entry");
3165 goto err_out_free_stats;
3166 }
3167
3168
3169 #define NUM_PAGES 20
3170 base_addr = map_contiguous_virtual_pages (phys_addr | 3, NUM_PAGES);
3171 if (!base_addr)
3172 goto err_out_free_stats;
3173
3174 DLOG ("phys_addr=0x%.08X base_addr=%p", phys_addr, base_addr);
3175
3176 spinlock_init (&bp->phy_lock);
3177 spinlock_init (&bp->indirect_lock);
3178
3179
3180
3181 bp->regview = base_addr;
3182
3183
3184
3185
3186
3187
3188 pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
3189 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
3190 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
3191
3192 bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
3193 DLOG ("chip_id=0x%X", bp->chip_id);
3194
3195 #if 0
3196 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
3197 if (pci_find_capability(pdev, PCI_CAP_ID_EXP) == 0) {
3198 dev_err(&pdev->dev,
3199 "Cannot find PCIE capability, aborting\n");
3200 rc = -EIO;
3201 goto err_out_unmap;
3202 }
3203 bp->flags |= BNX2_FLAG_PCIE;
3204 if (CHIP_REV(bp) == CHIP_REV_Ax)
3205 bp->flags |= BNX2_FLAG_JUMBO_BROKEN;
3206 } else {
3207 bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
3208 if (bp->pcix_cap == 0) {
3209 dev_err(&pdev->dev,
3210 "Cannot find PCIX capability, aborting\n");
3211 rc = -EIO;
3212 goto err_out_unmap;
3213 }
3214 bp->flags |= BNX2_FLAG_BROKEN_STATS;
3215 }
3216
3217 if (CHIP_NUM(bp) == CHIP_NUM_5709 && CHIP_REV(bp) != CHIP_REV_Ax) {
3218 if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
3219 bp->flags |= BNX2_FLAG_MSIX_CAP;
3220 }
3221
3222 if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) {
3223 if (pci_find_capability(pdev, PCI_CAP_ID_MSI))
3224 bp->flags |= BNX2_FLAG_MSI_CAP;
3225 }
3226
3227
3228 if (CHIP_NUM(bp) == CHIP_NUM_5708)
3229 persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
3230 else
3231 persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
3232
3233
3234 if (pci_set_dma_mask(pdev, dma_mask) == 0) {
3235 dev->features |= NETIF_F_HIGHDMA;
3236 rc = pci_set_consistent_dma_mask(pdev, persist_dma_mask);
3237 if (rc) {
3238 dev_err(&pdev->dev,
3239 "pci_set_consistent_dma_mask failed, aborting\n");
3240 goto err_out_unmap;
3241 }
3242 } else if ((rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
3243 dev_err(&pdev->dev, "System does not support DMA, aborting\n");
3244 goto err_out_unmap;
3245 }
3246
3247 if (!(bp->flags & BNX2_FLAG_PCIE))
3248 bnx2_get_pci_speed(bp);
3249
3250
3251 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
3252 reg = REG_RD(bp, PCI_COMMAND);
3253 reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
3254 REG_WR(bp, PCI_COMMAND, reg);
3255 }
3256 else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
3257 !(bp->flags & BNX2_FLAG_PCIX)) {
3258
3259 dev_err(&pdev->dev,
3260 "5706 A1 can only be used in a PCIX bus, aborting\n");
3261 goto err_out_unmap;
3262 }
3263
3264 #endif
3265
3266 bnx2_init_nvram(bp);
3267
3268 u32 reg = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_SIGNATURE);
3269
3270 if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
3271 BNX2_SHM_HDR_SIGNATURE_SIG) {
3272 u32 off = pdev->func << 2;
3273
3274 bp->shmem_base = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_ADDR_0 + off);
3275 } else
3276 bp->shmem_base = HOST_VIEW_SHMEM_BASE;
3277
3278
3279
3280
3281 reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_SIGNATURE);
3282
3283 if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
3284 BNX2_DEV_INFO_SIGNATURE_MAGIC) {
3285 DLOG("Firmware not running, aborting");
3286 rc = -ENODEV;
3287 goto err_out_unmap;
3288 }
3289
3290 #if 0
3291 bnx2_read_vpd_fw_ver(bp);
3292
3293 j = strlen(bp->fw_version);
3294 reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_BC_REV);
3295 for (i = 0; i < 3 && j < 24; i++) {
3296 u8 num, k, skip0;
3297
3298 if (i == 0) {
3299 bp->fw_version[j++] = 'b';
3300 bp->fw_version[j++] = 'c';
3301 bp->fw_version[j++] = ' ';
3302 }
3303 num = (u8) (reg >> (24 - (i * 8)));
3304 for (k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
3305 if (num >= k || !skip0 || k == 1) {
3306 bp->fw_version[j++] = (num / k) + '0';
3307 skip0 = 0;
3308 }
3309 }
3310 if (i != 2)
3311 bp->fw_version[j++] = '.';
3312 }
3313 reg = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE);
3314 if (reg & BNX2_PORT_FEATURE_WOL_ENABLED)
3315 bp->wol = 1;
3316
3317 if (reg & BNX2_PORT_FEATURE_ASF_ENABLED) {
3318 bp->flags |= BNX2_FLAG_ASF_ENABLE;
3319
3320 for (i = 0; i < 30; i++) {
3321 reg = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
3322 if (reg & BNX2_CONDITION_MFW_RUN_MASK)
3323 break;
3324 udelay(10*1000);
3325 }
3326 }
3327 reg = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
3328 reg &= BNX2_CONDITION_MFW_RUN_MASK;
3329 if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN &&
3330 reg != BNX2_CONDITION_MFW_RUN_NONE) {
3331 u32 addr = bnx2_shmem_rd(bp, BNX2_MFW_VER_PTR);
3332
3333 if (j < 32)
3334 bp->fw_version[j++] = ' ';
3335 for (i = 0; i < 3 && j < 28; i++) {
3336 reg = bnx2_reg_rd_ind(bp, addr + i * 4);
3337 reg = ___constant_swab32(reg);
3338 memcpy(&bp->fw_version[j], ®, 4);
3339 j += 4;
3340 }
3341 }
3342 #endif
3343
3344 reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_MAC_UPPER);
3345 bp->mac_addr[0] = (u8) (reg >> 8);
3346 bp->mac_addr[1] = (u8) reg;
3347
3348 reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_MAC_LOWER);
3349 bp->mac_addr[2] = (u8) (reg >> 24);
3350 bp->mac_addr[3] = (u8) (reg >> 16);
3351 bp->mac_addr[4] = (u8) (reg >> 8);
3352 bp->mac_addr[5] = (u8) reg;
3353
3354 DLOG ("mac_addr=%.02X:%.02X:%.02X:%.02X:%.02X:%.02X",
3355 bp->mac_addr[0], bp->mac_addr[1], bp->mac_addr[2],
3356 bp->mac_addr[3], bp->mac_addr[4], bp->mac_addr[5]);
3357
3358 bp->tx_ring_size = MAX_TX_DESC_CNT;
3359 bp->rx_ring_size = 255;
3360 #if 0
3361 bnx2_set_rx_ring_size(bp, 255);
3362 #endif
3363
3364 bp->rx_csum = 1;
3365
3366 bp->tx_quick_cons_trip_int = 2;
3367 bp->tx_quick_cons_trip = 20;
3368 bp->tx_ticks_int = 18;
3369 bp->tx_ticks = 80;
3370
3371 bp->rx_quick_cons_trip_int = 2;
3372 bp->rx_quick_cons_trip = 12;
3373 bp->rx_ticks_int = 18;
3374 bp->rx_ticks = 18;
3375
3376 #define USEC_PER_SEC 1000000
3377 bp->stats_ticks = USEC_PER_SEC & BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
3378
3379 bp->current_interval = BNX2_TIMER_INTERVAL;
3380
3381 bp->phy_addr = 1;
3382
3383
3384 if (CHIP_NUM(bp) == CHIP_NUM_5709)
3385 bnx2_get_5709_media(bp);
3386 else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
3387 bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
3388
3389 bp->phy_port = PORT_TP;
3390 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
3391 bp->phy_port = PORT_FIBRE;
3392 reg = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG);
3393 if (!(reg & BNX2_SHARED_HW_CFG_GIG_LINK_ON_VAUX)) {
3394 bp->flags |= BNX2_FLAG_NO_WOL;
3395 bp->wol = 0;
3396 }
3397 if (CHIP_NUM(bp) == CHIP_NUM_5706) {
3398
3399
3400
3401
3402 if (subsystem_vendor (bp->pdev) == PCI_VENDOR_ID_HP &&
3403 subsystem_device (bp->pdev) == 0x310c)
3404 bp->phy_flags |= BNX2_PHY_FLAG_NO_PARALLEL;
3405 } else {
3406 bp->phy_addr = 2;
3407 if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
3408 bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE;
3409 }
3410 } else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
3411 CHIP_NUM(bp) == CHIP_NUM_5708)
3412 bp->phy_flags |= BNX2_PHY_FLAG_CRC_FIX;
3413 else if (CHIP_NUM(bp) == CHIP_NUM_5709 &&
3414 (CHIP_REV(bp) == CHIP_REV_Ax ||
3415 CHIP_REV(bp) == CHIP_REV_Bx))
3416 bp->phy_flags |= BNX2_PHY_FLAG_DIS_EARLY_DAC;
3417
3418 bnx2_init_fw_cap(bp);
3419
3420 if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
3421 (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
3422 (CHIP_ID(bp) == CHIP_ID_5708_B1) ||
3423 !(REG_RD(bp, BNX2_PCI_CONFIG_3) & BNX2_PCI_CONFIG_3_VAUX_PRESET)) {
3424 bp->flags |= BNX2_FLAG_NO_WOL;
3425 bp->wol = 0;
3426 }
3427
3428 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
3429 bp->tx_quick_cons_trip_int =
3430 bp->tx_quick_cons_trip;
3431 bp->tx_ticks_int = bp->tx_ticks;
3432 bp->rx_quick_cons_trip_int =
3433 bp->rx_quick_cons_trip;
3434 bp->rx_ticks_int = bp->rx_ticks;
3435 bp->comp_prod_trip_int = bp->comp_prod_trip;
3436 bp->com_ticks_int = bp->com_ticks;
3437 bp->cmd_ticks_int = bp->cmd_ticks;
3438 }
3439
3440 bnx2_set_default_link(bp);
3441 bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
3442
3443 #if 0
3444 init_timer(&bp->timer);
3445 bp->timer.expires = RUN_AT(BNX2_TIMER_INTERVAL);
3446 bp->timer.data = (unsigned long) bp;
3447 bp->timer.function = bnx2_timer;
3448 #endif
3449
3450 return TRUE;
3451
3452 err_out_unmap:
3453 if (bp->regview) {
3454
3455 bp->regview = NULL;
3456 }
3457
3458 err_out_release:
3459
3460 unmap_virtual_pages (base_addr, NUM_PAGES);
3461
3462 err_out_disable:
3463
3464
3465
3466 err_out_free_stats:
3467 pow2_free ((u8 *) bp->temp_stats_blk);
3468
3469 return FALSE;
3470 }
3471
3472 #define MII_BMCR 0x00
3473 #define MII_BMSR 0x01
3474 #define MII_PHYSID1 0x02
3475 #define MII_PHYSID2 0x03
3476 #define MII_ADVERTISE 0x04
3477 #define MII_LPA 0x05
3478 #define MII_EXPANSION 0x06
3479 #define MII_CTRL1000 0x09
3480 #define MII_STAT1000 0x0a
3481 #define MII_ESTATUS 0x0f
3482 #define MII_DCOUNTER 0x12
3483 #define MII_FCSCOUNTER 0x13
3484 #define MII_NWAYTEST 0x14
3485 #define MII_RERRCOUNTER 0x15
3486 #define MII_SREVISION 0x16
3487 #define MII_RESV1 0x17
3488 #define MII_LBRERROR 0x18
3489 #define MII_PHYADDR 0x19
3490 #define MII_RESV2 0x1a
3491 #define MII_TPISTATUS 0x1b
3492 #define MII_NCONFIG 0x1c
3493
3494
3495 #define BMCR_RESV 0x003f
3496 #define BMCR_SPEED1000 0x0040
3497 #define BMCR_CTST 0x0080
3498 #define BMCR_FULLDPLX 0x0100
3499 #define BMCR_ANRESTART 0x0200
3500 #define BMCR_ISOLATE 0x0400
3501 #define BMCR_PDOWN 0x0800
3502 #define BMCR_ANENABLE 0x1000
3503 #define BMCR_SPEED100 0x2000
3504 #define BMCR_LOOPBACK 0x4000
3505 #define BMCR_RESET 0x8000
3506
3507
3508 #define BMSR_ERCAP 0x0001
3509 #define BMSR_JCD 0x0002
3510 #define BMSR_LSTATUS 0x0004
3511 #define BMSR_ANEGCAPABLE 0x0008
3512 #define BMSR_RFAULT 0x0010
3513 #define BMSR_ANEGCOMPLETE 0x0020
3514 #define BMSR_RESV 0x00c0
3515 #define BMSR_ESTATEN 0x0100
3516 #define BMSR_100HALF2 0x0200
3517 #define BMSR_100FULL2 0x0400
3518 #define BMSR_10HALF 0x0800
3519 #define BMSR_10FULL 0x1000
3520 #define BMSR_100HALF 0x2000
3521 #define BMSR_100FULL 0x4000
3522 #define BMSR_100BASE4 0x8000
3523
3524
3525 #define ADVERTISE_SLCT 0x001f
3526 #define ADVERTISE_CSMA 0x0001
3527 #define ADVERTISE_10HALF 0x0020
3528 #define ADVERTISE_1000XFULL 0x0020
3529 #define ADVERTISE_10FULL 0x0040
3530 #define ADVERTISE_1000XHALF 0x0040
3531 #define ADVERTISE_100HALF 0x0080
3532 #define ADVERTISE_1000XPAUSE 0x0080
3533 #define ADVERTISE_100FULL 0x0100
3534 #define ADVERTISE_1000XPSE_ASYM 0x0100
3535 #define ADVERTISE_100BASE4 0x0200
3536 #define ADVERTISE_PAUSE_CAP 0x0400
3537 #define ADVERTISE_PAUSE_ASYM 0x0800
3538 #define ADVERTISE_RESV 0x1000
3539 #define ADVERTISE_RFAULT 0x2000
3540 #define ADVERTISE_LPACK 0x4000
3541 #define ADVERTISE_NPAGE 0x8000
3542
3543 #define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
3544 ADVERTISE_CSMA)
3545 #define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
3546 ADVERTISE_100HALF | ADVERTISE_100FULL)
3547
3548
3549 #define ADVERTISE_1000FULL 0x0200
3550 #define ADVERTISE_1000HALF 0x0100
3551
3552 static int
3553 bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
3554 {
3555 u32 val1;
3556 int i, ret;
3557
3558 if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
3559 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3560 val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
3561
3562 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
3563 REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3564
3565 udelay(40);
3566 }
3567
3568 val1 = (bp->phy_addr << 21) | (reg << 16) |
3569 BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT |
3570 BNX2_EMAC_MDIO_COMM_START_BUSY;
3571 REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
3572
3573 for (i = 0; i < 50; i++) {
3574 udelay(10);
3575
3576 val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
3577 if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
3578 udelay(5);
3579
3580 val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
3581 val1 &= BNX2_EMAC_MDIO_COMM_DATA;
3582
3583 break;
3584 }
3585 }
3586
3587 if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) {
3588 *val = 0x0;
3589 ret = -EBUSY;
3590 }
3591 else {
3592 *val = val1;
3593 ret = 0;
3594 }
3595
3596 if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
3597 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3598 val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
3599
3600 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
3601 REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3602
3603 udelay(40);
3604 }
3605
3606 return ret;
3607 }
3608
3609 static int
3610 bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
3611 {
3612 u32 val1;
3613 int i, ret;
3614
3615 if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
3616 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3617 val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
3618
3619 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
3620 REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3621
3622 udelay(40);
3623 }
3624
3625 val1 = (bp->phy_addr << 21) | (reg << 16) | val |
3626 BNX2_EMAC_MDIO_COMM_COMMAND_WRITE |
3627 BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT;
3628 REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
3629
3630 for (i = 0; i < 50; i++) {
3631 udelay(10);
3632
3633 val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
3634 if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
3635 udelay(5);
3636 break;
3637 }
3638 }
3639
3640 if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)
3641 ret = -EBUSY;
3642 else
3643 ret = 0;
3644
3645 if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
3646 val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3647 val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
3648
3649 REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
3650 REG_RD(bp, BNX2_EMAC_MDIO_MODE);
3651
3652 udelay(40);
3653 }
3654
3655 return ret;
3656 }
3657
3658 static int
3659 bnx2_reset_phy(struct bnx2 *bp)
3660 {
3661 int i;
3662 u32 reg;
3663
3664 bnx2_write_phy(bp, bp->mii_bmcr, BMCR_RESET);
3665
3666 #define PHY_RESET_MAX_WAIT 100
3667 for (i = 0; i < PHY_RESET_MAX_WAIT; i++) {
3668 udelay(10);
3669
3670 bnx2_read_phy(bp, bp->mii_bmcr, ®);
3671 if (!(reg & BMCR_RESET)) {
3672 udelay(20);
3673 break;
3674 }
3675 }
3676 if (i == PHY_RESET_MAX_WAIT) {
3677 return -EBUSY;
3678 }
3679 return 0;
3680 }
3681
3682 static int
3683 bnx2_init_5709s_phy(struct bnx2 *bp, int reset_phy)
3684 {
3685 u32 val;
3686
3687 bp->mii_bmcr = MII_BMCR + 0x10;
3688 bp->mii_bmsr = MII_BMSR + 0x10;
3689 bp->mii_bmsr1 = MII_BNX2_GP_TOP_AN_STATUS1;
3690 bp->mii_adv = MII_ADVERTISE + 0x10;
3691 bp->mii_lpa = MII_LPA + 0x10;
3692 bp->mii_up1 = MII_BNX2_OVER1G_UP1;
3693
3694 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_AER);
3695 bnx2_write_phy(bp, MII_BNX2_AER_AER, MII_BNX2_AER_AER_AN_MMD);
3696
3697 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
3698 if (reset_phy)
3699 bnx2_reset_phy(bp);
3700
3701 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_SERDES_DIG);
3702
3703 bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_1000XCTL1, &val);
3704 val &= ~MII_BNX2_SD_1000XCTL1_AUTODET;
3705 val |= MII_BNX2_SD_1000XCTL1_FIBER;
3706
3707 if (bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG) & 0x80000000)
3708 val |= (1 << 3);
3709 bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_1000XCTL1, val);
3710
3711 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G);
3712 bnx2_read_phy(bp, MII_BNX2_OVER1G_UP1, &val);
3713 if (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)
3714 val |= BCM5708S_UP1_2G5;
3715 else
3716 val &= ~BCM5708S_UP1_2G5;
3717 bnx2_write_phy(bp, MII_BNX2_OVER1G_UP1, val);
3718
3719 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_BAM_NXTPG);
3720 bnx2_read_phy(bp, MII_BNX2_BAM_NXTPG_CTL, &val);
3721 val |= MII_BNX2_NXTPG_CTL_T2 | MII_BNX2_NXTPG_CTL_BAM;
3722 bnx2_write_phy(bp, MII_BNX2_BAM_NXTPG_CTL, val);
3723
3724 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_CL73_USERB0);
3725
3726 val = MII_BNX2_CL73_BAM_EN | MII_BNX2_CL73_BAM_STA_MGR_EN |
3727 MII_BNX2_CL73_BAM_NP_AFT_BP_EN;
3728 bnx2_write_phy(bp, MII_BNX2_CL73_BAM_CTL1, val);
3729
3730 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
3731
3732 return 0;
3733 }
3734
3735 #define MTU 1500
3736
3737 static int
3738 bnx2_init_5706s_phy(struct bnx2 *bp, int reset_phy)
3739 {
3740 if (reset_phy)
3741 bnx2_reset_phy(bp);
3742
3743 bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
3744
3745 if (CHIP_NUM(bp) == CHIP_NUM_5706)
3746 REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);
3747
3748 if (MTU > 1500) {
3749 u32 val;
3750
3751
3752 bnx2_write_phy(bp, 0x18, 0x7);
3753 bnx2_read_phy(bp, 0x18, &val);
3754 bnx2_write_phy(bp, 0x18, (val & 0xfff8) | 0x4000);
3755
3756 bnx2_write_phy(bp, 0x1c, 0x6c00);
3757 bnx2_read_phy(bp, 0x1c, &val);
3758 bnx2_write_phy(bp, 0x1c, (val & 0x3ff) | 0xec02);
3759 }
3760 else {
3761 u32 val;
3762
3763 bnx2_write_phy(bp, 0x18, 0x7);
3764 bnx2_read_phy(bp, 0x18, &val);
3765 bnx2_write_phy(bp, 0x18, val & ~0x4007);
3766
3767 bnx2_write_phy(bp, 0x1c, 0x6c00);
3768 bnx2_read_phy(bp, 0x1c, &val);
3769 bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00);
3770 }
3771
3772 return 0;
3773 }
3774
3775 static int
3776 bnx2_init_copper_phy(struct bnx2 *bp, int reset_phy)
3777 {
3778 u32 val;
3779
3780 if (reset_phy)
3781 bnx2_reset_phy(bp);
3782
3783 if (bp->phy_flags & BNX2_PHY_FLAG_CRC_FIX) {
3784 bnx2_write_phy(bp, 0x18, 0x0c00);
3785 bnx2_write_phy(bp, 0x17, 0x000a);
3786 bnx2_write_phy(bp, 0x15, 0x310b);
3787 bnx2_write_phy(bp, 0x17, 0x201f);
3788 bnx2_write_phy(bp, 0x15, 0x9506);
3789 bnx2_write_phy(bp, 0x17, 0x401f);
3790 bnx2_write_phy(bp, 0x15, 0x14e2);
3791 bnx2_write_phy(bp, 0x18, 0x0400);
3792 }
3793
3794 if (bp->phy_flags & BNX2_PHY_FLAG_DIS_EARLY_DAC) {
3795 bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS,
3796 MII_BNX2_DSP_EXPAND_REG | 0x8);
3797 bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val);
3798 val &= ~(1 << 8);
3799 bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val);
3800 }
3801
3802 if (MTU > 1500) {
3803
3804 bnx2_write_phy(bp, 0x18, 0x7);
3805 bnx2_read_phy(bp, 0x18, &val);
3806 bnx2_write_phy(bp, 0x18, val | 0x4000);
3807
3808 bnx2_read_phy(bp, 0x10, &val);
3809 bnx2_write_phy(bp, 0x10, val | 0x1);
3810 }
3811 else {
3812 bnx2_write_phy(bp, 0x18, 0x7);
3813 bnx2_read_phy(bp, 0x18, &val);
3814 bnx2_write_phy(bp, 0x18, val & ~0x4007);
3815
3816 bnx2_read_phy(bp, 0x10, &val);
3817 bnx2_write_phy(bp, 0x10, val & ~0x1);
3818 }
3819
3820
3821 bnx2_write_phy(bp, 0x18, 0x7007);
3822 bnx2_read_phy(bp, 0x18, &val);
3823 bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
3824 return 0;
3825 }
3826
3827 static int
3828 bnx2_init_5708s_phy(struct bnx2 *bp, int reset_phy)
3829 {
3830 u32 val;
3831
3832 if (reset_phy)
3833 bnx2_reset_phy(bp);
3834
3835 bp->mii_up1 = BCM5708S_UP1;
3836
3837 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
3838 bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
3839 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
3840
3841 bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
3842 val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
3843 bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
3844
3845 bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
3846 val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
3847 bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
3848
3849 if (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) {
3850 bnx2_read_phy(bp, BCM5708S_UP1, &val);
3851 val |= BCM5708S_UP1_2G5;
3852 bnx2_write_phy(bp, BCM5708S_UP1, val);
3853 }
3854
3855 if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
3856 (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
3857 (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
3858
3859 bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
3860 BCM5708S_BLK_ADDR_TX_MISC);
3861 bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
3862 val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
3863 bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
3864 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
3865 }
3866
3867 val = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_CONFIG) &
3868 BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
3869
3870 if (val) {
3871 u32 is_backplane;
3872
3873 is_backplane = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG);
3874 if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
3875 bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
3876 BCM5708S_BLK_ADDR_TX_MISC);
3877 bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
3878 bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
3879 BCM5708S_BLK_ADDR_DIG);
3880 }
3881 }
3882 return 0;
3883 }
3884
3885 static void
3886 bnx2_resolve_flow_ctrl(struct bnx2 *bp)
3887 {
3888 u32 local_adv, remote_adv;
3889
3890 bp->flow_ctrl = 0;
3891 if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) !=
3892 (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) {
3893
3894 if (bp->duplex == DUPLEX_FULL) {
3895 bp->flow_ctrl = bp->req_flow_ctrl;
3896 }
3897 return;
3898 }
3899
3900 if (bp->duplex != DUPLEX_FULL) {
3901 return;
3902 }
3903
3904 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
3905 (CHIP_NUM(bp) == CHIP_NUM_5708)) {
3906 u32 val;
3907
3908 bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
3909 if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
3910 bp->flow_ctrl |= FLOW_CTRL_TX;
3911 if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
3912 bp->flow_ctrl |= FLOW_CTRL_RX;
3913 return;
3914 }
3915
3916 bnx2_read_phy(bp, bp->mii_adv, &local_adv);
3917 bnx2_read_phy(bp, bp->mii_lpa, &remote_adv);
3918
3919 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
3920 u32 new_local_adv = 0;
3921 u32 new_remote_adv = 0;
3922
3923 if (local_adv & ADVERTISE_1000XPAUSE)
3924 new_local_adv |= ADVERTISE_PAUSE_CAP;
3925 if (local_adv & ADVERTISE_1000XPSE_ASYM)
3926 new_local_adv |= ADVERTISE_PAUSE_ASYM;
3927 if (remote_adv & ADVERTISE_1000XPAUSE)
3928 new_remote_adv |= ADVERTISE_PAUSE_CAP;
3929 if (remote_adv & ADVERTISE_1000XPSE_ASYM)
3930 new_remote_adv |= ADVERTISE_PAUSE_ASYM;
3931
3932 local_adv = new_local_adv;
3933 remote_adv = new_remote_adv;
3934 }
3935
3936
3937 if (local_adv & ADVERTISE_PAUSE_CAP) {
3938 if(local_adv & ADVERTISE_PAUSE_ASYM) {
3939 if (remote_adv & ADVERTISE_PAUSE_CAP) {
3940 bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
3941 }
3942 else if (remote_adv & ADVERTISE_PAUSE_ASYM) {
3943 bp->flow_ctrl = FLOW_CTRL_RX;
3944 }
3945 }
3946 else {
3947 if (remote_adv & ADVERTISE_PAUSE_CAP) {
3948 bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
3949 }
3950 }
3951 }
3952 else if (local_adv & ADVERTISE_PAUSE_ASYM) {
3953 if ((remote_adv & ADVERTISE_PAUSE_CAP) &&
3954 (remote_adv & ADVERTISE_PAUSE_ASYM)) {
3955
3956 bp->flow_ctrl = FLOW_CTRL_TX;
3957 }
3958 }
3959 }
3960
3961 static void
3962 bnx2_init_all_rx_contexts(struct bnx2 *bp)
3963 {
3964 int i;
3965 u32 cid;
3966
3967 for (i = 0, cid = RX_CID; i < bp->num_rx_rings; i++, cid++) {
3968 if (i == 1)
3969 cid = RX_RSS_CID;
3970 bnx2_init_rx_context(bp, cid);
3971 }
3972 }
3973
3974 static void
3975 bnx2_set_mac_link(struct bnx2 *bp)
3976 {
3977 u32 val;
3978
3979 REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620);
3980 if (bp->link_up && (bp->line_speed == SPEED_1000) &&
3981 (bp->duplex == DUPLEX_HALF)) {
3982 REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff);
3983 }
3984
3985
3986 val = REG_RD(bp, BNX2_EMAC_MODE);
3987 DLOG ("set_mac_link: EMAC_MODE=0x%.08X line_speed=%d duplex=%d", val, bp->line_speed, bp->duplex);
3988 val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
3989 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
3990 BNX2_EMAC_MODE_25G_MODE);
3991
3992 if (bp->link_up) {
3993 switch (bp->line_speed) {
3994 case SPEED_10:
3995 if (CHIP_NUM(bp) != CHIP_NUM_5706) {
3996 val |= BNX2_EMAC_MODE_PORT_MII_10M;
3997 break;
3998 }
3999
4000 case SPEED_100:
4001 val |= BNX2_EMAC_MODE_PORT_MII;
4002 break;
4003 case SPEED_2500:
4004 val |= BNX2_EMAC_MODE_25G_MODE;
4005
4006 case SPEED_1000:
4007 val |= BNX2_EMAC_MODE_PORT_GMII;
4008 break;
4009 }
4010 }
4011 else {
4012 val |= BNX2_EMAC_MODE_PORT_GMII;
4013 }
4014
4015
4016 if (bp->duplex == DUPLEX_HALF)
4017 val |= BNX2_EMAC_MODE_HALF_DUPLEX;
4018 REG_WR(bp, BNX2_EMAC_MODE, val);
4019
4020
4021 bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN;
4022
4023 if (bp->flow_ctrl & FLOW_CTRL_RX)
4024 bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN;
4025 DLOG ("set_mac_link: EMAC_RX_MODE <- 0x%.08X", bp->rx_mode);
4026 REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode);
4027
4028
4029 val = REG_RD(bp, BNX2_EMAC_TX_MODE);
4030 val &= ~BNX2_EMAC_TX_MODE_FLOW_EN;
4031
4032 if (bp->flow_ctrl & FLOW_CTRL_TX)
4033 val |= BNX2_EMAC_TX_MODE_FLOW_EN;
4034 REG_WR(bp, BNX2_EMAC_TX_MODE, val);
4035
4036
4037 REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
4038 DLOG ("set_mac_link: EMAC_STATUS=0x%.08X", REG_RD (bp, BNX2_EMAC_STATUS));
4039
4040 if (CHIP_NUM(bp) == CHIP_NUM_5709)
4041 bnx2_init_all_rx_contexts(bp);
4042 }
4043
4044 static u32
4045 bnx2_phy_get_pause_adv(struct bnx2 *bp)
4046 {
4047 u32 adv = 0;
4048
4049 if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) ==
4050 (FLOW_CTRL_RX | FLOW_CTRL_TX)) {
4051
4052 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
4053 adv = ADVERTISE_1000XPAUSE;
4054 }
4055 else {
4056 adv = ADVERTISE_PAUSE_CAP;
4057 }
4058 }
4059 else if (bp->req_flow_ctrl & FLOW_CTRL_TX) {
4060 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
4061 adv = ADVERTISE_1000XPSE_ASYM;
4062 }
4063 else {
4064 adv = ADVERTISE_PAUSE_ASYM;
4065 }
4066 }
4067 else if (bp->req_flow_ctrl & FLOW_CTRL_RX) {
4068 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
4069 adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
4070 }
4071 else {
4072 adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
4073 }
4074 }
4075 return adv;
4076 }
4077
4078 static int
4079 bnx2_setup_copper_phy(struct bnx2 *bp)
4080 {
4081 u32 bmcr;
4082 u32 new_bmcr;
4083
4084 bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
4085 DLOG ("setup_copper_phy: bmcr=0x%.08X", bmcr);
4086
4087 if (bp->autoneg & AUTONEG_SPEED) {
4088 u32 adv_reg, adv1000_reg;
4089 u32 new_adv_reg = 0;
4090 u32 new_adv1000_reg = 0;
4091
4092 bnx2_read_phy(bp, bp->mii_adv, &adv_reg);
4093 DLOG ("setup_copper_phy: adv_reg=0x%.08X", adv_reg);
4094 adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
4095 ADVERTISE_PAUSE_ASYM);
4096
4097 bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
4098 DLOG ("setup_copper_phy: adv1000_reg=0x%.08X", adv1000_reg);
4099 adv1000_reg &= PHY_ALL_1000_SPEED;
4100
4101 if (bp->advertising & ADVERTISED_10baseT_Half)
4102 new_adv_reg |= ADVERTISE_10HALF;
4103 if (bp->advertising & ADVERTISED_10baseT_Full)
4104 new_adv_reg |= ADVERTISE_10FULL;
4105 if (bp->advertising & ADVERTISED_100baseT_Half)
4106 new_adv_reg |= ADVERTISE_100HALF;
4107 if (bp->advertising & ADVERTISED_100baseT_Full)
4108 new_adv_reg |= ADVERTISE_100FULL;
4109 if (bp->advertising & ADVERTISED_1000baseT_Full)
4110 new_adv1000_reg |= ADVERTISE_1000FULL;
4111
4112 new_adv_reg |= ADVERTISE_CSMA;
4113
4114 new_adv_reg |= bnx2_phy_get_pause_adv(bp);
4115
4116 if ((adv1000_reg != new_adv1000_reg) ||
4117 (adv_reg != new_adv_reg) ||
4118 ((bmcr & BMCR_ANENABLE) == 0)) {
4119 DLOG ("setup_copper_phy: Toggling autoneg");
4120 bnx2_write_phy(bp, bp->mii_adv, new_adv_reg);
4121 bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg);
4122 bnx2_write_phy(bp, bp->mii_bmcr, BMCR_ANRESTART |
4123 BMCR_ANENABLE);
4124 u32 bmsr;
4125 do {
4126 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4127 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4128 } while (!(bmsr & BMSR_ANEGCOMPLETE));
4129 }
4130 else if (bp->link_up) {
4131
4132
4133
4134 bnx2_resolve_flow_ctrl(bp);
4135 bnx2_set_mac_link(bp);
4136 }
4137 return 0;
4138 }
4139
4140 new_bmcr = 0;
4141 if (bp->req_line_speed == SPEED_100) {
4142 new_bmcr |= BMCR_SPEED100;
4143 }
4144 if (bp->req_duplex == DUPLEX_FULL) {
4145 new_bmcr |= BMCR_FULLDPLX;
4146 }
4147 if (new_bmcr != bmcr) {
4148 u32 bmsr;
4149
4150 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4151 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4152 DLOG ("setup_copper_phy: bmsr=0x%.08X", bmsr);
4153 if (bmsr & BMSR_LSTATUS) {
4154
4155 DLOG ("setup_copper_phy: Force Link Down");
4156 bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK);
4157 spinlock_unlock(&bp->phy_lock);
4158 udelay(50*1000);
4159 spinlock_lock(&bp->phy_lock);
4160
4161 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4162 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4163 DLOG ("setup_copper_phy: ===============> bmsr=0x%.08X", bmsr);
4164 }
4165
4166 bnx2_write_phy(bp, bp->mii_bmcr, new_bmcr);
4167
4168
4169
4170
4171
4172 if (bmsr & BMSR_LSTATUS) {
4173 bp->line_speed = bp->req_line_speed;
4174 bp->duplex = bp->req_duplex;
4175 bnx2_resolve_flow_ctrl(bp);
4176 bnx2_set_mac_link(bp);
4177 }
4178 } else {
4179 bnx2_resolve_flow_ctrl(bp);
4180 bnx2_set_mac_link(bp);
4181 }
4182 return 0;
4183 }
4184
4185 static int
4186 bnx2_setup_phy(struct bnx2 *bp, u8 port)
4187 {
4188 if (bp->loopback == MAC_LOOPBACK)
4189 return 0;
4190
4191 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
4192
4193 return -1;
4194 }
4195 else {
4196 DLOG ("bnx2_setup_phy: bnx2_setup_copper_phy");
4197 return (bnx2_setup_copper_phy(bp));
4198 }
4199 }
4200
4201 static bool
4202 bnx2_init_phy (struct bnx2 *bp, int reset_phy)
4203 {
4204 u32 val; bool rc = TRUE;
4205 bp->phy_flags &= ~BNX2_PHY_FLAG_INT_MODE_MASK;
4206 bp->phy_flags |= BNX2_PHY_FLAG_INT_MODE_LINK_READY;
4207
4208 bp->mii_bmcr = MII_BMCR;
4209 bp->mii_bmsr = MII_BMSR;
4210 bp->mii_bmsr1 = MII_BMSR;
4211 bp->mii_adv = MII_ADVERTISE;
4212 bp->mii_lpa = MII_LPA;
4213 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
4214
4215 if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
4216 goto setup_phy;
4217
4218 bnx2_read_phy(bp, MII_PHYSID1, &val);
4219 bp->phy_id = val << 16;
4220 bnx2_read_phy(bp, MII_PHYSID2, &val);
4221 bp->phy_id |= val & 0xffff;
4222
4223 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
4224 if (CHIP_NUM(bp) == CHIP_NUM_5706) {
4225 DLOG ("PHY: 5706");
4226 rc = bnx2_init_5706s_phy(bp, reset_phy) == 0;
4227 } else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
4228 DLOG ("PHY: 5708");
4229 rc = bnx2_init_5708s_phy(bp, reset_phy) == 0;
4230 } else if (CHIP_NUM(bp) == CHIP_NUM_5709) {
4231 DLOG ("PHY: 5709");
4232 rc = bnx2_init_5709s_phy(bp, reset_phy) == 0;
4233 }
4234 }
4235 else {
4236 DLOG ("PHY: copper");
4237 rc = bnx2_init_copper_phy(bp, reset_phy) == 0;
4238 }
4239
4240 setup_phy:
4241 if (rc == TRUE) {
4242 rc = bnx2_setup_phy(bp, bp->phy_port) == 0;
4243 }
4244 DLOG ("bnx2_init_phy returned %d", rc);
4245 return rc;
4246 }
4247
4248 static void
4249 bnx2_enable_bmsr1(struct bnx2 *bp)
4250 {
4251 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
4252 (CHIP_NUM(bp) == CHIP_NUM_5709))
4253 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
4254 MII_BNX2_BLK_ADDR_GP_STATUS);
4255 }
4256
4257 static void
4258 bnx2_disable_bmsr1(struct bnx2 *bp)
4259 {
4260 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
4261 (CHIP_NUM(bp) == CHIP_NUM_5709))
4262 bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
4263 MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
4264 }
4265
4266 static int
4267 bnx2_copper_linkup(struct bnx2 *bp)
4268 {
4269 u32 bmcr;
4270
4271 bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
4272 if (bmcr & BMCR_ANENABLE) {
4273 u32 local_adv, remote_adv, common;
4274
4275 bnx2_read_phy(bp, MII_CTRL1000, &local_adv);
4276 bnx2_read_phy(bp, MII_STAT1000, &remote_adv);
4277
4278 common = local_adv & (remote_adv >> 2);
4279 if (common & ADVERTISE_1000FULL) {
4280 bp->line_speed = SPEED_1000;
4281 bp->duplex = DUPLEX_FULL;
4282 }
4283 else if (common & ADVERTISE_1000HALF) {
4284 bp->line_speed = SPEED_1000;
4285 bp->duplex = DUPLEX_HALF;
4286 }
4287 else {
4288 bnx2_read_phy(bp, bp->mii_adv, &local_adv);
4289 bnx2_read_phy(bp, bp->mii_lpa, &remote_adv);
4290
4291 common = local_adv & remote_adv;
4292 if (common & ADVERTISE_100FULL) {
4293 bp->line_speed = SPEED_100;
4294 bp->duplex = DUPLEX_FULL;
4295 }
4296 else if (common & ADVERTISE_100HALF) {
4297 bp->line_speed = SPEED_100;
4298 bp->duplex = DUPLEX_HALF;
4299 }
4300 else if (common & ADVERTISE_10FULL) {
4301 bp->line_speed = SPEED_10;
4302 bp->duplex = DUPLEX_FULL;
4303 }
4304 else if (common & ADVERTISE_10HALF) {
4305 bp->line_speed = SPEED_10;
4306 bp->duplex = DUPLEX_HALF;
4307 }
4308 else {
4309 bp->line_speed = 0;
4310 bp->link_up = 0;
4311 }
4312 }
4313 }
4314 else {
4315 if (bmcr & BMCR_SPEED100) {
4316 bp->line_speed = SPEED_100;
4317 }
4318 else {
4319 bp->line_speed = SPEED_10;
4320 }
4321 if (bmcr & BMCR_FULLDPLX) {
4322 bp->duplex = DUPLEX_FULL;
4323 }
4324 else {
4325 bp->duplex = DUPLEX_HALF;
4326 }
4327 }
4328
4329 return 0;
4330 }
4331
4332 static void
4333 bnx2_report_fw_link(struct bnx2 *bp)
4334 {
4335 u32 fw_link_status = 0;
4336
4337 if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
4338 return;
4339
4340 if (bp->link_up) {
4341 u32 bmsr;
4342
4343 switch (bp->line_speed) {
4344 case SPEED_10:
4345 if (bp->duplex == DUPLEX_HALF)
4346 fw_link_status = BNX2_LINK_STATUS_10HALF;
4347 else
4348 fw_link_status = BNX2_LINK_STATUS_10FULL;
4349 break;
4350 case SPEED_100:
4351 if (bp->duplex == DUPLEX_HALF)
4352 fw_link_status = BNX2_LINK_STATUS_100HALF;
4353 else
4354 fw_link_status = BNX2_LINK_STATUS_100FULL;
4355 break;
4356 case SPEED_1000:
4357 if (bp->duplex == DUPLEX_HALF)
4358 fw_link_status = BNX2_LINK_STATUS_1000HALF;
4359 else
4360 fw_link_status = BNX2_LINK_STATUS_1000FULL;
4361 break;
4362 case SPEED_2500:
4363 if (bp->duplex == DUPLEX_HALF)
4364 fw_link_status = BNX2_LINK_STATUS_2500HALF;
4365 else
4366 fw_link_status = BNX2_LINK_STATUS_2500FULL;
4367 break;
4368 }
4369
4370 fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
4371
4372 if (bp->autoneg) {
4373 fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
4374
4375 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4376 bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
4377
4378 if (!(bmsr & BMSR_ANEGCOMPLETE) ||
4379 bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)
4380 fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
4381 else
4382 fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
4383 }
4384 }
4385 else
4386 fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
4387
4388 bnx2_shmem_wr(bp, BNX2_LINK_STATUS, fw_link_status);
4389 }
4390
4391 static void
4392 bnx2_report_link(struct bnx2 *bp)
4393 {
4394 if (bp->link_up) {
4395
4396
4397
4398
4399 logger_printf("bnx2: Link is up, %d Mbps ", bp->line_speed);
4400
4401 if (bp->duplex == DUPLEX_FULL)
4402 logger_printf("full duplex");
4403 else
4404 logger_printf("half duplex");
4405
4406 if (bp->flow_ctrl) {
4407 if (bp->flow_ctrl & FLOW_CTRL_RX) {
4408 logger_printf(", receive ");
4409 if (bp->flow_ctrl & FLOW_CTRL_TX)
4410 logger_printf("& transmit ");
4411 }
4412 else {
4413 logger_printf(", transmit ");
4414 }
4415 logger_printf("flow control ON");
4416 }
4417 logger_printf("\n");
4418 }
4419 else {
4420
4421
4422
4423 logger_printf ("bnx2: Link is down\n");
4424 }
4425
4426 bnx2_report_fw_link(bp);
4427 }
4428
4429 static int
4430 bnx2_set_link(struct bnx2 *bp)
4431 {
4432 u32 bmsr;
4433 u8 link_up;
4434
4435 if (bp->loopback == MAC_LOOPBACK || bp->loopback == PHY_LOOPBACK) {
4436 bp->link_up = 1;
4437 return 0;
4438 }
4439
4440 if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
4441 return 0;
4442
4443 link_up = bp->link_up;
4444
4445 bnx2_enable_bmsr1(bp);
4446 bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr);
4447 bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr);
4448 bnx2_disable_bmsr1(bp);
4449
4450
4451 #if 0
4452 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
4453 (CHIP_NUM(bp) == CHIP_NUM_5706)) {
4454 u32 val, an_dbg;
4455
4456 if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
4457 bnx2_5706s_force_link_dn(bp, 0);
4458 bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
4459 }
4460 val = REG_RD(bp, BNX2_EMAC_STATUS);
4461
4462 bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
4463 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
4464 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
4465
4466 if ((val & BNX2_EMAC_STATUS_LINK) &&
4467 !(an_dbg & MISC_SHDW_AN_DBG_NOSYNC))
4468 bmsr |= BMSR_LSTATUS;
4469 else
4470 bmsr &= ~BMSR_LSTATUS;
4471 }
4472 #endif
4473 DLOG ("phy_flags=0x%.08X bmsr=0x%.08X", bp->phy_flags, bmsr);
4474 if (bmsr & BMSR_LSTATUS) {
4475 bp->link_up = 1;
4476
4477 if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
4478 #if 0
4479 if (CHIP_NUM(bp) == CHIP_NUM_5706)
4480 bnx2_5706s_linkup(bp);
4481 else if (CHIP_NUM(bp) == CHIP_NUM_5708)
4482 bnx2_5708s_linkup(bp);
4483 else if (CHIP_NUM(bp) == CHIP_NUM_5709)
4484 bnx2_5709s_linkup(bp);
4485 #endif
4486 }
4487 else {
4488 DLOG ("bnx2_set_link: bnx2_copper_linkup");
4489 bnx2_copper_linkup(bp);
4490 }
4491 bnx2_resolve_flow_ctrl(bp);
4492 }
4493 else {
4494 #if 0
4495 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
4496 (bp->autoneg & AUTONEG_SPEED))
4497 bnx2_disable_forced_2g5(bp);
4498 #endif
4499
4500 if (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT) {
4501 u32 bmcr;
4502
4503 bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
4504 bmcr |= BMCR_ANENABLE;
4505 bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
4506
4507 bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
4508 }
4509 bp->link_up = 0;
4510 }
4511
4512 if (bp->link_up != link_up) {
4513 bnx2_report_link(bp);
4514 }
4515
4516 bnx2_set_mac_link(bp);
4517
4518 return 0;
4519 }
4520
4521 static u32 bnx2_timer_stack[1024] ALIGNED (0x1000);
4522 static void
4523 bnx2_timer (struct bnx2 *bp)
4524 {
4525 for (;;) {
4526 bnx2_send_heart_beat (bp);
4527 sched_usleep (BNX2_TIMER_INTERVAL * 10000);
4528 }
4529 }
4530
4531 static uint device_index;
4532 static pci_device pdev;
4533
4534 static sint
4535 bnx2_transmit (u8 *buf, u32 len)
4536 {
4537 return -1;
4538 }
4539
4540 static bool
4541 bnx2_get_hwaddr (u8 addr[ETH_ADDR_LEN])
4542 {
4543 struct bnx2 *bp = bnx2_ethdev.drvdata;
4544 int i;
4545 for (i=0; i<ETH_ADDR_LEN; i++) {
4546 addr[i] = bp->mac_addr[i];
4547 }
4548 return TRUE;
4549 }
4550
4551 static void
4552 bnx2_poll (void)
4553 {
4554 }
4555
4556 static u32 bnx2_test_stack[1024] ALIGNED (0x1000);
4557 static void
4558 bnx2_test_thread (void)
4559 {
4560 struct bnx2 *bp = bnx2_ethdev.drvdata;
4561 struct status_block *st = bp->status_blk;
4562 struct statistics_block *stats = bp->stats_blk;
4563
4564 for (;;) {
4565 u32 bmsr;
4566 sched_usleep (5*1000000);
4567 DLOG ("status_idx=%d attn_bits=0x%.08X attn_bits_ack=0x%.08X",
4568 st->status_idx,
4569 st->status_attn_bits,
4570 st->status_attn_bits_ack);
4571 DLOG ("rxQC0=%d rxQC1=%d",
4572 st->status_rx_quick_consumer_index0,
4573 st->status_rx_quick_consumer_index1);
4574 DLOG ("IfHCInOctets=0x%.08X%.08X IfHCInBadOctets=0x%.08X%.08X",
4575 stats->stat_IfHCInOctets_hi,
4576 stats->stat_IfHCInOctets_lo,
4577 stats->stat_IfHCInBadOctets_hi,
4578 stats->stat_IfHCInBadOctets_lo
4579 );
4580 bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr);
4581 bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr);
4582 DLOG ("bmsr=0x%.08X EMAC_STATUS=0x%.08X", bmsr, REG_RD (bp, BNX2_EMAC_STATUS));
4583
4584 int i;
4585 u32 attn = st->status_attn_bits;
4586 u32 ack = st->status_attn_bits_ack;
4587 for (i=0; i<32; i++) {
4588 u32 mask = 1 << i;
4589 if ((attn & mask) && !(ack & mask)) {
4590
4591 DLOG ("bit %d went from 0 -> 1", i);
4592 REG_WR (bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, (1 << i));
4593 } else if (!(attn & mask) && (ack & mask)) {
4594
4595 DLOG ("bit %d went from 1 -> 0", i);
4596 REG_WR (bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, (1 << i));
4597 }
4598 }
4599
4600 DLOG ("RXPmode=0x%.08X RXPstate=0x%.08X",
4601 bnx2_reg_rd_ind (bp, BNX2_RXP_CPU_MODE),
4602 bnx2_reg_rd_ind (bp, BNX2_RXP_CPU_STATE)
4603 );
4604 DLOG ("CTXcmd=0x%.08X CTXstatus=0x%.08X CTXrepstatus=0x%.08X",
4605 REG_RD (bp, BNX2_CTX_COMMAND),
4606 REG_RD (bp, BNX2_CTX_STATUS),
4607 REG_RD (bp, BNX2_CTX_REP_STATUS));
4608 REG_WR (bp, BNX2_CTX_STATUS, 0x07000000 & REG_RD (bp, BNX2_CTX_STATUS));
4609
4610 struct bnx2_rx_ring_info *rxr = &bp->rx_ring;
4611 struct rx_bd *rx_desc;
4612 rx_desc = &rxr->rx_desc_ring[0][255];
4613 DLOG (" rx_desc[255]=0x%p 0x%p 0x%p 0x%p",
4614 rx_desc->rx_bd_haddr_hi,
4615 rx_desc->rx_bd_haddr_lo,
4616 rx_desc->rx_bd_len,
4617 rx_desc->rx_bd_flags);
4618 for (i=0; i<RXBD_RING_SIZE; i++)
4619 if (((u8 *) backup_rx_desc)[i] != ((u8 *) rxr->rx_desc_ring[0])[i])
4620 DLOG (" rx_desc byte changed at i=%d from 0x%X to 0x%X",
4621 i, ((u8 *) backup_rx_desc)[i], ((u8 *) rxr->rx_desc_ring[0])[i]);
4622 }
4623 }
4624
4625 extern bool
4626 bnx2_init (void)
4627 {
4628 uint i, frame_count;
4629 pci_irq_t irq;
4630 struct bnx2 *bp;
4631
4632 if (mp_ISA_PC) {
4633 DLOG ("Requires PCI support");
4634 goto abort;
4635 }
4636
4637 for (i=0; compatible_ids[i].vendor != 0xFFFF; i++)
4638 if (pci_find_device (compatible_ids[i].vendor, compatible_ids[i].device,
4639 0xFF, 0xFF, 0, &device_index))
4640 break;
4641 else
4642 device_index = ~0;
4643
4644 if (device_index == (uint)(~0)) {
4645 DLOG ("Unable to detect compatible device.");
4646 goto abort;
4647 }
4648
4649 DLOG ("Found device_index=%d", device_index);
4650
4651 if (!pci_get_device (device_index, &pdev)) {
4652 DLOG ("pci_get_device");
4653 goto abort;
4654 }
4655
4656 pow2_alloc (sizeof (struct bnx2), (u8 **) &bp);
4657 memset (bp, 0, sizeof (struct bnx2));
4658
4659 u32 status_size = sizeof (struct status_block);
4660 status_size += LOCK_ALIGNMENT - 1;
4661 status_size &= ~(LOCK_ALIGNMENT - 1);
4662 u32 status_stats_size =
4663 status_size + sizeof (struct statistics_block);
4664 u32 status_stats_pages =
4665 (status_stats_size >> PAGE_SHIFT) +
4666 ((status_stats_size & ((1<<PAGE_SHIFT)-1)) ? 1 : 0);
4667 DLOG ("status_size=%d status_stats_size=%d status_stats_pages=%d",
4668 status_size, status_stats_size, status_stats_pages);
4669 u32 status_stats_phys = alloc_phys_frames (status_stats_pages);
4670 if (status_stats_phys == (u32) -1)
4671 goto abort_bp;
4672 void *status_stats =
4673 map_contiguous_virtual_pages (status_stats_phys | 3, status_stats_pages);
4674 if (!status_stats)
4675 goto abort_status_phys;
4676 memset (status_stats, 0, status_stats_pages << PAGE_SHIFT);
4677
4678 bp->status_blk = (struct status_block *) status_stats;
4679 bp->status_blk_mapping = status_stats_phys;
4680 bp->stats_blk = (struct statistics_block *) (status_stats + status_size);
4681 bp->stats_blk_mapping = status_stats_phys + status_size;
4682 DLOG ("status_blk=%p status_blk_mapping=%p", bp->status_blk, bp->status_blk_mapping);
4683 DLOG ("stats_blk=%p stats_blk_mapping=%p", bp->stats_blk, bp->stats_blk_mapping);
4684
4685 pdev.drvdata = bp;
4686 bp->pdev = &pdev;
4687
4688
4689 pci_write_word (pci_addr (pdev.bus, pdev.slot, pdev.func, 0x04), 0x0006);
4690
4691 if (!bnx2_init_board (&pdev))
4692 goto abort_status_virt;
4693
4694 bp->num_rx_rings = 1;
4695 bnx2_mac_reset (bp);
4696 bnx2_mac_init (bp);
4697 bnx2_enable_int (bp);
4698 if (!bnx2_alloc_rx_mem (bp)) {
4699 DLOG ("failed to alloc rx mem");
4700 goto abort_status_virt;
4701 }
4702 bnx2_init_all_rings (bp);
4703 spinlock_lock (&bp->phy_lock);
4704 bnx2_init_phy (bp, TRUE);
4705 bnx2_set_link(bp);
4706 if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
4707 DLOG ("bnx2_remote_phy_event(bp);");
4708
4709 spinlock_unlock (&bp->phy_lock);
4710
4711 DLOG ("PCICMD=0x%.04X", pci_read_word (pci_addr (pdev.bus, pdev.slot, pdev.func, 0x04)));
4712 DLOG ("PCISTS=0x%.04X", pci_read_word (pci_addr (pdev.bus, pdev.slot, pdev.func, 0x06)));
4713
4714
4715 pci_write_word (pci_addr (pdev.bus, pdev.slot, pdev.func, 0x06), pci_read_word (pci_addr (pdev.bus, pdev.slot, pdev.func, 0x06)));
4716
4717
4718 bnx2_ethdev.recv_func = NULL;
4719 bnx2_ethdev.send_func = bnx2_transmit;
4720 bnx2_ethdev.get_hwaddr_func = bnx2_get_hwaddr;
4721 bnx2_ethdev.poll_func = bnx2_poll;
4722 bnx2_ethdev.drvdata = bp;
4723
4724 if (!net_register_device (&bnx2_ethdev)) {
4725 DLOG ("registration failed");
4726 goto abort_status_virt;
4727 }
4728
4729 create_kernel_thread_args ((u32) bnx2_test_thread, (u32) &bnx2_test_stack[1023], TRUE, 0);
4730 create_kernel_thread_args ((u32) bnx2_timer, (u32) &bnx2_timer_stack[1023], TRUE, 1, bp);
4731
4732 return TRUE;
4733
4734 abort_status_virt:
4735 unmap_virtual_pages (status_stats, status_stats_pages);
4736 abort_status_phys:
4737 free_phys_frames (status_stats_phys, status_stats_pages);
4738 abort_bp:
4739 pow2_free ((u8 *) bp);
4740 abort:
4741 return FALSE;
4742 }
4743
4744 #include "module/header.h"
4745
4746 static const struct module_ops mod_ops = {
4747 .init = bnx2_init
4748 };
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761