mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-20 19:23:57 +08:00
Merge branch 'pci/virtualization' into next
* pci/virtualization: PCI: Add comments about ROM BAR updating PCI: Decouple IORESOURCE_ROM_ENABLE and PCI_ROM_ADDRESS_ENABLE PCI: Remove pci_resource_bar() and pci_iov_resource_bar() PCI: Don't update VF BARs while VF memory space is enabled PCI: Separate VF BAR updates from standard BAR updates PCI: Update BARs using property bits appropriate for type PCI: Ignore BAR updates on virtual functions PCI: Do any VF BAR updates before enabling the BARs PCI: Support INTx masking on ConnectX-4 with firmware x.14.1100+ PCI: Convert Mellanox broken INTx quirks to be for listed devices only PCI: Convert broken INTx masking quirks from HEADER to FINAL net/mlx4_core: Use device ID defines PCI: Add Mellanox device IDs
This commit is contained in:
commit
2583157141
@ -4012,49 +4012,51 @@ int mlx4_restart_one(struct pci_dev *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT }
|
||||
#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF }
|
||||
#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 }
|
||||
|
||||
static const struct pci_device_id mlx4_pci_table[] = {
|
||||
/* MT25408 "Hermon" SDR */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" DDR */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" QDR */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" DDR PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" QDR PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" EN 10GigE */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25408 "Hermon" EN 10GigE PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25458 ConnectX EN 10GBASE-T 10GigE */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT26468 ConnectX EN 10GigE PCIe gen2*/
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT26478 ConnectX2 40GigE PCIe gen2 */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT },
|
||||
/* MT25400 Family [ConnectX-2 Virtual Function] */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF },
|
||||
/* MT25408 "Hermon" */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_SDR), /* SDR */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR), /* DDR */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR), /* QDR */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2), /* DDR Gen2 */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2), /* QDR Gen2 */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN), /* EN 10GigE */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2), /* EN 10GigE Gen2 */
|
||||
/* MT25458 ConnectX EN 10GBASE-T */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN),
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2), /* Gen2 */
|
||||
/* MT26468 ConnectX EN 10GigE PCIe Gen2*/
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2),
|
||||
/* MT26438 ConnectX EN 40GigE PCIe Gen2 5GT/s */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2),
|
||||
/* MT26478 ConnectX2 40GigE PCIe Gen2 */
|
||||
MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX2),
|
||||
/* MT25400 Family [ConnectX-2] */
|
||||
MLX_VF(0x1002), /* Virtual Function */
|
||||
/* MT27500 Family [ConnectX-3] */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1003), 0 },
|
||||
/* MT27500 Family [ConnectX-3 Virtual Function] */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF },
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */
|
||||
{ PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */
|
||||
MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3),
|
||||
MLX_VF(0x1004), /* Virtual Function */
|
||||
MLX_GN(0x1005), /* MT27510 Family */
|
||||
MLX_GN(0x1006), /* MT27511 Family */
|
||||
MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO), /* MT27520 Family */
|
||||
MLX_GN(0x1008), /* MT27521 Family */
|
||||
MLX_GN(0x1009), /* MT27530 Family */
|
||||
MLX_GN(0x100a), /* MT27531 Family */
|
||||
MLX_GN(0x100b), /* MT27540 Family */
|
||||
MLX_GN(0x100c), /* MT27541 Family */
|
||||
MLX_GN(0x100d), /* MT27550 Family */
|
||||
MLX_GN(0x100e), /* MT27551 Family */
|
||||
MLX_GN(0x100f), /* MT27560 Family */
|
||||
MLX_GN(0x1010), /* MT27561 Family */
|
||||
|
||||
/*
|
||||
* See the mellanox_check_broken_intx_masking() quirk when
|
||||
* adding devices
|
||||
*/
|
||||
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
@ -306,13 +306,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
|
||||
return rc;
|
||||
}
|
||||
|
||||
pci_iov_set_numvfs(dev, nr_virtfn);
|
||||
iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
|
||||
pci_cfg_access_lock(dev);
|
||||
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
|
||||
msleep(100);
|
||||
pci_cfg_access_unlock(dev);
|
||||
|
||||
iov->initial_VFs = initial;
|
||||
if (nr_virtfn < initial)
|
||||
initial = nr_virtfn;
|
||||
@ -323,6 +316,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
|
||||
goto err_pcibios;
|
||||
}
|
||||
|
||||
pci_iov_set_numvfs(dev, nr_virtfn);
|
||||
iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
|
||||
pci_cfg_access_lock(dev);
|
||||
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
|
||||
msleep(100);
|
||||
pci_cfg_access_unlock(dev);
|
||||
|
||||
for (i = 0; i < initial; i++) {
|
||||
rc = pci_iov_add_virtfn(dev, i, 0);
|
||||
if (rc)
|
||||
@ -554,21 +554,61 @@ void pci_iov_release(struct pci_dev *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_iov_resource_bar - get position of the SR-IOV BAR
|
||||
* pci_iov_update_resource - update a VF BAR
|
||||
* @dev: the PCI device
|
||||
* @resno: the resource number
|
||||
*
|
||||
* Returns position of the BAR encapsulated in the SR-IOV capability.
|
||||
* Update a VF BAR in the SR-IOV capability of a PF.
|
||||
*/
|
||||
int pci_iov_resource_bar(struct pci_dev *dev, int resno)
|
||||
void pci_iov_update_resource(struct pci_dev *dev, int resno)
|
||||
{
|
||||
if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
|
||||
return 0;
|
||||
struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL;
|
||||
struct resource *res = dev->resource + resno;
|
||||
int vf_bar = resno - PCI_IOV_RESOURCES;
|
||||
struct pci_bus_region region;
|
||||
u16 cmd;
|
||||
u32 new;
|
||||
int reg;
|
||||
|
||||
BUG_ON(!dev->is_physfn);
|
||||
/*
|
||||
* The generic pci_restore_bars() path calls this for all devices,
|
||||
* including VFs and non-SR-IOV devices. If this is not a PF, we
|
||||
* have nothing to do.
|
||||
*/
|
||||
if (!iov)
|
||||
return;
|
||||
|
||||
return dev->sriov->pos + PCI_SRIOV_BAR +
|
||||
4 * (resno - PCI_IOV_RESOURCES);
|
||||
pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &cmd);
|
||||
if ((cmd & PCI_SRIOV_CTRL_VFE) && (cmd & PCI_SRIOV_CTRL_MSE)) {
|
||||
dev_WARN(&dev->dev, "can't update enabled VF BAR%d %pR\n",
|
||||
vf_bar, res);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore unimplemented BARs, unused resource slots for 64-bit
|
||||
* BARs, and non-movable resources, e.g., those described via
|
||||
* Enhanced Allocation.
|
||||
*/
|
||||
if (!res->flags)
|
||||
return;
|
||||
|
||||
if (res->flags & IORESOURCE_UNSET)
|
||||
return;
|
||||
|
||||
if (res->flags & IORESOURCE_PCI_FIXED)
|
||||
return;
|
||||
|
||||
pcibios_resource_to_bus(dev->bus, ®ion, res);
|
||||
new = region.start;
|
||||
new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
|
||||
|
||||
reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar;
|
||||
pci_write_config_dword(dev, reg, new);
|
||||
if (res->flags & IORESOURCE_MEM_64) {
|
||||
new = region.start >> 16 >> 16;
|
||||
pci_write_config_dword(dev, reg + 4, new);
|
||||
}
|
||||
}
|
||||
|
||||
resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev,
|
||||
|
@ -564,10 +564,6 @@ static void pci_restore_bars(struct pci_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
|
||||
if (dev->is_virtfn)
|
||||
return;
|
||||
|
||||
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
|
||||
pci_update_resource(dev, i);
|
||||
}
|
||||
@ -4831,36 +4827,6 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags)
|
||||
}
|
||||
EXPORT_SYMBOL(pci_select_bars);
|
||||
|
||||
/**
|
||||
* pci_resource_bar - get position of the BAR associated with a resource
|
||||
* @dev: the PCI device
|
||||
* @resno: the resource number
|
||||
* @type: the BAR type to be filled in
|
||||
*
|
||||
* Returns BAR position in config space, or 0 if the BAR is invalid.
|
||||
*/
|
||||
int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
|
||||
{
|
||||
int reg;
|
||||
|
||||
if (resno < PCI_ROM_RESOURCE) {
|
||||
*type = pci_bar_unknown;
|
||||
return PCI_BASE_ADDRESS_0 + 4 * resno;
|
||||
} else if (resno == PCI_ROM_RESOURCE) {
|
||||
*type = pci_bar_mem32;
|
||||
return dev->rom_base_reg;
|
||||
} else if (resno < PCI_BRIDGE_RESOURCES) {
|
||||
/* device specific resource */
|
||||
*type = pci_bar_unknown;
|
||||
reg = pci_iov_resource_bar(dev, resno);
|
||||
if (reg)
|
||||
return reg;
|
||||
}
|
||||
|
||||
dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some architectures require additional programming to enable VGA */
|
||||
static arch_set_vga_state_t arch_set_vga_state;
|
||||
|
||||
|
@ -242,7 +242,6 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
|
||||
int pci_setup_device(struct pci_dev *dev);
|
||||
int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
struct resource *res, unsigned int reg);
|
||||
int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type);
|
||||
void pci_configure_ari(struct pci_dev *dev);
|
||||
void __pci_bus_size_bridges(struct pci_bus *bus,
|
||||
struct list_head *realloc_head);
|
||||
@ -286,7 +285,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
int pci_iov_init(struct pci_dev *dev);
|
||||
void pci_iov_release(struct pci_dev *dev);
|
||||
int pci_iov_resource_bar(struct pci_dev *dev, int resno);
|
||||
void pci_iov_update_resource(struct pci_dev *dev, int resno);
|
||||
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
|
||||
void pci_restore_iov_state(struct pci_dev *dev);
|
||||
int pci_iov_bus_range(struct pci_bus *bus);
|
||||
@ -300,10 +299,6 @@ static inline void pci_iov_release(struct pci_dev *dev)
|
||||
|
||||
{
|
||||
}
|
||||
static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void pci_restore_iov_state(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
|
@ -227,7 +227,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK;
|
||||
}
|
||||
} else {
|
||||
res->flags |= (l & IORESOURCE_ROM_ENABLE);
|
||||
if (l & PCI_ROM_ADDRESS_ENABLE)
|
||||
res->flags |= IORESOURCE_ROM_ENABLE;
|
||||
l64 = l & PCI_ROM_ADDRESS_MASK;
|
||||
sz64 = sz & PCI_ROM_ADDRESS_MASK;
|
||||
mask64 = (u32)PCI_ROM_ADDRESS_MASK;
|
||||
|
@ -3137,8 +3137,9 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay);
|
||||
|
||||
/*
|
||||
* Some devices may pass our check in pci_intx_mask_supported if
|
||||
* Some devices may pass our check in pci_intx_mask_supported() if
|
||||
* PCI_COMMAND_INTX_DISABLE works though they actually do not properly
|
||||
* support this feature.
|
||||
*/
|
||||
@ -3146,53 +3147,139 @@ static void quirk_broken_intx_masking(struct pci_dev *dev)
|
||||
{
|
||||
dev->broken_intx_masking = 1;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, 0x0030,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x0030,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
|
||||
quirk_broken_intx_masking);
|
||||
|
||||
/*
|
||||
* Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10)
|
||||
* Subsystem: Realtek RTL8169/8110 Family PCI Gigabit Ethernet NIC
|
||||
*
|
||||
* RTL8110SC - Fails under PCI device assignment using DisINTx masking.
|
||||
*/
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, 0x8169,
|
||||
quirk_broken_intx_masking);
|
||||
|
||||
/*
|
||||
* Intel i40e (XL710/X710) 10/20/40GbE NICs all have broken INTx masking,
|
||||
* DisINTx can be set but the interrupt status bit is non-functional.
|
||||
*/
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1572,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1574,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1580,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1581,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1583,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1584,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1585,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1586,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1587,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1588,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1589,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d0,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d1,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d2,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1572,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1574,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1580,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1581,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1583,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1584,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1585,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1586,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1587,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1588,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1589,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2,
|
||||
quirk_broken_intx_masking);
|
||||
|
||||
static u16 mellanox_broken_intx_devs[] = {
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_SDR,
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_DDR,
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_QDR,
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2,
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2,
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_EN,
|
||||
PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX_EN,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX2,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX3,
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO,
|
||||
};
|
||||
|
||||
#define CONNECTX_4_CURR_MAX_MINOR 99
|
||||
#define CONNECTX_4_INTX_SUPPORT_MINOR 14
|
||||
|
||||
/*
|
||||
* Check ConnectX-4/LX FW version to see if it supports legacy interrupts.
|
||||
* If so, don't mark it as broken.
|
||||
* FW minor > 99 means older FW version format and no INTx masking support.
|
||||
* FW minor < 14 means new FW version format and no INTx masking support.
|
||||
*/
|
||||
static void mellanox_check_broken_intx_masking(struct pci_dev *pdev)
|
||||
{
|
||||
__be32 __iomem *fw_ver;
|
||||
u16 fw_major;
|
||||
u16 fw_minor;
|
||||
u16 fw_subminor;
|
||||
u32 fw_maj_min;
|
||||
u32 fw_sub_min;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mellanox_broken_intx_devs); i++) {
|
||||
if (pdev->device == mellanox_broken_intx_devs[i]) {
|
||||
pdev->broken_intx_masking = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Getting here means Connect-IB cards and up. Connect-IB has no INTx
|
||||
* support so shouldn't be checked further
|
||||
*/
|
||||
if (pdev->device == PCI_DEVICE_ID_MELLANOX_CONNECTIB)
|
||||
return;
|
||||
|
||||
if (pdev->device != PCI_DEVICE_ID_MELLANOX_CONNECTX4 &&
|
||||
pdev->device != PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX)
|
||||
return;
|
||||
|
||||
/* For ConnectX-4 and ConnectX-4LX, need to check FW support */
|
||||
if (pci_enable_device_mem(pdev)) {
|
||||
dev_warn(&pdev->dev, "Can't enable device memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fw_ver = ioremap(pci_resource_start(pdev, 0), 4);
|
||||
if (!fw_ver) {
|
||||
dev_warn(&pdev->dev, "Can't map ConnectX-4 initialization segment\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Reading from resource space should be 32b aligned */
|
||||
fw_maj_min = ioread32be(fw_ver);
|
||||
fw_sub_min = ioread32be(fw_ver + 1);
|
||||
fw_major = fw_maj_min & 0xffff;
|
||||
fw_minor = fw_maj_min >> 16;
|
||||
fw_subminor = fw_sub_min & 0xffff;
|
||||
if (fw_minor > CONNECTX_4_CURR_MAX_MINOR ||
|
||||
fw_minor < CONNECTX_4_INTX_SUPPORT_MINOR) {
|
||||
dev_warn(&pdev->dev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n",
|
||||
fw_major, fw_minor, fw_subminor, pdev->device ==
|
||||
PCI_DEVICE_ID_MELLANOX_CONNECTX4 ? 12 : 14);
|
||||
pdev->broken_intx_masking = 1;
|
||||
}
|
||||
|
||||
iounmap(fw_ver);
|
||||
|
||||
out:
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID,
|
||||
mellanox_check_broken_intx_masking);
|
||||
|
||||
static void quirk_no_bus_reset(struct pci_dev *dev)
|
||||
{
|
||||
|
@ -35,6 +35,11 @@ int pci_enable_rom(struct pci_dev *pdev)
|
||||
if (res->flags & IORESOURCE_ROM_SHADOW)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ideally pci_update_resource() would update the ROM BAR address,
|
||||
* and we would only set the enable bit here. But apparently some
|
||||
* devices have buggy ROM BARs that read as zero when disabled.
|
||||
*/
|
||||
pcibios_resource_to_bus(pdev->bus, ®ion, res);
|
||||
pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
|
||||
rom_addr &= ~PCI_ROM_ADDRESS_MASK;
|
||||
|
@ -25,21 +25,18 @@
|
||||
#include <linux/slab.h>
|
||||
#include "pci.h"
|
||||
|
||||
|
||||
void pci_update_resource(struct pci_dev *dev, int resno)
|
||||
static void pci_std_update_resource(struct pci_dev *dev, int resno)
|
||||
{
|
||||
struct pci_bus_region region;
|
||||
bool disable;
|
||||
u16 cmd;
|
||||
u32 new, check, mask;
|
||||
int reg;
|
||||
enum pci_bar_type type;
|
||||
struct resource *res = dev->resource + resno;
|
||||
|
||||
if (dev->is_virtfn) {
|
||||
dev_warn(&dev->dev, "can't update VF BAR%d\n", resno);
|
||||
/* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
|
||||
if (dev->is_virtfn)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore resources for unimplemented BARs and unused resource slots
|
||||
@ -60,21 +57,34 @@ void pci_update_resource(struct pci_dev *dev, int resno)
|
||||
return;
|
||||
|
||||
pcibios_resource_to_bus(dev->bus, ®ion, res);
|
||||
new = region.start;
|
||||
|
||||
new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
|
||||
else
|
||||
new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
|
||||
} else if (resno == PCI_ROM_RESOURCE) {
|
||||
mask = (u32)PCI_ROM_ADDRESS_MASK;
|
||||
} else {
|
||||
mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
|
||||
new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
|
||||
}
|
||||
|
||||
reg = pci_resource_bar(dev, resno, &type);
|
||||
if (!reg)
|
||||
return;
|
||||
if (type != pci_bar_unknown) {
|
||||
if (resno < PCI_ROM_RESOURCE) {
|
||||
reg = PCI_BASE_ADDRESS_0 + 4 * resno;
|
||||
} else if (resno == PCI_ROM_RESOURCE) {
|
||||
|
||||
/*
|
||||
* Apparently some Matrox devices have ROM BARs that read
|
||||
* as zero when disabled, so don't update ROM BARs unless
|
||||
* they're enabled. See https://lkml.org/lkml/2005/8/30/138.
|
||||
*/
|
||||
if (!(res->flags & IORESOURCE_ROM_ENABLE))
|
||||
return;
|
||||
|
||||
reg = dev->rom_base_reg;
|
||||
new |= PCI_ROM_ADDRESS_ENABLE;
|
||||
}
|
||||
} else
|
||||
return;
|
||||
|
||||
/*
|
||||
* We can't update a 64-bit BAR atomically, so when possible,
|
||||
@ -110,6 +120,16 @@ void pci_update_resource(struct pci_dev *dev, int resno)
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
}
|
||||
|
||||
void pci_update_resource(struct pci_dev *dev, int resno)
|
||||
{
|
||||
if (resno <= PCI_ROM_RESOURCE)
|
||||
pci_std_update_resource(dev, resno);
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
|
||||
pci_iov_update_resource(dev, resno);
|
||||
#endif
|
||||
}
|
||||
|
||||
int pci_claim_resource(struct pci_dev *dev, int resource)
|
||||
{
|
||||
struct resource *res = &dev->resource[resource];
|
||||
|
@ -2256,12 +2256,29 @@
|
||||
#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0
|
||||
|
||||
#define PCI_VENDOR_ID_MELLANOX 0x15b3
|
||||
#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX3 0x1003
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO 0x1007
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTIB 0x1011
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX4 0x1013
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX 0x1015
|
||||
#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
|
||||
#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46
|
||||
#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
|
||||
#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
|
||||
#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
|
||||
#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
|
||||
#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
|
||||
#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
|
||||
#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
|
||||
#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_SDR 0x6340
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_DDR 0x634a
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_QDR 0x6354
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_EN 0x6368
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN 0x6372
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2 0x6732
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2 0x673c
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2 0x6746
|
||||
#define PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2 0x6750
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2 0x675a
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2 0x6764
|
||||
#define PCI_DEVICE_ID_MELLANOX_CONNECTX2 0x676e
|
||||
|
||||
#define PCI_VENDOR_ID_DFI 0x15bd
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user