diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/tg3.c | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3708159548fc..8dfde34b2415 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -5901,27 +5901,16 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, | |||
5901 | #endif | 5901 | #endif |
5902 | } | 5902 | } |
5903 | 5903 | ||
5904 | static void tg3_set_txd(struct tg3_napi *tnapi, int entry, | 5904 | static inline void tg3_tx_set_bd(struct tg3_napi *tnapi, u32 entry, |
5905 | dma_addr_t mapping, int len, u32 flags, | 5905 | dma_addr_t mapping, u32 len, u32 flags, |
5906 | u32 mss_and_is_end) | 5906 | u32 mss, u32 vlan) |
5907 | { | 5907 | { |
5908 | struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry]; | 5908 | struct tg3_tx_buffer_desc *txbd = &tnapi->tx_ring[entry]; |
5909 | int is_end = (mss_and_is_end & 0x1); | ||
5910 | u32 mss = (mss_and_is_end >> 1); | ||
5911 | u32 vlan_tag = 0; | ||
5912 | 5909 | ||
5913 | if (is_end) | 5910 | txbd->addr_hi = ((u64) mapping >> 32); |
5914 | flags |= TXD_FLAG_END; | 5911 | txbd->addr_lo = ((u64) mapping & 0xffffffff); |
5915 | if (flags & TXD_FLAG_VLAN) { | 5912 | txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff); |
5916 | vlan_tag = flags >> 16; | 5913 | txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT); |
5917 | flags &= 0xffff; | ||
5918 | } | ||
5919 | vlan_tag |= (mss << TXD_MSS_SHIFT); | ||
5920 | |||
5921 | txd->addr_hi = ((u64) mapping >> 32); | ||
5922 | txd->addr_lo = ((u64) mapping & 0xffffffff); | ||
5923 | txd->len_flags = (len << TXD_LEN_SHIFT) | flags; | ||
5924 | txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; | ||
5925 | } | 5914 | } |
5926 | 5915 | ||
5927 | static void tg3_skb_error_unmap(struct tg3_napi *tnapi, | 5916 | static void tg3_skb_error_unmap(struct tg3_napi *tnapi, |
@@ -5950,7 +5939,7 @@ static void tg3_skb_error_unmap(struct tg3_napi *tnapi, | |||
5950 | /* Workaround 4GB and 40-bit hardware DMA bugs. */ | 5939 | /* Workaround 4GB and 40-bit hardware DMA bugs. */ |
5951 | static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, | 5940 | static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, |
5952 | struct sk_buff *skb, | 5941 | struct sk_buff *skb, |
5953 | u32 base_flags, u32 mss) | 5942 | u32 base_flags, u32 mss, u32 vlan) |
5954 | { | 5943 | { |
5955 | struct tg3 *tp = tnapi->tp; | 5944 | struct tg3 *tp = tnapi->tp; |
5956 | struct sk_buff *new_skb; | 5945 | struct sk_buff *new_skb; |
@@ -5988,12 +5977,14 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, | |||
5988 | ret = -1; | 5977 | ret = -1; |
5989 | dev_kfree_skb(new_skb); | 5978 | dev_kfree_skb(new_skb); |
5990 | } else { | 5979 | } else { |
5980 | base_flags |= TXD_FLAG_END; | ||
5981 | |||
5991 | tnapi->tx_buffers[entry].skb = new_skb; | 5982 | tnapi->tx_buffers[entry].skb = new_skb; |
5992 | dma_unmap_addr_set(&tnapi->tx_buffers[entry], | 5983 | dma_unmap_addr_set(&tnapi->tx_buffers[entry], |
5993 | mapping, new_addr); | 5984 | mapping, new_addr); |
5994 | 5985 | ||
5995 | tg3_set_txd(tnapi, entry, new_addr, new_skb->len, | 5986 | tg3_tx_set_bd(tnapi, entry, new_addr, new_skb->len, |
5996 | base_flags, 1 | (mss << 1)); | 5987 | base_flags, mss, vlan); |
5997 | } | 5988 | } |
5998 | } | 5989 | } |
5999 | 5990 | ||
@@ -6051,7 +6042,7 @@ tg3_tso_bug_end: | |||
6051 | static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | 6042 | static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) |
6052 | { | 6043 | { |
6053 | struct tg3 *tp = netdev_priv(dev); | 6044 | struct tg3 *tp = netdev_priv(dev); |
6054 | u32 len, entry, base_flags, mss; | 6045 | u32 len, entry, base_flags, mss, vlan = 0; |
6055 | int i = -1, would_hit_hwbug; | 6046 | int i = -1, would_hit_hwbug; |
6056 | dma_addr_t mapping; | 6047 | dma_addr_t mapping; |
6057 | struct tg3_napi *tnapi; | 6048 | struct tg3_napi *tnapi; |
@@ -6153,9 +6144,12 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6153 | } | 6144 | } |
6154 | } | 6145 | } |
6155 | 6146 | ||
6156 | if (vlan_tx_tag_present(skb)) | 6147 | #ifdef BCM_KERNEL_SUPPORTS_8021Q |
6157 | base_flags |= (TXD_FLAG_VLAN | | 6148 | if (vlan_tx_tag_present(skb)) { |
6158 | (vlan_tx_tag_get(skb) << 16)); | 6149 | base_flags |= TXD_FLAG_VLAN; |
6150 | vlan = vlan_tx_tag_get(skb); | ||
6151 | } | ||
6152 | #endif | ||
6159 | 6153 | ||
6160 | if (tg3_flag(tp, USE_JUMBO_BDFLAG) && | 6154 | if (tg3_flag(tp, USE_JUMBO_BDFLAG) && |
6161 | !mss && skb->len > VLAN_ETH_FRAME_LEN) | 6155 | !mss && skb->len > VLAN_ETH_FRAME_LEN) |
@@ -6186,13 +6180,21 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6186 | if (tg3_flag(tp, 5701_DMA_BUG)) | 6180 | if (tg3_flag(tp, 5701_DMA_BUG)) |
6187 | would_hit_hwbug = 1; | 6181 | would_hit_hwbug = 1; |
6188 | 6182 | ||
6189 | tg3_set_txd(tnapi, entry, mapping, len, base_flags, | 6183 | tg3_tx_set_bd(tnapi, entry, mapping, len, base_flags | |
6190 | (skb_shinfo(skb)->nr_frags == 0) | (mss << 1)); | 6184 | ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), |
6185 | mss, vlan); | ||
6191 | 6186 | ||
6192 | entry = NEXT_TX(entry); | 6187 | entry = NEXT_TX(entry); |
6193 | 6188 | ||
6194 | /* Now loop through additional data fragments, and queue them. */ | 6189 | /* Now loop through additional data fragments, and queue them. */ |
6195 | if (skb_shinfo(skb)->nr_frags > 0) { | 6190 | if (skb_shinfo(skb)->nr_frags > 0) { |
6191 | u32 tmp_mss = mss; | ||
6192 | |||
6193 | if (!tg3_flag(tp, HW_TSO_1) && | ||
6194 | !tg3_flag(tp, HW_TSO_2) && | ||
6195 | !tg3_flag(tp, HW_TSO_3)) | ||
6196 | tmp_mss = 0; | ||
6197 | |||
6196 | last = skb_shinfo(skb)->nr_frags - 1; | 6198 | last = skb_shinfo(skb)->nr_frags - 1; |
6197 | for (i = 0; i <= last; i++) { | 6199 | for (i = 0; i <= last; i++) { |
6198 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 6200 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
@@ -6219,14 +6221,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6219 | if (tg3_40bit_overflow_test(tp, mapping, len)) | 6221 | if (tg3_40bit_overflow_test(tp, mapping, len)) |
6220 | would_hit_hwbug = 1; | 6222 | would_hit_hwbug = 1; |
6221 | 6223 | ||
6222 | if (tg3_flag(tp, HW_TSO_1) || | 6224 | tg3_tx_set_bd(tnapi, entry, mapping, len, base_flags | |
6223 | tg3_flag(tp, HW_TSO_2) || | 6225 | ((i == last) ? TXD_FLAG_END : 0), |
6224 | tg3_flag(tp, HW_TSO_3)) | 6226 | tmp_mss, vlan); |
6225 | tg3_set_txd(tnapi, entry, mapping, len, | ||
6226 | base_flags, (i == last)|(mss << 1)); | ||
6227 | else | ||
6228 | tg3_set_txd(tnapi, entry, mapping, len, | ||
6229 | base_flags, (i == last)); | ||
6230 | 6227 | ||
6231 | entry = NEXT_TX(entry); | 6228 | entry = NEXT_TX(entry); |
6232 | } | 6229 | } |
@@ -6238,7 +6235,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6238 | /* If the workaround fails due to memory/mapping | 6235 | /* If the workaround fails due to memory/mapping |
6239 | * failure, silently drop this packet. | 6236 | * failure, silently drop this packet. |
6240 | */ | 6237 | */ |
6241 | if (tigon3_dma_hwbug_workaround(tnapi, skb, base_flags, mss)) | 6238 | if (tigon3_dma_hwbug_workaround(tnapi, skb, base_flags, |
6239 | mss, vlan)) | ||
6242 | goto out_unlock; | 6240 | goto out_unlock; |
6243 | 6241 | ||
6244 | entry = NEXT_TX(tnapi->tx_prod); | 6242 | entry = NEXT_TX(tnapi->tx_prod); |
@@ -11370,8 +11368,8 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) | |||
11370 | 11368 | ||
11371 | rx_start_idx = rnapi->hw_status->idx[0].rx_producer; | 11369 | rx_start_idx = rnapi->hw_status->idx[0].rx_producer; |
11372 | 11370 | ||
11373 | tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, | 11371 | tg3_tx_set_bd(tnapi, tnapi->tx_prod, map, tx_len, |
11374 | base_flags, (mss << 1) | 1); | 11372 | base_flags | TXD_FLAG_END, mss, 0); |
11375 | 11373 | ||
11376 | tnapi->tx_prod++; | 11374 | tnapi->tx_prod++; |
11377 | 11375 | ||