2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
28 #include <linux/firmware.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include "rt_config.h"
33 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
35 /* for wireless system event message */
36 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
37 /* system status event */
38 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
39 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
40 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
41 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
42 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
43 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
44 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
45 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
46 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
47 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
48 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
49 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
50 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
51 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
52 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
53 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
54 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
55 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
56 "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
59 /* for wireless IDS_spoof_attack event message */
60 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
61 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
62 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
63 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
64 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
65 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
66 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
67 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
68 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
69 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
70 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
73 /* for wireless IDS_flooding_attack event message */
74 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
75 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
76 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
77 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
78 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
79 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
80 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
81 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
85 void RTMP_SetPeriodicTimer(struct timer_list *pTimer,
86 IN unsigned long timeout)
88 timeout = ((timeout * OS_HZ) / 1000);
89 pTimer->expires = jiffies + timeout;
93 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
94 void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
95 struct timer_list *pTimer,
96 IN TIMER_FUNCTION function, void *data)
99 pTimer->data = (unsigned long)data;
100 pTimer->function = function;
103 void RTMP_OS_Add_Timer(struct timer_list *pTimer,
104 IN unsigned long timeout)
106 if (timer_pending(pTimer))
109 timeout = ((timeout * OS_HZ) / 1000);
110 pTimer->expires = jiffies + timeout;
114 void RTMP_OS_Mod_Timer(struct timer_list *pTimer,
115 IN unsigned long timeout)
117 timeout = ((timeout * OS_HZ) / 1000);
118 mod_timer(pTimer, jiffies + timeout);
121 void RTMP_OS_Del_Timer(struct timer_list *pTimer,
122 OUT BOOLEAN * pCancelled)
124 if (timer_pending(pTimer)) {
125 *pCancelled = del_timer_sync(pTimer);
132 void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
134 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
137 /* Unify all delay routine by using udelay */
138 void RTMPusecDelay(unsigned long usec)
142 for (i = 0; i < (usec / 50); i++)
149 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
151 time->u.LowPart = jiffies;
154 /* pAd MUST allow to be NULL */
155 int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
157 *mem = kmalloc(size, GFP_ATOMIC);
159 return NDIS_STATUS_SUCCESS;
161 return NDIS_STATUS_FAILURE;
164 /* pAd MUST allow to be NULL */
165 int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
170 return NDIS_STATUS_SUCCESS;
173 void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
176 /* Add 2 more bytes for ip header alignment */
177 skb = dev_alloc_skb(size + 2);
182 void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
183 unsigned long Length)
187 pkt = dev_alloc_skb(Length);
190 DBGPRINT(RT_DEBUG_ERROR,
191 ("can't allocate frag rx %ld size packet\n", Length));
195 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
201 void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
202 unsigned long Length,
204 void **VirtualAddress)
208 pkt = dev_alloc_skb(Length);
211 DBGPRINT(RT_DEBUG_ERROR,
212 ("can't allocate tx %ld size packet\n", Length));
216 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
217 *VirtualAddress = (void *)pkt->data;
219 *VirtualAddress = (void *)NULL;
225 void build_tx_packet(struct rt_rtmp_adapter *pAd,
227 u8 *pFrame, unsigned long FrameLen)
230 struct sk_buff *pTxPkt;
233 pTxPkt = RTPKT_TO_OSPKT(pPacket);
235 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
238 void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
240 struct os_cookie *os_cookie;
243 os_cookie = (struct os_cookie *)pAd->OS_Cookie;
246 kfree(pAd->BeaconBuf);
248 NdisFreeSpinLock(&pAd->MgmtRingLock);
251 NdisFreeSpinLock(&pAd->RxRingLock);
253 NdisFreeSpinLock(&pAd->McuCmdLock);
254 #endif /* RT3090 // */
255 #endif /* RTMP_MAC_PCI // */
257 for (index = 0; index < NUM_OF_TX_RING; index++) {
258 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
259 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
260 pAd->DeQueueRunning[index] = FALSE;
263 NdisFreeSpinLock(&pAd->irq_lock);
265 release_firmware(pAd->firmware);
267 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
272 BOOLEAN OS_Need_Clone_Packet(void)
278 ========================================================================
281 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
282 must have only one NDIS BUFFER
283 return - byte copied. 0 means can't create NDIS PACKET
284 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
287 pAd Pointer to our adapter
288 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
289 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
297 ========================================================================
299 int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
300 IN BOOLEAN pInsAMSDUHdr,
310 /* 1. Allocate a packet */
311 pkt = dev_alloc_skb(2048);
314 return NDIS_STATUS_FAILURE;
317 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
318 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
319 GET_OS_PKT_LEN(pInPacket));
320 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
322 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
324 printk(KERN_DEBUG "###Clone###\n");
326 return NDIS_STATUS_SUCCESS;
329 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
330 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
334 u8 *pData, u32 DataLen)
340 /* 1. Allocate a packet */
342 (void **) dev_alloc_skb(HeaderLen + DataLen +
343 RTMP_PKT_TAIL_PADDING);
344 if (pPacket == NULL) {
346 pr_devel("RTMPAllocateNdisPacket Fail\n");
348 return NDIS_STATUS_FAILURE;
350 /* 2. clone the frame content */
352 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
354 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
357 /* 3. update length of packet */
358 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
360 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
361 /* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
363 return NDIS_STATUS_SUCCESS;
367 ========================================================================
369 This routine frees a miniport internally allocated char and its
370 corresponding NDIS_BUFFER and allocated memory.
371 ========================================================================
373 void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
375 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
378 /* IRQL = DISPATCH_LEVEL */
379 /* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
380 /* scatter gather buffer */
381 int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
383 u8 *pByte0, u8 *pByte1)
385 *pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
386 *pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
388 return NDIS_STATUS_SUCCESS;
391 void RTMP_QueryPacketInfo(void *pPacket,
392 struct rt_packet_info *pPacketInfo,
393 u8 **pSrcBufVA, u32 * pSrcBufLen)
395 pPacketInfo->BufferCount = 1;
396 pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
397 pPacketInfo->PhysicalBufferCount = 1;
398 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
400 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
401 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
404 void RTMP_QueryNextPacketInfo(void **ppPacket,
405 struct rt_packet_info *pPacketInfo,
406 u8 **pSrcBufVA, u32 * pSrcBufLen)
408 void *pPacket = NULL;
411 pPacket = GET_OS_PKT_NEXT(*ppPacket);
414 pPacketInfo->BufferCount = 1;
415 pPacketInfo->pFirstBuffer =
416 (char *)GET_OS_PKT_DATAPTR(pPacket);
417 pPacketInfo->PhysicalBufferCount = 1;
418 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
420 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
421 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
422 *ppPacket = GET_OS_PKT_NEXT(pPacket);
424 pPacketInfo->BufferCount = 0;
425 pPacketInfo->pFirstBuffer = NULL;
426 pPacketInfo->PhysicalBufferCount = 0;
427 pPacketInfo->TotalPacketLength = 0;
435 void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
436 void *pPacket, u8 FromWhichBSSID)
439 void *pRetPacket = NULL;
443 DataSize = (u16)GET_OS_PKT_LEN(pPacket);
444 pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
446 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
448 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
449 pRetPacket = OSPKT_TO_RTPKT(skb);
456 void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
460 unsigned long DataSize, u8 FromWhichBSSID)
463 void *pPacket = NULL;
465 skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG);
468 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
469 skb_put(skb, HdrLen);
470 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
471 skb_put(skb, DataSize);
472 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
473 pPacket = OSPKT_TO_RTPKT(skb);
479 #define TKIP_TX_MIC_SIZE 8
480 void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
483 struct sk_buff *skb, *newskb;
485 skb = RTPKT_TO_OSPKT(pPacket);
486 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
487 /* alloc a new skb and copy the packet */
489 skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
491 dev_kfree_skb_any(skb);
492 if (newskb == NULL) {
493 DBGPRINT(RT_DEBUG_ERROR,
494 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
500 return OSPKT_TO_RTPKT(skb);
503 void *ClonePacket(struct rt_rtmp_adapter *pAd,
505 u8 *pData, unsigned long DataSize)
507 struct sk_buff *pRxPkt;
508 struct sk_buff *pClonedPkt;
511 pRxPkt = RTPKT_TO_OSPKT(pPacket);
513 /* clone the packet */
514 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
517 /* set the correct dataptr and data len */
518 pClonedPkt->dev = pRxPkt->dev;
519 pClonedPkt->data = pData;
520 pClonedPkt->len = DataSize;
521 skb_set_tail_pointer(pClonedPkt, DataSize)
522 ASSERT(DataSize < 1530);
528 /* change OS packet DataPtr and DataLen */
530 void update_os_packet_info(struct rt_rtmp_adapter *pAd,
531 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
533 struct sk_buff *pOSPkt;
535 ASSERT(pRxBlk->pRxPacket);
536 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
538 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
539 pOSPkt->data = pRxBlk->pData;
540 pOSPkt->len = pRxBlk->DataSize;
541 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
544 void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
545 struct rt_rx_blk *pRxBlk,
549 struct sk_buff *pOSPkt;
551 ASSERT(pRxBlk->pRxPacket);
552 ASSERT(pHeader802_3);
554 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
556 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
557 pOSPkt->data = pRxBlk->pData;
558 pOSPkt->len = pRxBlk->DataSize;
559 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
562 /* copy 802.3 header */
566 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
570 void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
573 struct sk_buff *pRxPkt;
577 pRxPkt = RTPKT_TO_OSPKT(pPacket);
579 /* Push up the protocol stack */
580 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
585 struct rt_rtmp_sg_list *
586 rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
588 sg->NumberOfElements = 1;
589 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
590 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
594 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
599 if (RTDebugLevel < RT_DEBUG_TRACE)
603 printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
604 for (x = 0; x < SrcBufLen; x++) {
606 printk(KERN_DEBUG "0x%04x : ", x);
607 printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x]));
609 printk(KERN_DEBUG "\n");
611 printk(KERN_DEBUG "\n");
615 ========================================================================
618 Send log message through wireless event
620 Support standard iw_event with IWEVCUSTOM. It is used below.
622 iwreq_data.data.flags is used to store event_flag that is defined by user.
623 iwreq_data.data.length is the length of the event log.
625 The format of the event log is composed of the entry's MAC address and
626 the desired log message (refer to pWirelessEventText).
628 ex: 11:22:33:44:55:66 has associated successfully
630 p.s. The requirement of Wireless Extension is v15 or newer.
632 ========================================================================
634 void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
636 u8 *pAddr, u8 BssIdx, char Rssi)
639 /*union iwreq_data wrqu; */
640 char *pBuf = NULL, *pBufPtr = NULL;
641 u16 event, type, BufLen;
642 u8 event_table_len = 0;
644 type = Event_flag & 0xFF00;
645 event = Event_flag & 0x00FF;
648 case IW_SYS_EVENT_FLAG_START:
649 event_table_len = IW_SYS_EVENT_TYPE_NUM;
652 case IW_SPOOF_EVENT_FLAG_START:
653 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
656 case IW_FLOOD_EVENT_FLAG_START:
657 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
661 if (event_table_len == 0) {
662 DBGPRINT(RT_DEBUG_ERROR,
663 ("%s : The type(%0x02x) is not valid.\n", __func__,
668 if (event >= event_table_len) {
669 DBGPRINT(RT_DEBUG_ERROR,
670 ("%s : The event(%0x02x) is not valid.\n", __func__,
674 /*Allocate memory and copy the msg. */
675 pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC);
677 /*Prepare the payload */
678 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
684 sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr);
685 else if (BssIdx < MAX_MBSSID_NUM)
687 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
689 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
691 if (type == IW_SYS_EVENT_FLAG_START)
693 sprintf(pBufPtr, "%s",
694 pWirelessSysEventText[event]);
695 else if (type == IW_SPOOF_EVENT_FLAG_START)
697 sprintf(pBufPtr, "%s (RSSI=%d)",
698 pWirelessSpoofEventText[event], Rssi);
699 else if (type == IW_FLOOD_EVENT_FLAG_START)
701 sprintf(pBufPtr, "%s",
702 pWirelessFloodEventText[event]);
704 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
706 pBufPtr[pBufPtr - pBuf] = '\0';
707 BufLen = pBufPtr - pBuf;
709 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
711 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
715 DBGPRINT(RT_DEBUG_ERROR,
716 ("%s : Can't allocate memory for wireless event.\n",
720 void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
722 struct sk_buff *pOSPkt;
723 struct rt_wlan_ng_prism2_header *ph;
726 u8 temp_header[40] = { 0 };
728 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 */
729 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
730 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
731 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
732 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
733 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
734 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
735 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
736 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
737 72, 73, 74, 75, 76, 77, 78, 79, 80
740 ASSERT(pRxBlk->pRxPacket);
741 if (pRxBlk->DataSize < 10) {
742 DBGPRINT(RT_DEBUG_ERROR,
743 ("%s : Size is too small! (%d)\n", __func__,
745 goto err_free_sk_buff;
748 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
749 RX_BUFFER_AGGRESIZE) {
750 DBGPRINT(RT_DEBUG_ERROR,
751 ("%s : Size is too large! (%zu)\n", __func__,
752 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
753 goto err_free_sk_buff;
756 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
757 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
758 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
759 pRxBlk->DataSize -= LENGTH_802_11;
760 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
761 (pRxBlk->pHeader->FC.FrDs == 1))
762 header_len = LENGTH_802_11_WITH_ADDR4;
764 header_len = LENGTH_802_11;
767 if (pRxBlk->pHeader->FC.SubType & 0x08) {
769 /* Data skip QOS control field */
770 pRxBlk->DataSize -= 2;
772 /* Order bit: A-Ralink or HTC+ */
773 if (pRxBlk->pHeader->FC.Order) {
775 /* Data skip HTC control field */
776 pRxBlk->DataSize -= 4;
779 if (header_len <= 40)
780 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
782 /* skip HW padding */
783 if (pRxBlk->RxD.L2PAD)
784 pRxBlk->pData += (header_len + 2);
786 pRxBlk->pData += header_len;
789 if (pRxBlk->DataSize < pOSPkt->len) {
790 skb_trim(pOSPkt, pRxBlk->DataSize);
792 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
795 if ((pRxBlk->pData - pOSPkt->data) > 0) {
796 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
797 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
800 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
802 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
804 DBGPRINT(RT_DEBUG_ERROR,
805 ("%s : Reallocate header size of sk_buff fail!\n",
807 goto err_free_sk_buff;
812 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
815 ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
816 sizeof(struct rt_wlan_ng_prism2_header));
817 NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
819 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
820 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
821 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
823 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
824 ph->hosttime.status = 0;
825 ph->hosttime.len = 4;
826 ph->hosttime.data = jiffies;
828 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
829 ph->mactime.status = 0;
831 ph->mactime.data = 0;
833 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
838 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
839 ph->channel.status = 0;
842 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
844 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
848 (u_int32_t) RTMPMaxRssi(pAd,
849 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
850 RSSI_0), ConvertToRssi(pAd,
855 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
858 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
859 ph->signal.status = 0;
861 ph->signal.data = 0; /*rssi + noise; */
863 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
864 ph->noise.status = 0;
868 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
870 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
871 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
872 ((u8)pRxBlk->pRxWI->MCS);
873 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
874 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
876 rate_index = (u8)(pRxBlk->pRxWI->MCS);
879 if (rate_index > 255)
882 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
885 ph->rate.data = ralinkrate[rate_index];
887 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
888 ph->frmlen.status = 0;
890 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
892 pOSPkt->pkt_type = PACKET_OTHERHOST;
893 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
894 pOSPkt->ip_summed = CHECKSUM_NONE;
900 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
905 /*******************************************************************************
907 Device IRQ related functions.
909 *******************************************************************************/
910 int RtmpOSIRQRequest(struct net_device *pNetDev)
912 #ifdef RTMP_PCI_SUPPORT
913 struct net_device *net_dev = pNetDev;
914 struct rt_rtmp_adapter *pAd = NULL;
917 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
921 if (pAd->infType == RTMP_DEV_INF_PCI) {
922 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
923 RTMP_MSI_ENABLE(pAd);
925 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
926 (net_dev)->name, (net_dev));
928 printk(KERN_ERR "rt2860: request_irq ERROR(%d)\n", retval);
937 int RtmpOSIRQRelease(struct net_device *pNetDev)
939 struct net_device *net_dev = pNetDev;
940 struct rt_rtmp_adapter *pAd = NULL;
942 GET_PAD_FROM_NET_DEV(pAd, net_dev);
946 #ifdef RTMP_PCI_SUPPORT
947 if (pAd->infType == RTMP_DEV_INF_PCI) {
948 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
949 synchronize_irq(pObj->pci_dev->irq);
950 free_irq(pObj->pci_dev->irq, (net_dev));
951 RTMP_MSI_DISABLE(pAd);
953 #endif /* RTMP_PCI_SUPPORT // */
958 /*******************************************************************************
960 File open/close related functions.
962 *******************************************************************************/
963 struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
965 struct file *filePtr;
967 filePtr = filp_open(pPath, flag, 0);
968 if (IS_ERR(filePtr)) {
969 DBGPRINT(RT_DEBUG_ERROR,
970 ("%s(): Error %ld opening %s\n", __func__,
971 -PTR_ERR(filePtr), pPath));
974 return (struct file *)filePtr;
977 int RtmpOSFileClose(struct file *osfd)
979 filp_close(osfd, NULL);
983 void RtmpOSFileSeek(struct file *osfd, int offset)
985 osfd->f_pos = offset;
988 int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
990 /* The object must have a read method */
991 if (osfd->f_op && osfd->f_op->read) {
992 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
994 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
999 int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
1001 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
1005 /*******************************************************************************
1007 Task create/management/kill related functions.
1009 *******************************************************************************/
1010 int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
1012 struct rt_rtmp_adapter *pAd;
1013 int ret = NDIS_STATUS_FAILURE;
1017 #ifdef KTHREAD_SUPPORT
1018 if (pTask->kthread_task) {
1019 kthread_stop(pTask->kthread_task);
1020 ret = NDIS_STATUS_SUCCESS;
1023 CHECK_PID_LEGALITY(pTask->taskPID) {
1024 printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n",
1025 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1027 pTask->task_killed = 1;
1029 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1032 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1033 pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
1036 wait_for_completion(&pTask->taskComplete);
1037 pTask->taskPID = THREAD_PID_INIT_VALUE;
1038 pTask->task_killed = 0;
1039 ret = NDIS_STATUS_SUCCESS;
1048 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
1051 #ifndef KTHREAD_SUPPORT
1052 complete_and_exit(&pTask->taskComplete, 0);
1058 void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
1061 #ifndef KTHREAD_SUPPORT
1063 daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */);
1065 allow_signal(SIGTERM);
1066 allow_signal(SIGKILL);
1067 current->flags |= PF_NOFREEZE;
1069 /* signal that we've started the thread */
1070 complete(&pTask->taskComplete);
1075 int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
1076 IN int (*fn) (void *), IN void *arg)
1078 int status = NDIS_STATUS_SUCCESS;
1080 #ifdef KTHREAD_SUPPORT
1081 pTask->task_killed = 0;
1082 pTask->kthread_task = NULL;
1083 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1084 if (IS_ERR(pTask->kthread_task))
1085 status = NDIS_STATUS_FAILURE;
1087 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1088 if (pid_number < 0) {
1089 DBGPRINT(RT_DEBUG_ERROR,
1090 ("Attach task(%s) failed!\n", pTask->taskName));
1091 status = NDIS_STATUS_FAILURE;
1093 pTask->taskPID = GET_PID(pid_number);
1095 /* Wait for the thread to start */
1096 wait_for_completion(&pTask->taskComplete);
1097 status = NDIS_STATUS_SUCCESS;
1103 int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
1104 char *pTaskName, void * pPriv)
1110 #ifndef KTHREAD_SUPPORT
1111 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
1114 len = strlen(pTaskName);
1117 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
1118 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1119 pTask->priv = pPriv;
1121 #ifndef KTHREAD_SUPPORT
1122 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1123 pTask->taskPID = THREAD_PID_INIT_VALUE;
1125 init_completion(&pTask->taskComplete);
1128 return NDIS_STATUS_SUCCESS;
1131 void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
1133 if (pAd->CommonCfg.bWirelessEvent) {
1134 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1135 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1136 pAd->MacTab.Content[BSSID_WCID].
1139 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1140 pAd->MacTab.Content[BSSID_WCID].
1146 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
1150 u8 *pData, u32 dataLen)
1152 union iwreq_data wrqu;
1154 memset(&wrqu, 0, sizeof(wrqu));
1157 wrqu.data.flags = flags;
1160 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1162 if ((pData != NULL) && (dataLen > 0))
1163 wrqu.data.length = dataLen;
1165 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1169 int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
1171 struct net_device *net_dev;
1172 struct rt_rtmp_adapter *pAd;
1175 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1177 /* work-around for SuSE, due to them having their own interface name management system. */
1179 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1180 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1181 strlen(net_dev->name));
1184 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1190 * Assign the network dev name for created Ralink WiFi interface.
1192 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
1193 struct net_device *dev,
1194 char *pPrefixStr, int devIdx)
1196 struct net_device *existNetDev;
1197 char suffixName[IFNAMSIZ];
1198 char desiredName[IFNAMSIZ];
1199 int ifNameIdx, prefixLen, slotNameLen;
1202 prefixLen = strlen(pPrefixStr);
1203 ASSERT((prefixLen < IFNAMSIZ));
1205 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
1206 memset(suffixName, 0, IFNAMSIZ);
1207 memset(desiredName, 0, IFNAMSIZ);
1208 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1210 sprintf(suffixName, "%d", ifNameIdx);
1212 slotNameLen = strlen(suffixName);
1213 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1214 strcat(desiredName, suffixName);
1216 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1217 if (existNetDev == NULL)
1220 RtmpOSNetDeviceRefPut(existNetDev);
1223 if (ifNameIdx < 32) {
1224 strcpy(&dev->name[0], &desiredName[0]);
1225 Status = NDIS_STATUS_SUCCESS;
1227 DBGPRINT(RT_DEBUG_ERROR,
1228 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1230 Status = NDIS_STATUS_FAILURE;
1236 void RtmpOSNetDevClose(struct net_device *pNetDev)
1241 void RtmpOSNetDevFree(struct net_device *pNetDev)
1245 free_netdev(pNetDev);
1248 int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize)
1250 /* assign it as null first. */
1253 DBGPRINT(RT_DEBUG_TRACE,
1254 ("Allocate a net device with private data size=%d!\n",
1256 *new_dev_p = alloc_etherdev(privDataSize);
1258 return NDIS_STATUS_SUCCESS;
1260 return NDIS_STATUS_FAILURE;
1263 struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
1265 struct net_device *pTargetNetDev = NULL;
1267 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1269 return pTargetNetDev;
1272 void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
1275 every time dev_get_by_name is called, and it has returned a valid struct
1276 net_device*, dev_put should be called afterwards, because otherwise the
1277 machine hangs when the device is unregistered (since dev->refcnt > 1).
1283 int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
1286 /* TODO: Need to fix this */
1287 printk("WARNING: This function(%s) not implement yet!\n", __func__);
1291 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1293 unregister_netdev(pNetDev);
1296 int RtmpOSNetDevAttach(struct net_device *pNetDev,
1297 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
1299 int ret, rtnl_locked = FALSE;
1301 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1302 /* If we need hook some callback function to the net device structure, now do it. */
1304 struct rt_rtmp_adapter *pAd = NULL;
1306 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1308 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1310 /* OS specific flags, here we used to indicate if we are virtual interface */
1311 pNetDev->priv_flags = pDevOpHook->priv_flags;
1313 if (pAd->OpMode == OPMODE_STA)
1314 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1316 /* copy the net device mac address to the net_device structure. */
1317 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1320 rtnl_locked = pDevOpHook->needProtcted;
1324 ret = register_netdevice(pNetDev);
1326 ret = register_netdev(pNetDev);
1328 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1330 return NDIS_STATUS_SUCCESS;
1332 return NDIS_STATUS_FAILURE;
1335 struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
1338 int privMemSize, char *pNamePrefix)
1340 struct net_device *pNetDev = NULL;
1343 /* allocate a new network device */
1344 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */);
1345 if (status != NDIS_STATUS_SUCCESS) {
1346 /* allocation fail, exit */
1347 DBGPRINT(RT_DEBUG_ERROR,
1348 ("Allocate network device fail (%s)...\n",
1353 /* find an available interface name, max 32 interfaces */
1354 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1355 if (status != NDIS_STATUS_SUCCESS) {
1356 /* error! no available ra name can be used! */
1357 DBGPRINT(RT_DEBUG_ERROR,
1358 ("Assign interface name (%s with suffix 0~32) failed...\n",
1360 RtmpOSNetDevFree(pNetDev);
1364 DBGPRINT(RT_DEBUG_TRACE,
1365 ("The name of the new %s interface is %s...\n",
1366 pNamePrefix, pNetDev->name));