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(BeaconUpdateExec
);
40 BUILD_TIMER_FUNCTION(BeaconTimeout
);
41 BUILD_TIMER_FUNCTION(ScanTimeout
);
42 BUILD_TIMER_FUNCTION(AuthTimeout
);
43 BUILD_TIMER_FUNCTION(AssocTimeout
);
44 BUILD_TIMER_FUNCTION(ReassocTimeout
);
45 BUILD_TIMER_FUNCTION(DisassocTimeout
);
46 BUILD_TIMER_FUNCTION(LinkDownExec
);
47 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec
);
48 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc
);
50 BUILD_TIMER_FUNCTION(PsPollWakeExec
);
51 BUILD_TIMER_FUNCTION(RadioOnExec
);
54 // for wireless system event message
55 char const *pWirelessSysEventText
[IW_SYS_EVENT_TYPE_NUM
] = {
56 // system status event
57 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
58 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
59 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
60 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
61 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
62 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
63 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
64 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
65 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
66 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
67 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
68 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
69 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
70 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
71 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
72 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
73 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
74 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
75 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
78 // for wireless IDS_spoof_attack event message
79 char const *pWirelessSpoofEventText
[IW_SPOOF_EVENT_TYPE_NUM
] = {
80 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
81 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
82 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
83 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
84 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
85 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
86 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
87 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
88 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
89 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
92 // for wireless IDS_flooding_attack event message
93 char const *pWirelessFloodEventText
[IW_FLOOD_EVENT_TYPE_NUM
] = {
94 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
95 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
96 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
97 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
98 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
99 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
100 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
104 VOID
RTMP_SetPeriodicTimer(
105 IN NDIS_MINIPORT_TIMER
*pTimer
,
106 IN
unsigned long timeout
)
108 timeout
= ((timeout
*HZ
) / 1000);
109 pTimer
->expires
= jiffies
+ timeout
;
113 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
114 VOID
RTMP_OS_Init_Timer(
115 IN PRTMP_ADAPTER pAd
,
116 IN NDIS_MINIPORT_TIMER
*pTimer
,
117 IN TIMER_FUNCTION function
,
121 pTimer
->data
= (unsigned long)data
;
122 pTimer
->function
= function
;
126 VOID
RTMP_OS_Add_Timer(
127 IN NDIS_MINIPORT_TIMER
*pTimer
,
128 IN
unsigned long timeout
)
130 if (timer_pending(pTimer
))
133 timeout
= ((timeout
*HZ
) / 1000);
134 pTimer
->expires
= jiffies
+ timeout
;
138 VOID
RTMP_OS_Mod_Timer(
139 IN NDIS_MINIPORT_TIMER
*pTimer
,
140 IN
unsigned long timeout
)
142 timeout
= ((timeout
*HZ
) / 1000);
143 mod_timer(pTimer
, jiffies
+ timeout
);
146 VOID
RTMP_OS_Del_Timer(
147 IN NDIS_MINIPORT_TIMER
*pTimer
,
148 OUT BOOLEAN
*pCancelled
)
150 if (timer_pending(pTimer
))
152 *pCancelled
= del_timer_sync(pTimer
);
161 VOID
RTMP_OS_Release_Packet(
162 IN PRTMP_ADAPTER pAd
,
163 IN PQUEUE_ENTRY pEntry
)
165 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
168 // Unify all delay routine by using udelay
174 for (i
= 0; i
< (usec
/ 50); i
++)
181 void RTMP_GetCurrentSystemTime(LARGE_INTEGER
*time
)
183 time
->u
.LowPart
= jiffies
;
186 // pAd MUST allow to be NULL
187 NDIS_STATUS
os_alloc_mem(
188 IN PRTMP_ADAPTER pAd
,
192 *mem
= (PUCHAR
) kmalloc(size
, GFP_ATOMIC
);
194 return (NDIS_STATUS_SUCCESS
);
196 return (NDIS_STATUS_FAILURE
);
199 // pAd MUST allow to be NULL
200 NDIS_STATUS
os_free_mem(
201 IN PRTMP_ADAPTER pAd
,
207 return (NDIS_STATUS_SUCCESS
);
211 PNDIS_PACKET
RTMP_AllocateFragPacketBuffer(
212 IN PRTMP_ADAPTER pAd
,
217 pkt
= dev_alloc_skb(Length
);
221 DBGPRINT(RT_DEBUG_ERROR
, ("can't allocate frag rx %ld size packet\n",Length
));
226 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
229 return (PNDIS_PACKET
) pkt
;
233 PNDIS_PACKET
RTMP_AllocateTxPacketBuffer(
234 IN PRTMP_ADAPTER pAd
,
237 OUT PVOID
*VirtualAddress
)
241 pkt
= dev_alloc_skb(Length
);
245 DBGPRINT(RT_DEBUG_ERROR
, ("can't allocate tx %ld size packet\n",Length
));
250 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
251 *VirtualAddress
= (PVOID
) pkt
->data
;
255 *VirtualAddress
= (PVOID
) NULL
;
258 return (PNDIS_PACKET
) pkt
;
262 VOID
build_tx_packet(
263 IN PRTMP_ADAPTER pAd
,
264 IN PNDIS_PACKET pPacket
,
269 struct sk_buff
*pTxPkt
;
272 pTxPkt
= RTPKT_TO_OSPKT(pPacket
);
274 NdisMoveMemory(skb_put(pTxPkt
, FrameLen
), pFrame
, FrameLen
);
277 VOID
RTMPFreeAdapter(
278 IN PRTMP_ADAPTER pAd
)
280 POS_COOKIE os_cookie
;
283 os_cookie
=(POS_COOKIE
)pAd
->OS_Cookie
;
285 kfree(pAd
->BeaconBuf
);
288 NdisFreeSpinLock(&pAd
->MgmtRingLock
);
290 NdisFreeSpinLock(&pAd
->RxRingLock
);
292 for (index
=0 ; index
< NUM_OF_TX_RING
; index
++)
294 NdisFreeSpinLock(&pAd
->TxSwQueueLock
[index
]);
295 NdisFreeSpinLock(&pAd
->DeQueueLock
[index
]);
296 pAd
->DeQueueRunning
[index
] = FALSE
;
299 NdisFreeSpinLock(&pAd
->irq_lock
);
301 vfree(pAd
); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
305 BOOLEAN
OS_Need_Clone_Packet(void)
313 ========================================================================
316 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
317 must have only one NDIS BUFFER
318 return - byte copied. 0 means can't create NDIS PACKET
319 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
322 pAd Pointer to our adapter
323 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
324 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
332 ========================================================================
334 NDIS_STATUS
RTMPCloneNdisPacket(
335 IN PRTMP_ADAPTER pAd
,
336 IN BOOLEAN pInsAMSDUHdr
,
337 IN PNDIS_PACKET pInPacket
,
338 OUT PNDIS_PACKET
*ppOutPacket
)
346 // 1. Allocate a packet
347 pkt
= dev_alloc_skb(2048);
351 return NDIS_STATUS_FAILURE
;
354 skb_put(pkt
, GET_OS_PKT_LEN(pInPacket
));
355 NdisMoveMemory(pkt
->data
, GET_OS_PKT_DATAPTR(pInPacket
), GET_OS_PKT_LEN(pInPacket
));
356 *ppOutPacket
= OSPKT_TO_RTPKT(pkt
);
359 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
361 printk("###Clone###\n");
363 return NDIS_STATUS_SUCCESS
;
367 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
368 NDIS_STATUS
RTMPAllocateNdisPacket(
369 IN PRTMP_ADAPTER pAd
,
370 OUT PNDIS_PACKET
*ppPacket
,
376 PNDIS_PACKET pPacket
;
380 // 1. Allocate a packet
381 pPacket
= (PNDIS_PACKET
*) dev_alloc_skb(HeaderLen
+ DataLen
+ TXPADDING_SIZE
);
386 printk("RTMPAllocateNdisPacket Fail\n\n");
388 return NDIS_STATUS_FAILURE
;
391 // 2. clone the frame content
393 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket
), pHeader
, HeaderLen
);
395 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket
) + HeaderLen
, pData
, DataLen
);
397 // 3. update length of packet
398 skb_put(GET_OS_PKT_TYPE(pPacket
), HeaderLen
+DataLen
);
400 RTMP_SET_PACKET_SOURCE(pPacket
, PKTSRC_NDIS
);
401 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
403 return NDIS_STATUS_SUCCESS
;
407 ========================================================================
409 This routine frees a miniport internally allocated NDIS_PACKET and its
410 corresponding NDIS_BUFFER and allocated memory.
411 ========================================================================
413 VOID
RTMPFreeNdisPacket(
414 IN PRTMP_ADAPTER pAd
,
415 IN PNDIS_PACKET pPacket
)
417 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket
));
421 // IRQL = DISPATCH_LEVEL
422 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
423 // scatter gather buffer
424 NDIS_STATUS
Sniff2BytesFromNdisBuffer(
425 IN PNDIS_BUFFER pFirstBuffer
,
426 IN UCHAR DesiredOffset
,
430 *pByte0
= *(PUCHAR
)(pFirstBuffer
+ DesiredOffset
);
431 *pByte1
= *(PUCHAR
)(pFirstBuffer
+ DesiredOffset
+ 1);
433 return NDIS_STATUS_SUCCESS
;
437 void RTMP_QueryPacketInfo(
438 IN PNDIS_PACKET pPacket
,
439 OUT PACKET_INFO
*pPacketInfo
,
440 OUT PUCHAR
*pSrcBufVA
,
441 OUT UINT
*pSrcBufLen
)
443 pPacketInfo
->BufferCount
= 1;
444 pPacketInfo
->pFirstBuffer
= GET_OS_PKT_DATAPTR(pPacket
);
445 pPacketInfo
->PhysicalBufferCount
= 1;
446 pPacketInfo
->TotalPacketLength
= GET_OS_PKT_LEN(pPacket
);
448 *pSrcBufVA
= GET_OS_PKT_DATAPTR(pPacket
);
449 *pSrcBufLen
= GET_OS_PKT_LEN(pPacket
);
452 void RTMP_QueryNextPacketInfo(
453 IN PNDIS_PACKET
*ppPacket
,
454 OUT PACKET_INFO
*pPacketInfo
,
455 OUT PUCHAR
*pSrcBufVA
,
456 OUT UINT
*pSrcBufLen
)
458 PNDIS_PACKET pPacket
= NULL
;
461 pPacket
= GET_OS_PKT_NEXT(*ppPacket
);
465 pPacketInfo
->BufferCount
= 1;
466 pPacketInfo
->pFirstBuffer
= GET_OS_PKT_DATAPTR(pPacket
);
467 pPacketInfo
->PhysicalBufferCount
= 1;
468 pPacketInfo
->TotalPacketLength
= GET_OS_PKT_LEN(pPacket
);
470 *pSrcBufVA
= GET_OS_PKT_DATAPTR(pPacket
);
471 *pSrcBufLen
= GET_OS_PKT_LEN(pPacket
);
472 *ppPacket
= GET_OS_PKT_NEXT(pPacket
);
476 pPacketInfo
->BufferCount
= 0;
477 pPacketInfo
->pFirstBuffer
= NULL
;
478 pPacketInfo
->PhysicalBufferCount
= 0;
479 pPacketInfo
->TotalPacketLength
= 0;
487 // not yet support MBSS
488 PNET_DEV
get_netdev_from_bssid(
489 IN PRTMP_ADAPTER pAd
,
490 IN UCHAR FromWhichBSSID
)
492 PNET_DEV dev_p
= NULL
;
494 dev_p
= pAd
->net_dev
;
497 return dev_p
; /* return one of MBSS */
500 PNDIS_PACKET
DuplicatePacket(
501 IN PRTMP_ADAPTER pAd
,
502 IN PNDIS_PACKET pPacket
,
503 IN UCHAR FromWhichBSSID
)
506 PNDIS_PACKET pRetPacket
= NULL
;
510 DataSize
= (USHORT
) GET_OS_PKT_LEN(pPacket
);
511 pData
= (PUCHAR
) GET_OS_PKT_DATAPTR(pPacket
);
514 skb
= skb_clone(RTPKT_TO_OSPKT(pPacket
), MEM_ALLOC_FLAG
);
517 skb
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
518 pRetPacket
= OSPKT_TO_RTPKT(skb
);
525 PNDIS_PACKET
duplicate_pkt(
526 IN PRTMP_ADAPTER pAd
,
527 IN PUCHAR pHeader802_3
,
531 IN UCHAR FromWhichBSSID
)
534 PNDIS_PACKET pPacket
= NULL
;
537 if ((skb
= __dev_alloc_skb(HdrLen
+ DataSize
+ 2, MEM_ALLOC_FLAG
)) != NULL
)
540 NdisMoveMemory(skb_tail_pointer(skb
), pHeader802_3
, HdrLen
);
541 skb_put(skb
, HdrLen
);
542 NdisMoveMemory(skb_tail_pointer(skb
), pData
, DataSize
);
543 skb_put(skb
, DataSize
);
544 skb
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
545 pPacket
= OSPKT_TO_RTPKT(skb
);
552 #define TKIP_TX_MIC_SIZE 8
553 PNDIS_PACKET
duplicate_pkt_with_TKIP_MIC(
554 IN PRTMP_ADAPTER pAd
,
555 IN PNDIS_PACKET pPacket
)
557 struct sk_buff
*skb
, *newskb
;
560 skb
= RTPKT_TO_OSPKT(pPacket
);
561 if (skb_tailroom(skb
) < TKIP_TX_MIC_SIZE
)
563 // alloc a new skb and copy the packet
564 newskb
= skb_copy_expand(skb
, skb_headroom(skb
), TKIP_TX_MIC_SIZE
, GFP_ATOMIC
);
565 dev_kfree_skb_any(skb
);
568 DBGPRINT(RT_DEBUG_ERROR
, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
574 return OSPKT_TO_RTPKT(skb
);
580 PNDIS_PACKET
ClonePacket(
581 IN PRTMP_ADAPTER pAd
,
582 IN PNDIS_PACKET pPacket
,
586 struct sk_buff
*pRxPkt
;
587 struct sk_buff
*pClonedPkt
;
590 pRxPkt
= RTPKT_TO_OSPKT(pPacket
);
593 pClonedPkt
= skb_clone(pRxPkt
, MEM_ALLOC_FLAG
);
597 // set the correct dataptr and data len
598 pClonedPkt
->dev
= pRxPkt
->dev
;
599 pClonedPkt
->data
= pData
;
600 pClonedPkt
->len
= DataSize
;
601 pClonedPkt
->tail
= pClonedPkt
->data
+ pClonedPkt
->len
;
602 ASSERT(DataSize
< 1530);
608 // change OS packet DataPtr and DataLen
610 void update_os_packet_info(
611 IN PRTMP_ADAPTER pAd
,
613 IN UCHAR FromWhichBSSID
)
615 struct sk_buff
*pOSPkt
;
617 ASSERT(pRxBlk
->pRxPacket
);
618 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
620 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
621 pOSPkt
->data
= pRxBlk
->pData
;
622 pOSPkt
->len
= pRxBlk
->DataSize
;
623 pOSPkt
->tail
= pOSPkt
->data
+ pOSPkt
->len
;
627 void wlan_802_11_to_802_3_packet(
628 IN PRTMP_ADAPTER pAd
,
630 IN PUCHAR pHeader802_3
,
631 IN UCHAR FromWhichBSSID
)
633 struct sk_buff
*pOSPkt
;
635 ASSERT(pRxBlk
->pRxPacket
);
636 ASSERT(pHeader802_3
);
638 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
640 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
641 pOSPkt
->data
= pRxBlk
->pData
;
642 pOSPkt
->len
= pRxBlk
->DataSize
;
643 pOSPkt
->tail
= pOSPkt
->data
+ pOSPkt
->len
;
650 NdisMoveMemory(skb_push(pOSPkt
, LENGTH_802_3
), pHeader802_3
, LENGTH_802_3
);
653 void announce_802_3_packet(
654 IN PRTMP_ADAPTER pAd
,
655 IN PNDIS_PACKET pPacket
)
658 struct sk_buff
*pRxPkt
;
662 pRxPkt
= RTPKT_TO_OSPKT(pPacket
);
664 /* Push up the protocol stack */
665 pRxPkt
->protocol
= eth_type_trans(pRxPkt
, pRxPkt
->dev
);
671 PRTMP_SCATTER_GATHER_LIST
672 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket
, RTMP_SCATTER_GATHER_LIST
*sg
)
674 sg
->NumberOfElements
= 1;
675 sg
->Elements
[0].Address
= GET_OS_PKT_DATAPTR(pPacket
);
676 sg
->Elements
[0].Length
= GET_OS_PKT_LEN(pPacket
);
680 void hex_dump(char *str
, unsigned char *pSrcBufVA
, unsigned int SrcBufLen
)
685 if (RTDebugLevel
< RT_DEBUG_TRACE
)
689 printk("%s: %p, len = %d\n",str
, pSrcBufVA
, SrcBufLen
);
690 for (x
=0; x
<SrcBufLen
; x
++)
693 printk("0x%04x : ", x
);
694 printk("%02x ", ((unsigned char)pt
[x
]));
695 if (x
%16 == 15) printk("\n");
701 ========================================================================
704 Send log message through wireless event
706 Support standard iw_event with IWEVCUSTOM. It is used below.
708 iwreq_data.data.flags is used to store event_flag that is defined by user.
709 iwreq_data.data.length is the length of the event log.
711 The format of the event log is composed of the entry's MAC address and
712 the desired log message (refer to pWirelessEventText).
714 ex: 11:22:33:44:55:66 has associated successfully
716 p.s. The requirement of Wireless Extension is v15 or newer.
718 ========================================================================
720 VOID
RTMPSendWirelessEvent(
721 IN PRTMP_ADAPTER pAd
,
722 IN USHORT Event_flag
,
728 union iwreq_data wrqu
;
729 PUCHAR pBuf
= NULL
, pBufPtr
= NULL
;
730 USHORT event
, type
, BufLen
;
731 UCHAR event_table_len
= 0;
733 type
= Event_flag
& 0xFF00;
734 event
= Event_flag
& 0x00FF;
738 case IW_SYS_EVENT_FLAG_START
:
739 event_table_len
= IW_SYS_EVENT_TYPE_NUM
;
742 case IW_SPOOF_EVENT_FLAG_START
:
743 event_table_len
= IW_SPOOF_EVENT_TYPE_NUM
;
746 case IW_FLOOD_EVENT_FLAG_START
:
747 event_table_len
= IW_FLOOD_EVENT_TYPE_NUM
;
751 if (event_table_len
== 0)
753 DBGPRINT(RT_DEBUG_ERROR
, ("%s : The type(%0x02x) is not valid.\n", __func__
, type
));
757 if (event
>= event_table_len
)
759 DBGPRINT(RT_DEBUG_ERROR
, ("%s : The event(%0x02x) is not valid.\n", __func__
, event
));
763 //Allocate memory and copy the msg.
764 if((pBuf
= kmalloc(IW_CUSTOM_MAX_LEN
, GFP_ATOMIC
)) != NULL
)
766 //Prepare the payload
767 memset(pBuf
, 0, IW_CUSTOM_MAX_LEN
);
772 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr
));
773 else if (BssIdx
< MAX_MBSSID_NUM
)
774 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) BSS(wlan%d) ", BssIdx
);
776 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) ");
778 if (type
== IW_SYS_EVENT_FLAG_START
)
779 pBufPtr
+= sprintf(pBufPtr
, "%s", pWirelessSysEventText
[event
]);
780 else if (type
== IW_SPOOF_EVENT_FLAG_START
)
781 pBufPtr
+= sprintf(pBufPtr
, "%s (RSSI=%d)", pWirelessSpoofEventText
[event
], Rssi
);
782 else if (type
== IW_FLOOD_EVENT_FLAG_START
)
783 pBufPtr
+= sprintf(pBufPtr
, "%s", pWirelessFloodEventText
[event
]);
785 pBufPtr
+= sprintf(pBufPtr
, "%s", "unknown event");
787 pBufPtr
[pBufPtr
- pBuf
] = '\0';
788 BufLen
= pBufPtr
- pBuf
;
790 memset(&wrqu
, 0, sizeof(wrqu
));
791 wrqu
.data
.flags
= Event_flag
;
792 wrqu
.data
.length
= BufLen
;
794 //send wireless event
795 wireless_send_event(pAd
->net_dev
, IWEVCUSTOM
, &wrqu
, pBuf
);
797 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
802 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Can't allocate memory for wireless event.\n", __func__
));
805 void send_monitor_packets(
806 IN PRTMP_ADAPTER pAd
,
809 struct sk_buff
*pOSPkt
;
810 wlan_ng_prism2_header
*ph
;
812 USHORT header_len
= 0;
813 UCHAR temp_header
[40] = {0};
815 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
816 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,
817 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};
820 ASSERT(pRxBlk
->pRxPacket
);
821 if (pRxBlk
->DataSize
< 10)
823 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Size is too small! (%d)\n", __func__
, pRxBlk
->DataSize
));
824 goto err_free_sk_buff
;
827 if (pRxBlk
->DataSize
+ sizeof(wlan_ng_prism2_header
) > RX_BUFFER_AGGRESIZE
)
829 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Size is too large! (%zu)\n", __func__
, pRxBlk
->DataSize
+ sizeof(wlan_ng_prism2_header
)));
830 goto err_free_sk_buff
;
833 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
834 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, BSS0
);
835 if (pRxBlk
->pHeader
->FC
.Type
== BTYPE_DATA
)
837 pRxBlk
->DataSize
-= LENGTH_802_11
;
838 if ((pRxBlk
->pHeader
->FC
.ToDs
== 1) &&
839 (pRxBlk
->pHeader
->FC
.FrDs
== 1))
840 header_len
= LENGTH_802_11_WITH_ADDR4
;
842 header_len
= LENGTH_802_11
;
845 if (pRxBlk
->pHeader
->FC
.SubType
& 0x08)
848 // Data skip QOS contorl field
849 pRxBlk
->DataSize
-=2;
852 // Order bit: A-Ralink or HTC+
853 if (pRxBlk
->pHeader
->FC
.Order
)
856 // Data skip HTC contorl field
857 pRxBlk
->DataSize
-= 4;
861 if (header_len
<= 40)
862 NdisMoveMemory(temp_header
, pRxBlk
->pData
, header_len
);
865 if (pRxBlk
->RxD
.L2PAD
)
866 pRxBlk
->pData
+= (header_len
+ 2);
868 pRxBlk
->pData
+= header_len
;
872 if (pRxBlk
->DataSize
< pOSPkt
->len
) {
873 skb_trim(pOSPkt
,pRxBlk
->DataSize
);
875 skb_put(pOSPkt
,(pRxBlk
->DataSize
- pOSPkt
->len
));
878 if ((pRxBlk
->pData
- pOSPkt
->data
) > 0) {
879 skb_put(pOSPkt
,(pRxBlk
->pData
- pOSPkt
->data
));
880 skb_pull(pOSPkt
,(pRxBlk
->pData
- pOSPkt
->data
));
883 if (skb_headroom(pOSPkt
) < (sizeof(wlan_ng_prism2_header
)+ header_len
)) {
884 if (pskb_expand_head(pOSPkt
, (sizeof(wlan_ng_prism2_header
) + header_len
), 0, GFP_ATOMIC
)) {
885 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Reallocate header size of sk_buff fail!\n", __func__
));
886 goto err_free_sk_buff
;
891 NdisMoveMemory(skb_push(pOSPkt
, header_len
), temp_header
, header_len
);
893 ph
= (wlan_ng_prism2_header
*) skb_push(pOSPkt
, sizeof(wlan_ng_prism2_header
));
894 NdisZeroMemory(ph
, sizeof(wlan_ng_prism2_header
));
896 ph
->msgcode
= DIDmsg_lnxind_wlansniffrm
;
897 ph
->msglen
= sizeof(wlan_ng_prism2_header
);
898 strcpy(ph
->devname
, pAd
->net_dev
->name
);
900 ph
->hosttime
.did
= DIDmsg_lnxind_wlansniffrm_hosttime
;
901 ph
->hosttime
.status
= 0;
902 ph
->hosttime
.len
= 4;
903 ph
->hosttime
.data
= jiffies
;
905 ph
->mactime
.did
= DIDmsg_lnxind_wlansniffrm_mactime
;
906 ph
->mactime
.status
= 0;
908 ph
->mactime
.data
= 0;
910 ph
->istx
.did
= DIDmsg_lnxind_wlansniffrm_istx
;
915 ph
->channel
.did
= DIDmsg_lnxind_wlansniffrm_channel
;
916 ph
->channel
.status
= 0;
919 ph
->channel
.data
= (u_int32_t
)pAd
->CommonCfg
.Channel
;
921 ph
->rssi
.did
= DIDmsg_lnxind_wlansniffrm_rssi
;
924 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
));;
926 ph
->signal
.did
= DIDmsg_lnxind_wlansniffrm_signal
;
927 ph
->signal
.status
= 0;
929 ph
->signal
.data
= 0; //rssi + noise;
931 ph
->noise
.did
= DIDmsg_lnxind_wlansniffrm_noise
;
932 ph
->noise
.status
= 0;
936 if (pRxBlk
->pRxWI
->PHYMODE
>= MODE_HTMIX
)
938 rate_index
= 16 + ((UCHAR
)pRxBlk
->pRxWI
->BW
*16) + ((UCHAR
)pRxBlk
->pRxWI
->ShortGI
*32) + ((UCHAR
)pRxBlk
->pRxWI
->MCS
);
941 if (pRxBlk
->pRxWI
->PHYMODE
== MODE_OFDM
)
942 rate_index
= (UCHAR
)(pRxBlk
->pRxWI
->MCS
) + 4;
944 rate_index
= (UCHAR
)(pRxBlk
->pRxWI
->MCS
);
947 if (rate_index
> 255)
950 ph
->rate
.did
= DIDmsg_lnxind_wlansniffrm_rate
;
953 ph
->rate
.data
= ralinkrate
[rate_index
];
955 ph
->frmlen
.did
= DIDmsg_lnxind_wlansniffrm_frmlen
;
956 ph
->frmlen
.status
= 0;
958 ph
->frmlen
.data
= (u_int32_t
)pRxBlk
->DataSize
;
961 pOSPkt
->pkt_type
= PACKET_OTHERHOST
;
962 pOSPkt
->protocol
= eth_type_trans(pOSPkt
, pOSPkt
->dev
);
963 pOSPkt
->ip_summed
= CHECKSUM_NONE
;
969 RELEASE_NDIS_PACKET(pAd
, pRxBlk
->pRxPacket
, NDIS_STATUS_FAILURE
);
974 void rtmp_os_thread_init(PUCHAR pThreadName
, PVOID pNotify
)
976 daemonize(pThreadName
/*"%s",pAd->net_dev->name*/);
978 allow_signal(SIGTERM
);
979 allow_signal(SIGKILL
);
980 current
->flags
|= PF_NOFREEZE
;
982 /* signal that we've started the thread */
986 void RTMP_IndicateMediaState(
987 IN PRTMP_ADAPTER pAd
)
989 if (pAd
->CommonCfg
.bWirelessEvent
)
991 if (pAd
->IndicateMediaState
== NdisMediaStateConnected
)
993 RTMPSendWirelessEvent(pAd
, IW_STA_LINKUP_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
997 RTMPSendWirelessEvent(pAd
, IW_STA_LINKDOWN_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);