usb: gadget: Zero ffs_io_data
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / utils.h
1 /******************************************************************************
2 *
3 * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 *****************************************************************************/
6
7 #ifndef SLSI_UTILS_H__
8 #define SLSI_UTILS_H__
9
10 #include <linux/version.h>
11 #include <linux/types.h>
12 #include <linux/spinlock.h>
13 #include <linux/workqueue.h>
14 #include <linux/skbuff.h>
15 #include <net/cfg80211.h>
16
17 #include "netif.h"
18 #include "wakelock.h"
19 #ifdef CONFIG_SCSC_SMAPPER
20 struct slsi_skb_cb {
21 u32 sig_length;
22 u32 data_length;
23 u32 frame_format;
24 u32 colour;
25 bool free_ma_unitdat;
26 struct sk_buff *skb_addr;
27 };
28
29 static inline struct slsi_skb_cb *slsi_skb_cb_get(struct sk_buff *skb)
30 {
31 return (struct slsi_skb_cb *)skb->cb;
32 }
33
34 static inline struct slsi_skb_cb *slsi_skb_cb_init(struct sk_buff *skb)
35 {
36 BUILD_BUG_ON(sizeof(struct slsi_skb_cb) > sizeof(skb->cb));
37
38 memset(skb->cb, 0, sizeof(struct slsi_skb_cb));
39 return slsi_skb_cb_get(skb);
40 }
41 #endif
42
43 static inline u32 slsi_convert_tlv_data_to_value(u8 *data, u16 length)
44 {
45 u32 value = 0;
46 int i;
47
48 if (length > 4)
49 return 0;
50 for (i = 0; i < length; i++)
51 value |= ((u32)data[i]) << i * 8;
52
53 return value;
54 }
55
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59
60 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
61 #define SLSI_ETHER_COPY(dst, src) ether_addr_copy((dst), (src))
62 #define SLSI_ETHER_EQUAL(mac1, mac2) ether_addr_equal((mac1), (mac2))
63 #else
64 #define SLSI_ETHER_COPY(dst, src) memcpy((dst), (src), ETH_ALEN)
65 #define SLSI_ETHER_EQUAL(mac1, mac2) (memcmp((mac1), (mac2), ETH_ALEN) == 0)
66 #endif
67
68 extern uint slsi_sg_host_align_mask;
69 #define SLSI_HIP_FH_SIG_PREAMBLE_LEN 4
70 #define SLSI_SKB_GET_ALIGNMENT_OFFSET(skb) (0)
71
72 /* Get the Compiler to ignore Unused parameters */
73 #define SLSI_UNUSED_PARAMETER(x) ((void)(x))
74
75 /* Helper ERROR Macros */
76 #define SLSI_ECR(func) \
77 do { \
78 int _err = (func); \
79 if (_err != 0) { \
80 SLSI_ERR_NODEV("e=%d\n", _err); \
81 return _err; \
82 } \
83 } while (0)
84
85 #define SLSI_EC(func) \
86 do { \
87 int _err = (func); \
88 if (_err != 0) { \
89 SLSI_ERR_NODEV("e=%d\n", _err); \
90 return; \
91 } \
92 } while (0)
93
94 #define SLSI_EC_GOTO(func, err, label) \
95 do { \
96 (err) = func; \
97 if ((err) != 0) { \
98 WARN_ON(1); \
99 SLSI_ERR(sdev, "fail at line:%d\n", __LINE__); \
100 goto label; \
101 } \
102 } while (0)
103
104 /*------------------------------------------------------------------*/
105 /* Endian conversion */
106 /*------------------------------------------------------------------*/
107 #define SLSI_BUFF_LE_TO_U16(ptr) (((u16)((u8 *)(ptr))[0]) | ((u16)((u8 *)(ptr))[1]) << 8)
108 #define SLSI_U16_TO_BUFF_LE(uint, ptr) \
109 do { \
110 u32 local_uint_tmp = (uint); \
111 ((u8 *)(ptr))[0] = ((u8)((local_uint_tmp & 0x00FF))); \
112 ((u8 *)(ptr))[1] = ((u8)(local_uint_tmp >> 8)); \
113 } while (0)
114
115 #define SLSI_U32_TO_BUFF_LE(uint, ptr) ((*(u32 *)ptr) = cpu_to_le32(uint))
116
117 #define SLSI_BUFF_LE_TO_U16_P(output, input) \
118 do { \
119 (output) = (u16)((((u16)(input)[1]) << 8) | ((u16)(input)[0])); \
120 (input) += 2; \
121 } while (0)
122
123 #define SLSI_BUFF_LE_TO_U32_P(output, input) \
124 do { \
125 (output) = le32_to_cpu(*(u32 *)input); \
126 (input) += 4; \
127 } while (0)
128
129 #define SLSI_U16_TO_BUFF_LE_P(output, input) \
130 do { \
131 (output)[0] = ((u8)((input) & 0x00FF)); \
132 (output)[1] = ((u8)((input) >> 8)); \
133 (output) += 2; \
134 } while (0)
135
136 #define SLSI_U32_TO_BUFF_LE_P(output, input) \
137 do { \
138 (*(u32 *)output) = cpu_to_le32(input); \
139 (output) += 4; \
140 } while (0)
141
142 #ifdef CONFIG_SCSC_WLAN_SKB_TRACKING
143 void slsi_dbg_track_skb_init(void);
144 void slsi_dbg_track_skb_reset(void);
145 void slsi_dbg_track_skb_f(struct sk_buff *skb, gfp_t flags, const char *file, int line);
146 bool slsi_dbg_untrack_skb_f(struct sk_buff *skb, const char *file, int line);
147 bool slsi_dbg_track_skb_marker_f(struct sk_buff *skb, const char *file, int line);
148 #define slsi_dbg_track_skb(skb_, flags_) slsi_dbg_track_skb_f(skb_, flags_, __FILE__, __LINE__)
149 #define slsi_dbg_untrack_skb(skb_) slsi_dbg_untrack_skb_f(skb_, __FILE__, __LINE__)
150 #define slsi_dbg_track_skb_marker(skb_) slsi_dbg_track_skb_marker_f(skb_, __FILE__, __LINE__)
151 void slsi_dbg_track_skb_report(void);
152
153 static inline struct sk_buff *slsi_dev_alloc_skb_f(unsigned int length, const char *file, int line)
154 {
155 struct sk_buff *skb = dev_alloc_skb(SLSI_NETIF_SKB_HEADROOM + SLSI_NETIF_SKB_TAILROOM + length);
156
157 if (skb) {
158 #ifdef CONFIG_SCSC_SMAPPER
159 slsi_skb_cb_init(skb);
160 #endif
161 skb_reserve(skb, SLSI_NETIF_SKB_HEADROOM - SLSI_SKB_GET_ALIGNMENT_OFFSET(skb));
162 slsi_dbg_track_skb_f(skb, GFP_ATOMIC, file, line);
163 }
164 return skb;
165 }
166
167 static inline struct sk_buff *slsi_alloc_skb_f(unsigned int size, gfp_t priority, const char *file, int line)
168 {
169 struct sk_buff *skb = alloc_skb(size, priority);
170
171 if (skb) {
172 #ifdef CONFIG_SCSC_SMAPPER
173 slsi_skb_cb_init(skb);
174 #endif
175 slsi_dbg_track_skb_f(skb, priority, file, line);
176 }
177
178 return skb;
179 }
180
181 static inline struct sk_buff *slsi_alloc_skb_headroom_f(unsigned int size, gfp_t priority, const char *file, int line)
182 {
183 struct sk_buff *skb = alloc_skb(SLSI_NETIF_SKB_HEADROOM + SLSI_NETIF_SKB_TAILROOM + size, priority);
184
185 if (skb) {
186 #ifdef CONFIG_SCSC_SMAPPER
187 slsi_skb_cb_init(skb);
188 #endif
189 skb_reserve(skb, SLSI_NETIF_SKB_HEADROOM - SLSI_SKB_GET_ALIGNMENT_OFFSET(skb));
190 slsi_dbg_track_skb_f(skb, priority, file, line);
191 }
192 return skb;
193 }
194
195 static inline void slsi_skb_unlink_f(struct sk_buff *skb, struct sk_buff_head *list, const char *file, int line)
196 {
197 skb_unlink(skb, list);
198 slsi_dbg_track_skb_marker_f(skb, file, line);
199 }
200
201 static inline void slsi_skb_queue_tail_f(struct sk_buff_head *list, struct sk_buff *skb, const char *file, int line)
202 {
203 skb_queue_tail(list, skb);
204 slsi_dbg_track_skb_marker_f(skb, file, line);
205 }
206
207 static inline void slsi_skb_queue_head_f(struct sk_buff_head *list, struct sk_buff *skb, const char *file, int line)
208 {
209 skb_queue_head(list, skb);
210 slsi_dbg_track_skb_marker_f(skb, file, line);
211 }
212
213 static inline struct sk_buff *slsi_skb_dequeue_f(struct sk_buff_head *list, const char *file, int line)
214 {
215 struct sk_buff *skb = skb_dequeue(list);
216
217 if (skb)
218 slsi_dbg_track_skb_marker_f(skb, file, line);
219 return skb;
220 }
221
222 static inline struct sk_buff *slsi_skb_realloc_headroom_f(struct sk_buff *skb, unsigned int headroom, const char *file, int line)
223 {
224 skb = skb_realloc_headroom(skb, headroom);
225 if (skb) {
226 #ifdef CONFIG_SCSC_SMAPPER
227 slsi_skb_cb_init(skb);
228 #endif
229 slsi_dbg_track_skb_f(skb, GFP_ATOMIC, file, line);
230 }
231 return skb;
232 }
233
234 static inline struct sk_buff *slsi_skb_copy_f(struct sk_buff *skb, gfp_t priority, const char *file, int line)
235 {
236 skb = skb_copy(skb, priority);
237
238 if (skb)
239 slsi_dbg_track_skb_f(skb, priority, file, line);
240 return skb;
241 }
242
243 static inline struct sk_buff *skb_copy_expand_f(struct sk_buff *skb, int newheadroom, int newtailroom, gfp_t priority, const char *file, int line)
244 {
245 skb = skb_copy_expand(skb, newheadroom, newtailroom, priority);
246
247 if (skb)
248 slsi_dbg_track_skb_f(skb, priority, file, line);
249 return skb;
250 }
251
252 static inline struct sk_buff *slsi_skb_clone_f(struct sk_buff *skb, gfp_t priority, const char *file, int line)
253 {
254 skb = skb_clone(skb, priority);
255
256 if (skb)
257 slsi_dbg_track_skb_f(skb, priority, file, line);
258 return skb;
259 }
260
261 static inline void slsi_kfree_skb_f(struct sk_buff *skb, const char *file, int line)
262 {
263 /* If untrack fails we do not free the SKB
264 * This helps tracking bad pointers and double frees
265 */
266 #ifdef CONFIG_SCSC_SMAPPER
267 struct slsi_skb_cb *cb;
268
269 if (!skb)
270 return;
271
272 cb = (struct slsi_skb_cb *)skb->cb;
273
274 if (cb && !cb->free_ma_unitdat && cb->skb_addr && slsi_dbg_untrack_skb_f(cb->skb_addr, file, line)) {
275 kfree_skb(cb->skb_addr);
276 cb->skb_addr = NULL;
277 }
278 #endif
279 if (slsi_dbg_untrack_skb_f(skb, file, line))
280 kfree_skb(skb);
281 }
282
283 #define slsi_dev_alloc_skb(length_) slsi_dev_alloc_skb_f(length_, __FILE__, __LINE__)
284 #define slsi_alloc_skb(size_, priority_) slsi_alloc_skb_f(size_, priority_, __FILE__, __LINE__)
285 #define slsi_alloc_skb_headroom(size_, priority_) slsi_alloc_skb_headroom_f(size_, priority_, __FILE__, __LINE__)
286 #define slsi_skb_realloc_headroom(skb_, headroom_) slsi_skb_realloc_headroom_f(skb_, headroom_, __FILE__, __LINE__)
287 #define slsi_skb_copy(skb_, priority_) slsi_skb_copy_f(skb_, priority_, __FILE__, __LINE__)
288 #define slsi_skb_copy_expand(skb_, newheadroom_, newtailroom_, priority_) skb_copy_expand_f(skb_, newheadroom_, newtailroom_, priority_, __FILE__, __LINE__)
289 #define slsi_skb_clone(skb_, priority_) slsi_skb_clone_f(skb_, priority_, __FILE__, __LINE__)
290 #define slsi_kfree_skb(skb_) slsi_kfree_skb_f(skb_, __FILE__, __LINE__)
291 #define slsi_skb_unlink(skb_, list_) slsi_skb_unlink_f(skb_, list_, __FILE__, __LINE__)
292 #define slsi_skb_queue_tail(list_, skb_) slsi_skb_queue_tail_f(list_, skb_, __FILE__, __LINE__)
293 #define slsi_skb_queue_head(list_, skb_) slsi_skb_queue_head_f(list_, skb_, __FILE__, __LINE__)
294 #define slsi_skb_dequeue(list_) slsi_skb_dequeue_f(list_, __FILE__, __LINE__)
295
296 static inline void slsi_skb_queue_purge(struct sk_buff_head *list)
297 {
298 struct sk_buff *skb;
299
300 while ((skb = skb_dequeue(list)) != NULL)
301 slsi_kfree_skb(skb);
302 }
303
304 #else
305 #define slsi_dbg_track_skb_init()
306 #define slsi_dbg_track_skb_reset()
307 #define slsi_dbg_track_skb(skb_, flags_)
308 #define slsi_dbg_untrack_skb(skb_)
309 #define slsi_dbg_track_skb_marker(skb_)
310 #define slsi_dbg_track_skb_report()
311
312 static inline struct sk_buff *slsi_dev_alloc_skb_f(unsigned int length, const char *file, int line)
313 {
314 struct sk_buff *skb = dev_alloc_skb(SLSI_NETIF_SKB_HEADROOM + SLSI_NETIF_SKB_TAILROOM + length);
315
316 SLSI_UNUSED_PARAMETER(file);
317 SLSI_UNUSED_PARAMETER(line);
318 if (skb) {
319 #ifdef CONFIG_SCSC_SMAPPER
320 slsi_skb_cb_init(skb);
321 #endif
322 skb_reserve(skb, SLSI_NETIF_SKB_HEADROOM - SLSI_SKB_GET_ALIGNMENT_OFFSET(skb));
323 }
324 return skb;
325 }
326
327 static inline struct sk_buff *slsi_alloc_skb_f(unsigned int size, gfp_t priority, const char *file, int line)
328 {
329 struct sk_buff *skb = alloc_skb(size, priority);
330
331 SLSI_UNUSED_PARAMETER(file);
332 SLSI_UNUSED_PARAMETER(line);
333 #ifdef CONFIG_SCSC_SMAPPER
334 if (skb)
335 slsi_skb_cb_init(skb);
336 #endif
337 return skb;
338 }
339
340 static inline struct sk_buff *slsi_alloc_skb_headroom_f(unsigned int size, gfp_t priority, const char *file, int line)
341 {
342 struct sk_buff *skb = alloc_skb(SLSI_NETIF_SKB_HEADROOM + SLSI_NETIF_SKB_TAILROOM + size, priority);
343
344 SLSI_UNUSED_PARAMETER(file);
345 SLSI_UNUSED_PARAMETER(line);
346
347 if (skb) {
348 #ifdef CONFIG_SCSC_SMAPPER
349 slsi_skb_cb_init(skb);
350 #endif
351 skb_reserve(skb, SLSI_NETIF_SKB_HEADROOM - SLSI_SKB_GET_ALIGNMENT_OFFSET(skb));
352 }
353 return skb;
354 }
355
356 static inline void slsi_kfree_skb_f(struct sk_buff *skb)
357 {
358 /* If untrack fails we do not free the SKB
359 * This helps tracking bad pointers and double frees
360 */
361 #ifdef CONFIG_SCSC_SMAPPER
362 struct slsi_skb_cb *cb;
363
364 if (!skb)
365 return;
366
367 cb = (struct slsi_skb_cb *)skb->cb;
368
369 if (cb && !cb->free_ma_unitdat && cb->skb_addr) {
370 kfree_skb(cb->skb_addr);
371 cb->skb_addr = NULL;
372 }
373 #endif
374 kfree_skb(skb);
375 }
376
377 #define slsi_dev_alloc_skb(length_) slsi_dev_alloc_skb_f(length_, __FILE__, __LINE__)
378 #define slsi_alloc_skb(size_, priority_) slsi_alloc_skb_f(size_, priority_, __FILE__, __LINE__)
379 #define slsi_alloc_skb_headroom(size_, priority_) slsi_alloc_skb_headroom_f(size_, priority_, __FILE__, __LINE__)
380 #define slsi_skb_realloc_headroom(skb_, headroom_) skb_realloc_headroom(skb_, headroom_)
381 #define slsi_skb_copy(skb_, priority_) skb_copy(skb_, priority_)
382 #define slsi_skb_copy_expand(skb_, newheadroom_, newtailroom_, priority_) skb_copy_expand(skb_, newheadroom_, newtailroom_, priority_)
383 #define slsi_skb_clone(skb_, priority_) skb_clone(skb_, priority_)
384 #define slsi_kfree_skb(skb_) slsi_kfree_skb_f(skb_)
385 #define slsi_skb_unlink(skb_, list_) skb_unlink(skb_, list_)
386 #define slsi_skb_queue_tail(list_, skb_) skb_queue_tail(list_, skb_)
387 #define slsi_skb_queue_head(list_, skb_) skb_queue_head(list_, skb_)
388 #define slsi_skb_dequeue(list_) skb_dequeue(list_)
389 #define slsi_skb_queue_purge(list_) slsi_skb_queue_purge(list_)
390
391 static inline void slsi_skb_queue_purge(struct sk_buff_head *list)
392 {
393 struct sk_buff *skb;
394
395 while ((skb = skb_dequeue(list)) != NULL)
396 slsi_kfree_skb(skb);
397 }
398
399 #endif
400
401 struct slsi_spinlock {
402 /* a std spinlock */
403 spinlock_t lock;
404 unsigned long flags;
405 };
406
407 /* Spinlock create can't fail, so return success regardless. */
408 static inline void slsi_spinlock_create(struct slsi_spinlock *lock)
409 {
410 spin_lock_init(&lock->lock);
411 }
412
413 static inline void slsi_spinlock_lock(struct slsi_spinlock *lock)
414 {
415 spin_lock_bh(&lock->lock);
416 }
417
418 static inline void slsi_spinlock_unlock(struct slsi_spinlock *lock)
419 {
420 spin_unlock_bh(&lock->lock);
421 }
422
423 struct slsi_dev;
424 struct slsi_skb_work {
425 struct slsi_dev *sdev;
426 struct net_device *dev; /* This can be NULL */
427 struct workqueue_struct *workqueue;
428 struct work_struct work;
429 struct sk_buff_head queue;
430 void __rcu *sync_ptr;
431 };
432
433 static inline int slsi_skb_work_init(struct slsi_dev *sdev, struct net_device *dev, struct slsi_skb_work *work, const char *name, void (*func)(struct work_struct *work))
434 {
435 rcu_assign_pointer(work->sync_ptr, (void *)sdev);
436 work->sdev = sdev;
437 work->dev = dev;
438 skb_queue_head_init(&work->queue);
439 INIT_WORK(&work->work, func);
440 work->workqueue = alloc_ordered_workqueue(name, 0);
441
442 if (!work->workqueue)
443 return -ENOMEM;
444 return 0;
445 }
446
447 static inline void slsi_skb_schedule_work(struct slsi_skb_work *work)
448 {
449 queue_work(work->workqueue, &work->work);
450 }
451
452 static inline void slsi_skb_work_enqueue_l(struct slsi_skb_work *work, struct sk_buff *skb)
453 {
454 void *sync_ptr;
455
456 rcu_read_lock();
457
458 sync_ptr = rcu_dereference(work->sync_ptr);
459
460 if (WARN_ON(!sync_ptr)) {
461 slsi_kfree_skb(skb);
462 rcu_read_unlock();
463 return;
464 }
465 skb_queue_tail(&work->queue, skb);
466 slsi_skb_schedule_work(work);
467
468 rcu_read_unlock();
469 }
470
471 static inline struct sk_buff *slsi_skb_work_dequeue_l(struct slsi_skb_work *work)
472 {
473 return skb_dequeue(&work->queue);
474 }
475
476 static inline void slsi_skb_work_deinit(struct slsi_skb_work *work)
477 {
478 rcu_read_lock();
479
480 if (WARN_ON(!work->sync_ptr)) {
481 rcu_read_unlock();
482 return;
483 }
484
485 rcu_assign_pointer(work->sync_ptr, NULL);
486 rcu_read_unlock();
487
488 synchronize_rcu();
489 flush_workqueue(work->workqueue);
490 destroy_workqueue(work->workqueue);
491 work->workqueue = NULL;
492 slsi_skb_queue_purge(&work->queue);
493 }
494
495 static inline void slsi_cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss)
496 {
497 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
498 cfg80211_put_bss(wiphy, bss);
499 #else
500 cfg80211_put_bss(bss);
501 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) */
502 }
503
504 #ifdef CONFIG_SCSC_WLAN_SKB_TRACKING
505 static inline void slsi_skb_work_enqueue_f(struct slsi_skb_work *work, struct sk_buff *skb, const char *file, int line)
506 {
507 slsi_dbg_track_skb_marker_f(skb, file, line);
508 slsi_skb_work_enqueue_l(work, skb);
509 }
510
511 static inline struct sk_buff *slsi_skb_work_dequeue_f(struct slsi_skb_work *work, const char *file, int line)
512 {
513 struct sk_buff *skb;
514
515 skb = slsi_skb_work_dequeue_l(work);
516 if (skb)
517 slsi_dbg_track_skb_marker_f(skb, file, line);
518 return skb;
519 }
520
521 #define slsi_skb_work_enqueue(work_, skb_) slsi_skb_work_enqueue_f(work_, skb_, __FILE__, __LINE__)
522 #define slsi_skb_work_dequeue(work_) slsi_skb_work_dequeue_f(work_, __FILE__, __LINE__)
523 #else
524 #define slsi_skb_work_enqueue(work_, skb_) slsi_skb_work_enqueue_l(work_, skb_)
525 #define slsi_skb_work_dequeue(work_) slsi_skb_work_dequeue_l(work_)
526 #endif
527
528 static inline void slsi_eth_zero_addr(u8 *addr)
529 {
530 memset(addr, 0x00, ETH_ALEN);
531 }
532
533 static inline void slsi_eth_broadcast_addr(u8 *addr)
534 {
535 memset(addr, 0xff, ETH_ALEN);
536 }
537
538 static inline int slsi_str_to_int(char *str, int *result)
539 {
540 int i = 0;
541
542 *result = 0;
543 if ((str[i] == '-') || ((str[i] >= '0') && (str[i] <= '9'))) {
544 if (str[0] == '-')
545 i++;
546 while (str[i] >= '0' && str[i] <= '9') {
547 *result *= 10;
548 *result += (int)str[i++] - '0';
549 }
550
551 *result = ((str[0] == '-') ? (-(*result)) : *result);
552 }
553 return i;
554 }
555
556 #define P80211_OUI_LEN 3
557
558 struct ieee80211_snap_hdr {
559 u8 dsap; /* always 0xAA */
560 u8 ssap; /* always 0xAA */
561 u8 ctrl; /* always 0x03 */
562 u8 oui[P80211_OUI_LEN]; /* organizational universal id */
563 } __packed;
564
565 struct msdu_hdr {
566 unsigned char da[ETH_ALEN];
567 unsigned char sa[ETH_ALEN];
568 __be16 length;
569 struct ieee80211_snap_hdr snap;
570 __be16 ether_type;
571 } __packed;
572
573 #define ETHER_TYPE_SIZE 2
574 #define MSDU_HLEN sizeof(struct msdu_hdr)
575 #define MSDU_LENGTH (sizeof(struct ieee80211_snap_hdr) + sizeof(__be16))
576
577 static inline int slsi_skb_msdu_to_ethhdr(struct sk_buff *skb)
578 {
579 struct ethhdr *eth;
580 struct msdu_hdr *msdu;
581
582 unsigned char da[ETH_ALEN];
583 unsigned char sa[ETH_ALEN];
584 __be16 proto;
585
586 msdu = (struct msdu_hdr *)skb->data;
587 SLSI_ETHER_COPY(da, msdu->da);
588 SLSI_ETHER_COPY(sa, msdu->sa);
589 proto = msdu->ether_type;
590
591 skb_pull(skb, MSDU_HLEN);
592
593 eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
594
595 SLSI_ETHER_COPY(eth->h_dest, da);
596 SLSI_ETHER_COPY(eth->h_source, sa);
597 eth->h_proto = proto;
598
599 return 0;
600 }
601
602 static inline int slsi_skb_ethhdr_to_msdu(struct sk_buff *skb)
603 {
604 struct ethhdr *eth;
605 struct msdu_hdr *msdu;
606 unsigned int len;
607 __be16 ether_type;
608
609 if (skb_headroom(skb) < (MSDU_HLEN - ETH_HLEN))
610 return -EINVAL;
611
612 eth = eth_hdr(skb);
613 ether_type = eth->h_proto;
614
615 len = skb->len;
616
617 skb_pull(skb, ETH_HLEN);
618
619 msdu = (struct msdu_hdr *)skb_push(skb, MSDU_HLEN);
620
621 SLSI_ETHER_COPY(msdu->da, eth->h_dest);
622 SLSI_ETHER_COPY(msdu->sa, eth->h_source);
623 msdu->length = htons(len - ETH_HLEN + MSDU_LENGTH);
624 memcpy(&msdu->snap, rfc1042_header, sizeof(struct ieee80211_snap_hdr));
625 msdu->ether_type = ether_type;
626
627 return 0;
628 }
629
630 static inline u32 slsi_get_center_freq1(struct slsi_dev *sdev, u16 chann_info, u16 center_freq)
631 {
632 u32 center_freq1 = 0x0000;
633
634 SLSI_UNUSED_PARAMETER(sdev);
635
636 switch (chann_info & 0xFF) {
637 case 40:
638 center_freq1 = center_freq - 20 * ((chann_info & 0xFF00) >> 8) + 10;
639 break;
640 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
641 case 80:
642 center_freq1 = center_freq - 20 * ((chann_info & 0xFF00) >> 8) + 30;
643 break;
644 #endif
645 default:
646 break;
647 }
648 return center_freq1;
649 }
650
651 #ifdef __cplusplus
652 }
653 #endif
654
655 #endif /* SLSI_UTILS_H__ */