ipw2200: Set core hw rfkill status when hardware changes state
[firewire-audio.git] / drivers / staging / rt2860 / rt_linux.c
blobb396a9b570e2f165ed1bb966af75932fe6a4622e
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);
36 #ifdef RT2870
37 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
38 #endif // RT2870 //
40 BUILD_TIMER_FUNCTION(BeaconTimeout);
41 BUILD_TIMER_FUNCTION(ScanTimeout);
42 BUILD_TIMER_FUNCTION(AuthTimeout);
43 BUILD_TIMER_FUNCTION(AssocTimeout);
44 BUILD_TIMER_FUNCTION(ReassocTimeout);
45 BUILD_TIMER_FUNCTION(DisassocTimeout);
46 BUILD_TIMER_FUNCTION(LinkDownExec);
47 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
48 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
49 #ifdef RT2860
50 BUILD_TIMER_FUNCTION(PsPollWakeExec);
51 BUILD_TIMER_FUNCTION(RadioOnExec);
52 #endif
54 // for wireless system event message
55 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
56 // system status event
57 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
58 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
59 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
60 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
61 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
62 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
63 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
64 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
65 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
66 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
67 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
68 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
69 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
70 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
71 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
72 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
73 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
74 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
75 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
78 // for wireless IDS_spoof_attack event message
79 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
80 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
81 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
82 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
83 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
84 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
85 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
86 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
87 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
88 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
89 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
92 // for wireless IDS_flooding_attack event message
93 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
94 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
95 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
96 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
97 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
98 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
99 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
100 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
103 /* timeout -- ms */
104 VOID RTMP_SetPeriodicTimer(
105 IN NDIS_MINIPORT_TIMER *pTimer,
106 IN unsigned long timeout)
108 timeout = ((timeout*HZ) / 1000);
109 pTimer->expires = jiffies + timeout;
110 add_timer(pTimer);
113 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
114 VOID RTMP_OS_Init_Timer(
115 IN PRTMP_ADAPTER pAd,
116 IN NDIS_MINIPORT_TIMER *pTimer,
117 IN TIMER_FUNCTION function,
118 IN PVOID data)
120 init_timer(pTimer);
121 pTimer->data = (unsigned long)data;
122 pTimer->function = function;
126 VOID RTMP_OS_Add_Timer(
127 IN NDIS_MINIPORT_TIMER *pTimer,
128 IN unsigned long timeout)
130 if (timer_pending(pTimer))
131 return;
133 timeout = ((timeout*HZ) / 1000);
134 pTimer->expires = jiffies + timeout;
135 add_timer(pTimer);
138 VOID RTMP_OS_Mod_Timer(
139 IN NDIS_MINIPORT_TIMER *pTimer,
140 IN unsigned long timeout)
142 timeout = ((timeout*HZ) / 1000);
143 mod_timer(pTimer, jiffies + timeout);
146 VOID RTMP_OS_Del_Timer(
147 IN NDIS_MINIPORT_TIMER *pTimer,
148 OUT BOOLEAN *pCancelled)
150 if (timer_pending(pTimer))
152 *pCancelled = del_timer_sync(pTimer);
154 else
156 *pCancelled = TRUE;
161 VOID RTMP_OS_Release_Packet(
162 IN PRTMP_ADAPTER pAd,
163 IN PQUEUE_ENTRY pEntry)
165 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
168 // Unify all delay routine by using udelay
169 VOID RTMPusecDelay(
170 IN ULONG usec)
172 ULONG i;
174 for (i = 0; i < (usec / 50); i++)
175 udelay(50);
177 if (usec % 50)
178 udelay(usec % 50);
181 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
183 time->u.LowPart = jiffies;
186 // pAd MUST allow to be NULL
187 NDIS_STATUS os_alloc_mem(
188 IN PRTMP_ADAPTER pAd,
189 OUT PUCHAR *mem,
190 IN ULONG size)
192 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
193 if (*mem)
194 return (NDIS_STATUS_SUCCESS);
195 else
196 return (NDIS_STATUS_FAILURE);
199 // pAd MUST allow to be NULL
200 NDIS_STATUS os_free_mem(
201 IN PRTMP_ADAPTER pAd,
202 IN PUCHAR mem)
205 ASSERT(mem);
206 kfree(mem);
207 return (NDIS_STATUS_SUCCESS);
211 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
212 IN PRTMP_ADAPTER pAd,
213 IN ULONG Length)
215 struct sk_buff *pkt;
217 pkt = dev_alloc_skb(Length);
219 if (pkt == NULL)
221 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
224 if (pkt)
226 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
229 return (PNDIS_PACKET) pkt;
233 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
234 IN PRTMP_ADAPTER pAd,
235 IN ULONG Length,
236 IN BOOLEAN Cached,
237 OUT PVOID *VirtualAddress)
239 struct sk_buff *pkt;
241 pkt = dev_alloc_skb(Length);
243 if (pkt == NULL)
245 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
248 if (pkt)
250 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
251 *VirtualAddress = (PVOID) pkt->data;
253 else
255 *VirtualAddress = (PVOID) NULL;
258 return (PNDIS_PACKET) pkt;
262 VOID build_tx_packet(
263 IN PRTMP_ADAPTER pAd,
264 IN PNDIS_PACKET pPacket,
265 IN PUCHAR pFrame,
266 IN ULONG FrameLen)
269 struct sk_buff *pTxPkt;
271 ASSERT(pPacket);
272 pTxPkt = RTPKT_TO_OSPKT(pPacket);
274 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
277 VOID RTMPFreeAdapter(
278 IN PRTMP_ADAPTER pAd)
280 POS_COOKIE os_cookie;
281 int index;
283 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
285 kfree(pAd->BeaconBuf);
288 NdisFreeSpinLock(&pAd->MgmtRingLock);
289 #ifdef RT2860
290 NdisFreeSpinLock(&pAd->RxRingLock);
291 #endif
292 for (index =0 ; index < NUM_OF_TX_RING; index++)
294 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
295 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
296 pAd->DeQueueRunning[index] = FALSE;
299 NdisFreeSpinLock(&pAd->irq_lock);
301 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
302 kfree(os_cookie);
305 BOOLEAN OS_Need_Clone_Packet(void)
307 return (FALSE);
313 ========================================================================
315 Routine Description:
316 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
317 must have only one NDIS BUFFER
318 return - byte copied. 0 means can't create NDIS PACKET
319 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
321 Arguments:
322 pAd Pointer to our adapter
323 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
324 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
326 Return Value:
327 NDIS_STATUS_SUCCESS
328 NDIS_STATUS_FAILURE
330 Note:
332 ========================================================================
334 NDIS_STATUS RTMPCloneNdisPacket(
335 IN PRTMP_ADAPTER pAd,
336 IN BOOLEAN pInsAMSDUHdr,
337 IN PNDIS_PACKET pInPacket,
338 OUT PNDIS_PACKET *ppOutPacket)
341 struct sk_buff *pkt;
343 ASSERT(pInPacket);
344 ASSERT(ppOutPacket);
346 // 1. Allocate a packet
347 pkt = dev_alloc_skb(2048);
349 if (pkt == NULL)
351 return NDIS_STATUS_FAILURE;
354 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
355 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
356 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
359 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
361 printk("###Clone###\n");
363 return NDIS_STATUS_SUCCESS;
367 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
368 NDIS_STATUS RTMPAllocateNdisPacket(
369 IN PRTMP_ADAPTER pAd,
370 OUT PNDIS_PACKET *ppPacket,
371 IN PUCHAR pHeader,
372 IN UINT HeaderLen,
373 IN PUCHAR pData,
374 IN UINT DataLen)
376 PNDIS_PACKET pPacket;
377 ASSERT(pData);
378 ASSERT(DataLen);
380 // 1. Allocate a packet
381 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
382 if (pPacket == NULL)
384 *ppPacket = NULL;
385 #ifdef DEBUG
386 printk("RTMPAllocateNdisPacket Fail\n\n");
387 #endif
388 return NDIS_STATUS_FAILURE;
391 // 2. clone the frame content
392 if (HeaderLen > 0)
393 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
394 if (DataLen > 0)
395 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
397 // 3. update length of packet
398 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
400 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
401 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
402 *ppPacket = pPacket;
403 return NDIS_STATUS_SUCCESS;
407 ========================================================================
408 Description:
409 This routine frees a miniport internally allocated NDIS_PACKET and its
410 corresponding NDIS_BUFFER and allocated memory.
411 ========================================================================
413 VOID RTMPFreeNdisPacket(
414 IN PRTMP_ADAPTER pAd,
415 IN PNDIS_PACKET pPacket)
417 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
421 // IRQL = DISPATCH_LEVEL
422 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
423 // scatter gather buffer
424 NDIS_STATUS Sniff2BytesFromNdisBuffer(
425 IN PNDIS_BUFFER pFirstBuffer,
426 IN UCHAR DesiredOffset,
427 OUT PUCHAR pByte0,
428 OUT PUCHAR pByte1)
430 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
431 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
433 return NDIS_STATUS_SUCCESS;
437 void RTMP_QueryPacketInfo(
438 IN PNDIS_PACKET pPacket,
439 OUT PACKET_INFO *pPacketInfo,
440 OUT PUCHAR *pSrcBufVA,
441 OUT UINT *pSrcBufLen)
443 pPacketInfo->BufferCount = 1;
444 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
445 pPacketInfo->PhysicalBufferCount = 1;
446 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
448 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
449 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
452 void RTMP_QueryNextPacketInfo(
453 IN PNDIS_PACKET *ppPacket,
454 OUT PACKET_INFO *pPacketInfo,
455 OUT PUCHAR *pSrcBufVA,
456 OUT UINT *pSrcBufLen)
458 PNDIS_PACKET pPacket = NULL;
460 if (*ppPacket)
461 pPacket = GET_OS_PKT_NEXT(*ppPacket);
463 if (pPacket)
465 pPacketInfo->BufferCount = 1;
466 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
467 pPacketInfo->PhysicalBufferCount = 1;
468 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
470 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
471 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
472 *ppPacket = GET_OS_PKT_NEXT(pPacket);
474 else
476 pPacketInfo->BufferCount = 0;
477 pPacketInfo->pFirstBuffer = NULL;
478 pPacketInfo->PhysicalBufferCount = 0;
479 pPacketInfo->TotalPacketLength = 0;
481 *pSrcBufVA = NULL;
482 *pSrcBufLen = 0;
483 *ppPacket = NULL;
487 // not yet support MBSS
488 PNET_DEV get_netdev_from_bssid(
489 IN PRTMP_ADAPTER pAd,
490 IN UCHAR FromWhichBSSID)
492 PNET_DEV dev_p = NULL;
494 dev_p = pAd->net_dev;
496 ASSERT(dev_p);
497 return dev_p; /* return one of MBSS */
500 PNDIS_PACKET DuplicatePacket(
501 IN PRTMP_ADAPTER pAd,
502 IN PNDIS_PACKET pPacket,
503 IN UCHAR FromWhichBSSID)
505 struct sk_buff *skb;
506 PNDIS_PACKET pRetPacket = NULL;
507 USHORT DataSize;
508 UCHAR *pData;
510 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
511 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
514 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
515 if (skb)
517 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
518 pRetPacket = OSPKT_TO_RTPKT(skb);
521 return pRetPacket;
525 PNDIS_PACKET duplicate_pkt(
526 IN PRTMP_ADAPTER pAd,
527 IN PUCHAR pHeader802_3,
528 IN UINT HdrLen,
529 IN PUCHAR pData,
530 IN ULONG DataSize,
531 IN UCHAR FromWhichBSSID)
533 struct sk_buff *skb;
534 PNDIS_PACKET pPacket = NULL;
537 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
539 skb_reserve(skb, 2);
540 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
541 skb_put(skb, HdrLen);
542 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
543 skb_put(skb, DataSize);
544 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
545 pPacket = OSPKT_TO_RTPKT(skb);
548 return pPacket;
552 #define TKIP_TX_MIC_SIZE 8
553 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
554 IN PRTMP_ADAPTER pAd,
555 IN PNDIS_PACKET pPacket)
557 struct sk_buff *skb, *newskb;
560 skb = RTPKT_TO_OSPKT(pPacket);
561 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
563 // alloc a new skb and copy the packet
564 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
565 dev_kfree_skb_any(skb);
566 if (newskb == NULL)
568 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
569 return NULL;
571 skb = newskb;
574 return OSPKT_TO_RTPKT(skb);
580 PNDIS_PACKET ClonePacket(
581 IN PRTMP_ADAPTER pAd,
582 IN PNDIS_PACKET pPacket,
583 IN PUCHAR pData,
584 IN ULONG DataSize)
586 struct sk_buff *pRxPkt;
587 struct sk_buff *pClonedPkt;
589 ASSERT(pPacket);
590 pRxPkt = RTPKT_TO_OSPKT(pPacket);
592 // clone the packet
593 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
595 if (pClonedPkt)
597 // set the correct dataptr and data len
598 pClonedPkt->dev = pRxPkt->dev;
599 pClonedPkt->data = pData;
600 pClonedPkt->len = DataSize;
601 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
602 ASSERT(DataSize < 1530);
604 return pClonedPkt;
608 // change OS packet DataPtr and DataLen
610 void update_os_packet_info(
611 IN PRTMP_ADAPTER pAd,
612 IN RX_BLK *pRxBlk,
613 IN UCHAR FromWhichBSSID)
615 struct sk_buff *pOSPkt;
617 ASSERT(pRxBlk->pRxPacket);
618 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
620 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
621 pOSPkt->data = pRxBlk->pData;
622 pOSPkt->len = pRxBlk->DataSize;
623 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
627 void wlan_802_11_to_802_3_packet(
628 IN PRTMP_ADAPTER pAd,
629 IN RX_BLK *pRxBlk,
630 IN PUCHAR pHeader802_3,
631 IN UCHAR FromWhichBSSID)
633 struct sk_buff *pOSPkt;
635 ASSERT(pRxBlk->pRxPacket);
636 ASSERT(pHeader802_3);
638 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
640 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
641 pOSPkt->data = pRxBlk->pData;
642 pOSPkt->len = pRxBlk->DataSize;
643 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
646 // copy 802.3 header
650 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
653 void announce_802_3_packet(
654 IN PRTMP_ADAPTER pAd,
655 IN PNDIS_PACKET pPacket)
658 struct sk_buff *pRxPkt;
660 ASSERT(pPacket);
662 pRxPkt = RTPKT_TO_OSPKT(pPacket);
664 /* Push up the protocol stack */
665 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
667 netif_rx(pRxPkt);
671 PRTMP_SCATTER_GATHER_LIST
672 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
674 sg->NumberOfElements = 1;
675 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
676 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
677 return (sg);
680 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
682 unsigned char *pt;
683 int x;
685 if (RTDebugLevel < RT_DEBUG_TRACE)
686 return;
688 pt = pSrcBufVA;
689 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
690 for (x=0; x<SrcBufLen; x++)
692 if (x % 16 == 0)
693 printk("0x%04x : ", x);
694 printk("%02x ", ((unsigned char)pt[x]));
695 if (x%16 == 15) printk("\n");
697 printk("\n");
701 ========================================================================
703 Routine Description:
704 Send log message through wireless event
706 Support standard iw_event with IWEVCUSTOM. It is used below.
708 iwreq_data.data.flags is used to store event_flag that is defined by user.
709 iwreq_data.data.length is the length of the event log.
711 The format of the event log is composed of the entry's MAC address and
712 the desired log message (refer to pWirelessEventText).
714 ex: 11:22:33:44:55:66 has associated successfully
716 p.s. The requirement of Wireless Extension is v15 or newer.
718 ========================================================================
720 VOID RTMPSendWirelessEvent(
721 IN PRTMP_ADAPTER pAd,
722 IN USHORT Event_flag,
723 IN PUCHAR pAddr,
724 IN UCHAR BssIdx,
725 IN CHAR Rssi)
728 union iwreq_data wrqu;
729 PUCHAR pBuf = NULL, pBufPtr = NULL;
730 USHORT event, type, BufLen;
731 UCHAR event_table_len = 0;
733 type = Event_flag & 0xFF00;
734 event = Event_flag & 0x00FF;
736 switch (type)
738 case IW_SYS_EVENT_FLAG_START:
739 event_table_len = IW_SYS_EVENT_TYPE_NUM;
740 break;
742 case IW_SPOOF_EVENT_FLAG_START:
743 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
744 break;
746 case IW_FLOOD_EVENT_FLAG_START:
747 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
748 break;
751 if (event_table_len == 0)
753 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
754 return;
757 if (event >= event_table_len)
759 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
760 return;
763 //Allocate memory and copy the msg.
764 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
766 //Prepare the payload
767 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
769 pBufPtr = pBuf;
771 if (pAddr)
772 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
773 else if (BssIdx < MAX_MBSSID_NUM)
774 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
775 else
776 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
778 if (type == IW_SYS_EVENT_FLAG_START)
779 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
780 else if (type == IW_SPOOF_EVENT_FLAG_START)
781 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
782 else if (type == IW_FLOOD_EVENT_FLAG_START)
783 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
784 else
785 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
787 pBufPtr[pBufPtr - pBuf] = '\0';
788 BufLen = pBufPtr - pBuf;
790 memset(&wrqu, 0, sizeof(wrqu));
791 wrqu.data.flags = Event_flag;
792 wrqu.data.length = BufLen;
794 //send wireless event
795 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
797 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
799 kfree(pBuf);
801 else
802 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
805 void send_monitor_packets(
806 IN PRTMP_ADAPTER pAd,
807 IN RX_BLK *pRxBlk)
809 struct sk_buff *pOSPkt;
810 wlan_ng_prism2_header *ph;
811 int rate_index = 0;
812 USHORT header_len = 0;
813 UCHAR temp_header[40] = {0};
815 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
816 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,
817 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};
820 ASSERT(pRxBlk->pRxPacket);
821 if (pRxBlk->DataSize < 10)
823 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
824 goto err_free_sk_buff;
827 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
829 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
830 goto err_free_sk_buff;
833 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
834 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
835 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
837 pRxBlk->DataSize -= LENGTH_802_11;
838 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
839 (pRxBlk->pHeader->FC.FrDs == 1))
840 header_len = LENGTH_802_11_WITH_ADDR4;
841 else
842 header_len = LENGTH_802_11;
844 // QOS
845 if (pRxBlk->pHeader->FC.SubType & 0x08)
847 header_len += 2;
848 // Data skip QOS contorl field
849 pRxBlk->DataSize -=2;
852 // Order bit: A-Ralink or HTC+
853 if (pRxBlk->pHeader->FC.Order)
855 header_len += 4;
856 // Data skip HTC contorl field
857 pRxBlk->DataSize -= 4;
860 // Copy Header
861 if (header_len <= 40)
862 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
864 // skip HW padding
865 if (pRxBlk->RxD.L2PAD)
866 pRxBlk->pData += (header_len + 2);
867 else
868 pRxBlk->pData += header_len;
869 } //end if
872 if (pRxBlk->DataSize < pOSPkt->len) {
873 skb_trim(pOSPkt,pRxBlk->DataSize);
874 } else {
875 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
876 } //end if
878 if ((pRxBlk->pData - pOSPkt->data) > 0) {
879 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
880 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
881 } //end if
883 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
884 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
885 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
886 goto err_free_sk_buff;
887 } //end if
888 } //end if
890 if (header_len > 0)
891 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
893 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
894 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
896 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
897 ph->msglen = sizeof(wlan_ng_prism2_header);
898 strcpy(ph->devname, pAd->net_dev->name);
900 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
901 ph->hosttime.status = 0;
902 ph->hosttime.len = 4;
903 ph->hosttime.data = jiffies;
905 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
906 ph->mactime.status = 0;
907 ph->mactime.len = 0;
908 ph->mactime.data = 0;
910 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
911 ph->istx.status = 0;
912 ph->istx.len = 0;
913 ph->istx.data = 0;
915 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
916 ph->channel.status = 0;
917 ph->channel.len = 4;
919 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
921 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
922 ph->rssi.status = 0;
923 ph->rssi.len = 4;
924 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));;
926 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
927 ph->signal.status = 0;
928 ph->signal.len = 4;
929 ph->signal.data = 0; //rssi + noise;
931 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
932 ph->noise.status = 0;
933 ph->noise.len = 4;
934 ph->noise.data = 0;
936 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
938 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
940 else
941 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
942 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
943 else
944 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
945 if (rate_index < 0)
946 rate_index = 0;
947 if (rate_index > 255)
948 rate_index = 255;
950 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
951 ph->rate.status = 0;
952 ph->rate.len = 4;
953 ph->rate.data = ralinkrate[rate_index];
955 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
956 ph->frmlen.status = 0;
957 ph->frmlen.len = 4;
958 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
961 pOSPkt->pkt_type = PACKET_OTHERHOST;
962 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
963 pOSPkt->ip_summed = CHECKSUM_NONE;
964 netif_rx(pOSPkt);
966 return;
968 err_free_sk_buff:
969 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
970 return;
974 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
976 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
978 allow_signal(SIGTERM);
979 allow_signal(SIGKILL);
980 current->flags |= PF_NOFREEZE;
982 /* signal that we've started the thread */
983 complete(pNotify);
986 void RTMP_IndicateMediaState(
987 IN PRTMP_ADAPTER pAd)
989 if (pAd->CommonCfg.bWirelessEvent)
991 if (pAd->IndicateMediaState == NdisMediaStateConnected)
993 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
995 else
997 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);