diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-01-15 00:26:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-15 11:28:13 -0500 |
commit | 0c6671b0d94f706dfc20cb22d792218ba9814412 (patch) | |
tree | 14e2c50441814544dbd3f6aba095848ffffe8203 /drivers/net/bnx2x_main.c | |
parent | a5e9a7cfad5fd301ce2b7869bbf386b70aa39e7c (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/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 42 |
1 files changed, 33 insertions, 9 deletions
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; |