diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h index 2e27bd90e31cc6abc3d9896246d0347d4de51cc6..3da3a9904d5627dff8f3ff1f37141ee04de9e789 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k.h @@ -27,7 +27,14 @@ #include #include -#include "fm10k_type.h" +#include "fm10k_common.h" + +struct fm10k_intfc { + struct pci_dev *pdev; + + struct fm10k_hw hw; + u32 __iomem *uc_addr; +}; /* main */ extern char fm10k_driver_name[]; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_common.h b/drivers/net/ethernet/intel/fm10k/fm10k_common.h new file mode 100644 index 0000000000000000000000000000000000000000..2b214a6a4adb8190d8d4b1b418ecf77e7a53b39c --- /dev/null +++ b/drivers/net/ethernet/intel/fm10k/fm10k_common.h @@ -0,0 +1,44 @@ +/* Intel Ethernet Switch Host Interface Driver + * Copyright(c) 2013 - 2014 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * e1000-devel Mailing List + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + */ + +#ifndef _FM10K_COMMON_H_ +#define _FM10K_COMMON_H_ + +#include "fm10k_type.h" + +#define FM10K_REMOVED(hw_addr) unlikely(!(hw_addr)) + +/* PCI configuration read */ +u16 fm10k_read_pci_cfg_word(struct fm10k_hw *hw, u32 reg); + +/* read operations, indexed using DWORDS */ +u32 fm10k_read_reg(struct fm10k_hw *hw, int reg); + +/* write operations, indexed using DWORDS */ +#define fm10k_write_reg(hw, reg, val) \ +do { \ + u32 __iomem *hw_addr = ACCESS_ONCE((hw)->hw_addr); \ + if (!FM10K_REMOVED(hw_addr)) \ + writel((val), &hw_addr[(reg)]); \ +} while (0) + +/* read ctrl register which has no clear on read fields as PCIe flush */ +#define fm10k_write_flush(hw) fm10k_read_reg((hw), FM10K_CTRL) +#endif /* _FM10K_COMMON_H_ */ diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index 12089cedbe56704b762605c8b8dc4920266221e5..6d5e33cde6a7d9ac25464940d9ae01a2fde9f4ef 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -38,6 +38,36 @@ static const struct pci_device_id fm10k_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, fm10k_pci_tbl); +u16 fm10k_read_pci_cfg_word(struct fm10k_hw *hw, u32 reg) +{ + struct fm10k_intfc *interface = hw->back; + u16 value = 0; + + if (FM10K_REMOVED(hw->hw_addr)) + return ~value; + + pci_read_config_word(interface->pdev, reg, &value); + if (value == 0xFFFF) + fm10k_write_flush(hw); + + return value; +} + +u32 fm10k_read_reg(struct fm10k_hw *hw, int reg) +{ + u32 __iomem *hw_addr = ACCESS_ONCE(hw->hw_addr); + u32 value = 0; + + if (FM10K_REMOVED(hw_addr)) + return ~value; + + value = readl(&hw_addr[reg]); + if (!(~value) && (!reg || !(~readl(hw_addr)))) + hw->hw_addr = NULL; + + return value; +} + /** * fm10k_probe - Device Initialization Routine * @pdev: PCI device information struct