Skip to content

Commit a37d942

Browse files
harini-katakamclaudiubeznea
authored andcommitted
net: macb: Allocate valid memory for TX and RX BD prefetch
GEM version in ZynqMP and most versions greater than r1p07 supports TX and RX BD prefetch. The number of BDs that can be prefetched is a HW configurable parameter. For ZynqMP, this parameter is 4. When GEM DMA is accessing the last BD in the ring, even before the BD is processed and the WRAP bit is noticed, it will have prefetched BDs outside the BD ring. These will not be processed but it is necessary to have accessible memory after the last BD. Especially in cases where SMMU is used, memory locations immediately after the last BD may not have translation tables triggering HRESP errors. Hence always allocate extra BDs to accommodate for prefetch. The value of tx/rx bd prefetch for any given SoC version is: 2 ^ (corresponding field in design config 10 register). (value of this field >= 1) Added a capability flag so that older IP versions that do not have DCFG10 or this prefetch capability are not affected. Signed-off-by: Harini Katakam <harini.katakam@xilinx.com> Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ecf25f0 commit a37d942

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

drivers/net/ethernet/cadence/macb.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@
166166
#define GEM_DCFG6 0x0294 /* Design Config 6 */
167167
#define GEM_DCFG7 0x0298 /* Design Config 7 */
168168
#define GEM_DCFG8 0x029C /* Design Config 8 */
169+
#define GEM_DCFG10 0x02A4 /* Design Config 10 */
169170

170171
#define GEM_TXBDCTRL 0x04cc /* TX Buffer Descriptor control register */
171172
#define GEM_RXBDCTRL 0x04d0 /* RX Buffer Descriptor control register */
@@ -490,6 +491,12 @@
490491
#define GEM_SCR2CMP_OFFSET 0
491492
#define GEM_SCR2CMP_SIZE 8
492493

494+
/* Bitfields in DCFG10 */
495+
#define GEM_TXBD_RDBUFF_OFFSET 12
496+
#define GEM_TXBD_RDBUFF_SIZE 4
497+
#define GEM_RXBD_RDBUFF_OFFSET 8
498+
#define GEM_RXBD_RDBUFF_SIZE 4
499+
493500
/* Bitfields in TISUBN */
494501
#define GEM_SUBNSINCR_OFFSET 0
495502
#define GEM_SUBNSINCR_SIZE 16
@@ -635,6 +642,7 @@
635642
#define MACB_CAPS_USRIO_DISABLED 0x00000010
636643
#define MACB_CAPS_JUMBO 0x00000020
637644
#define MACB_CAPS_GEM_HAS_PTP 0x00000040
645+
#define MACB_CAPS_BD_RD_PREFETCH 0x00000080
638646
#define MACB_CAPS_FIFO_MODE 0x10000000
639647
#define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000
640648
#define MACB_CAPS_SG_DISABLED 0x40000000
@@ -1203,6 +1211,9 @@ struct macb {
12031211
unsigned int max_tuples;
12041212

12051213
struct tasklet_struct hresp_err_tasklet;
1214+
1215+
int rx_bd_rd_prefetch;
1216+
int tx_bd_rd_prefetch;
12061217
};
12071218

12081219
#ifdef CONFIG_MACB_USE_HWSTAMP

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,19 +1811,22 @@ static void macb_free_consistent(struct macb *bp)
18111811
{
18121812
struct macb_queue *queue;
18131813
unsigned int q;
1814+
int size;
18141815

18151816
bp->macbgem_ops.mog_free_rx_buffers(bp);
18161817

18171818
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
18181819
kfree(queue->tx_skb);
18191820
queue->tx_skb = NULL;
18201821
if (queue->tx_ring) {
1821-
dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES(bp),
1822+
size = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch;
1823+
dma_free_coherent(&bp->pdev->dev, size,
18221824
queue->tx_ring, queue->tx_ring_dma);
18231825
queue->tx_ring = NULL;
18241826
}
18251827
if (queue->rx_ring) {
1826-
dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES(bp),
1828+
size = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch;
1829+
dma_free_coherent(&bp->pdev->dev, size,
18271830
queue->rx_ring, queue->rx_ring_dma);
18281831
queue->rx_ring = NULL;
18291832
}
@@ -1873,7 +1876,7 @@ static int macb_alloc_consistent(struct macb *bp)
18731876
int size;
18741877

18751878
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
1876-
size = TX_RING_BYTES(bp);
1879+
size = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch;
18771880
queue->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
18781881
&queue->tx_ring_dma,
18791882
GFP_KERNEL);
@@ -1889,7 +1892,7 @@ static int macb_alloc_consistent(struct macb *bp)
18891892
if (!queue->tx_skb)
18901893
goto out_err;
18911894

1892-
size = RX_RING_BYTES(bp);
1895+
size = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch;
18931896
queue->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
18941897
&queue->rx_ring_dma, GFP_KERNEL);
18951898
if (!queue->rx_ring)
@@ -3796,7 +3799,7 @@ static const struct macb_config np4_config = {
37963799
static const struct macb_config zynqmp_config = {
37973800
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
37983801
MACB_CAPS_JUMBO |
3799-
MACB_CAPS_GEM_HAS_PTP,
3802+
MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH,
38003803
.dma_burst_length = 16,
38013804
.clk_init = macb_clk_init,
38023805
.init = macb_init,
@@ -3857,7 +3860,7 @@ static int macb_probe(struct platform_device *pdev)
38573860
void __iomem *mem;
38583861
const char *mac;
38593862
struct macb *bp;
3860-
int err;
3863+
int err, val;
38613864

38623865
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
38633866
mem = devm_ioremap_resource(&pdev->dev, regs);
@@ -3946,6 +3949,18 @@ static int macb_probe(struct platform_device *pdev)
39463949
else
39473950
dev->max_mtu = ETH_DATA_LEN;
39483951

3952+
if (bp->caps & MACB_CAPS_BD_RD_PREFETCH) {
3953+
val = GEM_BFEXT(RXBD_RDBUFF, gem_readl(bp, DCFG10));
3954+
if (val)
3955+
bp->rx_bd_rd_prefetch = (2 << (val - 1)) *
3956+
macb_dma_desc_get_size(bp);
3957+
3958+
val = GEM_BFEXT(TXBD_RDBUFF, gem_readl(bp, DCFG10));
3959+
if (val)
3960+
bp->tx_bd_rd_prefetch = (2 << (val - 1)) *
3961+
macb_dma_desc_get_size(bp);
3962+
}
3963+
39493964
mac = of_get_mac_address(np);
39503965
if (mac) {
39513966
ether_addr_copy(bp->dev->dev_addr, mac);

0 commit comments

Comments
 (0)