diff options
author | David S. Miller <davem@davemloft.net> | 2017-10-11 16:01:57 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-11 16:01:57 -0700 |
commit | 5ef9d78e559553a4acc4bcbc3720fde069af5fba (patch) | |
tree | 29553181be9be0d3a225ac4a5d7bbd63b6393637 | |
parent | c7c64bca62f35351cf033a1dcea05cba522200a2 (diff) | |
parent | 740d6f188fb71ae13e3e9f7208b6b3094517509d (diff) | |
download | linux-stable-5ef9d78e559553a4acc4bcbc3720fde069af5fba.tar.gz linux-stable-5ef9d78e559553a4acc4bcbc3720fde069af5fba.tar.bz2 linux-stable-5ef9d78e559553a4acc4bcbc3720fde069af5fba.zip |
Merge branch 'qcom-emac-various-minor-fixes'
Timur Tabi says:
====================
net: qcom/emac: various minor fixes
A set of patches for 4.15 that clean up some code, apply minors fixes,
and so on. Some of the code also prepares the driver for a future
version of the EMAC controller.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qualcomm/emac/emac-mac.c | 55 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/emac/emac-sgmii.c | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/qualcomm/emac/emac.c | 25 |
3 files changed, 41 insertions, 54 deletions
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-mac.c b/drivers/net/ethernet/qualcomm/emac/emac-mac.c index 3ed9033e56db..0f5ece5d9507 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c @@ -309,22 +309,12 @@ void emac_mac_mode_config(struct emac_adapter *adpt) /* Config descriptor rings */ static void emac_mac_dma_rings_config(struct emac_adapter *adpt) { - static const unsigned short tpd_q_offset[] = { - EMAC_DESC_CTRL_8, EMAC_H1TPD_BASE_ADDR_LO, - EMAC_H2TPD_BASE_ADDR_LO, EMAC_H3TPD_BASE_ADDR_LO}; - static const unsigned short rfd_q_offset[] = { - EMAC_DESC_CTRL_2, EMAC_DESC_CTRL_10, - EMAC_DESC_CTRL_12, EMAC_DESC_CTRL_13}; - static const unsigned short rrd_q_offset[] = { - EMAC_DESC_CTRL_5, EMAC_DESC_CTRL_14, - EMAC_DESC_CTRL_15, EMAC_DESC_CTRL_16}; - /* TPD (Transmit Packet Descriptor) */ writel(upper_32_bits(adpt->tx_q.tpd.dma_addr), adpt->base + EMAC_DESC_CTRL_1); writel(lower_32_bits(adpt->tx_q.tpd.dma_addr), - adpt->base + tpd_q_offset[0]); + adpt->base + EMAC_DESC_CTRL_8); writel(adpt->tx_q.tpd.count & TPD_RING_SIZE_BMSK, adpt->base + EMAC_DESC_CTRL_9); @@ -334,9 +324,9 @@ static void emac_mac_dma_rings_config(struct emac_adapter *adpt) adpt->base + EMAC_DESC_CTRL_0); writel(lower_32_bits(adpt->rx_q.rfd.dma_addr), - adpt->base + rfd_q_offset[0]); + adpt->base + EMAC_DESC_CTRL_2); writel(lower_32_bits(adpt->rx_q.rrd.dma_addr), - adpt->base + rrd_q_offset[0]); + adpt->base + EMAC_DESC_CTRL_5); writel(adpt->rx_q.rfd.count & RFD_RING_SIZE_BMSK, adpt->base + EMAC_DESC_CTRL_3); @@ -744,6 +734,11 @@ static int emac_rx_descs_alloc(struct emac_adapter *adpt) rx_q->rrd.size = rx_q->rrd.count * (adpt->rrd_size * 4); rx_q->rfd.size = rx_q->rfd.count * (adpt->rfd_size * 4); + /* Check if the RRD and RFD are aligned properly, and if not, adjust. */ + if (upper_32_bits(ring_header->dma_addr) != + upper_32_bits(ring_header->dma_addr + ALIGN(rx_q->rrd.size, 8))) + ring_header->used = ALIGN(rx_q->rrd.size, 8); + rx_q->rrd.dma_addr = ring_header->dma_addr + ring_header->used; rx_q->rrd.v_addr = ring_header->v_addr + ring_header->used; ring_header->used += ALIGN(rx_q->rrd.size, 8); @@ -777,11 +772,18 @@ int emac_mac_rx_tx_rings_alloc_all(struct emac_adapter *adpt) /* Ring DMA buffer. Each ring may need up to 8 bytes for alignment, * hence the additional padding bytes are allocated. + * + * Also double the memory allocated for the RRD so that we can + * re-align it if necessary. The EMAC has a restriction that the + * upper 32 bits of the base addresses for the RFD and RRD rings + * must be the same. It is extremely unlikely that this is not the + * case, since the rings are only a few KB in size. However, we + * need to check for this anyway, and if the two rings are not + * compliant, then we re-align. */ - ring_header->size = num_tx_descs * (adpt->tpd_size * 4) + - num_rx_descs * (adpt->rfd_size * 4) + - num_rx_descs * (adpt->rrd_size * 4) + - 8 + 2 * 8; /* 8 byte per one Tx and two Rx rings */ + ring_header->size = ALIGN(num_tx_descs * (adpt->tpd_size * 4), 8) + + ALIGN(num_rx_descs * (adpt->rfd_size * 4), 8) + + ALIGN(num_rx_descs * (adpt->rrd_size * 4), 8) * 2; ring_header->used = 0; ring_header->v_addr = dma_zalloc_coherent(dev, ring_header->size, @@ -790,26 +792,23 @@ int emac_mac_rx_tx_rings_alloc_all(struct emac_adapter *adpt) if (!ring_header->v_addr) return -ENOMEM; - ring_header->used = ALIGN(ring_header->dma_addr, 8) - - ring_header->dma_addr; - - ret = emac_tx_q_desc_alloc(adpt, &adpt->tx_q); - if (ret) { - netdev_err(adpt->netdev, "error: Tx Queue alloc failed\n"); - goto err_alloc_tx; - } - ret = emac_rx_descs_alloc(adpt); if (ret) { netdev_err(adpt->netdev, "error: Rx Queue alloc failed\n"); goto err_alloc_rx; } + ret = emac_tx_q_desc_alloc(adpt, &adpt->tx_q); + if (ret) { + netdev_err(adpt->netdev, "transmit queue allocation failed\n"); + goto err_alloc_tx; + } + return 0; -err_alloc_rx: - emac_tx_q_bufs_free(adpt); err_alloc_tx: + emac_rx_q_bufs_free(adpt); +err_alloc_rx: dma_free_coherent(dev, ring_header->size, ring_header->v_addr, ring_header->dma_addr); diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c index 29ba37a08372..e8ab512ee7e3 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c @@ -68,10 +68,10 @@ static void emac_sgmii_link_init(struct emac_adapter *adpt) writel(val, phy->base + EMAC_SGMII_PHY_AUTONEG_CFG2); } -static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u32 irq_bits) +static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u8 irq_bits) { struct emac_sgmii *phy = &adpt->phy; - u32 status; + u8 status; writel_relaxed(irq_bits, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR); writel_relaxed(IRQ_GLOBAL_CLEAR, phy->base + EMAC_SGMII_PHY_IRQ_CMD); @@ -86,9 +86,8 @@ static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u32 irq_bits) EMAC_SGMII_PHY_INTERRUPT_STATUS, status, !(status & irq_bits), 1, SGMII_PHY_IRQ_CLR_WAIT_TIME)) { - netdev_err(adpt->netdev, - "error: failed clear SGMII irq: status:0x%x bits:0x%x\n", - status, irq_bits); + net_err_ratelimited("%s: failed to clear SGMII irq: status:0x%x bits:0x%x\n", + adpt->netdev->name, status, irq_bits); return -EIO; } @@ -109,7 +108,7 @@ static irqreturn_t emac_sgmii_interrupt(int irq, void *data) { struct emac_adapter *adpt = data; struct emac_sgmii *phy = &adpt->phy; - u32 status; + u8 status; status = readl(phy->base + EMAC_SGMII_PHY_INTERRUPT_STATUS); status &= SGMII_ISR_MASK; @@ -139,10 +138,8 @@ static irqreturn_t emac_sgmii_interrupt(int irq, void *data) atomic_set(&phy->decode_error_count, 0); } - if (emac_sgmii_irq_clear(adpt, status)) { - netdev_warn(adpt->netdev, "failed to clear SGMII interrupt\n"); + if (emac_sgmii_irq_clear(adpt, status)) schedule_work(&adpt->work_thread); - } return IRQ_HANDLED; } diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index f477ba29c569..70c92b649b29 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -148,9 +148,8 @@ static irqreturn_t emac_isr(int _irq, void *data) goto exit; if (status & ISR_ERROR) { - netif_warn(adpt, intr, adpt->netdev, - "warning: error irq status 0x%lx\n", - status & ISR_ERROR); + net_err_ratelimited("%s: error interrupt 0x%lx\n", + adpt->netdev->name, status & ISR_ERROR); /* reset MAC */ schedule_work(&adpt->work_thread); } @@ -169,7 +168,8 @@ static irqreturn_t emac_isr(int _irq, void *data) emac_mac_tx_process(adpt, &adpt->tx_q); if (status & ISR_OVER) - net_warn_ratelimited("warning: TX/RX overflow\n"); + net_warn_ratelimited("%s: TX/RX overflow interrupt\n", + adpt->netdev->name); exit: /* enable the interrupt */ @@ -615,20 +615,11 @@ static int emac_probe(struct platform_device *pdev) u32 reg; int ret; - /* The EMAC itself is capable of 64-bit DMA, so try that first. */ - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + /* The TPD buffer address is limited to 45 bits. */ + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(45)); if (ret) { - /* Some platforms may restrict the EMAC's address bus to less - * then the size of DDR. In this case, we need to try a - * smaller mask. We could try every possible smaller mask, - * but that's overkill. Instead, just fall to 32-bit, which - * should always work. - */ - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "could not set DMA mask\n"); - return ret; - } + dev_err(&pdev->dev, "could not set DMA mask\n"); + return ret; } netdev = alloc_etherdev(sizeof(struct emac_adapter)); |