Staging: rt2870: remove dead CONFIG_AP_SUPPORT code
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt2870 / rt_linux.c
blobf7964f07ce56e5ed14be615e17a23e78c6b3f739
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(MlmeRssiReportExec);
34 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
35 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
36 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
37 #ifdef RT2870
38 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
39 #endif // RT2870 //
41 BUILD_TIMER_FUNCTION(BeaconTimeout);
42 BUILD_TIMER_FUNCTION(ScanTimeout);
43 BUILD_TIMER_FUNCTION(AuthTimeout);
44 BUILD_TIMER_FUNCTION(AssocTimeout);
45 BUILD_TIMER_FUNCTION(ReassocTimeout);
46 BUILD_TIMER_FUNCTION(DisassocTimeout);
47 BUILD_TIMER_FUNCTION(LinkDownExec);
48 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
49 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51 // for wireless system event message
52 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
53 // system status event
54 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
55 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
56 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
57 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
58 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
59 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
60 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
61 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
62 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
63 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
64 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
65 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
66 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
67 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
68 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
69 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
70 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
71 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
72 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
75 // for wireless IDS_spoof_attack event message
76 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
77 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
78 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
79 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
80 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
81 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
82 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
83 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
84 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
85 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
86 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
89 // for wireless IDS_flooding_attack event message
90 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
91 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
92 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
93 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
94 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
95 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
96 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
97 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
100 /* timeout -- ms */
101 VOID RTMP_SetPeriodicTimer(
102 IN NDIS_MINIPORT_TIMER *pTimer,
103 IN unsigned long timeout)
105 timeout = ((timeout*HZ) / 1000);
106 pTimer->expires = jiffies + timeout;
107 add_timer(pTimer);
110 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
111 VOID RTMP_OS_Init_Timer(
112 IN PRTMP_ADAPTER pAd,
113 IN NDIS_MINIPORT_TIMER *pTimer,
114 IN TIMER_FUNCTION function,
115 IN PVOID data)
117 init_timer(pTimer);
118 pTimer->data = (unsigned long)data;
119 pTimer->function = function;
123 VOID RTMP_OS_Add_Timer(
124 IN NDIS_MINIPORT_TIMER *pTimer,
125 IN unsigned long timeout)
127 if (timer_pending(pTimer))
128 return;
130 timeout = ((timeout*HZ) / 1000);
131 pTimer->expires = jiffies + timeout;
132 add_timer(pTimer);
135 VOID RTMP_OS_Mod_Timer(
136 IN NDIS_MINIPORT_TIMER *pTimer,
137 IN unsigned long timeout)
139 timeout = ((timeout*HZ) / 1000);
140 mod_timer(pTimer, jiffies + timeout);
143 VOID RTMP_OS_Del_Timer(
144 IN NDIS_MINIPORT_TIMER *pTimer,
145 OUT BOOLEAN *pCancelled)
147 if (timer_pending(pTimer))
149 *pCancelled = del_timer_sync(pTimer);
151 else
153 *pCancelled = TRUE;
158 VOID RTMP_OS_Release_Packet(
159 IN PRTMP_ADAPTER pAd,
160 IN PQUEUE_ENTRY pEntry)
162 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
165 // Unify all delay routine by using udelay
166 VOID RTMPusecDelay(
167 IN ULONG usec)
169 ULONG i;
171 for (i = 0; i < (usec / 50); i++)
172 udelay(50);
174 if (usec % 50)
175 udelay(usec % 50);
178 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
180 time->u.LowPart = jiffies;
183 // pAd MUST allow to be NULL
184 NDIS_STATUS os_alloc_mem(
185 IN PRTMP_ADAPTER pAd,
186 OUT PUCHAR *mem,
187 IN ULONG size)
189 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
190 if (*mem)
191 return (NDIS_STATUS_SUCCESS);
192 else
193 return (NDIS_STATUS_FAILURE);
196 // pAd MUST allow to be NULL
197 NDIS_STATUS os_free_mem(
198 IN PRTMP_ADAPTER pAd,
199 IN PUCHAR mem)
202 ASSERT(mem);
203 kfree(mem);
204 return (NDIS_STATUS_SUCCESS);
208 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
209 IN PRTMP_ADAPTER pAd,
210 IN ULONG Length)
212 struct sk_buff *pkt;
214 pkt = dev_alloc_skb(Length);
216 if (pkt == NULL)
218 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
221 if (pkt)
223 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
226 return (PNDIS_PACKET) pkt;
230 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
231 IN PRTMP_ADAPTER pAd,
232 IN ULONG Length,
233 IN BOOLEAN Cached,
234 OUT PVOID *VirtualAddress)
236 struct sk_buff *pkt;
238 pkt = dev_alloc_skb(Length);
240 if (pkt == NULL)
242 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
245 if (pkt)
247 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
248 *VirtualAddress = (PVOID) pkt->data;
250 else
252 *VirtualAddress = (PVOID) NULL;
255 return (PNDIS_PACKET) pkt;
259 VOID build_tx_packet(
260 IN PRTMP_ADAPTER pAd,
261 IN PNDIS_PACKET pPacket,
262 IN PUCHAR pFrame,
263 IN ULONG FrameLen)
266 struct sk_buff *pTxPkt;
268 ASSERT(pPacket);
269 pTxPkt = RTPKT_TO_OSPKT(pPacket);
271 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
274 VOID RTMPFreeAdapter(
275 IN PRTMP_ADAPTER pAd)
277 POS_COOKIE os_cookie;
278 int index;
280 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
282 kfree(pAd->BeaconBuf);
285 NdisFreeSpinLock(&pAd->MgmtRingLock);
288 for (index =0 ; index < NUM_OF_TX_RING; index++)
290 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
291 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
292 pAd->DeQueueRunning[index] = FALSE;
295 NdisFreeSpinLock(&pAd->irq_lock);
298 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
299 kfree(os_cookie);
302 BOOLEAN OS_Need_Clone_Packet(void)
304 return (FALSE);
310 ========================================================================
312 Routine Description:
313 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
314 must have only one NDIS BUFFER
315 return - byte copied. 0 means can't create NDIS PACKET
316 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
318 Arguments:
319 pAd Pointer to our adapter
320 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
321 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
323 Return Value:
324 NDIS_STATUS_SUCCESS
325 NDIS_STATUS_FAILURE
327 Note:
329 ========================================================================
331 NDIS_STATUS RTMPCloneNdisPacket(
332 IN PRTMP_ADAPTER pAd,
333 IN BOOLEAN pInsAMSDUHdr,
334 IN PNDIS_PACKET pInPacket,
335 OUT PNDIS_PACKET *ppOutPacket)
338 struct sk_buff *pkt;
340 ASSERT(pInPacket);
341 ASSERT(ppOutPacket);
343 // 1. Allocate a packet
344 pkt = dev_alloc_skb(2048);
346 if (pkt == NULL)
348 return NDIS_STATUS_FAILURE;
351 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
352 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
353 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
356 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
358 printk("###Clone###\n");
360 return NDIS_STATUS_SUCCESS;
364 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
365 NDIS_STATUS RTMPAllocateNdisPacket(
366 IN PRTMP_ADAPTER pAd,
367 OUT PNDIS_PACKET *ppPacket,
368 IN PUCHAR pHeader,
369 IN UINT HeaderLen,
370 IN PUCHAR pData,
371 IN UINT DataLen)
373 PNDIS_PACKET pPacket;
374 ASSERT(pData);
375 ASSERT(DataLen);
377 // 1. Allocate a packet
378 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
379 if (pPacket == NULL)
381 *ppPacket = NULL;
382 #ifdef DEBUG
383 printk("RTMPAllocateNdisPacket Fail\n\n");
384 #endif
385 return NDIS_STATUS_FAILURE;
388 // 2. clone the frame content
389 if (HeaderLen > 0)
390 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
391 if (DataLen > 0)
392 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
394 // 3. update length of packet
395 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
397 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
398 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
399 *ppPacket = pPacket;
400 return NDIS_STATUS_SUCCESS;
404 ========================================================================
405 Description:
406 This routine frees a miniport internally allocated NDIS_PACKET and its
407 corresponding NDIS_BUFFER and allocated memory.
408 ========================================================================
410 VOID RTMPFreeNdisPacket(
411 IN PRTMP_ADAPTER pAd,
412 IN PNDIS_PACKET pPacket)
414 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
418 // IRQL = DISPATCH_LEVEL
419 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
420 // scatter gather buffer
421 NDIS_STATUS Sniff2BytesFromNdisBuffer(
422 IN PNDIS_BUFFER pFirstBuffer,
423 IN UCHAR DesiredOffset,
424 OUT PUCHAR pByte0,
425 OUT PUCHAR pByte1)
427 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
428 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
430 return NDIS_STATUS_SUCCESS;
434 void RTMP_QueryPacketInfo(
435 IN PNDIS_PACKET pPacket,
436 OUT PACKET_INFO *pPacketInfo,
437 OUT PUCHAR *pSrcBufVA,
438 OUT UINT *pSrcBufLen)
440 pPacketInfo->BufferCount = 1;
441 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
442 pPacketInfo->PhysicalBufferCount = 1;
443 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
445 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
446 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
449 void RTMP_QueryNextPacketInfo(
450 IN PNDIS_PACKET *ppPacket,
451 OUT PACKET_INFO *pPacketInfo,
452 OUT PUCHAR *pSrcBufVA,
453 OUT UINT *pSrcBufLen)
455 PNDIS_PACKET pPacket = NULL;
457 if (*ppPacket)
458 pPacket = GET_OS_PKT_NEXT(*ppPacket);
460 if (pPacket)
462 pPacketInfo->BufferCount = 1;
463 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
464 pPacketInfo->PhysicalBufferCount = 1;
465 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
467 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
468 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
469 *ppPacket = GET_OS_PKT_NEXT(pPacket);
471 else
473 pPacketInfo->BufferCount = 0;
474 pPacketInfo->pFirstBuffer = NULL;
475 pPacketInfo->PhysicalBufferCount = 0;
476 pPacketInfo->TotalPacketLength = 0;
478 *pSrcBufVA = NULL;
479 *pSrcBufLen = 0;
480 *ppPacket = NULL;
484 // not yet support MBSS
485 PNET_DEV get_netdev_from_bssid(
486 IN PRTMP_ADAPTER pAd,
487 IN UCHAR FromWhichBSSID)
489 PNET_DEV dev_p = NULL;
491 dev_p = pAd->net_dev;
493 ASSERT(dev_p);
494 return dev_p; /* return one of MBSS */
497 PNDIS_PACKET DuplicatePacket(
498 IN PRTMP_ADAPTER pAd,
499 IN PNDIS_PACKET pPacket,
500 IN UCHAR FromWhichBSSID)
502 struct sk_buff *skb;
503 PNDIS_PACKET pRetPacket = NULL;
504 USHORT DataSize;
505 UCHAR *pData;
507 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
508 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
511 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
512 if (skb)
514 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
515 pRetPacket = OSPKT_TO_RTPKT(skb);
518 #if 0
519 if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL)
521 skb_reserve(skb, 2+32);
522 NdisMoveMemory(skb->tail, pData, DataSize);
523 skb_put(skb, DataSize);
524 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
525 pRetPacket = OSPKT_TO_RTPKT(skb);
527 #endif
529 return pRetPacket;
533 PNDIS_PACKET duplicate_pkt(
534 IN PRTMP_ADAPTER pAd,
535 IN PUCHAR pHeader802_3,
536 IN UINT HdrLen,
537 IN PUCHAR pData,
538 IN ULONG DataSize,
539 IN UCHAR FromWhichBSSID)
541 struct sk_buff *skb;
542 PNDIS_PACKET pPacket = NULL;
545 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
547 skb_reserve(skb, 2);
548 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
549 skb_put(skb, HdrLen);
550 NdisMoveMemory(skb->tail, pData, DataSize);
551 skb_put(skb, DataSize);
552 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
553 pPacket = OSPKT_TO_RTPKT(skb);
556 return pPacket;
560 #define TKIP_TX_MIC_SIZE 8
561 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
562 IN PRTMP_ADAPTER pAd,
563 IN PNDIS_PACKET pPacket)
565 struct sk_buff *skb, *newskb;
568 skb = RTPKT_TO_OSPKT(pPacket);
569 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
571 // alloc a new skb and copy the packet
572 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
573 dev_kfree_skb_any(skb);
574 if (newskb == NULL)
576 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
577 return NULL;
579 skb = newskb;
582 return OSPKT_TO_RTPKT(skb);
584 #if 0
585 if ((data = skb_put(skb, TKIP_TX_MIC_SIZE)) != NULL)
586 { // If we can extend it, well, copy it first.
587 NdisMoveMemory(data, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
589 else
591 // Otherwise, copy the packet.
592 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
593 dev_kfree_skb_any(skb);
594 if (newskb == NULL)
596 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC to packet failed!, dropping packet\n"));
597 return NULL;
599 skb = newskb;
601 NdisMoveMemory(skb->tail, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
602 skb_put(skb, TKIP_TX_MIC_SIZE);
605 return OSPKT_TO_RTPKT(skb);
606 #endif
613 PNDIS_PACKET ClonePacket(
614 IN PRTMP_ADAPTER pAd,
615 IN PNDIS_PACKET pPacket,
616 IN PUCHAR pData,
617 IN ULONG DataSize)
619 struct sk_buff *pRxPkt;
620 struct sk_buff *pClonedPkt;
622 ASSERT(pPacket);
623 pRxPkt = RTPKT_TO_OSPKT(pPacket);
625 // clone the packet
626 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
628 if (pClonedPkt)
630 // set the correct dataptr and data len
631 pClonedPkt->dev = pRxPkt->dev;
632 pClonedPkt->data = pData;
633 pClonedPkt->len = DataSize;
634 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
635 ASSERT(DataSize < 1530);
637 return pClonedPkt;
641 // change OS packet DataPtr and DataLen
643 void update_os_packet_info(
644 IN PRTMP_ADAPTER pAd,
645 IN RX_BLK *pRxBlk,
646 IN UCHAR FromWhichBSSID)
648 struct sk_buff *pOSPkt;
650 ASSERT(pRxBlk->pRxPacket);
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;
660 void wlan_802_11_to_802_3_packet(
661 IN PRTMP_ADAPTER pAd,
662 IN RX_BLK *pRxBlk,
663 IN PUCHAR pHeader802_3,
664 IN UCHAR FromWhichBSSID)
666 struct sk_buff *pOSPkt;
668 ASSERT(pRxBlk->pRxPacket);
669 ASSERT(pHeader802_3);
671 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
673 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
674 pOSPkt->data = pRxBlk->pData;
675 pOSPkt->len = pRxBlk->DataSize;
676 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
679 // copy 802.3 header
683 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
686 void announce_802_3_packet(
687 IN PRTMP_ADAPTER pAd,
688 IN PNDIS_PACKET pPacket)
691 struct sk_buff *pRxPkt;
693 ASSERT(pPacket);
695 pRxPkt = RTPKT_TO_OSPKT(pPacket);
697 /* Push up the protocol stack */
698 #ifdef IKANOS_VX_1X0
699 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
700 #else
701 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
703 //#ifdef CONFIG_5VT_ENHANCE
704 // *(int*)(pRxPkt->cb) = BRIDGE_TAG;
705 //#endif
706 netif_rx(pRxPkt);
707 #endif // IKANOS_VX_1X0 //
711 PRTMP_SCATTER_GATHER_LIST
712 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
714 sg->NumberOfElements = 1;
715 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
716 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
717 return (sg);
720 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
722 unsigned char *pt;
723 int x;
725 if (RTDebugLevel < RT_DEBUG_TRACE)
726 return;
728 pt = pSrcBufVA;
729 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
730 for (x=0; x<SrcBufLen; x++)
732 if (x % 16 == 0)
733 printk("0x%04x : ", x);
734 printk("%02x ", ((unsigned char)pt[x]));
735 if (x%16 == 15) printk("\n");
737 printk("\n");
741 ========================================================================
743 Routine Description:
744 Send log message through wireless event
746 Support standard iw_event with IWEVCUSTOM. It is used below.
748 iwreq_data.data.flags is used to store event_flag that is defined by user.
749 iwreq_data.data.length is the length of the event log.
751 The format of the event log is composed of the entry's MAC address and
752 the desired log message (refer to pWirelessEventText).
754 ex: 11:22:33:44:55:66 has associated successfully
756 p.s. The requirement of Wireless Extension is v15 or newer.
758 ========================================================================
760 VOID RTMPSendWirelessEvent(
761 IN PRTMP_ADAPTER pAd,
762 IN USHORT Event_flag,
763 IN PUCHAR pAddr,
764 IN UCHAR BssIdx,
765 IN CHAR Rssi)
767 #if WIRELESS_EXT >= 15
769 union iwreq_data wrqu;
770 PUCHAR pBuf = NULL, pBufPtr = NULL;
771 USHORT event, type, BufLen;
772 UCHAR event_table_len = 0;
774 type = Event_flag & 0xFF00;
775 event = Event_flag & 0x00FF;
777 switch (type)
779 case IW_SYS_EVENT_FLAG_START:
780 event_table_len = IW_SYS_EVENT_TYPE_NUM;
781 break;
783 case IW_SPOOF_EVENT_FLAG_START:
784 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
785 break;
787 case IW_FLOOD_EVENT_FLAG_START:
788 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
789 break;
792 if (event_table_len == 0)
794 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
795 return;
798 if (event >= event_table_len)
800 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
801 return;
804 //Allocate memory and copy the msg.
805 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
807 //Prepare the payload
808 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
810 pBufPtr = pBuf;
812 if (pAddr)
813 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
814 else if (BssIdx < MAX_MBSSID_NUM)
815 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
816 else
817 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
819 if (type == IW_SYS_EVENT_FLAG_START)
820 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
821 else if (type == IW_SPOOF_EVENT_FLAG_START)
822 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
823 else if (type == IW_FLOOD_EVENT_FLAG_START)
824 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
825 else
826 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
828 pBufPtr[pBufPtr - pBuf] = '\0';
829 BufLen = pBufPtr - pBuf;
831 memset(&wrqu, 0, sizeof(wrqu));
832 wrqu.data.flags = Event_flag;
833 wrqu.data.length = BufLen;
835 //send wireless event
836 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
838 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
840 kfree(pBuf);
842 else
843 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
844 #else
845 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
846 #endif /* WIRELESS_EXT >= 15 */
849 void send_monitor_packets(
850 IN PRTMP_ADAPTER pAd,
851 IN RX_BLK *pRxBlk)
853 struct sk_buff *pOSPkt;
854 wlan_ng_prism2_header *ph;
855 int rate_index = 0;
856 USHORT header_len = 0;
857 UCHAR temp_header[40] = {0};
859 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
860 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,
861 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};
864 ASSERT(pRxBlk->pRxPacket);
865 if (pRxBlk->DataSize < 10)
867 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
868 goto err_free_sk_buff;
871 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
873 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
874 goto err_free_sk_buff;
877 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
878 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
879 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
881 pRxBlk->DataSize -= LENGTH_802_11;
882 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
883 (pRxBlk->pHeader->FC.FrDs == 1))
884 header_len = LENGTH_802_11_WITH_ADDR4;
885 else
886 header_len = LENGTH_802_11;
888 // QOS
889 if (pRxBlk->pHeader->FC.SubType & 0x08)
891 header_len += 2;
892 // Data skip QOS contorl field
893 pRxBlk->DataSize -=2;
896 // Order bit: A-Ralink or HTC+
897 if (pRxBlk->pHeader->FC.Order)
899 header_len += 4;
900 // Data skip HTC contorl field
901 pRxBlk->DataSize -= 4;
904 // Copy Header
905 if (header_len <= 40)
906 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
908 // skip HW padding
909 if (pRxBlk->RxD.L2PAD)
910 pRxBlk->pData += (header_len + 2);
911 else
912 pRxBlk->pData += header_len;
913 } //end if
916 if (pRxBlk->DataSize < pOSPkt->len) {
917 skb_trim(pOSPkt,pRxBlk->DataSize);
918 } else {
919 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
920 } //end if
922 if ((pRxBlk->pData - pOSPkt->data) > 0) {
923 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
924 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
925 } //end if
927 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
928 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
929 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
930 goto err_free_sk_buff;
931 } //end if
932 } //end if
934 if (header_len > 0)
935 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
937 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
938 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
940 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
941 ph->msglen = sizeof(wlan_ng_prism2_header);
942 strcpy(ph->devname, pAd->net_dev->name);
944 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
945 ph->hosttime.status = 0;
946 ph->hosttime.len = 4;
947 ph->hosttime.data = jiffies;
949 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
950 ph->mactime.status = 0;
951 ph->mactime.len = 0;
952 ph->mactime.data = 0;
954 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
955 ph->istx.status = 0;
956 ph->istx.len = 0;
957 ph->istx.data = 0;
959 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
960 ph->channel.status = 0;
961 ph->channel.len = 4;
963 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
965 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
966 ph->rssi.status = 0;
967 ph->rssi.len = 4;
968 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));;
970 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
971 ph->signal.status = 0;
972 ph->signal.len = 4;
973 ph->signal.data = 0; //rssi + noise;
975 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
976 ph->noise.status = 0;
977 ph->noise.len = 4;
978 ph->noise.data = 0;
980 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
982 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
984 else
985 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
986 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
987 else
988 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
989 if (rate_index < 0)
990 rate_index = 0;
991 if (rate_index > 255)
992 rate_index = 255;
994 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
995 ph->rate.status = 0;
996 ph->rate.len = 4;
997 ph->rate.data = ralinkrate[rate_index];
999 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
1000 ph->frmlen.status = 0;
1001 ph->frmlen.len = 4;
1002 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
1005 pOSPkt->pkt_type = PACKET_OTHERHOST;
1006 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
1007 pOSPkt->ip_summed = CHECKSUM_NONE;
1008 netif_rx(pOSPkt);
1010 return;
1012 err_free_sk_buff:
1013 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1014 return;
1018 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1020 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1022 allow_signal(SIGTERM);
1023 allow_signal(SIGKILL);
1024 current->flags |= PF_NOFREEZE;
1026 /* signal that we've started the thread */
1027 complete(pNotify);
1030 void RTMP_IndicateMediaState(
1031 IN PRTMP_ADAPTER pAd)
1033 if (pAd->CommonCfg.bWirelessEvent)
1035 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1037 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1039 else
1041 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);