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