]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt2860/rt_linux.c
staging: __FUNCTION__ is gcc-specific, use __func__
[net-next-2.6.git] / drivers / staging / rt2860 / rt_linux.c
CommitLineData
91980990
GKH
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
30ULONG RTDebugLevel = RT_DEBUG_ERROR;
31
32BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
34BUILD_TIMER_FUNCTION(APSDPeriodicExec);
35BUILD_TIMER_FUNCTION(AsicRfTuningExec);
36
37
38#ifdef CONFIG_STA_SUPPORT
39BUILD_TIMER_FUNCTION(BeaconTimeout);
40BUILD_TIMER_FUNCTION(ScanTimeout);
41BUILD_TIMER_FUNCTION(AuthTimeout);
42BUILD_TIMER_FUNCTION(AssocTimeout);
43BUILD_TIMER_FUNCTION(ReassocTimeout);
44BUILD_TIMER_FUNCTION(DisassocTimeout);
45BUILD_TIMER_FUNCTION(LinkDownExec);
46#ifdef LEAP_SUPPORT
47BUILD_TIMER_FUNCTION(LeapAuthTimeout);
48#endif
49BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
50BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51#ifdef RT2860
52BUILD_TIMER_FUNCTION(PsPollWakeExec);
53BUILD_TIMER_FUNCTION(RadioOnExec);
54#endif // RT2860 //
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#ifdef RT2860
297 NdisFreeSpinLock(&pAd->RxRingLock);
298#endif // RT2860 //
299
300 for (index =0 ; index < NUM_OF_TX_RING; index++)
301 {
302 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
303 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
304 pAd->DeQueueRunning[index] = FALSE;
305 }
306
307 NdisFreeSpinLock(&pAd->irq_lock);
308
309 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
310 kfree(os_cookie);
311}
312
313BOOLEAN OS_Need_Clone_Packet(void)
314{
315 return (FALSE);
316}
317
318
319
320/*
321 ========================================================================
322
323 Routine Description:
324 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
325 must have only one NDIS BUFFER
326 return - byte copied. 0 means can't create NDIS PACKET
327 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
328
329 Arguments:
330 pAd Pointer to our adapter
331 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
332 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
333
334 Return Value:
335 NDIS_STATUS_SUCCESS
336 NDIS_STATUS_FAILURE
337
338 Note:
339
340 ========================================================================
341*/
342NDIS_STATUS RTMPCloneNdisPacket(
343 IN PRTMP_ADAPTER pAd,
344 IN BOOLEAN pInsAMSDUHdr,
345 IN PNDIS_PACKET pInPacket,
346 OUT PNDIS_PACKET *ppOutPacket)
347{
348
349 struct sk_buff *pkt;
350
351 ASSERT(pInPacket);
352 ASSERT(ppOutPacket);
353
354 // 1. Allocate a packet
355 pkt = dev_alloc_skb(2048);
356
357 if (pkt == NULL)
358 {
359 return NDIS_STATUS_FAILURE;
360 }
361
362 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
363 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
364 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
365
366
367 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
368
369 printk("###Clone###\n");
370
371 return NDIS_STATUS_SUCCESS;
372}
373
374
375// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
376NDIS_STATUS RTMPAllocateNdisPacket(
377 IN PRTMP_ADAPTER pAd,
378 OUT PNDIS_PACKET *ppPacket,
379 IN PUCHAR pHeader,
380 IN UINT HeaderLen,
381 IN PUCHAR pData,
382 IN UINT DataLen)
383{
384 PNDIS_PACKET pPacket;
385 ASSERT(pData);
386 ASSERT(DataLen);
387
388 // 1. Allocate a packet
389 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
390 if (pPacket == NULL)
391 {
392 *ppPacket = NULL;
393#ifdef DEBUG
394 printk("RTMPAllocateNdisPacket Fail\n\n");
395#endif
396 return NDIS_STATUS_FAILURE;
397 }
398
399 // 2. clone the frame content
400 if (HeaderLen > 0)
401 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
402 if (DataLen > 0)
403 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
404
405 // 3. update length of packet
406 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
407
408 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
d599edca 409// printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
91980990
GKH
410 *ppPacket = pPacket;
411 return NDIS_STATUS_SUCCESS;
412}
413
414/*
415 ========================================================================
416 Description:
417 This routine frees a miniport internally allocated NDIS_PACKET and its
418 corresponding NDIS_BUFFER and allocated memory.
419 ========================================================================
420*/
421VOID RTMPFreeNdisPacket(
422 IN PRTMP_ADAPTER pAd,
423 IN PNDIS_PACKET pPacket)
424{
425 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
426}
427
428
429// IRQL = DISPATCH_LEVEL
430// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
431// scatter gather buffer
432NDIS_STATUS Sniff2BytesFromNdisBuffer(
433 IN PNDIS_BUFFER pFirstBuffer,
434 IN UCHAR DesiredOffset,
435 OUT PUCHAR pByte0,
436 OUT PUCHAR pByte1)
437{
438 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
439 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
440
441 return NDIS_STATUS_SUCCESS;
442}
443
444
445void RTMP_QueryPacketInfo(
446 IN PNDIS_PACKET pPacket,
447 OUT PACKET_INFO *pPacketInfo,
448 OUT PUCHAR *pSrcBufVA,
449 OUT UINT *pSrcBufLen)
450{
451 pPacketInfo->BufferCount = 1;
452 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
453 pPacketInfo->PhysicalBufferCount = 1;
454 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
455
456 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
457 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
458}
459
460void RTMP_QueryNextPacketInfo(
461 IN PNDIS_PACKET *ppPacket,
462 OUT PACKET_INFO *pPacketInfo,
463 OUT PUCHAR *pSrcBufVA,
464 OUT UINT *pSrcBufLen)
465{
466 PNDIS_PACKET pPacket = NULL;
467
468 if (*ppPacket)
469 pPacket = GET_OS_PKT_NEXT(*ppPacket);
470
471 if (pPacket)
472 {
473 pPacketInfo->BufferCount = 1;
474 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
475 pPacketInfo->PhysicalBufferCount = 1;
476 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
477
478 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
479 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
480 *ppPacket = GET_OS_PKT_NEXT(pPacket);
481 }
482 else
483 {
484 pPacketInfo->BufferCount = 0;
485 pPacketInfo->pFirstBuffer = NULL;
486 pPacketInfo->PhysicalBufferCount = 0;
487 pPacketInfo->TotalPacketLength = 0;
488
489 *pSrcBufVA = NULL;
490 *pSrcBufLen = 0;
491 *ppPacket = NULL;
492 }
493}
494
495// not yet support MBSS
496PNET_DEV get_netdev_from_bssid(
497 IN PRTMP_ADAPTER pAd,
498 IN UCHAR FromWhichBSSID)
499{
500 PNET_DEV dev_p = NULL;
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
513PNDIS_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
538PNDIS_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
566PNDIS_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
593PNDIS_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//
623void 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
640void 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
671void 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 /* Push up the protocol stack */
683#ifdef IKANOS_VX_1X0
684 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
685#else
686 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
687
688 netif_rx(pRxPkt);
689#endif // IKANOS_VX_1X0 //
690}
691
692
693PRTMP_SCATTER_GATHER_LIST
694rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
695{
696 sg->NumberOfElements = 1;
697 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
698 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
699 return (sg);
700}
701
702void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
703{
704 unsigned char *pt;
705 int x;
706
707 if (RTDebugLevel < RT_DEBUG_TRACE)
708 return;
709
710 pt = pSrcBufVA;
711 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
712 for (x=0; x<SrcBufLen; x++)
713 {
714 if (x % 16 == 0)
715 printk("0x%04x : ", x);
716 printk("%02x ", ((unsigned char)pt[x]));
717 if (x%16 == 15) printk("\n");
718 }
719 printk("\n");
720}
721
722/*
723 ========================================================================
724
725 Routine Description:
726 Send log message through wireless event
727
728 Support standard iw_event with IWEVCUSTOM. It is used below.
729
730 iwreq_data.data.flags is used to store event_flag that is defined by user.
731 iwreq_data.data.length is the length of the event log.
732
733 The format of the event log is composed of the entry's MAC address and
734 the desired log message (refer to pWirelessEventText).
735
736 ex: 11:22:33:44:55:66 has associated successfully
737
738 p.s. The requirement of Wireless Extension is v15 or newer.
739
740 ========================================================================
741*/
742VOID RTMPSendWirelessEvent(
743 IN PRTMP_ADAPTER pAd,
744 IN USHORT Event_flag,
745 IN PUCHAR pAddr,
746 IN UCHAR BssIdx,
747 IN CHAR Rssi)
748{
749#if WIRELESS_EXT >= 15
750
751 union iwreq_data wrqu;
752 PUCHAR pBuf = NULL, pBufPtr = NULL;
753 USHORT event, type, BufLen;
754 UCHAR event_table_len = 0;
755
756 type = Event_flag & 0xFF00;
757 event = Event_flag & 0x00FF;
758
759 switch (type)
760 {
761 case IW_SYS_EVENT_FLAG_START:
762 event_table_len = IW_SYS_EVENT_TYPE_NUM;
763 break;
764
765 case IW_SPOOF_EVENT_FLAG_START:
766 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
767 break;
768
769 case IW_FLOOD_EVENT_FLAG_START:
770 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
771 break;
772 }
773
774 if (event_table_len == 0)
775 {
d599edca 776 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
91980990
GKH
777 return;
778 }
779
780 if (event >= event_table_len)
781 {
d599edca 782 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
91980990
GKH
783 return;
784 }
785
786 //Allocate memory and copy the msg.
787 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
788 {
789 //Prepare the payload
790 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
791
792 pBufPtr = pBuf;
793
794 if (pAddr)
795 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
796 else if (BssIdx < MAX_MBSSID_NUM)
797 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
798 else
799 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
800
801 if (type == IW_SYS_EVENT_FLAG_START)
802 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
803 else if (type == IW_SPOOF_EVENT_FLAG_START)
804 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
805 else if (type == IW_FLOOD_EVENT_FLAG_START)
806 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
807 else
808 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
809
810 pBufPtr[pBufPtr - pBuf] = '\0';
811 BufLen = pBufPtr - pBuf;
812
813 memset(&wrqu, 0, sizeof(wrqu));
814 wrqu.data.flags = Event_flag;
815 wrqu.data.length = BufLen;
816
817 //send wireless event
818 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
819
d599edca 820 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
91980990
GKH
821
822 kfree(pBuf);
823 }
824 else
d599edca 825 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
91980990 826#else
d599edca 827 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
91980990
GKH
828#endif /* WIRELESS_EXT >= 15 */
829}
830
831
832#ifdef CONFIG_STA_SUPPORT
833void send_monitor_packets(
834 IN PRTMP_ADAPTER pAd,
835 IN RX_BLK *pRxBlk)
836{
837 struct sk_buff *pOSPkt;
838 wlan_ng_prism2_header *ph;
839 int rate_index = 0;
840 USHORT header_len = 0;
841 UCHAR temp_header[40] = {0};
842
843 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
844 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,
845 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};
846
847
848 ASSERT(pRxBlk->pRxPacket);
849 if (pRxBlk->DataSize < 10)
850 {
d599edca 851 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
91980990
GKH
852 goto err_free_sk_buff;
853 }
854
855 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
856 {
d599edca 857 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
91980990
GKH
858 goto err_free_sk_buff;
859 }
860
861 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
862 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
863 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
864 {
865 pRxBlk->DataSize -= LENGTH_802_11;
866 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
867 (pRxBlk->pHeader->FC.FrDs == 1))
868 header_len = LENGTH_802_11_WITH_ADDR4;
869 else
870 header_len = LENGTH_802_11;
871
872 // QOS
873 if (pRxBlk->pHeader->FC.SubType & 0x08)
874 {
875 header_len += 2;
876 // Data skip QOS contorl field
877 pRxBlk->DataSize -=2;
878 }
879
880 // Order bit: A-Ralink or HTC+
881 if (pRxBlk->pHeader->FC.Order)
882 {
883 header_len += 4;
884 // Data skip HTC contorl field
885 pRxBlk->DataSize -= 4;
886 }
887
888 // Copy Header
889 if (header_len <= 40)
890 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
891
892 // skip HW padding
893 if (pRxBlk->RxD.L2PAD)
894 pRxBlk->pData += (header_len + 2);
895 else
896 pRxBlk->pData += header_len;
897 } //end if
898
899
900 if (pRxBlk->DataSize < pOSPkt->len) {
901 skb_trim(pOSPkt,pRxBlk->DataSize);
902 } else {
903 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
904 } //end if
905
906 if ((pRxBlk->pData - pOSPkt->data) > 0) {
907 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
908 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
909 } //end if
910
911 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
912 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
d599edca 913 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
91980990
GKH
914 goto err_free_sk_buff;
915 } //end if
916 } //end if
917
918 if (header_len > 0)
919 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
920
921 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
922 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
923
924 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
925 ph->msglen = sizeof(wlan_ng_prism2_header);
926 strcpy(ph->devname, pAd->net_dev->name);
927
928 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
929 ph->hosttime.status = 0;
930 ph->hosttime.len = 4;
931 ph->hosttime.data = jiffies;
932
933 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
934 ph->mactime.status = 0;
935 ph->mactime.len = 0;
936 ph->mactime.data = 0;
937
938 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
939 ph->istx.status = 0;
940 ph->istx.len = 0;
941 ph->istx.data = 0;
942
943 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
944 ph->channel.status = 0;
945 ph->channel.len = 4;
946
947 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
948
949 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
950 ph->rssi.status = 0;
951 ph->rssi.len = 4;
952 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));;
953
954 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
955 ph->signal.status = 0;
956 ph->signal.len = 4;
957 ph->signal.data = 0; //rssi + noise;
958
959 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
960 ph->noise.status = 0;
961 ph->noise.len = 4;
962 ph->noise.data = 0;
963
964#ifdef DOT11_N_SUPPORT
965 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
966 {
967 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
968 }
969 else
970#endif // DOT11_N_SUPPORT //
971 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
972 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
973 else
974 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
975 if (rate_index < 0)
976 rate_index = 0;
977 if (rate_index > 255)
978 rate_index = 255;
979
980 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
981 ph->rate.status = 0;
982 ph->rate.len = 4;
983 ph->rate.data = ralinkrate[rate_index];
984
985 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
986 ph->frmlen.status = 0;
987 ph->frmlen.len = 4;
988 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
989
990
991 pOSPkt->pkt_type = PACKET_OTHERHOST;
992 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
993 pOSPkt->ip_summed = CHECKSUM_NONE;
994 netif_rx(pOSPkt);
995
996 return;
997
998err_free_sk_buff:
999 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1000 return;
1001
1002}
1003#endif // CONFIG_STA_SUPPORT //
1004
1005
1006void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1007{
1008
1009#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1010 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1011
1012 allow_signal(SIGTERM);
1013 allow_signal(SIGKILL);
1014 current->flags |= PF_NOFREEZE;
1015#else
1016 unsigned long flags;
1017
1018 daemonize();
1019 reparent_to_init();
1020 strcpy(current->comm, pThreadName);
1021
1022 siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1023
1024 /* Allow interception of SIGKILL only
1025 * Don't allow other signals to interrupt the transmission */
1026#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1027 spin_lock_irqsave(&current->sigmask_lock, flags);
1028 flush_signals(current);
1029 recalc_sigpending(current);
1030 spin_unlock_irqrestore(&current->sigmask_lock, flags);
1031#endif
1032#endif
1033
1034 /* signal that we've started the thread */
1035 complete(pNotify);
1036
1037}
1038
1039void RTMP_IndicateMediaState(
1040 IN PRTMP_ADAPTER pAd)
1041{
1042 if (pAd->CommonCfg.bWirelessEvent)
1043 {
1044 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1045 {
1046 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1047 }
1048 else
1049 {
1050 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1051 }
1052 }
1053}
1054