aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c103
2 files changed, 54 insertions, 50 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 77793a9debcc..de35c02876aa 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -146,6 +146,7 @@ struct igb_tx_buffer {
146 struct sk_buff *skb; 146 struct sk_buff *skb;
147 unsigned int bytecount; 147 unsigned int bytecount;
148 u16 gso_segs; 148 u16 gso_segs;
149 __be16 protocol;
149 dma_addr_t dma; 150 dma_addr_t dma;
150 u32 length; 151 u32 length;
151 u32 tx_flags; 152 u32 tx_flags;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 862dd7c0cc70..1c234f03b21c 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -3975,10 +3975,11 @@ void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens,
3975 context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); 3975 context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
3976} 3976}
3977 3977
3978static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb, 3978static int igb_tso(struct igb_ring *tx_ring,
3979 u32 tx_flags, __be16 protocol, u8 *hdr_len) 3979 struct igb_tx_buffer *first,
3980 u8 *hdr_len)
3980{ 3981{
3981 int err; 3982 struct sk_buff *skb = first->skb;
3982 u32 vlan_macip_lens, type_tucmd; 3983 u32 vlan_macip_lens, type_tucmd;
3983 u32 mss_l4len_idx, l4len; 3984 u32 mss_l4len_idx, l4len;
3984 3985
@@ -3986,7 +3987,7 @@ static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb,
3986 return 0; 3987 return 0;
3987 3988
3988 if (skb_header_cloned(skb)) { 3989 if (skb_header_cloned(skb)) {
3989 err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); 3990 int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
3990 if (err) 3991 if (err)
3991 return err; 3992 return err;
3992 } 3993 }
@@ -3994,7 +3995,7 @@ static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb,
3994 /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ 3995 /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
3995 type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP; 3996 type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;
3996 3997
3997 if (protocol == __constant_htons(ETH_P_IP)) { 3998 if (first->protocol == __constant_htons(ETH_P_IP)) {
3998 struct iphdr *iph = ip_hdr(skb); 3999 struct iphdr *iph = ip_hdr(skb);
3999 iph->tot_len = 0; 4000 iph->tot_len = 0;
4000 iph->check = 0; 4001 iph->check = 0;
@@ -4003,16 +4004,26 @@ static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb,
4003 IPPROTO_TCP, 4004 IPPROTO_TCP,
4004 0); 4005 0);
4005 type_tucmd |= E1000_ADVTXD_TUCMD_IPV4; 4006 type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
4007 first->tx_flags |= IGB_TX_FLAGS_TSO |
4008 IGB_TX_FLAGS_CSUM |
4009 IGB_TX_FLAGS_IPV4;
4006 } else if (skb_is_gso_v6(skb)) { 4010 } else if (skb_is_gso_v6(skb)) {
4007 ipv6_hdr(skb)->payload_len = 0; 4011 ipv6_hdr(skb)->payload_len = 0;
4008 tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, 4012 tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
4009 &ipv6_hdr(skb)->daddr, 4013 &ipv6_hdr(skb)->daddr,
4010 0, IPPROTO_TCP, 0); 4014 0, IPPROTO_TCP, 0);
4015 first->tx_flags |= IGB_TX_FLAGS_TSO |
4016 IGB_TX_FLAGS_CSUM;
4011 } 4017 }
4012 4018
4019 /* compute header lengths */
4013 l4len = tcp_hdrlen(skb); 4020 l4len = tcp_hdrlen(skb);
4014 *hdr_len = skb_transport_offset(skb) + l4len; 4021 *hdr_len = skb_transport_offset(skb) + l4len;
4015 4022
4023 /* update gso size and bytecount with header size */
4024 first->gso_segs = skb_shinfo(skb)->gso_segs;
4025 first->bytecount += (first->gso_segs - 1) * *hdr_len;
4026
4016 /* MSS L4LEN IDX */ 4027 /* MSS L4LEN IDX */
4017 mss_l4len_idx = l4len << E1000_ADVTXD_L4LEN_SHIFT; 4028 mss_l4len_idx = l4len << E1000_ADVTXD_L4LEN_SHIFT;
4018 mss_l4len_idx |= skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT; 4029 mss_l4len_idx |= skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT;
@@ -4020,26 +4031,26 @@ static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb,
4020 /* VLAN MACLEN IPLEN */ 4031 /* VLAN MACLEN IPLEN */
4021 vlan_macip_lens = skb_network_header_len(skb); 4032 vlan_macip_lens = skb_network_header_len(skb);
4022 vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT; 4033 vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT;
4023 vlan_macip_lens |= tx_flags & IGB_TX_FLAGS_VLAN_MASK; 4034 vlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK;
4024 4035
4025 igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx); 4036 igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);
4026 4037
4027 return 1; 4038 return 1;
4028} 4039}
4029 4040
4030static inline bool igb_tx_csum(struct igb_ring *tx_ring, struct sk_buff *skb, 4041static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
4031 u32 tx_flags, __be16 protocol)
4032{ 4042{
4043 struct sk_buff *skb = first->skb;
4033 u32 vlan_macip_lens = 0; 4044 u32 vlan_macip_lens = 0;
4034 u32 mss_l4len_idx = 0; 4045 u32 mss_l4len_idx = 0;
4035 u32 type_tucmd = 0; 4046 u32 type_tucmd = 0;
4036 4047
4037 if (skb->ip_summed != CHECKSUM_PARTIAL) { 4048 if (skb->ip_summed != CHECKSUM_PARTIAL) {
4038 if (!(tx_flags & IGB_TX_FLAGS_VLAN)) 4049 if (!(first->tx_flags & IGB_TX_FLAGS_VLAN))
4039 return false; 4050 return;
4040 } else { 4051 } else {
4041 u8 l4_hdr = 0; 4052 u8 l4_hdr = 0;
4042 switch (protocol) { 4053 switch (first->protocol) {
4043 case __constant_htons(ETH_P_IP): 4054 case __constant_htons(ETH_P_IP):
4044 vlan_macip_lens |= skb_network_header_len(skb); 4055 vlan_macip_lens |= skb_network_header_len(skb);
4045 type_tucmd |= E1000_ADVTXD_TUCMD_IPV4; 4056 type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
@@ -4053,7 +4064,7 @@ static inline bool igb_tx_csum(struct igb_ring *tx_ring, struct sk_buff *skb,
4053 if (unlikely(net_ratelimit())) { 4064 if (unlikely(net_ratelimit())) {
4054 dev_warn(tx_ring->dev, 4065 dev_warn(tx_ring->dev,
4055 "partial checksum but proto=%x!\n", 4066 "partial checksum but proto=%x!\n",
4056 protocol); 4067 first->protocol);
4057 } 4068 }
4058 break; 4069 break;
4059 } 4070 }
@@ -4081,14 +4092,15 @@ static inline bool igb_tx_csum(struct igb_ring *tx_ring, struct sk_buff *skb,
4081 } 4092 }
4082 break; 4093 break;
4083 } 4094 }
4095
4096 /* update TX checksum flag */
4097 first->tx_flags |= IGB_TX_FLAGS_CSUM;
4084 } 4098 }
4085 4099
4086 vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT; 4100 vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT;
4087 vlan_macip_lens |= tx_flags & IGB_TX_FLAGS_VLAN_MASK; 4101 vlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK;
4088 4102
4089 igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx); 4103 igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);
4090
4091 return (skb->ip_summed == CHECKSUM_PARTIAL);
4092} 4104}
4093 4105
4094static __le32 igb_tx_cmd_type(u32 tx_flags) 4106static __le32 igb_tx_cmd_type(u32 tx_flags)
@@ -4113,8 +4125,9 @@ static __le32 igb_tx_cmd_type(u32 tx_flags)
4113 return cmd_type; 4125 return cmd_type;
4114} 4126}
4115 4127
4116static __le32 igb_tx_olinfo_status(u32 tx_flags, unsigned int paylen, 4128static void igb_tx_olinfo_status(struct igb_ring *tx_ring,
4117 struct igb_ring *tx_ring) 4129 union e1000_adv_tx_desc *tx_desc,
4130 u32 tx_flags, unsigned int paylen)
4118{ 4131{
4119 u32 olinfo_status = paylen << E1000_ADVTXD_PAYLEN_SHIFT; 4132 u32 olinfo_status = paylen << E1000_ADVTXD_PAYLEN_SHIFT;
4120 4133
@@ -4132,7 +4145,7 @@ static __le32 igb_tx_olinfo_status(u32 tx_flags, unsigned int paylen,
4132 olinfo_status |= E1000_TXD_POPTS_IXSM << 8; 4145 olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
4133 } 4146 }
4134 4147
4135 return cpu_to_le32(olinfo_status); 4148 tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
4136} 4149}
4137 4150
4138/* 4151/*
@@ -4140,12 +4153,13 @@ static __le32 igb_tx_olinfo_status(u32 tx_flags, unsigned int paylen,
4140 * maintain a power of two alignment we have to limit ourselves to 32K. 4153 * maintain a power of two alignment we have to limit ourselves to 32K.
4141 */ 4154 */
4142#define IGB_MAX_TXD_PWR 15 4155#define IGB_MAX_TXD_PWR 15
4143#define IGB_MAX_DATA_PER_TXD (1 << IGB_MAX_TXD_PWR) 4156#define IGB_MAX_DATA_PER_TXD (1<<IGB_MAX_TXD_PWR)
4144 4157
4145static void igb_tx_map(struct igb_ring *tx_ring, struct sk_buff *skb, 4158static void igb_tx_map(struct igb_ring *tx_ring,
4146 struct igb_tx_buffer *first, u32 tx_flags, 4159 struct igb_tx_buffer *first,
4147 const u8 hdr_len) 4160 const u8 hdr_len)
4148{ 4161{
4162 struct sk_buff *skb = first->skb;
4149 struct igb_tx_buffer *tx_buffer_info; 4163 struct igb_tx_buffer *tx_buffer_info;
4150 union e1000_adv_tx_desc *tx_desc; 4164 union e1000_adv_tx_desc *tx_desc;
4151 dma_addr_t dma; 4165 dma_addr_t dma;
@@ -4154,24 +4168,12 @@ static void igb_tx_map(struct igb_ring *tx_ring, struct sk_buff *skb,
4154 unsigned int size = skb_headlen(skb); 4168 unsigned int size = skb_headlen(skb);
4155 unsigned int paylen = skb->len - hdr_len; 4169 unsigned int paylen = skb->len - hdr_len;
4156 __le32 cmd_type; 4170 __le32 cmd_type;
4171 u32 tx_flags = first->tx_flags;
4157 u16 i = tx_ring->next_to_use; 4172 u16 i = tx_ring->next_to_use;
4158 u16 gso_segs;
4159
4160 if (tx_flags & IGB_TX_FLAGS_TSO)
4161 gso_segs = skb_shinfo(skb)->gso_segs;
4162 else
4163 gso_segs = 1;
4164
4165 /* multiply data chunks by size of headers */
4166 first->bytecount = paylen + (gso_segs * hdr_len);
4167 first->gso_segs = gso_segs;
4168 first->skb = skb;
4169 4173
4170 tx_desc = IGB_TX_DESC(tx_ring, i); 4174 tx_desc = IGB_TX_DESC(tx_ring, i);
4171 4175
4172 tx_desc->read.olinfo_status = 4176 igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, paylen);
4173 igb_tx_olinfo_status(tx_flags, paylen, tx_ring);
4174
4175 cmd_type = igb_tx_cmd_type(tx_flags); 4177 cmd_type = igb_tx_cmd_type(tx_flags);
4176 4178
4177 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE); 4179 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
@@ -4181,7 +4183,6 @@ static void igb_tx_map(struct igb_ring *tx_ring, struct sk_buff *skb,
4181 /* record length, and DMA address */ 4183 /* record length, and DMA address */
4182 first->length = size; 4184 first->length = size;
4183 first->dma = dma; 4185 first->dma = dma;
4184 first->tx_flags = tx_flags;
4185 tx_desc->read.buffer_addr = cpu_to_le64(dma); 4186 tx_desc->read.buffer_addr = cpu_to_le64(dma);
4186 4187
4187 for (;;) { 4188 for (;;) {
@@ -4336,6 +4337,12 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
4336 return NETDEV_TX_BUSY; 4337 return NETDEV_TX_BUSY;
4337 } 4338 }
4338 4339
4340 /* record the location of the first descriptor for this packet */
4341 first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
4342 first->skb = skb;
4343 first->bytecount = skb->len;
4344 first->gso_segs = 1;
4345
4339 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 4346 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
4340 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 4347 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
4341 tx_flags |= IGB_TX_FLAGS_TSTAMP; 4348 tx_flags |= IGB_TX_FLAGS_TSTAMP;
@@ -4346,22 +4353,17 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
4346 tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); 4353 tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
4347 } 4354 }
4348 4355
4349 /* record the location of the first descriptor for this packet */ 4356 /* record initial flags and protocol */
4350 first = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; 4357 first->tx_flags = tx_flags;
4358 first->protocol = protocol;
4351 4359
4352 tso = igb_tso(tx_ring, skb, tx_flags, protocol, &hdr_len); 4360 tso = igb_tso(tx_ring, first, &hdr_len);
4353 if (tso < 0) { 4361 if (tso < 0)
4354 goto out_drop; 4362 goto out_drop;
4355 } else if (tso) { 4363 else if (!tso)
4356 tx_flags |= IGB_TX_FLAGS_TSO | IGB_TX_FLAGS_CSUM; 4364 igb_tx_csum(tx_ring, first);
4357 if (protocol == htons(ETH_P_IP))
4358 tx_flags |= IGB_TX_FLAGS_IPV4;
4359 } else if (igb_tx_csum(tx_ring, skb, tx_flags, protocol) &&
4360 (skb->ip_summed == CHECKSUM_PARTIAL)) {
4361 tx_flags |= IGB_TX_FLAGS_CSUM;
4362 }
4363 4365
4364 igb_tx_map(tx_ring, skb, first, tx_flags, hdr_len); 4366 igb_tx_map(tx_ring, first, hdr_len);
4365 4367
4366 /* Make sure there is space in the ring for the next send. */ 4368 /* Make sure there is space in the ring for the next send. */
4367 igb_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 4); 4369 igb_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 4);
@@ -4369,7 +4371,8 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
4369 return NETDEV_TX_OK; 4371 return NETDEV_TX_OK;
4370 4372
4371out_drop: 4373out_drop:
4372 dev_kfree_skb_any(skb); 4374 igb_unmap_and_free_tx_resource(tx_ring, first);
4375
4373 return NETDEV_TX_OK; 4376 return NETDEV_TX_OK;
4374} 4377}
4375 4378