aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-01-15 00:26:51 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-15 11:28:13 -0500
commit0c6671b0d94f706dfc20cb22d792218ba9814412 (patch)
tree14e2c50441814544dbd3f6aba095848ffffe8203 /drivers/net
parenta5e9a7cfad5fd301ce2b7869bbf386b70aa39e7c (diff)
bnx2x: VLAN tagged packets without VLAN offload
Wrong handling of tagged packet if VLAN offload is disabled caused packets to get corrupted Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bnx2x.h12
-rw-r--r--drivers/net/bnx2x_main.c42
2 files changed, 40 insertions, 14 deletions
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 2cd1e4278283..e7fbca7722dc 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -20,6 +20,11 @@
20 * (you will need to reboot afterwards) */ 20 * (you will need to reboot afterwards) */
21/* #define BNX2X_STOP_ON_ERROR */ 21/* #define BNX2X_STOP_ON_ERROR */
22 22
23#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
24#define BCM_VLAN 1
25#endif
26
27
23/* error/debug prints */ 28/* error/debug prints */
24 29
25#define DRV_MODULE_NAME "bnx2x" 30#define DRV_MODULE_NAME "bnx2x"
@@ -78,11 +83,6 @@
78#endif 83#endif
79 84
80 85
81#ifdef NETIF_F_HW_VLAN_TX
82#define BCM_VLAN 1
83#endif
84
85
86#define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) 86#define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff)
87#define U64_HI(x) (u32)(((u64)(x)) >> 32) 87#define U64_HI(x) (u32)(((u64)(x)) >> 32)
88#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) 88#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
@@ -804,6 +804,8 @@ struct bnx2x {
804#define TPA_ENABLE_FLAG 0x80 804#define TPA_ENABLE_FLAG 0x80
805#define NO_MCP_FLAG 0x100 805#define NO_MCP_FLAG 0x100
806#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) 806#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
807#define HW_VLAN_TX_FLAG 0x400
808#define HW_VLAN_RX_FLAG 0x800
807 809
808 int func; 810 int func;
809#define BP_PORT(bp) (bp->func % PORT_MAX) 811#define BP_PORT(bp) (bp->func % PORT_MAX)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 701bcc1260c2..ca8b25126b22 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -38,9 +38,7 @@
38#include <linux/time.h> 38#include <linux/time.h>
39#include <linux/ethtool.h> 39#include <linux/ethtool.h>
40#include <linux/mii.h> 40#include <linux/mii.h>
41#ifdef NETIF_F_HW_VLAN_TX 41#include <linux/if_vlan.h>
42 #include <linux/if_vlan.h>
43#endif
44#include <net/ip.h> 42#include <net/ip.h>
45#include <net/tcp.h> 43#include <net/tcp.h>
46#include <net/checksum.h> 44#include <net/checksum.h>
@@ -1283,6 +1281,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
1283 if (likely(new_skb)) { 1281 if (likely(new_skb)) {
1284 /* fix ip xsum and give it to the stack */ 1282 /* fix ip xsum and give it to the stack */
1285 /* (no need to map the new skb) */ 1283 /* (no need to map the new skb) */
1284#ifdef BCM_VLAN
1285 int is_vlan_cqe =
1286 (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
1287 PARSING_FLAGS_VLAN);
1288 int is_not_hwaccel_vlan_cqe =
1289 (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
1290#endif
1286 1291
1287 prefetch(skb); 1292 prefetch(skb);
1288 prefetch(((char *)(skb)) + 128); 1293 prefetch(((char *)(skb)) + 128);
@@ -1307,6 +1312,12 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
1307 struct iphdr *iph; 1312 struct iphdr *iph;
1308 1313
1309 iph = (struct iphdr *)skb->data; 1314 iph = (struct iphdr *)skb->data;
1315#ifdef BCM_VLAN
1316 /* If there is no Rx VLAN offloading -
1317 take VLAN tag into an account */
1318 if (unlikely(is_not_hwaccel_vlan_cqe))
1319 iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
1320#endif
1310 iph->check = 0; 1321 iph->check = 0;
1311 iph->check = ip_fast_csum((u8 *)iph, iph->ihl); 1322 iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
1312 } 1323 }
@@ -1314,9 +1325,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
1314 if (!bnx2x_fill_frag_skb(bp, fp, skb, 1325 if (!bnx2x_fill_frag_skb(bp, fp, skb,
1315 &cqe->fast_path_cqe, cqe_idx)) { 1326 &cqe->fast_path_cqe, cqe_idx)) {
1316#ifdef BCM_VLAN 1327#ifdef BCM_VLAN
1317 if ((bp->vlgrp != NULL) && 1328 if ((bp->vlgrp != NULL) && is_vlan_cqe &&
1318 (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & 1329 (!is_not_hwaccel_vlan_cqe))
1319 PARSING_FLAGS_VLAN))
1320 vlan_hwaccel_receive_skb(skb, bp->vlgrp, 1330 vlan_hwaccel_receive_skb(skb, bp->vlgrp,
1321 le16_to_cpu(cqe->fast_path_cqe. 1331 le16_to_cpu(cqe->fast_path_cqe.
1322 vlan_tag)); 1332 vlan_tag));
@@ -1560,7 +1570,7 @@ reuse_rx:
1560 } 1570 }
1561 1571
1562#ifdef BCM_VLAN 1572#ifdef BCM_VLAN
1563 if ((bp->vlgrp != NULL) && 1573 if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
1564 (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & 1574 (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
1565 PARSING_FLAGS_VLAN)) 1575 PARSING_FLAGS_VLAN))
1566 vlan_hwaccel_receive_skb(skb, bp->vlgrp, 1576 vlan_hwaccel_receive_skb(skb, bp->vlgrp,
@@ -4538,7 +4548,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
4538 tstorm_client.config_flags = 4548 tstorm_client.config_flags =
4539 TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; 4549 TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
4540#ifdef BCM_VLAN 4550#ifdef BCM_VLAN
4541 if (bp->rx_mode && bp->vlgrp) { 4551 if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) {
4542 tstorm_client.config_flags |= 4552 tstorm_client.config_flags |=
4543 TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; 4553 TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
4544 DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); 4554 DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
@@ -9567,11 +9577,14 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
9567 "sending pkt %u @%p next_idx %u bd %u @%p\n", 9577 "sending pkt %u @%p next_idx %u bd %u @%p\n",
9568 pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd); 9578 pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd);
9569 9579
9570 if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) { 9580#ifdef BCM_VLAN
9581 if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) &&
9582 (bp->flags & HW_VLAN_TX_FLAG)) {
9571 tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); 9583 tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
9572 tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; 9584 tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
9573 vlan_off += 4; 9585 vlan_off += 4;
9574 } else 9586 } else
9587#endif
9575 tx_bd->vlan = cpu_to_le16(pkt_prod); 9588 tx_bd->vlan = cpu_to_le16(pkt_prod);
9576 9589
9577 if (xmit_type) { 9590 if (xmit_type) {
@@ -10017,6 +10030,16 @@ static void bnx2x_vlan_rx_register(struct net_device *dev,
10017 struct bnx2x *bp = netdev_priv(dev); 10030 struct bnx2x *bp = netdev_priv(dev);
10018 10031
10019 bp->vlgrp = vlgrp; 10032 bp->vlgrp = vlgrp;
10033
10034 /* Set flags according to the required capabilities */
10035 bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
10036
10037 if (dev->features & NETIF_F_HW_VLAN_TX)
10038 bp->flags |= HW_VLAN_TX_FLAG;
10039
10040 if (dev->features & NETIF_F_HW_VLAN_RX)
10041 bp->flags |= HW_VLAN_RX_FLAG;
10042
10020 if (netif_running(dev)) 10043 if (netif_running(dev))
10021 bnx2x_set_client_config(bp); 10044 bnx2x_set_client_config(bp);
10022} 10045}
@@ -10173,6 +10196,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
10173 dev->features |= NETIF_F_HIGHDMA; 10196 dev->features |= NETIF_F_HIGHDMA;
10174#ifdef BCM_VLAN 10197#ifdef BCM_VLAN
10175 dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); 10198 dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
10199 bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
10176#endif 10200#endif
10177 dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); 10201 dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
10178 dev->features |= NETIF_F_TSO6; 10202 dev->features |= NETIF_F_TSO6;