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 */
RTMP_SetPeriodicTimer(struct timer_list * pTimer,IN unsigned long timeout)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 */
RTMP_OS_Init_Timer(struct rt_rtmp_adapter * pAd,struct timer_list * pTimer,IN TIMER_FUNCTION function,void * data)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 
RTMP_OS_Add_Timer(struct timer_list * pTimer,IN unsigned long timeout)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 
RTMP_OS_Mod_Timer(struct timer_list * pTimer,IN unsigned long timeout)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 
RTMP_OS_Del_Timer(struct timer_list * pTimer,OUT BOOLEAN * pCancelled)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 
RTMP_OS_Release_Packet(struct rt_rtmp_adapter * pAd,struct rt_queue_entry * pEntry)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 */
RTMPusecDelay(unsigned long usec)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 
RTMP_GetCurrentSystemTime(LARGE_INTEGER * time)148 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
149 {
150 	time->u.LowPart = jiffies;
151 }
152 
153 /* pAd MUST allow to be NULL */
os_alloc_mem(struct rt_rtmp_adapter * pAd,u8 ** mem,unsigned long size)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 */
os_free_mem(struct rt_rtmp_adapter * pAd,void * mem)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 
RtmpOSNetPktAlloc(struct rt_rtmp_adapter * pAd,IN int size)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 
RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter * pAd,unsigned long Length)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 
RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter * pAd,unsigned long Length,IN BOOLEAN Cached,void ** VirtualAddress)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 
build_tx_packet(struct rt_rtmp_adapter * pAd,void * pPacket,u8 * pFrame,unsigned long FrameLen)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 
RTMPFreeAdapter(struct rt_rtmp_adapter * pAd)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 
OS_Need_Clone_Packet(void)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 */
RTMPCloneNdisPacket(struct rt_rtmp_adapter * pAd,IN BOOLEAN pInsAMSDUHdr,void * pInPacket,void ** ppOutPacket)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() */
RTMPAllocateNdisPacket(struct rt_rtmp_adapter * pAd,void ** ppPacket,u8 * pHeader,u32 HeaderLen,u8 * pData,u32 DataLen)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 */
RTMPFreeNdisPacket(struct rt_rtmp_adapter * pAd,void * pPacket)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 */
Sniff2BytesFromNdisBuffer(char * pFirstBuffer,u8 DesiredOffset,u8 * pByte0,u8 * pByte1)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 
RTMP_QueryPacketInfo(void * pPacket,struct rt_packet_info * pPacketInfo,u8 ** pSrcBufVA,u32 * pSrcBufLen)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 
RTMP_QueryNextPacketInfo(void ** ppPacket,struct rt_packet_info * pPacketInfo,u8 ** pSrcBufVA,u32 * pSrcBufLen)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 
DuplicatePacket(struct rt_rtmp_adapter * pAd,void * pPacket,u8 FromWhichBSSID)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 
duplicate_pkt(struct rt_rtmp_adapter * pAd,u8 * pHeader802_3,u32 HdrLen,u8 * pData,unsigned long DataSize,u8 FromWhichBSSID)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
duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter * pAd,void * pPacket)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 
ClonePacket(struct rt_rtmp_adapter * pAd,void * pPacket,u8 * pData,unsigned long DataSize)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 /* */
update_os_packet_info(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,u8 FromWhichBSSID)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 
wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk,u8 * pHeader802_3,u8 FromWhichBSSID)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 
announce_802_3_packet(struct rt_rtmp_adapter * pAd,void * pPacket)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 *
rt_get_sg_list_from_packet(void * pPacket,struct rt_rtmp_sg_list * sg)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 
hex_dump(char * str,unsigned char * pSrcBufVA,unsigned int SrcBufLen)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 */
RTMPSendWirelessEvent(struct rt_rtmp_adapter * pAd,u16 Event_flag,u8 * pAddr,u8 BssIdx,char Rssi)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 
send_monitor_packets(struct rt_rtmp_adapter * pAd,struct rt_rx_blk * pRxBlk)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  *******************************************************************************/
RtmpOSIRQRequest(struct net_device * pNetDev)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 
RtmpOSIRQRelease(struct net_device * pNetDev)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  *******************************************************************************/
RtmpOSFileOpen(char * pPath,int flag,int mode)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 
RtmpOSFileClose(struct file * osfd)974 int RtmpOSFileClose(struct file *osfd)
975 {
976 	filp_close(osfd, NULL);
977 	return 0;
978 }
979 
RtmpOSFileSeek(struct file * osfd,int offset)980 void RtmpOSFileSeek(struct file *osfd, int offset)
981 {
982 	osfd->f_pos = offset;
983 }
984 
RtmpOSFileRead(struct file * osfd,char * pDataPtr,int readLen)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 
RtmpOSFileWrite(struct file * osfd,char * pDataPtr,int writeLen)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  *******************************************************************************/
RtmpOSTaskKill(struct rt_rtmp_os_task * pTask)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 
RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task * pTask)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 
RtmpOSTaskCustomize(struct rt_rtmp_os_task * pTask)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 
RtmpOSTaskAttach(struct rt_rtmp_os_task * pTask,IN int (* fn)(void *),IN void * arg)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 
RtmpOSTaskInit(struct rt_rtmp_os_task * pTask,char * pTaskName,void * pPriv)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 
RTMP_IndicateMediaState(struct rt_rtmp_adapter * pAd)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 
RtmpOSWrielessEventSend(struct rt_rtmp_adapter * pAd,u32 eventType,int flags,u8 * pSrcMac,u8 * pData,u32 dataLen)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 
RtmpOSNetDevAddrSet(struct net_device * pNetDev,u8 * pMacAddr)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   */
RtmpOSNetDevRequestName(struct rt_rtmp_adapter * pAd,struct net_device * dev,char * pPrefixStr,int devIdx)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 
RtmpOSNetDevClose(struct net_device * pNetDev)1233 void RtmpOSNetDevClose(struct net_device *pNetDev)
1234 {
1235 	dev_close(pNetDev);
1236 }
1237 
RtmpOSNetDevFree(struct net_device * pNetDev)1238 void RtmpOSNetDevFree(struct net_device *pNetDev)
1239 {
1240 	ASSERT(pNetDev);
1241 
1242 	free_netdev(pNetDev);
1243 }
1244 
RtmpOSNetDevAlloc(struct net_device ** new_dev_p,u32 privDataSize)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 
RtmpOSNetDevGetByName(struct net_device * pNetDev,char * pDevName)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 
RtmpOSNetDeviceRefPut(struct net_device * pNetDev)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 
RtmpOSNetDevDestory(struct rt_rtmp_adapter * pAd,struct net_device * pNetDev)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 
RtmpOSNetDevDetach(struct net_device * pNetDev)1288 void RtmpOSNetDevDetach(struct net_device *pNetDev)
1289 {
1290 	unregister_netdev(pNetDev);
1291 }
1292 
RtmpOSNetDevAttach(struct net_device * pNetDev,struct rt_rtmp_os_netdev_op_hook * pDevOpHook)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 
RtmpOSNetDevCreate(struct rt_rtmp_adapter * pAd,int devType,int devNum,int privMemSize,char * pNamePrefix)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 }
1368