2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
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. *
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. *
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. *
25 *************************************************************************
28 #include "rt_config.h"
30 ULONG RTDebugLevel = RT_DEBUG_ERROR;
32 BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
34 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
35 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
38 #ifdef CONFIG_STA_SUPPORT
39 BUILD_TIMER_FUNCTION(BeaconTimeout);
40 BUILD_TIMER_FUNCTION(ScanTimeout);
41 BUILD_TIMER_FUNCTION(AuthTimeout);
42 BUILD_TIMER_FUNCTION(AssocTimeout);
43 BUILD_TIMER_FUNCTION(ReassocTimeout);
44 BUILD_TIMER_FUNCTION(DisassocTimeout);
45 BUILD_TIMER_FUNCTION(LinkDownExec);
47 BUILD_TIMER_FUNCTION(LeapAuthTimeout);
49 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
50 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51 BUILD_TIMER_FUNCTION(PsPollWakeExec);
52 BUILD_TIMER_FUNCTION(RadioOnExec);
53 #endif // CONFIG_STA_SUPPORT //
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 */
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 */
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 */
105 VOID RTMP_SetPeriodicTimer(
106 IN NDIS_MINIPORT_TIMER *pTimer,
107 IN unsigned long timeout)
109 timeout = ((timeout*HZ) / 1000);
110 pTimer->expires = jiffies + timeout;
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,
122 pTimer->data = (unsigned long)data;
123 pTimer->function = function;
127 VOID RTMP_OS_Add_Timer(
128 IN NDIS_MINIPORT_TIMER *pTimer,
129 IN unsigned long timeout)
131 if (timer_pending(pTimer))
134 timeout = ((timeout*HZ) / 1000);
135 pTimer->expires = jiffies + timeout;
139 VOID RTMP_OS_Mod_Timer(
140 IN NDIS_MINIPORT_TIMER *pTimer,
141 IN unsigned long timeout)
143 timeout = ((timeout*HZ) / 1000);
144 mod_timer(pTimer, jiffies + timeout);
147 VOID RTMP_OS_Del_Timer(
148 IN NDIS_MINIPORT_TIMER *pTimer,
149 OUT BOOLEAN *pCancelled)
151 if (timer_pending(pTimer))
153 *pCancelled = del_timer_sync(pTimer);
162 VOID RTMP_OS_Release_Packet(
163 IN PRTMP_ADAPTER pAd,
164 IN PQUEUE_ENTRY pEntry)
166 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
169 // Unify all delay routine by using udelay
175 for (i = 0; i < (usec / 50); i++)
182 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
184 time->u.LowPart = jiffies;
187 // pAd MUST allow to be NULL
188 NDIS_STATUS os_alloc_mem(
189 IN PRTMP_ADAPTER pAd,
193 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
195 return (NDIS_STATUS_SUCCESS);
197 return (NDIS_STATUS_FAILURE);
200 // pAd MUST allow to be NULL
201 NDIS_STATUS os_free_mem(
202 IN PRTMP_ADAPTER pAd,
208 return (NDIS_STATUS_SUCCESS);
212 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
213 IN PRTMP_ADAPTER pAd,
218 pkt = dev_alloc_skb(Length);
222 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
227 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
230 return (PNDIS_PACKET) pkt;
234 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
235 IN PRTMP_ADAPTER pAd,
238 OUT PVOID *VirtualAddress)
242 pkt = dev_alloc_skb(Length);
246 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
251 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
252 *VirtualAddress = (PVOID) pkt->data;
256 *VirtualAddress = (PVOID) NULL;
259 return (PNDIS_PACKET) pkt;
263 VOID build_tx_packet(
264 IN PRTMP_ADAPTER pAd,
265 IN PNDIS_PACKET pPacket,
270 struct sk_buff *pTxPkt;
273 pTxPkt = RTPKT_TO_OSPKT(pPacket);
275 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
278 VOID RTMPFreeAdapter(
279 IN PRTMP_ADAPTER pAd)
281 POS_COOKIE os_cookie;
284 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
286 kfree(pAd->BeaconBuf);
289 NdisFreeSpinLock(&pAd->MgmtRingLock);
291 NdisFreeSpinLock(&pAd->RxRingLock);
293 for (index =0 ; index < NUM_OF_TX_RING; index++)
295 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
296 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
297 pAd->DeQueueRunning[index] = FALSE;
300 NdisFreeSpinLock(&pAd->irq_lock);
302 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
306 BOOLEAN OS_Need_Clone_Packet(void)
314 ========================================================================
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
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.
333 ========================================================================
335 NDIS_STATUS RTMPCloneNdisPacket(
336 IN PRTMP_ADAPTER pAd,
337 IN BOOLEAN pInsAMSDUHdr,
338 IN PNDIS_PACKET pInPacket,
339 OUT PNDIS_PACKET *ppOutPacket)
347 // 1. Allocate a packet
348 pkt = dev_alloc_skb(2048);
352 return NDIS_STATUS_FAILURE;
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);
360 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
362 printk("###Clone###\n");
364 return NDIS_STATUS_SUCCESS;
368 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
369 NDIS_STATUS RTMPAllocateNdisPacket(
370 IN PRTMP_ADAPTER pAd,
371 OUT PNDIS_PACKET *ppPacket,
377 PNDIS_PACKET pPacket;
381 // 1. Allocate a packet
382 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
387 printk("RTMPAllocateNdisPacket Fail\n\n");
389 return NDIS_STATUS_FAILURE;
392 // 2. clone the frame content
394 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
396 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
398 // 3. update length of packet
399 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
401 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
402 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
404 return NDIS_STATUS_SUCCESS;
408 ========================================================================
410 This routine frees a miniport internally allocated NDIS_PACKET and its
411 corresponding NDIS_BUFFER and allocated memory.
412 ========================================================================
414 VOID RTMPFreeNdisPacket(
415 IN PRTMP_ADAPTER pAd,
416 IN PNDIS_PACKET pPacket)
418 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
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,
431 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
432 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
434 return NDIS_STATUS_SUCCESS;
438 void RTMP_QueryPacketInfo(
439 IN PNDIS_PACKET pPacket,
440 OUT PACKET_INFO *pPacketInfo,
441 OUT PUCHAR *pSrcBufVA,
442 OUT UINT *pSrcBufLen)
444 pPacketInfo->BufferCount = 1;
445 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
446 pPacketInfo->PhysicalBufferCount = 1;
447 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
449 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
450 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
453 void RTMP_QueryNextPacketInfo(
454 IN PNDIS_PACKET *ppPacket,
455 OUT PACKET_INFO *pPacketInfo,
456 OUT PUCHAR *pSrcBufVA,
457 OUT UINT *pSrcBufLen)
459 PNDIS_PACKET pPacket = NULL;
462 pPacket = GET_OS_PKT_NEXT(*ppPacket);
466 pPacketInfo->BufferCount = 1;
467 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
468 pPacketInfo->PhysicalBufferCount = 1;
469 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
471 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
472 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
473 *ppPacket = GET_OS_PKT_NEXT(pPacket);
477 pPacketInfo->BufferCount = 0;
478 pPacketInfo->pFirstBuffer = NULL;
479 pPacketInfo->PhysicalBufferCount = 0;
480 pPacketInfo->TotalPacketLength = 0;
488 // not yet support MBSS
489 PNET_DEV get_netdev_from_bssid(
490 IN PRTMP_ADAPTER pAd,
491 IN UCHAR FromWhichBSSID)
493 PNET_DEV dev_p = NULL;
495 #ifdef CONFIG_STA_SUPPORT
496 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
498 dev_p = pAd->net_dev;
500 #endif // CONFIG_STA_SUPPORT //
503 return dev_p; /* return one of MBSS */
506 PNDIS_PACKET DuplicatePacket(
507 IN PRTMP_ADAPTER pAd,
508 IN PNDIS_PACKET pPacket,
509 IN UCHAR FromWhichBSSID)
512 PNDIS_PACKET pRetPacket = NULL;
516 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
517 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
520 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
523 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
524 pRetPacket = OSPKT_TO_RTPKT(skb);
531 PNDIS_PACKET duplicate_pkt(
532 IN PRTMP_ADAPTER pAd,
533 IN PUCHAR pHeader802_3,
537 IN UCHAR FromWhichBSSID)
540 PNDIS_PACKET pPacket = NULL;
543 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
546 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
547 skb_put(skb, HdrLen);
548 NdisMoveMemory(skb->tail, pData, DataSize);
549 skb_put(skb, DataSize);
550 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
551 pPacket = OSPKT_TO_RTPKT(skb);
558 #define TKIP_TX_MIC_SIZE 8
559 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
560 IN PRTMP_ADAPTER pAd,
561 IN PNDIS_PACKET pPacket)
563 struct sk_buff *skb, *newskb;
566 skb = RTPKT_TO_OSPKT(pPacket);
567 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
569 // alloc a new skb and copy the packet
570 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
571 dev_kfree_skb_any(skb);
574 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
580 return OSPKT_TO_RTPKT(skb);
586 PNDIS_PACKET ClonePacket(
587 IN PRTMP_ADAPTER pAd,
588 IN PNDIS_PACKET pPacket,
592 struct sk_buff *pRxPkt;
593 struct sk_buff *pClonedPkt;
596 pRxPkt = RTPKT_TO_OSPKT(pPacket);
599 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
603 // set the correct dataptr and data len
604 pClonedPkt->dev = pRxPkt->dev;
605 pClonedPkt->data = pData;
606 pClonedPkt->len = DataSize;
607 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
608 ASSERT(DataSize < 1530);
614 // change OS packet DataPtr and DataLen
616 void update_os_packet_info(
617 IN PRTMP_ADAPTER pAd,
619 IN UCHAR FromWhichBSSID)
621 struct sk_buff *pOSPkt;
623 ASSERT(pRxBlk->pRxPacket);
624 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
626 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
627 pOSPkt->data = pRxBlk->pData;
628 pOSPkt->len = pRxBlk->DataSize;
629 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
633 void wlan_802_11_to_802_3_packet(
634 IN PRTMP_ADAPTER pAd,
636 IN PUCHAR pHeader802_3,
637 IN UCHAR FromWhichBSSID)
639 struct sk_buff *pOSPkt;
641 ASSERT(pRxBlk->pRxPacket);
642 ASSERT(pHeader802_3);
644 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
646 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
647 pOSPkt->data = pRxBlk->pData;
648 pOSPkt->len = pRxBlk->DataSize;
649 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
656 #ifdef CONFIG_STA_SUPPORT
657 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
658 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
659 #endif // CONFIG_STA_SUPPORT //
664 void announce_802_3_packet(
665 IN PRTMP_ADAPTER pAd,
666 IN PNDIS_PACKET pPacket)
669 struct sk_buff *pRxPkt;
673 pRxPkt = RTPKT_TO_OSPKT(pPacket);
675 /* Push up the protocol stack */
677 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
679 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
682 #endif // IKANOS_VX_1X0 //
686 PRTMP_SCATTER_GATHER_LIST
687 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
689 sg->NumberOfElements = 1;
690 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
691 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
695 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
700 if (RTDebugLevel < RT_DEBUG_TRACE)
704 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
705 for (x=0; x<SrcBufLen; x++)
708 printk("0x%04x : ", x);
709 printk("%02x ", ((unsigned char)pt[x]));
710 if (x%16 == 15) printk("\n");
716 ========================================================================
719 Send log message through wireless event
721 Support standard iw_event with IWEVCUSTOM. It is used below.
723 iwreq_data.data.flags is used to store event_flag that is defined by user.
724 iwreq_data.data.length is the length of the event log.
726 The format of the event log is composed of the entry's MAC address and
727 the desired log message (refer to pWirelessEventText).
729 ex: 11:22:33:44:55:66 has associated successfully
731 p.s. The requirement of Wireless Extension is v15 or newer.
733 ========================================================================
735 VOID RTMPSendWirelessEvent(
736 IN PRTMP_ADAPTER pAd,
737 IN USHORT Event_flag,
742 #if WIRELESS_EXT >= 15
744 union iwreq_data wrqu;
745 PUCHAR pBuf = NULL, pBufPtr = NULL;
746 USHORT event, type, BufLen;
747 UCHAR event_table_len = 0;
749 type = Event_flag & 0xFF00;
750 event = Event_flag & 0x00FF;
754 case IW_SYS_EVENT_FLAG_START:
755 event_table_len = IW_SYS_EVENT_TYPE_NUM;
758 case IW_SPOOF_EVENT_FLAG_START:
759 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
762 case IW_FLOOD_EVENT_FLAG_START:
763 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
767 if (event_table_len == 0)
769 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
773 if (event >= event_table_len)
775 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
779 //Allocate memory and copy the msg.
780 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
782 //Prepare the payload
783 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
788 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
789 else if (BssIdx < MAX_MBSSID_NUM)
790 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
792 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
794 if (type == IW_SYS_EVENT_FLAG_START)
795 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
796 else if (type == IW_SPOOF_EVENT_FLAG_START)
797 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
798 else if (type == IW_FLOOD_EVENT_FLAG_START)
799 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
801 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
803 pBufPtr[pBufPtr - pBuf] = '\0';
804 BufLen = pBufPtr - pBuf;
806 memset(&wrqu, 0, sizeof(wrqu));
807 wrqu.data.flags = Event_flag;
808 wrqu.data.length = BufLen;
810 //send wireless event
811 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
813 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
818 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
820 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
821 #endif /* WIRELESS_EXT >= 15 */
825 #ifdef CONFIG_STA_SUPPORT
826 void send_monitor_packets(
827 IN PRTMP_ADAPTER pAd,
830 struct sk_buff *pOSPkt;
831 wlan_ng_prism2_header *ph;
833 USHORT header_len = 0;
834 UCHAR temp_header[40] = {0};
836 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
837 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,
838 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};
841 ASSERT(pRxBlk->pRxPacket);
842 if (pRxBlk->DataSize < 10)
844 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
845 goto err_free_sk_buff;
848 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
850 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
851 goto err_free_sk_buff;
854 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
855 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
856 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
858 pRxBlk->DataSize -= LENGTH_802_11;
859 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
860 (pRxBlk->pHeader->FC.FrDs == 1))
861 header_len = LENGTH_802_11_WITH_ADDR4;
863 header_len = LENGTH_802_11;
866 if (pRxBlk->pHeader->FC.SubType & 0x08)
869 // Data skip QOS contorl field
870 pRxBlk->DataSize -=2;
873 // Order bit: A-Ralink or HTC+
874 if (pRxBlk->pHeader->FC.Order)
877 // Data skip HTC contorl field
878 pRxBlk->DataSize -= 4;
882 if (header_len <= 40)
883 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
886 if (pRxBlk->RxD.L2PAD)
887 pRxBlk->pData += (header_len + 2);
889 pRxBlk->pData += header_len;
893 if (pRxBlk->DataSize < pOSPkt->len) {
894 skb_trim(pOSPkt,pRxBlk->DataSize);
896 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
899 if ((pRxBlk->pData - pOSPkt->data) > 0) {
900 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
901 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
904 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
905 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
906 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
907 goto err_free_sk_buff;
912 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
914 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
915 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
917 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
918 ph->msglen = sizeof(wlan_ng_prism2_header);
919 strcpy(ph->devname, pAd->net_dev->name);
921 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
922 ph->hosttime.status = 0;
923 ph->hosttime.len = 4;
924 ph->hosttime.data = jiffies;
926 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
927 ph->mactime.status = 0;
929 ph->mactime.data = 0;
931 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
936 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
937 ph->channel.status = 0;
940 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
942 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
945 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));;
947 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
948 ph->signal.status = 0;
950 ph->signal.data = 0; //rssi + noise;
952 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
953 ph->noise.status = 0;
957 #ifdef DOT11_N_SUPPORT
958 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
960 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
963 #endif // DOT11_N_SUPPORT //
964 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
965 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
967 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
970 if (rate_index > 255)
973 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
976 ph->rate.data = ralinkrate[rate_index];
978 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
979 ph->frmlen.status = 0;
981 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
984 pOSPkt->pkt_type = PACKET_OTHERHOST;
985 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
986 pOSPkt->ip_summed = CHECKSUM_NONE;
992 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
996 #endif // CONFIG_STA_SUPPORT //
999 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1001 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1003 allow_signal(SIGTERM);
1004 allow_signal(SIGKILL);
1005 current->flags |= PF_NOFREEZE;
1007 /* signal that we've started the thread */
1011 void RTMP_IndicateMediaState(
1012 IN PRTMP_ADAPTER pAd)
1014 if (pAd->CommonCfg.bWirelessEvent)
1016 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1018 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1022 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);