1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * NXP Wireless LAN device driver: SDIO specific definitions
4 *
5 * Copyright 2011-2024 NXP
6 */
7
8 #ifndef _NXPWIFI_SDIO_H
9 #define _NXPWIFI_SDIO_H
10
11 #include "main.h"
12
13 #define IW61X_SDIO_FW_NAME "nxp/sd_w61x_v1.bin.se"
14
15 #define BLOCK_MODE 1
16 #define BYTE_MODE 0
17
18 #define NXPWIFI_SDIO_IO_PORT_MASK 0xfffff
19
20 #define NXPWIFI_SDIO_BYTE_MODE_MASK 0x80000000
21
22 #define NXPWIFI_MAX_FUNC2_REG_NUM 13
23 #define NXPWIFI_SDIO_SCRATCH_SIZE 10
24
25 #define SDIO_MPA_ADDR_BASE 0x1000
26
27 #define CMD_PORT_UPLD_INT_MASK (0x1U << 6)
28 #define CMD_PORT_DNLD_INT_MASK (0x1U << 7)
29 #define HOST_TERM_CMD53 (0x1U << 2)
30 #define REG_PORT 0
31 #define MEM_PORT 0x10000
32
33 #define CMD53_NEW_MODE (0x1U << 0)
34 #define CMD_PORT_RD_LEN_EN (0x1U << 2)
35 #define CMD_PORT_AUTO_EN (0x1U << 0)
36 #define CMD_PORT_SLCT 0x8000
37 #define UP_LD_CMD_PORT_HOST_INT_STATUS (0x40U)
38 #define DN_LD_CMD_PORT_HOST_INT_STATUS (0x80U)
39
40 #define NXPWIFI_MP_AGGR_BSIZE_32K (32768)
41 /* we leave one block of 256 bytes for DMA alignment*/
42 #define NXPWIFI_MP_AGGR_BSIZE_MAX (65280)
43
44 /* Misc. Config Register : Auto Re-enable interrupts */
45 #define AUTO_RE_ENABLE_INT BIT(4)
46
47 /* Host Control Registers : Configuration */
48 #define CONFIGURATION_REG 0x00
49 /* Host Control Registers : Host power up */
50 #define HOST_POWER_UP (0x1U << 1)
51
52 /* Host Control Registers : Upload host interrupt mask */
53 #define UP_LD_HOST_INT_MASK (0x1U)
54 /* Host Control Registers : Download host interrupt mask */
55 #define DN_LD_HOST_INT_MASK (0x2U)
56
57 /* Host Control Registers : Upload host interrupt status */
58 #define UP_LD_HOST_INT_STATUS (0x1U)
59 /* Host Control Registers : Download host interrupt status */
60 #define DN_LD_HOST_INT_STATUS (0x2U)
61
62 /* Host Control Registers : Host interrupt status */
63 #define CARD_INT_STATUS_REG 0x28
64
65 /* Card Control Registers : Card I/O ready */
66 #define CARD_IO_READY (0x1U << 3)
67 /* Card Control Registers : Download card ready */
68 #define DN_LD_CARD_RDY (0x1U << 0)
69
70 /* Max retry number of CMD53 write */
71 #define MAX_WRITE_IOMEM_RETRY 2
72
73 /* SDIO Tx aggregation in progress ? */
74 #define MP_TX_AGGR_IN_PROGRESS(a) ((a)->mpa_tx.pkt_cnt > 0)
75
76 /* SDIO Tx aggregation buffer room for next packet ? */
77 #define MP_TX_AGGR_BUF_HAS_ROOM(a, len) ({ \
78 typeof(a) (_a) = a; \
79 (((_a)->mpa_tx.buf_len + (len)) <= (_a)->mpa_tx.buf_size); \
80 })
81
82 /* Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */
83 #define MP_TX_AGGR_BUF_PUT(a, payload, pkt_len, port) do { \
84 typeof(a) (_a) = (a); \
85 typeof(pkt_len) (_pkt_len) = pkt_len; \
86 typeof(port) (_port) = port; \
87 memmove(&(_a)->mpa_tx.buf[(_a)->mpa_tx.buf_len], \
88 payload, (_pkt_len)); \
89 (_a)->mpa_tx.buf_len += (_pkt_len); \
90 if (!(_a)->mpa_tx.pkt_cnt) \
91 (_a)->mpa_tx.start_port = (_port); \
92 if ((_a)->mpa_tx.start_port <= (_port)) \
93 (_a)->mpa_tx.ports |= (1 << ((_a)->mpa_tx.pkt_cnt)); \
94 else \
95 (_a)->mpa_tx.ports |= (1 << ((_a)->mpa_tx.pkt_cnt + 1 + \
96 ((_a)->max_ports - \
97 (_a)->mp_end_port))); \
98 (_a)->mpa_tx.pkt_cnt++; \
99 } while (0)
100
101 /* SDIO Tx aggregation limit ? */
102 #define MP_TX_AGGR_PKT_LIMIT_REACHED(a) ({ \
103 typeof(a) (_a) = a; \
104 ((_a)->mpa_tx.pkt_cnt == (_a)->mpa_tx.pkt_aggr_limit); \
105 })
106
107 /* Reset SDIO Tx aggregation buffer parameters */
108 #define MP_TX_AGGR_BUF_RESET(a) do { \
109 typeof(a) (_a) = (a); \
110 (_a)->mpa_tx.pkt_cnt = 0; \
111 (_a)->mpa_tx.buf_len = 0; \
112 (_a)->mpa_tx.ports = 0; \
113 (_a)->mpa_tx.start_port = 0; \
114 } while (0)
115
116 /* SDIO Rx aggregation limit ? */
117 #define MP_RX_AGGR_PKT_LIMIT_REACHED(a) ({ \
118 typeof(a) (_a) = a; \
119 ((_a)->mpa_rx.pkt_cnt == (_a)->mpa_rx.pkt_aggr_limit); \
120 })
121
122 /* SDIO Rx aggregation in progress ? */
123 #define MP_RX_AGGR_IN_PROGRESS(a) ((a)->mpa_rx.pkt_cnt > 0)
124
125 /* SDIO Rx aggregation buffer room for next packet ? */
126 #define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) ({ \
127 typeof(a) (_a) = a; \
128 ((((_a)->mpa_rx.buf_len + (rx_len))) <= (_a)->mpa_rx.buf_size); \
129 })
130
131 /* Reset SDIO Rx aggregation buffer parameters */
132 #define MP_RX_AGGR_BUF_RESET(a) do { \
133 typeof(a) (_a) = (a); \
134 (_a)->mpa_rx.pkt_cnt = 0; \
135 (_a)->mpa_rx.buf_len = 0; \
136 (_a)->mpa_rx.ports = 0; \
137 (_a)->mpa_rx.start_port = 0; \
138 } while (0)
139
140 /* data structure for SDIO MPA TX */
141 struct nxpwifi_sdio_mpa_tx {
142 /* multiport tx aggregation buffer pointer */
143 u8 *buf;
144 u32 buf_len;
145 u32 pkt_cnt;
146 u32 ports;
147 u16 start_port;
148 u8 enabled;
149 u32 buf_size;
150 u32 pkt_aggr_limit;
151 };
152
153 struct nxpwifi_sdio_mpa_rx {
154 u8 *buf;
155 u32 buf_len;
156 u32 pkt_cnt;
157 u32 ports;
158 u16 start_port;
159 u32 *len_arr;
160 u8 enabled;
161 u32 buf_size;
162 u32 pkt_aggr_limit;
163 };
164
165 int nxpwifi_bus_register(void);
166 void nxpwifi_bus_unregister(void);
167
168 struct nxpwifi_sdio_card_reg {
169 u8 start_rd_port;
170 u8 start_wr_port;
171 u8 base_0_reg;
172 u8 base_1_reg;
173 u8 poll_reg;
174 u8 host_int_enable;
175 u8 host_int_rsr_reg;
176 u8 host_int_status_reg;
177 u8 host_int_mask_reg;
178 u8 host_strap_reg;
179 u8 host_strap_mask;
180 u8 host_strap_value;
181 u8 status_reg_0;
182 u8 status_reg_1;
183 u8 sdio_int_mask;
184 u32 data_port_mask;
185 u8 io_port_0_reg;
186 u8 io_port_1_reg;
187 u8 io_port_2_reg;
188 u8 max_mp_regs;
189 u8 rd_bitmap_l;
190 u8 rd_bitmap_u;
191 u8 rd_bitmap_1l;
192 u8 rd_bitmap_1u;
193 u8 wr_bitmap_l;
194 u8 wr_bitmap_u;
195 u8 wr_bitmap_1l;
196 u8 wr_bitmap_1u;
197 u8 rd_len_p0_l;
198 u8 rd_len_p0_u;
199 u8 card_misc_cfg_reg;
200 u8 card_cfg_2_1_reg;
201 u8 cmd_rd_len_0;
202 u8 cmd_rd_len_1;
203 u8 cmd_rd_len_2;
204 u8 cmd_rd_len_3;
205 u8 cmd_cfg_0;
206 u8 cmd_cfg_1;
207 u8 cmd_cfg_2;
208 u8 cmd_cfg_3;
209 u8 fw_dump_host_ready;
210 u8 fw_dump_ctrl;
211 u8 fw_dump_start;
212 u8 fw_dump_end;
213 u8 func1_dump_reg_start;
214 u8 func1_dump_reg_end;
215 u8 func1_scratch_reg;
216 u8 func1_spec_reg_num;
217 u8 func1_spec_reg_table[NXPWIFI_MAX_FUNC2_REG_NUM];
218 };
219
220 struct sdio_mmc_card {
221 struct sdio_func *func;
222 struct nxpwifi_adapter *adapter;
223
224 struct completion fw_done;
225 const char *firmware;
226 const char *firmware_sdiouart;
227 const struct nxpwifi_sdio_card_reg *reg;
228 u8 max_ports;
229 u8 mp_agg_pkt_limit;
230 u16 tx_buf_size;
231 u32 mp_tx_agg_buf_size;
232 u32 mp_rx_agg_buf_size;
233
234 u32 mp_rd_bitmap;
235 u32 mp_wr_bitmap;
236
237 u16 mp_end_port;
238 u32 mp_data_port_mask;
239
240 u8 curr_rd_port;
241 u8 curr_wr_port;
242
243 u8 *mp_regs;
244 bool can_dump_fw;
245 bool fw_dump_enh;
246 bool can_ext_scan;
247
248 struct nxpwifi_sdio_mpa_tx mpa_tx;
249 struct nxpwifi_sdio_mpa_rx mpa_rx;
250
251 struct work_struct work;
252 unsigned long work_flags;
253 };
254
255 struct nxpwifi_sdio_device {
256 const char *firmware;
257 const char *firmware_sdiouart;
258 const struct nxpwifi_sdio_card_reg *reg;
259 u8 max_ports;
260 u8 mp_agg_pkt_limit;
261 u16 tx_buf_size;
262 u32 mp_tx_agg_buf_size;
263 u32 mp_rx_agg_buf_size;
264 bool can_dump_fw;
265 bool fw_dump_enh;
266 bool can_ext_scan;
267 };
268
269 /* .cmdrsp_complete handler
270 */
nxpwifi_sdio_cmdrsp_complete(struct nxpwifi_adapter * adapter,struct sk_buff * skb)271 static inline int nxpwifi_sdio_cmdrsp_complete(struct nxpwifi_adapter *adapter,
272 struct sk_buff *skb)
273 {
274 dev_kfree_skb_any(skb);
275 return 0;
276 }
277
278 /* .event_complete handler
279 */
nxpwifi_sdio_event_complete(struct nxpwifi_adapter * adapter,struct sk_buff * skb)280 static inline int nxpwifi_sdio_event_complete(struct nxpwifi_adapter *adapter,
281 struct sk_buff *skb)
282 {
283 dev_kfree_skb_any(skb);
284 return 0;
285 }
286
287 static inline bool
mp_rx_aggr_port_limit_reached(struct sdio_mmc_card * card)288 mp_rx_aggr_port_limit_reached(struct sdio_mmc_card *card)
289 {
290 u8 tmp;
291
292 if (card->curr_rd_port < card->mpa_rx.start_port) {
293 tmp = card->mp_end_port >> 1;
294
295 if (((card->max_ports - card->mpa_rx.start_port) +
296 card->curr_rd_port) >= tmp)
297 return true;
298 }
299
300 if ((card->curr_rd_port - card->mpa_rx.start_port) >=
301 (card->mp_end_port >> 1))
302 return true;
303
304 return false;
305 }
306
307 static inline bool
mp_tx_aggr_port_limit_reached(struct sdio_mmc_card * card)308 mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
309 {
310 u16 tmp;
311
312 if (card->curr_wr_port < card->mpa_tx.start_port) {
313 tmp = card->mp_end_port >> 1;
314
315 if (((card->max_ports - card->mpa_tx.start_port) +
316 card->curr_wr_port) >= tmp)
317 return true;
318 }
319
320 if ((card->curr_wr_port - card->mpa_tx.start_port) >=
321 (card->mp_end_port >> 1))
322 return true;
323
324 return false;
325 }
326
327 /* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
mp_rx_aggr_setup(struct sdio_mmc_card * card,u16 rx_len,u8 port)328 static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
329 u16 rx_len, u8 port)
330 {
331 card->mpa_rx.buf_len += rx_len;
332
333 if (!card->mpa_rx.pkt_cnt)
334 card->mpa_rx.start_port = port;
335
336 card->mpa_rx.ports |= (1 << port);
337 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = rx_len;
338 card->mpa_rx.pkt_cnt++;
339 }
340 #endif /* _NXPWIFI_SDIO_H */
341