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