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