1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 其他头文件包含
21 **************************************************************************** */
22 #include "hdf_wlan_config.h"
23 #include "oal_util.h"
24 #include "oal_sdio.h"
25 #include "oal_sdio_host_if.h"
26 #include "oal_net.h"
27 #include "oal_chr.h"
28 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
29 #include "plat_board_adapt.h"
30 #include <linux/types.h>
31 #endif
32
33 #ifdef CONFIG_MMC
34 #include "exception_rst.h"
35 #include "plat_pm.h"
36 #include "oal_interrupt.h"
37 #include "oal_thread.h"
38
39 #include "plat_firmware.h"
40 #include "oam_ext_if.h"
41 #include "oal_mm.h"
42
43 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
44 #ifndef HAVE_PCLINT_CHECK
45 #include "oal_scatterlist.h"
46 #endif
47 #include "plat_board_adapt.h"
48 #endif
49 #endif
50 #include "hdf_wifi_core.h"
51
52 #ifdef __cplusplus
53 #if __cplusplus
54 extern "C" {
55 #endif
56 #endif
57
58 /* ****************************************************************************
59 2 宏定义
60 **************************************************************************** */
61 #ifdef CONFIG_MMC
62 #define DELAY_10_US 10
63 #define TIMEOUT_MUTIPLE_10 10
64 #define TIMEOUT_MUTIPLE_5 5
65 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
66 #define SDIO_RESET_RETRY 5
67 #define SDIO_RX_RETRY 5
68 #endif
69
70 #ifdef _PRE_HDF_LINUX
71 #ifndef UINTPTR
72 typedef uintptr_t UINTPTR;
73 #endif
74 #endif
75
76 /* ****************************************************************************
77 3 Global Variable Definition
78 **************************************************************************** */
79 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
80 enum {
81 DUMP_PREFIX_NONE,
82 DUMP_PREFIX_ADDRESS,
83 DUMP_PREFIX_OFFSET
84 };
85 #endif
86
87 struct task_struct *g_sdio_int_task = HI_NULL;
88 #undef CONFIG_SDIO_MSG_ACK_HOST2ARM_DEBUG
89
90 static oal_completion g_sdio_driver_complete;
91 oal_semaphore_stru g_chan_wake_sema;
92 static struct BusDev *g_bus = NULL;
93 static hi_char *g_sdio_enum_err_str = "probe timeout";
94
95 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
96 hi_u32 g_ul_pm_wakeup_event = HI_FALSE;
97 struct sdio_func *g_p_gst_sdio_func = HI_NULL;
98 #endif
99
100 /* 0 -sdio 1-gpio */
101 #ifdef _PRE_FEATURE_NO_GPIO
102 hi_s32 g_hisdio_intr_mode = 0;
103 #else
104 hi_s32 g_hisdio_intr_mode = 1;
105 #endif
106
107 #ifdef CONFIG_SDIO_FUNC_EXTEND
108 hi_u32 g_sdio_extend_func = 1;
109 #else
110 hi_u32 g_sdio_extend_func = 0;
111 #endif
112 hi_u32 g_wifi_patch_enable = 1;
113
114 module_param(g_hisdio_intr_mode, int, S_IRUGO | S_IWUSR);
115 module_param(g_sdio_extend_func, uint, S_IRUGO | S_IWUSR);
116 module_param(g_wifi_patch_enable, uint, S_IRUGO | S_IWUSR);
117
118 /* ****************************************************************************
119 * 3 Function Definition
120 * *************************************************************************** */
121 hi_s32 oal_sdio_data_sg_irq(struct BusDev *bus);
122
123 static hi_s32 oal_sdio_single_transfer(struct BusDev *bus, hi_s32 rw, hi_void *buf, hi_u32 size);
124 static hi_s32 _oal_sdio_transfer_scatt(struct BusDev *bus, hi_s32 rw, hi_u32 addr, struct scatterlist *sg,
125 hi_u32 sg_len, hi_u32 rw_sz);
126 extern hi_void dw_mci_sdio_card_detect_change(hi_void);
127
oal_sdio_print_state(hi_u32 old_state,hi_u32 new_state)128 static hi_void oal_sdio_print_state(hi_u32 old_state, hi_u32 new_state)
129 {
130 if (old_state != new_state) {
131 oam_info_log4(0, 0, "sdio state changed, tx[%d=>%d],rx[%d=>%d] (1:on, 0:off)\n",
132 (old_state & OAL_SDIO_TX) ? 1 : 0, (new_state & OAL_SDIO_TX) ? 1 : 0,
133 (old_state & OAL_SDIO_RX) ? 1 : 0, (new_state & OAL_SDIO_RX) ? 1 : 0);
134 }
135 }
oal_get_sdio_default_handler(hi_void)136 struct BusDev *oal_get_sdio_default_handler(hi_void)
137 {
138 return g_bus;
139 }
140
oal_free_sdio_stru(oal_channel_stru * hi_sdio)141 hi_void oal_free_sdio_stru(oal_channel_stru *hi_sdio)
142 {
143 hi_unref_param(hi_sdio);
144 printk("oal_free_sdio_stru\n");
145 }
146
oal_sdio_send_msg(struct BusDev * bus,unsigned long val)147 hi_s32 oal_sdio_send_msg(struct BusDev *bus, unsigned long val)
148 {
149 hi_s32 ret;
150 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
151 if (hi_sdio == HI_NULL || hi_sdio->func == HI_NULL) {
152 oam_error_log0(0, OAM_SF_ANY, "{oal_sdio_send_msg::sdio is not initialized,can't send sdio msg!}");
153 return -OAL_EINVAL;
154 }
155 if (hi_sdio->pst_pm_callback) {
156 if (hi_sdio->pst_pm_callback->wlan_pm_wakeup_dev() != HI_SUCCESS) {
157 oam_error_log0(0, OAM_SF_ANY, "{oal_sdio_send_msg::host wakeup device failed}");
158 }
159 }
160
161 if (val >= H2D_MSG_COUNT) {
162 oam_error_log1(0, OAM_SF_ANY, "[Error]invalid param[%lu]!\n", val);
163 return -OAL_EINVAL;
164 }
165 oal_sdio_wake_lock(bus);
166 bus->ops.claimHost(bus);
167 /* sdio message can sent when wifi power on */
168 if (wlan_pm_is_poweron() == 0) {
169 oam_error_log0(0, OAM_SF_ANY, "{oal_sdio_send_msg::wifi power off,can't send sdio msg!}");
170 bus->ops.releaseHost(bus);
171 oal_sdio_wake_unlock(bus);
172 return -OAL_EBUSY;
173 }
174
175 unsigned long data = 1 << val;
176 ret = bus->ops.writeData(bus, HISDIO_REG_FUNC1_WRITE_MSG, FOUR_BYTE, (hi_u8 *)&data);
177 if (ret) {
178 oam_error_log2(0, OAM_SF_ANY, "{oal_sdio_send_msg::failed to send sdio msg[%lu]!ret=%d}", val, ret);
179 }
180 bus->ops.releaseHost(bus);
181 oal_sdio_wake_unlock(bus);
182 return ret;
183 }
184
185 /*
186 * Description : read or write buf
187 * Input : struct sdio_func *func, hi_s32 rw, hi_u32 addr, hi_u8 *buf, hi_u32 rw_sz
188 * Output : None
189 * Return Value : static hi_s32
190 */
oal_sdio_rw_buf(struct BusDev * bus,hi_s32 rw,hi_u32 addr,hi_u8 * buf,hi_u32 rw_sz)191 hi_s32 oal_sdio_rw_buf(struct BusDev *bus, hi_s32 rw, hi_u32 addr, hi_u8 *buf, hi_u32 rw_sz)
192 {
193 hi_s32 ret = HI_SUCCESS;
194
195 /* padding len of buf has been assure when alloc */
196 rw_sz = HISDIO_ALIGN_4_OR_BLK(rw_sz);
197 if (OAL_WARN_ON(rw_sz != HISDIO_ALIGN_4_OR_BLK(rw_sz))) {
198 /* just for debug, remove later */
199 printk("invalid len %u\n", rw_sz);
200 return -OAL_EINVAL;
201 }
202
203 bus->ops.claimHost(bus);
204 if (rw == SDIO_READ) {
205 ret = bus->ops.bulkRead(bus, addr, rw_sz, buf, 0);
206 } else if (rw == SDIO_WRITE) {
207 ret = bus->ops.bulkWrite(bus, addr, rw_sz, buf, 0);
208 }
209
210 bus->ops.releaseHost(bus);
211
212 return ret;
213 }
214
oal_sdio_check_rx_len(oal_channel_stru * hi_sdio,hi_u32 count)215 hi_s32 oal_sdio_check_rx_len(oal_channel_stru *hi_sdio, hi_u32 count)
216 {
217 hi_unref_param(hi_sdio);
218 hi_unref_param(count);
219 return HI_SUCCESS;
220 }
221
oal_sdio_xfercount_get(struct BusDev * bus,hi_u32 * xfercount)222 static hi_s32 oal_sdio_xfercount_get(struct BusDev *bus, hi_u32 *xfercount)
223 {
224 hi_s32 ret = 0;
225 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
226 #ifdef CONFIG_SDIO_MSG_ACK_HOST2ARM_DEBUG
227 /* read from 0x0c */
228 ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_XFER_COUNT, FOUR_BYTE, (hi_u8*)xfercount);
229 if (oal_unlikely(ret)) {
230 printk("[ERROR]sdio read single package len failed ret=%d\n", ret);
231 return ret;
232 }
233 hi_sdio->sdio_extend->xfer_count = *xfercount;
234 #else
235 if (g_sdio_extend_func) {
236 *xfercount = hi_sdio->sdio_extend->xfer_count;
237 return HI_SUCCESS;
238 }
239
240 /* read from 0x0c */
241 ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_XFER_COUNT, FOUR_BYTE, (hi_u8*)xfercount);
242 if (oal_unlikely(ret)) {
243 printk("[E]sdio read xercount failed ret=%d\n", ret);
244 return ret;
245 }
246 hi_sdio->sdio_extend->xfer_count = *xfercount;
247 #endif
248 return HI_SUCCESS;
249 }
250
251 /*
252 * Description : rx data from sdio, Just support single transfer
253 * Input : None
254 * Output : None
255 * Return Value : hi_s32
256 */
oal_sdio_data_sg_irq(struct BusDev * bus)257 hi_s32 oal_sdio_data_sg_irq(struct BusDev *bus)
258 {
259 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
260 hi_s32 ret;
261 hi_u32 xfer_count;
262
263 if (hi_sdio == HI_NULL || hi_sdio->func == HI_NULL || hi_sdio->bus_data == HI_NULL) {
264 return -OAL_EINVAL;
265 }
266
267 ret = oal_sdio_xfercount_get(bus, &xfer_count);
268 if (oal_unlikely(ret)) {
269 return -OAL_EFAIL;
270 }
271
272 if (oal_unlikely(oal_sdio_check_rx_len(hi_sdio, xfer_count) != HI_SUCCESS)) {
273 printk("[SDIO][Err]Sdio Rx Single Transfer len[%u] invalid\n", xfer_count);
274 }
275
276 /* beacause get buf may cost lot of time, so release bus first */
277 if (hi_sdio->bus_ops.rx == HI_NULL) {
278 return -OAL_EINVAL;
279 }
280
281 bus->ops.releaseHost(bus);
282 hi_sdio->bus_ops.rx(hi_sdio->bus_data);
283 bus->ops.claimHost(bus);
284
285 return HI_SUCCESS;
286 }
287
oal_sdio_transfer_rx_register(struct BusDev * bus,hisdio_rx rx)288 hi_s32 oal_sdio_transfer_rx_register(struct BusDev *bus, hisdio_rx rx)
289 {
290 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
291 if (hi_sdio == HI_NULL) {
292 return -OAL_EINVAL;
293 }
294 hi_sdio->bus_ops.rx = rx;
295 return HI_SUCCESS;
296 }
297
298 /*
299 * Description : msg irq
300 * Input : hisdio_rx rx
301 * Output : HI_NULL
302 * Return Value : hi_s32
303 */
oal_sdio_transfer_rx_unregister(struct BusDev * bus)304 hi_void oal_sdio_transfer_rx_unregister(struct BusDev *bus)
305 {
306 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
307 hi_sdio->bus_ops.rx = HI_NULL;
308 }
309
310 /*
311 * Description : sdio msg register
312 * Input :
313 * Output : None
314 * Return Value : hi_s32
315 */
oal_sdio_message_register(struct BusDev * bus,hi_u8 msg,sdio_msg_rx cb,hi_void * data)316 hi_s32 oal_sdio_message_register(struct BusDev *bus, hi_u8 msg, sdio_msg_rx cb, hi_void *data)
317 {
318 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
319 if (hi_sdio == HI_NULL || msg >= D2H_MSG_COUNT) {
320 return -OAL_EFAIL;
321 }
322 hi_sdio->msg[msg].msg_rx = cb;
323 hi_sdio->msg[msg].data = data;
324 return HI_SUCCESS;
325 }
326
327 /*
328 * Description : sdio msg unregister
329 * Input :
330 * Output : None
331 * Return Value : hi_s32
332 */
oal_sdio_message_unregister(struct BusDev * bus,hi_u8 msg)333 hi_void oal_sdio_message_unregister(struct BusDev *bus, hi_u8 msg)
334 {
335 oal_channel_stru *hi_sdio = NULL;
336 if (bus == HI_NULL || msg >= D2H_MSG_COUNT) {
337 return;
338 }
339 hi_sdio = (oal_channel_stru *)bus->priData.data;
340 hi_sdio->msg[msg].msg_rx = HI_NULL;
341 hi_sdio->msg[msg].data = HI_NULL;
342 }
343
oal_sdio_msg_stat(struct BusDev * bus,hi_u32 * msg)344 static hi_s32 oal_sdio_msg_stat(struct BusDev *bus, hi_u32 *msg)
345 {
346 hi_s32 ret = 0;
347 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
348 #ifdef CONFIG_SDIO_MSG_ACK_HOST2ARM_DEBUG
349 /* read from old register */
350 #ifdef CONFIG_SDIO_D2H_MSG_ACK
351 ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_MSG_FROM_DEV, FOUR_BYTE, (hi_u8 *)msg);
352 #else
353 ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_MSG_FROM_DEV, ONE_BYTE, (hi_u8 *)msg);
354 #endif
355
356 if (ret) {
357 printk("sdio readb error![ret=%d]\n", ret);
358 return ret;
359 }
360 hi_sdio->sdio_extend->msg_stat = *msg;
361 #else
362 if (g_sdio_extend_func) {
363 *msg = hi_sdio->sdio_extend->msg_stat;
364 }
365
366 if (*msg == 0) {
367 /* no sdio message! */
368 return HI_SUCCESS;
369 }
370 #ifdef CONFIG_SDIO_D2H_MSG_ACK
371 /* read from old register */
372 /* 当使用0x30寄存器时需要下发CMD52读0x2B 才会产生HOST2ARM ACK中断 */
373 hi_u8 buf;
374 ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_MSG_HIGH_FROM_DEV, ONE_BYTE, &buf);
375 if (ret) {
376 printk("[E]sdio readb error![ret=%d]\n", ret);
377 }
378 #endif
379 #endif
380 return HI_SUCCESS;
381 }
382
383 /*
384 * Description : msg irq
385 * Input : oal_channel_stru *hi_sdio
386 * Output : None
387 * Return Value : hi_s32
388 */
389 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
390 #define cpu_clock(m) (m)
391 #endif
392
oal_sdio_msg_irq(struct BusDev * bus)393 hi_s32 oal_sdio_msg_irq(struct BusDev *bus)
394 {
395 oal_bitops bit = 0;
396 hi_u32 msg = 0;
397 hi_s32 ret;
398 unsigned long msg_tmp;
399 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
400 /* reading interrupt form ARM Gerneral Purpose Register(0x28) */
401 ret = oal_sdio_msg_stat(bus, &msg);
402 if (ret) {
403 printk("[SDIO][Err]oal_sdio_msg_stat error![ret=%d]\n", ret);
404 return ret;
405 }
406 msg_tmp = (unsigned long)msg;
407
408 if (!msg) {
409 return HI_SUCCESS;
410 }
411 if (oal_bit_atomic_test(D2H_MSG_DEVICE_PANIC, &msg_tmp)) {
412 oal_disable_sdio_state(bus, OAL_SDIO_ALL);
413 }
414 oal_sdio_release_host(bus);
415 oal_sdio_rx_transfer_unlock(bus);
416 if (oal_bit_atomic_test_and_clear(D2H_MSG_DEVICE_PANIC, &msg_tmp)) {
417 bit = D2H_MSG_DEVICE_PANIC;
418 hi_sdio->msg[bit].count++;
419 hi_sdio->last_msg = bit;
420 hi_sdio->msg[bit].cpu_time = cpu_clock(UINT_MAX);
421 if (hi_sdio->msg[bit].msg_rx) {
422 printk("device panic msg come, 0x%8x\n", msg);
423 hi_sdio->msg[bit].msg_rx(hi_sdio->msg[bit].data);
424 }
425 }
426 bit = 0;
427 oal_bit_atomic_for_each_set(bit, (const unsigned long *)&msg_tmp, D2H_MSG_COUNT) {
428 if (bit >= D2H_MSG_COUNT) {
429 printk("oal_sdio_msg_irq, bit >= D2H_MSG_COUNT\n");
430 return -OAL_EFAIL;
431 }
432 hi_sdio->msg[bit].count++;
433 hi_sdio->last_msg = bit;
434 hi_sdio->msg[bit].cpu_time = cpu_clock(UINT_MAX);
435 if (hi_sdio->msg[bit].msg_rx) {
436 hi_sdio->msg[bit].msg_rx(hi_sdio->msg[bit].data);
437 }
438 }
439 oal_sdio_rx_transfer_lock(bus);
440 oal_sdio_claim_host(bus);
441
442 return HI_SUCCESS;
443 }
444
oal_sdio_credit_info_update(oal_channel_stru * hi_sdio)445 hi_u32 oal_sdio_credit_info_update(oal_channel_stru *hi_sdio)
446 {
447 hi_u8 short_free_cnt, large_free_cnt;
448 hi_u32 ret = 0;
449 oal_spin_lock(&hi_sdio->sdio_credit_info.credit_lock);
450
451 short_free_cnt = hisdio_short_pkt_get(hi_sdio->sdio_extend->credit_info);
452 large_free_cnt = hisdio_large_pkt_get(hi_sdio->sdio_extend->credit_info);
453
454 if (hi_sdio->sdio_credit_info.short_free_cnt != short_free_cnt) {
455 #ifdef CONFIG_SDIO_DEBUG
456 printk("short free cnt:%d ==> %d\r\n", hi_sdio->sdio_credit_info.short_free_cnt, short_free_cnt);
457 #endif
458 hi_sdio->sdio_credit_info.short_free_cnt = short_free_cnt;
459 ret = 1;
460 }
461
462 if (hi_sdio->sdio_credit_info.large_free_cnt != large_free_cnt) {
463 #ifdef CONFIG_SDIO_DEBUG
464 printk("large free cnt:%d ==> %d\r\n", hi_sdio->sdio_credit_info.large_free_cnt, large_free_cnt);
465 #endif
466 hi_sdio->sdio_credit_info.large_free_cnt = large_free_cnt;
467 ret = 1;
468 }
469
470 oal_spin_unlock(&hi_sdio->sdio_credit_info.credit_lock);
471
472 return ret;
473 }
474
oal_sdio_credit_update_cb_register(oal_channel_stru * hi_sdio,hisdio_rx cb)475 hi_void oal_sdio_credit_update_cb_register(oal_channel_stru *hi_sdio, hisdio_rx cb)
476 {
477 if (hi_sdio == HI_NULL) {
478 return;
479 }
480 if (OAL_WARN_ON(hi_sdio->credit_update_cb != HI_NULL)) {
481 return;
482 }
483 hi_sdio->credit_update_cb = cb;
484 return;
485 }
486
oal_sdio_get_credit(struct BusDev * bus,hi_u32 * uc_hipriority_cnt)487 hi_s32 oal_sdio_get_credit(struct BusDev *bus, hi_u32 *uc_hipriority_cnt)
488 {
489 hi_s32 ret;
490 bus->ops.claimHost(bus);
491 ret = oal_sdio_memcpy_fromio(bus, (hi_u8 *)uc_hipriority_cnt,
492 HISDIO_EXTEND_CREDIT_ADDR, sizeof(*uc_hipriority_cnt));
493 bus->ops.releaseHost(bus);
494 /* 此处要让出CPU */
495 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
496 schedule();
497 #endif
498 return ret;
499 }
500
501 #ifndef CONFIG_SDIO_MSG_ACK_HOST2ARM_DEBUG
oal_sdio_extend_buf_get(struct BusDev * bus)502 static hi_s32 oal_sdio_extend_buf_get(struct BusDev *bus)
503 {
504 hi_s32 ret = HI_SUCCESS;
505 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
506 if (g_sdio_extend_func) {
507 ret = oal_sdio_memcpy_fromio(bus, (hi_void *)hi_sdio->sdio_extend,
508 HISDIO_EXTEND_BASE_ADDR, sizeof(hisdio_extend_func));
509 if (oal_likely(ret == HI_SUCCESS)) {
510 #ifdef CONFIG_SDIO_DEBUG
511 printk(KERN_DEBUG"=========extend buff:%d=====\n",
512 HISDIO_COMM_REG_SEQ_GET(hi_sdio->sdio_extend->credit_info));
513 oal_print_hex_dump((hi_u8 *)hi_sdio->sdio_extend,
514 sizeof(hisdio_extend_func), 32, "extend :"); /* 32 进制 */
515
516 /* 此credit更新只在调试时使用 */
517 if (oal_sdio_credit_info_update(hi_sdio)) {
518 if (oal_likely(hi_sdio->credit_update_cb)) {
519 hi_sdio->credit_update_cb(hi_sdio->bus_data);
520 }
521 }
522 #endif
523 } else {
524 oam_info_log0(0, OAM_SF_ANY, "{[SDIO][Err]sdio read extend_buf fail!}");
525 }
526 }
527 return ret;
528 }
529 #else
oal_sdio_extend_buf_get(struct BusDev * bus)530 static hi_s32 oal_sdio_extend_buf_get(struct BusDev *bus)
531 {
532 hi_s32 ret;
533 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
534 {
535 memset_s(hi_sdio->sdio_extend, sizeof(struct hisdio_extend_func), 0, sizeof(struct hisdio_extend_func));
536 ret = oal_sdio_memcpy_fromio(bus, (hi_void *)&hi_sdio->sdio_extend->credit_info,
537 HISDIO_EXTEND_BASE_ADDR + 12, HISDIO_EXTEND_REG_COUNT + 4); /* addr+ 12, count+ 4 */
538 #ifdef CONFIG_SDIO_DEBUG
539 if (ret == HI_SUCCESS) {
540 printk(KERN_DEBUG "=========extend buff:%d=====\n",
541 HISDIO_COMM_REG_SEQ_GET(hi_sdio->sdio_extend->credit_info));
542 oal_print_hex_dump((hi_u8 *)hi_sdio->sdio_extend,
543 sizeof(struct hisdio_extend_func), 32, "extend :"); /* 32 进制 */
544 }
545 #endif
546 }
547 return ret;
548 }
549 #endif
550
oal_sdio_transfer_rx_reserved_buff(struct BusDev * bus)551 hi_s32 oal_sdio_transfer_rx_reserved_buff(struct BusDev *bus)
552 {
553 hi_u32 i = 0;
554 hi_s32 ret;
555 hi_u32 left_size;
556 hi_u32 seg_nums, seg_size;
557 struct scatterlist *sg = HI_NULL;
558 struct scatterlist *sg_t = HI_NULL;
559 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
560 if (hi_sdio->sdio_extend == HI_NULL) {
561 oam_error_log0(0, OAM_SF_ANY, "{hi_sdio->sdio_extend NULL!}");
562 return -OAL_EINVAL;
563 }
564
565 hi_u32 ul_extend_len = hi_sdio->sdio_extend->xfer_count;
566
567 if (ul_extend_len == 0) {
568 oam_error_log0(0, OAM_SF_ANY, "{extend_len is zero!}");
569 return -OAL_EINVAL;
570 }
571
572 seg_size = hi_sdio->rx_reserved_buff_len;
573 if (seg_size == 0) {
574 oam_error_log0(0, OAM_SF_ANY, "{seg_size is zero!}");
575 return -OAL_EINVAL;
576 }
577 seg_nums = ((ul_extend_len - 1) / seg_size) + 1;
578 if (hi_sdio->scatt_info[SDIO_READ].max_scatt_num < seg_nums) {
579 oam_error_log2(0, OAM_SF_ANY, "{sdio seg nums :%u large than rx scatt num %u!}", seg_nums,
580 hi_sdio->scatt_info[SDIO_READ].max_scatt_num);
581 return -OAL_EINVAL;
582 }
583
584 oam_info_log1(0, OAM_SF_ANY, "{drop the rx buff length:%u}", ul_extend_len);
585
586 sg = hi_sdio->scatt_info[SDIO_READ].sglist;
587 if (sg == HI_NULL) {
588 printk("oal_sdio_transfer_rx_reserved_buff::sg is null!\n");
589 return -OAL_EINVAL;
590 }
591 sg_init_table(sg, seg_nums);
592 left_size = ul_extend_len;
593 for_each_sg(sg, sg_t, seg_nums, i) {
594 if (sg_t == HI_NULL) {
595 printk("oal_sdio_transfer_rx_reserved_buff::sg_t is null!\n");
596 return -OAL_EINVAL;
597 }
598 sg_set_buf(sg_t, (const void *)(UINTPTR)hi_sdio->rx_reserved_buff, oal_min(seg_size, left_size));
599 left_size = left_size - seg_size;
600 }
601 ret = _oal_sdio_transfer_scatt(bus, SDIO_READ, HISDIO_REG_FUNC1_FIFO, sg, seg_nums, ul_extend_len);
602 if (oal_unlikely(ret)) {
603 printk("sdio trans revered mem failed! ret=%d\n", ret);
604 }
605 return ret;
606 }
607
608 #undef CONFIG_SDIO_RX_NETBUF_ALLOC_FAILED_DEBUG
609 #ifdef CONFIG_SDIO_RX_NETBUF_ALLOC_FAILED_DEBUG
610 hi_u32 g_rx_alloc_netbuf_debug = 0;
611 module_param(g_rx_alloc_netbuf_debug, uint, S_IRUGO | S_IWUSR);
612 #endif
613
oal_sdio_alloc_rx_netbuf(hi_u32 ul_len)614 oal_netbuf_stru *oal_sdio_alloc_rx_netbuf(hi_u32 ul_len)
615 {
616 #ifdef CONFIG_SDIO_RX_NETBUF_ALLOC_FAILED_DEBUG
617 if (g_rx_alloc_netbuf_debug) {
618 if (prandom_u32() % 256) { /* 256 */
619 return HI_NULL;
620 }
621 }
622 #endif
623
624 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
625 return __netdev_alloc_skb(HI_NULL, ul_len, GFP_KERNEL);
626 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
627
628 #ifdef _PRE_LWIP_ZERO_COPY
629 return oal_pbuf_netbuf_alloc(ul_len);
630 #else
631 return oal_dev_alloc_skb(ul_len);
632 #endif
633 #endif
634 }
635
oal_sdio_build_rx_netbuf_list(struct BusDev * bus,oal_netbuf_head_stru * head)636 hi_s32 oal_sdio_build_rx_netbuf_list(struct BusDev *bus, oal_netbuf_head_stru *head)
637 {
638 #ifdef CONFIG_SDIO_FUNC_EXTEND
639 hi_s32 i;
640 hi_u8 buff_len;
641 hi_u16 buff_len_t;
642 #endif
643 hi_s32 ret = HI_SUCCESS;
644 hi_u32 sum_len = 0;
645 oal_netbuf_stru *netbuf = HI_NULL;
646 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
647
648 if (!oal_netbuf_list_empty(head)) {
649 oam_error_log0(0, OAM_SF_ANY, "oal_sdio_build_rx_netbuf_list: oal netbuf list empty");
650 return -OAL_EINVAL;
651 }
652 #ifdef CONFIG_SDIO_FUNC_EXTEND
653 for (i = 0; i < HISDIO_EXTEND_REG_COUNT; i++) {
654 buff_len = hi_sdio->sdio_extend->comm_reg[i];
655 if (buff_len == 0) {
656 break;
657 }
658
659 buff_len_t = buff_len << HISDIO_D2H_SCATT_BUFFLEN_ALIGN_BITS;
660
661 netbuf = oal_sdio_alloc_rx_netbuf(buff_len_t);
662 if (netbuf == HI_NULL) {
663 oam_error_log2(0, OAM_SF_ANY, "{[WIFI][E]rx no mem:%u, index:%d}", buff_len, i);
664 goto failed_netbuf_alloc;
665 }
666
667 oal_netbuf_put(netbuf, buff_len_t);
668 sum_len += buff_len_t;
669
670 if ((!oal_netbuf_head_prev(head)) || (!oal_netbuf_head_next(head))) {
671 oam_error_log0(0, OAM_SF_ANY, "oal_sdio_build_rx_netbuf_list: head null");
672 goto failed_netbuf_alloc;
673 }
674 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
675 __skb_queue_tail(head, netbuf);
676 #else
677 oal_netbuf_list_tail(head, netbuf);
678 #endif
679 }
680
681 if (OAL_WARN_ON(HISDIO_ALIGN_4_OR_BLK(sum_len) != hi_sdio->sdio_extend->xfer_count)) {
682 oam_warning_log3(0, OAM_SF_ANY, "{[WIFI][E]scatt total len[%u] should = xfercount[%u],after pad len:%u}",
683 sum_len, hi_sdio->sdio_extend->xfer_count, HISDIO_ALIGN_4_OR_BLK(sum_len));
684 hi_sdio->error_stat.rx_scatt_info_not_match++;
685 goto failed_netbuf_alloc;
686 }
687 #else
688 netbuf = oal_sdio_alloc_rx_netbuf(hi_sdio->sdio_extend->xfer_count);
689 if (netbuf == HI_NULL) {
690 oam_error_log1(0, OAM_SF_ANY, "{rx no mem:%u}", hi_sdio->sdio_extend->xfer_count);
691 goto failed_netbuf_alloc;
692 }
693
694 oal_netbuf_put(netbuf, hi_sdio->sdio_extend->xfer_count);
695 sum_len += hi_sdio->sdio_extend->xfer_count;
696 __skb_queue_tail(head, netbuf);
697 #endif
698
699 if (oal_unlikely(oal_netbuf_list_empty(head))) {
700 #ifdef CONFIG_PRINTK
701 printk("unvaild scatt info:xfercount:%u\n", hi_sdio->sdio_extend->xfer_count);
702 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
703 print_hex_dump_bytes("scatt extend:", DUMP_PREFIX_ADDRESS, hi_sdio->sdio_extend->comm_reg,
704 HISDIO_EXTEND_REG_COUNT);
705 #endif
706 #endif
707 return -OAL_EINVAL;
708 }
709
710 return ret;
711 failed_netbuf_alloc:
712 oal_netbuf_list_purge(head);
713 ret = oal_sdio_transfer_rx_reserved_buff(bus);
714 if (ret != HI_SUCCESS) {
715 printk("oal_sdio_transfer_rx_reserved_buff fail\n");
716 }
717 return -OAL_ENOMEM;
718 }
719
oal_sdio_get_func1_int_status(struct BusDev * bus,hi_u8 * int_stat)720 static hi_s32 oal_sdio_get_func1_int_status(struct BusDev *bus, hi_u8 *int_stat)
721 {
722 hi_s32 ret = 0;
723 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
724 if (g_sdio_extend_func) {
725 hi_sdio->sdio_extend->int_stat &= hi_sdio->func1_int_mask;
726 *int_stat = (hi_sdio->sdio_extend->int_stat & 0xF);
727 return HI_SUCCESS;
728 } else {
729 /* read interrupt indicator register */
730 ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_INT_STATUS, ONE_BYTE, int_stat);
731 if (oal_unlikely(ret)) {
732 printk("[SDIO][Err]failed to read sdio func1 interrupt status!ret=%d\n", ret);
733 return ret;
734 }
735 *int_stat = (*int_stat) & hi_sdio->func1_int_mask;
736 }
737 return HI_SUCCESS;
738 }
739
oal_sdio_clear_int_status(struct BusDev * bus,hi_u8 int_stat)740 static hi_s32 oal_sdio_clear_int_status(struct BusDev *bus, hi_u8 int_stat)
741 {
742 hi_s32 ret = 0;
743
744 if (g_sdio_extend_func) {
745 return HI_SUCCESS;
746 }
747 ret = bus->ops.writeData(bus, HISDIO_REG_FUNC1_INT_STATUS, ONE_BYTE, &int_stat);
748 if (oal_unlikely(ret)) {
749 printk("[SDIO][Err]failed to clear sdio func1 interrupt!ret=%d\n", ret);
750 return ret;
751 }
752 return HI_SUCCESS;
753 }
754
755 /*
756 * Description : sdio rx data
757 * Input :
758 * Output : None
759 * Return Value : hi_s32
760 */
oal_sdio_do_isr(struct BusDev * bus)761 hi_s32 oal_sdio_do_isr(struct BusDev *bus)
762 {
763 hi_u8 int_mask;
764 hi_s32 ret;
765 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
766
767 hi_sdio->sdio_int_count++;
768 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
769 hi_s32 rx_retry_count = SDIO_RX_RETRY;
770 #endif
771 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
772 /* sdio bus state access lock by sdio bus claim locked. */
773 if (oal_unlikely(HI_TRUE != oal_sdio_get_state(hi_sdio, OAL_SDIO_RX))) {
774 return HI_SUCCESS;
775 }
776 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
777 /* sdio bus state access lock by sdio bus claim locked. */
778 while (1) {
779 if (oal_unlikely(HI_TRUE == oal_sdio_get_state(hi_sdio, OAL_SDIO_RX))) {
780 break;
781 }
782 rx_retry_count--;
783 if (rx_retry_count == 0) {
784 printk("[SDIO][W][%s]sdio closed,state:%u\n", __FUNCTION__, oal_sdio_get_state(hi_sdio, OAL_SDIO_RX));
785 return HI_SUCCESS;
786 }
787 msleep(10); /* sleep 10ms */
788 }
789 #endif
790
791 #ifndef CONFIG_SDIO_MSG_ACK_HOST2ARM_DEBUG
792 ret = oal_sdio_extend_buf_get(bus);
793 if (oal_unlikely(ret)) {
794 printk("[SDIO][Err]failed to read sdio extend area ret=%d\n", ret);
795 return -OAL_EFAIL;
796 }
797 #endif
798
799 ret = oal_sdio_get_func1_int_status(bus, &int_mask);
800 if (oal_unlikely(ret)) {
801 return ret;
802 }
803
804 if (oal_unlikely(0 == (int_mask & HISDIO_FUNC1_INT_MASK))) {
805 hi_sdio->func1_stat.func1_no_int_count++;
806 return HI_SUCCESS;
807 }
808
809 /* clear interrupt mask */
810 ret = oal_sdio_clear_int_status(bus, int_mask);
811 if (oal_unlikely(ret)) {
812 return ret;
813 }
814
815 if (int_mask & HISDIO_FUNC1_INT_RERROR) {
816 /* try to read the data again */
817 hi_sdio->func1_stat.func1_err_int_count++;
818 }
819
820 /* message interrupt, flow control */
821 if (int_mask & HISDIO_FUNC1_INT_MFARM) {
822 hi_sdio->func1_stat.func1_msg_int_count++;
823 if (oal_sdio_msg_irq(bus) != HI_SUCCESS) {
824 return -OAL_EFAIL;
825 }
826 }
827
828 if (int_mask & HISDIO_FUNC1_INT_DREADY) {
829 hi_sdio->func1_stat.func1_data_int_count++;
830 return oal_sdio_data_sg_irq(bus);
831 }
832 hi_sdio->func1_stat.func1_unknow_int_count++;
833 return HI_SUCCESS;
834 }
835
836 /*
837 * Description : sdio interrupt routine
838 * Input : func sdio_func handler
839 * Output : None
840 * Return Value : err or succ
841 */
oal_sdio_isr(void * func)842 hi_void oal_sdio_isr(void *func)
843 {
844 struct BusDev *bus = oal_get_bus_default_handler();
845 hi_s32 ret;
846
847 if (func == HI_NULL) {
848 oam_error_log0(0, 0, "oal_sdio_isr func null\n");
849 return;
850 }
851 bus->ops.claimHost(bus);
852 ret = oal_sdio_do_isr(bus);
853 if (oal_unlikely(ret)) {
854 oam_error_log0(0, 0, "oal_sdio_do_isr fail\n");
855 oal_exception_submit(TRANS_FAIL);
856 }
857 bus->ops.releaseHost(bus);
858 }
859
860 #undef COFNIG_TEST_SDIO_INT_LOSS
861
862 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
863 oal_atomic g_pm_spinlock_get;
864 #endif
865
866 /*
867 * Description : initialize sdio pm interface
868 * Input :
869 * Output : None
870 * Return Value : hi_void
871 */
oal_unregister_gpio_intr(struct BusDev * bus)872 hi_void oal_unregister_gpio_intr(struct BusDev *bus)
873 {
874 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
875 /* disable wlan irq */
876 oal_wlan_gpio_intr_enable(bus, HI_FALSE);
877
878 /* free irq when sdio driver deinit */
879 oal_free_irq(hi_sdio->ul_wlan_irq, hi_sdio);
880 oal_kthread_stop(hi_sdio->gpio_rx_tsk);
881 hi_sdio->gpio_rx_tsk = HI_NULL;
882 }
883
884 /* ****************************************************************************
885 功能描述 : 使能/关闭 WLAN GPIO 中断
886 输入参数 : 1:enable; 0:disenable
887 输出参数 : 无
888 返 回 值 : 成功或失败原因
889 **************************************************************************** */
oal_wlan_gpio_intr_enable(struct BusDev * bus,hi_u32 ul_en)890 hi_void oal_wlan_gpio_intr_enable(struct BusDev *bus, hi_u32 ul_en)
891 {
892 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
893 #ifndef _PRE_FEATURE_NO_GPIO
894 unsigned long flags;
895
896 oal_spin_lock_irq_save(&hi_sdio->st_irq_lock, &flags);
897 if (ul_en) {
898 oal_enable_irq(hi_sdio->ul_wlan_irq);
899 } else {
900 oal_disable_irq_nosync(hi_sdio->ul_wlan_irq);
901 }
902 oal_spin_unlock_irq_restore(&hi_sdio->st_irq_lock, &flags);
903 #else
904 hi_unref_param(hi_sdio);
905 hi_unref_param(ul_en);
906 #endif
907 }
908
oal_register_sdio_intr(struct BusDev * bus)909 hi_s32 oal_register_sdio_intr(struct BusDev *bus)
910 {
911 hi_s32 ret;
912
913 bus->ops.claimHost(bus);
914 /* use sdio bus line data1 for sdio data interrupt */
915 ret = bus->ops.claimIrq(bus, (IrqHandler *)oal_sdio_isr, NULL);
916 if (ret < 0) {
917 oam_error_log0(0, 0, "oal_register_sdio_intr:: failed to register sdio interrupt");
918 bus->ops.releaseHost(bus);
919 return -OAL_EFAIL;
920 }
921 bus->ops.releaseHost(bus);
922 oam_info_log0(0, 0, "oal_register_sdio_intr:: sdio interrupt register");
923 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
924 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
925 struct sdio_func *func = hi_sdio->func;
926 pm_runtime_get_sync(mmc_dev(hi_sdio->func->card->host));
927 #endif
928 return ret;
929 }
930
oal_unregister_sdio_intr(struct BusDev * bus)931 hi_void oal_unregister_sdio_intr(struct BusDev *bus)
932 {
933 bus->ops.claimHost(bus);
934 /* use sdio bus line data1 for sdio data interrupt */
935 bus->ops.releaseIrq(bus);
936 bus->ops.releaseHost(bus);
937 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
938 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
939 struct sdio_func *func = hi_sdio->func;
940 pm_runtime_put_sync(mmc_dev(hi_sdio->func->card->host));
941 #endif
942 }
943
944 /*
945 * Description : unregister interrupt
946 * Input : None
947 * Output : None
948 */
oal_sdio_interrupt_unregister(struct BusDev * bus)949 hi_void oal_sdio_interrupt_unregister(struct BusDev *bus)
950 {
951 if (g_hisdio_intr_mode) {
952 /* use GPIO interrupt for sdio data interrupt */
953 oal_unregister_gpio_intr(bus);
954 } else {
955 /* use sdio interrupt for sdio data interrupt */
956 oal_unregister_sdio_intr(bus);
957 }
958 }
959
960 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_sdio_get_sleep_state(struct BusDev * bus)961 unsigned long oal_sdio_get_sleep_state(struct BusDev *bus)
962 {
963 int ret;
964 unsigned long ul_value;
965
966 bus->ops.claimHost(bus);
967 (void)bus->ops.readFunc0(bus, HISDIO_WAKEUP_DEV_REG, 1, (hi_u8 *)&ul_value);
968 bus->ops.releaseHost(bus);
969
970 return ul_value;
971 }
972 #endif
973
974 /*
975 * Description : get device low power state by sdio 0xf1~0xf4 registers for debug
976 * Input : None
977 * Output : None
978 */
979 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_sdio_get_dev_pm_state(struct BusDev * bus,unsigned long * pst_ul_f1,unsigned long * pst_ul_f2,unsigned long * pst_ul_f3,unsigned long * pst_ul_f4)980 hi_void oal_sdio_get_dev_pm_state(struct BusDev *bus, unsigned long *pst_ul_f1,
981 unsigned long *pst_ul_f2, unsigned long *pst_ul_f3, unsigned long *pst_ul_f4)
982 {
983 int ret;
984 bus->ops.claimHost(bus);
985 (void)bus->ops.readFunc0(bus, 0xf1, 1, (hi_u8 *)pst_ul_f1);
986 (void)bus->ops.readFunc0(bus, 0xf2, 1, (hi_u8 *)pst_ul_f2);
987 (void)bus->ops.readFunc0(bus, 0xf3, 1, (hi_u8 *)pst_ul_f3);
988 (void)bus->ops.readFunc0(bus, 0xf4, 1, (hi_u8 *)pst_ul_f4);
989 bus->ops.releaseHost(bus);
990
991 return;
992 }
993 #endif
994
995 /*
996 * Description : wakeup device
997 * Input : None
998 * Output : None
999 * Return Value :
1000 */
1001 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_sdio_wakeup_dev(struct BusDev * bus)1002 hi_s32 oal_sdio_wakeup_dev(struct BusDev *bus)
1003 {
1004 int ret;
1005 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1006 if (hi_sdio == HI_NULL) {
1007 return -OAL_EFAIL;
1008 }
1009 oal_sdio_claim_host(bus);
1010 hi_u32 data = DISALLOW_TO_SLEEP_VALUE;
1011 ret = bus->ops.writeFunc0(bus, HISDIO_WAKEUP_DEV_REG, 1, (hi_u8 *)&data);
1012 oal_sdio_release_host(bus);
1013
1014 return ret;
1015 }
1016 #endif
1017
1018 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
oal_sdio_wakeup_dev(struct BusDev * bus)1019 hi_s32 oal_sdio_wakeup_dev(struct BusDev *bus)
1020 {
1021 int ret;
1022 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1023 if (hi_sdio == HI_NULL) {
1024 return -OAL_EFAIL;
1025 }
1026 oal_sdio_claim_host(bus);
1027 hi_u32 data = DISALLOW_TO_SLEEP_VALUE;
1028 ret = bus->ops.writeFunc0(bus, HISDIO_WAKEUP_DEV_REG, 1, (hi_u8 *)&data);
1029 oal_sdio_release_host(bus);
1030 return ret;
1031 }
1032 #endif
1033
1034 /*
1035 * Description : allow device to sleep
1036 * Input : None
1037 * Output : None
1038 * Return Value :
1039 */
1040 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_sdio_sleep_dev(struct BusDev * bus)1041 hi_s32 oal_sdio_sleep_dev(struct BusDev *bus)
1042 {
1043 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1044 if (hi_sdio == HI_NULL) {
1045 return -OAL_EFAIL;
1046 }
1047 int ret;
1048 oal_sdio_claim_host(bus);
1049 hi_u32 data = ALLOW_TO_SLEEP_VALUE;
1050 ret = bus->ops.writeFunc0(bus, HISDIO_WAKEUP_DEV_REG, 1, (hi_u8 *)&data);
1051 oal_sdio_release_host(bus);
1052 return ret;
1053 }
1054 #endif
1055
1056 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
oal_sdio_sleep_dev(struct BusDev * bus)1057 hi_s32 oal_sdio_sleep_dev(struct BusDev *bus)
1058 {
1059 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1060
1061 if (hi_sdio == HI_NULL) {
1062 return -OAL_EFAIL;
1063 }
1064 oal_sdio_claim_host(bus);
1065 uint8_t data = ALLOW_TO_SLEEP_VALUE;
1066 (void)bus->ops.writeFunc0(bus, HISDIO_WAKEUP_DEV_REG, 1, &data);
1067 oal_sdio_release_host(bus);
1068
1069 return HI_SUCCESS;
1070 }
1071 #endif
1072
1073 /*
1074 * Description : init sdio function
1075 * Input : adapter oal_sdio handler
1076 * Output :
1077 * Return Value : succ or fail
1078 */
oal_sdio_dev_init(struct BusDev * bus)1079 hi_s32 oal_sdio_dev_init(struct BusDev *bus)
1080 {
1081 hi_s32 ret;
1082 hi_u32 data;
1083 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1084 if (hi_sdio == HI_NULL) {
1085 return -OAL_EFAIL;
1086 }
1087
1088 oal_sdio_claim_host(bus);
1089 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1090 oal_disable_sdio_state(bus, OAL_SDIO_ALL);
1091 #endif
1092
1093 /* before enable sdio function 1, clear its interrupt flag, no matter it exist or not */
1094 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1095 #ifdef _PRE_WLAN_PM_FEATURE_FORCESLP_RESUME
1096 if (wlan_resume_state_get() == 0) { /* host镜像恢复起来不清中断,防止数据丢失 */
1097 #endif
1098 #endif
1099 data = HISDIO_FUNC1_INT_MASK;
1100 ret = bus->ops.writeData(bus, HISDIO_REG_FUNC1_INT_STATUS, ONE_BYTE, (hi_u8 *)&data);
1101 if (ret) {
1102 printk("failed to clear sdio interrupt! ret=%d\n", ret);
1103 goto failed_clear_func1_int;
1104 }
1105 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1106 #ifdef _PRE_WLAN_PM_FEATURE_FORCESLP_RESUME
1107 }
1108 #endif
1109 #endif
1110 /*
1111 * enable four interrupt sources in function 1:
1112 * data ready for host to read
1113 * read data error
1114 * message from arm is available
1115 * device has receive message from host
1116 * */
1117 data = HISDIO_FUNC1_INT_MASK;
1118 ret = bus->ops.writeData(bus, HISDIO_REG_FUNC1_INT_ENABLE, ONE_BYTE, (hi_u8 *)&data);
1119 if (ret < 0) {
1120 printk("failed to enable sdio interrupt! ret=%d\n", ret);
1121 goto failed_enable_func1;
1122 }
1123
1124 oal_enable_sdio_state(bus, OAL_SDIO_ALL);
1125 oal_sdio_release_host(bus);
1126
1127 return HI_SUCCESS;
1128
1129 failed_enable_func1:
1130 failed_clear_func1_int:
1131 (void)bus->ops.disableBus(bus);
1132 oal_sdio_release_host(bus);
1133 return ret;
1134 }
1135
1136 /*
1137 * Description : deinit
1138 * Input :
1139 * Output : None
1140 * Return Value : hi_s32
1141 */
oal_sdio_dev_deinit(struct BusDev * bus)1142 static hi_void oal_sdio_dev_deinit(struct BusDev *bus)
1143 {
1144 bus->ops.claimHost(bus);
1145 hi_u32 data = 0;
1146 (void)bus->ops.writeData(bus, HISDIO_REG_FUNC1_INT_ENABLE, ONE_BYTE, (uint8_t *)&data);
1147 oal_sdio_interrupt_unregister(bus);
1148 (void)bus->ops.disableBus(bus);
1149 oal_disable_sdio_state(bus, OAL_SDIO_ALL);
1150 bus->ops.releaseHost(bus);
1151
1152 printk("oal_sdio_dev_deinit! \n");
1153 }
1154
1155 /*
1156 * Description : get the sdio bus state
1157 * Input :
1158 * Output : None
1159 * Return Value : TRUE/FALSE
1160 */
oal_sdio_get_state(const oal_channel_stru * hi_sdio,hi_u32 mask)1161 hi_s32 oal_sdio_get_state(const oal_channel_stru *hi_sdio, hi_u32 mask)
1162 {
1163 if (hi_sdio == HI_NULL) {
1164 return HI_FALSE;
1165 }
1166
1167 if ((hi_sdio->state & mask) == mask) {
1168 return HI_TRUE;
1169 } else {
1170 return HI_FALSE;
1171 }
1172 }
1173
1174 /*
1175 * Description : set the sdio bus state
1176 * Input : struct iodevice *io_dev, hi_u8 state: TRUE/FALSE
1177 * Output : None
1178 * Return Value : hi_void
1179 */
oal_enable_sdio_state(struct BusDev * bus,hi_u32 mask)1180 hi_void oal_enable_sdio_state(struct BusDev *bus, hi_u32 mask)
1181 {
1182 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1183 hi_u32 old_state;
1184 if (hi_sdio == HI_NULL) {
1185 printk("oal_enable_sdio_state: hi_sdio null!\n");
1186 return;
1187 }
1188
1189 old_state = hi_sdio->state;
1190 hi_sdio->state |= mask;
1191 oal_sdio_print_state(old_state, hi_sdio->state);
1192 }
1193
oal_disable_sdio_state(struct BusDev * bus,hi_u32 mask)1194 hi_void oal_disable_sdio_state(struct BusDev *bus, hi_u32 mask)
1195 {
1196 hi_u32 old_state;
1197 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1198 if (hi_sdio == HI_NULL) {
1199 printk("oal_enable_sdio_state: hi_sdio null!\n");
1200 return;
1201 }
1202
1203 old_state = hi_sdio->state;
1204 hi_sdio->state &= ~mask;
1205 oal_sdio_print_state(old_state, hi_sdio->state);
1206 }
1207
1208 /*
1209 * Description : free sdio dev
1210 * Input :
1211 * Output : None
1212 * Return Value : hi_void
1213 */
oal_sdio_free(oal_channel_stru * hi_sdio)1214 static hi_void oal_sdio_free(oal_channel_stru *hi_sdio)
1215 {
1216 if (hi_sdio == HI_NULL) {
1217 return;
1218 }
1219 OAL_MUTEX_DESTROY(&hi_sdio->rx_transfer_lock);
1220 oal_free_sdio_stru(hi_sdio);
1221 }
1222
oal_sdio_interrupt_register(struct BusDev * bus)1223 hi_s32 oal_sdio_interrupt_register(struct BusDev *bus)
1224 {
1225 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1226 #ifndef _PRE_FEATURE_NO_GPIO
1227 hi_s32 ret;
1228
1229 if (g_hisdio_intr_mode) {
1230 /* use gpio interrupt for sdio data interrupt */
1231 ret = oal_register_gpio_intr(bus);
1232 if (ret < 0) {
1233 printk("failed to register gpio interrupt\n");
1234 return ret;
1235 }
1236 } else {
1237 /* use sdio interrupt for sdio data interrupt */
1238 ret = oal_register_sdio_intr(bus);
1239 if (ret < 0) {
1240 printk("failed to register sdio interrupt\n");
1241 return ret;
1242 }
1243 }
1244 #else
1245 hi_unref_param(hi_sdio);
1246 #endif
1247 return HI_SUCCESS;
1248 }
1249
1250 /*
1251 * Description : initialize sdio interface
1252 * Input :
1253 * Output : None
1254 * Return Value : succ or fail
1255 */
oal_sdio_init(struct BusDev * bus)1256 static hi_s32 oal_sdio_init(struct BusDev *bus)
1257 {
1258 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1259 void *func = hi_sdio->func;
1260 hi_s32 ret;
1261 if (func == HI_NULL) {
1262 printk("oal_sdio_probe func/func->card->host ids null\n");
1263 return -OAL_EFAIL;
1264 }
1265
1266 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1267 g_p_gst_sdio_func = func;
1268 #endif
1269 /* alloce sdio control struct */
1270 if (hi_sdio == HI_NULL) {
1271 g_sdio_enum_err_str = "failed to alloc hi_sdio!";
1272 printk(KERN_ERR "%s\n", g_sdio_enum_err_str);
1273 goto failed_sdio_alloc;
1274 }
1275 OAL_MUTEX_INIT(&hi_sdio->rx_transfer_lock);
1276 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1277 /* func keep a pointer to oal_sdio */
1278 sdio_set_drvdata((struct sdio_func *)func, hi_sdio);
1279 #endif
1280
1281 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1282 /* register interrupt process function */
1283 ret = oal_sdio_interrupt_register(bus);
1284 if (ret < 0) {
1285 g_sdio_enum_err_str = "failed to register sdio interrupt";
1286 printk("%s\n", g_sdio_enum_err_str);
1287 printf("failed to register sdio interrupt\n");
1288 goto failed_sdio_int_reg;
1289 }
1290 #endif
1291
1292 oal_disable_sdio_state(bus, OAL_SDIO_ALL);
1293
1294 if (oal_sdio_dev_init(bus) != HI_SUCCESS) {
1295 g_sdio_enum_err_str = "sdio dev init failed";
1296 goto failed_sdio_dev_init;
1297 }
1298
1299 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1300 /* Print the sdio's cap */
1301 oam_print_info("max_segs:%u, max_blk_size:%u,max_blk_count:%u,,max_seg_size:%u,max_req_size:%u\n",
1302 sdio_get_max_segs((struct sdio_func *)func), sdio_get_max_blk_size((struct sdio_func*)func),
1303 sdio_get_max_block_count((struct sdio_func *)func), sdio_get_max_seg_size((struct sdio_func *)func),
1304 sdio_get_max_req_size((struct sdio_func *)func));
1305 #endif
1306
1307 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1308 /* register interrupt process function */
1309 ret = oal_sdio_interrupt_register(bus);
1310 if (ret < 0) {
1311 g_sdio_enum_err_str = "failed to register sdio interrupt";
1312 oam_print_info("%s\n", g_sdio_enum_err_str);
1313 goto failed_sdio_int_reg;
1314 }
1315 #endif
1316
1317 oal_wake_lock_init(&hi_sdio->st_sdio_wakelock, "wlan_sdio_lock");
1318 oal_sema_init(&g_chan_wake_sema, 1);
1319
1320 return HI_SUCCESS;
1321 failed_sdio_int_reg:
1322 failed_sdio_dev_init:
1323 oal_sdio_free(hi_sdio);
1324 failed_sdio_alloc:
1325
1326 return -OAL_EFAIL;
1327 }
1328
1329 /* ****************************************************************************
1330 功能描述 : 强行释放wakelock锁
1331 输入参数 : 无
1332 输出参数 : 无
1333 返 回 值 : 成功或失败原因
1334 **************************************************************************** */
oal_sdio_wakelocks_release_detect(struct BusDev * bus)1335 hi_void oal_sdio_wakelocks_release_detect(struct BusDev *bus)
1336 {
1337 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1338 /* before call this function , please make sure the rx/tx queue is empty and no data transfer!! */
1339 if (hi_sdio == HI_NULL) {
1340 printk("oal_sdio_wakelocks_release_detect hi_sdio null\n");
1341 return;
1342 }
1343 if (oal_sdio_wakelock_active(hi_sdio) != 0) {
1344 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1345 #ifdef CONFIG_HAS_WAKELOCK
1346 printk("[E]We still hold %s %lu wake locks, Now release all", hi_sdio->st_sdio_wakelock.st_wakelock.ws.name,
1347 hi_sdio->st_sdio_wakelock.lock_count);
1348 #endif
1349 #endif
1350 hi_sdio->st_sdio_wakelock.lock_count = 1;
1351 oal_sdio_wake_unlock(bus);
1352 }
1353 }
1354
oal_sdio_single_transfer(struct BusDev * bus,hi_s32 rw,hi_void * buf,hi_u32 size)1355 static hi_s32 oal_sdio_single_transfer(struct BusDev *bus, hi_s32 rw, hi_void *buf, hi_u32 size)
1356 {
1357 if ((bus == HI_NULL) || (bus->priData.data == HI_NULL) || (buf == HI_NULL) || ((uintptr_t)buf & 0x3)) {
1358 printk("oal_sdio_single_transfer:hi_sdio/hi_sdio->func/buf/(uintptr_t)buf & 0x3 err\n");
1359 return -OAL_EINVAL;
1360 }
1361
1362 return oal_sdio_rw_buf(bus, rw, HISDIO_REG_FUNC1_FIFO, buf, size);
1363 }
1364
oal_sdio_transfer_tx(struct BusDev * bus,oal_netbuf_stru * netbuf)1365 hi_s32 oal_sdio_transfer_tx(struct BusDev *bus, oal_netbuf_stru *netbuf)
1366 {
1367 hi_s32 ret = HI_SUCCESS;
1368 hi_u32 tailroom, tailroom_add;
1369 if (netbuf == HI_NULL) {
1370 printk("oal_sdio_transfer_tx netbuf null\n");
1371 return -OAL_EFAIL;
1372 }
1373
1374 tailroom = HISDIO_ALIGN_4_OR_BLK(oal_netbuf_len(netbuf)) - oal_netbuf_len(netbuf);
1375 if (tailroom > oal_netbuf_tailroom(netbuf)) {
1376 tailroom_add = tailroom - oal_netbuf_tailroom(netbuf);
1377 /* relloc the netbuf */
1378 ret = oal_netbuf_expand_head(netbuf, 0, tailroom_add, GFP_ATOMIC);
1379 if (oal_unlikely(ret != HI_SUCCESS)) {
1380 printk("alloc tail room failed\n");
1381 return -OAL_EFAIL;
1382 }
1383 }
1384
1385 oal_netbuf_put(netbuf, tailroom);
1386
1387 return oal_sdio_single_transfer(bus, SDIO_WRITE, oal_netbuf_data(netbuf), oal_netbuf_len(netbuf));
1388 }
1389
check_sg_format(struct scatterlist * sg,hi_u32 sg_len)1390 hi_void check_sg_format(struct scatterlist *sg, hi_u32 sg_len)
1391 {
1392 hi_u32 i = 0;
1393 struct scatterlist *sg_t = HI_NULL;
1394 for_each_sg(sg, sg_t, sg_len, i) {
1395 if (oal_unlikely(HI_NULL == sg_t)) {
1396 return;
1397 }
1398 if (OAL_WARN_ON(((uintptr_t)sg_virt(sg_t) & 0x03) || (sg_t->length & 0x03))) {
1399 printk("check_sg_format:[i:%d][addr:%p][len:%u]\n", i, sg_virt(sg_t), sg_t->length);
1400 }
1401 }
1402 }
1403
dump_sg_format(struct scatterlist * sg,hi_u32 sg_len)1404 hi_void dump_sg_format(struct scatterlist *sg, hi_u32 sg_len)
1405 {
1406 hi_u32 i = 0;
1407 struct scatterlist *sg_t = HI_NULL;
1408 printk("sg dump nums:%d\n", sg_len);
1409 if (sg == HI_NULL) {
1410 printk("dump_sg_format::sg is null!\n");
1411 return;
1412 }
1413 for_each_sg(sg, sg_t, sg_len, i) {
1414 if (sg_t == HI_NULL) {
1415 printk("dump_sg_format::sg_t is null!\n");
1416 return;
1417 }
1418 printk("sg descr:%3d,addr:%p,len:%6d\n", i, sg_virt(sg_t), sg_t->length);
1419 }
1420 }
1421
1422 #ifdef CONFIG_HISDIO_H2D_SCATT_LIST_ASSEMBLE
oal_sdio_tx_scatt_list_merge(oal_channel_stru * hi_sdio,struct scatterlist * sg,hi_u32 sg_len,hi_u32 rw_sz)1423 hi_s32 oal_sdio_tx_scatt_list_merge(oal_channel_stru *hi_sdio, struct scatterlist *sg, hi_u32 sg_len, hi_u32 rw_sz)
1424 {
1425 hi_s32 i;
1426 hi_s32 offset = 0;
1427 hi_s32 left_size, nents;
1428 struct scatterlist *sg_t = HI_NULL;
1429 hi_u8 *pst_scatt_buff = (hi_u8 *)hi_sdio->scatt_buff.buff;
1430 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1431 hi_u32 seg_size = sdio_get_max_seg_size(hi_sdio->func);
1432 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1433 hi_u32 seg_size = sdio_get_max_blk_size(hi_sdio->func);
1434 #endif
1435 if (seg_size == 0) {
1436 return -OAL_EINVAL;
1437 }
1438
1439 if (oal_unlikely(rw_sz > hi_sdio->scatt_buff.len)) {
1440 printk("[E]sdio tx request %u bytes,scatt buf had %u,failed!\n", rw_sz, hi_sdio->scatt_buff.len);
1441 OAL_BUG_ON(1);
1442 return -OAL_ENOMEM;
1443 }
1444
1445 if (sg == HI_NULL) {
1446 printk("oal_sdio_tx_scatt_list_merge::sg is null!\n");
1447 return -OAL_EINVAL;
1448 }
1449 for_each_sg(sg, sg_t, sg_len, i) {
1450 if (sg_t == HI_NULL) {
1451 printk("oal_sdio_tx_scatt_list_merge::sg_t is null!\n");
1452 return -OAL_EINVAL;
1453 }
1454 memcpy_s(pst_scatt_buff + offset, sg_t->length, sg_virt(sg_t), sg_t->length);
1455 offset += sg_t->length;
1456 }
1457
1458 if (oal_unlikely(offset > rw_sz)) {
1459 printk("[E]%s offset:%u > rw_sz:%u!\n", __FUNCTION__, offset, rw_sz);
1460 OAL_BUG_ON(1);
1461 return -OAL_EINVAL;
1462 }
1463
1464 left_size = offset;
1465 /* reset the sg list! */
1466 nents = ((left_size - 1) / seg_size) + 1;
1467 if (oal_unlikely(nents > (hi_s32)sg_len)) {
1468 printk("[E]%s merged scatt list num %d > sg_len:%u,max seg size:%u\n", __FUNCTION__, nents, sg_len, seg_size);
1469 OAL_BUG_ON(1);
1470 return -OAL_ENOMEM;
1471 }
1472
1473 sg_init_table(sg, nents);
1474 for_each_sg(sg, sg_t, nents, i) {
1475 if (HI_NULL == sg_t) {
1476 printk("oal_sdio_tx_scatt_list_merge::sg_t is null!\n");
1477 return -OAL_EINVAL;
1478 }
1479 sg_set_buf(sg_t, pst_scatt_buff + i * seg_size, oal_min(seg_size, left_size));
1480 left_size = left_size - seg_size;
1481 }
1482
1483 return nents;
1484 }
1485 #endif
1486
1487 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_mmc_io_rw_scat_extended(const oal_channel_stru * hi_sdio,hi_s32 write,hi_u32 fn,hi_u32 addr,hi_s32 incr_addr,struct scatterlist * sg,hi_u32 sg_len,hi_u32 blocks,hi_u32 blksz)1488 hi_s32 oal_mmc_io_rw_scat_extended(const oal_channel_stru *hi_sdio, hi_s32 write, hi_u32 fn, hi_u32 addr,
1489 hi_s32 incr_addr, struct scatterlist *sg, hi_u32 sg_len, hi_u32 blocks, hi_u32 blksz)
1490 {
1491 struct mmc_request mrq = { 0 };
1492 struct mmc_command cmd = { 0 };
1493 struct mmc_data data = { 0 };
1494 struct mmc_card *card = HI_NULL;
1495 struct sdio_func *func = HI_NULL;
1496
1497 OAL_BUG_ON(!hi_sdio);
1498 OAL_BUG_ON(!sg);
1499 OAL_BUG_ON(sg_len == 0);
1500 OAL_BUG_ON(fn > 7); /* fn must bigger than 7 */
1501
1502 if (OAL_WARN_ON(blksz == 0)) {
1503 return -EINVAL;
1504 }
1505
1506 /* sanity check */
1507 if (oal_unlikely(addr & ~0x1FFFF)) {
1508 return -EINVAL;
1509 }
1510 func = hi_sdio->func;
1511 card = func->card;
1512
1513 /* sg format */
1514 check_sg_format(sg, sg_len);
1515
1516 #ifdef CONFIG_HISDIO_H2D_SCATT_LIST_ASSEMBLE
1517 #ifndef LITEOS_IPC_CODE
1518 if (write) {
1519 /* copy the buffs ,align to SDIO_BLOCK
1520 Fix the sdio host ip fifo depth issue temporarily */
1521 hi_s32 ret = oal_sdio_tx_scatt_list_merge(hi_sdio, sg, sg_len, blocks * blksz);
1522 if (oal_likely(ret > 0)) {
1523 sg_len = ret;
1524 } else {
1525 return ret;
1526 }
1527 }
1528 #endif
1529 #endif
1530
1531 mrq.cmd = &cmd;
1532 mrq.data = &data;
1533
1534 cmd.opcode = SD_IO_RW_EXTENDED;
1535 cmd.arg = write ? 0x80000000 : 0x00000000;
1536 cmd.arg |= fn << 28; /* left shift 28 */
1537 cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
1538 cmd.arg |= addr << 9; /* left shift 9 */
1539 if (blocks == 1 && blksz <= 512) { /* blksz range [1 512] */
1540 cmd.arg |= (blksz == 512) ? 0 : blksz; /* blksz equal 512, use byte mode */
1541 } else {
1542 cmd.arg |= 0x08000000 | blocks; /* block mode */
1543 }
1544 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
1545
1546 data.blksz = blksz;
1547 data.blocks = blocks;
1548 data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
1549 data.sg = sg;
1550 data.sg_len = sg_len;
1551 #ifdef CONFIG_SDIO_DEBUG
1552 printk("[blksz:%u][blocks:%u][sg_len:%u][mode:%s]\n", blksz, blocks, sg_len, write ? "write" : "read");
1553 printk("%s : [cmd opcode:%d][cmd arg:0x%8x][cmd flags: 0x%8x]\n", mmc_hostname(card->host), cmd.opcode, cmd.arg,
1554 cmd.flags);
1555 printk("Sdio %s data transfer start\n", write ? "write" : "read");
1556 #endif
1557
1558 mmc_set_data_timeout(&data, card);
1559 mmc_wait_for_req(card->host, &mrq);
1560
1561 #ifdef CONFIG_SDIO_DEBUG
1562 printk("wait for %s transfer over.\n", write ? "write" : "read");
1563 #endif
1564 if (cmd.error) {
1565 return cmd.error;
1566 }
1567 if (data.error) {
1568 return data.error;
1569 }
1570
1571 if (OAL_WARN_ON(mmc_host_is_spi(card->host))) {
1572 printk("HiSi WiFi driver do not support spi sg transfer!\n");
1573 return -EIO;
1574 }
1575 if (cmd.resp[0] & R5_ERROR) {
1576 return -EIO;
1577 }
1578 if (cmd.resp[0] & R5_FUNCTION_NUMBER) {
1579 return -EINVAL;
1580 }
1581 if (cmd.resp[0] & R5_OUT_OF_RANGE) {
1582 return -ERANGE;
1583 }
1584 #ifdef CONFIG_SDIO_DEBUG
1585 do {
1586 int i;
1587 struct scatterlist *sg_t;
1588 for_each_sg(data.sg, sg_t, data.sg_len, i) {
1589 printk(KERN_DEBUG "======netbuf pkts %d, len:%d=========\n", i, sg_t->length);
1590 oal_print_hex_dump(sg_virt(sg_t), sg_t->length, 32, "sg buf :"); /* 32 进制 */
1591 }
1592 } while (0);
1593 printk("Transfer done. %s sucuess!\n", write ? "write" : "read");
1594 #endif
1595 return 0;
1596 }
1597 #endif
1598
_oal_sdio_transfer_scatt(struct BusDev * bus,hi_s32 rw,hi_u32 addr,struct scatterlist * sg,hi_u32 sg_len,hi_u32 rw_sz)1599 static hi_s32 _oal_sdio_transfer_scatt(struct BusDev *bus, hi_s32 rw, hi_u32 addr, struct scatterlist *sg,
1600 hi_u32 sg_len, hi_u32 rw_sz)
1601 {
1602 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1603 struct BusConfig busCfg = {0};
1604 #ifdef CONFIG_HISI_SDIO_TIME_DEBUG
1605 oal_time_t_stru time_start;
1606 time_start = oal_ktime_get();
1607 #endif
1608 hi_s32 ret;
1609 hi_s32 write = (rw == SDIO_READ) ? 0 : 1;
1610 bus->ops.claimHost(bus);
1611
1612 if (oal_unlikely(oal_sdio_get_state(hi_sdio, OAL_SDIO_ALL) != HI_TRUE)) {
1613 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1614 if (printk_ratelimit())
1615 #endif
1616 printk("[W][%s]sdio closed,state:%u\n", __FUNCTION__, oal_sdio_get_state(hi_sdio, OAL_SDIO_ALL));
1617 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1618 schedule();
1619 #endif
1620 bus->ops.releaseHost(bus);
1621 return -OAL_EFAIL;
1622 }
1623 busCfg.busType = BUS_SDIO;
1624 ret = bus->ops.getBusInfo(bus, &busCfg);
1625 if (ret != 0) {
1626 printk("get Bus info failed!\n");
1627 return -OAL_EINVAL;
1628 }
1629 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1630 ret = oal_mmc_io_rw_scat_extended(hi_sdio, write, busCfg.busInfo.sdioInfo.funcNumSize, addr, 0, sg, sg_len,
1631 (rw_sz / HISDIO_BLOCK_SIZE) ? : 1, min(rw_sz, (hi_u32)HISDIO_BLOCK_SIZE));
1632 #else
1633 if (rw == SDIO_READ) {
1634 ret = bus->ops.bulkRead(bus, addr, rw_sz, (uint8_t *)sg, sg_len);
1635 } else {
1636 ret = bus->ops.bulkWrite(bus, addr, rw_sz, (uint8_t *)sg, sg_len);
1637 }
1638 #endif
1639 if (oal_unlikely(ret)) {
1640 #ifdef CONFIG_HISI_SDIO_TIME_DEBUG
1641 hi_u64 trans_us;
1642 oal_time_t_stru time_stop = oal_ktime_get();
1643 trans_us = (hi_u64)oal_ktime_to_us(oal_ktime_sub(time_stop, time_start));
1644 printk("[W][%s]trans_us:%llu\n", __FUNCTION__, trans_us);
1645 #endif
1646 if (write) {
1647 oam_error_log1(0, OAM_SF_ANY, "{oal_sdio_transfer_scatt::write failed=%d}", ret);
1648 } else {
1649 oam_error_log1(0, OAM_SF_ANY, "{oal_sdio_transfer_scatt::read failed=%d}", ret);
1650 }
1651 oal_exception_submit(TRANS_FAIL);
1652 }
1653 bus->ops.releaseHost(bus);
1654 if (rw == SDIO_READ) {
1655 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1656 schedule();
1657 #endif
1658 }
1659 return ret;
1660 }
1661
1662 /*
1663 * Description : sdio scatter data transfer
1664 * Input :
1665 * Output : None
1666 * Return Value : err or succ
1667 */
oal_sdio_transfer_scatt(struct BusDev * bus,hi_s32 rw,hi_u32 addr,struct scatterlist * sg,hi_u32 sg_len,hi_u32 sg_max_len,hi_u32 rw_sz)1668 hi_s32 oal_sdio_transfer_scatt(struct BusDev *bus, hi_s32 rw, hi_u32 addr, struct scatterlist *sg,
1669 hi_u32 sg_len, hi_u32 sg_max_len, hi_u32 rw_sz)
1670 {
1671 hi_s32 ret;
1672 hi_u32 align_len;
1673 hi_u32 align_t;
1674 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1675
1676 if ((hi_sdio == HI_NULL) || (rw_sz == 0) || (sg_max_len < sg_len)) {
1677 return -OAL_EINVAL;
1678 }
1679
1680 #ifdef CONFIG_SDIO_DEBUG
1681 hi_s32 write = (rw == SDIO_READ) ? 0 : 1;
1682 #endif
1683
1684 if ((!hi_sdio) || (!rw_sz) || (sg_max_len < sg_len) || (sg == HI_NULL)) {
1685 oam_error_log3(0, OAM_SF_ANY, "oal_sdio_transfer_scatt: hi_sdio:%p,/rw_sz:%d,/sg_max_len<sg_len?:%d,/sg null}",
1686 (uintptr_t)hi_sdio, rw_sz, sg_max_len < sg_len);
1687 return -OAL_EINVAL;
1688 }
1689
1690 if (OAL_WARN_ON(!sg_len)) {
1691 oam_error_log2(0, OAM_SF_ANY,
1692 "Sdio %d(1:read,2:write) Scatter list num should never be zero, total request len: %u}",
1693 rw == SDIO_READ ? 1 : 2, rw_sz); /* read:1 write:2 */
1694 return -OAL_EINVAL;
1695 }
1696
1697 align_t = HISDIO_ALIGN_4_OR_BLK(rw_sz);
1698 align_len = align_t - rw_sz;
1699
1700 if (oal_likely(align_len)) {
1701 if (oal_unlikely(sg_len + 1 > sg_max_len)) {
1702 oam_error_log2(0, OAM_SF_ANY, "{sg list over,sg_len:%u, sg_max_len:%u\n}", sg_len, sg_max_len);
1703 return -OAL_ENOMEM;
1704 }
1705 sg_set_buf(&sg[sg_len], (const void *)(UINTPTR)hi_sdio->sdio_align_buff, align_len);
1706 sg_len++;
1707 }
1708 sg_mark_end(&sg[sg_len - 1]);
1709
1710 #ifdef CONFIG_SDIO_DEBUG
1711 oam_warning_log4(0, OAM_SF_ANY, "{sdio %s request %u bytes transfer, scatter list num %u, used %u bytes to align}",
1712 write ? "write" : "read", rw_sz, sg_len, align_len);
1713 #endif
1714
1715 rw_sz = align_t;
1716
1717 /* sdio scatter list driver ,when letter than 512 bytes bytes mode, other blockmode */
1718 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1719 OAL_WARN_ON((rw_sz >= HISDIO_BLOCK_SIZE) && (rw_sz & (HISDIO_BLOCK_SIZE - 1)));
1720 OAL_WARN_ON((rw_sz < HISDIO_BLOCK_SIZE) && (rw_sz & (4 - 1))); /* 4 */
1721 #endif
1722
1723 if (OAL_WARN_ON(align_len & 0x3)) {
1724 oam_warning_log1(0, OAM_SF_ANY, "{not 4 bytes align:%u\n}", align_len);
1725 }
1726
1727 ret = _oal_sdio_transfer_scatt(bus, rw, addr, sg, sg_len, rw_sz);
1728
1729 return ret;
1730 }
1731
oal_sdio_transfer_netbuf_list(struct BusDev * bus,const oal_netbuf_head_stru * head,hi_s32 rw)1732 hi_s32 oal_sdio_transfer_netbuf_list(struct BusDev *bus, const oal_netbuf_head_stru *head, hi_s32 rw)
1733 {
1734 hi_u8 sg_realloc = 0;
1735 hi_s32 ret;
1736 hi_u32 idx = 0;
1737 hi_u32 queue_len;
1738 hi_u32 sum_len = 0;
1739 hi_u32 request_sg_len;
1740 oal_netbuf_stru *netbuf = HI_NULL;
1741 oal_netbuf_stru *tmp = HI_NULL;
1742 struct scatterlist *sg = HI_NULL;
1743 struct sg_table sgtable = { 0 };
1744 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1745 if ((!hi_sdio) || (!head)) {
1746 printk("hi_sdio / head null\n");
1747 return -OAL_EINVAL;
1748 }
1749
1750 if (OAL_WARN_ON(rw >= SDIO_OPT_BUTT)) {
1751 printk("invalid rw:%d\n", rw);
1752 return -OAL_EINVAL;
1753 }
1754
1755 if (OAL_WARN_ON(oal_netbuf_list_empty(head))) {
1756 return -OAL_EINVAL;
1757 }
1758 if (rw == SDIO_WRITE) {
1759 if (hi_sdio->pst_pm_callback) {
1760 if (hi_sdio->pst_pm_callback->wlan_pm_wakeup_dev() != HI_SUCCESS) {
1761 oam_error_log0(0, OAM_SF_ANY, "{oal_sdio_transfer_netbuf_list::host wakeup device failed}");
1762 return -OAL_EBUSY;
1763 }
1764 }
1765 }
1766 queue_len = oal_netbuf_list_len(head);
1767 /* must realloc the sg list mem, alloc more sg for the align buff */
1768 request_sg_len = queue_len + 1;
1769 if (oal_unlikely(request_sg_len > hi_sdio->scatt_info[rw].max_scatt_num)) {
1770 oam_warning_log2(0, OAM_SF_ANY, "transfer_netbuf_list realloc sg!, request:%d,max scatt num:%d",
1771 request_sg_len, hi_sdio->scatt_info[rw].max_scatt_num);
1772 /* must realloc the sg list mem, alloc more sgs for the align buff */
1773 if (sg_alloc_table(&sgtable, request_sg_len, GFP_KERNEL) != 0) {
1774 oam_error_log0(0, OAM_SF_ANY, "{transfer_netbuf_list alloc sg failed!}");
1775 return -OAL_ENOMEM;
1776 }
1777 sg_realloc = 1;
1778 sg = sgtable.sgl;
1779 } else {
1780 sg = hi_sdio->scatt_info[rw].sglist;
1781 }
1782
1783 memset_s(sg, sizeof(struct scatterlist) * request_sg_len, 0, sizeof(struct scatterlist) * request_sg_len);
1784
1785 oal_skb_queue_walk_safe(head, netbuf, tmp) {
1786 /* assert, should drop the scatt transfer */
1787 if (!oal_is_aligned((uintptr_t)oal_netbuf_data(netbuf), 4)) { /* 4 字节对齐 */
1788 oam_error_log0(0, OAM_SF_ANY, "{oal_sdio_transfer_netbuf_list netbuf 4 aligned fail!}");
1789 return -OAL_EINVAL;
1790 }
1791 if (OAL_WARN_ON(!oal_is_aligned(oal_netbuf_len(netbuf), HISDIO_H2D_SCATT_BUFFLEN_ALIGN))) {
1792 /* This should never happned, debug */
1793 oal_netbuf_hex_dump(netbuf);
1794 }
1795 if (!oal_is_aligned(oal_netbuf_len(netbuf), HISDIO_H2D_SCATT_BUFFLEN_ALIGN)) {
1796 oam_error_log0(0, OAM_SF_ANY, "{oal_sdio_transfer_netbuf_list netbuf 8 aligned fail!}");
1797 return -OAL_EINVAL;
1798 }
1799 sg_set_buf(&sg[idx], oal_netbuf_data(netbuf), oal_netbuf_len(netbuf));
1800 sum_len += oal_netbuf_len(netbuf);
1801 idx++;
1802 }
1803
1804 if (oal_unlikely(idx > queue_len)) {
1805 printk("idx:%d, queue_len:%d\n", idx, queue_len);
1806 return -OAL_EINVAL;
1807 }
1808 wlan_pm_set_packet_cnt(1);
1809 ret = oal_sdio_transfer_scatt(bus, rw, HISDIO_REG_FUNC1_FIFO, sg, idx, request_sg_len, sum_len);
1810 if (sg_realloc) {
1811 sg_free_table(&sgtable);
1812 }
1813 return ret;
1814 }
1815
1816 /*
1817 * Description :
1818 * Input : struct device *dev
1819 * Output : None
1820 * Return Value : static hi_s32
1821 */
1822 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_sdio_suspend(struct device * dev)1823 static hi_s32 oal_sdio_suspend(struct device *dev)
1824 {
1825 struct sdio_func *func = HI_NULL;
1826 oal_channel_stru *hi_sdio = HI_NULL;
1827
1828 printk(KERN_ERR "+++++++sdio suspend+++++++++++++\n");
1829 if (dev == HI_NULL) {
1830 printk("[WARN]dev is null\n");
1831 return HI_SUCCESS;
1832 }
1833 func = dev_to_sdio_func(dev);
1834 hi_sdio = sdio_get_drvdata(func);
1835 if (hi_sdio == HI_NULL) {
1836 printk("hi_sdio is null\n");
1837 return HI_SUCCESS;
1838 }
1839
1840 if (oal_down_interruptible(&g_chan_wake_sema)) {
1841 printk(KERN_ERR "g_chan_wake_sema down failed.");
1842 return -OAL_EFAIL;
1843 }
1844
1845 if (oal_sdio_wakelock_active(hi_sdio) != 0) {
1846 /* has wake lock so stop controller's suspend,
1847 * otherwise controller maybe error while sdio reinit */
1848 printk(KERN_ERR "Already wake up");
1849 oal_up(&g_chan_wake_sema);
1850 return -OAL_EFAIL;
1851 }
1852 hi_sdio->ul_sdio_suspend++;
1853 return HI_SUCCESS;
1854 }
1855 #endif
1856
1857 /*
1858 * Description : sdio resume
1859 * Input : struct device *dev
1860 * Output : None
1861 * Return Value : static hi_s32
1862 */
1863 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_sdio_resume(struct device * dev)1864 static hi_s32 oal_sdio_resume(struct device *dev)
1865 {
1866 struct sdio_func *func = HI_NULL;
1867 oal_channel_stru *hi_sdio = HI_NULL;
1868
1869 printk("+++++++sdio resume+++++++++++++\n");
1870 if (dev == HI_NULL) {
1871 printk("[WARN]dev is null\n");
1872 return HI_SUCCESS;
1873 }
1874 func = dev_to_sdio_func(dev);
1875 hi_sdio = sdio_get_drvdata(func);
1876 if (hi_sdio == HI_NULL) {
1877 printk("hi_sdio is null\n");
1878 return HI_SUCCESS;
1879 }
1880 oal_up(&g_chan_wake_sema);
1881
1882 hi_sdio->ul_sdio_resume++;
1883
1884 return HI_SUCCESS;
1885 }
1886 #endif
1887
1888 MODULE_DEVICE_TABLE(sdio, g_oal_sdio_ids);
1889
1890 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1891 static const struct dev_pm_ops oal_sdio_pm_ops = {
1892 .suspend = oal_sdio_suspend,
1893 .resume = oal_sdio_resume,
1894 };
1895 #endif
1896
oal_sdio_dev_shutdown(struct device * dev)1897 hi_void oal_sdio_dev_shutdown(struct device *dev)
1898 {
1899 struct BusDev *bus = oal_get_bus_default_handler();
1900 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1901
1902 hi_unref_param(dev);
1903 /* poweroff */
1904 if ((hi_sdio == HI_NULL) || (hi_sdio->func == NULL)) {
1905 goto exit;
1906 }
1907
1908 hi_wifi_plat_pm_disable();
1909 oal_sdio_sleep_dev(oal_get_sdio_default_handler());
1910
1911 if (oal_sdio_send_msg(oal_get_sdio_default_handler(), H2D_MSG_PM_WLAN_OFF) != HI_SUCCESS) {
1912 goto exit;
1913 }
1914
1915 if (HI_TRUE != oal_sdio_get_state(hi_sdio, OAL_SDIO_ALL)) {
1916 goto exit;
1917 }
1918 if (g_hisdio_intr_mode) {
1919 oal_wlan_gpio_intr_enable(bus, 0);
1920 } else {
1921 hi_s32 ret;
1922 oal_sdio_claim_host(bus);
1923 ret = bus->ops.disableBus(bus);
1924 oal_sdio_release_host(bus);
1925 if (ret) {
1926 goto exit;
1927 }
1928 }
1929 exit:
1930 return;
1931 }
1932
sdio_card_detect_change(hi_s32 val)1933 hi_void sdio_card_detect_change(hi_s32 val)
1934 {
1935 hi_unref_param(val);
1936 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
1937 hisi_sdio_rescan(HdfWifiGetBusIdx());
1938 #else
1939 hi_s32 ret = hisi_sdio_rescan(HdfWifiGetBusIdx());
1940 if (ret != HI_ERR_SUCCESS) {
1941 oam_error_log0(0, 0, "sdio rescan failed.");
1942 }
1943 #endif
1944 }
1945
hi_wlan_power_set(hi_s32 on)1946 hi_void hi_wlan_power_set(hi_s32 on)
1947 {
1948 /*
1949 * this should be done in mpw1
1950 * it depends on the gpio used to power up and down 1101 chip
1951 *
1952 * */
1953 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
1954 if (on) {
1955 printk("sdio probe:pull up power on gpio\n");
1956 board_power_on();
1957 } else {
1958 printk("sdio probe:pull down power on gpio\n");
1959 board_power_off();
1960 }
1961 #else
1962 hi_unref_param(on);
1963 #endif
1964 }
1965
1966 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
oal_sdio_func_probe_resume(struct BusDev * bus)1967 hi_s32 oal_sdio_func_probe_resume(struct BusDev *bus)
1968 {
1969 hi_s32 ret;
1970
1971 oam_info_log0(0, OAM_SF_ANY, "{start to register sdio module!}");
1972 ret = oal_sdio_init(bus);
1973 if (ret) {
1974 printk("fail to init sdio\n");
1975 goto failed_sdio_enum;
1976 }
1977 return HI_SUCCESS;
1978 failed_sdio_enum:
1979 /* sdio can not remove!
1980 hi_sdio_detectcard_to_core(0); */
1981 return -OAL_EFAIL;
1982 }
1983 #endif
1984
oal_sdio_func_init(struct BusDev * bus)1985 hi_s32 oal_sdio_func_init(struct BusDev *bus)
1986 {
1987 hi_s32 ret;
1988 hi_s32 i;
1989 void *func = NULL;
1990 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
1991 struct BusConfig busCfg = {0};
1992
1993 if (hi_sdio == HI_NULL) {
1994 return -OAL_EFAIL;
1995 }
1996
1997 struct HdfConfigWlanBus *busConfig = NULL;
1998 struct HdfConfigWlanDeviceList *devList = NULL;
1999 struct HdfConfigWlanRoot *rootConfig = HdfWlanGetModuleConfigRoot();
2000 if (rootConfig == NULL) {
2001 oam_print_err("%s:NULL ptr!", __func__);
2002 return -OAL_EFAIL;
2003 }
2004 devList = &rootConfig->wlanConfig.deviceList;
2005 if (devList == NULL) {
2006 oam_print_err("%s:No device defined.", __func__);
2007 return -OAL_EFAIL;
2008 }
2009 for (i = 0; i < devList->deviceListSize; i++) {
2010 busConfig = &rootConfig->wlanConfig.deviceList.deviceInst[i].bus;
2011 ret = bus->ops.init(bus, busConfig);
2012 if (ret == 0) {
2013 break;
2014 }
2015 }
2016 if (i == devList->deviceListSize) {
2017 oam_print_err("%s:sdio init failed", __func__);
2018 return -OAL_EFAIL;
2019 }
2020 busCfg.busType = BUS_SDIO;
2021 if (bus->ops.getBusInfo(bus, &busCfg) != 0) {
2022 oam_print_err("get bus info failed!\n");
2023 return -OAL_EFAIL;
2024 }
2025 func = busCfg.busInfo.sdioInfo.data;
2026 if (func == NULL) {
2027 oam_print_err("func is NULL!\n");
2028 return -OAL_EFAIL;
2029 }
2030 hi_sdio->func = func;
2031
2032 /* notify mmc core to detect sdio device */
2033 ret = oal_sdio_init(bus);
2034 if (ret) {
2035 oam_print_err("fail to detect sdio card, ret=%d\n", ret);
2036 goto failed_sdio_reg;
2037 }
2038 oal_sdio_claim_host(bus);
2039 oal_disable_sdio_state(bus, OAL_SDIO_ALL);
2040
2041 oal_sdio_release_host(bus);
2042
2043 return HI_SUCCESS;
2044 failed_sdio_reg:
2045 return -OAL_EFAIL;
2046 }
2047
oal_sdio_func_reset(void)2048 hi_s32 oal_sdio_func_reset(void)
2049 {
2050 hi_s32 ret;
2051 hi_s32 l_need_retry = 1;
2052 struct BusDev *bus = oal_get_bus_default_handler();
2053 OAL_INIT_COMPLETION(&g_sdio_driver_complete);
2054
2055 oal_sdio_func_remove(bus);
2056 #ifndef _PRE_FEATURE_NO_GPIO
2057 wlan_rst();
2058 #endif
2059 detect_retry:
2060 /* notify mmc core to detect sdio device */
2061 ret = oal_sdio_init(bus);
2062 if (ret) {
2063 oam_print_err("fail to detect sdio card, ret=%d\n", ret);
2064 goto failed_sdio_enum;
2065 }
2066 if (oal_wait_for_completion_timeout(&g_sdio_driver_complete, TIMEOUT_MUTIPLE_5 * HZ) != 0) {
2067 printk("hisi sdio load sucuess, sdio enum done.\n");
2068 } else {
2069 printk("sdio enum timeout, reason[%s]\n", g_sdio_enum_err_str);
2070
2071 if (l_need_retry) {
2072 printk("sdio enum retry.\n");
2073 l_need_retry = 0;
2074 hi_wlan_power_set(1);
2075 goto detect_retry;
2076 }
2077 goto failed_sdio_enum;
2078 }
2079 return HI_SUCCESS;
2080
2081 failed_sdio_enum:
2082 hi_wlan_power_set(0);
2083 return -OAL_EFAIL;
2084 }
2085
oal_sdio_func_remove(struct BusDev * bus)2086 hi_void oal_sdio_func_remove(struct BusDev *bus)
2087 {
2088 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
2089 hi_unref_param(hi_sdio);
2090 oal_wake_lock_exit(&hi_sdio->st_sdio_wakelock);
2091 oal_sdio_dev_deinit(bus);
2092 oal_sdio_free(hi_sdio);
2093 oal_sema_destroy(&g_chan_wake_sema);
2094
2095 printk("hisilicon connectivity sdio driver has been removed.");
2096 }
2097
oal_sdio_credit_info_init(oal_channel_stru * hi_sdio)2098 static hi_void oal_sdio_credit_info_init(oal_channel_stru *hi_sdio)
2099 {
2100 hi_sdio->sdio_credit_info.large_free_cnt = 0;
2101 hi_sdio->sdio_credit_info.short_free_cnt = 0;
2102 oal_spin_lock_init(&hi_sdio->sdio_credit_info.credit_lock);
2103 }
2104
oal_sdio_init_module(struct BusDev * bus,hi_void * data)2105 oal_channel_stru *oal_sdio_init_module(struct BusDev *bus, hi_void *data)
2106 {
2107 #ifdef CONFIG_HISDIO_H2D_SCATT_LIST_ASSEMBLE
2108 hi_u32 tx_scatt_buff_len = 0;
2109 #endif
2110 hi_u32 ul_rx_seg_size;
2111 hi_void *p_sdio = NULL;
2112 oal_channel_stru *hi_sdio;
2113
2114 oam_info_log0(0, OAM_SF_ANY, "{hii110x sdio driver installing...!}");
2115 hi_sdio = (oal_channel_stru *)oal_memalloc(sizeof(oal_channel_stru));
2116 if (hi_sdio == HI_NULL) {
2117 printk("[E]alloc oal_sdio failed [%d]\n", (hi_s32)sizeof(oal_channel_stru));
2118 return HI_NULL;
2119 }
2120 p_sdio = hi_sdio;
2121 memset_s(p_sdio, sizeof(oal_channel_stru), 0, sizeof(oal_channel_stru));
2122
2123 #ifdef CONFIG_SDIO_FUNC_EXTEND
2124 g_sdio_extend_func = 1;
2125 #else
2126 g_sdio_extend_func = 0;
2127 #endif
2128
2129 ul_rx_seg_size = ALIGN((HSDIO_HOST2DEV_PKTS_MAX_LEN), HISDIO_BLOCK_SIZE);
2130 /* alloc rx reserved mem */
2131 hi_sdio->rx_reserved_buff = (hi_void *)oal_memalloc(ul_rx_seg_size);
2132 if (hi_sdio->rx_reserved_buff == HI_NULL) {
2133 printk("[E]alloc rx_reserved_buff failed [%u]\n", ul_rx_seg_size);
2134 goto failed_rx_reserved_buff_alloc;
2135 }
2136 hi_sdio->rx_reserved_buff_len = ul_rx_seg_size;
2137 oam_info_log1(0, OAM_SF_ANY, "{alloc %u bytes rx_reserved_buff!}", ul_rx_seg_size);
2138
2139 hi_sdio->func1_int_mask = HISDIO_FUNC1_INT_MASK;
2140
2141 oal_sdio_credit_info_init(hi_sdio);
2142
2143 hi_sdio->sdio_extend = (hisdio_extend_func *)oal_memalloc(sizeof(hisdio_extend_func));
2144 if (hi_sdio->sdio_extend == HI_NULL) {
2145 printk("[E]alloc sdio_extend failed [%d]\n", (hi_s32)sizeof(hisdio_extend_func));
2146 goto failed_sdio_extend_alloc;
2147 }
2148 memset_s(hi_sdio->sdio_extend, sizeof(hisdio_extend_func), 0, sizeof(hisdio_extend_func));
2149 hi_sdio->bus_data = data;
2150 hi_sdio->scatt_info[SDIO_READ].max_scatt_num = HISDIO_DEV2HOST_SCATT_MAX + 1;
2151
2152 hi_sdio->scatt_info[SDIO_READ].sglist =
2153 oal_kzalloc(sizeof(struct scatterlist) * (HISDIO_DEV2HOST_SCATT_MAX + 1), OAL_GFP_KERNEL);
2154 if (hi_sdio->scatt_info[SDIO_READ].sglist == HI_NULL) {
2155 goto failed_sdio_read_sg_alloc;
2156 }
2157
2158 /* 1 for algin buff, 1 for scatt info buff */
2159 hi_sdio->scatt_info[SDIO_WRITE].max_scatt_num = HISDIO_HOST2DEV_SCATT_MAX + 2; /* add 2 */
2160 hi_sdio->scatt_info[SDIO_WRITE].sglist =
2161 oal_kzalloc(sizeof(struct scatterlist) * (hi_sdio->scatt_info[SDIO_WRITE].max_scatt_num), OAL_GFP_KERNEL);
2162 if (hi_sdio->scatt_info[SDIO_WRITE].sglist == HI_NULL) {
2163 goto failed_sdio_write_sg_alloc;
2164 }
2165
2166 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
2167 hi_sdio->sdio_align_buff = memalign(CACHE_ALIGNED_SIZE, SKB_DATA_ALIGN(HISDIO_BLOCK_SIZE));
2168 #else
2169 hi_sdio->sdio_align_buff = oal_kzalloc(HISDIO_BLOCK_SIZE, OAL_GFP_KERNEL);
2170 #endif
2171 if (hi_sdio->sdio_align_buff == HI_NULL) {
2172 goto failed_sdio_align_buff_alloc;
2173 }
2174 #ifdef CONFIG_HISDIO_H2D_SCATT_LIST_ASSEMBLE
2175 tx_scatt_buff_len = HISDIO_HOST2DEV_SCATT_SIZE + HISDIO_HOST2DEV_SCATT_MAX *
2176 (HCC_HDR_TOTAL_LEN + oal_round_up(HSDIO_HOST2DEV_PKTS_MAX_LEN, HISDIO_H2D_SCATT_BUFFLEN_ALIGN));
2177 tx_scatt_buff_len = HISDIO_ALIGN_4_OR_BLK(tx_scatt_buff_len);
2178
2179 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
2180 tx_scatt_buff_len = SKB_DATA_ALIGN(tx_scatt_buff_len);
2181 hi_sdio->scatt_buff.buff = memalign(CACHE_ALIGNED_SIZE, tx_scatt_buff_len);
2182 #else
2183 hi_sdio->scatt_buff.buff = oal_memalloc(tx_scatt_buff_len);
2184 #endif
2185
2186 if (hi_sdio->scatt_buff.buff == HI_NULL) {
2187 printk("alloc scatt_buff failed,request %u bytes\n", tx_scatt_buff_len);
2188 goto failed_sdio_scatt_buff_alloc;
2189 }
2190 hi_sdio->scatt_buff.len = tx_scatt_buff_len;
2191
2192 printk("alloc scatt_buff ok,request %u bytes\n", tx_scatt_buff_len);
2193 #endif
2194 bus->priData.data = (void *)hi_sdio;
2195 hi_s32 ret = oal_sdio_message_register(bus, D2H_MSG_DEVICE_PANIC, oal_device_panic_callback, HI_NULL);
2196 if (ret != HI_SUCCESS) {
2197 printk("oal_sdio_message_register fail\n");
2198 }
2199 g_bus = bus;
2200 return hi_sdio;
2201
2202 #ifdef CONFIG_HISDIO_H2D_SCATT_LIST_ASSEMBLE
2203 failed_sdio_scatt_buff_alloc:
2204 oal_free(hi_sdio->sdio_align_buff);
2205 #endif
2206 failed_sdio_align_buff_alloc:
2207 oal_free(hi_sdio->scatt_info[SDIO_WRITE].sglist);
2208 failed_sdio_write_sg_alloc:
2209 oal_free(hi_sdio->scatt_info[SDIO_READ].sglist);
2210 failed_sdio_read_sg_alloc:
2211 oal_free(hi_sdio->sdio_extend);
2212 failed_sdio_extend_alloc:
2213 oal_free(hi_sdio->rx_reserved_buff);
2214 failed_rx_reserved_buff_alloc:
2215 oal_free(hi_sdio);
2216 return HI_NULL;
2217 }
2218 EXPORT_SYMBOL(oal_sdio_init_module);
2219
oal_sdio_exit_module(void * data)2220 hi_s32 oal_sdio_exit_module(void *data)
2221 {
2222 printk("sdio module unregistered\n");
2223 oal_channel_stru *hi_sdio = (oal_channel_stru *)data;
2224 #ifdef CONFIG_HISDIO_H2D_SCATT_LIST_ASSEMBLE
2225 oal_free(hi_sdio->scatt_buff.buff);
2226 #endif
2227 oal_free(hi_sdio->sdio_align_buff);
2228 oal_free(hi_sdio->scatt_info[SDIO_WRITE].sglist);
2229 oal_free(hi_sdio->scatt_info[SDIO_READ].sglist);
2230 oal_free(hi_sdio->sdio_extend);
2231 oal_free(hi_sdio->rx_reserved_buff);
2232 oal_free(hi_sdio);
2233 hi_sdio = NULL;
2234 g_bus = NULL;
2235 return HI_SUCCESS;
2236 }
2237 EXPORT_SYMBOL(oal_sdio_exit_module);
2238
oal_sdio_func_max_req_size(struct BusDev * bus)2239 hi_u32 oal_sdio_func_max_req_size(struct BusDev *bus)
2240 {
2241 hi_u32 max_blocks;
2242 hi_u32 size, size_device;
2243 hi_u32 size_host;
2244 hi_s32 ret;
2245 oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
2246 struct BusConfig busCfg = {0};
2247
2248 /* host transer limit */
2249 /* Blocks per command is limited by host count, host transfer
2250 * size and the maximum for IO_RW_EXTENDED of 511 blocks. */
2251 if (hi_sdio == HI_NULL) {
2252 printk("oal_sdio_func_max_req_size:hi_sdio is null!\n");
2253 return -OAL_EFAIL;
2254 }
2255 busCfg.busType = BUS_SDIO;
2256 ret = bus->ops.getBusInfo(bus, &busCfg);
2257 if (ret != 0) {
2258 printk("get bus info failed!\n");
2259 return -OAL_EFAIL;
2260 }
2261 max_blocks = oal_min(busCfg.busInfo.sdioInfo.maxBlockNum, 511u);
2262 size = max_blocks * HISDIO_BLOCK_SIZE;
2263 size = oal_min(size, busCfg.busInfo.sdioInfo.maxRequestSize);
2264 /* device transer limit,per adma descr limit 32K in bootloader,
2265 and total we have 20 descs */
2266 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
2267 size_device = (32 * 1024); /* size device 32*1024 */
2268 #else
2269 size_device = (32 * 1024) * 20; /* size device 32*1024*20 */
2270 #endif
2271
2272 #ifdef HOST_SDIO_MAX_TRANSFER_SIZE
2273 size_host = HOST_SDIO_MAX_TRANSFER_SIZE;
2274 #else
2275 size_host = 0xffffffff;
2276 #endif
2277 size = oal_min(size, size_device);
2278 size = oal_min(size, size_host);
2279 return size;
2280 }
2281
oal_sdio_transfer_prepare(struct BusDev * bus)2282 hi_s32 oal_sdio_transfer_prepare(struct BusDev *bus)
2283 {
2284 oal_enable_sdio_state(bus, OAL_SDIO_ALL);
2285 #ifdef _PRE_FEATURE_NO_GPIO
2286 if (oal_register_sdio_intr(bus) < 0) {
2287 printk("failed to register sdio interrupt\n");
2288 return -OAL_EFAIL;
2289 }
2290 #else
2291 oal_wlan_gpio_intr_enable(bus, HI_TRUE);
2292 #endif
2293 return HI_SUCCESS;
2294 }
2295 #endif /* #ifdef CONFIG_MMC */
2296
oal_netbuf_list_hex_dump(const oal_netbuf_head_stru * head)2297 hi_void oal_netbuf_list_hex_dump(const oal_netbuf_head_stru *head)
2298 {
2299 #ifdef CONFIG_PRINTK
2300 hi_s32 index = 0;
2301 oal_netbuf_stru *netbuf = HI_NULL;
2302 oal_netbuf_stru *tmp = HI_NULL;
2303 if (!oal_netbuf_queue_num(head)) {
2304 return;
2305 }
2306 printk(KERN_DEBUG "prepare to dump %d pkts=========\n", oal_netbuf_queue_num(head));
2307 oal_skb_queue_walk_safe(head, netbuf, tmp) {
2308 index++;
2309 printk(KERN_DEBUG "======netbuf pkts %d, len:%d=========\n", index, oal_netbuf_len(netbuf));
2310 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
2311 print_hex_dump_bytes("netbuf :", DUMP_PREFIX_ADDRESS, oal_netbuf_data(netbuf), oal_netbuf_len(netbuf));
2312 #endif
2313 }
2314 #else
2315 OAL_REFERENCE(head);
2316 #endif
2317 }
2318
oal_netbuf_hex_dump(const oal_netbuf_stru * netbuf)2319 hi_void oal_netbuf_hex_dump(const oal_netbuf_stru *netbuf)
2320 {
2321 #ifdef CONFIG_PRINTK
2322 printk(KERN_DEBUG "==prepare to netbuf,%p,len:%d=========\n", oal_netbuf_data(netbuf), oal_netbuf_len(netbuf));
2323 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
2324 print_hex_dump_bytes("netbuf :", DUMP_PREFIX_ADDRESS, oal_netbuf_data(netbuf), oal_netbuf_len(netbuf));
2325 #endif
2326 #else
2327 OAL_REFERENCE(netbuf);
2328 #endif
2329 }
2330
oal_sdio_get_large_pkt_free_cnt(oal_channel_stru * hi_sdio)2331 hi_u32 oal_sdio_get_large_pkt_free_cnt(oal_channel_stru *hi_sdio)
2332 {
2333 hi_u32 free_cnt;
2334
2335 if (hi_sdio == HI_NULL) {
2336 return -OAL_EFAIL;
2337 }
2338 oal_spin_lock(&hi_sdio->sdio_credit_info.credit_lock);
2339 free_cnt = (hi_u32)hi_sdio->sdio_credit_info.large_free_cnt;
2340 oal_spin_unlock(&hi_sdio->sdio_credit_info.credit_lock);
2341 return free_cnt;
2342 }
2343
2344 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
sdio_dev_init(struct BusDev * bus)2345 hi_s32 sdio_dev_init(struct BusDev *bus)
2346 {
2347 hi_s32 ret;
2348 hi_u32 data;
2349 oal_channel_stru *pstSdio = (oal_channel_stru *)bus->priData.data;
2350 if (pstSdio == HI_NULL || pstSdio->func == HI_NULL) {
2351 printk("sdio handler is NULL or func is NULL!\n");
2352 return -OAL_EFAIL;
2353 }
2354 bus->ops.claimHost(bus);
2355
2356 /* before enable sdio function 1, clear its interrupt flag, no matter it exist or not */
2357 /* if clear the interrupt, host can't receive dev wake up ok ack. debug by 1131c */
2358 /*
2359 * enable four interrupt sources in function 1:
2360 * data ready for host to read
2361 * read data error
2362 * message from arm is available
2363 * device has receive message from host
2364 * */
2365 data = HISDIO_FUNC1_INT_MASK;
2366 ret = bus->ops.writeData(bus, HISDIO_REG_FUNC1_INT_ENABLE, ONE_BYTE, (hi_u8 *)&data);
2367 if (ret < 0) {
2368 oam_info_log1(0, OAM_SF_ANY, "{failed to enable sdio interrupt! ret=%d}", ret);
2369 }
2370 oal_enable_sdio_state(bus, OAL_SDIO_ALL);
2371 bus->ops.releaseHost(bus);
2372
2373 oam_info_log1(0, OAM_SF_ANY, "{sdio function %d enabled.}", pstSdio->func->num);
2374 return ret;
2375 }
2376 #endif
2377
2378 #ifdef __cplusplus
2379 #if __cplusplus
2380 }
2381 #endif
2382 #endif
2383