From 5c60f81a2553213856b3bb80f18003e56a6a110d Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 1 Sep 2012 05:12:38 +0000 Subject: 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 Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 5 +++++ drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/intel/ixgbevf') 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 { __IXGBEVF_DOWN }; +struct ixgbevf_cb { + struct sk_buff *prev; +}; +#define IXGBE_CB(skb) ((struct ixgbevf_cb *)(skb)->cb) + enum ixgbevf_boards { board_82599_vf, 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, if (!(staterr & IXGBE_RXD_STAT_EOP)) { skb->next = next_buffer->skb; - skb->next->prev = skb; + IXGBE_CB(skb->next)->prev = skb; adapter->non_eop_descs++; goto next_desc; } + /* we should not be chaining buffers, if we did drop the skb */ + if (IXGBE_CB(skb)->prev) { + do { + struct sk_buff *this = skb; + skb = IXGBE_CB(skb)->prev; + dev_kfree_skb(this); + } while (skb); + goto next_desc; + } + /* ERR_MASK will only have valid bits if EOP set */ if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { dev_kfree_skb_irq(skb); @@ -1439,7 +1449,7 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_adapter *adapter, rx_buffer_info->skb = NULL; do { struct sk_buff *this = skb; - skb = skb->prev; + skb = IXGBE_CB(skb)->prev; dev_kfree_skb(this); } while (skb); } -- cgit v1.2.1