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