Commit 099978b434d4924594516db540ccc50652e7cc94

Authored by Vladislav Zolotarov
Committed by David S. Miller
1 parent 4d7b6b5d24

bnx2x: LSO code was broken on BE platforms

Make the LSO code work on BE platforms: parsing_data field of
a parsing BD (PBD) for 57712 was improperly composed which made FW read wrong
values for TCP header's length and offset and, as a result, the corresponding
PCI device was performing bad DMA reads triggering EEH.

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 26 additions and 16 deletions Side-by-side Diff

drivers/net/bnx2x/bnx2x_cmn.c
... ... @@ -1782,15 +1782,15 @@
1782 1782 }
1783 1783 #endif
1784 1784  
1785   -static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
1786   - struct eth_tx_parse_bd_e2 *pbd,
1787   - u32 xmit_type)
  1785 +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
  1786 + u32 xmit_type)
1788 1787 {
1789   - pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
1790   - ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
  1788 + *parsing_data |= (skb_shinfo(skb)->gso_size <<
  1789 + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
  1790 + ETH_TX_PARSE_BD_E2_LSO_MSS;
1791 1791 if ((xmit_type & XMIT_GSO_V6) &&
1792 1792 (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
1793   - pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
  1793 + *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
1794 1794 }
1795 1795  
1796 1796 /**
1797 1797  
1798 1798  
... ... @@ -1835,15 +1835,15 @@
1835 1835 * @return header len
1836 1836 */
1837 1837 static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
1838   - struct eth_tx_parse_bd_e2 *pbd,
1839   - u32 xmit_type)
  1838 + u32 *parsing_data, u32 xmit_type)
1840 1839 {
1841   - pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
1842   - ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
  1840 + *parsing_data |= ((tcp_hdrlen(skb)/4) <<
  1841 + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
  1842 + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
1843 1843  
1844   - pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
1845   - skb->data) / 2) <<
1846   - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
  1844 + *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) <<
  1845 + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) &
  1846 + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W;
1847 1847  
1848 1848 return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
1849 1849 }
... ... @@ -1912,6 +1912,7 @@
1912 1912 struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
1913 1913 struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
1914 1914 struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
  1915 + u32 pbd_e2_parsing_data = 0;
1915 1916 u16 pkt_prod, bd_prod;
1916 1917 int nbd, fp_index;
1917 1918 dma_addr_t mapping;
... ... @@ -2033,8 +2034,9 @@
2033 2034 memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
2034 2035 /* Set PBD in checksum offload case */
2035 2036 if (xmit_type & XMIT_CSUM)
2036   - hlen = bnx2x_set_pbd_csum_e2(bp,
2037   - skb, pbd_e2, xmit_type);
  2037 + hlen = bnx2x_set_pbd_csum_e2(bp, skb,
  2038 + &pbd_e2_parsing_data,
  2039 + xmit_type);
2038 2040 } else {
2039 2041 pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
2040 2042 memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
2041 2043  
... ... @@ -2076,10 +2078,18 @@
2076 2078 bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
2077 2079 hlen, bd_prod, ++nbd);
2078 2080 if (CHIP_IS_E2(bp))
2079   - bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
  2081 + bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
  2082 + xmit_type);
2080 2083 else
2081 2084 bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
2082 2085 }
  2086 +
  2087 + /* Set the PBD's parsing_data field if not zero
  2088 + * (for the chips newer than 57711).
  2089 + */
  2090 + if (pbd_e2_parsing_data)
  2091 + pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
  2092 +
2083 2093 tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
2084 2094  
2085 2095 /* Handle fragmented skb */