]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/staging/rt2860/rt_linux.c
Fix common misspellings
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / rt2860 / rt_linux.c
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
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 *************************************************************************
26 */
27
28 #include <linux/firmware.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include "rt_config.h"
32
33 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
34
35 /* for wireless system event message */
36 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
37 /* system status event */
38 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
39 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
40 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
41 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
42 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
43 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
44 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
45 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
46 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
47 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
48 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
49 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
50 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
51 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
52 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
53 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
54 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
55 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
56 "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
57 };
58
59 /* for wireless IDS_spoof_attack event message */
60 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
61 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
62 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
63 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
64 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
65 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
66 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
67 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
68 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
69 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
70 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
71 };
72
73 /* for wireless IDS_flooding_attack event message */
74 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
75 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
76 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
77 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
78 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
79 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
80 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
81 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
82 };
83
84 /* timeout -- ms */
85 void RTMP_SetPeriodicTimer(struct timer_list *pTimer,
86 IN unsigned long timeout)
87 {
88 timeout = ((timeout * OS_HZ) / 1000);
89 pTimer->expires = jiffies + timeout;
90 add_timer(pTimer);
91 }
92
93 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
94 void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
95 struct timer_list *pTimer,
96 IN TIMER_FUNCTION function, void *data)
97 {
98 init_timer(pTimer);
99 pTimer->data = (unsigned long)data;
100 pTimer->function = function;
101 }
102
103 void RTMP_OS_Add_Timer(struct timer_list *pTimer,
104 IN unsigned long timeout)
105 {
106 if (timer_pending(pTimer))
107 return;
108
109 timeout = ((timeout * OS_HZ) / 1000);
110 pTimer->expires = jiffies + timeout;
111 add_timer(pTimer);
112 }
113
114 void RTMP_OS_Mod_Timer(struct timer_list *pTimer,
115 IN unsigned long timeout)
116 {
117 timeout = ((timeout * OS_HZ) / 1000);
118 mod_timer(pTimer, jiffies + timeout);
119 }
120
121 void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN *pCancelled)
122 {
123 if (timer_pending(pTimer)) {
124 *pCancelled = del_timer_sync(pTimer);
125 } else {
126 *pCancelled = TRUE;
127 }
128
129 }
130
131 void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
132 {
133 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
134 }
135
136 /* Unify all delay routine by using udelay */
137 void RTMPusecDelay(unsigned long usec)
138 {
139 unsigned long i;
140
141 for (i = 0; i < (usec / 50); i++)
142 udelay(50);
143
144 if (usec % 50)
145 udelay(usec % 50);
146 }
147
148 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
149 {
150 time->u.LowPart = jiffies;
151 }
152
153 /* pAd MUST allow to be NULL */
154 int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
155 {
156 *mem = kmalloc(size, GFP_ATOMIC);
157 if (*mem)
158 return NDIS_STATUS_SUCCESS;
159 else
160 return NDIS_STATUS_FAILURE;
161 }
162
163 /* pAd MUST allow to be NULL */
164 int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
165 {
166
167 ASSERT(mem);
168 kfree(mem);
169 return NDIS_STATUS_SUCCESS;
170 }
171
172 void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
173 {
174 struct sk_buff *skb;
175 /* Add 2 more bytes for ip header alignment */
176 skb = dev_alloc_skb(size + 2);
177
178 return (void *)skb;
179 }
180
181 void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
182 unsigned long Length)
183 {
184 struct sk_buff *pkt;
185
186 pkt = dev_alloc_skb(Length);
187
188 if (pkt == NULL) {
189 DBGPRINT(RT_DEBUG_ERROR,
190 ("can't allocate frag rx %ld size packet\n", Length));
191 }
192
193 if (pkt) {
194 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
195 }
196
197 return (void *)pkt;
198 }
199
200 void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
201 unsigned long Length,
202 IN BOOLEAN Cached,
203 void **VirtualAddress)
204 {
205 struct sk_buff *pkt;
206
207 pkt = dev_alloc_skb(Length);
208
209 if (pkt == NULL) {
210 DBGPRINT(RT_DEBUG_ERROR,
211 ("can't allocate tx %ld size packet\n", Length));
212 }
213
214 if (pkt) {
215 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
216 *VirtualAddress = (void *)pkt->data;
217 } else {
218 *VirtualAddress = (void *)NULL;
219 }
220
221 return (void *)pkt;
222 }
223
224 void build_tx_packet(struct rt_rtmp_adapter *pAd,
225 void *pPacket,
226 u8 *pFrame, unsigned long FrameLen)
227 {
228
229 struct sk_buff *pTxPkt;
230
231 ASSERT(pPacket);
232 pTxPkt = RTPKT_TO_OSPKT(pPacket);
233
234 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
235 }
236
237 void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
238 {
239 struct os_cookie *os_cookie;
240 int index;
241
242 os_cookie = (struct os_cookie *)pAd->OS_Cookie;
243
244 kfree(pAd->BeaconBuf);
245
246 NdisFreeSpinLock(&pAd->MgmtRingLock);
247
248 #ifdef RTMP_MAC_PCI
249 NdisFreeSpinLock(&pAd->RxRingLock);
250 #ifdef RT3090
251 NdisFreeSpinLock(&pAd->McuCmdLock);
252 #endif /* RT3090 // */
253 #endif /* RTMP_MAC_PCI // */
254
255 for (index = 0; index < NUM_OF_TX_RING; index++) {
256 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
257 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
258 pAd->DeQueueRunning[index] = FALSE;
259 }
260
261 NdisFreeSpinLock(&pAd->irq_lock);
262
263 release_firmware(pAd->firmware);
264
265 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
266 kfree(os_cookie);
267 }
268
269 BOOLEAN OS_Need_Clone_Packet(void)
270 {
271 return FALSE;
272 }
273
274 /*
275 ========================================================================
276
277 Routine Description:
278 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
279 must have only one NDIS BUFFER
280 return - byte copied. 0 means can't create NDIS PACKET
281 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
282
283 Arguments:
284 pAd Pointer to our adapter
285 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
286 *pSrcTotalLen return total packet length. This length is calculated with 802.3 format packet.
287
288 Return Value:
289 NDIS_STATUS_SUCCESS
290 NDIS_STATUS_FAILURE
291
292 Note:
293
294 ========================================================================
295 */
296 int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
297 IN BOOLEAN pInsAMSDUHdr,
298 void *pInPacket,
299 void **ppOutPacket)
300 {
301
302 struct sk_buff *pkt;
303
304 ASSERT(pInPacket);
305 ASSERT(ppOutPacket);
306
307 /* 1. Allocate a packet */
308 pkt = dev_alloc_skb(2048);
309
310 if (pkt == NULL) {
311 return NDIS_STATUS_FAILURE;
312 }
313
314 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
315 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
316 GET_OS_PKT_LEN(pInPacket));
317 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
318
319 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
320
321 printk(KERN_DEBUG "###Clone###\n");
322
323 return NDIS_STATUS_SUCCESS;
324 }
325
326 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
327 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
328 void **ppPacket,
329 u8 *pHeader,
330 u32 HeaderLen,
331 u8 *pData, u32 DataLen)
332 {
333 void *pPacket;
334 ASSERT(pData);
335 ASSERT(DataLen);
336
337 /* 1. Allocate a packet */
338 pPacket =
339 (void **) dev_alloc_skb(HeaderLen + DataLen +
340 RTMP_PKT_TAIL_PADDING);
341 if (pPacket == NULL) {
342 *ppPacket = NULL;
343 pr_devel("RTMPAllocateNdisPacket Fail\n");
344
345 return NDIS_STATUS_FAILURE;
346 }
347 /* 2. clone the frame content */
348 if (HeaderLen > 0)
349 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
350 if (DataLen > 0)
351 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
352 DataLen);
353
354 /* 3. update length of packet */
355 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
356
357 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
358 /* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
359 *ppPacket = pPacket;
360 return NDIS_STATUS_SUCCESS;
361 }
362
363 /*
364 ========================================================================
365 Description:
366 This routine frees a miniport internally allocated char and its
367 corresponding NDIS_BUFFER and allocated memory.
368 ========================================================================
369 */
370 void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
371 {
372 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
373 }
374
375 /* IRQL = DISPATCH_LEVEL */
376 /* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
377 /* scatter gather buffer */
378 int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
379 u8 DesiredOffset,
380 u8 *pByte0, u8 *pByte1)
381 {
382 *pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
383 *pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
384
385 return NDIS_STATUS_SUCCESS;
386 }
387
388 void RTMP_QueryPacketInfo(void *pPacket,
389 struct rt_packet_info *pPacketInfo,
390 u8 **pSrcBufVA, u32 * pSrcBufLen)
391 {
392 pPacketInfo->BufferCount = 1;
393 pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
394 pPacketInfo->PhysicalBufferCount = 1;
395 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
396
397 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
398 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
399 }
400
401 void RTMP_QueryNextPacketInfo(void **ppPacket,
402 struct rt_packet_info *pPacketInfo,
403 u8 **pSrcBufVA, u32 * pSrcBufLen)
404 {
405 void *pPacket = NULL;
406
407 if (*ppPacket)
408 pPacket = GET_OS_PKT_NEXT(*ppPacket);
409
410 if (pPacket) {
411 pPacketInfo->BufferCount = 1;
412 pPacketInfo->pFirstBuffer =
413 (char *)GET_OS_PKT_DATAPTR(pPacket);
414 pPacketInfo->PhysicalBufferCount = 1;
415 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
416
417 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
418 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
419 *ppPacket = GET_OS_PKT_NEXT(pPacket);
420 } else {
421 pPacketInfo->BufferCount = 0;
422 pPacketInfo->pFirstBuffer = NULL;
423 pPacketInfo->PhysicalBufferCount = 0;
424 pPacketInfo->TotalPacketLength = 0;
425
426 *pSrcBufVA = NULL;
427 *pSrcBufLen = 0;
428 *ppPacket = NULL;
429 }
430 }
431
432 void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
433 void *pPacket, u8 FromWhichBSSID)
434 {
435 struct sk_buff *skb;
436 void *pRetPacket = NULL;
437 u16 DataSize;
438 u8 *pData;
439
440 DataSize = (u16)GET_OS_PKT_LEN(pPacket);
441 pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
442
443 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
444 if (skb) {
445 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
446 pRetPacket = OSPKT_TO_RTPKT(skb);
447 }
448
449 return pRetPacket;
450
451 }
452
453 void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
454 u8 *pHeader802_3,
455 u32 HdrLen,
456 u8 *pData,
457 unsigned long DataSize, u8 FromWhichBSSID)
458 {
459 struct sk_buff *skb;
460 void *pPacket = NULL;
461
462 skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG);
463 if (skb != NULL) {
464 skb_reserve(skb, 2);
465 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
466 skb_put(skb, HdrLen);
467 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
468 skb_put(skb, DataSize);
469 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
470 pPacket = OSPKT_TO_RTPKT(skb);
471 }
472
473 return pPacket;
474 }
475
476 #define TKIP_TX_MIC_SIZE 8
477 void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
478 void *pPacket)
479 {
480 struct sk_buff *skb, *newskb;
481
482 skb = RTPKT_TO_OSPKT(pPacket);
483 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
484 /* alloc a new skb and copy the packet */
485 newskb =
486 skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
487 GFP_ATOMIC);
488 dev_kfree_skb_any(skb);
489 if (newskb == NULL) {
490 DBGPRINT(RT_DEBUG_ERROR,
491 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
492 return NULL;
493 }
494 skb = newskb;
495 }
496
497 return OSPKT_TO_RTPKT(skb);
498 }
499
500 void *ClonePacket(struct rt_rtmp_adapter *pAd,
501 void *pPacket,
502 u8 *pData, unsigned long DataSize)
503 {
504 struct sk_buff *pRxPkt;
505 struct sk_buff *pClonedPkt;
506
507 ASSERT(pPacket);
508 pRxPkt = RTPKT_TO_OSPKT(pPacket);
509
510 /* clone the packet */
511 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
512
513 if (pClonedPkt) {
514 /* set the correct dataptr and data len */
515 pClonedPkt->dev = pRxPkt->dev;
516 pClonedPkt->data = pData;
517 pClonedPkt->len = DataSize;
518 skb_set_tail_pointer(pClonedPkt, DataSize)
519 ASSERT(DataSize < 1530);
520 }
521 return pClonedPkt;
522 }
523
524 /* */
525 /* change OS packet DataPtr and DataLen */
526 /* */
527 void update_os_packet_info(struct rt_rtmp_adapter *pAd,
528 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
529 {
530 struct sk_buff *pOSPkt;
531
532 ASSERT(pRxBlk->pRxPacket);
533 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
534
535 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
536 pOSPkt->data = pRxBlk->pData;
537 pOSPkt->len = pRxBlk->DataSize;
538 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
539 }
540
541 void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
542 struct rt_rx_blk *pRxBlk,
543 u8 *pHeader802_3,
544 u8 FromWhichBSSID)
545 {
546 struct sk_buff *pOSPkt;
547
548 ASSERT(pRxBlk->pRxPacket);
549 ASSERT(pHeader802_3);
550
551 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
552
553 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
554 pOSPkt->data = pRxBlk->pData;
555 pOSPkt->len = pRxBlk->DataSize;
556 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
557
558 /* */
559 /* copy 802.3 header */
560 /* */
561 /* */
562
563 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
564 LENGTH_802_3);
565 }
566
567 void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
568 {
569
570 struct sk_buff *pRxPkt;
571
572 ASSERT(pPacket);
573
574 pRxPkt = RTPKT_TO_OSPKT(pPacket);
575
576 /* Push up the protocol stack */
577 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
578
579 netif_rx(pRxPkt);
580 }
581
582 struct rt_rtmp_sg_list *
583 rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
584 {
585 sg->NumberOfElements = 1;
586 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
587 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
588 return sg;
589 }
590
591 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
592 {
593 unsigned char *pt;
594 int x;
595
596 if (RTDebugLevel < RT_DEBUG_TRACE)
597 return;
598
599 pt = pSrcBufVA;
600 printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
601 for (x = 0; x < SrcBufLen; x++) {
602 if (x % 16 == 0)
603 printk(KERN_DEBUG "0x%04x : ", x);
604 printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x]));
605 if (x % 16 == 15)
606 printk(KERN_DEBUG "\n");
607 }
608 printk(KERN_DEBUG "\n");
609 }
610
611 /*
612 ========================================================================
613
614 Routine Description:
615 Send log message through wireless event
616
617 Support standard iw_event with IWEVCUSTOM. It is used below.
618
619 iwreq_data.data.flags is used to store event_flag that is defined by user.
620 iwreq_data.data.length is the length of the event log.
621
622 The format of the event log is composed of the entry's MAC address and
623 the desired log message (refer to pWirelessEventText).
624
625 ex: 11:22:33:44:55:66 has associated successfully
626
627 p.s. The requirement of Wireless Extension is v15 or newer.
628
629 ========================================================================
630 */
631 void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
632 u16 Event_flag,
633 u8 *pAddr, u8 BssIdx, char Rssi)
634 {
635
636 /*union iwreq_data wrqu; */
637 char *pBuf = NULL, *pBufPtr = NULL;
638 u16 event, type, BufLen;
639 u8 event_table_len = 0;
640
641 type = Event_flag & 0xFF00;
642 event = Event_flag & 0x00FF;
643
644 switch (type) {
645 case IW_SYS_EVENT_FLAG_START:
646 event_table_len = IW_SYS_EVENT_TYPE_NUM;
647 break;
648
649 case IW_SPOOF_EVENT_FLAG_START:
650 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
651 break;
652
653 case IW_FLOOD_EVENT_FLAG_START:
654 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
655 break;
656 }
657
658 if (event_table_len == 0) {
659 DBGPRINT(RT_DEBUG_ERROR,
660 ("%s : The type(%0x02x) is not valid.\n", __func__,
661 type));
662 return;
663 }
664
665 if (event >= event_table_len) {
666 DBGPRINT(RT_DEBUG_ERROR,
667 ("%s : The event(%0x02x) is not valid.\n", __func__,
668 event));
669 return;
670 }
671 /*Allocate memory and copy the msg. */
672 pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC);
673 if (pBuf != NULL) {
674 /*Prepare the payload */
675 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
676
677 pBufPtr = pBuf;
678
679 if (pAddr)
680 pBufPtr +=
681 sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr);
682 else if (BssIdx < MAX_MBSSID_NUM)
683 pBufPtr +=
684 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
685 else
686 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
687
688 if (type == IW_SYS_EVENT_FLAG_START)
689 pBufPtr +=
690 sprintf(pBufPtr, "%s",
691 pWirelessSysEventText[event]);
692 else if (type == IW_SPOOF_EVENT_FLAG_START)
693 pBufPtr +=
694 sprintf(pBufPtr, "%s (RSSI=%d)",
695 pWirelessSpoofEventText[event], Rssi);
696 else if (type == IW_FLOOD_EVENT_FLAG_START)
697 pBufPtr +=
698 sprintf(pBufPtr, "%s",
699 pWirelessFloodEventText[event]);
700 else
701 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
702
703 pBufPtr[pBufPtr - pBuf] = '\0';
704 BufLen = pBufPtr - pBuf;
705
706 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
707 (u8 *)pBuf, BufLen);
708 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
709
710 kfree(pBuf);
711 } else
712 DBGPRINT(RT_DEBUG_ERROR,
713 ("%s : Can't allocate memory for wireless event.\n",
714 __func__));
715 }
716
717 void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
718 {
719 struct sk_buff *pOSPkt;
720 struct rt_wlan_ng_prism2_header *ph;
721 int rate_index = 0;
722 u16 header_len = 0;
723 u8 temp_header[40] = { 0 };
724
725 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 */
726 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
727 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
728 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
729 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
730 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
731 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
732 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
733 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
734 72, 73, 74, 75, 76, 77, 78, 79, 80
735 };
736
737 ASSERT(pRxBlk->pRxPacket);
738 if (pRxBlk->DataSize < 10) {
739 DBGPRINT(RT_DEBUG_ERROR,
740 ("%s : Size is too small! (%d)\n", __func__,
741 pRxBlk->DataSize));
742 goto err_free_sk_buff;
743 }
744
745 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
746 RX_BUFFER_AGGRESIZE) {
747 DBGPRINT(RT_DEBUG_ERROR,
748 ("%s : Size is too large! (%zu)\n", __func__,
749 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
750 goto err_free_sk_buff;
751 }
752
753 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
754 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
755 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
756 pRxBlk->DataSize -= LENGTH_802_11;
757 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
758 (pRxBlk->pHeader->FC.FrDs == 1))
759 header_len = LENGTH_802_11_WITH_ADDR4;
760 else
761 header_len = LENGTH_802_11;
762
763 /* QOS */
764 if (pRxBlk->pHeader->FC.SubType & 0x08) {
765 header_len += 2;
766 /* Data skip QOS control field */
767 pRxBlk->DataSize -= 2;
768 }
769 /* Order bit: A-Ralink or HTC+ */
770 if (pRxBlk->pHeader->FC.Order) {
771 header_len += 4;
772 /* Data skip HTC control field */
773 pRxBlk->DataSize -= 4;
774 }
775 /* Copy Header */
776 if (header_len <= 40)
777 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
778
779 /* skip HW padding */
780 if (pRxBlk->RxD.L2PAD)
781 pRxBlk->pData += (header_len + 2);
782 else
783 pRxBlk->pData += header_len;
784 } /*end if */
785
786 if (pRxBlk->DataSize < pOSPkt->len) {
787 skb_trim(pOSPkt, pRxBlk->DataSize);
788 } else {
789 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
790 } /*end if */
791
792 if ((pRxBlk->pData - pOSPkt->data) > 0) {
793 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
794 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
795 } /*end if */
796
797 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
798 if (pskb_expand_head
799 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
800 GFP_ATOMIC)) {
801 DBGPRINT(RT_DEBUG_ERROR,
802 ("%s : Reallocate header size of sk_buff fail!\n",
803 __func__));
804 goto err_free_sk_buff;
805 } /*end if */
806 } /*end if */
807
808 if (header_len > 0)
809 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
810 header_len);
811
812 ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
813 sizeof(struct rt_wlan_ng_prism2_header));
814 NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
815
816 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
817 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
818 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
819
820 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
821 ph->hosttime.status = 0;
822 ph->hosttime.len = 4;
823 ph->hosttime.data = jiffies;
824
825 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
826 ph->mactime.status = 0;
827 ph->mactime.len = 0;
828 ph->mactime.data = 0;
829
830 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
831 ph->istx.status = 0;
832 ph->istx.len = 0;
833 ph->istx.data = 0;
834
835 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
836 ph->channel.status = 0;
837 ph->channel.len = 4;
838
839 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
840
841 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
842 ph->rssi.status = 0;
843 ph->rssi.len = 4;
844 ph->rssi.data =
845 (u_int32_t) RTMPMaxRssi(pAd,
846 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
847 RSSI_0), ConvertToRssi(pAd,
848 pRxBlk->
849 pRxWI->
850 RSSI1,
851 RSSI_1),
852 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
853 RSSI_2));
854
855 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
856 ph->signal.status = 0;
857 ph->signal.len = 4;
858 ph->signal.data = 0; /*rssi + noise; */
859
860 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
861 ph->noise.status = 0;
862 ph->noise.len = 4;
863 ph->noise.data = 0;
864
865 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
866 rate_index =
867 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
868 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
869 ((u8)pRxBlk->pRxWI->MCS);
870 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
871 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
872 else
873 rate_index = (u8)(pRxBlk->pRxWI->MCS);
874 if (rate_index < 0)
875 rate_index = 0;
876 if (rate_index > 255)
877 rate_index = 255;
878
879 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
880 ph->rate.status = 0;
881 ph->rate.len = 4;
882 ph->rate.data = ralinkrate[rate_index];
883
884 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
885 ph->frmlen.status = 0;
886 ph->frmlen.len = 4;
887 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
888
889 pOSPkt->pkt_type = PACKET_OTHERHOST;
890 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
891 pOSPkt->ip_summed = CHECKSUM_NONE;
892 netif_rx(pOSPkt);
893
894 return;
895
896 err_free_sk_buff:
897 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
898 return;
899
900 }
901
902 /*******************************************************************************
903
904 Device IRQ related functions.
905
906 *******************************************************************************/
907 int RtmpOSIRQRequest(struct net_device *pNetDev)
908 {
909 #ifdef RTMP_PCI_SUPPORT
910 struct net_device *net_dev = pNetDev;
911 struct rt_rtmp_adapter *pAd = NULL;
912 int retval = 0;
913
914 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
915
916 ASSERT(pAd);
917
918 if (pAd->infType == RTMP_DEV_INF_PCI) {
919 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
920 RTMP_MSI_ENABLE(pAd);
921 retval =
922 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
923 (net_dev)->name, (net_dev));
924 if (retval != 0)
925 printk(KERN_ERR "rt2860: request_irq ERROR(%d)\n", retval);
926 }
927
928 return retval;
929 #else
930 return 0;
931 #endif
932 }
933
934 int RtmpOSIRQRelease(struct net_device *pNetDev)
935 {
936 struct net_device *net_dev = pNetDev;
937 struct rt_rtmp_adapter *pAd = NULL;
938
939 GET_PAD_FROM_NET_DEV(pAd, net_dev);
940
941 ASSERT(pAd);
942
943 #ifdef RTMP_PCI_SUPPORT
944 if (pAd->infType == RTMP_DEV_INF_PCI) {
945 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
946 synchronize_irq(pObj->pci_dev->irq);
947 free_irq(pObj->pci_dev->irq, (net_dev));
948 RTMP_MSI_DISABLE(pAd);
949 }
950 #endif /* RTMP_PCI_SUPPORT // */
951
952 return 0;
953 }
954
955 /*******************************************************************************
956
957 File open/close related functions.
958
959 *******************************************************************************/
960 struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
961 {
962 struct file *filePtr;
963
964 filePtr = filp_open(pPath, flag, 0);
965 if (IS_ERR(filePtr)) {
966 DBGPRINT(RT_DEBUG_ERROR,
967 ("%s(): Error %ld opening %s\n", __func__,
968 -PTR_ERR(filePtr), pPath));
969 }
970
971 return (struct file *)filePtr;
972 }
973
974 int RtmpOSFileClose(struct file *osfd)
975 {
976 filp_close(osfd, NULL);
977 return 0;
978 }
979
980 void RtmpOSFileSeek(struct file *osfd, int offset)
981 {
982 osfd->f_pos = offset;
983 }
984
985 int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
986 {
987 /* The object must have a read method */
988 if (osfd->f_op && osfd->f_op->read) {
989 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
990 } else {
991 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
992 return -1;
993 }
994 }
995
996 int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
997 {
998 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
999 &osfd->f_pos);
1000 }
1001
1002 /*******************************************************************************
1003
1004 Task create/management/kill related functions.
1005
1006 *******************************************************************************/
1007 int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
1008 {
1009 struct rt_rtmp_adapter *pAd;
1010 int ret = NDIS_STATUS_FAILURE;
1011
1012 pAd = pTask->priv;
1013
1014 #ifdef KTHREAD_SUPPORT
1015 if (pTask->kthread_task) {
1016 kthread_stop(pTask->kthread_task);
1017 ret = NDIS_STATUS_SUCCESS;
1018 }
1019 #else
1020 CHECK_PID_LEGALITY(pTask->taskPID) {
1021 printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n",
1022 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1023 mb();
1024 pTask->task_killed = 1;
1025 mb();
1026 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1027 if (ret) {
1028 printk(KERN_WARNING
1029 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1030 pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
1031 ret);
1032 } else {
1033 wait_for_completion(&pTask->taskComplete);
1034 pTask->taskPID = THREAD_PID_INIT_VALUE;
1035 pTask->task_killed = 0;
1036 ret = NDIS_STATUS_SUCCESS;
1037 }
1038 }
1039 #endif
1040
1041 return ret;
1042
1043 }
1044
1045 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
1046 {
1047
1048 #ifndef KTHREAD_SUPPORT
1049 complete_and_exit(&pTask->taskComplete, 0);
1050 #endif
1051
1052 return 0;
1053 }
1054
1055 void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
1056 {
1057
1058 #ifndef KTHREAD_SUPPORT
1059
1060 daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */);
1061
1062 allow_signal(SIGTERM);
1063 allow_signal(SIGKILL);
1064 current->flags |= PF_NOFREEZE;
1065
1066 /* signal that we've started the thread */
1067 complete(&pTask->taskComplete);
1068
1069 #endif
1070 }
1071
1072 int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
1073 IN int (*fn) (void *), IN void *arg)
1074 {
1075 int status = NDIS_STATUS_SUCCESS;
1076
1077 #ifdef KTHREAD_SUPPORT
1078 pTask->task_killed = 0;
1079 pTask->kthread_task = NULL;
1080 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1081 if (IS_ERR(pTask->kthread_task))
1082 status = NDIS_STATUS_FAILURE;
1083 #else
1084 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1085 if (pid_number < 0) {
1086 DBGPRINT(RT_DEBUG_ERROR,
1087 ("Attach task(%s) failed!\n", pTask->taskName));
1088 status = NDIS_STATUS_FAILURE;
1089 } else {
1090 pTask->taskPID = GET_PID(pid_number);
1091
1092 /* Wait for the thread to start */
1093 wait_for_completion(&pTask->taskComplete);
1094 status = NDIS_STATUS_SUCCESS;
1095 }
1096 #endif
1097 return status;
1098 }
1099
1100 int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
1101 char *pTaskName, void * pPriv)
1102 {
1103 int len;
1104
1105 ASSERT(pTask);
1106
1107 #ifndef KTHREAD_SUPPORT
1108 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
1109 #endif
1110
1111 len = strlen(pTaskName);
1112 len =
1113 len >
1114 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
1115 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1116 pTask->priv = pPriv;
1117
1118 #ifndef KTHREAD_SUPPORT
1119 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1120 pTask->taskPID = THREAD_PID_INIT_VALUE;
1121
1122 init_completion(&pTask->taskComplete);
1123 #endif
1124
1125 return NDIS_STATUS_SUCCESS;
1126 }
1127
1128 void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
1129 {
1130 if (pAd->CommonCfg.bWirelessEvent) {
1131 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1132 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1133 pAd->MacTab.Content[BSSID_WCID].
1134 Addr, BSS0, 0);
1135 } else {
1136 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1137 pAd->MacTab.Content[BSSID_WCID].
1138 Addr, BSS0, 0);
1139 }
1140 }
1141 }
1142
1143 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
1144 u32 eventType,
1145 int flags,
1146 u8 *pSrcMac,
1147 u8 *pData, u32 dataLen)
1148 {
1149 union iwreq_data wrqu;
1150
1151 memset(&wrqu, 0, sizeof(wrqu));
1152
1153 if (flags > -1)
1154 wrqu.data.flags = flags;
1155
1156 if (pSrcMac)
1157 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1158
1159 if ((pData != NULL) && (dataLen > 0))
1160 wrqu.data.length = dataLen;
1161
1162 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1163 return 0;
1164 }
1165
1166 int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
1167 {
1168 struct net_device *net_dev;
1169 struct rt_rtmp_adapter *pAd;
1170
1171 net_dev = pNetDev;
1172 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1173
1174 /* work-around for SuSE, due to them having their own interface name management system. */
1175 {
1176 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1177 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1178 strlen(net_dev->name));
1179 }
1180
1181 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1182
1183 return 0;
1184 }
1185
1186 /*
1187 * Assign the network dev name for created Ralink WiFi interface.
1188 */
1189 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
1190 struct net_device *dev,
1191 char *pPrefixStr, int devIdx)
1192 {
1193 struct net_device *existNetDev;
1194 char suffixName[IFNAMSIZ];
1195 char desiredName[IFNAMSIZ];
1196 int ifNameIdx, prefixLen, slotNameLen;
1197 int Status;
1198
1199 prefixLen = strlen(pPrefixStr);
1200 ASSERT((prefixLen < IFNAMSIZ));
1201
1202 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
1203 memset(suffixName, 0, IFNAMSIZ);
1204 memset(desiredName, 0, IFNAMSIZ);
1205 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1206
1207 sprintf(suffixName, "%d", ifNameIdx);
1208
1209 slotNameLen = strlen(suffixName);
1210 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1211 strcat(desiredName, suffixName);
1212
1213 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1214 if (existNetDev == NULL)
1215 break;
1216 else
1217 RtmpOSNetDeviceRefPut(existNetDev);
1218 }
1219
1220 if (ifNameIdx < 32) {
1221 strcpy(&dev->name[0], &desiredName[0]);
1222 Status = NDIS_STATUS_SUCCESS;
1223 } else {
1224 DBGPRINT(RT_DEBUG_ERROR,
1225 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1226 pPrefixStr));
1227 Status = NDIS_STATUS_FAILURE;
1228 }
1229
1230 return Status;
1231 }
1232
1233 void RtmpOSNetDevClose(struct net_device *pNetDev)
1234 {
1235 dev_close(pNetDev);
1236 }
1237
1238 void RtmpOSNetDevFree(struct net_device *pNetDev)
1239 {
1240 ASSERT(pNetDev);
1241
1242 free_netdev(pNetDev);
1243 }
1244
1245 int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize)
1246 {
1247 /* assign it as null first. */
1248 *new_dev_p = NULL;
1249
1250 DBGPRINT(RT_DEBUG_TRACE,
1251 ("Allocate a net device with private data size=%d!\n",
1252 privDataSize));
1253 *new_dev_p = alloc_etherdev(privDataSize);
1254 if (*new_dev_p)
1255 return NDIS_STATUS_SUCCESS;
1256 else
1257 return NDIS_STATUS_FAILURE;
1258 }
1259
1260 struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
1261 {
1262 struct net_device *pTargetNetDev = NULL;
1263
1264 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1265
1266 return pTargetNetDev;
1267 }
1268
1269 void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
1270 {
1271 /*
1272 every time dev_get_by_name is called, and it has returned a valid struct
1273 net_device*, dev_put should be called afterwards, because otherwise the
1274 machine hangs when the device is unregistered (since dev->refcnt > 1).
1275 */
1276 if (pNetDev)
1277 dev_put(pNetDev);
1278 }
1279
1280 int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
1281 {
1282
1283 /* TODO: Need to fix this */
1284 printk("WARNING: This function(%s) not implement yet!\n", __func__);
1285 return 0;
1286 }
1287
1288 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1289 {
1290 unregister_netdev(pNetDev);
1291 }
1292
1293 int RtmpOSNetDevAttach(struct net_device *pNetDev,
1294 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
1295 {
1296 int ret, rtnl_locked = FALSE;
1297
1298 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1299 /* If we need hook some callback function to the net device structure, now do it. */
1300 if (pDevOpHook) {
1301 struct rt_rtmp_adapter *pAd = NULL;
1302
1303 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1304
1305 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1306
1307 /* OS specific flags, here we used to indicate if we are virtual interface */
1308 pNetDev->priv_flags = pDevOpHook->priv_flags;
1309
1310 if (pAd->OpMode == OPMODE_STA)
1311 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1312
1313 /* copy the net device mac address to the net_device structure. */
1314 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1315 MAC_ADDR_LEN);
1316
1317 rtnl_locked = pDevOpHook->needProtcted;
1318 }
1319
1320 if (rtnl_locked)
1321 ret = register_netdevice(pNetDev);
1322 else
1323 ret = register_netdev(pNetDev);
1324
1325 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1326 if (ret == 0)
1327 return NDIS_STATUS_SUCCESS;
1328 else
1329 return NDIS_STATUS_FAILURE;
1330 }
1331
1332 struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
1333 int devType,
1334 int devNum,
1335 int privMemSize, char *pNamePrefix)
1336 {
1337 struct net_device *pNetDev = NULL;
1338 int status;
1339
1340 /* allocate a new network device */
1341 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */);
1342 if (status != NDIS_STATUS_SUCCESS) {
1343 /* allocation fail, exit */
1344 DBGPRINT(RT_DEBUG_ERROR,
1345 ("Allocate network device fail (%s)...\n",
1346 pNamePrefix));
1347 return NULL;
1348 }
1349
1350 /* find an available interface name, max 32 interfaces */
1351 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1352 if (status != NDIS_STATUS_SUCCESS) {
1353 /* error! no available ra name can be used! */
1354 DBGPRINT(RT_DEBUG_ERROR,
1355 ("Assign interface name (%s with suffix 0~32) failed...\n",
1356 pNamePrefix));
1357 RtmpOSNetDevFree(pNetDev);
1358
1359 return NULL;
1360 } else {
1361 DBGPRINT(RT_DEBUG_TRACE,
1362 ("The name of the new %s interface is %s...\n",
1363 pNamePrefix, pNetDev->name));
1364 }
1365
1366 return pNetDev;
1367 }