]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/staging/rt2860/rt_linux.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / rt2860 / rt_linux.c
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28 #include <linux/firmware.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include "rt_config.h"
32
33 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
34
35 /* for wireless system event message */
36 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
37 /* system status event */
38 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
39 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
40 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
41 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
42 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
43 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
44 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
45 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
46 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
47 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
48 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
49 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
50 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
51 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
52 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
53 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
54 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
55 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
56 "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
57 };
58
59 /* for wireless IDS_spoof_attack event message */
60 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
61 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
62 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
63 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
64 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
65 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
66 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
67 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
68 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
69 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
70 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
71 };
72
73 /* for wireless IDS_flooding_attack event message */
74 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
75 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
76 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
77 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
78 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
79 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
80 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
81 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
82 };
83
84 /* timeout -- ms */
85 void RTMP_SetPeriodicTimer(struct timer_list * pTimer,
86 IN unsigned long timeout)
87 {
88 timeout = ((timeout * OS_HZ) / 1000);
89 pTimer->expires = jiffies + timeout;
90 add_timer(pTimer);
91 }
92
93 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
94 void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
95 struct timer_list * pTimer,
96 IN TIMER_FUNCTION function, void *data)
97 {
98 init_timer(pTimer);
99 pTimer->data = (unsigned long)data;
100 pTimer->function = function;
101 }
102
103 void RTMP_OS_Add_Timer(struct timer_list * pTimer,
104 IN unsigned long timeout)
105 {
106 if (timer_pending(pTimer))
107 return;
108
109 timeout = ((timeout * OS_HZ) / 1000);
110 pTimer->expires = jiffies + timeout;
111 add_timer(pTimer);
112 }
113
114 void RTMP_OS_Mod_Timer(struct timer_list * pTimer,
115 IN unsigned long timeout)
116 {
117 timeout = ((timeout * OS_HZ) / 1000);
118 mod_timer(pTimer, jiffies + timeout);
119 }
120
121 void RTMP_OS_Del_Timer(struct timer_list * pTimer,
122 OUT BOOLEAN * pCancelled)
123 {
124 if (timer_pending(pTimer)) {
125 *pCancelled = del_timer_sync(pTimer);
126 } else {
127 *pCancelled = TRUE;
128 }
129
130 }
131
132 void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
133 {
134 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
135 }
136
137 /* Unify all delay routine by using udelay */
138 void RTMPusecDelay(unsigned long usec)
139 {
140 unsigned long i;
141
142 for (i = 0; i < (usec / 50); i++)
143 udelay(50);
144
145 if (usec % 50)
146 udelay(usec % 50);
147 }
148
149 void RTMP_GetCurrentSystemTime(LARGE_INTEGER * time)
150 {
151 time->u.LowPart = jiffies;
152 }
153
154 /* pAd MUST allow to be NULL */
155 int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
156 {
157 *mem = (u8 *)kmalloc(size, GFP_ATOMIC);
158 if (*mem)
159 return (NDIS_STATUS_SUCCESS);
160 else
161 return (NDIS_STATUS_FAILURE);
162 }
163
164 /* pAd MUST allow to be NULL */
165 int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
166 {
167
168 ASSERT(mem);
169 kfree(mem);
170 return (NDIS_STATUS_SUCCESS);
171 }
172
173 void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
174 {
175 struct sk_buff *skb;
176 /* Add 2 more bytes for ip header alignment */
177 skb = dev_alloc_skb(size + 2);
178
179 return ((void *)skb);
180 }
181
182 void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
183 unsigned long Length)
184 {
185 struct sk_buff *pkt;
186
187 pkt = dev_alloc_skb(Length);
188
189 if (pkt == NULL) {
190 DBGPRINT(RT_DEBUG_ERROR,
191 ("can't allocate frag rx %ld size packet\n", Length));
192 }
193
194 if (pkt) {
195 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
196 }
197
198 return (void *)pkt;
199 }
200
201 void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
202 unsigned long Length,
203 IN BOOLEAN Cached,
204 void ** VirtualAddress)
205 {
206 struct sk_buff *pkt;
207
208 pkt = dev_alloc_skb(Length);
209
210 if (pkt == NULL) {
211 DBGPRINT(RT_DEBUG_ERROR,
212 ("can't allocate tx %ld size packet\n", Length));
213 }
214
215 if (pkt) {
216 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
217 *VirtualAddress = (void *)pkt->data;
218 } else {
219 *VirtualAddress = (void *)NULL;
220 }
221
222 return (void *)pkt;
223 }
224
225 void build_tx_packet(struct rt_rtmp_adapter *pAd,
226 void *pPacket,
227 u8 *pFrame, unsigned long FrameLen)
228 {
229
230 struct sk_buff *pTxPkt;
231
232 ASSERT(pPacket);
233 pTxPkt = RTPKT_TO_OSPKT(pPacket);
234
235 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
236 }
237
238 void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
239 {
240 struct os_cookie *os_cookie;
241 int index;
242
243 os_cookie = (struct os_cookie *)pAd->OS_Cookie;
244
245 if (pAd->BeaconBuf)
246 kfree(pAd->BeaconBuf);
247
248 NdisFreeSpinLock(&pAd->MgmtRingLock);
249
250 #ifdef RTMP_MAC_PCI
251 NdisFreeSpinLock(&pAd->RxRingLock);
252 #ifdef RT3090
253 NdisFreeSpinLock(&pAd->McuCmdLock);
254 #endif /* RT3090 // */
255 #endif /* RTMP_MAC_PCI // */
256
257 for (index = 0; index < NUM_OF_TX_RING; index++) {
258 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
259 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
260 pAd->DeQueueRunning[index] = FALSE;
261 }
262
263 NdisFreeSpinLock(&pAd->irq_lock);
264
265 release_firmware(pAd->firmware);
266
267 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
268 if (os_cookie)
269 kfree(os_cookie);
270 }
271
272 BOOLEAN OS_Need_Clone_Packet(void)
273 {
274 return (FALSE);
275 }
276
277 /*
278 ========================================================================
279
280 Routine Description:
281 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
282 must have only one NDIS BUFFER
283 return - byte copied. 0 means can't create NDIS PACKET
284 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
285
286 Arguments:
287 pAd Pointer to our adapter
288 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
289 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
290
291 Return Value:
292 NDIS_STATUS_SUCCESS
293 NDIS_STATUS_FAILURE
294
295 Note:
296
297 ========================================================================
298 */
299 int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
300 IN BOOLEAN pInsAMSDUHdr,
301 void *pInPacket,
302 void ** ppOutPacket)
303 {
304
305 struct sk_buff *pkt;
306
307 ASSERT(pInPacket);
308 ASSERT(ppOutPacket);
309
310 /* 1. Allocate a packet */
311 pkt = dev_alloc_skb(2048);
312
313 if (pkt == NULL) {
314 return NDIS_STATUS_FAILURE;
315 }
316
317 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
318 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
319 GET_OS_PKT_LEN(pInPacket));
320 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
321
322 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
323
324 printk("###Clone###\n");
325
326 return NDIS_STATUS_SUCCESS;
327 }
328
329 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
330 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
331 void ** ppPacket,
332 u8 *pHeader,
333 u32 HeaderLen,
334 u8 *pData, u32 DataLen)
335 {
336 void *pPacket;
337 ASSERT(pData);
338 ASSERT(DataLen);
339
340 /* 1. Allocate a packet */
341 pPacket =
342 (void **) dev_alloc_skb(HeaderLen + DataLen +
343 RTMP_PKT_TAIL_PADDING);
344 if (pPacket == NULL) {
345 *ppPacket = NULL;
346 #ifdef DEBUG
347 printk("RTMPAllocateNdisPacket Fail\n");
348 #endif
349 return NDIS_STATUS_FAILURE;
350 }
351 /* 2. clone the frame content */
352 if (HeaderLen > 0)
353 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
354 if (DataLen > 0)
355 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
356 DataLen);
357
358 /* 3. update length of packet */
359 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
360
361 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
362 /* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
363 *ppPacket = pPacket;
364 return NDIS_STATUS_SUCCESS;
365 }
366
367 /*
368 ========================================================================
369 Description:
370 This routine frees a miniport internally allocated char and its
371 corresponding NDIS_BUFFER and allocated memory.
372 ========================================================================
373 */
374 void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
375 {
376 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
377 }
378
379 /* IRQL = DISPATCH_LEVEL */
380 /* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
381 /* scatter gather buffer */
382 int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
383 u8 DesiredOffset,
384 u8 *pByte0, u8 *pByte1)
385 {
386 *pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
387 *pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
388
389 return NDIS_STATUS_SUCCESS;
390 }
391
392 void RTMP_QueryPacketInfo(void *pPacket,
393 struct rt_packet_info *pPacketInfo,
394 u8 ** pSrcBufVA, u32 * pSrcBufLen)
395 {
396 pPacketInfo->BufferCount = 1;
397 pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
398 pPacketInfo->PhysicalBufferCount = 1;
399 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
400
401 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
402 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
403 }
404
405 void RTMP_QueryNextPacketInfo(void ** ppPacket,
406 struct rt_packet_info *pPacketInfo,
407 u8 ** pSrcBufVA, u32 * pSrcBufLen)
408 {
409 void *pPacket = NULL;
410
411 if (*ppPacket)
412 pPacket = GET_OS_PKT_NEXT(*ppPacket);
413
414 if (pPacket) {
415 pPacketInfo->BufferCount = 1;
416 pPacketInfo->pFirstBuffer =
417 (char *)GET_OS_PKT_DATAPTR(pPacket);
418 pPacketInfo->PhysicalBufferCount = 1;
419 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
420
421 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
422 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
423 *ppPacket = GET_OS_PKT_NEXT(pPacket);
424 } else {
425 pPacketInfo->BufferCount = 0;
426 pPacketInfo->pFirstBuffer = NULL;
427 pPacketInfo->PhysicalBufferCount = 0;
428 pPacketInfo->TotalPacketLength = 0;
429
430 *pSrcBufVA = NULL;
431 *pSrcBufLen = 0;
432 *ppPacket = NULL;
433 }
434 }
435
436 void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
437 void *pPacket, u8 FromWhichBSSID)
438 {
439 struct sk_buff *skb;
440 void *pRetPacket = NULL;
441 u16 DataSize;
442 u8 *pData;
443
444 DataSize = (u16)GET_OS_PKT_LEN(pPacket);
445 pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
446
447 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
448 if (skb) {
449 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
450 pRetPacket = OSPKT_TO_RTPKT(skb);
451 }
452
453 return pRetPacket;
454
455 }
456
457 void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
458 u8 *pHeader802_3,
459 u32 HdrLen,
460 u8 *pData,
461 unsigned long DataSize, u8 FromWhichBSSID)
462 {
463 struct sk_buff *skb;
464 void *pPacket = NULL;
465
466 if ((skb =
467 __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
468 skb_reserve(skb, 2);
469 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
470 skb_put(skb, HdrLen);
471 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
472 skb_put(skb, DataSize);
473 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
474 pPacket = OSPKT_TO_RTPKT(skb);
475 }
476
477 return pPacket;
478 }
479
480 #define TKIP_TX_MIC_SIZE 8
481 void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
482 void *pPacket)
483 {
484 struct sk_buff *skb, *newskb;
485
486 skb = RTPKT_TO_OSPKT(pPacket);
487 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
488 /* alloc a new skb and copy the packet */
489 newskb =
490 skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
491 GFP_ATOMIC);
492 dev_kfree_skb_any(skb);
493 if (newskb == NULL) {
494 DBGPRINT(RT_DEBUG_ERROR,
495 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
496 return NULL;
497 }
498 skb = newskb;
499 }
500
501 return OSPKT_TO_RTPKT(skb);
502 }
503
504 void *ClonePacket(struct rt_rtmp_adapter *pAd,
505 void *pPacket,
506 u8 *pData, unsigned long DataSize)
507 {
508 struct sk_buff *pRxPkt;
509 struct sk_buff *pClonedPkt;
510
511 ASSERT(pPacket);
512 pRxPkt = RTPKT_TO_OSPKT(pPacket);
513
514 /* clone the packet */
515 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
516
517 if (pClonedPkt) {
518 /* set the correct dataptr and data len */
519 pClonedPkt->dev = pRxPkt->dev;
520 pClonedPkt->data = pData;
521 pClonedPkt->len = DataSize;
522 skb_set_tail_pointer(pClonedPkt, DataSize)
523 ASSERT(DataSize < 1530);
524 }
525 return pClonedPkt;
526 }
527
528 /* */
529 /* change OS packet DataPtr and DataLen */
530 /* */
531 void update_os_packet_info(struct rt_rtmp_adapter *pAd,
532 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
533 {
534 struct sk_buff *pOSPkt;
535
536 ASSERT(pRxBlk->pRxPacket);
537 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
538
539 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
540 pOSPkt->data = pRxBlk->pData;
541 pOSPkt->len = pRxBlk->DataSize;
542 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
543 }
544
545 void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
546 struct rt_rx_blk *pRxBlk,
547 u8 *pHeader802_3,
548 u8 FromWhichBSSID)
549 {
550 struct sk_buff *pOSPkt;
551
552 ASSERT(pRxBlk->pRxPacket);
553 ASSERT(pHeader802_3);
554
555 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
556
557 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
558 pOSPkt->data = pRxBlk->pData;
559 pOSPkt->len = pRxBlk->DataSize;
560 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
561
562 /* */
563 /* copy 802.3 header */
564 /* */
565 /* */
566
567 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
568 LENGTH_802_3);
569 }
570
571 void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
572 {
573
574 struct sk_buff *pRxPkt;
575
576 ASSERT(pPacket);
577
578 pRxPkt = RTPKT_TO_OSPKT(pPacket);
579
580 /* Push up the protocol stack */
581 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
582
583 netif_rx(pRxPkt);
584 }
585
586 struct rt_rtmp_sg_list *
587 rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
588 {
589 sg->NumberOfElements = 1;
590 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
591 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
592 return (sg);
593 }
594
595 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
596 {
597 unsigned char *pt;
598 int x;
599
600 if (RTDebugLevel < RT_DEBUG_TRACE)
601 return;
602
603 pt = pSrcBufVA;
604 printk("%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
605 for (x = 0; x < SrcBufLen; x++) {
606 if (x % 16 == 0)
607 printk("0x%04x : ", x);
608 printk("%02x ", ((unsigned char)pt[x]));
609 if (x % 16 == 15)
610 printk("\n");
611 }
612 printk("\n");
613 }
614
615 /*
616 ========================================================================
617
618 Routine Description:
619 Send log message through wireless event
620
621 Support standard iw_event with IWEVCUSTOM. It is used below.
622
623 iwreq_data.data.flags is used to store event_flag that is defined by user.
624 iwreq_data.data.length is the length of the event log.
625
626 The format of the event log is composed of the entry's MAC address and
627 the desired log message (refer to pWirelessEventText).
628
629 ex: 11:22:33:44:55:66 has associated successfully
630
631 p.s. The requirement of Wireless Extension is v15 or newer.
632
633 ========================================================================
634 */
635 void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
636 u16 Event_flag,
637 u8 *pAddr, u8 BssIdx, char Rssi)
638 {
639
640 /*union iwreq_data wrqu; */
641 char *pBuf = NULL, *pBufPtr = NULL;
642 u16 event, type, BufLen;
643 u8 event_table_len = 0;
644
645 type = Event_flag & 0xFF00;
646 event = Event_flag & 0x00FF;
647
648 switch (type) {
649 case IW_SYS_EVENT_FLAG_START:
650 event_table_len = IW_SYS_EVENT_TYPE_NUM;
651 break;
652
653 case IW_SPOOF_EVENT_FLAG_START:
654 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
655 break;
656
657 case IW_FLOOD_EVENT_FLAG_START:
658 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
659 break;
660 }
661
662 if (event_table_len == 0) {
663 DBGPRINT(RT_DEBUG_ERROR,
664 ("%s : The type(%0x02x) is not valid.\n", __func__,
665 type));
666 return;
667 }
668
669 if (event >= event_table_len) {
670 DBGPRINT(RT_DEBUG_ERROR,
671 ("%s : The event(%0x02x) is not valid.\n", __func__,
672 event));
673 return;
674 }
675 /*Allocate memory and copy the msg. */
676 if ((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) {
677 /*Prepare the payload */
678 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
679
680 pBufPtr = pBuf;
681
682 if (pAddr)
683 pBufPtr +=
684 sprintf(pBufPtr,
685 "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ",
686 PRINT_MAC(pAddr));
687 else if (BssIdx < MAX_MBSSID_NUM)
688 pBufPtr +=
689 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
690 else
691 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
692
693 if (type == IW_SYS_EVENT_FLAG_START)
694 pBufPtr +=
695 sprintf(pBufPtr, "%s",
696 pWirelessSysEventText[event]);
697 else if (type == IW_SPOOF_EVENT_FLAG_START)
698 pBufPtr +=
699 sprintf(pBufPtr, "%s (RSSI=%d)",
700 pWirelessSpoofEventText[event], Rssi);
701 else if (type == IW_FLOOD_EVENT_FLAG_START)
702 pBufPtr +=
703 sprintf(pBufPtr, "%s",
704 pWirelessFloodEventText[event]);
705 else
706 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
707
708 pBufPtr[pBufPtr - pBuf] = '\0';
709 BufLen = pBufPtr - pBuf;
710
711 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
712 (u8 *)pBuf, BufLen);
713 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
714
715 kfree(pBuf);
716 } else
717 DBGPRINT(RT_DEBUG_ERROR,
718 ("%s : Can't allocate memory for wireless event.\n",
719 __func__));
720 }
721
722 void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
723 {
724 struct sk_buff *pOSPkt;
725 struct rt_wlan_ng_prism2_header *ph;
726 int rate_index = 0;
727 u16 header_len = 0;
728 u8 temp_header[40] = { 0 };
729
730 u_int32_t ralinkrate[256] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112, 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, 27, 54, 81, 108, 162, 216, 243, 270, /* Last 38 */
731 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
732 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
733 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
734 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
735 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
736 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
737 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
738 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
739 72, 73, 74, 75, 76, 77, 78, 79, 80
740 };
741
742 ASSERT(pRxBlk->pRxPacket);
743 if (pRxBlk->DataSize < 10) {
744 DBGPRINT(RT_DEBUG_ERROR,
745 ("%s : Size is too small! (%d)\n", __func__,
746 pRxBlk->DataSize));
747 goto err_free_sk_buff;
748 }
749
750 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
751 RX_BUFFER_AGGRESIZE) {
752 DBGPRINT(RT_DEBUG_ERROR,
753 ("%s : Size is too large! (%zu)\n", __func__,
754 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
755 goto err_free_sk_buff;
756 }
757
758 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
759 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
760 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
761 pRxBlk->DataSize -= LENGTH_802_11;
762 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
763 (pRxBlk->pHeader->FC.FrDs == 1))
764 header_len = LENGTH_802_11_WITH_ADDR4;
765 else
766 header_len = LENGTH_802_11;
767
768 /* QOS */
769 if (pRxBlk->pHeader->FC.SubType & 0x08) {
770 header_len += 2;
771 /* Data skip QOS contorl field */
772 pRxBlk->DataSize -= 2;
773 }
774 /* Order bit: A-Ralink or HTC+ */
775 if (pRxBlk->pHeader->FC.Order) {
776 header_len += 4;
777 /* Data skip HTC contorl field */
778 pRxBlk->DataSize -= 4;
779 }
780 /* Copy Header */
781 if (header_len <= 40)
782 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
783
784 /* skip HW padding */
785 if (pRxBlk->RxD.L2PAD)
786 pRxBlk->pData += (header_len + 2);
787 else
788 pRxBlk->pData += header_len;
789 } /*end if */
790
791 if (pRxBlk->DataSize < pOSPkt->len) {
792 skb_trim(pOSPkt, pRxBlk->DataSize);
793 } else {
794 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
795 } /*end if */
796
797 if ((pRxBlk->pData - pOSPkt->data) > 0) {
798 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
799 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
800 } /*end if */
801
802 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
803 if (pskb_expand_head
804 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
805 GFP_ATOMIC)) {
806 DBGPRINT(RT_DEBUG_ERROR,
807 ("%s : Reallocate header size of sk_buff fail!\n",
808 __func__));
809 goto err_free_sk_buff;
810 } /*end if */
811 } /*end if */
812
813 if (header_len > 0)
814 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
815 header_len);
816
817 ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
818 sizeof(struct rt_wlan_ng_prism2_header));
819 NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
820
821 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
822 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
823 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
824
825 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
826 ph->hosttime.status = 0;
827 ph->hosttime.len = 4;
828 ph->hosttime.data = jiffies;
829
830 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
831 ph->mactime.status = 0;
832 ph->mactime.len = 0;
833 ph->mactime.data = 0;
834
835 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
836 ph->istx.status = 0;
837 ph->istx.len = 0;
838 ph->istx.data = 0;
839
840 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
841 ph->channel.status = 0;
842 ph->channel.len = 4;
843
844 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
845
846 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
847 ph->rssi.status = 0;
848 ph->rssi.len = 4;
849 ph->rssi.data =
850 (u_int32_t) RTMPMaxRssi(pAd,
851 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
852 RSSI_0), ConvertToRssi(pAd,
853 pRxBlk->
854 pRxWI->
855 RSSI1,
856 RSSI_1),
857 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
858 RSSI_2));;
859
860 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
861 ph->signal.status = 0;
862 ph->signal.len = 4;
863 ph->signal.data = 0; /*rssi + noise; */
864
865 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
866 ph->noise.status = 0;
867 ph->noise.len = 4;
868 ph->noise.data = 0;
869
870 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
871 rate_index =
872 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
873 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
874 ((u8)pRxBlk->pRxWI->MCS);
875 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
876 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
877 else
878 rate_index = (u8)(pRxBlk->pRxWI->MCS);
879 if (rate_index < 0)
880 rate_index = 0;
881 if (rate_index > 255)
882 rate_index = 255;
883
884 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
885 ph->rate.status = 0;
886 ph->rate.len = 4;
887 ph->rate.data = ralinkrate[rate_index];
888
889 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
890 ph->frmlen.status = 0;
891 ph->frmlen.len = 4;
892 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
893
894 pOSPkt->pkt_type = PACKET_OTHERHOST;
895 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
896 pOSPkt->ip_summed = CHECKSUM_NONE;
897 netif_rx(pOSPkt);
898
899 return;
900
901 err_free_sk_buff:
902 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
903 return;
904
905 }
906
907 /*******************************************************************************
908
909 Device IRQ related functions.
910
911 *******************************************************************************/
912 int RtmpOSIRQRequest(struct net_device *pNetDev)
913 {
914 #ifdef RTMP_PCI_SUPPORT
915 struct net_device *net_dev = pNetDev;
916 struct rt_rtmp_adapter *pAd = NULL;
917 int retval = 0;
918
919 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
920
921 ASSERT(pAd);
922
923 if (pAd->infType == RTMP_DEV_INF_PCI) {
924 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
925 RTMP_MSI_ENABLE(pAd);
926 retval =
927 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
928 (net_dev)->name, (net_dev));
929 if (retval != 0)
930 printk("RT2860: request_irq ERROR(%d)\n", retval);
931 }
932
933 return retval;
934 #else
935 return 0;
936 #endif
937 }
938
939 int RtmpOSIRQRelease(struct net_device *pNetDev)
940 {
941 struct net_device *net_dev = pNetDev;
942 struct rt_rtmp_adapter *pAd = NULL;
943
944 GET_PAD_FROM_NET_DEV(pAd, net_dev);
945
946 ASSERT(pAd);
947
948 #ifdef RTMP_PCI_SUPPORT
949 if (pAd->infType == RTMP_DEV_INF_PCI) {
950 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
951 synchronize_irq(pObj->pci_dev->irq);
952 free_irq(pObj->pci_dev->irq, (net_dev));
953 RTMP_MSI_DISABLE(pAd);
954 }
955 #endif /* RTMP_PCI_SUPPORT // */
956
957 return 0;
958 }
959
960 /*******************************************************************************
961
962 File open/close related functions.
963
964 *******************************************************************************/
965 struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
966 {
967 struct file *filePtr;
968
969 filePtr = filp_open(pPath, flag, 0);
970 if (IS_ERR(filePtr)) {
971 DBGPRINT(RT_DEBUG_ERROR,
972 ("%s(): Error %ld opening %s\n", __func__,
973 -PTR_ERR(filePtr), pPath));
974 }
975
976 return (struct file *)filePtr;
977 }
978
979 int RtmpOSFileClose(struct file *osfd)
980 {
981 filp_close(osfd, NULL);
982 return 0;
983 }
984
985 void RtmpOSFileSeek(struct file *osfd, int offset)
986 {
987 osfd->f_pos = offset;
988 }
989
990 int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
991 {
992 /* The object must have a read method */
993 if (osfd->f_op && osfd->f_op->read) {
994 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
995 } else {
996 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
997 return -1;
998 }
999 }
1000
1001 int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
1002 {
1003 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
1004 &osfd->f_pos);
1005 }
1006
1007 /*******************************************************************************
1008
1009 Task create/management/kill related functions.
1010
1011 *******************************************************************************/
1012 int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
1013 {
1014 struct rt_rtmp_adapter *pAd;
1015 int ret = NDIS_STATUS_FAILURE;
1016
1017 pAd = (struct rt_rtmp_adapter *)pTask->priv;
1018
1019 #ifdef KTHREAD_SUPPORT
1020 if (pTask->kthread_task) {
1021 kthread_stop(pTask->kthread_task);
1022 ret = NDIS_STATUS_SUCCESS;
1023 }
1024 #else
1025 CHECK_PID_LEGALITY(pTask->taskPID) {
1026 printk("Terminate the task(%s) with pid(%d)!\n",
1027 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1028 mb();
1029 pTask->task_killed = 1;
1030 mb();
1031 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1032 if (ret) {
1033 printk(KERN_WARNING
1034 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1035 pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
1036 ret);
1037 } else {
1038 wait_for_completion(&pTask->taskComplete);
1039 pTask->taskPID = THREAD_PID_INIT_VALUE;
1040 pTask->task_killed = 0;
1041 ret = NDIS_STATUS_SUCCESS;
1042 }
1043 }
1044 #endif
1045
1046 return ret;
1047
1048 }
1049
1050 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
1051 {
1052
1053 #ifndef KTHREAD_SUPPORT
1054 complete_and_exit(&pTask->taskComplete, 0);
1055 #endif
1056
1057 return 0;
1058 }
1059
1060 void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
1061 {
1062
1063 #ifndef KTHREAD_SUPPORT
1064
1065 daemonize((char *)& pTask->taskName[0] /*"%s",pAd->net_dev->name */ );
1066
1067 allow_signal(SIGTERM);
1068 allow_signal(SIGKILL);
1069 current->flags |= PF_NOFREEZE;
1070
1071 /* signal that we've started the thread */
1072 complete(&pTask->taskComplete);
1073
1074 #endif
1075 }
1076
1077 int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
1078 IN int (*fn) (void *), IN void *arg)
1079 {
1080 int status = NDIS_STATUS_SUCCESS;
1081
1082 #ifdef KTHREAD_SUPPORT
1083 pTask->task_killed = 0;
1084 pTask->kthread_task = NULL;
1085 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1086 if (IS_ERR(pTask->kthread_task))
1087 status = NDIS_STATUS_FAILURE;
1088 #else
1089 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1090 if (pid_number < 0) {
1091 DBGPRINT(RT_DEBUG_ERROR,
1092 ("Attach task(%s) failed!\n", pTask->taskName));
1093 status = NDIS_STATUS_FAILURE;
1094 } else {
1095 pTask->taskPID = GET_PID(pid_number);
1096
1097 /* Wait for the thread to start */
1098 wait_for_completion(&pTask->taskComplete);
1099 status = NDIS_STATUS_SUCCESS;
1100 }
1101 #endif
1102 return status;
1103 }
1104
1105 int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
1106 char *pTaskName, void * pPriv)
1107 {
1108 int len;
1109
1110 ASSERT(pTask);
1111
1112 #ifndef KTHREAD_SUPPORT
1113 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
1114 #endif
1115
1116 len = strlen(pTaskName);
1117 len =
1118 len >
1119 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
1120 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1121 pTask->priv = pPriv;
1122
1123 #ifndef KTHREAD_SUPPORT
1124 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1125 pTask->taskPID = THREAD_PID_INIT_VALUE;
1126
1127 init_completion(&pTask->taskComplete);
1128 #endif
1129
1130 return NDIS_STATUS_SUCCESS;
1131 }
1132
1133 void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
1134 {
1135 if (pAd->CommonCfg.bWirelessEvent) {
1136 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1137 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1138 pAd->MacTab.Content[BSSID_WCID].
1139 Addr, BSS0, 0);
1140 } else {
1141 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1142 pAd->MacTab.Content[BSSID_WCID].
1143 Addr, BSS0, 0);
1144 }
1145 }
1146 }
1147
1148 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
1149 u32 eventType,
1150 int flags,
1151 u8 *pSrcMac,
1152 u8 *pData, u32 dataLen)
1153 {
1154 union iwreq_data wrqu;
1155
1156 memset(&wrqu, 0, sizeof(wrqu));
1157
1158 if (flags > -1)
1159 wrqu.data.flags = flags;
1160
1161 if (pSrcMac)
1162 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1163
1164 if ((pData != NULL) && (dataLen > 0))
1165 wrqu.data.length = dataLen;
1166
1167 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1168 return 0;
1169 }
1170
1171 int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
1172 {
1173 struct net_device *net_dev;
1174 struct rt_rtmp_adapter *pAd;
1175
1176 net_dev = pNetDev;
1177 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1178
1179 /* work-around for the SuSE due to it has it's own interface name management system. */
1180 {
1181 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1182 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1183 strlen(net_dev->name));
1184 }
1185
1186 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1187
1188 return 0;
1189 }
1190
1191 /*
1192 * Assign the network dev name for created Ralink WiFi interface.
1193 */
1194 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
1195 struct net_device *dev,
1196 char *pPrefixStr, int devIdx)
1197 {
1198 struct net_device *existNetDev;
1199 char suffixName[IFNAMSIZ];
1200 char desiredName[IFNAMSIZ];
1201 int ifNameIdx, prefixLen, slotNameLen;
1202 int Status;
1203
1204 prefixLen = strlen(pPrefixStr);
1205 ASSERT((prefixLen < IFNAMSIZ));
1206
1207 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
1208 memset(suffixName, 0, IFNAMSIZ);
1209 memset(desiredName, 0, IFNAMSIZ);
1210 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1211
1212 sprintf(suffixName, "%d", ifNameIdx);
1213
1214 slotNameLen = strlen(suffixName);
1215 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1216 strcat(desiredName, suffixName);
1217
1218 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1219 if (existNetDev == NULL)
1220 break;
1221 else
1222 RtmpOSNetDeviceRefPut(existNetDev);
1223 }
1224
1225 if (ifNameIdx < 32) {
1226 strcpy(&dev->name[0], &desiredName[0]);
1227 Status = NDIS_STATUS_SUCCESS;
1228 } else {
1229 DBGPRINT(RT_DEBUG_ERROR,
1230 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1231 pPrefixStr));
1232 Status = NDIS_STATUS_FAILURE;
1233 }
1234
1235 return Status;
1236 }
1237
1238 void RtmpOSNetDevClose(struct net_device *pNetDev)
1239 {
1240 dev_close(pNetDev);
1241 }
1242
1243 void RtmpOSNetDevFree(struct net_device *pNetDev)
1244 {
1245 ASSERT(pNetDev);
1246
1247 free_netdev(pNetDev);
1248 }
1249
1250 int RtmpOSNetDevAlloc(struct net_device ** new_dev_p, u32 privDataSize)
1251 {
1252 /* assign it as null first. */
1253 *new_dev_p = NULL;
1254
1255 DBGPRINT(RT_DEBUG_TRACE,
1256 ("Allocate a net device with private data size=%d!\n",
1257 privDataSize));
1258 *new_dev_p = alloc_etherdev(privDataSize);
1259 if (*new_dev_p)
1260 return NDIS_STATUS_SUCCESS;
1261 else
1262 return NDIS_STATUS_FAILURE;
1263 }
1264
1265 struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
1266 {
1267 struct net_device *pTargetNetDev = NULL;
1268
1269 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1270
1271 return pTargetNetDev;
1272 }
1273
1274 void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
1275 {
1276 /*
1277 every time dev_get_by_name is called, and it has returned a valid struct
1278 net_device*, dev_put should be called afterwards, because otherwise the
1279 machine hangs when the device is unregistered (since dev->refcnt > 1).
1280 */
1281 if (pNetDev)
1282 dev_put(pNetDev);
1283 }
1284
1285 int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
1286 {
1287
1288 /* TODO: Need to fix this */
1289 printk("WARNING: This function(%s) not implement yet!\n", __func__);
1290 return 0;
1291 }
1292
1293 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1294 {
1295 unregister_netdev(pNetDev);
1296 }
1297
1298 int RtmpOSNetDevAttach(struct net_device *pNetDev,
1299 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
1300 {
1301 int ret, rtnl_locked = FALSE;
1302
1303 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1304 /* If we need hook some callback function to the net device structrue, now do it. */
1305 if (pDevOpHook) {
1306 struct rt_rtmp_adapter *pAd = NULL;
1307
1308 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1309
1310 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1311
1312 /* OS specific flags, here we used to indicate if we are virtual interface */
1313 pNetDev->priv_flags = pDevOpHook->priv_flags;
1314
1315 if (pAd->OpMode == OPMODE_STA) {
1316 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1317 }
1318
1319 /* copy the net device mac address to the net_device structure. */
1320 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1321 MAC_ADDR_LEN);
1322
1323 rtnl_locked = pDevOpHook->needProtcted;
1324 }
1325
1326 if (rtnl_locked)
1327 ret = register_netdevice(pNetDev);
1328 else
1329 ret = register_netdev(pNetDev);
1330
1331 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1332 if (ret == 0)
1333 return NDIS_STATUS_SUCCESS;
1334 else
1335 return NDIS_STATUS_FAILURE;
1336 }
1337
1338 struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
1339 int devType,
1340 int devNum,
1341 int privMemSize, char *pNamePrefix)
1342 {
1343 struct net_device *pNetDev = NULL;
1344 int status;
1345
1346 /* allocate a new network device */
1347 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */ );
1348 if (status != NDIS_STATUS_SUCCESS) {
1349 /* allocation fail, exit */
1350 DBGPRINT(RT_DEBUG_ERROR,
1351 ("Allocate network device fail (%s)...\n",
1352 pNamePrefix));
1353 return NULL;
1354 }
1355
1356 /* find a available interface name, max 32 interfaces */
1357 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1358 if (status != NDIS_STATUS_SUCCESS) {
1359 /* error! no any available ra name can be used! */
1360 DBGPRINT(RT_DEBUG_ERROR,
1361 ("Assign interface name (%s with suffix 0~32) failed...\n",
1362 pNamePrefix));
1363 RtmpOSNetDevFree(pNetDev);
1364
1365 return NULL;
1366 } else {
1367 DBGPRINT(RT_DEBUG_TRACE,
1368 ("The name of the new %s interface is %s...\n",
1369 pNamePrefix, pNetDev->name));
1370 }
1371
1372 return pNetDev;
1373 }