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