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(MlmeRssiReportExec);
34 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
35 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
36 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
38 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
41 BUILD_TIMER_FUNCTION(BeaconTimeout);
42 BUILD_TIMER_FUNCTION(ScanTimeout);
43 BUILD_TIMER_FUNCTION(AuthTimeout);
44 BUILD_TIMER_FUNCTION(AssocTimeout);
45 BUILD_TIMER_FUNCTION(ReassocTimeout);
46 BUILD_TIMER_FUNCTION(DisassocTimeout);
47 BUILD_TIMER_FUNCTION(LinkDownExec);
48 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
49 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51 // for wireless system event message
52 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
53 // system status event
54 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
55 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
56 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
57 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
58 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
59 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
60 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
61 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
62 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
63 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
64 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
65 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
66 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
67 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
68 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
69 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
70 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
71 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
72 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
75 // for wireless IDS_spoof_attack event message
76 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
77 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
78 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
79 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
80 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
81 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
82 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
83 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
84 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
85 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
86 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
89 // for wireless IDS_flooding_attack event message
90 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
91 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
92 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
93 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
94 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
95 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
96 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
97 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
101 VOID RTMP_SetPeriodicTimer(
102 IN NDIS_MINIPORT_TIMER *pTimer,
103 IN unsigned long timeout)
105 timeout = ((timeout*HZ) / 1000);
106 pTimer->expires = jiffies + timeout;
110 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
111 VOID RTMP_OS_Init_Timer(
112 IN PRTMP_ADAPTER pAd,
113 IN NDIS_MINIPORT_TIMER *pTimer,
114 IN TIMER_FUNCTION function,
118 pTimer->data = (unsigned long)data;
119 pTimer->function = function;
123 VOID RTMP_OS_Add_Timer(
124 IN NDIS_MINIPORT_TIMER *pTimer,
125 IN unsigned long timeout)
127 if (timer_pending(pTimer))
130 timeout = ((timeout*HZ) / 1000);
131 pTimer->expires = jiffies + timeout;
135 VOID RTMP_OS_Mod_Timer(
136 IN NDIS_MINIPORT_TIMER *pTimer,
137 IN unsigned long timeout)
139 timeout = ((timeout*HZ) / 1000);
140 mod_timer(pTimer, jiffies + timeout);
143 VOID RTMP_OS_Del_Timer(
144 IN NDIS_MINIPORT_TIMER *pTimer,
145 OUT BOOLEAN *pCancelled)
147 if (timer_pending(pTimer))
149 *pCancelled = del_timer_sync(pTimer);
158 VOID RTMP_OS_Release_Packet(
159 IN PRTMP_ADAPTER pAd,
160 IN PQUEUE_ENTRY pEntry)
162 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
165 // Unify all delay routine by using udelay
171 for (i = 0; i < (usec / 50); i++)
178 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
180 time->u.LowPart = jiffies;
183 // pAd MUST allow to be NULL
184 NDIS_STATUS os_alloc_mem(
185 IN PRTMP_ADAPTER pAd,
189 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
191 return (NDIS_STATUS_SUCCESS);
193 return (NDIS_STATUS_FAILURE);
196 // pAd MUST allow to be NULL
197 NDIS_STATUS os_free_mem(
198 IN PRTMP_ADAPTER pAd,
204 return (NDIS_STATUS_SUCCESS);
208 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
209 IN PRTMP_ADAPTER pAd,
214 pkt = dev_alloc_skb(Length);
218 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
223 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
226 return (PNDIS_PACKET) pkt;
230 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
231 IN PRTMP_ADAPTER pAd,
234 OUT PVOID *VirtualAddress)
238 pkt = dev_alloc_skb(Length);
242 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
247 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
248 *VirtualAddress = (PVOID) pkt->data;
252 *VirtualAddress = (PVOID) NULL;
255 return (PNDIS_PACKET) pkt;
259 VOID build_tx_packet(
260 IN PRTMP_ADAPTER pAd,
261 IN PNDIS_PACKET pPacket,
266 struct sk_buff *pTxPkt;
269 pTxPkt = RTPKT_TO_OSPKT(pPacket);
271 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
274 VOID RTMPFreeAdapter(
275 IN PRTMP_ADAPTER pAd)
277 POS_COOKIE os_cookie;
280 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
282 kfree(pAd->BeaconBuf);
285 NdisFreeSpinLock(&pAd->MgmtRingLock);
288 for (index =0 ; index < NUM_OF_TX_RING; index++)
290 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
291 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
292 pAd->DeQueueRunning[index] = FALSE;
295 NdisFreeSpinLock(&pAd->irq_lock);
298 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
302 BOOLEAN OS_Need_Clone_Packet(void)
310 ========================================================================
313 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
314 must have only one NDIS BUFFER
315 return - byte copied. 0 means can't create NDIS PACKET
316 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
319 pAd Pointer to our adapter
320 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
321 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
329 ========================================================================
331 NDIS_STATUS RTMPCloneNdisPacket(
332 IN PRTMP_ADAPTER pAd,
333 IN BOOLEAN pInsAMSDUHdr,
334 IN PNDIS_PACKET pInPacket,
335 OUT PNDIS_PACKET *ppOutPacket)
343 // 1. Allocate a packet
344 pkt = dev_alloc_skb(2048);
348 return NDIS_STATUS_FAILURE;
351 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
352 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
353 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
356 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
358 printk("###Clone###\n");
360 return NDIS_STATUS_SUCCESS;
364 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
365 NDIS_STATUS RTMPAllocateNdisPacket(
366 IN PRTMP_ADAPTER pAd,
367 OUT PNDIS_PACKET *ppPacket,
373 PNDIS_PACKET pPacket;
377 // 1. Allocate a packet
378 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
383 printk("RTMPAllocateNdisPacket Fail\n\n");
385 return NDIS_STATUS_FAILURE;
388 // 2. clone the frame content
390 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
392 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
394 // 3. update length of packet
395 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
397 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
398 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
400 return NDIS_STATUS_SUCCESS;
404 ========================================================================
406 This routine frees a miniport internally allocated NDIS_PACKET and its
407 corresponding NDIS_BUFFER and allocated memory.
408 ========================================================================
410 VOID RTMPFreeNdisPacket(
411 IN PRTMP_ADAPTER pAd,
412 IN PNDIS_PACKET pPacket)
414 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
418 // IRQL = DISPATCH_LEVEL
419 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
420 // scatter gather buffer
421 NDIS_STATUS Sniff2BytesFromNdisBuffer(
422 IN PNDIS_BUFFER pFirstBuffer,
423 IN UCHAR DesiredOffset,
427 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
428 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
430 return NDIS_STATUS_SUCCESS;
434 void RTMP_QueryPacketInfo(
435 IN PNDIS_PACKET pPacket,
436 OUT PACKET_INFO *pPacketInfo,
437 OUT PUCHAR *pSrcBufVA,
438 OUT UINT *pSrcBufLen)
440 pPacketInfo->BufferCount = 1;
441 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
442 pPacketInfo->PhysicalBufferCount = 1;
443 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
445 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
446 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
449 void RTMP_QueryNextPacketInfo(
450 IN PNDIS_PACKET *ppPacket,
451 OUT PACKET_INFO *pPacketInfo,
452 OUT PUCHAR *pSrcBufVA,
453 OUT UINT *pSrcBufLen)
455 PNDIS_PACKET pPacket = NULL;
458 pPacket = GET_OS_PKT_NEXT(*ppPacket);
462 pPacketInfo->BufferCount = 1;
463 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
464 pPacketInfo->PhysicalBufferCount = 1;
465 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
467 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
468 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
469 *ppPacket = GET_OS_PKT_NEXT(pPacket);
473 pPacketInfo->BufferCount = 0;
474 pPacketInfo->pFirstBuffer = NULL;
475 pPacketInfo->PhysicalBufferCount = 0;
476 pPacketInfo->TotalPacketLength = 0;
484 // not yet support MBSS
485 PNET_DEV get_netdev_from_bssid(
486 IN PRTMP_ADAPTER pAd,
487 IN UCHAR FromWhichBSSID)
489 PNET_DEV dev_p = NULL;
491 dev_p = pAd->net_dev;
494 return dev_p; /* return one of MBSS */
497 PNDIS_PACKET DuplicatePacket(
498 IN PRTMP_ADAPTER pAd,
499 IN PNDIS_PACKET pPacket,
500 IN UCHAR FromWhichBSSID)
503 PNDIS_PACKET pRetPacket = NULL;
507 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
508 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
511 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
514 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
515 pRetPacket = OSPKT_TO_RTPKT(skb);
519 if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL)
521 skb_reserve(skb, 2+32);
522 NdisMoveMemory(skb->tail, pData, DataSize);
523 skb_put(skb, DataSize);
524 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
525 pRetPacket = OSPKT_TO_RTPKT(skb);
533 PNDIS_PACKET duplicate_pkt(
534 IN PRTMP_ADAPTER pAd,
535 IN PUCHAR pHeader802_3,
539 IN UCHAR FromWhichBSSID)
542 PNDIS_PACKET pPacket = NULL;
545 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
548 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
549 skb_put(skb, HdrLen);
550 NdisMoveMemory(skb->tail, pData, DataSize);
551 skb_put(skb, DataSize);
552 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
553 pPacket = OSPKT_TO_RTPKT(skb);
560 #define TKIP_TX_MIC_SIZE 8
561 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
562 IN PRTMP_ADAPTER pAd,
563 IN PNDIS_PACKET pPacket)
565 struct sk_buff *skb, *newskb;
568 skb = RTPKT_TO_OSPKT(pPacket);
569 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
571 // alloc a new skb and copy the packet
572 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
573 dev_kfree_skb_any(skb);
576 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
582 return OSPKT_TO_RTPKT(skb);
585 if ((data = skb_put(skb, TKIP_TX_MIC_SIZE)) != NULL)
586 { // If we can extend it, well, copy it first.
587 NdisMoveMemory(data, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
591 // Otherwise, copy the packet.
592 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
593 dev_kfree_skb_any(skb);
596 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC to packet failed!, dropping packet\n"));
601 NdisMoveMemory(skb->tail, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
602 skb_put(skb, TKIP_TX_MIC_SIZE);
605 return OSPKT_TO_RTPKT(skb);
613 PNDIS_PACKET ClonePacket(
614 IN PRTMP_ADAPTER pAd,
615 IN PNDIS_PACKET pPacket,
619 struct sk_buff *pRxPkt;
620 struct sk_buff *pClonedPkt;
623 pRxPkt = RTPKT_TO_OSPKT(pPacket);
626 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
630 // set the correct dataptr and data len
631 pClonedPkt->dev = pRxPkt->dev;
632 pClonedPkt->data = pData;
633 pClonedPkt->len = DataSize;
634 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
635 ASSERT(DataSize < 1530);
641 // change OS packet DataPtr and DataLen
643 void update_os_packet_info(
644 IN PRTMP_ADAPTER pAd,
646 IN UCHAR FromWhichBSSID)
648 struct sk_buff *pOSPkt;
650 ASSERT(pRxBlk->pRxPacket);
651 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
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;
660 void wlan_802_11_to_802_3_packet(
661 IN PRTMP_ADAPTER pAd,
663 IN PUCHAR pHeader802_3,
664 IN UCHAR FromWhichBSSID)
666 struct sk_buff *pOSPkt;
668 ASSERT(pRxBlk->pRxPacket);
669 ASSERT(pHeader802_3);
671 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
673 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
674 pOSPkt->data = pRxBlk->pData;
675 pOSPkt->len = pRxBlk->DataSize;
676 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
683 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
686 void announce_802_3_packet(
687 IN PRTMP_ADAPTER pAd,
688 IN PNDIS_PACKET pPacket)
691 struct sk_buff *pRxPkt;
695 pRxPkt = RTPKT_TO_OSPKT(pPacket);
697 /* Push up the protocol stack */
699 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
701 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
703 //#ifdef CONFIG_5VT_ENHANCE
704 // *(int*)(pRxPkt->cb) = BRIDGE_TAG;
707 #endif // IKANOS_VX_1X0 //
711 PRTMP_SCATTER_GATHER_LIST
712 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
714 sg->NumberOfElements = 1;
715 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
716 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
720 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
725 if (RTDebugLevel < RT_DEBUG_TRACE)
729 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
730 for (x=0; x<SrcBufLen; x++)
733 printk("0x%04x : ", x);
734 printk("%02x ", ((unsigned char)pt[x]));
735 if (x%16 == 15) printk("\n");
741 ========================================================================
744 Send log message through wireless event
746 Support standard iw_event with IWEVCUSTOM. It is used below.
748 iwreq_data.data.flags is used to store event_flag that is defined by user.
749 iwreq_data.data.length is the length of the event log.
751 The format of the event log is composed of the entry's MAC address and
752 the desired log message (refer to pWirelessEventText).
754 ex: 11:22:33:44:55:66 has associated successfully
756 p.s. The requirement of Wireless Extension is v15 or newer.
758 ========================================================================
760 VOID RTMPSendWirelessEvent(
761 IN PRTMP_ADAPTER pAd,
762 IN USHORT Event_flag,
767 #if WIRELESS_EXT >= 15
769 union iwreq_data wrqu;
770 PUCHAR pBuf = NULL, pBufPtr = NULL;
771 USHORT event, type, BufLen;
772 UCHAR event_table_len = 0;
774 type = Event_flag & 0xFF00;
775 event = Event_flag & 0x00FF;
779 case IW_SYS_EVENT_FLAG_START:
780 event_table_len = IW_SYS_EVENT_TYPE_NUM;
783 case IW_SPOOF_EVENT_FLAG_START:
784 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
787 case IW_FLOOD_EVENT_FLAG_START:
788 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
792 if (event_table_len == 0)
794 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
798 if (event >= event_table_len)
800 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
804 //Allocate memory and copy the msg.
805 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
807 //Prepare the payload
808 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
813 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
814 else if (BssIdx < MAX_MBSSID_NUM)
815 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
817 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
819 if (type == IW_SYS_EVENT_FLAG_START)
820 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
821 else if (type == IW_SPOOF_EVENT_FLAG_START)
822 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
823 else if (type == IW_FLOOD_EVENT_FLAG_START)
824 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
826 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
828 pBufPtr[pBufPtr - pBuf] = '\0';
829 BufLen = pBufPtr - pBuf;
831 memset(&wrqu, 0, sizeof(wrqu));
832 wrqu.data.flags = Event_flag;
833 wrqu.data.length = BufLen;
835 //send wireless event
836 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
838 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
843 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
845 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
846 #endif /* WIRELESS_EXT >= 15 */
849 void send_monitor_packets(
850 IN PRTMP_ADAPTER pAd,
853 struct sk_buff *pOSPkt;
854 wlan_ng_prism2_header *ph;
856 USHORT header_len = 0;
857 UCHAR temp_header[40] = {0};
859 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
860 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,
861 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};
864 ASSERT(pRxBlk->pRxPacket);
865 if (pRxBlk->DataSize < 10)
867 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
868 goto err_free_sk_buff;
871 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
873 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
874 goto err_free_sk_buff;
877 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
878 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
879 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
881 pRxBlk->DataSize -= LENGTH_802_11;
882 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
883 (pRxBlk->pHeader->FC.FrDs == 1))
884 header_len = LENGTH_802_11_WITH_ADDR4;
886 header_len = LENGTH_802_11;
889 if (pRxBlk->pHeader->FC.SubType & 0x08)
892 // Data skip QOS contorl field
893 pRxBlk->DataSize -=2;
896 // Order bit: A-Ralink or HTC+
897 if (pRxBlk->pHeader->FC.Order)
900 // Data skip HTC contorl field
901 pRxBlk->DataSize -= 4;
905 if (header_len <= 40)
906 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
909 if (pRxBlk->RxD.L2PAD)
910 pRxBlk->pData += (header_len + 2);
912 pRxBlk->pData += header_len;
916 if (pRxBlk->DataSize < pOSPkt->len) {
917 skb_trim(pOSPkt,pRxBlk->DataSize);
919 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
922 if ((pRxBlk->pData - pOSPkt->data) > 0) {
923 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
924 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
927 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
928 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
929 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
930 goto err_free_sk_buff;
935 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
937 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
938 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
940 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
941 ph->msglen = sizeof(wlan_ng_prism2_header);
942 strcpy(ph->devname, pAd->net_dev->name);
944 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
945 ph->hosttime.status = 0;
946 ph->hosttime.len = 4;
947 ph->hosttime.data = jiffies;
949 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
950 ph->mactime.status = 0;
952 ph->mactime.data = 0;
954 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
959 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
960 ph->channel.status = 0;
963 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
965 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
968 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));;
970 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
971 ph->signal.status = 0;
973 ph->signal.data = 0; //rssi + noise;
975 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
976 ph->noise.status = 0;
980 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
982 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
985 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
986 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
988 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
991 if (rate_index > 255)
994 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
997 ph->rate.data = ralinkrate[rate_index];
999 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
1000 ph->frmlen.status = 0;
1002 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
1005 pOSPkt->pkt_type = PACKET_OTHERHOST;
1006 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
1007 pOSPkt->ip_summed = CHECKSUM_NONE;
1013 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1018 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1020 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1022 allow_signal(SIGTERM);
1023 allow_signal(SIGKILL);
1024 current->flags |= PF_NOFREEZE;
1026 /* signal that we've started the thread */
1030 void RTMP_IndicateMediaState(
1031 IN PRTMP_ADAPTER pAd)
1033 if (pAd->CommonCfg.bWirelessEvent)
1035 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1037 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1041 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);