diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-09-01 01:12:38 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-09-24 04:50:35 -0400 |
commit | 5c60f81a2553213856b3bb80f18003e56a6a110d (patch) | |
tree | 7107a3cc1e16c790f5d89ab74161dc6172be121d /drivers/net/ethernet/intel | |
parent | ac6ed8f00aca7dd1abf0c90bcb3c8e46e7f44243 (diff) |
ixgbevf: Add fix to VF to handle multi-descriptor buffers
This change fixes the ixgbevf driver so that it can correctly drop a frame
should it receive a jumbo frame.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 14 |
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index eb26fda63c99..383b4e1cd175 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | |||
@@ -261,6 +261,11 @@ enum ixbgevf_state_t { | |||
261 | __IXGBEVF_DOWN | 261 | __IXGBEVF_DOWN |
262 | }; | 262 | }; |
263 | 263 | ||
264 | struct ixgbevf_cb { | ||
265 | struct sk_buff *prev; | ||
266 | }; | ||
267 | #define IXGBE_CB(skb) ((struct ixgbevf_cb *)(skb)->cb) | ||
268 | |||
264 | enum ixgbevf_boards { | 269 | enum ixgbevf_boards { |
265 | board_82599_vf, | 270 | board_82599_vf, |
266 | board_X540_vf, | 271 | board_X540_vf, |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 37bbd86529e3..2ba15ae2335c 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -433,11 +433,21 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, | |||
433 | 433 | ||
434 | if (!(staterr & IXGBE_RXD_STAT_EOP)) { | 434 | if (!(staterr & IXGBE_RXD_STAT_EOP)) { |
435 | skb->next = next_buffer->skb; | 435 | skb->next = next_buffer->skb; |
436 | skb->next->prev = skb; | 436 | IXGBE_CB(skb->next)->prev = skb; |
437 | adapter->non_eop_descs++; | 437 | adapter->non_eop_descs++; |
438 | goto next_desc; | 438 | goto next_desc; |
439 | } | 439 | } |
440 | 440 | ||
441 | /* we should not be chaining buffers, if we did drop the skb */ | ||
442 | if (IXGBE_CB(skb)->prev) { | ||
443 | do { | ||
444 | struct sk_buff *this = skb; | ||
445 | skb = IXGBE_CB(skb)->prev; | ||
446 | dev_kfree_skb(this); | ||
447 | } while (skb); | ||
448 | goto next_desc; | ||
449 | } | ||
450 | |||
441 | /* ERR_MASK will only have valid bits if EOP set */ | 451 | /* ERR_MASK will only have valid bits if EOP set */ |
442 | if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { | 452 | if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { |
443 | dev_kfree_skb_irq(skb); | 453 | dev_kfree_skb_irq(skb); |
@@ -1439,7 +1449,7 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_adapter *adapter, | |||
1439 | rx_buffer_info->skb = NULL; | 1449 | rx_buffer_info->skb = NULL; |
1440 | do { | 1450 | do { |
1441 | struct sk_buff *this = skb; | 1451 | struct sk_buff *this = skb; |
1442 | skb = skb->prev; | 1452 | skb = IXGBE_CB(skb)->prev; |
1443 | dev_kfree_skb(this); | 1453 | dev_kfree_skb(this); |
1444 | } while (skb); | 1454 | } while (skb); |
1445 | } | 1455 | } |