aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index a2a010ede591..1f2e76fda01e 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2876,6 +2876,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2876 struct sw_bd *rx_buf; 2876 struct sw_bd *rx_buf;
2877 struct sk_buff *skb; 2877 struct sk_buff *skb;
2878 dma_addr_t dma_addr; 2878 dma_addr_t dma_addr;
2879 u16 vtag = 0;
2880 int hw_vlan __maybe_unused = 0;
2879 2881
2880 sw_ring_cons = RX_RING_IDX(sw_cons); 2882 sw_ring_cons = RX_RING_IDX(sw_cons);
2881 sw_ring_prod = RX_RING_IDX(sw_prod); 2883 sw_ring_prod = RX_RING_IDX(sw_prod);
@@ -2919,7 +2921,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2919 if (len <= bp->rx_copy_thresh) { 2921 if (len <= bp->rx_copy_thresh) {
2920 struct sk_buff *new_skb; 2922 struct sk_buff *new_skb;
2921 2923
2922 new_skb = netdev_alloc_skb(bp->dev, len + 2); 2924 new_skb = netdev_alloc_skb(bp->dev, len + 6);
2923 if (new_skb == NULL) { 2925 if (new_skb == NULL) {
2924 bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, 2926 bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
2925 sw_ring_prod); 2927 sw_ring_prod);
@@ -2928,9 +2930,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2928 2930
2929 /* aligned copy */ 2931 /* aligned copy */
2930 skb_copy_from_linear_data_offset(skb, 2932 skb_copy_from_linear_data_offset(skb,
2931 BNX2_RX_OFFSET - 2, 2933 BNX2_RX_OFFSET - 6,
2932 new_skb->data, len + 2); 2934 new_skb->data, len + 6);
2933 skb_reserve(new_skb, 2); 2935 skb_reserve(new_skb, 6);
2934 skb_put(new_skb, len); 2936 skb_put(new_skb, len);
2935 2937
2936 bnx2_reuse_rx_skb(bp, rxr, skb, 2938 bnx2_reuse_rx_skb(bp, rxr, skb,
@@ -2941,6 +2943,25 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2941 dma_addr, (sw_ring_cons << 16) | sw_ring_prod))) 2943 dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
2942 goto next_rx; 2944 goto next_rx;
2943 2945
2946 if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
2947 !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
2948 vtag = rx_hdr->l2_fhdr_vlan_tag;
2949#ifdef BCM_VLAN
2950 if (bp->vlgrp)
2951 hw_vlan = 1;
2952 else
2953#endif
2954 {
2955 struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
2956 __skb_push(skb, 4);
2957
2958 memmove(ve, skb->data + 4, ETH_ALEN * 2);
2959 ve->h_vlan_proto = htons(ETH_P_8021Q);
2960 ve->h_vlan_TCI = htons(vtag);
2961 len += 4;
2962 }
2963 }
2964
2944 skb->protocol = eth_type_trans(skb, bp->dev); 2965 skb->protocol = eth_type_trans(skb, bp->dev);
2945 2966
2946 if ((len > (bp->dev->mtu + ETH_HLEN)) && 2967 if ((len > (bp->dev->mtu + ETH_HLEN)) &&
@@ -2962,10 +2983,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2962 } 2983 }
2963 2984
2964#ifdef BCM_VLAN 2985#ifdef BCM_VLAN
2965 if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) { 2986 if (hw_vlan)
2966 vlan_hwaccel_receive_skb(skb, bp->vlgrp, 2987 vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
2967 rx_hdr->l2_fhdr_vlan_tag);
2968 }
2969 else 2988 else
2970#endif 2989#endif
2971 netif_receive_skb(skb); 2990 netif_receive_skb(skb);