From b3bbfe7c4386b5044fef3e8016bd3f57c31b5f36 Mon Sep 17 00:00:00 2001 From: Srinath Pandey Date: Fri, 23 Aug 2024 18:31:25 +0530 Subject: [PATCH] net: stmmac: Re initialize Rx buffers reinit rx buffers in resume. Add support for driver remove\shutdown operation. Change-Id: I3df26647627817a574990c223382d8e5d4da4c03 Signed-off-by: Srinath Pandey --- .../stmicro/stmmac/dwmac-qcom-ethqos.c | 11 +++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 84 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index 7fd3fe6a83d6..6311f9a51b5a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -2460,6 +2460,16 @@ static int qcom_ethqos_remove(struct platform_device *pdev) return ret; } +static void qcom_ethqos_shutdown_main(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + if (!dev) + return; + + qcom_ethqos_remove(pdev); +} + static int qcom_ethqos_suspend(struct device *dev) { struct qcom_ethqos *ethqos; @@ -2775,6 +2785,7 @@ static const struct dev_pm_ops qcom_ethqos_pm_ops = { static struct platform_driver qcom_ethqos_driver = { .probe = qcom_ethqos_probe, .remove = qcom_ethqos_remove, + .shutdown = qcom_ethqos_shutdown_main, .driver = { .name = DRV_NAME, .pm = &qcom_ethqos_pm_ops, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 58123275b30e..e1153465046c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1821,6 +1821,88 @@ static struct xsk_buff_pool *stmmac_get_xsk_pool(struct stmmac_priv *priv, u32 q return xsk_get_pool_from_qid(priv->dev, queue); } +static void stmmac_reinit_rx_buffers(struct stmmac_priv *priv, struct stmmac_dma_conf *dma_conf) +{ + u32 rx_count = priv->plat->rx_queues_to_use; + u32 queue; + int i; + + for (queue = 0; queue < rx_count; queue++) { + struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; + + for (i = 0; i < dma_conf->dma_rx_size; i++) { + struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; + + if (buf->page) { + page_pool_recycle_direct(rx_q->page_pool, buf->page); + buf->page = NULL; + } + + if (priv->sph && buf->sec_page) { + page_pool_recycle_direct(rx_q->page_pool, buf->sec_page); + buf->sec_page = NULL; + } + } + } + + for (queue = 0; queue < rx_count; queue++) { + struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; + + for (i = 0; i < dma_conf->dma_rx_size; i++) { + struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; + struct dma_desc *p; + + if (priv->extend_desc) + p = &((rx_q->dma_erx + i)->basic); + else + p = rx_q->dma_rx + i; + + if (!buf->page) { + buf->page = page_pool_dev_alloc_pages(rx_q->page_pool); + if (!buf->page) + goto err_reinit_rx_buffers; + + buf->addr = page_pool_get_dma_addr(buf->page); + if (!buf->addr) { + pr_err("buf->addr is NULL\n"); + goto err_reinit_rx_buffers; + } + } + + if (priv->sph && !buf->sec_page) { + buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool); + if (!buf->sec_page) + goto err_reinit_rx_buffers; + + buf->sec_addr = page_pool_get_dma_addr(buf->sec_page); + if (!buf->sec_addr) { + pr_err("buf->sec_addr is NULL\n"); + goto err_reinit_rx_buffers; + } + stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true); + } else { + buf->sec_page = NULL; + stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false); + } + + stmmac_set_desc_addr(priv, p, buf->addr); + + if (dma_conf->dma_buf_sz == BUF_SIZE_16KiB) + stmmac_init_desc3(priv, p); + } + } + + return; + +err_reinit_rx_buffers: + pr_err(" error in reinit_rx_buffers\n"); + do { + dma_free_rx_skbufs(priv, dma_conf, queue); + if (queue == 0) + break; + } while (queue-- > 0); +} + /** * __init_dma_rx_desc_rings - init the RX descriptor ring (per queue) * @priv: driver private structure @@ -7834,6 +7916,8 @@ int stmmac_resume(struct device *dev) stmmac_reset_queues_param(priv); + stmmac_reinit_rx_buffers(priv, &priv->dma_conf); + stmmac_free_tx_skbufs(priv); stmmac_clear_descriptors(priv, &priv->dma_conf);