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