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 "rt_config.h"
32 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
34 /* for wireless system event message */
35 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
36 /* system status event */
37 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
38 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
39 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
40 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
41 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
42 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
43 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
44 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
45 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
46 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
47 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
48 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
49 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
50 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
51 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
52 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
53 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
54 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
55 "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
58 /* for wireless IDS_spoof_attack event message */
59 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
60 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
61 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
62 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
63 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
64 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
65 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
66 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
67 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
68 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
69 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
72 /* for wireless IDS_flooding_attack event message */
73 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
74 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
75 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
76 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
77 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
78 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
79 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
80 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
84 void RTMP_SetPeriodicTimer(struct timer_list * pTimer,
85 IN unsigned long timeout)
87 timeout = ((timeout * OS_HZ) / 1000);
88 pTimer->expires = jiffies + timeout;
92 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
93 void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
94 struct timer_list * pTimer,
95 IN TIMER_FUNCTION function, void *data)
98 pTimer->data = (unsigned long)data;
99 pTimer->function = function;
102 void RTMP_OS_Add_Timer(struct timer_list * pTimer,
103 IN unsigned long timeout)
105 if (timer_pending(pTimer))
108 timeout = ((timeout * OS_HZ) / 1000);
109 pTimer->expires = jiffies + timeout;
113 void RTMP_OS_Mod_Timer(struct timer_list * pTimer,
114 IN unsigned long timeout)
116 timeout = ((timeout * OS_HZ) / 1000);
117 mod_timer(pTimer, jiffies + timeout);
120 void RTMP_OS_Del_Timer(struct timer_list * pTimer,
121 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 = (u8 *)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);
178 return ((void *)skb);
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;
245 kfree(pAd->BeaconBuf);
247 NdisFreeSpinLock(&pAd->MgmtRingLock);
250 NdisFreeSpinLock(&pAd->RxRingLock);
252 NdisFreeSpinLock(&pAd->McuCmdLock);
253 #endif /* RT3090 // */
254 #endif /* RTMP_MAC_PCI // */
256 for (index = 0; index < NUM_OF_TX_RING; index++) {
257 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
258 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
259 pAd->DeQueueRunning[index] = FALSE;
262 NdisFreeSpinLock(&pAd->irq_lock);
264 release_firmware(pAd->firmware);
266 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
271 BOOLEAN OS_Need_Clone_Packet(void)
277 ========================================================================
280 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
281 must have only one NDIS BUFFER
282 return - byte copied. 0 means can't create NDIS PACKET
283 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
286 pAd Pointer to our adapter
287 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
288 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
296 ========================================================================
298 int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
299 IN BOOLEAN pInsAMSDUHdr,
309 /* 1. Allocate a packet */
310 pkt = dev_alloc_skb(2048);
313 return NDIS_STATUS_FAILURE;
316 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
317 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
318 GET_OS_PKT_LEN(pInPacket));
319 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
321 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
323 printk("###Clone###\n");
325 return NDIS_STATUS_SUCCESS;
328 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
329 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
333 u8 *pData, u32 DataLen)
339 /* 1. Allocate a packet */
341 (void **) dev_alloc_skb(HeaderLen + DataLen +
342 RTMP_PKT_TAIL_PADDING);
343 if (pPacket == NULL) {
346 printk("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;
466 __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
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("%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
604 for (x = 0; x < SrcBufLen; x++) {
606 printk("0x%04x : ", x);
607 printk("%02x ", ((unsigned char)pt[x]));
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 if ((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) {
676 /*Prepare the payload */
677 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
684 "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ",
686 else if (BssIdx < MAX_MBSSID_NUM)
688 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
690 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
692 if (type == IW_SYS_EVENT_FLAG_START)
694 sprintf(pBufPtr, "%s",
695 pWirelessSysEventText[event]);
696 else if (type == IW_SPOOF_EVENT_FLAG_START)
698 sprintf(pBufPtr, "%s (RSSI=%d)",
699 pWirelessSpoofEventText[event], Rssi);
700 else if (type == IW_FLOOD_EVENT_FLAG_START)
702 sprintf(pBufPtr, "%s",
703 pWirelessFloodEventText[event]);
705 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
707 pBufPtr[pBufPtr - pBuf] = '\0';
708 BufLen = pBufPtr - pBuf;
710 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
712 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
716 DBGPRINT(RT_DEBUG_ERROR,
717 ("%s : Can't allocate memory for wireless event.\n",
721 void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
723 struct sk_buff *pOSPkt;
724 struct rt_wlan_ng_prism2_header *ph;
727 u8 temp_header[40] = { 0 };
729 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 */
730 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
731 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
732 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
733 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
734 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
735 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
736 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
737 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
738 72, 73, 74, 75, 76, 77, 78, 79, 80
741 ASSERT(pRxBlk->pRxPacket);
742 if (pRxBlk->DataSize < 10) {
743 DBGPRINT(RT_DEBUG_ERROR,
744 ("%s : Size is too small! (%d)\n", __func__,
746 goto err_free_sk_buff;
749 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
750 RX_BUFFER_AGGRESIZE) {
751 DBGPRINT(RT_DEBUG_ERROR,
752 ("%s : Size is too large! (%zu)\n", __func__,
753 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
754 goto err_free_sk_buff;
757 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
758 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
759 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
760 pRxBlk->DataSize -= LENGTH_802_11;
761 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
762 (pRxBlk->pHeader->FC.FrDs == 1))
763 header_len = LENGTH_802_11_WITH_ADDR4;
765 header_len = LENGTH_802_11;
768 if (pRxBlk->pHeader->FC.SubType & 0x08) {
770 /* Data skip QOS contorl field */
771 pRxBlk->DataSize -= 2;
773 /* Order bit: A-Ralink or HTC+ */
774 if (pRxBlk->pHeader->FC.Order) {
776 /* Data skip HTC contorl field */
777 pRxBlk->DataSize -= 4;
780 if (header_len <= 40)
781 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
783 /* skip HW padding */
784 if (pRxBlk->RxD.L2PAD)
785 pRxBlk->pData += (header_len + 2);
787 pRxBlk->pData += header_len;
790 if (pRxBlk->DataSize < pOSPkt->len) {
791 skb_trim(pOSPkt, pRxBlk->DataSize);
793 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
796 if ((pRxBlk->pData - pOSPkt->data) > 0) {
797 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
798 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
801 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
803 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
805 DBGPRINT(RT_DEBUG_ERROR,
806 ("%s : Reallocate header size of sk_buff fail!\n",
808 goto err_free_sk_buff;
813 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
816 ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
817 sizeof(struct rt_wlan_ng_prism2_header));
818 NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
820 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
821 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
822 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
824 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
825 ph->hosttime.status = 0;
826 ph->hosttime.len = 4;
827 ph->hosttime.data = jiffies;
829 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
830 ph->mactime.status = 0;
832 ph->mactime.data = 0;
834 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
839 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
840 ph->channel.status = 0;
843 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
845 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
849 (u_int32_t) RTMPMaxRssi(pAd,
850 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
851 RSSI_0), ConvertToRssi(pAd,
856 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
859 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
860 ph->signal.status = 0;
862 ph->signal.data = 0; /*rssi + noise; */
864 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
865 ph->noise.status = 0;
869 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
871 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
872 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
873 ((u8)pRxBlk->pRxWI->MCS);
874 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
875 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
877 rate_index = (u8)(pRxBlk->pRxWI->MCS);
880 if (rate_index > 255)
883 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
886 ph->rate.data = ralinkrate[rate_index];
888 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
889 ph->frmlen.status = 0;
891 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
893 pOSPkt->pkt_type = PACKET_OTHERHOST;
894 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
895 pOSPkt->ip_summed = CHECKSUM_NONE;
901 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
906 /*******************************************************************************
908 Device IRQ related functions.
910 *******************************************************************************/
911 int RtmpOSIRQRequest(struct net_device *pNetDev)
913 #ifdef RTMP_PCI_SUPPORT
914 struct net_device *net_dev = pNetDev;
915 struct rt_rtmp_adapter *pAd = NULL;
918 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
922 if (pAd->infType == RTMP_DEV_INF_PCI) {
923 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
924 RTMP_MSI_ENABLE(pAd);
926 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
927 (net_dev)->name, (net_dev));
929 printk("RT2860: request_irq ERROR(%d)\n", retval);
938 int RtmpOSIRQRelease(struct net_device *pNetDev)
940 struct net_device *net_dev = pNetDev;
941 struct rt_rtmp_adapter *pAd = NULL;
943 GET_PAD_FROM_NET_DEV(pAd, net_dev);
947 #ifdef RTMP_PCI_SUPPORT
948 if (pAd->infType == RTMP_DEV_INF_PCI) {
949 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
950 synchronize_irq(pObj->pci_dev->irq);
951 free_irq(pObj->pci_dev->irq, (net_dev));
952 RTMP_MSI_DISABLE(pAd);
954 #endif /* RTMP_PCI_SUPPORT // */
959 /*******************************************************************************
961 File open/close related functions.
963 *******************************************************************************/
964 struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
966 struct file *filePtr;
968 filePtr = filp_open(pPath, flag, 0);
969 if (IS_ERR(filePtr)) {
970 DBGPRINT(RT_DEBUG_ERROR,
971 ("%s(): Error %ld opening %s\n", __func__,
972 -PTR_ERR(filePtr), pPath));
975 return (struct file *)filePtr;
978 int RtmpOSFileClose(struct file *osfd)
980 filp_close(osfd, NULL);
984 void RtmpOSFileSeek(struct file *osfd, int offset)
986 osfd->f_pos = offset;
989 int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
991 /* The object must have a read method */
992 if (osfd->f_op && osfd->f_op->read) {
993 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
995 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
1000 int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
1002 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
1006 /*******************************************************************************
1008 Task create/management/kill related functions.
1010 *******************************************************************************/
1011 int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
1013 struct rt_rtmp_adapter *pAd;
1014 int ret = NDIS_STATUS_FAILURE;
1016 pAd = (struct rt_rtmp_adapter *)pTask->priv;
1018 #ifdef KTHREAD_SUPPORT
1019 if (pTask->kthread_task) {
1020 kthread_stop(pTask->kthread_task);
1021 ret = NDIS_STATUS_SUCCESS;
1024 CHECK_PID_LEGALITY(pTask->taskPID) {
1025 printk("Terminate the task(%s) with pid(%d)!\n",
1026 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1028 pTask->task_killed = 1;
1030 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1033 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1034 pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
1037 wait_for_completion(&pTask->taskComplete);
1038 pTask->taskPID = THREAD_PID_INIT_VALUE;
1039 pTask->task_killed = 0;
1040 ret = NDIS_STATUS_SUCCESS;
1049 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
1052 #ifndef KTHREAD_SUPPORT
1053 complete_and_exit(&pTask->taskComplete, 0);
1059 void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
1062 #ifndef KTHREAD_SUPPORT
1064 daemonize((char *)& pTask->taskName[0] /*"%s",pAd->net_dev->name */ );
1066 allow_signal(SIGTERM);
1067 allow_signal(SIGKILL);
1068 current->flags |= PF_NOFREEZE;
1070 /* signal that we've started the thread */
1071 complete(&pTask->taskComplete);
1076 int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
1077 IN int (*fn) (void *), IN void *arg)
1079 int status = NDIS_STATUS_SUCCESS;
1081 #ifdef KTHREAD_SUPPORT
1082 pTask->task_killed = 0;
1083 pTask->kthread_task = NULL;
1084 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1085 if (IS_ERR(pTask->kthread_task))
1086 status = NDIS_STATUS_FAILURE;
1088 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1089 if (pid_number < 0) {
1090 DBGPRINT(RT_DEBUG_ERROR,
1091 ("Attach task(%s) failed!\n", pTask->taskName));
1092 status = NDIS_STATUS_FAILURE;
1094 pTask->taskPID = GET_PID(pid_number);
1096 /* Wait for the thread to start */
1097 wait_for_completion(&pTask->taskComplete);
1098 status = NDIS_STATUS_SUCCESS;
1104 int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
1105 char *pTaskName, void * pPriv)
1111 #ifndef KTHREAD_SUPPORT
1112 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
1115 len = strlen(pTaskName);
1118 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
1119 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1120 pTask->priv = pPriv;
1122 #ifndef KTHREAD_SUPPORT
1123 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1124 pTask->taskPID = THREAD_PID_INIT_VALUE;
1126 init_completion(&pTask->taskComplete);
1129 return NDIS_STATUS_SUCCESS;
1132 void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
1134 if (pAd->CommonCfg.bWirelessEvent) {
1135 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1136 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1137 pAd->MacTab.Content[BSSID_WCID].
1140 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1141 pAd->MacTab.Content[BSSID_WCID].
1147 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
1151 u8 *pData, u32 dataLen)
1153 union iwreq_data wrqu;
1155 memset(&wrqu, 0, sizeof(wrqu));
1158 wrqu.data.flags = flags;
1161 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1163 if ((pData != NULL) && (dataLen > 0))
1164 wrqu.data.length = dataLen;
1166 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1170 int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
1172 struct net_device *net_dev;
1173 struct rt_rtmp_adapter *pAd;
1176 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1178 /* work-around for the SuSE due to it has it's own interface name management system. */
1180 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1181 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1182 strlen(net_dev->name));
1185 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1191 * Assign the network dev name for created Ralink WiFi interface.
1193 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
1194 struct net_device *dev,
1195 char *pPrefixStr, int devIdx)
1197 struct net_device *existNetDev;
1198 char suffixName[IFNAMSIZ];
1199 char desiredName[IFNAMSIZ];
1200 int ifNameIdx, prefixLen, slotNameLen;
1203 prefixLen = strlen(pPrefixStr);
1204 ASSERT((prefixLen < IFNAMSIZ));
1206 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
1207 memset(suffixName, 0, IFNAMSIZ);
1208 memset(desiredName, 0, IFNAMSIZ);
1209 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1211 sprintf(suffixName, "%d", ifNameIdx);
1213 slotNameLen = strlen(suffixName);
1214 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1215 strcat(desiredName, suffixName);
1217 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1218 if (existNetDev == NULL)
1221 RtmpOSNetDeviceRefPut(existNetDev);
1224 if (ifNameIdx < 32) {
1225 strcpy(&dev->name[0], &desiredName[0]);
1226 Status = NDIS_STATUS_SUCCESS;
1228 DBGPRINT(RT_DEBUG_ERROR,
1229 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1231 Status = NDIS_STATUS_FAILURE;
1237 void RtmpOSNetDevClose(struct net_device *pNetDev)
1242 void RtmpOSNetDevFree(struct net_device *pNetDev)
1246 free_netdev(pNetDev);
1249 int RtmpOSNetDevAlloc(struct net_device ** new_dev_p, u32 privDataSize)
1251 /* assign it as null first. */
1254 DBGPRINT(RT_DEBUG_TRACE,
1255 ("Allocate a net device with private data size=%d!\n",
1257 *new_dev_p = alloc_etherdev(privDataSize);
1259 return NDIS_STATUS_SUCCESS;
1261 return NDIS_STATUS_FAILURE;
1264 struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
1266 struct net_device *pTargetNetDev = NULL;
1268 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1270 return pTargetNetDev;
1273 void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
1276 every time dev_get_by_name is called, and it has returned a valid struct
1277 net_device*, dev_put should be called afterwards, because otherwise the
1278 machine hangs when the device is unregistered (since dev->refcnt > 1).
1284 int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
1287 /* TODO: Need to fix this */
1288 printk("WARNING: This function(%s) not implement yet!\n", __func__);
1292 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1294 unregister_netdev(pNetDev);
1297 int RtmpOSNetDevAttach(struct net_device *pNetDev,
1298 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
1300 int ret, rtnl_locked = FALSE;
1302 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1303 /* If we need hook some callback function to the net device structrue, now do it. */
1305 struct rt_rtmp_adapter *pAd = NULL;
1307 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1309 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1311 /* OS specific flags, here we used to indicate if we are virtual interface */
1312 pNetDev->priv_flags = pDevOpHook->priv_flags;
1314 if (pAd->OpMode == OPMODE_STA) {
1315 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1318 /* copy the net device mac address to the net_device structure. */
1319 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1322 rtnl_locked = pDevOpHook->needProtcted;
1326 ret = register_netdevice(pNetDev);
1328 ret = register_netdev(pNetDev);
1330 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1332 return NDIS_STATUS_SUCCESS;
1334 return NDIS_STATUS_FAILURE;
1337 struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
1340 int privMemSize, char *pNamePrefix)
1342 struct net_device *pNetDev = NULL;
1345 /* allocate a new network device */
1346 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */ );
1347 if (status != NDIS_STATUS_SUCCESS) {
1348 /* allocation fail, exit */
1349 DBGPRINT(RT_DEBUG_ERROR,
1350 ("Allocate network device fail (%s)...\n",
1355 /* find a available interface name, max 32 interfaces */
1356 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1357 if (status != NDIS_STATUS_SUCCESS) {
1358 /* error! no any available ra name can be used! */
1359 DBGPRINT(RT_DEBUG_ERROR,
1360 ("Assign interface name (%s with suffix 0~32) failed...\n",
1362 RtmpOSNetDevFree(pNetDev);
1366 DBGPRINT(RT_DEBUG_TRACE,
1367 ("The name of the new %s interface is %s...\n",
1368 pNamePrefix, pNetDev->name));