diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 535 |
1 files changed, 244 insertions, 291 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index e6a803f1c507..57d3293c65bd 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* bnx2.c: Broadcom NX2 network driver. | 1 | /* bnx2.c: Broadcom NX2 network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2004-2010 Broadcom Corporation | 3 | * Copyright (c) 2004-2011 Broadcom Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -37,9 +37,6 @@ | |||
37 | #include <linux/ethtool.h> | 37 | #include <linux/ethtool.h> |
38 | #include <linux/mii.h> | 38 | #include <linux/mii.h> |
39 | #include <linux/if_vlan.h> | 39 | #include <linux/if_vlan.h> |
40 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
41 | #define BCM_VLAN 1 | ||
42 | #endif | ||
43 | #include <net/ip.h> | 40 | #include <net/ip.h> |
44 | #include <net/tcp.h> | 41 | #include <net/tcp.h> |
45 | #include <net/checksum.h> | 42 | #include <net/checksum.h> |
@@ -49,6 +46,7 @@ | |||
49 | #include <linux/cache.h> | 46 | #include <linux/cache.h> |
50 | #include <linux/firmware.h> | 47 | #include <linux/firmware.h> |
51 | #include <linux/log2.h> | 48 | #include <linux/log2.h> |
49 | #include <linux/aer.h> | ||
52 | 50 | ||
53 | #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) | 51 | #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) |
54 | #define BCM_CNIC 1 | 52 | #define BCM_CNIC 1 |
@@ -58,13 +56,13 @@ | |||
58 | #include "bnx2_fw.h" | 56 | #include "bnx2_fw.h" |
59 | 57 | ||
60 | #define DRV_MODULE_NAME "bnx2" | 58 | #define DRV_MODULE_NAME "bnx2" |
61 | #define DRV_MODULE_VERSION "2.0.17" | 59 | #define DRV_MODULE_VERSION "2.1.6" |
62 | #define DRV_MODULE_RELDATE "July 18, 2010" | 60 | #define DRV_MODULE_RELDATE "Mar 7, 2011" |
63 | #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-5.0.0.j6.fw" | 61 | #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" |
64 | #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-5.0.0.j3.fw" | 62 | #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" |
65 | #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-5.0.0.j15.fw" | 63 | #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw" |
66 | #define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw" | 64 | #define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw" |
67 | #define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-5.0.0.j10.fw" | 65 | #define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw" |
68 | 66 | ||
69 | #define RUN_AT(x) (jiffies + (x)) | 67 | #define RUN_AT(x) (jiffies + (x)) |
70 | 68 | ||
@@ -265,7 +263,7 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) | |||
265 | if (diff == TX_DESC_CNT) | 263 | if (diff == TX_DESC_CNT) |
266 | diff = MAX_TX_DESC_CNT; | 264 | diff = MAX_TX_DESC_CNT; |
267 | } | 265 | } |
268 | return (bp->tx_ring_size - diff); | 266 | return bp->tx_ring_size - diff; |
269 | } | 267 | } |
270 | 268 | ||
271 | static u32 | 269 | static u32 |
@@ -298,7 +296,7 @@ bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val) | |||
298 | static u32 | 296 | static u32 |
299 | bnx2_shmem_rd(struct bnx2 *bp, u32 offset) | 297 | bnx2_shmem_rd(struct bnx2 *bp, u32 offset) |
300 | { | 298 | { |
301 | return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset)); | 299 | return bnx2_reg_rd_ind(bp, bp->shmem_base + offset); |
302 | } | 300 | } |
303 | 301 | ||
304 | static void | 302 | static void |
@@ -437,7 +435,8 @@ bnx2_cnic_stop(struct bnx2 *bp) | |||
437 | struct cnic_ctl_info info; | 435 | struct cnic_ctl_info info; |
438 | 436 | ||
439 | mutex_lock(&bp->cnic_lock); | 437 | mutex_lock(&bp->cnic_lock); |
440 | c_ops = bp->cnic_ops; | 438 | c_ops = rcu_dereference_protected(bp->cnic_ops, |
439 | lockdep_is_held(&bp->cnic_lock)); | ||
441 | if (c_ops) { | 440 | if (c_ops) { |
442 | info.cmd = CNIC_CTL_STOP_CMD; | 441 | info.cmd = CNIC_CTL_STOP_CMD; |
443 | c_ops->cnic_ctl(bp->cnic_data, &info); | 442 | c_ops->cnic_ctl(bp->cnic_data, &info); |
@@ -452,7 +451,8 @@ bnx2_cnic_start(struct bnx2 *bp) | |||
452 | struct cnic_ctl_info info; | 451 | struct cnic_ctl_info info; |
453 | 452 | ||
454 | mutex_lock(&bp->cnic_lock); | 453 | mutex_lock(&bp->cnic_lock); |
455 | c_ops = bp->cnic_ops; | 454 | c_ops = rcu_dereference_protected(bp->cnic_ops, |
455 | lockdep_is_held(&bp->cnic_lock)); | ||
456 | if (c_ops) { | 456 | if (c_ops) { |
457 | if (!(bp->flags & BNX2_FLAG_USING_MSIX)) { | 457 | if (!(bp->flags & BNX2_FLAG_USING_MSIX)) { |
458 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; | 458 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
@@ -768,13 +768,10 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) | |||
768 | int j; | 768 | int j; |
769 | 769 | ||
770 | rxr->rx_buf_ring = | 770 | rxr->rx_buf_ring = |
771 | vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); | 771 | vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); |
772 | if (rxr->rx_buf_ring == NULL) | 772 | if (rxr->rx_buf_ring == NULL) |
773 | return -ENOMEM; | 773 | return -ENOMEM; |
774 | 774 | ||
775 | memset(rxr->rx_buf_ring, 0, | ||
776 | SW_RXBD_RING_SIZE * bp->rx_max_ring); | ||
777 | |||
778 | for (j = 0; j < bp->rx_max_ring; j++) { | 775 | for (j = 0; j < bp->rx_max_ring; j++) { |
779 | rxr->rx_desc_ring[j] = | 776 | rxr->rx_desc_ring[j] = |
780 | dma_alloc_coherent(&bp->pdev->dev, | 777 | dma_alloc_coherent(&bp->pdev->dev, |
@@ -787,13 +784,11 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) | |||
787 | } | 784 | } |
788 | 785 | ||
789 | if (bp->rx_pg_ring_size) { | 786 | if (bp->rx_pg_ring_size) { |
790 | rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE * | 787 | rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE * |
791 | bp->rx_max_pg_ring); | 788 | bp->rx_max_pg_ring); |
792 | if (rxr->rx_pg_ring == NULL) | 789 | if (rxr->rx_pg_ring == NULL) |
793 | return -ENOMEM; | 790 | return -ENOMEM; |
794 | 791 | ||
795 | memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE * | ||
796 | bp->rx_max_pg_ring); | ||
797 | } | 792 | } |
798 | 793 | ||
799 | for (j = 0; j < bp->rx_max_pg_ring; j++) { | 794 | for (j = 0; j < bp->rx_max_pg_ring; j++) { |
@@ -976,9 +971,9 @@ bnx2_report_fw_link(struct bnx2 *bp) | |||
976 | static char * | 971 | static char * |
977 | bnx2_xceiver_str(struct bnx2 *bp) | 972 | bnx2_xceiver_str(struct bnx2 *bp) |
978 | { | 973 | { |
979 | return ((bp->phy_port == PORT_FIBRE) ? "SerDes" : | 974 | return (bp->phy_port == PORT_FIBRE) ? "SerDes" : |
980 | ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" : | 975 | ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" : |
981 | "Copper")); | 976 | "Copper"); |
982 | } | 977 | } |
983 | 978 | ||
984 | static void | 979 | static void |
@@ -1268,30 +1263,9 @@ bnx2_init_rx_context(struct bnx2 *bp, u32 cid) | |||
1268 | val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; | 1263 | val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; |
1269 | val |= 0x02 << 8; | 1264 | val |= 0x02 << 8; |
1270 | 1265 | ||
1271 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | 1266 | if (bp->flow_ctrl & FLOW_CTRL_TX) |
1272 | u32 lo_water, hi_water; | 1267 | val |= BNX2_L2CTX_FLOW_CTRL_ENABLE; |
1273 | |||
1274 | if (bp->flow_ctrl & FLOW_CTRL_TX) | ||
1275 | lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT; | ||
1276 | else | ||
1277 | lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS; | ||
1278 | if (lo_water >= bp->rx_ring_size) | ||
1279 | lo_water = 0; | ||
1280 | |||
1281 | hi_water = min_t(int, bp->rx_ring_size / 4, lo_water + 16); | ||
1282 | |||
1283 | if (hi_water <= lo_water) | ||
1284 | lo_water = 0; | ||
1285 | |||
1286 | hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE; | ||
1287 | lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE; | ||
1288 | 1268 | ||
1289 | if (hi_water > 0xf) | ||
1290 | hi_water = 0xf; | ||
1291 | else if (hi_water == 0) | ||
1292 | lo_water = 0; | ||
1293 | val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT); | ||
1294 | } | ||
1295 | bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val); | 1269 | bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val); |
1296 | } | 1270 | } |
1297 | 1271 | ||
@@ -1372,8 +1346,7 @@ bnx2_set_mac_link(struct bnx2 *bp) | |||
1372 | /* Acknowledge the interrupt. */ | 1346 | /* Acknowledge the interrupt. */ |
1373 | REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); | 1347 | REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); |
1374 | 1348 | ||
1375 | if (CHIP_NUM(bp) == CHIP_NUM_5709) | 1349 | bnx2_init_all_rx_contexts(bp); |
1376 | bnx2_init_all_rx_contexts(bp); | ||
1377 | } | 1350 | } |
1378 | 1351 | ||
1379 | static void | 1352 | static void |
@@ -1757,7 +1730,7 @@ __acquires(&bp->phy_lock) | |||
1757 | u32 new_adv = 0; | 1730 | u32 new_adv = 0; |
1758 | 1731 | ||
1759 | if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) | 1732 | if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) |
1760 | return (bnx2_setup_remote_phy(bp, port)); | 1733 | return bnx2_setup_remote_phy(bp, port); |
1761 | 1734 | ||
1762 | if (!(bp->autoneg & AUTONEG_SPEED)) { | 1735 | if (!(bp->autoneg & AUTONEG_SPEED)) { |
1763 | u32 new_bmcr; | 1736 | u32 new_bmcr; |
@@ -2170,10 +2143,10 @@ __acquires(&bp->phy_lock) | |||
2170 | return 0; | 2143 | return 0; |
2171 | 2144 | ||
2172 | if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) { | 2145 | if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) { |
2173 | return (bnx2_setup_serdes_phy(bp, port)); | 2146 | return bnx2_setup_serdes_phy(bp, port); |
2174 | } | 2147 | } |
2175 | else { | 2148 | else { |
2176 | return (bnx2_setup_copper_phy(bp)); | 2149 | return bnx2_setup_copper_phy(bp); |
2177 | } | 2150 | } |
2178 | } | 2151 | } |
2179 | 2152 | ||
@@ -3108,8 +3081,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3108 | struct sw_bd *rx_buf, *next_rx_buf; | 3081 | struct sw_bd *rx_buf, *next_rx_buf; |
3109 | struct sk_buff *skb; | 3082 | struct sk_buff *skb; |
3110 | dma_addr_t dma_addr; | 3083 | dma_addr_t dma_addr; |
3111 | u16 vtag = 0; | ||
3112 | int hw_vlan __maybe_unused = 0; | ||
3113 | 3084 | ||
3114 | sw_ring_cons = RX_RING_IDX(sw_cons); | 3085 | sw_ring_cons = RX_RING_IDX(sw_cons); |
3115 | sw_ring_prod = RX_RING_IDX(sw_prod); | 3086 | sw_ring_prod = RX_RING_IDX(sw_prod); |
@@ -3189,23 +3160,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3189 | goto next_rx; | 3160 | goto next_rx; |
3190 | 3161 | ||
3191 | if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && | 3162 | if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && |
3192 | !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) { | 3163 | !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) |
3193 | vtag = rx_hdr->l2_fhdr_vlan_tag; | 3164 | __vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag); |
3194 | #ifdef BCM_VLAN | ||
3195 | if (bp->vlgrp) | ||
3196 | hw_vlan = 1; | ||
3197 | else | ||
3198 | #endif | ||
3199 | { | ||
3200 | struct vlan_ethhdr *ve = (struct vlan_ethhdr *) | ||
3201 | __skb_push(skb, 4); | ||
3202 | |||
3203 | memmove(ve, skb->data + 4, ETH_ALEN * 2); | ||
3204 | ve->h_vlan_proto = htons(ETH_P_8021Q); | ||
3205 | ve->h_vlan_TCI = htons(vtag); | ||
3206 | len += 4; | ||
3207 | } | ||
3208 | } | ||
3209 | 3165 | ||
3210 | skb->protocol = eth_type_trans(skb, bp->dev); | 3166 | skb->protocol = eth_type_trans(skb, bp->dev); |
3211 | 3167 | ||
@@ -3217,8 +3173,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3217 | 3173 | ||
3218 | } | 3174 | } |
3219 | 3175 | ||
3220 | skb->ip_summed = CHECKSUM_NONE; | 3176 | skb_checksum_none_assert(skb); |
3221 | if (bp->rx_csum && | 3177 | if ((bp->dev->features & NETIF_F_RXCSUM) && |
3222 | (status & (L2_FHDR_STATUS_TCP_SEGMENT | | 3178 | (status & (L2_FHDR_STATUS_TCP_SEGMENT | |
3223 | L2_FHDR_STATUS_UDP_DATAGRAM))) { | 3179 | L2_FHDR_STATUS_UDP_DATAGRAM))) { |
3224 | 3180 | ||
@@ -3232,14 +3188,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3232 | skb->rxhash = rx_hdr->l2_fhdr_hash; | 3188 | skb->rxhash = rx_hdr->l2_fhdr_hash; |
3233 | 3189 | ||
3234 | skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]); | 3190 | skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]); |
3235 | 3191 | napi_gro_receive(&bnapi->napi, skb); | |
3236 | #ifdef BCM_VLAN | ||
3237 | if (hw_vlan) | ||
3238 | vlan_gro_receive(&bnapi->napi, bp->vlgrp, vtag, skb); | ||
3239 | else | ||
3240 | #endif | ||
3241 | napi_gro_receive(&bnapi->napi, skb); | ||
3242 | |||
3243 | rx_pkt++; | 3192 | rx_pkt++; |
3244 | 3193 | ||
3245 | next_rx: | 3194 | next_rx: |
@@ -3554,13 +3503,9 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3554 | rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | | 3503 | rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | |
3555 | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); | 3504 | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); |
3556 | sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; | 3505 | sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; |
3557 | #ifdef BCM_VLAN | 3506 | if (!(dev->features & NETIF_F_HW_VLAN_RX) && |
3558 | if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) | 3507 | (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) |
3559 | rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; | ||
3560 | #else | ||
3561 | if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) | ||
3562 | rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; | 3508 | rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; |
3563 | #endif | ||
3564 | if (dev->flags & IFF_PROMISC) { | 3509 | if (dev->flags & IFF_PROMISC) { |
3565 | /* Promiscuous mode. */ | 3510 | /* Promiscuous mode. */ |
3566 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; | 3511 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; |
@@ -4697,13 +4642,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |||
4697 | 4642 | ||
4698 | /* Wait for the current PCI transaction to complete before | 4643 | /* Wait for the current PCI transaction to complete before |
4699 | * issuing a reset. */ | 4644 | * issuing a reset. */ |
4700 | REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, | 4645 | if ((CHIP_NUM(bp) == CHIP_NUM_5706) || |
4701 | BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | | 4646 | (CHIP_NUM(bp) == CHIP_NUM_5708)) { |
4702 | BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | | 4647 | REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, |
4703 | BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | | 4648 | BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | |
4704 | BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); | 4649 | BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | |
4705 | val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); | 4650 | BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | |
4706 | udelay(5); | 4651 | BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); |
4652 | val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); | ||
4653 | udelay(5); | ||
4654 | } else { /* 5709 */ | ||
4655 | val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); | ||
4656 | val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE; | ||
4657 | REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val); | ||
4658 | val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); | ||
4659 | |||
4660 | for (i = 0; i < 100; i++) { | ||
4661 | msleep(1); | ||
4662 | val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL); | ||
4663 | if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND)) | ||
4664 | break; | ||
4665 | } | ||
4666 | } | ||
4707 | 4667 | ||
4708 | /* Wait for the firmware to tell us it is ok to issue a reset. */ | 4668 | /* Wait for the firmware to tell us it is ok to issue a reset. */ |
4709 | bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); | 4669 | bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); |
@@ -4725,7 +4685,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |||
4725 | val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | | 4685 | val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | |
4726 | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; | 4686 | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; |
4727 | 4687 | ||
4728 | pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val); | 4688 | REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); |
4729 | 4689 | ||
4730 | } else { | 4690 | } else { |
4731 | val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | | 4691 | val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | |
@@ -4973,6 +4933,11 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4973 | 4933 | ||
4974 | REG_WR(bp, BNX2_HC_CONFIG, val); | 4934 | REG_WR(bp, BNX2_HC_CONFIG, val); |
4975 | 4935 | ||
4936 | if (bp->rx_ticks < 25) | ||
4937 | bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 1); | ||
4938 | else | ||
4939 | bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 0); | ||
4940 | |||
4976 | for (i = 1; i < bp->irq_nvecs; i++) { | 4941 | for (i = 1; i < bp->irq_nvecs; i++) { |
4977 | u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) + | 4942 | u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) + |
4978 | BNX2_HC_SB_CONFIG_1; | 4943 | BNX2_HC_SB_CONFIG_1; |
@@ -5241,18 +5206,20 @@ bnx2_init_all_rings(struct bnx2 *bp) | |||
5241 | bnx2_init_rx_ring(bp, i); | 5206 | bnx2_init_rx_ring(bp, i); |
5242 | 5207 | ||
5243 | if (bp->num_rx_rings > 1) { | 5208 | if (bp->num_rx_rings > 1) { |
5244 | u32 tbl_32; | 5209 | u32 tbl_32 = 0; |
5245 | u8 *tbl = (u8 *) &tbl_32; | ||
5246 | |||
5247 | bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, | ||
5248 | BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES); | ||
5249 | 5210 | ||
5250 | for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) { | 5211 | for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) { |
5251 | tbl[i % 4] = i % (bp->num_rx_rings - 1); | 5212 | int shift = (i % 8) << 2; |
5252 | if ((i % 4) == 3) | 5213 | |
5253 | bnx2_reg_wr_ind(bp, | 5214 | tbl_32 |= (i % (bp->num_rx_rings - 1)) << shift; |
5254 | BNX2_RXP_SCRATCH_RSS_TBL + i, | 5215 | if ((i % 8) == 7) { |
5255 | cpu_to_be32(tbl_32)); | 5216 | REG_WR(bp, BNX2_RLUP_RSS_DATA, tbl_32); |
5217 | REG_WR(bp, BNX2_RLUP_RSS_COMMAND, (i >> 3) | | ||
5218 | BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK | | ||
5219 | BNX2_RLUP_RSS_COMMAND_WRITE | | ||
5220 | BNX2_RLUP_RSS_COMMAND_HASH_MASK); | ||
5221 | tbl_32 = 0; | ||
5222 | } | ||
5256 | } | 5223 | } |
5257 | 5224 | ||
5258 | val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI | | 5225 | val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI | |
@@ -6131,7 +6098,7 @@ bnx2_request_irq(struct bnx2 *bp) | |||
6131 | } | 6098 | } |
6132 | 6099 | ||
6133 | static void | 6100 | static void |
6134 | bnx2_free_irq(struct bnx2 *bp) | 6101 | __bnx2_free_irq(struct bnx2 *bp) |
6135 | { | 6102 | { |
6136 | struct bnx2_irq *irq; | 6103 | struct bnx2_irq *irq; |
6137 | int i; | 6104 | int i; |
@@ -6142,6 +6109,13 @@ bnx2_free_irq(struct bnx2 *bp) | |||
6142 | free_irq(irq->vector, &bp->bnx2_napi[i]); | 6109 | free_irq(irq->vector, &bp->bnx2_napi[i]); |
6143 | irq->requested = 0; | 6110 | irq->requested = 0; |
6144 | } | 6111 | } |
6112 | } | ||
6113 | |||
6114 | static void | ||
6115 | bnx2_free_irq(struct bnx2 *bp) | ||
6116 | { | ||
6117 | |||
6118 | __bnx2_free_irq(bp); | ||
6145 | if (bp->flags & BNX2_FLAG_USING_MSI) | 6119 | if (bp->flags & BNX2_FLAG_USING_MSI) |
6146 | pci_disable_msi(bp->pdev); | 6120 | pci_disable_msi(bp->pdev); |
6147 | else if (bp->flags & BNX2_FLAG_USING_MSIX) | 6121 | else if (bp->flags & BNX2_FLAG_USING_MSIX) |
@@ -6201,7 +6175,7 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) | |||
6201 | } | 6175 | } |
6202 | } | 6176 | } |
6203 | 6177 | ||
6204 | static void | 6178 | static int |
6205 | bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | 6179 | bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) |
6206 | { | 6180 | { |
6207 | int cpus = num_online_cpus(); | 6181 | int cpus = num_online_cpus(); |
@@ -6230,9 +6204,10 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | |||
6230 | } | 6204 | } |
6231 | 6205 | ||
6232 | bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); | 6206 | bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); |
6233 | bp->dev->real_num_tx_queues = bp->num_tx_rings; | 6207 | netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings); |
6234 | 6208 | ||
6235 | bp->num_rx_rings = bp->irq_nvecs; | 6209 | bp->num_rx_rings = bp->irq_nvecs; |
6210 | return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings); | ||
6236 | } | 6211 | } |
6237 | 6212 | ||
6238 | /* Called with rtnl_lock */ | 6213 | /* Called with rtnl_lock */ |
@@ -6247,7 +6222,9 @@ bnx2_open(struct net_device *dev) | |||
6247 | bnx2_set_power_state(bp, PCI_D0); | 6222 | bnx2_set_power_state(bp, PCI_D0); |
6248 | bnx2_disable_int(bp); | 6223 | bnx2_disable_int(bp); |
6249 | 6224 | ||
6250 | bnx2_setup_int_mode(bp, disable_msi); | 6225 | rc = bnx2_setup_int_mode(bp, disable_msi); |
6226 | if (rc) | ||
6227 | goto open_err; | ||
6251 | bnx2_init_napi(bp); | 6228 | bnx2_init_napi(bp); |
6252 | bnx2_napi_enable(bp); | 6229 | bnx2_napi_enable(bp); |
6253 | rc = bnx2_alloc_mem(bp); | 6230 | rc = bnx2_alloc_mem(bp); |
@@ -6376,29 +6353,6 @@ bnx2_tx_timeout(struct net_device *dev) | |||
6376 | schedule_work(&bp->reset_task); | 6353 | schedule_work(&bp->reset_task); |
6377 | } | 6354 | } |
6378 | 6355 | ||
6379 | #ifdef BCM_VLAN | ||
6380 | /* Called with rtnl_lock */ | ||
6381 | static void | ||
6382 | bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp) | ||
6383 | { | ||
6384 | struct bnx2 *bp = netdev_priv(dev); | ||
6385 | |||
6386 | if (netif_running(dev)) | ||
6387 | bnx2_netif_stop(bp, false); | ||
6388 | |||
6389 | bp->vlgrp = vlgrp; | ||
6390 | |||
6391 | if (!netif_running(dev)) | ||
6392 | return; | ||
6393 | |||
6394 | bnx2_set_rx_mode(dev); | ||
6395 | if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) | ||
6396 | bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); | ||
6397 | |||
6398 | bnx2_netif_start(bp, false); | ||
6399 | } | ||
6400 | #endif | ||
6401 | |||
6402 | /* Called with netif_tx_lock. | 6356 | /* Called with netif_tx_lock. |
6403 | * bnx2_tx_int() runs without netif_tx_lock unless it needs to call | 6357 | * bnx2_tx_int() runs without netif_tx_lock unless it needs to call |
6404 | * netif_wake_queue(). | 6358 | * netif_wake_queue(). |
@@ -6439,12 +6393,11 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6439 | vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; | 6393 | vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; |
6440 | } | 6394 | } |
6441 | 6395 | ||
6442 | #ifdef BCM_VLAN | 6396 | if (vlan_tx_tag_present(skb)) { |
6443 | if (bp->vlgrp && vlan_tx_tag_present(skb)) { | ||
6444 | vlan_tag_flags |= | 6397 | vlan_tag_flags |= |
6445 | (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); | 6398 | (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); |
6446 | } | 6399 | } |
6447 | #endif | 6400 | |
6448 | if ((mss = skb_shinfo(skb)->gso_size)) { | 6401 | if ((mss = skb_shinfo(skb)->gso_size)) { |
6449 | u32 tcp_opt_len; | 6402 | u32 tcp_opt_len; |
6450 | struct iphdr *iph; | 6403 | struct iphdr *iph; |
@@ -6743,17 +6696,16 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
6743 | 6696 | ||
6744 | if (bp->autoneg & AUTONEG_SPEED) { | 6697 | if (bp->autoneg & AUTONEG_SPEED) { |
6745 | cmd->autoneg = AUTONEG_ENABLE; | 6698 | cmd->autoneg = AUTONEG_ENABLE; |
6746 | } | 6699 | } else { |
6747 | else { | ||
6748 | cmd->autoneg = AUTONEG_DISABLE; | 6700 | cmd->autoneg = AUTONEG_DISABLE; |
6749 | } | 6701 | } |
6750 | 6702 | ||
6751 | if (netif_carrier_ok(dev)) { | 6703 | if (netif_carrier_ok(dev)) { |
6752 | cmd->speed = bp->line_speed; | 6704 | ethtool_cmd_speed_set(cmd, bp->line_speed); |
6753 | cmd->duplex = bp->duplex; | 6705 | cmd->duplex = bp->duplex; |
6754 | } | 6706 | } |
6755 | else { | 6707 | else { |
6756 | cmd->speed = -1; | 6708 | ethtool_cmd_speed_set(cmd, -1); |
6757 | cmd->duplex = -1; | 6709 | cmd->duplex = -1; |
6758 | } | 6710 | } |
6759 | spin_unlock_bh(&bp->phy_lock); | 6711 | spin_unlock_bh(&bp->phy_lock); |
@@ -6805,21 +6757,21 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
6805 | advertising |= ADVERTISED_Autoneg; | 6757 | advertising |= ADVERTISED_Autoneg; |
6806 | } | 6758 | } |
6807 | else { | 6759 | else { |
6760 | u32 speed = ethtool_cmd_speed(cmd); | ||
6808 | if (cmd->port == PORT_FIBRE) { | 6761 | if (cmd->port == PORT_FIBRE) { |
6809 | if ((cmd->speed != SPEED_1000 && | 6762 | if ((speed != SPEED_1000 && |
6810 | cmd->speed != SPEED_2500) || | 6763 | speed != SPEED_2500) || |
6811 | (cmd->duplex != DUPLEX_FULL)) | 6764 | (cmd->duplex != DUPLEX_FULL)) |
6812 | goto err_out_unlock; | 6765 | goto err_out_unlock; |
6813 | 6766 | ||
6814 | if (cmd->speed == SPEED_2500 && | 6767 | if (speed == SPEED_2500 && |
6815 | !(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) | 6768 | !(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) |
6816 | goto err_out_unlock; | 6769 | goto err_out_unlock; |
6817 | } | 6770 | } else if (speed == SPEED_1000 || speed == SPEED_2500) |
6818 | else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500) | ||
6819 | goto err_out_unlock; | 6771 | goto err_out_unlock; |
6820 | 6772 | ||
6821 | autoneg &= ~AUTONEG_SPEED; | 6773 | autoneg &= ~AUTONEG_SPEED; |
6822 | req_line_speed = cmd->speed; | 6774 | req_line_speed = speed; |
6823 | req_duplex = cmd->duplex; | 6775 | req_duplex = cmd->duplex; |
6824 | advertising = 0; | 6776 | advertising = 0; |
6825 | } | 6777 | } |
@@ -6867,28 +6819,30 @@ bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) | |||
6867 | u32 *p = _p, i, offset; | 6819 | u32 *p = _p, i, offset; |
6868 | u8 *orig_p = _p; | 6820 | u8 *orig_p = _p; |
6869 | struct bnx2 *bp = netdev_priv(dev); | 6821 | struct bnx2 *bp = netdev_priv(dev); |
6870 | u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c, | 6822 | static const u32 reg_boundaries[] = { |
6871 | 0x0800, 0x0880, 0x0c00, 0x0c10, | 6823 | 0x0000, 0x0098, 0x0400, 0x045c, |
6872 | 0x0c30, 0x0d08, 0x1000, 0x101c, | 6824 | 0x0800, 0x0880, 0x0c00, 0x0c10, |
6873 | 0x1040, 0x1048, 0x1080, 0x10a4, | 6825 | 0x0c30, 0x0d08, 0x1000, 0x101c, |
6874 | 0x1400, 0x1490, 0x1498, 0x14f0, | 6826 | 0x1040, 0x1048, 0x1080, 0x10a4, |
6875 | 0x1500, 0x155c, 0x1580, 0x15dc, | 6827 | 0x1400, 0x1490, 0x1498, 0x14f0, |
6876 | 0x1600, 0x1658, 0x1680, 0x16d8, | 6828 | 0x1500, 0x155c, 0x1580, 0x15dc, |
6877 | 0x1800, 0x1820, 0x1840, 0x1854, | 6829 | 0x1600, 0x1658, 0x1680, 0x16d8, |
6878 | 0x1880, 0x1894, 0x1900, 0x1984, | 6830 | 0x1800, 0x1820, 0x1840, 0x1854, |
6879 | 0x1c00, 0x1c0c, 0x1c40, 0x1c54, | 6831 | 0x1880, 0x1894, 0x1900, 0x1984, |
6880 | 0x1c80, 0x1c94, 0x1d00, 0x1d84, | 6832 | 0x1c00, 0x1c0c, 0x1c40, 0x1c54, |
6881 | 0x2000, 0x2030, 0x23c0, 0x2400, | 6833 | 0x1c80, 0x1c94, 0x1d00, 0x1d84, |
6882 | 0x2800, 0x2820, 0x2830, 0x2850, | 6834 | 0x2000, 0x2030, 0x23c0, 0x2400, |
6883 | 0x2b40, 0x2c10, 0x2fc0, 0x3058, | 6835 | 0x2800, 0x2820, 0x2830, 0x2850, |
6884 | 0x3c00, 0x3c94, 0x4000, 0x4010, | 6836 | 0x2b40, 0x2c10, 0x2fc0, 0x3058, |
6885 | 0x4080, 0x4090, 0x43c0, 0x4458, | 6837 | 0x3c00, 0x3c94, 0x4000, 0x4010, |
6886 | 0x4c00, 0x4c18, 0x4c40, 0x4c54, | 6838 | 0x4080, 0x4090, 0x43c0, 0x4458, |
6887 | 0x4fc0, 0x5010, 0x53c0, 0x5444, | 6839 | 0x4c00, 0x4c18, 0x4c40, 0x4c54, |
6888 | 0x5c00, 0x5c18, 0x5c80, 0x5c90, | 6840 | 0x4fc0, 0x5010, 0x53c0, 0x5444, |
6889 | 0x5fc0, 0x6000, 0x6400, 0x6428, | 6841 | 0x5c00, 0x5c18, 0x5c80, 0x5c90, |
6890 | 0x6800, 0x6848, 0x684c, 0x6860, | 6842 | 0x5fc0, 0x6000, 0x6400, 0x6428, |
6891 | 0x6888, 0x6910, 0x8000 }; | 6843 | 0x6800, 0x6848, 0x684c, 0x6860, |
6844 | 0x6888, 0x6910, 0x8000 | ||
6845 | }; | ||
6892 | 6846 | ||
6893 | regs->version = 0; | 6847 | regs->version = 0; |
6894 | 6848 | ||
@@ -7146,6 +7100,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) | |||
7146 | 7100 | ||
7147 | bnx2_netif_stop(bp, true); | 7101 | bnx2_netif_stop(bp, true); |
7148 | bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); | 7102 | bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); |
7103 | __bnx2_free_irq(bp); | ||
7149 | bnx2_free_skbs(bp); | 7104 | bnx2_free_skbs(bp); |
7150 | bnx2_free_mem(bp); | 7105 | bnx2_free_mem(bp); |
7151 | } | 7106 | } |
@@ -7158,6 +7113,9 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) | |||
7158 | 7113 | ||
7159 | rc = bnx2_alloc_mem(bp); | 7114 | rc = bnx2_alloc_mem(bp); |
7160 | if (!rc) | 7115 | if (!rc) |
7116 | rc = bnx2_request_irq(bp); | ||
7117 | |||
7118 | if (!rc) | ||
7161 | rc = bnx2_init_nic(bp, 0); | 7119 | rc = bnx2_init_nic(bp, 0); |
7162 | 7120 | ||
7163 | if (rc) { | 7121 | if (rc) { |
@@ -7230,38 +7188,6 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | |||
7230 | return 0; | 7188 | return 0; |
7231 | } | 7189 | } |
7232 | 7190 | ||
7233 | static u32 | ||
7234 | bnx2_get_rx_csum(struct net_device *dev) | ||
7235 | { | ||
7236 | struct bnx2 *bp = netdev_priv(dev); | ||
7237 | |||
7238 | return bp->rx_csum; | ||
7239 | } | ||
7240 | |||
7241 | static int | ||
7242 | bnx2_set_rx_csum(struct net_device *dev, u32 data) | ||
7243 | { | ||
7244 | struct bnx2 *bp = netdev_priv(dev); | ||
7245 | |||
7246 | bp->rx_csum = data; | ||
7247 | return 0; | ||
7248 | } | ||
7249 | |||
7250 | static int | ||
7251 | bnx2_set_tso(struct net_device *dev, u32 data) | ||
7252 | { | ||
7253 | struct bnx2 *bp = netdev_priv(dev); | ||
7254 | |||
7255 | if (data) { | ||
7256 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; | ||
7257 | if (CHIP_NUM(bp) == CHIP_NUM_5709) | ||
7258 | dev->features |= NETIF_F_TSO6; | ||
7259 | } else | ||
7260 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | | ||
7261 | NETIF_F_TSO_ECN); | ||
7262 | return 0; | ||
7263 | } | ||
7264 | |||
7265 | static struct { | 7191 | static struct { |
7266 | char string[ETH_GSTRING_LEN]; | 7192 | char string[ETH_GSTRING_LEN]; |
7267 | } bnx2_stats_str_arr[] = { | 7193 | } bnx2_stats_str_arr[] = { |
@@ -7536,60 +7462,77 @@ bnx2_get_ethtool_stats(struct net_device *dev, | |||
7536 | } | 7462 | } |
7537 | 7463 | ||
7538 | static int | 7464 | static int |
7539 | bnx2_phys_id(struct net_device *dev, u32 data) | 7465 | bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) |
7540 | { | 7466 | { |
7541 | struct bnx2 *bp = netdev_priv(dev); | 7467 | struct bnx2 *bp = netdev_priv(dev); |
7542 | int i; | ||
7543 | u32 save; | ||
7544 | 7468 | ||
7545 | bnx2_set_power_state(bp, PCI_D0); | 7469 | switch (state) { |
7470 | case ETHTOOL_ID_ACTIVE: | ||
7471 | bnx2_set_power_state(bp, PCI_D0); | ||
7546 | 7472 | ||
7547 | if (data == 0) | 7473 | bp->leds_save = REG_RD(bp, BNX2_MISC_CFG); |
7548 | data = 2; | 7474 | REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); |
7475 | return 1; /* cycle on/off once per second */ | ||
7476 | |||
7477 | case ETHTOOL_ID_ON: | ||
7478 | REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | | ||
7479 | BNX2_EMAC_LED_1000MB_OVERRIDE | | ||
7480 | BNX2_EMAC_LED_100MB_OVERRIDE | | ||
7481 | BNX2_EMAC_LED_10MB_OVERRIDE | | ||
7482 | BNX2_EMAC_LED_TRAFFIC_OVERRIDE | | ||
7483 | BNX2_EMAC_LED_TRAFFIC); | ||
7484 | break; | ||
7549 | 7485 | ||
7550 | save = REG_RD(bp, BNX2_MISC_CFG); | 7486 | case ETHTOOL_ID_OFF: |
7551 | REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); | 7487 | REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); |
7488 | break; | ||
7552 | 7489 | ||
7553 | for (i = 0; i < (data * 2); i++) { | 7490 | case ETHTOOL_ID_INACTIVE: |
7554 | if ((i % 2) == 0) { | 7491 | REG_WR(bp, BNX2_EMAC_LED, 0); |
7555 | REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); | 7492 | REG_WR(bp, BNX2_MISC_CFG, bp->leds_save); |
7556 | } | ||
7557 | else { | ||
7558 | REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | | ||
7559 | BNX2_EMAC_LED_1000MB_OVERRIDE | | ||
7560 | BNX2_EMAC_LED_100MB_OVERRIDE | | ||
7561 | BNX2_EMAC_LED_10MB_OVERRIDE | | ||
7562 | BNX2_EMAC_LED_TRAFFIC_OVERRIDE | | ||
7563 | BNX2_EMAC_LED_TRAFFIC); | ||
7564 | } | ||
7565 | msleep_interruptible(500); | ||
7566 | if (signal_pending(current)) | ||
7567 | break; | ||
7568 | } | ||
7569 | REG_WR(bp, BNX2_EMAC_LED, 0); | ||
7570 | REG_WR(bp, BNX2_MISC_CFG, save); | ||
7571 | 7493 | ||
7572 | if (!netif_running(dev)) | 7494 | if (!netif_running(dev)) |
7573 | bnx2_set_power_state(bp, PCI_D3hot); | 7495 | bnx2_set_power_state(bp, PCI_D3hot); |
7496 | break; | ||
7497 | } | ||
7574 | 7498 | ||
7575 | return 0; | 7499 | return 0; |
7576 | } | 7500 | } |
7577 | 7501 | ||
7578 | static int | 7502 | static u32 |
7579 | bnx2_set_tx_csum(struct net_device *dev, u32 data) | 7503 | bnx2_fix_features(struct net_device *dev, u32 features) |
7580 | { | 7504 | { |
7581 | struct bnx2 *bp = netdev_priv(dev); | 7505 | struct bnx2 *bp = netdev_priv(dev); |
7582 | 7506 | ||
7583 | if (CHIP_NUM(bp) == CHIP_NUM_5709) | 7507 | if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) |
7584 | return (ethtool_op_set_tx_ipv6_csum(dev, data)); | 7508 | features |= NETIF_F_HW_VLAN_RX; |
7585 | else | 7509 | |
7586 | return (ethtool_op_set_tx_csum(dev, data)); | 7510 | return features; |
7587 | } | 7511 | } |
7588 | 7512 | ||
7589 | static int | 7513 | static int |
7590 | bnx2_set_flags(struct net_device *dev, u32 data) | 7514 | bnx2_set_features(struct net_device *dev, u32 features) |
7591 | { | 7515 | { |
7592 | return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH); | 7516 | struct bnx2 *bp = netdev_priv(dev); |
7517 | |||
7518 | /* TSO with VLAN tag won't work with current firmware */ | ||
7519 | if (features & NETIF_F_HW_VLAN_TX) | ||
7520 | dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO); | ||
7521 | else | ||
7522 | dev->vlan_features &= ~NETIF_F_ALL_TSO; | ||
7523 | |||
7524 | if ((!!(features & NETIF_F_HW_VLAN_RX) != | ||
7525 | !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) && | ||
7526 | netif_running(dev)) { | ||
7527 | bnx2_netif_stop(bp, false); | ||
7528 | dev->features = features; | ||
7529 | bnx2_set_rx_mode(dev); | ||
7530 | bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); | ||
7531 | bnx2_netif_start(bp, false); | ||
7532 | return 1; | ||
7533 | } | ||
7534 | |||
7535 | return 0; | ||
7593 | } | 7536 | } |
7594 | 7537 | ||
7595 | static const struct ethtool_ops bnx2_ethtool_ops = { | 7538 | static const struct ethtool_ops bnx2_ethtool_ops = { |
@@ -7611,18 +7554,11 @@ static const struct ethtool_ops bnx2_ethtool_ops = { | |||
7611 | .set_ringparam = bnx2_set_ringparam, | 7554 | .set_ringparam = bnx2_set_ringparam, |
7612 | .get_pauseparam = bnx2_get_pauseparam, | 7555 | .get_pauseparam = bnx2_get_pauseparam, |
7613 | .set_pauseparam = bnx2_set_pauseparam, | 7556 | .set_pauseparam = bnx2_set_pauseparam, |
7614 | .get_rx_csum = bnx2_get_rx_csum, | ||
7615 | .set_rx_csum = bnx2_set_rx_csum, | ||
7616 | .set_tx_csum = bnx2_set_tx_csum, | ||
7617 | .set_sg = ethtool_op_set_sg, | ||
7618 | .set_tso = bnx2_set_tso, | ||
7619 | .self_test = bnx2_self_test, | 7557 | .self_test = bnx2_self_test, |
7620 | .get_strings = bnx2_get_strings, | 7558 | .get_strings = bnx2_get_strings, |
7621 | .phys_id = bnx2_phys_id, | 7559 | .set_phys_id = bnx2_set_phys_id, |
7622 | .get_ethtool_stats = bnx2_get_ethtool_stats, | 7560 | .get_ethtool_stats = bnx2_get_ethtool_stats, |
7623 | .get_sset_count = bnx2_get_sset_count, | 7561 | .get_sset_count = bnx2_get_sset_count, |
7624 | .set_flags = bnx2_set_flags, | ||
7625 | .get_flags = ethtool_op_get_flags, | ||
7626 | }; | 7562 | }; |
7627 | 7563 | ||
7628 | /* Called with rtnl_lock */ | 7564 | /* Called with rtnl_lock */ |
@@ -7704,7 +7640,7 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu) | |||
7704 | return -EINVAL; | 7640 | return -EINVAL; |
7705 | 7641 | ||
7706 | dev->mtu = new_mtu; | 7642 | dev->mtu = new_mtu; |
7707 | return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size)); | 7643 | return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size); |
7708 | } | 7644 | } |
7709 | 7645 | ||
7710 | #ifdef CONFIG_NET_POLL_CONTROLLER | 7646 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -7890,6 +7826,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
7890 | int rc, i, j; | 7826 | int rc, i, j; |
7891 | u32 reg; | 7827 | u32 reg; |
7892 | u64 dma_mask, persist_dma_mask; | 7828 | u64 dma_mask, persist_dma_mask; |
7829 | int err; | ||
7893 | 7830 | ||
7894 | SET_NETDEV_DEV(dev, &pdev->dev); | 7831 | SET_NETDEV_DEV(dev, &pdev->dev); |
7895 | bp = netdev_priv(dev); | 7832 | bp = netdev_priv(dev); |
@@ -7926,7 +7863,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
7926 | } | 7863 | } |
7927 | 7864 | ||
7928 | pci_set_master(pdev); | 7865 | pci_set_master(pdev); |
7929 | pci_save_state(pdev); | ||
7930 | 7866 | ||
7931 | bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); | 7867 | bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); |
7932 | if (bp->pm_cap == 0) { | 7868 | if (bp->pm_cap == 0) { |
@@ -7959,15 +7895,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
7959 | goto err_out_release; | 7895 | goto err_out_release; |
7960 | } | 7896 | } |
7961 | 7897 | ||
7898 | bnx2_set_power_state(bp, PCI_D0); | ||
7899 | |||
7962 | /* Configure byte swap and enable write to the reg_window registers. | 7900 | /* Configure byte swap and enable write to the reg_window registers. |
7963 | * Rely on CPU to do target byte swapping on big endian systems | 7901 | * Rely on CPU to do target byte swapping on big endian systems |
7964 | * The chip's target access swapping will not swap all accesses | 7902 | * The chip's target access swapping will not swap all accesses |
7965 | */ | 7903 | */ |
7966 | pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, | 7904 | REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, |
7967 | BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | | 7905 | BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | |
7968 | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); | 7906 | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); |
7969 | |||
7970 | bnx2_set_power_state(bp, PCI_D0); | ||
7971 | 7907 | ||
7972 | bp->chip_id = REG_RD(bp, BNX2_MISC_ID); | 7908 | bp->chip_id = REG_RD(bp, BNX2_MISC_ID); |
7973 | 7909 | ||
@@ -7981,6 +7917,12 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
7981 | bp->flags |= BNX2_FLAG_PCIE; | 7917 | bp->flags |= BNX2_FLAG_PCIE; |
7982 | if (CHIP_REV(bp) == CHIP_REV_Ax) | 7918 | if (CHIP_REV(bp) == CHIP_REV_Ax) |
7983 | bp->flags |= BNX2_FLAG_JUMBO_BROKEN; | 7919 | bp->flags |= BNX2_FLAG_JUMBO_BROKEN; |
7920 | |||
7921 | /* AER (Advanced Error Reporting) hooks */ | ||
7922 | err = pci_enable_pcie_error_reporting(pdev); | ||
7923 | if (!err) | ||
7924 | bp->flags |= BNX2_FLAG_AER_ENABLED; | ||
7925 | |||
7984 | } else { | 7926 | } else { |
7985 | bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); | 7927 | bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); |
7986 | if (bp->pcix_cap == 0) { | 7928 | if (bp->pcix_cap == 0) { |
@@ -8128,8 +8070,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
8128 | bp->tx_ring_size = MAX_TX_DESC_CNT; | 8070 | bp->tx_ring_size = MAX_TX_DESC_CNT; |
8129 | bnx2_set_rx_ring_size(bp, 255); | 8071 | bnx2_set_rx_ring_size(bp, 255); |
8130 | 8072 | ||
8131 | bp->rx_csum = 1; | ||
8132 | |||
8133 | bp->tx_quick_cons_trip_int = 2; | 8073 | bp->tx_quick_cons_trip_int = 2; |
8134 | bp->tx_quick_cons_trip = 20; | 8074 | bp->tx_quick_cons_trip = 20; |
8135 | bp->tx_ticks_int = 18; | 8075 | bp->tx_ticks_int = 18; |
@@ -8237,9 +8177,16 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
8237 | bp->timer.data = (unsigned long) bp; | 8177 | bp->timer.data = (unsigned long) bp; |
8238 | bp->timer.function = bnx2_timer; | 8178 | bp->timer.function = bnx2_timer; |
8239 | 8179 | ||
8180 | pci_save_state(pdev); | ||
8181 | |||
8240 | return 0; | 8182 | return 0; |
8241 | 8183 | ||
8242 | err_out_unmap: | 8184 | err_out_unmap: |
8185 | if (bp->flags & BNX2_FLAG_AER_ENABLED) { | ||
8186 | pci_disable_pcie_error_reporting(pdev); | ||
8187 | bp->flags &= ~BNX2_FLAG_AER_ENABLED; | ||
8188 | } | ||
8189 | |||
8243 | if (bp->regview) { | 8190 | if (bp->regview) { |
8244 | iounmap(bp->regview); | 8191 | iounmap(bp->regview); |
8245 | bp->regview = NULL; | 8192 | bp->regview = NULL; |
@@ -8314,22 +8261,14 @@ static const struct net_device_ops bnx2_netdev_ops = { | |||
8314 | .ndo_validate_addr = eth_validate_addr, | 8261 | .ndo_validate_addr = eth_validate_addr, |
8315 | .ndo_set_mac_address = bnx2_change_mac_addr, | 8262 | .ndo_set_mac_address = bnx2_change_mac_addr, |
8316 | .ndo_change_mtu = bnx2_change_mtu, | 8263 | .ndo_change_mtu = bnx2_change_mtu, |
8264 | .ndo_fix_features = bnx2_fix_features, | ||
8265 | .ndo_set_features = bnx2_set_features, | ||
8317 | .ndo_tx_timeout = bnx2_tx_timeout, | 8266 | .ndo_tx_timeout = bnx2_tx_timeout, |
8318 | #ifdef BCM_VLAN | ||
8319 | .ndo_vlan_rx_register = bnx2_vlan_rx_register, | ||
8320 | #endif | ||
8321 | #ifdef CONFIG_NET_POLL_CONTROLLER | 8267 | #ifdef CONFIG_NET_POLL_CONTROLLER |
8322 | .ndo_poll_controller = poll_bnx2, | 8268 | .ndo_poll_controller = poll_bnx2, |
8323 | #endif | 8269 | #endif |
8324 | }; | 8270 | }; |
8325 | 8271 | ||
8326 | static void inline vlan_features_add(struct net_device *dev, unsigned long flags) | ||
8327 | { | ||
8328 | #ifdef BCM_VLAN | ||
8329 | dev->vlan_features |= flags; | ||
8330 | #endif | ||
8331 | } | ||
8332 | |||
8333 | static int __devinit | 8272 | static int __devinit |
8334 | bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 8273 | bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
8335 | { | 8274 | { |
@@ -8369,22 +8308,17 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
8369 | memcpy(dev->dev_addr, bp->mac_addr, 6); | 8308 | memcpy(dev->dev_addr, bp->mac_addr, 6); |
8370 | memcpy(dev->perm_addr, bp->mac_addr, 6); | 8309 | memcpy(dev->perm_addr, bp->mac_addr, 6); |
8371 | 8310 | ||
8372 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO | | 8311 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | |
8373 | NETIF_F_RXHASH; | 8312 | NETIF_F_TSO | NETIF_F_TSO_ECN | |
8374 | vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG); | 8313 | NETIF_F_RXHASH | NETIF_F_RXCSUM; |
8375 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | 8314 | |
8376 | dev->features |= NETIF_F_IPV6_CSUM; | 8315 | if (CHIP_NUM(bp) == CHIP_NUM_5709) |
8377 | vlan_features_add(dev, NETIF_F_IPV6_CSUM); | 8316 | dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; |
8378 | } | 8317 | |
8379 | #ifdef BCM_VLAN | 8318 | dev->vlan_features = dev->hw_features; |
8380 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 8319 | dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
8381 | #endif | 8320 | dev->features |= dev->hw_features; |
8382 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; | 8321 | |
8383 | vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN); | ||
8384 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | ||
8385 | dev->features |= NETIF_F_TSO6; | ||
8386 | vlan_features_add(dev, NETIF_F_TSO6); | ||
8387 | } | ||
8388 | if ((rc = register_netdev(dev))) { | 8322 | if ((rc = register_netdev(dev))) { |
8389 | dev_err(&pdev->dev, "Cannot register net device\n"); | 8323 | dev_err(&pdev->dev, "Cannot register net device\n"); |
8390 | goto error; | 8324 | goto error; |
@@ -8421,10 +8355,10 @@ bnx2_remove_one(struct pci_dev *pdev) | |||
8421 | struct net_device *dev = pci_get_drvdata(pdev); | 8355 | struct net_device *dev = pci_get_drvdata(pdev); |
8422 | struct bnx2 *bp = netdev_priv(dev); | 8356 | struct bnx2 *bp = netdev_priv(dev); |
8423 | 8357 | ||
8424 | flush_scheduled_work(); | ||
8425 | |||
8426 | unregister_netdev(dev); | 8358 | unregister_netdev(dev); |
8427 | 8359 | ||
8360 | del_timer_sync(&bp->timer); | ||
8361 | |||
8428 | if (bp->mips_firmware) | 8362 | if (bp->mips_firmware) |
8429 | release_firmware(bp->mips_firmware); | 8363 | release_firmware(bp->mips_firmware); |
8430 | if (bp->rv2p_firmware) | 8364 | if (bp->rv2p_firmware) |
@@ -8435,7 +8369,13 @@ bnx2_remove_one(struct pci_dev *pdev) | |||
8435 | 8369 | ||
8436 | kfree(bp->temp_stats_blk); | 8370 | kfree(bp->temp_stats_blk); |
8437 | 8371 | ||
8372 | if (bp->flags & BNX2_FLAG_AER_ENABLED) { | ||
8373 | pci_disable_pcie_error_reporting(pdev); | ||
8374 | bp->flags &= ~BNX2_FLAG_AER_ENABLED; | ||
8375 | } | ||
8376 | |||
8438 | free_netdev(dev); | 8377 | free_netdev(dev); |
8378 | |||
8439 | pci_release_regions(pdev); | 8379 | pci_release_regions(pdev); |
8440 | pci_disable_device(pdev); | 8380 | pci_disable_device(pdev); |
8441 | pci_set_drvdata(pdev, NULL); | 8381 | pci_set_drvdata(pdev, NULL); |
@@ -8455,7 +8395,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
8455 | if (!netif_running(dev)) | 8395 | if (!netif_running(dev)) |
8456 | return 0; | 8396 | return 0; |
8457 | 8397 | ||
8458 | flush_scheduled_work(); | 8398 | cancel_work_sync(&bp->reset_task); |
8459 | bnx2_netif_stop(bp, true); | 8399 | bnx2_netif_stop(bp, true); |
8460 | netif_device_detach(dev); | 8400 | netif_device_detach(dev); |
8461 | del_timer_sync(&bp->timer); | 8401 | del_timer_sync(&bp->timer); |
@@ -8527,25 +8467,38 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev) | |||
8527 | { | 8467 | { |
8528 | struct net_device *dev = pci_get_drvdata(pdev); | 8468 | struct net_device *dev = pci_get_drvdata(pdev); |
8529 | struct bnx2 *bp = netdev_priv(dev); | 8469 | struct bnx2 *bp = netdev_priv(dev); |
8470 | pci_ers_result_t result; | ||
8471 | int err; | ||
8530 | 8472 | ||
8531 | rtnl_lock(); | 8473 | rtnl_lock(); |
8532 | if (pci_enable_device(pdev)) { | 8474 | if (pci_enable_device(pdev)) { |
8533 | dev_err(&pdev->dev, | 8475 | dev_err(&pdev->dev, |
8534 | "Cannot re-enable PCI device after reset\n"); | 8476 | "Cannot re-enable PCI device after reset\n"); |
8535 | rtnl_unlock(); | 8477 | result = PCI_ERS_RESULT_DISCONNECT; |
8536 | return PCI_ERS_RESULT_DISCONNECT; | 8478 | } else { |
8479 | pci_set_master(pdev); | ||
8480 | pci_restore_state(pdev); | ||
8481 | pci_save_state(pdev); | ||
8482 | |||
8483 | if (netif_running(dev)) { | ||
8484 | bnx2_set_power_state(bp, PCI_D0); | ||
8485 | bnx2_init_nic(bp, 1); | ||
8486 | } | ||
8487 | result = PCI_ERS_RESULT_RECOVERED; | ||
8537 | } | 8488 | } |
8538 | pci_set_master(pdev); | 8489 | rtnl_unlock(); |
8539 | pci_restore_state(pdev); | ||
8540 | pci_save_state(pdev); | ||
8541 | 8490 | ||
8542 | if (netif_running(dev)) { | 8491 | if (!(bp->flags & BNX2_FLAG_AER_ENABLED)) |
8543 | bnx2_set_power_state(bp, PCI_D0); | 8492 | return result; |
8544 | bnx2_init_nic(bp, 1); | 8493 | |
8494 | err = pci_cleanup_aer_uncorrect_error_status(pdev); | ||
8495 | if (err) { | ||
8496 | dev_err(&pdev->dev, | ||
8497 | "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n", | ||
8498 | err); /* non-fatal, continue */ | ||
8545 | } | 8499 | } |
8546 | 8500 | ||
8547 | rtnl_unlock(); | 8501 | return result; |
8548 | return PCI_ERS_RESULT_RECOVERED; | ||
8549 | } | 8502 | } |
8550 | 8503 | ||
8551 | /** | 8504 | /** |