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