Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt3070 / rt_linux.c
blobbf3385365da1b329e38b19be511090fea35264e4
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
28 #include "rt_config.h"
30 ULONG RTDebugLevel = RT_DEBUG_ERROR;
32 BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33 //BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
34 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
35 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
36 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
37 #ifdef RT2870
38 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
39 #endif // RT2870 //
42 #ifdef CONFIG_STA_SUPPORT
43 BUILD_TIMER_FUNCTION(BeaconTimeout);
44 BUILD_TIMER_FUNCTION(ScanTimeout);
45 BUILD_TIMER_FUNCTION(AuthTimeout);
46 BUILD_TIMER_FUNCTION(AssocTimeout);
47 BUILD_TIMER_FUNCTION(ReassocTimeout);
48 BUILD_TIMER_FUNCTION(DisassocTimeout);
49 BUILD_TIMER_FUNCTION(LinkDownExec);
50 #ifdef LEAP_SUPPORT
51 BUILD_TIMER_FUNCTION(LeapAuthTimeout);
52 #endif
53 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
54 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
55 #ifdef QOS_DLS_SUPPORT
56 BUILD_TIMER_FUNCTION(DlsTimeoutAction);
57 #endif // QOS_DLS_SUPPORT //
58 #endif // CONFIG_STA_SUPPORT //
63 // for wireless system event message
64 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
65 // system status event
66 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
67 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
68 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
69 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
70 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
71 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
72 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
73 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
74 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
75 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
76 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
77 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
78 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
79 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
80 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
81 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
82 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
83 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
84 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
87 // for wireless IDS_spoof_attack event message
88 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
89 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
90 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
91 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
92 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
93 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
94 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
95 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
96 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
97 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
98 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
101 // for wireless IDS_flooding_attack event message
102 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
103 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
104 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
105 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
106 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
107 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
108 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
109 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
113 /* timeout -- ms */
114 VOID RTMP_SetPeriodicTimer(
115 IN NDIS_MINIPORT_TIMER *pTimer,
116 IN unsigned long timeout)
118 timeout = ((timeout*HZ) / 1000);
119 pTimer->expires = jiffies + timeout;
120 add_timer(pTimer);
123 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
124 VOID RTMP_OS_Init_Timer(
125 IN PRTMP_ADAPTER pAd,
126 IN NDIS_MINIPORT_TIMER *pTimer,
127 IN TIMER_FUNCTION function,
128 IN PVOID data)
130 init_timer(pTimer);
131 pTimer->data = (unsigned long)data;
132 pTimer->function = function;
136 VOID RTMP_OS_Add_Timer(
137 IN NDIS_MINIPORT_TIMER *pTimer,
138 IN unsigned long timeout)
140 if (timer_pending(pTimer))
141 return;
143 timeout = ((timeout*HZ) / 1000);
144 pTimer->expires = jiffies + timeout;
145 add_timer(pTimer);
148 VOID RTMP_OS_Mod_Timer(
149 IN NDIS_MINIPORT_TIMER *pTimer,
150 IN unsigned long timeout)
152 timeout = ((timeout*HZ) / 1000);
153 mod_timer(pTimer, jiffies + timeout);
156 VOID RTMP_OS_Del_Timer(
157 IN NDIS_MINIPORT_TIMER *pTimer,
158 OUT BOOLEAN *pCancelled)
160 if (timer_pending(pTimer))
162 *pCancelled = del_timer_sync(pTimer);
164 else
166 *pCancelled = TRUE;
171 VOID RTMP_OS_Release_Packet(
172 IN PRTMP_ADAPTER pAd,
173 IN PQUEUE_ENTRY pEntry)
175 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
178 // Unify all delay routine by using udelay
179 VOID RTMPusecDelay(
180 IN ULONG usec)
182 ULONG i;
184 for (i = 0; i < (usec / 50); i++)
185 udelay(50);
187 if (usec % 50)
188 udelay(usec % 50);
191 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
193 time->u.LowPart = jiffies;
196 // pAd MUST allow to be NULL
197 NDIS_STATUS os_alloc_mem(
198 IN PRTMP_ADAPTER pAd,
199 OUT PUCHAR *mem,
200 IN ULONG size)
202 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
203 if (*mem)
204 return (NDIS_STATUS_SUCCESS);
205 else
206 return (NDIS_STATUS_FAILURE);
209 // pAd MUST allow to be NULL
210 NDIS_STATUS os_free_mem(
211 IN PRTMP_ADAPTER pAd,
212 IN PUCHAR mem)
215 ASSERT(mem);
216 kfree(mem);
217 return (NDIS_STATUS_SUCCESS);
221 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
222 IN PRTMP_ADAPTER pAd,
223 IN ULONG Length)
225 struct sk_buff *pkt;
227 pkt = dev_alloc_skb(Length);
229 if (pkt == NULL)
231 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
234 if (pkt)
236 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
239 return (PNDIS_PACKET) pkt;
243 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
244 IN PRTMP_ADAPTER pAd,
245 IN ULONG Length,
246 IN BOOLEAN Cached,
247 OUT PVOID *VirtualAddress)
249 struct sk_buff *pkt;
251 pkt = dev_alloc_skb(Length);
253 if (pkt == NULL)
255 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
258 if (pkt)
260 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
261 *VirtualAddress = (PVOID) pkt->data;
263 else
265 *VirtualAddress = (PVOID) NULL;
268 return (PNDIS_PACKET) pkt;
272 VOID build_tx_packet(
273 IN PRTMP_ADAPTER pAd,
274 IN PNDIS_PACKET pPacket,
275 IN PUCHAR pFrame,
276 IN ULONG FrameLen)
279 struct sk_buff *pTxPkt;
281 ASSERT(pPacket);
282 pTxPkt = RTPKT_TO_OSPKT(pPacket);
284 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
287 VOID RTMPFreeAdapter(
288 IN PRTMP_ADAPTER pAd)
290 POS_COOKIE os_cookie;
291 int index;
293 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
295 kfree(pAd->BeaconBuf);
298 NdisFreeSpinLock(&pAd->MgmtRingLock);
301 for (index =0 ; index < NUM_OF_TX_RING; index++)
303 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
304 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
305 pAd->DeQueueRunning[index] = FALSE;
308 NdisFreeSpinLock(&pAd->irq_lock);
311 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
312 kfree(os_cookie);
315 BOOLEAN OS_Need_Clone_Packet(void)
317 return (FALSE);
323 ========================================================================
325 Routine Description:
326 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
327 must have only one NDIS BUFFER
328 return - byte copied. 0 means can't create NDIS PACKET
329 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
331 Arguments:
332 pAd Pointer to our adapter
333 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
334 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
336 Return Value:
337 NDIS_STATUS_SUCCESS
338 NDIS_STATUS_FAILURE
340 Note:
342 ========================================================================
344 NDIS_STATUS RTMPCloneNdisPacket(
345 IN PRTMP_ADAPTER pAd,
346 IN BOOLEAN pInsAMSDUHdr,
347 IN PNDIS_PACKET pInPacket,
348 OUT PNDIS_PACKET *ppOutPacket)
351 struct sk_buff *pkt;
353 ASSERT(pInPacket);
354 ASSERT(ppOutPacket);
356 // 1. Allocate a packet
357 pkt = dev_alloc_skb(2048);
359 if (pkt == NULL)
361 return NDIS_STATUS_FAILURE;
364 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
365 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
366 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
369 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
371 printk("###Clone###\n");
373 return NDIS_STATUS_SUCCESS;
377 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
378 NDIS_STATUS RTMPAllocateNdisPacket(
379 IN PRTMP_ADAPTER pAd,
380 OUT PNDIS_PACKET *ppPacket,
381 IN PUCHAR pHeader,
382 IN UINT HeaderLen,
383 IN PUCHAR pData,
384 IN UINT DataLen)
386 PNDIS_PACKET pPacket;
387 ASSERT(pData);
388 ASSERT(DataLen);
390 // 1. Allocate a packet
391 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
392 if (pPacket == NULL)
394 *ppPacket = NULL;
395 #ifdef DEBUG
396 printk("RTMPAllocateNdisPacket Fail\n\n");
397 #endif
398 return NDIS_STATUS_FAILURE;
401 // 2. clone the frame content
402 if (HeaderLen > 0)
403 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
404 if (DataLen > 0)
405 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
407 // 3. update length of packet
408 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
410 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
411 // printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
412 *ppPacket = pPacket;
413 return NDIS_STATUS_SUCCESS;
417 ========================================================================
418 Description:
419 This routine frees a miniport internally allocated NDIS_PACKET and its
420 corresponding NDIS_BUFFER and allocated memory.
421 ========================================================================
423 VOID RTMPFreeNdisPacket(
424 IN PRTMP_ADAPTER pAd,
425 IN PNDIS_PACKET pPacket)
427 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
431 // IRQL = DISPATCH_LEVEL
432 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
433 // scatter gather buffer
434 NDIS_STATUS Sniff2BytesFromNdisBuffer(
435 IN PNDIS_BUFFER pFirstBuffer,
436 IN UCHAR DesiredOffset,
437 OUT PUCHAR pByte0,
438 OUT PUCHAR pByte1)
440 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
441 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
443 return NDIS_STATUS_SUCCESS;
447 void RTMP_QueryPacketInfo(
448 IN PNDIS_PACKET pPacket,
449 OUT PACKET_INFO *pPacketInfo,
450 OUT PUCHAR *pSrcBufVA,
451 OUT UINT *pSrcBufLen)
453 pPacketInfo->BufferCount = 1;
454 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
455 pPacketInfo->PhysicalBufferCount = 1;
456 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
458 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
459 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
462 void RTMP_QueryNextPacketInfo(
463 IN PNDIS_PACKET *ppPacket,
464 OUT PACKET_INFO *pPacketInfo,
465 OUT PUCHAR *pSrcBufVA,
466 OUT UINT *pSrcBufLen)
468 PNDIS_PACKET pPacket = NULL;
470 if (*ppPacket)
471 pPacket = GET_OS_PKT_NEXT(*ppPacket);
473 if (pPacket)
475 pPacketInfo->BufferCount = 1;
476 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
477 pPacketInfo->PhysicalBufferCount = 1;
478 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
480 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
481 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
482 *ppPacket = GET_OS_PKT_NEXT(pPacket);
484 else
486 pPacketInfo->BufferCount = 0;
487 pPacketInfo->pFirstBuffer = NULL;
488 pPacketInfo->PhysicalBufferCount = 0;
489 pPacketInfo->TotalPacketLength = 0;
491 *pSrcBufVA = NULL;
492 *pSrcBufLen = 0;
493 *ppPacket = NULL;
497 // not yet support MBSS
498 PNET_DEV get_netdev_from_bssid(
499 IN PRTMP_ADAPTER pAd,
500 IN UCHAR FromWhichBSSID)
502 PNET_DEV dev_p = NULL;
505 #ifdef CONFIG_STA_SUPPORT
506 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
508 dev_p = pAd->net_dev;
510 #endif // CONFIG_STA_SUPPORT //
512 ASSERT(dev_p);
513 return dev_p; /* return one of MBSS */
516 PNDIS_PACKET DuplicatePacket(
517 IN PRTMP_ADAPTER pAd,
518 IN PNDIS_PACKET pPacket,
519 IN UCHAR FromWhichBSSID)
521 struct sk_buff *skb;
522 PNDIS_PACKET pRetPacket = NULL;
523 USHORT DataSize;
524 UCHAR *pData;
526 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
527 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
530 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
531 if (skb)
533 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
534 pRetPacket = OSPKT_TO_RTPKT(skb);
537 return pRetPacket;
541 PNDIS_PACKET duplicate_pkt(
542 IN PRTMP_ADAPTER pAd,
543 IN PUCHAR pHeader802_3,
544 IN UINT HdrLen,
545 IN PUCHAR pData,
546 IN ULONG DataSize,
547 IN UCHAR FromWhichBSSID)
549 struct sk_buff *skb;
550 PNDIS_PACKET pPacket = NULL;
553 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
555 skb_reserve(skb, 2);
556 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
557 skb_put(skb, HdrLen);
558 NdisMoveMemory(skb->tail, pData, DataSize);
559 skb_put(skb, DataSize);
560 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
561 pPacket = OSPKT_TO_RTPKT(skb);
564 return pPacket;
568 #define TKIP_TX_MIC_SIZE 8
569 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
570 IN PRTMP_ADAPTER pAd,
571 IN PNDIS_PACKET pPacket)
573 struct sk_buff *skb, *newskb;
576 skb = RTPKT_TO_OSPKT(pPacket);
577 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
579 // alloc a new skb and copy the packet
580 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
581 dev_kfree_skb_any(skb);
582 if (newskb == NULL)
584 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
585 return NULL;
587 skb = newskb;
590 return OSPKT_TO_RTPKT(skb);
596 PNDIS_PACKET ClonePacket(
597 IN PRTMP_ADAPTER pAd,
598 IN PNDIS_PACKET pPacket,
599 IN PUCHAR pData,
600 IN ULONG DataSize)
602 struct sk_buff *pRxPkt;
603 struct sk_buff *pClonedPkt;
605 ASSERT(pPacket);
606 pRxPkt = RTPKT_TO_OSPKT(pPacket);
608 // clone the packet
609 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
611 if (pClonedPkt)
613 // set the correct dataptr and data len
614 pClonedPkt->dev = pRxPkt->dev;
615 pClonedPkt->data = pData;
616 pClonedPkt->len = DataSize;
617 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
618 ASSERT(DataSize < 1530);
620 return pClonedPkt;
624 // change OS packet DataPtr and DataLen
626 void update_os_packet_info(
627 IN PRTMP_ADAPTER pAd,
628 IN RX_BLK *pRxBlk,
629 IN UCHAR FromWhichBSSID)
631 struct sk_buff *pOSPkt;
633 ASSERT(pRxBlk->pRxPacket);
634 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
636 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
637 pOSPkt->data = pRxBlk->pData;
638 pOSPkt->len = pRxBlk->DataSize;
639 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
643 void wlan_802_11_to_802_3_packet(
644 IN PRTMP_ADAPTER pAd,
645 IN RX_BLK *pRxBlk,
646 IN PUCHAR pHeader802_3,
647 IN UCHAR FromWhichBSSID)
649 struct sk_buff *pOSPkt;
651 ASSERT(pRxBlk->pRxPacket);
652 ASSERT(pHeader802_3);
654 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
656 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
657 pOSPkt->data = pRxBlk->pData;
658 pOSPkt->len = pRxBlk->DataSize;
659 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
662 // copy 802.3 header
666 #ifdef CONFIG_STA_SUPPORT
667 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
668 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
669 #endif // CONFIG_STA_SUPPORT //
674 void announce_802_3_packet(
675 IN PRTMP_ADAPTER pAd,
676 IN PNDIS_PACKET pPacket)
679 struct sk_buff *pRxPkt;
681 ASSERT(pPacket);
683 pRxPkt = RTPKT_TO_OSPKT(pPacket);
685 #ifdef CONFIG_STA_SUPPORT
686 #endif // CONFIG_STA_SUPPORT //
688 /* Push up the protocol stack */
689 #ifdef IKANOS_VX_1X0
690 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
691 #else
692 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
694 //#ifdef CONFIG_5VT_ENHANCE
695 // *(int*)(pRxPkt->cb) = BRIDGE_TAG;
696 //#endif
697 netif_rx(pRxPkt);
698 #endif // IKANOS_VX_1X0 //
702 PRTMP_SCATTER_GATHER_LIST
703 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
705 sg->NumberOfElements = 1;
706 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
707 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
708 return (sg);
711 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
713 unsigned char *pt;
714 int x;
716 if (RTDebugLevel < RT_DEBUG_TRACE)
717 return;
719 pt = pSrcBufVA;
720 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
721 for (x=0; x<SrcBufLen; x++)
723 if (x % 16 == 0)
724 printk("0x%04x : ", x);
725 printk("%02x ", ((unsigned char)pt[x]));
726 if (x%16 == 15) printk("\n");
728 printk("\n");
732 ========================================================================
734 Routine Description:
735 Send log message through wireless event
737 Support standard iw_event with IWEVCUSTOM. It is used below.
739 iwreq_data.data.flags is used to store event_flag that is defined by user.
740 iwreq_data.data.length is the length of the event log.
742 The format of the event log is composed of the entry's MAC address and
743 the desired log message (refer to pWirelessEventText).
745 ex: 11:22:33:44:55:66 has associated successfully
747 p.s. The requirement of Wireless Extension is v15 or newer.
749 ========================================================================
751 VOID RTMPSendWirelessEvent(
752 IN PRTMP_ADAPTER pAd,
753 IN USHORT Event_flag,
754 IN PUCHAR pAddr,
755 IN UCHAR BssIdx,
756 IN CHAR Rssi)
758 #if WIRELESS_EXT >= 15
760 union iwreq_data wrqu;
761 PUCHAR pBuf = NULL, pBufPtr = NULL;
762 USHORT event, type, BufLen;
763 UCHAR event_table_len = 0;
765 type = Event_flag & 0xFF00;
766 event = Event_flag & 0x00FF;
768 switch (type)
770 case IW_SYS_EVENT_FLAG_START:
771 event_table_len = IW_SYS_EVENT_TYPE_NUM;
772 break;
774 case IW_SPOOF_EVENT_FLAG_START:
775 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
776 break;
778 case IW_FLOOD_EVENT_FLAG_START:
779 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
780 break;
783 if (event_table_len == 0)
785 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
786 return;
789 if (event >= event_table_len)
791 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
792 return;
795 //Allocate memory and copy the msg.
796 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
798 //Prepare the payload
799 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
801 pBufPtr = pBuf;
803 if (pAddr)
804 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
805 else if (BssIdx < MAX_MBSSID_NUM)
806 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
807 else
808 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
810 if (type == IW_SYS_EVENT_FLAG_START)
811 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
812 else if (type == IW_SPOOF_EVENT_FLAG_START)
813 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
814 else if (type == IW_FLOOD_EVENT_FLAG_START)
815 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
816 else
817 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
819 pBufPtr[pBufPtr - pBuf] = '\0';
820 BufLen = pBufPtr - pBuf;
822 memset(&wrqu, 0, sizeof(wrqu));
823 wrqu.data.flags = Event_flag;
824 wrqu.data.length = BufLen;
826 //send wireless event
827 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
829 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
831 kfree(pBuf);
833 else
834 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
835 #else
836 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
837 #endif /* WIRELESS_EXT >= 15 */
841 #ifdef CONFIG_STA_SUPPORT
842 void send_monitor_packets(
843 IN PRTMP_ADAPTER pAd,
844 IN RX_BLK *pRxBlk)
846 struct sk_buff *pOSPkt;
847 wlan_ng_prism2_header *ph;
848 int rate_index = 0;
849 USHORT header_len = 0;
850 UCHAR temp_header[40] = {0};
852 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
853 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,
854 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};
857 ASSERT(pRxBlk->pRxPacket);
858 if (pRxBlk->DataSize < 10)
860 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
861 goto err_free_sk_buff;
864 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
866 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
867 goto err_free_sk_buff;
870 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
871 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
872 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
874 pRxBlk->DataSize -= LENGTH_802_11;
875 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
876 (pRxBlk->pHeader->FC.FrDs == 1))
877 header_len = LENGTH_802_11_WITH_ADDR4;
878 else
879 header_len = LENGTH_802_11;
881 // QOS
882 if (pRxBlk->pHeader->FC.SubType & 0x08)
884 header_len += 2;
885 // Data skip QOS contorl field
886 pRxBlk->DataSize -=2;
889 // Order bit: A-Ralink or HTC+
890 if (pRxBlk->pHeader->FC.Order)
892 header_len += 4;
893 // Data skip HTC contorl field
894 pRxBlk->DataSize -= 4;
897 // Copy Header
898 if (header_len <= 40)
899 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
901 // skip HW padding
902 if (pRxBlk->RxD.L2PAD)
903 pRxBlk->pData += (header_len + 2);
904 else
905 pRxBlk->pData += header_len;
906 } //end if
909 if (pRxBlk->DataSize < pOSPkt->len) {
910 skb_trim(pOSPkt,pRxBlk->DataSize);
911 } else {
912 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
913 } //end if
915 if ((pRxBlk->pData - pOSPkt->data) > 0) {
916 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
917 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
918 } //end if
920 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
921 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
922 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
923 goto err_free_sk_buff;
924 } //end if
925 } //end if
927 if (header_len > 0)
928 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
930 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
931 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
933 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
934 ph->msglen = sizeof(wlan_ng_prism2_header);
935 strcpy(ph->devname, pAd->net_dev->name);
937 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
938 ph->hosttime.status = 0;
939 ph->hosttime.len = 4;
940 ph->hosttime.data = jiffies;
942 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
943 ph->mactime.status = 0;
944 ph->mactime.len = 0;
945 ph->mactime.data = 0;
947 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
948 ph->istx.status = 0;
949 ph->istx.len = 0;
950 ph->istx.data = 0;
952 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
953 ph->channel.status = 0;
954 ph->channel.len = 4;
956 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
958 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
959 ph->rssi.status = 0;
960 ph->rssi.len = 4;
961 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));;
963 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
964 ph->signal.status = 0;
965 ph->signal.len = 4;
966 ph->signal.data = 0; //rssi + noise;
968 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
969 ph->noise.status = 0;
970 ph->noise.len = 4;
971 ph->noise.data = 0;
973 #ifdef DOT11_N_SUPPORT
974 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
976 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
978 else
979 #endif // DOT11_N_SUPPORT //
980 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
981 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
982 else
983 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
984 if (rate_index < 0)
985 rate_index = 0;
986 if (rate_index > 255)
987 rate_index = 255;
989 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
990 ph->rate.status = 0;
991 ph->rate.len = 4;
992 ph->rate.data = ralinkrate[rate_index];
994 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
995 ph->frmlen.status = 0;
996 ph->frmlen.len = 4;
997 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
1000 pOSPkt->pkt_type = PACKET_OTHERHOST;
1001 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
1002 pOSPkt->ip_summed = CHECKSUM_NONE;
1003 netif_rx(pOSPkt);
1005 return;
1007 err_free_sk_buff:
1008 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1009 return;
1012 #endif // CONFIG_STA_SUPPORT //
1015 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1018 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1019 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1021 allow_signal(SIGTERM);
1022 allow_signal(SIGKILL);
1023 current->flags |= PF_NOFREEZE;
1024 #else
1025 unsigned long flags;
1027 daemonize();
1028 reparent_to_init();
1029 strcpy(current->comm, pThreadName);
1031 siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1033 /* Allow interception of SIGKILL only
1034 * Don't allow other signals to interrupt the transmission */
1035 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1036 spin_lock_irqsave(&current->sigmask_lock, flags);
1037 flush_signals(current);
1038 recalc_sigpending(current);
1039 spin_unlock_irqrestore(&current->sigmask_lock, flags);
1040 #endif
1041 #endif
1043 /* signal that we've started the thread */
1044 complete(pNotify);
1048 void RTMP_IndicateMediaState(
1049 IN PRTMP_ADAPTER pAd)
1051 if (pAd->CommonCfg.bWirelessEvent)
1053 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1055 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1057 else
1059 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);