diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-09 01:07:12 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-09 01:07:12 -0500 |
commit | a892acacd3a8546ac161526522f13b5174f2c471 (patch) | |
tree | ee6d36f27f1388989ebfcabf90253fb7194112ac /drivers/net/bnx2.c | |
parent | 193515d51ccb363165d6b09e9ba5c21089e34bad (diff) | |
parent | 330d57fb98a916fa8e1363846540dd420e99499a (diff) |
Merge branch 'master'
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 468 |
1 files changed, 390 insertions, 78 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 11d252318221..8f464271664d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -14,8 +14,8 @@ | |||
14 | 14 | ||
15 | #define DRV_MODULE_NAME "bnx2" | 15 | #define DRV_MODULE_NAME "bnx2" |
16 | #define PFX DRV_MODULE_NAME ": " | 16 | #define PFX DRV_MODULE_NAME ": " |
17 | #define DRV_MODULE_VERSION "1.2.21" | 17 | #define DRV_MODULE_VERSION "1.4.30" |
18 | #define DRV_MODULE_RELDATE "September 7, 2005" | 18 | #define DRV_MODULE_RELDATE "October 11, 2005" |
19 | 19 | ||
20 | #define RUN_AT(x) (jiffies + (x)) | 20 | #define RUN_AT(x) (jiffies + (x)) |
21 | 21 | ||
@@ -26,7 +26,7 @@ static char version[] __devinitdata = | |||
26 | "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 26 | "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
27 | 27 | ||
28 | MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>"); | 28 | MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>"); |
29 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver"); | 29 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver"); |
30 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
31 | MODULE_VERSION(DRV_MODULE_VERSION); | 31 | MODULE_VERSION(DRV_MODULE_VERSION); |
32 | 32 | ||
@@ -41,6 +41,8 @@ typedef enum { | |||
41 | NC370I, | 41 | NC370I, |
42 | BCM5706S, | 42 | BCM5706S, |
43 | NC370F, | 43 | NC370F, |
44 | BCM5708, | ||
45 | BCM5708S, | ||
44 | } board_t; | 46 | } board_t; |
45 | 47 | ||
46 | /* indexed by board_t, above */ | 48 | /* indexed by board_t, above */ |
@@ -52,6 +54,8 @@ static struct { | |||
52 | { "HP NC370i Multifunction Gigabit Server Adapter" }, | 54 | { "HP NC370i Multifunction Gigabit Server Adapter" }, |
53 | { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, | 55 | { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, |
54 | { "HP NC370F Multifunction Gigabit Server Adapter" }, | 56 | { "HP NC370F Multifunction Gigabit Server Adapter" }, |
57 | { "Broadcom NetXtreme II BCM5708 1000Base-T" }, | ||
58 | { "Broadcom NetXtreme II BCM5708 1000Base-SX" }, | ||
55 | }; | 59 | }; |
56 | 60 | ||
57 | static struct pci_device_id bnx2_pci_tbl[] = { | 61 | static struct pci_device_id bnx2_pci_tbl[] = { |
@@ -61,48 +65,102 @@ static struct pci_device_id bnx2_pci_tbl[] = { | |||
61 | PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I }, | 65 | PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I }, |
62 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, | 66 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, |
63 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 }, | 67 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 }, |
68 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708, | ||
69 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708 }, | ||
64 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, | 70 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, |
65 | PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F }, | 71 | PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F }, |
66 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, | 72 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, |
67 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S }, | 73 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S }, |
74 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S, | ||
75 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S }, | ||
68 | { 0, } | 76 | { 0, } |
69 | }; | 77 | }; |
70 | 78 | ||
71 | static struct flash_spec flash_table[] = | 79 | static struct flash_spec flash_table[] = |
72 | { | 80 | { |
73 | /* Slow EEPROM */ | 81 | /* Slow EEPROM */ |
74 | {0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400, | 82 | {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400, |
75 | 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, | 83 | 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, |
76 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, | 84 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, |
77 | "EEPROM - slow"}, | 85 | "EEPROM - slow"}, |
78 | /* Fast EEPROM */ | 86 | /* Expansion entry 0001 */ |
79 | {0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400, | 87 | {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406, |
80 | 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, | ||
81 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, | ||
82 | "EEPROM - fast"}, | ||
83 | /* ATMEL AT45DB011B (buffered flash) */ | ||
84 | {0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400, | ||
85 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | ||
86 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, | ||
87 | "Buffered flash"}, | ||
88 | /* Saifun SA25F005 (non-buffered flash) */ | ||
89 | /* strap, cfg1, & write1 need updates */ | ||
90 | {0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406, | ||
91 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 88 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
92 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, | 89 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
93 | "Non-buffered flash (64kB)"}, | 90 | "Entry 0001"}, |
94 | /* Saifun SA25F010 (non-buffered flash) */ | 91 | /* Saifun SA25F010 (non-buffered flash) */ |
95 | /* strap, cfg1, & write1 need updates */ | 92 | /* strap, cfg1, & write1 need updates */ |
96 | {0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406, | 93 | {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406, |
97 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 94 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
98 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, | 95 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, |
99 | "Non-buffered flash (128kB)"}, | 96 | "Non-buffered flash (128kB)"}, |
100 | /* Saifun SA25F020 (non-buffered flash) */ | 97 | /* Saifun SA25F020 (non-buffered flash) */ |
101 | /* strap, cfg1, & write1 need updates */ | 98 | /* strap, cfg1, & write1 need updates */ |
102 | {0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406, | 99 | {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406, |
103 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 100 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
104 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, | 101 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, |
105 | "Non-buffered flash (256kB)"}, | 102 | "Non-buffered flash (256kB)"}, |
103 | /* Expansion entry 0100 */ | ||
104 | {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406, | ||
105 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | ||
106 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | ||
107 | "Entry 0100"}, | ||
108 | /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */ | ||
109 | {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406, | ||
110 | 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, | ||
111 | ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2, | ||
112 | "Entry 0101: ST M45PE10 (128kB non-bufferred)"}, | ||
113 | /* Entry 0110: ST M45PE20 (non-buffered flash)*/ | ||
114 | {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406, | ||
115 | 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, | ||
116 | ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4, | ||
117 | "Entry 0110: ST M45PE20 (256kB non-bufferred)"}, | ||
118 | /* Saifun SA25F005 (non-buffered flash) */ | ||
119 | /* strap, cfg1, & write1 need updates */ | ||
120 | {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406, | ||
121 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | ||
122 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, | ||
123 | "Non-buffered flash (64kB)"}, | ||
124 | /* Fast EEPROM */ | ||
125 | {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400, | ||
126 | 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, | ||
127 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, | ||
128 | "EEPROM - fast"}, | ||
129 | /* Expansion entry 1001 */ | ||
130 | {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406, | ||
131 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | ||
132 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | ||
133 | "Entry 1001"}, | ||
134 | /* Expansion entry 1010 */ | ||
135 | {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406, | ||
136 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | ||
137 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | ||
138 | "Entry 1010"}, | ||
139 | /* ATMEL AT45DB011B (buffered flash) */ | ||
140 | {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400, | ||
141 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | ||
142 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, | ||
143 | "Buffered flash (128kB)"}, | ||
144 | /* Expansion entry 1100 */ | ||
145 | {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406, | ||
146 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | ||
147 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | ||
148 | "Entry 1100"}, | ||
149 | /* Expansion entry 1101 */ | ||
150 | {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406, | ||
151 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | ||
152 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | ||
153 | "Entry 1101"}, | ||
154 | /* Ateml Expansion entry 1110 */ | ||
155 | {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400, | ||
156 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | ||
157 | BUFFERED_FLASH_BYTE_ADDR_MASK, 0, | ||
158 | "Entry 1110 (Atmel)"}, | ||
159 | /* ATMEL AT45DB021B (buffered flash) */ | ||
160 | {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400, | ||
161 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | ||
162 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2, | ||
163 | "Buffered flash (256kB)"}, | ||
106 | }; | 164 | }; |
107 | 165 | ||
108 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); | 166 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); |
@@ -379,6 +437,62 @@ alloc_mem_err: | |||
379 | } | 437 | } |
380 | 438 | ||
381 | static void | 439 | static void |
440 | bnx2_report_fw_link(struct bnx2 *bp) | ||
441 | { | ||
442 | u32 fw_link_status = 0; | ||
443 | |||
444 | if (bp->link_up) { | ||
445 | u32 bmsr; | ||
446 | |||
447 | switch (bp->line_speed) { | ||
448 | case SPEED_10: | ||
449 | if (bp->duplex == DUPLEX_HALF) | ||
450 | fw_link_status = BNX2_LINK_STATUS_10HALF; | ||
451 | else | ||
452 | fw_link_status = BNX2_LINK_STATUS_10FULL; | ||
453 | break; | ||
454 | case SPEED_100: | ||
455 | if (bp->duplex == DUPLEX_HALF) | ||
456 | fw_link_status = BNX2_LINK_STATUS_100HALF; | ||
457 | else | ||
458 | fw_link_status = BNX2_LINK_STATUS_100FULL; | ||
459 | break; | ||
460 | case SPEED_1000: | ||
461 | if (bp->duplex == DUPLEX_HALF) | ||
462 | fw_link_status = BNX2_LINK_STATUS_1000HALF; | ||
463 | else | ||
464 | fw_link_status = BNX2_LINK_STATUS_1000FULL; | ||
465 | break; | ||
466 | case SPEED_2500: | ||
467 | if (bp->duplex == DUPLEX_HALF) | ||
468 | fw_link_status = BNX2_LINK_STATUS_2500HALF; | ||
469 | else | ||
470 | fw_link_status = BNX2_LINK_STATUS_2500FULL; | ||
471 | break; | ||
472 | } | ||
473 | |||
474 | fw_link_status |= BNX2_LINK_STATUS_LINK_UP; | ||
475 | |||
476 | if (bp->autoneg) { | ||
477 | fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED; | ||
478 | |||
479 | bnx2_read_phy(bp, MII_BMSR, &bmsr); | ||
480 | bnx2_read_phy(bp, MII_BMSR, &bmsr); | ||
481 | |||
482 | if (!(bmsr & BMSR_ANEGCOMPLETE) || | ||
483 | bp->phy_flags & PHY_PARALLEL_DETECT_FLAG) | ||
484 | fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET; | ||
485 | else | ||
486 | fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE; | ||
487 | } | ||
488 | } | ||
489 | else | ||
490 | fw_link_status = BNX2_LINK_STATUS_LINK_DOWN; | ||
491 | |||
492 | REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status); | ||
493 | } | ||
494 | |||
495 | static void | ||
382 | bnx2_report_link(struct bnx2 *bp) | 496 | bnx2_report_link(struct bnx2 *bp) |
383 | { | 497 | { |
384 | if (bp->link_up) { | 498 | if (bp->link_up) { |
@@ -409,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp) | |||
409 | netif_carrier_off(bp->dev); | 523 | netif_carrier_off(bp->dev); |
410 | printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name); | 524 | printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name); |
411 | } | 525 | } |
526 | |||
527 | bnx2_report_fw_link(bp); | ||
412 | } | 528 | } |
413 | 529 | ||
414 | static void | 530 | static void |
@@ -430,6 +546,18 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp) | |||
430 | return; | 546 | return; |
431 | } | 547 | } |
432 | 548 | ||
549 | if ((bp->phy_flags & PHY_SERDES_FLAG) && | ||
550 | (CHIP_NUM(bp) == CHIP_NUM_5708)) { | ||
551 | u32 val; | ||
552 | |||
553 | bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val); | ||
554 | if (val & BCM5708S_1000X_STAT1_TX_PAUSE) | ||
555 | bp->flow_ctrl |= FLOW_CTRL_TX; | ||
556 | if (val & BCM5708S_1000X_STAT1_RX_PAUSE) | ||
557 | bp->flow_ctrl |= FLOW_CTRL_RX; | ||
558 | return; | ||
559 | } | ||
560 | |||
433 | bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); | 561 | bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); |
434 | bnx2_read_phy(bp, MII_LPA, &remote_adv); | 562 | bnx2_read_phy(bp, MII_LPA, &remote_adv); |
435 | 563 | ||
@@ -476,7 +604,36 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp) | |||
476 | } | 604 | } |
477 | 605 | ||
478 | static int | 606 | static int |
479 | bnx2_serdes_linkup(struct bnx2 *bp) | 607 | bnx2_5708s_linkup(struct bnx2 *bp) |
608 | { | ||
609 | u32 val; | ||
610 | |||
611 | bp->link_up = 1; | ||
612 | bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val); | ||
613 | switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) { | ||
614 | case BCM5708S_1000X_STAT1_SPEED_10: | ||
615 | bp->line_speed = SPEED_10; | ||
616 | break; | ||
617 | case BCM5708S_1000X_STAT1_SPEED_100: | ||
618 | bp->line_speed = SPEED_100; | ||
619 | break; | ||
620 | case BCM5708S_1000X_STAT1_SPEED_1G: | ||
621 | bp->line_speed = SPEED_1000; | ||
622 | break; | ||
623 | case BCM5708S_1000X_STAT1_SPEED_2G5: | ||
624 | bp->line_speed = SPEED_2500; | ||
625 | break; | ||
626 | } | ||
627 | if (val & BCM5708S_1000X_STAT1_FD) | ||
628 | bp->duplex = DUPLEX_FULL; | ||
629 | else | ||
630 | bp->duplex = DUPLEX_HALF; | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int | ||
636 | bnx2_5706s_linkup(struct bnx2 *bp) | ||
480 | { | 637 | { |
481 | u32 bmcr, local_adv, remote_adv, common; | 638 | u32 bmcr, local_adv, remote_adv, common; |
482 | 639 | ||
@@ -593,13 +750,27 @@ bnx2_set_mac_link(struct bnx2 *bp) | |||
593 | val = REG_RD(bp, BNX2_EMAC_MODE); | 750 | val = REG_RD(bp, BNX2_EMAC_MODE); |
594 | 751 | ||
595 | val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | | 752 | val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | |
596 | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK); | 753 | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | |
754 | BNX2_EMAC_MODE_25G); | ||
597 | 755 | ||
598 | if (bp->link_up) { | 756 | if (bp->link_up) { |
599 | if (bp->line_speed != SPEED_1000) | 757 | switch (bp->line_speed) { |
600 | val |= BNX2_EMAC_MODE_PORT_MII; | 758 | case SPEED_10: |
601 | else | 759 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { |
602 | val |= BNX2_EMAC_MODE_PORT_GMII; | 760 | val |= BNX2_EMAC_MODE_PORT_MII_10; |
761 | break; | ||
762 | } | ||
763 | /* fall through */ | ||
764 | case SPEED_100: | ||
765 | val |= BNX2_EMAC_MODE_PORT_MII; | ||
766 | break; | ||
767 | case SPEED_2500: | ||
768 | val |= BNX2_EMAC_MODE_25G; | ||
769 | /* fall through */ | ||
770 | case SPEED_1000: | ||
771 | val |= BNX2_EMAC_MODE_PORT_GMII; | ||
772 | break; | ||
773 | } | ||
603 | } | 774 | } |
604 | else { | 775 | else { |
605 | val |= BNX2_EMAC_MODE_PORT_GMII; | 776 | val |= BNX2_EMAC_MODE_PORT_GMII; |
@@ -662,7 +833,10 @@ bnx2_set_link(struct bnx2 *bp) | |||
662 | bp->link_up = 1; | 833 | bp->link_up = 1; |
663 | 834 | ||
664 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 835 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
665 | bnx2_serdes_linkup(bp); | 836 | if (CHIP_NUM(bp) == CHIP_NUM_5706) |
837 | bnx2_5706s_linkup(bp); | ||
838 | else if (CHIP_NUM(bp) == CHIP_NUM_5708) | ||
839 | bnx2_5708s_linkup(bp); | ||
666 | } | 840 | } |
667 | else { | 841 | else { |
668 | bnx2_copper_linkup(bp); | 842 | bnx2_copper_linkup(bp); |
@@ -755,39 +929,61 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp) | |||
755 | static int | 929 | static int |
756 | bnx2_setup_serdes_phy(struct bnx2 *bp) | 930 | bnx2_setup_serdes_phy(struct bnx2 *bp) |
757 | { | 931 | { |
758 | u32 adv, bmcr; | 932 | u32 adv, bmcr, up1; |
759 | u32 new_adv = 0; | 933 | u32 new_adv = 0; |
760 | 934 | ||
761 | if (!(bp->autoneg & AUTONEG_SPEED)) { | 935 | if (!(bp->autoneg & AUTONEG_SPEED)) { |
762 | u32 new_bmcr; | 936 | u32 new_bmcr; |
937 | int force_link_down = 0; | ||
938 | |||
939 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { | ||
940 | bnx2_read_phy(bp, BCM5708S_UP1, &up1); | ||
941 | if (up1 & BCM5708S_UP1_2G5) { | ||
942 | up1 &= ~BCM5708S_UP1_2G5; | ||
943 | bnx2_write_phy(bp, BCM5708S_UP1, up1); | ||
944 | force_link_down = 1; | ||
945 | } | ||
946 | } | ||
947 | |||
948 | bnx2_read_phy(bp, MII_ADVERTISE, &adv); | ||
949 | adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF); | ||
763 | 950 | ||
764 | bnx2_read_phy(bp, MII_BMCR, &bmcr); | 951 | bnx2_read_phy(bp, MII_BMCR, &bmcr); |
765 | new_bmcr = bmcr & ~BMCR_ANENABLE; | 952 | new_bmcr = bmcr & ~BMCR_ANENABLE; |
766 | new_bmcr |= BMCR_SPEED1000; | 953 | new_bmcr |= BMCR_SPEED1000; |
767 | if (bp->req_duplex == DUPLEX_FULL) { | 954 | if (bp->req_duplex == DUPLEX_FULL) { |
955 | adv |= ADVERTISE_1000XFULL; | ||
768 | new_bmcr |= BMCR_FULLDPLX; | 956 | new_bmcr |= BMCR_FULLDPLX; |
769 | } | 957 | } |
770 | else { | 958 | else { |
959 | adv |= ADVERTISE_1000XHALF; | ||
771 | new_bmcr &= ~BMCR_FULLDPLX; | 960 | new_bmcr &= ~BMCR_FULLDPLX; |
772 | } | 961 | } |
773 | if (new_bmcr != bmcr) { | 962 | if ((new_bmcr != bmcr) || (force_link_down)) { |
774 | /* Force a link down visible on the other side */ | 963 | /* Force a link down visible on the other side */ |
775 | if (bp->link_up) { | 964 | if (bp->link_up) { |
776 | bnx2_read_phy(bp, MII_ADVERTISE, &adv); | 965 | bnx2_write_phy(bp, MII_ADVERTISE, adv & |
777 | adv &= ~(ADVERTISE_1000XFULL | | 966 | ~(ADVERTISE_1000XFULL | |
778 | ADVERTISE_1000XHALF); | 967 | ADVERTISE_1000XHALF)); |
779 | bnx2_write_phy(bp, MII_ADVERTISE, adv); | ||
780 | bnx2_write_phy(bp, MII_BMCR, bmcr | | 968 | bnx2_write_phy(bp, MII_BMCR, bmcr | |
781 | BMCR_ANRESTART | BMCR_ANENABLE); | 969 | BMCR_ANRESTART | BMCR_ANENABLE); |
782 | 970 | ||
783 | bp->link_up = 0; | 971 | bp->link_up = 0; |
784 | netif_carrier_off(bp->dev); | 972 | netif_carrier_off(bp->dev); |
973 | bnx2_write_phy(bp, MII_BMCR, new_bmcr); | ||
785 | } | 974 | } |
975 | bnx2_write_phy(bp, MII_ADVERTISE, adv); | ||
786 | bnx2_write_phy(bp, MII_BMCR, new_bmcr); | 976 | bnx2_write_phy(bp, MII_BMCR, new_bmcr); |
787 | } | 977 | } |
788 | return 0; | 978 | return 0; |
789 | } | 979 | } |
790 | 980 | ||
981 | if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { | ||
982 | bnx2_read_phy(bp, BCM5708S_UP1, &up1); | ||
983 | up1 |= BCM5708S_UP1_2G5; | ||
984 | bnx2_write_phy(bp, BCM5708S_UP1, up1); | ||
985 | } | ||
986 | |||
791 | if (bp->advertising & ADVERTISED_1000baseT_Full) | 987 | if (bp->advertising & ADVERTISED_1000baseT_Full) |
792 | new_adv |= ADVERTISE_1000XFULL; | 988 | new_adv |= ADVERTISE_1000XFULL; |
793 | 989 | ||
@@ -952,7 +1148,60 @@ bnx2_setup_phy(struct bnx2 *bp) | |||
952 | } | 1148 | } |
953 | 1149 | ||
954 | static int | 1150 | static int |
955 | bnx2_init_serdes_phy(struct bnx2 *bp) | 1151 | bnx2_init_5708s_phy(struct bnx2 *bp) |
1152 | { | ||
1153 | u32 val; | ||
1154 | |||
1155 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3); | ||
1156 | bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE); | ||
1157 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); | ||
1158 | |||
1159 | bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val); | ||
1160 | val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN; | ||
1161 | bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val); | ||
1162 | |||
1163 | bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val); | ||
1164 | val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN; | ||
1165 | bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val); | ||
1166 | |||
1167 | if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { | ||
1168 | bnx2_read_phy(bp, BCM5708S_UP1, &val); | ||
1169 | val |= BCM5708S_UP1_2G5; | ||
1170 | bnx2_write_phy(bp, BCM5708S_UP1, val); | ||
1171 | } | ||
1172 | |||
1173 | if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || | ||
1174 | (CHIP_ID(bp) == CHIP_ID_5708_B0)) { | ||
1175 | /* increase tx signal amplitude */ | ||
1176 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, | ||
1177 | BCM5708S_BLK_ADDR_TX_MISC); | ||
1178 | bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val); | ||
1179 | val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM; | ||
1180 | bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val); | ||
1181 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); | ||
1182 | } | ||
1183 | |||
1184 | val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) & | ||
1185 | BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK; | ||
1186 | |||
1187 | if (val) { | ||
1188 | u32 is_backplane; | ||
1189 | |||
1190 | is_backplane = REG_RD_IND(bp, bp->shmem_base + | ||
1191 | BNX2_SHARED_HW_CFG_CONFIG); | ||
1192 | if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) { | ||
1193 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, | ||
1194 | BCM5708S_BLK_ADDR_TX_MISC); | ||
1195 | bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val); | ||
1196 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, | ||
1197 | BCM5708S_BLK_ADDR_DIG); | ||
1198 | } | ||
1199 | } | ||
1200 | return 0; | ||
1201 | } | ||
1202 | |||
1203 | static int | ||
1204 | bnx2_init_5706s_phy(struct bnx2 *bp) | ||
956 | { | 1205 | { |
957 | bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; | 1206 | bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; |
958 | 1207 | ||
@@ -990,6 +1239,8 @@ bnx2_init_serdes_phy(struct bnx2 *bp) | |||
990 | static int | 1239 | static int |
991 | bnx2_init_copper_phy(struct bnx2 *bp) | 1240 | bnx2_init_copper_phy(struct bnx2 *bp) |
992 | { | 1241 | { |
1242 | u32 val; | ||
1243 | |||
993 | bp->phy_flags |= PHY_CRC_FIX_FLAG; | 1244 | bp->phy_flags |= PHY_CRC_FIX_FLAG; |
994 | 1245 | ||
995 | if (bp->phy_flags & PHY_CRC_FIX_FLAG) { | 1246 | if (bp->phy_flags & PHY_CRC_FIX_FLAG) { |
@@ -1004,8 +1255,6 @@ bnx2_init_copper_phy(struct bnx2 *bp) | |||
1004 | } | 1255 | } |
1005 | 1256 | ||
1006 | if (bp->dev->mtu > 1500) { | 1257 | if (bp->dev->mtu > 1500) { |
1007 | u32 val; | ||
1008 | |||
1009 | /* Set extended packet length bit */ | 1258 | /* Set extended packet length bit */ |
1010 | bnx2_write_phy(bp, 0x18, 0x7); | 1259 | bnx2_write_phy(bp, 0x18, 0x7); |
1011 | bnx2_read_phy(bp, 0x18, &val); | 1260 | bnx2_read_phy(bp, 0x18, &val); |
@@ -1015,8 +1264,6 @@ bnx2_init_copper_phy(struct bnx2 *bp) | |||
1015 | bnx2_write_phy(bp, 0x10, val | 0x1); | 1264 | bnx2_write_phy(bp, 0x10, val | 0x1); |
1016 | } | 1265 | } |
1017 | else { | 1266 | else { |
1018 | u32 val; | ||
1019 | |||
1020 | bnx2_write_phy(bp, 0x18, 0x7); | 1267 | bnx2_write_phy(bp, 0x18, 0x7); |
1021 | bnx2_read_phy(bp, 0x18, &val); | 1268 | bnx2_read_phy(bp, 0x18, &val); |
1022 | bnx2_write_phy(bp, 0x18, val & ~0x4007); | 1269 | bnx2_write_phy(bp, 0x18, val & ~0x4007); |
@@ -1025,6 +1272,10 @@ bnx2_init_copper_phy(struct bnx2 *bp) | |||
1025 | bnx2_write_phy(bp, 0x10, val & ~0x1); | 1272 | bnx2_write_phy(bp, 0x10, val & ~0x1); |
1026 | } | 1273 | } |
1027 | 1274 | ||
1275 | /* ethernet@wirespeed */ | ||
1276 | bnx2_write_phy(bp, 0x18, 0x7007); | ||
1277 | bnx2_read_phy(bp, 0x18, &val); | ||
1278 | bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4)); | ||
1028 | return 0; | 1279 | return 0; |
1029 | } | 1280 | } |
1030 | 1281 | ||
@@ -1048,7 +1299,10 @@ bnx2_init_phy(struct bnx2 *bp) | |||
1048 | bp->phy_id |= val & 0xffff; | 1299 | bp->phy_id |= val & 0xffff; |
1049 | 1300 | ||
1050 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 1301 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
1051 | rc = bnx2_init_serdes_phy(bp); | 1302 | if (CHIP_NUM(bp) == CHIP_NUM_5706) |
1303 | rc = bnx2_init_5706s_phy(bp); | ||
1304 | else if (CHIP_NUM(bp) == CHIP_NUM_5708) | ||
1305 | rc = bnx2_init_5708s_phy(bp); | ||
1052 | } | 1306 | } |
1053 | else { | 1307 | else { |
1054 | rc = bnx2_init_copper_phy(bp); | 1308 | rc = bnx2_init_copper_phy(bp); |
@@ -1084,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data) | |||
1084 | bp->fw_wr_seq++; | 1338 | bp->fw_wr_seq++; |
1085 | msg_data |= bp->fw_wr_seq; | 1339 | msg_data |= bp->fw_wr_seq; |
1086 | 1340 | ||
1087 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); | 1341 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); |
1088 | 1342 | ||
1089 | /* wait for an acknowledgement. */ | 1343 | /* wait for an acknowledgement. */ |
1090 | for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { | 1344 | for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { |
1091 | udelay(5); | 1345 | udelay(5); |
1092 | 1346 | ||
1093 | val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB); | 1347 | val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB); |
1094 | 1348 | ||
1095 | if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) | 1349 | if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) |
1096 | break; | 1350 | break; |
@@ -1103,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data) | |||
1103 | msg_data &= ~BNX2_DRV_MSG_CODE; | 1357 | msg_data &= ~BNX2_DRV_MSG_CODE; |
1104 | msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; | 1358 | msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; |
1105 | 1359 | ||
1106 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); | 1360 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); |
1107 | 1361 | ||
1108 | bp->fw_timed_out = 1; | 1362 | bp->fw_timed_out = 1; |
1109 | 1363 | ||
@@ -1279,10 +1533,11 @@ bnx2_phy_int(struct bnx2 *bp) | |||
1279 | static void | 1533 | static void |
1280 | bnx2_tx_int(struct bnx2 *bp) | 1534 | bnx2_tx_int(struct bnx2 *bp) |
1281 | { | 1535 | { |
1536 | struct status_block *sblk = bp->status_blk; | ||
1282 | u16 hw_cons, sw_cons, sw_ring_cons; | 1537 | u16 hw_cons, sw_cons, sw_ring_cons; |
1283 | int tx_free_bd = 0; | 1538 | int tx_free_bd = 0; |
1284 | 1539 | ||
1285 | hw_cons = bp->status_blk->status_tx_quick_consumer_index0; | 1540 | hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0; |
1286 | if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { | 1541 | if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { |
1287 | hw_cons++; | 1542 | hw_cons++; |
1288 | } | 1543 | } |
@@ -1337,7 +1592,9 @@ bnx2_tx_int(struct bnx2 *bp) | |||
1337 | 1592 | ||
1338 | dev_kfree_skb_irq(skb); | 1593 | dev_kfree_skb_irq(skb); |
1339 | 1594 | ||
1340 | hw_cons = bp->status_blk->status_tx_quick_consumer_index0; | 1595 | hw_cons = bp->hw_tx_cons = |
1596 | sblk->status_tx_quick_consumer_index0; | ||
1597 | |||
1341 | if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { | 1598 | if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { |
1342 | hw_cons++; | 1599 | hw_cons++; |
1343 | } | 1600 | } |
@@ -1382,11 +1639,12 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb, | |||
1382 | static int | 1639 | static int |
1383 | bnx2_rx_int(struct bnx2 *bp, int budget) | 1640 | bnx2_rx_int(struct bnx2 *bp, int budget) |
1384 | { | 1641 | { |
1642 | struct status_block *sblk = bp->status_blk; | ||
1385 | u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; | 1643 | u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; |
1386 | struct l2_fhdr *rx_hdr; | 1644 | struct l2_fhdr *rx_hdr; |
1387 | int rx_pkt = 0; | 1645 | int rx_pkt = 0; |
1388 | 1646 | ||
1389 | hw_cons = bp->status_blk->status_rx_quick_consumer_index0; | 1647 | hw_cons = bp->hw_rx_cons = sblk->status_rx_quick_consumer_index0; |
1390 | if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { | 1648 | if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { |
1391 | hw_cons++; | 1649 | hw_cons++; |
1392 | } | 1650 | } |
@@ -1506,6 +1764,15 @@ next_rx: | |||
1506 | 1764 | ||
1507 | if ((rx_pkt == budget)) | 1765 | if ((rx_pkt == budget)) |
1508 | break; | 1766 | break; |
1767 | |||
1768 | /* Refresh hw_cons to see if there is new work */ | ||
1769 | if (sw_cons == hw_cons) { | ||
1770 | hw_cons = bp->hw_rx_cons = | ||
1771 | sblk->status_rx_quick_consumer_index0; | ||
1772 | if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) | ||
1773 | hw_cons++; | ||
1774 | rmb(); | ||
1775 | } | ||
1509 | } | 1776 | } |
1510 | bp->rx_cons = sw_cons; | 1777 | bp->rx_cons = sw_cons; |
1511 | bp->rx_prod = sw_prod; | 1778 | bp->rx_prod = sw_prod; |
@@ -1573,15 +1840,27 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs) | |||
1573 | return IRQ_HANDLED; | 1840 | return IRQ_HANDLED; |
1574 | } | 1841 | } |
1575 | 1842 | ||
1843 | static inline int | ||
1844 | bnx2_has_work(struct bnx2 *bp) | ||
1845 | { | ||
1846 | struct status_block *sblk = bp->status_blk; | ||
1847 | |||
1848 | if ((sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) || | ||
1849 | (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)) | ||
1850 | return 1; | ||
1851 | |||
1852 | if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) != | ||
1853 | bp->link_up) | ||
1854 | return 1; | ||
1855 | |||
1856 | return 0; | ||
1857 | } | ||
1858 | |||
1576 | static int | 1859 | static int |
1577 | bnx2_poll(struct net_device *dev, int *budget) | 1860 | bnx2_poll(struct net_device *dev, int *budget) |
1578 | { | 1861 | { |
1579 | struct bnx2 *bp = dev->priv; | 1862 | struct bnx2 *bp = dev->priv; |
1580 | int rx_done = 1; | ||
1581 | 1863 | ||
1582 | bp->last_status_idx = bp->status_blk->status_idx; | ||
1583 | |||
1584 | rmb(); | ||
1585 | if ((bp->status_blk->status_attn_bits & | 1864 | if ((bp->status_blk->status_attn_bits & |
1586 | STATUS_ATTN_BITS_LINK_STATE) != | 1865 | STATUS_ATTN_BITS_LINK_STATE) != |
1587 | (bp->status_blk->status_attn_bits_ack & | 1866 | (bp->status_blk->status_attn_bits_ack & |
@@ -1592,11 +1871,10 @@ bnx2_poll(struct net_device *dev, int *budget) | |||
1592 | spin_unlock(&bp->phy_lock); | 1871 | spin_unlock(&bp->phy_lock); |
1593 | } | 1872 | } |
1594 | 1873 | ||
1595 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { | 1874 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) |
1596 | bnx2_tx_int(bp); | 1875 | bnx2_tx_int(bp); |
1597 | } | ||
1598 | 1876 | ||
1599 | if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) { | 1877 | if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) { |
1600 | int orig_budget = *budget; | 1878 | int orig_budget = *budget; |
1601 | int work_done; | 1879 | int work_done; |
1602 | 1880 | ||
@@ -1606,13 +1884,12 @@ bnx2_poll(struct net_device *dev, int *budget) | |||
1606 | work_done = bnx2_rx_int(bp, orig_budget); | 1884 | work_done = bnx2_rx_int(bp, orig_budget); |
1607 | *budget -= work_done; | 1885 | *budget -= work_done; |
1608 | dev->quota -= work_done; | 1886 | dev->quota -= work_done; |
1609 | |||
1610 | if (work_done >= orig_budget) { | ||
1611 | rx_done = 0; | ||
1612 | } | ||
1613 | } | 1887 | } |
1614 | 1888 | ||
1615 | if (rx_done) { | 1889 | bp->last_status_idx = bp->status_blk->status_idx; |
1890 | rmb(); | ||
1891 | |||
1892 | if (!bnx2_has_work(bp)) { | ||
1616 | netif_rx_complete(dev); | 1893 | netif_rx_complete(dev); |
1617 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 1894 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
1618 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 1895 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
@@ -2383,21 +2660,27 @@ bnx2_init_nvram(struct bnx2 *bp) | |||
2383 | 2660 | ||
2384 | /* Flash interface has been reconfigured */ | 2661 | /* Flash interface has been reconfigured */ |
2385 | for (j = 0, flash = &flash_table[0]; j < entry_count; | 2662 | for (j = 0, flash = &flash_table[0]; j < entry_count; |
2386 | j++, flash++) { | 2663 | j++, flash++) { |
2387 | 2664 | if ((val & FLASH_BACKUP_STRAP_MASK) == | |
2388 | if (val == flash->config1) { | 2665 | (flash->config1 & FLASH_BACKUP_STRAP_MASK)) { |
2389 | bp->flash_info = flash; | 2666 | bp->flash_info = flash; |
2390 | break; | 2667 | break; |
2391 | } | 2668 | } |
2392 | } | 2669 | } |
2393 | } | 2670 | } |
2394 | else { | 2671 | else { |
2672 | u32 mask; | ||
2395 | /* Not yet been reconfigured */ | 2673 | /* Not yet been reconfigured */ |
2396 | 2674 | ||
2675 | if (val & (1 << 23)) | ||
2676 | mask = FLASH_BACKUP_STRAP_MASK; | ||
2677 | else | ||
2678 | mask = FLASH_STRAP_MASK; | ||
2679 | |||
2397 | for (j = 0, flash = &flash_table[0]; j < entry_count; | 2680 | for (j = 0, flash = &flash_table[0]; j < entry_count; |
2398 | j++, flash++) { | 2681 | j++, flash++) { |
2399 | 2682 | ||
2400 | if ((val & FLASH_STRAP_MASK) == flash->strapping) { | 2683 | if ((val & mask) == (flash->strapping & mask)) { |
2401 | bp->flash_info = flash; | 2684 | bp->flash_info = flash; |
2402 | 2685 | ||
2403 | /* Request access to the flash interface. */ | 2686 | /* Request access to the flash interface. */ |
@@ -2733,7 +3016,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |||
2733 | 3016 | ||
2734 | /* Deposit a driver reset signature so the firmware knows that | 3017 | /* Deposit a driver reset signature so the firmware knows that |
2735 | * this is a soft reset. */ | 3018 | * this is a soft reset. */ |
2736 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE, | 3019 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE, |
2737 | BNX2_DRV_RESET_SIGNATURE_MAGIC); | 3020 | BNX2_DRV_RESET_SIGNATURE_MAGIC); |
2738 | 3021 | ||
2739 | bp->fw_timed_out = 0; | 3022 | bp->fw_timed_out = 0; |
@@ -2962,6 +3245,7 @@ bnx2_init_tx_ring(struct bnx2 *bp) | |||
2962 | 3245 | ||
2963 | bp->tx_prod = 0; | 3246 | bp->tx_prod = 0; |
2964 | bp->tx_cons = 0; | 3247 | bp->tx_cons = 0; |
3248 | bp->hw_tx_cons = 0; | ||
2965 | bp->tx_prod_bseq = 0; | 3249 | bp->tx_prod_bseq = 0; |
2966 | 3250 | ||
2967 | val = BNX2_L2CTX_TYPE_TYPE_L2; | 3251 | val = BNX2_L2CTX_TYPE_TYPE_L2; |
@@ -2994,6 +3278,7 @@ bnx2_init_rx_ring(struct bnx2 *bp) | |||
2994 | 3278 | ||
2995 | ring_prod = prod = bp->rx_prod = 0; | 3279 | ring_prod = prod = bp->rx_prod = 0; |
2996 | bp->rx_cons = 0; | 3280 | bp->rx_cons = 0; |
3281 | bp->hw_rx_cons = 0; | ||
2997 | bp->rx_prod_bseq = 0; | 3282 | bp->rx_prod_bseq = 0; |
2998 | 3283 | ||
2999 | rxbd = &bp->rx_desc_ring[0]; | 3284 | rxbd = &bp->rx_desc_ring[0]; |
@@ -3079,7 +3364,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp) | |||
3079 | struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; | 3364 | struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; |
3080 | struct sk_buff *skb = rx_buf->skb; | 3365 | struct sk_buff *skb = rx_buf->skb; |
3081 | 3366 | ||
3082 | if (skb == 0) | 3367 | if (skb == NULL) |
3083 | continue; | 3368 | continue; |
3084 | 3369 | ||
3085 | pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), | 3370 | pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), |
@@ -3234,7 +3519,7 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3234 | { 0x1408, 0, 0x01c00800, 0x00000000 }, | 3519 | { 0x1408, 0, 0x01c00800, 0x00000000 }, |
3235 | { 0x149c, 0, 0x8000ffff, 0x00000000 }, | 3520 | { 0x149c, 0, 0x8000ffff, 0x00000000 }, |
3236 | { 0x14a8, 0, 0x00000000, 0x000001ff }, | 3521 | { 0x14a8, 0, 0x00000000, 0x000001ff }, |
3237 | { 0x14ac, 0, 0x4fffffff, 0x10000000 }, | 3522 | { 0x14ac, 0, 0x0fffffff, 0x10000000 }, |
3238 | { 0x14b0, 0, 0x00000002, 0x00000001 }, | 3523 | { 0x14b0, 0, 0x00000002, 0x00000001 }, |
3239 | { 0x14b8, 0, 0x00000000, 0x00000000 }, | 3524 | { 0x14b8, 0, 0x00000000, 0x00000000 }, |
3240 | { 0x14c0, 0, 0x00000000, 0x00000009 }, | 3525 | { 0x14c0, 0, 0x00000000, 0x00000009 }, |
@@ -3577,7 +3862,7 @@ bnx2_test_memory(struct bnx2 *bp) | |||
3577 | u32 len; | 3862 | u32 len; |
3578 | } mem_tbl[] = { | 3863 | } mem_tbl[] = { |
3579 | { 0x60000, 0x4000 }, | 3864 | { 0x60000, 0x4000 }, |
3580 | { 0xa0000, 0x4000 }, | 3865 | { 0xa0000, 0x3000 }, |
3581 | { 0xe0000, 0x4000 }, | 3866 | { 0xe0000, 0x4000 }, |
3582 | { 0x120000, 0x4000 }, | 3867 | { 0x120000, 0x4000 }, |
3583 | { 0x1a0000, 0x4000 }, | 3868 | { 0x1a0000, 0x4000 }, |
@@ -3810,7 +4095,7 @@ bnx2_timer(unsigned long data) | |||
3810 | goto bnx2_restart_timer; | 4095 | goto bnx2_restart_timer; |
3811 | 4096 | ||
3812 | msg = (u32) ++bp->fw_drv_pulse_wr_seq; | 4097 | msg = (u32) ++bp->fw_drv_pulse_wr_seq; |
3813 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg); | 4098 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); |
3814 | 4099 | ||
3815 | if ((bp->phy_flags & PHY_SERDES_FLAG) && | 4100 | if ((bp->phy_flags & PHY_SERDES_FLAG) && |
3816 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { | 4101 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { |
@@ -4264,7 +4549,8 @@ bnx2_get_stats(struct net_device *dev) | |||
4264 | (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions + | 4549 | (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions + |
4265 | stats_blk->stat_Dot3StatsLateCollisions); | 4550 | stats_blk->stat_Dot3StatsLateCollisions); |
4266 | 4551 | ||
4267 | if (CHIP_NUM(bp) == CHIP_NUM_5706) | 4552 | if ((CHIP_NUM(bp) == CHIP_NUM_5706) || |
4553 | (CHIP_ID(bp) == CHIP_ID_5708_A0)) | ||
4268 | net_stats->tx_carrier_errors = 0; | 4554 | net_stats->tx_carrier_errors = 0; |
4269 | else { | 4555 | else { |
4270 | net_stats->tx_carrier_errors = | 4556 | net_stats->tx_carrier_errors = |
@@ -4814,6 +5100,14 @@ static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { | |||
4814 | 4,4,4,4,4, | 5100 | 4,4,4,4,4, |
4815 | }; | 5101 | }; |
4816 | 5102 | ||
5103 | static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = { | ||
5104 | 8,0,8,8,8,8,8,8,8,8, | ||
5105 | 4,4,4,4,4,4,4,4,4,4, | ||
5106 | 4,4,4,4,4,4,4,4,4,4, | ||
5107 | 4,4,4,4,4,4,4,4,4,4, | ||
5108 | 4,4,4,4,4, | ||
5109 | }; | ||
5110 | |||
4817 | #define BNX2_NUM_TESTS 6 | 5111 | #define BNX2_NUM_TESTS 6 |
4818 | 5112 | ||
4819 | static struct { | 5113 | static struct { |
@@ -4922,8 +5216,13 @@ bnx2_get_ethtool_stats(struct net_device *dev, | |||
4922 | return; | 5216 | return; |
4923 | } | 5217 | } |
4924 | 5218 | ||
4925 | if (CHIP_NUM(bp) == CHIP_NUM_5706) | 5219 | if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || |
5220 | (CHIP_ID(bp) == CHIP_ID_5706_A1) || | ||
5221 | (CHIP_ID(bp) == CHIP_ID_5706_A2) || | ||
5222 | (CHIP_ID(bp) == CHIP_ID_5708_A0)) | ||
4926 | stats_len_arr = bnx2_5706_stats_len_arr; | 5223 | stats_len_arr = bnx2_5706_stats_len_arr; |
5224 | else | ||
5225 | stats_len_arr = bnx2_5708_stats_len_arr; | ||
4927 | 5226 | ||
4928 | for (i = 0; i < BNX2_NUM_STATS; i++) { | 5227 | for (i = 0; i < BNX2_NUM_STATS; i++) { |
4929 | if (stats_len_arr[i] == 0) { | 5228 | if (stats_len_arr[i] == 0) { |
@@ -5205,8 +5504,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5205 | 5504 | ||
5206 | bp->chip_id = REG_RD(bp, BNX2_MISC_ID); | 5505 | bp->chip_id = REG_RD(bp, BNX2_MISC_ID); |
5207 | 5506 | ||
5208 | bp->phy_addr = 1; | ||
5209 | |||
5210 | /* Get bus information. */ | 5507 | /* Get bus information. */ |
5211 | reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); | 5508 | reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); |
5212 | if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { | 5509 | if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { |
@@ -5269,10 +5566,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5269 | 5566 | ||
5270 | bnx2_init_nvram(bp); | 5567 | bnx2_init_nvram(bp); |
5271 | 5568 | ||
5569 | reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); | ||
5570 | |||
5571 | if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == | ||
5572 | BNX2_SHM_HDR_SIGNATURE_SIG) | ||
5573 | bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); | ||
5574 | else | ||
5575 | bp->shmem_base = HOST_VIEW_SHMEM_BASE; | ||
5576 | |||
5272 | /* Get the permanent MAC address. First we need to make sure the | 5577 | /* Get the permanent MAC address. First we need to make sure the |
5273 | * firmware is actually running. | 5578 | * firmware is actually running. |
5274 | */ | 5579 | */ |
5275 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE); | 5580 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE); |
5276 | 5581 | ||
5277 | if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != | 5582 | if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != |
5278 | BNX2_DEV_INFO_SIGNATURE_MAGIC) { | 5583 | BNX2_DEV_INFO_SIGNATURE_MAGIC) { |
@@ -5281,14 +5586,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5281 | goto err_out_unmap; | 5586 | goto err_out_unmap; |
5282 | } | 5587 | } |
5283 | 5588 | ||
5284 | bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | 5589 | bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV); |
5285 | BNX2_DEV_INFO_BC_REV); | ||
5286 | 5590 | ||
5287 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER); | 5591 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER); |
5288 | bp->mac_addr[0] = (u8) (reg >> 8); | 5592 | bp->mac_addr[0] = (u8) (reg >> 8); |
5289 | bp->mac_addr[1] = (u8) reg; | 5593 | bp->mac_addr[1] = (u8) reg; |
5290 | 5594 | ||
5291 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER); | 5595 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER); |
5292 | bp->mac_addr[2] = (u8) (reg >> 24); | 5596 | bp->mac_addr[2] = (u8) (reg >> 24); |
5293 | bp->mac_addr[3] = (u8) (reg >> 16); | 5597 | bp->mac_addr[3] = (u8) (reg >> 16); |
5294 | bp->mac_addr[4] = (u8) (reg >> 8); | 5598 | bp->mac_addr[4] = (u8) (reg >> 8); |
@@ -5316,10 +5620,19 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5316 | bp->timer_interval = HZ; | 5620 | bp->timer_interval = HZ; |
5317 | bp->current_interval = HZ; | 5621 | bp->current_interval = HZ; |
5318 | 5622 | ||
5623 | bp->phy_addr = 1; | ||
5624 | |||
5319 | /* Disable WOL support if we are running on a SERDES chip. */ | 5625 | /* Disable WOL support if we are running on a SERDES chip. */ |
5320 | if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { | 5626 | if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { |
5321 | bp->phy_flags |= PHY_SERDES_FLAG; | 5627 | bp->phy_flags |= PHY_SERDES_FLAG; |
5322 | bp->flags |= NO_WOL_FLAG; | 5628 | bp->flags |= NO_WOL_FLAG; |
5629 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { | ||
5630 | bp->phy_addr = 2; | ||
5631 | reg = REG_RD_IND(bp, bp->shmem_base + | ||
5632 | BNX2_SHARED_HW_CFG_CONFIG); | ||
5633 | if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) | ||
5634 | bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; | ||
5635 | } | ||
5323 | } | 5636 | } |
5324 | 5637 | ||
5325 | if (CHIP_ID(bp) == CHIP_ID_5706_A0) { | 5638 | if (CHIP_ID(bp) == CHIP_ID_5706_A0) { |
@@ -5339,8 +5652,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5339 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 5652 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
5340 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; | 5653 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; |
5341 | 5654 | ||
5342 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | 5655 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG); |
5343 | BNX2_PORT_HW_CFG_CONFIG); | ||
5344 | reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; | 5656 | reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; |
5345 | if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { | 5657 | if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { |
5346 | bp->autoneg = 0; | 5658 | bp->autoneg = 0; |