Commit 5bed8d58 authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'add-wed-support-for-mt7988-chipset'

Lorenzo Bianconi says:

====================
Add WED support for MT7988 chipset

Similar to MT7622 and MT7986, introduce Wireless Ethernet Dispatcher (WED)
support for MT7988 chipset in order to offload to the hw packet engine traffic
received from LAN/WAN device to WLAN nic (MT7996E).
Add WED RX support in order to offload traffic received by WLAN nic to the
wired interfaces (LAN/WAN).
====================

Link: https://lore.kernel.org/r/cover.1695032290.git.lorenzo@kernel.orgSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents fa17a6d8 1543b8ff
...@@ -22,6 +22,7 @@ properties: ...@@ -22,6 +22,7 @@ properties:
- mediatek,mt7622-wed - mediatek,mt7622-wed
- mediatek,mt7981-wed - mediatek,mt7981-wed
- mediatek,mt7986-wed - mediatek,mt7986-wed
- mediatek,mt7988-wed
- const: syscon - const: syscon
reg: reg:
......
...@@ -20,6 +20,7 @@ properties: ...@@ -20,6 +20,7 @@ properties:
items: items:
- enum: - enum:
- mediatek,mt7986-wo-ccif - mediatek,mt7986-wo-ccif
- mediatek,mt7988-wo-ccif
- const: syscon - const: syscon
reg: reg:
......
...@@ -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;
}; };
......
...@@ -425,7 +425,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, ...@@ -425,7 +425,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
} }
int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
int wdma_idx, int txq, int bss, int wcid) int wdma_idx, int txq, int bss, int wcid,
bool amsdu_en)
{ {
struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
u32 *ib2 = mtk_foe_entry_ib2(eth, entry); u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
...@@ -437,6 +438,7 @@ int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, ...@@ -437,6 +438,7 @@ int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
MTK_FOE_IB2_WDMA_WINFO_V2; MTK_FOE_IB2_WDMA_WINFO_V2;
l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
l2->amsdu = FIELD_PREP(MTK_FOE_WINFO_AMSDU_EN, amsdu_en);
break; break;
case 2: case 2:
*ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
......
...@@ -88,13 +88,13 @@ enum { ...@@ -88,13 +88,13 @@ enum {
#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) #define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) #define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) #define MTK_FOE_WINFO_AMSDU_USR_INFO GENMASK(15, 0)
#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) #define MTK_FOE_WINFO_AMSDU_TID GENMASK(19, 16)
#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) #define MTK_FOE_WINFO_AMSDU_IS_FIXEDRATE BIT(20)
#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) #define MTK_FOE_WINFO_AMSDU_IS_PRIOR BIT(21)
#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) #define MTK_FOE_WINFO_AMSDU_IS_SP BIT(22)
#define MTK_FOE_WINFO_PAO_HF BIT(23) #define MTK_FOE_WINFO_AMSDU_HF BIT(23)
#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) #define MTK_FOE_WINFO_AMSDU_EN BIT(24)
enum { enum {
MTK_FOE_STATE_INVALID, MTK_FOE_STATE_INVALID,
...@@ -123,7 +123,7 @@ struct mtk_foe_mac_info { ...@@ -123,7 +123,7 @@ struct mtk_foe_mac_info {
/* netsys_v3 */ /* netsys_v3 */
u32 w3info; u32 w3info;
u32 wpao; u32 amsdu;
}; };
/* software-only entry type */ /* software-only entry type */
...@@ -392,7 +392,8 @@ int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, ...@@ -392,7 +392,8 @@ int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry,
int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
int sid); int sid);
int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
int wdma_idx, int txq, int bss, int wcid); int wdma_idx, int txq, int bss, int wcid,
bool amsdu_en);
int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
unsigned int queue); unsigned int queue);
int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
......
...@@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i ...@@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
info->queue = path->mtk_wdma.queue; info->queue = path->mtk_wdma.queue;
info->bss = path->mtk_wdma.bss; info->bss = path->mtk_wdma.bss;
info->wcid = path->mtk_wdma.wcid; info->wcid = path->mtk_wdma.wcid;
info->amsdu = path->mtk_wdma.amsdu;
return 0; return 0;
} }
...@@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, ...@@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
info.bss, info.wcid); info.bss, info.wcid, info.amsdu);
if (mtk_is_netsys_v2_or_greater(eth)) { if (mtk_is_netsys_v2_or_greater(eth)) {
switch (info.wdma_idx) { switch (info.wdma_idx) {
case 0: case 0:
...@@ -201,6 +202,9 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, ...@@ -201,6 +202,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,10 +9,29 @@ ...@@ -9,10 +9,29 @@
#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;
struct mtk_wed_soc_data {
struct {
u32 tx_bm_tkid;
u32 wpdma_rx_ring0;
u32 reset_idx_tx_mask;
u32 reset_idx_rx_mask;
} regmap;
u32 tx_ring_desc_size;
u32 wdma_desc_size;
};
struct mtk_wed_amsdu {
void *txd;
dma_addr_t txd_phy;
};
struct mtk_wed_hw { struct mtk_wed_hw {
const struct mtk_wed_soc_data *soc;
struct device_node *node; struct device_node *node;
struct mtk_eth *eth; struct mtk_eth *eth;
struct regmap *regs; struct regmap *regs;
...@@ -24,6 +43,8 @@ struct mtk_wed_hw { ...@@ -24,6 +43,8 @@ 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;
struct mtk_wed_amsdu *wed_amsdu;
u32 pcie_base;
u32 debugfs_reg; u32 debugfs_reg;
u32 num_flows; u32 num_flows;
u8 version; u8 version;
...@@ -37,9 +58,30 @@ struct mtk_wdma_info { ...@@ -37,9 +58,30 @@ struct mtk_wdma_info {
u8 queue; u8 queue;
u16 wcid; u16 wcid;
u8 bss; u8 bss;
u8 amsdu;
}; };
#ifdef CONFIG_NET_MEDIATEK_SOC_WED #ifdef CONFIG_NET_MEDIATEK_SOC_WED
static inline bool mtk_wed_is_v1(struct mtk_wed_hw *hw)
{
return hw->version == 1;
}
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 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)
{ {
...@@ -122,6 +164,21 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val) ...@@ -122,6 +164,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);
......
...@@ -16,14 +16,30 @@ ...@@ -16,14 +16,30 @@
#include "mtk_wed_wo.h" #include "mtk_wed_wo.h"
#include "mtk_wed.h" #include "mtk_wed.h"
static struct mtk_wed_wo_memory_region mem_region[] = {
[MTK_WED_WO_REGION_EMI] = {
.name = "wo-emi",
},
[MTK_WED_WO_REGION_ILM] = {
.name = "wo-ilm",
},
[MTK_WED_WO_REGION_DATA] = {
.name = "wo-data",
.shared = true,
},
[MTK_WED_WO_REGION_BOOT] = {
.name = "wo-boot",
},
};
static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
{ {
return readl(wo->boot.addr + reg); return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
} }
static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
{ {
writel(val, wo->boot.addr + reg); writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
} }
static struct sk_buff * static struct sk_buff *
...@@ -207,7 +223,7 @@ int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, ...@@ -207,7 +223,7 @@ int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,
{ {
struct mtk_wed_wo *wo = dev->hw->wed_wo; struct mtk_wed_wo *wo = dev->hw->wed_wo;
if (dev->hw->version == 1) if (!mtk_wed_get_rx_capa(dev))
return 0; return 0;
if (WARN_ON(!wo)) if (WARN_ON(!wo))
...@@ -218,19 +234,13 @@ int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, ...@@ -218,19 +234,13 @@ int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,
} }
static int static int
mtk_wed_get_memory_region(struct mtk_wed_wo *wo, mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index,
struct mtk_wed_wo_memory_region *region) struct mtk_wed_wo_memory_region *region)
{ {
struct reserved_mem *rmem; struct reserved_mem *rmem;
struct device_node *np; struct device_node *np;
int index;
index = of_property_match_string(wo->hw->node, "memory-region-names", np = of_parse_phandle(hw->node, "memory-region", index);
region->name);
if (index < 0)
return index;
np = of_parse_phandle(wo->hw->node, "memory-region", index);
if (!np) if (!np)
return -ENODEV; return -ENODEV;
...@@ -242,7 +252,7 @@ mtk_wed_get_memory_region(struct mtk_wed_wo *wo, ...@@ -242,7 +252,7 @@ mtk_wed_get_memory_region(struct mtk_wed_wo *wo,
region->phy_addr = rmem->base; region->phy_addr = rmem->base;
region->size = rmem->size; region->size = rmem->size;
region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size); region->addr = devm_ioremap(hw->dev, region->phy_addr, region->size);
return !region->addr ? -EINVAL : 0; return !region->addr ? -EINVAL : 0;
} }
...@@ -255,6 +265,9 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw, ...@@ -255,6 +265,9 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw,
const struct mtk_wed_fw_trailer *trailer; const struct mtk_wed_fw_trailer *trailer;
const struct mtk_wed_fw_region *fw_region; const struct mtk_wed_fw_region *fw_region;
if (!region->phy_addr || !region->size)
return 0;
trailer_ptr = fw->data + fw->size - sizeof(*trailer); trailer_ptr = fw->data + fw->size - sizeof(*trailer);
trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr; trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr;
region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region); region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region);
...@@ -294,18 +307,6 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw, ...@@ -294,18 +307,6 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw,
static int static int
mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
{ {
static struct mtk_wed_wo_memory_region mem_region[] = {
[MTK_WED_WO_REGION_EMI] = {
.name = "wo-emi",
},
[MTK_WED_WO_REGION_ILM] = {
.name = "wo-ilm",
},
[MTK_WED_WO_REGION_DATA] = {
.name = "wo-data",
.shared = true,
},
};
const struct mtk_wed_fw_trailer *trailer; const struct mtk_wed_fw_trailer *trailer;
const struct firmware *fw; const struct firmware *fw;
const char *fw_name; const char *fw_name;
...@@ -314,25 +315,38 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) ...@@ -314,25 +315,38 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
/* load firmware region metadata */ /* load firmware region metadata */
for (i = 0; i < ARRAY_SIZE(mem_region); i++) { for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
ret = mtk_wed_get_memory_region(wo, &mem_region[i]); int index = of_property_match_string(wo->hw->node,
if (ret) "memory-region-names",
return ret; mem_region[i].name);
} if (index < 0)
continue;
wo->boot.name = "wo-boot"; ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]);
ret = mtk_wed_get_memory_region(wo, &wo->boot);
if (ret) if (ret)
return ret; return ret;
}
/* set dummy cr */ /* set dummy cr */
wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL, wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL,
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) {
case 2:
if (of_device_is_compatible(wo->hw->node,
"mediatek,mt7981-wed"))
fw_name = MT7981_FIRMWARE_WO; fw_name = MT7981_FIRMWARE_WO;
else else
fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; 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)
...@@ -353,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) ...@@ -353,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);
...@@ -396,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *wo) ...@@ -396,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)
...@@ -228,7 +230,6 @@ struct mtk_wed_wo_queue { ...@@ -228,7 +230,6 @@ struct mtk_wed_wo_queue {
struct mtk_wed_wo { struct mtk_wed_wo {
struct mtk_wed_hw *hw; struct mtk_wed_hw *hw;
struct mtk_wed_wo_memory_region boot;
struct mtk_wed_wo_queue q_tx; struct mtk_wed_wo_queue q_tx;
struct mtk_wed_wo_queue q_rx; struct mtk_wed_wo_queue q_rx;
......
...@@ -591,7 +591,7 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed) ...@@ -591,7 +591,7 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
{ {
struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc; struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
struct mt76_txwi_cache *t = NULL; struct mt76_txwi_cache *t = NULL;
struct mt7915_dev *dev; struct mt7915_dev *dev;
struct mt76_queue *q; struct mt76_queue *q;
......
...@@ -919,6 +919,7 @@ struct net_device_path { ...@@ -919,6 +919,7 @@ struct net_device_path {
u8 queue; u8 queue;
u16 wcid; u16 wcid;
u8 bss; u8 bss;
u8 amsdu;
} mtk_wdma; } mtk_wdma;
}; };
}; };
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define MTK_WED_TX_QUEUES 2 #define MTK_WED_TX_QUEUES 2
#define MTK_WED_RX_QUEUES 2 #define MTK_WED_RX_QUEUES 2
#define MTK_WED_RX_PAGE_QUEUES 3
#define WED_WO_STA_REC 0x6 #define WED_WO_STA_REC 0x6
...@@ -45,7 +46,7 @@ enum mtk_wed_wo_cmd { ...@@ -45,7 +46,7 @@ enum mtk_wed_wo_cmd {
MTK_WED_WO_CMD_WED_END MTK_WED_WO_CMD_WED_END
}; };
struct mtk_rxbm_desc { struct mtk_wed_bm_desc {
__le32 buf0; __le32 buf0;
__le32 token; __le32 token;
} __packed __aligned(4); } __packed __aligned(4);
...@@ -76,6 +77,11 @@ struct mtk_wed_wo_rx_stats { ...@@ -76,6 +77,11 @@ struct mtk_wed_wo_rx_stats {
__le32 rx_drop_cnt; __le32 rx_drop_cnt;
}; };
struct mtk_wed_buf {
void *p;
dma_addr_t phy_addr;
};
struct mtk_wed_device { struct mtk_wed_device {
#ifdef CONFIG_NET_MEDIATEK_SOC_WED #ifdef CONFIG_NET_MEDIATEK_SOC_WED
const struct mtk_wed_ops *ops; const struct mtk_wed_ops *ops;
...@@ -94,17 +100,20 @@ struct mtk_wed_device { ...@@ -94,17 +100,20 @@ struct mtk_wed_device {
struct mtk_wed_ring txfree_ring; struct mtk_wed_ring txfree_ring;
struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES];
struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES];
struct mtk_wed_ring ind_cmd_ring;
struct { struct {
int size; int size;
void **pages; struct mtk_wed_buf *pages;
struct mtk_wdma_desc *desc; struct mtk_wdma_desc *desc;
dma_addr_t desc_phys; dma_addr_t desc_phys;
} tx_buf_ring; } tx_buf_ring;
struct { struct {
int size; int size;
struct mtk_rxbm_desc *desc; struct mtk_wed_bm_desc *desc;
dma_addr_t desc_phys; dma_addr_t desc_phys;
} rx_buf_ring; } rx_buf_ring;
...@@ -114,6 +123,13 @@ struct mtk_wed_device { ...@@ -114,6 +123,13 @@ struct mtk_wed_device {
dma_addr_t fdbk_phys; dma_addr_t fdbk_phys;
} rro; } rro;
struct {
int size;
struct mtk_wed_buf *pages;
struct mtk_wed_bm_desc *desc;
dma_addr_t desc_phys;
} hw_rro;
/* filled by driver: */ /* filled by driver: */
struct { struct {
union { union {
...@@ -123,6 +139,7 @@ struct mtk_wed_device { ...@@ -123,6 +139,7 @@ struct mtk_wed_device {
enum mtk_wed_bus_tye bus_type; enum mtk_wed_bus_tye bus_type;
void __iomem *base; void __iomem *base;
u32 phy_base; u32 phy_base;
u32 id;
u32 wpdma_phys; u32 wpdma_phys;
u32 wpdma_int; u32 wpdma_int;
...@@ -131,18 +148,35 @@ struct mtk_wed_device { ...@@ -131,18 +148,35 @@ struct mtk_wed_device {
u32 wpdma_txfree; u32 wpdma_txfree;
u32 wpdma_rx_glo; u32 wpdma_rx_glo;
u32 wpdma_rx; u32 wpdma_rx;
u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
u32 wpdma_rx_pg;
bool wcid_512; bool wcid_512;
bool hw_rro;
bool msi;
u16 token_start; u16 token_start;
unsigned int nbuf; unsigned int nbuf;
unsigned int rx_nbuf; unsigned int rx_nbuf;
unsigned int rx_npkt; unsigned int rx_npkt;
unsigned int rx_size; unsigned int rx_size;
unsigned int amsdu_max_len;
u8 tx_tbit[MTK_WED_TX_QUEUES]; u8 tx_tbit[MTK_WED_TX_QUEUES];
u8 rx_tbit[MTK_WED_RX_QUEUES]; u8 rx_tbit[MTK_WED_RX_QUEUES];
u8 rro_rx_tbit[MTK_WED_RX_QUEUES];
u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES];
u8 txfree_tbit; u8 txfree_tbit;
u8 amsdu_max_subframes;
struct {
u8 se_group_nums;
u16 win_size;
u16 particular_sid;
u32 ack_sn_addr;
dma_addr_t particular_se_phys;
dma_addr_t addr_elem_phys[1024];
} ind_cmd;
u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
int (*offload_enable)(struct mtk_wed_device *wed); int (*offload_enable)(struct mtk_wed_device *wed);
...@@ -182,6 +216,14 @@ struct mtk_wed_ops { ...@@ -182,6 +216,14 @@ struct mtk_wed_ops {
void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
enum tc_setup_type type, void *type_data); enum tc_setup_type type, void *type_data);
void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask,
bool reset);
void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs);
void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs);
int (*ind_rx_ring_setup)(struct mtk_wed_device *dev,
void __iomem *regs);
}; };
extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
...@@ -206,16 +248,27 @@ mtk_wed_device_attach(struct mtk_wed_device *dev) ...@@ -206,16 +248,27 @@ 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;
#endif #endif
} }
static inline bool mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev)
{
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
return dev->version == 3;
#else
return false;
#endif
}
#ifdef CONFIG_NET_MEDIATEK_SOC_WED #ifdef CONFIG_NET_MEDIATEK_SOC_WED
#define mtk_wed_device_active(_dev) !!(_dev)->ops #define mtk_wed_device_active(_dev) !!(_dev)->ops
#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
...@@ -242,6 +295,15 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev) ...@@ -242,6 +295,15 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \
(_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data)
#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) \
(_dev)->ops->start_hw_rro(_dev, _mask, _reset)
#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
(_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
(_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs)
#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \
(_dev)->ops->ind_rx_ring_setup(_dev, _regs)
#else #else
static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
{ {
...@@ -261,6 +323,10 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) ...@@ -261,6 +323,10 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
#define mtk_wed_device_stop(_dev) do {} while (0) #define mtk_wed_device_stop(_dev) do {} while (0)
#define mtk_wed_device_dma_reset(_dev) do {} while (0) #define mtk_wed_device_dma_reset(_dev) do {} while (0)
#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP
#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) do {} while (0)
#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
#endif #endif
#endif #endif
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