blob: 992e3d16f9b4fbab893aeba7ed34fe83f8d2de0f [file] [log] [blame]
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -08001/*
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
30ULONG RTDebugLevel = RT_DEBUG_ERROR;
31
32BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
34BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
35BUILD_TIMER_FUNCTION(APSDPeriodicExec);
36BUILD_TIMER_FUNCTION(AsicRfTuningExec);
37#ifdef RT2870
38BUILD_TIMER_FUNCTION(BeaconUpdateExec);
39#endif // RT2870 //
40
41
42#ifdef CONFIG_STA_SUPPORT
43BUILD_TIMER_FUNCTION(BeaconTimeout);
44BUILD_TIMER_FUNCTION(ScanTimeout);
45BUILD_TIMER_FUNCTION(AuthTimeout);
46BUILD_TIMER_FUNCTION(AssocTimeout);
47BUILD_TIMER_FUNCTION(ReassocTimeout);
48BUILD_TIMER_FUNCTION(DisassocTimeout);
49BUILD_TIMER_FUNCTION(LinkDownExec);
50#ifdef LEAP_SUPPORT
51BUILD_TIMER_FUNCTION(LeapAuthTimeout);
52#endif
53BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
54BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
55#ifdef QOS_DLS_SUPPORT
56BUILD_TIMER_FUNCTION(DlsTimeoutAction);
57#endif // QOS_DLS_SUPPORT //
58#endif // CONFIG_STA_SUPPORT //
59
60// for wireless system event message
61char 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
85char 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
99char 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 */
110VOID 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 */
120VOID 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
132VOID 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
144VOID 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
152VOID 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
167VOID 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
175VOID 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
187void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
188{
189 time->u.LowPart = jiffies;
190}
191
192// pAd MUST allow to be NULL
193NDIS_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
206NDIS_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
217PNDIS_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
239PNDIS_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
268VOID 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
283VOID 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
311BOOLEAN 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*/
340NDIS_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()
374NDIS_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);
Harvey Harrisond599edc2009-01-07 14:31:57 -0800407// printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800408 *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*/
419VOID 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
430NDIS_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
443void 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
458void 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
494PNET_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
512PNDIS_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
548PNDIS_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
576PNDIS_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
628PNDIS_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//
658void 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
675void 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
706void 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
734PRTMP_SCATTER_GATHER_LIST
735rt_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
743void 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*/
783VOID 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 {
Harvey Harrisond599edc2009-01-07 14:31:57 -0800817 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800818 return;
819 }
820
821 if (event >= event_table_len)
822 {
Harvey Harrisond599edc2009-01-07 14:31:57 -0800823 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800824 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
Harvey Harrisond599edc2009-01-07 14:31:57 -0800861 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800862
863 kfree(pBuf);
864 }
865 else
Harvey Harrisond599edc2009-01-07 14:31:57 -0800866 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800867#else
Harvey Harrisond599edc2009-01-07 14:31:57 -0800868 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800869#endif /* WIRELESS_EXT >= 15 */
870}
871
872
873#ifdef CONFIG_STA_SUPPORT
874void 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 {
Harvey Harrisond599edc2009-01-07 14:31:57 -0800892 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800893 goto err_free_sk_buff;
894 }
895
896 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
897 {
Harvey Harrisond599edc2009-01-07 14:31:57 -0800898 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800899 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)) {
Harvey Harrisond599edc2009-01-07 14:31:57 -0800954 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
Greg Kroah-Hartmanc55519f2008-12-17 17:04:23 -0800955 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
1039err_free_sk_buff:
1040 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1041 return;
1042
1043}
1044#endif // CONFIG_STA_SUPPORT //
1045
1046
1047void 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
1080void 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