1 /******************************************************************************
2  * Copyright (c) 2013-2016 Realtek Semiconductor Corp.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 #ifndef __OSDEP_SERVICE_H_
18 #define __OSDEP_SERVICE_H_
19 
20 /** @addtogroup RTOS
21  *  @{
22  */
23 
24 /*************************** OS dep feature enable *******************************/
25 
26 /******************************************************
27  *                    Macros
28  ******************************************************/
29 #define CONFIG_LITTLE_ENDIAN
30 
31 #if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) || defined(CONFIG_PLATFORM_8721D)
32 #ifndef CONFIG_PLATFORM_AMEBA_X
33 #define CONFIG_PLATFORM_AMEBA_X    1
34 #endif
35 #endif
36 
37 #if defined(CONFIG_PLATFORM_8195A)
38 	#define CONFIG_USE_TCM_HEAP 1					/* USE TCM HEAP */
39 	#define USE_MUTEX_FOR_SPINLOCK	1
40 #endif
41 
42 #if defined(CONFIG_PLATFORM_AMEBA_X)
43 	#define CONFIG_MEM_MONITOR	MEM_MONITOR_SIMPLE
44 #else
45 	#define CONFIG_MEM_MONITOR	MEM_MONITOR_LEAK
46 #endif
47 
48 /* Define compilor specific symbol */
49 
50 /*************************** inline functions *******************************/
51 #if defined ( __ICCARM__ )
52 #define __inline__                      inline
53 #define __inline                        inline
54 #define __inline_definition			//In dialect C99, inline means that a function's definition is provided
55 								//only for inlining, and that there is another definition
56 								//(without inline) somewhere else in the program.
57 								//That means that this program is incomplete, because if
58 								//add isn't inlined (for example, when compiling without optimization),
59 								//then main will have an unresolved reference to that other definition.
60 
61 								// Do not inline function is the function body is defined .c file and this
62 								// function will be called somewhere else, otherwise there is compile error
63 #elif defined ( __CC_ARM   )
64 #define __inline__			__inline	//__linine__ is not supported in keil compilor, use __inline instead
65 #define inline				__inline
66 #define __inline_definition			// for dialect C99
67 #elif defined   (  __GNUC__  )
68 #define __inline__                      inline
69 #define __inline                        inline
70 #define __inline_definition	inline
71 #endif
72 
73 #include <stdio.h>
74 #if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) || defined(CONFIG_PLATFORM_8721D)
75 #include "platform_autoconf.h"
76 #else //for 8189FM/8189FTV  add by frankie_li 20160408
77 #ifndef SUCCESS
78 #define SUCCESS	0
79 #endif
80 #ifndef FAIL
81 #define FAIL	(-1)
82 #endif
83 #ifndef _SUCCESS
84 #define _SUCCESS	1
85 #endif
86 #ifndef _FAIL
87 #define _FAIL	0
88 #endif
89 #ifndef FALSE
90     #define FALSE   0
91 #endif
92 
93 #ifndef TRUE
94     #define TRUE    (!FALSE)
95 #endif
96 
97 #define _TRUE        TRUE
98 #define _FALSE	     FALSE
99 
100 #endif
101 #if defined( PLATFORM_FREERTOS)
102 #include "freertos_service.h"
103 #elif defined( PLATFORM_ECOS)
104 #include "ecos/ecos_service.h"
105 #elif defined( PLATFORM_ALIOS)
106 #include "aos_osdep.h"
107 #endif
108 
109 #ifndef pdTRUE
110 #define pdTRUE		( 1 )
111 #endif
112 #ifndef pdFALSE
113 #define pdFALSE		( 0 )
114 #endif
115 
116 #ifndef pdPASS
117 #define pdPASS									( 1 )
118 #endif
119 #ifndef pdFAIL
120 #define pdFAIL									( 0 )
121 #endif
122 
123 #define RTW_MAX_DELAY			0xFFFFFFFF
124 #define RTW_WAIT_FOREVER		0xFFFFFFFF
125 
126 /******************************************************
127  *                    Constants
128  ******************************************************/
129 /**
130   * @brief  Definitions returned by xTaskGetSchedulerState().
131   */
132 
133 #define OS_SCHEDULER_NOT_STARTED	0
134 #define OS_SCHEDULER_RUNNING		1
135 #define OS_SCHEDULER_SUSPENDED		2
136 /******************************************************
137  *                    Structures
138  ******************************************************/
139 struct timer_list {
140 	_timerHandle 	timer_hdl;
141 	unsigned long	data;
142 	void (*function)(void *);
143 };
144 
145 
146 /******************************************************
147  *                 Type Definitions
148  ******************************************************/
149 typedef void* (*thread_func_t)(void*);
150 typedef void (*TIMER_FUN)(void* timer, void *context);
151 typedef int (*event_handler_t)(char *buf, int buf_len, int flags, void *user_data);
152 
153 #define CONFIG_THREAD_COMM_SEMA
154 struct task_struct {
155 	const char *task_name;
156 	aos_task_t task;	/* I: workqueue thread */
157 
158 #ifdef CONFIG_THREAD_COMM_SIGNAL
159 	const char *name;	/* I: workqueue thread name */
160 	u32 queue_num;		/* total signal num */
161 	u32 cur_queue_num;	/* cur signal num should < queue_num */
162 #elif defined(CONFIG_THREAD_COMM_SEMA)
163 	_sema wakeup_sema;
164 	_sema terminate_sema;
165 //	_queue work_queue;  //TODO
166 #endif
167 	u32 blocked;
168 	u32 callback_running;
169 };
170 
171 typedef struct {
172 	_xqueue event_queue;
173 	struct task_struct thread;
174 }rtw_worker_thread_t;
175 
176 typedef struct
177 {
178 	event_handler_t function;
179 	char *buf;
180 	int buf_len;
181 	int flags;
182 	void *user_data;
183 } rtw_event_message_t;
184 
185 struct worker_timer_entry {
186 	struct list_head 	list;
187 	_timerHandle 		timer_hdl;
188 	rtw_event_message_t	message;
189 	rtw_worker_thread_t	*worker_thread;
190 	u32 				timeout;
191 };
192 
193 #ifdef CONFIG_THREAD_COMM_SIGNAL
194 struct work_struct;
195 typedef void (*work_func_t)(void *context);
196 struct work_struct {
197 	_list list;
198 	u32 data;
199 	work_func_t func;
200 	void *context;
201 	struct task_struct *used_wq;
202 };
203 
204 struct delayed_work {
205 	struct work_struct work;
206 	struct timer_list timer;
207 };
208 #endif
209 
210 
211 #ifdef CONFIG_MEM_MONITOR
212 
213 /*************************** Memory Monitor *******************************/
214 #define MEM_MONITOR_SIMPLE		0x1
215 #define MEM_MONITOR_LEAK		0x2
216 
217 #define MEM_MONITOR_FLAG_WIFI_DRV	0x1
218 #define MEM_MONITOR_FLAG_WPAS		0x2
219 #if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
220 struct mem_entry {
221 	struct list_head	list;
222 	int		size;
223 	void	*ptr;
224 };
225 #endif
226 #define ALLOC_CPSR u32 cpsr
227 /**
228  * @brief  This function initializes a memory table.
229  * @param[in] pmem_table: The pointer to the memory table.
230  * @param[in] used_num: The number of mem_entry kept in monitor which will be set to 0.
231  * @return	  None
232  */
233 void init_mem_monitor(_list *pmem_table, int *used_num);
234 
235 /**
236  * @brief  This function deinitializes a memory table.
237  * @param[in] pmem_table: The pointer to the memory table.
238  * @param[in] used_num: The number of mem_entry kept in monitor.
239  * @return	  None
240  */
241 void deinit_mem_monitor(_list *pmem_table, int *used_num);
242 
243 /**
244  * @brief  This function alloc mem_entry to the memory table.
245  * @param[in] pmem_table: The pointer to the memory table to be added.
246  * @param[in] ptr: The pointer to the position to be added.
247  * @param[in] size: The size of added memory.
248  * @param[in] used_num: The number of mem_entry kept in monitor which will add 1 after.
249  * @param[in] flag: MEM_MONITOR_FLAG_WPAS/MEM_MONITOR_FLAG_WIFI_DRV
250  * @return	  None
251  */
252 void add_mem_usage(_list *pmem_table, void *ptr, int size, int *used_num, int flag);
253 
254 /**
255  * @brief  This function frees memory from the memory table.
256  * @param[in] pmem_table: The pointer to the memory table
257  * @param[in] ptr: The pointer to the position to be free.
258  * @param[in] used_num: The number of mem_entry kept in monitor.
259  * @param[in] flag: MEM_MONITOR_FLAG_WPAS/MEM_MONITOR_FLAG_WIFI_DRV
260  * @return	  None
261  */
262 void del_mem_usage(_list *pmem_table, void *ptr, int *used_num, int flag);
263 
264 /**
265  * @brief  This function get the memory usage of a memory table.
266  * @param[in] pmem_table: The pointer to the memory table.
267  * @return	  The size of the memory used
268  */
269 int get_mem_usage(_list *pmem_table);
270 /*************************** End Memory Monitor *******************************/
271 #endif
272 
273 
274 /*************************** Memory Management *******************************/
275 u8*	_rtw_vmalloc(u32 sz);
276 u8*	_rtw_zvmalloc(u32 sz);
277 void	_rtw_vmfree(u8 *pbuf, u32 sz);
278 u8*	_rtw_zmalloc(u32 sz);
279 u8*	_rtw_malloc(u32 sz);
280 void	_rtw_mfree(u8 *pbuf, u32 sz);
281 #ifdef CONFIG_MEM_MONITOR
282 
283 /**
284  * @brief  This function allocates the virtually contiguous memory.
285  * @param[in] sz: The size of memory to be allocated.
286  * @return	  The pointer to the beginning of the memory
287  */
288 u8*	rtw_vmalloc(u32 sz);
289 
290 /**
291  * @brief  This function allocates the virtually contiguous memory
292  *		   and the values of the memory are setted to 0.
293  * @param[in] sz: The size of memory to be allocated.
294  * @return	  The pointer to the beginning of the memory
295  */
296 u8*	rtw_zvmalloc(u32 sz);
297 
298 /**
299  * @brief  This function frees the virtually contiguous memory.
300  * @param[in] pbuf: The pointer to the beginning of the memory to be free
301  * @param[in] sz: The size of memory allocated.
302  * @return	  None
303  */
304 void	rtw_vmfree(u8 *pbuf, u32 sz);
305 
306 /**
307  * @brief  This function allocates the memory
308  *		   and the values of the memory are setted to 0.
309  * @param[in] sz: The size of memory to be allocated.
310  * @return	  The pointer to the beginning of the memory
311  */
312 u8*	rtw_zmalloc(u32 sz);
313 
314 /**
315  * @brief  This function allocates the memory.
316  * @param[in] sz: The size of memory to be allocated.
317  * @return	  The pointer to the beginning of the memory
318  */
319 u8*	rtw_malloc(u32 sz);
320 
321 /**
322  * @brief  This function frees the virtually contiguous memory.
323  * @param[in] pbuf: The pointer to the beginning of the memory to be free
324  * @param[in] sz: The size of memory allocated.
325  * @return	  None
326  */
327 void	rtw_mfree(u8 *pbuf, u32 sz);
328 #else
329 #define	rtw_vmalloc		_rtw_vmalloc
330 #define	rtw_zvmalloc		_rtw_zvmalloc
331 #define	rtw_vmfree  		_rtw_vmfree
332 #define	rtw_zmalloc 		_rtw_zmalloc
333 #define	rtw_malloc  		_rtw_malloc
334 #define	rtw_mfree   		_rtw_mfree
335 #endif
336 #define rtw_free(buf)		rtw_mfree((u8 *)buf, 0)
337 
338 /**
339  * @brief  This function allocates a 2 dimensional array memory.
340  * @param[in] h: The height of the 2D array.
341  * @param[in] w: The width of the 2D array.
342  * @param[in] size: The size of the each charactor in array.
343  * @return	  the pointer to the beginning of the block
344  */
345 void*	rtw_malloc2d(int h, int w, int size);
346 
347 /**
348  * @brief  This function deallocates the block of memory previously allocated to make it available again.
349  * @param[in] pbuf: Pointer to a memory block previously allocated.
350  * @param[in] h: The height of the 2D array.
351  * @param[in] w: The width of the 2D array.
352  * @param[in] size: The size of the each charactor in array.
353  * @return	  None
354  */
355 void	rtw_mfree2d(void *pbuf, int h, int w, int size);
356 
357 /**
358  * @brief  This function copies the values of "sz" bytes from the location pointed to by "src"
359  *         directly to the memory block pointed to by "des".
360  * @param[in] dst: Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.
361  * @param[in] src: Pointer to the source of data to be copied, type-casted to a pointer of type void*.
362  * @param[in] sz: Size of memory to copy.
363  * @return	  None
364  */
365 void	rtw_memcpy(void* dst, void* src, u32 sz);
366 
367 /**
368  * @brief  This function compares the first "sz" bytes of the block of memory pointed by "dst"
369  *		   to the first "sz" bytes pointed by "src".
370  * @param[in] dst: Pointer to block of memory to be compared.
371  * @param[in] src: pointer to block of memory to compare.
372  * @param[in] sz: Size of memory to compare.
373  * @return	<0: The first byte that does not match in both memory blocks has a lower value in dst than in src.
374  * @return	0: The contents of both memory blocks are equal.
375  * @return	<0: The first byte that does not match in both memory blocks has a greater value in dst than in src.
376  */
377 int	rtw_memcmp(void *dst, void *src, u32 sz);
378 
379 /**
380  * @brief  This function sets the first "sz" bytes of the block of memory pointed by "pbuf" to the specified "c".
381  * @param[in] pbuf: Pointer to the block of memory to fill.
382  * @param[in] c: Value to be set.
383  * @param[in] sz: Size of memory to be set to the value "c".
384  * @return	  None
385  */
386 void	rtw_memset(void *pbuf, int c, u32 sz);
387 /*************************** End Memory Management *******************************/
388 
389 /*************************** List *******************************/
390 
391 /**
392  * @brief  This function initializes the head of the list.
393  * @param[in] list: Pointer to the list to be initialized.
394  * @return	  None
395  */
396 void	rtw_init_listhead(_list *list);
397 
398 /**
399  * @brief  This function tests whether a list is empty.
400  * @param[in] phead: Pointer to the list to test.
401  * @return	  _TRUE/_FALSE
402  */
403 u32	rtw_is_list_empty(_list *phead);
404 
405 /**
406  * @brief  This function adds a new entry after "phead" for the list.
407  * @param[in] plist: Pointer to the list to be added.
408  * @param[in] phead: List head to add it after.
409  * @return	  None
410  */
411 void	rtw_list_insert_head(_list *plist, _list *phead);
412 
413 /**
414  * @brief  This function adds a new entry before "phead" for the list.
415  * @param[in] plist: Pointer to the list to be added.
416  * @param[in] phead: List head to add it before.
417  * @return	  None
418  */
419 void	rtw_list_insert_tail(_list *plist, _list *phead);
420 
421 /**
422  * @brief  This function deletes entry from list and reinitialize it.
423  * @param[in] plist: The element to delete from the list.
424  * @return	  None
425  * @note	  Caller must check if the list is empty before calling rtw_list_delete
426  */
427 void	rtw_list_delete(_list *plist);
428 /*************************** End List *******************************/
429 
430 
431 /*************************** Semaphores *******************************/
432 /**
433  * @brief  This function initializes the unnamed semaphore referred to by "sema" to the value "init_val".
434  * @param[in] sema: Pointer to the semaphore handle to be initialized.
435  * @param[in] init_val: Initial value for semaphore.
436  * @return	  None
437  */
438 void	rtw_init_sema(_sema *sema, int init_val);
439 
440 /**
441  * @brief  This function deletes the semaphore.
442  * @param[in] sema: The semaphore to be deleted.
443  * @return	  None
444  */
445 void	rtw_free_sema(_sema *sema);
446 
447 /**
448  * @brief  This function releases the semaphore.
449  *		   This macro must not be used from an ISR.
450  * @param[in] sema: The semaphore to be released.
451  * @return	  None
452  */
453 void	rtw_up_sema(_sema	*sema);
454 
455 /**
456  * @brief  This function releases the semaphore.
457  *		   This macro can be used from an ISR.
458  * @param[in] sema: The semaphore to be released.
459  * @return	  None
460  */
461 void	rtw_up_sema_from_isr(_sema *sema);
462 
463 /**
464  * @brief  This function acquires the semaphore. If no more tasks are allowed to acquire the semaphore,
465  *		   calling this function will put the task to sleep until the semaphore is up.
466  * @param[in] sema: The semaphore to be acquired.
467  * @return	pdTRUE: The semaphore was obtained.
468  * @return	pdFALSE: Obtain the semaphore failed.
469  */
470 u32	rtw_down_sema(_sema *sema);
471 
472 /**
473  * @brief  This function acquires the semaphore. If no more tasks are allowed to acquire the semaphore,
474  *		   calling this function will put the task to sleep until the semaphore is up.
475  * @param[in] sema: The semaphore to be acquired.
476  * @param[in] timeout: The time in ms to wait for the semaphore to become available.
477  * @return	pdTRUE: The semaphore was obtained.
478  * @return	pdFALSE: Timeout without the semaphore becoming available.
479  */
480 u32	rtw_down_timeout_sema(_sema *sema, u32 timeout);
481 /*************************** End Semaphores *******************************/
482 
483 /*************************** Mutexes *******************************/
484 /**
485  * @brief  This function implements a mutex semaphore by using the existing queue mechanism.
486  * @param[in] pmutex: Pointer to the created mutex semaphore.
487  * @return	  None
488  */
489 void	rtw_mutex_init(_mutex *pmutex);
490 
491 /**
492  * @brief  This function deletes the mutex semaphore.
493  * @param[in] pmutex: Pointer to the mutex semaphore to be deleted.
494  * @return	  None
495  */
496 void	rtw_mutex_free(_mutex *pmutex);
497 
498 /**
499  * @brief  This function releases a mutex semaphore.
500  * @param[in] pmutex: Pointer to the mutex semaphore to be released.
501  * @return	  None
502  */
503 void	rtw_mutex_put(_mutex *pmutex);
504 
505 /**
506  * @brief  This function obtains a mutex semaphore.
507  * @param[in] pmutex: Pointer to the mutex semaphore being taken - obtained when
508  *			  the mutex semaphore was created.
509  * @return	  None
510  */
511 void	rtw_mutex_get(_mutex *pmutex);
512 
513 /**
514  * @brief  This function obtains a mutex semaphore with a timeout setting.
515  * @param[in] pmutex: Pointer to the mutex semaphore being taken - obtained when
516  *			  the mutex semaphore was created.
517  * @param[in] timeout: The time in ms to wait for the semaphore to become available.
518  * @return	0: The semaphore was obtained.
519  * @return	-1: Timeout without the semaphore becoming available.
520  */
521 int	rtw_mutex_get_timeout(_mutex *pmutex, u32 timeout_ms);
522 /*************************** End Mutexes *******************************/
523 
524 /*************************** SchedulerControl *******************************/
525 /**
526  * @brief  This function marks the start of a critical code region.
527  * 		   Preemptive context switches cannot occur when in a critical region.
528  * @param[in] plock: Pointer to the spin lock semaphore.
529  * @param[in] pirqL: Pointer to the IRQ.
530  * @return	  None
531  * @note: This may alter the stack (depending on the portable implementation)
532  * so must be used with care!
533  */
534 #if 1
535 void rtw_enter_critical(_lock *plock, _irqL *pirqL);
536 /**
537  * @brief  This function marks end of a critical code region. Preemptive context
538  * switches cannot occur when in a critical region.
539  * @param[in] plock: Pointer to the spin lock semaphore.
540  * @param[in] pirqL: Pointer to the IRQ.
541  * @return	  None
542  * @note: This may alter the stack (depending on the portable implementation)
543  * so must be used with care!
544  */
545 void rtw_exit_critical(_lock *plock, _irqL *pirqL);
546 
547 /**
548  * @brief  This function marks the start of a critical code region from isr.
549  * @param[in] plock: Pointer to the spin lock semaphore.
550  * @param[in] pirqL: Pointer to the IRQ.
551  * @return	  None
552  */
553 void rtw_enter_critical_from_isr(_lock *plock, _irqL *pirqL);
554 
555 /**
556  * @brief  This function marks the end of a critical code region from isr.
557  * @param[in] plock: Pointer to the spin lock semaphore.
558  * @param[in] pirqL: Pointer to the IRQ.
559  * @return	  None
560  */
561 void rtw_exit_critical_from_isr(_lock *plock, _irqL *pirqL);
562 #else
563     #define  rtw_enter_critical(plock,pirqL) {cpsr =cpu_intrpt_save();}
564     #define  rtw_exit_critical(plock,pirqL)   {cpu_intrpt_restore(cpsr);}
565     #define  rtw_enter_critical_from_isr(plock,pirqL) {cpsr =cpu_intrpt_save();}
566     #define  rtw_exit_critical_from_isr(plock,pirqL)   {cpu_intrpt_restore(cpsr);}
567 
568 #endif
569 /**
570  * @brief  This function obtains a spin lock semaphore.
571  * @param[in] plock: Pointer to the spin lock semaphore being taken - obtained when
572  *			  the mutex semaphore was created.
573  * @param[in] pirqL: Pointer to the IRQ.
574  * @return	  None
575  */
576 void	rtw_enter_critical_bh(_lock *plock, _irqL *pirqL);
577 
578 /**
579  * @brief  This function releases a spin lock semaphore.
580  * @param[in] plock: Pointer to the spin lock semaphore to be released.
581  * @param[in] pirqL: Pointer to the IRQ.
582  * @return	  None
583  */
584 void	rtw_exit_critical_bh(_lock *plock, _irqL *pirqL);
585 
586 /**
587  * @brief  This function obtains a semaphore.
588  * @param[in] pmutex: The handle to the mutex semaphore to be obtained.
589  * @param[in] pirqL: Pointer to the IRQ.
590  * @return	  None
591  */
592 int	rtw_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL);
593 
594 /**
595  * @brief  This function releases a semaphore.
596  * @param[in] pmutex: The handle to the mutex semaphore to be released.
597  * @param[in] pirqL: Pointer to the IRQ.
598  * @return	  None
599  */
600 void	rtw_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL);
601 /*************************** End SchedulerControl *******************************/
602 
603 /*************************** Semaphores *******************************/
604 
605 /**
606  * @brief  This function implements a spin lock semaphore by using the existing queue mechanism.
607  * @param[in] plock: Pointer to the created spin lock semaphore.
608  * @return	  None
609  */
610 void	rtw_spinlock_init(_lock *plock);
611 
612 /**
613  * @brief  This function deletes the spin lock semaphore.
614  * @param[in] pmutex: Pointer to the spin lock semaphore to be deleted.
615  * @return	  None
616  */
617 void	rtw_spinlock_free(_lock *plock);
618 
619 /**
620  * @brief  This function obtains a spin lock semaphore.
621  * @param[in] plock: Pointer to the spin lock semaphore being taken - obtained when
622  *			  the mutex semaphore was created.
623  * @return	  None
624  */
625 void	rtw_spin_lock(_lock *plock);
626 
627 /**
628  * @brief  This function releases a spin lock semaphore.
629  * @param[in] plock: Pointer to the spin lock semaphore to be released.
630  * @return	  None
631  */
632 void	rtw_spin_unlock(_lock *plock);
633 
634 /**
635  * @brief  This function marks the start of a critical code region and
636  *		   obtains a spin lock semaphore.
637  * @param[in] plock: Pointer to the spin lock semaphore being taken - obtained when
638  *			  the mutex semaphore was created.
639  * @param[in] irqL: Pointer to the IRQ.
640  * @return	  None
641  */
642 void	rtw_spinlock_irqsave(_lock *plock, _irqL *irqL);
643 
644 /**
645  * @brief  This function releases a spin lock semaphore and
646  		   marks the end of a critical code region.
647  * @param[in] plock: Pointer to the spin lock semaphore to be released.
648  * @param[in] irqL: Pointer to the IRQ.
649  * @return	  None
650  */
651 void	rtw_spinunlock_irqsave(_lock *plock, _irqL *irqL);
652 /*************************** End Semaphores *******************************/
653 
654 /*************************** Queues *******************************/
655 
656 /**
657  * @brief  This function creates a new queue instance.
658  * @param[in] queue: The handle to the newly created queue.
659  * @param[in] name: The name of the queue
660  * @param[in] message_size: The number of bytes each message in the queue will require.
661  * @param[in] number_of_messages: The maximum number of messages that kthe queue can contain.
662  * @return	  0: Creating queue success
663  * @return	  -1: Creating queue fail
664  */
665 int rtw_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages );
666 
667 /**
668  * @brief  This function posts a message to the back of a queue.
669  *		   The message is queued by copy, not by reference.
670  * @param[in] queue: The handle to the queue on which the message is to be posted.
671  * @param[in] message: The pointer to the message that is to be placed on the queue.
672  * @param[in] timeout_ms: The maximum amout of time the task should block waiting for
673  			              the space to become available on the queue, should it already be full.
674  			              The time is defined in ms.
675  * @return	  0: The message was successfully posted.
676  * @return	  -1: The message was not posted.
677  */
678 int rtw_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms );
679 
680 /**
681  * @brief  This function receives a message from a queue.
682  *		   The message is recieved by copy so a buffer adequate size must be provided.
683  * @param[in] queue: The handle to the queue from which the message is to be received.
684  * @param[in] message: The pointer to the buffer into which the received message will be copied.
685  * @param[in] timeout_ms: The maximum amout of time the task should block waiting for a message to
686  *						  receive should the queue be empty at the time of the call.
687  			              The time is defined in ms.
688  * @return	  0: A message was successfully received from the queue.
689  * @return	  -1: No message was received from the queue.
690  */
691 int rtw_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms );
692 
693 /**
694  * @brief  Delete a queue - freeing all the memory allocated for storing of messages placed on the queue.
695  * @param[in] queue: The handle to the queue to be deleted.
696  * @return	  0: The queue was successfully deleted.
697  * @return	  -1: The queue was not empty so cannot be deleted.
698  */
699 int rtw_deinit_xqueue( _xqueue* queue );
700 
701 /**
702  * @brief  This function creates a new queue instance.
703  * @param[in] pqueue: The handle to the newly created queue.
704  * @return	 None
705  */
706 void	rtw_init_queue(_queue	*pqueue);
707 void	rtw_deinit_queue(_queue	*pqueue);
708 u32	rtw_is_queue_empty(_queue *pqueue);
709 
710 /**
711  * @brief  This function tests whether the queue is empty.
712  * @param[in] pqueue: The handle to the queue to be tested.
713  * @return	 None
714  */
715 u32	rtw_queue_empty(_queue	*pqueue);
716 
717 /**
718  * @brief  This function tests whether the "pelement" is at the "queue".
719  * @param[in] queue: The pointer to the queue that to be tested.
720  * @param[in] pelement: The element that to be tested.
721  * @return	 _TRUE/_FALSE
722  */
723 u32	rtw_end_of_queue_search(_list *queue, _list *pelement);
724 _list* rtw_get_queue_head(_queue	*queue);
725 /*************************** End Queues *******************************/
726 
727 /*************************** Time Management *******************************/
728 
729 /**
730  * @brief  Get the count of ticks since the vTaskStartScheduler was called.
731  * @return	The count of ticks since the vTaskStartScheduler was called.
732  */
733 u32	rtw_get_current_time(void);
734 
735 /**
736  * @brief  Convert system time to milliseconds.
737  * @param[in] systime: The system time to be converted.
738  * @return : The milliseconds that converted by the system time.
739  */
740 u32	rtw_systime_to_ms(u32 systime);
741 
742 /**
743  * @brief  Convert system time to seconds.
744  * @param[in] systime: The system time to be converted.
745  * @return : The seconds that converted by the system time.
746  */
747 u32 rtw_systime_to_sec(u32 systime);
748 
749 /**
750  * @brief  Convert milliseconds to system time.
751  * @param[in] systime: The milliseconds to be converted.
752  * @return : The system time that converted by the milliseconds.
753  */
754 u32	rtw_ms_to_systime(u32 ms);
755 
756 /**
757  * @brief  Convert seconds to system time.
758  * @param[in] systime: The seconds to be converted.
759  * @return : The system time that converted by the seconds.
760  */
761 u32	rtw_sec_to_systime(u32 sec);
762 
763 /**
764  * @brief  Get the passing time from the "start" in milliseconds.
765  * @param[in] start: The start time which is in system time format.
766  * @return : The passing time from "start" in milliseconds.
767  */
768 s32	rtw_get_passing_time_ms(u32 start);
769 
770 /**
771  * @brief  Get the interval time from the "start" to "end" in milliseconds.
772  * @param[in] start: The start time which is in system time format.
773  * @param[in] end: The end time which is in system time format.
774  * @return : The interval time from "start" to "end" in milliseconds.
775  */
776 s32	rtw_get_time_interval_ms(u32 start, u32 end);
777 /*************************** End Time Management *******************************/
778 
779 /**
780  * @brief  This function suspends execution of the calling thread for "ms" milliseconds.
781  * @param[in] ms: The time that the function sleep in milliseconds
782  * @return	  None
783 */
784 void	rtw_msleep_os(int ms);
785 
786 /**
787  * @brief  This function suspends execution of the calling thread for "us" microseconds.
788  * @param[in] ms: The time that the function sleep in microseconds
789  * @return	  None
790 */
791 void	rtw_usleep_os(int us);
792 
793 /**
794  * @brief  This function converts the initial portion of the string to integer.
795  * @param[in] s: The pointer to the string to be converted.
796  * @return	  The converted value.
797 */
798 u32 	rtw_atoi(u8* s);
799 
800 /**
801  * @brief  This function delays a task for the giving time in milliseconds.
802  * @param[in] ms: The amount of time, in milliseconds, that the calling task should block.
803  * @return	  None
804 */
805 void	rtw_mdelay_os(int ms);
806 
807 /**
808  * @brief  This function delays a task for the giving time in microseconds.
809  * @param[in] ms: The amount of time, in microseconds, that the calling task should block.
810  * @return	  None
811 */
812 void	rtw_udelay_os(int us);
813 
814 /**
815  * @brief  This function for forcing a context switch.
816  * @return	  None
817 */
818 void	rtw_yield_os(void);
819 
820 /*************************** ATOMIC Integer *******************************/
821 
822 /**
823  * @brief  This function atomically sets the value of the variable.
824  * @param[in] v: Pointer of type atomic_t that to be set value.
825  * @param[in] i: Required value.
826  * @return	  None
827  * @note    The guaranteed useful range of an atomic_t is only 24 bits.
828 */
829 void 	ATOMIC_SET(ATOMIC_T *v, int i);
830 
831 /**
832  * @brief  This function atomically reads the value of the variable.
833  * @param[in] v: Pointer of type atomic_t that to be read.
834  * @return	  The value of the variable.
835  * @note	The guaranteed useful range of an atomic_t is only 24 bits.
836 */
837 int		ATOMIC_READ(ATOMIC_T *v);
838 
839 /**
840  * @brief  This function adds "i" to the contained "v".
841  * @param[in] v: Pointer of type atomic_t.
842  * @param[in] i: value to add.
843  * @return	  None
844 */
845 void 	ATOMIC_ADD(ATOMIC_T *v, int i);
846 
847 /**
848  * @brief  This function subtracts "i" from th econtained "v".
849  * @param[in] v: Pointer of type atomic_t.
850  * @param[in] i: value to subtract.
851  * @return	  None
852 */
853 void 	ATOMIC_SUB(ATOMIC_T *v, int i);
854 
855 /**
856  * @brief  This function adds 1 to the contained "v".
857  * @param[in] v: Pointer of type atomic_t.
858  * @return	  None
859 */
860 void 	ATOMIC_INC(ATOMIC_T *v);
861 
862 /**
863  * @brief  This function subtracts 1 from th econtained "v".
864  * @param[in] v: Pointer of type atomic_t.
865  * @return	  None
866 */
867 void 	ATOMIC_DEC(ATOMIC_T *v);
868 
869 /**
870  * @brief  This function adds "i" to the contained "v" and returns the result.
871  * @param[in] v: Pointer of type atomic_t.
872  * @param[in] i: value to add.
873  * @return	  None
874 */
875 int 	ATOMIC_ADD_RETURN(ATOMIC_T *v, int i);
876 
877 /**
878  * @brief  This function subtracts "i" from th econtained "v" and returns the result.
879  * @param[in] v: Pointer of type atomic_t.
880  * @param[in] i: value to subtract.
881  * @return	  None
882 */
883 int 	ATOMIC_SUB_RETURN(ATOMIC_T *v, int i);
884 
885 /**
886  * @brief  This function adds 1 to the contained "v" and returns the result.
887  * @param[in] v: Pointer of type atomic_t.
888  * @return	  None
889 */
890 int 	ATOMIC_INC_RETURN(ATOMIC_T *v);
891 
892 /**
893  * @brief  This function subtracts 1 from th econtained "v" and returns the result.
894  * @param[in] v: Pointer of type atomic_t.
895  * @return	  None
896 */
897 int 	ATOMIC_DEC_RETURN(ATOMIC_T *v);
898 
899 /**
900  * @brief  This function subtracts 1 from th econtained "v" and test if the result equals 0.
901  * @param[in] v: Pointer of type atomic_t.
902  * @return	  0: The result after subtracting 1 is 0
903  * @return	 -1: The result after subtracting 1 is not 0
904 */
905 int ATOMIC_DEC_AND_TEST(ATOMIC_T *v);
906 /*************************** End ATOMIC *******************************/
907 
908 u64	rtw_modular64(u64 x, u64 y);
909 
910 /**
911  * @brief  This function generates random bytes.
912  * @param[in] dst: The pointer to the buffer to store the random bytes.
913  * @param[in] size: The size of the random bytes.
914  * @return	  0
915 */
916 int	rtw_get_random_bytes(void* dst, u32 size);
917 
918 /**
919  * @brief  This function gets the available heap size.
920  * @return	  The value of the available heap size.
921 */
922 u32	rtw_getFreeHeapSize(void);
923 
924 void	flush_signals_thread(void);
925 
926 /**
927  * @brief  This function indicates that the WLAN needs to stay on which means cannot go into power saving mode.
928  * @return  None
929  * @note  Defining configUSE_WAKELOCK_PMU 1 in "FreeRTOSConfig.h" needs to be done before compiling,
930  *			or this API won't be effective.
931  */
932 void	rtw_acquire_wakelock(void);
933 
934 /**
935  * @brief  This function indicates that the WLAN does not need to stay on which means can go into power saving mode.
936  * @return  None
937  * @note  Defining configUSE_WAKELOCK_PMU 1 in "FreeRTOSConfig.h" needs to be done before compiling,
938  *			or this API won't be effective.
939  */
940 void	rtw_release_wakelock(void);
941 void rtw_wakelock_timeout(u32 timeout);
942 
943 /*********************************** Thread related *****************************************/
944 
945 /**
946  * @brief  This function creates a new task and adds it to the list of tasks that are ready to run.
947  * @param[in] task:  The task stucture which will store the task related infomation.
948  * @param[in] name: A descriptive name for the task.
949  * @param[in] stack_size: The size of the task stack specified as the variables the stack can hold.
950  * @param[in] priority: The priority at which the task should run.
951  * @param[in] func: The task entry function.
952  * @param[in] thctx: The pointer that will be used as the parameter for the task being created.
953  * @return  pdPASS: The task was successfully created and added to a ready list.
954  * @return  other error code defined in the file errors.h.
955  * @note  For the task name, please do not use "rtw_little_wifi_mcu_thread", "rtw_check_in_req_state_thread",
956  		  "rtw_TDMA_change_state_thread", "xmit_thread", "recv_thread", "rtw_recv_tasklet", "rtw_xmit_tasklet",
957  		  "rtw_interrupt_thread", "cmd_thread", "usb_init", "MSC_BULK_CMD" and "MSC_BULK_DATA".
958  */
959 int	rtw_create_task(struct task_struct *task, const char *name, u32  stack_size, u32 priority, thread_func_t func, void *thctx);
960 
961 /**
962  * @brief  This function deletes a task.
963  * @param[in] task:  The task stucture which will be deleted.
964  * @return  None
965  */
966 void rtw_delete_task(struct task_struct * task);
967 
968 /**
969  * @brief  This function wake up a task.
970  * @param[in] task:  The task stucture which will be waked up.
971  * @return  None
972  */
973 void rtw_wakeup_task(struct task_struct *task);
974 
975 void rtw_set_priority_task(void* task, u32 NewPriority );
976 
977 int rtw_get_priority_task(void* task);
978 void rtw_suspend_task (void* task);
979 
980 void rtw_resume_task (void* task);
981 
982 /**
983  * @brief  This function creates a new worker thread.
984  * @param[in] worker_thread:  The pointer to the worker thread stucture.
985  * @param[in] priority: The priority of the thread.
986  * @param[in] stack_size: The size of the thread stack specified as the variables the stack can hold.
987  * @param[in] event_queue_size: The queue size of events.
988  * @return  SUCCESS/FAIL.
989  */
990 int rtw_create_worker_thread( rtw_worker_thread_t* worker_thread, u8 priority, u32 stack_size, u32 event_queue_size );
991 
992 /**
993  * @brief  This function deletes a worker thread.
994  * @param[in] worker_thread:  The pointer to the worker thread stucture to be deleted.
995  * @return  SUCCESS/FAIL.
996  */
997 int rtw_delete_worker_thread( rtw_worker_thread_t* worker_thread );
998 
999 #if 0 //TODO
1000 void	rtw_init_delayed_work(struct delayed_work *dwork, work_func_t func, const char *name);
1001 void	rtw_deinit_delayed_work(struct delayed_work *dwork);
1002 int		rtw_queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, u32 delay, void* context);
1003 BOOLEAN rtw_cancel_delayed_work(struct delayed_work *dwork);
1004 #endif
1005 
1006 /**
1007  * @brief  This function prints the name of the thread in DBG_INFO.
1008  * @param[in] name:  The name of the thread.
1009  * @return  None
1010  */
1011 void	rtw_thread_enter(char *name);
1012 
1013 /**
1014  * @brief  This function exits the calling thread.
1015  * @return  None
1016  */
1017 void	rtw_thread_exit(void);
1018 
1019 /**
1020  * @brief  This function gets the scheduler state of the calling thread.
1021  * @return  OS_SCHEDULER_NOT_STARTED
1022  * @return  OS_SCHEDULER_RUNNING
1023  * @return  OS_SCHEDULER_SUSPENDED
1024  */
1025 u8		rtw_get_scheduler_state(void);
1026 
1027 /*************************** End Threads *******************************/
1028 #ifdef PLATFORM_LINUX
1029 #define rtw_warn_on(condition) WARN_ON(condition)
1030 #else
1031 #define rtw_warn_on(condition) do {} while (0)
1032 #endif
1033 
1034 /*************************** Timers *******************************/
1035 
1036 /**
1037  * @brief  This function creates a new software timer instance.
1038  * @param[in] pcTimerName:  A text name that is assigned to the timer.
1039  * @param[in] xTimerPeriodInTicks: The timer period which is defined in tick periods.
1040  * @param[in] uxAutoReload: If uxAutoReload is set to pdTRUE then the timer will
1041  * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.  If
1042  * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
1043  * enter the dormant state after it expires.
1044  * @param[in] pvTimerID: An identifier that is assigned to the timer being created.
1045  * @param[in] pxCallbackFunction: The function to call when the timer expires.
1046  * @return  If the timer is successfully create then a handle to the newly
1047  * created timer is returned.  If the timer cannot be created, then 0 is returned.
1048  */
1049 _timerHandle rtw_timerCreate( const signed char *pcTimerName,
1050 							  osdepTickType xTimerPeriodInTicks,
1051 							  u32 uxAutoReload,
1052 							  void * pvTimerID,
1053 							  TIMER_FUN pxCallbackFunction );
1054 
1055 /**
1056  * @brief  This function deletes a timer that was previously created using rtw_timerCreate.
1057  * @param[in] xTimer:  The handle of the timer being deleted.
1058  * @param[in] xBlockTime: Specifies th etime, in ticks, that the calling task should be held in the Blocked
1059  *						  State to wait for the delete command to be successfully sent to the timer command queue,
1060  *						  should the queue already be full when rtw_timerDelete was called.
1061  * @return  pdFAIL will be returned if the delete command could not be sent to
1062  * the timer command queue even after xTicksToWait ticks had passed.  pdPASS will
1063  * be returned if the command was successfully sent to the timer command queue.
1064  * When the command is actually processed will depend on the priority of the
1065  * timer service/daemon task relative to other tasks in the system.
1066  */
1067 u32 rtw_timerDelete( _timerHandle xTimer, osdepTickType xBlockTime );
1068 
1069 /**
1070  * @brief  This function queries a timer to see if it is active or dormant.
1071  * @param[in] xTimer:  The timer being queried.
1072  * @return  pdFALSE will be returned if the timer is dormant.  A value other than
1073  * pdFALSE will be returned if the timer is active.
1074  * @note  A timer will be dormant if:
1075  *     1) It has been created but not started, or
1076  *     2) It is an expired one-shot timer that has not been restarted.
1077  */
1078 u32 rtw_timerIsTimerActive( _timerHandle xTimer );
1079 
1080 /**
1081  * @brief  This function stops a timer that was previously started.
1082  * @param[in] xTimer:  The handle of the timer being stopped.
1083  * @param[in] xBlockTime:  Specifies the time, in ticks, that the calling task should
1084  * be held in the Blocked state to wait for the stop command to be successfully
1085  * sent to the timer command queue, should the queue already be full when
1086  * rtw_timerStop() was called.
1087  * @return  pdFAIL will be returned if the stop command could not be sent to
1088  * the timer command queue even after xTicksToWait ticks had passed.  pdPASS will
1089  * be returned if the command was successfully sent to the timer command queue.
1090  * When the command is actually processed will depend on the priority of the
1091  * timer service/daemon task relative to other tasks in the system.
1092  */
1093 u32 rtw_timerStop( _timerHandle xTimer, osdepTickType xBlockTime );
1094 
1095 /**
1096  * @brief  This function changes the period of a timer that was previously created.
1097  * @param[in] xTimer:  The handle of the timer that is having its period changed.
1098  * @param[in] xNewPeriod:  The new period for xTimer.
1099  * @param[in] xBlockTime:  Specifies the time, in ticks, that the calling task should
1100  * be held in the Blocked state to wait for the change period command to be
1101  * successfully sent to the timer command queue, should the queue already be
1102  * full when rtw_timerChangePeriod() was called.
1103  * @return  pdFAIL will be returned if the change period command could not be
1104  * sent to the timer command queue even after xTicksToWait ticks had passed.
1105  * pdPASS will be returned if the command was successfully sent to the timer
1106  * command queue.  When the command is actually processed will depend on the
1107  * priority of the timer service/daemon task relative to other tasks in the
1108  * system.
1109  */
1110 u32 rtw_timerChangePeriod( _timerHandle xTimer,
1111 							   osdepTickType xNewPeriod,
1112 							   osdepTickType xBlockTime );
1113 
1114 void *rtw_timerGetID( _timerHandle xTimer );
1115 
1116 u32  rtw_timerStart( _timerHandle xTimer, osdepTickType xBlockTime );
1117 
1118 u32  rtw_timerStartFromISR( _timerHandle xTimer,
1119 								osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1120 
1121 u32  rtw_timerStopFromISR( _timerHandle xTimer,
1122 							   osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1123 
1124 u32  rtw_timerResetFromISR( _timerHandle xTimer,
1125 							   osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1126 
1127 u32  rtw_timerChangePeriodFromISR( _timerHandle xTimer,
1128 							   osdepTickType xNewPeriod,
1129 							   osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1130 
1131 u32  rtw_timerReset( _timerHandle xTimer,
1132 						osdepTickType xBlockTime );
1133 
1134 
1135 /*************************** End Timers *******************************/
1136 #define LIST_CONTAINOR(ptr, type, member) \
1137 	((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr)))
1138 
1139 #define time_after(a,b)	((long)(b) - (long)(a) < 0)
1140 #define time_before(a,b)	time_after(b,a)
1141 #define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
1142 #define time_before_eq(a,b)	time_after_eq(b,a)
1143 
1144 #define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
1145 #define RND4(x)	(((x >> 2) + (((x & 3) == 0) ?  0: 1)) << 2)
1146 
_RND4(u32 sz)1147 __inline static u32 _RND4(u32 sz)
1148 {
1149 	u32	val;
1150 
1151 	val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2;
1152 
1153 	return val;
1154 }
1155 
_RND8(u32 sz)1156 __inline static u32 _RND8(u32 sz)
1157 {
1158 	u32	val;
1159 
1160 	val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3;
1161 
1162 	return val;
1163 }
1164 
_RND128(u32 sz)1165 __inline static u32 _RND128(u32 sz)
1166 {
1167 	u32	val;
1168 
1169 	val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7;
1170 
1171 	return val;
1172 }
1173 
_RND256(u32 sz)1174 __inline static u32 _RND256(u32 sz)
1175 {
1176 	u32	val;
1177 
1178 	val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8;
1179 
1180 	return val;
1181 }
1182 
_RND512(u32 sz)1183 __inline static u32 _RND512(u32 sz)
1184 {
1185 	u32	val;
1186 
1187 	val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9;
1188 
1189 	return val;
1190 }
1191 
bitshift(u32 bitmask)1192 __inline static u32 bitshift(u32 bitmask)
1193 {
1194 	u32 i;
1195 
1196 	for (i = 0; i <= 31; i++)
1197 		if (((bitmask>>i) &  0x1) == 1) break;
1198 
1199 	return i;
1200 }
1201 
1202 /* Macros for handling unaligned memory accesses */
1203 
1204 #define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
1205 #define RTW_PUT_BE16(a, val)			\
1206 	do {					\
1207 		(a)[0] = ((u16) (val)) >> 8;	\
1208 		(a)[1] = ((u16) (val)) & 0xff;	\
1209 	} while (0)
1210 
1211 #define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
1212 #define RTW_PUT_LE16(a, val)			\
1213 	do {					\
1214 		(a)[1] = ((u16) (val)) >> 8;	\
1215 		(a)[0] = ((u16) (val)) & 0xff;	\
1216 	} while (0)
1217 
1218 #define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
1219 			 ((u32) (a)[2]))
1220 #define RTW_PUT_BE24(a, val)					\
1221 	do {							\
1222 		(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
1223 		(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
1224 		(a)[2] = (u8) (((u32) (val)) & 0xff);		\
1225 	} while (0)
1226 
1227 #define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
1228 			 (((u32) (a)[2]) << 8) | ((u32) (a)[3]))
1229 #define RTW_PUT_BE32(a, val)					\
1230 	do {							\
1231 		(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
1232 		(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
1233 		(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
1234 		(a)[3] = (u8) (((u32) (val)) & 0xff);		\
1235 	} while (0)
1236 
1237 #define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
1238 			 (((u32) (a)[1]) << 8) | ((u32) (a)[0]))
1239 #define RTW_PUT_LE32(a, val)					\
1240 	do {							\
1241 		(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
1242 		(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
1243 		(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
1244 		(a)[0] = (u8) (((u32) (val)) & 0xff);		\
1245 	} while (0)
1246 
1247 #define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
1248 			 (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
1249 			 (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
1250 			 (((u64) (a)[6]) << 8) | ((u64) (a)[7]))
1251 #define RTW_PUT_BE64(a, val)				\
1252 	do {						\
1253 		(a)[0] = (u8) (((u64) (val)) >> 56);	\
1254 		(a)[1] = (u8) (((u64) (val)) >> 48);	\
1255 		(a)[2] = (u8) (((u64) (val)) >> 40);	\
1256 		(a)[3] = (u8) (((u64) (val)) >> 32);	\
1257 		(a)[4] = (u8) (((u64) (val)) >> 24);	\
1258 		(a)[5] = (u8) (((u64) (val)) >> 16);	\
1259 		(a)[6] = (u8) (((u64) (val)) >> 8);	\
1260 		(a)[7] = (u8) (((u64) (val)) & 0xff);	\
1261 	} while (0)
1262 
1263 #define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
1264 			 (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
1265 			 (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
1266 			 (((u64) (a)[1]) << 8) | ((u64) (a)[0]))
1267 
1268 struct osdep_service_ops {
1269 	u8* (*rtw_vmalloc)(u32 sz);
1270 	u8* (*rtw_zvmalloc)(u32 sz);
1271 	void (*rtw_vmfree)(u8 *pbuf, u32 sz);
1272 	u8* (*rtw_malloc)(u32 sz);
1273 	u8* (*rtw_zmalloc)(u32 sz);
1274 	void (*rtw_mfree)(u8 *pbuf, u32 sz);
1275 	void (*rtw_memcpy)(void* dst, void* src, u32 sz);
1276 	int (*rtw_memcmp)(void *dst, void *src, u32 sz);
1277 	void (*rtw_memset)(void *pbuf, int c, u32 sz);
1278 	void (*rtw_init_sema)(_sema *sema, int init_val);
1279 	void (*rtw_free_sema)(_sema *sema);
1280 	void (*rtw_up_sema)(_sema *sema);
1281 	void (*rtw_up_sema_from_isr)(_sema *sema);
1282 	u32 (*rtw_down_timeout_sema)(_sema *sema, u32 timeout);
1283 	void (*rtw_mutex_init)(_mutex *pmutex);
1284 	void (*rtw_mutex_free)(_mutex *pmutex);
1285 	void (*rtw_mutex_get)(_mutex *pmutex);
1286 	int (*rtw_mutex_get_timeout)(_mutex *pmutex, u32 timeout_ms);
1287 	void (*rtw_mutex_put)(_mutex *pmutex);
1288 	void (*rtw_enter_critical)(_lock *plock, _irqL *pirqL);
1289 	void (*rtw_exit_critical)(_lock *plock, _irqL *pirqL);
1290 	void (*rtw_enter_critical_from_isr)(_lock *plock, _irqL *pirqL);
1291 	void (*rtw_exit_critical_from_isr)(_lock *plock, _irqL *pirqL);
1292 	void (*rtw_enter_critical_bh)(_lock *plock, _irqL *pirqL);
1293 	void (*rtw_exit_critical_bh)(_lock *plock, _irqL *pirqL);
1294 	int (*rtw_enter_critical_mutex)(_mutex *pmutex, _irqL *pirqL);
1295 	void (*rtw_exit_critical_mutex)(_mutex *pmutex, _irqL *pirqL);
1296 	void (*rtw_spinlock_init)(_lock *plock);
1297 	void (*rtw_spinlock_free)(_lock *plock);
1298 	void (*rtw_spin_lock)(_lock *plock);
1299 	void (*rtw_spin_unlock)(_lock *plock);
1300 	void (*rtw_spinlock_irqsave)(_lock *plock, _irqL *irqL);
1301 	void (*rtw_spinunlock_irqsave)(_lock *plock, _irqL *irqL);
1302 	int (*rtw_init_xqueue)( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages );
1303 	int (*rtw_push_to_xqueue)( _xqueue* queue, void* message, u32 timeout_ms );
1304 	int (*rtw_pop_from_xqueue)( _xqueue* queue, void* message, u32 timeout_ms );
1305 	int (*rtw_deinit_xqueue)( _xqueue* queue );
1306 	u32	(*rtw_get_current_time)(void);
1307 	u32 (*rtw_systime_to_ms)(u32 systime);
1308 	u32 (*rtw_systime_to_sec)(u32 systime);
1309 	u32 (*rtw_ms_to_systime)(u32 ms);
1310 	u32	(*rtw_sec_to_systime)(u32 sec);
1311 	void (*rtw_msleep_os)(int ms);
1312 	void (*rtw_usleep_os)(int us);
1313 	void (*rtw_mdelay_os)(int ms);
1314 	void (*rtw_udelay_os)(int us);
1315 	void (*rtw_yield_os)(void);
1316 	void (*ATOMIC_SET)(ATOMIC_T *v, int i);
1317 	int (*ATOMIC_READ)(ATOMIC_T *v);
1318 	void (*ATOMIC_ADD)(ATOMIC_T *v, int i);
1319 	void (*ATOMIC_SUB)(ATOMIC_T *v, int i);
1320 	void (*ATOMIC_INC)(ATOMIC_T *v);
1321 	void (*ATOMIC_DEC)(ATOMIC_T *v);
1322 	int (*ATOMIC_ADD_RETURN)(ATOMIC_T *v, int i);
1323 	int (*ATOMIC_SUB_RETURN)(ATOMIC_T *v, int i);
1324 	int (*ATOMIC_INC_RETURN)(ATOMIC_T *v);
1325 	int (*ATOMIC_DEC_RETURN)(ATOMIC_T *v);
1326 	u64 (*rtw_modular64)(u64 x, u64 y);
1327 	int (*rtw_get_random_bytes)(void* dst, u32 size);
1328 	u32 (*rtw_getFreeHeapSize)(void);
1329 	int (*rtw_create_task)(struct task_struct *task, const char *name, u32 stack_size, u32 priority, thread_func_t func, void *thctx);
1330 	void (*rtw_delete_task)(struct task_struct *task);
1331 	void (*rtw_wakeup_task)(struct task_struct *task);
1332 	void (*rtw_set_priority_task)(void* task, u32 NewPriority);
1333 	int (*rtw_get_priority_task)(void* task);
1334 	void (*rtw_suspend_task)(void* task);
1335 	void (*rtw_resume_task)(void* task);
1336 
1337 #if 0	//TODO
1338 	void (*rtw_init_delayed_work)(struct delayed_work *dwork, work_func_t func, const char *name);
1339 	void (*rtw_deinit_delayed_work)(struct delayed_work *dwork);
1340 	int (*rtw_queue_delayed_work)(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay, void* context);
1341 	BOOLEAN (*rtw_cancel_delayed_work)(struct delayed_work *dwork);
1342 #endif
1343 	void (*rtw_thread_enter)(char *name);
1344 	void (*rtw_thread_exit)(void);
1345 	_timerHandle (*rtw_timerCreate)( const signed char *pcTimerName,
1346 							  osdepTickType xTimerPeriodInTicks,
1347 							  u32 uxAutoReload,
1348 							  void * pvTimerID,
1349 							  TIMER_FUN pxCallbackFunction );
1350 	u32 (*rtw_timerDelete)( _timerHandle xTimer,
1351 							   osdepTickType xBlockTime );
1352 	u32 (*rtw_timerIsTimerActive)( _timerHandle xTimer );
1353 	u32 (*rtw_timerStop)( _timerHandle xTimer,
1354 							   osdepTickType xBlockTime );
1355 	u32 (*rtw_timerChangePeriod)( _timerHandle xTimer,
1356 							   osdepTickType xNewPeriod,
1357 							   osdepTickType xBlockTime );
1358 	void* (*rtw_timerGetID)( _timerHandle xTimer );
1359 	u32 (*rtw_timerStart)( _timerHandle xTimer,
1360 								osdepTickType xBlockTime );
1361 	u32 (*rtw_timerStartFromISR)( _timerHandle xTimer,
1362 									osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1363 
1364 	u32 (*rtw_timerStopFromISR)( _timerHandle xTimer,
1365 								   osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1366 
1367 	u32  (*rtw_timerResetFromISR)( _timerHandle xTimer,
1368 								   osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1369 
1370 	u32  (*rtw_timerChangePeriodFromISR)( _timerHandle xTimer,
1371 								   osdepTickType xNewPeriod,
1372 								   osdepBASE_TYPE *pxHigherPriorityTaskWoken );
1373 
1374 	u32  (*rtw_timerReset)( _timerHandle xTimer,
1375 							osdepTickType xBlockTime );
1376 
1377 	void (*rtw_acquire_wakelock)(void);
1378 	void (*rtw_release_wakelock)(void);
1379 	void (*rtw_wakelock_timeout)(u32 timeoutMs);
1380 	u8 (*rtw_get_scheduler_state)(void);
1381 };
1382 
1383 /*\@}*/
1384 
1385 #endif	//#ifndef __OSDEP_SERVICE_H_
1386 //----------------------------------------------------------------------------//
1387