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