• 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 #ifndef __OAL_SDIO_HOST_IF_H__
20 #define __OAL_SDIO_HOST_IF_H__
21 
22 /* ****************************************************************************
23   1 外部头文件
24 **************************************************************************** */
25 #include "oal_util.h"
26 #include "oal_net.h"
27 #include "oal_sdio_comm.h"
28 #include "oal_wakelock.h"
29 #include "oal_workqueue.h"
30 #include "oal_semaphore.h"
31 #include "oal_schedule.h"
32 #include "oal_thread.h"
33 #include "oal_sdio_if.h"
34 #include "oal_spinlock.h"
35 
36 #ifdef __cplusplus
37 #if __cplusplus
38 extern "C" {
39 #endif
40 #endif
41 
42 /* ****************************************************************************
43   2 宏定义
44 **************************************************************************** */
45 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
46 #define MODULE_DEVICE_TABLE(a, b)
47 #endif
48 
49 /* 0x30~0x38, 0x3c~7B */
50 #define HISDIO_EXTEND_BASE_ADDR     0x30
51 #define HISDIO_EXTEND_CREDIT_ADDR   0x3c
52 #define HISDIO_EXTEND_REG_COUNT     64
53 
54 #define HISDIO_ALIGN_4_OR_BLK(len)  ((len) < HISDIO_BLOCK_SIZE ? ALIGN((len), 4) : ALIGN((len), HISDIO_BLOCK_SIZE))
55 
56 #define HISDIO_WAKEUP_DEV_REG       0xf0
57 #define ALLOW_TO_SLEEP_VALUE        1
58 #define DISALLOW_TO_SLEEP_VALUE     0
59 
60 #define OAL_SDIO_TX                 (1<<0)
61 #define OAL_SDIO_RX                 (1<<1)
62 #define OAL_SDIO_ALL                (OAL_SDIO_TX | OAL_SDIO_RX)
63 
64 #define ONE_BYTE 1
65 #define FOUR_BYTE 4
66 /* ****************************************************************************
67   3 枚举 结构体定义
68 **************************************************************************** */
69 enum {
70     SDIO_READ = 0,
71     SDIO_WRITE,
72     SDIO_OPT_BUTT
73 };
74 
75 typedef hi_s32(*sdio_msg_rx)(hi_void *data);
76 typedef hi_s32(*hisdio_rx)(hi_void *data);
77 typedef struct _sdio_bus_ops_ {
78     hisdio_rx rx;
79 } sdio_bus_ops;
80 
81 typedef struct {
82     hi_u32 max_scatt_num;
83     struct scatterlist *sglist;
84 } sdio_scatt_stru;
85 
86 typedef struct {
87     sdio_msg_rx msg_rx;
88     void *data;
89     hi_u32 count;
90     hi_u64 cpu_time; /* the time of the last come! */
91 } sdio_msg_stru;
92 
93 typedef struct {
94     hi_u32 int_stat;
95     hi_u32 msg_stat;
96     hi_u32 xfer_count;
97     hi_u32 credit_info;
98     hi_u8 comm_reg[HISDIO_EXTEND_REG_COUNT];
99 } hisdio_extend_func;
100 
101 typedef struct {
102     hi_u8 short_free_cnt;
103     hi_u8 large_free_cnt;
104     oal_spin_lock_stru credit_lock;
105 } hsdio_credit_info;
106 
107 typedef struct {
108     hi_u32 func1_err_reg_info;
109     hi_u32 func1_err_int_count;
110     hi_u32 func1_ack_int_acount;
111     hi_u32 func1_msg_int_count;
112     hi_u32 func1_data_int_count;
113     hi_u32 func1_unknow_int_count;
114     hi_u32 func1_no_int_count;
115 } hsdio_func1_info;
116 
117 typedef struct {
118     hi_u32 rx_scatt_info_not_match;
119 } hsdio_error_info;
120 
121 typedef struct _wlan_pm_callback {
122     unsigned long (*wlan_pm_wakeup_dev)(hi_void); /* SDIO发包过程中中PM状态检查,如果是睡眠状态,同时唤醒 */
123     unsigned long (*wlan_pm_state_get)(hi_void);   /* 获取当前PM状态 */
124     unsigned long (*wlan_pm_wakeup_host)(hi_void); /* device唤醒host中断处理 */
125     hi_void (*wlan_pm_feed_wdg)(hi_void);          /* PM Sleep watch dog喂狗接口 */
126     hi_void (*wlan_pm_wakeup_dev_ack)(hi_void);    /* 唤醒device的ACK 中断处理 */
127 } wlan_pm_callback_stru;
128 
129 typedef struct {
130     /* record the tx scatt list assembled buffer */
131     hi_void *buff;
132     hi_u32   len;
133 } hsdio_tx_scatt_buff;
134 
135 typedef struct {
136     /* sdio work state, sleep , work or shutdown */
137     hi_u32                  state;
138 
139     oal_spin_lock_stru      st_pm_state_lock;       /* pm state互斥锁,pm和gpio中断都用到 */
140     wlan_pm_callback_stru  *pst_pm_callback;
141 
142     oal_spin_lock_stru      st_irq_lock;            /* wlan gpio中断操作锁 */
143     unsigned long           ul_wlan_irq ;           /* wlan gpio中断 */
144     oal_wakelock_stru       st_sdio_wakelock;
145 
146 #ifdef CONFIG_MMC
147     struct sdio_func       *func;
148 #endif
149     oal_mutex_stru          rx_transfer_lock;
150     /* used to sg list sdio block align */
151     hi_u8                  *sdio_align_buff;
152 
153     hi_u64                  sdio_int_count;
154     hi_u64                  gpio_int_count;
155     hi_u64                  data_int_count;
156     hi_u64                  data_int_finish_count;
157     hi_u64                  wakeup_int_count;
158     hi_u32                  ul_sdio_suspend;
159     hi_u32                  ul_sdio_resume;
160     oal_kthread_stru       *gpio_rx_tsk;
161 
162     /* used to process the sdio int */
163     oal_semaphore_stru      gpio_rx_sema;
164 
165     hi_void                *bus_data;
166     sdio_bus_ops            bus_ops;
167     hisdio_rx               credit_update_cb;
168 
169     sdio_scatt_stru         scatt_info[SDIO_OPT_BUTT];
170 
171     sdio_msg_stru           msg[D2H_MSG_COUNT];
172     hi_u32                  last_msg;
173 
174     /* This is get from sdio , must alloc for dma,
175        the extend area only can access by CMD53 */
176     hisdio_extend_func     *sdio_extend;
177     hsdio_credit_info       sdio_credit_info;
178     hi_u32                  func1_int_mask;
179     hsdio_func1_info        func1_stat;
180     hsdio_error_info        error_stat;
181 
182     hsdio_tx_scatt_buff     scatt_buff;
183     hi_void                *rx_reserved_buff;   /* use the mem when rx alloc mem failed! */
184     hi_u32                  rx_reserved_buff_len;
185 
186     hi_u32                  ul_last_step_time[10];  /* array len 10 */
187 } oal_channel_stru;
188 
189 struct sdio_scatt {
190     hi_u32 max_scatt_num;
191     struct scatterlist *sglist;
192 };
193 
194 extern oal_semaphore_stru g_chan_wake_sema;
195 
196 /* ****************************************************************************
197   4 外部函数声明
198 **************************************************************************** */
199 hi_s32 oal_sdio_get_credit(struct BusDev *bus, hi_u32 *uc_priority_cnt);
200 hi_u32 oal_sdio_get_large_pkt_free_cnt(oal_channel_stru *hi_sdio);
201 hi_void oal_netbuf_list_hex_dump(const oal_netbuf_head_stru *head);
202 hi_void oal_netbuf_hex_dump(const oal_netbuf_stru *netbuf);
203 #ifdef CONFIG_MMC
204 hi_s32 oal_sdio_get_state(const oal_channel_stru *hi_sdio, hi_u32 mask);
205 hi_void oal_enable_sdio_state(struct BusDev *bus, hi_u32 mask);
206 hi_void oal_disable_sdio_state(struct BusDev *bus, hi_u32 mask);
207 hi_void oal_sdio_info_show(oal_channel_stru *hi_sdio);
208 hi_void oal_netbuf_list_hex_dump(const oal_netbuf_head_stru *head);
209 hi_void oal_netbuf_hex_dump(const oal_netbuf_stru *netbuf);
210 hi_s32 oal_sdio_build_rx_netbuf_list(struct BusDev *bus, oal_netbuf_head_stru    *head);
211 hi_void oal_gpio_intr_enable(oal_channel_stru *hi_sdio, hi_char enable);
212 hi_s32 oal_sdio_func_init(struct BusDev *bus);
213 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
214 hi_s32 oal_sdio_func_probe_resume(struct BusDev *bus);
215 #endif
216 hi_s32 oal_sdio_func_reset(void);
217 hi_void oal_sdio_func_remove(struct BusDev *bus);
218 hi_s32 oal_sdio_message_register(struct BusDev *bus, hi_u8 msg, sdio_msg_rx cb, hi_void *data);
219 hi_void oal_sdio_message_unregister(struct BusDev *bus, hi_u8 msg);
220 hi_s32 oal_sdio_transfer_rx_register(struct BusDev *bus, hisdio_rx rx);
221 hi_void  oal_sdio_credit_update_cb_register(oal_channel_stru *hi_sdio, hisdio_rx cb);
222 hi_void oal_sdio_transfer_rx_unregister(struct BusDev *bus);
223 extern hi_s32 oal_sdio_transfer_tx(struct BusDev *bus, oal_netbuf_stru *netbuf);
224 hi_s32 oal_sdio_transfer_netbuf_list(struct BusDev *bus, const oal_netbuf_head_stru *head, hi_s32 rw);
225 extern oal_channel_stru  *oal_sdio_init_module(struct BusDev *bus, hi_void *data);
226 extern hi_s32  oal_sdio_exit_module(void *data);
227 hi_s32 oal_sdio_send_msg(struct BusDev *bus, unsigned long val);
228 extern struct BusDev *oal_get_sdio_default_handler(hi_void);
229 extern unsigned long oal_sdio_get_sleep_state(struct BusDev *bus);
230 extern hi_void oal_sdio_get_dev_pm_state(struct BusDev *bus, unsigned long *pst_ul_f1,
231     unsigned long *pst_ul_f2, unsigned long *pst_ul_f3, unsigned long *pst_ul_f4);
232 extern hi_s32 oal_sdio_wakeup_dev(struct BusDev *bus);
233 extern hi_s32 oal_sdio_sleep_dev(struct BusDev *bus);
234 extern void oal_sdio_wake_lock(struct BusDev *bus);
235 extern void oal_sdio_wake_unlock(struct BusDev *bus);
236 extern unsigned long oal_sdio_wakelock_active(oal_channel_stru *pst_hi_sdio);
237 extern hi_void oal_sdio_wakelocks_release_detect(struct BusDev *bus);
238 extern hi_u32 oal_sdio_func_max_req_size(struct BusDev *bus);
239 extern hi_void oal_wlan_gpio_intr_enable(struct BusDev *bus, hi_u32 ul_en);
240 extern hi_s32 oal_sdio_transfer_prepare(struct BusDev *bus);
241 hi_void oal_unregister_sdio_intr(struct BusDev *bus);
242 hi_void oal_sdio_isr(void *func);
243 #endif /* #ifdef CONFIG_MMC */
244 
oal_sdio_claim_host(struct BusDev * bus)245 static inline hi_void oal_sdio_claim_host(struct BusDev *bus)
246 {
247     oal_channel_stru *hi_sdio = NULL;
248 #ifdef CONFIG_MMC
249     hi_sdio = (oal_channel_stru *)bus->priData.data;
250     if (OAL_WARN_ON(hi_sdio == NULL)) {
251         return;
252     }
253     if (OAL_WARN_ON(hi_sdio->func == NULL)) {
254         return;
255     }
256     bus->ops.claimHost(bus);
257 #endif
258 }
259 
oal_sdio_release_host(struct BusDev * bus)260 static inline hi_void oal_sdio_release_host(struct BusDev *bus)
261 {
262     oal_channel_stru *hi_sdio = NULL;
263 #ifdef CONFIG_MMC
264     hi_sdio = (oal_channel_stru *)bus->priData.data;
265     if (OAL_WARN_ON(hi_sdio == NULL)) {
266         return;
267     }
268     if (OAL_WARN_ON(hi_sdio->func == NULL)) {
269         return;
270     }
271     bus->ops.releaseHost(bus);
272 #endif
273 }
274 
oal_sdio_rx_transfer_lock(struct BusDev * bus)275 static inline hi_void oal_sdio_rx_transfer_lock(struct BusDev *bus)
276 {
277     oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
278     /* wakelock modified */
279     hi_unref_param(hi_sdio);
280 }
281 
oal_sdio_rx_transfer_unlock(struct BusDev * bus)282 static inline hi_void oal_sdio_rx_transfer_unlock(struct BusDev *bus)
283 {
284     oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
285     /* wakelock modified */
286     hi_unref_param(hi_sdio);
287 }
288 
oal_sdio_func1_int_mask(struct BusDev * bus,hi_u32 func1_int_mask)289 static inline hi_void oal_sdio_func1_int_mask(struct BusDev *bus, hi_u32 func1_int_mask)
290 {
291     oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
292     if (OAL_WARN_ON(hi_sdio == NULL)) {
293         return;
294     }
295     oal_sdio_claim_host(bus);
296     hi_sdio->func1_int_mask &= ~func1_int_mask;
297     oal_sdio_release_host(bus);
298 }
299 
oal_sdio_func1_int_unmask(struct BusDev * bus,hi_u32 func1_int_mask)300 static inline hi_void oal_sdio_func1_int_unmask(struct BusDev *bus, hi_u32 func1_int_mask)
301 {
302     oal_channel_stru *hi_sdio = (oal_channel_stru *)bus->priData.data;
303     if (OAL_WARN_ON(hi_sdio == NULL)) {
304         return;
305     }
306     oal_sdio_claim_host(bus);
307     hi_sdio->func1_int_mask |= func1_int_mask;
308     oal_sdio_release_host(bus);
309 }
310 
311 /* ****************************************************************************
312  函 数 名  : oal_sdio_wake_lock
313  功能描述  : 获取wifi wakelock锁
314  输入参数  : 无
315  输出参数  : 无
316  返 回 值  : 成功或失败原因
317  调用函数  : 无
318  被调函数  : 无
319 
320  修改历史      :
321   1.日    期   : 2015年5月20日
322     作    者   : HiSilicon
323     修改内容   : 新生成函数
324 
325 **************************************************************************** */
326 #define oal_sdio_wake_lock(bus) oal_wake_lock(&((oal_channel_stru *)(bus->priData.data))->st_sdio_wakelock)
327 
328 /* ****************************************************************************
329  函 数 名  : oal_sdio_wake_unlock
330  功能描述  : 释放wifi wakelock锁
331  输入参数  : 无
332  输出参数  : 无
333  返 回 值  : 成功或失败原因
334  调用函数  : 无
335  被调函数  : 无
336 
337  修改历史      :
338   1.日    期   : 2015年5月20日
339     作    者   : HiSilicon
340     修改内容   : 新生成函数
341 
342 **************************************************************************** */
343 #define oal_sdio_wake_unlock(bus) oal_wake_unlock(&((oal_channel_stru *)bus->priData.data)->st_sdio_wakelock)
344 
345 /* ****************************************************************************
346  函 数 名  : wlan_pm_wakelock_active
347  功能描述  : 判断 wifi wakelock锁是否active
348  输入参数  : 无
349  输出参数  : 无
350  返 回 值  : 成功或失败原因
351  调用函数  : 无
352  被调函数  : 无
353 
354  修改历史      :
355   1.日    期   : 2015年5月20日
356     作    者   : HiSilicon
357     修改内容   : 新生成函数
358 
359 **************************************************************************** */
360 #define oal_sdio_wakelock_active(pst_hi_sdio) oal_wakelock_active(&(pst_hi_sdio)->st_sdio_wakelock)
361 
362 #ifdef __cplusplus
363 #if __cplusplus
364 }
365 #endif
366 #endif
367 
368 #endif
369