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 = {
.wdma_base = {
[0] = 0x4800,
[1] = 0x4c00,
[2] = 0x5000,
},
.pse_iq_sta = 0x0180,
.pse_oq_sta = 0x01a0,
......
......@@ -1132,7 +1132,7 @@ struct mtk_reg_map {
u32 gdm1_cnt;
u32 gdma_to_ppe;
u32 ppe_base;
u32 wdma_base[2];
u32 wdma_base[3];
u32 pse_iq_sta;
u32 pse_oq_sta;
};
......
......@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
case 1:
pse_port = PSE_WDMA1_PORT;
break;
case 2:
pse_port = PSE_WDMA2_PORT;
break;
default:
return -EINVAL;
}
......
This diff is collapsed.
......@@ -9,6 +9,8 @@
#include <linux/regmap.h>
#include <linux/netdevice.h>
#include "mtk_wed_regs.h"
struct mtk_eth;
struct mtk_wed_wo;
......@@ -19,6 +21,7 @@ struct mtk_wed_soc_data {
u32 reset_idx_tx_mask;
u32 reset_idx_rx_mask;
} regmap;
u32 tx_ring_desc_size;
u32 wdma_desc_size;
};
......@@ -35,6 +38,7 @@ struct mtk_wed_hw {
struct dentry *debugfs_dir;
struct mtk_wed_device *wed_dev;
struct mtk_wed_wo *wed_wo;
u32 pcie_base;
u32 debugfs_reg;
u32 num_flows;
u8 version;
......@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw)
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
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)
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 __iomem *wdma, phys_addr_t wdma_phy,
int index);
......
......@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
wo->hw->index + 1);
/* load firmware */
if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
fw_name = MT7981_FIRMWARE_WO;
else
fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
switch (wo->hw->version) {
case 2:
if (of_device_is_compatible(wo->hw->node,
"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);
if (ret)
......@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
}
/* set the start address */
boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR
: MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
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 firmware reset */
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->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;
val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
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);
out:
release_firmware(fw);
......@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *wo)
MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
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 {
#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.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_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
......
......@@ -138,6 +138,8 @@ struct mtk_wed_device {
u32 wpdma_rx;
bool wcid_512;
bool hw_rro;
bool msi;
u16 token_start;
unsigned int nbuf;
......@@ -211,10 +213,12 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
return ret;
}
static inline bool
mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
{
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
if (dev->version == 3)
return dev->wlan.hw_rro;
return dev->version != 1;
#else
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