]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/rt2860/rt_linux.c
Fix common misspellings
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / rt2860 / rt_linux.c
CommitLineData
91980990
GKH
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
c22202fa 28#include <linux/firmware.h>
5f267996 29#include <linux/sched.h>
5a0e3ad6 30#include <linux/slab.h>
91980990
GKH
31#include "rt_config.h"
32
51126deb 33unsigned long RTDebugLevel = RT_DEBUG_ERROR;
91980990 34
9f548a2a 35/* for wireless system event message */
91980990 36char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
9f548a2a 37 /* system status event */
66cd8d6e
BZ
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 */
06aea994 56 "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
66cd8d6e 57};
91980990 58
9f548a2a 59/* for wireless IDS_spoof_attack event message */
91980990 60char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
66cd8d6e
BZ
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};
91980990 72
9f548a2a 73/* for wireless IDS_flooding_attack event message */
91980990 74char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
66cd8d6e
BZ
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};
91980990
GKH
83
84/* timeout -- ms */
cc9b5222 85void RTMP_SetPeriodicTimer(struct timer_list *pTimer,
66cd8d6e 86 IN unsigned long timeout)
91980990 87{
66cd8d6e 88 timeout = ((timeout * OS_HZ) / 1000);
91980990
GKH
89 pTimer->expires = jiffies + timeout;
90 add_timer(pTimer);
91}
92
93/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
62eb734b 94void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
cc9b5222 95 struct timer_list *pTimer,
51126deb 96 IN TIMER_FUNCTION function, void *data)
91980990
GKH
97{
98 init_timer(pTimer);
66cd8d6e
BZ
99 pTimer->data = (unsigned long)data;
100 pTimer->function = function;
91980990
GKH
101}
102
cc9b5222 103void RTMP_OS_Add_Timer(struct timer_list *pTimer,
66cd8d6e 104 IN unsigned long timeout)
91980990
GKH
105{
106 if (timer_pending(pTimer))
107 return;
108
66cd8d6e 109 timeout = ((timeout * OS_HZ) / 1000);
91980990
GKH
110 pTimer->expires = jiffies + timeout;
111 add_timer(pTimer);
112}
113
cc9b5222 114void RTMP_OS_Mod_Timer(struct timer_list *pTimer,
66cd8d6e 115 IN unsigned long timeout)
91980990 116{
66cd8d6e 117 timeout = ((timeout * OS_HZ) / 1000);
91980990
GKH
118 mod_timer(pTimer, jiffies + timeout);
119}
120
5673db40 121void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN *pCancelled)
91980990 122{
66cd8d6e 123 if (timer_pending(pTimer)) {
91980990 124 *pCancelled = del_timer_sync(pTimer);
66cd8d6e 125 } else {
91980990
GKH
126 *pCancelled = TRUE;
127 }
128
129}
130
62eb734b 131void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
91980990 132{
9f548a2a 133 /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
91980990
GKH
134}
135
9f548a2a 136/* Unify all delay routine by using udelay */
51126deb 137void RTMPusecDelay(unsigned long usec)
91980990 138{
51126deb 139 unsigned long i;
91980990
GKH
140
141 for (i = 0; i < (usec / 50); i++)
142 udelay(50);
143
144 if (usec % 50)
145 udelay(usec % 50);
146}
147
cc9b5222 148void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
91980990
GKH
149{
150 time->u.LowPart = jiffies;
151}
152
9f548a2a 153/* pAd MUST allow to be NULL */
62eb734b 154int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
91980990 155{
32414878 156 *mem = kmalloc(size, GFP_ATOMIC);
91980990 157 if (*mem)
cc9b5222 158 return NDIS_STATUS_SUCCESS;
91980990 159 else
cc9b5222 160 return NDIS_STATUS_FAILURE;
91980990
GKH
161}
162
9f548a2a 163/* pAd MUST allow to be NULL */
62eb734b 164int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
91980990
GKH
165{
166
167 ASSERT(mem);
168 kfree(mem);
cc9b5222 169 return NDIS_STATUS_SUCCESS;
91980990
GKH
170}
171
62eb734b 172void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
ca97b838
BZ
173{
174 struct sk_buff *skb;
66cd8d6e
BZ
175 /* Add 2 more bytes for ip header alignment */
176 skb = dev_alloc_skb(size + 2);
ca97b838 177
cc9b5222 178 return (void *)skb;
ca97b838
BZ
179}
180
62eb734b 181void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
51126deb 182 unsigned long Length)
91980990
GKH
183{
184 struct sk_buff *pkt;
185
186 pkt = dev_alloc_skb(Length);
187
66cd8d6e
BZ
188 if (pkt == NULL) {
189 DBGPRINT(RT_DEBUG_ERROR,
190 ("can't allocate frag rx %ld size packet\n", Length));
91980990
GKH
191 }
192
66cd8d6e 193 if (pkt) {
91980990
GKH
194 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
195 }
196
8a10a546 197 return (void *)pkt;
91980990
GKH
198}
199
62eb734b 200void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
51126deb 201 unsigned long Length,
66cd8d6e 202 IN BOOLEAN Cached,
cc9b5222 203 void **VirtualAddress)
91980990
GKH
204{
205 struct sk_buff *pkt;
206
207 pkt = dev_alloc_skb(Length);
208
66cd8d6e
BZ
209 if (pkt == NULL) {
210 DBGPRINT(RT_DEBUG_ERROR,
211 ("can't allocate tx %ld size packet\n", Length));
91980990
GKH
212 }
213
66cd8d6e 214 if (pkt) {
91980990 215 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
51126deb 216 *VirtualAddress = (void *)pkt->data;
66cd8d6e 217 } else {
51126deb 218 *VirtualAddress = (void *)NULL;
91980990
GKH
219 }
220
8a10a546 221 return (void *)pkt;
91980990
GKH
222}
223
62eb734b 224void build_tx_packet(struct rt_rtmp_adapter *pAd,
8a10a546 225 void *pPacket,
51126deb 226 u8 *pFrame, unsigned long FrameLen)
91980990
GKH
227{
228
66cd8d6e 229 struct sk_buff *pTxPkt;
91980990
GKH
230
231 ASSERT(pPacket);
232 pTxPkt = RTPKT_TO_OSPKT(pPacket);
233
234 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
235}
236
62eb734b 237void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
91980990 238{
8a10a546 239 struct os_cookie *os_cookie;
91980990
GKH
240 int index;
241
8a10a546 242 os_cookie = (struct os_cookie *)pAd->OS_Cookie;
91980990 243
aea9d72f 244 kfree(pAd->BeaconBuf);
91980990
GKH
245
246 NdisFreeSpinLock(&pAd->MgmtRingLock);
ca97b838
BZ
247
248#ifdef RTMP_MAC_PCI
91980990 249 NdisFreeSpinLock(&pAd->RxRingLock);
e44fd1cf 250#ifdef RT3090
66cd8d6e 251 NdisFreeSpinLock(&pAd->McuCmdLock);
9f548a2a
BZ
252#endif /* RT3090 // */
253#endif /* RTMP_MAC_PCI // */
ca97b838 254
66cd8d6e
BZ
255 for (index = 0; index < NUM_OF_TX_RING; index++) {
256 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
91980990
GKH
257 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
258 pAd->DeQueueRunning[index] = FALSE;
259 }
260
261 NdisFreeSpinLock(&pAd->irq_lock);
262
c22202fa
BH
263 release_firmware(pAd->firmware);
264
62eb734b 265 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
aea9d72f 266 kfree(os_cookie);
91980990
GKH
267}
268
269BOOLEAN OS_Need_Clone_Packet(void)
270{
cc9b5222 271 return FALSE;
91980990
GKH
272}
273
91980990
GKH
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
8a10a546 281 NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
91980990
GKH
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.
25985edc 286 *pSrcTotalLen return total packet length. This length is calculated with 802.3 format packet.
91980990
GKH
287
288 Return Value:
289 NDIS_STATUS_SUCCESS
290 NDIS_STATUS_FAILURE
291
292 Note:
293
294 ========================================================================
295*/
62eb734b 296int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
66cd8d6e 297 IN BOOLEAN pInsAMSDUHdr,
8a10a546 298 void *pInPacket,
cc9b5222 299 void **ppOutPacket)
91980990
GKH
300{
301
302 struct sk_buff *pkt;
303
304 ASSERT(pInPacket);
305 ASSERT(ppOutPacket);
306
9f548a2a 307 /* 1. Allocate a packet */
91980990
GKH
308 pkt = dev_alloc_skb(2048);
309
66cd8d6e 310 if (pkt == NULL) {
91980990
GKH
311 return NDIS_STATUS_FAILURE;
312 }
313
66cd8d6e
BZ
314 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
315 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
316 GET_OS_PKT_LEN(pInPacket));
91980990
GKH
317 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
318
91980990
GKH
319 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
320
3be305fd 321 printk(KERN_DEBUG "###Clone###\n");
91980990
GKH
322
323 return NDIS_STATUS_SUCCESS;
324}
325
9f548a2a 326/* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
62eb734b 327int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
cc9b5222 328 void **ppPacket,
51126deb
BZ
329 u8 *pHeader,
330 u32 HeaderLen,
331 u8 *pData, u32 DataLen)
91980990 332{
8a10a546 333 void *pPacket;
91980990
GKH
334 ASSERT(pData);
335 ASSERT(DataLen);
336
9f548a2a 337 /* 1. Allocate a packet */
66cd8d6e 338 pPacket =
8a10a546 339 (void **) dev_alloc_skb(HeaderLen + DataLen +
66cd8d6e
BZ
340 RTMP_PKT_TAIL_PADDING);
341 if (pPacket == NULL) {
91980990 342 *ppPacket = NULL;
3be305fd
AG
343 pr_devel("RTMPAllocateNdisPacket Fail\n");
344
91980990
GKH
345 return NDIS_STATUS_FAILURE;
346 }
9f548a2a 347 /* 2. clone the frame content */
91980990
GKH
348 if (HeaderLen > 0)
349 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
350 if (DataLen > 0)
66cd8d6e
BZ
351 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
352 DataLen);
91980990 353
9f548a2a 354 /* 3. update length of packet */
66cd8d6e 355 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
91980990
GKH
356
357 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
9f548a2a 358/* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
91980990
GKH
359 *ppPacket = pPacket;
360 return NDIS_STATUS_SUCCESS;
361}
362
363/*
364 ========================================================================
365 Description:
8a10a546 366 This routine frees a miniport internally allocated char and its
91980990
GKH
367 corresponding NDIS_BUFFER and allocated memory.
368 ========================================================================
369*/
62eb734b 370void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
91980990
GKH
371{
372 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
373}
374
9f548a2a
BZ
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 */
8a10a546 378int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
51126deb
BZ
379 u8 DesiredOffset,
380 u8 *pByte0, u8 *pByte1)
91980990 381{
51126deb
BZ
382 *pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
383 *pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
91980990
GKH
384
385 return NDIS_STATUS_SUCCESS;
386}
387
8a10a546 388void RTMP_QueryPacketInfo(void *pPacket,
62eb734b 389 struct rt_packet_info *pPacketInfo,
cc9b5222 390 u8 **pSrcBufVA, u32 * pSrcBufLen)
91980990
GKH
391{
392 pPacketInfo->BufferCount = 1;
8a10a546 393 pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
91980990
GKH
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
cc9b5222 401void RTMP_QueryNextPacketInfo(void **ppPacket,
62eb734b 402 struct rt_packet_info *pPacketInfo,
cc9b5222 403 u8 **pSrcBufVA, u32 * pSrcBufLen)
91980990 404{
8a10a546 405 void *pPacket = NULL;
91980990
GKH
406
407 if (*ppPacket)
408 pPacket = GET_OS_PKT_NEXT(*ppPacket);
409
66cd8d6e 410 if (pPacket) {
91980990 411 pPacketInfo->BufferCount = 1;
66cd8d6e 412 pPacketInfo->pFirstBuffer =
8a10a546 413 (char *)GET_OS_PKT_DATAPTR(pPacket);
91980990
GKH
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);
66cd8d6e 420 } else {
91980990
GKH
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
62eb734b 432void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
8a10a546 433 void *pPacket, u8 FromWhichBSSID)
91980990 434{
66cd8d6e 435 struct sk_buff *skb;
8a10a546 436 void *pRetPacket = NULL;
51126deb
BZ
437 u16 DataSize;
438 u8 *pData;
91980990 439
51126deb
BZ
440 DataSize = (u16)GET_OS_PKT_LEN(pPacket);
441 pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
91980990 442
91980990 443 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
66cd8d6e 444 if (skb) {
91980990
GKH
445 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
446 pRetPacket = OSPKT_TO_RTPKT(skb);
447 }
448
449 return pRetPacket;
450
451}
452
62eb734b 453void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
51126deb
BZ
454 u8 *pHeader802_3,
455 u32 HdrLen,
456 u8 *pData,
457 unsigned long DataSize, u8 FromWhichBSSID)
91980990 458{
66cd8d6e 459 struct sk_buff *skb;
8a10a546 460 void *pPacket = NULL;
91980990 461
6aed5295
JP
462 skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG);
463 if (skb != NULL) {
91980990 464 skb_reserve(skb, 2);
53cf8743 465 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
91980990 466 skb_put(skb, HdrLen);
53cf8743 467 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
91980990
GKH
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
91980990 476#define TKIP_TX_MIC_SIZE 8
62eb734b 477void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
8a10a546 478 void *pPacket)
91980990 479{
66cd8d6e 480 struct sk_buff *skb, *newskb;
91980990
GKH
481
482 skb = RTPKT_TO_OSPKT(pPacket);
66cd8d6e 483 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
9f548a2a 484 /* alloc a new skb and copy the packet */
66cd8d6e
BZ
485 newskb =
486 skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
487 GFP_ATOMIC);
91980990 488 dev_kfree_skb_any(skb);
66cd8d6e
BZ
489 if (newskb == NULL) {
490 DBGPRINT(RT_DEBUG_ERROR,
491 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
91980990
GKH
492 return NULL;
493 }
494 skb = newskb;
495 }
496
497 return OSPKT_TO_RTPKT(skb);
498}
499
62eb734b 500void *ClonePacket(struct rt_rtmp_adapter *pAd,
8a10a546 501 void *pPacket,
51126deb 502 u8 *pData, unsigned long DataSize)
91980990 503{
66cd8d6e
BZ
504 struct sk_buff *pRxPkt;
505 struct sk_buff *pClonedPkt;
91980990
GKH
506
507 ASSERT(pPacket);
508 pRxPkt = RTPKT_TO_OSPKT(pPacket);
509
9f548a2a 510 /* clone the packet */
91980990
GKH
511 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
512
66cd8d6e 513 if (pClonedPkt) {
9f548a2a 514 /* set the correct dataptr and data len */
66cd8d6e
BZ
515 pClonedPkt->dev = pRxPkt->dev;
516 pClonedPkt->data = pData;
517 pClonedPkt->len = DataSize;
53cf8743 518 skb_set_tail_pointer(pClonedPkt, DataSize)
91980990
GKH
519 ASSERT(DataSize < 1530);
520 }
521 return pClonedPkt;
522}
523
9f548a2a
BZ
524/* */
525/* change OS packet DataPtr and DataLen */
526/* */
62eb734b
BZ
527void update_os_packet_info(struct rt_rtmp_adapter *pAd,
528 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
91980990 529{
66cd8d6e 530 struct sk_buff *pOSPkt;
91980990
GKH
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;
53cf8743 538 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
91980990
GKH
539}
540
62eb734b
BZ
541void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
542 struct rt_rx_blk *pRxBlk,
51126deb
BZ
543 u8 *pHeader802_3,
544 u8 FromWhichBSSID)
91980990 545{
66cd8d6e 546 struct sk_buff *pOSPkt;
91980990
GKH
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;
53cf8743 556 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
91980990 557
9f548a2a
BZ
558 /* */
559 /* copy 802.3 header */
560 /* */
561 /* */
91980990 562
66cd8d6e
BZ
563 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
564 LENGTH_802_3);
565}
91980990 566
62eb734b 567void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
91980990
GKH
568{
569
66cd8d6e 570 struct sk_buff *pRxPkt;
91980990
GKH
571
572 ASSERT(pPacket);
573
574 pRxPkt = RTPKT_TO_OSPKT(pPacket);
575
66cd8d6e 576 /* Push up the protocol stack */
91980990
GKH
577 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
578
579 netif_rx(pRxPkt);
91980990
GKH
580}
581
62eb734b
BZ
582struct rt_rtmp_sg_list *
583rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
91980990
GKH
584{
585 sg->NumberOfElements = 1;
66cd8d6e 586 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
91980990 587 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
cc9b5222 588 return sg;
91980990
GKH
589}
590
591void 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;
3be305fd 600 printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
66cd8d6e 601 for (x = 0; x < SrcBufLen; x++) {
91980990 602 if (x % 16 == 0)
3be305fd
AG
603 printk(KERN_DEBUG "0x%04x : ", x);
604 printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x]));
66cd8d6e 605 if (x % 16 == 15)
3be305fd 606 printk(KERN_DEBUG "\n");
91980990 607 }
3be305fd 608 printk(KERN_DEBUG "\n");
91980990
GKH
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*/
62eb734b 631void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
51126deb
BZ
632 u16 Event_flag,
633 u8 *pAddr, u8 BssIdx, char Rssi)
91980990 634{
91980990 635
9f548a2a 636 /*union iwreq_data wrqu; */
51126deb
BZ
637 char *pBuf = NULL, *pBufPtr = NULL;
638 u16 event, type, BufLen;
639 u8 event_table_len = 0;
91980990
GKH
640
641 type = Event_flag & 0xFF00;
642 event = Event_flag & 0x00FF;
643
66cd8d6e
BZ
644 switch (type) {
645 case IW_SYS_EVENT_FLAG_START:
646 event_table_len = IW_SYS_EVENT_TYPE_NUM;
647 break;
91980990 648
66cd8d6e
BZ
649 case IW_SPOOF_EVENT_FLAG_START:
650 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
651 break;
91980990 652
66cd8d6e
BZ
653 case IW_FLOOD_EVENT_FLAG_START:
654 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
655 break;
91980990
GKH
656 }
657
66cd8d6e
BZ
658 if (event_table_len == 0) {
659 DBGPRINT(RT_DEBUG_ERROR,
660 ("%s : The type(%0x02x) is not valid.\n", __func__,
661 type));
91980990
GKH
662 return;
663 }
664
66cd8d6e
BZ
665 if (event >= event_table_len) {
666 DBGPRINT(RT_DEBUG_ERROR,
667 ("%s : The event(%0x02x) is not valid.\n", __func__,
668 event));
91980990
GKH
669 return;
670 }
9f548a2a 671 /*Allocate memory and copy the msg. */
6aed5295
JP
672 pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC);
673 if (pBuf != NULL) {
9f548a2a 674 /*Prepare the payload */
91980990
GKH
675 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
676
677 pBufPtr = pBuf;
678
679 if (pAddr)
66cd8d6e 680 pBufPtr +=
aa4d282c 681 sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr);
91980990 682 else if (BssIdx < MAX_MBSSID_NUM)
66cd8d6e
BZ
683 pBufPtr +=
684 sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
91980990
GKH
685 else
686 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
687
688 if (type == IW_SYS_EVENT_FLAG_START)
66cd8d6e
BZ
689 pBufPtr +=
690 sprintf(pBufPtr, "%s",
691 pWirelessSysEventText[event]);
91980990 692 else if (type == IW_SPOOF_EVENT_FLAG_START)
66cd8d6e
BZ
693 pBufPtr +=
694 sprintf(pBufPtr, "%s (RSSI=%d)",
695 pWirelessSpoofEventText[event], Rssi);
91980990 696 else if (type == IW_FLOOD_EVENT_FLAG_START)
66cd8d6e
BZ
697 pBufPtr +=
698 sprintf(pBufPtr, "%s",
699 pWirelessFloodEventText[event]);
91980990
GKH
700 else
701 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
702
703 pBufPtr[pBufPtr - pBuf] = '\0';
704 BufLen = pBufPtr - pBuf;
705
66cd8d6e 706 RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
51126deb 707 (u8 *)pBuf, BufLen);
9f548a2a 708 /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
91980990
GKH
709
710 kfree(pBuf);
66cd8d6e
BZ
711 } else
712 DBGPRINT(RT_DEBUG_ERROR,
713 ("%s : Can't allocate memory for wireless event.\n",
714 __func__));
91980990
GKH
715}
716
62eb734b 717void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
91980990 718{
66cd8d6e 719 struct sk_buff *pOSPkt;
62eb734b 720 struct rt_wlan_ng_prism2_header *ph;
66cd8d6e 721 int rate_index = 0;
51126deb
BZ
722 u16 header_len = 0;
723 u8 temp_header[40] = { 0 };
66cd8d6e 724
9f548a2a 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 */
66cd8d6e
BZ
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 };
91980990 736
66cd8d6e
BZ
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));
91980990 742 goto err_free_sk_buff;
66cd8d6e 743 }
91980990 744
62eb734b 745 if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
66cd8d6e
BZ
746 RX_BUFFER_AGGRESIZE) {
747 DBGPRINT(RT_DEBUG_ERROR,
748 ("%s : Size is too large! (%zu)\n", __func__,
62eb734b 749 pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
91980990 750 goto err_free_sk_buff;
66cd8d6e 751 }
91980990 752
66cd8d6e 753 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
91980990 754 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
66cd8d6e
BZ
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
9f548a2a 763 /* QOS */
66cd8d6e
BZ
764 if (pRxBlk->pHeader->FC.SubType & 0x08) {
765 header_len += 2;
6ccb5d7c 766 /* Data skip QOS control field */
66cd8d6e
BZ
767 pRxBlk->DataSize -= 2;
768 }
9f548a2a 769 /* Order bit: A-Ralink or HTC+ */
66cd8d6e
BZ
770 if (pRxBlk->pHeader->FC.Order) {
771 header_len += 4;
6ccb5d7c 772 /* Data skip HTC control field */
91980990 773 pRxBlk->DataSize -= 4;
66cd8d6e 774 }
9f548a2a 775 /* Copy Header */
66cd8d6e
BZ
776 if (header_len <= 40)
777 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
91980990 778
9f548a2a 779 /* skip HW padding */
66cd8d6e
BZ
780 if (pRxBlk->RxD.L2PAD)
781 pRxBlk->pData += (header_len + 2);
782 else
783 pRxBlk->pData += header_len;
9f548a2a 784 } /*end if */
91980990
GKH
785
786 if (pRxBlk->DataSize < pOSPkt->len) {
66cd8d6e
BZ
787 skb_trim(pOSPkt, pRxBlk->DataSize);
788 } else {
789 skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
9f548a2a 790 } /*end if */
66cd8d6e
BZ
791
792 if ((pRxBlk->pData - pOSPkt->data) > 0) {
793 skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
794 skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
9f548a2a 795 } /*end if */
66cd8d6e 796
62eb734b 797 if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
66cd8d6e 798 if (pskb_expand_head
62eb734b 799 (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
66cd8d6e
BZ
800 GFP_ATOMIC)) {
801 DBGPRINT(RT_DEBUG_ERROR,
802 ("%s : Reallocate header size of sk_buff fail!\n",
803 __func__));
91980990 804 goto err_free_sk_buff;
9f548a2a
BZ
805 } /*end if */
806 } /*end if */
91980990 807
66cd8d6e
BZ
808 if (header_len > 0)
809 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
810 header_len);
91980990 811
62eb734b
BZ
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));
91980990 815
66cd8d6e 816 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
62eb734b 817 ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
51126deb 818 strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
91980990 819
66cd8d6e 820 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
91980990
GKH
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
66cd8d6e 830 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
91980990
GKH
831 ph->istx.status = 0;
832 ph->istx.len = 0;
833 ph->istx.data = 0;
834
66cd8d6e 835 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
91980990
GKH
836 ph->channel.status = 0;
837 ph->channel.len = 4;
838
66cd8d6e 839 ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
91980990 840
66cd8d6e 841 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
91980990
GKH
842 ph->rssi.status = 0;
843 ph->rssi.len = 4;
66cd8d6e
BZ
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,
859171ca 853 RSSI_2));
91980990
GKH
854
855 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
856 ph->signal.status = 0;
857 ph->signal.len = 4;
9f548a2a 858 ph->signal.data = 0; /*rssi + noise; */
91980990
GKH
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
66cd8d6e
BZ
865 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
866 rate_index =
51126deb
BZ
867 16 + ((u8)pRxBlk->pRxWI->BW * 16) +
868 ((u8)pRxBlk->pRxWI->ShortGI * 32) +
869 ((u8)pRxBlk->pRxWI->MCS);
66cd8d6e 870 } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
51126deb 871 rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
66cd8d6e 872 else
51126deb 873 rate_index = (u8)(pRxBlk->pRxWI->MCS);
66cd8d6e
BZ
874 if (rate_index < 0)
875 rate_index = 0;
876 if (rate_index > 255)
877 rate_index = 255;
91980990
GKH
878
879 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
880 ph->rate.status = 0;
881 ph->rate.len = 4;
66cd8d6e 882 ph->rate.data = ralinkrate[rate_index];
91980990
GKH
883
884 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
66cd8d6e 885 ph->frmlen.status = 0;
91980990 886 ph->frmlen.len = 4;
66cd8d6e 887 ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
91980990 888
66cd8d6e
BZ
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);
91980990 893
66cd8d6e 894 return;
91980990
GKH
895
896err_free_sk_buff:
897 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
898 return;
899
900}
91980990 901
ca97b838
BZ
902/*******************************************************************************
903
904 Device IRQ related functions.
905
906 *******************************************************************************/
8a10a546 907int RtmpOSIRQRequest(struct net_device *pNetDev)
ca97b838 908{
ca58fb30 909#ifdef RTMP_PCI_SUPPORT
ca97b838 910 struct net_device *net_dev = pNetDev;
62eb734b 911 struct rt_rtmp_adapter *pAd = NULL;
ca97b838
BZ
912 int retval = 0;
913
914 GET_PAD_FROM_NET_DEV(pAd, pNetDev);
915
916 ASSERT(pAd);
917
66cd8d6e 918 if (pAd->infType == RTMP_DEV_INF_PCI) {
8a10a546 919 struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
ca97b838 920 RTMP_MSI_ENABLE(pAd);
66cd8d6e
BZ
921 retval =
922 request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
923 (net_dev)->name, (net_dev));
ca97b838 924 if (retval != 0)
3be305fd 925 printk(KERN_ERR "rt2860: request_irq ERROR(%d)\n", retval);
ca97b838 926 }
ca97b838
BZ
927
928 return retval;
ca58fb30
BZ
929#else
930 return 0;
931#endif
ca97b838
BZ
932}
933
8a10a546 934int RtmpOSIRQRelease(struct net_device *pNetDev)
91980990 935{
ca97b838 936 struct net_device *net_dev = pNetDev;
62eb734b 937 struct rt_rtmp_adapter *pAd = NULL;
ca97b838
BZ
938
939 GET_PAD_FROM_NET_DEV(pAd, net_dev);
940
941 ASSERT(pAd);
942
943#ifdef RTMP_PCI_SUPPORT
66cd8d6e 944 if (pAd->infType == RTMP_DEV_INF_PCI) {
8a10a546 945 struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
ca97b838
BZ
946 synchronize_irq(pObj->pci_dev->irq);
947 free_irq(pObj->pci_dev->irq, (net_dev));
948 RTMP_MSI_DISABLE(pAd);
949 }
9f548a2a 950#endif /* RTMP_PCI_SUPPORT // */
ca97b838 951
ca97b838
BZ
952 return 0;
953}
954
ca97b838
BZ
955/*******************************************************************************
956
957 File open/close related functions.
958
959 *******************************************************************************/
8a10a546 960struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
ca97b838 961{
66cd8d6e 962 struct file *filePtr;
ca97b838
BZ
963
964 filePtr = filp_open(pPath, flag, 0);
66cd8d6e
BZ
965 if (IS_ERR(filePtr)) {
966 DBGPRINT(RT_DEBUG_ERROR,
967 ("%s(): Error %ld opening %s\n", __func__,
968 -PTR_ERR(filePtr), pPath));
ca97b838
BZ
969 }
970
8a10a546 971 return (struct file *)filePtr;
ca97b838
BZ
972}
973
8a10a546 974int RtmpOSFileClose(struct file *osfd)
ca97b838
BZ
975{
976 filp_close(osfd, NULL);
977 return 0;
978}
979
8a10a546 980void RtmpOSFileSeek(struct file *osfd, int offset)
ca97b838
BZ
981{
982 osfd->f_pos = offset;
983}
984
8a10a546 985int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
ca97b838 986{
9f548a2a 987 /* The object must have a read method */
66cd8d6e
BZ
988 if (osfd->f_op && osfd->f_op->read) {
989 return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
990 } else {
ca97b838
BZ
991 DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
992 return -1;
993 }
994}
995
8a10a546 996int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
ca97b838 997{
66cd8d6e
BZ
998 return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
999 &osfd->f_pos);
ca97b838
BZ
1000}
1001
ca97b838
BZ
1002/*******************************************************************************
1003
1004 Task create/management/kill related functions.
1005
1006 *******************************************************************************/
62eb734b 1007int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
ca97b838 1008{
62eb734b 1009 struct rt_rtmp_adapter *pAd;
ca97b838
BZ
1010 int ret = NDIS_STATUS_FAILURE;
1011
5401843d 1012 pAd = pTask->priv;
ca97b838
BZ
1013
1014#ifdef KTHREAD_SUPPORT
66cd8d6e 1015 if (pTask->kthread_task) {
ca97b838
BZ
1016 kthread_stop(pTask->kthread_task);
1017 ret = NDIS_STATUS_SUCCESS;
1018 }
1019#else
66cd8d6e 1020 CHECK_PID_LEGALITY(pTask->taskPID) {
3be305fd 1021 printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n",
66cd8d6e 1022 pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
ca97b838
BZ
1023 mb();
1024 pTask->task_killed = 1;
1025 mb();
1026 ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
66cd8d6e
BZ
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 {
ca97b838
BZ
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
62eb734b 1045int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
ca97b838
BZ
1046{
1047
1048#ifndef KTHREAD_SUPPORT
1049 complete_and_exit(&pTask->taskComplete, 0);
1050#endif
1051
1052 return 0;
1053}
1054
62eb734b 1055void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
ca97b838
BZ
1056{
1057
1058#ifndef KTHREAD_SUPPORT
1059
cc9b5222 1060 daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */);
91980990
GKH
1061
1062 allow_signal(SIGTERM);
1063 allow_signal(SIGKILL);
1064 current->flags |= PF_NOFREEZE;
91980990 1065
7f20a18d 1066 /* signal that we've started the thread */
ca97b838
BZ
1067 complete(&pTask->taskComplete);
1068
1069#endif
91980990
GKH
1070}
1071
62eb734b 1072int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
66cd8d6e 1073 IN int (*fn) (void *), IN void *arg)
ca97b838 1074{
51126deb 1075 int status = NDIS_STATUS_SUCCESS;
ca97b838
BZ
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);
66cd8d6e
BZ
1085 if (pid_number < 0) {
1086 DBGPRINT(RT_DEBUG_ERROR,
1087 ("Attach task(%s) failed!\n", pTask->taskName));
ca97b838 1088 status = NDIS_STATUS_FAILURE;
66cd8d6e 1089 } else {
ca97b838
BZ
1090 pTask->taskPID = GET_PID(pid_number);
1091
9f548a2a 1092 /* Wait for the thread to start */
ca97b838
BZ
1093 wait_for_completion(&pTask->taskComplete);
1094 status = NDIS_STATUS_SUCCESS;
1095 }
1096#endif
1097 return status;
1098}
1099
62eb734b 1100int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
51126deb 1101 char *pTaskName, void * pPriv)
ca97b838
BZ
1102{
1103 int len;
1104
1105 ASSERT(pTask);
1106
1107#ifndef KTHREAD_SUPPORT
62eb734b 1108 NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
ca97b838
BZ
1109#endif
1110
1111 len = strlen(pTaskName);
66cd8d6e
BZ
1112 len =
1113 len >
1114 (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
ca97b838
BZ
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
66cd8d6e 1122 init_completion(&pTask->taskComplete);
ca97b838
BZ
1123#endif
1124
1125 return NDIS_STATUS_SUCCESS;
1126}
1127
62eb734b 1128void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
91980990 1129{
66cd8d6e
BZ
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);
91980990
GKH
1139 }
1140 }
1141}
1142
62eb734b 1143int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1144 u32 eventType,
1145 int flags,
1146 u8 *pSrcMac,
1147 u8 *pData, u32 dataLen)
ca97b838 1148{
66cd8d6e 1149 union iwreq_data wrqu;
ca97b838 1150
66cd8d6e 1151 memset(&wrqu, 0, sizeof(wrqu));
ca97b838 1152
66cd8d6e
BZ
1153 if (flags > -1)
1154 wrqu.data.flags = flags;
ca97b838
BZ
1155
1156 if (pSrcMac)
1157 memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
1158
66cd8d6e 1159 if ((pData != NULL) && (dataLen > 0))
ca97b838
BZ
1160 wrqu.data.length = dataLen;
1161
66cd8d6e 1162 wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
ca97b838
BZ
1163 return 0;
1164}
1165
8a10a546 1166int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
ca97b838
BZ
1167{
1168 struct net_device *net_dev;
62eb734b 1169 struct rt_rtmp_adapter *pAd;
ca97b838
BZ
1170
1171 net_dev = pNetDev;
1172 GET_PAD_FROM_NET_DEV(pAd, net_dev);
1173
6ccb5d7c 1174 /* work-around for SuSE, due to them having their own interface name management system. */
ca97b838
BZ
1175 {
1176 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
66cd8d6e
BZ
1177 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
1178 strlen(net_dev->name));
ca97b838
BZ
1179 }
1180
1181 NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
1182
1183 return 0;
1184}
1185
ca97b838
BZ
1186/*
1187 * Assign the network dev name for created Ralink WiFi interface.
1188 */
62eb734b 1189static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
8a10a546 1190 struct net_device *dev,
51126deb 1191 char *pPrefixStr, int devIdx)
ca97b838 1192{
8a10a546 1193 struct net_device *existNetDev;
51126deb
BZ
1194 char suffixName[IFNAMSIZ];
1195 char desiredName[IFNAMSIZ];
66cd8d6e 1196 int ifNameIdx, prefixLen, slotNameLen;
ca97b838
BZ
1197 int Status;
1198
ca97b838
BZ
1199 prefixLen = strlen(pPrefixStr);
1200 ASSERT((prefixLen < IFNAMSIZ));
1201
66cd8d6e 1202 for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
ca97b838
BZ
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
66cd8d6e 1220 if (ifNameIdx < 32) {
ca97b838
BZ
1221 strcpy(&dev->name[0], &desiredName[0]);
1222 Status = NDIS_STATUS_SUCCESS;
66cd8d6e 1223 } else {
ca97b838 1224 DBGPRINT(RT_DEBUG_ERROR,
66cd8d6e
BZ
1225 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
1226 pPrefixStr));
ca97b838
BZ
1227 Status = NDIS_STATUS_FAILURE;
1228 }
1229
1230 return Status;
1231}
1232
8a10a546 1233void RtmpOSNetDevClose(struct net_device *pNetDev)
ca97b838
BZ
1234{
1235 dev_close(pNetDev);
1236}
1237
8a10a546 1238void RtmpOSNetDevFree(struct net_device *pNetDev)
ca97b838
BZ
1239{
1240 ASSERT(pNetDev);
1241
1242 free_netdev(pNetDev);
1243}
1244
cc9b5222 1245int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize)
ca97b838 1246{
9f548a2a 1247 /* assign it as null first. */
ca97b838
BZ
1248 *new_dev_p = NULL;
1249
66cd8d6e
BZ
1250 DBGPRINT(RT_DEBUG_TRACE,
1251 ("Allocate a net device with private data size=%d!\n",
1252 privDataSize));
ca97b838
BZ
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
8a10a546 1260struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
ca97b838 1261{
8a10a546 1262 struct net_device *pTargetNetDev = NULL;
ca97b838
BZ
1263
1264 pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
1265
1266 return pTargetNetDev;
1267}
1268
8a10a546 1269void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
ca97b838
BZ
1270{
1271 /*
66cd8d6e
BZ
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)
ca97b838
BZ
1277 dev_put(pNetDev);
1278}
1279
62eb734b 1280int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
ca97b838
BZ
1281{
1282
9f548a2a 1283 /* TODO: Need to fix this */
06aea994 1284 printk("WARNING: This function(%s) not implement yet!\n", __func__);
ca97b838
BZ
1285 return 0;
1286}
1287
8a10a546 1288void RtmpOSNetDevDetach(struct net_device *pNetDev)
ca97b838
BZ
1289{
1290 unregister_netdev(pNetDev);
1291}
1292
8a10a546 1293int RtmpOSNetDevAttach(struct net_device *pNetDev,
62eb734b 1294 struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
ca97b838
BZ
1295{
1296 int ret, rtnl_locked = FALSE;
1297
1298 DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
6ccb5d7c 1299 /* If we need hook some callback function to the net device structure, now do it. */
66cd8d6e 1300 if (pDevOpHook) {
62eb734b 1301 struct rt_rtmp_adapter *pAd = NULL;
ca97b838
BZ
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
30cb3e5f 1310 if (pAd->OpMode == OPMODE_STA)
ca97b838 1311 pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
ca97b838 1312
9f548a2a 1313 /* copy the net device mac address to the net_device structure. */
66cd8d6e
BZ
1314 NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
1315 MAC_ADDR_LEN);
ca97b838
BZ
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
62eb734b 1332struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1333 int devType,
1334 int devNum,
1335 int privMemSize, char *pNamePrefix)
ca97b838
BZ
1336{
1337 struct net_device *pNetDev = NULL;
1338 int status;
1339
ca97b838 1340 /* allocate a new network device */
cc9b5222 1341 status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */);
66cd8d6e 1342 if (status != NDIS_STATUS_SUCCESS) {
ca97b838 1343 /* allocation fail, exit */
66cd8d6e
BZ
1344 DBGPRINT(RT_DEBUG_ERROR,
1345 ("Allocate network device fail (%s)...\n",
1346 pNamePrefix));
ca97b838
BZ
1347 return NULL;
1348 }
1349
6ccb5d7c 1350 /* find an available interface name, max 32 interfaces */
ca97b838 1351 status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
66cd8d6e 1352 if (status != NDIS_STATUS_SUCCESS) {
6ccb5d7c 1353 /* error! no available ra name can be used! */
66cd8d6e
BZ
1354 DBGPRINT(RT_DEBUG_ERROR,
1355 ("Assign interface name (%s with suffix 0~32) failed...\n",
1356 pNamePrefix));
ca97b838
BZ
1357 RtmpOSNetDevFree(pNetDev);
1358
1359 return NULL;
66cd8d6e
BZ
1360 } else {
1361 DBGPRINT(RT_DEBUG_TRACE,
1362 ("The name of the new %s interface is %s...\n",
1363 pNamePrefix, pNetDev->name));
ca97b838
BZ
1364 }
1365
1366 return pNetDev;
1367}