Staging: rt2870: remove dead EXT_BUILD_CHANNEL_LIST code
[linux-2.6] / drivers / staging / rt2860 / rt_linux.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26  */
27
28 #include "rt_config.h"
29
30 ULONG   RTDebugLevel = RT_DEBUG_ERROR;
31
32 BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
34 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
35 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
36
37
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 #ifdef LEAP_SUPPORT
47 BUILD_TIMER_FUNCTION(LeapAuthTimeout);
48 #endif
49 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
50 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51 BUILD_TIMER_FUNCTION(PsPollWakeExec);
52 BUILD_TIMER_FUNCTION(RadioOnExec);
53 #endif // CONFIG_STA_SUPPORT //
54
55 // for wireless system event message
56 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
57         // system status event
58     "had associated successfully",                                                      /* IW_ASSOC_EVENT_FLAG */
59     "had disassociated",                                                                        /* IW_DISASSOC_EVENT_FLAG */
60     "had deauthenticated",                                                                      /* IW_DEAUTH_EVENT_FLAG */
61     "had been aged-out and disassociated",                                      /* IW_AGEOUT_EVENT_FLAG */
62     "occurred CounterMeasures attack",                                          /* IW_COUNTER_MEASURES_EVENT_FLAG */
63     "occurred replay counter different in Key Handshaking",     /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
64     "occurred RSNIE different in Key Handshaking",                      /* IW_RSNIE_DIFF_EVENT_FLAG */
65     "occurred MIC different in Key Handshaking",                        /* IW_MIC_DIFF_EVENT_FLAG */
66     "occurred ICV error in RX",                                                         /* IW_ICV_ERROR_EVENT_FLAG */
67     "occurred MIC error in RX",                                                         /* IW_MIC_ERROR_EVENT_FLAG */
68         "Group Key Handshaking timeout",                                                /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
69         "Pairwise Key Handshaking timeout",                                             /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
70         "RSN IE sanity check failure",                                                  /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
71         "set key done in WPA/WPAPSK",                                                   /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
72         "set key done in WPA2/WPA2PSK",                         /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
73         "connects with our wireless client",                    /* IW_STA_LINKUP_EVENT_FLAG */
74         "disconnects with our wireless client",                 /* IW_STA_LINKDOWN_EVENT_FLAG */
75         "scan completed"                                                                                /* IW_SCAN_COMPLETED_EVENT_FLAG */
76         "scan terminate!! Busy!! Enqueue fail!!"                                /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
77         };
78
79 // for wireless IDS_spoof_attack event message
80 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
81     "detected conflict SSID",                                                           /* IW_CONFLICT_SSID_EVENT_FLAG */
82     "detected spoofed association response",                            /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
83     "detected spoofed reassociation responses",                         /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
84     "detected spoofed probe response",                                          /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
85     "detected spoofed beacon",                                                          /* IW_SPOOF_BEACON_EVENT_FLAG */
86     "detected spoofed disassociation",                                          /* IW_SPOOF_DISASSOC_EVENT_FLAG */
87     "detected spoofed authentication",                                          /* IW_SPOOF_AUTH_EVENT_FLAG */
88     "detected spoofed deauthentication",                                        /* IW_SPOOF_DEAUTH_EVENT_FLAG */
89     "detected spoofed unknown management frame",                        /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
90         "detected replay attack"                                                                /* IW_REPLAY_ATTACK_EVENT_FLAG */
91         };
92
93 // for wireless IDS_flooding_attack event message
94 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
95         "detected authentication flooding",                                             /* IW_FLOOD_AUTH_EVENT_FLAG */
96     "detected association request flooding",                            /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
97     "detected reassociation request flooding",                          /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
98     "detected probe request flooding",                                          /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
99     "detected disassociation flooding",                                         /* IW_FLOOD_DISASSOC_EVENT_FLAG */
100     "detected deauthentication flooding",                                       /* IW_FLOOD_DEAUTH_EVENT_FLAG */
101     "detected 802.1x eap-request flooding"                                      /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
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         NdisFreeSpinLock(&pAd->RxRingLock);
292
293         for (index =0 ; index < NUM_OF_TX_RING; index++)
294         {
295         NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
296                 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
297                 pAd->DeQueueRunning[index] = FALSE;
298         }
299
300         NdisFreeSpinLock(&pAd->irq_lock);
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 #ifdef CONFIG_STA_SUPPORT
496         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
497         {
498                 dev_p = pAd->net_dev;
499         }
500 #endif // CONFIG_STA_SUPPORT //
501
502         ASSERT(dev_p);
503         return dev_p; /* return one of MBSS */
504 }
505
506 PNDIS_PACKET DuplicatePacket(
507         IN      PRTMP_ADAPTER   pAd,
508         IN      PNDIS_PACKET    pPacket,
509         IN      UCHAR                   FromWhichBSSID)
510 {
511         struct sk_buff  *skb;
512         PNDIS_PACKET    pRetPacket = NULL;
513         USHORT                  DataSize;
514         UCHAR                   *pData;
515
516         DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
517         pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
518
519
520         skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
521         if (skb)
522         {
523                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
524                 pRetPacket = OSPKT_TO_RTPKT(skb);
525         }
526
527         return pRetPacket;
528
529 }
530
531 PNDIS_PACKET duplicate_pkt(
532         IN      PRTMP_ADAPTER   pAd,
533         IN      PUCHAR                  pHeader802_3,
534     IN  UINT            HdrLen,
535         IN      PUCHAR                  pData,
536         IN      ULONG                   DataSize,
537         IN      UCHAR                   FromWhichBSSID)
538 {
539         struct sk_buff  *skb;
540         PNDIS_PACKET    pPacket = NULL;
541
542
543         if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
544         {
545                 skb_reserve(skb, 2);
546                 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
547                 skb_put(skb, HdrLen);
548                 NdisMoveMemory(skb->tail, pData, DataSize);
549                 skb_put(skb, DataSize);
550                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
551                 pPacket = OSPKT_TO_RTPKT(skb);
552         }
553
554         return pPacket;
555 }
556
557
558 #define TKIP_TX_MIC_SIZE                8
559 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
560         IN      PRTMP_ADAPTER   pAd,
561         IN      PNDIS_PACKET    pPacket)
562 {
563         struct sk_buff  *skb, *newskb;
564
565
566         skb = RTPKT_TO_OSPKT(pPacket);
567         if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
568         {
569                 // alloc a new skb and copy the packet
570                 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
571                 dev_kfree_skb_any(skb);
572                 if (newskb == NULL)
573                 {
574                         DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
575                         return NULL;
576                 }
577                 skb = newskb;
578         }
579
580         return OSPKT_TO_RTPKT(skb);
581 }
582
583
584
585
586 PNDIS_PACKET ClonePacket(
587         IN      PRTMP_ADAPTER   pAd,
588         IN      PNDIS_PACKET    pPacket,
589         IN      PUCHAR                  pData,
590         IN      ULONG                   DataSize)
591 {
592         struct sk_buff  *pRxPkt;
593         struct sk_buff  *pClonedPkt;
594
595         ASSERT(pPacket);
596         pRxPkt = RTPKT_TO_OSPKT(pPacket);
597
598         // clone the packet
599         pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
600
601         if (pClonedPkt)
602         {
603         // set the correct dataptr and data len
604         pClonedPkt->dev = pRxPkt->dev;
605         pClonedPkt->data = pData;
606         pClonedPkt->len = DataSize;
607         pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
608                 ASSERT(DataSize < 1530);
609         }
610         return pClonedPkt;
611 }
612
613 //
614 // change OS packet DataPtr and DataLen
615 //
616 void  update_os_packet_info(
617         IN      PRTMP_ADAPTER   pAd,
618         IN      RX_BLK                  *pRxBlk,
619         IN  UCHAR                       FromWhichBSSID)
620 {
621         struct sk_buff  *pOSPkt;
622
623         ASSERT(pRxBlk->pRxPacket);
624         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
625
626         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
627         pOSPkt->data = pRxBlk->pData;
628         pOSPkt->len = pRxBlk->DataSize;
629         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
630 }
631
632
633 void wlan_802_11_to_802_3_packet(
634         IN      PRTMP_ADAPTER   pAd,
635         IN      RX_BLK                  *pRxBlk,
636         IN      PUCHAR                  pHeader802_3,
637         IN  UCHAR                       FromWhichBSSID)
638 {
639         struct sk_buff  *pOSPkt;
640
641         ASSERT(pRxBlk->pRxPacket);
642         ASSERT(pHeader802_3);
643
644         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
645
646         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
647         pOSPkt->data = pRxBlk->pData;
648         pOSPkt->len = pRxBlk->DataSize;
649         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
650
651         //
652         // copy 802.3 header
653         //
654         //
655
656 #ifdef CONFIG_STA_SUPPORT
657         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
658                 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
659 #endif // CONFIG_STA_SUPPORT //
660         }
661
662
663
664 void announce_802_3_packet(
665         IN      PRTMP_ADAPTER   pAd,
666         IN      PNDIS_PACKET    pPacket)
667 {
668
669         struct sk_buff  *pRxPkt;
670
671         ASSERT(pPacket);
672
673         pRxPkt = RTPKT_TO_OSPKT(pPacket);
674
675     /* Push up the protocol stack */
676 #ifdef IKANOS_VX_1X0
677         IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
678 #else
679         pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
680
681         netif_rx(pRxPkt);
682 #endif // IKANOS_VX_1X0 //
683 }
684
685
686 PRTMP_SCATTER_GATHER_LIST
687 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
688 {
689         sg->NumberOfElements = 1;
690         sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
691         sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
692         return (sg);
693 }
694
695 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
696 {
697         unsigned char *pt;
698         int x;
699
700         if (RTDebugLevel < RT_DEBUG_TRACE)
701                 return;
702
703         pt = pSrcBufVA;
704         printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
705         for (x=0; x<SrcBufLen; x++)
706         {
707                 if (x % 16 == 0)
708                         printk("0x%04x : ", x);
709                 printk("%02x ", ((unsigned char)pt[x]));
710                 if (x%16 == 15) printk("\n");
711         }
712         printk("\n");
713 }
714
715 /*
716         ========================================================================
717
718         Routine Description:
719                 Send log message through wireless event
720
721                 Support standard iw_event with IWEVCUSTOM. It is used below.
722
723                 iwreq_data.data.flags is used to store event_flag that is defined by user.
724                 iwreq_data.data.length is the length of the event log.
725
726                 The format of the event log is composed of the entry's MAC address and
727                 the desired log message (refer to pWirelessEventText).
728
729                         ex: 11:22:33:44:55:66 has associated successfully
730
731                 p.s. The requirement of Wireless Extension is v15 or newer.
732
733         ========================================================================
734 */
735 VOID RTMPSendWirelessEvent(
736         IN      PRTMP_ADAPTER   pAd,
737         IN      USHORT                  Event_flag,
738         IN      PUCHAR                  pAddr,
739         IN      UCHAR                   BssIdx,
740         IN      CHAR                    Rssi)
741 {
742 #if WIRELESS_EXT >= 15
743
744         union   iwreq_data      wrqu;
745         PUCHAR  pBuf = NULL, pBufPtr = NULL;
746         USHORT  event, type, BufLen;
747         UCHAR   event_table_len = 0;
748
749         type = Event_flag & 0xFF00;
750         event = Event_flag & 0x00FF;
751
752         switch (type)
753         {
754                 case IW_SYS_EVENT_FLAG_START:
755                         event_table_len = IW_SYS_EVENT_TYPE_NUM;
756                         break;
757
758                 case IW_SPOOF_EVENT_FLAG_START:
759                         event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
760                         break;
761
762                 case IW_FLOOD_EVENT_FLAG_START:
763                         event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
764                         break;
765         }
766
767         if (event_table_len == 0)
768         {
769                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
770                 return;
771         }
772
773         if (event >= event_table_len)
774         {
775                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
776                 return;
777         }
778
779         //Allocate memory and copy the msg.
780         if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
781         {
782                 //Prepare the payload
783                 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
784
785                 pBufPtr = pBuf;
786
787                 if (pAddr)
788                         pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
789                 else if (BssIdx < MAX_MBSSID_NUM)
790                         pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
791                 else
792                         pBufPtr += sprintf(pBufPtr, "(RT2860) ");
793
794                 if (type == IW_SYS_EVENT_FLAG_START)
795                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
796                 else if (type == IW_SPOOF_EVENT_FLAG_START)
797                         pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
798                 else if (type == IW_FLOOD_EVENT_FLAG_START)
799                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
800                 else
801                         pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
802
803                 pBufPtr[pBufPtr - pBuf] = '\0';
804                 BufLen = pBufPtr - pBuf;
805
806                 memset(&wrqu, 0, sizeof(wrqu));
807             wrqu.data.flags = Event_flag;
808                 wrqu.data.length = BufLen;
809
810                 //send wireless event
811             wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
812
813                 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
814
815                 kfree(pBuf);
816         }
817         else
818                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
819 #else
820         DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
821 #endif  /* WIRELESS_EXT >= 15 */
822 }
823
824
825 #ifdef CONFIG_STA_SUPPORT
826 void send_monitor_packets(
827         IN      PRTMP_ADAPTER   pAd,
828         IN      RX_BLK                  *pRxBlk)
829 {
830     struct sk_buff      *pOSPkt;
831     wlan_ng_prism2_header *ph;
832     int rate_index = 0;
833     USHORT header_len = 0;
834     UCHAR temp_header[40] = {0};
835
836     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
837         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,
838         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};
839
840
841     ASSERT(pRxBlk->pRxPacket);
842     if (pRxBlk->DataSize < 10)
843     {
844         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
845                 goto err_free_sk_buff;
846     }
847
848     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
849     {
850         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
851                 goto err_free_sk_buff;
852     }
853
854     pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
855         pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
856     if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
857     {
858         pRxBlk->DataSize -= LENGTH_802_11;
859         if ((pRxBlk->pHeader->FC.ToDs == 1) &&
860             (pRxBlk->pHeader->FC.FrDs == 1))
861             header_len = LENGTH_802_11_WITH_ADDR4;
862         else
863             header_len = LENGTH_802_11;
864
865         // QOS
866         if (pRxBlk->pHeader->FC.SubType & 0x08)
867         {
868             header_len += 2;
869                 // Data skip QOS contorl field
870                 pRxBlk->DataSize -=2;
871         }
872
873         // Order bit: A-Ralink or HTC+
874         if (pRxBlk->pHeader->FC.Order)
875         {
876             header_len += 4;
877                         // Data skip HTC contorl field
878                         pRxBlk->DataSize -= 4;
879         }
880
881         // Copy Header
882         if (header_len <= 40)
883             NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
884
885         // skip HW padding
886         if (pRxBlk->RxD.L2PAD)
887             pRxBlk->pData += (header_len + 2);
888         else
889             pRxBlk->pData += header_len;
890     } //end if
891
892
893         if (pRxBlk->DataSize < pOSPkt->len) {
894         skb_trim(pOSPkt,pRxBlk->DataSize);
895     } else {
896         skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
897     } //end if
898
899     if ((pRxBlk->pData - pOSPkt->data) > 0) {
900             skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
901             skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
902     } //end if
903
904     if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
905         if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
906                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
907                         goto err_free_sk_buff;
908             } //end if
909     } //end if
910
911     if (header_len > 0)
912         NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
913
914     ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
915         NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
916
917     ph->msgcode             = DIDmsg_lnxind_wlansniffrm;
918         ph->msglen                  = sizeof(wlan_ng_prism2_header);
919         strcpy(ph->devname, pAd->net_dev->name);
920
921     ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
922         ph->hosttime.status = 0;
923         ph->hosttime.len = 4;
924         ph->hosttime.data = jiffies;
925
926         ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
927         ph->mactime.status = 0;
928         ph->mactime.len = 0;
929         ph->mactime.data = 0;
930
931     ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
932         ph->istx.status = 0;
933         ph->istx.len = 0;
934         ph->istx.data = 0;
935
936     ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
937         ph->channel.status = 0;
938         ph->channel.len = 4;
939
940     ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
941
942     ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
943         ph->rssi.status = 0;
944         ph->rssi.len = 4;
945     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));;
946
947         ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
948         ph->signal.status = 0;
949         ph->signal.len = 4;
950         ph->signal.data = 0; //rssi + noise;
951
952         ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
953         ph->noise.status = 0;
954         ph->noise.len = 4;
955         ph->noise.data = 0;
956
957 #ifdef DOT11_N_SUPPORT
958     if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
959     {
960         rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
961     }
962     else
963 #endif // DOT11_N_SUPPORT //
964         if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
965         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
966     else
967         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
968     if (rate_index < 0)
969         rate_index = 0;
970     if (rate_index > 255)
971         rate_index = 255;
972
973         ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
974         ph->rate.status = 0;
975         ph->rate.len = 4;
976     ph->rate.data = ralinkrate[rate_index];
977
978         ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
979     ph->frmlen.status = 0;
980         ph->frmlen.len = 4;
981         ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
982
983
984     pOSPkt->pkt_type = PACKET_OTHERHOST;
985     pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
986     pOSPkt->ip_summed = CHECKSUM_NONE;
987     netif_rx(pOSPkt);
988
989     return;
990
991 err_free_sk_buff:
992         RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
993         return;
994
995 }
996 #endif // CONFIG_STA_SUPPORT //
997
998
999 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1000 {
1001         daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1002
1003         allow_signal(SIGTERM);
1004         allow_signal(SIGKILL);
1005         current->flags |= PF_NOFREEZE;
1006
1007         /* signal that we've started the thread */
1008         complete(pNotify);
1009 }
1010
1011 void RTMP_IndicateMediaState(
1012         IN      PRTMP_ADAPTER   pAd)
1013 {
1014         if (pAd->CommonCfg.bWirelessEvent)
1015         {
1016                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1017                 {
1018                         RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1019                 }
1020                 else
1021                 {
1022                         RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1023                 }
1024         }
1025 }
1026