| From a77480d9f1e1f2de7d27365a9668daf98184b0e2 Mon Sep 17 00:00:00 2001 |
| From: mtk27745 <rex.lu@mediatek.com> |
| Date: Mon, 18 Sep 2023 13:22:44 +0800 |
| Subject: [PATCH 21/22] mtk wed add wed3 ser support |
| |
| --- |
| drivers/net/ethernet/mediatek/mtk_wed.c | 236 +++++++++++++++++-- |
| drivers/net/ethernet/mediatek/mtk_wed_regs.h | 73 +++++- |
| include/linux/soc/mediatek/mtk_wed.h | 6 +- |
| 3 files changed, 291 insertions(+), 24 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c |
| index 9047cb0..0d101d5 100644 |
| --- a/drivers/net/ethernet/mediatek/mtk_wed.c |
| +++ b/drivers/net/ethernet/mediatek/mtk_wed.c |
| @@ -99,11 +99,65 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev) |
| u32 status; |
| u32 mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; |
| int busy, i; |
| + u32 value; |
| |
| wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); |
| busy = readx_poll_timeout(mtk_wdma_read_reset, dev, status, |
| - !(status & mask), 0, 10000); |
| + !(status & mask), 0, 10000); |
| |
| + if (dev->hw->version == 3) { |
| + wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); |
| + wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_PREF_TX_CFG); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_PREF_RX_CFG); |
| + |
| + wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); |
| + wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_WRBK_TX_CFG); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_WRBK_RX_CFG); |
| + |
| + /* Prefetch FIFO */ |
| + wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG, |
| + MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR | |
| + MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG, |
| + MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR | |
| + MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR); |
| + |
| + /* Core FIFO */ |
| + value = (MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR); |
| + |
| + wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, value); |
| + wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, value); |
| + |
| + /* Writeback FIFO */ |
| + wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); |
| + wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); |
| + |
| + wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); |
| + |
| + /* Prefetch ring status */ |
| + wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR); |
| + /* Writeback ring status */ |
| + wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR); |
| + } |
| wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); |
| wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); |
| |
| @@ -121,13 +175,62 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev) |
| { |
| u32 status; |
| u32 mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY; |
| - int i; |
| + int busy, i; |
| + u32 value; |
| |
| wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); |
| if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, |
| !(status & mask), 0, 10000)) |
| WARN_ON_ONCE(1); |
| |
| + if (dev->hw->version == 3) { |
| + wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); |
| + wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_PREF_TX_CFG); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_PREF_RX_CFG); |
| + |
| + wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); |
| + wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_WRBK_TX_CFG); |
| + busy = read_poll_timeout(wdma_r32, status, |
| + !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), 0, 10000, |
| + false, dev, MTK_WDMA_WRBK_RX_CFG); |
| + |
| + /* Prefetch FIFO */ |
| + wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG, |
| + MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR | |
| + MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG, |
| + MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR | |
| + MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR); |
| + /* Core FIFO */ |
| + value = (MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR | |
| + MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR); |
| + |
| + wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, value); |
| + wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, value); |
| + /* Writeback FIFO */ |
| + wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); |
| + wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); |
| + |
| + wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); |
| + |
| + /* Prefetch ring status */ |
| + wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR); |
| + /* Writeback ring status */ |
| + wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR); |
| + wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR); |
| + } |
| wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); |
| wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); |
| for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) |
| @@ -903,7 +1006,7 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev) |
| MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4); |
| |
| wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); |
| - //wdma_w32(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); |
| + wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); |
| if (mtk_wed_get_rx_capa(dev)) { |
| wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, |
| MTK_WED_WPDMA_RX_D_PREF_EN | |
| @@ -1466,13 +1569,30 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev) |
| mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE, |
| &state, sizeof(state), true); |
| |
| + if (dev->wlan.hwrro) { |
| + wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN); |
| + mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS, |
| + MTK_WED_RX_IND_CMD_BUSY); |
| + mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG); |
| + } |
| wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); |
| busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, |
| MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); |
| + if (dev->hw->version == 3) |
| + busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, |
| + MTK_WED_WPDMA_RX_D_PREF_BUSY); |
| if (busy) { |
| mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); |
| mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); |
| } else { |
| + if (dev->hw->version == 3) { |
| + /*1.a. Disable Prefetch HW*/ |
| + wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, MTK_WED_WPDMA_RX_D_PREF_EN); |
| + mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, |
| + MTK_WED_WPDMA_RX_D_PREF_BUSY); |
| + wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, |
| + MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL); |
| + } |
| wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, |
| MTK_WED_WPDMA_RX_D_RST_CRX_IDX | |
| MTK_WED_WPDMA_RX_D_RST_DRV_IDX); |
| @@ -1500,6 +1620,24 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev) |
| wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); |
| } |
| |
| + if (dev->wlan.hwrro) { |
| + /* Disable RRO MSDU Page Drv */ |
| + wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN); |
| + |
| + /* Disable RRO Data Drv */ |
| + wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN); |
| + |
| + /* RRO MSDU Page Drv Reset */ |
| + wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR); |
| + mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, |
| + MTK_WED_RRO_MSDU_PG_DRV_CLR); |
| + |
| + /* RRO Data Drv Reset */ |
| + wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_CLR); |
| + mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2), |
| + MTK_WED_RRO_RX_D_DRV_CLR); |
| + } |
| + |
| /* reset route qm */ |
| wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); |
| busy = mtk_wed_poll_busy(dev, MTK_WED_CTRL, |
| @@ -1507,8 +1645,13 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev) |
| if (busy) { |
| mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); |
| } else { |
| - wed_set(dev, MTK_WED_RTQM_GLO_CFG, |
| - MTK_WED_RTQM_Q_RST); |
| + if (dev->hw->version == 3) { |
| + wed_set(dev, MTK_WED_RTQM_RST, BIT(0)); |
| + wed_clr(dev, MTK_WED_RTQM_RST, BIT(0)); |
| + mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); |
| + } else |
| + wed_set(dev, MTK_WED_RTQM_GLO_CFG, |
| + MTK_WED_RTQM_Q_RST); |
| } |
| |
| /* reset tx wdma */ |
| @@ -1516,8 +1659,13 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev) |
| |
| /* reset tx wdma drv */ |
| wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); |
| - mtk_wed_poll_busy(dev, MTK_WED_CTRL, |
| - MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); |
| + if (dev->hw->version == 3) |
| + mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS, |
| + MTK_WED_WPDMA_STATUS_TX_DRV); |
| + else |
| + mtk_wed_poll_busy(dev, MTK_WED_CTRL, |
| + MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); |
| + |
| mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); |
| |
| /* reset wed rx dma */ |
| @@ -1535,9 +1683,17 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev) |
| /* reset rx bm */ |
| wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); |
| mtk_wed_poll_busy(dev, MTK_WED_CTRL, |
| - MTK_WED_CTRL_WED_RX_BM_BUSY); |
| + MTK_WED_CTRL_WED_RX_BM_BUSY); |
| mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); |
| |
| + if (dev->wlan.hwrro) { |
| + wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN); |
| + mtk_wed_poll_busy(dev, MTK_WED_CTRL, |
| + MTK_WED_CTRL_WED_RX_PG_BM_BUSY); |
| + wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM); |
| + wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM); |
| + } |
| + |
| /* wo change to enable state */ |
| state = WO_STATE_ENABLE; |
| mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE, |
| @@ -1554,6 +1710,9 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev) |
| } |
| |
| mtk_wed_free_rx_buffer(dev); |
| + |
| + if (dev->wlan.hwrro) |
| + mtk_wed_rx_page_free_buffer(dev); |
| } |
| |
| |
| @@ -1587,18 +1746,40 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) |
| |
| /* 2. Reset WDMA Rx DMA/Driver_Engine */ |
| busy = !!mtk_wdma_rx_reset(dev); |
| + if (dev->hw->version == 3) { |
| + val = wed_r32(dev, MTK_WED_WDMA_GLO_CFG); |
| + val |= MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE; |
| + val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN; |
| + wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val); |
| + } else |
| + wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); |
| |
| - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); |
| busy = !!(busy || |
| mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, |
| - MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)); |
| + MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)); |
| + if (dev->hw->version == 3) |
| + busy = !!(busy || |
| + mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG, |
| + MTK_WED_WDMA_RX_PREF_BUSY)); |
| |
| if (busy) { |
| mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); |
| mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); |
| } else { |
| + if (dev->hw->version == 3) { |
| + /*1.a. Disable Prefetch HW*/ |
| + wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN); |
| + mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG, |
| + MTK_WED_WDMA_RX_PREF_BUSY); |
| + wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_DDONE2_EN); |
| + |
| + /*2. Reset dma index*/ |
| + wed_w32(dev, MTK_WED_WDMA_RESET_IDX, |
| + MTK_WED_WDMA_RESET_IDX_RX_ALL); |
| + } |
| wed_w32(dev, MTK_WED_WDMA_RESET_IDX, |
| - MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV); |
| + MTK_WED_WDMA_RESET_IDX_RX | |
| + MTK_WED_WDMA_RESET_IDX_DRV); |
| wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0); |
| |
| wed_set(dev, MTK_WED_WDMA_GLO_CFG, |
| @@ -1613,9 +1794,15 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) |
| MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); |
| |
| for (i = 0; i < 100; i++) { |
| - val = wed_r32(dev, MTK_WED_TX_BM_INTF); |
| - if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) |
| - break; |
| + if (dev->ver > MTK_WED_V1) { |
| + val = wed_r32(dev, MTK_WED_TX_TKID_INTF); |
| + if (FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP, val) == 0x40) |
| + break; |
| + } else { |
| + val = wed_r32(dev, MTK_WED_TX_BM_INTF); |
| + if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) |
| + break; |
| + } |
| } |
| mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT); |
| |
| @@ -1624,18 +1811,20 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) |
| |
| /* 4. Reset WED WPDMA Tx Driver Engine */ |
| busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, |
| - MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY); |
| + MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY); |
| wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, |
| MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | |
| MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); |
| |
| busy = !!(busy || |
| mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, |
| - MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY)); |
| + MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY)); |
| if (busy) { |
| mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); |
| mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); |
| mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV); |
| + if (dev->hw->version == 3) |
| + wed_w32(dev, MTK_WED_RX1_CTRL2, 0); |
| } else { |
| wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, |
| MTK_WED_WPDMA_RESET_IDX_TX | |
| @@ -1648,7 +1837,13 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) |
| } |
| } |
| |
| - if (dev->ver > MTK_WED_V1) { |
| + if (dev->hw->version == 3) { |
| + /*reset wed pao*/ |
| + wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN); |
| + mtk_wed_reset(dev, MTK_WED_RESET_TX_PAO); |
| + } |
| + |
| + if (mtk_wed_get_rx_capa(dev)) { |
| dev->init_done = false; |
| mtk_wed_rx_reset(dev); |
| } |
| @@ -1863,7 +2058,7 @@ mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb, |
| } |
| |
| static void |
| -mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask) |
| +mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask, bool reset) |
| { |
| int idx, ret; |
| |
| @@ -1873,6 +2068,11 @@ mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask) |
| if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hwrro) |
| return; |
| |
| + if (reset) { |
| + wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN); |
| + return; |
| + } |
| + |
| wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR); |
| wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR); |
| |
| diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h |
| index 25be547..4379dc4 100644 |
| --- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h |
| +++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h |
| @@ -42,6 +42,8 @@ struct mtk_wdma_desc { |
| #define MTK_WED_RESET 0x008 |
| #define MTK_WED_RESET_TX_BM BIT(0) |
| #define MTK_WED_RESET_RX_BM BIT(1) |
| +#define MTK_WED_RESET_RX_PG_BM BIT(2) |
| +#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3) |
| #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) |
| #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) |
| #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) |
| @@ -64,7 +66,7 @@ struct mtk_wdma_desc { |
| #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3) |
| #define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5) |
| #define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6) |
| -#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7) |
| +#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7) |
| #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8) |
| #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) |
| #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) |
| @@ -123,6 +125,10 @@ struct mtk_wdma_desc { |
| #define MTK_WED_STATUS 0x060 |
| #define MTK_WED_STATUS_TX GENMASK(15, 8) |
| |
| +#define MTK_WED_WPDMA_STATUS 0x068 |
| +#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8) |
| + |
| + |
| #define MTK_WED_TX_BM_CTRL 0x080 |
| #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0) |
| #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16) |
| @@ -167,6 +173,9 @@ struct mtk_wdma_desc { |
| |
| #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) |
| |
| +#define MTK_WED_TX_TKID_INTF 0x0dc |
| +#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16) |
| + |
| #define MTK_WED_TX_TKID_DYN_THR 0x0e0 |
| #define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) |
| #define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) |
| @@ -203,10 +212,11 @@ struct mtk_wdma_desc { |
| #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31) |
| |
| #define MTK_WED_RESET_IDX 0x20c |
| -#define MTK_WED_RESET_IDX_TX GENMASK(3, 0) |
| -#if defined(CONFIG_MEDIATEK_NETSYS_V2) |
| +#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3) |
| +#define MTK_WED_RESET_IDX_TX GENMASK(1, 0) |
| #define MTK_WED_RESET_IDX_RX GENMASK(7, 6) |
| #else |
| +#define MTK_WED_RESET_IDX_TX GENMASK(3, 0) |
| #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) |
| #endif |
| #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) |
| @@ -221,6 +231,7 @@ struct mtk_wdma_desc { |
| #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10) |
| |
| #define MTK_WED_SCR0 0x3c0 |
| +#define MTK_WED_RX1_CTRL2 0x418 |
| #define MTK_WED_WPDMA_INT_TRIGGER 0x504 |
| #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) |
| #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) |
| @@ -336,6 +347,7 @@ struct mtk_wdma_desc { |
| |
| #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760 |
| #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16) |
| +#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20) |
| #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) |
| |
| #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c |
| @@ -352,6 +364,7 @@ struct mtk_wdma_desc { |
| |
| #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4 |
| #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0) |
| +#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1) |
| #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8) |
| #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16) |
| |
| @@ -373,11 +386,13 @@ struct mtk_wdma_desc { |
| |
| #define MTK_WED_WDMA_RX_PREF_CFG 0x950 |
| #define MTK_WED_WDMA_RX_PREF_EN BIT(0) |
| +#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1) |
| #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8) |
| #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16) |
| #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24) |
| #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25) |
| #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26) |
| +#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27) |
| |
| #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C |
| #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0) |
| @@ -406,6 +421,7 @@ struct mtk_wdma_desc { |
| |
| #define MTK_WED_WDMA_RESET_IDX 0xa08 |
| #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) |
| +#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20) |
| #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) |
| |
| #define MTK_WED_WDMA_INT_CLR 0xa24 |
| @@ -474,21 +490,66 @@ struct mtk_wdma_desc { |
| #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30) |
| #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31) |
| |
| +#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238 |
| +#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0) |
| +#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4) |
| +#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8) |
| +#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12) |
| + |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0) |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4) |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8) |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12) |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15) |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18) |
| +#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21) |
| + |
| + |
| + |
| #define MTK_WDMA_INT_GRP1 0x250 |
| #define MTK_WDMA_INT_GRP2 0x254 |
| |
| #define MTK_WDMA_PREF_TX_CFG 0x2d0 |
| #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0) |
| +#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1) |
| |
| #define MTK_WDMA_PREF_RX_CFG 0x2dc |
| #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0) |
| +#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1) |
| + |
| +#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0 |
| +#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0) |
| +#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16) |
| + |
| +#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4 |
| +#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0) |
| +#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16) |
| + |
| +#define MTK_WDMA_PREF_SIDX_CFG 0x2e4 |
| +#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0) |
| +#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4) |
| |
| #define MTK_WDMA_WRBK_TX_CFG 0x300 |
| +#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0) |
| #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30) |
| |
| +#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4) |
| +#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0) |
| + |
| + |
| #define MTK_WDMA_WRBK_RX_CFG 0x344 |
| +#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0) |
| #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30) |
| |
| +#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4) |
| +#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0) |
| + |
| + |
| +#define MTK_WDMA_WRBK_SIDX_CFG 0x388 |
| +#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0) |
| +#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4) |
| + |
| #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0) |
| #define MTK_PCIE_MIRROR_MAP_EN BIT(0) |
| #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1) |
| @@ -502,6 +563,9 @@ struct mtk_wdma_desc { |
| #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) |
| #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) |
| |
| +#define MTK_WED_RTQM_RST 0xb04 |
| + |
| + |
| #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c |
| #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4) |
| #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28 |
| @@ -691,6 +755,9 @@ struct mtk_wdma_desc { |
| #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17) |
| #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18) |
| |
| +#define MTK_WED_RRO_RX_HW_STS 0xf00 |
| +#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0) |
| + |
| #define MTK_WED_RX_IND_CMD_CNT0 0xf20 |
| #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31) |
| |
| diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h |
| index 92df4ba..1438692 100644 |
| --- a/include/linux/soc/mediatek/mtk_wed.h |
| +++ b/include/linux/soc/mediatek/mtk_wed.h |
| @@ -240,7 +240,7 @@ struct mtk_wed_ops { |
| void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); |
| void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb, |
| u32 reason, u32 hash); |
| - void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask); |
| + void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask, bool reset); |
| }; |
| |
| extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; |
| @@ -317,8 +317,8 @@ mtk_wed_device_support_pao(struct mtk_wed_device *dev) |
| (_dev)->ops->reset_dma(_dev) |
| #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ |
| (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) |
| -#define mtk_wed_device_start_hwrro(_dev, _mask) \ |
| - (_dev)->ops->start_hwrro(_dev, _mask) |
| +#define mtk_wed_device_start_hwrro(_dev, _mask, _reset) \ |
| + (_dev)->ops->start_hwrro(_dev, _mask, _reset) |
| |
| #else |
| static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) |
| -- |
| 2.18.0 |
| |