diff options
-rw-r--r-- | drivers/net/ethernet/cadence/macb.h | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/macb_main.c | 27 |
2 files changed, 39 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index b6d5bf8deb79..78c972bb1d96 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 50a4b04315e9..2e35e200fdcb 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 */ |