1 /******************************************************************************
2 *
3 * Copyright(c) 2019 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15 #include "_sdio.h"
16
17 #if MAC_AX_SDIO_SUPPORT
18 static struct mac_sdio_tbl sdio_tbl;
19
20 static u8 r_indir_cmd52_sdio(struct mac_ax_adapter *adapter, u32 adr);
21 static u8 _r_indir_cmd52_sdio(struct mac_ax_adapter *adapter, u32 adr);
22 static u32 r_indir_cmd53_sdio(struct mac_ax_adapter *adapter, u32 adr);
23 static u32 _r_indir_cmd53_sdio(struct mac_ax_adapter *adapter, u32 adr);
24 static u32 r8_indir_sdio(struct mac_ax_adapter *adapter, u32 adr);
25 static u32 r16_indir_sdio(struct mac_ax_adapter *adapter, u32 adr);
26 static u32 r32_indir_sdio(struct mac_ax_adapter *adapter, u32 adr);
27 static void w_indir_cmd52_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val,
28 enum sdio_io_size size);
29 static void w_indir_cmd53_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val,
30 enum sdio_io_size size);
31 static void w8_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val);
32 static void w16_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val);
33 static void w32_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val);
34 static u8 pwr_state_chk_sdio(struct mac_ax_adapter *adapter);
35 static u8 reg_chk_sdio(struct mac_ax_adapter *adapter, u32 adr);
36 static void chk_rqd_pg_num(struct mac_ax_adapter *adapter,
37 struct mac_ax_sdio_tx_info *tx_info);
38 static u32 chk_fs_enuf(struct mac_ax_adapter *adapter,
39 struct mac_ax_sdio_tx_info *tx_info);
40 static void ud_fs(struct mac_ax_adapter *adapter);
41 static u32 get_pg_size_pow(u32 size);
42 static u32 tx_allow_data_ch(struct mac_ax_adapter *adapter,
43 struct mac_ax_sdio_tx_info *info);
44 static u32 tx_allow_fwcmd_ch(struct mac_ax_adapter *adapter,
45 struct mac_ax_sdio_tx_info *info);
46
_pltfm_sdio_cmd53_r8(struct mac_ax_adapter * adapter,u32 adr)47 static u8 _pltfm_sdio_cmd53_r8(struct mac_ax_adapter *adapter, u32 adr)
48 {
49 u32 dw_adr = adr & 0xFFFFFFFC;
50 u8 dw_sh = adr - dw_adr;
51 u8 cnt = 0;
52 union {
53 __le32 dword;
54 u8 byte[4];
55 } val32 = { 0x00000000 };
56
57 if (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A) ||
58 is_chip_id(adapter, MAC_AX_CHIP_ID_8852B)) {
59 if (!(adr >= R_AX_CMAC_FUNC_EN && adr <= R_AX_CMAC_REG_END))
60 return PLTFM_SDIO_CMD53_R8(adr);
61 } else {
62 return PLTFM_SDIO_CMD53_R8(adr);
63 }
64
65 while (cnt < MAC_REG_POOL_COUNT) {
66 val32.dword = PLTFM_SDIO_CMD53_R32(dw_adr);
67
68 if (le32_to_cpu(val32.dword) != MAC_AX_R32_DEAD)
69 break;
70
71 PLTFM_MSG_ERR("[ERR]addr 0x%x = 0xdeadbeef\n", dw_adr);
72 PLTFM_SDIO_CMD53_W32(R_AX_CK_EN, CMAC_CLK_ALLEN);
73 cnt++;
74 }
75
76 return val32.byte[dw_sh];
77 }
78
_pltfm_sdio_cmd53_r16(struct mac_ax_adapter * adapter,u32 adr)79 static u16 _pltfm_sdio_cmd53_r16(struct mac_ax_adapter *adapter, u32 adr)
80 {
81 u32 dw_adr = adr & 0xFFFFFFFD;
82 u8 dw_sh = (adr - dw_adr) ? 1 : 0;
83 u8 cnt = 0;
84 union {
85 __le32 dword;
86 u16 word[2];
87 } val32 = { 0x00000000 };
88
89 if (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A) ||
90 is_chip_id(adapter, MAC_AX_CHIP_ID_8852B)) {
91 if (!(adr >= R_AX_CMAC_FUNC_EN && adr <= R_AX_CMAC_REG_END))
92 return PLTFM_SDIO_CMD53_R16(adr);
93 } else {
94 return PLTFM_SDIO_CMD53_R16(adr);
95 }
96
97 while (cnt < MAC_REG_POOL_COUNT) {
98 val32.dword = PLTFM_SDIO_CMD53_R32(dw_adr);
99
100 if (le32_to_cpu(val32.dword) != MAC_AX_R32_DEAD)
101 break;
102
103 PLTFM_MSG_ERR("[ERR]addr 0x%x = 0xdeadbeef\n", dw_adr);
104 PLTFM_SDIO_CMD53_W32(R_AX_CK_EN, CMAC_CLK_ALLEN);
105 cnt++;
106 }
107
108 return val32.word[dw_sh];
109 }
110
_pltfm_sdio_cmd53_r32(struct mac_ax_adapter * adapter,u32 adr)111 static u32 _pltfm_sdio_cmd53_r32(struct mac_ax_adapter *adapter, u32 adr)
112 {
113 u8 cnt = 0;
114 __le32 dword = 0x00000000;
115
116 if (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A) ||
117 is_chip_id(adapter, MAC_AX_CHIP_ID_8852B)) {
118 if (!(adr >= R_AX_CMAC_FUNC_EN && adr <= R_AX_CMAC_REG_END))
119 return PLTFM_SDIO_CMD53_R32(adr);
120 } else {
121 return PLTFM_SDIO_CMD53_R32(adr);
122 }
123
124 while (cnt < MAC_REG_POOL_COUNT) {
125 dword = PLTFM_SDIO_CMD53_R32(adr);
126
127 if (le32_to_cpu(dword) != MAC_AX_R32_DEAD)
128 break;
129
130 PLTFM_MSG_ERR("[ERR]addr 0x%x = 0xdeadbeef\n", adr);
131 PLTFM_SDIO_CMD53_W32(R_AX_CK_EN, CMAC_CLK_ALLEN);
132 cnt++;
133 }
134
135 return dword;
136 }
137
reg_read8_sdio(struct mac_ax_adapter * adapter,u32 adr)138 u8 reg_read8_sdio(struct mac_ax_adapter *adapter, u32 adr)
139 {
140 u8 val8;
141 u8 pwr_state, reg_domain;
142 enum mac_ax_sdio_4byte_mode cmd53_4byte = adapter->sdio_info.sdio_4byte;
143
144 pwr_state = pwr_state_chk_sdio(adapter);
145 reg_domain = reg_chk_sdio(adapter, adr);
146
147 if (reg_domain == SDIO_REG_LOCAL) {
148 val8 = PLTFM_SDIO_CMD52_R8(adr);
149 } else if (reg_domain == SDIO_REG_WLAN_PLTFM) {
150 val8 = (u8)r_indir_sdio(adapter, adr, SDIO_IO_BYTE);
151 } else {
152 if (pwr_state == SDIO_PWR_OFF)
153 val8 = (u8)r_indir_sdio(adapter, adr, SDIO_IO_BYTE);
154 else if (cmd53_4byte == MAC_AX_SDIO_4BYTE_MODE_DISABLE)
155 val8 = _pltfm_sdio_cmd53_r8(adapter, adr);
156 else
157 val8 = (u8)(_pltfm_sdio_cmd53_r32(adapter, adr) & 0xFF);
158 }
159
160 return val8;
161 }
162
reg_write8_sdio(struct mac_ax_adapter * adapter,u32 adr,u8 val)163 void reg_write8_sdio(struct mac_ax_adapter *adapter, u32 adr, u8 val)
164 {
165 u8 reg_domain;
166
167 reg_domain = reg_chk_sdio(adapter, adr);
168
169 if (reg_domain == SDIO_REG_LOCAL)
170 PLTFM_SDIO_CMD52_W8(adr, val);
171 else
172 w_indir_sdio(adapter, adr, val, SDIO_IO_BYTE);
173 }
174
reg_read16_sdio(struct mac_ax_adapter * adapter,u32 adr)175 u16 reg_read16_sdio(struct mac_ax_adapter *adapter, u32 adr)
176 {
177 u8 pwr_state, reg_domain;
178 enum mac_ax_sdio_4byte_mode sdio_4byte = adapter->sdio_info.sdio_4byte;
179 union {
180 __le16 word;
181 u8 byte[2];
182 } value16 = { 0x0000 };
183
184 pwr_state = pwr_state_chk_sdio(adapter);
185 reg_domain = reg_chk_sdio(adapter, adr);
186
187 if ((adr & (2 - 1)) == 0) {
188 if (pwr_state == SDIO_PWR_ON &&
189 sdio_4byte == MAC_AX_SDIO_4BYTE_MODE_DISABLE)
190 return _pltfm_sdio_cmd53_r16(adapter, adr);
191 if (reg_domain == SDIO_REG_LOCAL) {
192 value16.byte[0] = PLTFM_SDIO_CMD52_R8(adr);
193 value16.byte[1] = PLTFM_SDIO_CMD52_R8(adr + 1);
194 return le16_to_cpu(value16.word);
195 }
196 if (pwr_state == SDIO_PWR_OFF ||
197 reg_domain == SDIO_REG_WLAN_PLTFM)
198 return (u16)r_indir_sdio(adapter, adr, SDIO_IO_WORD);
199 return (u16)(_pltfm_sdio_cmd53_r32(adapter, adr) & 0xFFFF);
200 }
201
202 if (reg_domain == SDIO_REG_LOCAL) {
203 value16.byte[0] = PLTFM_SDIO_CMD52_R8(adr);
204 value16.byte[1] = PLTFM_SDIO_CMD52_R8(adr + 1);
205 return le16_to_cpu(value16.word);
206 }
207 value16.byte[0] = (u8)r_indir_sdio(adapter, adr, SDIO_IO_BYTE);
208 value16.byte[1] = (u8)r_indir_sdio(adapter, adr + 1, SDIO_IO_BYTE);
209 return le16_to_cpu(value16.word);
210 }
211
reg_write16_sdio(struct mac_ax_adapter * adapter,u32 adr,u16 val)212 void reg_write16_sdio(struct mac_ax_adapter *adapter, u32 adr, u16 val)
213 {
214 u8 pwr_state, reg_domain;
215 enum mac_ax_sdio_4byte_mode sdio_4byte = adapter->sdio_info.sdio_4byte;
216
217 pwr_state = pwr_state_chk_sdio(adapter);
218 reg_domain = reg_chk_sdio(adapter, adr);
219
220 if ((adr & (2 - 1)) == 0) {
221 if (pwr_state == SDIO_PWR_ON &&
222 sdio_4byte == MAC_AX_SDIO_4BYTE_MODE_DISABLE) {
223 PLTFM_SDIO_CMD53_W16(adr, val);
224 } else if (reg_domain == SDIO_REG_WLAN_REG ||
225 reg_domain == SDIO_REG_WLAN_PLTFM) {
226 w_indir_sdio(adapter, adr, val, SDIO_IO_WORD);
227 } else {
228 PLTFM_SDIO_CMD52_W8(adr, (u8)(val & 0xFF));
229 PLTFM_SDIO_CMD52_W8(adr + 1,
230 (u8)((val & 0xFF00) >> 8));
231 }
232 } else {
233 if (reg_domain == SDIO_REG_LOCAL) {
234 PLTFM_SDIO_CMD52_W8(adr, (u8)(val & 0xFF));
235 PLTFM_SDIO_CMD52_W8(adr + 1,
236 (u8)((val & 0xFF00) >> 8));
237 } else {
238 w_indir_sdio(adapter, adr, (u8)(val & 0xFF),
239 SDIO_IO_BYTE);
240 w_indir_sdio(adapter, adr + 1,
241 (u8)((val & 0xFF00) >> 8), SDIO_IO_BYTE);
242 }
243 }
244 }
245
reg_read32_sdio(struct mac_ax_adapter * adapter,u32 adr)246 u32 reg_read32_sdio(struct mac_ax_adapter *adapter, u32 adr)
247 {
248 u8 pwr_state, reg_domain;
249 union {
250 __le32 dword;
251 u8 byte[4];
252 } value32 = { 0x00000000 };
253
254 pwr_state = pwr_state_chk_sdio(adapter);
255 reg_domain = reg_chk_sdio(adapter, adr);
256
257 if ((adr & (4 - 1)) == 0) {
258 if (pwr_state == SDIO_PWR_OFF && reg_domain == SDIO_REG_LOCAL) {
259 value32.byte[0] = PLTFM_SDIO_CMD52_R8(adr);
260 value32.byte[1] = PLTFM_SDIO_CMD52_R8(adr + 1);
261 value32.byte[2] = PLTFM_SDIO_CMD52_R8(adr + 2);
262 value32.byte[3] = PLTFM_SDIO_CMD52_R8(adr + 3);
263 return le32_to_cpu(value32.dword);
264 }
265 if (pwr_state == SDIO_PWR_ON &&
266 (reg_domain == SDIO_REG_LOCAL ||
267 reg_domain == SDIO_REG_WLAN_REG))
268 return _pltfm_sdio_cmd53_r32(adapter, adr);
269 return r_indir_sdio(adapter, adr, SDIO_IO_DWORD);
270 }
271
272 if (reg_domain == SDIO_REG_LOCAL) {
273 value32.byte[0] = PLTFM_SDIO_CMD52_R8(adr);
274 value32.byte[1] = PLTFM_SDIO_CMD52_R8(adr + 1);
275 value32.byte[2] = PLTFM_SDIO_CMD52_R8(adr + 2);
276 value32.byte[3] = PLTFM_SDIO_CMD52_R8(adr + 3);
277 return le32_to_cpu(value32.dword);
278 }
279 value32.byte[0] = (u8)r_indir_sdio(adapter, adr, SDIO_IO_BYTE);
280 value32.byte[1] = (u8)r_indir_sdio(adapter, adr + 1, SDIO_IO_BYTE);
281 value32.byte[2] = (u8)r_indir_sdio(adapter, adr + 2, SDIO_IO_BYTE);
282 value32.byte[3] = (u8)r_indir_sdio(adapter, adr + 3, SDIO_IO_BYTE);
283 return le32_to_cpu(value32.dword);
284 }
285
reg_write32_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val)286 void reg_write32_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val)
287 {
288 u8 pwr_state, reg_domain;
289
290 pwr_state = pwr_state_chk_sdio(adapter);
291 reg_domain = reg_chk_sdio(adapter, adr);
292
293 if ((adr & (4 - 1)) == 0) {
294 if (pwr_state == SDIO_PWR_OFF && reg_domain == SDIO_REG_LOCAL) {
295 PLTFM_SDIO_CMD52_W8(adr, (u8)(val & 0xFF));
296 PLTFM_SDIO_CMD52_W8(adr + 1, (u8)((val >> 8) & 0xFF));
297 PLTFM_SDIO_CMD52_W8(adr + 2, (u8)((val >> 16) & 0xFF));
298 PLTFM_SDIO_CMD52_W8(adr + 3, (u8)((val >> 24) & 0xFF));
299 } else if (pwr_state == SDIO_PWR_ON &&
300 (reg_domain == SDIO_REG_LOCAL ||
301 reg_domain == SDIO_REG_WLAN_REG)) {
302 PLTFM_SDIO_CMD53_W32(adr, val);
303 } else {
304 w_indir_sdio(adapter, adr, val, SDIO_IO_DWORD);
305 }
306 } else {
307 if (reg_domain == SDIO_REG_LOCAL) {
308 PLTFM_SDIO_CMD52_W8(adr, (u8)(val & 0xFF));
309 PLTFM_SDIO_CMD52_W8(adr + 1, (u8)((val >> 8) & 0xFF));
310 PLTFM_SDIO_CMD52_W8(adr + 2, (u8)((val >> 16) & 0xFF));
311 PLTFM_SDIO_CMD52_W8(adr + 3, (u8)((val >> 24) & 0xFF));
312 } else {
313 w_indir_sdio(adapter, adr, (u8)(val & 0xFF),
314 SDIO_IO_BYTE);
315 w_indir_sdio(adapter, adr + 1,
316 (u8)((val >> 8) & 0xFF), SDIO_IO_BYTE);
317 w_indir_sdio(adapter, adr + 2,
318 (u8)((val >> 16) & 0xFF), SDIO_IO_BYTE);
319 w_indir_sdio(adapter, adr + 3,
320 (u8)((val >> 24) & 0xFF), SDIO_IO_BYTE);
321 }
322 }
323 }
324
reg_read_n_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 size,u8 * val)325 u32 reg_read_n_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 size, u8 *val)
326 {
327 u8 *r_val = NULL;
328 u32 r_size;
329 u8 pwr_state, reg_domain;
330 enum mac_ax_sdio_4byte_mode cmd53_4byte = adapter->sdio_info.sdio_4byte;
331
332 pwr_state = pwr_state_chk_sdio(adapter);
333 reg_domain = reg_chk_sdio(adapter, adr);
334
335 if (reg_domain != SDIO_REG_LOCAL) {
336 PLTFM_MSG_ERR("[ERR]adr 0x%x\n", adr);
337 return MACBADDR;
338 }
339
340 if (pwr_state == SDIO_PWR_OFF) {
341 PLTFM_MSG_ERR("[ERR]power off\n");
342 return MACPWRSTAT;
343 }
344
345 if (cmd53_4byte == MAC_AX_SDIO_4BYTE_MODE_RW && (size & 0x03) != 0) {
346 PLTFM_MSG_WARN("[WARN]reg_rn !align,addr 0x%x,siz %d\n", adr,
347 size);
348 r_size = size - (size & 0x03) + 4;
349 r_val = (u8 *)PLTFM_MALLOC(r_size);
350 if (!r_val) {
351 PLTFM_MSG_ERR("[ERR]malloc!!\n");
352 return MACBUFALLOC;
353 }
354 PLTFM_MEMSET(r_val, 0x00, r_size);
355 PLTFM_SDIO_CMD53_RN(adr, r_size, r_val);
356 PLTFM_MEMCPY(val, r_val, size);
357 PLTFM_FREE(r_val, r_size);
358 } else {
359 PLTFM_SDIO_CMD53_RN(adr, size, val);
360 }
361
362 return MACSUCCESS;
363 }
364
tx_allow_sdio(struct mac_ax_adapter * adapter,struct mac_ax_sdio_tx_info * info)365 u32 tx_allow_sdio(struct mac_ax_adapter *adapter,
366 struct mac_ax_sdio_tx_info *info)
367 {
368 u32 ret;
369
370 if (info->ch_dma != MAC_AX_DMA_H2C)
371 ret = tx_allow_data_ch(adapter, info);
372 else
373 ret = tx_allow_fwcmd_ch(adapter, info);
374
375 if (ret != MACSUCCESS)
376 return ret;
377
378 return MACSUCCESS;
379 }
380
tx_cmd_addr_sdio(struct mac_ax_adapter * adapter,struct mac_ax_sdio_tx_info * info,u32 * cmd_addr)381 u32 tx_cmd_addr_sdio(struct mac_ax_adapter *adapter,
382 struct mac_ax_sdio_tx_info *info, u32 *cmd_addr)
383 {
384 struct mac_ax_sdio_info *sdio_info = &adapter->sdio_info;
385 u16 block_size = sdio_info->block_size;
386 u32 len_unit1, len_unit8, val32, size;
387 enum sdio_tx_byte_cnt byte_cnt;
388 enum mac_ax_sdio_opn_mode opn_mode = sdio_info->opn_mode;
389
390 size = info->total_size;
391
392 if (size == 0) {
393 PLTFM_MSG_ERR("size is 0!!\n");
394 return MACBUFSZ;
395 }
396
397 if (info->ch_dma < 13)
398 *cmd_addr = (info->ch_dma << SDIO_CMD_ADDR_TXFF_SHIFT) |
399 SDIO_TX_BASE;
400 else
401 return MACTXCHDMA;
402
403 len_unit8 = (size >> 3) + ((size & (8 - 1)) ? 1 : 0);
404 len_unit1 = (len_unit8 << 3);
405
406 switch (sdio_info->tx_mode) {
407 case MAC_AX_SDIO_TX_MODE_AGG:
408 byte_cnt = SDIO_TX_AGG_8_BYTE_CNT;
409 break;
410 case MAC_AX_SDIO_TX_MODE_DUMMY_BLOCK:
411 byte_cnt = SDIO_TX_DUMMY_4_BYTE_CNT;
412 break;
413 case MAC_AX_SDIO_TX_MODE_DUMMY_AUTO:
414 if (len_unit1 == SDIO_BYTE_MODE_SIZE_MAX) {
415 if (opn_mode == MAC_AX_SDIO_OPN_MODE_BYTE) {
416 byte_cnt = SDIO_TX_AGG_8_BYTE_CNT;
417 } else if (opn_mode == MAC_AX_SDIO_OPN_MODE_BLOCK) {
418 byte_cnt = SDIO_TX_DUMMY_4_BYTE_CNT;
419 } else {
420 PLTFM_MSG_ERR("[ERR]opn_mode is unknown\n");
421 return MACSDIOOPNMODE;
422 }
423 } else if (len_unit1 >= block_size) {
424 byte_cnt = SDIO_TX_DUMMY_4_BYTE_CNT;
425 } else if (len_unit1 < SDIO_BYTE_MODE_SIZE_MAX) {
426 byte_cnt = SDIO_TX_AGG_8_BYTE_CNT;
427 } else {
428 byte_cnt = SDIO_TX_DUMMY_4_BYTE_CNT;
429 }
430 break;
431 default:
432 PLTFM_MSG_ERR("[ERR]tx_mode is undefined\n");
433 return MACSDIOTXMODE;
434 }
435
436 if (byte_cnt == SDIO_TX_AGG_8_BYTE_CNT) {
437 *cmd_addr |= len_unit8 & SDIO_8BYTE_LEN_MASK;
438 } else if (byte_cnt == SDIO_TX_DUMMY_4_BYTE_CNT) {
439 val32 = len_unit1 & (block_size - 1);
440 if (val32)
441 val32 = block_size - val32;
442 val32 = (val32 >> 2) & SDIO_4BYTE_LEN_MASK;
443 *cmd_addr |= (val32 << 1) | sdio_info->tx_seq;
444 sdio_info->tx_seq = ~sdio_info->tx_seq & 0x01;
445 }
446
447 //cmd_len = adapter->sdio_info.tx_align_size;
448
449 return MACSUCCESS;
450 }
451
sdio_pre_init(struct mac_ax_adapter * adapter,void * param)452 u32 sdio_pre_init(struct mac_ax_adapter *adapter, void *param)
453 {
454 u16 val16;
455 u32 val32;
456 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
457
458 val32 = MAC_REG_R32(R_AX_HCI_OPT_CTRL);
459 MAC_REG_W32(R_AX_HCI_OPT_CTRL, val32 | B_AX_SDIO_DATA_PAD_SMT);
460
461 val32 = MAC_REG_R32(R_AX_SDIO_TX_CTRL) & ~(B_AX_CMD53_TX_FORMAT);
462 MAC_REG_W32(R_AX_SDIO_TX_CTRL, val32 | B_AX_RXINT_READ_MASK_DIS);
463 adapter->sdio_info.tx_mode = MAC_AX_SDIO_TX_MODE_AGG;
464 adapter->sdio_info.tx_seq = 1;
465
466 val16 = MAC_REG_R16(R_AX_SDIO_BUS_CTRL);
467 MAC_REG_W16(R_AX_SDIO_BUS_CTRL, val16 | B_AX_EN_RPT_TXCRC);
468
469 return MACSUCCESS;
470 }
471
sdio_init(struct mac_ax_adapter * adapter,void * param)472 u32 sdio_init(struct mac_ax_adapter *adapter, void *param)
473 {
474 u32 val32;
475 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
476
477 if (adapter->hw_info->intf != MAC_AX_INTF_SDIO)
478 return MACINTF;
479
480 val32 = MAC_REG_R32(R_AX_RXDMA_SETTING);
481 MAC_REG_W32(R_AX_RXDMA_SETTING, val32 & ~B_AX_PLE_BURST_READ);
482
483 return MACSUCCESS;
484 }
485
sdio_deinit(struct mac_ax_adapter * adapter,void * param)486 u32 sdio_deinit(struct mac_ax_adapter *adapter, void *param)
487 {
488 return MACSUCCESS;
489 }
490
r_indir_sdio(struct mac_ax_adapter * adapter,u32 adr,enum sdio_io_size size)491 u32 r_indir_sdio(struct mac_ax_adapter *adapter, u32 adr,
492 enum sdio_io_size size)
493 {
494 u32 value32 = 0;
495
496 PLTFM_MUTEX_LOCK(&sdio_tbl.lock);
497
498 switch (size) {
499 case SDIO_IO_BYTE:
500 value32 = r8_indir_sdio(adapter, adr);
501 break;
502 case SDIO_IO_WORD:
503 value32 = r16_indir_sdio(adapter, adr);
504 break;
505 case SDIO_IO_DWORD:
506 value32 = r32_indir_sdio(adapter, adr);
507 break;
508 default:
509 PLTFM_MSG_ERR("[ERR]invalid IO size\n");
510 break;
511 }
512
513 PLTFM_MUTEX_UNLOCK(&sdio_tbl.lock);
514
515 return value32;
516 }
517
w_indir_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val,enum sdio_io_size size)518 void w_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val,
519 enum sdio_io_size size)
520 {
521 PLTFM_MUTEX_LOCK(&sdio_tbl.lock);
522
523 switch (size) {
524 case SDIO_IO_BYTE:
525 w8_indir_sdio(adapter, adr, val);
526 break;
527 case SDIO_IO_WORD:
528 w16_indir_sdio(adapter, adr, val);
529 break;
530 case SDIO_IO_DWORD:
531 w32_indir_sdio(adapter, adr, val);
532 break;
533 default:
534 PLTFM_MSG_ERR("[ERR]invalid IO size\n");
535 break;
536 }
537
538 PLTFM_MUTEX_UNLOCK(&sdio_tbl.lock);
539 }
540
set_info_sdio(struct mac_ax_adapter * adapter,struct mac_ax_sdio_info * info)541 u32 set_info_sdio(struct mac_ax_adapter *adapter, struct mac_ax_sdio_info *info)
542 {
543 adapter->sdio_info.spec_ver = info->spec_ver;
544 adapter->sdio_info.block_size = info->block_size;
545 adapter->sdio_info.sdio_4byte = info->sdio_4byte;
546 adapter->sdio_info.opn_mode = info->opn_mode;
547
548 return MACSUCCESS;
549 }
550
tx_mode_cfg_sdio(struct mac_ax_adapter * adapter,enum mac_ax_sdio_tx_mode mode)551 u32 tx_mode_cfg_sdio(struct mac_ax_adapter *adapter,
552 enum mac_ax_sdio_tx_mode mode)
553 {
554 u16 val16;
555 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
556
557 val16 = MAC_REG_R16(R_AX_SDIO_TX_CTRL);
558
559 if (mode == MAC_AX_SDIO_TX_MODE_AGG) {
560 MAC_REG_W16(R_AX_SDIO_TX_CTRL, val16 & ~(B_AX_CMD53_TX_FORMAT));
561 } else if (mode == MAC_AX_SDIO_TX_MODE_DUMMY_BLOCK ||
562 mode == MAC_AX_SDIO_TX_MODE_DUMMY_AUTO) {
563 if ((val16 & B_AX_CMD53_W_MIX) == 0) {
564 MAC_REG_W16(R_AX_SDIO_TX_CTRL,
565 val16 | B_AX_CMD53_TX_FORMAT);
566 } else {
567 if ((val16 & B_AX_CMD53_TX_FORMAT) == 0)
568 return MACSDIOMIXMODE;
569 else
570 return MACSDIOSEQERR;
571 }
572 } else {
573 PLTFM_MSG_ERR("[ERR]sdio tx mode = %d\n", mode);
574 return MACNOITEM;
575 }
576
577 adapter->sdio_info.tx_mode = mode;
578
579 return MACSUCCESS;
580 }
581
rx_agg_cfg_sdio(struct mac_ax_adapter * adapter,struct mac_ax_rx_agg_cfg * cfg)582 void rx_agg_cfg_sdio(struct mac_ax_adapter *adapter,
583 struct mac_ax_rx_agg_cfg *cfg)
584 {
585 u8 size;
586 u8 timeout;
587 u8 agg_en;
588 u8 pkt_num;
589 u32 val32;
590 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
591
592 if (cfg->mode == MAC_AX_RX_AGG_MODE_DMA)
593 agg_en = 1;
594 else
595 agg_en = 0;
596
597 if (cfg->thold.drv_define == 0) {
598 size = 0xFF;
599 timeout = 0x01;
600 pkt_num = 0;
601 } else {
602 size = cfg->thold.size;
603 timeout = cfg->thold.timeout;
604 pkt_num = cfg->thold.pkt_num;
605 }
606
607 val32 = MAC_REG_R32(R_AX_RXAGG_0);
608 MAC_REG_W32(R_AX_RXAGG_0, (agg_en ? B_AX_RXAGG_EN : 0) |
609 B_AX_RXAGG_DMA_STORE | (val32 & B_AX_RXAGG_SW_EN) |
610 SET_WORD(pkt_num, B_AX_RXAGG_PKTNUM_TH) |
611 SET_WORD(timeout, B_AX_RXAGG_TIMEOUT_TH) |
612 SET_WORD(size, B_AX_RXAGG_LEN_TH));
613 }
614
tx_agg_cfg_sdio(struct mac_ax_adapter * adapter,struct mac_ax_sdio_txagg_cfg * cfg)615 u32 tx_agg_cfg_sdio(struct mac_ax_adapter *adapter,
616 struct mac_ax_sdio_txagg_cfg *cfg)
617 {
618 u8 i;
619 u8 flag = 0;
620 u16 align_size = cfg->align_size;
621 u8 enable = cfg->en;
622 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
623
624 if ((align_size & 0xF000) != 0) {
625 PLTFM_MSG_ERR("[ERR]out of range\n");
626 return MACFUNCINPUT;
627 }
628
629 for (i = 3; i <= 11; i++) {
630 if (align_size == 1 << i) {
631 flag = 1;
632 break;
633 }
634 }
635
636 if (flag == 0) {
637 PLTFM_MSG_ERR("[ERR]not 2^3 ~ 2^11\n");
638 return MACFUNCINPUT;
639 }
640
641 if (enable) {
642 MAC_REG_W32(R_AX_TXAGG_ALIGN_CFG,
643 align_size | B_AX_TXAGG_ALIGN_SIZE_EN);
644 } else {
645 MAC_REG_W32(R_AX_TXAGG_ALIGN_CFG,
646 align_size & ~B_AX_TXAGG_ALIGN_SIZE_EN);
647 align_size = 8;
648 }
649
650 adapter->sdio_info.tx_align_size = align_size;
651
652 return MACSUCCESS;
653 }
654
aval_page_cfg_sdio(struct mac_ax_adapter * adapter,struct mac_ax_aval_page_cfg * cfg)655 void aval_page_cfg_sdio(struct mac_ax_adapter *adapter,
656 struct mac_ax_aval_page_cfg *cfg)
657 {
658 u32 val32;
659 struct mac_sdio_ch_thr ch_thr;
660 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
661
662 switch (cfg->ch_dma) {
663 case 0:
664 ch_thr.thr = R_AX_ACH0_THR;
665 ch_thr.intrpt_en = B_AX_ACH0_INTRPT_EN;
666 ch_thr.wp_sh = B_AX_ACH0_THR_WP_SH;
667 ch_thr.wp_msk = B_AX_ACH0_THR_WP_MSK;
668 ch_thr.wd_sh = B_AX_ACH0_THR_WD_SH;
669 ch_thr.wd_msk = B_AX_ACH0_THR_WD_MSK;
670 break;
671 case 1:
672 ch_thr.thr = R_AX_ACH1_THR;
673 ch_thr.intrpt_en = B_AX_ACH1_INTRPT_EN;
674 ch_thr.wp_sh = B_AX_ACH1_THR_WP_SH;
675 ch_thr.wp_msk = B_AX_ACH1_THR_WP_MSK;
676 ch_thr.wd_sh = B_AX_ACH1_THR_WD_SH;
677 ch_thr.wd_msk = B_AX_ACH1_THR_WD_MSK;
678 break;
679 case 2:
680 ch_thr.thr = R_AX_ACH2_THR;
681 ch_thr.intrpt_en = B_AX_ACH2_INTRPT_EN;
682 ch_thr.wp_sh = B_AX_ACH2_THR_WP_SH;
683 ch_thr.wp_msk = B_AX_ACH2_THR_WP_MSK;
684 ch_thr.wd_sh = B_AX_ACH2_THR_WD_SH;
685 ch_thr.wd_msk = B_AX_ACH2_THR_WD_MSK;
686 break;
687 case 3:
688 ch_thr.thr = R_AX_ACH3_THR;
689 ch_thr.intrpt_en = B_AX_ACH3_INTRPT_EN;
690 ch_thr.wp_sh = B_AX_ACH3_THR_WP_SH;
691 ch_thr.wp_msk = B_AX_ACH3_THR_WP_MSK;
692 ch_thr.wd_sh = B_AX_ACH3_THR_WD_SH;
693 ch_thr.wd_msk = B_AX_ACH3_THR_WD_MSK;
694 break;
695 case 4:
696 ch_thr.thr = R_AX_ACH4_THR;
697 ch_thr.intrpt_en = B_AX_ACH4_INTRPT_EN;
698 ch_thr.wp_sh = B_AX_ACH4_THR_WP_SH;
699 ch_thr.wp_msk = B_AX_ACH4_THR_WP_MSK;
700 ch_thr.wd_sh = B_AX_ACH4_THR_WD_SH;
701 ch_thr.wd_msk = B_AX_ACH4_THR_WD_MSK;
702 break;
703 case 5:
704 ch_thr.thr = R_AX_ACH5_THR;
705 ch_thr.intrpt_en = B_AX_ACH5_INTRPT_EN;
706 ch_thr.wp_sh = B_AX_ACH5_THR_WP_SH;
707 ch_thr.wp_msk = B_AX_ACH5_THR_WP_MSK;
708 ch_thr.wd_sh = B_AX_ACH5_THR_WD_SH;
709 ch_thr.wd_msk = B_AX_ACH5_THR_WD_MSK;
710 break;
711 case 6:
712 ch_thr.thr = R_AX_ACH6_THR;
713 ch_thr.intrpt_en = B_AX_ACH6_INTRPT_EN;
714 ch_thr.wp_sh = B_AX_ACH6_THR_WP_SH;
715 ch_thr.wp_msk = B_AX_ACH6_THR_WP_MSK;
716 ch_thr.wd_sh = B_AX_ACH6_THR_WD_SH;
717 ch_thr.wd_msk = B_AX_ACH6_THR_WD_MSK;
718 break;
719 case 7:
720 ch_thr.thr = R_AX_ACH7_THR;
721 ch_thr.intrpt_en = B_AX_ACH7_INTRPT_EN;
722 ch_thr.wp_sh = B_AX_ACH7_THR_WP_SH;
723 ch_thr.wp_msk = B_AX_ACH7_THR_WP_MSK;
724 ch_thr.wd_sh = B_AX_ACH7_THR_WD_SH;
725 ch_thr.wd_msk = B_AX_ACH7_THR_WD_MSK;
726 break;
727 case 8:
728 ch_thr.thr = R_AX_CH8_THR;
729 ch_thr.intrpt_en = B_AX_CH8_INTRPT_EN;
730 ch_thr.wp_sh = B_AX_CH8_THR_WP_SH;
731 ch_thr.wp_msk = B_AX_CH8_THR_WP_MSK;
732 ch_thr.wd_sh = B_AX_CH8_THR_WD_SH;
733 ch_thr.wd_msk = B_AX_CH8_THR_WD_MSK;
734 break;
735 case 9:
736 ch_thr.thr = R_AX_CH9_THR;
737 ch_thr.intrpt_en = B_AX_CH9_INTRPT_EN;
738 ch_thr.wp_sh = B_AX_CH9_THR_WP_SH;
739 ch_thr.wp_msk = B_AX_CH9_THR_WP_MSK;
740 ch_thr.wd_sh = B_AX_CH9_THR_WD_SH;
741 ch_thr.wd_msk = B_AX_CH9_THR_WD_MSK;
742 break;
743 case 10:
744 ch_thr.thr = R_AX_CH10_THR;
745 ch_thr.intrpt_en = B_AX_CH10_INTRPT_EN;
746 ch_thr.wp_sh = B_AX_CH10_THR_WP_SH;
747 ch_thr.wp_msk = B_AX_CH10_THR_WP_MSK;
748 ch_thr.wd_sh = B_AX_CH10_THR_WD_SH;
749 ch_thr.wd_msk = B_AX_CH10_THR_WD_MSK;
750 break;
751 case 11:
752 ch_thr.thr = R_AX_CH11_THR;
753 ch_thr.intrpt_en = B_AX_CH11_INTRPT_EN;
754 ch_thr.wp_sh = B_AX_CH11_THR_WP_SH;
755 ch_thr.wp_msk = B_AX_CH11_THR_WP_MSK;
756 ch_thr.wd_sh = B_AX_CH11_THR_WD_SH;
757 ch_thr.wd_msk = B_AX_CH11_THR_WD_MSK;
758 break;
759 default:
760 PLTFM_MSG_ERR("[ERR]invalid channel number\n");
761 return;
762 }
763
764 val32 = ((cfg->thold_wd & ch_thr.wd_msk) << ch_thr.wd_sh) |
765 ((cfg->thold_wp & ch_thr.wp_msk) << ch_thr.wp_sh);
766 if (cfg->en)
767 val32 |= ch_thr.intrpt_en;
768 else
769 val32 &= ~ch_thr.intrpt_en;
770 MAC_REG_W32(ch_thr.thr, val32);
771 }
772
get_int_latency_sdio(struct mac_ax_adapter * adapter)773 u32 get_int_latency_sdio(struct mac_ax_adapter *adapter)
774 {
775 u32 free_cnt, free_cnt2;
776 u32 int_start;
777 u32 int_latency = 0;
778 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
779
780 int_start = MAC_REG_R32(R_AX_SDIO_MONITOR);
781 free_cnt = MAC_REG_R32(R_AX_FREERUN_CNT_LOW);
782 free_cnt2 = MAC_REG_R32(R_AX_FREERUN_CNT_LOW);
783 int_latency = free_cnt - int_start - (free_cnt2 - free_cnt);
784
785 return int_latency;
786 }
787
get_clk_cnt_sdio(struct mac_ax_adapter * adapter,u32 * cnt)788 u32 get_clk_cnt_sdio(struct mac_ax_adapter *adapter, u32 *cnt)
789 {
790 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
791 u32 val32;
792
793 val32 = MAC_REG_R32(R_AX_SDIO_MONITOR_2);
794 if (GET_FIELD(val32, B_AX_SDIO_CLK_MONITOR) == 0)
795 *cnt = GET_FIELD(val32, B_AX_SDIO_CLK_CNT);
796 else
797 return MACNOITEM;
798
799 return MACSUCCESS;
800 }
801
set_wt_cfg_sdio(struct mac_ax_adapter * adapter,u8 en)802 u32 set_wt_cfg_sdio(struct mac_ax_adapter *adapter, u8 en)
803 {
804 u32 reg = R_AX_SDIO_MONITOR_2 + 2;
805
806 if (en)
807 PLTFM_SDIO_CMD52_W8(reg, BIT(7));
808 else
809 PLTFM_SDIO_CMD52_W8(reg, 0);
810
811 return MACSUCCESS;
812 }
813
set_clk_mon_sdio(struct mac_ax_adapter * adapter,struct mac_ax_sdio_clk_mon_cfg * cfg)814 u32 set_clk_mon_sdio(struct mac_ax_adapter *adapter,
815 struct mac_ax_sdio_clk_mon_cfg *cfg)
816 {
817 u32 reg = R_AX_SDIO_MONITOR_2 + 2;
818 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
819
820 set_wt_cfg_sdio(adapter, 0);
821
822 switch (cfg->mon) {
823 case MAC_AX_SDIO_CLK_MON_SHORT:
824 PLTFM_SDIO_CMD52_W8(reg, BIT(5));
825 break;
826 case MAC_AX_SDIO_CLK_MON_LONG:
827 PLTFM_SDIO_CMD52_W8(reg, BIT(6));
828 break;
829 case MAC_AX_SDIO_CLK_MON_USER_DEFINE:
830 MAC_REG_W32(R_AX_SDIO_MONITOR_2,
831 cfg->cycle & B_AX_SDIO_CLK_CNT_MSK);
832 PLTFM_SDIO_CMD52_W8(reg, BIT(5) | BIT(6));
833 break;
834 default:
835 break;
836 }
837
838 return MACSUCCESS;
839 }
840
sdio_tbl_init(struct mac_ax_adapter * adapter)841 u32 sdio_tbl_init(struct mac_ax_adapter *adapter)
842 {
843 PLTFM_MUTEX_INIT(&sdio_tbl.lock);
844
845 return MACSUCCESS;
846 }
847
sdio_tbl_exit(struct mac_ax_adapter * adapter)848 u32 sdio_tbl_exit(struct mac_ax_adapter *adapter)
849 {
850 PLTFM_MUTEX_DEINIT(&sdio_tbl.lock);
851
852 return MACSUCCESS;
853 }
854
leave_suspend_sdio(struct mac_ax_adapter * adapter)855 u32 leave_suspend_sdio(struct mac_ax_adapter *adapter)
856 {
857 u8 val8;
858 u32 cnt;
859 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
860
861 val8 = MAC_REG_R8(R_AX_SDIO_BUS_CTRL + 2);
862 MAC_REG_W8(R_AX_SDIO_BUS_CTRL + 2, val8 & ~(BIT(0)));
863
864 cnt = 10000;
865 while (!(MAC_REG_R8(R_AX_SDIO_BUS_CTRL + 2) & BIT(1))) {
866 cnt--;
867 if (cnt == 0)
868 return MACLSUS;
869 }
870
871 val8 = MAC_REG_R8(R_AX_HCI_OPT_CTRL + 2);
872 if (adapter->sdio_info.spec_ver == MAC_AX_SDIO_SPEC_VER_3_00)
873 MAC_REG_W8(R_AX_HCI_OPT_CTRL + 2, val8 | BIT(2));
874 else
875 MAC_REG_W8(R_AX_HCI_OPT_CTRL + 2, val8 & ~(BIT(2)));
876
877 return MACSUCCESS;
878 }
879
sdio_pwr_switch(void * vadapter,u8 pre_switch,u8 on)880 u32 sdio_pwr_switch(void *vadapter,
881 u8 pre_switch, u8 on)
882 {
883 struct mac_ax_adapter *adapter = (struct mac_ax_adapter *)vadapter;
884 struct mac_ax_intf_ops *ops = adapter_to_intf_ops(adapter);
885
886 if (pre_switch == PWR_PRE_SWITCH) {
887 adapter->sdio_info.rpwm_bak = MAC_REG_R32(R_AX_SDIO_HIMR);
888 MAC_REG_W32(R_AX_SDIO_HIMR, 0);
889 adapter->mac_pwr_info.pwr_seq_proc = 1;
890 } else if (pre_switch == PWR_POST_SWITCH) {
891 if (on)
892 adapter->sdio_info.tx_seq = 1;
893 adapter->mac_pwr_info.pwr_seq_proc = 0;
894 } else if (pre_switch == PWR_END_SWITCH) {
895 MAC_REG_W32(R_AX_SDIO_HIMR, adapter->sdio_info.rpwm_bak);
896 }
897
898 return MACSUCCESS;
899 }
900
set_sdio_wowlan(struct mac_ax_adapter * adapter,enum mac_ax_wow_ctrl w_c)901 u32 set_sdio_wowlan(struct mac_ax_adapter *adapter, enum mac_ax_wow_ctrl w_c)
902 {
903 return MACSUCCESS;
904 }
905
r_indir_cmd52_sdio(struct mac_ax_adapter * adapter,u32 adr)906 static u8 r_indir_cmd52_sdio(struct mac_ax_adapter *adapter, u32 adr)
907 {
908 u8 count = 0;
909 u32 dw_adr = adr & 0xFFFFFFFC;
910 u8 dw_sh = adr & (4 - 1);
911 u32 val = CMAC_CLK_ALLEN;
912
913 union {
914 __le32 dword;
915 u8 byte[4];
916 } val32 = { 0x00000000 };
917
918 if (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A) ||
919 is_chip_id(adapter, MAC_AX_CHIP_ID_8852B)) {
920 if (!(adr >= R_AX_CMAC_FUNC_EN && adr <= R_AX_CMAC_REG_END))
921 return _r_indir_cmd52_sdio(adapter, adr);
922 } else {
923 return _r_indir_cmd52_sdio(adapter, adr);
924 }
925
926 while (count < MAC_REG_POOL_COUNT) {
927 val32.byte[0] = _r_indir_cmd52_sdio(adapter, dw_adr);
928 val32.byte[1] =
929 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 1);
930 val32.byte[2] =
931 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 2);
932 val32.byte[3] =
933 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 3);
934
935 if (le32_to_cpu(val32.dword) != MAC_AX_R32_DEAD)
936 break;
937
938 PLTFM_MSG_ERR("[ERR]addr 0x%x = 0xdeadbeef\n", dw_adr);
939
940 PLTFM_SDIO_CMD52_W8(R_AX_CK_EN, (u8)val);
941 PLTFM_SDIO_CMD52_W8(R_AX_CK_EN + 1, (u8)(val >> 8));
942 PLTFM_SDIO_CMD52_W8(R_AX_CK_EN + 2, (u8)(val >> 16));
943 PLTFM_SDIO_CMD52_W8(R_AX_CK_EN + 3, (u8)(val >> 24));
944
945 count++;
946 }
947
948 return val32.byte[dw_sh];
949 }
950
_r_indir_cmd52_sdio(struct mac_ax_adapter * adapter,u32 adr)951 static u8 _r_indir_cmd52_sdio(struct mac_ax_adapter *adapter, u32 adr)
952 {
953 u8 tmp;
954 u32 cnt;
955
956 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR, (u8)adr);
957 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR + 1, (u8)(adr >> 8));
958 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR + 2, (u8)(adr >> 16));
959 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR + 3,
960 (u8)((adr | B_AX_INDIRECT_RDY) >> 24));
961 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_CTRL, (u8)B_AX_INDIRECT_REG_R);
962
963 cnt = SDIO_WAIT_CNT;
964 do {
965 tmp = PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_ADDR + 3);
966 cnt--;
967 } while (((tmp & BIT(7)) == 0) && (cnt > 0));
968
969 if (((tmp & BIT(7)) == 0) && cnt == 0)
970 PLTFM_MSG_ERR("[ERR]sdio indirect CMD52 read\n");
971
972 return PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA);
973 }
974
r_indir_cmd53_sdio(struct mac_ax_adapter * adapter,u32 adr)975 static u32 r_indir_cmd53_sdio(struct mac_ax_adapter *adapter, u32 adr)
976 {
977 u32 dw_adr = adr & 0xFFFFFFFC;
978 u8 dw_sh = (adr & (4 - 1)) << 3;
979 u8 count = 0;
980 u32 dw = 0;
981
982 if (is_chip_id(adapter, MAC_AX_CHIP_ID_8852A) ||
983 is_chip_id(adapter, MAC_AX_CHIP_ID_8852B)) {
984 if (!(adr >= R_AX_CMAC_FUNC_EN && adr <= R_AX_CMAC_REG_END))
985 return _r_indir_cmd53_sdio(adapter, adr);
986 } else {
987 return _r_indir_cmd53_sdio(adapter, adr);
988 }
989
990 while (count < MAC_REG_POOL_COUNT) {
991 dw = _r_indir_cmd53_sdio(adapter, dw_adr);
992 if (dw != MAC_AX_R32_DEAD)
993 break;
994 PLTFM_MSG_ERR("[ERR]addr 0x%x = 0xdeadbeef\n", dw_adr);
995 PLTFM_SDIO_CMD53_W32(R_AX_CK_EN, CMAC_CLK_ALLEN);
996 count++;
997 }
998
999 return (dw >> dw_sh);
1000 }
1001
_r_indir_cmd53_sdio(struct mac_ax_adapter * adapter,u32 adr)1002 static u32 _r_indir_cmd53_sdio(struct mac_ax_adapter *adapter, u32 adr)
1003 {
1004 u8 val[12] = {0};
1005 u32 cnt, i;
1006
1007 union {
1008 __le32 dword;
1009 u8 byte[4];
1010 } value32 = { 0x00000000 };
1011
1012 for (i = 0; i < 3; i++)
1013 *(val + i) = (u8)(adr >> (i << 3));
1014 *(val + 3) = (u8)((adr | B_AX_INDIRECT_RDY) >> 24);
1015 *(val + 8) = (u8)(B_AX_INDIRECT_REG_R);
1016 PLTFM_SDIO_CMD53_WN(R_AX_SDIO_INDIRECT_ADDR, sizeof(val), val);
1017
1018 cnt = SDIO_WAIT_CNT;
1019 do {
1020 PLTFM_SDIO_CMD53_RN(R_AX_SDIO_INDIRECT_ADDR + 3, 8, val);
1021 cnt--;
1022 } while (((val[0] & BIT(7)) == 0) && (cnt > 0));
1023
1024 if (((val[0] & BIT(7)) == 0) && cnt == 0)
1025 PLTFM_MSG_ERR("[ERR]sdio indirect CMD53 read\n");
1026
1027 value32.byte[0] = val[1];
1028 value32.byte[1] = val[2];
1029 value32.byte[2] = val[3];
1030 value32.byte[3] = val[4];
1031
1032 return le32_to_cpu(value32.dword);
1033 }
1034
r8_indir_sdio(struct mac_ax_adapter * adapter,u32 adr)1035 static u32 r8_indir_sdio(struct mac_ax_adapter *adapter, u32 adr)
1036 {
1037 u8 pwr_state;
1038 union {
1039 __le32 dword;
1040 u8 byte[4];
1041 } val32 = { 0x00000000 };
1042
1043 pwr_state = pwr_state_chk_sdio(adapter);
1044
1045 if (pwr_state == SDIO_PWR_OFF) {
1046 val32.byte[0] = r_indir_cmd52_sdio(adapter, adr);
1047 return le32_to_cpu(val32.dword);
1048 }
1049
1050 return r_indir_cmd53_sdio(adapter, adr);
1051 }
1052
r16_indir_sdio(struct mac_ax_adapter * adapter,u32 adr)1053 static u32 r16_indir_sdio(struct mac_ax_adapter *adapter, u32 adr)
1054 {
1055 u8 pwr_state;
1056 union {
1057 __le32 dword;
1058 u8 byte[4];
1059 } val32 = { 0x00000000 };
1060
1061 pwr_state = pwr_state_chk_sdio(adapter);
1062
1063 if (pwr_state == SDIO_PWR_OFF) {
1064 val32.byte[0] = r_indir_cmd52_sdio(adapter, adr);
1065 val32.byte[1] =
1066 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 1);
1067 return le32_to_cpu(val32.dword);
1068 }
1069
1070 return r_indir_cmd53_sdio(adapter, adr);
1071 }
1072
r32_indir_sdio(struct mac_ax_adapter * adapter,u32 adr)1073 static u32 r32_indir_sdio(struct mac_ax_adapter *adapter, u32 adr)
1074 {
1075 u8 pwr_state;
1076 union {
1077 __le32 dword;
1078 u8 byte[4];
1079 } val32 = { 0x00000000 };
1080
1081 pwr_state = pwr_state_chk_sdio(adapter);
1082
1083 if (pwr_state == SDIO_PWR_OFF) {
1084 val32.byte[0] = r_indir_cmd52_sdio(adapter, adr);
1085 val32.byte[1] =
1086 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 1);
1087 val32.byte[2] =
1088 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 2);
1089 val32.byte[3] =
1090 PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_DATA + 3);
1091 return le32_to_cpu(val32.dword);
1092 }
1093
1094 return r_indir_cmd53_sdio(adapter, adr);
1095 }
1096
w_indir_cmd52_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val,enum sdio_io_size size)1097 static void w_indir_cmd52_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val,
1098 enum sdio_io_size size)
1099 {
1100 u8 tmp;
1101 u32 cnt;
1102
1103 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR, (u8)adr);
1104 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR + 1, (u8)(adr >> 8));
1105 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR + 2, (u8)(adr >> 16));
1106 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_ADDR + 3,
1107 (u8)((adr | B_AX_INDIRECT_RDY) >> 24));
1108 switch (size) {
1109 case SDIO_IO_BYTE:
1110 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA, (u8)val);
1111 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_CTRL,
1112 (u8)(B_AX_INDIRECT_REG_W));
1113 break;
1114 case SDIO_IO_WORD:
1115 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA, (u8)val);
1116 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA + 1,
1117 (u8)(val >> 8));
1118 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_CTRL,
1119 (u8)(B_AX_INDIRECT_REG_W | 0x1));
1120 break;
1121 case SDIO_IO_DWORD:
1122 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA, (u8)val);
1123 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA + 1,
1124 (u8)(val >> 8));
1125 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA + 2,
1126 (u8)(val >> 16));
1127 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_DATA + 3,
1128 (u8)(val >> 24));
1129 PLTFM_SDIO_CMD52_W8(R_AX_SDIO_INDIRECT_CTRL,
1130 (u8)(B_AX_INDIRECT_REG_W | 0x2));
1131 break;
1132 default:
1133 PLTFM_MSG_ERR("[ERR]invalid IO size\n");
1134 break;
1135 }
1136
1137 cnt = SDIO_WAIT_CNT;
1138 do {
1139 tmp = PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_ADDR + 3);
1140 cnt--;
1141 } while (((tmp & BIT(7)) == 0) && (cnt > 0));
1142
1143 if (((tmp & BIT(7)) == 0) && cnt == 0)
1144 PLTFM_MSG_ERR("[ERR]sdio indirect CMD52 write\n");
1145 }
1146
w_indir_cmd53_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val,enum sdio_io_size size)1147 static void w_indir_cmd53_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val,
1148 enum sdio_io_size size)
1149 {
1150 u8 value[12] = {0};
1151 u8 tmp;
1152 u32 cnt, i;
1153
1154 switch (size) {
1155 case SDIO_IO_BYTE:
1156 *(value + 8) = (u8)B_AX_INDIRECT_REG_W;
1157 break;
1158 case SDIO_IO_WORD:
1159 *(value + 8) = (u8)(B_AX_INDIRECT_REG_W | 0x1);
1160 break;
1161 case SDIO_IO_DWORD:
1162 *(value + 8) = (u8)(B_AX_INDIRECT_REG_W | 0x2);
1163 break;
1164 default:
1165 PLTFM_MSG_ERR("[ERR]invalid IO size\n");
1166 break;
1167 }
1168
1169 for (i = 0; i < 3; i++)
1170 *(value + i) = (u8)(adr >> (i << 3));
1171 *(value + 3) = (u8)((adr | B_AX_INDIRECT_RDY) >> 24);
1172 for (i = 0; i < 4; i++)
1173 *(value + i + 4) = (u8)(val >> (i << 3));
1174 PLTFM_SDIO_CMD53_WN(R_AX_SDIO_INDIRECT_ADDR, sizeof(value), value);
1175
1176 cnt = SDIO_WAIT_CNT;
1177 do {
1178 tmp = PLTFM_SDIO_CMD52_R8(R_AX_SDIO_INDIRECT_ADDR + 3);
1179 cnt--;
1180 } while (((tmp & BIT(7)) == 0) && (cnt > 0));
1181
1182 if (((tmp & BIT(7)) == 0) && cnt == 0)
1183 PLTFM_MSG_ERR("[ERR]sdio indirect CMD53 read\n");
1184 }
1185
w8_indir_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val)1186 static void w8_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val)
1187 {
1188 u8 pwr_state = pwr_state_chk_sdio(adapter);
1189
1190 if (pwr_state == SDIO_PWR_OFF)
1191 w_indir_cmd52_sdio(adapter, adr, val, SDIO_IO_BYTE);
1192 else
1193 w_indir_cmd53_sdio(adapter, adr, val, SDIO_IO_BYTE);
1194 }
1195
w16_indir_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val)1196 static void w16_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val)
1197 {
1198 u8 pwr_state = pwr_state_chk_sdio(adapter);
1199
1200 if (pwr_state == SDIO_PWR_OFF)
1201 w_indir_cmd52_sdio(adapter, adr, val, SDIO_IO_WORD);
1202 else
1203 w_indir_cmd53_sdio(adapter, adr, val, SDIO_IO_WORD);
1204 }
1205
w32_indir_sdio(struct mac_ax_adapter * adapter,u32 adr,u32 val)1206 static void w32_indir_sdio(struct mac_ax_adapter *adapter, u32 adr, u32 val)
1207 {
1208 u8 pwr_state = pwr_state_chk_sdio(adapter);
1209
1210 if (pwr_state == SDIO_PWR_OFF)
1211 w_indir_cmd52_sdio(adapter, adr, val, SDIO_IO_DWORD);
1212 else
1213 w_indir_cmd53_sdio(adapter, adr, val, SDIO_IO_DWORD);
1214 }
1215
pwr_state_chk_sdio(struct mac_ax_adapter * adapter)1216 static u8 pwr_state_chk_sdio(struct mac_ax_adapter *adapter)
1217 {
1218 if (adapter->mac_pwr_info.pwr_seq_proc == 1 ||
1219 adapter->sm.pwr == MAC_AX_PWR_OFF ||
1220 adapter->mac_pwr_info.pwr_in_lps == 1 ||
1221 adapter->sm.fw_rst == MAC_AX_FW_RESET_RECV ||
1222 adapter->sm.fw_rst == MAC_AX_FW_RESET_RECV_DONE ||
1223 adapter->sm.fw_rst == MAC_AX_FW_RESET_PROCESS) {
1224 adapter->sdio_info.tx_seq = 1;
1225 return SDIO_PWR_OFF;
1226 }
1227 return SDIO_PWR_ON;
1228 }
1229
reg_chk_sdio(struct mac_ax_adapter * adapter,u32 adr)1230 static u8 reg_chk_sdio(struct mac_ax_adapter *adapter, u32 adr)
1231 {
1232 u8 cv = adapter->hw_info->cv;
1233 u8 chip_id = adapter->hw_info->chip_id;
1234
1235 if (chip_id == CHIP_WIFI6_8852A && cv <= CBV) {
1236 if (adr >= SDIO_LOCAL_REG_START &&
1237 adr < SDIO_LOCAL_REG_END_PATCH)
1238 return SDIO_REG_LOCAL;
1239 else if (adr > SDIO_WLAN_REG_END_PATCH)
1240 return SDIO_REG_WLAN_PLTFM;
1241 } else {
1242 if (adr >= SDIO_LOCAL_REG_START && adr < SDIO_LOCAL_REG_END)
1243 return SDIO_REG_LOCAL;
1244 else if (adr > SDIO_WLAN_REG_END)
1245 return SDIO_REG_WLAN_PLTFM;
1246 }
1247 return SDIO_REG_WLAN_REG;
1248 }
1249
chk_rqd_pg_num(struct mac_ax_adapter * adapter,struct mac_ax_sdio_tx_info * tx_info)1250 static void chk_rqd_pg_num(struct mac_ax_adapter *adapter,
1251 struct mac_ax_sdio_tx_info *tx_info)
1252 {
1253 u32 ple_rqd = 0;
1254 u16 wde_rqd = 0;
1255 u8 *pkt_size = tx_info->pkt_size;
1256 u8 *wp_offset = tx_info->wp_offset;
1257 u16 ple_pg_size = adapter->dle_info.ple_pg_size;
1258 u16 wde_pg_size = adapter->dle_info.wde_pg_size;
1259 u8 ple_rsvd_size = adapter->hw_info->ple_rsvd_space;
1260 u8 pd_size = adapter->hw_info->payload_desc_size;
1261 u16 size;
1262 u32 ple_pg_size_sh;
1263 u8 dma_txagg_num, i;
1264
1265 ple_pg_size_sh = get_pg_size_pow(ple_pg_size);
1266
1267 dma_txagg_num =
1268 (tx_info->dma_txagg_num == 0) ? 1 : tx_info->dma_txagg_num;
1269 for (i = 0; i < dma_txagg_num; i++) {
1270 if (tx_info->ch_dma != MAC_AX_DMA_H2C)
1271 size = *pkt_size + (*(pkt_size + 1) << 8) + *wp_offset +
1272 ple_rsvd_size + pd_size;
1273 else
1274 size = *pkt_size + (*(pkt_size + 1) << 8) + *wp_offset;
1275 ple_rqd += (size >> ple_pg_size_sh) +
1276 ((size & (ple_pg_size - 1)) ? 1 : 0);
1277 wde_rqd += wde_pg_size >> 6;
1278 pkt_size += 2;
1279 wp_offset++;
1280 }
1281 tx_info->ple_rqd_num = (u16)(ple_rqd << 1);
1282 tx_info->wde_rqd_num = wde_rqd;
1283 }
1284
chk_fs_enuf(struct mac_ax_adapter * adapter,struct mac_ax_sdio_tx_info * tx_info)1285 static u32 chk_fs_enuf(struct mac_ax_adapter *adapter,
1286 struct mac_ax_sdio_tx_info *tx_info)
1287 {
1288 struct mac_ax_hfc_ch_cfg *ch_cfg = adapter->hfc_param->ch_cfg;
1289 struct mac_ax_hfc_ch_info *ch_info = adapter->hfc_param->ch_info;
1290 struct mac_ax_hfc_pub_info *pub_info = adapter->hfc_param->pub_info;
1291 u16 wde_min = ch_cfg[tx_info->ch_dma].min;
1292 u16 wde_max = ch_cfg[tx_info->ch_dma].max;
1293 u16 wde_use = ch_info[tx_info->ch_dma].used;
1294 u16 ple_thrd = adapter->hfc_param->pub_cfg->wp_thrd;
1295 u16 wde_aval;
1296 u8 i;
1297
1298 wde_aval = wde_max - wde_min; //public
1299 for (i = 0; i < MAC_AX_DMA_CH_NUM - 1; i++) {
1300 wde_aval -= (ch_info[i].used < ch_cfg[i].min) ?
1301 0 : (ch_info[i].used - ch_cfg[i].min);
1302 }
1303 wde_aval += (wde_min < wde_use) ? 0 : (wde_min - wde_use);
1304
1305 if (wde_aval < tx_info->wde_rqd_num)
1306 return MACHFSWDENOTNUF;
1307 if (pub_info->wp_aval < tx_info->ple_rqd_num)
1308 return MACHFSPLENOTNUF;
1309 if (pub_info->wp_aval <= ple_thrd && wde_use > wde_min)
1310 return MACHFSPLENOTNUF;
1311 return MACSUCCESS;
1312 }
1313
ud_fs(struct mac_ax_adapter * adapter)1314 static void ud_fs(struct mac_ax_adapter *adapter)
1315 {
1316 u8 val[28] = {0};
1317 u32 fs0, fs1, fs2, fs3, fs4, fs5, fs6;
1318 struct mac_ax_hfc_ch_info *ch_info = adapter->hfc_param->ch_info;
1319 struct mac_ax_hfc_pub_info *pub_info = adapter->hfc_param->pub_info;
1320
1321 PLTFM_SDIO_CMD53_RN(R_AX_SDIO_TXPG_WP, sizeof(val), val);
1322
1323 fs0 = le32_to_cpu(*(u32 *)(val));
1324 fs1 = le32_to_cpu(*(u32 *)(val + 4));
1325 fs2 = le32_to_cpu(*(u32 *)(val + 8));
1326 fs3 = le32_to_cpu(*(u32 *)(val + 12));
1327 fs4 = le32_to_cpu(*(u32 *)(val + 16));
1328 fs5 = le32_to_cpu(*(u32 *)(val + 20));
1329 fs6 = le32_to_cpu(*(u32 *)(val + 24));
1330
1331 ch_info[MAC_AX_DMA_H2C].aval = GET_FIELD(fs0, B_AX_SDIO_ACH12_AVAL_PG);
1332 pub_info->wp_aval = GET_FIELD(fs0, B_AX_SDIO_WP_AVAL_PG);
1333 ch_info[MAC_AX_DMA_ACH0].used = GET_FIELD(fs1, B_AX_SDIO_ACH0_USE_PG);
1334 ch_info[MAC_AX_DMA_ACH1].used = GET_FIELD(fs1, B_AX_SDIO_ACH1_USE_PG);
1335 ch_info[MAC_AX_DMA_ACH2].used = GET_FIELD(fs2, B_AX_SDIO_ACH2_USE_PG);
1336 ch_info[MAC_AX_DMA_ACH3].used = GET_FIELD(fs2, B_AX_SDIO_ACH3_USE_PG);
1337 ch_info[MAC_AX_DMA_ACH4].used = GET_FIELD(fs3, B_AX_SDIO_ACH4_USE_PG);
1338 ch_info[MAC_AX_DMA_ACH5].used = GET_FIELD(fs3, B_AX_SDIO_ACH5_USE_PG);
1339 ch_info[MAC_AX_DMA_ACH6].used = GET_FIELD(fs4, B_AX_SDIO_ACH6_USE_PG);
1340 ch_info[MAC_AX_DMA_ACH7].used = GET_FIELD(fs4, B_AX_SDIO_ACH7_USE_PG);
1341 ch_info[MAC_AX_DMA_B0MG].used = GET_FIELD(fs5, B_AX_SDIO_ACH8_USE_PG);
1342 ch_info[MAC_AX_DMA_B0HI].used = GET_FIELD(fs5, B_AX_SDIO_ACH9_USE_PG);
1343 ch_info[MAC_AX_DMA_B1MG].used = GET_FIELD(fs6, B_AX_SDIO_ACH10_USE_PG);
1344 ch_info[MAC_AX_DMA_B1HI].used = GET_FIELD(fs6, B_AX_SDIO_ACH11_USE_PG);
1345 }
1346
get_pg_size_pow(u32 size)1347 static u32 get_pg_size_pow(u32 size)
1348 {
1349 u32 val32;
1350
1351 switch (size) {
1352 case 64:
1353 val32 = 6;
1354 break;
1355 case 128:
1356 val32 = 7;
1357 break;
1358 case 256:
1359 val32 = 8;
1360 break;
1361 default:
1362 val32 = 8;
1363 break;
1364 }
1365
1366 return val32;
1367 }
1368
tx_allow_data_ch(struct mac_ax_adapter * adapter,struct mac_ax_sdio_tx_info * info)1369 static u32 tx_allow_data_ch(struct mac_ax_adapter *adapter,
1370 struct mac_ax_sdio_tx_info *info)
1371 {
1372 struct mac_ax_hfc_ch_info *ch_info = adapter->hfc_param->ch_info;
1373 struct mac_ax_hfc_pub_info *pub_info = adapter->hfc_param->pub_info;
1374 u32 cnt;
1375 u32 ret;
1376
1377 chk_rqd_pg_num(adapter, info);
1378
1379 cnt = info->chk_cnt;
1380 do {
1381 ret = chk_fs_enuf(adapter, info);
1382 if (ret == MACSUCCESS) {
1383 ch_info[info->ch_dma].used += info->wde_rqd_num;
1384 pub_info->wp_aval -= info->ple_rqd_num;
1385 break;
1386 }
1387 ud_fs(adapter);
1388 cnt--;
1389 } while (cnt);
1390
1391 if (!cnt)
1392 return ret;
1393
1394 return MACSUCCESS;
1395 }
1396
tx_allow_fwcmd_ch(struct mac_ax_adapter * adapter,struct mac_ax_sdio_tx_info * info)1397 static u32 tx_allow_fwcmd_ch(struct mac_ax_adapter *adapter,
1398 struct mac_ax_sdio_tx_info *info)
1399 {
1400 struct mac_ax_hfc_ch_info *ch_info = adapter->hfc_param->ch_info;
1401 u32 cnt;
1402
1403 chk_rqd_pg_num(adapter, info);
1404
1405 cnt = info->chk_cnt;
1406 do {
1407 if (ch_info[MAC_AX_DMA_H2C].aval >= info->ple_rqd_num) {
1408 ch_info[MAC_AX_DMA_H2C].aval -= info->ple_rqd_num;
1409 break;
1410 }
1411 ud_fs(adapter);
1412 cnt--;
1413 } while (cnt);
1414
1415 if (!cnt)
1416 return MACHFSPLENOTNUF;
1417
1418 return MACSUCCESS;
1419 }
1420
sdio_get_txagg_num(struct mac_ax_adapter * adapter,u8 band)1421 u32 sdio_get_txagg_num(struct mac_ax_adapter *adapter, u8 band)
1422 {
1423 return SDIO_DEFAULT_AGG_NUM;
1424 }
1425
sdio_autok_counter_avg(struct mac_ax_adapter * adapter)1426 u32 sdio_autok_counter_avg(struct mac_ax_adapter *adapter)
1427 {
1428 return MACSUCCESS;
1429 }
1430
dbcc_hci_ctrl_sdio(struct mac_ax_adapter * adapter,struct mac_ax_dbcc_hci_ctrl * info)1431 u32 dbcc_hci_ctrl_sdio(struct mac_ax_adapter *adapter,
1432 struct mac_ax_dbcc_hci_ctrl *info)
1433 {
1434 return MACSUCCESS;
1435 }
1436 #endif /*MAC_AX_SDIO_SUPPORT*/
1437