diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2011-06-11 01:45:13 +0000 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-07-21 22:56:37 -0700 |
commit | ff886dfce2bdacbe71583ec973cec117973d8859 (patch) | |
tree | ea48f94008d8ef554f709962b7f0b7fcee860c3b /drivers/net/ixgbe/ixgbe_fcoe.c | |
parent | bd19805803a954415ec36a559fd3b8a0a3647d7c (diff) | |
download | op-kernel-dev-ff886dfce2bdacbe71583ec973cec117973d8859.zip op-kernel-dev-ff886dfce2bdacbe71583ec973cec117973d8859.tar.gz |
ixgbe: Pass staterr instead of re-reading status and error bits from descriptor
This change is meant to address possible race conditions from the status
and error bits on the RX descriptors being re-read by multiple functions in
the RX cleanup path. To resolve this I have added code that will pass the
staterr value to those functions.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_fcoe.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_fcoe.c | 35 |
1 files changed, 6 insertions, 29 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index f0c1018..824edae 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -37,25 +37,6 @@ #include <scsi/libfcoe.h> /** - * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @rx_desc: advanced rx descriptor - * - * Returns : true if it is FCoE pkt - */ -static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc) -{ - u16 p; - - p = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info); - if (p & IXGBE_RXDADV_PKTTYPE_ETQF) { - p &= IXGBE_RXDADV_PKTTYPE_ETQF_MASK; - p >>= IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT; - return p == IXGBE_ETQF_FILTER_FCOE; - } - return false; -} - -/** * ixgbe_fcoe_clear_ddp - clear the given ddp context * @ddp - ptr to the ixgbe_fcoe_ddp * @@ -136,7 +117,6 @@ out_ddp_put: return len; } - /** * ixgbe_fcoe_ddp_setup - called to set up ddp context * @netdev: the corresponding net_device @@ -380,23 +360,20 @@ int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, */ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb) + struct sk_buff *skb, + u32 staterr) { u16 xid; u32 fctl; - u32 sterr, fceofe, fcerr, fcstat; + u32 fceofe, fcerr, fcstat; int rc = -EINVAL; struct ixgbe_fcoe *fcoe; struct ixgbe_fcoe_ddp *ddp; struct fc_frame_header *fh; struct fcoe_crc_eof *crc; - if (!ixgbe_rx_is_fcoe(rx_desc)) - goto ddp_out; - - sterr = le32_to_cpu(rx_desc->wb.upper.status_error); - fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR); - fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE); + fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR); + fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE); if (fcerr == IXGBE_FCERR_BADCRC) skb_checksum_none_assert(skb); else @@ -425,7 +402,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (fcerr | fceofe) goto ddp_out; - fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT); + fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT); if (fcstat) { /* update length of DDPed data */ ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); |