b396a9b570e2f165ed1bb966af75932fe6a4622e
[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 "rt_config.h"
29
30 ULONG   RTDebugLevel = RT_DEBUG_ERROR;
31
32 BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
34 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
35 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
36 #ifdef RT2870
37 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
38 #endif // RT2870 //
39
40 BUILD_TIMER_FUNCTION(BeaconTimeout);
41 BUILD_TIMER_FUNCTION(ScanTimeout);
42 BUILD_TIMER_FUNCTION(AuthTimeout);
43 BUILD_TIMER_FUNCTION(AssocTimeout);
44 BUILD_TIMER_FUNCTION(ReassocTimeout);
45 BUILD_TIMER_FUNCTION(DisassocTimeout);
46 BUILD_TIMER_FUNCTION(LinkDownExec);
47 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
48 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
49 #ifdef RT2860
50 BUILD_TIMER_FUNCTION(PsPollWakeExec);
51 BUILD_TIMER_FUNCTION(RadioOnExec);
52 #endif
53
54 // for wireless system event message
55 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
56         // system status event
57     "had associated successfully",                                                      /* IW_ASSOC_EVENT_FLAG */
58     "had disassociated",                                                                        /* IW_DISASSOC_EVENT_FLAG */
59     "had deauthenticated",                                                                      /* IW_DEAUTH_EVENT_FLAG */
60     "had been aged-out and disassociated",                                      /* IW_AGEOUT_EVENT_FLAG */
61     "occurred CounterMeasures attack",                                          /* IW_COUNTER_MEASURES_EVENT_FLAG */
62     "occurred replay counter different in Key Handshaking",     /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
63     "occurred RSNIE different in Key Handshaking",                      /* IW_RSNIE_DIFF_EVENT_FLAG */
64     "occurred MIC different in Key Handshaking",                        /* IW_MIC_DIFF_EVENT_FLAG */
65     "occurred ICV error in RX",                                                         /* IW_ICV_ERROR_EVENT_FLAG */
66     "occurred MIC error in RX",                                                         /* IW_MIC_ERROR_EVENT_FLAG */
67         "Group Key Handshaking timeout",                                                /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
68         "Pairwise Key Handshaking timeout",                                             /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
69         "RSN IE sanity check failure",                                                  /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
70         "set key done in WPA/WPAPSK",                                                   /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
71         "set key done in WPA2/WPA2PSK",                         /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
72         "connects with our wireless client",                    /* IW_STA_LINKUP_EVENT_FLAG */
73         "disconnects with our wireless client",                 /* IW_STA_LINKDOWN_EVENT_FLAG */
74         "scan completed"                                                                                /* IW_SCAN_COMPLETED_EVENT_FLAG */
75         "scan terminate!! Busy!! Enqueue fail!!"                                /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
76         };
77
78 // for wireless IDS_spoof_attack event message
79 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
80     "detected conflict SSID",                                                           /* IW_CONFLICT_SSID_EVENT_FLAG */
81     "detected spoofed association response",                            /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
82     "detected spoofed reassociation responses",                         /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
83     "detected spoofed probe response",                                          /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
84     "detected spoofed beacon",                                                          /* IW_SPOOF_BEACON_EVENT_FLAG */
85     "detected spoofed disassociation",                                          /* IW_SPOOF_DISASSOC_EVENT_FLAG */
86     "detected spoofed authentication",                                          /* IW_SPOOF_AUTH_EVENT_FLAG */
87     "detected spoofed deauthentication",                                        /* IW_SPOOF_DEAUTH_EVENT_FLAG */
88     "detected spoofed unknown management frame",                        /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
89         "detected replay attack"                                                                /* IW_REPLAY_ATTACK_EVENT_FLAG */
90         };
91
92 // for wireless IDS_flooding_attack event message
93 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
94         "detected authentication flooding",                                             /* IW_FLOOD_AUTH_EVENT_FLAG */
95     "detected association request flooding",                            /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
96     "detected reassociation request flooding",                          /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
97     "detected probe request flooding",                                          /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
98     "detected disassociation flooding",                                         /* IW_FLOOD_DISASSOC_EVENT_FLAG */
99     "detected deauthentication flooding",                                       /* IW_FLOOD_DEAUTH_EVENT_FLAG */
100     "detected 802.1x eap-request flooding"                                      /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
101         };
102
103 /* timeout -- ms */
104 VOID RTMP_SetPeriodicTimer(
105         IN      NDIS_MINIPORT_TIMER *pTimer,
106         IN      unsigned long timeout)
107 {
108         timeout = ((timeout*HZ) / 1000);
109         pTimer->expires = jiffies + timeout;
110         add_timer(pTimer);
111 }
112
113 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
114 VOID RTMP_OS_Init_Timer(
115         IN      PRTMP_ADAPTER pAd,
116         IN      NDIS_MINIPORT_TIMER *pTimer,
117         IN      TIMER_FUNCTION function,
118         IN      PVOID data)
119 {
120         init_timer(pTimer);
121     pTimer->data = (unsigned long)data;
122     pTimer->function = function;
123 }
124
125
126 VOID RTMP_OS_Add_Timer(
127         IN      NDIS_MINIPORT_TIMER             *pTimer,
128         IN      unsigned long timeout)
129 {
130         if (timer_pending(pTimer))
131                 return;
132
133         timeout = ((timeout*HZ) / 1000);
134         pTimer->expires = jiffies + timeout;
135         add_timer(pTimer);
136 }
137
138 VOID RTMP_OS_Mod_Timer(
139         IN      NDIS_MINIPORT_TIMER             *pTimer,
140         IN      unsigned long timeout)
141 {
142         timeout = ((timeout*HZ) / 1000);
143         mod_timer(pTimer, jiffies + timeout);
144 }
145
146 VOID RTMP_OS_Del_Timer(
147         IN      NDIS_MINIPORT_TIMER             *pTimer,
148         OUT     BOOLEAN                                 *pCancelled)
149 {
150         if (timer_pending(pTimer))
151         {
152                 *pCancelled = del_timer_sync(pTimer);
153         }
154         else
155         {
156                 *pCancelled = TRUE;
157         }
158
159 }
160
161 VOID RTMP_OS_Release_Packet(
162         IN      PRTMP_ADAPTER pAd,
163         IN      PQUEUE_ENTRY  pEntry)
164 {
165         //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
166 }
167
168 // Unify all delay routine by using udelay
169 VOID RTMPusecDelay(
170         IN      ULONG   usec)
171 {
172         ULONG   i;
173
174         for (i = 0; i < (usec / 50); i++)
175                 udelay(50);
176
177         if (usec % 50)
178                 udelay(usec % 50);
179 }
180
181 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
182 {
183         time->u.LowPart = jiffies;
184 }
185
186 // pAd MUST allow to be NULL
187 NDIS_STATUS os_alloc_mem(
188         IN      PRTMP_ADAPTER pAd,
189         OUT     PUCHAR *mem,
190         IN      ULONG  size)
191 {
192         *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
193         if (*mem)
194                 return (NDIS_STATUS_SUCCESS);
195         else
196                 return (NDIS_STATUS_FAILURE);
197 }
198
199 // pAd MUST allow to be NULL
200 NDIS_STATUS os_free_mem(
201         IN      PRTMP_ADAPTER pAd,
202         IN      PUCHAR mem)
203 {
204
205         ASSERT(mem);
206         kfree(mem);
207         return (NDIS_STATUS_SUCCESS);
208 }
209
210
211 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
212         IN      PRTMP_ADAPTER pAd,
213         IN      ULONG   Length)
214 {
215         struct sk_buff *pkt;
216
217         pkt = dev_alloc_skb(Length);
218
219         if (pkt == NULL)
220         {
221                 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
222         }
223
224         if (pkt)
225         {
226                 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
227         }
228
229         return (PNDIS_PACKET) pkt;
230 }
231
232
233 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
234         IN      PRTMP_ADAPTER pAd,
235         IN      ULONG   Length,
236         IN      BOOLEAN Cached,
237         OUT     PVOID   *VirtualAddress)
238 {
239         struct sk_buff *pkt;
240
241         pkt = dev_alloc_skb(Length);
242
243         if (pkt == NULL)
244         {
245                 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
246         }
247
248         if (pkt)
249         {
250                 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
251                 *VirtualAddress = (PVOID) pkt->data;
252         }
253         else
254         {
255                 *VirtualAddress = (PVOID) NULL;
256         }
257
258         return (PNDIS_PACKET) pkt;
259 }
260
261
262 VOID build_tx_packet(
263         IN      PRTMP_ADAPTER   pAd,
264         IN      PNDIS_PACKET    pPacket,
265         IN      PUCHAR  pFrame,
266         IN      ULONG   FrameLen)
267 {
268
269         struct sk_buff  *pTxPkt;
270
271         ASSERT(pPacket);
272         pTxPkt = RTPKT_TO_OSPKT(pPacket);
273
274         NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
275 }
276
277 VOID    RTMPFreeAdapter(
278         IN      PRTMP_ADAPTER   pAd)
279 {
280     POS_COOKIE os_cookie;
281         int index;
282
283         os_cookie=(POS_COOKIE)pAd->OS_Cookie;
284
285         kfree(pAd->BeaconBuf);
286
287
288         NdisFreeSpinLock(&pAd->MgmtRingLock);
289 #ifdef RT2860
290         NdisFreeSpinLock(&pAd->RxRingLock);
291 #endif
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         vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
302         kfree(os_cookie);
303 }
304
305 BOOLEAN OS_Need_Clone_Packet(void)
306 {
307         return (FALSE);
308 }
309
310
311
312 /*
313         ========================================================================
314
315         Routine Description:
316                 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
317                 must have only one NDIS BUFFER
318                 return - byte copied. 0 means can't create NDIS PACKET
319                 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
320
321         Arguments:
322                 pAd     Pointer to our adapter
323                 pInsAMSDUHdr    EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
324                 *pSrcTotalLen                   return total packet length. This lenght is calculated with 802.3 format packet.
325
326         Return Value:
327                 NDIS_STATUS_SUCCESS
328                 NDIS_STATUS_FAILURE
329
330         Note:
331
332         ========================================================================
333 */
334 NDIS_STATUS RTMPCloneNdisPacket(
335         IN      PRTMP_ADAPTER   pAd,
336         IN      BOOLEAN                 pInsAMSDUHdr,
337         IN      PNDIS_PACKET    pInPacket,
338         OUT PNDIS_PACKET   *ppOutPacket)
339 {
340
341         struct sk_buff *pkt;
342
343         ASSERT(pInPacket);
344         ASSERT(ppOutPacket);
345
346         // 1. Allocate a packet
347         pkt = dev_alloc_skb(2048);
348
349         if (pkt == NULL)
350         {
351                 return NDIS_STATUS_FAILURE;
352         }
353
354         skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
355         NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
356         *ppOutPacket = OSPKT_TO_RTPKT(pkt);
357
358
359         RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
360
361         printk("###Clone###\n");
362
363         return NDIS_STATUS_SUCCESS;
364 }
365
366
367 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
368 NDIS_STATUS RTMPAllocateNdisPacket(
369         IN      PRTMP_ADAPTER   pAd,
370         OUT PNDIS_PACKET   *ppPacket,
371         IN      PUCHAR                  pHeader,
372         IN      UINT                    HeaderLen,
373         IN      PUCHAR                  pData,
374         IN      UINT                    DataLen)
375 {
376         PNDIS_PACKET    pPacket;
377         ASSERT(pData);
378         ASSERT(DataLen);
379
380         // 1. Allocate a packet
381         pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
382         if (pPacket == NULL)
383         {
384                 *ppPacket = NULL;
385 #ifdef DEBUG
386                 printk("RTMPAllocateNdisPacket Fail\n\n");
387 #endif
388                 return NDIS_STATUS_FAILURE;
389         }
390
391         // 2. clone the frame content
392         if (HeaderLen > 0)
393                 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
394         if (DataLen > 0)
395                 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
396
397         // 3. update length of packet
398         skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
399
400         RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
401 //      printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
402         *ppPacket = pPacket;
403         return NDIS_STATUS_SUCCESS;
404 }
405
406 /*
407   ========================================================================
408   Description:
409         This routine frees a miniport internally allocated NDIS_PACKET and its
410         corresponding NDIS_BUFFER and allocated memory.
411   ========================================================================
412 */
413 VOID RTMPFreeNdisPacket(
414         IN PRTMP_ADAPTER pAd,
415         IN PNDIS_PACKET  pPacket)
416 {
417         dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
418 }
419
420
421 // IRQL = DISPATCH_LEVEL
422 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
423 //                       scatter gather buffer
424 NDIS_STATUS Sniff2BytesFromNdisBuffer(
425         IN      PNDIS_BUFFER    pFirstBuffer,
426         IN      UCHAR                   DesiredOffset,
427         OUT PUCHAR                      pByte0,
428         OUT PUCHAR                      pByte1)
429 {
430     *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
431     *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
432
433         return NDIS_STATUS_SUCCESS;
434 }
435
436
437 void RTMP_QueryPacketInfo(
438         IN  PNDIS_PACKET pPacket,
439         OUT PACKET_INFO  *pPacketInfo,
440         OUT PUCHAR               *pSrcBufVA,
441         OUT     UINT             *pSrcBufLen)
442 {
443         pPacketInfo->BufferCount = 1;
444         pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
445         pPacketInfo->PhysicalBufferCount = 1;
446         pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
447
448         *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
449         *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
450 }
451
452 void RTMP_QueryNextPacketInfo(
453         IN  PNDIS_PACKET *ppPacket,
454         OUT PACKET_INFO  *pPacketInfo,
455         OUT PUCHAR               *pSrcBufVA,
456         OUT     UINT             *pSrcBufLen)
457 {
458         PNDIS_PACKET pPacket = NULL;
459
460         if (*ppPacket)
461                 pPacket = GET_OS_PKT_NEXT(*ppPacket);
462
463         if (pPacket)
464         {
465                 pPacketInfo->BufferCount = 1;
466                 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
467                 pPacketInfo->PhysicalBufferCount = 1;
468                 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
469
470                 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
471                 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
472                 *ppPacket = GET_OS_PKT_NEXT(pPacket);
473         }
474         else
475         {
476                 pPacketInfo->BufferCount = 0;
477                 pPacketInfo->pFirstBuffer = NULL;
478                 pPacketInfo->PhysicalBufferCount = 0;
479                 pPacketInfo->TotalPacketLength = 0;
480
481                 *pSrcBufVA = NULL;
482                 *pSrcBufLen = 0;
483                 *ppPacket = NULL;
484         }
485 }
486
487 // not yet support MBSS
488 PNET_DEV get_netdev_from_bssid(
489         IN      PRTMP_ADAPTER   pAd,
490         IN      UCHAR                   FromWhichBSSID)
491 {
492     PNET_DEV dev_p = NULL;
493
494         dev_p = pAd->net_dev;
495
496         ASSERT(dev_p);
497         return dev_p; /* return one of MBSS */
498 }
499
500 PNDIS_PACKET DuplicatePacket(
501         IN      PRTMP_ADAPTER   pAd,
502         IN      PNDIS_PACKET    pPacket,
503         IN      UCHAR                   FromWhichBSSID)
504 {
505         struct sk_buff  *skb;
506         PNDIS_PACKET    pRetPacket = NULL;
507         USHORT                  DataSize;
508         UCHAR                   *pData;
509
510         DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
511         pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
512
513
514         skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
515         if (skb)
516         {
517                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
518                 pRetPacket = OSPKT_TO_RTPKT(skb);
519         }
520
521         return pRetPacket;
522
523 }
524
525 PNDIS_PACKET duplicate_pkt(
526         IN      PRTMP_ADAPTER   pAd,
527         IN      PUCHAR                  pHeader802_3,
528     IN  UINT            HdrLen,
529         IN      PUCHAR                  pData,
530         IN      ULONG                   DataSize,
531         IN      UCHAR                   FromWhichBSSID)
532 {
533         struct sk_buff  *skb;
534         PNDIS_PACKET    pPacket = NULL;
535
536
537         if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
538         {
539                 skb_reserve(skb, 2);
540                 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
541                 skb_put(skb, HdrLen);
542                 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
543                 skb_put(skb, DataSize);
544                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
545                 pPacket = OSPKT_TO_RTPKT(skb);
546         }
547
548         return pPacket;
549 }
550
551
552 #define TKIP_TX_MIC_SIZE                8
553 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
554         IN      PRTMP_ADAPTER   pAd,
555         IN      PNDIS_PACKET    pPacket)
556 {
557         struct sk_buff  *skb, *newskb;
558
559
560         skb = RTPKT_TO_OSPKT(pPacket);
561         if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
562         {
563                 // alloc a new skb and copy the packet
564                 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
565                 dev_kfree_skb_any(skb);
566                 if (newskb == NULL)
567                 {
568                         DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
569                         return NULL;
570                 }
571                 skb = newskb;
572         }
573
574         return OSPKT_TO_RTPKT(skb);
575 }
576
577
578
579
580 PNDIS_PACKET ClonePacket(
581         IN      PRTMP_ADAPTER   pAd,
582         IN      PNDIS_PACKET    pPacket,
583         IN      PUCHAR                  pData,
584         IN      ULONG                   DataSize)
585 {
586         struct sk_buff  *pRxPkt;
587         struct sk_buff  *pClonedPkt;
588
589         ASSERT(pPacket);
590         pRxPkt = RTPKT_TO_OSPKT(pPacket);
591
592         // clone the packet
593         pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
594
595         if (pClonedPkt)
596         {
597         // set the correct dataptr and data len
598         pClonedPkt->dev = pRxPkt->dev;
599         pClonedPkt->data = pData;
600         pClonedPkt->len = DataSize;
601         pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
602                 ASSERT(DataSize < 1530);
603         }
604         return pClonedPkt;
605 }
606
607 //
608 // change OS packet DataPtr and DataLen
609 //
610 void  update_os_packet_info(
611         IN      PRTMP_ADAPTER   pAd,
612         IN      RX_BLK                  *pRxBlk,
613         IN  UCHAR                       FromWhichBSSID)
614 {
615         struct sk_buff  *pOSPkt;
616
617         ASSERT(pRxBlk->pRxPacket);
618         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
619
620         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
621         pOSPkt->data = pRxBlk->pData;
622         pOSPkt->len = pRxBlk->DataSize;
623         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
624 }
625
626
627 void wlan_802_11_to_802_3_packet(
628         IN      PRTMP_ADAPTER   pAd,
629         IN      RX_BLK                  *pRxBlk,
630         IN      PUCHAR                  pHeader802_3,
631         IN  UCHAR                       FromWhichBSSID)
632 {
633         struct sk_buff  *pOSPkt;
634
635         ASSERT(pRxBlk->pRxPacket);
636         ASSERT(pHeader802_3);
637
638         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
639
640         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
641         pOSPkt->data = pRxBlk->pData;
642         pOSPkt->len = pRxBlk->DataSize;
643         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
644
645         //
646         // copy 802.3 header
647         //
648         //
649
650         NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
651 }
652
653 void announce_802_3_packet(
654         IN      PRTMP_ADAPTER   pAd,
655         IN      PNDIS_PACKET    pPacket)
656 {
657
658         struct sk_buff  *pRxPkt;
659
660         ASSERT(pPacket);
661
662         pRxPkt = RTPKT_TO_OSPKT(pPacket);
663
664     /* Push up the protocol stack */
665         pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
666
667         netif_rx(pRxPkt);
668 }
669
670
671 PRTMP_SCATTER_GATHER_LIST
672 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
673 {
674         sg->NumberOfElements = 1;
675         sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
676         sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
677         return (sg);
678 }
679
680 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
681 {
682         unsigned char *pt;
683         int x;
684
685         if (RTDebugLevel < RT_DEBUG_TRACE)
686                 return;
687
688         pt = pSrcBufVA;
689         printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
690         for (x=0; x<SrcBufLen; x++)
691         {
692                 if (x % 16 == 0)
693                         printk("0x%04x : ", x);
694                 printk("%02x ", ((unsigned char)pt[x]));
695                 if (x%16 == 15) printk("\n");
696         }
697         printk("\n");
698 }
699
700 /*
701         ========================================================================
702
703         Routine Description:
704                 Send log message through wireless event
705
706                 Support standard iw_event with IWEVCUSTOM. It is used below.
707
708                 iwreq_data.data.flags is used to store event_flag that is defined by user.
709                 iwreq_data.data.length is the length of the event log.
710
711                 The format of the event log is composed of the entry's MAC address and
712                 the desired log message (refer to pWirelessEventText).
713
714                         ex: 11:22:33:44:55:66 has associated successfully
715
716                 p.s. The requirement of Wireless Extension is v15 or newer.
717
718         ========================================================================
719 */
720 VOID RTMPSendWirelessEvent(
721         IN      PRTMP_ADAPTER   pAd,
722         IN      USHORT                  Event_flag,
723         IN      PUCHAR                  pAddr,
724         IN      UCHAR                   BssIdx,
725         IN      CHAR                    Rssi)
726 {
727
728         union   iwreq_data      wrqu;
729         PUCHAR  pBuf = NULL, pBufPtr = NULL;
730         USHORT  event, type, BufLen;
731         UCHAR   event_table_len = 0;
732
733         type = Event_flag & 0xFF00;
734         event = Event_flag & 0x00FF;
735
736         switch (type)
737         {
738                 case IW_SYS_EVENT_FLAG_START:
739                         event_table_len = IW_SYS_EVENT_TYPE_NUM;
740                         break;
741
742                 case IW_SPOOF_EVENT_FLAG_START:
743                         event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
744                         break;
745
746                 case IW_FLOOD_EVENT_FLAG_START:
747                         event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
748                         break;
749         }
750
751         if (event_table_len == 0)
752         {
753                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
754                 return;
755         }
756
757         if (event >= event_table_len)
758         {
759                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
760                 return;
761         }
762
763         //Allocate memory and copy the msg.
764         if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
765         {
766                 //Prepare the payload
767                 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
768
769                 pBufPtr = pBuf;
770
771                 if (pAddr)
772                         pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
773                 else if (BssIdx < MAX_MBSSID_NUM)
774                         pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
775                 else
776                         pBufPtr += sprintf(pBufPtr, "(RT2860) ");
777
778                 if (type == IW_SYS_EVENT_FLAG_START)
779                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
780                 else if (type == IW_SPOOF_EVENT_FLAG_START)
781                         pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
782                 else if (type == IW_FLOOD_EVENT_FLAG_START)
783                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
784                 else
785                         pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
786
787                 pBufPtr[pBufPtr - pBuf] = '\0';
788                 BufLen = pBufPtr - pBuf;
789
790                 memset(&wrqu, 0, sizeof(wrqu));
791             wrqu.data.flags = Event_flag;
792                 wrqu.data.length = BufLen;
793
794                 //send wireless event
795             wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
796
797                 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
798
799                 kfree(pBuf);
800         }
801         else
802                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
803 }
804
805 void send_monitor_packets(
806         IN      PRTMP_ADAPTER   pAd,
807         IN      RX_BLK                  *pRxBlk)
808 {
809     struct sk_buff      *pOSPkt;
810     wlan_ng_prism2_header *ph;
811     int rate_index = 0;
812     USHORT header_len = 0;
813     UCHAR temp_header[40] = {0};
814
815     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
816         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,
817         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};
818
819
820     ASSERT(pRxBlk->pRxPacket);
821     if (pRxBlk->DataSize < 10)
822     {
823         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
824                 goto err_free_sk_buff;
825     }
826
827     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
828     {
829         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
830                 goto err_free_sk_buff;
831     }
832
833     pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
834         pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
835     if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
836     {
837         pRxBlk->DataSize -= LENGTH_802_11;
838         if ((pRxBlk->pHeader->FC.ToDs == 1) &&
839             (pRxBlk->pHeader->FC.FrDs == 1))
840             header_len = LENGTH_802_11_WITH_ADDR4;
841         else
842             header_len = LENGTH_802_11;
843
844         // QOS
845         if (pRxBlk->pHeader->FC.SubType & 0x08)
846         {
847             header_len += 2;
848                 // Data skip QOS contorl field
849                 pRxBlk->DataSize -=2;
850         }
851
852         // Order bit: A-Ralink or HTC+
853         if (pRxBlk->pHeader->FC.Order)
854         {
855             header_len += 4;
856                         // Data skip HTC contorl field
857                         pRxBlk->DataSize -= 4;
858         }
859
860         // Copy Header
861         if (header_len <= 40)
862             NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
863
864         // skip HW padding
865         if (pRxBlk->RxD.L2PAD)
866             pRxBlk->pData += (header_len + 2);
867         else
868             pRxBlk->pData += header_len;
869     } //end if
870
871
872         if (pRxBlk->DataSize < pOSPkt->len) {
873         skb_trim(pOSPkt,pRxBlk->DataSize);
874     } else {
875         skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
876     } //end if
877
878     if ((pRxBlk->pData - pOSPkt->data) > 0) {
879             skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
880             skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
881     } //end if
882
883     if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
884         if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
885                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
886                         goto err_free_sk_buff;
887             } //end if
888     } //end if
889
890     if (header_len > 0)
891         NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
892
893     ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
894         NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
895
896     ph->msgcode             = DIDmsg_lnxind_wlansniffrm;
897         ph->msglen                  = sizeof(wlan_ng_prism2_header);
898         strcpy(ph->devname, pAd->net_dev->name);
899
900     ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
901         ph->hosttime.status = 0;
902         ph->hosttime.len = 4;
903         ph->hosttime.data = jiffies;
904
905         ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
906         ph->mactime.status = 0;
907         ph->mactime.len = 0;
908         ph->mactime.data = 0;
909
910     ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
911         ph->istx.status = 0;
912         ph->istx.len = 0;
913         ph->istx.data = 0;
914
915     ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
916         ph->channel.status = 0;
917         ph->channel.len = 4;
918
919     ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
920
921     ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
922         ph->rssi.status = 0;
923         ph->rssi.len = 4;
924     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));;
925
926         ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
927         ph->signal.status = 0;
928         ph->signal.len = 4;
929         ph->signal.data = 0; //rssi + noise;
930
931         ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
932         ph->noise.status = 0;
933         ph->noise.len = 4;
934         ph->noise.data = 0;
935
936     if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
937     {
938         rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
939     }
940     else
941         if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
942         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
943     else
944         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
945     if (rate_index < 0)
946         rate_index = 0;
947     if (rate_index > 255)
948         rate_index = 255;
949
950         ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
951         ph->rate.status = 0;
952         ph->rate.len = 4;
953     ph->rate.data = ralinkrate[rate_index];
954
955         ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
956     ph->frmlen.status = 0;
957         ph->frmlen.len = 4;
958         ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
959
960
961     pOSPkt->pkt_type = PACKET_OTHERHOST;
962     pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
963     pOSPkt->ip_summed = CHECKSUM_NONE;
964     netif_rx(pOSPkt);
965
966     return;
967
968 err_free_sk_buff:
969         RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
970         return;
971
972 }
973
974 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
975 {
976         daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
977
978         allow_signal(SIGTERM);
979         allow_signal(SIGKILL);
980         current->flags |= PF_NOFREEZE;
981
982         /* signal that we've started the thread */
983         complete(pNotify);
984 }
985
986 void RTMP_IndicateMediaState(
987         IN      PRTMP_ADAPTER   pAd)
988 {
989         if (pAd->CommonCfg.bWirelessEvent)
990         {
991                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
992                 {
993                         RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
994                 }
995                 else
996                 {
997                         RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
998                 }
999         }
1000 }
1001