aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-12-05 09:37:56 -0500
committerDavid Howells <dhowells@warthog.cambridge.redhat.com>2006-12-05 09:37:56 -0500
commit4c1ac1b49122b805adfa4efc620592f68dccf5db (patch)
tree87557f4bc2fd4fe65b7570489c2f610c45c0adcd /drivers/net/bnx2.c
parentc4028958b6ecad064b1a6303a6a5906d4fe48d73 (diff)
parentd916faace3efc0bf19fe9a615a1ab8fa1a24cd93 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/infiniband/core/iwcm.c drivers/net/chelsio/cxgb2.c drivers/net/wireless/bcm43xx/bcm43xx_main.c drivers/net/wireless/prism54/islpci_eth.c drivers/usb/core/hub.h drivers/usb/input/hid-core.c net/core/netpoll.c Fix up merge failures with Linus's head and fix new compilation failures. Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c689
1 files changed, 388 insertions, 301 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index b12cc4596b8d..5bacb7587df4 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -53,11 +53,12 @@
53 53
54#include "bnx2.h" 54#include "bnx2.h"
55#include "bnx2_fw.h" 55#include "bnx2_fw.h"
56#include "bnx2_fw2.h"
56 57
57#define DRV_MODULE_NAME "bnx2" 58#define DRV_MODULE_NAME "bnx2"
58#define PFX DRV_MODULE_NAME ": " 59#define PFX DRV_MODULE_NAME ": "
59#define DRV_MODULE_VERSION "1.4.45" 60#define DRV_MODULE_VERSION "1.5.1"
60#define DRV_MODULE_RELDATE "September 29, 2006" 61#define DRV_MODULE_RELDATE "November 15, 2006"
61 62
62#define RUN_AT(x) (jiffies + (x)) 63#define RUN_AT(x) (jiffies + (x))
63 64
@@ -85,6 +86,7 @@ typedef enum {
85 NC370F, 86 NC370F,
86 BCM5708, 87 BCM5708,
87 BCM5708S, 88 BCM5708S,
89 BCM5709,
88} board_t; 90} board_t;
89 91
90/* indexed by board_t, above */ 92/* indexed by board_t, above */
@@ -98,6 +100,7 @@ static const struct {
98 { "HP NC370F Multifunction Gigabit Server Adapter" }, 100 { "HP NC370F Multifunction Gigabit Server Adapter" },
99 { "Broadcom NetXtreme II BCM5708 1000Base-T" }, 101 { "Broadcom NetXtreme II BCM5708 1000Base-T" },
100 { "Broadcom NetXtreme II BCM5708 1000Base-SX" }, 102 { "Broadcom NetXtreme II BCM5708 1000Base-SX" },
103 { "Broadcom NetXtreme II BCM5709 1000Base-T" },
101 }; 104 };
102 105
103static struct pci_device_id bnx2_pci_tbl[] = { 106static struct pci_device_id bnx2_pci_tbl[] = {
@@ -115,6 +118,8 @@ static struct pci_device_id bnx2_pci_tbl[] = {
115 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S }, 118 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
116 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S, 119 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
117 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S }, 120 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
121 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709,
122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709 },
118 { 0, } 123 { 0, }
119}; 124};
120 125
@@ -236,8 +241,23 @@ static void
236bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) 241bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
237{ 242{
238 offset += cid_addr; 243 offset += cid_addr;
239 REG_WR(bp, BNX2_CTX_DATA_ADR, offset); 244 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
240 REG_WR(bp, BNX2_CTX_DATA, val); 245 int i;
246
247 REG_WR(bp, BNX2_CTX_CTX_DATA, val);
248 REG_WR(bp, BNX2_CTX_CTX_CTRL,
249 offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
250 for (i = 0; i < 5; i++) {
251 u32 val;
252 val = REG_RD(bp, BNX2_CTX_CTX_CTRL);
253 if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0)
254 break;
255 udelay(5);
256 }
257 } else {
258 REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
259 REG_WR(bp, BNX2_CTX_DATA, val);
260 }
241} 261}
242 262
243static int 263static int
@@ -403,6 +423,14 @@ bnx2_free_mem(struct bnx2 *bp)
403{ 423{
404 int i; 424 int i;
405 425
426 for (i = 0; i < bp->ctx_pages; i++) {
427 if (bp->ctx_blk[i]) {
428 pci_free_consistent(bp->pdev, BCM_PAGE_SIZE,
429 bp->ctx_blk[i],
430 bp->ctx_blk_mapping[i]);
431 bp->ctx_blk[i] = NULL;
432 }
433 }
406 if (bp->status_blk) { 434 if (bp->status_blk) {
407 pci_free_consistent(bp->pdev, bp->status_stats_size, 435 pci_free_consistent(bp->pdev, bp->status_stats_size,
408 bp->status_blk, bp->status_blk_mapping); 436 bp->status_blk, bp->status_blk_mapping);
@@ -481,6 +509,18 @@ bnx2_alloc_mem(struct bnx2 *bp)
481 509
482 bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size; 510 bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
483 511
512 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
513 bp->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
514 if (bp->ctx_pages == 0)
515 bp->ctx_pages = 1;
516 for (i = 0; i < bp->ctx_pages; i++) {
517 bp->ctx_blk[i] = pci_alloc_consistent(bp->pdev,
518 BCM_PAGE_SIZE,
519 &bp->ctx_blk_mapping[i]);
520 if (bp->ctx_blk[i] == NULL)
521 goto alloc_mem_err;
522 }
523 }
484 return 0; 524 return 0;
485 525
486alloc_mem_err: 526alloc_mem_err:
@@ -803,13 +843,13 @@ bnx2_set_mac_link(struct bnx2 *bp)
803 843
804 val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | 844 val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
805 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | 845 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
806 BNX2_EMAC_MODE_25G); 846 BNX2_EMAC_MODE_25G_MODE);
807 847
808 if (bp->link_up) { 848 if (bp->link_up) {
809 switch (bp->line_speed) { 849 switch (bp->line_speed) {
810 case SPEED_10: 850 case SPEED_10:
811 if (CHIP_NUM(bp) == CHIP_NUM_5708) { 851 if (CHIP_NUM(bp) != CHIP_NUM_5706) {
812 val |= BNX2_EMAC_MODE_PORT_MII_10; 852 val |= BNX2_EMAC_MODE_PORT_MII_10M;
813 break; 853 break;
814 } 854 }
815 /* fall through */ 855 /* fall through */
@@ -817,7 +857,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
817 val |= BNX2_EMAC_MODE_PORT_MII; 857 val |= BNX2_EMAC_MODE_PORT_MII;
818 break; 858 break;
819 case SPEED_2500: 859 case SPEED_2500:
820 val |= BNX2_EMAC_MODE_25G; 860 val |= BNX2_EMAC_MODE_25G_MODE;
821 /* fall through */ 861 /* fall through */
822 case SPEED_1000: 862 case SPEED_1000:
823 val |= BNX2_EMAC_MODE_PORT_GMII; 863 val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -860,7 +900,7 @@ bnx2_set_link(struct bnx2 *bp)
860 u32 bmsr; 900 u32 bmsr;
861 u8 link_up; 901 u8 link_up;
862 902
863 if (bp->loopback == MAC_LOOPBACK) { 903 if (bp->loopback == MAC_LOOPBACK || bp->loopback == PHY_LOOPBACK) {
864 bp->link_up = 1; 904 bp->link_up = 1;
865 return 0; 905 return 0;
866 } 906 }
@@ -902,6 +942,7 @@ bnx2_set_link(struct bnx2 *bp)
902 u32 bmcr; 942 u32 bmcr;
903 943
904 bnx2_read_phy(bp, MII_BMCR, &bmcr); 944 bnx2_read_phy(bp, MII_BMCR, &bmcr);
945 bmcr &= ~BCM5708S_BMCR_FORCE_2500;
905 if (!(bmcr & BMCR_ANENABLE)) { 946 if (!(bmcr & BMCR_ANENABLE)) {
906 bnx2_write_phy(bp, MII_BMCR, bmcr | 947 bnx2_write_phy(bp, MII_BMCR, bmcr |
907 BMCR_ANENABLE); 948 BMCR_ANENABLE);
@@ -988,7 +1029,21 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
988 u32 new_bmcr; 1029 u32 new_bmcr;
989 int force_link_down = 0; 1030 int force_link_down = 0;
990 1031
991 if (CHIP_NUM(bp) == CHIP_NUM_5708) { 1032 bnx2_read_phy(bp, MII_ADVERTISE, &adv);
1033 adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
1034
1035 bnx2_read_phy(bp, MII_BMCR, &bmcr);
1036 new_bmcr = bmcr & ~(BMCR_ANENABLE | BCM5708S_BMCR_FORCE_2500);
1037 new_bmcr |= BMCR_SPEED1000;
1038 if (bp->req_line_speed == SPEED_2500) {
1039 new_bmcr |= BCM5708S_BMCR_FORCE_2500;
1040 bnx2_read_phy(bp, BCM5708S_UP1, &up1);
1041 if (!(up1 & BCM5708S_UP1_2G5)) {
1042 up1 |= BCM5708S_UP1_2G5;
1043 bnx2_write_phy(bp, BCM5708S_UP1, up1);
1044 force_link_down = 1;
1045 }
1046 } else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
992 bnx2_read_phy(bp, BCM5708S_UP1, &up1); 1047 bnx2_read_phy(bp, BCM5708S_UP1, &up1);
993 if (up1 & BCM5708S_UP1_2G5) { 1048 if (up1 & BCM5708S_UP1_2G5) {
994 up1 &= ~BCM5708S_UP1_2G5; 1049 up1 &= ~BCM5708S_UP1_2G5;
@@ -997,12 +1052,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
997 } 1052 }
998 } 1053 }
999 1054
1000 bnx2_read_phy(bp, MII_ADVERTISE, &adv);
1001 adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
1002
1003 bnx2_read_phy(bp, MII_BMCR, &bmcr);
1004 new_bmcr = bmcr & ~BMCR_ANENABLE;
1005 new_bmcr |= BMCR_SPEED1000;
1006 if (bp->req_duplex == DUPLEX_FULL) { 1055 if (bp->req_duplex == DUPLEX_FULL) {
1007 adv |= ADVERTISE_1000XFULL; 1056 adv |= ADVERTISE_1000XFULL;
1008 new_bmcr |= BMCR_FULLDPLX; 1057 new_bmcr |= BMCR_FULLDPLX;
@@ -1023,6 +1072,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
1023 bp->link_up = 0; 1072 bp->link_up = 0;
1024 netif_carrier_off(bp->dev); 1073 netif_carrier_off(bp->dev);
1025 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 1074 bnx2_write_phy(bp, MII_BMCR, new_bmcr);
1075 bnx2_report_link(bp);
1026 } 1076 }
1027 bnx2_write_phy(bp, MII_ADVERTISE, adv); 1077 bnx2_write_phy(bp, MII_ADVERTISE, adv);
1028 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 1078 bnx2_write_phy(bp, MII_BMCR, new_bmcr);
@@ -1048,30 +1098,26 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
1048 if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) { 1098 if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) {
1049 /* Force a link down visible on the other side */ 1099 /* Force a link down visible on the other side */
1050 if (bp->link_up) { 1100 if (bp->link_up) {
1051 int i;
1052
1053 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); 1101 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
1054 for (i = 0; i < 110; i++) { 1102 spin_unlock_bh(&bp->phy_lock);
1055 udelay(100); 1103 msleep(20);
1056 } 1104 spin_lock_bh(&bp->phy_lock);
1057 } 1105 }
1058 1106
1059 bnx2_write_phy(bp, MII_ADVERTISE, new_adv); 1107 bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
1060 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | 1108 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
1061 BMCR_ANENABLE); 1109 BMCR_ANENABLE);
1062 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 1110 /* Speed up link-up time when the link partner
1063 /* Speed up link-up time when the link partner 1111 * does not autonegotiate which is very common
1064 * does not autonegotiate which is very common 1112 * in blade servers. Some blade servers use
1065 * in blade servers. Some blade servers use 1113 * IPMI for kerboard input and it's important
1066 * IPMI for kerboard input and it's important 1114 * to minimize link disruptions. Autoneg. involves
1067 * to minimize link disruptions. Autoneg. involves 1115 * exchanging base pages plus 3 next pages and
1068 * exchanging base pages plus 3 next pages and 1116 * normally completes in about 120 msec.
1069 * normally completes in about 120 msec. 1117 */
1070 */ 1118 bp->current_interval = SERDES_AN_TIMEOUT;
1071 bp->current_interval = SERDES_AN_TIMEOUT; 1119 bp->serdes_an_pending = 1;
1072 bp->serdes_an_pending = 1; 1120 mod_timer(&bp->timer, jiffies + bp->current_interval);
1073 mod_timer(&bp->timer, jiffies + bp->current_interval);
1074 }
1075 } 1121 }
1076 1122
1077 return 0; 1123 return 0;
@@ -1153,7 +1199,6 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
1153 } 1199 }
1154 if (new_bmcr != bmcr) { 1200 if (new_bmcr != bmcr) {
1155 u32 bmsr; 1201 u32 bmsr;
1156 int i = 0;
1157 1202
1158 bnx2_read_phy(bp, MII_BMSR, &bmsr); 1203 bnx2_read_phy(bp, MII_BMSR, &bmsr);
1159 bnx2_read_phy(bp, MII_BMSR, &bmsr); 1204 bnx2_read_phy(bp, MII_BMSR, &bmsr);
@@ -1161,12 +1206,12 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
1161 if (bmsr & BMSR_LSTATUS) { 1206 if (bmsr & BMSR_LSTATUS) {
1162 /* Force link down */ 1207 /* Force link down */
1163 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); 1208 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
1164 do { 1209 spin_unlock_bh(&bp->phy_lock);
1165 udelay(100); 1210 msleep(50);
1166 bnx2_read_phy(bp, MII_BMSR, &bmsr); 1211 spin_lock_bh(&bp->phy_lock);
1167 bnx2_read_phy(bp, MII_BMSR, &bmsr); 1212
1168 i++; 1213 bnx2_read_phy(bp, MII_BMSR, &bmsr);
1169 } while ((bmsr & BMSR_LSTATUS) && (i < 620)); 1214 bnx2_read_phy(bp, MII_BMSR, &bmsr);
1170 } 1215 }
1171 1216
1172 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 1217 bnx2_write_phy(bp, MII_BMCR, new_bmcr);
@@ -1258,9 +1303,8 @@ bnx2_init_5706s_phy(struct bnx2 *bp)
1258{ 1303{
1259 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; 1304 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
1260 1305
1261 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 1306 if (CHIP_NUM(bp) == CHIP_NUM_5706)
1262 REG_WR(bp, BNX2_MISC_UNUSED0, 0x300); 1307 REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);
1263 }
1264 1308
1265 if (bp->dev->mtu > 1500) { 1309 if (bp->dev->mtu > 1500) {
1266 u32 val; 1310 u32 val;
@@ -1397,13 +1441,13 @@ bnx2_set_phy_loopback(struct bnx2 *bp)
1397 for (i = 0; i < 10; i++) { 1441 for (i = 0; i < 10; i++) {
1398 if (bnx2_test_link(bp) == 0) 1442 if (bnx2_test_link(bp) == 0)
1399 break; 1443 break;
1400 udelay(10); 1444 msleep(100);
1401 } 1445 }
1402 1446
1403 mac_mode = REG_RD(bp, BNX2_EMAC_MODE); 1447 mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
1404 mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | 1448 mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
1405 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | 1449 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
1406 BNX2_EMAC_MODE_25G); 1450 BNX2_EMAC_MODE_25G_MODE);
1407 1451
1408 mac_mode |= BNX2_EMAC_MODE_PORT_GMII; 1452 mac_mode |= BNX2_EMAC_MODE_PORT_GMII;
1409 REG_WR(bp, BNX2_EMAC_MODE, mac_mode); 1453 REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
@@ -1454,6 +1498,40 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
1454 return 0; 1498 return 0;
1455} 1499}
1456 1500
1501static int
1502bnx2_init_5709_context(struct bnx2 *bp)
1503{
1504 int i, ret = 0;
1505 u32 val;
1506
1507 val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
1508 val |= (BCM_PAGE_BITS - 8) << 16;
1509 REG_WR(bp, BNX2_CTX_COMMAND, val);
1510 for (i = 0; i < bp->ctx_pages; i++) {
1511 int j;
1512
1513 REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0,
1514 (bp->ctx_blk_mapping[i] & 0xffffffff) |
1515 BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID);
1516 REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA1,
1517 (u64) bp->ctx_blk_mapping[i] >> 32);
1518 REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL, i |
1519 BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
1520 for (j = 0; j < 10; j++) {
1521
1522 val = REG_RD(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL);
1523 if (!(val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ))
1524 break;
1525 udelay(5);
1526 }
1527 if (val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) {
1528 ret = -EBUSY;
1529 break;
1530 }
1531 }
1532 return ret;
1533}
1534
1457static void 1535static void
1458bnx2_init_context(struct bnx2 *bp) 1536bnx2_init_context(struct bnx2 *bp)
1459{ 1537{
@@ -1576,9 +1654,8 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
1576 return -ENOMEM; 1654 return -ENOMEM;
1577 } 1655 }
1578 1656
1579 if (unlikely((align = (unsigned long) skb->data & 0x7))) { 1657 if (unlikely((align = (unsigned long) skb->data & (BNX2_RX_ALIGN - 1))))
1580 skb_reserve(skb, 8 - align); 1658 skb_reserve(skb, BNX2_RX_ALIGN - align);
1581 }
1582 1659
1583 mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, 1660 mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
1584 PCI_DMA_FROMDEVICE); 1661 PCI_DMA_FROMDEVICE);
@@ -2040,7 +2117,8 @@ bnx2_set_rx_mode(struct net_device *dev)
2040 if (dev->flags & IFF_PROMISC) { 2117 if (dev->flags & IFF_PROMISC) {
2041 /* Promiscuous mode. */ 2118 /* Promiscuous mode. */
2042 rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; 2119 rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
2043 sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN; 2120 sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
2121 BNX2_RPM_SORT_USER0_PROM_VLAN;
2044 } 2122 }
2045 else if (dev->flags & IFF_ALLMULTI) { 2123 else if (dev->flags & IFF_ALLMULTI) {
2046 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { 2124 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
@@ -2208,11 +2286,12 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,
2208 } 2286 }
2209} 2287}
2210 2288
2211static void 2289static int
2212load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) 2290load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
2213{ 2291{
2214 u32 offset; 2292 u32 offset;
2215 u32 val; 2293 u32 val;
2294 int rc;
2216 2295
2217 /* Halt the CPU. */ 2296 /* Halt the CPU. */
2218 val = REG_RD_IND(bp, cpu_reg->mode); 2297 val = REG_RD_IND(bp, cpu_reg->mode);
@@ -2222,7 +2301,18 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
2222 2301
2223 /* Load the Text area. */ 2302 /* Load the Text area. */
2224 offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base); 2303 offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
2225 if (fw->text) { 2304 if (fw->gz_text) {
2305 u32 text_len;
2306 void *text;
2307
2308 rc = bnx2_gunzip(bp, fw->gz_text, fw->gz_text_len, &text,
2309 &text_len);
2310 if (rc)
2311 return rc;
2312
2313 fw->text = text;
2314 }
2315 if (fw->gz_text) {
2226 int j; 2316 int j;
2227 2317
2228 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) { 2318 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
@@ -2280,13 +2370,15 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
2280 val &= ~cpu_reg->mode_value_halt; 2370 val &= ~cpu_reg->mode_value_halt;
2281 REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); 2371 REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
2282 REG_WR_IND(bp, cpu_reg->mode, val); 2372 REG_WR_IND(bp, cpu_reg->mode, val);
2373
2374 return 0;
2283} 2375}
2284 2376
2285static int 2377static int
2286bnx2_init_cpus(struct bnx2 *bp) 2378bnx2_init_cpus(struct bnx2 *bp)
2287{ 2379{
2288 struct cpu_reg cpu_reg; 2380 struct cpu_reg cpu_reg;
2289 struct fw_info fw; 2381 struct fw_info *fw;
2290 int rc = 0; 2382 int rc = 0;
2291 void *text; 2383 void *text;
2292 u32 text_len; 2384 u32 text_len;
@@ -2323,44 +2415,15 @@ bnx2_init_cpus(struct bnx2 *bp)
2323 cpu_reg.spad_base = BNX2_RXP_SCRATCH; 2415 cpu_reg.spad_base = BNX2_RXP_SCRATCH;
2324 cpu_reg.mips_view_base = 0x8000000; 2416 cpu_reg.mips_view_base = 0x8000000;
2325 2417
2326 fw.ver_major = bnx2_RXP_b06FwReleaseMajor; 2418 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2327 fw.ver_minor = bnx2_RXP_b06FwReleaseMinor; 2419 fw = &bnx2_rxp_fw_09;
2328 fw.ver_fix = bnx2_RXP_b06FwReleaseFix; 2420 else
2329 fw.start_addr = bnx2_RXP_b06FwStartAddr; 2421 fw = &bnx2_rxp_fw_06;
2330
2331 fw.text_addr = bnx2_RXP_b06FwTextAddr;
2332 fw.text_len = bnx2_RXP_b06FwTextLen;
2333 fw.text_index = 0;
2334 2422
2335 rc = bnx2_gunzip(bp, bnx2_RXP_b06FwText, sizeof(bnx2_RXP_b06FwText), 2423 rc = load_cpu_fw(bp, &cpu_reg, fw);
2336 &text, &text_len);
2337 if (rc) 2424 if (rc)
2338 goto init_cpu_err; 2425 goto init_cpu_err;
2339 2426
2340 fw.text = text;
2341
2342 fw.data_addr = bnx2_RXP_b06FwDataAddr;
2343 fw.data_len = bnx2_RXP_b06FwDataLen;
2344 fw.data_index = 0;
2345 fw.data = bnx2_RXP_b06FwData;
2346
2347 fw.sbss_addr = bnx2_RXP_b06FwSbssAddr;
2348 fw.sbss_len = bnx2_RXP_b06FwSbssLen;
2349 fw.sbss_index = 0;
2350 fw.sbss = bnx2_RXP_b06FwSbss;
2351
2352 fw.bss_addr = bnx2_RXP_b06FwBssAddr;
2353 fw.bss_len = bnx2_RXP_b06FwBssLen;
2354 fw.bss_index = 0;
2355 fw.bss = bnx2_RXP_b06FwBss;
2356
2357 fw.rodata_addr = bnx2_RXP_b06FwRodataAddr;
2358 fw.rodata_len = bnx2_RXP_b06FwRodataLen;
2359 fw.rodata_index = 0;
2360 fw.rodata = bnx2_RXP_b06FwRodata;
2361
2362 load_cpu_fw(bp, &cpu_reg, &fw);
2363
2364 /* Initialize the TX Processor. */ 2427 /* Initialize the TX Processor. */
2365 cpu_reg.mode = BNX2_TXP_CPU_MODE; 2428 cpu_reg.mode = BNX2_TXP_CPU_MODE;
2366 cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT; 2429 cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT;
@@ -2375,44 +2438,15 @@ bnx2_init_cpus(struct bnx2 *bp)
2375 cpu_reg.spad_base = BNX2_TXP_SCRATCH; 2438 cpu_reg.spad_base = BNX2_TXP_SCRATCH;
2376 cpu_reg.mips_view_base = 0x8000000; 2439 cpu_reg.mips_view_base = 0x8000000;
2377 2440
2378 fw.ver_major = bnx2_TXP_b06FwReleaseMajor; 2441 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2379 fw.ver_minor = bnx2_TXP_b06FwReleaseMinor; 2442 fw = &bnx2_txp_fw_09;
2380 fw.ver_fix = bnx2_TXP_b06FwReleaseFix; 2443 else
2381 fw.start_addr = bnx2_TXP_b06FwStartAddr; 2444 fw = &bnx2_txp_fw_06;
2382
2383 fw.text_addr = bnx2_TXP_b06FwTextAddr;
2384 fw.text_len = bnx2_TXP_b06FwTextLen;
2385 fw.text_index = 0;
2386 2445
2387 rc = bnx2_gunzip(bp, bnx2_TXP_b06FwText, sizeof(bnx2_TXP_b06FwText), 2446 rc = load_cpu_fw(bp, &cpu_reg, fw);
2388 &text, &text_len);
2389 if (rc) 2447 if (rc)
2390 goto init_cpu_err; 2448 goto init_cpu_err;
2391 2449
2392 fw.text = text;
2393
2394 fw.data_addr = bnx2_TXP_b06FwDataAddr;
2395 fw.data_len = bnx2_TXP_b06FwDataLen;
2396 fw.data_index = 0;
2397 fw.data = bnx2_TXP_b06FwData;
2398
2399 fw.sbss_addr = bnx2_TXP_b06FwSbssAddr;
2400 fw.sbss_len = bnx2_TXP_b06FwSbssLen;
2401 fw.sbss_index = 0;
2402 fw.sbss = bnx2_TXP_b06FwSbss;
2403
2404 fw.bss_addr = bnx2_TXP_b06FwBssAddr;
2405 fw.bss_len = bnx2_TXP_b06FwBssLen;
2406 fw.bss_index = 0;
2407 fw.bss = bnx2_TXP_b06FwBss;
2408
2409 fw.rodata_addr = bnx2_TXP_b06FwRodataAddr;
2410 fw.rodata_len = bnx2_TXP_b06FwRodataLen;
2411 fw.rodata_index = 0;
2412 fw.rodata = bnx2_TXP_b06FwRodata;
2413
2414 load_cpu_fw(bp, &cpu_reg, &fw);
2415
2416 /* Initialize the TX Patch-up Processor. */ 2450 /* Initialize the TX Patch-up Processor. */
2417 cpu_reg.mode = BNX2_TPAT_CPU_MODE; 2451 cpu_reg.mode = BNX2_TPAT_CPU_MODE;
2418 cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT; 2452 cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT;
@@ -2427,44 +2461,15 @@ bnx2_init_cpus(struct bnx2 *bp)
2427 cpu_reg.spad_base = BNX2_TPAT_SCRATCH; 2461 cpu_reg.spad_base = BNX2_TPAT_SCRATCH;
2428 cpu_reg.mips_view_base = 0x8000000; 2462 cpu_reg.mips_view_base = 0x8000000;
2429 2463
2430 fw.ver_major = bnx2_TPAT_b06FwReleaseMajor; 2464 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2431 fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor; 2465 fw = &bnx2_tpat_fw_09;
2432 fw.ver_fix = bnx2_TPAT_b06FwReleaseFix; 2466 else
2433 fw.start_addr = bnx2_TPAT_b06FwStartAddr; 2467 fw = &bnx2_tpat_fw_06;
2434
2435 fw.text_addr = bnx2_TPAT_b06FwTextAddr;
2436 fw.text_len = bnx2_TPAT_b06FwTextLen;
2437 fw.text_index = 0;
2438 2468
2439 rc = bnx2_gunzip(bp, bnx2_TPAT_b06FwText, sizeof(bnx2_TPAT_b06FwText), 2469 rc = load_cpu_fw(bp, &cpu_reg, fw);
2440 &text, &text_len);
2441 if (rc) 2470 if (rc)
2442 goto init_cpu_err; 2471 goto init_cpu_err;
2443 2472
2444 fw.text = text;
2445
2446 fw.data_addr = bnx2_TPAT_b06FwDataAddr;
2447 fw.data_len = bnx2_TPAT_b06FwDataLen;
2448 fw.data_index = 0;
2449 fw.data = bnx2_TPAT_b06FwData;
2450
2451 fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr;
2452 fw.sbss_len = bnx2_TPAT_b06FwSbssLen;
2453 fw.sbss_index = 0;
2454 fw.sbss = bnx2_TPAT_b06FwSbss;
2455
2456 fw.bss_addr = bnx2_TPAT_b06FwBssAddr;
2457 fw.bss_len = bnx2_TPAT_b06FwBssLen;
2458 fw.bss_index = 0;
2459 fw.bss = bnx2_TPAT_b06FwBss;
2460
2461 fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr;
2462 fw.rodata_len = bnx2_TPAT_b06FwRodataLen;
2463 fw.rodata_index = 0;
2464 fw.rodata = bnx2_TPAT_b06FwRodata;
2465
2466 load_cpu_fw(bp, &cpu_reg, &fw);
2467
2468 /* Initialize the Completion Processor. */ 2473 /* Initialize the Completion Processor. */
2469 cpu_reg.mode = BNX2_COM_CPU_MODE; 2474 cpu_reg.mode = BNX2_COM_CPU_MODE;
2470 cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT; 2475 cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT;
@@ -2479,44 +2484,36 @@ bnx2_init_cpus(struct bnx2 *bp)
2479 cpu_reg.spad_base = BNX2_COM_SCRATCH; 2484 cpu_reg.spad_base = BNX2_COM_SCRATCH;
2480 cpu_reg.mips_view_base = 0x8000000; 2485 cpu_reg.mips_view_base = 0x8000000;
2481 2486
2482 fw.ver_major = bnx2_COM_b06FwReleaseMajor; 2487 if (CHIP_NUM(bp) == CHIP_NUM_5709)
2483 fw.ver_minor = bnx2_COM_b06FwReleaseMinor; 2488 fw = &bnx2_com_fw_09;
2484 fw.ver_fix = bnx2_COM_b06FwReleaseFix; 2489 else
2485 fw.start_addr = bnx2_COM_b06FwStartAddr; 2490 fw = &bnx2_com_fw_06;
2486
2487 fw.text_addr = bnx2_COM_b06FwTextAddr;
2488 fw.text_len = bnx2_COM_b06FwTextLen;
2489 fw.text_index = 0;
2490 2491
2491 rc = bnx2_gunzip(bp, bnx2_COM_b06FwText, sizeof(bnx2_COM_b06FwText), 2492 rc = load_cpu_fw(bp, &cpu_reg, fw);
2492 &text, &text_len);
2493 if (rc) 2493 if (rc)
2494 goto init_cpu_err; 2494 goto init_cpu_err;
2495 2495
2496 fw.text = text; 2496 /* Initialize the Command Processor. */
2497 2497 cpu_reg.mode = BNX2_CP_CPU_MODE;
2498 fw.data_addr = bnx2_COM_b06FwDataAddr; 2498 cpu_reg.mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT;
2499 fw.data_len = bnx2_COM_b06FwDataLen; 2499 cpu_reg.mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA;
2500 fw.data_index = 0; 2500 cpu_reg.state = BNX2_CP_CPU_STATE;
2501 fw.data = bnx2_COM_b06FwData; 2501 cpu_reg.state_value_clear = 0xffffff;
2502 2502 cpu_reg.gpr0 = BNX2_CP_CPU_REG_FILE;
2503 fw.sbss_addr = bnx2_COM_b06FwSbssAddr; 2503 cpu_reg.evmask = BNX2_CP_CPU_EVENT_MASK;
2504 fw.sbss_len = bnx2_COM_b06FwSbssLen; 2504 cpu_reg.pc = BNX2_CP_CPU_PROGRAM_COUNTER;
2505 fw.sbss_index = 0; 2505 cpu_reg.inst = BNX2_CP_CPU_INSTRUCTION;
2506 fw.sbss = bnx2_COM_b06FwSbss; 2506 cpu_reg.bp = BNX2_CP_CPU_HW_BREAKPOINT;
2507 2507 cpu_reg.spad_base = BNX2_CP_SCRATCH;
2508 fw.bss_addr = bnx2_COM_b06FwBssAddr; 2508 cpu_reg.mips_view_base = 0x8000000;
2509 fw.bss_len = bnx2_COM_b06FwBssLen;
2510 fw.bss_index = 0;
2511 fw.bss = bnx2_COM_b06FwBss;
2512
2513 fw.rodata_addr = bnx2_COM_b06FwRodataAddr;
2514 fw.rodata_len = bnx2_COM_b06FwRodataLen;
2515 fw.rodata_index = 0;
2516 fw.rodata = bnx2_COM_b06FwRodata;
2517 2509
2518 load_cpu_fw(bp, &cpu_reg, &fw); 2510 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
2511 fw = &bnx2_cp_fw_09;
2519 2512
2513 load_cpu_fw(bp, &cpu_reg, fw);
2514 if (rc)
2515 goto init_cpu_err;
2516 }
2520init_cpu_err: 2517init_cpu_err:
2521 bnx2_gunzip_end(bp); 2518 bnx2_gunzip_end(bp);
2522 return rc; 2519 return rc;
@@ -3288,31 +3285,44 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
3288 * before we issue a reset. */ 3285 * before we issue a reset. */
3289 val = REG_RD(bp, BNX2_MISC_ID); 3286 val = REG_RD(bp, BNX2_MISC_ID);
3290 3287
3291 val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | 3288 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
3292 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 3289 REG_WR(bp, BNX2_MISC_COMMAND, BNX2_MISC_COMMAND_SW_RESET);
3293 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; 3290 REG_RD(bp, BNX2_MISC_COMMAND);
3291 udelay(5);
3294 3292
3295 /* Chip reset. */ 3293 val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
3296 REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); 3294 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
3297 3295
3298 if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || 3296 pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
3299 (CHIP_ID(bp) == CHIP_ID_5706_A1))
3300 msleep(15);
3301 3297
3302 /* Reset takes approximate 30 usec */ 3298 } else {
3303 for (i = 0; i < 10; i++) { 3299 val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3304 val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG); 3300 BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
3305 if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | 3301 BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
3306 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) { 3302
3307 break; 3303 /* Chip reset. */
3304 REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
3305
3306 if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
3307 (CHIP_ID(bp) == CHIP_ID_5706_A1)) {
3308 current->state = TASK_UNINTERRUPTIBLE;
3309 schedule_timeout(HZ / 50);
3308 } 3310 }
3309 udelay(10);
3310 }
3311 3311
3312 if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | 3312 /* Reset takes approximate 30 usec */
3313 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) { 3313 for (i = 0; i < 10; i++) {
3314 printk(KERN_ERR PFX "Chip reset did not complete\n"); 3314 val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
3315 return -EBUSY; 3315 if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3316 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
3317 break;
3318 udelay(10);
3319 }
3320
3321 if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3322 BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
3323 printk(KERN_ERR PFX "Chip reset did not complete\n");
3324 return -EBUSY;
3325 }
3316 } 3326 }
3317 3327
3318 /* Make sure byte swapping is properly configured. */ 3328 /* Make sure byte swapping is properly configured. */
@@ -3390,7 +3400,10 @@ bnx2_init_chip(struct bnx2 *bp)
3390 3400
3391 /* Initialize context mapping and zero out the quick contexts. The 3401 /* Initialize context mapping and zero out the quick contexts. The
3392 * context block must have already been enabled. */ 3402 * context block must have already been enabled. */
3393 bnx2_init_context(bp); 3403 if (CHIP_NUM(bp) == CHIP_NUM_5709)
3404 bnx2_init_5709_context(bp);
3405 else
3406 bnx2_init_context(bp);
3394 3407
3395 if ((rc = bnx2_init_cpus(bp)) != 0) 3408 if ((rc = bnx2_init_cpus(bp)) != 0)
3396 return rc; 3409 return rc;
@@ -3501,12 +3514,40 @@ bnx2_init_chip(struct bnx2 *bp)
3501 return rc; 3514 return rc;
3502} 3515}
3503 3516
3517static void
3518bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
3519{
3520 u32 val, offset0, offset1, offset2, offset3;
3521
3522 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
3523 offset0 = BNX2_L2CTX_TYPE_XI;
3524 offset1 = BNX2_L2CTX_CMD_TYPE_XI;
3525 offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI;
3526 offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI;
3527 } else {
3528 offset0 = BNX2_L2CTX_TYPE;
3529 offset1 = BNX2_L2CTX_CMD_TYPE;
3530 offset2 = BNX2_L2CTX_TBDR_BHADDR_HI;
3531 offset3 = BNX2_L2CTX_TBDR_BHADDR_LO;
3532 }
3533 val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2;
3534 CTX_WR(bp, GET_CID_ADDR(cid), offset0, val);
3535
3536 val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
3537 CTX_WR(bp, GET_CID_ADDR(cid), offset1, val);
3538
3539 val = (u64) bp->tx_desc_mapping >> 32;
3540 CTX_WR(bp, GET_CID_ADDR(cid), offset2, val);
3541
3542 val = (u64) bp->tx_desc_mapping & 0xffffffff;
3543 CTX_WR(bp, GET_CID_ADDR(cid), offset3, val);
3544}
3504 3545
3505static void 3546static void
3506bnx2_init_tx_ring(struct bnx2 *bp) 3547bnx2_init_tx_ring(struct bnx2 *bp)
3507{ 3548{
3508 struct tx_bd *txbd; 3549 struct tx_bd *txbd;
3509 u32 val; 3550 u32 cid;
3510 3551
3511 bp->tx_wake_thresh = bp->tx_ring_size / 2; 3552 bp->tx_wake_thresh = bp->tx_ring_size / 2;
3512 3553
@@ -3520,19 +3561,11 @@ bnx2_init_tx_ring(struct bnx2 *bp)
3520 bp->hw_tx_cons = 0; 3561 bp->hw_tx_cons = 0;
3521 bp->tx_prod_bseq = 0; 3562 bp->tx_prod_bseq = 0;
3522 3563
3523 val = BNX2_L2CTX_TYPE_TYPE_L2; 3564 cid = TX_CID;
3524 val |= BNX2_L2CTX_TYPE_SIZE_L2; 3565 bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
3525 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val); 3566 bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;
3526 3567
3527 val = BNX2_L2CTX_CMD_TYPE_TYPE_L2; 3568 bnx2_init_tx_context(bp, cid);
3528 val |= 8 << 16;
3529 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val);
3530
3531 val = (u64) bp->tx_desc_mapping >> 32;
3532 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, val);
3533
3534 val = (u64) bp->tx_desc_mapping & 0xffffffff;
3535 CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val);
3536} 3569}
3537 3570
3538static void 3571static void
@@ -3545,8 +3578,8 @@ bnx2_init_rx_ring(struct bnx2 *bp)
3545 3578
3546 /* 8 for CRC and VLAN */ 3579 /* 8 for CRC and VLAN */
3547 bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8; 3580 bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
3548 /* 8 for alignment */ 3581 /* hw alignment */
3549 bp->rx_buf_size = bp->rx_buf_use_size + 8; 3582 bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
3550 3583
3551 ring_prod = prod = bp->rx_prod = 0; 3584 ring_prod = prod = bp->rx_prod = 0;
3552 bp->rx_cons = 0; 3585 bp->rx_cons = 0;
@@ -3712,7 +3745,9 @@ bnx2_init_nic(struct bnx2 *bp)
3712 if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0) 3745 if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
3713 return rc; 3746 return rc;
3714 3747
3748 spin_lock_bh(&bp->phy_lock);
3715 bnx2_init_phy(bp); 3749 bnx2_init_phy(bp);
3750 spin_unlock_bh(&bp->phy_lock);
3716 bnx2_set_link(bp); 3751 bnx2_set_link(bp);
3717 return 0; 3752 return 0;
3718} 3753}
@@ -3952,7 +3987,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
3952 bnx2_set_mac_loopback(bp); 3987 bnx2_set_mac_loopback(bp);
3953 } 3988 }
3954 else if (loopback_mode == BNX2_PHY_LOOPBACK) { 3989 else if (loopback_mode == BNX2_PHY_LOOPBACK) {
3955 bp->loopback = 0; 3990 bp->loopback = PHY_LOOPBACK;
3956 bnx2_set_phy_loopback(bp); 3991 bnx2_set_phy_loopback(bp);
3957 } 3992 }
3958 else 3993 else
@@ -3992,8 +4027,8 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
3992 bp->tx_prod = NEXT_TX_BD(bp->tx_prod); 4027 bp->tx_prod = NEXT_TX_BD(bp->tx_prod);
3993 bp->tx_prod_bseq += pkt_size; 4028 bp->tx_prod_bseq += pkt_size;
3994 4029
3995 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod); 4030 REG_WR16(bp, bp->tx_bidx_addr, bp->tx_prod);
3996 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); 4031 REG_WR(bp, bp->tx_bseq_addr, bp->tx_prod_bseq);
3997 4032
3998 udelay(100); 4033 udelay(100);
3999 4034
@@ -4162,80 +4197,117 @@ bnx2_test_intr(struct bnx2 *bp)
4162} 4197}
4163 4198
4164static void 4199static void
4165bnx2_timer(unsigned long data) 4200bnx2_5706_serdes_timer(struct bnx2 *bp)
4166{ 4201{
4167 struct bnx2 *bp = (struct bnx2 *) data; 4202 spin_lock(&bp->phy_lock);
4168 u32 msg; 4203 if (bp->serdes_an_pending)
4204 bp->serdes_an_pending--;
4205 else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
4206 u32 bmcr;
4169 4207
4170 if (!netif_running(bp->dev)) 4208 bp->current_interval = bp->timer_interval;
4171 return;
4172 4209
4173 if (atomic_read(&bp->intr_sem) != 0) 4210 bnx2_read_phy(bp, MII_BMCR, &bmcr);
4174 goto bnx2_restart_timer;
4175 4211
4176 msg = (u32) ++bp->fw_drv_pulse_wr_seq; 4212 if (bmcr & BMCR_ANENABLE) {
4177 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); 4213 u32 phy1, phy2;
4178 4214
4179 bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); 4215 bnx2_write_phy(bp, 0x1c, 0x7c00);
4216 bnx2_read_phy(bp, 0x1c, &phy1);
4180 4217
4181 if ((bp->phy_flags & PHY_SERDES_FLAG) && 4218 bnx2_write_phy(bp, 0x17, 0x0f01);
4182 (CHIP_NUM(bp) == CHIP_NUM_5706)) { 4219 bnx2_read_phy(bp, 0x15, &phy2);
4220 bnx2_write_phy(bp, 0x17, 0x0f01);
4221 bnx2_read_phy(bp, 0x15, &phy2);
4183 4222
4184 spin_lock(&bp->phy_lock); 4223 if ((phy1 & 0x10) && /* SIGNAL DETECT */
4185 if (bp->serdes_an_pending) { 4224 !(phy2 & 0x20)) { /* no CONFIG */
4186 bp->serdes_an_pending--; 4225
4226 bmcr &= ~BMCR_ANENABLE;
4227 bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
4228 bnx2_write_phy(bp, MII_BMCR, bmcr);
4229 bp->phy_flags |= PHY_PARALLEL_DETECT_FLAG;
4230 }
4187 } 4231 }
4188 else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { 4232 }
4189 u32 bmcr; 4233 else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) &&
4234 (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
4235 u32 phy2;
4190 4236
4191 bp->current_interval = bp->timer_interval; 4237 bnx2_write_phy(bp, 0x17, 0x0f01);
4238 bnx2_read_phy(bp, 0x15, &phy2);
4239 if (phy2 & 0x20) {
4240 u32 bmcr;
4192 4241
4193 bnx2_read_phy(bp, MII_BMCR, &bmcr); 4242 bnx2_read_phy(bp, MII_BMCR, &bmcr);
4243 bmcr |= BMCR_ANENABLE;
4244 bnx2_write_phy(bp, MII_BMCR, bmcr);
4194 4245
4195 if (bmcr & BMCR_ANENABLE) { 4246 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
4196 u32 phy1, phy2; 4247 }
4248 } else
4249 bp->current_interval = bp->timer_interval;
4197 4250
4198 bnx2_write_phy(bp, 0x1c, 0x7c00); 4251 spin_unlock(&bp->phy_lock);
4199 bnx2_read_phy(bp, 0x1c, &phy1); 4252}
4200 4253
4201 bnx2_write_phy(bp, 0x17, 0x0f01); 4254static void
4202 bnx2_read_phy(bp, 0x15, &phy2); 4255bnx2_5708_serdes_timer(struct bnx2 *bp)
4203 bnx2_write_phy(bp, 0x17, 0x0f01); 4256{
4204 bnx2_read_phy(bp, 0x15, &phy2); 4257 if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
4258 bp->serdes_an_pending = 0;
4259 return;
4260 }
4205 4261
4206 if ((phy1 & 0x10) && /* SIGNAL DETECT */ 4262 spin_lock(&bp->phy_lock);
4207 !(phy2 & 0x20)) { /* no CONFIG */ 4263 if (bp->serdes_an_pending)
4264 bp->serdes_an_pending--;
4265 else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
4266 u32 bmcr;
4208 4267
4209 bmcr &= ~BMCR_ANENABLE; 4268 bnx2_read_phy(bp, MII_BMCR, &bmcr);
4210 bmcr |= BMCR_SPEED1000 | 4269
4211 BMCR_FULLDPLX; 4270 if (bmcr & BMCR_ANENABLE) {
4212 bnx2_write_phy(bp, MII_BMCR, bmcr); 4271 bmcr &= ~BMCR_ANENABLE;
4213 bp->phy_flags |= 4272 bmcr |= BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500;
4214 PHY_PARALLEL_DETECT_FLAG; 4273 bnx2_write_phy(bp, MII_BMCR, bmcr);
4215 } 4274 bp->current_interval = SERDES_FORCED_TIMEOUT;
4216 } 4275 } else {
4276 bmcr &= ~(BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500);
4277 bmcr |= BMCR_ANENABLE;
4278 bnx2_write_phy(bp, MII_BMCR, bmcr);
4279 bp->serdes_an_pending = 2;
4280 bp->current_interval = bp->timer_interval;
4217 } 4281 }
4218 else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) &&
4219 (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
4220 u32 phy2;
4221 4282
4222 bnx2_write_phy(bp, 0x17, 0x0f01); 4283 } else
4223 bnx2_read_phy(bp, 0x15, &phy2); 4284 bp->current_interval = bp->timer_interval;
4224 if (phy2 & 0x20) {
4225 u32 bmcr;
4226 4285
4227 bnx2_read_phy(bp, MII_BMCR, &bmcr); 4286 spin_unlock(&bp->phy_lock);
4228 bmcr |= BMCR_ANENABLE; 4287}
4229 bnx2_write_phy(bp, MII_BMCR, bmcr); 4288
4289static void
4290bnx2_timer(unsigned long data)
4291{
4292 struct bnx2 *bp = (struct bnx2 *) data;
4293 u32 msg;
4230 4294
4231 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; 4295 if (!netif_running(bp->dev))
4296 return;
4232 4297
4233 } 4298 if (atomic_read(&bp->intr_sem) != 0)
4234 } 4299 goto bnx2_restart_timer;
4235 else
4236 bp->current_interval = bp->timer_interval;
4237 4300
4238 spin_unlock(&bp->phy_lock); 4301 msg = (u32) ++bp->fw_drv_pulse_wr_seq;
4302 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
4303
4304 bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
4305
4306 if (bp->phy_flags & PHY_SERDES_FLAG) {
4307 if (CHIP_NUM(bp) == CHIP_NUM_5706)
4308 bnx2_5706_serdes_timer(bp);
4309 else if (CHIP_NUM(bp) == CHIP_NUM_5708)
4310 bnx2_5708_serdes_timer(bp);
4239 } 4311 }
4240 4312
4241bnx2_restart_timer: 4313bnx2_restart_timer:
@@ -4508,8 +4580,8 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4508 prod = NEXT_TX_BD(prod); 4580 prod = NEXT_TX_BD(prod);
4509 bp->tx_prod_bseq += skb->len; 4581 bp->tx_prod_bseq += skb->len;
4510 4582
4511 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); 4583 REG_WR16(bp, bp->tx_bidx_addr, prod);
4512 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); 4584 REG_WR(bp, bp->tx_bseq_addr, bp->tx_prod_bseq);
4513 4585
4514 mmiowb(); 4586 mmiowb();
4515 4587
@@ -4743,10 +4815,14 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
4743 } 4815 }
4744 else { 4816 else {
4745 if (bp->phy_flags & PHY_SERDES_FLAG) { 4817 if (bp->phy_flags & PHY_SERDES_FLAG) {
4746 if ((cmd->speed != SPEED_1000) || 4818 if ((cmd->speed != SPEED_1000 &&
4747 (cmd->duplex != DUPLEX_FULL)) { 4819 cmd->speed != SPEED_2500) ||
4820 (cmd->duplex != DUPLEX_FULL))
4821 return -EINVAL;
4822
4823 if (cmd->speed == SPEED_2500 &&
4824 !(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
4748 return -EINVAL; 4825 return -EINVAL;
4749 }
4750 } 4826 }
4751 else if (cmd->speed == SPEED_1000) { 4827 else if (cmd->speed == SPEED_1000) {
4752 return -EINVAL; 4828 return -EINVAL;
@@ -4903,11 +4979,10 @@ bnx2_nway_reset(struct net_device *dev)
4903 msleep(20); 4979 msleep(20);
4904 4980
4905 spin_lock_bh(&bp->phy_lock); 4981 spin_lock_bh(&bp->phy_lock);
4906 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 4982
4907 bp->current_interval = SERDES_AN_TIMEOUT; 4983 bp->current_interval = SERDES_AN_TIMEOUT;
4908 bp->serdes_an_pending = 1; 4984 bp->serdes_an_pending = 1;
4909 mod_timer(&bp->timer, jiffies + bp->current_interval); 4985 mod_timer(&bp->timer, jiffies + bp->current_interval);
4910 }
4911 } 4986 }
4912 4987
4913 bnx2_read_phy(bp, MII_BMCR, &bmcr); 4988 bnx2_read_phy(bp, MII_BMCR, &bmcr);
@@ -5288,6 +5363,8 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
5288 5363
5289 memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS); 5364 memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS);
5290 if (etest->flags & ETH_TEST_FL_OFFLINE) { 5365 if (etest->flags & ETH_TEST_FL_OFFLINE) {
5366 int i;
5367
5291 bnx2_netif_stop(bp); 5368 bnx2_netif_stop(bp);
5292 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG); 5369 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
5293 bnx2_free_skbs(bp); 5370 bnx2_free_skbs(bp);
@@ -5312,9 +5389,11 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
5312 } 5389 }
5313 5390
5314 /* wait for link up */ 5391 /* wait for link up */
5315 msleep_interruptible(3000); 5392 for (i = 0; i < 7; i++) {
5316 if ((!bp->link_up) && !(bp->phy_flags & PHY_SERDES_FLAG)) 5393 if (bp->link_up)
5317 msleep_interruptible(4000); 5394 break;
5395 msleep_interruptible(1000);
5396 }
5318 } 5397 }
5319 5398
5320 if (bnx2_test_nvram(bp) != 0) { 5399 if (bnx2_test_nvram(bp) != 0) {
@@ -5604,13 +5683,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5604 goto err_out_release; 5683 goto err_out_release;
5605 } 5684 }
5606 5685
5607 bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
5608 if (bp->pcix_cap == 0) {
5609 dev_err(&pdev->dev, "Cannot find PCIX capability, aborting.\n");
5610 rc = -EIO;
5611 goto err_out_release;
5612 }
5613
5614 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { 5686 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
5615 bp->flags |= USING_DAC_FLAG; 5687 bp->flags |= USING_DAC_FLAG;
5616 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) { 5688 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
@@ -5633,7 +5705,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5633 INIT_WORK(&bp->reset_task, bnx2_reset_task); 5705 INIT_WORK(&bp->reset_task, bnx2_reset_task);
5634 5706
5635 dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); 5707 dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
5636 mem_len = MB_GET_CID_ADDR(17); 5708 mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1);
5637 dev->mem_end = dev->mem_start + mem_len; 5709 dev->mem_end = dev->mem_start + mem_len;
5638 dev->irq = pdev->irq; 5710 dev->irq = pdev->irq;
5639 5711
@@ -5657,6 +5729,16 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5657 5729
5658 bp->chip_id = REG_RD(bp, BNX2_MISC_ID); 5730 bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
5659 5731
5732 if (CHIP_NUM(bp) != CHIP_NUM_5709) {
5733 bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
5734 if (bp->pcix_cap == 0) {
5735 dev_err(&pdev->dev,
5736 "Cannot find PCIX capability, aborting.\n");
5737 rc = -EIO;
5738 goto err_out_unmap;
5739 }
5740 }
5741
5660 /* Get bus information. */ 5742 /* Get bus information. */
5661 reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); 5743 reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
5662 if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { 5744 if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -5776,10 +5858,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5776 bp->phy_addr = 1; 5858 bp->phy_addr = 1;
5777 5859
5778 /* Disable WOL support if we are running on a SERDES chip. */ 5860 /* Disable WOL support if we are running on a SERDES chip. */
5779 if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { 5861 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
5862 if (CHIP_BOND_ID(bp) != BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C)
5863 bp->phy_flags |= PHY_SERDES_FLAG;
5864 } else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
5780 bp->phy_flags |= PHY_SERDES_FLAG; 5865 bp->phy_flags |= PHY_SERDES_FLAG;
5866
5867 if (bp->phy_flags & PHY_SERDES_FLAG) {
5781 bp->flags |= NO_WOL_FLAG; 5868 bp->flags |= NO_WOL_FLAG;
5782 if (CHIP_NUM(bp) == CHIP_NUM_5708) { 5869 if (CHIP_NUM(bp) != CHIP_NUM_5706) {
5783 bp->phy_addr = 2; 5870 bp->phy_addr = 2;
5784 reg = REG_RD_IND(bp, bp->shmem_base + 5871 reg = REG_RD_IND(bp, bp->shmem_base +
5785 BNX2_SHARED_HW_CFG_CONFIG); 5872 BNX2_SHARED_HW_CFG_CONFIG);