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;
33 // for wireless system event message
34 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
35 // system status event
36 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
37 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
38 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
39 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
40 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
41 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
42 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
43 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
44 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
45 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
46 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
47 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
48 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
49 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
50 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
51 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
52 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
53 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
54 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
57 // for wireless IDS_spoof_attack event message
58 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
59 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
60 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
61 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
62 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
63 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
64 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
65 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
66 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
67 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
68 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
71 // for wireless IDS_flooding_attack event message
72 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
73 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
74 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
75 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
76 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
77 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
78 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
79 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
84 VOID RTMP_SetPeriodicTimer(
85 IN NDIS_MINIPORT_TIMER *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(
96 IN NDIS_MINIPORT_TIMER *pTimer,
97 IN TIMER_FUNCTION function,
101 pTimer->data = (unsigned long)data;
102 pTimer->function = function;
106 VOID RTMP_OS_Add_Timer(
107 IN NDIS_MINIPORT_TIMER *pTimer,
108 IN unsigned long timeout)
110 if (timer_pending(pTimer))
113 timeout = ((timeout*OS_HZ) / 1000);
114 pTimer->expires = jiffies + timeout;
118 VOID RTMP_OS_Mod_Timer(
119 IN NDIS_MINIPORT_TIMER *pTimer,
120 IN unsigned long timeout)
122 timeout = ((timeout*OS_HZ) / 1000);
123 mod_timer(pTimer, jiffies + timeout);
126 VOID RTMP_OS_Del_Timer(
127 IN NDIS_MINIPORT_TIMER *pTimer,
128 OUT BOOLEAN *pCancelled)
130 if (timer_pending(pTimer))
132 *pCancelled = del_timer_sync(pTimer);
141 VOID RTMP_OS_Release_Packet(
142 IN PRTMP_ADAPTER pAd,
143 IN PQUEUE_ENTRY pEntry)
145 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
148 // Unify all delay routine by using udelay
154 for (i = 0; i < (usec / 50); i++)
161 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
163 time->u.LowPart = jiffies;
166 // pAd MUST allow to be NULL
167 NDIS_STATUS os_alloc_mem(
168 IN RTMP_ADAPTER *pAd,
172 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
174 return (NDIS_STATUS_SUCCESS);
176 return (NDIS_STATUS_FAILURE);
179 // pAd MUST allow to be NULL
180 NDIS_STATUS os_free_mem(
181 IN PRTMP_ADAPTER pAd,
187 return (NDIS_STATUS_SUCCESS);
193 PNDIS_PACKET RtmpOSNetPktAlloc(
194 IN RTMP_ADAPTER *pAd,
198 /* Add 2 more bytes for ip header alignment*/
199 skb = dev_alloc_skb(size+2);
201 return ((PNDIS_PACKET)skb);
205 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
206 IN PRTMP_ADAPTER pAd,
211 pkt = dev_alloc_skb(Length);
215 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
220 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
223 return (PNDIS_PACKET) pkt;
227 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
228 IN PRTMP_ADAPTER pAd,
231 OUT PVOID *VirtualAddress)
235 pkt = dev_alloc_skb(Length);
239 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
244 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
245 *VirtualAddress = (PVOID) pkt->data;
249 *VirtualAddress = (PVOID) NULL;
252 return (PNDIS_PACKET) pkt;
256 VOID build_tx_packet(
257 IN PRTMP_ADAPTER pAd,
258 IN PNDIS_PACKET pPacket,
263 struct sk_buff *pTxPkt;
266 pTxPkt = RTPKT_TO_OSPKT(pPacket);
268 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
271 VOID RTMPFreeAdapter(
272 IN PRTMP_ADAPTER pAd)
274 POS_COOKIE os_cookie;
277 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
280 kfree(pAd->BeaconBuf);
283 NdisFreeSpinLock(&pAd->MgmtRingLock);
286 NdisFreeSpinLock(&pAd->RxRingLock);
288 NdisFreeSpinLock(&pAd->McuCmdLock);
290 #endif // RTMP_MAC_PCI //
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);
302 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
307 BOOLEAN OS_Need_Clone_Packet(void)
315 ========================================================================
318 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
319 must have only one NDIS BUFFER
320 return - byte copied. 0 means can't create NDIS PACKET
321 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
324 pAd Pointer to our adapter
325 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
326 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
334 ========================================================================
336 NDIS_STATUS RTMPCloneNdisPacket(
337 IN PRTMP_ADAPTER pAd,
338 IN BOOLEAN pInsAMSDUHdr,
339 IN PNDIS_PACKET pInPacket,
340 OUT PNDIS_PACKET *ppOutPacket)
348 // 1. Allocate a packet
349 pkt = dev_alloc_skb(2048);
353 return NDIS_STATUS_FAILURE;
356 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
357 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
358 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
361 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
363 printk("###Clone###\n");
365 return NDIS_STATUS_SUCCESS;
369 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
370 NDIS_STATUS RTMPAllocateNdisPacket(
371 IN PRTMP_ADAPTER pAd,
372 OUT PNDIS_PACKET *ppPacket,
378 PNDIS_PACKET pPacket;
382 // 1. Allocate a packet
383 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + RTMP_PKT_TAIL_PADDING);
388 printk("RTMPAllocateNdisPacket Fail\n\n");
390 return NDIS_STATUS_FAILURE;
393 // 2. clone the frame content
395 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
397 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
399 // 3. update length of packet
400 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
402 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
403 // printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
405 return NDIS_STATUS_SUCCESS;
409 ========================================================================
411 This routine frees a miniport internally allocated NDIS_PACKET and its
412 corresponding NDIS_BUFFER and allocated memory.
413 ========================================================================
415 VOID RTMPFreeNdisPacket(
416 IN PRTMP_ADAPTER pAd,
417 IN PNDIS_PACKET pPacket)
419 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
423 // IRQL = DISPATCH_LEVEL
424 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
425 // scatter gather buffer
426 NDIS_STATUS Sniff2BytesFromNdisBuffer(
427 IN PNDIS_BUFFER pFirstBuffer,
428 IN UCHAR DesiredOffset,
432 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
433 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
435 return NDIS_STATUS_SUCCESS;
439 void RTMP_QueryPacketInfo(
440 IN PNDIS_PACKET pPacket,
441 OUT PACKET_INFO *pPacketInfo,
442 OUT PUCHAR *pSrcBufVA,
443 OUT UINT *pSrcBufLen)
445 pPacketInfo->BufferCount = 1;
446 pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
447 pPacketInfo->PhysicalBufferCount = 1;
448 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
450 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
451 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
454 void RTMP_QueryNextPacketInfo(
455 IN PNDIS_PACKET *ppPacket,
456 OUT PACKET_INFO *pPacketInfo,
457 OUT PUCHAR *pSrcBufVA,
458 OUT UINT *pSrcBufLen)
460 PNDIS_PACKET pPacket = NULL;
463 pPacket = GET_OS_PKT_NEXT(*ppPacket);
467 pPacketInfo->BufferCount = 1;
468 pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
469 pPacketInfo->PhysicalBufferCount = 1;
470 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
472 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
473 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
474 *ppPacket = GET_OS_PKT_NEXT(pPacket);
478 pPacketInfo->BufferCount = 0;
479 pPacketInfo->pFirstBuffer = NULL;
480 pPacketInfo->PhysicalBufferCount = 0;
481 pPacketInfo->TotalPacketLength = 0;
490 PNDIS_PACKET DuplicatePacket(
491 IN PRTMP_ADAPTER pAd,
492 IN PNDIS_PACKET pPacket,
493 IN UCHAR FromWhichBSSID)
496 PNDIS_PACKET pRetPacket = NULL;
500 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
501 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
504 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
507 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
508 pRetPacket = OSPKT_TO_RTPKT(skb);
516 PNDIS_PACKET duplicate_pkt(
517 IN PRTMP_ADAPTER pAd,
518 IN PUCHAR pHeader802_3,
522 IN UCHAR FromWhichBSSID)
525 PNDIS_PACKET pPacket = NULL;
528 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
531 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
532 skb_put(skb, HdrLen);
533 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
534 skb_put(skb, DataSize);
535 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
536 pPacket = OSPKT_TO_RTPKT(skb);
543 #define TKIP_TX_MIC_SIZE 8
544 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
545 IN PRTMP_ADAPTER pAd,
546 IN PNDIS_PACKET pPacket)
548 struct sk_buff *skb, *newskb;
551 skb = RTPKT_TO_OSPKT(pPacket);
552 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
554 // alloc a new skb and copy the packet
555 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
556 dev_kfree_skb_any(skb);
559 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
565 return OSPKT_TO_RTPKT(skb);
573 PNDIS_PACKET ClonePacket(
574 IN PRTMP_ADAPTER pAd,
575 IN PNDIS_PACKET pPacket,
579 struct sk_buff *pRxPkt;
580 struct sk_buff *pClonedPkt;
583 pRxPkt = RTPKT_TO_OSPKT(pPacket);
586 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
590 // set the correct dataptr and data len
591 pClonedPkt->dev = pRxPkt->dev;
592 pClonedPkt->data = pData;
593 pClonedPkt->len = DataSize;
594 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
595 ASSERT(DataSize < 1530);
601 // change OS packet DataPtr and DataLen
603 void update_os_packet_info(
604 IN PRTMP_ADAPTER pAd,
606 IN UCHAR FromWhichBSSID)
608 struct sk_buff *pOSPkt;
610 ASSERT(pRxBlk->pRxPacket);
611 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
613 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
614 pOSPkt->data = pRxBlk->pData;
615 pOSPkt->len = pRxBlk->DataSize;
616 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
620 void wlan_802_11_to_802_3_packet(
621 IN PRTMP_ADAPTER pAd,
623 IN PUCHAR pHeader802_3,
624 IN UCHAR FromWhichBSSID)
626 struct sk_buff *pOSPkt;
628 ASSERT(pRxBlk->pRxPacket);
629 ASSERT(pHeader802_3);
631 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
633 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
634 pOSPkt->data = pRxBlk->pData;
635 pOSPkt->len = pRxBlk->DataSize;
636 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
643 #ifdef CONFIG_STA_SUPPORT
644 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
645 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
646 #endif // CONFIG_STA_SUPPORT //
651 void announce_802_3_packet(
652 IN PRTMP_ADAPTER pAd,
653 IN PNDIS_PACKET pPacket)
656 struct sk_buff *pRxPkt;
657 #ifdef INF_AMAZON_PPA
659 unsigned int ppa_flags = 0; /* reserved for now */
660 #endif // INF_AMAZON_PPA //
664 pRxPkt = RTPKT_TO_OSPKT(pPacket);
666 #ifdef CONFIG_STA_SUPPORT
667 #endif // CONFIG_STA_SUPPORT //
669 /* Push up the protocol stack */
671 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
675 BG_FTPH_PacketFromApHandle(pRxPkt);
677 #endif // BG_FT_SUPPORT //
678 #endif // INF_AMAZON_SE //
679 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
681 #ifdef INF_AMAZON_PPA
682 if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE )
684 memset(pRxPkt->head,0,pRxPkt->data-pRxPkt->head-14);
685 DBGPRINT(RT_DEBUG_TRACE, ("ppa_hook_directpath_send_fn rx :ret:%d headroom:%d dev:%s pktlen:%d<===\n",ret,skb_headroom(pRxPkt)
686 ,pRxPkt->dev->name,pRxPkt->len));
687 hex_dump("rx packet", pRxPkt->data, 32);
688 ret = ppa_hook_directpath_send_fn(pAd->g_if_id, pRxPkt, pRxPkt->len, ppa_flags);
693 #endif // INF_AMAZON_PPA //
695 //#ifdef CONFIG_5VT_ENHANCE
696 // *(int*)(pRxPkt->cb) = BRIDGE_TAG;
703 #endif // IKANOS_VX_1X0 //
707 PRTMP_SCATTER_GATHER_LIST
708 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
710 sg->NumberOfElements = 1;
711 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
712 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
716 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
721 if (RTDebugLevel < RT_DEBUG_TRACE)
725 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
726 for (x=0; x<SrcBufLen; x++)
729 printk("0x%04x : ", x);
730 printk("%02x ", ((unsigned char)pt[x]));
731 if (x%16 == 15) printk("\n");
737 ========================================================================
740 Send log message through wireless event
742 Support standard iw_event with IWEVCUSTOM. It is used below.
744 iwreq_data.data.flags is used to store event_flag that is defined by user.
745 iwreq_data.data.length is the length of the event log.
747 The format of the event log is composed of the entry's MAC address and
748 the desired log message (refer to pWirelessEventText).
750 ex: 11:22:33:44:55:66 has associated successfully
752 p.s. The requirement of Wireless Extension is v15 or newer.
754 ========================================================================
756 VOID RTMPSendWirelessEvent(
757 IN PRTMP_ADAPTER pAd,
758 IN USHORT Event_flag,
763 #if WIRELESS_EXT >= 15
765 //union iwreq_data wrqu;
766 PSTRING pBuf = NULL, pBufPtr = NULL;
767 USHORT event, type, BufLen;
768 UCHAR event_table_len = 0;
770 type = Event_flag & 0xFF00;
771 event = Event_flag & 0x00FF;
775 case IW_SYS_EVENT_FLAG_START:
776 event_table_len = IW_SYS_EVENT_TYPE_NUM;
779 case IW_SPOOF_EVENT_FLAG_START:
780 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
783 case IW_FLOOD_EVENT_FLAG_START:
784 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
788 if (event_table_len == 0)
790 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
794 if (event >= event_table_len)
796 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
800 //Allocate memory and copy the msg.
801 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
803 //Prepare the payload
804 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
809 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
810 else if (BssIdx < MAX_MBSSID_NUM)
811 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
813 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
815 if (type == IW_SYS_EVENT_FLAG_START)
816 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
817 else if (type == IW_SPOOF_EVENT_FLAG_START)
818 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
819 else if (type == IW_FLOOD_EVENT_FLAG_START)
820 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
822 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
824 pBufPtr[pBufPtr - pBuf] = '\0';
825 BufLen = pBufPtr - pBuf;
827 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen);
828 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
833 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
835 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
836 #endif /* WIRELESS_EXT >= 15 */
842 #ifdef CONFIG_STA_SUPPORT
843 void send_monitor_packets(
844 IN PRTMP_ADAPTER pAd,
847 struct sk_buff *pOSPkt;
848 wlan_ng_prism2_header *ph;
850 USHORT header_len = 0;
851 UCHAR temp_header[40] = {0};
853 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
854 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,
855 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};
858 ASSERT(pRxBlk->pRxPacket);
859 if (pRxBlk->DataSize < 10)
861 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
862 goto err_free_sk_buff;
865 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
867 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
868 goto err_free_sk_buff;
871 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
872 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
873 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
875 pRxBlk->DataSize -= LENGTH_802_11;
876 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
877 (pRxBlk->pHeader->FC.FrDs == 1))
878 header_len = LENGTH_802_11_WITH_ADDR4;
880 header_len = LENGTH_802_11;
883 if (pRxBlk->pHeader->FC.SubType & 0x08)
886 // Data skip QOS contorl field
887 pRxBlk->DataSize -=2;
890 // Order bit: A-Ralink or HTC+
891 if (pRxBlk->pHeader->FC.Order)
894 // Data skip HTC contorl field
895 pRxBlk->DataSize -= 4;
899 if (header_len <= 40)
900 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
903 if (pRxBlk->RxD.L2PAD)
904 pRxBlk->pData += (header_len + 2);
906 pRxBlk->pData += header_len;
910 if (pRxBlk->DataSize < pOSPkt->len) {
911 skb_trim(pOSPkt,pRxBlk->DataSize);
913 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
916 if ((pRxBlk->pData - pOSPkt->data) > 0) {
917 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
918 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
921 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
922 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
923 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
924 goto err_free_sk_buff;
929 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
931 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
932 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
934 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
935 ph->msglen = sizeof(wlan_ng_prism2_header);
936 strcpy((PSTRING) ph->devname, (PSTRING) pAd->net_dev->name);
938 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
939 ph->hosttime.status = 0;
940 ph->hosttime.len = 4;
941 ph->hosttime.data = jiffies;
943 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
944 ph->mactime.status = 0;
946 ph->mactime.data = 0;
948 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
953 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
954 ph->channel.status = 0;
957 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
959 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
962 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));;
964 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
965 ph->signal.status = 0;
967 ph->signal.data = 0; //rssi + noise;
969 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
970 ph->noise.status = 0;
974 #ifdef DOT11_N_SUPPORT
975 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
977 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
980 #endif // DOT11_N_SUPPORT //
981 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
982 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
984 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
987 if (rate_index > 255)
990 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
993 ph->rate.data = ralinkrate[rate_index];
995 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
996 ph->frmlen.status = 0;
998 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
1001 pOSPkt->pkt_type = PACKET_OTHERHOST;
1002 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
1003 pOSPkt->ip_summed = CHECKSUM_NONE;
1009 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1013 #endif // CONFIG_STA_SUPPORT //
1017 /*******************************************************************************
1019 File open/close related functions.
1021 *******************************************************************************/
1022 RTMP_OS_FD RtmpOSFileOpen(char *pPath, int flag, int mode)
1024 struct file *filePtr;
1026 filePtr = filp_open(pPath, flag, 0);
1027 if (IS_ERR(filePtr))
1029 DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(filePtr), pPath));
1032 return (RTMP_OS_FD)filePtr;
1035 int RtmpOSFileClose(RTMP_OS_FD osfd)
1037 filp_close(osfd, NULL);
1042 void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset)
1044 osfd->f_pos = offset;
1048 int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
1050 // The object must have a read method
1051 if (osfd->f_op && osfd->f_op->read)
1053 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
1057 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
1063 int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen)
1065 return osfd->f_op->write(osfd, pDataPtr, (size_t)writeLen, &osfd->f_pos);
1069 void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfo, BOOLEAN bSet)
1073 // Save uid and gid used for filesystem access.
1074 // Set user and group to 0 (root)
1075 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
1076 pOSFSInfo->fsuid= current->fsuid;
1077 pOSFSInfo->fsgid = current->fsgid;
1078 current->fsuid = current->fsgid = 0;
1080 pOSFSInfo->fsuid = current_fsuid();
1081 pOSFSInfo->fsgid = current_fsgid();
1083 pOSFSInfo->fs = get_fs();
1088 set_fs(pOSFSInfo->fs);
1089 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
1090 current->fsuid = pOSFSInfo->fsuid;
1091 current->fsgid = pOSFSInfo->fsgid;
1098 /*******************************************************************************
1100 Task create/management/kill related functions.
1102 *******************************************************************************/
1103 NDIS_STATUS RtmpOSTaskKill(
1104 IN RTMP_OS_TASK *pTask)
1107 int ret = NDIS_STATUS_FAILURE;
1109 pAd = (RTMP_ADAPTER *)pTask->priv;
1111 #ifdef KTHREAD_SUPPORT
1112 if (pTask->kthread_task)
1114 kthread_stop(pTask->kthread_task);
1115 ret = NDIS_STATUS_SUCCESS;
1118 CHECK_PID_LEGALITY(pTask->taskPID)
1120 printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1122 pTask->task_killed = 1;
1124 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1127 printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1128 pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret);
1132 wait_for_completion(&pTask->taskComplete);
1133 pTask->taskPID = THREAD_PID_INIT_VALUE;
1134 pTask->task_killed = 0;
1135 ret = NDIS_STATUS_SUCCESS;
1145 INT RtmpOSTaskNotifyToExit(
1146 IN RTMP_OS_TASK *pTask)
1149 #ifndef KTHREAD_SUPPORT
1150 complete_and_exit(&pTask->taskComplete, 0);
1157 void RtmpOSTaskCustomize(
1158 IN RTMP_OS_TASK *pTask)
1161 #ifndef KTHREAD_SUPPORT
1163 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1164 daemonize((PSTRING)&pTask->taskName[0]/*"%s",pAd->net_dev->name*/);
1166 allow_signal(SIGTERM);
1167 allow_signal(SIGKILL);
1168 current->flags |= PF_NOFREEZE;
1170 unsigned long flags;
1174 strcpy(current->comm, &pTask->taskName[0]);
1176 siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1178 /* Allow interception of SIGKILL only
1179 * Don't allow other signals to interrupt the transmission */
1180 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1181 spin_lock_irqsave(¤t->sigmask_lock, flags);
1182 flush_signals(current);
1183 recalc_sigpending(current);
1184 spin_unlock_irqrestore(¤t->sigmask_lock, flags);
1188 /* signal that we've started the thread */
1189 complete(&pTask->taskComplete);
1195 NDIS_STATUS RtmpOSTaskAttach(
1196 IN RTMP_OS_TASK *pTask,
1197 IN int (*fn)(void *),
1200 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
1201 pid_t pid_number = -1;
1203 #ifdef KTHREAD_SUPPORT
1204 pTask->task_killed = 0;
1205 pTask->kthread_task = NULL;
1206 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1207 if (IS_ERR(pTask->kthread_task))
1208 status = NDIS_STATUS_FAILURE;
1210 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1213 DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName));
1214 status = NDIS_STATUS_FAILURE;
1218 pTask->taskPID = GET_PID(pid_number);
1220 // Wait for the thread to start
1221 wait_for_completion(&pTask->taskComplete);
1222 status = NDIS_STATUS_SUCCESS;
1229 NDIS_STATUS RtmpOSTaskInit(
1230 IN RTMP_OS_TASK *pTask,
1231 IN PSTRING pTaskName,
1238 #ifndef KTHREAD_SUPPORT
1239 NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK));
1242 len = strlen(pTaskName);
1243 len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len;
1244 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1245 pTask->priv = pPriv;
1247 #ifndef KTHREAD_SUPPORT
1248 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1249 pTask->taskPID = THREAD_PID_INIT_VALUE;
1251 init_completion (&pTask->taskComplete);
1254 return NDIS_STATUS_SUCCESS;
1258 void RTMP_IndicateMediaState(
1259 IN PRTMP_ADAPTER pAd)
1261 if (pAd->CommonCfg.bWirelessEvent)
1263 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1265 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1269 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1275 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1276 //static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
1277 struct net_device *alloc_netdev(
1280 void (*setup)(struct net_device *))
1282 struct net_device *dev;
1286 /* ensure 32-byte alignment of the private area */
1287 alloc_size = sizeof (*dev) + sizeof_priv + 31;
1289 dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
1292 DBGPRINT(RT_DEBUG_ERROR,
1293 ("alloc_netdev: Unable to allocate device memory.\n"));
1297 memset(dev, 0, alloc_size);
1300 dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
1303 strcpy(dev->name, mask);
1307 #endif // LINUX_VERSION_CODE //
1310 int RtmpOSWrielessEventSend(
1311 IN RTMP_ADAPTER *pAd,
1312 IN UINT32 eventType,
1318 union iwreq_data wrqu;
1320 memset(&wrqu, 0, sizeof(wrqu));
1323 wrqu.data.flags = flags;
1326 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1328 if ((pData!= NULL) && (dataLen > 0))
1329 wrqu.data.length = dataLen;
1331 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1336 int RtmpOSNetDevAddrSet(
1337 IN PNET_DEV pNetDev,
1340 struct net_device *net_dev;
1344 //pAd = (RTMP_ADAPTER *)net_dev->priv;
1345 pAd=RTMP_OS_NETDEV_GET_PRIV(pNetDev);
1347 #ifdef CONFIG_STA_SUPPORT
1348 // work-around for the SuSE due to it has it's own interface name management system.
1349 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1351 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1352 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
1354 #endif // CONFIG_STA_SUPPORT //
1356 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1364 * Assign the network dev name for created Ralink WiFi interface.
1366 static int RtmpOSNetDevRequestName(
1367 IN RTMP_ADAPTER *pAd,
1369 IN PSTRING pPrefixStr,
1372 PNET_DEV existNetDev;
1373 STRING suffixName[IFNAMSIZ];
1374 STRING desiredName[IFNAMSIZ];
1375 int ifNameIdx, prefixLen, slotNameLen;
1379 prefixLen = strlen(pPrefixStr);
1380 ASSERT((prefixLen < IFNAMSIZ));
1382 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++)
1384 memset(suffixName, 0, IFNAMSIZ);
1385 memset(desiredName, 0, IFNAMSIZ);
1386 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1388 #ifdef MULTIPLE_CARD_SUPPORT
1389 if (pAd->MC_RowID >= 0)
1390 sprintf(suffixName, "%02d_%d", pAd->MC_RowID, ifNameIdx);
1392 #endif // MULTIPLE_CARD_SUPPORT //
1393 sprintf(suffixName, "%d", ifNameIdx);
1395 slotNameLen = strlen(suffixName);
1396 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1397 strcat(desiredName, suffixName);
1399 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1400 if (existNetDev == NULL)
1403 RtmpOSNetDeviceRefPut(existNetDev);
1408 strcpy(&dev->name[0], &desiredName[0]);
1409 Status = NDIS_STATUS_SUCCESS;
1413 DBGPRINT(RT_DEBUG_ERROR,
1414 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr));
1415 Status = NDIS_STATUS_FAILURE;
1422 void RtmpOSNetDevClose(
1423 IN PNET_DEV pNetDev)
1429 void RtmpOSNetDevFree(PNET_DEV pNetDev)
1433 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1434 free_netdev(pNetDev);
1441 INT RtmpOSNetDevAlloc(
1442 IN PNET_DEV *new_dev_p,
1443 IN UINT32 privDataSize)
1445 // assign it as null first.
1448 DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize));
1449 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1450 *new_dev_p = alloc_netdev(privDataSize, "eth%d", ether_setup);
1452 *new_dev_p = alloc_etherdev(privDataSize);
1453 #endif // LINUX_VERSION_CODE //
1456 return NDIS_STATUS_SUCCESS;
1458 return NDIS_STATUS_FAILURE;
1462 PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName)
1464 PNET_DEV pTargetNetDev = NULL;
1467 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1469 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1470 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
1471 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1474 pTargetNetDev = dev_get_by_name(pNetDev->nd_net, pDevName);
1477 pTargetNetDev = dev_get_by_name(pDevName);
1478 #endif // KERNEL_VERSION(2,6,24) //
1483 devNameLen = strlen(pDevName);
1484 ASSERT((devNameLen <= IFNAMSIZ));
1486 for(pTargetNetDev=dev_base; pTargetNetDev!=NULL; pTargetNetDev=pTargetNetDev->next)
1488 if (strncmp(pTargetNetDev->name, pDevName, devNameLen) == 0)
1491 #endif // KERNEL_VERSION(2,5,0) //
1493 return pTargetNetDev;
1497 void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev)
1499 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1501 every time dev_get_by_name is called, and it has returned a valid struct
1502 net_device*, dev_put should be called afterwards, because otherwise the
1503 machine hangs when the device is unregistered (since dev->refcnt > 1).
1507 #endif // LINUX_VERSION_CODE //
1511 INT RtmpOSNetDevDestory(
1512 IN RTMP_ADAPTER *pAd,
1513 IN PNET_DEV pNetDev)
1516 // TODO: Need to fix this
1517 printk("WARNING: This function(%s) not implement yet!!!\n", __FUNCTION__);
1522 void RtmpOSNetDevDetach(PNET_DEV pNetDev)
1524 unregister_netdev(pNetDev);
1528 int RtmpOSNetDevAttach(
1529 IN PNET_DEV pNetDev,
1530 IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook)
1532 int ret, rtnl_locked = FALSE;
1534 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1535 // If we need hook some callback function to the net device structrue, now do it.
1538 PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(pNetDev);
1540 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1542 /* OS specific flags, here we used to indicate if we are virtual interface */
1543 pNetDev->priv_flags = pDevOpHook->priv_flags;
1545 #if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12)
1546 pNetDev->get_wireless_stats = rt28xx_get_wireless_stats;
1549 #ifdef CONFIG_STA_SUPPORT
1550 #if WIRELESS_EXT >= 12
1551 if (pAd->OpMode == OPMODE_STA)
1553 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1555 #endif //WIRELESS_EXT >= 12
1556 #endif // CONFIG_STA_SUPPORT //
1558 #ifdef CONFIG_APSTA_MIXED_SUPPORT
1559 #if WIRELESS_EXT >= 12
1560 if (pAd->OpMode == OPMODE_AP)
1562 pNetDev->wireless_handlers = &rt28xx_ap_iw_handler_def;
1564 #endif //WIRELESS_EXT >= 12
1565 #endif // CONFIG_APSTA_MIXED_SUPPORT //
1567 // copy the net device mac address to the net_device structure.
1568 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
1570 rtnl_locked = pDevOpHook->needProtcted;
1574 ret = register_netdevice(pNetDev);
1576 ret = register_netdev(pNetDev);
1578 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1580 return NDIS_STATUS_SUCCESS;
1582 return NDIS_STATUS_FAILURE;
1586 PNET_DEV RtmpOSNetDevCreate(
1587 IN RTMP_ADAPTER *pAd,
1591 IN PSTRING pNamePrefix)
1593 struct net_device *pNetDev = NULL;
1597 /* allocate a new network device */
1598 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/);
1599 if (status != NDIS_STATUS_SUCCESS)
1601 /* allocation fail, exit */
1602 DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix));
1607 /* find a available interface name, max 32 interfaces */
1608 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1609 if (status != NDIS_STATUS_SUCCESS)
1611 /* error! no any available ra name can be used! */
1612 DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix));
1613 RtmpOSNetDevFree(pNetDev);
1619 DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name));