On Tue, Nov 06, 2007 at 02:33:53AM -0800, akpm@linux-foundation.org wrote:
[mmotm.git] / drivers / staging / rt2860 / rt_linux.c
blob30fc3f2a9ae5216d14813cfcbe6d70057a6a1fbe
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;
33 // for wireless system event message
34 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
35 // system status event
36 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
37 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
38 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
39 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
40 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
41 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
42 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
43 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
44 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
45 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
46 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
47 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
48 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
49 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
50 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
51 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
52 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
53 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
54 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
57 // for wireless IDS_spoof_attack event message
58 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
59 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
60 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
61 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
62 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
63 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
64 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
65 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
66 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
67 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
68 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
71 // for wireless IDS_flooding_attack event message
72 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
73 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
74 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
75 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
76 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
77 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
78 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
79 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
82 /* timeout -- ms */
83 VOID RTMP_SetPeriodicTimer(
84 IN NDIS_MINIPORT_TIMER *pTimer,
85 IN unsigned long timeout)
87 timeout = ((timeout*OS_HZ) / 1000);
88 pTimer->expires = jiffies + timeout;
89 add_timer(pTimer);
92 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
93 VOID RTMP_OS_Init_Timer(
94 IN PRTMP_ADAPTER pAd,
95 IN NDIS_MINIPORT_TIMER *pTimer,
96 IN TIMER_FUNCTION function,
97 IN PVOID data)
99 init_timer(pTimer);
100 pTimer->data = (unsigned long)data;
101 pTimer->function = function;
105 VOID RTMP_OS_Add_Timer(
106 IN NDIS_MINIPORT_TIMER *pTimer,
107 IN unsigned long timeout)
109 if (timer_pending(pTimer))
110 return;
112 timeout = ((timeout*OS_HZ) / 1000);
113 pTimer->expires = jiffies + timeout;
114 add_timer(pTimer);
117 VOID RTMP_OS_Mod_Timer(
118 IN NDIS_MINIPORT_TIMER *pTimer,
119 IN unsigned long timeout)
121 timeout = ((timeout*OS_HZ) / 1000);
122 mod_timer(pTimer, jiffies + timeout);
125 VOID RTMP_OS_Del_Timer(
126 IN NDIS_MINIPORT_TIMER *pTimer,
127 OUT BOOLEAN *pCancelled)
129 if (timer_pending(pTimer))
131 *pCancelled = del_timer_sync(pTimer);
133 else
135 *pCancelled = TRUE;
140 VOID RTMP_OS_Release_Packet(
141 IN PRTMP_ADAPTER pAd,
142 IN PQUEUE_ENTRY pEntry)
144 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
147 // Unify all delay routine by using udelay
148 VOID RTMPusecDelay(
149 IN ULONG usec)
151 ULONG i;
153 for (i = 0; i < (usec / 50); i++)
154 udelay(50);
156 if (usec % 50)
157 udelay(usec % 50);
160 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
162 time->u.LowPart = jiffies;
165 // pAd MUST allow to be NULL
166 NDIS_STATUS os_alloc_mem(
167 IN RTMP_ADAPTER *pAd,
168 OUT UCHAR **mem,
169 IN ULONG size)
171 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
172 if (*mem)
173 return (NDIS_STATUS_SUCCESS);
174 else
175 return (NDIS_STATUS_FAILURE);
178 // pAd MUST allow to be NULL
179 NDIS_STATUS os_free_mem(
180 IN PRTMP_ADAPTER pAd,
181 IN PVOID mem)
184 ASSERT(mem);
185 kfree(mem);
186 return (NDIS_STATUS_SUCCESS);
192 PNDIS_PACKET RtmpOSNetPktAlloc(
193 IN RTMP_ADAPTER *pAd,
194 IN int size)
196 struct sk_buff *skb;
197 /* Add 2 more bytes for ip header alignment*/
198 skb = dev_alloc_skb(size+2);
200 return ((PNDIS_PACKET)skb);
204 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
205 IN PRTMP_ADAPTER pAd,
206 IN ULONG Length)
208 struct sk_buff *pkt;
210 pkt = dev_alloc_skb(Length);
212 if (pkt == NULL)
214 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
217 if (pkt)
219 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
222 return (PNDIS_PACKET) pkt;
226 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
227 IN PRTMP_ADAPTER pAd,
228 IN ULONG Length,
229 IN BOOLEAN Cached,
230 OUT PVOID *VirtualAddress)
232 struct sk_buff *pkt;
234 pkt = dev_alloc_skb(Length);
236 if (pkt == NULL)
238 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
241 if (pkt)
243 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
244 *VirtualAddress = (PVOID) pkt->data;
246 else
248 *VirtualAddress = (PVOID) NULL;
251 return (PNDIS_PACKET) pkt;
255 VOID build_tx_packet(
256 IN PRTMP_ADAPTER pAd,
257 IN PNDIS_PACKET pPacket,
258 IN PUCHAR pFrame,
259 IN ULONG FrameLen)
262 struct sk_buff *pTxPkt;
264 ASSERT(pPacket);
265 pTxPkt = RTPKT_TO_OSPKT(pPacket);
267 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
270 VOID RTMPFreeAdapter(
271 IN PRTMP_ADAPTER pAd)
273 POS_COOKIE os_cookie;
274 int index;
276 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
278 if (pAd->BeaconBuf)
279 kfree(pAd->BeaconBuf);
282 NdisFreeSpinLock(&pAd->MgmtRingLock);
284 #ifdef RTMP_MAC_PCI
285 NdisFreeSpinLock(&pAd->RxRingLock);
286 #ifdef RT3090
287 NdisFreeSpinLock(&pAd->McuCmdLock);
288 #endif // RT3090 //
289 #endif // RTMP_MAC_PCI //
291 for (index =0 ; index < NUM_OF_TX_RING; index++)
293 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
294 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
295 pAd->DeQueueRunning[index] = FALSE;
298 NdisFreeSpinLock(&pAd->irq_lock);
301 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
302 if (os_cookie)
303 kfree(os_cookie);
306 BOOLEAN OS_Need_Clone_Packet(void)
308 return (FALSE);
314 ========================================================================
316 Routine Description:
317 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
318 must have only one NDIS BUFFER
319 return - byte copied. 0 means can't create NDIS PACKET
320 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
322 Arguments:
323 pAd Pointer to our adapter
324 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
325 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
327 Return Value:
328 NDIS_STATUS_SUCCESS
329 NDIS_STATUS_FAILURE
331 Note:
333 ========================================================================
335 NDIS_STATUS RTMPCloneNdisPacket(
336 IN PRTMP_ADAPTER pAd,
337 IN BOOLEAN pInsAMSDUHdr,
338 IN PNDIS_PACKET pInPacket,
339 OUT PNDIS_PACKET *ppOutPacket)
342 struct sk_buff *pkt;
344 ASSERT(pInPacket);
345 ASSERT(ppOutPacket);
347 // 1. Allocate a packet
348 pkt = dev_alloc_skb(2048);
350 if (pkt == NULL)
352 return NDIS_STATUS_FAILURE;
355 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
356 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
357 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
360 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
362 printk("###Clone###\n");
364 return NDIS_STATUS_SUCCESS;
368 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
369 NDIS_STATUS RTMPAllocateNdisPacket(
370 IN PRTMP_ADAPTER pAd,
371 OUT PNDIS_PACKET *ppPacket,
372 IN PUCHAR pHeader,
373 IN UINT HeaderLen,
374 IN PUCHAR pData,
375 IN UINT DataLen)
377 PNDIS_PACKET pPacket;
378 ASSERT(pData);
379 ASSERT(DataLen);
381 // 1. Allocate a packet
382 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + RTMP_PKT_TAIL_PADDING);
383 if (pPacket == NULL)
385 *ppPacket = NULL;
386 #ifdef DEBUG
387 printk("RTMPAllocateNdisPacket Fail\n\n");
388 #endif
389 return NDIS_STATUS_FAILURE;
392 // 2. clone the frame content
393 if (HeaderLen > 0)
394 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
395 if (DataLen > 0)
396 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
398 // 3. update length of packet
399 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
401 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
402 // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
403 *ppPacket = pPacket;
404 return NDIS_STATUS_SUCCESS;
408 ========================================================================
409 Description:
410 This routine frees a miniport internally allocated NDIS_PACKET and its
411 corresponding NDIS_BUFFER and allocated memory.
412 ========================================================================
414 VOID RTMPFreeNdisPacket(
415 IN PRTMP_ADAPTER pAd,
416 IN PNDIS_PACKET pPacket)
418 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
422 // IRQL = DISPATCH_LEVEL
423 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
424 // scatter gather buffer
425 NDIS_STATUS Sniff2BytesFromNdisBuffer(
426 IN PNDIS_BUFFER pFirstBuffer,
427 IN UCHAR DesiredOffset,
428 OUT PUCHAR pByte0,
429 OUT PUCHAR pByte1)
431 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
432 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
434 return NDIS_STATUS_SUCCESS;
438 void RTMP_QueryPacketInfo(
439 IN PNDIS_PACKET pPacket,
440 OUT PACKET_INFO *pPacketInfo,
441 OUT PUCHAR *pSrcBufVA,
442 OUT UINT *pSrcBufLen)
444 pPacketInfo->BufferCount = 1;
445 pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
446 pPacketInfo->PhysicalBufferCount = 1;
447 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
449 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
450 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
453 void RTMP_QueryNextPacketInfo(
454 IN PNDIS_PACKET *ppPacket,
455 OUT PACKET_INFO *pPacketInfo,
456 OUT PUCHAR *pSrcBufVA,
457 OUT UINT *pSrcBufLen)
459 PNDIS_PACKET pPacket = NULL;
461 if (*ppPacket)
462 pPacket = GET_OS_PKT_NEXT(*ppPacket);
464 if (pPacket)
466 pPacketInfo->BufferCount = 1;
467 pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
468 pPacketInfo->PhysicalBufferCount = 1;
469 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
471 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
472 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
473 *ppPacket = GET_OS_PKT_NEXT(pPacket);
475 else
477 pPacketInfo->BufferCount = 0;
478 pPacketInfo->pFirstBuffer = NULL;
479 pPacketInfo->PhysicalBufferCount = 0;
480 pPacketInfo->TotalPacketLength = 0;
482 *pSrcBufVA = NULL;
483 *pSrcBufLen = 0;
484 *ppPacket = NULL;
489 PNDIS_PACKET DuplicatePacket(
490 IN PRTMP_ADAPTER pAd,
491 IN PNDIS_PACKET pPacket,
492 IN UCHAR FromWhichBSSID)
494 struct sk_buff *skb;
495 PNDIS_PACKET pRetPacket = NULL;
496 USHORT DataSize;
497 UCHAR *pData;
499 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
500 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
503 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
504 if (skb)
506 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
507 pRetPacket = OSPKT_TO_RTPKT(skb);
510 return pRetPacket;
514 PNDIS_PACKET duplicate_pkt(
515 IN PRTMP_ADAPTER pAd,
516 IN PUCHAR pHeader802_3,
517 IN UINT HdrLen,
518 IN PUCHAR pData,
519 IN ULONG DataSize,
520 IN UCHAR FromWhichBSSID)
522 struct sk_buff *skb;
523 PNDIS_PACKET pPacket = NULL;
526 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
528 skb_reserve(skb, 2);
529 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
530 skb_put(skb, HdrLen);
531 NdisMoveMemory(skb->tail, pData, DataSize);
532 skb_put(skb, DataSize);
533 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
534 pPacket = OSPKT_TO_RTPKT(skb);
537 return pPacket;
541 #define TKIP_TX_MIC_SIZE 8
542 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
543 IN PRTMP_ADAPTER pAd,
544 IN PNDIS_PACKET pPacket)
546 struct sk_buff *skb, *newskb;
549 skb = RTPKT_TO_OSPKT(pPacket);
550 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
552 // alloc a new skb and copy the packet
553 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
554 dev_kfree_skb_any(skb);
555 if (newskb == NULL)
557 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
558 return NULL;
560 skb = newskb;
563 return OSPKT_TO_RTPKT(skb);
569 PNDIS_PACKET ClonePacket(
570 IN PRTMP_ADAPTER pAd,
571 IN PNDIS_PACKET pPacket,
572 IN PUCHAR pData,
573 IN ULONG DataSize)
575 struct sk_buff *pRxPkt;
576 struct sk_buff *pClonedPkt;
578 ASSERT(pPacket);
579 pRxPkt = RTPKT_TO_OSPKT(pPacket);
581 // clone the packet
582 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
584 if (pClonedPkt)
586 // set the correct dataptr and data len
587 pClonedPkt->dev = pRxPkt->dev;
588 pClonedPkt->data = pData;
589 pClonedPkt->len = DataSize;
590 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
591 ASSERT(DataSize < 1530);
593 return pClonedPkt;
597 // change OS packet DataPtr and DataLen
599 void update_os_packet_info(
600 IN PRTMP_ADAPTER pAd,
601 IN RX_BLK *pRxBlk,
602 IN UCHAR FromWhichBSSID)
604 struct sk_buff *pOSPkt;
606 ASSERT(pRxBlk->pRxPacket);
607 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
609 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
610 pOSPkt->data = pRxBlk->pData;
611 pOSPkt->len = pRxBlk->DataSize;
612 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
616 void wlan_802_11_to_802_3_packet(
617 IN PRTMP_ADAPTER pAd,
618 IN RX_BLK *pRxBlk,
619 IN PUCHAR pHeader802_3,
620 IN UCHAR FromWhichBSSID)
622 struct sk_buff *pOSPkt;
624 ASSERT(pRxBlk->pRxPacket);
625 ASSERT(pHeader802_3);
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;
635 // copy 802.3 header
639 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
644 void announce_802_3_packet(
645 IN PRTMP_ADAPTER pAd,
646 IN PNDIS_PACKET pPacket)
649 struct sk_buff *pRxPkt;
651 ASSERT(pPacket);
653 pRxPkt = RTPKT_TO_OSPKT(pPacket);
655 /* Push up the protocol stack */
656 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
658 netif_rx(pRxPkt);
662 PRTMP_SCATTER_GATHER_LIST
663 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
665 sg->NumberOfElements = 1;
666 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
667 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
668 return (sg);
671 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
673 unsigned char *pt;
674 int x;
676 if (RTDebugLevel < RT_DEBUG_TRACE)
677 return;
679 pt = pSrcBufVA;
680 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
681 for (x=0; x<SrcBufLen; x++)
683 if (x % 16 == 0)
684 printk("0x%04x : ", x);
685 printk("%02x ", ((unsigned char)pt[x]));
686 if (x%16 == 15) printk("\n");
688 printk("\n");
692 ========================================================================
694 Routine Description:
695 Send log message through wireless event
697 Support standard iw_event with IWEVCUSTOM. It is used below.
699 iwreq_data.data.flags is used to store event_flag that is defined by user.
700 iwreq_data.data.length is the length of the event log.
702 The format of the event log is composed of the entry's MAC address and
703 the desired log message (refer to pWirelessEventText).
705 ex: 11:22:33:44:55:66 has associated successfully
707 p.s. The requirement of Wireless Extension is v15 or newer.
709 ========================================================================
711 VOID RTMPSendWirelessEvent(
712 IN PRTMP_ADAPTER pAd,
713 IN USHORT Event_flag,
714 IN PUCHAR pAddr,
715 IN UCHAR BssIdx,
716 IN CHAR Rssi)
719 //union iwreq_data wrqu;
720 PSTRING pBuf = NULL, pBufPtr = NULL;
721 USHORT event, type, BufLen;
722 UCHAR event_table_len = 0;
724 type = Event_flag & 0xFF00;
725 event = Event_flag & 0x00FF;
727 switch (type)
729 case IW_SYS_EVENT_FLAG_START:
730 event_table_len = IW_SYS_EVENT_TYPE_NUM;
731 break;
733 case IW_SPOOF_EVENT_FLAG_START:
734 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
735 break;
737 case IW_FLOOD_EVENT_FLAG_START:
738 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
739 break;
742 if (event_table_len == 0)
744 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
745 return;
748 if (event >= event_table_len)
750 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
751 return;
754 //Allocate memory and copy the msg.
755 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
757 //Prepare the payload
758 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
760 pBufPtr = pBuf;
762 if (pAddr)
763 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
764 else if (BssIdx < MAX_MBSSID_NUM)
765 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
766 else
767 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
769 if (type == IW_SYS_EVENT_FLAG_START)
770 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
771 else if (type == IW_SPOOF_EVENT_FLAG_START)
772 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
773 else if (type == IW_FLOOD_EVENT_FLAG_START)
774 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
775 else
776 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
778 pBufPtr[pBufPtr - pBuf] = '\0';
779 BufLen = pBufPtr - pBuf;
781 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen);
782 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
784 kfree(pBuf);
786 else
787 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
790 void send_monitor_packets(
791 IN PRTMP_ADAPTER pAd,
792 IN RX_BLK *pRxBlk)
794 struct sk_buff *pOSPkt;
795 wlan_ng_prism2_header *ph;
796 int rate_index = 0;
797 USHORT header_len = 0;
798 UCHAR temp_header[40] = {0};
800 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
801 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,
802 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};
805 ASSERT(pRxBlk->pRxPacket);
806 if (pRxBlk->DataSize < 10)
808 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
809 goto err_free_sk_buff;
812 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
814 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
815 goto err_free_sk_buff;
818 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
819 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
820 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
822 pRxBlk->DataSize -= LENGTH_802_11;
823 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
824 (pRxBlk->pHeader->FC.FrDs == 1))
825 header_len = LENGTH_802_11_WITH_ADDR4;
826 else
827 header_len = LENGTH_802_11;
829 // QOS
830 if (pRxBlk->pHeader->FC.SubType & 0x08)
832 header_len += 2;
833 // Data skip QOS contorl field
834 pRxBlk->DataSize -=2;
837 // Order bit: A-Ralink or HTC+
838 if (pRxBlk->pHeader->FC.Order)
840 header_len += 4;
841 // Data skip HTC contorl field
842 pRxBlk->DataSize -= 4;
845 // Copy Header
846 if (header_len <= 40)
847 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
849 // skip HW padding
850 if (pRxBlk->RxD.L2PAD)
851 pRxBlk->pData += (header_len + 2);
852 else
853 pRxBlk->pData += header_len;
854 } //end if
857 if (pRxBlk->DataSize < pOSPkt->len) {
858 skb_trim(pOSPkt,pRxBlk->DataSize);
859 } else {
860 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
861 } //end if
863 if ((pRxBlk->pData - pOSPkt->data) > 0) {
864 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
865 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
866 } //end if
868 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
869 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
870 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
871 goto err_free_sk_buff;
872 } //end if
873 } //end if
875 if (header_len > 0)
876 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
878 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
879 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
881 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
882 ph->msglen = sizeof(wlan_ng_prism2_header);
883 strcpy((PSTRING) ph->devname, (PSTRING) pAd->net_dev->name);
885 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
886 ph->hosttime.status = 0;
887 ph->hosttime.len = 4;
888 ph->hosttime.data = jiffies;
890 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
891 ph->mactime.status = 0;
892 ph->mactime.len = 0;
893 ph->mactime.data = 0;
895 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
896 ph->istx.status = 0;
897 ph->istx.len = 0;
898 ph->istx.data = 0;
900 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
901 ph->channel.status = 0;
902 ph->channel.len = 4;
904 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
906 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
907 ph->rssi.status = 0;
908 ph->rssi.len = 4;
909 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));;
911 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
912 ph->signal.status = 0;
913 ph->signal.len = 4;
914 ph->signal.data = 0; //rssi + noise;
916 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
917 ph->noise.status = 0;
918 ph->noise.len = 4;
919 ph->noise.data = 0;
921 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
923 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
925 else
926 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
927 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
928 else
929 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
930 if (rate_index < 0)
931 rate_index = 0;
932 if (rate_index > 255)
933 rate_index = 255;
935 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
936 ph->rate.status = 0;
937 ph->rate.len = 4;
938 ph->rate.data = ralinkrate[rate_index];
940 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
941 ph->frmlen.status = 0;
942 ph->frmlen.len = 4;
943 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
946 pOSPkt->pkt_type = PACKET_OTHERHOST;
947 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
948 pOSPkt->ip_summed = CHECKSUM_NONE;
949 netif_rx(pOSPkt);
951 return;
953 err_free_sk_buff:
954 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
955 return;
960 /*******************************************************************************
962 Device IRQ related functions.
964 *******************************************************************************/
965 int RtmpOSIRQRequest(IN PNET_DEV pNetDev)
967 struct net_device *net_dev = pNetDev;
968 PRTMP_ADAPTER pAd = NULL;
969 int retval = 0;
971 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
973 ASSERT(pAd);
975 #ifdef RTMP_PCI_SUPPORT
976 if (pAd->infType == RTMP_DEV_INF_PCI)
978 POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie);
979 RTMP_MSI_ENABLE(pAd);
980 retval = request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev));
981 if (retval != 0)
982 printk("RT2860: request_irq ERROR(%d)\n", retval);
984 #endif // RTMP_PCI_SUPPORT //
987 return retval;
992 int RtmpOSIRQRelease(IN PNET_DEV pNetDev)
994 struct net_device *net_dev = pNetDev;
995 PRTMP_ADAPTER pAd = NULL;
997 GET_PAD_FROM_NET_DEV(pAd, net_dev);
999 ASSERT(pAd);
1001 #ifdef RTMP_PCI_SUPPORT
1002 if (pAd->infType == RTMP_DEV_INF_PCI)
1004 POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie);
1005 synchronize_irq(pObj->pci_dev->irq);
1006 free_irq(pObj->pci_dev->irq, (net_dev));
1007 RTMP_MSI_DISABLE(pAd);
1009 #endif // RTMP_PCI_SUPPORT //
1012 return 0;
1016 /*******************************************************************************
1018 File open/close related functions.
1020 *******************************************************************************/
1021 RTMP_OS_FD RtmpOSFileOpen(char *pPath, int flag, int mode)
1023 struct file *filePtr;
1025 filePtr = filp_open(pPath, flag, 0);
1026 if (IS_ERR(filePtr))
1028 DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error %ld opening %s\n", __func__, -PTR_ERR(filePtr), pPath));
1031 return (RTMP_OS_FD)filePtr;
1034 int RtmpOSFileClose(RTMP_OS_FD osfd)
1036 filp_close(osfd, NULL);
1037 return 0;
1041 void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset)
1043 osfd->f_pos = offset;
1047 int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
1049 // The object must have a read method
1050 if (osfd->f_op && osfd->f_op->read)
1052 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
1054 else
1056 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
1057 return -1;
1062 int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen)
1064 return osfd->f_op->write(osfd, pDataPtr, (size_t)writeLen, &osfd->f_pos);
1068 void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfo, BOOLEAN bSet)
1070 if (bSet)
1072 // Save uid and gid used for filesystem access.
1073 // Set user and group to 0 (root)
1074 pOSFSInfo->fsuid = current_fsuid();
1075 pOSFSInfo->fsgid = current_fsgid();
1076 pOSFSInfo->fs = get_fs();
1077 set_fs(KERNEL_DS);
1079 else
1081 set_fs(pOSFSInfo->fs);
1087 /*******************************************************************************
1089 Task create/management/kill related functions.
1091 *******************************************************************************/
1092 NDIS_STATUS RtmpOSTaskKill(
1093 IN RTMP_OS_TASK *pTask)
1095 RTMP_ADAPTER *pAd;
1096 int ret = NDIS_STATUS_FAILURE;
1098 pAd = (RTMP_ADAPTER *)pTask->priv;
1100 #ifdef KTHREAD_SUPPORT
1101 if (pTask->kthread_task)
1103 kthread_stop(pTask->kthread_task);
1104 ret = NDIS_STATUS_SUCCESS;
1106 #else
1107 CHECK_PID_LEGALITY(pTask->taskPID)
1109 printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1110 mb();
1111 pTask->task_killed = 1;
1112 mb();
1113 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1114 if (ret)
1116 printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1117 pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret);
1119 else
1121 wait_for_completion(&pTask->taskComplete);
1122 pTask->taskPID = THREAD_PID_INIT_VALUE;
1123 pTask->task_killed = 0;
1124 ret = NDIS_STATUS_SUCCESS;
1127 #endif
1129 return ret;
1134 INT RtmpOSTaskNotifyToExit(
1135 IN RTMP_OS_TASK *pTask)
1138 #ifndef KTHREAD_SUPPORT
1139 complete_and_exit(&pTask->taskComplete, 0);
1140 #endif
1142 return 0;
1146 void RtmpOSTaskCustomize(
1147 IN RTMP_OS_TASK *pTask)
1150 #ifndef KTHREAD_SUPPORT
1152 daemonize((PSTRING)&pTask->taskName[0]/*"%s",pAd->net_dev->name*/);
1154 allow_signal(SIGTERM);
1155 allow_signal(SIGKILL);
1156 current->flags |= PF_NOFREEZE;
1158 /* signal that we've started the thread */
1159 complete(&pTask->taskComplete);
1161 #endif
1165 NDIS_STATUS RtmpOSTaskAttach(
1166 IN RTMP_OS_TASK *pTask,
1167 IN int (*fn)(void *),
1168 IN void *arg)
1170 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
1171 pid_t pid_number = -1;
1173 #ifdef KTHREAD_SUPPORT
1174 pTask->task_killed = 0;
1175 pTask->kthread_task = NULL;
1176 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1177 if (IS_ERR(pTask->kthread_task))
1178 status = NDIS_STATUS_FAILURE;
1179 #else
1180 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1181 if (pid_number < 0)
1183 DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName));
1184 status = NDIS_STATUS_FAILURE;
1186 else
1188 pTask->taskPID = GET_PID(pid_number);
1190 // Wait for the thread to start
1191 wait_for_completion(&pTask->taskComplete);
1192 status = NDIS_STATUS_SUCCESS;
1194 #endif
1195 return status;
1199 NDIS_STATUS RtmpOSTaskInit(
1200 IN RTMP_OS_TASK *pTask,
1201 IN PSTRING pTaskName,
1202 IN VOID *pPriv)
1204 int len;
1206 ASSERT(pTask);
1208 #ifndef KTHREAD_SUPPORT
1209 NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK));
1210 #endif
1212 len = strlen(pTaskName);
1213 len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len;
1214 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1215 pTask->priv = pPriv;
1217 #ifndef KTHREAD_SUPPORT
1218 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1219 pTask->taskPID = THREAD_PID_INIT_VALUE;
1221 init_completion (&pTask->taskComplete);
1222 #endif
1224 return NDIS_STATUS_SUCCESS;
1228 void RTMP_IndicateMediaState(
1229 IN PRTMP_ADAPTER pAd)
1231 if (pAd->CommonCfg.bWirelessEvent)
1233 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1235 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1237 else
1239 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1244 int RtmpOSWrielessEventSend(
1245 IN RTMP_ADAPTER *pAd,
1246 IN UINT32 eventType,
1247 IN INT flags,
1248 IN PUCHAR pSrcMac,
1249 IN PUCHAR pData,
1250 IN UINT32 dataLen)
1252 union iwreq_data wrqu;
1254 memset(&wrqu, 0, sizeof(wrqu));
1256 if (flags>-1)
1257 wrqu.data.flags = flags;
1259 if (pSrcMac)
1260 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1262 if ((pData!= NULL) && (dataLen > 0))
1263 wrqu.data.length = dataLen;
1265 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1266 return 0;
1270 int RtmpOSNetDevAddrSet(
1271 IN PNET_DEV pNetDev,
1272 IN PUCHAR pMacAddr)
1274 struct net_device *net_dev;
1275 RTMP_ADAPTER *pAd;
1277 net_dev = pNetDev;
1278 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1280 // work-around for the SuSE due to it has it's own interface name management system.
1282 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1283 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
1286 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1288 return 0;
1294 * Assign the network dev name for created Ralink WiFi interface.
1296 static int RtmpOSNetDevRequestName(
1297 IN RTMP_ADAPTER *pAd,
1298 IN PNET_DEV dev,
1299 IN PSTRING pPrefixStr,
1300 IN INT devIdx)
1302 PNET_DEV existNetDev;
1303 STRING suffixName[IFNAMSIZ];
1304 STRING desiredName[IFNAMSIZ];
1305 int ifNameIdx, prefixLen, slotNameLen;
1306 int Status;
1309 prefixLen = strlen(pPrefixStr);
1310 ASSERT((prefixLen < IFNAMSIZ));
1312 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++)
1314 memset(suffixName, 0, IFNAMSIZ);
1315 memset(desiredName, 0, IFNAMSIZ);
1316 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1318 sprintf(suffixName, "%d", ifNameIdx);
1320 slotNameLen = strlen(suffixName);
1321 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1322 strcat(desiredName, suffixName);
1324 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1325 if (existNetDev == NULL)
1326 break;
1327 else
1328 RtmpOSNetDeviceRefPut(existNetDev);
1331 if(ifNameIdx < 32)
1333 strcpy(&dev->name[0], &desiredName[0]);
1334 Status = NDIS_STATUS_SUCCESS;
1336 else
1338 DBGPRINT(RT_DEBUG_ERROR,
1339 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr));
1340 Status = NDIS_STATUS_FAILURE;
1343 return Status;
1347 void RtmpOSNetDevClose(
1348 IN PNET_DEV pNetDev)
1350 dev_close(pNetDev);
1354 void RtmpOSNetDevFree(PNET_DEV pNetDev)
1356 ASSERT(pNetDev);
1358 free_netdev(pNetDev);
1362 INT RtmpOSNetDevAlloc(
1363 IN PNET_DEV *new_dev_p,
1364 IN UINT32 privDataSize)
1366 // assign it as null first.
1367 *new_dev_p = NULL;
1369 DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize));
1370 *new_dev_p = alloc_etherdev(privDataSize);
1371 if (*new_dev_p)
1372 return NDIS_STATUS_SUCCESS;
1373 else
1374 return NDIS_STATUS_FAILURE;
1378 PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName)
1380 PNET_DEV pTargetNetDev = NULL;
1382 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1384 return pTargetNetDev;
1388 void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev)
1391 every time dev_get_by_name is called, and it has returned a valid struct
1392 net_device*, dev_put should be called afterwards, because otherwise the
1393 machine hangs when the device is unregistered (since dev->refcnt > 1).
1395 if(pNetDev)
1396 dev_put(pNetDev);
1400 INT RtmpOSNetDevDestory(
1401 IN RTMP_ADAPTER *pAd,
1402 IN PNET_DEV pNetDev)
1405 // TODO: Need to fix this
1406 printk("WARNING: This function(%s) not implement yet!!!\n", __func__);
1407 return 0;
1411 void RtmpOSNetDevDetach(PNET_DEV pNetDev)
1413 unregister_netdev(pNetDev);
1417 int RtmpOSNetDevAttach(
1418 IN PNET_DEV pNetDev,
1419 IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook)
1421 int ret, rtnl_locked = FALSE;
1423 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1424 // If we need hook some callback function to the net device structrue, now do it.
1425 if (pDevOpHook)
1427 PRTMP_ADAPTER pAd = NULL;
1429 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1431 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1433 /* OS specific flags, here we used to indicate if we are virtual interface */
1434 pNetDev->priv_flags = pDevOpHook->priv_flags;
1437 if (pAd->OpMode == OPMODE_STA)
1439 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1443 // copy the net device mac address to the net_device structure.
1444 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
1446 rtnl_locked = pDevOpHook->needProtcted;
1449 if (rtnl_locked)
1450 ret = register_netdevice(pNetDev);
1451 else
1452 ret = register_netdev(pNetDev);
1454 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1455 if (ret == 0)
1456 return NDIS_STATUS_SUCCESS;
1457 else
1458 return NDIS_STATUS_FAILURE;
1462 PNET_DEV RtmpOSNetDevCreate(
1463 IN RTMP_ADAPTER *pAd,
1464 IN INT devType,
1465 IN INT devNum,
1466 IN INT privMemSize,
1467 IN PSTRING pNamePrefix)
1469 struct net_device *pNetDev = NULL;
1470 int status;
1473 /* allocate a new network device */
1474 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/);
1475 if (status != NDIS_STATUS_SUCCESS)
1477 /* allocation fail, exit */
1478 DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix));
1479 return NULL;
1483 /* find a available interface name, max 32 interfaces */
1484 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1485 if (status != NDIS_STATUS_SUCCESS)
1487 /* error! no any available ra name can be used! */
1488 DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix));
1489 RtmpOSNetDevFree(pNetDev);
1491 return NULL;
1493 else
1495 DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name));
1498 return pNetDev;