From: Greg Kroah-Hartman Date: Tue, 12 Feb 2013 20:05:45 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.0.64~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d8c3e9e7d1359a33ab40e1d76a4d252ac573bb84;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: be2net-fix-to-trim-skb-for-padded-vlan-packets-to-workaround-an-asic-bug.patch --- diff --git a/queue-3.4/be2net-fix-to-trim-skb-for-padded-vlan-packets-to-workaround-an-asic-bug.patch b/queue-3.4/be2net-fix-to-trim-skb-for-padded-vlan-packets-to-workaround-an-asic-bug.patch new file mode 100644 index 00000000000..64bc55eb192 --- /dev/null +++ b/queue-3.4/be2net-fix-to-trim-skb-for-padded-vlan-packets-to-workaround-an-asic-bug.patch @@ -0,0 +1,122 @@ +From 93040ae5cc8dcc893eca4a4366dc8415af278edf Mon Sep 17 00:00:00 2001 +From: Somnath Kotur +Date: Tue, 26 Jun 2012 22:32:10 +0000 +Subject: be2net: Fix to trim skb for padded vlan packets to workaround an ASIC Bug + +From: Somnath Kotur + +commit 93040ae5cc8dcc893eca4a4366dc8415af278edf upstream. + +Fixed spelling error in a comment as pointed out by DaveM. +Also refactored existing code a bit to provide placeholders for another ASIC +Bug workaround that will be checked-in soon after this. + +Signed-off-by: Somnath Kotur +Signed-off-by: David S. Miller +Cc: Jacek Luczak +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/emulex/benet/be.h | 5 ++ + drivers/net/ethernet/emulex/benet/be_main.c | 56 +++++++++++++++++++++------- + 2 files changed, 47 insertions(+), 14 deletions(-) + +--- a/drivers/net/ethernet/emulex/benet/be.h ++++ b/drivers/net/ethernet/emulex/benet/be.h +@@ -536,6 +536,11 @@ static inline void be_check_sriov_fn_typ + adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; + } + ++static inline bool is_ipv4_pkt(struct sk_buff *skb) ++{ ++ return skb->protocol == ntohs(ETH_P_IP) && ip_hdr(skb)->version == 4; ++} ++ + static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) + { + u32 addr; +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -571,6 +571,11 @@ static inline u16 be_get_tx_vlan_tag(str + return vlan_tag; + } + ++static int be_vlan_tag_chk(struct be_adapter *adapter, struct sk_buff *skb) ++{ ++ return vlan_tx_tag_present(skb) || adapter->pvid; ++} ++ + static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, + struct sk_buff *skb, u32 wrb_cnt, u32 len) + { +@@ -698,33 +703,56 @@ dma_err: + return 0; + } + ++static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, ++ struct sk_buff *skb) ++{ ++ u16 vlan_tag = 0; ++ ++ skb = skb_share_check(skb, GFP_ATOMIC); ++ if (unlikely(!skb)) ++ return skb; ++ ++ if (vlan_tx_tag_present(skb)) { ++ vlan_tag = be_get_tx_vlan_tag(adapter, skb); ++ __vlan_put_tag(skb, vlan_tag); ++ skb->vlan_tci = 0; ++ } ++ ++ return skb; ++} ++ + static netdev_tx_t be_xmit(struct sk_buff *skb, + struct net_device *netdev) + { + struct be_adapter *adapter = netdev_priv(netdev); + struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)]; + struct be_queue_info *txq = &txo->q; ++ struct iphdr *ip = NULL; + u32 wrb_cnt = 0, copied = 0; +- u32 start = txq->head; ++ u32 start = txq->head, eth_hdr_len; + bool dummy_wrb, stopped = false; + +- /* For vlan tagged pkts, BE +- * 1) calculates checksum even when CSO is not requested +- * 2) calculates checksum wrongly for padded pkt less than +- * 60 bytes long. +- * As a workaround disable TX vlan offloading in such cases. ++ eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ? ++ VLAN_ETH_HLEN : ETH_HLEN; ++ ++ /* HW has a bug which considers padding bytes as legal ++ * and modifies the IPv4 hdr's 'tot_len' field + */ +- if (unlikely(vlan_tx_tag_present(skb) && +- (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) { +- skb = skb_share_check(skb, GFP_ATOMIC); +- if (unlikely(!skb)) +- goto tx_drop; ++ if (skb->len <= 60 && be_vlan_tag_chk(adapter, skb) && ++ is_ipv4_pkt(skb)) { ++ ip = (struct iphdr *)ip_hdr(skb); ++ pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); ++ } + +- skb = __vlan_put_tag(skb, be_get_tx_vlan_tag(adapter, skb)); ++ /* HW has a bug wherein it will calculate CSUM for VLAN ++ * pkts even though it is disabled. ++ * Manually insert VLAN in pkt. ++ */ ++ if (skb->ip_summed != CHECKSUM_PARTIAL && ++ be_vlan_tag_chk(adapter, skb)) { ++ skb = be_insert_vlan_in_pkt(adapter, skb); + if (unlikely(!skb)) + goto tx_drop; +- +- skb->vlan_tci = 0; + } + + wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); diff --git a/queue-3.4/series b/queue-3.4/series index e4ca7bfd356..3c1751ca122 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -33,3 +33,4 @@ tcp-fix-for-zero-packets_in_flight-was-too-broad.patch bridge-pull-ip-header-into-skb-data-before-looking-into-ip-header.patch tg3-avoid-null-pointer-dereference-in-tg3_interrupt-in-netconsole-mode.patch tg3-fix-crc-errors-on-jumbo-frame-receive.patch +be2net-fix-to-trim-skb-for-padded-vlan-packets-to-workaround-an-asic-bug.patch