Staging: rt2860: remove superfluous newlines
[deliverable/linux.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/sched.h>
29 #include "rt_config.h"
30
31 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
32
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 */
55 };
56
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 */
69 };
70
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 */
80 };
81
82 /* timeout -- ms */
83 void RTMP_SetPeriodicTimer(struct timer_list * pTimer,
84 IN unsigned long timeout)
85 {
86 timeout = ((timeout * OS_HZ) / 1000);
87 pTimer->expires = jiffies + timeout;
88 add_timer(pTimer);
89 }
90
91 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
92 void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
93 struct timer_list * pTimer,
94 IN TIMER_FUNCTION function, void *data)
95 {
96 init_timer(pTimer);
97 pTimer->data = (unsigned long)data;
98 pTimer->function = function;
99 }
100
101 void RTMP_OS_Add_Timer(struct timer_list * pTimer,
102 IN unsigned long timeout)
103 {
104 if (timer_pending(pTimer))
105 return;
106
107 timeout = ((timeout * OS_HZ) / 1000);
108 pTimer->expires = jiffies + timeout;
109 add_timer(pTimer);
110 }
111
112 void RTMP_OS_Mod_Timer(struct timer_list * pTimer,
113 IN unsigned long timeout)
114 {
115 timeout = ((timeout * OS_HZ) / 1000);
116 mod_timer(pTimer, jiffies + timeout);
117 }
118
119 void RTMP_OS_Del_Timer(struct timer_list * pTimer,
120 OUT BOOLEAN * pCancelled)
121 {
122 if (timer_pending(pTimer)) {
123 *pCancelled = del_timer_sync(pTimer);
124 } else {
125 *pCancelled = TRUE;
126 }
127
128 }
129
130 void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
131 {
132 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
133 }
134
135 /* Unify all delay routine by using udelay */
136 void RTMPusecDelay(unsigned long usec)
137 {
138 unsigned long i;
139
140 for (i = 0; i < (usec / 50); i++)
141 udelay(50);
142
143 if (usec % 50)
144 udelay(usec % 50);
145 }
146
147 void RTMP_GetCurrentSystemTime(LARGE_INTEGER * time)
148 {
149 time->u.LowPart = jiffies;
150 }
151
152 /* pAd MUST allow to be NULL */
153 int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
154 {
155 *mem = (u8 *)kmalloc(size, GFP_ATOMIC);
156 if (*mem)
157 return (NDIS_STATUS_SUCCESS);
158 else
159 return (NDIS_STATUS_FAILURE);
160 }
161
162 /* pAd MUST allow to be NULL */
163 int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
164 {
165
166 ASSERT(mem);
167 kfree(mem);
168 return (NDIS_STATUS_SUCCESS);
169 }
170
171 void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
172 {
173 struct sk_buff *skb;
174 /* Add 2 more bytes for ip header alignment */
175 skb = dev_alloc_skb(size + 2);
176
177 return ((void *)skb);
178 }
179
180 void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
181 unsigned long Length)
182 {
183 struct sk_buff *pkt;
184
185 pkt = dev_alloc_skb(Length);
186
187 if (pkt == NULL) {
188 DBGPRINT(RT_DEBUG_ERROR,
189 ("can't allocate frag rx %ld size packet\n", Length));
190 }
191
192 if (pkt) {
193 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
194 }
195
196 return (void *)pkt;
197 }
198
199 void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
200 unsigned long Length,
201 IN BOOLEAN Cached,
202 void ** VirtualAddress)
203 {
204 struct sk_buff *pkt;
205
206 pkt = dev_alloc_skb(Length);
207
208 if (pkt == NULL) {
209 DBGPRINT(RT_DEBUG_ERROR,
210 ("can't allocate tx %ld size packet\n", Length));
211 }
212
213 if (pkt) {
214 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
215 *VirtualAddress = (void *)pkt->data;
216 } else {
217 *VirtualAddress = (void *)NULL;
218 }
219
220 return (void *)pkt;
221 }
222
223 void build_tx_packet(struct rt_rtmp_adapter *pAd,
224 void *pPacket,
225 u8 *pFrame, unsigned long FrameLen)
226 {
227
228 struct sk_buff *pTxPkt;
229
230 ASSERT(pPacket);
231 pTxPkt = RTPKT_TO_OSPKT(pPacket);
232
233 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
234 }
235
236 void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
237 {
238 struct os_cookie *os_cookie;
239 int index;
240
241 os_cookie = (struct os_cookie *)pAd->OS_Cookie;
242
243 if (pAd->BeaconBuf)
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 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
264 if (os_cookie)
265 kfree(os_cookie);
266 }
267
268 BOOLEAN OS_Need_Clone_Packet(void)
269 {
270 return (FALSE);
271 }
272
273 /*
274 ========================================================================
275
276 Routine Description:
277 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
278 must have only one NDIS BUFFER
279 return - byte copied. 0 means can't create NDIS PACKET
280 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
281
282 Arguments:
283 pAd Pointer to our adapter
284 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
285 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
286
287 Return Value:
288 NDIS_STATUS_SUCCESS
289 NDIS_STATUS_FAILURE
290
291 Note:
292
293 ========================================================================
294 */
295 int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
296 IN BOOLEAN pInsAMSDUHdr,
297 void *pInPacket,
298 void ** ppOutPacket)
299 {
300
301 struct sk_buff *pkt;
302
303 ASSERT(pInPacket);
304 ASSERT(ppOutPacket);
305
306 /* 1. Allocate a packet */
307 pkt = dev_alloc_skb(2048);
308
309 if (pkt == NULL) {
310 return NDIS_STATUS_FAILURE;
311 }
312
313 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
314 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
315 GET_OS_PKT_LEN(pInPacket));
316 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
317
318 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
319
320 printk("###Clone###\n");
321
322 return NDIS_STATUS_SUCCESS;
323 }
324
325 /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
326 int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
327 void ** ppPacket,
328 u8 *pHeader,
329 u32 HeaderLen,
330 u8 *pData, u32 DataLen)
331 {
332 void *pPacket;
333 ASSERT(pData);
334 ASSERT(DataLen);
335
336 /* 1. Allocate a packet */
337 pPacket =
338 (void **) dev_alloc_skb(HeaderLen + DataLen +
339 RTMP_PKT_TAIL_PADDING);
340 if (pPacket == NULL) {
341 *ppPacket = NULL;
342 #ifdef DEBUG
343 printk("RTMPAllocateNdisPacket Fail\n");
344 #endif
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 if ((skb =
463 __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
464 skb_reserve(skb, 2);
465 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
466 skb_put(skb, HdrLen);
467 NdisMoveMemory(skb->tail, 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 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
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 pOSPkt->tail = pOSPkt->data + 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 pOSPkt->tail = pOSPkt->data + 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("%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
601 for (x = 0; x < SrcBufLen; x++) {
602 if (x % 16 == 0)
603 printk("0x%04x : ", x);
604 printk("%02x ", ((unsigned char)pt[x]));
605 if (x % 16 == 15)
606 printk("\n");
607 }
608 printk("\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 if ((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) {
673 /*Prepare the payload */
674 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
675
676 pBufPtr = pBuf;
677
678 if (pAddr)
679 pBufPtr +=
680 sprintf(pBufPtr,
681 "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ",
682 PRINT_MAC(pAddr));
683 else if (BssIdx < MAX_MBSSID_NUM)
684 pBufPtr +=
685 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
686 else
687 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
688
689 if (type == IW_SYS_EVENT_FLAG_START)
690 pBufPtr +=
691 sprintf(pBufPtr, "%s",
692 pWirelessSysEventText[event]);
693 else if (type == IW_SPOOF_EVENT_FLAG_START)
694 pBufPtr +=
695 sprintf(pBufPtr, "%s (RSSI=%d)",
696 pWirelessSpoofEventText[event], Rssi);
697 else if (type == IW_FLOOD_EVENT_FLAG_START)
698 pBufPtr +=
699 sprintf(pBufPtr, "%s",
700 pWirelessFloodEventText[event]);
701 else
702 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
703
704 pBufPtr[pBufPtr - pBuf] = '\0';
705 BufLen = pBufPtr - pBuf;
706
707 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
708 (u8 *)pBuf, BufLen);
709 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
710
711 kfree(pBuf);
712 } else
713 DBGPRINT(RT_DEBUG_ERROR,
714 ("%s : Can't allocate memory for wireless event.\n",
715 __func__));
716 }
717
718 void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
719 {
720 struct sk_buff *pOSPkt;
721 struct rt_wlan_ng_prism2_header *ph;
722 int rate_index = 0;
723 u16 header_len = 0;
724 u8 temp_header[40] = { 0 };
725
726 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 */
727 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
728 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
729 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
730 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
731 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
732 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
733 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
734 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
735 72, 73, 74, 75, 76, 77, 78, 79, 80
736 };
737
738 ASSERT(pRxBlk->pRxPacket);
739 if (pRxBlk->DataSize < 10) {
740 DBGPRINT(RT_DEBUG_ERROR,
741 ("%s : Size is too small! (%d)\n", __func__,
742 pRxBlk->DataSize));
743 goto err_free_sk_buff;
744 }
745
746 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
747 RX_BUFFER_AGGRESIZE) {
748 DBGPRINT(RT_DEBUG_ERROR,
749 ("%s : Size is too large! (%zu)\n", __func__,
750 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
751 goto err_free_sk_buff;
752 }
753
754 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
755 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
756 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
757 pRxBlk->DataSize -= LENGTH_802_11;
758 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
759 (pRxBlk->pHeader->FC.FrDs == 1))
760 header_len = LENGTH_802_11_WITH_ADDR4;
761 else
762 header_len = LENGTH_802_11;
763
764 /* QOS */
765 if (pRxBlk->pHeader->FC.SubType & 0x08) {
766 header_len += 2;
767 /* Data skip QOS contorl field */
768 pRxBlk->DataSize -= 2;
769 }
770 /* Order bit: A-Ralink or HTC+ */
771 if (pRxBlk->pHeader->FC.Order) {
772 header_len += 4;
773 /* Data skip HTC contorl field */
774 pRxBlk->DataSize -= 4;
775 }
776 /* Copy Header */
777 if (header_len <= 40)
778 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
779
780 /* skip HW padding */
781 if (pRxBlk->RxD.L2PAD)
782 pRxBlk->pData += (header_len + 2);
783 else
784 pRxBlk->pData += header_len;
785 } /*end if */
786
787 if (pRxBlk->DataSize < pOSPkt->len) {
788 skb_trim(pOSPkt, pRxBlk->DataSize);
789 } else {
790 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
791 } /*end if */
792
793 if ((pRxBlk->pData - pOSPkt->data) > 0) {
794 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
795 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
796 } /*end if */
797
798 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
799 if (pskb_expand_head
800 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
801 GFP_ATOMIC)) {
802 DBGPRINT(RT_DEBUG_ERROR,
803 ("%s : Reallocate header size of sk_buff fail!\n",
804 __func__));
805 goto err_free_sk_buff;
806 } /*end if */
807 } /*end if */
808
809 if (header_len > 0)
810 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
811 header_len);
812
813 ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
814 sizeof(struct rt_wlan_ng_prism2_header));
815 NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
816
817 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
818 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
819 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
820
821 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
822 ph->hosttime.status = 0;
823 ph->hosttime.len = 4;
824 ph->hosttime.data = jiffies;
825
826 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
827 ph->mactime.status = 0;
828 ph->mactime.len = 0;
829 ph->mactime.data = 0;
830
831 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
832 ph->istx.status = 0;
833 ph->istx.len = 0;
834 ph->istx.data = 0;
835
836 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
837 ph->channel.status = 0;
838 ph->channel.len = 4;
839
840 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
841
842 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
843 ph->rssi.status = 0;
844 ph->rssi.len = 4;
845 ph->rssi.data =
846 (u_int32_t) RTMPMaxRssi(pAd,
847 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
848 RSSI_0), ConvertToRssi(pAd,
849 pRxBlk->
850 pRxWI->
851 RSSI1,
852 RSSI_1),
853 ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
854 RSSI_2));;
855
856 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
857 ph->signal.status = 0;
858 ph->signal.len = 4;
859 ph->signal.data = 0; /*rssi + noise; */
860
861 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
862 ph->noise.status = 0;
863 ph->noise.len = 4;
864 ph->noise.data = 0;
865
866 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
867 rate_index =
868 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
869 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
870 ((u8)pRxBlk->pRxWI->MCS);
871 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
872 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
873 else
874 rate_index = (u8)(pRxBlk->pRxWI->MCS);
875 if (rate_index < 0)
876 rate_index = 0;
877 if (rate_index > 255)
878 rate_index = 255;
879
880 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
881 ph->rate.status = 0;
882 ph->rate.len = 4;
883 ph->rate.data = ralinkrate[rate_index];
884
885 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
886 ph->frmlen.status = 0;
887 ph->frmlen.len = 4;
888 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
889
890 pOSPkt->pkt_type = PACKET_OTHERHOST;
891 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
892 pOSPkt->ip_summed = CHECKSUM_NONE;
893 netif_rx(pOSPkt);
894
895 return;
896
897 err_free_sk_buff:
898 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
899 return;
900
901 }
902
903 /*******************************************************************************
904
905 Device IRQ related functions.
906
907 *******************************************************************************/
908 int RtmpOSIRQRequest(struct net_device *pNetDev)
909 {
910 #ifdef RTMP_PCI_SUPPORT
911 struct net_device *net_dev = pNetDev;
912 struct rt_rtmp_adapter *pAd = NULL;
913 int retval = 0;
914
915 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
916
917 ASSERT(pAd);
918
919 if (pAd->infType == RTMP_DEV_INF_PCI) {
920 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
921 RTMP_MSI_ENABLE(pAd);
922 retval =
923 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
924 (net_dev)->name, (net_dev));
925 if (retval != 0)
926 printk("RT2860: request_irq ERROR(%d)\n", retval);
927 }
928
929 return retval;
930 #else
931 return 0;
932 #endif
933 }
934
935 int RtmpOSIRQRelease(struct net_device *pNetDev)
936 {
937 struct net_device *net_dev = pNetDev;
938 struct rt_rtmp_adapter *pAd = NULL;
939
940 GET_PAD_FROM_NET_DEV(pAd, net_dev);
941
942 ASSERT(pAd);
943
944 #ifdef RTMP_PCI_SUPPORT
945 if (pAd->infType == RTMP_DEV_INF_PCI) {
946 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
947 synchronize_irq(pObj->pci_dev->irq);
948 free_irq(pObj->pci_dev->irq, (net_dev));
949 RTMP_MSI_DISABLE(pAd);
950 }
951 #endif /* RTMP_PCI_SUPPORT // */
952
953 return 0;
954 }
955
956 /*******************************************************************************
957
958 File open/close related functions.
959
960 *******************************************************************************/
961 struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
962 {
963 struct file *filePtr;
964
965 filePtr = filp_open(pPath, flag, 0);
966 if (IS_ERR(filePtr)) {
967 DBGPRINT(RT_DEBUG_ERROR,
968 ("%s(): Error %ld opening %s\n", __func__,
969 -PTR_ERR(filePtr), pPath));
970 }
971
972 return (struct file *)filePtr;
973 }
974
975 int RtmpOSFileClose(struct file *osfd)
976 {
977 filp_close(osfd, NULL);
978 return 0;
979 }
980
981 void RtmpOSFileSeek(struct file *osfd, int offset)
982 {
983 osfd->f_pos = offset;
984 }
985
986 int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
987 {
988 /* The object must have a read method */
989 if (osfd->f_op && osfd->f_op->read) {
990 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
991 } else {
992 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
993 return -1;
994 }
995 }
996
997 int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
998 {
999 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
1000 &osfd->f_pos);
1001 }
1002
1003 /*******************************************************************************
1004
1005 Task create/management/kill related functions.
1006
1007 *******************************************************************************/
1008 int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
1009 {
1010 struct rt_rtmp_adapter *pAd;
1011 int ret = NDIS_STATUS_FAILURE;
1012
1013 pAd = (struct rt_rtmp_adapter *)pTask->priv;
1014
1015 #ifdef KTHREAD_SUPPORT
1016 if (pTask->kthread_task) {
1017 kthread_stop(pTask->kthread_task);
1018 ret = NDIS_STATUS_SUCCESS;
1019 }
1020 #else
1021 CHECK_PID_LEGALITY(pTask->taskPID) {
1022 printk("Terminate the task(%s) with pid(%d)!\n",
1023 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
1024 mb();
1025 pTask->task_killed = 1;
1026 mb();
1027 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
1028 if (ret) {
1029 printk(KERN_WARNING
1030 "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
1031 pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
1032 ret);
1033 } else {
1034 wait_for_completion(&pTask->taskComplete);
1035 pTask->taskPID = THREAD_PID_INIT_VALUE;
1036 pTask->task_killed = 0;
1037 ret = NDIS_STATUS_SUCCESS;
1038 }
1039 }
1040 #endif
1041
1042 return ret;
1043
1044 }
1045
1046 int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
1047 {
1048
1049 #ifndef KTHREAD_SUPPORT
1050 complete_and_exit(&pTask->taskComplete, 0);
1051 #endif
1052
1053 return 0;
1054 }
1055
1056 void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
1057 {
1058
1059 #ifndef KTHREAD_SUPPORT
1060
1061 daemonize((char *)& pTask->taskName[0] /*"%s",pAd->net_dev->name */ );
1062
1063 allow_signal(SIGTERM);
1064 allow_signal(SIGKILL);
1065 current->flags |= PF_NOFREEZE;
1066
1067 /* signal that we've started the thread */
1068 complete(&pTask->taskComplete);
1069
1070 #endif
1071 }
1072
1073 int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
1074 IN int (*fn) (void *), IN void *arg)
1075 {
1076 int status = NDIS_STATUS_SUCCESS;
1077
1078 #ifdef KTHREAD_SUPPORT
1079 pTask->task_killed = 0;
1080 pTask->kthread_task = NULL;
1081 pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
1082 if (IS_ERR(pTask->kthread_task))
1083 status = NDIS_STATUS_FAILURE;
1084 #else
1085 pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
1086 if (pid_number < 0) {
1087 DBGPRINT(RT_DEBUG_ERROR,
1088 ("Attach task(%s) failed!\n", pTask->taskName));
1089 status = NDIS_STATUS_FAILURE;
1090 } else {
1091 pTask->taskPID = GET_PID(pid_number);
1092
1093 /* Wait for the thread to start */
1094 wait_for_completion(&pTask->taskComplete);
1095 status = NDIS_STATUS_SUCCESS;
1096 }
1097 #endif
1098 return status;
1099 }
1100
1101 int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
1102 char *pTaskName, void * pPriv)
1103 {
1104 int len;
1105
1106 ASSERT(pTask);
1107
1108 #ifndef KTHREAD_SUPPORT
1109 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
1110 #endif
1111
1112 len = strlen(pTaskName);
1113 len =
1114 len >
1115 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
1116 NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
1117 pTask->priv = pPriv;
1118
1119 #ifndef KTHREAD_SUPPORT
1120 RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
1121 pTask->taskPID = THREAD_PID_INIT_VALUE;
1122
1123 init_completion(&pTask->taskComplete);
1124 #endif
1125
1126 return NDIS_STATUS_SUCCESS;
1127 }
1128
1129 void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
1130 {
1131 if (pAd->CommonCfg.bWirelessEvent) {
1132 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1133 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1134 pAd->MacTab.Content[BSSID_WCID].
1135 Addr, BSS0, 0);
1136 } else {
1137 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1138 pAd->MacTab.Content[BSSID_WCID].
1139 Addr, BSS0, 0);
1140 }
1141 }
1142 }
1143
1144 int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
1145 u32 eventType,
1146 int flags,
1147 u8 *pSrcMac,
1148 u8 *pData, u32 dataLen)
1149 {
1150 union iwreq_data wrqu;
1151
1152 memset(&wrqu, 0, sizeof(wrqu));
1153
1154 if (flags > -1)
1155 wrqu.data.flags = flags;
1156
1157 if (pSrcMac)
1158 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1159
1160 if ((pData != NULL) && (dataLen > 0))
1161 wrqu.data.length = dataLen;
1162
1163 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
1164 return 0;
1165 }
1166
1167 int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
1168 {
1169 struct net_device *net_dev;
1170 struct rt_rtmp_adapter *pAd;
1171
1172 net_dev = pNetDev;
1173 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1174
1175 /* work-around for the SuSE due to it has it's own interface name management system. */
1176 {
1177 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
1178 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1179 strlen(net_dev->name));
1180 }
1181
1182 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1183
1184 return 0;
1185 }
1186
1187 /*
1188 * Assign the network dev name for created Ralink WiFi interface.
1189 */
1190 static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
1191 struct net_device *dev,
1192 char *pPrefixStr, int devIdx)
1193 {
1194 struct net_device *existNetDev;
1195 char suffixName[IFNAMSIZ];
1196 char desiredName[IFNAMSIZ];
1197 int ifNameIdx, prefixLen, slotNameLen;
1198 int Status;
1199
1200 prefixLen = strlen(pPrefixStr);
1201 ASSERT((prefixLen < IFNAMSIZ));
1202
1203 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
1204 memset(suffixName, 0, IFNAMSIZ);
1205 memset(desiredName, 0, IFNAMSIZ);
1206 strncpy(&desiredName[0], pPrefixStr, prefixLen);
1207
1208 sprintf(suffixName, "%d", ifNameIdx);
1209
1210 slotNameLen = strlen(suffixName);
1211 ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
1212 strcat(desiredName, suffixName);
1213
1214 existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
1215 if (existNetDev == NULL)
1216 break;
1217 else
1218 RtmpOSNetDeviceRefPut(existNetDev);
1219 }
1220
1221 if (ifNameIdx < 32) {
1222 strcpy(&dev->name[0], &desiredName[0]);
1223 Status = NDIS_STATUS_SUCCESS;
1224 } else {
1225 DBGPRINT(RT_DEBUG_ERROR,
1226 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1227 pPrefixStr));
1228 Status = NDIS_STATUS_FAILURE;
1229 }
1230
1231 return Status;
1232 }
1233
1234 void RtmpOSNetDevClose(struct net_device *pNetDev)
1235 {
1236 dev_close(pNetDev);
1237 }
1238
1239 void RtmpOSNetDevFree(struct net_device *pNetDev)
1240 {
1241 ASSERT(pNetDev);
1242
1243 free_netdev(pNetDev);
1244 }
1245
1246 int RtmpOSNetDevAlloc(struct net_device ** new_dev_p, u32 privDataSize)
1247 {
1248 /* assign it as null first. */
1249 *new_dev_p = NULL;
1250
1251 DBGPRINT(RT_DEBUG_TRACE,
1252 ("Allocate a net device with private data size=%d!\n",
1253 privDataSize));
1254 *new_dev_p = alloc_etherdev(privDataSize);
1255 if (*new_dev_p)
1256 return NDIS_STATUS_SUCCESS;
1257 else
1258 return NDIS_STATUS_FAILURE;
1259 }
1260
1261 struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
1262 {
1263 struct net_device *pTargetNetDev = NULL;
1264
1265 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1266
1267 return pTargetNetDev;
1268 }
1269
1270 void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
1271 {
1272 /*
1273 every time dev_get_by_name is called, and it has returned a valid struct
1274 net_device*, dev_put should be called afterwards, because otherwise the
1275 machine hangs when the device is unregistered (since dev->refcnt > 1).
1276 */
1277 if (pNetDev)
1278 dev_put(pNetDev);
1279 }
1280
1281 int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
1282 {
1283
1284 /* TODO: Need to fix this */
1285 printk("WARNING: This function(%s) not implement yet!!!\n", __func__);
1286 return 0;
1287 }
1288
1289 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1290 {
1291 unregister_netdev(pNetDev);
1292 }
1293
1294 int RtmpOSNetDevAttach(struct net_device *pNetDev,
1295 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
1296 {
1297 int ret, rtnl_locked = FALSE;
1298
1299 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
1300 /* If we need hook some callback function to the net device structrue, now do it. */
1301 if (pDevOpHook) {
1302 struct rt_rtmp_adapter *pAd = NULL;
1303
1304 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
1305
1306 pNetDev->netdev_ops = pDevOpHook->netdev_ops;
1307
1308 /* OS specific flags, here we used to indicate if we are virtual interface */
1309 pNetDev->priv_flags = pDevOpHook->priv_flags;
1310
1311 if (pAd->OpMode == OPMODE_STA) {
1312 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
1313 }
1314
1315 /* copy the net device mac address to the net_device structure. */
1316 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1317 MAC_ADDR_LEN);
1318
1319 rtnl_locked = pDevOpHook->needProtcted;
1320 }
1321
1322 if (rtnl_locked)
1323 ret = register_netdevice(pNetDev);
1324 else
1325 ret = register_netdev(pNetDev);
1326
1327 DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
1328 if (ret == 0)
1329 return NDIS_STATUS_SUCCESS;
1330 else
1331 return NDIS_STATUS_FAILURE;
1332 }
1333
1334 struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
1335 int devType,
1336 int devNum,
1337 int privMemSize, char *pNamePrefix)
1338 {
1339 struct net_device *pNetDev = NULL;
1340 int status;
1341
1342 /* allocate a new network device */
1343 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */ );
1344 if (status != NDIS_STATUS_SUCCESS) {
1345 /* allocation fail, exit */
1346 DBGPRINT(RT_DEBUG_ERROR,
1347 ("Allocate network device fail (%s)...\n",
1348 pNamePrefix));
1349 return NULL;
1350 }
1351
1352 /* find a available interface name, max 32 interfaces */
1353 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
1354 if (status != NDIS_STATUS_SUCCESS) {
1355 /* error! no any available ra name can be used! */
1356 DBGPRINT(RT_DEBUG_ERROR,
1357 ("Assign interface name (%s with suffix 0~32) failed...\n",
1358 pNamePrefix));
1359 RtmpOSNetDevFree(pNetDev);
1360
1361 return NULL;
1362 } else {
1363 DBGPRINT(RT_DEBUG_TRACE,
1364 ("The name of the new %s interface is %s...\n",
1365 pNamePrefix, pNetDev->name));
1366 }
1367
1368 return pNetDev;
1369 }
This page took 0.058447 seconds and 5 git commands to generate.