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