From: Maulik Jodhani Date: Tue, 13 Jun 2023 05:43:40 +0000 (-0600) Subject: net: macb: Add support for partial store and forward X-Git-Tag: v6.6.17~4555^2~94^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cae4bc06b3e41bc6dfd7116a45c1006e50ffe153;p=platform%2Fkernel%2Flinux-rpi.git net: macb: Add support for partial store and forward When the receive partial store and forward mode is activated, the receiver will only begin to forward the packet to the external AHB or AXI slave when enough packet data is stored in the packet buffer. The amount of packet data required to activate the forwarding process is programmable via watermark registers which are located at the same address as the partial store and forward enable bits. Adding support to read this rx-watermark value from device-tree, to program the watermark registers and enable partial store and forwarding. Signed-off-by: Maulik Jodhani Signed-off-by: Pranavi Somisetty Reviewed-by: Claudiu Beznea Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index b6d5bf8..78c972b 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -82,6 +82,7 @@ #define GEM_NCFGR 0x0004 /* Network Config */ #define GEM_USRIO 0x000c /* User IO */ #define GEM_DMACFG 0x0010 /* DMA Configuration */ +#define GEM_PBUFRXCUT 0x0044 /* RX Partial Store and Forward */ #define GEM_JML 0x0048 /* Jumbo Max Length */ #define GEM_HS_MAC_CONFIG 0x0050 /* GEM high speed config */ #define GEM_HRB 0x0080 /* Hash Bottom */ @@ -347,6 +348,10 @@ #define GEM_ADDR64_SIZE 1 +/* Bitfields in PBUFRXCUT */ +#define GEM_ENCUTTHRU_OFFSET 31 /* Enable RX partial store and forward */ +#define GEM_ENCUTTHRU_SIZE 1 + /* Bitfields in NSR */ #define MACB_NSR_LINK_OFFSET 0 /* pcs_link_state */ #define MACB_NSR_LINK_SIZE 1 @@ -513,6 +518,8 @@ #define GEM_TX_PKT_BUFF_OFFSET 21 #define GEM_TX_PKT_BUFF_SIZE 1 +#define GEM_RX_PBUF_ADDR_OFFSET 22 +#define GEM_RX_PBUF_ADDR_SIZE 4 /* Bitfields in DCFG5. */ #define GEM_TSU_OFFSET 8 @@ -521,6 +528,8 @@ /* Bitfields in DCFG6. */ #define GEM_PBUF_LSO_OFFSET 27 #define GEM_PBUF_LSO_SIZE 1 +#define GEM_PBUF_CUTTHRU_OFFSET 25 +#define GEM_PBUF_CUTTHRU_SIZE 1 #define GEM_DAW64_OFFSET 23 #define GEM_DAW64_SIZE 1 @@ -1290,6 +1299,9 @@ struct macb { u32 wol; + /* holds value of rx watermark value for pbuf_rxcutthru register */ + u32 rx_watermark; + struct macb_ptp_info *ptp_info; /* macb-ptp interface */ struct phy *sgmii_phy; /* for ZynqMP SGMII mode */ diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 50a4b04..2e35e20 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2635,6 +2635,9 @@ static void macb_reset_hw(struct macb *bp) macb_writel(bp, TSR, -1); macb_writel(bp, RSR, -1); + /* Disable RX partial store and forward and reset watermark value */ + gem_writel(bp, PBUFRXCUT, 0); + /* Disable all interrupts */ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { queue_writel(queue, IDR, -1); @@ -2792,6 +2795,10 @@ static void macb_init_hw(struct macb *bp) bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK; macb_configure_dma(bp); + + /* Enable RX partial store and forward and set watermark */ + if (bp->rx_watermark) + gem_writel(bp, PBUFRXCUT, (bp->rx_watermark | GEM_BIT(ENCUTTHRU))); } /* The hash address register is 64 bits long and takes up two @@ -4946,6 +4953,7 @@ static int macb_probe(struct platform_device *pdev) phy_interface_t interface; struct net_device *dev; struct resource *regs; + u32 wtrmrk_rst_val; void __iomem *mem; struct macb *bp; int err, val; @@ -5025,6 +5033,25 @@ static int macb_probe(struct platform_device *pdev) bp->usrio = macb_config->usrio; + /* By default we set to partial store and forward mode for zynqmp. + * Disable if not set in devicetree. + */ + if (GEM_BFEXT(PBUF_CUTTHRU, gem_readl(bp, DCFG6))) { + err = of_property_read_u32(bp->pdev->dev.of_node, + "cdns,rx-watermark", + &bp->rx_watermark); + + if (!err) { + /* Disable partial store and forward in case of error or + * invalid watermark value + */ + wtrmrk_rst_val = (1 << (GEM_BFEXT(RX_PBUF_ADDR, gem_readl(bp, DCFG2)))) - 1; + if (bp->rx_watermark > wtrmrk_rst_val || !bp->rx_watermark) { + dev_info(&bp->pdev->dev, "Invalid watermark value\n"); + bp->rx_watermark = 0; + } + } + } spin_lock_init(&bp->lock); /* setup capabilities */