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/sched.h>
29 #include "rt_config.h"
31 ULONG RTDebugLevel
= RT_DEBUG_ERROR
;
34 // for wireless system event message
35 char const *pWirelessSysEventText
[IW_SYS_EVENT_TYPE_NUM
] = {
36 // system status event
37 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
38 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
39 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
40 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
41 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
42 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
43 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
44 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
45 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
46 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
47 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
48 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
49 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
50 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
51 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
52 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
53 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
54 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
55 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
58 // for wireless IDS_spoof_attack event message
59 char const *pWirelessSpoofEventText
[IW_SPOOF_EVENT_TYPE_NUM
] = {
60 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
61 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
62 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
63 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
64 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
65 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
66 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
67 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
68 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
69 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
72 // for wireless IDS_flooding_attack event message
73 char const *pWirelessFloodEventText
[IW_FLOOD_EVENT_TYPE_NUM
] = {
74 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
75 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
76 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
77 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
78 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
79 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
80 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
85 VOID
RTMP_SetPeriodicTimer(
86 IN NDIS_MINIPORT_TIMER
*pTimer
,
87 IN
unsigned long timeout
)
89 timeout
= ((timeout
*OS_HZ
) / 1000);
90 pTimer
->expires
= jiffies
+ timeout
;
94 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
95 VOID
RTMP_OS_Init_Timer(
97 IN NDIS_MINIPORT_TIMER
*pTimer
,
98 IN TIMER_FUNCTION function
,
102 pTimer
->data
= (unsigned long)data
;
103 pTimer
->function
= function
;
107 VOID
RTMP_OS_Add_Timer(
108 IN NDIS_MINIPORT_TIMER
*pTimer
,
109 IN
unsigned long timeout
)
111 if (timer_pending(pTimer
))
114 timeout
= ((timeout
*OS_HZ
) / 1000);
115 pTimer
->expires
= jiffies
+ timeout
;
119 VOID
RTMP_OS_Mod_Timer(
120 IN NDIS_MINIPORT_TIMER
*pTimer
,
121 IN
unsigned long timeout
)
123 timeout
= ((timeout
*OS_HZ
) / 1000);
124 mod_timer(pTimer
, jiffies
+ timeout
);
127 VOID
RTMP_OS_Del_Timer(
128 IN NDIS_MINIPORT_TIMER
*pTimer
,
129 OUT BOOLEAN
*pCancelled
)
131 if (timer_pending(pTimer
))
133 *pCancelled
= del_timer_sync(pTimer
);
142 VOID
RTMP_OS_Release_Packet(
143 IN PRTMP_ADAPTER pAd
,
144 IN PQUEUE_ENTRY pEntry
)
146 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
149 // Unify all delay routine by using udelay
155 for (i
= 0; i
< (usec
/ 50); i
++)
162 void RTMP_GetCurrentSystemTime(LARGE_INTEGER
*time
)
164 time
->u
.LowPart
= jiffies
;
167 // pAd MUST allow to be NULL
168 NDIS_STATUS
os_alloc_mem(
169 IN RTMP_ADAPTER
*pAd
,
173 *mem
= (PUCHAR
) kmalloc(size
, GFP_ATOMIC
);
175 return (NDIS_STATUS_SUCCESS
);
177 return (NDIS_STATUS_FAILURE
);
180 // pAd MUST allow to be NULL
181 NDIS_STATUS
os_free_mem(
182 IN PRTMP_ADAPTER pAd
,
188 return (NDIS_STATUS_SUCCESS
);
194 PNDIS_PACKET
RtmpOSNetPktAlloc(
195 IN RTMP_ADAPTER
*pAd
,
199 /* Add 2 more bytes for ip header alignment*/
200 skb
= dev_alloc_skb(size
+2);
202 return ((PNDIS_PACKET
)skb
);
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
;
281 kfree(pAd
->BeaconBuf
);
284 NdisFreeSpinLock(&pAd
->MgmtRingLock
);
287 NdisFreeSpinLock(&pAd
->RxRingLock
);
289 NdisFreeSpinLock(&pAd
->McuCmdLock
);
291 #endif // RTMP_MAC_PCI //
293 for (index
=0 ; index
< NUM_OF_TX_RING
; index
++)
295 NdisFreeSpinLock(&pAd
->TxSwQueueLock
[index
]);
296 NdisFreeSpinLock(&pAd
->DeQueueLock
[index
]);
297 pAd
->DeQueueRunning
[index
] = FALSE
;
300 NdisFreeSpinLock(&pAd
->irq_lock
);
303 vfree(pAd
); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
308 BOOLEAN
OS_Need_Clone_Packet(void)
316 ========================================================================
319 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
320 must have only one NDIS BUFFER
321 return - byte copied. 0 means can't create NDIS PACKET
322 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
325 pAd Pointer to our adapter
326 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
327 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
335 ========================================================================
337 NDIS_STATUS
RTMPCloneNdisPacket(
338 IN PRTMP_ADAPTER pAd
,
339 IN BOOLEAN pInsAMSDUHdr
,
340 IN PNDIS_PACKET pInPacket
,
341 OUT PNDIS_PACKET
*ppOutPacket
)
349 // 1. Allocate a packet
350 pkt
= dev_alloc_skb(2048);
354 return NDIS_STATUS_FAILURE
;
357 skb_put(pkt
, GET_OS_PKT_LEN(pInPacket
));
358 NdisMoveMemory(pkt
->data
, GET_OS_PKT_DATAPTR(pInPacket
), GET_OS_PKT_LEN(pInPacket
));
359 *ppOutPacket
= OSPKT_TO_RTPKT(pkt
);
362 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt
), PKTSRC_NDIS
);
364 printk("###Clone###\n");
366 return NDIS_STATUS_SUCCESS
;
370 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
371 NDIS_STATUS
RTMPAllocateNdisPacket(
372 IN PRTMP_ADAPTER pAd
,
373 OUT PNDIS_PACKET
*ppPacket
,
379 PNDIS_PACKET pPacket
;
383 // 1. Allocate a packet
384 pPacket
= (PNDIS_PACKET
*) dev_alloc_skb(HeaderLen
+ DataLen
+ RTMP_PKT_TAIL_PADDING
);
389 printk("RTMPAllocateNdisPacket Fail\n\n");
391 return NDIS_STATUS_FAILURE
;
394 // 2. clone the frame content
396 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket
), pHeader
, HeaderLen
);
398 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket
) + HeaderLen
, pData
, DataLen
);
400 // 3. update length of packet
401 skb_put(GET_OS_PKT_TYPE(pPacket
), HeaderLen
+DataLen
);
403 RTMP_SET_PACKET_SOURCE(pPacket
, PKTSRC_NDIS
);
404 // printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
406 return NDIS_STATUS_SUCCESS
;
410 ========================================================================
412 This routine frees a miniport internally allocated NDIS_PACKET and its
413 corresponding NDIS_BUFFER and allocated memory.
414 ========================================================================
416 VOID
RTMPFreeNdisPacket(
417 IN PRTMP_ADAPTER pAd
,
418 IN PNDIS_PACKET pPacket
)
420 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket
));
424 // IRQL = DISPATCH_LEVEL
425 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
426 // scatter gather buffer
427 NDIS_STATUS
Sniff2BytesFromNdisBuffer(
428 IN PNDIS_BUFFER pFirstBuffer
,
429 IN UCHAR DesiredOffset
,
433 *pByte0
= *(PUCHAR
)(pFirstBuffer
+ DesiredOffset
);
434 *pByte1
= *(PUCHAR
)(pFirstBuffer
+ DesiredOffset
+ 1);
436 return NDIS_STATUS_SUCCESS
;
440 void RTMP_QueryPacketInfo(
441 IN PNDIS_PACKET pPacket
,
442 OUT PACKET_INFO
*pPacketInfo
,
443 OUT PUCHAR
*pSrcBufVA
,
444 OUT UINT
*pSrcBufLen
)
446 pPacketInfo
->BufferCount
= 1;
447 pPacketInfo
->pFirstBuffer
= (PNDIS_BUFFER
)GET_OS_PKT_DATAPTR(pPacket
);
448 pPacketInfo
->PhysicalBufferCount
= 1;
449 pPacketInfo
->TotalPacketLength
= GET_OS_PKT_LEN(pPacket
);
451 *pSrcBufVA
= GET_OS_PKT_DATAPTR(pPacket
);
452 *pSrcBufLen
= GET_OS_PKT_LEN(pPacket
);
455 void RTMP_QueryNextPacketInfo(
456 IN PNDIS_PACKET
*ppPacket
,
457 OUT PACKET_INFO
*pPacketInfo
,
458 OUT PUCHAR
*pSrcBufVA
,
459 OUT UINT
*pSrcBufLen
)
461 PNDIS_PACKET pPacket
= NULL
;
464 pPacket
= GET_OS_PKT_NEXT(*ppPacket
);
468 pPacketInfo
->BufferCount
= 1;
469 pPacketInfo
->pFirstBuffer
= (PNDIS_BUFFER
)GET_OS_PKT_DATAPTR(pPacket
);
470 pPacketInfo
->PhysicalBufferCount
= 1;
471 pPacketInfo
->TotalPacketLength
= GET_OS_PKT_LEN(pPacket
);
473 *pSrcBufVA
= GET_OS_PKT_DATAPTR(pPacket
);
474 *pSrcBufLen
= GET_OS_PKT_LEN(pPacket
);
475 *ppPacket
= GET_OS_PKT_NEXT(pPacket
);
479 pPacketInfo
->BufferCount
= 0;
480 pPacketInfo
->pFirstBuffer
= NULL
;
481 pPacketInfo
->PhysicalBufferCount
= 0;
482 pPacketInfo
->TotalPacketLength
= 0;
491 PNDIS_PACKET
DuplicatePacket(
492 IN PRTMP_ADAPTER pAd
,
493 IN PNDIS_PACKET pPacket
,
494 IN UCHAR FromWhichBSSID
)
497 PNDIS_PACKET pRetPacket
= NULL
;
501 DataSize
= (USHORT
) GET_OS_PKT_LEN(pPacket
);
502 pData
= (PUCHAR
) GET_OS_PKT_DATAPTR(pPacket
);
505 skb
= skb_clone(RTPKT_TO_OSPKT(pPacket
), MEM_ALLOC_FLAG
);
508 skb
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
509 pRetPacket
= OSPKT_TO_RTPKT(skb
);
517 PNDIS_PACKET
duplicate_pkt(
518 IN PRTMP_ADAPTER pAd
,
519 IN PUCHAR pHeader802_3
,
523 IN UCHAR FromWhichBSSID
)
526 PNDIS_PACKET pPacket
= NULL
;
529 if ((skb
= __dev_alloc_skb(HdrLen
+ DataSize
+ 2, MEM_ALLOC_FLAG
)) != NULL
)
532 NdisMoveMemory(skb_tail_pointer(skb
), pHeader802_3
, HdrLen
);
533 skb_put(skb
, HdrLen
);
534 NdisMoveMemory(skb_tail_pointer(skb
), pData
, DataSize
);
535 skb_put(skb
, DataSize
);
536 skb
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
537 pPacket
= OSPKT_TO_RTPKT(skb
);
544 #define TKIP_TX_MIC_SIZE 8
545 PNDIS_PACKET
duplicate_pkt_with_TKIP_MIC(
546 IN PRTMP_ADAPTER pAd
,
547 IN PNDIS_PACKET pPacket
)
549 struct sk_buff
*skb
, *newskb
;
552 skb
= RTPKT_TO_OSPKT(pPacket
);
553 if (skb_tailroom(skb
) < TKIP_TX_MIC_SIZE
)
555 // alloc a new skb and copy the packet
556 newskb
= skb_copy_expand(skb
, skb_headroom(skb
), TKIP_TX_MIC_SIZE
, GFP_ATOMIC
);
557 dev_kfree_skb_any(skb
);
560 DBGPRINT(RT_DEBUG_ERROR
, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
566 return OSPKT_TO_RTPKT(skb
);
574 PNDIS_PACKET
ClonePacket(
575 IN PRTMP_ADAPTER pAd
,
576 IN PNDIS_PACKET pPacket
,
580 struct sk_buff
*pRxPkt
;
581 struct sk_buff
*pClonedPkt
;
584 pRxPkt
= RTPKT_TO_OSPKT(pPacket
);
587 pClonedPkt
= skb_clone(pRxPkt
, MEM_ALLOC_FLAG
);
591 // set the correct dataptr and data len
592 pClonedPkt
->dev
= pRxPkt
->dev
;
593 pClonedPkt
->data
= pData
;
594 pClonedPkt
->len
= DataSize
;
595 pClonedPkt
->tail
= pClonedPkt
->data
+ pClonedPkt
->len
;
596 ASSERT(DataSize
< 1530);
602 // change OS packet DataPtr and DataLen
604 void update_os_packet_info(
605 IN PRTMP_ADAPTER pAd
,
607 IN UCHAR FromWhichBSSID
)
609 struct sk_buff
*pOSPkt
;
611 ASSERT(pRxBlk
->pRxPacket
);
612 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
614 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
615 pOSPkt
->data
= pRxBlk
->pData
;
616 pOSPkt
->len
= pRxBlk
->DataSize
;
617 pOSPkt
->tail
= pOSPkt
->data
+ pOSPkt
->len
;
621 void wlan_802_11_to_802_3_packet(
622 IN PRTMP_ADAPTER pAd
,
624 IN PUCHAR pHeader802_3
,
625 IN UCHAR FromWhichBSSID
)
627 struct sk_buff
*pOSPkt
;
629 ASSERT(pRxBlk
->pRxPacket
);
630 ASSERT(pHeader802_3
);
632 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
634 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, FromWhichBSSID
);
635 pOSPkt
->data
= pRxBlk
->pData
;
636 pOSPkt
->len
= pRxBlk
->DataSize
;
637 pOSPkt
->tail
= pOSPkt
->data
+ pOSPkt
->len
;
644 #ifdef CONFIG_STA_SUPPORT
645 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
646 NdisMoveMemory(skb_push(pOSPkt
, LENGTH_802_3
), pHeader802_3
, LENGTH_802_3
);
647 #endif // CONFIG_STA_SUPPORT //
652 void announce_802_3_packet(
653 IN PRTMP_ADAPTER pAd
,
654 IN PNDIS_PACKET pPacket
)
657 struct sk_buff
*pRxPkt
;
658 #ifdef INF_AMAZON_PPA
660 unsigned int ppa_flags
= 0; /* reserved for now */
661 #endif // INF_AMAZON_PPA //
665 pRxPkt
= RTPKT_TO_OSPKT(pPacket
);
667 #ifdef CONFIG_STA_SUPPORT
668 #endif // CONFIG_STA_SUPPORT //
670 /* Push up the protocol stack */
672 IKANOS_DataFrameRx(pAd
, pRxPkt
->dev
, pRxPkt
, pRxPkt
->len
);
676 BG_FTPH_PacketFromApHandle(pRxPkt
);
678 #endif // BG_FT_SUPPORT //
679 #endif // INF_AMAZON_SE //
680 pRxPkt
->protocol
= eth_type_trans(pRxPkt
, pRxPkt
->dev
);
682 #ifdef INF_AMAZON_PPA
683 if (ppa_hook_directpath_send_fn
&& pAd
->PPAEnable
==TRUE
)
685 memset(pRxPkt
->head
,0,pRxPkt
->data
-pRxPkt
->head
-14);
686 DBGPRINT(RT_DEBUG_TRACE
, ("ppa_hook_directpath_send_fn rx :ret:%d headroom:%d dev:%s pktlen:%d<===\n",ret
,skb_headroom(pRxPkt
)
687 ,pRxPkt
->dev
->name
,pRxPkt
->len
));
688 hex_dump("rx packet", pRxPkt
->data
, 32);
689 ret
= ppa_hook_directpath_send_fn(pAd
->g_if_id
, pRxPkt
, pRxPkt
->len
, ppa_flags
);
694 #endif // INF_AMAZON_PPA //
696 //#ifdef CONFIG_5VT_ENHANCE
697 // *(int*)(pRxPkt->cb) = BRIDGE_TAG;
704 #endif // IKANOS_VX_1X0 //
708 PRTMP_SCATTER_GATHER_LIST
709 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket
, RTMP_SCATTER_GATHER_LIST
*sg
)
711 sg
->NumberOfElements
= 1;
712 sg
->Elements
[0].Address
= GET_OS_PKT_DATAPTR(pPacket
);
713 sg
->Elements
[0].Length
= GET_OS_PKT_LEN(pPacket
);
717 void hex_dump(char *str
, unsigned char *pSrcBufVA
, unsigned int SrcBufLen
)
722 if (RTDebugLevel
< RT_DEBUG_TRACE
)
726 printk("%s: %p, len = %d\n",str
, pSrcBufVA
, SrcBufLen
);
727 for (x
=0; x
<SrcBufLen
; x
++)
730 printk("0x%04x : ", x
);
731 printk("%02x ", ((unsigned char)pt
[x
]));
732 if (x
%16 == 15) printk("\n");
738 ========================================================================
741 Send log message through wireless event
743 Support standard iw_event with IWEVCUSTOM. It is used below.
745 iwreq_data.data.flags is used to store event_flag that is defined by user.
746 iwreq_data.data.length is the length of the event log.
748 The format of the event log is composed of the entry's MAC address and
749 the desired log message (refer to pWirelessEventText).
751 ex: 11:22:33:44:55:66 has associated successfully
753 p.s. The requirement of Wireless Extension is v15 or newer.
755 ========================================================================
757 VOID
RTMPSendWirelessEvent(
758 IN PRTMP_ADAPTER pAd
,
759 IN USHORT Event_flag
,
764 #if WIRELESS_EXT >= 15
766 //union iwreq_data wrqu;
767 PSTRING pBuf
= NULL
, pBufPtr
= NULL
;
768 USHORT event
, type
, BufLen
;
769 UCHAR event_table_len
= 0;
771 type
= Event_flag
& 0xFF00;
772 event
= Event_flag
& 0x00FF;
776 case IW_SYS_EVENT_FLAG_START
:
777 event_table_len
= IW_SYS_EVENT_TYPE_NUM
;
780 case IW_SPOOF_EVENT_FLAG_START
:
781 event_table_len
= IW_SPOOF_EVENT_TYPE_NUM
;
784 case IW_FLOOD_EVENT_FLAG_START
:
785 event_table_len
= IW_FLOOD_EVENT_TYPE_NUM
;
789 if (event_table_len
== 0)
791 DBGPRINT(RT_DEBUG_ERROR
, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__
, type
));
795 if (event
>= event_table_len
)
797 DBGPRINT(RT_DEBUG_ERROR
, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__
, event
));
801 //Allocate memory and copy the msg.
802 if((pBuf
= kmalloc(IW_CUSTOM_MAX_LEN
, GFP_ATOMIC
)) != NULL
)
804 //Prepare the payload
805 memset(pBuf
, 0, IW_CUSTOM_MAX_LEN
);
810 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr
));
811 else if (BssIdx
< MAX_MBSSID_NUM
)
812 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) BSS(ra%d) ", BssIdx
);
814 pBufPtr
+= sprintf(pBufPtr
, "(RT2860) ");
816 if (type
== IW_SYS_EVENT_FLAG_START
)
817 pBufPtr
+= sprintf(pBufPtr
, "%s", pWirelessSysEventText
[event
]);
818 else if (type
== IW_SPOOF_EVENT_FLAG_START
)
819 pBufPtr
+= sprintf(pBufPtr
, "%s (RSSI=%d)", pWirelessSpoofEventText
[event
], Rssi
);
820 else if (type
== IW_FLOOD_EVENT_FLAG_START
)
821 pBufPtr
+= sprintf(pBufPtr
, "%s", pWirelessFloodEventText
[event
]);
823 pBufPtr
+= sprintf(pBufPtr
, "%s", "unknown event");
825 pBufPtr
[pBufPtr
- pBuf
] = '\0';
826 BufLen
= pBufPtr
- pBuf
;
828 RtmpOSWrielessEventSend(pAd
, IWEVCUSTOM
, Event_flag
, NULL
, (PUCHAR
)pBuf
, BufLen
);
829 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
834 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__
));
836 DBGPRINT(RT_DEBUG_ERROR
, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__
));
837 #endif /* WIRELESS_EXT >= 15 */
843 #ifdef CONFIG_STA_SUPPORT
844 void send_monitor_packets(
845 IN PRTMP_ADAPTER pAd
,
848 struct sk_buff
*pOSPkt
;
849 wlan_ng_prism2_header
*ph
;
851 USHORT header_len
= 0;
852 UCHAR temp_header
[40] = {0};
854 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
855 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,
856 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};
859 ASSERT(pRxBlk
->pRxPacket
);
860 if (pRxBlk
->DataSize
< 10)
862 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Size is too small! (%d)\n", __FUNCTION__
, pRxBlk
->DataSize
));
863 goto err_free_sk_buff
;
866 if (pRxBlk
->DataSize
+ sizeof(wlan_ng_prism2_header
) > RX_BUFFER_AGGRESIZE
)
868 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Size is too large! (%d)\n", __FUNCTION__
, pRxBlk
->DataSize
+ sizeof(wlan_ng_prism2_header
)));
869 goto err_free_sk_buff
;
872 pOSPkt
= RTPKT_TO_OSPKT(pRxBlk
->pRxPacket
);
873 pOSPkt
->dev
= get_netdev_from_bssid(pAd
, BSS0
);
874 if (pRxBlk
->pHeader
->FC
.Type
== BTYPE_DATA
)
876 pRxBlk
->DataSize
-= LENGTH_802_11
;
877 if ((pRxBlk
->pHeader
->FC
.ToDs
== 1) &&
878 (pRxBlk
->pHeader
->FC
.FrDs
== 1))
879 header_len
= LENGTH_802_11_WITH_ADDR4
;
881 header_len
= LENGTH_802_11
;
884 if (pRxBlk
->pHeader
->FC
.SubType
& 0x08)
887 // Data skip QOS contorl field
888 pRxBlk
->DataSize
-=2;
891 // Order bit: A-Ralink or HTC+
892 if (pRxBlk
->pHeader
->FC
.Order
)
895 // Data skip HTC contorl field
896 pRxBlk
->DataSize
-= 4;
900 if (header_len
<= 40)
901 NdisMoveMemory(temp_header
, pRxBlk
->pData
, header_len
);
904 if (pRxBlk
->RxD
.L2PAD
)
905 pRxBlk
->pData
+= (header_len
+ 2);
907 pRxBlk
->pData
+= header_len
;
911 if (pRxBlk
->DataSize
< pOSPkt
->len
) {
912 skb_trim(pOSPkt
,pRxBlk
->DataSize
);
914 skb_put(pOSPkt
,(pRxBlk
->DataSize
- pOSPkt
->len
));
917 if ((pRxBlk
->pData
- pOSPkt
->data
) > 0) {
918 skb_put(pOSPkt
,(pRxBlk
->pData
- pOSPkt
->data
));
919 skb_pull(pOSPkt
,(pRxBlk
->pData
- pOSPkt
->data
));
922 if (skb_headroom(pOSPkt
) < (sizeof(wlan_ng_prism2_header
)+ header_len
)) {
923 if (pskb_expand_head(pOSPkt
, (sizeof(wlan_ng_prism2_header
) + header_len
), 0, GFP_ATOMIC
)) {
924 DBGPRINT(RT_DEBUG_ERROR
, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__
));
925 goto err_free_sk_buff
;
930 NdisMoveMemory(skb_push(pOSPkt
, header_len
), temp_header
, header_len
);
932 ph
= (wlan_ng_prism2_header
*) skb_push(pOSPkt
, sizeof(wlan_ng_prism2_header
));
933 NdisZeroMemory(ph
, sizeof(wlan_ng_prism2_header
));
935 ph
->msgcode
= DIDmsg_lnxind_wlansniffrm
;
936 ph
->msglen
= sizeof(wlan_ng_prism2_header
);
937 strcpy((PSTRING
) ph
->devname
, (PSTRING
) pAd
->net_dev
->name
);
939 ph
->hosttime
.did
= DIDmsg_lnxind_wlansniffrm_hosttime
;
940 ph
->hosttime
.status
= 0;
941 ph
->hosttime
.len
= 4;
942 ph
->hosttime
.data
= jiffies
;
944 ph
->mactime
.did
= DIDmsg_lnxind_wlansniffrm_mactime
;
945 ph
->mactime
.status
= 0;
947 ph
->mactime
.data
= 0;
949 ph
->istx
.did
= DIDmsg_lnxind_wlansniffrm_istx
;
954 ph
->channel
.did
= DIDmsg_lnxind_wlansniffrm_channel
;
955 ph
->channel
.status
= 0;
958 ph
->channel
.data
= (u_int32_t
)pAd
->CommonCfg
.Channel
;
960 ph
->rssi
.did
= DIDmsg_lnxind_wlansniffrm_rssi
;
963 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
));;
965 ph
->signal
.did
= DIDmsg_lnxind_wlansniffrm_signal
;
966 ph
->signal
.status
= 0;
968 ph
->signal
.data
= 0; //rssi + noise;
970 ph
->noise
.did
= DIDmsg_lnxind_wlansniffrm_noise
;
971 ph
->noise
.status
= 0;
975 #ifdef DOT11_N_SUPPORT
976 if (pRxBlk
->pRxWI
->PHYMODE
>= MODE_HTMIX
)
978 rate_index
= 16 + ((UCHAR
)pRxBlk
->pRxWI
->BW
*16) + ((UCHAR
)pRxBlk
->pRxWI
->ShortGI
*32) + ((UCHAR
)pRxBlk
->pRxWI
->MCS
);
981 #endif // DOT11_N_SUPPORT //
982 if (pRxBlk
->pRxWI
->PHYMODE
== MODE_OFDM
)
983 rate_index
= (UCHAR
)(pRxBlk
->pRxWI
->MCS
) + 4;
985 rate_index
= (UCHAR
)(pRxBlk
->pRxWI
->MCS
);
988 if (rate_index
> 255)
991 ph
->rate
.did
= DIDmsg_lnxind_wlansniffrm_rate
;
994 ph
->rate
.data
= ralinkrate
[rate_index
];
996 ph
->frmlen
.did
= DIDmsg_lnxind_wlansniffrm_frmlen
;
997 ph
->frmlen
.status
= 0;
999 ph
->frmlen
.data
= (u_int32_t
)pRxBlk
->DataSize
;
1002 pOSPkt
->pkt_type
= PACKET_OTHERHOST
;
1003 pOSPkt
->protocol
= eth_type_trans(pOSPkt
, pOSPkt
->dev
);
1004 pOSPkt
->ip_summed
= CHECKSUM_NONE
;
1010 RELEASE_NDIS_PACKET(pAd
, pRxBlk
->pRxPacket
, NDIS_STATUS_FAILURE
);
1014 #endif // CONFIG_STA_SUPPORT //
1018 /*******************************************************************************
1020 File open/close related functions.
1022 *******************************************************************************/
1023 RTMP_OS_FD
RtmpOSFileOpen(char *pPath
, int flag
, int mode
)
1025 struct file
*filePtr
;
1027 filePtr
= filp_open(pPath
, flag
, 0);
1028 if (IS_ERR(filePtr
))
1030 DBGPRINT(RT_DEBUG_ERROR
, ("%s(): Error %ld opening %s\n", __FUNCTION__
, -PTR_ERR(filePtr
), pPath
));
1033 return (RTMP_OS_FD
)filePtr
;
1036 int RtmpOSFileClose(RTMP_OS_FD osfd
)
1038 filp_close(osfd
, NULL
);
1043 void RtmpOSFileSeek(RTMP_OS_FD osfd
, int offset
)
1045 osfd
->f_pos
= offset
;
1049 int RtmpOSFileRead(RTMP_OS_FD osfd
, char *pDataPtr
, int readLen
)
1051 // The object must have a read method
1052 if (osfd
->f_op
&& osfd
->f_op
->read
)
1054 return osfd
->f_op
->read(osfd
, pDataPtr
, readLen
, &osfd
->f_pos
);
1058 DBGPRINT(RT_DEBUG_ERROR
, ("no file read method\n"));
1064 int RtmpOSFileWrite(RTMP_OS_FD osfd
, char *pDataPtr
, int writeLen
)
1066 return osfd
->f_op
->write(osfd
, pDataPtr
, (size_t)writeLen
, &osfd
->f_pos
);
1070 void RtmpOSFSInfoChange(RTMP_OS_FS_INFO
*pOSFSInfo
, BOOLEAN bSet
)
1074 // Save uid and gid used for filesystem access.
1075 // Set user and group to 0 (root)
1076 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
1077 pOSFSInfo
->fsuid
= current
->fsuid
;
1078 pOSFSInfo
->fsgid
= current
->fsgid
;
1079 current
->fsuid
= current
->fsgid
= 0;
1081 pOSFSInfo
->fsuid
= current_fsuid();
1082 pOSFSInfo
->fsgid
= current_fsgid();
1084 pOSFSInfo
->fs
= get_fs();
1089 set_fs(pOSFSInfo
->fs
);
1090 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
1091 current
->fsuid
= pOSFSInfo
->fsuid
;
1092 current
->fsgid
= pOSFSInfo
->fsgid
;
1099 /*******************************************************************************
1101 Task create/management/kill related functions.
1103 *******************************************************************************/
1104 NDIS_STATUS
RtmpOSTaskKill(
1105 IN RTMP_OS_TASK
*pTask
)
1108 int ret
= NDIS_STATUS_FAILURE
;
1110 pAd
= (RTMP_ADAPTER
*)pTask
->priv
;
1112 #ifdef KTHREAD_SUPPORT
1113 if (pTask
->kthread_task
)
1115 kthread_stop(pTask
->kthread_task
);
1116 ret
= NDIS_STATUS_SUCCESS
;
1119 CHECK_PID_LEGALITY(pTask
->taskPID
)
1121 printk("Terminate the task(%s) with pid(%d)!\n", pTask
->taskName
, GET_PID_NUMBER(pTask
->taskPID
));
1123 pTask
->task_killed
= 1;
1125 ret
= KILL_THREAD_PID(pTask
->taskPID
, SIGTERM
, 1);
1128 printk(KERN_WARNING
"kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1129 pTask
->taskName
, GET_PID_NUMBER(pTask
->taskPID
), ret
);
1133 wait_for_completion(&pTask
->taskComplete
);
1134 pTask
->taskPID
= THREAD_PID_INIT_VALUE
;
1135 pTask
->task_killed
= 0;
1136 ret
= NDIS_STATUS_SUCCESS
;
1146 INT
RtmpOSTaskNotifyToExit(
1147 IN RTMP_OS_TASK
*pTask
)
1150 #ifndef KTHREAD_SUPPORT
1151 complete_and_exit(&pTask
->taskComplete
, 0);
1158 void RtmpOSTaskCustomize(
1159 IN RTMP_OS_TASK
*pTask
)
1162 #ifndef KTHREAD_SUPPORT
1164 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1165 daemonize((PSTRING
)&pTask
->taskName
[0]/*"%s",pAd->net_dev->name*/);
1167 allow_signal(SIGTERM
);
1168 allow_signal(SIGKILL
);
1169 current
->flags
|= PF_NOFREEZE
;
1171 unsigned long flags
;
1175 strcpy(current
->comm
, &pTask
->taskName
[0]);
1177 siginitsetinv(¤t
->blocked
, sigmask(SIGTERM
) | sigmask(SIGKILL
));
1179 /* Allow interception of SIGKILL only
1180 * Don't allow other signals to interrupt the transmission */
1181 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1182 spin_lock_irqsave(¤t
->sigmask_lock
, flags
);
1183 flush_signals(current
);
1184 recalc_sigpending(current
);
1185 spin_unlock_irqrestore(¤t
->sigmask_lock
, flags
);
1189 /* signal that we've started the thread */
1190 complete(&pTask
->taskComplete
);
1196 NDIS_STATUS
RtmpOSTaskAttach(
1197 IN RTMP_OS_TASK
*pTask
,
1198 IN
int (*fn
)(void *),
1201 NDIS_STATUS status
= NDIS_STATUS_SUCCESS
;
1202 pid_t pid_number
= -1;
1204 #ifdef KTHREAD_SUPPORT
1205 pTask
->task_killed
= 0;
1206 pTask
->kthread_task
= NULL
;
1207 pTask
->kthread_task
= kthread_run(fn
, arg
, pTask
->taskName
);
1208 if (IS_ERR(pTask
->kthread_task
))
1209 status
= NDIS_STATUS_FAILURE
;
1211 pid_number
= kernel_thread(fn
, arg
, RTMP_OS_MGMT_TASK_FLAGS
);
1214 DBGPRINT (RT_DEBUG_ERROR
, ("Attach task(%s) failed!\n", pTask
->taskName
));
1215 status
= NDIS_STATUS_FAILURE
;
1219 pTask
->taskPID
= GET_PID(pid_number
);
1221 // Wait for the thread to start
1222 wait_for_completion(&pTask
->taskComplete
);
1223 status
= NDIS_STATUS_SUCCESS
;
1230 NDIS_STATUS
RtmpOSTaskInit(
1231 IN RTMP_OS_TASK
*pTask
,
1232 IN PSTRING pTaskName
,
1239 #ifndef KTHREAD_SUPPORT
1240 NdisZeroMemory((PUCHAR
)(pTask
), sizeof(RTMP_OS_TASK
));
1243 len
= strlen(pTaskName
);
1244 len
= len
> (RTMP_OS_TASK_NAME_LEN
-1) ? (RTMP_OS_TASK_NAME_LEN
-1) : len
;
1245 NdisMoveMemory(&pTask
->taskName
[0], pTaskName
, len
);
1246 pTask
->priv
= pPriv
;
1248 #ifndef KTHREAD_SUPPORT
1249 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask
->taskSema
));
1250 pTask
->taskPID
= THREAD_PID_INIT_VALUE
;
1252 init_completion (&pTask
->taskComplete
);
1255 return NDIS_STATUS_SUCCESS
;
1259 void RTMP_IndicateMediaState(
1260 IN PRTMP_ADAPTER pAd
)
1262 if (pAd
->CommonCfg
.bWirelessEvent
)
1264 if (pAd
->IndicateMediaState
== NdisMediaStateConnected
)
1266 RTMPSendWirelessEvent(pAd
, IW_STA_LINKUP_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
1270 RTMPSendWirelessEvent(pAd
, IW_STA_LINKDOWN_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
1276 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1277 //static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
1278 struct net_device
*alloc_netdev(
1281 void (*setup
)(struct net_device
*))
1283 struct net_device
*dev
;
1287 /* ensure 32-byte alignment of the private area */
1288 alloc_size
= sizeof (*dev
) + sizeof_priv
+ 31;
1290 dev
= (struct net_device
*) kmalloc(alloc_size
, GFP_KERNEL
);
1293 DBGPRINT(RT_DEBUG_ERROR
,
1294 ("alloc_netdev: Unable to allocate device memory.\n"));
1298 memset(dev
, 0, alloc_size
);
1301 dev
->priv
= (void *) (((long)(dev
+ 1) + 31) & ~31);
1304 strcpy(dev
->name
, mask
);
1308 #endif // LINUX_VERSION_CODE //
1311 int RtmpOSWrielessEventSend(
1312 IN RTMP_ADAPTER
*pAd
,
1313 IN UINT32 eventType
,
1319 union iwreq_data wrqu
;
1321 memset(&wrqu
, 0, sizeof(wrqu
));
1324 wrqu
.data
.flags
= flags
;
1327 memcpy(wrqu
.ap_addr
.sa_data
, pSrcMac
, MAC_ADDR_LEN
);
1329 if ((pData
!= NULL
) && (dataLen
> 0))
1330 wrqu
.data
.length
= dataLen
;
1332 wireless_send_event(pAd
->net_dev
, eventType
, &wrqu
, (char *)pData
);
1337 int RtmpOSNetDevAddrSet(
1338 IN PNET_DEV pNetDev
,
1341 struct net_device
*net_dev
;
1345 //pAd = (RTMP_ADAPTER *)net_dev->priv;
1346 pAd
=RTMP_OS_NETDEV_GET_PRIV(pNetDev
);
1348 #ifdef CONFIG_STA_SUPPORT
1349 // work-around for the SuSE due to it has it's own interface name management system.
1350 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
1352 NdisZeroMemory(pAd
->StaCfg
.dev_name
, 16);
1353 NdisMoveMemory(pAd
->StaCfg
.dev_name
, net_dev
->name
, strlen(net_dev
->name
));
1355 #endif // CONFIG_STA_SUPPORT //
1357 NdisMoveMemory(net_dev
->dev_addr
, pMacAddr
, 6);
1365 * Assign the network dev name for created Ralink WiFi interface.
1367 static int RtmpOSNetDevRequestName(
1368 IN RTMP_ADAPTER
*pAd
,
1370 IN PSTRING pPrefixStr
,
1373 PNET_DEV existNetDev
;
1374 STRING suffixName
[IFNAMSIZ
];
1375 STRING desiredName
[IFNAMSIZ
];
1376 int ifNameIdx
, prefixLen
, slotNameLen
;
1380 prefixLen
= strlen(pPrefixStr
);
1381 ASSERT((prefixLen
< IFNAMSIZ
));
1383 for (ifNameIdx
= devIdx
; ifNameIdx
< 32; ifNameIdx
++)
1385 memset(suffixName
, 0, IFNAMSIZ
);
1386 memset(desiredName
, 0, IFNAMSIZ
);
1387 strncpy(&desiredName
[0], pPrefixStr
, prefixLen
);
1389 #ifdef MULTIPLE_CARD_SUPPORT
1390 if (pAd
->MC_RowID
>= 0)
1391 sprintf(suffixName
, "%02d_%d", pAd
->MC_RowID
, ifNameIdx
);
1393 #endif // MULTIPLE_CARD_SUPPORT //
1394 sprintf(suffixName
, "%d", ifNameIdx
);
1396 slotNameLen
= strlen(suffixName
);
1397 ASSERT(((slotNameLen
+ prefixLen
) < IFNAMSIZ
));
1398 strcat(desiredName
, suffixName
);
1400 existNetDev
= RtmpOSNetDevGetByName(dev
, &desiredName
[0]);
1401 if (existNetDev
== NULL
)
1404 RtmpOSNetDeviceRefPut(existNetDev
);
1409 strcpy(&dev
->name
[0], &desiredName
[0]);
1410 Status
= NDIS_STATUS_SUCCESS
;
1414 DBGPRINT(RT_DEBUG_ERROR
,
1415 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr
));
1416 Status
= NDIS_STATUS_FAILURE
;
1423 void RtmpOSNetDevClose(
1424 IN PNET_DEV pNetDev
)
1430 void RtmpOSNetDevFree(PNET_DEV pNetDev
)
1434 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1435 free_netdev(pNetDev
);
1442 INT
RtmpOSNetDevAlloc(
1443 IN PNET_DEV
*new_dev_p
,
1444 IN UINT32 privDataSize
)
1446 // assign it as null first.
1449 DBGPRINT(RT_DEBUG_TRACE
, ("Allocate a net device with private data size=%d!\n", privDataSize
));
1450 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1451 *new_dev_p
= alloc_netdev(privDataSize
, "eth%d", ether_setup
);
1453 *new_dev_p
= alloc_etherdev(privDataSize
);
1454 #endif // LINUX_VERSION_CODE //
1457 return NDIS_STATUS_SUCCESS
;
1459 return NDIS_STATUS_FAILURE
;
1463 PNET_DEV
RtmpOSNetDevGetByName(PNET_DEV pNetDev
, PSTRING pDevName
)
1465 PNET_DEV pTargetNetDev
= NULL
;
1468 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1470 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1471 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
1472 pTargetNetDev
= dev_get_by_name(dev_net(pNetDev
), pDevName
);
1475 pTargetNetDev
= dev_get_by_name(pNetDev
->nd_net
, pDevName
);
1478 pTargetNetDev
= dev_get_by_name(pDevName
);
1479 #endif // KERNEL_VERSION(2,6,24) //
1484 devNameLen
= strlen(pDevName
);
1485 ASSERT((devNameLen
<= IFNAMSIZ
));
1487 for(pTargetNetDev
=dev_base
; pTargetNetDev
!=NULL
; pTargetNetDev
=pTargetNetDev
->next
)
1489 if (strncmp(pTargetNetDev
->name
, pDevName
, devNameLen
) == 0)
1492 #endif // KERNEL_VERSION(2,5,0) //
1494 return pTargetNetDev
;
1498 void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev
)
1500 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1502 every time dev_get_by_name is called, and it has returned a valid struct
1503 net_device*, dev_put should be called afterwards, because otherwise the
1504 machine hangs when the device is unregistered (since dev->refcnt > 1).
1508 #endif // LINUX_VERSION_CODE //
1512 INT
RtmpOSNetDevDestory(
1513 IN RTMP_ADAPTER
*pAd
,
1514 IN PNET_DEV pNetDev
)
1517 // TODO: Need to fix this
1518 printk("WARNING: This function(%s) not implement yet!!!\n", __FUNCTION__
);
1523 void RtmpOSNetDevDetach(PNET_DEV pNetDev
)
1525 unregister_netdev(pNetDev
);
1529 int RtmpOSNetDevAttach(
1530 IN PNET_DEV pNetDev
,
1531 IN RTMP_OS_NETDEV_OP_HOOK
*pDevOpHook
)
1533 int ret
, rtnl_locked
= FALSE
;
1535 DBGPRINT(RT_DEBUG_TRACE
, ("RtmpOSNetDevAttach()--->\n"));
1536 // If we need hook some callback function to the net device structrue, now do it.
1539 PRTMP_ADAPTER pAd
= RTMP_OS_NETDEV_GET_PRIV(pNetDev
);
1541 pNetDev
->netdev_ops
= pDevOpHook
->netdev_ops
;
1543 /* OS specific flags, here we used to indicate if we are virtual interface */
1544 pNetDev
->priv_flags
= pDevOpHook
->priv_flags
;
1546 #if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12)
1547 pNetDev
->get_wireless_stats
= rt28xx_get_wireless_stats
;
1550 #ifdef CONFIG_STA_SUPPORT
1551 #if WIRELESS_EXT >= 12
1552 if (pAd
->OpMode
== OPMODE_STA
)
1554 pNetDev
->wireless_handlers
= &rt28xx_iw_handler_def
;
1556 #endif //WIRELESS_EXT >= 12
1557 #endif // CONFIG_STA_SUPPORT //
1559 #ifdef CONFIG_APSTA_MIXED_SUPPORT
1560 #if WIRELESS_EXT >= 12
1561 if (pAd
->OpMode
== OPMODE_AP
)
1563 pNetDev
->wireless_handlers
= &rt28xx_ap_iw_handler_def
;
1565 #endif //WIRELESS_EXT >= 12
1566 #endif // CONFIG_APSTA_MIXED_SUPPORT //
1568 // copy the net device mac address to the net_device structure.
1569 NdisMoveMemory(pNetDev
->dev_addr
, &pDevOpHook
->devAddr
[0], MAC_ADDR_LEN
);
1571 rtnl_locked
= pDevOpHook
->needProtcted
;
1575 ret
= register_netdevice(pNetDev
);
1577 ret
= register_netdev(pNetDev
);
1579 DBGPRINT(RT_DEBUG_TRACE
, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret
));
1581 return NDIS_STATUS_SUCCESS
;
1583 return NDIS_STATUS_FAILURE
;
1587 PNET_DEV
RtmpOSNetDevCreate(
1588 IN RTMP_ADAPTER
*pAd
,
1592 IN PSTRING pNamePrefix
)
1594 struct net_device
*pNetDev
= NULL
;
1598 /* allocate a new network device */
1599 status
= RtmpOSNetDevAlloc(&pNetDev
, 0 /*privMemSize*/);
1600 if (status
!= NDIS_STATUS_SUCCESS
)
1602 /* allocation fail, exit */
1603 DBGPRINT(RT_DEBUG_ERROR
, ("Allocate network device fail (%s)...\n", pNamePrefix
));
1608 /* find a available interface name, max 32 interfaces */
1609 status
= RtmpOSNetDevRequestName(pAd
, pNetDev
, pNamePrefix
, devNum
);
1610 if (status
!= NDIS_STATUS_SUCCESS
)
1612 /* error! no any available ra name can be used! */
1613 DBGPRINT(RT_DEBUG_ERROR
, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix
));
1614 RtmpOSNetDevFree(pNetDev
);
1620 DBGPRINT(RT_DEBUG_TRACE
, ("The name of the new %s interface is %s...\n", pNamePrefix
, pNetDev
->name
));