Commit 4eccbfc3 authored by Lendacky, Thomas's avatar Lendacky, Thomas Committed by David S. Miller

amd-xgbe: Add a hardware quirk for register definitions

A newer version of the hardware is using the same PCI ids for the network
device but has altered register definitions for determining the window
settings for the indirect PCS access.  Add support to check for this
hardware and if found use the new register values.
Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b6677449
...@@ -891,6 +891,8 @@ ...@@ -891,6 +891,8 @@
#define PCS_V1_WINDOW_SELECT 0x03fc #define PCS_V1_WINDOW_SELECT 0x03fc
#define PCS_V2_WINDOW_DEF 0x9060 #define PCS_V2_WINDOW_DEF 0x9060
#define PCS_V2_WINDOW_SELECT 0x9064 #define PCS_V2_WINDOW_SELECT 0x9064
#define PCS_V2_RV_WINDOW_DEF 0x1060
#define PCS_V2_RV_WINDOW_SELECT 0x1064
/* PCS register entry bit positions and sizes */ /* PCS register entry bit positions and sizes */
#define PCS_V2_WINDOW_DEF_OFFSET_INDEX 6 #define PCS_V2_WINDOW_DEF_OFFSET_INDEX 6
......
...@@ -1151,7 +1151,7 @@ static int xgbe_read_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad, ...@@ -1151,7 +1151,7 @@ static int xgbe_read_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad,
offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask); offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
spin_lock_irqsave(&pdata->xpcs_lock, flags); spin_lock_irqsave(&pdata->xpcs_lock, flags);
XPCS32_IOWRITE(pdata, PCS_V2_WINDOW_SELECT, index); XPCS32_IOWRITE(pdata, pdata->xpcs_window_sel_reg, index);
mmd_data = XPCS16_IOREAD(pdata, offset); mmd_data = XPCS16_IOREAD(pdata, offset);
spin_unlock_irqrestore(&pdata->xpcs_lock, flags); spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
...@@ -1183,7 +1183,7 @@ static void xgbe_write_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad, ...@@ -1183,7 +1183,7 @@ static void xgbe_write_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad,
offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask); offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
spin_lock_irqsave(&pdata->xpcs_lock, flags); spin_lock_irqsave(&pdata->xpcs_lock, flags);
XPCS32_IOWRITE(pdata, PCS_V2_WINDOW_SELECT, index); XPCS32_IOWRITE(pdata, pdata->xpcs_window_sel_reg, index);
XPCS16_IOWRITE(pdata, offset, mmd_data); XPCS16_IOWRITE(pdata, offset, mmd_data);
spin_unlock_irqrestore(&pdata->xpcs_lock, flags); spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
} }
......
...@@ -265,6 +265,7 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -265,6 +265,7 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct xgbe_prv_data *pdata; struct xgbe_prv_data *pdata;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
void __iomem * const *iomap_table; void __iomem * const *iomap_table;
struct pci_dev *rdev;
unsigned int ma_lo, ma_hi; unsigned int ma_lo, ma_hi;
unsigned int reg; unsigned int reg;
int bar_mask; int bar_mask;
...@@ -326,8 +327,20 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -326,8 +327,20 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (netif_msg_probe(pdata)) if (netif_msg_probe(pdata))
dev_dbg(dev, "xpcs_regs = %p\n", pdata->xpcs_regs); dev_dbg(dev, "xpcs_regs = %p\n", pdata->xpcs_regs);
/* Set the PCS indirect addressing definition registers */
rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
if (rdev &&
(rdev->vendor == PCI_VENDOR_ID_AMD) && (rdev->device == 0x15d0)) {
pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
} else {
pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
}
pci_dev_put(rdev);
/* Configure the PCS indirect addressing support */ /* Configure the PCS indirect addressing support */
reg = XPCS32_IOREAD(pdata, PCS_V2_WINDOW_DEF); reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET); pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
pdata->xpcs_window <<= 6; pdata->xpcs_window <<= 6;
pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE); pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
......
...@@ -955,6 +955,8 @@ struct xgbe_prv_data { ...@@ -955,6 +955,8 @@ struct xgbe_prv_data {
/* XPCS indirect addressing lock */ /* XPCS indirect addressing lock */
spinlock_t xpcs_lock; spinlock_t xpcs_lock;
unsigned int xpcs_window_def_reg;
unsigned int xpcs_window_sel_reg;
unsigned int xpcs_window; unsigned int xpcs_window;
unsigned int xpcs_window_size; unsigned int xpcs_window_size;
unsigned int xpcs_window_mask; unsigned int xpcs_window_mask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment