2 * ---------------------------------------------------------------------------
6 * Routines to fulfil the OS-abstraction for the HIP lib.
7 * It is part of the porting exercise.
9 * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
11 * Refer to LICENSE.txt included with this source code for details on
14 * ---------------------------------------------------------------------------
18 * The HIP lib OS abstraction consists of the implementation
19 * of the functions in this file. It is part of the porting exercise.
22 #include "unifi_priv.h"
26 * ---------------------------------------------------------------------------
27 * unifi_net_data_malloc
29 * Allocate an OS specific net data buffer of "size" bytes.
30 * The bulk_data_slot.os_data_ptr must be initialised to point
31 * to the buffer allocated. The bulk_data_slot.length must be
32 * initialised to the requested size, zero otherwise.
33 * The bulk_data_slot.os_net_buf_ptr can be initialised to
34 * an OS specific pointer to be used in the unifi_net_data_free().
38 * ospriv Pointer to device private context struct.
39 * bulk_data_slot Pointer to the bulk data structure to initialise.
40 * size Size of the buffer to be allocated.
43 * CSR_RESULT_SUCCESS on success, CSR_RESULT_FAILURE otherwise.
44 * ---------------------------------------------------------------------------
47 unifi_net_data_malloc(void *ospriv
, bulk_data_desc_t
*bulk_data_slot
, unsigned int size
)
50 unifi_priv_t
*priv
= (unifi_priv_t
*)ospriv
;
53 if (priv
->card_info
.sdio_block_size
== 0) {
54 unifi_error(priv
, "unifi_net_data_malloc: Invalid SDIO block size\n");
55 return CSR_RESULT_FAILURE
;
58 rounded_length
= (size
+ priv
->card_info
.sdio_block_size
- 1) & ~(priv
->card_info
.sdio_block_size
- 1);
61 * (ETH_HLEN + 2) bytes tailroom for header manipulation
62 * CSR_WIFI_ALIGN_BYTES bytes headroom for alignment manipulation
64 skb
= dev_alloc_skb(rounded_length
+ 2 + ETH_HLEN
+ CSR_WIFI_ALIGN_BYTES
);
66 unifi_error(ospriv
, "alloc_skb failed.\n");
67 bulk_data_slot
->os_net_buf_ptr
= NULL
;
68 bulk_data_slot
->net_buf_length
= 0;
69 bulk_data_slot
->os_data_ptr
= NULL
;
70 bulk_data_slot
->data_length
= 0;
71 return CSR_RESULT_FAILURE
;
74 bulk_data_slot
->os_net_buf_ptr
= (const unsigned char*)skb
;
75 bulk_data_slot
->net_buf_length
= rounded_length
+ 2 + ETH_HLEN
+ CSR_WIFI_ALIGN_BYTES
;
76 bulk_data_slot
->os_data_ptr
= (const void*)skb
->data
;
77 bulk_data_slot
->data_length
= size
;
79 return CSR_RESULT_SUCCESS
;
80 } /* unifi_net_data_malloc() */
83 * ---------------------------------------------------------------------------
86 * Free an OS specific net data buffer.
87 * The bulk_data_slot.length must be initialised to 0.
91 * ospriv Pointer to device private context struct.
92 * bulk_data_slot Pointer to the bulk data structure that
93 * holds the data to be freed.
97 * ---------------------------------------------------------------------------
100 unifi_net_data_free(void *ospriv
, bulk_data_desc_t
*bulk_data_slot
)
105 skb
= (struct sk_buff
*)bulk_data_slot
->os_net_buf_ptr
;
108 bulk_data_slot
->net_buf_length
= 0;
109 bulk_data_slot
->data_length
= 0;
110 bulk_data_slot
->os_data_ptr
= bulk_data_slot
->os_net_buf_ptr
= NULL
;
112 } /* unifi_net_data_free() */
116 * ---------------------------------------------------------------------------
117 * unifi_net_dma_align
119 * DMA align an OS specific net data buffer.
120 * The buffer must be empty.
124 * ospriv Pointer to device private context struct.
125 * bulk_data_slot Pointer to the bulk data structure that
126 * holds the data to be aligned.
130 * ---------------------------------------------------------------------------
133 unifi_net_dma_align(void *ospriv
, bulk_data_desc_t
*bulk_data_slot
)
136 unsigned long buf_address
;
138 unifi_priv_t
*priv
= (unifi_priv_t
*)ospriv
;
140 if ((bulk_data_slot
== NULL
) || (CSR_WIFI_ALIGN_BYTES
== 0)) {
141 return CSR_RESULT_SUCCESS
;
144 if ((bulk_data_slot
->os_data_ptr
== NULL
) || (bulk_data_slot
->data_length
== 0)) {
145 return CSR_RESULT_SUCCESS
;
148 buf_address
= (unsigned long)(bulk_data_slot
->os_data_ptr
) & (CSR_WIFI_ALIGN_BYTES
- 1);
150 unifi_trace(priv
, UDBG5
,
151 "unifi_net_dma_align: Allign buffer (0x%p) by %d bytes\n",
152 bulk_data_slot
->os_data_ptr
, buf_address
);
154 offset
= CSR_WIFI_ALIGN_BYTES
- buf_address
;
156 unifi_error(priv
, "unifi_net_dma_align: Failed (offset=%d)\n", offset
);
157 return CSR_RESULT_FAILURE
;
160 skb
= (struct sk_buff
*)(bulk_data_slot
->os_net_buf_ptr
);
161 skb_reserve(skb
, offset
);
162 bulk_data_slot
->os_net_buf_ptr
= (const unsigned char*)skb
;
163 bulk_data_slot
->os_data_ptr
= (const void*)(skb
->data
);
165 return CSR_RESULT_SUCCESS
;
167 } /* unifi_net_dma_align() */
169 #ifdef ANDROID_TIMESTAMP
170 static volatile unsigned int printk_cpu
= UINT_MAX
;
173 char* print_time(void )
175 unsigned long long t
;
176 unsigned long nanosec_rem
;
178 t
= cpu_clock(printk_cpu
);
179 nanosec_rem
= do_div(t
, 1000000000);
180 sprintf(tbuf
, "[%5lu.%06lu] ",
189 /* Module parameters */
190 extern int unifi_debug
;
193 #define DEBUG_BUFFER_SIZE 120
195 #define FORMAT_TRACE(_s, _len, _args, _fmt) \
197 va_start(_args, _fmt); \
198 _len += vsnprintf(&(_s)[_len], \
199 (DEBUG_BUFFER_SIZE - _len), \
202 if (_len >= DEBUG_BUFFER_SIZE) { \
203 (_s)[DEBUG_BUFFER_SIZE - 2] = '\n'; \
204 (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \
209 unifi_error(void* ospriv
, const char *fmt
, ...)
211 unifi_priv_t
*priv
= (unifi_priv_t
*) ospriv
;
212 char s
[DEBUG_BUFFER_SIZE
];
215 #ifdef ANDROID_TIMESTAMP
217 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"%s unifi%d: ", print_time(), priv
->instance
);
219 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"%s unifi: ", print_time());
223 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"unifi%d: ", priv
->instance
);
225 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"unifi: ");
227 #endif /* ANDROID_TIMESTAMP */
228 FORMAT_TRACE(s
, len
, args
, fmt
);
234 unifi_warning(void* ospriv
, const char *fmt
, ...)
236 unifi_priv_t
*priv
= (unifi_priv_t
*) ospriv
;
237 char s
[DEBUG_BUFFER_SIZE
];
241 #ifdef ANDROID_TIMESTAMP
243 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_WARNING
"%s unifi%d: ", print_time(), priv
->instance
);
245 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_WARNING
"%s unifi: ", print_time());
249 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_WARNING
"unifi%d: ", priv
->instance
);
251 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_WARNING
"unifi: ");
253 #endif /* ANDROID_TIMESTAMP */
255 FORMAT_TRACE(s
, len
, args
, fmt
);
262 unifi_notice(void* ospriv
, const char *fmt
, ...)
264 unifi_priv_t
*priv
= (unifi_priv_t
*) ospriv
;
265 char s
[DEBUG_BUFFER_SIZE
];
269 #ifdef ANDROID_TIMESTAMP
271 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_NOTICE
"%s unifi%d: ", print_time(), priv
->instance
);
273 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_NOTICE
"%s unifi: ", print_time());
277 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_NOTICE
"unifi%d: ", priv
->instance
);
279 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_NOTICE
"unifi: ");
281 #endif /* ANDROID_TIMESTAMP */
283 FORMAT_TRACE(s
, len
, args
, fmt
);
290 unifi_info(void* ospriv
, const char *fmt
, ...)
292 unifi_priv_t
*priv
= (unifi_priv_t
*) ospriv
;
293 char s
[DEBUG_BUFFER_SIZE
];
297 #ifdef ANDROID_TIMESTAMP
299 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_INFO
"%s unifi%d: ", print_time(), priv
->instance
);
301 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_INFO
"%s unifi: ", print_time());
305 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_INFO
"unifi%d: ", priv
->instance
);
307 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_INFO
"unifi: ");
309 #endif /* ANDROID_TIMESTAMP */
311 FORMAT_TRACE(s
, len
, args
, fmt
);
318 unifi_trace(void* ospriv
, int level
, const char *fmt
, ...)
320 unifi_priv_t
*priv
= (unifi_priv_t
*) ospriv
;
321 char s
[DEBUG_BUFFER_SIZE
];
325 if (unifi_debug
>= level
) {
326 #ifdef ANDROID_TIMESTAMP
328 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"%s unifi%d: ", print_time(), priv
->instance
);
330 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"%s unifi: ", print_time());
334 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"unifi%d: ", priv
->instance
);
336 len
= snprintf(s
, DEBUG_BUFFER_SIZE
, KERN_ERR
"unifi: ");
338 #endif /* ANDROID_TIMESTAMP */
340 FORMAT_TRACE(s
, len
, args
, fmt
);
349 unifi_error_nop(void* ospriv
, const char *fmt
, ...)
354 unifi_trace_nop(void* ospriv
, int level
, const char *fmt
, ...)
358 #endif /* UNIFI_DEBUG */
362 * ---------------------------------------------------------------------------
366 * ---------------------------------------------------------------------------
371 /* Memory dump with level filter controlled by unifi_debug */
373 unifi_dump(void *ospriv
, int level
, const char *msg
, void *mem
, CsrUint16 len
)
375 unifi_priv_t
*priv
= (unifi_priv_t
*) ospriv
;
377 if (unifi_debug
>= level
) {
378 #ifdef ANDROID_TIMESTAMP
380 printk(KERN_ERR
"%s unifi%d: --- dump: %s ---\n", print_time(), priv
->instance
, msg
? msg
: "");
382 printk(KERN_ERR
"%s unifi: --- dump: %s ---\n", print_time(), msg
? msg
: "");
386 printk(KERN_ERR
"unifi%d: --- dump: %s ---\n", priv
->instance
, msg
? msg
: "");
388 printk(KERN_ERR
"unifi: --- dump: %s ---\n", msg
? msg
: "");
390 #endif /* ANDROID_TIMESTAMP */
394 printk(KERN_ERR
"unifi%d: --- end of dump ---\n", priv
->instance
);
396 printk(KERN_ERR
"unifi: --- end of dump ---\n");
401 /* Memory dump that appears all the time, use sparingly */
403 dump(void *mem
, CsrUint16 len
)
406 unsigned char *pdata
= (unsigned char *)mem
;
407 #ifdef ANDROID_TIMESTAMP
408 printk("timestamp %s \n", print_time());
409 #endif /* ANDROID_TIMESTAMP */
411 printk("(null dump)\n");
414 for (i
= 0; i
< len
; i
++) {
416 printk("0x%02X: ", i
);
419 printk(" %02X", pdata
[i
]);
433 dump16(void *mem
, CsrUint16 len
)
436 unsigned short *p
= (unsigned short *)mem
;
437 #ifdef ANDROID_TIMESTAMP
438 printk("timestamp %s \n", print_time());
439 #endif /* ANDROID_TIMESTAMP */
440 for (i
= 0; i
< len
; i
+=2) {
442 printk("0x%02X: ", i
);
445 printk(" %04X", *p
++);
458 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
460 dump_str(void *mem
, CsrUint16 len
)
463 unsigned char *pdata
= (unsigned char *)mem
;
464 #ifdef ANDROID_TIMESTAMP
465 printk("timestamp %s \n", print_time());
466 #endif /* ANDROID_TIMESTAMP */
467 for (i
= 0; i
< len
; i
++) {
468 printk("%c", pdata
[i
]);
475 #endif /* CSR_ONLY_NOTES */
478 #endif /* UNIFI_DEBUG */
481 /* ---------------------------------------------------------------------------
483 * ------------------------------------------------------------------------- */