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, OUT BOOLEAN *pCancelled)
123 if (timer_pending(pTimer)) {
124 *pCancelled = del_timer_sync(pTimer);
131 void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
133 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
136 /* Unify all delay routine by using udelay */
137 void RTMPusecDelay(unsigned long usec)
141 for (i = 0; i < (usec / 50); i++)
148 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
150 time->u.LowPart = jiffies;
153 /* pAd MUST allow to be NULL */
154 int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
156 *mem = kmalloc(size, GFP_ATOMIC);
158 return NDIS_STATUS_SUCCESS;
160 return NDIS_STATUS_FAILURE;
163 /* pAd MUST allow to be NULL */
164 int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
169 return NDIS_STATUS_SUCCESS;
172 void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
175 /* Add 2 more bytes for ip header alignment */
176 skb = dev_alloc_skb(size + 2);
181 void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
182 unsigned long Length)
186 pkt = dev_alloc_skb(Length);
189 DBGPRINT(RT_DEBUG_ERROR,
190 ("can't allocate frag rx %ld size packet\n", Length));
194 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
200 void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
201 unsigned long Length,
203 void **VirtualAddress)
207 pkt = dev_alloc_skb(Length);
210 DBGPRINT(RT_DEBUG_ERROR,
211 ("can't allocate tx %ld size packet\n", Length));
215 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
216 *VirtualAddress = (void *)pkt->data;
218 *VirtualAddress = (void *)NULL;
224 void build_tx_packet(struct rt_rtmp_adapter *pAd,
226 u8 *pFrame, unsigned long FrameLen)
229 struct sk_buff *pTxPkt;
232 pTxPkt = RTPKT_TO_OSPKT(pPacket);
234 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
237 void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
239 struct os_cookie *os_cookie;
242 os_cookie = (struct os_cookie *)pAd->OS_Cookie;
244 kfree(pAd->BeaconBuf);
246 NdisFreeSpinLock(&pAd->MgmtRingLock);
249 NdisFreeSpinLock(&pAd->RxRingLock);
251 NdisFreeSpinLock(&pAd->McuCmdLock);
252 #endif /* RT3090 // */
253 #endif /* RTMP_MAC_PCI // */
255 for (index = 0; index < NUM_OF_TX_RING; index++) {
256 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
257 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
258 pAd->DeQueueRunning[index] = FALSE;
261 NdisFreeSpinLock(&pAd->irq_lock);
263 release_firmware(pAd->firmware);
265 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
269 BOOLEAN OS_Need_Clone_Packet(void)
275 ========================================================================
278 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
279 must have only one NDIS BUFFER
280 return - byte copied. 0 means can't create NDIS PACKET
281 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
284 pAd Pointer to our adapter
285 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
286 *pSrcTotalLen return total packet length. This length is calculated with 802.3 format packet.
294 ========================================================================
296 int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
297 IN BOOLEAN pInsAMSDUHdr,
307 /* 1. Allocate a packet */
308 pkt = dev_alloc_skb(2048);
311 return NDIS_STATUS_FAILURE;
314 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
315 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
316 GET_OS_PKT_LEN(pInPacket));
317 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
319 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
321 printk(KERN_DEBUG "###Clone###\n");
323 return NDIS_STATUS_SUCCESS;
326 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
327 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
331 u8 *pData, u32 DataLen)
337 /* 1. Allocate a packet */
339 (void **) dev_alloc_skb(HeaderLen + DataLen +
340 RTMP_PKT_TAIL_PADDING);
341 if (pPacket == NULL) {
343 pr_devel("RTMPAllocateNdisPacket Fail\n");
345 return NDIS_STATUS_FAILURE;
347 /* 2. clone the frame content */
349 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
351 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
354 /* 3. update length of packet */
355 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
357 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
358 /* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
360 return NDIS_STATUS_SUCCESS;
364 ========================================================================
366 This routine frees a miniport internally allocated char and its
367 corresponding NDIS_BUFFER and allocated memory.
368 ========================================================================
370 void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
372 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
375 /* IRQL = DISPATCH_LEVEL */
376 /* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
377 /* scatter gather buffer */
378 int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
380 u8 *pByte0, u8 *pByte1)
382 *pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
383 *pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
385 return NDIS_STATUS_SUCCESS;
388 void RTMP_QueryPacketInfo(void *pPacket,
389 struct rt_packet_info *pPacketInfo,
390 u8 **pSrcBufVA, u32 * pSrcBufLen)
392 pPacketInfo->BufferCount = 1;
393 pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
394 pPacketInfo->PhysicalBufferCount = 1;
395 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
397 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
398 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
401 void RTMP_QueryNextPacketInfo(void **ppPacket,
402 struct rt_packet_info *pPacketInfo,
403 u8 **pSrcBufVA, u32 * pSrcBufLen)
405 void *pPacket = NULL;
408 pPacket = GET_OS_PKT_NEXT(*ppPacket);
411 pPacketInfo->BufferCount = 1;
412 pPacketInfo->pFirstBuffer =
413 (char *)GET_OS_PKT_DATAPTR(pPacket);
414 pPacketInfo->PhysicalBufferCount = 1;
415 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
417 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
418 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
419 *ppPacket = GET_OS_PKT_NEXT(pPacket);
421 pPacketInfo->BufferCount = 0;
422 pPacketInfo->pFirstBuffer = NULL;
423 pPacketInfo->PhysicalBufferCount = 0;
424 pPacketInfo->TotalPacketLength = 0;
432 void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
433 void *pPacket, u8 FromWhichBSSID)
436 void *pRetPacket = NULL;
440 DataSize = (u16)GET_OS_PKT_LEN(pPacket);
441 pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
443 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
445 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
446 pRetPacket = OSPKT_TO_RTPKT(skb);
453 void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
457 unsigned long DataSize, u8 FromWhichBSSID)
460 void *pPacket = NULL;
462 skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG);
465 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
466 skb_put(skb, HdrLen);
467 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
468 skb_put(skb, DataSize);
469 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
470 pPacket = OSPKT_TO_RTPKT(skb);
476 #define TKIP_TX_MIC_SIZE 8
477 void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
480 struct sk_buff *skb, *newskb;
482 skb = RTPKT_TO_OSPKT(pPacket);
483 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
484 /* alloc a new skb and copy the packet */
486 skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
488 dev_kfree_skb_any(skb);
489 if (newskb == NULL) {
490 DBGPRINT(RT_DEBUG_ERROR,
491 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
497 return OSPKT_TO_RTPKT(skb);
500 void *ClonePacket(struct rt_rtmp_adapter *pAd,
502 u8 *pData, unsigned long DataSize)
504 struct sk_buff *pRxPkt;
505 struct sk_buff *pClonedPkt;
508 pRxPkt = RTPKT_TO_OSPKT(pPacket);
510 /* clone the packet */
511 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
514 /* set the correct dataptr and data len */
515 pClonedPkt->dev = pRxPkt->dev;
516 pClonedPkt->data = pData;
517 pClonedPkt->len = DataSize;
518 skb_set_tail_pointer(pClonedPkt, DataSize)
519 ASSERT(DataSize < 1530);
525 /* change OS packet DataPtr and DataLen */
527 void update_os_packet_info(struct rt_rtmp_adapter *pAd,
528 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
530 struct sk_buff *pOSPkt;
532 ASSERT(pRxBlk->pRxPacket);
533 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
535 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
536 pOSPkt->data = pRxBlk->pData;
537 pOSPkt->len = pRxBlk->DataSize;
538 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
541 void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
542 struct rt_rx_blk *pRxBlk,
546 struct sk_buff *pOSPkt;
548 ASSERT(pRxBlk->pRxPacket);
549 ASSERT(pHeader802_3);
551 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
553 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
554 pOSPkt->data = pRxBlk->pData;
555 pOSPkt->len = pRxBlk->DataSize;
556 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
559 /* copy 802.3 header */
563 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
567 void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
570 struct sk_buff *pRxPkt;
574 pRxPkt = RTPKT_TO_OSPKT(pPacket);
576 /* Push up the protocol stack */
577 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
582 struct rt_rtmp_sg_list *
583 rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
585 sg->NumberOfElements = 1;
586 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
587 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
591 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
596 if (RTDebugLevel < RT_DEBUG_TRACE)
600 printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
601 for (x = 0; x < SrcBufLen; x++) {
603 printk(KERN_DEBUG "0x%04x : ", x);
604 printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x]));
606 printk(KERN_DEBUG "\n");
608 printk(KERN_DEBUG "\n");
612 ========================================================================
615 Send log message through wireless event
617 Support standard iw_event with IWEVCUSTOM. It is used below.
619 iwreq_data.data.flags is used to store event_flag that is defined by user.
620 iwreq_data.data.length is the length of the event log.
622 The format of the event log is composed of the entry's MAC address and
623 the desired log message (refer to pWirelessEventText).
625 ex: 11:22:33:44:55:66 has associated successfully
627 p.s. The requirement of Wireless Extension is v15 or newer.
629 ========================================================================
631 void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
633 u8 *pAddr, u8 BssIdx, char Rssi)
636 /*union iwreq_data wrqu; */
637 char *pBuf = NULL, *pBufPtr = NULL;
638 u16 event, type, BufLen;
639 u8 event_table_len = 0;
641 type = Event_flag & 0xFF00;
642 event = Event_flag & 0x00FF;
645 case IW_SYS_EVENT_FLAG_START:
646 event_table_len = IW_SYS_EVENT_TYPE_NUM;
649 case IW_SPOOF_EVENT_FLAG_START:
650 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
653 case IW_FLOOD_EVENT_FLAG_START:
654 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
658 if (event_table_len == 0) {
659 DBGPRINT(RT_DEBUG_ERROR,
660 ("%s : The type(%0x02x) is not valid.\n", __func__,
665 if (event >= event_table_len) {
666 DBGPRINT(RT_DEBUG_ERROR,
667 ("%s : The event(%0x02x) is not valid.\n", __func__,
671 /*Allocate memory and copy the msg. */
672 pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC);
674 /*Prepare the payload */
675 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
681 sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr);
682 else if (BssIdx < MAX_MBSSID_NUM)
684 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
686 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
688 if (type == IW_SYS_EVENT_FLAG_START)
690 sprintf(pBufPtr, "%s",
691 pWirelessSysEventText[event]);
692 else if (type == IW_SPOOF_EVENT_FLAG_START)
694 sprintf(pBufPtr, "%s (RSSI=%d)",
695 pWirelessSpoofEventText[event], Rssi);
696 else if (type == IW_FLOOD_EVENT_FLAG_START)
698 sprintf(pBufPtr, "%s",
699 pWirelessFloodEventText[event]);
701 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
703 pBufPtr[pBufPtr - pBuf] = '\0';
704 BufLen = pBufPtr - pBuf;
706 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
708 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
712 DBGPRINT(RT_DEBUG_ERROR,
713 ("%s : Can't allocate memory for wireless event.\n",
717 void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
719 struct sk_buff *pOSPkt;
720 struct rt_wlan_ng_prism2_header *ph;
723 u8 temp_header[40] = { 0 };
725 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 */
726 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
727 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
728 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
729 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
730 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
731 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
732 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
733 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
734 72, 73, 74, 75, 76, 77, 78, 79, 80
737 ASSERT(pRxBlk->pRxPacket);
738 if (pRxBlk->DataSize < 10) {
739 DBGPRINT(RT_DEBUG_ERROR,
740 ("%s : Size is too small! (%d)\n", __func__,
742 goto err_free_sk_buff;
745 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
746 RX_BUFFER_AGGRESIZE) {
747 DBGPRINT(RT_DEBUG_ERROR,
748 ("%s : Size is too large! (%zu)\n", __func__,
749 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
750 goto err_free_sk_buff;
753 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
754 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
755 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
756 pRxBlk->DataSize -= LENGTH_802_11;
757 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
758 (pRxBlk->pHeader->FC.FrDs == 1))
759 header_len = LENGTH_802_11_WITH_ADDR4;
761 header_len = LENGTH_802_11;
764 if (pRxBlk->pHeader->FC.SubType & 0x08) {
766 /* Data skip QOS control field */
767 pRxBlk->DataSize -= 2;
769 /* Order bit: A-Ralink or HTC+ */
770 if (pRxBlk->pHeader->FC.Order) {
772 /* Data skip HTC control field */
773 pRxBlk->DataSize -= 4;
776 if (header_len <= 40)
777 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
779 /* skip HW padding */
780 if (pRxBlk->RxD.L2PAD)
781 pRxBlk->pData += (header_len + 2);
783 pRxBlk->pData += header_len;
786 if (pRxBlk->DataSize < pOSPkt->len) {
787 skb_trim(pOSPkt, pRxBlk->DataSize);
789 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
792 if ((pRxBlk->pData - pOSPkt->data) > 0) {
793 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
794 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
797 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
799 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
801 DBGPRINT(RT_DEBUG_ERROR,
802 ("%s : Reallocate header size of sk_buff fail!\n",
804 goto err_free_sk_buff;
809 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
812 ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
813 sizeof(struct rt_wlan_ng_prism2_header));
814 NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
816 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
817 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
818 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
820 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
821 ph->hosttime.status = 0;
822 ph->hosttime.len = 4;
823 ph->hosttime.data = jiffies;
825 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
826 ph->mactime.status = 0;
828 ph->mactime.data = 0;
830 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
835 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
836 ph->channel.status = 0;
839 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
841 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
845 (u_int32_t) RTMPMaxRssi(pAd,
846 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
847 RSSI_0), ConvertToRssi(pAd,
852 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
855 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
856 ph->signal.status = 0;
858 ph->signal.data = 0; /*rssi + noise; */
860 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
861 ph->noise.status = 0;
865 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
867 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
868 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
869 ((u8)pRxBlk->pRxWI->MCS);
870 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
871 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
873 rate_index = (u8)(pRxBlk->pRxWI->MCS);
876 if (rate_index > 255)
879 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
882 ph->rate.data = ralinkrate[rate_index];
884 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
885 ph->frmlen.status = 0;
887 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
889 pOSPkt->pkt_type = PACKET_OTHERHOST;
890 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
891 pOSPkt->ip_summed = CHECKSUM_NONE;
897 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
902 /*******************************************************************************
904 Device IRQ related functions.
906 *******************************************************************************/
907 int RtmpOSIRQRequest(struct net_device *pNetDev)
909 #ifdef RTMP_PCI_SUPPORT
910 struct net_device *net_dev = pNetDev;
911 struct rt_rtmp_adapter *pAd = NULL;
914 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
918 if (pAd->infType == RTMP_DEV_INF_PCI) {
919 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
920 RTMP_MSI_ENABLE(pAd);
922 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
923 (net_dev)->name, (net_dev));
925 printk(KERN_ERR "rt2860: request_irq ERROR(%d)\n", retval);
934 int RtmpOSIRQRelease(struct net_device *pNetDev)
936 struct net_device *net_dev = pNetDev;
937 struct rt_rtmp_adapter *pAd = NULL;
939 GET_PAD_FROM_NET_DEV(pAd, net_dev);
943 #ifdef RTMP_PCI_SUPPORT
944 if (pAd->infType == RTMP_DEV_INF_PCI) {
945 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
946 synchronize_irq(pObj->pci_dev->irq);
947 free_irq(pObj->pci_dev->irq, (net_dev));
948 RTMP_MSI_DISABLE(pAd);
950 #endif /* RTMP_PCI_SUPPORT // */
955 /*******************************************************************************
957 File open/close related functions.
959 *******************************************************************************/
960 struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
962 struct file *filePtr;
964 filePtr = filp_open(pPath, flag, 0);
965 if (IS_ERR(filePtr)) {
966 DBGPRINT(RT_DEBUG_ERROR,
967 ("%s(): Error %ld opening %s\n", __func__,
968 -PTR_ERR(filePtr), pPath));
971 return (struct file *)filePtr;
974 int RtmpOSFileClose(struct file *osfd)
976 filp_close(osfd, NULL);
980 void RtmpOSFileSeek(struct file *osfd, int offset)
982 osfd->f_pos = offset;
985 int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
987 /* The object must have a read method */
988 if (osfd->f_op && osfd->f_op->read) {
989 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
991 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
996 int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
998 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
1002 /*******************************************************************************
1004 Task create/management/kill related functions.
1006 *******************************************************************************/
1007 int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
1009 struct rt_rtmp_adapter *pAd;
1010 int ret = NDIS_STATUS_FAILURE;
1014 #ifdef KTHREAD_SUPPORT
1015 if (pTask->kthread_task) {
1016 kthread_stop(pTask->kthread_task);
1017 ret = NDIS_STATUS_SUCCESS;
1020 CHECK_PID_LEGALITY(pTask->taskPID) {
1021 printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n",
1022 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1024 pTask->task_killed = 1;
1026 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1029 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1030 pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
1033 wait_for_completion(&pTask->taskComplete);
1034 pTask->taskPID = THREAD_PID_INIT_VALUE;
1035 pTask->task_killed = 0;
1036 ret = NDIS_STATUS_SUCCESS;
1045 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
1048 #ifndef KTHREAD_SUPPORT
1049 complete_and_exit(&pTask->taskComplete, 0);
1055 void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
1058 #ifndef KTHREAD_SUPPORT
1060 daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */);
1062 allow_signal(SIGTERM);
1063 allow_signal(SIGKILL);
1064 current->flags |= PF_NOFREEZE;
1066 /* signal that we've started the thread */
1067 complete(&pTask->taskComplete);
1072 int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
1073 IN int (*fn) (void *), IN void *arg)
1075 int status = NDIS_STATUS_SUCCESS;
1077 #ifdef KTHREAD_SUPPORT
1078 pTask->task_killed = 0;
1079 pTask->kthread_task = NULL;
1080 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1081 if (IS_ERR(pTask->kthread_task))
1082 status = NDIS_STATUS_FAILURE;
1084 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1085 if (pid_number < 0) {
1086 DBGPRINT(RT_DEBUG_ERROR,
1087 ("Attach task(%s) failed!\n", pTask->taskName));
1088 status = NDIS_STATUS_FAILURE;
1090 pTask->taskPID = GET_PID(pid_number);
1092 /* Wait for the thread to start */
1093 wait_for_completion(&pTask->taskComplete);
1094 status = NDIS_STATUS_SUCCESS;
1100 int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
1101 char *pTaskName, void * pPriv)
1107 #ifndef KTHREAD_SUPPORT
1108 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
1111 len = strlen(pTaskName);
1114 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
1115 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1116 pTask->priv = pPriv;
1118 #ifndef KTHREAD_SUPPORT
1119 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1120 pTask->taskPID = THREAD_PID_INIT_VALUE;
1122 init_completion(&pTask->taskComplete);
1125 return NDIS_STATUS_SUCCESS;
1128 void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
1130 if (pAd->CommonCfg.bWirelessEvent) {
1131 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1132 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1133 pAd->MacTab.Content[BSSID_WCID].
1136 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1137 pAd->MacTab.Content[BSSID_WCID].
1143 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
1147 u8 *pData, u32 dataLen)
1149 union iwreq_data wrqu;
1151 memset(&wrqu, 0, sizeof(wrqu));
1154 wrqu.data.flags = flags;
1157 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1159 if ((pData != NULL) && (dataLen > 0))
1160 wrqu.data.length = dataLen;
1162 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1166 int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
1168 struct net_device *net_dev;
1169 struct rt_rtmp_adapter *pAd;
1172 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1174 /* work-around for SuSE, due to them having their own interface name management system. */
1176 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1177 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1178 strlen(net_dev->name));
1181 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1187 * Assign the network dev name for created Ralink WiFi interface.
1189 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
1190 struct net_device *dev,
1191 char *pPrefixStr, int devIdx)
1193 struct net_device *existNetDev;
1194 char suffixName[IFNAMSIZ];
1195 char desiredName[IFNAMSIZ];
1196 int ifNameIdx, prefixLen, slotNameLen;
1199 prefixLen = strlen(pPrefixStr);
1200 ASSERT((prefixLen < IFNAMSIZ));
1202 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
1203 memset(suffixName, 0, IFNAMSIZ);
1204 memset(desiredName, 0, IFNAMSIZ);
1205 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1207 sprintf(suffixName, "%d", ifNameIdx);
1209 slotNameLen = strlen(suffixName);
1210 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1211 strcat(desiredName, suffixName);
1213 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1214 if (existNetDev == NULL)
1217 RtmpOSNetDeviceRefPut(existNetDev);
1220 if (ifNameIdx < 32) {
1221 strcpy(&dev->name[0], &desiredName[0]);
1222 Status = NDIS_STATUS_SUCCESS;
1224 DBGPRINT(RT_DEBUG_ERROR,
1225 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1227 Status = NDIS_STATUS_FAILURE;
1233 void RtmpOSNetDevClose(struct net_device *pNetDev)
1238 void RtmpOSNetDevFree(struct net_device *pNetDev)
1242 free_netdev(pNetDev);
1245 int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize)
1247 /* assign it as null first. */
1250 DBGPRINT(RT_DEBUG_TRACE,
1251 ("Allocate a net device with private data size=%d!\n",
1253 *new_dev_p = alloc_etherdev(privDataSize);
1255 return NDIS_STATUS_SUCCESS;
1257 return NDIS_STATUS_FAILURE;
1260 struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
1262 struct net_device *pTargetNetDev = NULL;
1264 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1266 return pTargetNetDev;
1269 void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
1272 every time dev_get_by_name is called, and it has returned a valid struct
1273 net_device*, dev_put should be called afterwards, because otherwise the
1274 machine hangs when the device is unregistered (since dev->refcnt > 1).
1280 int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
1283 /* TODO: Need to fix this */
1284 printk("WARNING: This function(%s) not implement yet!\n", __func__);
1288 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1290 unregister_netdev(pNetDev);
1293 int RtmpOSNetDevAttach(struct net_device *pNetDev,
1294 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
1296 int ret, rtnl_locked = FALSE;
1298 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1299 /* If we need hook some callback function to the net device structure, now do it. */
1301 struct rt_rtmp_adapter *pAd = NULL;
1303 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1305 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1307 /* OS specific flags, here we used to indicate if we are virtual interface */
1308 pNetDev->priv_flags = pDevOpHook->priv_flags;
1310 if (pAd->OpMode == OPMODE_STA)
1311 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1313 /* copy the net device mac address to the net_device structure. */
1314 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1317 rtnl_locked = pDevOpHook->needProtcted;
1321 ret = register_netdevice(pNetDev);
1323 ret = register_netdev(pNetDev);
1325 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1327 return NDIS_STATUS_SUCCESS;
1329 return NDIS_STATUS_FAILURE;
1332 struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
1335 int privMemSize, char *pNamePrefix)
1337 struct net_device *pNetDev = NULL;
1340 /* allocate a new network device */
1341 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */);
1342 if (status != NDIS_STATUS_SUCCESS) {
1343 /* allocation fail, exit */
1344 DBGPRINT(RT_DEBUG_ERROR,
1345 ("Allocate network device fail (%s)...\n",
1350 /* find an available interface name, max 32 interfaces */
1351 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1352 if (status != NDIS_STATUS_SUCCESS) {
1353 /* error! no available ra name can be used! */
1354 DBGPRINT(RT_DEBUG_ERROR,
1355 ("Assign interface name (%s with suffix 0~32) failed...\n",
1357 RtmpOSNetDevFree(pNetDev);
1361 DBGPRINT(RT_DEBUG_TRACE,
1362 ("The name of the new %s interface is %s...\n",
1363 pNamePrefix, pNetDev->name));