aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAnjali Singhai Jain <anjali.singhai@intel.com>2014-06-04 04:45:15 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-07-02 22:02:18 -0400
commit49d7d933316375665cea49473d563cb8447d8a06 (patch)
treeb3f44c1e5c97540e80baca8bc73527c022dcfcc9 /drivers
parentbd4578bc84a8c8a390cf6002539e75447e78e935 (diff)
i40e/i40evf: Do not free the dummy packet buffer synchronously
The HW still needs to consume it and freeing it in the function that created it would mean we will be racing with the HW. The i40e_clean_tx_ring() routine will free up the buffer attached once the HW has consumed it. The clean_fdir_tx_irq function had to be fixed to handle the freeing correctly. Cases where we program more than one filter per flow (Ipv4), the code had to be changed to allocate dummy buffer multiple times since it will be freed by the clean routine. This also fixes an issue where the filter program routine was not checking if there were descriptors available for programming a filter. Change-ID: Idf72028fd873221934e319d021ef65a1e51acaf7 Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com> Tested-by: Jim Young <jamesx.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c21
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c109
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.h6
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c6
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.h6
5 files changed, 96 insertions, 52 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 31709b8cdd5a..440b671e5d01 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -3087,16 +3087,33 @@ static bool i40e_clean_fdir_tx_irq(struct i40e_ring *tx_ring, int budget)
3087 /* clear next_to_watch to prevent false hangs */ 3087 /* clear next_to_watch to prevent false hangs */
3088 tx_buf->next_to_watch = NULL; 3088 tx_buf->next_to_watch = NULL;
3089 3089
3090 tx_desc->buffer_addr = 0;
3091 tx_desc->cmd_type_offset_bsz = 0;
3092 /* move past filter desc */
3093 tx_buf++;
3094 tx_desc++;
3095 i++;
3096 if (unlikely(!i)) {
3097 i -= tx_ring->count;
3098 tx_buf = tx_ring->tx_bi;
3099 tx_desc = I40E_TX_DESC(tx_ring, 0);
3100 }
3090 /* unmap skb header data */ 3101 /* unmap skb header data */
3091 dma_unmap_single(tx_ring->dev, 3102 dma_unmap_single(tx_ring->dev,
3092 dma_unmap_addr(tx_buf, dma), 3103 dma_unmap_addr(tx_buf, dma),
3093 dma_unmap_len(tx_buf, len), 3104 dma_unmap_len(tx_buf, len),
3094 DMA_TO_DEVICE); 3105 DMA_TO_DEVICE);
3106 if (tx_buf->tx_flags & I40E_TX_FLAGS_FD_SB)
3107 kfree(tx_buf->raw_buf);
3095 3108
3109 tx_buf->raw_buf = NULL;
3110 tx_buf->tx_flags = 0;
3111 tx_buf->next_to_watch = NULL;
3096 dma_unmap_len_set(tx_buf, len, 0); 3112 dma_unmap_len_set(tx_buf, len, 0);
3113 tx_desc->buffer_addr = 0;
3114 tx_desc->cmd_type_offset_bsz = 0;
3097 3115
3098 3116 /* move us past the eop_desc for start of next FD desc */
3099 /* move to the next desc and buffer to clean */
3100 tx_buf++; 3117 tx_buf++;
3101 tx_desc++; 3118 tx_desc++;
3102 i++; 3119 i++;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 051e2136715f..2c686e2dfe1d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -39,6 +39,7 @@ static inline __le64 build_ctob(u32 td_cmd, u32 td_offset, unsigned int size,
39} 39}
40 40
41#define I40E_TXD_CMD (I40E_TX_DESC_CMD_EOP | I40E_TX_DESC_CMD_RS) 41#define I40E_TXD_CMD (I40E_TX_DESC_CMD_EOP | I40E_TX_DESC_CMD_RS)
42#define I40E_FD_CLEAN_DELAY 10
42/** 43/**
43 * i40e_program_fdir_filter - Program a Flow Director filter 44 * i40e_program_fdir_filter - Program a Flow Director filter
44 * @fdir_data: Packet data that will be filter parameters 45 * @fdir_data: Packet data that will be filter parameters
@@ -50,7 +51,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
50 struct i40e_pf *pf, bool add) 51 struct i40e_pf *pf, bool add)
51{ 52{
52 struct i40e_filter_program_desc *fdir_desc; 53 struct i40e_filter_program_desc *fdir_desc;
53 struct i40e_tx_buffer *tx_buf; 54 struct i40e_tx_buffer *tx_buf, *first;
54 struct i40e_tx_desc *tx_desc; 55 struct i40e_tx_desc *tx_desc;
55 struct i40e_ring *tx_ring; 56 struct i40e_ring *tx_ring;
56 unsigned int fpt, dcc; 57 unsigned int fpt, dcc;
@@ -58,6 +59,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
58 struct device *dev; 59 struct device *dev;
59 dma_addr_t dma; 60 dma_addr_t dma;
60 u32 td_cmd = 0; 61 u32 td_cmd = 0;
62 u16 delay = 0;
61 u16 i; 63 u16 i;
62 64
63 /* find existing FDIR VSI */ 65 /* find existing FDIR VSI */
@@ -71,6 +73,17 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
71 tx_ring = vsi->tx_rings[0]; 73 tx_ring = vsi->tx_rings[0];
72 dev = tx_ring->dev; 74 dev = tx_ring->dev;
73 75
76 /* we need two descriptors to add/del a filter and we can wait */
77 do {
78 if (I40E_DESC_UNUSED(tx_ring) > 1)
79 break;
80 msleep_interruptible(1);
81 delay++;
82 } while (delay < I40E_FD_CLEAN_DELAY);
83
84 if (!(I40E_DESC_UNUSED(tx_ring) > 1))
85 return -EAGAIN;
86
74 dma = dma_map_single(dev, raw_packet, 87 dma = dma_map_single(dev, raw_packet,
75 I40E_FDIR_MAX_RAW_PACKET_SIZE, DMA_TO_DEVICE); 88 I40E_FDIR_MAX_RAW_PACKET_SIZE, DMA_TO_DEVICE);
76 if (dma_mapping_error(dev, dma)) 89 if (dma_mapping_error(dev, dma))
@@ -79,8 +92,10 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
79 /* grab the next descriptor */ 92 /* grab the next descriptor */
80 i = tx_ring->next_to_use; 93 i = tx_ring->next_to_use;
81 fdir_desc = I40E_TX_FDIRDESC(tx_ring, i); 94 fdir_desc = I40E_TX_FDIRDESC(tx_ring, i);
95 first = &tx_ring->tx_bi[i];
96 memset(first, 0, sizeof(struct i40e_tx_buffer));
82 97
83 tx_ring->next_to_use = (i + 1 < tx_ring->count) ? i + 1 : 0; 98 tx_ring->next_to_use = ((i + 1) < tx_ring->count) ? i + 1 : 0;
84 99
85 fpt = (fdir_data->q_index << I40E_TXD_FLTR_QW0_QINDEX_SHIFT) & 100 fpt = (fdir_data->q_index << I40E_TXD_FLTR_QW0_QINDEX_SHIFT) &
86 I40E_TXD_FLTR_QW0_QINDEX_MASK; 101 I40E_TXD_FLTR_QW0_QINDEX_MASK;
@@ -132,7 +147,9 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
132 tx_desc = I40E_TX_DESC(tx_ring, i); 147 tx_desc = I40E_TX_DESC(tx_ring, i);
133 tx_buf = &tx_ring->tx_bi[i]; 148 tx_buf = &tx_ring->tx_bi[i];
134 149
135 tx_ring->next_to_use = (i + 1 < tx_ring->count) ? i + 1 : 0; 150 tx_ring->next_to_use = ((i + 1) < tx_ring->count) ? i + 1 : 0;
151
152 memset(tx_buf, 0, sizeof(struct i40e_tx_buffer));
136 153
137 /* record length, and DMA address */ 154 /* record length, and DMA address */
138 dma_unmap_len_set(tx_buf, len, I40E_FDIR_MAX_RAW_PACKET_SIZE); 155 dma_unmap_len_set(tx_buf, len, I40E_FDIR_MAX_RAW_PACKET_SIZE);
@@ -141,6 +158,9 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
141 tx_desc->buffer_addr = cpu_to_le64(dma); 158 tx_desc->buffer_addr = cpu_to_le64(dma);
142 td_cmd = I40E_TXD_CMD | I40E_TX_DESC_CMD_DUMMY; 159 td_cmd = I40E_TXD_CMD | I40E_TX_DESC_CMD_DUMMY;
143 160
161 tx_buf->tx_flags = I40E_TX_FLAGS_FD_SB;
162 tx_buf->raw_buf = (void *)raw_packet;
163
144 tx_desc->cmd_type_offset_bsz = 164 tx_desc->cmd_type_offset_bsz =
145 build_ctob(td_cmd, 0, I40E_FDIR_MAX_RAW_PACKET_SIZE, 0); 165 build_ctob(td_cmd, 0, I40E_FDIR_MAX_RAW_PACKET_SIZE, 0);
146 166
@@ -148,14 +168,12 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
148 tx_buf->time_stamp = jiffies; 168 tx_buf->time_stamp = jiffies;
149 169
150 /* Force memory writes to complete before letting h/w 170 /* Force memory writes to complete before letting h/w
151 * know there are new descriptors to fetch. (Only 171 * know there are new descriptors to fetch.
152 * applicable for weak-ordered memory model archs,
153 * such as IA-64).
154 */ 172 */
155 wmb(); 173 wmb();
156 174
157 /* Mark the data descriptor to be watched */ 175 /* Mark the data descriptor to be watched */
158 tx_buf->next_to_watch = tx_desc; 176 first->next_to_watch = tx_desc;
159 177
160 writel(tx_ring->next_to_use, tx_ring->tail); 178 writel(tx_ring->next_to_use, tx_ring->tail);
161 return 0; 179 return 0;
@@ -170,24 +188,27 @@ dma_fail:
170 * i40e_add_del_fdir_udpv4 - Add/Remove UDPv4 filters 188 * i40e_add_del_fdir_udpv4 - Add/Remove UDPv4 filters
171 * @vsi: pointer to the targeted VSI 189 * @vsi: pointer to the targeted VSI
172 * @fd_data: the flow director data required for the FDir descriptor 190 * @fd_data: the flow director data required for the FDir descriptor
173 * @raw_packet: the pre-allocated packet buffer for FDir
174 * @add: true adds a filter, false removes it 191 * @add: true adds a filter, false removes it
175 * 192 *
176 * Returns 0 if the filters were successfully added or removed 193 * Returns 0 if the filters were successfully added or removed
177 **/ 194 **/
178static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi, 195static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
179 struct i40e_fdir_filter *fd_data, 196 struct i40e_fdir_filter *fd_data,
180 u8 *raw_packet, bool add) 197 bool add)
181{ 198{
182 struct i40e_pf *pf = vsi->back; 199 struct i40e_pf *pf = vsi->back;
183 struct udphdr *udp; 200 struct udphdr *udp;
184 struct iphdr *ip; 201 struct iphdr *ip;
185 bool err = false; 202 bool err = false;
203 u8 *raw_packet;
186 int ret; 204 int ret;
187 static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0, 205 static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0,
188 0x45, 0, 0, 0x1c, 0, 0, 0x40, 0, 0x40, 0x11, 0, 0, 0, 0, 0, 0, 206 0x45, 0, 0, 0x1c, 0, 0, 0x40, 0, 0x40, 0x11, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
190 208
209 raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
210 if (!raw_packet)
211 return -ENOMEM;
191 memcpy(raw_packet, packet, I40E_UDPIP_DUMMY_PACKET_LEN); 212 memcpy(raw_packet, packet, I40E_UDPIP_DUMMY_PACKET_LEN);
192 213
193 ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET); 214 ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
@@ -220,19 +241,19 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
220 * i40e_add_del_fdir_tcpv4 - Add/Remove TCPv4 filters 241 * i40e_add_del_fdir_tcpv4 - Add/Remove TCPv4 filters
221 * @vsi: pointer to the targeted VSI 242 * @vsi: pointer to the targeted VSI
222 * @fd_data: the flow director data required for the FDir descriptor 243 * @fd_data: the flow director data required for the FDir descriptor
223 * @raw_packet: the pre-allocated packet buffer for FDir
224 * @add: true adds a filter, false removes it 244 * @add: true adds a filter, false removes it
225 * 245 *
226 * Returns 0 if the filters were successfully added or removed 246 * Returns 0 if the filters were successfully added or removed
227 **/ 247 **/
228static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi, 248static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
229 struct i40e_fdir_filter *fd_data, 249 struct i40e_fdir_filter *fd_data,
230 u8 *raw_packet, bool add) 250 bool add)
231{ 251{
232 struct i40e_pf *pf = vsi->back; 252 struct i40e_pf *pf = vsi->back;
233 struct tcphdr *tcp; 253 struct tcphdr *tcp;
234 struct iphdr *ip; 254 struct iphdr *ip;
235 bool err = false; 255 bool err = false;
256 u8 *raw_packet;
236 int ret; 257 int ret;
237 /* Dummy packet */ 258 /* Dummy packet */
238 static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0, 259 static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0,
@@ -240,6 +261,9 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x11, 261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x11,
241 0x0, 0x72, 0, 0, 0, 0}; 262 0x0, 0x72, 0, 0, 0, 0};
242 263
264 raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
265 if (!raw_packet)
266 return -ENOMEM;
243 memcpy(raw_packet, packet, I40E_TCPIP_DUMMY_PACKET_LEN); 267 memcpy(raw_packet, packet, I40E_TCPIP_DUMMY_PACKET_LEN);
244 268
245 ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET); 269 ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
@@ -286,7 +310,7 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
286 **/ 310 **/
287static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi, 311static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi,
288 struct i40e_fdir_filter *fd_data, 312 struct i40e_fdir_filter *fd_data,
289 u8 *raw_packet, bool add) 313 bool add)
290{ 314{
291 return -EOPNOTSUPP; 315 return -EOPNOTSUPP;
292} 316}
@@ -297,33 +321,36 @@ static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi,
297 * a specific flow spec 321 * a specific flow spec
298 * @vsi: pointer to the targeted VSI 322 * @vsi: pointer to the targeted VSI
299 * @fd_data: the flow director data required for the FDir descriptor 323 * @fd_data: the flow director data required for the FDir descriptor
300 * @raw_packet: the pre-allocated packet buffer for FDir
301 * @add: true adds a filter, false removes it 324 * @add: true adds a filter, false removes it
302 * 325 *
303 * Returns 0 if the filters were successfully added or removed 326 * Returns 0 if the filters were successfully added or removed
304 **/ 327 **/
305static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi, 328static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi,
306 struct i40e_fdir_filter *fd_data, 329 struct i40e_fdir_filter *fd_data,
307 u8 *raw_packet, bool add) 330 bool add)
308{ 331{
309 struct i40e_pf *pf = vsi->back; 332 struct i40e_pf *pf = vsi->back;
310 struct iphdr *ip; 333 struct iphdr *ip;
311 bool err = false; 334 bool err = false;
335 u8 *raw_packet;
312 int ret; 336 int ret;
313 int i; 337 int i;
314 static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0, 338 static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0,
315 0x45, 0, 0, 0x14, 0, 0, 0x40, 0, 0x40, 0x10, 0, 0, 0, 0, 0, 0, 339 0x45, 0, 0, 0x14, 0, 0, 0x40, 0, 0x40, 0x10, 0, 0, 0, 0, 0, 0,
316 0, 0, 0, 0}; 340 0, 0, 0, 0};
317 341
318 memcpy(raw_packet, packet, I40E_IP_DUMMY_PACKET_LEN);
319 ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
320
321 ip->saddr = fd_data->src_ip[0];
322 ip->daddr = fd_data->dst_ip[0];
323 ip->protocol = 0;
324
325 for (i = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER; 342 for (i = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
326 i <= I40E_FILTER_PCTYPE_FRAG_IPV4; i++) { 343 i <= I40E_FILTER_PCTYPE_FRAG_IPV4; i++) {
344 raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
345 if (!raw_packet)
346 return -ENOMEM;
347 memcpy(raw_packet, packet, I40E_IP_DUMMY_PACKET_LEN);
348 ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
349
350 ip->saddr = fd_data->src_ip[0];
351 ip->daddr = fd_data->dst_ip[0];
352 ip->protocol = 0;
353
327 fd_data->pctype = i; 354 fd_data->pctype = i;
328 ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add); 355 ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add);
329 356
@@ -353,50 +380,34 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
353 struct i40e_fdir_filter *input, bool add) 380 struct i40e_fdir_filter *input, bool add)
354{ 381{
355 struct i40e_pf *pf = vsi->back; 382 struct i40e_pf *pf = vsi->back;
356 u8 *raw_packet;
357 int ret; 383 int ret;
358 384
359 /* Populate the Flow Director that we have at the moment
360 * and allocate the raw packet buffer for the calling functions
361 */
362 raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
363 if (!raw_packet)
364 return -ENOMEM;
365
366 switch (input->flow_type & ~FLOW_EXT) { 385 switch (input->flow_type & ~FLOW_EXT) {
367 case TCP_V4_FLOW: 386 case TCP_V4_FLOW:
368 ret = i40e_add_del_fdir_tcpv4(vsi, input, raw_packet, 387 ret = i40e_add_del_fdir_tcpv4(vsi, input, add);
369 add);
370 break; 388 break;
371 case UDP_V4_FLOW: 389 case UDP_V4_FLOW:
372 ret = i40e_add_del_fdir_udpv4(vsi, input, raw_packet, 390 ret = i40e_add_del_fdir_udpv4(vsi, input, add);
373 add);
374 break; 391 break;
375 case SCTP_V4_FLOW: 392 case SCTP_V4_FLOW:
376 ret = i40e_add_del_fdir_sctpv4(vsi, input, raw_packet, 393 ret = i40e_add_del_fdir_sctpv4(vsi, input, add);
377 add);
378 break; 394 break;
379 case IPV4_FLOW: 395 case IPV4_FLOW:
380 ret = i40e_add_del_fdir_ipv4(vsi, input, raw_packet, 396 ret = i40e_add_del_fdir_ipv4(vsi, input, add);
381 add);
382 break; 397 break;
383 case IP_USER_FLOW: 398 case IP_USER_FLOW:
384 switch (input->ip4_proto) { 399 switch (input->ip4_proto) {
385 case IPPROTO_TCP: 400 case IPPROTO_TCP:
386 ret = i40e_add_del_fdir_tcpv4(vsi, input, 401 ret = i40e_add_del_fdir_tcpv4(vsi, input, add);
387 raw_packet, add);
388 break; 402 break;
389 case IPPROTO_UDP: 403 case IPPROTO_UDP:
390 ret = i40e_add_del_fdir_udpv4(vsi, input, 404 ret = i40e_add_del_fdir_udpv4(vsi, input, add);
391 raw_packet, add);
392 break; 405 break;
393 case IPPROTO_SCTP: 406 case IPPROTO_SCTP:
394 ret = i40e_add_del_fdir_sctpv4(vsi, input, 407 ret = i40e_add_del_fdir_sctpv4(vsi, input, add);
395 raw_packet, add);
396 break; 408 break;
397 default: 409 default:
398 ret = i40e_add_del_fdir_ipv4(vsi, input, 410 ret = i40e_add_del_fdir_ipv4(vsi, input, add);
399 raw_packet, add);
400 break; 411 break;
401 } 412 }
402 break; 413 break;
@@ -406,7 +417,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
406 ret = -EINVAL; 417 ret = -EINVAL;
407 } 418 }
408 419
409 kfree(raw_packet); 420 /* The buffer allocated here is freed by the i40e_clean_tx_ring() */
410 return ret; 421 return ret;
411} 422}
412 423
@@ -480,7 +491,11 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
480 struct i40e_tx_buffer *tx_buffer) 491 struct i40e_tx_buffer *tx_buffer)
481{ 492{
482 if (tx_buffer->skb) { 493 if (tx_buffer->skb) {
483 dev_kfree_skb_any(tx_buffer->skb); 494 if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
495 kfree(tx_buffer->raw_buf);
496 else
497 dev_kfree_skb_any(tx_buffer->skb);
498
484 if (dma_unmap_len(tx_buffer, len)) 499 if (dma_unmap_len(tx_buffer, len))
485 dma_unmap_single(ring->dev, 500 dma_unmap_single(ring->dev,
486 dma_unmap_addr(tx_buffer, dma), 501 dma_unmap_addr(tx_buffer, dma),
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
index f09fb3ef691d..c1c356984b17 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -131,6 +131,7 @@ enum i40e_dyn_idx_t {
131#define I40E_TX_FLAGS_FCCRC (u32)(1 << 6) 131#define I40E_TX_FLAGS_FCCRC (u32)(1 << 6)
132#define I40E_TX_FLAGS_FSO (u32)(1 << 7) 132#define I40E_TX_FLAGS_FSO (u32)(1 << 7)
133#define I40E_TX_FLAGS_TSYN (u32)(1 << 8) 133#define I40E_TX_FLAGS_TSYN (u32)(1 << 8)
134#define I40E_TX_FLAGS_FD_SB (u32)(1 << 9)
134#define I40E_TX_FLAGS_VLAN_MASK 0xffff0000 135#define I40E_TX_FLAGS_VLAN_MASK 0xffff0000
135#define I40E_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000 136#define I40E_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
136#define I40E_TX_FLAGS_VLAN_PRIO_SHIFT 29 137#define I40E_TX_FLAGS_VLAN_PRIO_SHIFT 29
@@ -139,7 +140,10 @@ enum i40e_dyn_idx_t {
139struct i40e_tx_buffer { 140struct i40e_tx_buffer {
140 struct i40e_tx_desc *next_to_watch; 141 struct i40e_tx_desc *next_to_watch;
141 unsigned long time_stamp; 142 unsigned long time_stamp;
142 struct sk_buff *skb; 143 union {
144 struct sk_buff *skb;
145 void *raw_buf;
146 };
143 unsigned int bytecount; 147 unsigned int bytecount;
144 unsigned short gso_segs; 148 unsigned short gso_segs;
145 DEFINE_DMA_UNMAP_ADDR(dma); 149 DEFINE_DMA_UNMAP_ADDR(dma);
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index f2762f5927cc..b342f212e91f 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -50,7 +50,11 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
50 struct i40e_tx_buffer *tx_buffer) 50 struct i40e_tx_buffer *tx_buffer)
51{ 51{
52 if (tx_buffer->skb) { 52 if (tx_buffer->skb) {
53 dev_kfree_skb_any(tx_buffer->skb); 53 if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
54 kfree(tx_buffer->raw_buf);
55 else
56 dev_kfree_skb_any(tx_buffer->skb);
57
54 if (dma_unmap_len(tx_buffer, len)) 58 if (dma_unmap_len(tx_buffer, len))
55 dma_unmap_single(ring->dev, 59 dma_unmap_single(ring->dev,
56 dma_unmap_addr(tx_buffer, dma), 60 dma_unmap_addr(tx_buffer, dma),
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
index acd3c12b8f6a..8bc6858163b0 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
@@ -130,6 +130,7 @@ enum i40e_dyn_idx_t {
130#define I40E_TX_FLAGS_IPV6 (u32)(1 << 5) 130#define I40E_TX_FLAGS_IPV6 (u32)(1 << 5)
131#define I40E_TX_FLAGS_FCCRC (u32)(1 << 6) 131#define I40E_TX_FLAGS_FCCRC (u32)(1 << 6)
132#define I40E_TX_FLAGS_FSO (u32)(1 << 7) 132#define I40E_TX_FLAGS_FSO (u32)(1 << 7)
133#define I40E_TX_FLAGS_FD_SB (u32)(1 << 9)
133#define I40E_TX_FLAGS_VLAN_MASK 0xffff0000 134#define I40E_TX_FLAGS_VLAN_MASK 0xffff0000
134#define I40E_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000 135#define I40E_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
135#define I40E_TX_FLAGS_VLAN_PRIO_SHIFT 29 136#define I40E_TX_FLAGS_VLAN_PRIO_SHIFT 29
@@ -138,7 +139,10 @@ enum i40e_dyn_idx_t {
138struct i40e_tx_buffer { 139struct i40e_tx_buffer {
139 struct i40e_tx_desc *next_to_watch; 140 struct i40e_tx_desc *next_to_watch;
140 unsigned long time_stamp; 141 unsigned long time_stamp;
141 struct sk_buff *skb; 142 union {
143 struct sk_buff *skb;
144 void *raw_buf;
145 };
142 unsigned int bytecount; 146 unsigned int bytecount;
143 unsigned short gso_segs; 147 unsigned short gso_segs;
144 DEFINE_DMA_UNMAP_ADDR(dma); 148 DEFINE_DMA_UNMAP_ADDR(dma);