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