diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 128 |
1 files changed, 86 insertions, 42 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 5bacb7587df4..5a96d7611af1 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -39,12 +39,9 @@ | |||
39 | #include <linux/if_vlan.h> | 39 | #include <linux/if_vlan.h> |
40 | #define BCM_VLAN 1 | 40 | #define BCM_VLAN 1 |
41 | #endif | 41 | #endif |
42 | #ifdef NETIF_F_TSO | ||
43 | #include <net/ip.h> | 42 | #include <net/ip.h> |
44 | #include <net/tcp.h> | 43 | #include <net/tcp.h> |
45 | #include <net/checksum.h> | 44 | #include <net/checksum.h> |
46 | #define BCM_TSO 1 | ||
47 | #endif | ||
48 | #include <linux/workqueue.h> | 45 | #include <linux/workqueue.h> |
49 | #include <linux/crc32.h> | 46 | #include <linux/crc32.h> |
50 | #include <linux/prefetch.h> | 47 | #include <linux/prefetch.h> |
@@ -57,8 +54,8 @@ | |||
57 | 54 | ||
58 | #define DRV_MODULE_NAME "bnx2" | 55 | #define DRV_MODULE_NAME "bnx2" |
59 | #define PFX DRV_MODULE_NAME ": " | 56 | #define PFX DRV_MODULE_NAME ": " |
60 | #define DRV_MODULE_VERSION "1.5.1" | 57 | #define DRV_MODULE_VERSION "1.5.5" |
61 | #define DRV_MODULE_RELDATE "November 15, 2006" | 58 | #define DRV_MODULE_RELDATE "February 1, 2007" |
62 | 59 | ||
63 | #define RUN_AT(x) (jiffies + (x)) | 60 | #define RUN_AT(x) (jiffies + (x)) |
64 | 61 | ||
@@ -217,9 +214,16 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp) | |||
217 | u32 diff; | 214 | u32 diff; |
218 | 215 | ||
219 | smp_mb(); | 216 | smp_mb(); |
220 | diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons); | 217 | |
221 | if (diff > MAX_TX_DESC_CNT) | 218 | /* The ring uses 256 indices for 255 entries, one of them |
222 | diff = (diff & MAX_TX_DESC_CNT) - 1; | 219 | * needs to be skipped. |
220 | */ | ||
221 | diff = bp->tx_prod - bp->tx_cons; | ||
222 | if (unlikely(diff >= TX_DESC_CNT)) { | ||
223 | diff &= 0xffff; | ||
224 | if (diff == TX_DESC_CNT) | ||
225 | diff = MAX_TX_DESC_CNT; | ||
226 | } | ||
223 | return (bp->tx_ring_size - diff); | 227 | return (bp->tx_ring_size - diff); |
224 | } | 228 | } |
225 | 229 | ||
@@ -1338,8 +1342,6 @@ bnx2_init_copper_phy(struct bnx2 *bp) | |||
1338 | { | 1342 | { |
1339 | u32 val; | 1343 | u32 val; |
1340 | 1344 | ||
1341 | bp->phy_flags |= PHY_CRC_FIX_FLAG; | ||
1342 | |||
1343 | if (bp->phy_flags & PHY_CRC_FIX_FLAG) { | 1345 | if (bp->phy_flags & PHY_CRC_FIX_FLAG) { |
1344 | bnx2_write_phy(bp, 0x18, 0x0c00); | 1346 | bnx2_write_phy(bp, 0x18, 0x0c00); |
1345 | bnx2_write_phy(bp, 0x17, 0x000a); | 1347 | bnx2_write_phy(bp, 0x17, 0x000a); |
@@ -1351,6 +1353,14 @@ bnx2_init_copper_phy(struct bnx2 *bp) | |||
1351 | bnx2_write_phy(bp, 0x18, 0x0400); | 1353 | bnx2_write_phy(bp, 0x18, 0x0400); |
1352 | } | 1354 | } |
1353 | 1355 | ||
1356 | if (bp->phy_flags & PHY_DIS_EARLY_DAC_FLAG) { | ||
1357 | bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, | ||
1358 | MII_BNX2_DSP_EXPAND_REG | 0x8); | ||
1359 | bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val); | ||
1360 | val &= ~(1 << 8); | ||
1361 | bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val); | ||
1362 | } | ||
1363 | |||
1354 | if (bp->dev->mtu > 1500) { | 1364 | if (bp->dev->mtu > 1500) { |
1355 | /* Set extended packet length bit */ | 1365 | /* Set extended packet length bit */ |
1356 | bnx2_write_phy(bp, 0x18, 0x7); | 1366 | bnx2_write_phy(bp, 0x18, 0x7); |
@@ -1715,7 +1725,7 @@ bnx2_tx_int(struct bnx2 *bp) | |||
1715 | 1725 | ||
1716 | tx_buf = &bp->tx_buf_ring[sw_ring_cons]; | 1726 | tx_buf = &bp->tx_buf_ring[sw_ring_cons]; |
1717 | skb = tx_buf->skb; | 1727 | skb = tx_buf->skb; |
1718 | #ifdef BCM_TSO | 1728 | |
1719 | /* partial BD completions possible with TSO packets */ | 1729 | /* partial BD completions possible with TSO packets */ |
1720 | if (skb_is_gso(skb)) { | 1730 | if (skb_is_gso(skb)) { |
1721 | u16 last_idx, last_ring_idx; | 1731 | u16 last_idx, last_ring_idx; |
@@ -1731,7 +1741,7 @@ bnx2_tx_int(struct bnx2 *bp) | |||
1731 | break; | 1741 | break; |
1732 | } | 1742 | } |
1733 | } | 1743 | } |
1734 | #endif | 1744 | |
1735 | pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping), | 1745 | pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping), |
1736 | skb_headlen(skb), PCI_DMA_TODEVICE); | 1746 | skb_headlen(skb), PCI_DMA_TODEVICE); |
1737 | 1747 | ||
@@ -2510,7 +2520,7 @@ bnx2_init_cpus(struct bnx2 *bp) | |||
2510 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | 2520 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { |
2511 | fw = &bnx2_cp_fw_09; | 2521 | fw = &bnx2_cp_fw_09; |
2512 | 2522 | ||
2513 | load_cpu_fw(bp, &cpu_reg, fw); | 2523 | rc = load_cpu_fw(bp, &cpu_reg, fw); |
2514 | if (rc) | 2524 | if (rc) |
2515 | goto init_cpu_err; | 2525 | goto init_cpu_err; |
2516 | } | 2526 | } |
@@ -3078,7 +3088,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3078 | int buf_size) | 3088 | int buf_size) |
3079 | { | 3089 | { |
3080 | u32 written, offset32, len32; | 3090 | u32 written, offset32, len32; |
3081 | u8 *buf, start[4], end[4], *flash_buffer = NULL; | 3091 | u8 *buf, start[4], end[4], *align_buf = NULL, *flash_buffer = NULL; |
3082 | int rc = 0; | 3092 | int rc = 0; |
3083 | int align_start, align_end; | 3093 | int align_start, align_end; |
3084 | 3094 | ||
@@ -3089,7 +3099,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3089 | 3099 | ||
3090 | if ((align_start = (offset32 & 3))) { | 3100 | if ((align_start = (offset32 & 3))) { |
3091 | offset32 &= ~3; | 3101 | offset32 &= ~3; |
3092 | len32 += align_start; | 3102 | len32 += (4 - align_start); |
3093 | if ((rc = bnx2_nvram_read(bp, offset32, start, 4))) | 3103 | if ((rc = bnx2_nvram_read(bp, offset32, start, 4))) |
3094 | return rc; | 3104 | return rc; |
3095 | } | 3105 | } |
@@ -3106,16 +3116,17 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3106 | } | 3116 | } |
3107 | 3117 | ||
3108 | if (align_start || align_end) { | 3118 | if (align_start || align_end) { |
3109 | buf = kmalloc(len32, GFP_KERNEL); | 3119 | align_buf = kmalloc(len32, GFP_KERNEL); |
3110 | if (buf == 0) | 3120 | if (align_buf == NULL) |
3111 | return -ENOMEM; | 3121 | return -ENOMEM; |
3112 | if (align_start) { | 3122 | if (align_start) { |
3113 | memcpy(buf, start, 4); | 3123 | memcpy(align_buf, start, 4); |
3114 | } | 3124 | } |
3115 | if (align_end) { | 3125 | if (align_end) { |
3116 | memcpy(buf + len32 - 4, end, 4); | 3126 | memcpy(align_buf + len32 - 4, end, 4); |
3117 | } | 3127 | } |
3118 | memcpy(buf + align_start, data_buf, buf_size); | 3128 | memcpy(align_buf + align_start, data_buf, buf_size); |
3129 | buf = align_buf; | ||
3119 | } | 3130 | } |
3120 | 3131 | ||
3121 | if (bp->flash_info->buffered == 0) { | 3132 | if (bp->flash_info->buffered == 0) { |
@@ -3249,11 +3260,8 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3249 | } | 3260 | } |
3250 | 3261 | ||
3251 | nvram_write_end: | 3262 | nvram_write_end: |
3252 | if (bp->flash_info->buffered == 0) | 3263 | kfree(flash_buffer); |
3253 | kfree(flash_buffer); | 3264 | kfree(align_buf); |
3254 | |||
3255 | if (align_start || align_end) | ||
3256 | kfree(buf); | ||
3257 | return rc; | 3265 | return rc; |
3258 | } | 3266 | } |
3259 | 3267 | ||
@@ -3998,7 +4006,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
3998 | if (!skb) | 4006 | if (!skb) |
3999 | return -ENOMEM; | 4007 | return -ENOMEM; |
4000 | packet = skb_put(skb, pkt_size); | 4008 | packet = skb_put(skb, pkt_size); |
4001 | memcpy(packet, bp->mac_addr, 6); | 4009 | memcpy(packet, bp->dev->dev_addr, 6); |
4002 | memset(packet + 6, 0x0, 8); | 4010 | memset(packet + 6, 0x0, 8); |
4003 | for (i = 14; i < pkt_size; i++) | 4011 | for (i = 14; i < pkt_size; i++) |
4004 | packet[i] = (unsigned char) (i & 0xff); | 4012 | packet[i] = (unsigned char) (i & 0xff); |
@@ -4503,7 +4511,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4503 | vlan_tag_flags |= | 4511 | vlan_tag_flags |= |
4504 | (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); | 4512 | (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); |
4505 | } | 4513 | } |
4506 | #ifdef BCM_TSO | ||
4507 | if ((mss = skb_shinfo(skb)->gso_size) && | 4514 | if ((mss = skb_shinfo(skb)->gso_size) && |
4508 | (skb->len > (bp->dev->mtu + ETH_HLEN))) { | 4515 | (skb->len > (bp->dev->mtu + ETH_HLEN))) { |
4509 | u32 tcp_opt_len, ip_tcp_len; | 4516 | u32 tcp_opt_len, ip_tcp_len; |
@@ -4536,7 +4543,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4536 | } | 4543 | } |
4537 | } | 4544 | } |
4538 | else | 4545 | else |
4539 | #endif | ||
4540 | { | 4546 | { |
4541 | mss = 0; | 4547 | mss = 0; |
4542 | } | 4548 | } |
@@ -5533,10 +5539,8 @@ static const struct ethtool_ops bnx2_ethtool_ops = { | |||
5533 | .set_tx_csum = ethtool_op_set_tx_csum, | 5539 | .set_tx_csum = ethtool_op_set_tx_csum, |
5534 | .get_sg = ethtool_op_get_sg, | 5540 | .get_sg = ethtool_op_get_sg, |
5535 | .set_sg = ethtool_op_set_sg, | 5541 | .set_sg = ethtool_op_set_sg, |
5536 | #ifdef BCM_TSO | ||
5537 | .get_tso = ethtool_op_get_tso, | 5542 | .get_tso = ethtool_op_get_tso, |
5538 | .set_tso = bnx2_set_tso, | 5543 | .set_tso = bnx2_set_tso, |
5539 | #endif | ||
5540 | .self_test_count = bnx2_self_test_count, | 5544 | .self_test_count = bnx2_self_test_count, |
5541 | .self_test = bnx2_self_test, | 5545 | .self_test = bnx2_self_test, |
5542 | .get_strings = bnx2_get_strings, | 5546 | .get_strings = bnx2_get_strings, |
@@ -5638,6 +5642,44 @@ poll_bnx2(struct net_device *dev) | |||
5638 | } | 5642 | } |
5639 | #endif | 5643 | #endif |
5640 | 5644 | ||
5645 | static void __devinit | ||
5646 | bnx2_get_5709_media(struct bnx2 *bp) | ||
5647 | { | ||
5648 | u32 val = REG_RD(bp, BNX2_MISC_DUAL_MEDIA_CTRL); | ||
5649 | u32 bond_id = val & BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID; | ||
5650 | u32 strap; | ||
5651 | |||
5652 | if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) | ||
5653 | return; | ||
5654 | else if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) { | ||
5655 | bp->phy_flags |= PHY_SERDES_FLAG; | ||
5656 | return; | ||
5657 | } | ||
5658 | |||
5659 | if (val & BNX2_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE) | ||
5660 | strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21; | ||
5661 | else | ||
5662 | strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8; | ||
5663 | |||
5664 | if (PCI_FUNC(bp->pdev->devfn) == 0) { | ||
5665 | switch (strap) { | ||
5666 | case 0x4: | ||
5667 | case 0x5: | ||
5668 | case 0x6: | ||
5669 | bp->phy_flags |= PHY_SERDES_FLAG; | ||
5670 | return; | ||
5671 | } | ||
5672 | } else { | ||
5673 | switch (strap) { | ||
5674 | case 0x1: | ||
5675 | case 0x2: | ||
5676 | case 0x4: | ||
5677 | bp->phy_flags |= PHY_SERDES_FLAG; | ||
5678 | return; | ||
5679 | } | ||
5680 | } | ||
5681 | } | ||
5682 | |||
5641 | static int __devinit | 5683 | static int __devinit |
5642 | bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | 5684 | bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) |
5643 | { | 5685 | { |
@@ -5804,9 +5846,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5804 | reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); | 5846 | reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); |
5805 | 5847 | ||
5806 | if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == | 5848 | if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == |
5807 | BNX2_SHM_HDR_SIGNATURE_SIG) | 5849 | BNX2_SHM_HDR_SIGNATURE_SIG) { |
5808 | bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); | 5850 | u32 off = PCI_FUNC(pdev->devfn) << 2; |
5809 | else | 5851 | |
5852 | bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0 + off); | ||
5853 | } else | ||
5810 | bp->shmem_base = HOST_VIEW_SHMEM_BASE; | 5854 | bp->shmem_base = HOST_VIEW_SHMEM_BASE; |
5811 | 5855 | ||
5812 | /* Get the permanent MAC address. First we need to make sure the | 5856 | /* Get the permanent MAC address. First we need to make sure the |
@@ -5858,10 +5902,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5858 | bp->phy_addr = 1; | 5902 | bp->phy_addr = 1; |
5859 | 5903 | ||
5860 | /* Disable WOL support if we are running on a SERDES chip. */ | 5904 | /* Disable WOL support if we are running on a SERDES chip. */ |
5861 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | 5905 | if (CHIP_NUM(bp) == CHIP_NUM_5709) |
5862 | if (CHIP_BOND_ID(bp) != BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) | 5906 | bnx2_get_5709_media(bp); |
5863 | bp->phy_flags |= PHY_SERDES_FLAG; | 5907 | else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) |
5864 | } else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) | ||
5865 | bp->phy_flags |= PHY_SERDES_FLAG; | 5908 | bp->phy_flags |= PHY_SERDES_FLAG; |
5866 | 5909 | ||
5867 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 5910 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
@@ -5873,7 +5916,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5873 | if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) | 5916 | if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) |
5874 | bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; | 5917 | bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; |
5875 | } | 5918 | } |
5876 | } | 5919 | } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || |
5920 | CHIP_NUM(bp) == CHIP_NUM_5708) | ||
5921 | bp->phy_flags |= PHY_CRC_FIX_FLAG; | ||
5922 | else if (CHIP_ID(bp) == CHIP_ID_5709_A0) | ||
5923 | bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG; | ||
5877 | 5924 | ||
5878 | if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || | 5925 | if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || |
5879 | (CHIP_ID(bp) == CHIP_ID_5708_B0) || | 5926 | (CHIP_ID(bp) == CHIP_ID_5708_B0) || |
@@ -5900,8 +5947,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5900 | * responding after a while. | 5947 | * responding after a while. |
5901 | * | 5948 | * |
5902 | * AMD believes this incompatibility is unique to the 5706, and | 5949 | * AMD believes this incompatibility is unique to the 5706, and |
5903 | * prefers to locally disable MSI rather than globally disabling it | 5950 | * prefers to locally disable MSI rather than globally disabling it. |
5904 | * using pci_msi_quirk. | ||
5905 | */ | 5951 | */ |
5906 | if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) { | 5952 | if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) { |
5907 | struct pci_dev *amd_8132 = NULL; | 5953 | struct pci_dev *amd_8132 = NULL; |
@@ -6050,9 +6096,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6050 | #ifdef BCM_VLAN | 6096 | #ifdef BCM_VLAN |
6051 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 6097 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
6052 | #endif | 6098 | #endif |
6053 | #ifdef BCM_TSO | ||
6054 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; | 6099 | dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; |
6055 | #endif | ||
6056 | 6100 | ||
6057 | netif_carrier_off(bp->dev); | 6101 | netif_carrier_off(bp->dev); |
6058 | 6102 | ||