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