aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2014-01-14 18:53:15 -0800
committerDavid S. Miller <davem@davemloft.net>2014-01-14 18:59:17 -0800
commit2a1a091c1ff898b1de4dcac2236b85f88aa9d51f (patch)
treed1164356644dd2b50ae5545601371b1a85733344 /drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
parentixgbe: Make ethtool register test use accessors (diff)
downloadlinux-dev-2a1a091c1ff898b1de4dcac2236b85f88aa9d51f.tar.xz
linux-dev-2a1a091c1ff898b1de4dcac2236b85f88aa9d51f.zip
ixgbe: Check register reads for adapter removal
Check all register reads for adapter removal by checking the status register after any register read that returns 0xFFFFFFFF. Since the status register will never return 0xFFFFFFFF unless the adapter is removed, such a value from a status register read confirms the removal. Signed-off-by: Mark Rustad <mark.d.rustad@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_common.h')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index 449291df24b4..b6faaacbe7a9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -124,6 +124,15 @@ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw);
s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
+#define IXGBE_FAILED_READ_REG 0xffffffffU
+
+static inline bool ixgbe_removed(void __iomem *addr)
+{
+ return unlikely(!addr);
+}
+
+void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg);
+
static inline void ixgbe_write_reg(struct ixgbe_hw *hw, u32 reg, u32 value)
{
writel(value, hw->hw_addr + reg);
@@ -147,7 +156,15 @@ static inline void ixgbe_write_reg64(struct ixgbe_hw *hw, u32 reg, u64 value)
static inline u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
{
- return readl(hw->hw_addr + reg);
+ u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
+ u32 value;
+
+ if (ixgbe_removed(reg_addr))
+ return IXGBE_FAILED_READ_REG;
+ value = readl(reg_addr + reg);
+ if (unlikely(value == IXGBE_FAILED_READ_REG))
+ ixgbe_check_remove(hw, reg);
+ return value;
}
#define IXGBE_READ_REG(a, reg) ixgbe_read_reg((a), (reg))