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);
37 BUILD_TIMER_FUNCTION(BeaconTimeout);
38 BUILD_TIMER_FUNCTION(ScanTimeout);
39 BUILD_TIMER_FUNCTION(AuthTimeout);
40 BUILD_TIMER_FUNCTION(AssocTimeout);
41 BUILD_TIMER_FUNCTION(ReassocTimeout);
42 BUILD_TIMER_FUNCTION(DisassocTimeout);
43 BUILD_TIMER_FUNCTION(LinkDownExec);
44 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
45 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
46 BUILD_TIMER_FUNCTION(PsPollWakeExec);
47 BUILD_TIMER_FUNCTION(RadioOnExec);
49 // for wireless system event message
50 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
51 // system status event
52 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
53 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
54 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
55 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
56 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
57 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
58 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
59 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
60 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
61 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
62 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
63 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
64 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
65 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
66 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
67 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
68 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
69 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
70 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
73 // for wireless IDS_spoof_attack event message
74 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
75 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
76 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
77 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
78 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
79 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
80 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
81 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
82 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
83 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
84 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
87 // for wireless IDS_flooding_attack event message
88 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
89 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
90 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
91 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
92 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
93 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
94 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
95 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
99 VOID RTMP_SetPeriodicTimer(
100 IN NDIS_MINIPORT_TIMER *pTimer,
101 IN unsigned long timeout)
103 timeout = ((timeout*HZ) / 1000);
104 pTimer->expires = jiffies + timeout;
108 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
109 VOID RTMP_OS_Init_Timer(
110 IN PRTMP_ADAPTER pAd,
111 IN NDIS_MINIPORT_TIMER *pTimer,
112 IN TIMER_FUNCTION function,
116 pTimer->data = (unsigned long)data;
117 pTimer->function = function;
121 VOID RTMP_OS_Add_Timer(
122 IN NDIS_MINIPORT_TIMER *pTimer,
123 IN unsigned long timeout)
125 if (timer_pending(pTimer))
128 timeout = ((timeout*HZ) / 1000);
129 pTimer->expires = jiffies + timeout;
133 VOID RTMP_OS_Mod_Timer(
134 IN NDIS_MINIPORT_TIMER *pTimer,
135 IN unsigned long timeout)
137 timeout = ((timeout*HZ) / 1000);
138 mod_timer(pTimer, jiffies + timeout);
141 VOID RTMP_OS_Del_Timer(
142 IN NDIS_MINIPORT_TIMER *pTimer,
143 OUT BOOLEAN *pCancelled)
145 if (timer_pending(pTimer))
147 *pCancelled = del_timer_sync(pTimer);
156 VOID RTMP_OS_Release_Packet(
157 IN PRTMP_ADAPTER pAd,
158 IN PQUEUE_ENTRY pEntry)
160 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
163 // Unify all delay routine by using udelay
169 for (i = 0; i < (usec / 50); i++)
176 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
178 time->u.LowPart = jiffies;
181 // pAd MUST allow to be NULL
182 NDIS_STATUS os_alloc_mem(
183 IN PRTMP_ADAPTER pAd,
187 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
189 return (NDIS_STATUS_SUCCESS);
191 return (NDIS_STATUS_FAILURE);
194 // pAd MUST allow to be NULL
195 NDIS_STATUS os_free_mem(
196 IN PRTMP_ADAPTER pAd,
202 return (NDIS_STATUS_SUCCESS);
206 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
207 IN PRTMP_ADAPTER pAd,
212 pkt = dev_alloc_skb(Length);
216 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
221 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
224 return (PNDIS_PACKET) pkt;
228 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
229 IN PRTMP_ADAPTER pAd,
232 OUT PVOID *VirtualAddress)
236 pkt = dev_alloc_skb(Length);
240 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
245 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
246 *VirtualAddress = (PVOID) pkt->data;
250 *VirtualAddress = (PVOID) NULL;
253 return (PNDIS_PACKET) pkt;
257 VOID build_tx_packet(
258 IN PRTMP_ADAPTER pAd,
259 IN PNDIS_PACKET pPacket,
264 struct sk_buff *pTxPkt;
267 pTxPkt = RTPKT_TO_OSPKT(pPacket);
269 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
272 VOID RTMPFreeAdapter(
273 IN PRTMP_ADAPTER pAd)
275 POS_COOKIE os_cookie;
278 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
280 kfree(pAd->BeaconBuf);
283 NdisFreeSpinLock(&pAd->MgmtRingLock);
285 NdisFreeSpinLock(&pAd->RxRingLock);
287 for (index =0 ; index < NUM_OF_TX_RING; index++)
289 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
290 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
291 pAd->DeQueueRunning[index] = FALSE;
294 NdisFreeSpinLock(&pAd->irq_lock);
296 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
300 BOOLEAN OS_Need_Clone_Packet(void)
308 ========================================================================
311 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
312 must have only one NDIS BUFFER
313 return - byte copied. 0 means can't create NDIS PACKET
314 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
317 pAd Pointer to our adapter
318 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
319 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
327 ========================================================================
329 NDIS_STATUS RTMPCloneNdisPacket(
330 IN PRTMP_ADAPTER pAd,
331 IN BOOLEAN pInsAMSDUHdr,
332 IN PNDIS_PACKET pInPacket,
333 OUT PNDIS_PACKET *ppOutPacket)
341 // 1. Allocate a packet
342 pkt = dev_alloc_skb(2048);
346 return NDIS_STATUS_FAILURE;
349 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
350 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
351 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
354 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
356 printk("###Clone###\n");
358 return NDIS_STATUS_SUCCESS;
362 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
363 NDIS_STATUS RTMPAllocateNdisPacket(
364 IN PRTMP_ADAPTER pAd,
365 OUT PNDIS_PACKET *ppPacket,
371 PNDIS_PACKET pPacket;
375 // 1. Allocate a packet
376 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
381 printk("RTMPAllocateNdisPacket Fail\n\n");
383 return NDIS_STATUS_FAILURE;
386 // 2. clone the frame content
388 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
390 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
392 // 3. update length of packet
393 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
395 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
396 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
398 return NDIS_STATUS_SUCCESS;
402 ========================================================================
404 This routine frees a miniport internally allocated NDIS_PACKET and its
405 corresponding NDIS_BUFFER and allocated memory.
406 ========================================================================
408 VOID RTMPFreeNdisPacket(
409 IN PRTMP_ADAPTER pAd,
410 IN PNDIS_PACKET pPacket)
412 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
416 // IRQL = DISPATCH_LEVEL
417 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
418 // scatter gather buffer
419 NDIS_STATUS Sniff2BytesFromNdisBuffer(
420 IN PNDIS_BUFFER pFirstBuffer,
421 IN UCHAR DesiredOffset,
425 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
426 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
428 return NDIS_STATUS_SUCCESS;
432 void RTMP_QueryPacketInfo(
433 IN PNDIS_PACKET pPacket,
434 OUT PACKET_INFO *pPacketInfo,
435 OUT PUCHAR *pSrcBufVA,
436 OUT UINT *pSrcBufLen)
438 pPacketInfo->BufferCount = 1;
439 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
440 pPacketInfo->PhysicalBufferCount = 1;
441 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
443 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
444 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
447 void RTMP_QueryNextPacketInfo(
448 IN PNDIS_PACKET *ppPacket,
449 OUT PACKET_INFO *pPacketInfo,
450 OUT PUCHAR *pSrcBufVA,
451 OUT UINT *pSrcBufLen)
453 PNDIS_PACKET pPacket = NULL;
456 pPacket = GET_OS_PKT_NEXT(*ppPacket);
460 pPacketInfo->BufferCount = 1;
461 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
462 pPacketInfo->PhysicalBufferCount = 1;
463 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
465 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
466 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
467 *ppPacket = GET_OS_PKT_NEXT(pPacket);
471 pPacketInfo->BufferCount = 0;
472 pPacketInfo->pFirstBuffer = NULL;
473 pPacketInfo->PhysicalBufferCount = 0;
474 pPacketInfo->TotalPacketLength = 0;
482 // not yet support MBSS
483 PNET_DEV get_netdev_from_bssid(
484 IN PRTMP_ADAPTER pAd,
485 IN UCHAR FromWhichBSSID)
487 PNET_DEV dev_p = NULL;
489 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
491 dev_p = pAd->net_dev;
495 return dev_p; /* return one of MBSS */
498 PNDIS_PACKET DuplicatePacket(
499 IN PRTMP_ADAPTER pAd,
500 IN PNDIS_PACKET pPacket,
501 IN UCHAR FromWhichBSSID)
504 PNDIS_PACKET pRetPacket = NULL;
508 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
509 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
512 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
515 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
516 pRetPacket = OSPKT_TO_RTPKT(skb);
523 PNDIS_PACKET duplicate_pkt(
524 IN PRTMP_ADAPTER pAd,
525 IN PUCHAR pHeader802_3,
529 IN UCHAR FromWhichBSSID)
532 PNDIS_PACKET pPacket = NULL;
535 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
538 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
539 skb_put(skb, HdrLen);
540 NdisMoveMemory(skb->tail, pData, DataSize);
541 skb_put(skb, DataSize);
542 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
543 pPacket = OSPKT_TO_RTPKT(skb);
550 #define TKIP_TX_MIC_SIZE 8
551 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
552 IN PRTMP_ADAPTER pAd,
553 IN PNDIS_PACKET pPacket)
555 struct sk_buff *skb, *newskb;
558 skb = RTPKT_TO_OSPKT(pPacket);
559 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
561 // alloc a new skb and copy the packet
562 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
563 dev_kfree_skb_any(skb);
566 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
572 return OSPKT_TO_RTPKT(skb);
578 PNDIS_PACKET ClonePacket(
579 IN PRTMP_ADAPTER pAd,
580 IN PNDIS_PACKET pPacket,
584 struct sk_buff *pRxPkt;
585 struct sk_buff *pClonedPkt;
588 pRxPkt = RTPKT_TO_OSPKT(pPacket);
591 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
595 // set the correct dataptr and data len
596 pClonedPkt->dev = pRxPkt->dev;
597 pClonedPkt->data = pData;
598 pClonedPkt->len = DataSize;
599 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
600 ASSERT(DataSize < 1530);
606 // change OS packet DataPtr and DataLen
608 void update_os_packet_info(
609 IN PRTMP_ADAPTER pAd,
611 IN UCHAR FromWhichBSSID)
613 struct sk_buff *pOSPkt;
615 ASSERT(pRxBlk->pRxPacket);
616 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
618 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
619 pOSPkt->data = pRxBlk->pData;
620 pOSPkt->len = pRxBlk->DataSize;
621 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
625 void wlan_802_11_to_802_3_packet(
626 IN PRTMP_ADAPTER pAd,
628 IN PUCHAR pHeader802_3,
629 IN UCHAR FromWhichBSSID)
631 struct sk_buff *pOSPkt;
633 ASSERT(pRxBlk->pRxPacket);
634 ASSERT(pHeader802_3);
636 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
638 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
639 pOSPkt->data = pRxBlk->pData;
640 pOSPkt->len = pRxBlk->DataSize;
641 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
648 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
649 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
654 void announce_802_3_packet(
655 IN PRTMP_ADAPTER pAd,
656 IN PNDIS_PACKET pPacket)
659 struct sk_buff *pRxPkt;
663 pRxPkt = RTPKT_TO_OSPKT(pPacket);
665 /* Push up the protocol stack */
667 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
669 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
672 #endif // IKANOS_VX_1X0 //
676 PRTMP_SCATTER_GATHER_LIST
677 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
679 sg->NumberOfElements = 1;
680 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
681 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
685 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
690 if (RTDebugLevel < RT_DEBUG_TRACE)
694 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
695 for (x=0; x<SrcBufLen; x++)
698 printk("0x%04x : ", x);
699 printk("%02x ", ((unsigned char)pt[x]));
700 if (x%16 == 15) printk("\n");
706 ========================================================================
709 Send log message through wireless event
711 Support standard iw_event with IWEVCUSTOM. It is used below.
713 iwreq_data.data.flags is used to store event_flag that is defined by user.
714 iwreq_data.data.length is the length of the event log.
716 The format of the event log is composed of the entry's MAC address and
717 the desired log message (refer to pWirelessEventText).
719 ex: 11:22:33:44:55:66 has associated successfully
721 p.s. The requirement of Wireless Extension is v15 or newer.
723 ========================================================================
725 VOID RTMPSendWirelessEvent(
726 IN PRTMP_ADAPTER pAd,
727 IN USHORT Event_flag,
732 #if WIRELESS_EXT >= 15
734 union iwreq_data wrqu;
735 PUCHAR pBuf = NULL, pBufPtr = NULL;
736 USHORT event, type, BufLen;
737 UCHAR event_table_len = 0;
739 type = Event_flag & 0xFF00;
740 event = Event_flag & 0x00FF;
744 case IW_SYS_EVENT_FLAG_START:
745 event_table_len = IW_SYS_EVENT_TYPE_NUM;
748 case IW_SPOOF_EVENT_FLAG_START:
749 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
752 case IW_FLOOD_EVENT_FLAG_START:
753 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
757 if (event_table_len == 0)
759 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
763 if (event >= event_table_len)
765 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
769 //Allocate memory and copy the msg.
770 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
772 //Prepare the payload
773 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
778 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
779 else if (BssIdx < MAX_MBSSID_NUM)
780 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
782 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
784 if (type == IW_SYS_EVENT_FLAG_START)
785 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
786 else if (type == IW_SPOOF_EVENT_FLAG_START)
787 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
788 else if (type == IW_FLOOD_EVENT_FLAG_START)
789 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
791 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
793 pBufPtr[pBufPtr - pBuf] = '\0';
794 BufLen = pBufPtr - pBuf;
796 memset(&wrqu, 0, sizeof(wrqu));
797 wrqu.data.flags = Event_flag;
798 wrqu.data.length = BufLen;
800 //send wireless event
801 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
803 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
808 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
810 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
811 #endif /* WIRELESS_EXT >= 15 */
814 void send_monitor_packets(
815 IN PRTMP_ADAPTER pAd,
818 struct sk_buff *pOSPkt;
819 wlan_ng_prism2_header *ph;
821 USHORT header_len = 0;
822 UCHAR temp_header[40] = {0};
824 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
825 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,
826 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};
829 ASSERT(pRxBlk->pRxPacket);
830 if (pRxBlk->DataSize < 10)
832 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
833 goto err_free_sk_buff;
836 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
838 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
839 goto err_free_sk_buff;
842 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
843 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
844 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
846 pRxBlk->DataSize -= LENGTH_802_11;
847 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
848 (pRxBlk->pHeader->FC.FrDs == 1))
849 header_len = LENGTH_802_11_WITH_ADDR4;
851 header_len = LENGTH_802_11;
854 if (pRxBlk->pHeader->FC.SubType & 0x08)
857 // Data skip QOS contorl field
858 pRxBlk->DataSize -=2;
861 // Order bit: A-Ralink or HTC+
862 if (pRxBlk->pHeader->FC.Order)
865 // Data skip HTC contorl field
866 pRxBlk->DataSize -= 4;
870 if (header_len <= 40)
871 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
874 if (pRxBlk->RxD.L2PAD)
875 pRxBlk->pData += (header_len + 2);
877 pRxBlk->pData += header_len;
881 if (pRxBlk->DataSize < pOSPkt->len) {
882 skb_trim(pOSPkt,pRxBlk->DataSize);
884 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
887 if ((pRxBlk->pData - pOSPkt->data) > 0) {
888 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
889 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
892 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
893 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
894 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
895 goto err_free_sk_buff;
900 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
902 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
903 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
905 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
906 ph->msglen = sizeof(wlan_ng_prism2_header);
907 strcpy(ph->devname, pAd->net_dev->name);
909 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
910 ph->hosttime.status = 0;
911 ph->hosttime.len = 4;
912 ph->hosttime.data = jiffies;
914 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
915 ph->mactime.status = 0;
917 ph->mactime.data = 0;
919 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
924 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
925 ph->channel.status = 0;
928 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
930 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
933 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));;
935 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
936 ph->signal.status = 0;
938 ph->signal.data = 0; //rssi + noise;
940 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
941 ph->noise.status = 0;
945 #ifdef DOT11_N_SUPPORT
946 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
948 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
951 #endif // DOT11_N_SUPPORT //
952 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
953 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
955 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
958 if (rate_index > 255)
961 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
964 ph->rate.data = ralinkrate[rate_index];
966 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
967 ph->frmlen.status = 0;
969 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
972 pOSPkt->pkt_type = PACKET_OTHERHOST;
973 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
974 pOSPkt->ip_summed = CHECKSUM_NONE;
980 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
985 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
987 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
989 allow_signal(SIGTERM);
990 allow_signal(SIGKILL);
991 current->flags |= PF_NOFREEZE;
993 /* signal that we've started the thread */
997 void RTMP_IndicateMediaState(
998 IN PRTMP_ADAPTER pAd)
1000 if (pAd->CommonCfg.bWirelessEvent)
1002 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1004 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1008 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);