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