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