Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6
[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 #ifdef RT2870
37 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
38 #endif // RT2870 //
39
40 BUILD_TIMER_FUNCTION(BeaconTimeout);
41 BUILD_TIMER_FUNCTION(ScanTimeout);
42 BUILD_TIMER_FUNCTION(AuthTimeout);
43 BUILD_TIMER_FUNCTION(AssocTimeout);
44 BUILD_TIMER_FUNCTION(ReassocTimeout);
45 BUILD_TIMER_FUNCTION(DisassocTimeout);
46 BUILD_TIMER_FUNCTION(LinkDownExec);
47 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
48 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
49 #ifdef RT2860
50 BUILD_TIMER_FUNCTION(PsPollWakeExec);
51 BUILD_TIMER_FUNCTION(RadioOnExec);
52 #endif
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 #ifdef RT2860
290         NdisFreeSpinLock(&pAd->RxRingLock);
291 #endif
292         for (index =0 ; index < NUM_OF_TX_RING; index++)
293         {
294         NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
295                 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
296                 pAd->DeQueueRunning[index] = FALSE;
297         }
298
299         NdisFreeSpinLock(&pAd->irq_lock);
300
301         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         dev_p = pAd->net_dev;
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         return pRetPacket;
522
523 }
524
525 PNDIS_PACKET duplicate_pkt(
526         IN      PRTMP_ADAPTER   pAd,
527         IN      PUCHAR                  pHeader802_3,
528     IN  UINT            HdrLen,
529         IN      PUCHAR                  pData,
530         IN      ULONG                   DataSize,
531         IN      UCHAR                   FromWhichBSSID)
532 {
533         struct sk_buff  *skb;
534         PNDIS_PACKET    pPacket = NULL;
535
536
537         if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
538         {
539                 skb_reserve(skb, 2);
540                 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
541                 skb_put(skb, HdrLen);
542                 NdisMoveMemory(skb->tail, pData, DataSize);
543                 skb_put(skb, DataSize);
544                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
545                 pPacket = OSPKT_TO_RTPKT(skb);
546         }
547
548         return pPacket;
549 }
550
551
552 #define TKIP_TX_MIC_SIZE                8
553 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
554         IN      PRTMP_ADAPTER   pAd,
555         IN      PNDIS_PACKET    pPacket)
556 {
557         struct sk_buff  *skb, *newskb;
558
559
560         skb = RTPKT_TO_OSPKT(pPacket);
561         if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
562         {
563                 // alloc a new skb and copy the packet
564                 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
565                 dev_kfree_skb_any(skb);
566                 if (newskb == NULL)
567                 {
568                         DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
569                         return NULL;
570                 }
571                 skb = newskb;
572         }
573
574         return OSPKT_TO_RTPKT(skb);
575 }
576
577
578
579
580 PNDIS_PACKET ClonePacket(
581         IN      PRTMP_ADAPTER   pAd,
582         IN      PNDIS_PACKET    pPacket,
583         IN      PUCHAR                  pData,
584         IN      ULONG                   DataSize)
585 {
586         struct sk_buff  *pRxPkt;
587         struct sk_buff  *pClonedPkt;
588
589         ASSERT(pPacket);
590         pRxPkt = RTPKT_TO_OSPKT(pPacket);
591
592         // clone the packet
593         pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
594
595         if (pClonedPkt)
596         {
597         // set the correct dataptr and data len
598         pClonedPkt->dev = pRxPkt->dev;
599         pClonedPkt->data = pData;
600         pClonedPkt->len = DataSize;
601         pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
602                 ASSERT(DataSize < 1530);
603         }
604         return pClonedPkt;
605 }
606
607 //
608 // change OS packet DataPtr and DataLen
609 //
610 void  update_os_packet_info(
611         IN      PRTMP_ADAPTER   pAd,
612         IN      RX_BLK                  *pRxBlk,
613         IN  UCHAR                       FromWhichBSSID)
614 {
615         struct sk_buff  *pOSPkt;
616
617         ASSERT(pRxBlk->pRxPacket);
618         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
619
620         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
621         pOSPkt->data = pRxBlk->pData;
622         pOSPkt->len = pRxBlk->DataSize;
623         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
624 }
625
626
627 void wlan_802_11_to_802_3_packet(
628         IN      PRTMP_ADAPTER   pAd,
629         IN      RX_BLK                  *pRxBlk,
630         IN      PUCHAR                  pHeader802_3,
631         IN  UCHAR                       FromWhichBSSID)
632 {
633         struct sk_buff  *pOSPkt;
634
635         ASSERT(pRxBlk->pRxPacket);
636         ASSERT(pHeader802_3);
637
638         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
639
640         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
641         pOSPkt->data = pRxBlk->pData;
642         pOSPkt->len = pRxBlk->DataSize;
643         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
644
645         //
646         // copy 802.3 header
647         //
648         //
649
650         NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
651 }
652
653 void announce_802_3_packet(
654         IN      PRTMP_ADAPTER   pAd,
655         IN      PNDIS_PACKET    pPacket)
656 {
657
658         struct sk_buff  *pRxPkt;
659
660         ASSERT(pPacket);
661
662         pRxPkt = RTPKT_TO_OSPKT(pPacket);
663
664     /* Push up the protocol stack */
665 #ifdef IKANOS_VX_1X0
666         IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
667 #else
668         pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
669
670         netif_rx(pRxPkt);
671 #endif // IKANOS_VX_1X0 //
672 }
673
674
675 PRTMP_SCATTER_GATHER_LIST
676 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
677 {
678         sg->NumberOfElements = 1;
679         sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
680         sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
681         return (sg);
682 }
683
684 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
685 {
686         unsigned char *pt;
687         int x;
688
689         if (RTDebugLevel < RT_DEBUG_TRACE)
690                 return;
691
692         pt = pSrcBufVA;
693         printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
694         for (x=0; x<SrcBufLen; x++)
695         {
696                 if (x % 16 == 0)
697                         printk("0x%04x : ", x);
698                 printk("%02x ", ((unsigned char)pt[x]));
699                 if (x%16 == 15) printk("\n");
700         }
701         printk("\n");
702 }
703
704 /*
705         ========================================================================
706
707         Routine Description:
708                 Send log message through wireless event
709
710                 Support standard iw_event with IWEVCUSTOM. It is used below.
711
712                 iwreq_data.data.flags is used to store event_flag that is defined by user.
713                 iwreq_data.data.length is the length of the event log.
714
715                 The format of the event log is composed of the entry's MAC address and
716                 the desired log message (refer to pWirelessEventText).
717
718                         ex: 11:22:33:44:55:66 has associated successfully
719
720                 p.s. The requirement of Wireless Extension is v15 or newer.
721
722         ========================================================================
723 */
724 VOID RTMPSendWirelessEvent(
725         IN      PRTMP_ADAPTER   pAd,
726         IN      USHORT                  Event_flag,
727         IN      PUCHAR                  pAddr,
728         IN      UCHAR                   BssIdx,
729         IN      CHAR                    Rssi)
730 {
731 #if WIRELESS_EXT >= 15
732
733         union   iwreq_data      wrqu;
734         PUCHAR  pBuf = NULL, pBufPtr = NULL;
735         USHORT  event, type, BufLen;
736         UCHAR   event_table_len = 0;
737
738         type = Event_flag & 0xFF00;
739         event = Event_flag & 0x00FF;
740
741         switch (type)
742         {
743                 case IW_SYS_EVENT_FLAG_START:
744                         event_table_len = IW_SYS_EVENT_TYPE_NUM;
745                         break;
746
747                 case IW_SPOOF_EVENT_FLAG_START:
748                         event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
749                         break;
750
751                 case IW_FLOOD_EVENT_FLAG_START:
752                         event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
753                         break;
754         }
755
756         if (event_table_len == 0)
757         {
758                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
759                 return;
760         }
761
762         if (event >= event_table_len)
763         {
764                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
765                 return;
766         }
767
768         //Allocate memory and copy the msg.
769         if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
770         {
771                 //Prepare the payload
772                 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
773
774                 pBufPtr = pBuf;
775
776                 if (pAddr)
777                         pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
778                 else if (BssIdx < MAX_MBSSID_NUM)
779                         pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
780                 else
781                         pBufPtr += sprintf(pBufPtr, "(RT2860) ");
782
783                 if (type == IW_SYS_EVENT_FLAG_START)
784                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
785                 else if (type == IW_SPOOF_EVENT_FLAG_START)
786                         pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
787                 else if (type == IW_FLOOD_EVENT_FLAG_START)
788                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
789                 else
790                         pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
791
792                 pBufPtr[pBufPtr - pBuf] = '\0';
793                 BufLen = pBufPtr - pBuf;
794
795                 memset(&wrqu, 0, sizeof(wrqu));
796             wrqu.data.flags = Event_flag;
797                 wrqu.data.length = BufLen;
798
799                 //send wireless event
800             wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
801
802                 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
803
804                 kfree(pBuf);
805         }
806         else
807                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
808 #else
809         DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
810 #endif  /* WIRELESS_EXT >= 15 */
811 }
812
813 void send_monitor_packets(
814         IN      PRTMP_ADAPTER   pAd,
815         IN      RX_BLK                  *pRxBlk)
816 {
817     struct sk_buff      *pOSPkt;
818     wlan_ng_prism2_header *ph;
819     int rate_index = 0;
820     USHORT header_len = 0;
821     UCHAR temp_header[40] = {0};
822
823     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
824         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,
825         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};
826
827
828     ASSERT(pRxBlk->pRxPacket);
829     if (pRxBlk->DataSize < 10)
830     {
831         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
832                 goto err_free_sk_buff;
833     }
834
835     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
836     {
837 #ifndef RT30xx
838         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
839 #endif
840 #ifdef RT30xx
841         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
842 #endif
843                 goto err_free_sk_buff;
844     }
845
846     pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
847         pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
848     if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
849     {
850         pRxBlk->DataSize -= LENGTH_802_11;
851         if ((pRxBlk->pHeader->FC.ToDs == 1) &&
852             (pRxBlk->pHeader->FC.FrDs == 1))
853             header_len = LENGTH_802_11_WITH_ADDR4;
854         else
855             header_len = LENGTH_802_11;
856
857         // QOS
858         if (pRxBlk->pHeader->FC.SubType & 0x08)
859         {
860             header_len += 2;
861                 // Data skip QOS contorl field
862                 pRxBlk->DataSize -=2;
863         }
864
865         // Order bit: A-Ralink or HTC+
866         if (pRxBlk->pHeader->FC.Order)
867         {
868             header_len += 4;
869                         // Data skip HTC contorl field
870                         pRxBlk->DataSize -= 4;
871         }
872
873         // Copy Header
874         if (header_len <= 40)
875             NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
876
877         // skip HW padding
878         if (pRxBlk->RxD.L2PAD)
879             pRxBlk->pData += (header_len + 2);
880         else
881             pRxBlk->pData += header_len;
882     } //end if
883
884
885         if (pRxBlk->DataSize < pOSPkt->len) {
886         skb_trim(pOSPkt,pRxBlk->DataSize);
887     } else {
888         skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
889     } //end if
890
891     if ((pRxBlk->pData - pOSPkt->data) > 0) {
892             skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
893             skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
894     } //end if
895
896     if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
897         if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
898                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
899                         goto err_free_sk_buff;
900             } //end if
901     } //end if
902
903     if (header_len > 0)
904         NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
905
906     ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
907         NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
908
909     ph->msgcode             = DIDmsg_lnxind_wlansniffrm;
910         ph->msglen                  = sizeof(wlan_ng_prism2_header);
911         strcpy(ph->devname, pAd->net_dev->name);
912
913     ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
914         ph->hosttime.status = 0;
915         ph->hosttime.len = 4;
916         ph->hosttime.data = jiffies;
917
918         ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
919         ph->mactime.status = 0;
920         ph->mactime.len = 0;
921         ph->mactime.data = 0;
922
923     ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
924         ph->istx.status = 0;
925         ph->istx.len = 0;
926         ph->istx.data = 0;
927
928     ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
929         ph->channel.status = 0;
930         ph->channel.len = 4;
931
932     ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
933
934     ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
935         ph->rssi.status = 0;
936         ph->rssi.len = 4;
937     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));;
938
939         ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
940         ph->signal.status = 0;
941         ph->signal.len = 4;
942         ph->signal.data = 0; //rssi + noise;
943
944         ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
945         ph->noise.status = 0;
946         ph->noise.len = 4;
947         ph->noise.data = 0;
948
949     if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
950     {
951         rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
952     }
953     else
954         if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
955         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
956     else
957         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
958     if (rate_index < 0)
959         rate_index = 0;
960     if (rate_index > 255)
961         rate_index = 255;
962
963         ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
964         ph->rate.status = 0;
965         ph->rate.len = 4;
966     ph->rate.data = ralinkrate[rate_index];
967
968         ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
969     ph->frmlen.status = 0;
970         ph->frmlen.len = 4;
971         ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
972
973
974     pOSPkt->pkt_type = PACKET_OTHERHOST;
975     pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
976     pOSPkt->ip_summed = CHECKSUM_NONE;
977     netif_rx(pOSPkt);
978
979     return;
980
981 err_free_sk_buff:
982         RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
983         return;
984
985 }
986
987 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
988 {
989         daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
990
991         allow_signal(SIGTERM);
992         allow_signal(SIGKILL);
993         current->flags |= PF_NOFREEZE;
994
995         /* signal that we've started the thread */
996         complete(pNotify);
997 }
998
999 void RTMP_IndicateMediaState(
1000         IN      PRTMP_ADAPTER   pAd)
1001 {
1002         if (pAd->CommonCfg.bWirelessEvent)
1003         {
1004                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1005                 {
1006                         RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1007                 }
1008                 else
1009                 {
1010                         RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1011                 }
1012         }
1013 }
1014