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