Commit 65344ba9 authored by David S. Miller's avatar David S. Miller

Merge branch 'amd-xgbe-updates'

Tom Lendacky says:

====================
amd-xgbe: AMD XGBE driver updates 2016-06-28

The following updates and fixes are included in this driver update series:

- Simplify mailbox interface code
- Fix SFP supported and advertising settings
- Fix PTP initialization register usage
- Insure there is timestamp skb present before using it
- Add a timeout to timestamp register updates
- Handle return code from software reset function
- Some fixes for handling 2.5Gbps rates
- Limit I2C error messages
- Fix non-DMA interrupt handling through tasklet usage
- Add NUMA affinity support for memory allocations
- Add NUMA affinity support for interrupts
- Prepare for more fine-grained cache coherency controls
- Simplify setting the DMA burst length programming
- Performance improvements

This patch series is based on net-next.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e3ef6983 6f595959
...@@ -123,38 +123,13 @@ ...@@ -123,38 +123,13 @@
#define DMA_ISR 0x3008 #define DMA_ISR 0x3008
#define DMA_AXIARCR 0x3010 #define DMA_AXIARCR 0x3010
#define DMA_AXIAWCR 0x3018 #define DMA_AXIAWCR 0x3018
#define DMA_AXIAWARCR 0x301c
#define DMA_DSR0 0x3020 #define DMA_DSR0 0x3020
#define DMA_DSR1 0x3024 #define DMA_DSR1 0x3024
#define DMA_TXEDMACR 0x3040
#define DMA_RXEDMACR 0x3044
/* DMA register entry bit positions and sizes */ /* DMA register entry bit positions and sizes */
#define DMA_AXIARCR_DRC_INDEX 0
#define DMA_AXIARCR_DRC_WIDTH 4
#define DMA_AXIARCR_DRD_INDEX 4
#define DMA_AXIARCR_DRD_WIDTH 2
#define DMA_AXIARCR_TEC_INDEX 8
#define DMA_AXIARCR_TEC_WIDTH 4
#define DMA_AXIARCR_TED_INDEX 12
#define DMA_AXIARCR_TED_WIDTH 2
#define DMA_AXIARCR_THC_INDEX 16
#define DMA_AXIARCR_THC_WIDTH 4
#define DMA_AXIARCR_THD_INDEX 20
#define DMA_AXIARCR_THD_WIDTH 2
#define DMA_AXIAWCR_DWC_INDEX 0
#define DMA_AXIAWCR_DWC_WIDTH 4
#define DMA_AXIAWCR_DWD_INDEX 4
#define DMA_AXIAWCR_DWD_WIDTH 2
#define DMA_AXIAWCR_RPC_INDEX 8
#define DMA_AXIAWCR_RPC_WIDTH 4
#define DMA_AXIAWCR_RPD_INDEX 12
#define DMA_AXIAWCR_RPD_WIDTH 2
#define DMA_AXIAWCR_RHC_INDEX 16
#define DMA_AXIAWCR_RHC_WIDTH 4
#define DMA_AXIAWCR_RHD_INDEX 20
#define DMA_AXIAWCR_RHD_WIDTH 2
#define DMA_AXIAWCR_TDC_INDEX 24
#define DMA_AXIAWCR_TDC_WIDTH 4
#define DMA_AXIAWCR_TDD_INDEX 28
#define DMA_AXIAWCR_TDD_WIDTH 2
#define DMA_ISR_MACIS_INDEX 17 #define DMA_ISR_MACIS_INDEX 17
#define DMA_ISR_MACIS_WIDTH 1 #define DMA_ISR_MACIS_WIDTH 1
#define DMA_ISR_MTLIS_INDEX 16 #define DMA_ISR_MTLIS_INDEX 16
...@@ -163,14 +138,31 @@ ...@@ -163,14 +138,31 @@
#define DMA_MR_INTM_WIDTH 2 #define DMA_MR_INTM_WIDTH 2
#define DMA_MR_SWR_INDEX 0 #define DMA_MR_SWR_INDEX 0
#define DMA_MR_SWR_WIDTH 1 #define DMA_MR_SWR_WIDTH 1
#define DMA_RXEDMACR_RDPS_INDEX 0
#define DMA_RXEDMACR_RDPS_WIDTH 3
#define DMA_SBMR_AAL_INDEX 12
#define DMA_SBMR_AAL_WIDTH 1
#define DMA_SBMR_EAME_INDEX 11 #define DMA_SBMR_EAME_INDEX 11
#define DMA_SBMR_EAME_WIDTH 1 #define DMA_SBMR_EAME_WIDTH 1
#define DMA_SBMR_BLEN_256_INDEX 7 #define DMA_SBMR_BLEN_INDEX 1
#define DMA_SBMR_BLEN_256_WIDTH 1 #define DMA_SBMR_BLEN_WIDTH 7
#define DMA_SBMR_RD_OSR_LMT_INDEX 16
#define DMA_SBMR_RD_OSR_LMT_WIDTH 6
#define DMA_SBMR_UNDEF_INDEX 0 #define DMA_SBMR_UNDEF_INDEX 0
#define DMA_SBMR_UNDEF_WIDTH 1 #define DMA_SBMR_UNDEF_WIDTH 1
#define DMA_SBMR_WR_OSR_LMT_INDEX 24
#define DMA_SBMR_WR_OSR_LMT_WIDTH 6
#define DMA_TXEDMACR_TDPS_INDEX 0
#define DMA_TXEDMACR_TDPS_WIDTH 3
/* DMA register values */ /* DMA register values */
#define DMA_SBMR_BLEN_256 256
#define DMA_SBMR_BLEN_128 128
#define DMA_SBMR_BLEN_64 64
#define DMA_SBMR_BLEN_32 32
#define DMA_SBMR_BLEN_16 16
#define DMA_SBMR_BLEN_8 8
#define DMA_SBMR_BLEN_4 4
#define DMA_DSR_RPS_WIDTH 4 #define DMA_DSR_RPS_WIDTH 4
#define DMA_DSR_TPS_WIDTH 4 #define DMA_DSR_TPS_WIDTH 4
#define DMA_DSR_Q_WIDTH (DMA_DSR_RPS_WIDTH + DMA_DSR_TPS_WIDTH) #define DMA_DSR_Q_WIDTH (DMA_DSR_RPS_WIDTH + DMA_DSR_TPS_WIDTH)
...@@ -959,6 +951,7 @@ ...@@ -959,6 +951,7 @@
#define XP_DRIVER_INT_RO 0x0064 #define XP_DRIVER_INT_RO 0x0064
#define XP_DRIVER_SCRATCH_0 0x0068 #define XP_DRIVER_SCRATCH_0 0x0068
#define XP_DRIVER_SCRATCH_1 0x006c #define XP_DRIVER_SCRATCH_1 0x006c
#define XP_INT_REISSUE_EN 0x0074
#define XP_INT_EN 0x0078 #define XP_INT_EN 0x0078
#define XP_I2C_MUTEX 0x0080 #define XP_I2C_MUTEX 0x0080
#define XP_MDIO_MUTEX 0x0084 #define XP_MDIO_MUTEX 0x0084
......
...@@ -176,8 +176,8 @@ static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata) ...@@ -176,8 +176,8 @@ static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata)
DBGPR("-->xgbe_free_ring_resources\n"); DBGPR("-->xgbe_free_ring_resources\n");
channel = pdata->channel; for (i = 0; i < pdata->channel_count; i++) {
for (i = 0; i < pdata->channel_count; i++, channel++) { channel = pdata->channel[i];
xgbe_free_ring(pdata, channel->tx_ring); xgbe_free_ring(pdata, channel->tx_ring);
xgbe_free_ring(pdata, channel->rx_ring); xgbe_free_ring(pdata, channel->rx_ring);
} }
...@@ -185,34 +185,60 @@ static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata) ...@@ -185,34 +185,60 @@ static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata)
DBGPR("<--xgbe_free_ring_resources\n"); DBGPR("<--xgbe_free_ring_resources\n");
} }
static void *xgbe_alloc_node(size_t size, int node)
{
void *mem;
mem = kzalloc_node(size, GFP_KERNEL, node);
if (!mem)
mem = kzalloc(size, GFP_KERNEL);
return mem;
}
static void *xgbe_dma_alloc_node(struct device *dev, size_t size,
dma_addr_t *dma, int node)
{
void *mem;
int cur_node = dev_to_node(dev);
set_dev_node(dev, node);
mem = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
set_dev_node(dev, cur_node);
if (!mem)
mem = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
return mem;
}
static int xgbe_init_ring(struct xgbe_prv_data *pdata, static int xgbe_init_ring(struct xgbe_prv_data *pdata,
struct xgbe_ring *ring, unsigned int rdesc_count) struct xgbe_ring *ring, unsigned int rdesc_count)
{ {
DBGPR("-->xgbe_init_ring\n"); size_t size;
if (!ring) if (!ring)
return 0; return 0;
/* Descriptors */ /* Descriptors */
size = rdesc_count * sizeof(struct xgbe_ring_desc);
ring->rdesc_count = rdesc_count; ring->rdesc_count = rdesc_count;
ring->rdesc = dma_alloc_coherent(pdata->dev, ring->rdesc = xgbe_dma_alloc_node(pdata->dev, size, &ring->rdesc_dma,
(sizeof(struct xgbe_ring_desc) * ring->node);
rdesc_count), &ring->rdesc_dma,
GFP_KERNEL);
if (!ring->rdesc) if (!ring->rdesc)
return -ENOMEM; return -ENOMEM;
/* Descriptor information */ /* Descriptor information */
ring->rdata = kcalloc(rdesc_count, sizeof(struct xgbe_ring_data), size = rdesc_count * sizeof(struct xgbe_ring_data);
GFP_KERNEL);
ring->rdata = xgbe_alloc_node(size, ring->node);
if (!ring->rdata) if (!ring->rdata)
return -ENOMEM; return -ENOMEM;
netif_dbg(pdata, drv, pdata->netdev, netif_dbg(pdata, drv, pdata->netdev,
"rdesc=%p, rdesc_dma=%pad, rdata=%p\n", "rdesc=%p, rdesc_dma=%pad, rdata=%p, node=%d\n",
ring->rdesc, &ring->rdesc_dma, ring->rdata); ring->rdesc, &ring->rdesc_dma, ring->rdata, ring->node);
DBGPR("<--xgbe_init_ring\n");
return 0; return 0;
} }
...@@ -223,10 +249,8 @@ static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata) ...@@ -223,10 +249,8 @@ static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata)
unsigned int i; unsigned int i;
int ret; int ret;
DBGPR("-->xgbe_alloc_ring_resources\n"); for (i = 0; i < pdata->channel_count; i++) {
channel = pdata->channel[i];
channel = pdata->channel;
for (i = 0; i < pdata->channel_count; i++, channel++) {
netif_dbg(pdata, drv, pdata->netdev, "%s - Tx ring:\n", netif_dbg(pdata, drv, pdata->netdev, "%s - Tx ring:\n",
channel->name); channel->name);
...@@ -250,8 +274,6 @@ static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata) ...@@ -250,8 +274,6 @@ static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata)
} }
} }
DBGPR("<--xgbe_alloc_ring_resources\n");
return 0; return 0;
err_ring: err_ring:
...@@ -261,21 +283,33 @@ static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata) ...@@ -261,21 +283,33 @@ static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata)
} }
static int xgbe_alloc_pages(struct xgbe_prv_data *pdata, static int xgbe_alloc_pages(struct xgbe_prv_data *pdata,
struct xgbe_page_alloc *pa, gfp_t gfp, int order) struct xgbe_page_alloc *pa, int alloc_order,
int node)
{ {
struct page *pages = NULL; struct page *pages = NULL;
dma_addr_t pages_dma; dma_addr_t pages_dma;
int ret; gfp_t gfp;
int order, ret;
again:
order = alloc_order;
/* Try to obtain pages, decreasing order if necessary */ /* Try to obtain pages, decreasing order if necessary */
gfp |= __GFP_COLD | __GFP_COMP | __GFP_NOWARN; gfp = GFP_ATOMIC | __GFP_COLD | __GFP_COMP | __GFP_NOWARN;
while (order >= 0) { while (order >= 0) {
pages = alloc_pages(gfp, order); pages = alloc_pages_node(node, gfp, order);
if (pages) if (pages)
break; break;
order--; order--;
} }
/* If we couldn't get local pages, try getting from anywhere */
if (!pages && (node != NUMA_NO_NODE)) {
node = NUMA_NO_NODE;
goto again;
}
if (!pages) if (!pages)
return -ENOMEM; return -ENOMEM;
...@@ -327,14 +361,14 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata, ...@@ -327,14 +361,14 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata,
int ret; int ret;
if (!ring->rx_hdr_pa.pages) { if (!ring->rx_hdr_pa.pages) {
ret = xgbe_alloc_pages(pdata, &ring->rx_hdr_pa, GFP_ATOMIC, 0); ret = xgbe_alloc_pages(pdata, &ring->rx_hdr_pa, 0, ring->node);
if (ret) if (ret)
return ret; return ret;
} }
if (!ring->rx_buf_pa.pages) { if (!ring->rx_buf_pa.pages) {
ret = xgbe_alloc_pages(pdata, &ring->rx_buf_pa, GFP_ATOMIC, ret = xgbe_alloc_pages(pdata, &ring->rx_buf_pa,
PAGE_ALLOC_COSTLY_ORDER); PAGE_ALLOC_COSTLY_ORDER, ring->node);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -362,8 +396,8 @@ static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata) ...@@ -362,8 +396,8 @@ static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata)
DBGPR("-->xgbe_wrapper_tx_descriptor_init\n"); DBGPR("-->xgbe_wrapper_tx_descriptor_init\n");
channel = pdata->channel; for (i = 0; i < pdata->channel_count; i++) {
for (i = 0; i < pdata->channel_count; i++, channel++) { channel = pdata->channel[i];
ring = channel->tx_ring; ring = channel->tx_ring;
if (!ring) if (!ring)
break; break;
...@@ -403,8 +437,8 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata) ...@@ -403,8 +437,8 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)
DBGPR("-->xgbe_wrapper_rx_descriptor_init\n"); DBGPR("-->xgbe_wrapper_rx_descriptor_init\n");
channel = pdata->channel; for (i = 0; i < pdata->channel_count; i++) {
for (i = 0; i < pdata->channel_count; i++, channel++) { channel = pdata->channel[i];
ring = channel->rx_ring; ring = channel->rx_ring;
if (!ring) if (!ring)
break; break;
......
This diff is collapsed.
This diff is collapsed.
...@@ -274,13 +274,16 @@ static void xgbe_i2c_clear_isr_interrupts(struct xgbe_prv_data *pdata, ...@@ -274,13 +274,16 @@ static void xgbe_i2c_clear_isr_interrupts(struct xgbe_prv_data *pdata,
XI2C_IOREAD(pdata, IC_CLR_STOP_DET); XI2C_IOREAD(pdata, IC_CLR_STOP_DET);
} }
static irqreturn_t xgbe_i2c_isr(int irq, void *data) static void xgbe_i2c_isr_task(unsigned long data)
{ {
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
struct xgbe_i2c_op_state *state = &pdata->i2c.op_state; struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
unsigned int isr; unsigned int isr;
isr = XI2C_IOREAD(pdata, IC_RAW_INTR_STAT); isr = XI2C_IOREAD(pdata, IC_RAW_INTR_STAT);
if (!isr)
goto reissue_check;
netif_dbg(pdata, intr, pdata->netdev, netif_dbg(pdata, intr, pdata->netdev,
"I2C interrupt received: status=%#010x\n", isr); "I2C interrupt received: status=%#010x\n", isr);
...@@ -308,6 +311,21 @@ static irqreturn_t xgbe_i2c_isr(int irq, void *data) ...@@ -308,6 +311,21 @@ static irqreturn_t xgbe_i2c_isr(int irq, void *data)
if (state->ret || XI2C_GET_BITS(isr, IC_RAW_INTR_STAT, STOP_DET)) if (state->ret || XI2C_GET_BITS(isr, IC_RAW_INTR_STAT, STOP_DET))
complete(&pdata->i2c_complete); complete(&pdata->i2c_complete);
reissue_check:
/* Reissue interrupt if status is not clear */
if (pdata->vdata->irq_reissue_support)
XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 2);
}
static irqreturn_t xgbe_i2c_isr(int irq, void *data)
{
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
if (pdata->isr_as_tasklet)
tasklet_schedule(&pdata->tasklet_i2c);
else
xgbe_i2c_isr_task((unsigned long)pdata);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -349,12 +367,11 @@ static void xgbe_i2c_set_target(struct xgbe_prv_data *pdata, unsigned int addr) ...@@ -349,12 +367,11 @@ static void xgbe_i2c_set_target(struct xgbe_prv_data *pdata, unsigned int addr)
XI2C_IOWRITE(pdata, IC_TAR, addr); XI2C_IOWRITE(pdata, IC_TAR, addr);
} }
static irqreturn_t xgbe_i2c_combined_isr(int irq, struct xgbe_prv_data *pdata) static irqreturn_t xgbe_i2c_combined_isr(struct xgbe_prv_data *pdata)
{ {
if (!XI2C_IOREAD(pdata, IC_RAW_INTR_STAT)) xgbe_i2c_isr_task((unsigned long)pdata);
return IRQ_HANDLED;
return xgbe_i2c_isr(irq, pdata); return IRQ_HANDLED;
} }
static int xgbe_i2c_xfer(struct xgbe_prv_data *pdata, struct xgbe_i2c_op *op) static int xgbe_i2c_xfer(struct xgbe_prv_data *pdata, struct xgbe_i2c_op *op)
...@@ -445,6 +462,9 @@ static int xgbe_i2c_start(struct xgbe_prv_data *pdata) ...@@ -445,6 +462,9 @@ static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
/* If we have a separate I2C irq, enable it */ /* If we have a separate I2C irq, enable it */
if (pdata->dev_irq != pdata->i2c_irq) { if (pdata->dev_irq != pdata->i2c_irq) {
tasklet_init(&pdata->tasklet_i2c, xgbe_i2c_isr_task,
(unsigned long)pdata);
ret = devm_request_irq(pdata->dev, pdata->i2c_irq, ret = devm_request_irq(pdata->dev, pdata->i2c_irq,
xgbe_i2c_isr, 0, pdata->i2c_name, xgbe_i2c_isr, 0, pdata->i2c_name,
pdata); pdata);
......
...@@ -140,14 +140,16 @@ static void xgbe_default_config(struct xgbe_prv_data *pdata) ...@@ -140,14 +140,16 @@ static void xgbe_default_config(struct xgbe_prv_data *pdata)
{ {
DBGPR("-->xgbe_default_config\n"); DBGPR("-->xgbe_default_config\n");
pdata->pblx8 = DMA_PBL_X8_ENABLE; pdata->blen = DMA_SBMR_BLEN_64;
pdata->pbl = DMA_PBL_128;
pdata->aal = 1;
pdata->rd_osr_limit = 8;
pdata->wr_osr_limit = 8;
pdata->tx_sf_mode = MTL_TSF_ENABLE; pdata->tx_sf_mode = MTL_TSF_ENABLE;
pdata->tx_threshold = MTL_TX_THRESHOLD_64; pdata->tx_threshold = MTL_TX_THRESHOLD_64;
pdata->tx_pbl = DMA_PBL_16;
pdata->tx_osp_mode = DMA_OSP_ENABLE; pdata->tx_osp_mode = DMA_OSP_ENABLE;
pdata->rx_sf_mode = MTL_RSF_DISABLE; pdata->rx_sf_mode = MTL_RSF_DISABLE;
pdata->rx_threshold = MTL_RX_THRESHOLD_64; pdata->rx_threshold = MTL_RX_THRESHOLD_64;
pdata->rx_pbl = DMA_PBL_16;
pdata->pause_autoneg = 1; pdata->pause_autoneg = 1;
pdata->tx_pause = 1; pdata->tx_pause = 1;
pdata->rx_pause = 1; pdata->rx_pause = 1;
...@@ -277,7 +279,11 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) ...@@ -277,7 +279,11 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
pdata->desc_ded_period = jiffies; pdata->desc_ded_period = jiffies;
/* Issue software reset to device */ /* Issue software reset to device */
pdata->hw_if.exit(pdata); ret = pdata->hw_if.exit(pdata);
if (ret) {
dev_err(dev, "software reset failed\n");
return ret;
}
/* Set default configuration data */ /* Set default configuration data */
xgbe_default_config(pdata); xgbe_default_config(pdata);
......
...@@ -665,6 +665,10 @@ static void xgbe_an37_isr(struct xgbe_prv_data *pdata) ...@@ -665,6 +665,10 @@ static void xgbe_an37_isr(struct xgbe_prv_data *pdata)
} else { } else {
/* Enable AN interrupts */ /* Enable AN interrupts */
xgbe_an37_enable_interrupts(pdata); xgbe_an37_enable_interrupts(pdata);
/* Reissue interrupt if status is not clear */
if (pdata->vdata->irq_reissue_support)
XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
} }
} }
...@@ -684,10 +688,14 @@ static void xgbe_an73_isr(struct xgbe_prv_data *pdata) ...@@ -684,10 +688,14 @@ static void xgbe_an73_isr(struct xgbe_prv_data *pdata)
} else { } else {
/* Enable AN interrupts */ /* Enable AN interrupts */
xgbe_an73_enable_interrupts(pdata); xgbe_an73_enable_interrupts(pdata);
/* Reissue interrupt if status is not clear */
if (pdata->vdata->irq_reissue_support)
XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
} }
} }
static irqreturn_t xgbe_an_isr(int irq, void *data) static void xgbe_an_isr_task(unsigned long data)
{ {
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
...@@ -705,13 +713,25 @@ static irqreturn_t xgbe_an_isr(int irq, void *data) ...@@ -705,13 +713,25 @@ static irqreturn_t xgbe_an_isr(int irq, void *data)
default: default:
break; break;
} }
}
static irqreturn_t xgbe_an_isr(int irq, void *data)
{
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
if (pdata->isr_as_tasklet)
tasklet_schedule(&pdata->tasklet_an);
else
xgbe_an_isr_task((unsigned long)pdata);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t xgbe_an_combined_isr(int irq, struct xgbe_prv_data *pdata) static irqreturn_t xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
{ {
return xgbe_an_isr(irq, pdata); xgbe_an_isr_task((unsigned long)pdata);
return IRQ_HANDLED;
} }
static void xgbe_an_irq_work(struct work_struct *work) static void xgbe_an_irq_work(struct work_struct *work)
...@@ -915,6 +935,10 @@ static void xgbe_an_state_machine(struct work_struct *work) ...@@ -915,6 +935,10 @@ static void xgbe_an_state_machine(struct work_struct *work)
break; break;
} }
/* Reissue interrupt if status is not clear */
if (pdata->vdata->irq_reissue_support)
XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
mutex_unlock(&pdata->an_mutex); mutex_unlock(&pdata->an_mutex);
} }
...@@ -1379,6 +1403,9 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) ...@@ -1379,6 +1403,9 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
/* If we have a separate AN irq, enable it */ /* If we have a separate AN irq, enable it */
if (pdata->dev_irq != pdata->an_irq) { if (pdata->dev_irq != pdata->an_irq) {
tasklet_init(&pdata->tasklet_an, xgbe_an_isr_task,
(unsigned long)pdata);
ret = devm_request_irq(pdata->dev, pdata->an_irq, ret = devm_request_irq(pdata->dev, pdata->an_irq,
xgbe_an_isr, 0, pdata->an_name, xgbe_an_isr, 0, pdata->an_name,
pdata); pdata);
......
...@@ -139,6 +139,7 @@ static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata) ...@@ -139,6 +139,7 @@ static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
return ret; return ret;
} }
pdata->isr_as_tasklet = 1;
pdata->irq_count = ret; pdata->irq_count = ret;
pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0); pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
...@@ -175,6 +176,7 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata) ...@@ -175,6 +176,7 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
return ret; return ret;
} }
pdata->isr_as_tasklet = pdata->pcidev->msi_enabled ? 1 : 0;
pdata->irq_count = 1; pdata->irq_count = 1;
pdata->channel_irq_count = 1; pdata->channel_irq_count = 1;
...@@ -325,9 +327,9 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -325,9 +327,9 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Set the DMA coherency values */ /* Set the DMA coherency values */
pdata->coherent = 1; pdata->coherent = 1;
pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; pdata->arcr = XGBE_DMA_PCI_ARCR;
pdata->arcache = XGBE_DMA_OS_ARCACHE; pdata->awcr = XGBE_DMA_PCI_AWCR;
pdata->awcache = XGBE_DMA_OS_AWCACHE; pdata->awarcr = XGBE_DMA_PCI_AWARCR;
/* Set the maximum channels and queues */ /* Set the maximum channels and queues */
reg = XP_IOREAD(pdata, XP_PROP_1); reg = XP_IOREAD(pdata, XP_PROP_1);
...@@ -445,6 +447,9 @@ static const struct xgbe_version_data xgbe_v2a = { ...@@ -445,6 +447,9 @@ static const struct xgbe_version_data xgbe_v2a = {
.tx_tstamp_workaround = 1, .tx_tstamp_workaround = 1,
.ecc_support = 1, .ecc_support = 1,
.i2c_support = 1, .i2c_support = 1,
.irq_reissue_support = 1,
.tx_desc_prefetch = 5,
.rx_desc_prefetch = 5,
}; };
static const struct xgbe_version_data xgbe_v2b = { static const struct xgbe_version_data xgbe_v2b = {
...@@ -456,6 +461,9 @@ static const struct xgbe_version_data xgbe_v2b = { ...@@ -456,6 +461,9 @@ static const struct xgbe_version_data xgbe_v2b = {
.tx_tstamp_workaround = 1, .tx_tstamp_workaround = 1,
.ecc_support = 1, .ecc_support = 1,
.i2c_support = 1, .i2c_support = 1,
.irq_reissue_support = 1,
.tx_desc_prefetch = 5,
.rx_desc_prefetch = 5,
}; };
static const struct pci_device_id xgbe_pci_table[] = { static const struct pci_device_id xgbe_pci_table[] = {
......
This diff is collapsed.
...@@ -448,13 +448,11 @@ static int xgbe_platform_probe(struct platform_device *pdev) ...@@ -448,13 +448,11 @@ static int xgbe_platform_probe(struct platform_device *pdev)
} }
pdata->coherent = (attr == DEV_DMA_COHERENT); pdata->coherent = (attr == DEV_DMA_COHERENT);
if (pdata->coherent) { if (pdata->coherent) {
pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; pdata->arcr = XGBE_DMA_OS_ARCR;
pdata->arcache = XGBE_DMA_OS_ARCACHE; pdata->awcr = XGBE_DMA_OS_AWCR;
pdata->awcache = XGBE_DMA_OS_AWCACHE;
} else { } else {
pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN; pdata->arcr = XGBE_DMA_SYS_ARCR;
pdata->arcache = XGBE_DMA_SYS_ARCACHE; pdata->awcr = XGBE_DMA_SYS_AWCR;
pdata->awcache = XGBE_DMA_SYS_AWCACHE;
} }
/* Set the maximum fifo amounts */ /* Set the maximum fifo amounts */
......
...@@ -267,7 +267,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) ...@@ -267,7 +267,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
ktime_to_ns(ktime_get_real())); ktime_to_ns(ktime_get_real()));
/* Disable all timestamping to start */ /* Disable all timestamping to start */
XGMAC_IOWRITE(pdata, MAC_TCR, 0); XGMAC_IOWRITE(pdata, MAC_TSCR, 0);
pdata->tstamp_config.tx_type = HWTSTAMP_TX_OFF; pdata->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
pdata->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; pdata->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
} }
......
...@@ -128,6 +128,7 @@ ...@@ -128,6 +128,7 @@
#include <linux/net_tstamp.h> #include <linux/net_tstamp.h>
#include <net/dcbnl.h> #include <net/dcbnl.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/cpumask.h>
#define XGBE_DRV_NAME "amd-xgbe" #define XGBE_DRV_NAME "amd-xgbe"
#define XGBE_DRV_VERSION "1.0.3" #define XGBE_DRV_VERSION "1.0.3"
...@@ -163,14 +164,17 @@ ...@@ -163,14 +164,17 @@
#define XGBE_DMA_STOP_TIMEOUT 1 #define XGBE_DMA_STOP_TIMEOUT 1
/* DMA cache settings - Outer sharable, write-back, write-allocate */ /* DMA cache settings - Outer sharable, write-back, write-allocate */
#define XGBE_DMA_OS_AXDOMAIN 0x2 #define XGBE_DMA_OS_ARCR 0x002b2b2b
#define XGBE_DMA_OS_ARCACHE 0xb #define XGBE_DMA_OS_AWCR 0x2f2f2f2f
#define XGBE_DMA_OS_AWCACHE 0xf
/* DMA cache settings - System, no caches used */ /* DMA cache settings - System, no caches used */
#define XGBE_DMA_SYS_AXDOMAIN 0x3 #define XGBE_DMA_SYS_ARCR 0x00303030
#define XGBE_DMA_SYS_ARCACHE 0x0 #define XGBE_DMA_SYS_AWCR 0x30303030
#define XGBE_DMA_SYS_AWCACHE 0x0
/* DMA cache settings - PCI device */
#define XGBE_DMA_PCI_ARCR 0x00000003
#define XGBE_DMA_PCI_AWCR 0x13131313
#define XGBE_DMA_PCI_AWARCR 0x00000313
/* DMA channel interrupt modes */ /* DMA channel interrupt modes */
#define XGBE_IRQ_MODE_EDGE 0 #define XGBE_IRQ_MODE_EDGE 0
...@@ -412,6 +416,7 @@ struct xgbe_ring { ...@@ -412,6 +416,7 @@ struct xgbe_ring {
/* Page allocation for RX buffers */ /* Page allocation for RX buffers */
struct xgbe_page_alloc rx_hdr_pa; struct xgbe_page_alloc rx_hdr_pa;
struct xgbe_page_alloc rx_buf_pa; struct xgbe_page_alloc rx_buf_pa;
int node;
/* Ring index values /* Ring index values
* cur - Tx: index of descriptor to be used for current transfer * cur - Tx: index of descriptor to be used for current transfer
...@@ -462,6 +467,9 @@ struct xgbe_channel { ...@@ -462,6 +467,9 @@ struct xgbe_channel {
struct xgbe_ring *tx_ring; struct xgbe_ring *tx_ring;
struct xgbe_ring *rx_ring; struct xgbe_ring *rx_ring;
int node;
cpumask_t affinity_mask;
} ____cacheline_aligned; } ____cacheline_aligned;
enum xgbe_state { enum xgbe_state {
...@@ -734,13 +742,6 @@ struct xgbe_hw_if { ...@@ -734,13 +742,6 @@ struct xgbe_hw_if {
/* For TX DMA Operate on Second Frame config */ /* For TX DMA Operate on Second Frame config */
int (*config_osp_mode)(struct xgbe_prv_data *); int (*config_osp_mode)(struct xgbe_prv_data *);
/* For RX and TX PBL config */
int (*config_rx_pbl_val)(struct xgbe_prv_data *);
int (*get_rx_pbl_val)(struct xgbe_prv_data *);
int (*config_tx_pbl_val)(struct xgbe_prv_data *);
int (*get_tx_pbl_val)(struct xgbe_prv_data *);
int (*config_pblx8)(struct xgbe_prv_data *);
/* For MMC statistics */ /* For MMC statistics */
void (*rx_mmc_int)(struct xgbe_prv_data *); void (*rx_mmc_int)(struct xgbe_prv_data *);
void (*tx_mmc_int)(struct xgbe_prv_data *); void (*tx_mmc_int)(struct xgbe_prv_data *);
...@@ -837,7 +838,7 @@ struct xgbe_phy_if { ...@@ -837,7 +838,7 @@ struct xgbe_phy_if {
bool (*phy_valid_speed)(struct xgbe_prv_data *, int); bool (*phy_valid_speed)(struct xgbe_prv_data *, int);
/* For single interrupt support */ /* For single interrupt support */
irqreturn_t (*an_isr)(int, struct xgbe_prv_data *); irqreturn_t (*an_isr)(struct xgbe_prv_data *);
/* PHY implementation specific services */ /* PHY implementation specific services */
struct xgbe_phy_impl_if phy_impl; struct xgbe_phy_impl_if phy_impl;
...@@ -855,7 +856,7 @@ struct xgbe_i2c_if { ...@@ -855,7 +856,7 @@ struct xgbe_i2c_if {
int (*i2c_xfer)(struct xgbe_prv_data *, struct xgbe_i2c_op *); int (*i2c_xfer)(struct xgbe_prv_data *, struct xgbe_i2c_op *);
/* For single interrupt support */ /* For single interrupt support */
irqreturn_t (*i2c_isr)(int, struct xgbe_prv_data *); irqreturn_t (*i2c_isr)(struct xgbe_prv_data *);
}; };
struct xgbe_desc_if { struct xgbe_desc_if {
...@@ -924,6 +925,9 @@ struct xgbe_version_data { ...@@ -924,6 +925,9 @@ struct xgbe_version_data {
unsigned int tx_tstamp_workaround; unsigned int tx_tstamp_workaround;
unsigned int ecc_support; unsigned int ecc_support;
unsigned int i2c_support; unsigned int i2c_support;
unsigned int irq_reissue_support;
unsigned int tx_desc_prefetch;
unsigned int rx_desc_prefetch;
}; };
struct xgbe_prv_data { struct xgbe_prv_data {
...@@ -1001,9 +1005,9 @@ struct xgbe_prv_data { ...@@ -1001,9 +1005,9 @@ struct xgbe_prv_data {
/* AXI DMA settings */ /* AXI DMA settings */
unsigned int coherent; unsigned int coherent;
unsigned int axdomain; unsigned int arcr;
unsigned int arcache; unsigned int awcr;
unsigned int awcache; unsigned int awarcr;
/* Service routine support */ /* Service routine support */
struct workqueue_struct *dev_workqueue; struct workqueue_struct *dev_workqueue;
...@@ -1011,7 +1015,7 @@ struct xgbe_prv_data { ...@@ -1011,7 +1015,7 @@ struct xgbe_prv_data {
struct timer_list service_timer; struct timer_list service_timer;
/* Rings for Tx/Rx on a DMA channel */ /* Rings for Tx/Rx on a DMA channel */
struct xgbe_channel *channel; struct xgbe_channel *channel[XGBE_MAX_DMA_CHANNELS];
unsigned int tx_max_channel_count; unsigned int tx_max_channel_count;
unsigned int rx_max_channel_count; unsigned int rx_max_channel_count;
unsigned int channel_count; unsigned int channel_count;
...@@ -1026,19 +1030,21 @@ struct xgbe_prv_data { ...@@ -1026,19 +1030,21 @@ struct xgbe_prv_data {
unsigned int rx_q_count; unsigned int rx_q_count;
/* Tx/Rx common settings */ /* Tx/Rx common settings */
unsigned int pblx8; unsigned int blen;
unsigned int pbl;
unsigned int aal;
unsigned int rd_osr_limit;
unsigned int wr_osr_limit;
/* Tx settings */ /* Tx settings */
unsigned int tx_sf_mode; unsigned int tx_sf_mode;
unsigned int tx_threshold; unsigned int tx_threshold;
unsigned int tx_pbl;
unsigned int tx_osp_mode; unsigned int tx_osp_mode;
unsigned int tx_max_fifo_size; unsigned int tx_max_fifo_size;
/* Rx settings */ /* Rx settings */
unsigned int rx_sf_mode; unsigned int rx_sf_mode;
unsigned int rx_threshold; unsigned int rx_threshold;
unsigned int rx_pbl;
unsigned int rx_max_fifo_size; unsigned int rx_max_fifo_size;
/* Tx coalescing settings */ /* Tx coalescing settings */
...@@ -1159,6 +1165,12 @@ struct xgbe_prv_data { ...@@ -1159,6 +1165,12 @@ struct xgbe_prv_data {
unsigned int lpm_ctrl; /* CTRL1 for resume */ unsigned int lpm_ctrl; /* CTRL1 for resume */
unsigned int isr_as_tasklet;
struct tasklet_struct tasklet_dev;
struct tasklet_struct tasklet_ecc;
struct tasklet_struct tasklet_i2c;
struct tasklet_struct tasklet_an;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *xgbe_debugfs; struct dentry *xgbe_debugfs;
......
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