USB: musb_hdrc: another davinci buildfix (otg related)
[linux-2.6.git] / drivers / staging / rt2860 / rt_linux.c
blobf14500931efbdce7714f4c981c8b6a71030f413b
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 #ifdef RT2860
52 BUILD_TIMER_FUNCTION(PsPollWakeExec);
53 BUILD_TIMER_FUNCTION(RadioOnExec);
54 #endif // RT2860 //
55 #ifdef QOS_DLS_SUPPORT
56 BUILD_TIMER_FUNCTION(DlsTimeoutAction);
57 #endif // QOS_DLS_SUPPORT //
58 #endif // CONFIG_STA_SUPPORT //
60 // for wireless system event message
61 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
62 // system status event
63 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
64 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
65 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
66 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
67 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
68 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
69 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
70 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
71 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
72 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
73 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
74 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
75 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
76 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
77 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
78 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
79 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
80 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
81 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
84 // for wireless IDS_spoof_attack event message
85 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
86 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
87 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
88 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
89 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
90 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
91 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
92 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
93 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
94 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
95 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
98 // for wireless IDS_flooding_attack event message
99 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
100 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
101 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
102 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
103 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
104 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
105 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
106 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
109 /* timeout -- ms */
110 VOID RTMP_SetPeriodicTimer(
111 IN NDIS_MINIPORT_TIMER *pTimer,
112 IN unsigned long timeout)
114 timeout = ((timeout*HZ) / 1000);
115 pTimer->expires = jiffies + timeout;
116 add_timer(pTimer);
119 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
120 VOID RTMP_OS_Init_Timer(
121 IN PRTMP_ADAPTER pAd,
122 IN NDIS_MINIPORT_TIMER *pTimer,
123 IN TIMER_FUNCTION function,
124 IN PVOID data)
126 init_timer(pTimer);
127 pTimer->data = (unsigned long)data;
128 pTimer->function = function;
132 VOID RTMP_OS_Add_Timer(
133 IN NDIS_MINIPORT_TIMER *pTimer,
134 IN unsigned long timeout)
136 if (timer_pending(pTimer))
137 return;
139 timeout = ((timeout*HZ) / 1000);
140 pTimer->expires = jiffies + timeout;
141 add_timer(pTimer);
144 VOID RTMP_OS_Mod_Timer(
145 IN NDIS_MINIPORT_TIMER *pTimer,
146 IN unsigned long timeout)
148 timeout = ((timeout*HZ) / 1000);
149 mod_timer(pTimer, jiffies + timeout);
152 VOID RTMP_OS_Del_Timer(
153 IN NDIS_MINIPORT_TIMER *pTimer,
154 OUT BOOLEAN *pCancelled)
156 if (timer_pending(pTimer))
158 *pCancelled = del_timer_sync(pTimer);
160 else
162 *pCancelled = TRUE;
167 VOID RTMP_OS_Release_Packet(
168 IN PRTMP_ADAPTER pAd,
169 IN PQUEUE_ENTRY pEntry)
171 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
174 // Unify all delay routine by using udelay
175 VOID RTMPusecDelay(
176 IN ULONG usec)
178 ULONG i;
180 for (i = 0; i < (usec / 50); i++)
181 udelay(50);
183 if (usec % 50)
184 udelay(usec % 50);
187 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
189 time->u.LowPart = jiffies;
192 // pAd MUST allow to be NULL
193 NDIS_STATUS os_alloc_mem(
194 IN PRTMP_ADAPTER pAd,
195 OUT PUCHAR *mem,
196 IN ULONG size)
198 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
199 if (*mem)
200 return (NDIS_STATUS_SUCCESS);
201 else
202 return (NDIS_STATUS_FAILURE);
205 // pAd MUST allow to be NULL
206 NDIS_STATUS os_free_mem(
207 IN PRTMP_ADAPTER pAd,
208 IN PUCHAR mem)
211 ASSERT(mem);
212 kfree(mem);
213 return (NDIS_STATUS_SUCCESS);
217 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
218 IN PRTMP_ADAPTER pAd,
219 IN ULONG Length)
221 struct sk_buff *pkt;
223 pkt = dev_alloc_skb(Length);
225 if (pkt == NULL)
227 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
230 if (pkt)
232 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
235 return (PNDIS_PACKET) pkt;
239 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
240 IN PRTMP_ADAPTER pAd,
241 IN ULONG Length,
242 IN BOOLEAN Cached,
243 OUT PVOID *VirtualAddress)
245 struct sk_buff *pkt;
247 pkt = dev_alloc_skb(Length);
249 if (pkt == NULL)
251 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
254 if (pkt)
256 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
257 *VirtualAddress = (PVOID) pkt->data;
259 else
261 *VirtualAddress = (PVOID) NULL;
264 return (PNDIS_PACKET) pkt;
268 VOID build_tx_packet(
269 IN PRTMP_ADAPTER pAd,
270 IN PNDIS_PACKET pPacket,
271 IN PUCHAR pFrame,
272 IN ULONG FrameLen)
275 struct sk_buff *pTxPkt;
277 ASSERT(pPacket);
278 pTxPkt = RTPKT_TO_OSPKT(pPacket);
280 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
283 VOID RTMPFreeAdapter(
284 IN PRTMP_ADAPTER pAd)
286 POS_COOKIE os_cookie;
287 int index;
289 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
291 kfree(pAd->BeaconBuf);
294 NdisFreeSpinLock(&pAd->MgmtRingLock);
296 #ifdef RT2860
297 NdisFreeSpinLock(&pAd->RxRingLock);
298 #endif // RT2860 //
300 for (index =0 ; index < NUM_OF_TX_RING; index++)
302 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
303 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
304 pAd->DeQueueRunning[index] = FALSE;
307 NdisFreeSpinLock(&pAd->irq_lock);
309 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
310 kfree(os_cookie);
313 BOOLEAN OS_Need_Clone_Packet(void)
315 return (FALSE);
321 ========================================================================
323 Routine Description:
324 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
325 must have only one NDIS BUFFER
326 return - byte copied. 0 means can't create NDIS PACKET
327 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
329 Arguments:
330 pAd Pointer to our adapter
331 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
332 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
334 Return Value:
335 NDIS_STATUS_SUCCESS
336 NDIS_STATUS_FAILURE
338 Note:
340 ========================================================================
342 NDIS_STATUS RTMPCloneNdisPacket(
343 IN PRTMP_ADAPTER pAd,
344 IN BOOLEAN pInsAMSDUHdr,
345 IN PNDIS_PACKET pInPacket,
346 OUT PNDIS_PACKET *ppOutPacket)
349 struct sk_buff *pkt;
351 ASSERT(pInPacket);
352 ASSERT(ppOutPacket);
354 // 1. Allocate a packet
355 pkt = dev_alloc_skb(2048);
357 if (pkt == NULL)
359 return NDIS_STATUS_FAILURE;
362 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
363 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
364 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
367 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
369 printk("###Clone###\n");
371 return NDIS_STATUS_SUCCESS;
375 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
376 NDIS_STATUS RTMPAllocateNdisPacket(
377 IN PRTMP_ADAPTER pAd,
378 OUT PNDIS_PACKET *ppPacket,
379 IN PUCHAR pHeader,
380 IN UINT HeaderLen,
381 IN PUCHAR pData,
382 IN UINT DataLen)
384 PNDIS_PACKET pPacket;
385 ASSERT(pData);
386 ASSERT(DataLen);
388 // 1. Allocate a packet
389 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
390 if (pPacket == NULL)
392 *ppPacket = NULL;
393 #ifdef DEBUG
394 printk("RTMPAllocateNdisPacket Fail\n\n");
395 #endif
396 return NDIS_STATUS_FAILURE;
399 // 2. clone the frame content
400 if (HeaderLen > 0)
401 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
402 if (DataLen > 0)
403 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
405 // 3. update length of packet
406 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
408 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
409 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
410 *ppPacket = pPacket;
411 return NDIS_STATUS_SUCCESS;
415 ========================================================================
416 Description:
417 This routine frees a miniport internally allocated NDIS_PACKET and its
418 corresponding NDIS_BUFFER and allocated memory.
419 ========================================================================
421 VOID RTMPFreeNdisPacket(
422 IN PRTMP_ADAPTER pAd,
423 IN PNDIS_PACKET pPacket)
425 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
429 // IRQL = DISPATCH_LEVEL
430 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
431 // scatter gather buffer
432 NDIS_STATUS Sniff2BytesFromNdisBuffer(
433 IN PNDIS_BUFFER pFirstBuffer,
434 IN UCHAR DesiredOffset,
435 OUT PUCHAR pByte0,
436 OUT PUCHAR pByte1)
438 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
439 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
441 return NDIS_STATUS_SUCCESS;
445 void RTMP_QueryPacketInfo(
446 IN PNDIS_PACKET pPacket,
447 OUT PACKET_INFO *pPacketInfo,
448 OUT PUCHAR *pSrcBufVA,
449 OUT UINT *pSrcBufLen)
451 pPacketInfo->BufferCount = 1;
452 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
453 pPacketInfo->PhysicalBufferCount = 1;
454 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
456 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
457 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
460 void RTMP_QueryNextPacketInfo(
461 IN PNDIS_PACKET *ppPacket,
462 OUT PACKET_INFO *pPacketInfo,
463 OUT PUCHAR *pSrcBufVA,
464 OUT UINT *pSrcBufLen)
466 PNDIS_PACKET pPacket = NULL;
468 if (*ppPacket)
469 pPacket = GET_OS_PKT_NEXT(*ppPacket);
471 if (pPacket)
473 pPacketInfo->BufferCount = 1;
474 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
475 pPacketInfo->PhysicalBufferCount = 1;
476 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
478 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
479 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
480 *ppPacket = GET_OS_PKT_NEXT(pPacket);
482 else
484 pPacketInfo->BufferCount = 0;
485 pPacketInfo->pFirstBuffer = NULL;
486 pPacketInfo->PhysicalBufferCount = 0;
487 pPacketInfo->TotalPacketLength = 0;
489 *pSrcBufVA = NULL;
490 *pSrcBufLen = 0;
491 *ppPacket = NULL;
495 // not yet support MBSS
496 PNET_DEV get_netdev_from_bssid(
497 IN PRTMP_ADAPTER pAd,
498 IN UCHAR FromWhichBSSID)
500 PNET_DEV dev_p = NULL;
502 #ifdef CONFIG_STA_SUPPORT
503 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
505 dev_p = pAd->net_dev;
507 #endif // CONFIG_STA_SUPPORT //
509 ASSERT(dev_p);
510 return dev_p; /* return one of MBSS */
513 PNDIS_PACKET DuplicatePacket(
514 IN PRTMP_ADAPTER pAd,
515 IN PNDIS_PACKET pPacket,
516 IN UCHAR FromWhichBSSID)
518 struct sk_buff *skb;
519 PNDIS_PACKET pRetPacket = NULL;
520 USHORT DataSize;
521 UCHAR *pData;
523 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
524 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
527 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
528 if (skb)
530 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
531 pRetPacket = OSPKT_TO_RTPKT(skb);
534 return pRetPacket;
538 PNDIS_PACKET duplicate_pkt(
539 IN PRTMP_ADAPTER pAd,
540 IN PUCHAR pHeader802_3,
541 IN UINT HdrLen,
542 IN PUCHAR pData,
543 IN ULONG DataSize,
544 IN UCHAR FromWhichBSSID)
546 struct sk_buff *skb;
547 PNDIS_PACKET pPacket = NULL;
550 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
552 skb_reserve(skb, 2);
553 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
554 skb_put(skb, HdrLen);
555 NdisMoveMemory(skb->tail, pData, DataSize);
556 skb_put(skb, DataSize);
557 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
558 pPacket = OSPKT_TO_RTPKT(skb);
561 return pPacket;
565 #define TKIP_TX_MIC_SIZE 8
566 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
567 IN PRTMP_ADAPTER pAd,
568 IN PNDIS_PACKET pPacket)
570 struct sk_buff *skb, *newskb;
573 skb = RTPKT_TO_OSPKT(pPacket);
574 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
576 // alloc a new skb and copy the packet
577 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
578 dev_kfree_skb_any(skb);
579 if (newskb == NULL)
581 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
582 return NULL;
584 skb = newskb;
587 return OSPKT_TO_RTPKT(skb);
593 PNDIS_PACKET ClonePacket(
594 IN PRTMP_ADAPTER pAd,
595 IN PNDIS_PACKET pPacket,
596 IN PUCHAR pData,
597 IN ULONG DataSize)
599 struct sk_buff *pRxPkt;
600 struct sk_buff *pClonedPkt;
602 ASSERT(pPacket);
603 pRxPkt = RTPKT_TO_OSPKT(pPacket);
605 // clone the packet
606 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
608 if (pClonedPkt)
610 // set the correct dataptr and data len
611 pClonedPkt->dev = pRxPkt->dev;
612 pClonedPkt->data = pData;
613 pClonedPkt->len = DataSize;
614 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
615 ASSERT(DataSize < 1530);
617 return pClonedPkt;
621 // change OS packet DataPtr and DataLen
623 void update_os_packet_info(
624 IN PRTMP_ADAPTER pAd,
625 IN RX_BLK *pRxBlk,
626 IN UCHAR FromWhichBSSID)
628 struct sk_buff *pOSPkt;
630 ASSERT(pRxBlk->pRxPacket);
631 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
633 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
634 pOSPkt->data = pRxBlk->pData;
635 pOSPkt->len = pRxBlk->DataSize;
636 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
640 void wlan_802_11_to_802_3_packet(
641 IN PRTMP_ADAPTER pAd,
642 IN RX_BLK *pRxBlk,
643 IN PUCHAR pHeader802_3,
644 IN UCHAR FromWhichBSSID)
646 struct sk_buff *pOSPkt;
648 ASSERT(pRxBlk->pRxPacket);
649 ASSERT(pHeader802_3);
651 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
653 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
654 pOSPkt->data = pRxBlk->pData;
655 pOSPkt->len = pRxBlk->DataSize;
656 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
659 // copy 802.3 header
663 #ifdef CONFIG_STA_SUPPORT
664 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
665 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
666 #endif // CONFIG_STA_SUPPORT //
671 void announce_802_3_packet(
672 IN PRTMP_ADAPTER pAd,
673 IN PNDIS_PACKET pPacket)
676 struct sk_buff *pRxPkt;
678 ASSERT(pPacket);
680 pRxPkt = RTPKT_TO_OSPKT(pPacket);
682 /* Push up the protocol stack */
683 #ifdef IKANOS_VX_1X0
684 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
685 #else
686 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
688 netif_rx(pRxPkt);
689 #endif // IKANOS_VX_1X0 //
693 PRTMP_SCATTER_GATHER_LIST
694 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
696 sg->NumberOfElements = 1;
697 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
698 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
699 return (sg);
702 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
704 unsigned char *pt;
705 int x;
707 if (RTDebugLevel < RT_DEBUG_TRACE)
708 return;
710 pt = pSrcBufVA;
711 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
712 for (x=0; x<SrcBufLen; x++)
714 if (x % 16 == 0)
715 printk("0x%04x : ", x);
716 printk("%02x ", ((unsigned char)pt[x]));
717 if (x%16 == 15) printk("\n");
719 printk("\n");
723 ========================================================================
725 Routine Description:
726 Send log message through wireless event
728 Support standard iw_event with IWEVCUSTOM. It is used below.
730 iwreq_data.data.flags is used to store event_flag that is defined by user.
731 iwreq_data.data.length is the length of the event log.
733 The format of the event log is composed of the entry's MAC address and
734 the desired log message (refer to pWirelessEventText).
736 ex: 11:22:33:44:55:66 has associated successfully
738 p.s. The requirement of Wireless Extension is v15 or newer.
740 ========================================================================
742 VOID RTMPSendWirelessEvent(
743 IN PRTMP_ADAPTER pAd,
744 IN USHORT Event_flag,
745 IN PUCHAR pAddr,
746 IN UCHAR BssIdx,
747 IN CHAR Rssi)
749 #if WIRELESS_EXT >= 15
751 union iwreq_data wrqu;
752 PUCHAR pBuf = NULL, pBufPtr = NULL;
753 USHORT event, type, BufLen;
754 UCHAR event_table_len = 0;
756 type = Event_flag & 0xFF00;
757 event = Event_flag & 0x00FF;
759 switch (type)
761 case IW_SYS_EVENT_FLAG_START:
762 event_table_len = IW_SYS_EVENT_TYPE_NUM;
763 break;
765 case IW_SPOOF_EVENT_FLAG_START:
766 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
767 break;
769 case IW_FLOOD_EVENT_FLAG_START:
770 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
771 break;
774 if (event_table_len == 0)
776 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
777 return;
780 if (event >= event_table_len)
782 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
783 return;
786 //Allocate memory and copy the msg.
787 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
789 //Prepare the payload
790 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
792 pBufPtr = pBuf;
794 if (pAddr)
795 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
796 else if (BssIdx < MAX_MBSSID_NUM)
797 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
798 else
799 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
801 if (type == IW_SYS_EVENT_FLAG_START)
802 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
803 else if (type == IW_SPOOF_EVENT_FLAG_START)
804 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
805 else if (type == IW_FLOOD_EVENT_FLAG_START)
806 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
807 else
808 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
810 pBufPtr[pBufPtr - pBuf] = '\0';
811 BufLen = pBufPtr - pBuf;
813 memset(&wrqu, 0, sizeof(wrqu));
814 wrqu.data.flags = Event_flag;
815 wrqu.data.length = BufLen;
817 //send wireless event
818 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
820 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
822 kfree(pBuf);
824 else
825 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
826 #else
827 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
828 #endif /* WIRELESS_EXT >= 15 */
832 #ifdef CONFIG_STA_SUPPORT
833 void send_monitor_packets(
834 IN PRTMP_ADAPTER pAd,
835 IN RX_BLK *pRxBlk)
837 struct sk_buff *pOSPkt;
838 wlan_ng_prism2_header *ph;
839 int rate_index = 0;
840 USHORT header_len = 0;
841 UCHAR temp_header[40] = {0};
843 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
844 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,
845 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};
848 ASSERT(pRxBlk->pRxPacket);
849 if (pRxBlk->DataSize < 10)
851 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
852 goto err_free_sk_buff;
855 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
857 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
858 goto err_free_sk_buff;
861 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
862 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
863 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
865 pRxBlk->DataSize -= LENGTH_802_11;
866 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
867 (pRxBlk->pHeader->FC.FrDs == 1))
868 header_len = LENGTH_802_11_WITH_ADDR4;
869 else
870 header_len = LENGTH_802_11;
872 // QOS
873 if (pRxBlk->pHeader->FC.SubType & 0x08)
875 header_len += 2;
876 // Data skip QOS contorl field
877 pRxBlk->DataSize -=2;
880 // Order bit: A-Ralink or HTC+
881 if (pRxBlk->pHeader->FC.Order)
883 header_len += 4;
884 // Data skip HTC contorl field
885 pRxBlk->DataSize -= 4;
888 // Copy Header
889 if (header_len <= 40)
890 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
892 // skip HW padding
893 if (pRxBlk->RxD.L2PAD)
894 pRxBlk->pData += (header_len + 2);
895 else
896 pRxBlk->pData += header_len;
897 } //end if
900 if (pRxBlk->DataSize < pOSPkt->len) {
901 skb_trim(pOSPkt,pRxBlk->DataSize);
902 } else {
903 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
904 } //end if
906 if ((pRxBlk->pData - pOSPkt->data) > 0) {
907 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
908 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
909 } //end if
911 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
912 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
913 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
914 goto err_free_sk_buff;
915 } //end if
916 } //end if
918 if (header_len > 0)
919 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
921 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
922 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
924 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
925 ph->msglen = sizeof(wlan_ng_prism2_header);
926 strcpy(ph->devname, pAd->net_dev->name);
928 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
929 ph->hosttime.status = 0;
930 ph->hosttime.len = 4;
931 ph->hosttime.data = jiffies;
933 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
934 ph->mactime.status = 0;
935 ph->mactime.len = 0;
936 ph->mactime.data = 0;
938 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
939 ph->istx.status = 0;
940 ph->istx.len = 0;
941 ph->istx.data = 0;
943 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
944 ph->channel.status = 0;
945 ph->channel.len = 4;
947 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
949 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
950 ph->rssi.status = 0;
951 ph->rssi.len = 4;
952 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));;
954 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
955 ph->signal.status = 0;
956 ph->signal.len = 4;
957 ph->signal.data = 0; //rssi + noise;
959 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
960 ph->noise.status = 0;
961 ph->noise.len = 4;
962 ph->noise.data = 0;
964 #ifdef DOT11_N_SUPPORT
965 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
967 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
969 else
970 #endif // DOT11_N_SUPPORT //
971 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
972 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
973 else
974 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
975 if (rate_index < 0)
976 rate_index = 0;
977 if (rate_index > 255)
978 rate_index = 255;
980 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
981 ph->rate.status = 0;
982 ph->rate.len = 4;
983 ph->rate.data = ralinkrate[rate_index];
985 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
986 ph->frmlen.status = 0;
987 ph->frmlen.len = 4;
988 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
991 pOSPkt->pkt_type = PACKET_OTHERHOST;
992 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
993 pOSPkt->ip_summed = CHECKSUM_NONE;
994 netif_rx(pOSPkt);
996 return;
998 err_free_sk_buff:
999 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1000 return;
1003 #endif // CONFIG_STA_SUPPORT //
1006 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1009 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1010 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1012 allow_signal(SIGTERM);
1013 allow_signal(SIGKILL);
1014 current->flags |= PF_NOFREEZE;
1015 #else
1016 unsigned long flags;
1018 daemonize();
1019 reparent_to_init();
1020 strcpy(current->comm, pThreadName);
1022 siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1024 /* Allow interception of SIGKILL only
1025 * Don't allow other signals to interrupt the transmission */
1026 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1027 spin_lock_irqsave(&current->sigmask_lock, flags);
1028 flush_signals(current);
1029 recalc_sigpending(current);
1030 spin_unlock_irqrestore(&current->sigmask_lock, flags);
1031 #endif
1032 #endif
1034 /* signal that we've started the thread */
1035 complete(pNotify);
1039 void RTMP_IndicateMediaState(
1040 IN PRTMP_ADAPTER pAd)
1042 if (pAd->CommonCfg.bWirelessEvent)
1044 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1046 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1048 else
1050 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);