summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/amd/xgbe
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/amd/xgbe')
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-common.h2
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c8
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c10
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-pci.c143
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h10
5 files changed, 69 insertions, 104 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 5b7ba25e0065..8a280e7d66bd 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -891,6 +891,8 @@
#define PCS_V1_WINDOW_SELECT 0x03fc
#define PCS_V2_WINDOW_DEF 0x9060
#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 */
#define PCS_V2_WINDOW_DEF_OFFSET_INDEX 6
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index aaf0350076a9..a7d16db5c4b2 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -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);
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);
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,
offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
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);
spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
}
@@ -3407,8 +3407,10 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
/* Flush Tx queues */
ret = xgbe_flush_tx_queues(pdata);
- if (ret)
+ if (ret) {
+ netdev_err(pdata->netdev, "error flushing TX queues\n");
return ret;
+ }
/*
* Initialize DMA related features
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 9943629fcbf9..3aa457c8ca21 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1070,7 +1070,9 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
DBGPR("-->xgbe_start\n");
- hw_if->init(pdata);
+ ret = hw_if->init(pdata);
+ if (ret)
+ return ret;
xgbe_napi_enable(pdata, 1);
@@ -1759,8 +1761,8 @@ static void xgbe_tx_timeout(struct net_device *netdev)
schedule_work(&pdata->restart_work);
}
-static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev,
- struct rtnl_link_stats64 *s)
+static void xgbe_get_stats64(struct net_device *netdev,
+ struct rtnl_link_stats64 *s)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_mmc_stats *pstats = &pdata->mmc_stats;
@@ -1786,8 +1788,6 @@ static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev,
s->tx_dropped = netdev->stats.tx_dropped;
DBGPR("<--%s\n", __func__);
-
- return s;
}
static int xgbe_vlan_rx_add_vid(struct net_device *netdev, __be16 proto,
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
index e76b7f65b805..38392a520725 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
@@ -122,104 +122,40 @@
#include "xgbe.h"
#include "xgbe-common.h"
-static int xgbe_config_msi(struct xgbe_prv_data *pdata)
+static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
{
- unsigned int msi_count;
+ unsigned int vector_count;
unsigned int i, j;
int ret;
- msi_count = XGBE_MSIX_BASE_COUNT;
- msi_count += max(pdata->rx_ring_count,
- pdata->tx_ring_count);
- msi_count = roundup_pow_of_two(msi_count);
+ vector_count = XGBE_MSI_BASE_COUNT;
+ vector_count += max(pdata->rx_ring_count,
+ pdata->tx_ring_count);
- ret = pci_enable_msi_exact(pdata->pcidev, msi_count);
+ ret = pci_alloc_irq_vectors(pdata->pcidev, XGBE_MSI_MIN_COUNT,
+ vector_count, PCI_IRQ_MSI | PCI_IRQ_MSIX);
if (ret < 0) {
- dev_info(pdata->dev, "MSI request for %u interrupts failed\n",
- msi_count);
-
- ret = pci_enable_msi(pdata->pcidev);
- if (ret < 0) {
- dev_info(pdata->dev, "MSI enablement failed\n");
- return ret;
- }
-
- msi_count = 1;
- }
-
- pdata->irq_count = msi_count;
-
- pdata->dev_irq = pdata->pcidev->irq;
-
- if (msi_count > 1) {
- pdata->ecc_irq = pdata->pcidev->irq + 1;
- pdata->i2c_irq = pdata->pcidev->irq + 2;
- pdata->an_irq = pdata->pcidev->irq + 3;
-
- for (i = XGBE_MSIX_BASE_COUNT, j = 0;
- (i < msi_count) && (j < XGBE_MAX_DMA_CHANNELS);
- i++, j++)
- pdata->channel_irq[j] = pdata->pcidev->irq + i;
- pdata->channel_irq_count = j;
-
- pdata->per_channel_irq = 1;
- pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL;
- } else {
- pdata->ecc_irq = pdata->pcidev->irq;
- pdata->i2c_irq = pdata->pcidev->irq;
- pdata->an_irq = pdata->pcidev->irq;
- }
-
- if (netif_msg_probe(pdata))
- dev_dbg(pdata->dev, "MSI interrupts enabled\n");
-
- return 0;
-}
-
-static int xgbe_config_msix(struct xgbe_prv_data *pdata)
-{
- unsigned int msix_count;
- unsigned int i, j;
- int ret;
-
- msix_count = XGBE_MSIX_BASE_COUNT;
- msix_count += max(pdata->rx_ring_count,
- pdata->tx_ring_count);
-
- pdata->msix_entries = devm_kcalloc(pdata->dev, msix_count,
- sizeof(struct msix_entry),
- GFP_KERNEL);
- if (!pdata->msix_entries)
- return -ENOMEM;
-
- for (i = 0; i < msix_count; i++)
- pdata->msix_entries[i].entry = i;
-
- ret = pci_enable_msix_range(pdata->pcidev, pdata->msix_entries,
- XGBE_MSIX_MIN_COUNT, msix_count);
- if (ret < 0) {
- dev_info(pdata->dev, "MSI-X enablement failed\n");
- devm_kfree(pdata->dev, pdata->msix_entries);
- pdata->msix_entries = NULL;
+ dev_info(pdata->dev, "multi MSI/MSI-X enablement failed\n");
return ret;
}
pdata->irq_count = ret;
- pdata->dev_irq = pdata->msix_entries[0].vector;
- pdata->ecc_irq = pdata->msix_entries[1].vector;
- pdata->i2c_irq = pdata->msix_entries[2].vector;
- pdata->an_irq = pdata->msix_entries[3].vector;
+ pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
+ pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 1);
+ pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 2);
+ pdata->an_irq = pci_irq_vector(pdata->pcidev, 3);
- for (i = XGBE_MSIX_BASE_COUNT, j = 0; i < ret; i++, j++)
- pdata->channel_irq[j] = pdata->msix_entries[i].vector;
+ for (i = XGBE_MSI_BASE_COUNT, j = 0; i < ret; i++, j++)
+ pdata->channel_irq[j] = pci_irq_vector(pdata->pcidev, i);
pdata->channel_irq_count = j;
pdata->per_channel_irq = 1;
pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL;
if (netif_msg_probe(pdata))
- dev_dbg(pdata->dev, "MSI-X interrupts enabled\n");
+ dev_dbg(pdata->dev, "multi %s interrupts enabled\n",
+ pdata->pcidev->msix_enabled ? "MSI-X" : "MSI");
return 0;
}
@@ -228,21 +164,28 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
{
int ret;
- ret = xgbe_config_msix(pdata);
+ ret = xgbe_config_multi_msi(pdata);
if (!ret)
goto out;
- ret = xgbe_config_msi(pdata);
- if (!ret)
- goto out;
+ ret = pci_alloc_irq_vectors(pdata->pcidev, 1, 1,
+ PCI_IRQ_LEGACY | PCI_IRQ_MSI);
+ if (ret < 0) {
+ dev_info(pdata->dev, "single IRQ enablement failed\n");
+ return ret;
+ }
pdata->irq_count = 1;
- pdata->irq_shared = 1;
+ pdata->channel_irq_count = 1;
+
+ pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
+ pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 0);
+ pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 0);
+ pdata->an_irq = pci_irq_vector(pdata->pcidev, 0);
- pdata->dev_irq = pdata->pcidev->irq;
- pdata->ecc_irq = pdata->pcidev->irq;
- pdata->i2c_irq = pdata->pcidev->irq;
- pdata->an_irq = pdata->pcidev->irq;
+ if (netif_msg_probe(pdata))
+ dev_dbg(pdata->dev, "single %s interrupt enabled\n",
+ pdata->pcidev->msi_enabled ? "MSI" : "legacy");
out:
if (netif_msg_probe(pdata)) {
@@ -265,6 +208,7 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct xgbe_prv_data *pdata;
struct device *dev = &pdev->dev;
void __iomem * const *iomap_table;
+ struct pci_dev *rdev;
unsigned int ma_lo, ma_hi;
unsigned int reg;
int bar_mask;
@@ -326,8 +270,20 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (netif_msg_probe(pdata))
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 */
- 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 <<= 6;
pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
@@ -412,12 +368,15 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Configure the netdev resource */
ret = xgbe_config_netdev(pdata);
if (ret)
- goto err_pci_enable;
+ goto err_irq_vectors;
netdev_notice(pdata->netdev, "net device enabled\n");
return 0;
+err_irq_vectors:
+ pci_free_irq_vectors(pdata->pcidev);
+
err_pci_enable:
xgbe_free_pdata(pdata);
@@ -433,6 +392,8 @@ static void xgbe_pci_remove(struct pci_dev *pdev)
xgbe_deconfig_netdev(pdata);
+ pci_free_irq_vectors(pdata->pcidev);
+
xgbe_free_pdata(pdata);
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index f52a9bd05bac..f9a24639f574 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -211,9 +211,9 @@
#define XGBE_MAC_PROP_OFFSET 0x1d000
#define XGBE_I2C_CTRL_OFFSET 0x1e000
-/* PCI MSIx support */
-#define XGBE_MSIX_BASE_COUNT 4
-#define XGBE_MSIX_MIN_COUNT (XGBE_MSIX_BASE_COUNT + 1)
+/* PCI MSI/MSIx support */
+#define XGBE_MSI_BASE_COUNT 4
+#define XGBE_MSI_MIN_COUNT (XGBE_MSI_BASE_COUNT + 1)
/* PCI clock frequencies */
#define XGBE_V2_DMA_CLOCK_FREQ 500000000 /* 500 MHz */
@@ -955,6 +955,8 @@ struct xgbe_prv_data {
/* XPCS indirect addressing 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_size;
unsigned int xpcs_window_mask;
@@ -980,14 +982,12 @@ struct xgbe_prv_data {
unsigned int desc_ded_count;
unsigned int desc_sec_count;
- struct msix_entry *msix_entries;
int dev_irq;
int ecc_irq;
int i2c_irq;
int channel_irq[XGBE_MAX_DMA_CHANNELS];
unsigned int per_channel_irq;
- unsigned int irq_shared;
unsigned int irq_count;
unsigned int channel_irq_count;
unsigned int channel_irq_mode;
OpenPOWER on IntegriCloud