From 9b55bb038468a7b504ccdc1d956952598ae1b85b Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Tue, 16 Nov 2010 19:27:14 -0800 Subject: ixgbe: make sure FCoE DDP user buffers are really released by the HW When invalidating the DDP context is invalidated, the HW may not be done with the user buffer right away. In which case, we poll the FCBUFF register to check if the buffer valid bit is cleared or not, if not, we wait for max 100us that is guaranteed by the HW. Signed-off-by: Yi Zou Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 26dd274..6342d48 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -92,6 +92,7 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) struct ixgbe_fcoe *fcoe; struct ixgbe_adapter *adapter; struct ixgbe_fcoe_ddp *ddp; + u32 fcbuff; if (!netdev) goto out_ddp_put; @@ -115,7 +116,14 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCBUFF, 0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW, (xid | IXGBE_FCDMARW_WE)); + + /* guaranteed to be invalidated after 100us */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW, + (xid | IXGBE_FCDMARW_RE)); + fcbuff = IXGBE_READ_REG(&adapter->hw, IXGBE_FCBUFF); spin_unlock_bh(&fcoe->lock); + if (fcbuff & IXGBE_FCBUFF_VALID) + udelay(100); } if (ddp->sgl) pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, -- cgit v0.10.2