x86, mce: use a call vector to call the 64bit mce handler
[linux-2.6/mini2440.git] / drivers / staging / rt2860 / rt_linux.c
blobf3c128c72a218dc9404fee31fd089fa1c5e4f3b7
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
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. *
14 * *
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. *
19 * *
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. *
24 * *
25 *************************************************************************
28 #include "rt_config.h"
30 ULONG RTDebugLevel = RT_DEBUG_ERROR;
32 BUILD_TIMER_FUNCTION(MlmePeriodicExec);
33 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
34 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
35 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
38 #ifdef CONFIG_STA_SUPPORT
39 BUILD_TIMER_FUNCTION(BeaconTimeout);
40 BUILD_TIMER_FUNCTION(ScanTimeout);
41 BUILD_TIMER_FUNCTION(AuthTimeout);
42 BUILD_TIMER_FUNCTION(AssocTimeout);
43 BUILD_TIMER_FUNCTION(ReassocTimeout);
44 BUILD_TIMER_FUNCTION(DisassocTimeout);
45 BUILD_TIMER_FUNCTION(LinkDownExec);
46 #ifdef LEAP_SUPPORT
47 BUILD_TIMER_FUNCTION(LeapAuthTimeout);
48 #endif
49 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
50 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51 BUILD_TIMER_FUNCTION(PsPollWakeExec);
52 BUILD_TIMER_FUNCTION(RadioOnExec);
53 #ifdef QOS_DLS_SUPPORT
54 BUILD_TIMER_FUNCTION(DlsTimeoutAction);
55 #endif // QOS_DLS_SUPPORT //
56 #endif // CONFIG_STA_SUPPORT //
58 // for wireless system event message
59 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
60 // system status event
61 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
62 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
63 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
64 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
65 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
66 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
67 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
68 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
69 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
70 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
71 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
72 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
73 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
74 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
75 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
76 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
77 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
78 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
79 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
82 // for wireless IDS_spoof_attack event message
83 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
84 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
85 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
86 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
87 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
88 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
89 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
90 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
91 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
92 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
93 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
96 // for wireless IDS_flooding_attack event message
97 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
98 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
99 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
100 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
101 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
102 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
103 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
104 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
107 /* timeout -- ms */
108 VOID RTMP_SetPeriodicTimer(
109 IN NDIS_MINIPORT_TIMER *pTimer,
110 IN unsigned long timeout)
112 timeout = ((timeout*HZ) / 1000);
113 pTimer->expires = jiffies + timeout;
114 add_timer(pTimer);
117 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
118 VOID RTMP_OS_Init_Timer(
119 IN PRTMP_ADAPTER pAd,
120 IN NDIS_MINIPORT_TIMER *pTimer,
121 IN TIMER_FUNCTION function,
122 IN PVOID data)
124 init_timer(pTimer);
125 pTimer->data = (unsigned long)data;
126 pTimer->function = function;
130 VOID RTMP_OS_Add_Timer(
131 IN NDIS_MINIPORT_TIMER *pTimer,
132 IN unsigned long timeout)
134 if (timer_pending(pTimer))
135 return;
137 timeout = ((timeout*HZ) / 1000);
138 pTimer->expires = jiffies + timeout;
139 add_timer(pTimer);
142 VOID RTMP_OS_Mod_Timer(
143 IN NDIS_MINIPORT_TIMER *pTimer,
144 IN unsigned long timeout)
146 timeout = ((timeout*HZ) / 1000);
147 mod_timer(pTimer, jiffies + timeout);
150 VOID RTMP_OS_Del_Timer(
151 IN NDIS_MINIPORT_TIMER *pTimer,
152 OUT BOOLEAN *pCancelled)
154 if (timer_pending(pTimer))
156 *pCancelled = del_timer_sync(pTimer);
158 else
160 *pCancelled = TRUE;
165 VOID RTMP_OS_Release_Packet(
166 IN PRTMP_ADAPTER pAd,
167 IN PQUEUE_ENTRY pEntry)
169 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
172 // Unify all delay routine by using udelay
173 VOID RTMPusecDelay(
174 IN ULONG usec)
176 ULONG i;
178 for (i = 0; i < (usec / 50); i++)
179 udelay(50);
181 if (usec % 50)
182 udelay(usec % 50);
185 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
187 time->u.LowPart = jiffies;
190 // pAd MUST allow to be NULL
191 NDIS_STATUS os_alloc_mem(
192 IN PRTMP_ADAPTER pAd,
193 OUT PUCHAR *mem,
194 IN ULONG size)
196 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
197 if (*mem)
198 return (NDIS_STATUS_SUCCESS);
199 else
200 return (NDIS_STATUS_FAILURE);
203 // pAd MUST allow to be NULL
204 NDIS_STATUS os_free_mem(
205 IN PRTMP_ADAPTER pAd,
206 IN PUCHAR mem)
209 ASSERT(mem);
210 kfree(mem);
211 return (NDIS_STATUS_SUCCESS);
215 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
216 IN PRTMP_ADAPTER pAd,
217 IN ULONG Length)
219 struct sk_buff *pkt;
221 pkt = dev_alloc_skb(Length);
223 if (pkt == NULL)
225 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
228 if (pkt)
230 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
233 return (PNDIS_PACKET) pkt;
237 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
238 IN PRTMP_ADAPTER pAd,
239 IN ULONG Length,
240 IN BOOLEAN Cached,
241 OUT PVOID *VirtualAddress)
243 struct sk_buff *pkt;
245 pkt = dev_alloc_skb(Length);
247 if (pkt == NULL)
249 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
252 if (pkt)
254 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
255 *VirtualAddress = (PVOID) pkt->data;
257 else
259 *VirtualAddress = (PVOID) NULL;
262 return (PNDIS_PACKET) pkt;
266 VOID build_tx_packet(
267 IN PRTMP_ADAPTER pAd,
268 IN PNDIS_PACKET pPacket,
269 IN PUCHAR pFrame,
270 IN ULONG FrameLen)
273 struct sk_buff *pTxPkt;
275 ASSERT(pPacket);
276 pTxPkt = RTPKT_TO_OSPKT(pPacket);
278 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
281 VOID RTMPFreeAdapter(
282 IN PRTMP_ADAPTER pAd)
284 POS_COOKIE os_cookie;
285 int index;
287 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
289 kfree(pAd->BeaconBuf);
292 NdisFreeSpinLock(&pAd->MgmtRingLock);
294 NdisFreeSpinLock(&pAd->RxRingLock);
296 for (index =0 ; index < NUM_OF_TX_RING; index++)
298 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
299 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
300 pAd->DeQueueRunning[index] = FALSE;
303 NdisFreeSpinLock(&pAd->irq_lock);
305 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
306 kfree(os_cookie);
309 BOOLEAN OS_Need_Clone_Packet(void)
311 return (FALSE);
317 ========================================================================
319 Routine Description:
320 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
321 must have only one NDIS BUFFER
322 return - byte copied. 0 means can't create NDIS PACKET
323 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
325 Arguments:
326 pAd Pointer to our adapter
327 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
328 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
330 Return Value:
331 NDIS_STATUS_SUCCESS
332 NDIS_STATUS_FAILURE
334 Note:
336 ========================================================================
338 NDIS_STATUS RTMPCloneNdisPacket(
339 IN PRTMP_ADAPTER pAd,
340 IN BOOLEAN pInsAMSDUHdr,
341 IN PNDIS_PACKET pInPacket,
342 OUT PNDIS_PACKET *ppOutPacket)
345 struct sk_buff *pkt;
347 ASSERT(pInPacket);
348 ASSERT(ppOutPacket);
350 // 1. Allocate a packet
351 pkt = dev_alloc_skb(2048);
353 if (pkt == NULL)
355 return NDIS_STATUS_FAILURE;
358 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
359 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
360 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
363 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
365 printk("###Clone###\n");
367 return NDIS_STATUS_SUCCESS;
371 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
372 NDIS_STATUS RTMPAllocateNdisPacket(
373 IN PRTMP_ADAPTER pAd,
374 OUT PNDIS_PACKET *ppPacket,
375 IN PUCHAR pHeader,
376 IN UINT HeaderLen,
377 IN PUCHAR pData,
378 IN UINT DataLen)
380 PNDIS_PACKET pPacket;
381 ASSERT(pData);
382 ASSERT(DataLen);
384 // 1. Allocate a packet
385 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
386 if (pPacket == NULL)
388 *ppPacket = NULL;
389 #ifdef DEBUG
390 printk("RTMPAllocateNdisPacket Fail\n\n");
391 #endif
392 return NDIS_STATUS_FAILURE;
395 // 2. clone the frame content
396 if (HeaderLen > 0)
397 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
398 if (DataLen > 0)
399 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
401 // 3. update length of packet
402 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
404 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
405 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
406 *ppPacket = pPacket;
407 return NDIS_STATUS_SUCCESS;
411 ========================================================================
412 Description:
413 This routine frees a miniport internally allocated NDIS_PACKET and its
414 corresponding NDIS_BUFFER and allocated memory.
415 ========================================================================
417 VOID RTMPFreeNdisPacket(
418 IN PRTMP_ADAPTER pAd,
419 IN PNDIS_PACKET pPacket)
421 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
425 // IRQL = DISPATCH_LEVEL
426 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
427 // scatter gather buffer
428 NDIS_STATUS Sniff2BytesFromNdisBuffer(
429 IN PNDIS_BUFFER pFirstBuffer,
430 IN UCHAR DesiredOffset,
431 OUT PUCHAR pByte0,
432 OUT PUCHAR pByte1)
434 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
435 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
437 return NDIS_STATUS_SUCCESS;
441 void RTMP_QueryPacketInfo(
442 IN PNDIS_PACKET pPacket,
443 OUT PACKET_INFO *pPacketInfo,
444 OUT PUCHAR *pSrcBufVA,
445 OUT UINT *pSrcBufLen)
447 pPacketInfo->BufferCount = 1;
448 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
449 pPacketInfo->PhysicalBufferCount = 1;
450 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
452 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
453 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
456 void RTMP_QueryNextPacketInfo(
457 IN PNDIS_PACKET *ppPacket,
458 OUT PACKET_INFO *pPacketInfo,
459 OUT PUCHAR *pSrcBufVA,
460 OUT UINT *pSrcBufLen)
462 PNDIS_PACKET pPacket = NULL;
464 if (*ppPacket)
465 pPacket = GET_OS_PKT_NEXT(*ppPacket);
467 if (pPacket)
469 pPacketInfo->BufferCount = 1;
470 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
471 pPacketInfo->PhysicalBufferCount = 1;
472 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
474 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
475 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
476 *ppPacket = GET_OS_PKT_NEXT(pPacket);
478 else
480 pPacketInfo->BufferCount = 0;
481 pPacketInfo->pFirstBuffer = NULL;
482 pPacketInfo->PhysicalBufferCount = 0;
483 pPacketInfo->TotalPacketLength = 0;
485 *pSrcBufVA = NULL;
486 *pSrcBufLen = 0;
487 *ppPacket = NULL;
491 // not yet support MBSS
492 PNET_DEV get_netdev_from_bssid(
493 IN PRTMP_ADAPTER pAd,
494 IN UCHAR FromWhichBSSID)
496 PNET_DEV dev_p = NULL;
498 #ifdef CONFIG_STA_SUPPORT
499 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
501 dev_p = pAd->net_dev;
503 #endif // CONFIG_STA_SUPPORT //
505 ASSERT(dev_p);
506 return dev_p; /* return one of MBSS */
509 PNDIS_PACKET DuplicatePacket(
510 IN PRTMP_ADAPTER pAd,
511 IN PNDIS_PACKET pPacket,
512 IN UCHAR FromWhichBSSID)
514 struct sk_buff *skb;
515 PNDIS_PACKET pRetPacket = NULL;
516 USHORT DataSize;
517 UCHAR *pData;
519 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
520 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
523 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
524 if (skb)
526 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
527 pRetPacket = OSPKT_TO_RTPKT(skb);
530 return pRetPacket;
534 PNDIS_PACKET duplicate_pkt(
535 IN PRTMP_ADAPTER pAd,
536 IN PUCHAR pHeader802_3,
537 IN UINT HdrLen,
538 IN PUCHAR pData,
539 IN ULONG DataSize,
540 IN UCHAR FromWhichBSSID)
542 struct sk_buff *skb;
543 PNDIS_PACKET pPacket = NULL;
546 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
548 skb_reserve(skb, 2);
549 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
550 skb_put(skb, HdrLen);
551 NdisMoveMemory(skb->tail, pData, DataSize);
552 skb_put(skb, DataSize);
553 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
554 pPacket = OSPKT_TO_RTPKT(skb);
557 return pPacket;
561 #define TKIP_TX_MIC_SIZE 8
562 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
563 IN PRTMP_ADAPTER pAd,
564 IN PNDIS_PACKET pPacket)
566 struct sk_buff *skb, *newskb;
569 skb = RTPKT_TO_OSPKT(pPacket);
570 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
572 // alloc a new skb and copy the packet
573 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
574 dev_kfree_skb_any(skb);
575 if (newskb == NULL)
577 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
578 return NULL;
580 skb = newskb;
583 return OSPKT_TO_RTPKT(skb);
589 PNDIS_PACKET ClonePacket(
590 IN PRTMP_ADAPTER pAd,
591 IN PNDIS_PACKET pPacket,
592 IN PUCHAR pData,
593 IN ULONG DataSize)
595 struct sk_buff *pRxPkt;
596 struct sk_buff *pClonedPkt;
598 ASSERT(pPacket);
599 pRxPkt = RTPKT_TO_OSPKT(pPacket);
601 // clone the packet
602 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
604 if (pClonedPkt)
606 // set the correct dataptr and data len
607 pClonedPkt->dev = pRxPkt->dev;
608 pClonedPkt->data = pData;
609 pClonedPkt->len = DataSize;
610 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
611 ASSERT(DataSize < 1530);
613 return pClonedPkt;
617 // change OS packet DataPtr and DataLen
619 void update_os_packet_info(
620 IN PRTMP_ADAPTER pAd,
621 IN RX_BLK *pRxBlk,
622 IN UCHAR FromWhichBSSID)
624 struct sk_buff *pOSPkt;
626 ASSERT(pRxBlk->pRxPacket);
627 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
629 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
630 pOSPkt->data = pRxBlk->pData;
631 pOSPkt->len = pRxBlk->DataSize;
632 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
636 void wlan_802_11_to_802_3_packet(
637 IN PRTMP_ADAPTER pAd,
638 IN RX_BLK *pRxBlk,
639 IN PUCHAR pHeader802_3,
640 IN UCHAR FromWhichBSSID)
642 struct sk_buff *pOSPkt;
644 ASSERT(pRxBlk->pRxPacket);
645 ASSERT(pHeader802_3);
647 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
649 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
650 pOSPkt->data = pRxBlk->pData;
651 pOSPkt->len = pRxBlk->DataSize;
652 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
655 // copy 802.3 header
659 #ifdef CONFIG_STA_SUPPORT
660 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
661 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
662 #endif // CONFIG_STA_SUPPORT //
667 void announce_802_3_packet(
668 IN PRTMP_ADAPTER pAd,
669 IN PNDIS_PACKET pPacket)
672 struct sk_buff *pRxPkt;
674 ASSERT(pPacket);
676 pRxPkt = RTPKT_TO_OSPKT(pPacket);
678 /* Push up the protocol stack */
679 #ifdef IKANOS_VX_1X0
680 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
681 #else
682 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
684 netif_rx(pRxPkt);
685 #endif // IKANOS_VX_1X0 //
689 PRTMP_SCATTER_GATHER_LIST
690 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
692 sg->NumberOfElements = 1;
693 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
694 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
695 return (sg);
698 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
700 unsigned char *pt;
701 int x;
703 if (RTDebugLevel < RT_DEBUG_TRACE)
704 return;
706 pt = pSrcBufVA;
707 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
708 for (x=0; x<SrcBufLen; x++)
710 if (x % 16 == 0)
711 printk("0x%04x : ", x);
712 printk("%02x ", ((unsigned char)pt[x]));
713 if (x%16 == 15) printk("\n");
715 printk("\n");
719 ========================================================================
721 Routine Description:
722 Send log message through wireless event
724 Support standard iw_event with IWEVCUSTOM. It is used below.
726 iwreq_data.data.flags is used to store event_flag that is defined by user.
727 iwreq_data.data.length is the length of the event log.
729 The format of the event log is composed of the entry's MAC address and
730 the desired log message (refer to pWirelessEventText).
732 ex: 11:22:33:44:55:66 has associated successfully
734 p.s. The requirement of Wireless Extension is v15 or newer.
736 ========================================================================
738 VOID RTMPSendWirelessEvent(
739 IN PRTMP_ADAPTER pAd,
740 IN USHORT Event_flag,
741 IN PUCHAR pAddr,
742 IN UCHAR BssIdx,
743 IN CHAR Rssi)
745 #if WIRELESS_EXT >= 15
747 union iwreq_data wrqu;
748 PUCHAR pBuf = NULL, pBufPtr = NULL;
749 USHORT event, type, BufLen;
750 UCHAR event_table_len = 0;
752 type = Event_flag & 0xFF00;
753 event = Event_flag & 0x00FF;
755 switch (type)
757 case IW_SYS_EVENT_FLAG_START:
758 event_table_len = IW_SYS_EVENT_TYPE_NUM;
759 break;
761 case IW_SPOOF_EVENT_FLAG_START:
762 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
763 break;
765 case IW_FLOOD_EVENT_FLAG_START:
766 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
767 break;
770 if (event_table_len == 0)
772 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
773 return;
776 if (event >= event_table_len)
778 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
779 return;
782 //Allocate memory and copy the msg.
783 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
785 //Prepare the payload
786 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
788 pBufPtr = pBuf;
790 if (pAddr)
791 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
792 else if (BssIdx < MAX_MBSSID_NUM)
793 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
794 else
795 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
797 if (type == IW_SYS_EVENT_FLAG_START)
798 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
799 else if (type == IW_SPOOF_EVENT_FLAG_START)
800 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
801 else if (type == IW_FLOOD_EVENT_FLAG_START)
802 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
803 else
804 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
806 pBufPtr[pBufPtr - pBuf] = '\0';
807 BufLen = pBufPtr - pBuf;
809 memset(&wrqu, 0, sizeof(wrqu));
810 wrqu.data.flags = Event_flag;
811 wrqu.data.length = BufLen;
813 //send wireless event
814 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
816 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
818 kfree(pBuf);
820 else
821 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
822 #else
823 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
824 #endif /* WIRELESS_EXT >= 15 */
828 #ifdef CONFIG_STA_SUPPORT
829 void send_monitor_packets(
830 IN PRTMP_ADAPTER pAd,
831 IN RX_BLK *pRxBlk)
833 struct sk_buff *pOSPkt;
834 wlan_ng_prism2_header *ph;
835 int rate_index = 0;
836 USHORT header_len = 0;
837 UCHAR temp_header[40] = {0};
839 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
840 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10,
841 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
844 ASSERT(pRxBlk->pRxPacket);
845 if (pRxBlk->DataSize < 10)
847 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
848 goto err_free_sk_buff;
851 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
853 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
854 goto err_free_sk_buff;
857 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
858 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
859 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
861 pRxBlk->DataSize -= LENGTH_802_11;
862 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
863 (pRxBlk->pHeader->FC.FrDs == 1))
864 header_len = LENGTH_802_11_WITH_ADDR4;
865 else
866 header_len = LENGTH_802_11;
868 // QOS
869 if (pRxBlk->pHeader->FC.SubType & 0x08)
871 header_len += 2;
872 // Data skip QOS contorl field
873 pRxBlk->DataSize -=2;
876 // Order bit: A-Ralink or HTC+
877 if (pRxBlk->pHeader->FC.Order)
879 header_len += 4;
880 // Data skip HTC contorl field
881 pRxBlk->DataSize -= 4;
884 // Copy Header
885 if (header_len <= 40)
886 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
888 // skip HW padding
889 if (pRxBlk->RxD.L2PAD)
890 pRxBlk->pData += (header_len + 2);
891 else
892 pRxBlk->pData += header_len;
893 } //end if
896 if (pRxBlk->DataSize < pOSPkt->len) {
897 skb_trim(pOSPkt,pRxBlk->DataSize);
898 } else {
899 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
900 } //end if
902 if ((pRxBlk->pData - pOSPkt->data) > 0) {
903 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
904 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
905 } //end if
907 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
908 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
909 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
910 goto err_free_sk_buff;
911 } //end if
912 } //end if
914 if (header_len > 0)
915 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
917 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
918 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
920 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
921 ph->msglen = sizeof(wlan_ng_prism2_header);
922 strcpy(ph->devname, pAd->net_dev->name);
924 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
925 ph->hosttime.status = 0;
926 ph->hosttime.len = 4;
927 ph->hosttime.data = jiffies;
929 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
930 ph->mactime.status = 0;
931 ph->mactime.len = 0;
932 ph->mactime.data = 0;
934 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
935 ph->istx.status = 0;
936 ph->istx.len = 0;
937 ph->istx.data = 0;
939 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
940 ph->channel.status = 0;
941 ph->channel.len = 4;
943 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
945 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
946 ph->rssi.status = 0;
947 ph->rssi.len = 4;
948 ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
950 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
951 ph->signal.status = 0;
952 ph->signal.len = 4;
953 ph->signal.data = 0; //rssi + noise;
955 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
956 ph->noise.status = 0;
957 ph->noise.len = 4;
958 ph->noise.data = 0;
960 #ifdef DOT11_N_SUPPORT
961 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
963 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
965 else
966 #endif // DOT11_N_SUPPORT //
967 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
968 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
969 else
970 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
971 if (rate_index < 0)
972 rate_index = 0;
973 if (rate_index > 255)
974 rate_index = 255;
976 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
977 ph->rate.status = 0;
978 ph->rate.len = 4;
979 ph->rate.data = ralinkrate[rate_index];
981 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
982 ph->frmlen.status = 0;
983 ph->frmlen.len = 4;
984 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
987 pOSPkt->pkt_type = PACKET_OTHERHOST;
988 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
989 pOSPkt->ip_summed = CHECKSUM_NONE;
990 netif_rx(pOSPkt);
992 return;
994 err_free_sk_buff:
995 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
996 return;
999 #endif // CONFIG_STA_SUPPORT //
1002 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1004 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1006 allow_signal(SIGTERM);
1007 allow_signal(SIGKILL);
1008 current->flags |= PF_NOFREEZE;
1010 /* signal that we've started the thread */
1011 complete(pNotify);
1014 void RTMP_IndicateMediaState(
1015 IN PRTMP_ADAPTER pAd)
1017 if (pAd->CommonCfg.bWirelessEvent)
1019 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1021 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1023 else
1025 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);