• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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