Commit e2f64db1 authored by Sujuan Chen's avatar Sujuan Chen Committed by Paolo Abeni

net: ethernet: mtk_wed: introduce WED support for MT7988

Similar to MT7986 and MT7622, enable Wireless Ethernet Ditpatcher for
MT7988 in order to offload traffic forwarded from LAN/WLAN to WLAN/LAN
Co-developed-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarSujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 9ae7eca9
...@@ -197,6 +197,7 @@ static const struct mtk_reg_map mt7988_reg_map = { ...@@ -197,6 +197,7 @@ static const struct mtk_reg_map mt7988_reg_map = {
.wdma_base = { .wdma_base = {
[0] = 0x4800, [0] = 0x4800,
[1] = 0x4c00, [1] = 0x4c00,
[2] = 0x5000,
}, },
.pse_iq_sta = 0x0180, .pse_iq_sta = 0x0180,
.pse_oq_sta = 0x01a0, .pse_oq_sta = 0x01a0,
......
...@@ -1132,7 +1132,7 @@ struct mtk_reg_map { ...@@ -1132,7 +1132,7 @@ struct mtk_reg_map {
u32 gdm1_cnt; u32 gdm1_cnt;
u32 gdma_to_ppe; u32 gdma_to_ppe;
u32 ppe_base; u32 ppe_base;
u32 wdma_base[2]; u32 wdma_base[3];
u32 pse_iq_sta; u32 pse_iq_sta;
u32 pse_oq_sta; u32 pse_oq_sta;
}; };
......
...@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, ...@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
case 1: case 1:
pse_port = PSE_WDMA1_PORT; pse_port = PSE_WDMA1_PORT;
break; break;
case 2:
pse_port = PSE_WDMA2_PORT;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
......
This diff is collapsed.
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include "mtk_wed_regs.h"
struct mtk_eth; struct mtk_eth;
struct mtk_wed_wo; struct mtk_wed_wo;
...@@ -19,6 +21,7 @@ struct mtk_wed_soc_data { ...@@ -19,6 +21,7 @@ struct mtk_wed_soc_data {
u32 reset_idx_tx_mask; u32 reset_idx_tx_mask;
u32 reset_idx_rx_mask; u32 reset_idx_rx_mask;
} regmap; } regmap;
u32 tx_ring_desc_size;
u32 wdma_desc_size; u32 wdma_desc_size;
}; };
...@@ -35,6 +38,7 @@ struct mtk_wed_hw { ...@@ -35,6 +38,7 @@ struct mtk_wed_hw {
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
struct mtk_wed_device *wed_dev; struct mtk_wed_device *wed_dev;
struct mtk_wed_wo *wed_wo; struct mtk_wed_wo *wed_wo;
u32 pcie_base;
u32 debugfs_reg; u32 debugfs_reg;
u32 num_flows; u32 num_flows;
u8 version; u8 version;
...@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw) ...@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw)
return hw->version == 2; return hw->version == 2;
} }
static inline bool mtk_wed_is_v3(struct mtk_wed_hw *hw)
{
return hw->version == 3;
}
static inline bool mtk_wed_is_v3_or_greater(struct mtk_wed_hw *hw)
{
return hw->version > 2;
}
static inline void static inline void
wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val) wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
{ {
...@@ -143,6 +157,21 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val) ...@@ -143,6 +157,21 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
writel(val, dev->txfree_ring.wpdma + reg); writel(val, dev->txfree_ring.wpdma + reg);
} }
static inline u32 mtk_wed_get_pcie_base(struct mtk_wed_device *dev)
{
if (!mtk_wed_is_v3_or_greater(dev->hw))
return MTK_WED_PCIE_BASE;
switch (dev->hw->index) {
case 1:
return MTK_WED_PCIE_BASE1;
case 2:
return MTK_WED_PCIE_BASE2;
default:
return MTK_WED_PCIE_BASE0;
}
}
void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
void __iomem *wdma, phys_addr_t wdma_phy, void __iomem *wdma, phys_addr_t wdma_phy,
int index); int index);
......
...@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) ...@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
wo->hw->index + 1); wo->hw->index + 1);
/* load firmware */ /* load firmware */
if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed")) switch (wo->hw->version) {
fw_name = MT7981_FIRMWARE_WO; case 2:
else if (of_device_is_compatible(wo->hw->node,
fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; "mediatek,mt7981-wed"))
fw_name = MT7981_FIRMWARE_WO;
else
fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1
: MT7986_FIRMWARE_WO0;
break;
case 3:
fw_name = wo->hw->index ? MT7988_FIRMWARE_WO1
: MT7988_FIRMWARE_WO0;
break;
default:
return -EINVAL;
}
ret = request_firmware(&fw, fw_name, wo->hw->dev); ret = request_firmware(&fw, fw_name, wo->hw->dev);
if (ret) if (ret)
...@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) ...@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
} }
/* set the start address */ /* set the start address */
boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
: MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR;
else
boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
/* wo firmware reset */ /* wo firmware reset */
wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR); val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
: MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
out: out:
release_firmware(fw); release_firmware(fw);
...@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *wo) ...@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *wo)
MODULE_FIRMWARE(MT7981_FIRMWARE_WO); MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
MODULE_FIRMWARE(MT7988_FIRMWARE_WO0);
MODULE_FIRMWARE(MT7988_FIRMWARE_WO1);
...@@ -91,6 +91,8 @@ enum mtk_wed_dummy_cr_idx { ...@@ -91,6 +91,8 @@ enum mtk_wed_dummy_cr_idx {
#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
#define MTK_WO_MCU_CFG_LS_BASE 0 #define MTK_WO_MCU_CFG_LS_BASE 0
#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
......
...@@ -138,6 +138,8 @@ struct mtk_wed_device { ...@@ -138,6 +138,8 @@ struct mtk_wed_device {
u32 wpdma_rx; u32 wpdma_rx;
bool wcid_512; bool wcid_512;
bool hw_rro;
bool msi;
u16 token_start; u16 token_start;
unsigned int nbuf; unsigned int nbuf;
...@@ -211,10 +213,12 @@ mtk_wed_device_attach(struct mtk_wed_device *dev) ...@@ -211,10 +213,12 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
return ret; return ret;
} }
static inline bool static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
{ {
#ifdef CONFIG_NET_MEDIATEK_SOC_WED #ifdef CONFIG_NET_MEDIATEK_SOC_WED
if (dev->version == 3)
return dev->wlan.hw_rro;
return dev->version != 1; return dev->version != 1;
#else #else
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment