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