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