xref: /linux/drivers/net/wireless/mediatek/mt76/dma.h (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
2 /*
3  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
4  */
5 #ifndef __MT76_DMA_H
6 #define __MT76_DMA_H
7 
8 #include <linux/regmap.h>
9 
10 #define DMA_DUMMY_DATA			((void *)~0)
11 
12 #define MT_RING_SIZE			0x10
13 
14 #define MT_DMA_CTL_SD_LEN1		GENMASK(13, 0)
15 #define MT_DMA_CTL_LAST_SEC1		BIT(14)
16 #define MT_DMA_CTL_M_DONE		BIT(15)
17 #define MT_DMA_CTL_SD_LEN0		GENMASK(29, 16)
18 #define MT_DMA_CTL_LAST_SEC0		BIT(30)
19 #define MT_DMA_CTL_DMA_DONE		BIT(31)
20 #define MT_DMA_CTL_TO_HOST		BIT(8)
21 #define MT_DMA_CTL_TO_HOST_A		BIT(12)
22 #define MT_DMA_CTL_DROP			BIT(14)
23 #define MT_DMA_CTL_TOKEN		GENMASK(31, 16)
24 #define MT_DMA_CTL_SDP1_H		GENMASK(19, 16)
25 #define MT_DMA_CTL_SDP0_H		GENMASK(3, 0)
26 #define MT_DMA_CTL_WO_DROP		BIT(8)
27 
28 #define MT_DMA_PPE_CPU_REASON		GENMASK(15, 11)
29 #define MT_DMA_PPE_ENTRY		GENMASK(30, 16)
30 #define MT_DMA_INFO_DMA_FRAG		BIT(9)
31 #define MT_DMA_INFO_PPE_VLD		BIT(31)
32 
33 #define MT_DMA_CTL_PN_CHK_FAIL		BIT(13)
34 #define MT_DMA_CTL_VER_MASK		BIT(7)
35 
36 #define MT_DMA_SDP0			GENMASK(15, 0)
37 #define MT_DMA_TOKEN_ID			GENMASK(31, 16)
38 #define MT_DMA_MAGIC_MASK		GENMASK(31, 28)
39 #define MT_DMA_RRO_EN			BIT(13)
40 
41 #define MT_DMA_MAGIC_CNT		16
42 
43 #define MT_DMA_WED_IND_CMD_CNT		8
44 #define MT_DMA_WED_IND_REASON		GENMASK(15, 12)
45 
46 #define MT_DMA_HDR_LEN			4
47 #define MT_RX_INFO_LEN			4
48 #define MT_FCE_INFO_LEN			4
49 #define MT_RX_RXWI_LEN			32
50 
51 static inline bool
mt76_dma_handle_read(struct mt76_queue * q,u32 offset,u32 * val)52 mt76_dma_handle_read(struct mt76_queue *q, u32 offset, u32 *val)
53 {
54 #if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
55 	if (q->flags & MT_QFLAG_WED) {
56 		*val = mtk_wed_device_reg_read(q->wed, q->wed_regs + offset);
57 
58 		return true;
59 	}
60 #endif
61 #if IS_ENABLED(CONFIG_MT76_NPU)
62 	if (q->flags & MT_QFLAG_NPU) {
63 		struct airoha_npu *npu;
64 
65 		*val = 0;
66 		rcu_read_lock();
67 		npu = rcu_dereference(q->dev->mmio.npu);
68 		if (npu)
69 			regmap_read(npu->regmap, q->wed_regs + offset, val);
70 		rcu_read_unlock();
71 
72 		return true;
73 	}
74 #endif
75 
76 	return false;
77 }
78 
79 static inline bool
mt76_dma_handle_write(struct mt76_queue * q,u32 offset,u32 val)80 mt76_dma_handle_write(struct mt76_queue *q, u32 offset, u32 val)
81 {
82 #if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
83 	if (q->flags & MT_QFLAG_WED) {
84 		mtk_wed_device_reg_write(q->wed, q->wed_regs + offset, val);
85 
86 		return true;
87 	}
88 #endif
89 #if IS_ENABLED(CONFIG_MT76_NPU)
90 	if (q->flags & MT_QFLAG_NPU) {
91 		struct airoha_npu *npu;
92 
93 		rcu_read_lock();
94 		npu = rcu_dereference(q->dev->mmio.npu);
95 		if (npu)
96 			regmap_write(npu->regmap, q->wed_regs + offset, val);
97 		rcu_read_unlock();
98 
99 		return true;
100 	}
101 #endif
102 
103 	return false;
104 }
105 
106 #define Q_READ(_q, _field) ({						\
107 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
108 	u32 _val;							\
109 	if (!mt76_dma_handle_read(_q, _offset, &_val))			\
110 		_val = readl(&(_q)->regs->_field);			\
111 	_val;								\
112 })
113 
114 #define Q_WRITE(_q, _field, _val)	do {				\
115 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
116 	if (!mt76_dma_handle_write(_q, _offset, _val))			\
117 		writel(_val, &(_q)->regs->_field);			\
118 } while (0)
119 
120 struct mt76_desc {
121 	__le32 buf0;
122 	__le32 ctrl;
123 	__le32 buf1;
124 	__le32 info;
125 } __packed __aligned(4);
126 
127 struct mt76_wed_rro_desc {
128 	__le32 buf0;
129 	__le32 buf1;
130 } __packed __aligned(4);
131 
132 /* data1 */
133 #define RRO_RXDMAD_DATA1_LS_MASK		BIT(30)
134 #define RRO_RXDMAD_DATA1_SDL0_MASK		GENMASK(29, 16)
135 /* data2 */
136 #define RRO_RXDMAD_DATA2_RX_TOKEN_ID_MASK	GENMASK(31, 16)
137 #define RRO_RXDMAD_DATA2_IND_REASON_MASK	GENMASK(15, 12)
138 /* data3 */
139 #define RRO_RXDMAD_DATA3_MAGIC_CNT_MASK		GENMASK(31, 28)
140 struct mt76_rro_rxdmad_c {
141 	__le32 data0;
142 	__le32 data1;
143 	__le32 data2;
144 	__le32 data3;
145 };
146 
147 enum mt76_qsel {
148 	MT_QSEL_MGMT,
149 	MT_QSEL_HCCA,
150 	MT_QSEL_EDCA,
151 	MT_QSEL_EDCA_2,
152 };
153 
154 enum mt76_mcu_evt_type {
155 	EVT_CMD_DONE,
156 	EVT_CMD_ERROR,
157 	EVT_CMD_RETRY,
158 	EVT_EVENT_PWR_RSP,
159 	EVT_EVENT_WOW_RSP,
160 	EVT_EVENT_CARRIER_DETECT_RSP,
161 	EVT_EVENT_DFS_DETECT_RSP,
162 };
163 
164 enum mt76_dma_wed_ind_reason {
165 	MT_DMA_WED_IND_REASON_NORMAL,
166 	MT_DMA_WED_IND_REASON_REPEAT,
167 	MT_DMA_WED_IND_REASON_OLDPKT,
168 };
169 
170 int mt76_dma_rx_poll(struct napi_struct *napi, int budget);
171 void mt76_dma_attach(struct mt76_dev *dev);
172 void mt76_dma_cleanup(struct mt76_dev *dev);
173 int mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
174 		     bool allow_direct);
175 void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
176 			  bool reset_idx);
177 
178 static inline void
mt76_dma_reset_tx_queue(struct mt76_dev * dev,struct mt76_queue * q)179 mt76_dma_reset_tx_queue(struct mt76_dev *dev, struct mt76_queue *q)
180 {
181 	bool reset_idx = q && !mt76_queue_is_npu_tx(q);
182 
183 	dev->queue_ops->reset_q(dev, q, reset_idx);
184 	if (mtk_wed_device_active(&dev->mmio.wed))
185 		mt76_wed_dma_setup(dev, q, true);
186 }
187 
188 static inline void
mt76_dma_should_drop_buf(bool * drop,u32 ctrl,u32 buf1,u32 info)189 mt76_dma_should_drop_buf(bool *drop, u32 ctrl, u32 buf1, u32 info)
190 {
191 	if (!drop)
192 		return;
193 
194 	*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
195 	if (!(ctrl & MT_DMA_CTL_VER_MASK))
196 		return;
197 
198 	switch (FIELD_GET(MT_DMA_WED_IND_REASON, buf1)) {
199 	case MT_DMA_WED_IND_REASON_REPEAT:
200 		*drop = true;
201 		break;
202 	case MT_DMA_WED_IND_REASON_OLDPKT:
203 		*drop = !(info & MT_DMA_INFO_DMA_FRAG);
204 		break;
205 	default:
206 		*drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
207 		break;
208 	}
209 }
210 
mt76_priv(struct net_device * dev)211 static inline void *mt76_priv(struct net_device *dev)
212 {
213 	struct mt76_dev **priv;
214 
215 	priv = netdev_priv(dev);
216 
217 	return *priv;
218 }
219 
220 #endif
221