Staging: rt2860: remove dependency on WIRELESS_EXT version
[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, pHeader802_3, HdrLen);
541                 skb_put(skb, HdrLen);
542                 NdisMoveMemory(skb->tail, 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 #ifdef IKANOS_VX_1X0
666         IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
667 #else
668         pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
669
670         netif_rx(pRxPkt);
671 #endif // IKANOS_VX_1X0 //
672 }
673
674
675 PRTMP_SCATTER_GATHER_LIST
676 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
677 {
678         sg->NumberOfElements = 1;
679         sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
680         sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
681         return (sg);
682 }
683
684 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
685 {
686         unsigned char *pt;
687         int x;
688
689         if (RTDebugLevel < RT_DEBUG_TRACE)
690                 return;
691
692         pt = pSrcBufVA;
693         printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
694         for (x=0; x<SrcBufLen; x++)
695         {
696                 if (x % 16 == 0)
697                         printk("0x%04x : ", x);
698                 printk("%02x ", ((unsigned char)pt[x]));
699                 if (x%16 == 15) printk("\n");
700         }
701         printk("\n");
702 }
703
704 /*
705         ========================================================================
706
707         Routine Description:
708                 Send log message through wireless event
709
710                 Support standard iw_event with IWEVCUSTOM. It is used below.
711
712                 iwreq_data.data.flags is used to store event_flag that is defined by user.
713                 iwreq_data.data.length is the length of the event log.
714
715                 The format of the event log is composed of the entry's MAC address and
716                 the desired log message (refer to pWirelessEventText).
717
718                         ex: 11:22:33:44:55:66 has associated successfully
719
720                 p.s. The requirement of Wireless Extension is v15 or newer.
721
722         ========================================================================
723 */
724 VOID RTMPSendWirelessEvent(
725         IN      PRTMP_ADAPTER   pAd,
726         IN      USHORT                  Event_flag,
727         IN      PUCHAR                  pAddr,
728         IN      UCHAR                   BssIdx,
729         IN      CHAR                    Rssi)
730 {
731
732         union   iwreq_data      wrqu;
733         PUCHAR  pBuf = NULL, pBufPtr = NULL;
734         USHORT  event, type, BufLen;
735         UCHAR   event_table_len = 0;
736
737         type = Event_flag & 0xFF00;
738         event = Event_flag & 0x00FF;
739
740         switch (type)
741         {
742                 case IW_SYS_EVENT_FLAG_START:
743                         event_table_len = IW_SYS_EVENT_TYPE_NUM;
744                         break;
745
746                 case IW_SPOOF_EVENT_FLAG_START:
747                         event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
748                         break;
749
750                 case IW_FLOOD_EVENT_FLAG_START:
751                         event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
752                         break;
753         }
754
755         if (event_table_len == 0)
756         {
757                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
758                 return;
759         }
760
761         if (event >= event_table_len)
762         {
763                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
764                 return;
765         }
766
767         //Allocate memory and copy the msg.
768         if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
769         {
770                 //Prepare the payload
771                 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
772
773                 pBufPtr = pBuf;
774
775                 if (pAddr)
776                         pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
777                 else if (BssIdx < MAX_MBSSID_NUM)
778                         pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
779                 else
780                         pBufPtr += sprintf(pBufPtr, "(RT2860) ");
781
782                 if (type == IW_SYS_EVENT_FLAG_START)
783                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
784                 else if (type == IW_SPOOF_EVENT_FLAG_START)
785                         pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
786                 else if (type == IW_FLOOD_EVENT_FLAG_START)
787                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
788                 else
789                         pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
790
791                 pBufPtr[pBufPtr - pBuf] = '\0';
792                 BufLen = pBufPtr - pBuf;
793
794                 memset(&wrqu, 0, sizeof(wrqu));
795             wrqu.data.flags = Event_flag;
796                 wrqu.data.length = BufLen;
797
798                 //send wireless event
799             wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
800
801                 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
802
803                 kfree(pBuf);
804         }
805         else
806                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
807 }
808
809 void send_monitor_packets(
810         IN      PRTMP_ADAPTER   pAd,
811         IN      RX_BLK                  *pRxBlk)
812 {
813     struct sk_buff      *pOSPkt;
814     wlan_ng_prism2_header *ph;
815     int rate_index = 0;
816     USHORT header_len = 0;
817     UCHAR temp_header[40] = {0};
818
819     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
820         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,
821         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};
822
823
824     ASSERT(pRxBlk->pRxPacket);
825     if (pRxBlk->DataSize < 10)
826     {
827         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
828                 goto err_free_sk_buff;
829     }
830
831     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
832     {
833 #ifndef RT30xx
834         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
835 #endif
836 #ifdef RT30xx
837         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
838 #endif
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