refactor mtk_wed code to introduce SER support
Subsystems (5)
Lorenzo Bianconi
maintainercover refactor mtk_wed code to introduce SER support
Refactor mtk_wed support in order to introduce proper integration for hw reset between mtk_eth_soc/mtk_wed and mt76 drivers.
Lorenzo Bianconi (5):
net: ethernet: mtk_wed: return status value in mtk_wdma_rx_reset
net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX configuration in
mtk_wdma_tx_reset
net: ethernet: mtk_wed: update mtk_wed_stop
net: ethernet: mtk_wed: add mtk_wed_rx_reset routine
net: ethernet: mtk_wed: add reset to tx_ring_setup callback
drivers/net/ethernet/mediatek/mtk_wed.c | 279 ++++++++++++++----- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 9 + drivers/net/wireless/mediatek/mt76/dma.c | 2 +- include/linux/soc/mediatek/mtk_wed.h | 12 +- 4 files changed, 220 insertions(+), 82 deletions(-)
Signature · 1 line
2.38.1
Lorenzo Bianconi
maintainerPATCH 1/5 net: ethernet: mtk_wed: return status value in mtk_wdma_rx_reset
Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine. This is a preliminary patch to add Wireless Ethernet Dispatcher reset support.
--- drivers/net/ethernet/mediatek/mtk_wed.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +12 -13
@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)return wdma_r32 (dev,MTK_WDMA_GLO_CFG ); } -static void +static int mtk_wdma_rx_reset (struct mtk_wed_device *dev) {u32 status, mask =MTK_WDMA_GLO_CFG_RX_DMA_BUSY ; -int i; +int i, ret;wdma_clr (dev,MTK_WDMA_GLO_CFG ,MTK_WDMA_GLO_CFG_RX_DMA_EN ); -if (readx_poll_timeout (mtk_wdma_read_reset, dev, status, - !(status & mask),0 ,1000 )) + ret =readx_poll_timeout (mtk_wdma_read_reset, dev, status, + !(status & mask),0 ,10000 ); +if (ret)dev_err (dev->hw->dev,"rx reset failed\n" ); +wdma_w32 (dev,MTK_WDMA_RESET_IDX ,MTK_WDMA_RESET_IDX_RX ); +wdma_w32 (dev,MTK_WDMA_RESET_IDX ,0 ); +for (i =0 ; i <ARRAY_SIZE (dev->rx_wdma); i++) {if (dev->rx_wdma[i].desc)continue ;
@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)wdma_w32 (dev,MTK_WDMA_RING_RX (i) +MTK_WED_RING_OFS_CPU_IDX ,0 ); } + +return ret; } static void
@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *dev)mtk_wed_stop (dev); -wdma_w32 (dev,MTK_WDMA_RESET_IDX ,MTK_WDMA_RESET_IDX_RX ); -wdma_w32 (dev,MTK_WDMA_RESET_IDX ,0 ); - +mtk_wdma_rx_reset (dev);mtk_wed_reset (dev,MTK_WED_RESET_WED );if (mtk_wed_get_rx_capa (dev)) {wdma_clr (dev,MTK_WDMA_GLO_CFG ,MTK_WDMA_GLO_CFG_TX_DMA_EN );
@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *dev)mtk_wed_wo_reset (dev);mtk_wed_free_rx_rings (dev);mtk_wed_wo_deinit (hw); -mtk_wdma_rx_reset (dev); }if (dev->wlan.bus_type ==MTK_WED_BUS_PCIE ) {
@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)wed_w32 (dev,MTK_WED_RESET_IDX ,0 ); } -wdma_w32 (dev,MTK_WDMA_RESET_IDX ,MTK_WDMA_RESET_IDX_RX ); -wdma_w32 (dev,MTK_WDMA_RESET_IDX ,0 ); - -if (mtk_wed_get_rx_capa (dev)) -mtk_wdma_rx_reset (dev); +mtk_wdma_rx_reset (dev);if (busy) {mtk_wed_reset (dev,MTK_WED_RESET_WDMA_INT_AGENT );
Signature · 1 line
2.38.1
Re: [PATCH net-next 1/5] net: ethernet: mtk_wed: return status value in mtk_wdma_rx_reset
From: Lorenzo Bianconi <[email protected]>
Date: Mon, 21 Nov 2022 09:59:21 +0100
Quoted 22 lines
Move
MTK_WDMA_RESET_IDXconfiguration inmtk_wdma_rx_resetroutine. This is a preliminary patch to add Wireless Ethernet Dispatcher reset support.Co-developed-by Sujuan Chen <[email protected]>Signed-off-by Sujuan Chen <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/ethernet/mediatek/mtk_wed.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)drivers/net/ethernet/mediatek/mtk_wed.c +1
-1@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)return wdma_r32 (dev,MTK_WDMA_GLO_CFG ); } -static void +static int mtk_wdma_rx_reset (struct mtk_wed_device *dev)
drivers/net/ethernet/mediatek/mtk_wed.c mtk_wdma_read_reset(struct mtk_wed_device *dev) · line 112
Quoted 10 lines
drivers/net/ethernet/mediatek/mtk_wed.c +3
-3{u32 status, mask =MTK_WDMA_GLO_CFG_RX_DMA_BUSY ; -int i; +int i, ret;wdma_clr (dev,MTK_WDMA_GLO_CFG ,MTK_WDMA_GLO_CFG_RX_DMA_EN ); -if (readx_poll_timeout (mtk_wdma_read_reset, dev, status, - !(status & mask),0 ,1000 )) + ret =readx_poll_timeout (mtk_wdma_read_reset, dev, status, + !(status & mask),0 ,10000 );
You didn't mention anywhere this change of the timeout from 1000 to 10000, and for example for me it's not clear from the code why you did this. Maybe leave a comment in the commitmsg?
Same in 2/5 for Tx, also 1000 -> 10000.
Quoted 9 lines
drivers/net/ethernet/mediatek/mtk_wed.c +4
-0+if (ret)dev_err (dev->hw->dev,"rx reset failed\n" ); +wdma_w32 (dev,MTK_WDMA_RESET_IDX ,MTK_WDMA_RESET_IDX_RX ); +wdma_w32 (dev,MTK_WDMA_RESET_IDX ,0 ); +for (i =0 ; i <ARRAY_SIZE (dev->rx_wdma); i++) {if (dev->rx_wdma[i].desc)continue ;
[...]
Quoted 2 lines
Signature · 1 line
2.38.1
Thanks,
Olek
Lorenzo Bianconi
maintainerRe: [PATCH net-next 1/5] net: ethernet: mtk_wed: return status value in mtk_wdma_rx_reset
Quoted 31 lines
From: Lorenzo Bianconi <[email protected]>
Date: Mon, 21 Nov 2022 09:59:21 +0100Quoted 27 lines
Move
MTK_WDMA_RESET_IDXconfiguration inmtk_wdma_rx_resetroutine. This is a preliminary patch to add Wireless Ethernet Dispatcher reset support.Co-developed-by Sujuan Chen <[email protected]>Signed-off-by Sujuan Chen <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/ethernet/mediatek/mtk_wed.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)drivers/net/ethernet/mediatek/mtk_wed.c +2
-2@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)return wdma_r32 (dev,MTK_WDMA_GLO_CFG ); } -static void +static int mtk_wdma_rx_reset (struct mtk_wed_device *dev) {u32 status, mask =MTK_WDMA_GLO_CFG_RX_DMA_BUSY ; -int i; +int i, ret;
Quoted 10 lines
drivers/net/ethernet/mediatek/mtk_wed.c mtk_wdma_read_reset(struct mtk_wed_device *dev) · line 112
Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_wed.c +2
-2wdma_clr (dev,MTK_WDMA_GLO_CFG ,MTK_WDMA_GLO_CFG_RX_DMA_EN ); -if (readx_poll_timeout (mtk_wdma_read_reset, dev, status, - !(status & mask),0 ,1000 )) + ret =readx_poll_timeout (mtk_wdma_read_reset, dev, status, + !(status & mask),0 ,10000 );You didn't mention anywhere this change of the timeout from 1000 to 10000, and for example for me it's not clear from the code why you did this. Maybe leave a comment in the commitmsg?
Same in 2/5 for Tx, also 1000 -> 10000.
ops I forgot them, sorry. I actually aligned the these values to the vendor sdk.
Regards,
Lorenzo
Quoted 18 lines
Quoted 10 lines
drivers/net/ethernet/mediatek/mtk_wed.c +4
-0+if (ret)dev_err (dev->hw->dev,"rx reset failed\n" ); +wdma_w32 (dev,MTK_WDMA_RESET_IDX ,MTK_WDMA_RESET_IDX_RX ); +wdma_w32 (dev,MTK_WDMA_RESET_IDX ,0 ); +for (i =0 ; i <ARRAY_SIZE (dev->rx_wdma); i++) {if (dev->rx_wdma[i].desc)continue ;[...]
Quoted 2 lines
Signature · 1 line
2.38.1Thanks,
Olek
Lorenzo Bianconi
maintainerPATCH 2/5 net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX configuration in mtk_wdma_tx_reset
In reply to Lorenzo BianconiRemove duplicated code. This is a preliminary patch to add Wireless Ethernet Dispatcher reset support.
--- drivers/net/ethernet/mediatek/mtk_wed.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +4 -11
@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev)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 ,1000 )) + !(status & mask),0 ,10000 ))dev_err (dev->hw->dev,"tx reset failed\n" ); -for (i =0 ; i <ARRAY_SIZE (dev->tx_wdma); i++) { -if (dev->tx_wdma[i].desc) -continue ; +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++)wdma_w32 (dev,MTK_WDMA_RING_TX (i) +MTK_WED_RING_OFS_CPU_IDX ,0 ); - } } static void
@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *dev)mtk_wdma_rx_reset (dev);mtk_wed_reset (dev,MTK_WED_RESET_WED ); -if (mtk_wed_get_rx_capa (dev)) { -wdma_clr (dev,MTK_WDMA_GLO_CFG ,MTK_WDMA_GLO_CFG_TX_DMA_EN ); -wdma_w32 (dev,MTK_WDMA_RESET_IDX ,MTK_WDMA_RESET_IDX_TX ); -wdma_w32 (dev,MTK_WDMA_RESET_IDX ,0 ); - } -mtk_wed_free_tx_buffer (dev);mtk_wed_free_tx_rings (dev);
Signature · 1 line
2.38.1
Lorenzo Bianconi
maintainerPATCH 3/5 net: ethernet: mtk_wed: update mtk_wed_stop
In reply to Lorenzo BianconiUpdate mtk_wed_stop routine and rename old mtk_wed_stop() to mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet Dispatcher reset support.
--- drivers/net/ethernet/mediatek/mtk_wed.c | 32 ++++++++++++++++++------- include/linux/soc/mediatek/mtk_wed.h | 4 ++++ 2 files changed, 27 insertions(+), 9 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +23 -9
@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)static void mtk_wed_stop (struct mtk_wed_device *dev) { -mtk_wed_dma_disable (dev);mtk_wed_set_ext_int (dev, false); -wed_clr (dev,MTK_WED_CTRL , -MTK_WED_CTRL_WDMA_INT_AGENT_EN | -MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -MTK_WED_CTRL_WED_TX_BM_EN | -MTK_WED_CTRL_WED_TX_FREE_AGENT_EN );wed_w32 (dev,MTK_WED_WPDMA_INT_TRIGGER ,0 );wed_w32 (dev,MTK_WED_WDMA_INT_TRIGGER ,0 );wdma_w32 (dev,MTK_WDMA_INT_MASK ,0 );
@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev)wed_w32 (dev,MTK_WED_EXT_INT_MASK1 ,0 );wed_w32 (dev,MTK_WED_EXT_INT_MASK2 ,0 ); -wed_clr (dev,MTK_WED_CTRL ,MTK_WED_CTRL_WED_RX_BM_EN ); +} + +static void +mtk_wed_deinit (struct mtk_wed_device *dev) +{ +mtk_wed_stop (dev); +mtk_wed_dma_disable (dev); + +wed_clr (dev,MTK_WED_CTRL , +MTK_WED_CTRL_WDMA_INT_AGENT_EN | +MTK_WED_CTRL_WPDMA_INT_AGENT_EN | +MTK_WED_CTRL_WED_TX_BM_EN | +MTK_WED_CTRL_WED_TX_FREE_AGENT_EN ); + +if (dev->hw->version ==1 ) +return ; + +wed_clr (dev,MTK_WED_CTRL , +MTK_WED_CTRL_RX_ROUTE_QM_EN | +MTK_WED_CTRL_WED_RX_BM_EN | +MTK_WED_CTRL_RX_RRO_QM_EN ); } static void
@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *dev)mutex_lock (&hw_lock); -mtk_wed_stop (dev); +mtk_wed_deinit (dev);mtk_wdma_rx_reset (dev);mtk_wed_reset (dev,MTK_WED_RESET_WED );
@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev) {u32 mask, set; -mtk_wed_stop (dev); +mtk_wed_deinit (dev);mtk_wed_reset (dev,MTK_WED_RESET_WED );mtk_wed_set_wpdma (dev);
include/linux/soc/mediatek/mtk_wed.h +4 -0
@@ -231,6 +231,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev) (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)#define mtk_wed_device_update_msg (_dev, _id, _msg, _len) \ (_dev)->ops->msg_update(_dev, _id, _msg, _len) +#define mtk_wed_device_stop (_dev) (_dev)->ops->stop(_dev) +#define mtk_wed_device_dma_reset (_dev) (_dev)->ops->reset_dma(_dev)#else static inline bool mtk_wed_device_active (struct mtk_wed_device *dev) {
@@ -247,6 +249,8 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)#define mtk_wed_device_rx_ring_setup (_dev, _ring, _regs) -ENODEV#define mtk_wed_device_ppe_check (_dev, _skb, _reason, _hash) do {} while (0)#define mtk_wed_device_update_msg (_dev, _id, _msg, _len) -ENODEV +#define mtk_wed_device_stop (_dev) do {} while (0) +#define mtk_wed_device_dma_reset (_dev) do {} while (0)#endif #endif
Signature · 1 line
2.38.1
Lorenzo Bianconi
maintainerPATCH 4/5 net: ethernet: mtk_wed: add mtk_wed_rx_reset routine
In reply to Lorenzo BianconiIntroduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless Ethernet Dispatcher available on MT7986 SoC.
--- drivers/net/ethernet/mediatek/mtk_wed.c | 190 +++++++++++++++---- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 9 + 2 files changed, 162 insertions(+), 37 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +153 -37
@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx) }static u32 -mtk_wed_check_busy (struct mtk_wed_device *dev) +mtk_wed_check_busy (struct mtk_wed_device *dev,u32 reg,u32 mask) { -if (wed_r32 (dev,MTK_WED_GLO_CFG ) &MTK_WED_GLO_CFG_TX_DMA_BUSY ) -return true; - -if (wed_r32 (dev,MTK_WED_WPDMA_GLO_CFG ) & -MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY ) -return true; - -if (wed_r32 (dev,MTK_WED_CTRL ) &MTK_WED_CTRL_WDMA_INT_AGENT_BUSY ) -return true; - -if (wed_r32 (dev,MTK_WED_WDMA_GLO_CFG ) & -MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY ) -return true; - -if (wdma_r32 (dev,MTK_WDMA_GLO_CFG ) & -MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY ) -return true; - -if (wed_r32 (dev,MTK_WED_CTRL ) & - (MTK_WED_CTRL_WED_TX_BM_BUSY |MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY )) -return true; - -return false; +return !!(wed_r32 (dev, reg) & mask); }static int -mtk_wed_poll_busy (struct mtk_wed_device *dev) +mtk_wed_poll_busy (struct mtk_wed_device *dev,u32 reg,u32 mask) {int sleep =15000 ;int timeout =100 * sleep;u32 val;return read_poll_timeout (mtk_wed_check_busy, val, !val, sleep, - timeout, false, dev); + timeout, false, dev, reg, mask); +} + +static int +mtk_wed_rx_reset (struct mtk_wed_device *dev) +{ +struct mtk_wed_wo *wo = dev->hw->wed_wo; +u8 val =MTK_WED_WO_STATE_SER_RESET ; +int i, ret; + + ret =mtk_wed_mcu_send_msg (wo,MTK_WED_MODULE_ID_WO , +MTK_WED_WO_CMD_CHANGE_STATE , &val, +sizeof (val), true); +if (ret) +return ret; + +wed_clr (dev,MTK_WED_WPDMA_RX_D_GLO_CFG ,MTK_WED_WPDMA_RX_D_RX_DRV_EN ); + ret =mtk_wed_poll_busy (dev,MTK_WED_WPDMA_RX_D_GLO_CFG , +MTK_WED_WPDMA_RX_D_RX_DRV_BUSY ); +if (ret) { +mtk_wed_reset (dev,MTK_WED_RESET_WPDMA_INT_AGENT ); +mtk_wed_reset (dev,MTK_WED_RESET_WPDMA_RX_D_DRV ); + }else { +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 ); + +wed_set (dev,MTK_WED_WPDMA_RX_D_GLO_CFG , +MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | +MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE ); +wed_clr (dev,MTK_WED_WPDMA_RX_D_GLO_CFG , +MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | +MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE ); + +wed_w32 (dev,MTK_WED_WPDMA_RX_D_RST_IDX ,0 ); + } + +/* reset rro qm */ +wed_clr (dev,MTK_WED_CTRL ,MTK_WED_CTRL_RX_RRO_QM_EN ); + ret =mtk_wed_poll_busy (dev,MTK_WED_CTRL , +MTK_WED_CTRL_RX_RRO_QM_BUSY ); +if (ret) { +mtk_wed_reset (dev,MTK_WED_RESET_RX_RRO_QM ); + }else { +wed_set (dev,MTK_WED_RROQM_RST_IDX , +MTK_WED_RROQM_RST_IDX_MIOD | +MTK_WED_RROQM_RST_IDX_FDBK ); +wed_w32 (dev,MTK_WED_RROQM_RST_IDX ,0 ); + } + +/* reset route qm */ +wed_clr (dev,MTK_WED_CTRL ,MTK_WED_CTRL_RX_ROUTE_QM_EN ); + ret =mtk_wed_poll_busy (dev,MTK_WED_CTRL , +MTK_WED_CTRL_RX_ROUTE_QM_BUSY ); +if (ret) +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 */ +mtk_wdma_tx_reset (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 ); +mtk_wed_reset (dev,MTK_WED_RESET_WDMA_TX_DRV ); + +/* reset wed rx dma */ + ret =mtk_wed_poll_busy (dev,MTK_WED_GLO_CFG , +MTK_WED_GLO_CFG_RX_DMA_BUSY ); +wed_clr (dev,MTK_WED_GLO_CFG ,MTK_WED_GLO_CFG_RX_DMA_EN ); +if (ret) { +mtk_wed_reset (dev,MTK_WED_RESET_WED_RX_DMA ); + }else { +struct mtk_eth *eth = dev->hw->eth; + +if (MTK_HAS_CAPS (eth->soc->caps,MTK_NETSYS_V2 )) +wed_set (dev,MTK_WED_RESET_IDX , +MTK_WED_RESET_IDX_RX_V2 ); +else +wed_set (dev,MTK_WED_RESET_IDX ,MTK_WED_RESET_IDX_RX ); +wed_w32 (dev,MTK_WED_RESET_IDX ,0 ); + } + +/* 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_reset (dev,MTK_WED_RESET_RX_BM ); + +/* wo change to enable state */ + val =MTK_WED_WO_STATE_ENABLE ; + ret =mtk_wed_mcu_send_msg (wo,MTK_WED_MODULE_ID_WO , +MTK_WED_WO_CMD_CHANGE_STATE , &val, +sizeof (val), true); +if (ret) +return ret; + +/* wed_rx_ring_reset */ +for (i =0 ; i <ARRAY_SIZE (dev->rx_ring); i++) { +if (!dev->rx_ring[i].desc) +continue ; + +mtk_wed_ring_reset (&dev->rx_ring[i],MTK_WED_RX_RING_SIZE , + false); + } +mtk_wed_free_rx_buffer (dev); + +return 0 ; } static void
@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) true); } -if (mtk_wed_poll_busy (dev)) - busy =mtk_wed_check_busy (dev); - +/* 1. reset WED tx DMA */ +wed_clr (dev,MTK_WED_GLO_CFG ,MTK_WED_GLO_CFG_TX_DMA_EN ); + busy =mtk_wed_poll_busy (dev,MTK_WED_GLO_CFG , +MTK_WED_GLO_CFG_TX_DMA_BUSY );if (busy) {mtk_wed_reset (dev,MTK_WED_RESET_WED_TX_DMA ); }else { -wed_w32 (dev,MTK_WED_RESET_IDX , -MTK_WED_RESET_IDX_TX | -MTK_WED_RESET_IDX_RX ); +wed_w32 (dev,MTK_WED_RESET_IDX ,MTK_WED_RESET_IDX_TX );wed_w32 (dev,MTK_WED_RESET_IDX ,0 ); } -mtk_wdma_rx_reset (dev); +/* 2. reset WDMA rx DMA */ + busy = !!mtk_wdma_rx_reset (dev); +wed_clr (dev,MTK_WED_WDMA_GLO_CFG ,MTK_WED_WDMA_GLO_CFG_RX_DRV_EN ); +if (!busy) + busy =mtk_wed_poll_busy (dev,MTK_WED_WDMA_GLO_CFG , +MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY );if (busy) {mtk_wed_reset (dev,MTK_WED_RESET_WDMA_INT_AGENT );
@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); } +/* 3. reset WED WPDMA tx */ +wed_clr (dev,MTK_WED_CTRL ,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 )
@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) }mtk_wed_reset (dev,MTK_WED_RESET_TX_FREE_AGENT ); +wed_clr (dev,MTK_WED_CTRL ,MTK_WED_CTRL_WED_TX_BM_EN );mtk_wed_reset (dev,MTK_WED_RESET_TX_BM ); +/* 4. reset WED WPDMA tx */ + busy =mtk_wed_poll_busy (dev,MTK_WED_WPDMA_GLO_CFG , +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 ); +if (!busy) + busy =mtk_wed_poll_busy (dev,MTK_WED_WPDMA_GLO_CFG , +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 );
@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev) MTK_WED_WPDMA_RESET_IDX_RX);wed_w32 (dev,MTK_WED_WPDMA_RESET_IDX ,0 ); } + + dev->init_done = false; +if (dev->hw->version ==1 ) +return ; + +if (!busy) { +wed_w32 (dev,MTK_WED_RESET_IDX ,MTK_WED_RESET_WPDMA_IDX_RX ); +wed_w32 (dev,MTK_WED_RESET_IDX ,0 ); + } + +mtk_wed_rx_reset (dev); } static int
@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) {int i; +if (mtk_wed_get_rx_capa (dev) &&mtk_wed_rx_buffer_alloc (dev)) +return ; +for (i =0 ; i <ARRAY_SIZE (dev->rx_wdma); i++)if (!dev->rx_wdma[i].desc)mtk_wed_wdma_rx_ring_setup (dev, i,16 );
@@ -1354,10 +1474,6 @@ mtk_wed_attach(struct mtk_wed_device *dev) goto out;if (mtk_wed_get_rx_capa (dev)) { - ret =mtk_wed_rx_buffer_alloc (dev); -if (ret) - goto out; - ret =mtk_wed_rro_alloc (dev);if (ret) goto out;
drivers/net/ethernet/mediatek/mtk_wed_regs.h +9 -0
@@ -22,11 +22,15 @@ 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_TX_FREE_AGENT BIT(4)#define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)#define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) +#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10)#define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11)#define MTK_WED_RESET_WED_TX_DMA BIT(12) +#define MTK_WED_RESET_WED_RX_DMA BIT(13) +#define MTK_WED_RESET_WDMA_TX_DRV BIT(16)#define MTK_WED_RESET_WDMA_RX_DRV BIT(17)#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)#define MTK_WED_RESET_RX_RRO_QM BIT(20)
@@ -156,6 +160,8 @@ struct mtk_wdma_desc {#define MTK_WED_RESET_IDX 0x20c#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)#define MTK_WED_RESET_IDX_RX GENMASK(17, 16) +#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) +#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)#define MTK_WED_TX_MIB (_n) (0x2a0 + (_n) * 4)#define MTK_WED_RX_MIB (_n) (0x2e0 + (_n) * 4)
@@ -265,6 +271,9 @@ struct mtk_wdma_desc {#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) +#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1) +#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3) +#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4)#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
Signature · 1 line
2.38.1
Lorenzo Bianconi
maintainerPATCH 5/5 net: ethernet: mtk_wed: add reset to tx_ring_setup callback
In reply to Lorenzo BianconiIntroduce reset parameter to mtk_wed_tx_ring_setup signature. This is a preliminary patch to add Wireless Ethernet Dispatcher reset support.
--- drivers/net/ethernet/mediatek/mtk_wed.c | 19 +++++++++++-------- drivers/net/wireless/mediatek/mt76/dma.c | 2 +- include/linux/soc/mediatek/mtk_wed.h | 8 ++++---- 3 files changed, 16 insertions(+), 13 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +11 -8
@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, }static int -mtk_wed_wdma_rx_ring_setup (struct mtk_wed_device *dev,int idx,int size) +mtk_wed_wdma_rx_ring_setup (struct mtk_wed_device *dev,int idx,int size, +bool reset) {u32 desc_size =sizeof (struct mtk_wdma_desc ) * dev->hw->version;struct mtk_wed_ring *wdma;
@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)return -EINVAL ; wdma = &dev->rx_wdma[idx]; -if (mtk_wed_ring_alloc (dev, wdma,MTK_WED_WDMA_RING_SIZE , desc_size, - true)) +if (!reset &&mtk_wed_ring_alloc (dev, wdma,MTK_WED_WDMA_RING_SIZE , + desc_size, true))return -ENOMEM ; wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)for (i =0 ; i <ARRAY_SIZE (dev->rx_wdma); i++)if (!dev->rx_wdma[i].desc) -mtk_wed_wdma_rx_ring_setup (dev, i,16 ); +mtk_wed_wdma_rx_ring_setup (dev, i,16 , false);mtk_wed_hw_init (dev);mtk_wed_configure_irq (dev, irq_mask);
@@ -1495,7 +1496,8 @@ mtk_wed_attach(struct mtk_wed_device *dev) }static int -mtk_wed_tx_ring_setup (struct mtk_wed_device *dev,int idx,void __iomem *regs) +mtk_wed_tx_ring_setup (struct mtk_wed_device *dev,int idx,void __iomem *regs, +bool reset) {struct mtk_wed_ring *ring = &dev->tx_ring[idx];
@@ -1514,11 +1516,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)if (WARN_ON (idx >=ARRAY_SIZE (dev->tx_ring)))return -EINVAL ; -if (mtk_wed_ring_alloc (dev, ring,MTK_WED_TX_RING_SIZE , -sizeof (*ring->desc), true)) +if (!reset &&mtk_wed_ring_alloc (dev, ring,MTK_WED_TX_RING_SIZE , +sizeof (*ring->desc), true))return -ENOMEM ; -if (mtk_wed_wdma_rx_ring_setup (dev, idx,MTK_WED_WDMA_RING_SIZE )) +if (mtk_wed_wdma_rx_ring_setup (dev, idx,MTK_WED_WDMA_RING_SIZE , + reset))return -ENOMEM ; ring->reg_base =MTK_WED_RING_TX (idx);
drivers/net/wireless/mediatek/mt76/dma.c +1 -1
@@ -632,7 +632,7 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)switch (type) {case MT76_WED_Q_TX : - ret =mtk_wed_device_tx_ring_setup (wed, ring, q->regs); + ret =mtk_wed_device_tx_ring_setup (wed, ring, q->regs, false);if (!ret) q->wed_regs = wed->tx_ring[ring].reg_base;break ;
include/linux/soc/mediatek/mtk_wed.h +4 -4
@@ -155,7 +155,7 @@ struct mtk_wed_device {struct mtk_wed_ops {int (*attach)(struct mtk_wed_device *dev);int (*tx_ring_setup)(struct mtk_wed_device *dev,int ring, -void __iomem *regs); +void __iomem *regs,bool reset);int (*rx_ring_setup)(struct mtk_wed_device *dev,int ring,void __iomem *regs); int (*txfree_ring_setup)(struct mtk_wed_device *dev,
@@ -213,8 +213,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)#define mtk_wed_device_active (_dev) !!(_dev)->ops#define mtk_wed_device_detach (_dev) (_dev)->ops->detach(_dev)#define mtk_wed_device_start (_dev, _mask) (_dev)->ops->start(_dev, _mask) -#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs) \ - (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) +#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs, _reset) \ + (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)#define mtk_wed_device_txfree_ring_setup (_dev, _regs) \ (_dev)->ops->txfree_ring_setup(_dev, _regs)#define mtk_wed_device_reg_read (_dev, _reg) \
@@ -240,7 +240,7 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) }#define mtk_wed_device_detach (_dev) do {} while (0)#define mtk_wed_device_start (_dev, _mask) do {} while (0) -#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs) -ENODEV +#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs, _reset) -ENODEV#define mtk_wed_device_txfree_ring_setup (_dev, _ring, _regs) -ENODEV#define mtk_wed_device_reg_read (_dev, _reg) 0#define mtk_wed_device_reg_write (_dev, _reg, _val) do {} while (0)
Signature · 1 line
2.38.1
Jakub Kicinski
maintainerRe: [PATCH net-next 5/5] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
include/linux/soc/mediatek/mtk_wed.h mtk_wed_get_rx_capa(struct mtk_wed_device *dev) · line 217
Quoted 2 lines · On Mon, 21 Nov 2022 09:59:25 +0100 Lorenzo Bianconi wrote:
include/linux/soc/mediatek/mtk_wed.h +2
-0+#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs, _reset) \ + (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
FWIW I find the "op macros" quite painful when trying to read a driver I'm not familiar with. stmmac does this, too. Just letting you know, it is what it is.
Lorenzo Bianconi
maintainerRe: [PATCH net-next 5/5] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
Quoted 7 lines · On Mon, 21 Nov 2022 09:59:25 +0100 Lorenzo Bianconi wrote:
include/linux/soc/mediatek/mtk_wed.h mtk_wed_get_rx_capa(struct mtk_wed_device *dev) · line 217
Quoted 2 lines
include/linux/soc/mediatek/mtk_wed.h +2
-0+#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs, _reset) \ + (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)FWIW I find the "op macros" quite painful when trying to read a driver I'm not familiar with. stmmac does this, too. Just letting you know, it is what it is.
ack, fine. I maintained the approach currently used in the driver. Do you prefer to run the function pointer directly?
Regards,
Lorenzo
Jakub Kicinski
maintainerRe: [PATCH net-next 5/5] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
Quoted 10 lines · On Mon, 21 Nov 2022 22:18:33 +0100 Lorenzo Bianconi wrote:
Quoted 7 lines · On Mon, 21 Nov 2022 09:59:25 +0100 Lorenzo Bianconi wrote:
include/linux/soc/mediatek/mtk_wed.h mtk_wed_get_rx_capa(struct mtk_wed_device *dev) · line 217
Quoted 2 lines
include/linux/soc/mediatek/mtk_wed.h +2
-0+#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs, _reset) \ + (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)FWIW I find the "op macros" quite painful when trying to read a driver I'm not familiar with. stmmac does this, too. Just letting you know, it is what it is.
ack, fine. I maintained the approach currently used in the driver. Do you prefer to run the function pointer directly?
That's a tiny bit better, yes, saves the reader one lookup.
Are the ops here serving as a HAL or a way of breaking the dependency between the SoC/Eth and the WiFi drivers?
Felix Fietkau
maintainerRe: [PATCH net-next 5/5] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
Quoted 9 lines · Jakub Kicinski
Quoted 8 lines · On Mon, 21 Nov 2022 22:18:33 +0100 Lorenzo Bianconi wrote:
Quoted 7 lines · On Mon, 21 Nov 2022 09:59:25 +0100 Lorenzo Bianconi wrote:
include/linux/soc/mediatek/mtk_wed.h mtk_wed_get_rx_capa(struct mtk_wed_device *dev) · line 217
Quoted 2 lines
include/linux/soc/mediatek/mtk_wed.h +2
-0+#define mtk_wed_device_tx_ring_setup (_dev, _ring, _regs, _reset) \ + (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)FWIW I find the "op macros" quite painful when trying to read a driver I'm not familiar with. stmmac does this, too. Just letting you know, it is what it is.
Quoted 7 lines
Quoted 2 lines
ack, fine. I maintained the approach currently used in the driver. Do you prefer to run the function pointer directly?
That's a tiny bit better, yes, saves the reader one lookup.
Are the ops here serving as a HAL or a way of breaking the dependency between the SoC/Eth and the WiFi drivers?
The latter. For a multi-platform kernel it's important that the wifi driver does not depend on mtk_eth_soc directly, even when support for WED is enabled.
- Felix
Jakub Kicinski
maintainerRe: [PATCH net-next 5/5] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
Quoted 7 lines · On Tue, 22 Nov 2022 10:41:28 +0100 Felix Fietkau wrote:
Quoted 4 lines
That's a tiny bit better, yes, saves the reader one lookup.
Are the ops here serving as a HAL or a way of breaking the dependency between the SoC/Eth and the WiFi drivers?
The latter. For a multi-platform kernel it's important that the wifi driver does not depend on
mtk_eth_socdirectly, even when support for WED is enabled.
Ah, I see, that's more legit. In the stmmac case it was just a poorly designed abstraction. I'll try to remember not to complain again.