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 <linux/firmware.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include "rt_config.h"
33 unsigned long RTDebugLevel
= RT_DEBUG_ERROR
;
35 /* for wireless system event message */
36 char const *pWirelessSysEventText
[IW_SYS_EVENT_TYPE_NUM
] = {
37 /* system status event */
38 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
39 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
40 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
41 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
42 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
43 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
44 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
45 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
46 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
47 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
48 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
49 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
50 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
51 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
52 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
53 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
54 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
55 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
56 "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
59 /* for wireless IDS_spoof_attack event message */
60 char const *pWirelessSpoofEventText
[IW_SPOOF_EVENT_TYPE_NUM
] = {
61 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
62 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
63 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
64 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
65 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
66 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
67 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
68 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
69 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
70 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
73 /* for wireless IDS_flooding_attack event message */
74 char const *pWirelessFloodEventText
[IW_FLOOD_EVENT_TYPE_NUM
] = {
75 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
76 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
77 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
78 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
79 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
80 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
81 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
85 void RTMP_SetPeriodicTimer(struct timer_list
* pTimer
,
86 IN
unsigned long timeout
)
88 timeout
= ((timeout
* OS_HZ
) / 1000);
89 pTimer
->expires
= jiffies
+ timeout
;
93 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
94 void RTMP_OS_Init_Timer(struct rt_rtmp_adapter
*pAd
,
95 struct timer_list
* pTimer
,
96 IN TIMER_FUNCTION function
, void *data
)
99 pTimer
->data
= (unsigned long)data
;
100 pTimer
->function
= function
;
103 void RTMP_OS_Add_Timer(struct timer_list
* pTimer
,
104 IN
unsigned long timeout
)
106 if (timer_pending(pTimer
))
109 timeout
= ((timeout
* OS_HZ
) / 1000);
110 pTimer
->expires
= jiffies
+ timeout
;
114 void RTMP_OS_Mod_Timer(struct timer_list
* pTimer
,
115 IN
unsigned long timeout
)
117 timeout
= ((timeout
* OS_HZ
) / 1000);
118 mod_timer(pTimer
, jiffies
+ timeout
);
121 void RTMP_OS_Del_Timer(struct timer_list
* pTimer
,
122 OUT BOOLEAN
* pCancelled
)
124 if (timer_pending(pTimer
)) {
125 *pCancelled
= del_timer_sync(pTimer
);
132 void RTMP_OS_Release_Packet(struct rt_rtmp_adapter
*pAd
, struct rt_queue_entry
*pEntry
)
134 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
137 /* Unify all delay routine by using udelay */
138 void RTMPusecDelay(unsigned long usec
)
142 for (i
= 0; i
< (usec
/ 50); i
++)
149 void RTMP_GetCurrentSystemTime(LARGE_INTEGER
* time
)
151 time
->u
.LowPart
= jiffies
;
154 /* pAd MUST allow to be NULL */
155 int os_alloc_mem(struct rt_rtmp_adapter
*pAd
, u8
** mem
, unsigned long size
)
157 *mem
= (u8
*)kmalloc(size
, GFP_ATOMIC
);
159 return (NDIS_STATUS_SUCCESS
);
161 return (NDIS_STATUS_FAILURE
);
164 /* pAd MUST allow to be NULL */
165 int os_free_mem(struct rt_rtmp_adapter
*pAd
, void *mem
)
170 return (NDIS_STATUS_SUCCESS
);
173 void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter
*pAd
, IN
int size
)
176 /* Add 2 more bytes for ip header alignment */
177 skb
= dev_alloc_skb(size
+ 2);
179 return ((void *)skb
);
182 void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter
*pAd
,
183 unsigned long Length
)
187 pkt
= dev_alloc_skb(Length
);
190 DBGPRINT(RT_DEBUG_ERROR
,
191 ("can't allocate frag rx %ld size packet\n", Length
));
195 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
201 void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter
*pAd
,
202 unsigned long Length
,
204 void ** VirtualAddress
)
208 pkt
= dev_alloc_skb(Length
);
211 DBGPRINT(RT_DEBUG_ERROR
,
212 ("can't allocate tx %ld size packet\n", Length
));
216 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
217 *VirtualAddress
= (void *)pkt
->data
;
219 *VirtualAddress
= (void *)NULL
;
225 void build_tx_packet(struct rt_rtmp_adapter
*pAd
,
227 u8
*pFrame
, unsigned long FrameLen
)
230 struct sk_buff
*pTxPkt
;
233 pTxPkt
= RTPKT_TO_OSPKT(pPacket
);
235 NdisMoveMemory(skb_put(pTxPkt
, FrameLen
), pFrame
, FrameLen
);
238 void RTMPFreeAdapter(struct rt_rtmp_adapter
*pAd
)
240 struct os_cookie
*os_cookie
;
243 os_cookie
= (struct os_cookie
*)pAd
->OS_Cookie
;
246 kfree(pAd
->BeaconBuf
);
248 NdisFreeSpinLock(&pAd
->MgmtRingLock
);
251 NdisFreeSpinLock(&pAd
->RxRingLock
);
253 NdisFreeSpinLock(&pAd
->McuCmdLock
);
254 #endif /* RT3090 // */
255 #endif /* RTMP_MAC_PCI // */
257 for (index
= 0; index
< NUM_OF_TX_RING
; index
++) {
258 NdisFreeSpinLock(&pAd
->TxSwQueueLock
[index
]);
259 NdisFreeSpinLock(&pAd
->DeQueueLock
[index
]);
260 pAd
->DeQueueRunning
[index
] = FALSE
;
263 NdisFreeSpinLock(&pAd
->irq_lock
);
265 release_firmware(pAd
->firmware
);
267 vfree(pAd
); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
272 BOOLEAN
OS_Need_Clone_Packet(void)
278 ========================================================================
281 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
282 must have only one NDIS BUFFER
283 return - byte copied. 0 means can't create NDIS PACKET
284 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
287 pAd Pointer to our adapter
288 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
289 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
297 ========================================================================
299 int RTMPCloneNdisPacket(struct rt_rtmp_adapter
*pAd
,
300 IN BOOLEAN pInsAMSDUHdr
,
310 /* 1. Allocate a packet */
311 pkt
= dev_alloc_skb(2048);
314 return NDIS_STATUS_FAILURE
;
317 skb_put(pkt
, GET_OS_PKT_LEN(pInPacket
));
318 NdisMoveMemory(pkt
->data
, GET_OS_PKT_DATAPTR(pInPacket
),
319 GET_OS_PKT_LEN(pInPacket
));
320 *ppOutPacket
= OSPKT_TO_RTPKT(pkt
);
322 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
324 printk("###Clone###\n");
326 return NDIS_STATUS_SUCCESS
;
329 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
330 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter
*pAd
,
334 u8
*pData
, u32 DataLen
)
340 /* 1. Allocate a packet */
342 (void **) dev_alloc_skb(HeaderLen
+ DataLen
+
343 RTMP_PKT_TAIL_PADDING
);
344 if (pPacket
== NULL
) {
347 printk("RTMPAllocateNdisPacket Fail\n");
349 return NDIS_STATUS_FAILURE
;
351 /* 2. clone the frame content */
353 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket
), pHeader
, HeaderLen
);
355 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket
) + HeaderLen
, pData
,
358 /* 3. update length of packet */
359 skb_put(GET_OS_PKT_TYPE(pPacket
), HeaderLen
+ DataLen
);
361 RTMP_SET_PACKET_SOURCE(pPacket
, PKTSRC_NDIS
);
362 /* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
364 return NDIS_STATUS_SUCCESS
;
368 ========================================================================
370 This routine frees a miniport internally allocated char and its
371 corresponding NDIS_BUFFER and allocated memory.
372 ========================================================================
374 void RTMPFreeNdisPacket(struct rt_rtmp_adapter
*pAd
, void *pPacket
)
376 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket
));
379 /* IRQL = DISPATCH_LEVEL */
380 /* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
381 /* scatter gather buffer */
382 int Sniff2BytesFromNdisBuffer(char *pFirstBuffer
,
384 u8
*pByte0
, u8
*pByte1
)
386 *pByte0
= *(u8
*)(pFirstBuffer
+ DesiredOffset
);
387 *pByte1
= *(u8
*)(pFirstBuffer
+ DesiredOffset
+ 1);
389 return NDIS_STATUS_SUCCESS
;
392 void RTMP_QueryPacketInfo(void *pPacket
,
393 struct rt_packet_info
*pPacketInfo
,
394 u8
** pSrcBufVA
, u32
* pSrcBufLen
)
396 pPacketInfo
->BufferCount
= 1;
397 pPacketInfo
->pFirstBuffer
= (char *)GET_OS_PKT_DATAPTR(pPacket
);
398 pPacketInfo
->PhysicalBufferCount
= 1;
399 pPacketInfo
->TotalPacketLength
= GET_OS_PKT_LEN(pPacket
);
401 *pSrcBufVA
= GET_OS_PKT_DATAPTR(pPacket
);
402 *pSrcBufLen
= GET_OS_PKT_LEN(pPacket
);
405 void RTMP_QueryNextPacketInfo(void ** ppPacket
,
406 struct rt_packet_info
*pPacketInfo
,
407 u8
** pSrcBufVA
, u32
* pSrcBufLen
)
409 void *pPacket
= NULL
;
412 pPacket
= GET_OS_PKT_NEXT(*ppPacket
);
415 pPacketInfo
->BufferCount
= 1;
416 pPacketInfo
->pFirstBuffer
=
417 (char *)GET_OS_PKT_DATAPTR(pPacket
);
418 pPacketInfo
->PhysicalBufferCount
= 1;
419 pPacketInfo
->TotalPacketLength
= GET_OS_PKT_LEN(pPacket
);
421 *pSrcBufVA
= GET_OS_PKT_DATAPTR(pPacket
);
422 *pSrcBufLen
= GET_OS_PKT_LEN(pPacket
);
423 *ppPacket
= GET_OS_PKT_NEXT(pPacket
);
425 pPacketInfo
->BufferCount
= 0;
426 pPacketInfo
->pFirstBuffer
= NULL
;
427 pPacketInfo
->PhysicalBufferCount
= 0;
428 pPacketInfo
->TotalPacketLength
= 0;
436 void *DuplicatePacket(struct rt_rtmp_adapter
*pAd
,
437 void *pPacket
, u8 FromWhichBSSID
)
440 void *pRetPacket
= NULL
;
444 DataSize
= (u16
)GET_OS_PKT_LEN(pPacket
);
445 pData
= (u8
*)GET_OS_PKT_DATAPTR(pPacket
);
447 skb
= skb_clone(RTPKT_TO_OSPKT(pPacket
), MEM_ALLOC_FLAG
);
449 skb
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
450 pRetPacket
= OSPKT_TO_RTPKT(skb
);
457 void *duplicate_pkt(struct rt_rtmp_adapter
*pAd
,
461 unsigned long DataSize
, u8 FromWhichBSSID
)
464 void *pPacket
= NULL
;
467 __dev_alloc_skb(HdrLen
+ DataSize
+ 2, MEM_ALLOC_FLAG
)) != NULL
) {
469 NdisMoveMemory(skb_tail_pointer(skb
), pHeader802_3
, HdrLen
);
470 skb_put(skb
, HdrLen
);
471 NdisMoveMemory(skb_tail_pointer(skb
), pData
, DataSize
);
472 skb_put(skb
, DataSize
);
473 skb
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
474 pPacket
= OSPKT_TO_RTPKT(skb
);
480 #define TKIP_TX_MIC_SIZE 8
481 void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter
*pAd
,
484 struct sk_buff
*skb
, *newskb
;
486 skb
= RTPKT_TO_OSPKT(pPacket
);
487 if (skb_tailroom(skb
) < TKIP_TX_MIC_SIZE
) {
488 /* alloc a new skb and copy the packet */
490 skb_copy_expand(skb
, skb_headroom(skb
), TKIP_TX_MIC_SIZE
,
492 dev_kfree_skb_any(skb
);
493 if (newskb
== NULL
) {
494 DBGPRINT(RT_DEBUG_ERROR
,
495 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
501 return OSPKT_TO_RTPKT(skb
);
504 void *ClonePacket(struct rt_rtmp_adapter
*pAd
,
506 u8
*pData
, unsigned long DataSize
)
508 struct sk_buff
*pRxPkt
;
509 struct sk_buff
*pClonedPkt
;
512 pRxPkt
= RTPKT_TO_OSPKT(pPacket
);
514 /* clone the packet */
515 pClonedPkt
= skb_clone(pRxPkt
, MEM_ALLOC_FLAG
);
518 /* set the correct dataptr and data len */
519 pClonedPkt
->dev
= pRxPkt
->dev
;
520 pClonedPkt
->data
= pData
;
521 pClonedPkt
->len
= DataSize
;
522 skb_set_tail_pointer(pClonedPkt
, DataSize
)
523 ASSERT(DataSize
< 1530);
529 /* change OS packet DataPtr and DataLen */
531 void update_os_packet_info(struct rt_rtmp_adapter
*pAd
,
532 struct rt_rx_blk
*pRxBlk
, u8 FromWhichBSSID
)
534 struct sk_buff
*pOSPkt
;
536 ASSERT(pRxBlk
->pRxPacket
);
537 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
539 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
540 pOSPkt
->data
= pRxBlk
->pData
;
541 pOSPkt
->len
= pRxBlk
->DataSize
;
542 skb_set_tail_pointer(pOSPkt
, pOSPkt
->len
);
545 void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter
*pAd
,
546 struct rt_rx_blk
*pRxBlk
,
550 struct sk_buff
*pOSPkt
;
552 ASSERT(pRxBlk
->pRxPacket
);
553 ASSERT(pHeader802_3
);
555 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
557 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
558 pOSPkt
->data
= pRxBlk
->pData
;
559 pOSPkt
->len
= pRxBlk
->DataSize
;
560 skb_set_tail_pointer(pOSPkt
, pOSPkt
->len
);
563 /* copy 802.3 header */
567 NdisMoveMemory(skb_push(pOSPkt
, LENGTH_802_3
), pHeader802_3
,
571 void announce_802_3_packet(struct rt_rtmp_adapter
*pAd
, void *pPacket
)
574 struct sk_buff
*pRxPkt
;
578 pRxPkt
= RTPKT_TO_OSPKT(pPacket
);
580 /* Push up the protocol stack */
581 pRxPkt
->protocol
= eth_type_trans(pRxPkt
, pRxPkt
->dev
);
586 struct rt_rtmp_sg_list
*
587 rt_get_sg_list_from_packet(void *pPacket
, struct rt_rtmp_sg_list
*sg
)
589 sg
->NumberOfElements
= 1;
590 sg
->Elements
[0].Address
= GET_OS_PKT_DATAPTR(pPacket
);
591 sg
->Elements
[0].Length
= GET_OS_PKT_LEN(pPacket
);
595 void hex_dump(char *str
, unsigned char *pSrcBufVA
, unsigned int SrcBufLen
)
600 if (RTDebugLevel
< RT_DEBUG_TRACE
)
604 printk("%s: %p, len = %d\n", str
, pSrcBufVA
, SrcBufLen
);
605 for (x
= 0; x
< SrcBufLen
; x
++) {
607 printk("0x%04x : ", x
);
608 printk("%02x ", ((unsigned char)pt
[x
]));
616 ========================================================================
619 Send log message through wireless event
621 Support standard iw_event with IWEVCUSTOM. It is used below.
623 iwreq_data.data.flags is used to store event_flag that is defined by user.
624 iwreq_data.data.length is the length of the event log.
626 The format of the event log is composed of the entry's MAC address and
627 the desired log message (refer to pWirelessEventText).
629 ex: 11:22:33:44:55:66 has associated successfully
631 p.s. The requirement of Wireless Extension is v15 or newer.
633 ========================================================================
635 void RTMPSendWirelessEvent(struct rt_rtmp_adapter
*pAd
,
637 u8
*pAddr
, u8 BssIdx
, char Rssi
)
640 /*union iwreq_data wrqu; */
641 char *pBuf
= NULL
, *pBufPtr
= NULL
;
642 u16 event
, type
, BufLen
;
643 u8 event_table_len
= 0;
645 type
= Event_flag
& 0xFF00;
646 event
= Event_flag
& 0x00FF;
649 case IW_SYS_EVENT_FLAG_START
:
650 event_table_len
= IW_SYS_EVENT_TYPE_NUM
;
653 case IW_SPOOF_EVENT_FLAG_START
:
654 event_table_len
= IW_SPOOF_EVENT_TYPE_NUM
;
657 case IW_FLOOD_EVENT_FLAG_START
:
658 event_table_len
= IW_FLOOD_EVENT_TYPE_NUM
;
662 if (event_table_len
== 0) {
663 DBGPRINT(RT_DEBUG_ERROR
,
664 ("%s : The type(%0x02x) is not valid.\n", __func__
,
669 if (event
>= event_table_len
) {
670 DBGPRINT(RT_DEBUG_ERROR
,
671 ("%s : The event(%0x02x) is not valid.\n", __func__
,
675 /*Allocate memory and copy the msg. */
676 if ((pBuf
= kmalloc(IW_CUSTOM_MAX_LEN
, GFP_ATOMIC
)) != NULL
) {
677 /*Prepare the payload */
678 memset(pBuf
, 0, IW_CUSTOM_MAX_LEN
);
685 "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ",
687 else if (BssIdx
< MAX_MBSSID_NUM
)
689 sprintf(pBufPtr
, "(RT2860) BSS(wlan%d) ", BssIdx
);
691 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) ");
693 if (type
== IW_SYS_EVENT_FLAG_START
)
695 sprintf(pBufPtr
, "%s",
696 pWirelessSysEventText
[event
]);
697 else if (type
== IW_SPOOF_EVENT_FLAG_START
)
699 sprintf(pBufPtr
, "%s (RSSI=%d)",
700 pWirelessSpoofEventText
[event
], Rssi
);
701 else if (type
== IW_FLOOD_EVENT_FLAG_START
)
703 sprintf(pBufPtr
, "%s",
704 pWirelessFloodEventText
[event
]);
706 pBufPtr
+= sprintf(pBufPtr
, "%s", "unknown event");
708 pBufPtr
[pBufPtr
- pBuf
] = '\0';
709 BufLen
= pBufPtr
- pBuf
;
711 RtmpOSWrielessEventSend(pAd
, IWEVCUSTOM
, Event_flag
, NULL
,
713 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
717 DBGPRINT(RT_DEBUG_ERROR
,
718 ("%s : Can't allocate memory for wireless event.\n",
722 void send_monitor_packets(struct rt_rtmp_adapter
*pAd
, struct rt_rx_blk
*pRxBlk
)
724 struct sk_buff
*pOSPkt
;
725 struct rt_wlan_ng_prism2_header
*ph
;
728 u8 temp_header
[40] = { 0 };
730 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 */
731 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
732 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
733 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
734 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
735 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
736 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
737 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
738 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
739 72, 73, 74, 75, 76, 77, 78, 79, 80
742 ASSERT(pRxBlk
->pRxPacket
);
743 if (pRxBlk
->DataSize
< 10) {
744 DBGPRINT(RT_DEBUG_ERROR
,
745 ("%s : Size is too small! (%d)\n", __func__
,
747 goto err_free_sk_buff
;
750 if (pRxBlk
->DataSize
+ sizeof(struct rt_wlan_ng_prism2_header
) >
751 RX_BUFFER_AGGRESIZE
) {
752 DBGPRINT(RT_DEBUG_ERROR
,
753 ("%s : Size is too large! (%zu)\n", __func__
,
754 pRxBlk
->DataSize
+ sizeof(struct rt_wlan_ng_prism2_header
)));
755 goto err_free_sk_buff
;
758 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
759 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, BSS0
);
760 if (pRxBlk
->pHeader
->FC
.Type
== BTYPE_DATA
) {
761 pRxBlk
->DataSize
-= LENGTH_802_11
;
762 if ((pRxBlk
->pHeader
->FC
.ToDs
== 1) &&
763 (pRxBlk
->pHeader
->FC
.FrDs
== 1))
764 header_len
= LENGTH_802_11_WITH_ADDR4
;
766 header_len
= LENGTH_802_11
;
769 if (pRxBlk
->pHeader
->FC
.SubType
& 0x08) {
771 /* Data skip QOS contorl field */
772 pRxBlk
->DataSize
-= 2;
774 /* Order bit: A-Ralink or HTC+ */
775 if (pRxBlk
->pHeader
->FC
.Order
) {
777 /* Data skip HTC contorl field */
778 pRxBlk
->DataSize
-= 4;
781 if (header_len
<= 40)
782 NdisMoveMemory(temp_header
, pRxBlk
->pData
, header_len
);
784 /* skip HW padding */
785 if (pRxBlk
->RxD
.L2PAD
)
786 pRxBlk
->pData
+= (header_len
+ 2);
788 pRxBlk
->pData
+= header_len
;
791 if (pRxBlk
->DataSize
< pOSPkt
->len
) {
792 skb_trim(pOSPkt
, pRxBlk
->DataSize
);
794 skb_put(pOSPkt
, (pRxBlk
->DataSize
- pOSPkt
->len
));
797 if ((pRxBlk
->pData
- pOSPkt
->data
) > 0) {
798 skb_put(pOSPkt
, (pRxBlk
->pData
- pOSPkt
->data
));
799 skb_pull(pOSPkt
, (pRxBlk
->pData
- pOSPkt
->data
));
802 if (skb_headroom(pOSPkt
) < (sizeof(struct rt_wlan_ng_prism2_header
) + header_len
)) {
804 (pOSPkt
, (sizeof(struct rt_wlan_ng_prism2_header
) + header_len
), 0,
806 DBGPRINT(RT_DEBUG_ERROR
,
807 ("%s : Reallocate header size of sk_buff fail!\n",
809 goto err_free_sk_buff
;
814 NdisMoveMemory(skb_push(pOSPkt
, header_len
), temp_header
,
817 ph
= (struct rt_wlan_ng_prism2_header
*)skb_push(pOSPkt
,
818 sizeof(struct rt_wlan_ng_prism2_header
));
819 NdisZeroMemory(ph
, sizeof(struct rt_wlan_ng_prism2_header
));
821 ph
->msgcode
= DIDmsg_lnxind_wlansniffrm
;
822 ph
->msglen
= sizeof(struct rt_wlan_ng_prism2_header
);
823 strcpy((char *)ph
->devname
, (char *)pAd
->net_dev
->name
);
825 ph
->hosttime
.did
= DIDmsg_lnxind_wlansniffrm_hosttime
;
826 ph
->hosttime
.status
= 0;
827 ph
->hosttime
.len
= 4;
828 ph
->hosttime
.data
= jiffies
;
830 ph
->mactime
.did
= DIDmsg_lnxind_wlansniffrm_mactime
;
831 ph
->mactime
.status
= 0;
833 ph
->mactime
.data
= 0;
835 ph
->istx
.did
= DIDmsg_lnxind_wlansniffrm_istx
;
840 ph
->channel
.did
= DIDmsg_lnxind_wlansniffrm_channel
;
841 ph
->channel
.status
= 0;
844 ph
->channel
.data
= (u_int32_t
) pAd
->CommonCfg
.Channel
;
846 ph
->rssi
.did
= DIDmsg_lnxind_wlansniffrm_rssi
;
850 (u_int32_t
) RTMPMaxRssi(pAd
,
851 ConvertToRssi(pAd
, pRxBlk
->pRxWI
->RSSI0
,
852 RSSI_0
), ConvertToRssi(pAd
,
857 ConvertToRssi(pAd
, pRxBlk
->pRxWI
->RSSI2
,
860 ph
->signal
.did
= DIDmsg_lnxind_wlansniffrm_signal
;
861 ph
->signal
.status
= 0;
863 ph
->signal
.data
= 0; /*rssi + noise; */
865 ph
->noise
.did
= DIDmsg_lnxind_wlansniffrm_noise
;
866 ph
->noise
.status
= 0;
870 if (pRxBlk
->pRxWI
->PHYMODE
>= MODE_HTMIX
) {
872 16 + ((u8
)pRxBlk
->pRxWI
->BW
* 16) +
873 ((u8
)pRxBlk
->pRxWI
->ShortGI
* 32) +
874 ((u8
)pRxBlk
->pRxWI
->MCS
);
875 } else if (pRxBlk
->pRxWI
->PHYMODE
== MODE_OFDM
)
876 rate_index
= (u8
)(pRxBlk
->pRxWI
->MCS
) + 4;
878 rate_index
= (u8
)(pRxBlk
->pRxWI
->MCS
);
881 if (rate_index
> 255)
884 ph
->rate
.did
= DIDmsg_lnxind_wlansniffrm_rate
;
887 ph
->rate
.data
= ralinkrate
[rate_index
];
889 ph
->frmlen
.did
= DIDmsg_lnxind_wlansniffrm_frmlen
;
890 ph
->frmlen
.status
= 0;
892 ph
->frmlen
.data
= (u_int32_t
) pRxBlk
->DataSize
;
894 pOSPkt
->pkt_type
= PACKET_OTHERHOST
;
895 pOSPkt
->protocol
= eth_type_trans(pOSPkt
, pOSPkt
->dev
);
896 pOSPkt
->ip_summed
= CHECKSUM_NONE
;
902 RELEASE_NDIS_PACKET(pAd
, pRxBlk
->pRxPacket
, NDIS_STATUS_FAILURE
);
907 /*******************************************************************************
909 Device IRQ related functions.
911 *******************************************************************************/
912 int RtmpOSIRQRequest(struct net_device
*pNetDev
)
914 #ifdef RTMP_PCI_SUPPORT
915 struct net_device
*net_dev
= pNetDev
;
916 struct rt_rtmp_adapter
*pAd
= NULL
;
919 GET_PAD_FROM_NET_DEV(pAd
, pNetDev
);
923 if (pAd
->infType
== RTMP_DEV_INF_PCI
) {
924 struct os_cookie
*_pObj
= (struct os_cookie
*)(pAd
->OS_Cookie
);
925 RTMP_MSI_ENABLE(pAd
);
927 request_irq(_pObj
->pci_dev
->irq
, rt2860_interrupt
, SA_SHIRQ
,
928 (net_dev
)->name
, (net_dev
));
930 printk("RT2860: request_irq ERROR(%d)\n", retval
);
939 int RtmpOSIRQRelease(struct net_device
*pNetDev
)
941 struct net_device
*net_dev
= pNetDev
;
942 struct rt_rtmp_adapter
*pAd
= NULL
;
944 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
948 #ifdef RTMP_PCI_SUPPORT
949 if (pAd
->infType
== RTMP_DEV_INF_PCI
) {
950 struct os_cookie
*pObj
= (struct os_cookie
*)(pAd
->OS_Cookie
);
951 synchronize_irq(pObj
->pci_dev
->irq
);
952 free_irq(pObj
->pci_dev
->irq
, (net_dev
));
953 RTMP_MSI_DISABLE(pAd
);
955 #endif /* RTMP_PCI_SUPPORT // */
960 /*******************************************************************************
962 File open/close related functions.
964 *******************************************************************************/
965 struct file
*RtmpOSFileOpen(char *pPath
, int flag
, int mode
)
967 struct file
*filePtr
;
969 filePtr
= filp_open(pPath
, flag
, 0);
970 if (IS_ERR(filePtr
)) {
971 DBGPRINT(RT_DEBUG_ERROR
,
972 ("%s(): Error %ld opening %s\n", __func__
,
973 -PTR_ERR(filePtr
), pPath
));
976 return (struct file
*)filePtr
;
979 int RtmpOSFileClose(struct file
*osfd
)
981 filp_close(osfd
, NULL
);
985 void RtmpOSFileSeek(struct file
*osfd
, int offset
)
987 osfd
->f_pos
= offset
;
990 int RtmpOSFileRead(struct file
*osfd
, char *pDataPtr
, int readLen
)
992 /* The object must have a read method */
993 if (osfd
->f_op
&& osfd
->f_op
->read
) {
994 return osfd
->f_op
->read(osfd
, pDataPtr
, readLen
, &osfd
->f_pos
);
996 DBGPRINT(RT_DEBUG_ERROR
, ("no file read method\n"));
1001 int RtmpOSFileWrite(struct file
*osfd
, char *pDataPtr
, int writeLen
)
1003 return osfd
->f_op
->write(osfd
, pDataPtr
, (size_t) writeLen
,
1007 /*******************************************************************************
1009 Task create/management/kill related functions.
1011 *******************************************************************************/
1012 int RtmpOSTaskKill(struct rt_rtmp_os_task
*pTask
)
1014 struct rt_rtmp_adapter
*pAd
;
1015 int ret
= NDIS_STATUS_FAILURE
;
1017 pAd
= (struct rt_rtmp_adapter
*)pTask
->priv
;
1019 #ifdef KTHREAD_SUPPORT
1020 if (pTask
->kthread_task
) {
1021 kthread_stop(pTask
->kthread_task
);
1022 ret
= NDIS_STATUS_SUCCESS
;
1025 CHECK_PID_LEGALITY(pTask
->taskPID
) {
1026 printk("Terminate the task(%s) with pid(%d)!\n",
1027 pTask
->taskName
, GET_PID_NUMBER(pTask
->taskPID
));
1029 pTask
->task_killed
= 1;
1031 ret
= KILL_THREAD_PID(pTask
->taskPID
, SIGTERM
, 1);
1034 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1035 pTask
->taskName
, GET_PID_NUMBER(pTask
->taskPID
),
1038 wait_for_completion(&pTask
->taskComplete
);
1039 pTask
->taskPID
= THREAD_PID_INIT_VALUE
;
1040 pTask
->task_killed
= 0;
1041 ret
= NDIS_STATUS_SUCCESS
;
1050 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task
*pTask
)
1053 #ifndef KTHREAD_SUPPORT
1054 complete_and_exit(&pTask
->taskComplete
, 0);
1060 void RtmpOSTaskCustomize(struct rt_rtmp_os_task
*pTask
)
1063 #ifndef KTHREAD_SUPPORT
1065 daemonize((char *)& pTask
->taskName
[0] /*"%s",pAd->net_dev->name */ );
1067 allow_signal(SIGTERM
);
1068 allow_signal(SIGKILL
);
1069 current
->flags
|= PF_NOFREEZE
;
1071 /* signal that we've started the thread */
1072 complete(&pTask
->taskComplete
);
1077 int RtmpOSTaskAttach(struct rt_rtmp_os_task
*pTask
,
1078 IN
int (*fn
) (void *), IN
void *arg
)
1080 int status
= NDIS_STATUS_SUCCESS
;
1082 #ifdef KTHREAD_SUPPORT
1083 pTask
->task_killed
= 0;
1084 pTask
->kthread_task
= NULL
;
1085 pTask
->kthread_task
= kthread_run(fn
, arg
, pTask
->taskName
);
1086 if (IS_ERR(pTask
->kthread_task
))
1087 status
= NDIS_STATUS_FAILURE
;
1089 pid_number
= kernel_thread(fn
, arg
, RTMP_OS_MGMT_TASK_FLAGS
);
1090 if (pid_number
< 0) {
1091 DBGPRINT(RT_DEBUG_ERROR
,
1092 ("Attach task(%s) failed!\n", pTask
->taskName
));
1093 status
= NDIS_STATUS_FAILURE
;
1095 pTask
->taskPID
= GET_PID(pid_number
);
1097 /* Wait for the thread to start */
1098 wait_for_completion(&pTask
->taskComplete
);
1099 status
= NDIS_STATUS_SUCCESS
;
1105 int RtmpOSTaskInit(struct rt_rtmp_os_task
*pTask
,
1106 char *pTaskName
, void * pPriv
)
1112 #ifndef KTHREAD_SUPPORT
1113 NdisZeroMemory((u8
*)(pTask
), sizeof(struct rt_rtmp_os_task
));
1116 len
= strlen(pTaskName
);
1119 (RTMP_OS_TASK_NAME_LEN
- 1) ? (RTMP_OS_TASK_NAME_LEN
- 1) : len
;
1120 NdisMoveMemory(&pTask
->taskName
[0], pTaskName
, len
);
1121 pTask
->priv
= pPriv
;
1123 #ifndef KTHREAD_SUPPORT
1124 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask
->taskSema
));
1125 pTask
->taskPID
= THREAD_PID_INIT_VALUE
;
1127 init_completion(&pTask
->taskComplete
);
1130 return NDIS_STATUS_SUCCESS
;
1133 void RTMP_IndicateMediaState(struct rt_rtmp_adapter
*pAd
)
1135 if (pAd
->CommonCfg
.bWirelessEvent
) {
1136 if (pAd
->IndicateMediaState
== NdisMediaStateConnected
) {
1137 RTMPSendWirelessEvent(pAd
, IW_STA_LINKUP_EVENT_FLAG
,
1138 pAd
->MacTab
.Content
[BSSID_WCID
].
1141 RTMPSendWirelessEvent(pAd
, IW_STA_LINKDOWN_EVENT_FLAG
,
1142 pAd
->MacTab
.Content
[BSSID_WCID
].
1148 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter
*pAd
,
1152 u8
*pData
, u32 dataLen
)
1154 union iwreq_data wrqu
;
1156 memset(&wrqu
, 0, sizeof(wrqu
));
1159 wrqu
.data
.flags
= flags
;
1162 memcpy(wrqu
.ap_addr
.sa_data
, pSrcMac
, MAC_ADDR_LEN
);
1164 if ((pData
!= NULL
) && (dataLen
> 0))
1165 wrqu
.data
.length
= dataLen
;
1167 wireless_send_event(pAd
->net_dev
, eventType
, &wrqu
, (char *)pData
);
1171 int RtmpOSNetDevAddrSet(struct net_device
*pNetDev
, u8
*pMacAddr
)
1173 struct net_device
*net_dev
;
1174 struct rt_rtmp_adapter
*pAd
;
1177 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
1179 /* work-around for the SuSE due to it has it's own interface name management system. */
1181 NdisZeroMemory(pAd
->StaCfg
.dev_name
, 16);
1182 NdisMoveMemory(pAd
->StaCfg
.dev_name
, net_dev
->name
,
1183 strlen(net_dev
->name
));
1186 NdisMoveMemory(net_dev
->dev_addr
, pMacAddr
, 6);
1192 * Assign the network dev name for created Ralink WiFi interface.
1194 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter
*pAd
,
1195 struct net_device
*dev
,
1196 char *pPrefixStr
, int devIdx
)
1198 struct net_device
*existNetDev
;
1199 char suffixName
[IFNAMSIZ
];
1200 char desiredName
[IFNAMSIZ
];
1201 int ifNameIdx
, prefixLen
, slotNameLen
;
1204 prefixLen
= strlen(pPrefixStr
);
1205 ASSERT((prefixLen
< IFNAMSIZ
));
1207 for (ifNameIdx
= devIdx
; ifNameIdx
< 32; ifNameIdx
++) {
1208 memset(suffixName
, 0, IFNAMSIZ
);
1209 memset(desiredName
, 0, IFNAMSIZ
);
1210 strncpy(&desiredName
[0], pPrefixStr
, prefixLen
);
1212 sprintf(suffixName
, "%d", ifNameIdx
);
1214 slotNameLen
= strlen(suffixName
);
1215 ASSERT(((slotNameLen
+ prefixLen
) < IFNAMSIZ
));
1216 strcat(desiredName
, suffixName
);
1218 existNetDev
= RtmpOSNetDevGetByName(dev
, &desiredName
[0]);
1219 if (existNetDev
== NULL
)
1222 RtmpOSNetDeviceRefPut(existNetDev
);
1225 if (ifNameIdx
< 32) {
1226 strcpy(&dev
->name
[0], &desiredName
[0]);
1227 Status
= NDIS_STATUS_SUCCESS
;
1229 DBGPRINT(RT_DEBUG_ERROR
,
1230 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1232 Status
= NDIS_STATUS_FAILURE
;
1238 void RtmpOSNetDevClose(struct net_device
*pNetDev
)
1243 void RtmpOSNetDevFree(struct net_device
*pNetDev
)
1247 free_netdev(pNetDev
);
1250 int RtmpOSNetDevAlloc(struct net_device
** new_dev_p
, u32 privDataSize
)
1252 /* assign it as null first. */
1255 DBGPRINT(RT_DEBUG_TRACE
,
1256 ("Allocate a net device with private data size=%d!\n",
1258 *new_dev_p
= alloc_etherdev(privDataSize
);
1260 return NDIS_STATUS_SUCCESS
;
1262 return NDIS_STATUS_FAILURE
;
1265 struct net_device
*RtmpOSNetDevGetByName(struct net_device
*pNetDev
, char *pDevName
)
1267 struct net_device
*pTargetNetDev
= NULL
;
1269 pTargetNetDev
= dev_get_by_name(dev_net(pNetDev
), pDevName
);
1271 return pTargetNetDev
;
1274 void RtmpOSNetDeviceRefPut(struct net_device
*pNetDev
)
1277 every time dev_get_by_name is called, and it has returned a valid struct
1278 net_device*, dev_put should be called afterwards, because otherwise the
1279 machine hangs when the device is unregistered (since dev->refcnt > 1).
1285 int RtmpOSNetDevDestory(struct rt_rtmp_adapter
*pAd
, struct net_device
*pNetDev
)
1288 /* TODO: Need to fix this */
1289 printk("WARNING: This function(%s) not implement yet!\n", __func__
);
1293 void RtmpOSNetDevDetach(struct net_device
*pNetDev
)
1295 unregister_netdev(pNetDev
);
1298 int RtmpOSNetDevAttach(struct net_device
*pNetDev
,
1299 struct rt_rtmp_os_netdev_op_hook
*pDevOpHook
)
1301 int ret
, rtnl_locked
= FALSE
;
1303 DBGPRINT(RT_DEBUG_TRACE
, ("RtmpOSNetDevAttach()--->\n"));
1304 /* If we need hook some callback function to the net device structrue, now do it. */
1306 struct rt_rtmp_adapter
*pAd
= NULL
;
1308 GET_PAD_FROM_NET_DEV(pAd
, pNetDev
);
1310 pNetDev
->netdev_ops
= pDevOpHook
->netdev_ops
;
1312 /* OS specific flags, here we used to indicate if we are virtual interface */
1313 pNetDev
->priv_flags
= pDevOpHook
->priv_flags
;
1315 if (pAd
->OpMode
== OPMODE_STA
) {
1316 pNetDev
->wireless_handlers
= &rt28xx_iw_handler_def
;
1319 /* copy the net device mac address to the net_device structure. */
1320 NdisMoveMemory(pNetDev
->dev_addr
, &pDevOpHook
->devAddr
[0],
1323 rtnl_locked
= pDevOpHook
->needProtcted
;
1327 ret
= register_netdevice(pNetDev
);
1329 ret
= register_netdev(pNetDev
);
1331 DBGPRINT(RT_DEBUG_TRACE
, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret
));
1333 return NDIS_STATUS_SUCCESS
;
1335 return NDIS_STATUS_FAILURE
;
1338 struct net_device
*RtmpOSNetDevCreate(struct rt_rtmp_adapter
*pAd
,
1341 int privMemSize
, char *pNamePrefix
)
1343 struct net_device
*pNetDev
= NULL
;
1346 /* allocate a new network device */
1347 status
= RtmpOSNetDevAlloc(&pNetDev
, 0 /*privMemSize */ );
1348 if (status
!= NDIS_STATUS_SUCCESS
) {
1349 /* allocation fail, exit */
1350 DBGPRINT(RT_DEBUG_ERROR
,
1351 ("Allocate network device fail (%s)...\n",
1356 /* find a available interface name, max 32 interfaces */
1357 status
= RtmpOSNetDevRequestName(pAd
, pNetDev
, pNamePrefix
, devNum
);
1358 if (status
!= NDIS_STATUS_SUCCESS
) {
1359 /* error! no any available ra name can be used! */
1360 DBGPRINT(RT_DEBUG_ERROR
,
1361 ("Assign interface name (%s with suffix 0~32) failed...\n",
1363 RtmpOSNetDevFree(pNetDev
);
1367 DBGPRINT(RT_DEBUG_TRACE
,
1368 ("The name of the new %s interface is %s...\n",
1369 pNamePrefix
, pNetDev
->name
));