diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 103 |
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 | ||
3978 | static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb, | 3978 | static 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 | ||
4030 | static inline bool igb_tx_csum(struct igb_ring *tx_ring, struct sk_buff *skb, | 4041 | static 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 | ||
4094 | static __le32 igb_tx_cmd_type(u32 tx_flags) | 4106 | static __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 | ||
4116 | static __le32 igb_tx_olinfo_status(u32 tx_flags, unsigned int paylen, | 4128 | static 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 | ||
4145 | static void igb_tx_map(struct igb_ring *tx_ring, struct sk_buff *skb, | 4158 | static 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 | ||
4371 | out_drop: | 4373 | out_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 | ||