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