1804775dfSFelix Fietkau #ifndef __MTK_WED_H 2804775dfSFelix Fietkau #define __MTK_WED_H 3804775dfSFelix Fietkau 4804775dfSFelix Fietkau #include <linux/kernel.h> 5804775dfSFelix Fietkau #include <linux/rcupdate.h> 6804775dfSFelix Fietkau #include <linux/regmap.h> 7804775dfSFelix Fietkau #include <linux/pci.h> 84c5de09eSLorenzo Bianconi #include <linux/skbuff.h> 9*05f3ab77SFelix Fietkau #include <linux/netdevice.h> 10804775dfSFelix Fietkau 11804775dfSFelix Fietkau #define MTK_WED_TX_QUEUES 2 12084d60ceSLorenzo Bianconi #define MTK_WED_RX_QUEUES 2 13804775dfSFelix Fietkau 144c5de09eSLorenzo Bianconi #define WED_WO_STA_REC 0x6 154c5de09eSLorenzo Bianconi 16804775dfSFelix Fietkau struct mtk_wed_hw; 17804775dfSFelix Fietkau struct mtk_wdma_desc; 18804775dfSFelix Fietkau 19cc514101SSujuan Chen enum mtk_wed_wo_cmd { 20cc514101SSujuan Chen MTK_WED_WO_CMD_WED_CFG, 21cc514101SSujuan Chen MTK_WED_WO_CMD_WED_RX_STAT, 22cc514101SSujuan Chen MTK_WED_WO_CMD_RRO_SER, 23cc514101SSujuan Chen MTK_WED_WO_CMD_DBG_INFO, 24cc514101SSujuan Chen MTK_WED_WO_CMD_DEV_INFO, 25cc514101SSujuan Chen MTK_WED_WO_CMD_BSS_INFO, 26cc514101SSujuan Chen MTK_WED_WO_CMD_STA_REC, 27cc514101SSujuan Chen MTK_WED_WO_CMD_DEV_INFO_DUMP, 28cc514101SSujuan Chen MTK_WED_WO_CMD_BSS_INFO_DUMP, 29cc514101SSujuan Chen MTK_WED_WO_CMD_STA_REC_DUMP, 30cc514101SSujuan Chen MTK_WED_WO_CMD_BA_INFO_DUMP, 31cc514101SSujuan Chen MTK_WED_WO_CMD_FBCMD_Q_DUMP, 32cc514101SSujuan Chen MTK_WED_WO_CMD_FW_LOG_CTRL, 33cc514101SSujuan Chen MTK_WED_WO_CMD_LOG_FLUSH, 34cc514101SSujuan Chen MTK_WED_WO_CMD_CHANGE_STATE, 35cc514101SSujuan Chen MTK_WED_WO_CMD_CPU_STATS_ENABLE, 36cc514101SSujuan Chen MTK_WED_WO_CMD_CPU_STATS_DUMP, 37cc514101SSujuan Chen MTK_WED_WO_CMD_EXCEPTION_INIT, 38cc514101SSujuan Chen MTK_WED_WO_CMD_PROF_CTRL, 39cc514101SSujuan Chen MTK_WED_WO_CMD_STA_BA_DUMP, 40cc514101SSujuan Chen MTK_WED_WO_CMD_BA_CTRL_DUMP, 41cc514101SSujuan Chen MTK_WED_WO_CMD_RXCNT_CTRL, 42cc514101SSujuan Chen MTK_WED_WO_CMD_RXCNT_INFO, 43cc514101SSujuan Chen MTK_WED_WO_CMD_SET_CAP, 44cc514101SSujuan Chen MTK_WED_WO_CMD_CCIF_RING_DUMP, 45cc514101SSujuan Chen MTK_WED_WO_CMD_WED_END 46cc514101SSujuan Chen }; 47cc514101SSujuan Chen 484c5de09eSLorenzo Bianconi struct mtk_rxbm_desc { 494c5de09eSLorenzo Bianconi __le32 buf0; 504c5de09eSLorenzo Bianconi __le32 token; 514c5de09eSLorenzo Bianconi } __packed __aligned(4); 524c5de09eSLorenzo Bianconi 532b2ba3ecSLorenzo Bianconi enum mtk_wed_bus_tye { 542b2ba3ecSLorenzo Bianconi MTK_WED_BUS_PCIE, 552b2ba3ecSLorenzo Bianconi MTK_WED_BUS_AXI, 562b2ba3ecSLorenzo Bianconi }; 572b2ba3ecSLorenzo Bianconi 584c5de09eSLorenzo Bianconi #define MTK_WED_RING_CONFIGURED BIT(0) 59804775dfSFelix Fietkau struct mtk_wed_ring { 60804775dfSFelix Fietkau struct mtk_wdma_desc *desc; 61804775dfSFelix Fietkau dma_addr_t desc_phys; 62de84a090SLorenzo Bianconi u32 desc_size; 63804775dfSFelix Fietkau int size; 644c5de09eSLorenzo Bianconi u32 flags; 65804775dfSFelix Fietkau 66804775dfSFelix Fietkau u32 reg_base; 67804775dfSFelix Fietkau void __iomem *wpdma; 68804775dfSFelix Fietkau }; 69804775dfSFelix Fietkau 704c5de09eSLorenzo Bianconi struct mtk_wed_wo_rx_stats { 714c5de09eSLorenzo Bianconi __le16 wlan_idx; 724c5de09eSLorenzo Bianconi __le16 tid; 734c5de09eSLorenzo Bianconi __le32 rx_pkt_cnt; 744c5de09eSLorenzo Bianconi __le32 rx_byte_cnt; 754c5de09eSLorenzo Bianconi __le32 rx_err_cnt; 764c5de09eSLorenzo Bianconi __le32 rx_drop_cnt; 774c5de09eSLorenzo Bianconi }; 784c5de09eSLorenzo Bianconi 79804775dfSFelix Fietkau struct mtk_wed_device { 80804775dfSFelix Fietkau #ifdef CONFIG_NET_MEDIATEK_SOC_WED 81804775dfSFelix Fietkau const struct mtk_wed_ops *ops; 82804775dfSFelix Fietkau struct device *dev; 83804775dfSFelix Fietkau struct mtk_wed_hw *hw; 84804775dfSFelix Fietkau bool init_done, running; 85804775dfSFelix Fietkau int wdma_idx; 86804775dfSFelix Fietkau int irq; 874c5de09eSLorenzo Bianconi u8 version; 88804775dfSFelix Fietkau 89a66d79eeSSujuan Chen /* used by wlan driver */ 90a66d79eeSSujuan Chen u32 rev_id; 91a66d79eeSSujuan Chen 92804775dfSFelix Fietkau struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; 934c5de09eSLorenzo Bianconi struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; 94804775dfSFelix Fietkau struct mtk_wed_ring txfree_ring; 954c5de09eSLorenzo Bianconi struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; 96084d60ceSLorenzo Bianconi struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; 97804775dfSFelix Fietkau 98804775dfSFelix Fietkau struct { 99804775dfSFelix Fietkau int size; 100804775dfSFelix Fietkau void **pages; 101804775dfSFelix Fietkau struct mtk_wdma_desc *desc; 102804775dfSFelix Fietkau dma_addr_t desc_phys; 1034c5de09eSLorenzo Bianconi } tx_buf_ring; 1044c5de09eSLorenzo Bianconi 1054c5de09eSLorenzo Bianconi struct { 1064c5de09eSLorenzo Bianconi int size; 1074c5de09eSLorenzo Bianconi struct mtk_rxbm_desc *desc; 1084c5de09eSLorenzo Bianconi dma_addr_t desc_phys; 1094c5de09eSLorenzo Bianconi } rx_buf_ring; 1104c5de09eSLorenzo Bianconi 1114c5de09eSLorenzo Bianconi struct { 1124c5de09eSLorenzo Bianconi struct mtk_wed_ring ring; 1134c5de09eSLorenzo Bianconi dma_addr_t miod_phys; 1144c5de09eSLorenzo Bianconi dma_addr_t fdbk_phys; 1154c5de09eSLorenzo Bianconi } rro; 116804775dfSFelix Fietkau 117804775dfSFelix Fietkau /* filled by driver: */ 118804775dfSFelix Fietkau struct { 1192b2ba3ecSLorenzo Bianconi union { 1202b2ba3ecSLorenzo Bianconi struct platform_device *platform_dev; 121804775dfSFelix Fietkau struct pci_dev *pci_dev; 1222b2ba3ecSLorenzo Bianconi }; 1232b2ba3ecSLorenzo Bianconi enum mtk_wed_bus_tye bus_type; 1244c5de09eSLorenzo Bianconi void __iomem *base; 1254c5de09eSLorenzo Bianconi u32 phy_base; 126804775dfSFelix Fietkau 127804775dfSFelix Fietkau u32 wpdma_phys; 128de84a090SLorenzo Bianconi u32 wpdma_int; 129de84a090SLorenzo Bianconi u32 wpdma_mask; 130de84a090SLorenzo Bianconi u32 wpdma_tx; 131de84a090SLorenzo Bianconi u32 wpdma_txfree; 1324c5de09eSLorenzo Bianconi u32 wpdma_rx_glo; 1334c5de09eSLorenzo Bianconi u32 wpdma_rx; 1344c5de09eSLorenzo Bianconi 1354c5de09eSLorenzo Bianconi bool wcid_512; 136804775dfSFelix Fietkau 137804775dfSFelix Fietkau u16 token_start; 138804775dfSFelix Fietkau unsigned int nbuf; 1394c5de09eSLorenzo Bianconi unsigned int rx_nbuf; 1404c5de09eSLorenzo Bianconi unsigned int rx_npkt; 1414c5de09eSLorenzo Bianconi unsigned int rx_size; 142804775dfSFelix Fietkau 143de84a090SLorenzo Bianconi u8 tx_tbit[MTK_WED_TX_QUEUES]; 1444c5de09eSLorenzo Bianconi u8 rx_tbit[MTK_WED_RX_QUEUES]; 145de84a090SLorenzo Bianconi u8 txfree_tbit; 146de84a090SLorenzo Bianconi 147804775dfSFelix Fietkau u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); 148804775dfSFelix Fietkau int (*offload_enable)(struct mtk_wed_device *wed); 149804775dfSFelix Fietkau void (*offload_disable)(struct mtk_wed_device *wed); 1504c5de09eSLorenzo Bianconi u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size); 1514c5de09eSLorenzo Bianconi void (*release_rx_buf)(struct mtk_wed_device *wed); 1524c5de09eSLorenzo Bianconi void (*update_wo_rx_stats)(struct mtk_wed_device *wed, 1534c5de09eSLorenzo Bianconi struct mtk_wed_wo_rx_stats *stats); 15408a764a7SLorenzo Bianconi int (*reset)(struct mtk_wed_device *wed); 15508a764a7SLorenzo Bianconi void (*reset_complete)(struct mtk_wed_device *wed); 156804775dfSFelix Fietkau } wlan; 157804775dfSFelix Fietkau #endif 158804775dfSFelix Fietkau }; 159804775dfSFelix Fietkau 160804775dfSFelix Fietkau struct mtk_wed_ops { 161804775dfSFelix Fietkau int (*attach)(struct mtk_wed_device *dev); 162804775dfSFelix Fietkau int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, 16323dca7a9SLorenzo Bianconi void __iomem *regs, bool reset); 1644c5de09eSLorenzo Bianconi int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, 165ed883becSLorenzo Bianconi void __iomem *regs, bool reset); 166804775dfSFelix Fietkau int (*txfree_ring_setup)(struct mtk_wed_device *dev, 167804775dfSFelix Fietkau void __iomem *regs); 1684c5de09eSLorenzo Bianconi int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, 1694c5de09eSLorenzo Bianconi void *data, int len); 170804775dfSFelix Fietkau void (*detach)(struct mtk_wed_device *dev); 1714c5de09eSLorenzo Bianconi void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb, 1724c5de09eSLorenzo Bianconi u32 reason, u32 hash); 173804775dfSFelix Fietkau 174804775dfSFelix Fietkau void (*stop)(struct mtk_wed_device *dev); 175804775dfSFelix Fietkau void (*start)(struct mtk_wed_device *dev, u32 irq_mask); 176804775dfSFelix Fietkau void (*reset_dma)(struct mtk_wed_device *dev); 177804775dfSFelix Fietkau 178804775dfSFelix Fietkau u32 (*reg_read)(struct mtk_wed_device *dev, u32 reg); 179804775dfSFelix Fietkau void (*reg_write)(struct mtk_wed_device *dev, u32 reg, u32 val); 180804775dfSFelix Fietkau 181804775dfSFelix Fietkau u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); 182804775dfSFelix Fietkau void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); 183*05f3ab77SFelix Fietkau int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, 184*05f3ab77SFelix Fietkau enum tc_setup_type type, void *type_data); 185804775dfSFelix Fietkau }; 186804775dfSFelix Fietkau 187804775dfSFelix Fietkau extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; 188804775dfSFelix Fietkau 189804775dfSFelix Fietkau static inline int 190804775dfSFelix Fietkau mtk_wed_device_attach(struct mtk_wed_device *dev) 191804775dfSFelix Fietkau { 192804775dfSFelix Fietkau int ret = -ENODEV; 193804775dfSFelix Fietkau 194804775dfSFelix Fietkau #ifdef CONFIG_NET_MEDIATEK_SOC_WED 195804775dfSFelix Fietkau rcu_read_lock(); 196804775dfSFelix Fietkau dev->ops = rcu_dereference(mtk_soc_wed_ops); 197804775dfSFelix Fietkau if (dev->ops) 198804775dfSFelix Fietkau ret = dev->ops->attach(dev); 199804775dfSFelix Fietkau else 200804775dfSFelix Fietkau rcu_read_unlock(); 201804775dfSFelix Fietkau 202804775dfSFelix Fietkau if (ret) 203804775dfSFelix Fietkau dev->ops = NULL; 204804775dfSFelix Fietkau #endif 205804775dfSFelix Fietkau 206804775dfSFelix Fietkau return ret; 207804775dfSFelix Fietkau } 208804775dfSFelix Fietkau 2094c5de09eSLorenzo Bianconi static inline bool 2104c5de09eSLorenzo Bianconi mtk_wed_get_rx_capa(struct mtk_wed_device *dev) 2114c5de09eSLorenzo Bianconi { 2124c5de09eSLorenzo Bianconi #ifdef CONFIG_NET_MEDIATEK_SOC_WED 2134c5de09eSLorenzo Bianconi return dev->version != 1; 2144c5de09eSLorenzo Bianconi #else 2154c5de09eSLorenzo Bianconi return false; 2164c5de09eSLorenzo Bianconi #endif 2174c5de09eSLorenzo Bianconi } 2184c5de09eSLorenzo Bianconi 219804775dfSFelix Fietkau #ifdef CONFIG_NET_MEDIATEK_SOC_WED 220804775dfSFelix Fietkau #define mtk_wed_device_active(_dev) !!(_dev)->ops 221804775dfSFelix Fietkau #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) 222804775dfSFelix Fietkau #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) 22323dca7a9SLorenzo Bianconi #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \ 22423dca7a9SLorenzo Bianconi (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset) 225804775dfSFelix Fietkau #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ 226804775dfSFelix Fietkau (_dev)->ops->txfree_ring_setup(_dev, _regs) 227804775dfSFelix Fietkau #define mtk_wed_device_reg_read(_dev, _reg) \ 228804775dfSFelix Fietkau (_dev)->ops->reg_read(_dev, _reg) 229804775dfSFelix Fietkau #define mtk_wed_device_reg_write(_dev, _reg, _val) \ 230804775dfSFelix Fietkau (_dev)->ops->reg_write(_dev, _reg, _val) 231804775dfSFelix Fietkau #define mtk_wed_device_irq_get(_dev, _mask) \ 232804775dfSFelix Fietkau (_dev)->ops->irq_get(_dev, _mask) 233804775dfSFelix Fietkau #define mtk_wed_device_irq_set_mask(_dev, _mask) \ 234804775dfSFelix Fietkau (_dev)->ops->irq_set_mask(_dev, _mask) 235ed883becSLorenzo Bianconi #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \ 236ed883becSLorenzo Bianconi (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset) 2374c5de09eSLorenzo Bianconi #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ 2384c5de09eSLorenzo Bianconi (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) 2394c5de09eSLorenzo Bianconi #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ 2404c5de09eSLorenzo Bianconi (_dev)->ops->msg_update(_dev, _id, _msg, _len) 241f78cd9c7SLorenzo Bianconi #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) 242f78cd9c7SLorenzo Bianconi #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) 243*05f3ab77SFelix Fietkau #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ 244*05f3ab77SFelix Fietkau (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) 245804775dfSFelix Fietkau #else 246804775dfSFelix Fietkau static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) 247804775dfSFelix Fietkau { 248804775dfSFelix Fietkau return false; 249804775dfSFelix Fietkau } 250804775dfSFelix Fietkau #define mtk_wed_device_detach(_dev) do {} while (0) 251804775dfSFelix Fietkau #define mtk_wed_device_start(_dev, _mask) do {} while (0) 25223dca7a9SLorenzo Bianconi #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV 253804775dfSFelix Fietkau #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV 254804775dfSFelix Fietkau #define mtk_wed_device_reg_read(_dev, _reg) 0 255804775dfSFelix Fietkau #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) 256804775dfSFelix Fietkau #define mtk_wed_device_irq_get(_dev, _mask) 0 257804775dfSFelix Fietkau #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) 258ed883becSLorenzo Bianconi #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV 2594c5de09eSLorenzo Bianconi #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) 2604c5de09eSLorenzo Bianconi #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV 261f78cd9c7SLorenzo Bianconi #define mtk_wed_device_stop(_dev) do {} while (0) 262f78cd9c7SLorenzo Bianconi #define mtk_wed_device_dma_reset(_dev) do {} while (0) 263*05f3ab77SFelix Fietkau #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP 264804775dfSFelix Fietkau #endif 265804775dfSFelix Fietkau 266804775dfSFelix Fietkau #endif 267