284 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/* Copyright (C) 2022 Lorenzo Bianconi <lorenzo@kernel.org> */3 4#ifndef __MTK_WED_WO_H5#define __MTK_WED_WO_H6 7#include <linux/skbuff.h>8#include <linux/netdevice.h>9 10struct mtk_wed_hw;11 12struct mtk_wed_mcu_hdr {13 /* DW0 */14 u8 version;15 u8 cmd;16 __le16 length;17 18 /* DW1 */19 __le16 seq;20 __le16 flag;21 22 /* DW2 */23 __le32 status;24 25 /* DW3 */26 u8 rsv[20];27};28 29struct mtk_wed_wo_log_info {30 __le32 sn;31 __le32 total;32 __le32 rro;33 __le32 mod;34};35 36enum mtk_wed_wo_event {37 MTK_WED_WO_EVT_LOG_DUMP = 0x1,38 MTK_WED_WO_EVT_PROFILING = 0x2,39 MTK_WED_WO_EVT_RXCNT_INFO = 0x3,40};41 42#define MTK_WED_MODULE_ID_WO 143#define MTK_FW_DL_TIMEOUT 4000000 /* us */44#define MTK_WOCPU_TIMEOUT 2000000 /* us */45 46enum {47 MTK_WED_WARP_CMD_FLAG_RSP = BIT(0),48 MTK_WED_WARP_CMD_FLAG_NEED_RSP = BIT(1),49 MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2),50};51 52#define MTK_WED_WO_CPU_MCUSYS_RESET_ADDR 0x1519405053#define MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK 0x2054#define MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK 0x155 56enum {57 MTK_WED_WO_REGION_EMI,58 MTK_WED_WO_REGION_ILM,59 MTK_WED_WO_REGION_DATA,60 MTK_WED_WO_REGION_BOOT,61 __MTK_WED_WO_REGION_MAX,62};63 64enum mtk_wed_wo_state {65 MTK_WED_WO_STATE_UNDEFINED,66 MTK_WED_WO_STATE_INIT,67 MTK_WED_WO_STATE_ENABLE,68 MTK_WED_WO_STATE_DISABLE,69 MTK_WED_WO_STATE_HALT,70 MTK_WED_WO_STATE_GATING,71 MTK_WED_WO_STATE_SER_RESET,72 MTK_WED_WO_STATE_WF_RESET,73};74 75enum mtk_wed_wo_done_state {76 MTK_WED_WOIF_UNDEFINED,77 MTK_WED_WOIF_DISABLE_DONE,78 MTK_WED_WOIF_TRIGGER_ENABLE,79 MTK_WED_WOIF_ENABLE_DONE,80 MTK_WED_WOIF_TRIGGER_GATING,81 MTK_WED_WOIF_GATING_DONE,82 MTK_WED_WOIF_TRIGGER_HALT,83 MTK_WED_WOIF_HALT_DONE,84};85 86enum mtk_wed_dummy_cr_idx {87 MTK_WED_DUMMY_CR_FWDL,88 MTK_WED_DUMMY_CR_WO_STATUS,89};90 91#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"92#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"93#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"94#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin"95#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin"96 97#define MTK_WO_MCU_CFG_LS_BASE 098#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)99#define MTK_WO_MCU_CFG_LS_FW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x004)100#define MTK_WO_MCU_CFG_LS_CFG_DBG1_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x00c)101#define MTK_WO_MCU_CFG_LS_CFG_DBG2_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x010)102#define MTK_WO_MCU_CFG_LS_WF_MCCR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x014)103#define MTK_WO_MCU_CFG_LS_WF_MCCR_SET_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x018)104#define MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x01c)105#define MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x050)106#define MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x060)107#define MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x064)108 109#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5)110#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0)111 112#define MTK_WED_WO_RING_SIZE 256113#define MTK_WED_WO_CMD_LEN 1504114 115#define MTK_WED_WO_TXCH_NUM 0116#define MTK_WED_WO_RXCH_NUM 1117#define MTK_WED_WO_RXCH_WO_EXCEPTION 7118 119#define MTK_WED_WO_TXCH_INT_MASK BIT(0)120#define MTK_WED_WO_RXCH_INT_MASK BIT(1)121#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7)122#define MTK_WED_WO_ALL_INT_MASK (MTK_WED_WO_RXCH_INT_MASK | \123 MTK_WED_WO_EXCEPTION_INT_MASK)124 125#define MTK_WED_WO_CCIF_BUSY 0x004126#define MTK_WED_WO_CCIF_START 0x008127#define MTK_WED_WO_CCIF_TCHNUM 0x00c128#define MTK_WED_WO_CCIF_RCHNUM 0x010129#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0)130 131#define MTK_WED_WO_CCIF_ACK 0x014132#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018133#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c134#define MTK_WED_WO_CCIF_DUMMY1 0x020135#define MTK_WED_WO_CCIF_DUMMY2 0x024136#define MTK_WED_WO_CCIF_DUMMY3 0x028137#define MTK_WED_WO_CCIF_DUMMY4 0x02c138#define MTK_WED_WO_CCIF_SHADOW1 0x030139#define MTK_WED_WO_CCIF_SHADOW2 0x034140#define MTK_WED_WO_CCIF_SHADOW3 0x038141#define MTK_WED_WO_CCIF_SHADOW4 0x03c142#define MTK_WED_WO_CCIF_DUMMY5 0x050143#define MTK_WED_WO_CCIF_DUMMY6 0x054144#define MTK_WED_WO_CCIF_DUMMY7 0x058145#define MTK_WED_WO_CCIF_DUMMY8 0x05c146#define MTK_WED_WO_CCIF_SHADOW5 0x060147#define MTK_WED_WO_CCIF_SHADOW6 0x064148#define MTK_WED_WO_CCIF_SHADOW7 0x068149#define MTK_WED_WO_CCIF_SHADOW8 0x06c150 151#define MTK_WED_WO_CTL_SD_LEN1 GENMASK(13, 0)152#define MTK_WED_WO_CTL_LAST_SEC1 BIT(14)153#define MTK_WED_WO_CTL_BURST BIT(15)154#define MTK_WED_WO_CTL_SD_LEN0_SHIFT 16155#define MTK_WED_WO_CTL_SD_LEN0 GENMASK(29, 16)156#define MTK_WED_WO_CTL_LAST_SEC0 BIT(30)157#define MTK_WED_WO_CTL_DMA_DONE BIT(31)158#define MTK_WED_WO_INFO_WINFO GENMASK(15, 0)159 160struct mtk_wed_wo_memory_region {161 const char *name;162 void __iomem *addr;163 phys_addr_t phy_addr;164 u32 size;165 bool shared:1;166 bool consumed:1;167};168 169struct mtk_wed_fw_region {170 __le32 decomp_crc;171 __le32 decomp_len;172 __le32 decomp_blk_sz;173 u8 rsv0[4];174 __le32 addr;175 __le32 len;176 u8 feature_set;177 u8 rsv1[15];178} __packed;179 180struct mtk_wed_fw_trailer {181 u8 chip_id;182 u8 eco_code;183 u8 num_region;184 u8 format_ver;185 u8 format_flag;186 u8 rsv[2];187 char fw_ver[10];188 char build_date[15];189 u32 crc;190};191 192struct mtk_wed_wo_queue_regs {193 u32 desc_base;194 u32 ring_size;195 u32 cpu_idx;196 u32 dma_idx;197};198 199struct mtk_wed_wo_queue_desc {200 __le32 buf0;201 __le32 ctrl;202 __le32 buf1;203 __le32 info;204 __le32 reserved[4];205} __packed __aligned(32);206 207struct mtk_wed_wo_queue_entry {208 dma_addr_t addr;209 void *buf;210 u32 len;211};212 213struct mtk_wed_wo_queue {214 struct mtk_wed_wo_queue_regs regs;215 216 struct page_frag_cache cache;217 218 struct mtk_wed_wo_queue_desc *desc;219 dma_addr_t desc_dma;220 221 struct mtk_wed_wo_queue_entry *entry;222 223 u16 head;224 u16 tail;225 int n_desc;226 int queued;227 int buf_size;228 229};230 231struct mtk_wed_wo {232 struct mtk_wed_hw *hw;233 234 struct mtk_wed_wo_queue q_tx;235 struct mtk_wed_wo_queue q_rx;236 237 struct {238 struct mutex mutex;239 int timeout;240 u16 seq;241 242 struct sk_buff_head res_q;243 wait_queue_head_t wait;244 } mcu;245 246 struct {247 struct regmap *regs;248 249 spinlock_t lock;250 struct tasklet_struct irq_tasklet;251 int irq;252 u32 irq_mask;253 } mmio;254};255 256static inline int257mtk_wed_mcu_check_msg(struct mtk_wed_wo *wo, struct sk_buff *skb)258{259 struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data;260 261 if (hdr->version)262 return -EINVAL;263 264 if (skb->len < sizeof(*hdr) || skb->len != le16_to_cpu(hdr->length))265 return -EINVAL;266 267 return 0;268}269 270void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb);271void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo,272 struct sk_buff *skb);273int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd,274 const void *data, int len, bool wait_resp);275int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data,276 int len);277int mtk_wed_mcu_init(struct mtk_wed_wo *wo);278int mtk_wed_wo_init(struct mtk_wed_hw *hw);279void mtk_wed_wo_deinit(struct mtk_wed_hw *hw);280int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *dev, struct mtk_wed_wo_queue *q,281 struct sk_buff *skb);282 283#endif /* __MTK_WED_WO_H */284