]>
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 | ||
28 | #include "rt_config.h" | |
29 | ||
30 | ULONG RTDebugLevel = RT_DEBUG_ERROR; | |
31 | ||
32 | BUILD_TIMER_FUNCTION(MlmePeriodicExec); | |
33 | BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout); | |
34 | BUILD_TIMER_FUNCTION(APSDPeriodicExec); | |
35 | BUILD_TIMER_FUNCTION(AsicRfTuningExec); | |
36 | ||
37 | ||
38 | #ifdef CONFIG_STA_SUPPORT | |
39 | BUILD_TIMER_FUNCTION(BeaconTimeout); | |
40 | BUILD_TIMER_FUNCTION(ScanTimeout); | |
41 | BUILD_TIMER_FUNCTION(AuthTimeout); | |
42 | BUILD_TIMER_FUNCTION(AssocTimeout); | |
43 | BUILD_TIMER_FUNCTION(ReassocTimeout); | |
44 | BUILD_TIMER_FUNCTION(DisassocTimeout); | |
45 | BUILD_TIMER_FUNCTION(LinkDownExec); | |
46 | #ifdef LEAP_SUPPORT | |
47 | BUILD_TIMER_FUNCTION(LeapAuthTimeout); | |
48 | #endif | |
49 | BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); | |
50 | BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); | |
51 | #ifdef RT2860 | |
52 | BUILD_TIMER_FUNCTION(PsPollWakeExec); | |
53 | BUILD_TIMER_FUNCTION(RadioOnExec); | |
54 | #endif // RT2860 // | |
55 | #ifdef QOS_DLS_SUPPORT | |
56 | BUILD_TIMER_FUNCTION(DlsTimeoutAction); | |
57 | #endif // QOS_DLS_SUPPORT // | |
58 | #endif // CONFIG_STA_SUPPORT // | |
59 | ||
60 | // for wireless system event message | |
61 | char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = { | |
62 | // system status event | |
63 | "had associated successfully", /* IW_ASSOC_EVENT_FLAG */ | |
64 | "had disassociated", /* IW_DISASSOC_EVENT_FLAG */ | |
65 | "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */ | |
66 | "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */ | |
67 | "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */ | |
68 | "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */ | |
69 | "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */ | |
70 | "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */ | |
71 | "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */ | |
72 | "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */ | |
73 | "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */ | |
74 | "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */ | |
75 | "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */ | |
76 | "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */ | |
77 | "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */ | |
78 | "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */ | |
79 | "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */ | |
80 | "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */ | |
81 | "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */ | |
82 | }; | |
83 | ||
84 | // for wireless IDS_spoof_attack event message | |
85 | char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = { | |
86 | "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */ | |
87 | "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */ | |
88 | "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */ | |
89 | "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */ | |
90 | "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */ | |
91 | "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */ | |
92 | "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */ | |
93 | "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */ | |
94 | "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */ | |
95 | "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */ | |
96 | }; | |
97 | ||
98 | // for wireless IDS_flooding_attack event message | |
99 | char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = { | |
100 | "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */ | |
101 | "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */ | |
102 | "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */ | |
103 | "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */ | |
104 | "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */ | |
105 | "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */ | |
106 | "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */ | |
107 | }; | |
108 | ||
109 | /* timeout -- ms */ | |
110 | VOID RTMP_SetPeriodicTimer( | |
111 | IN NDIS_MINIPORT_TIMER *pTimer, | |
112 | IN unsigned long timeout) | |
113 | { | |
114 | timeout = ((timeout*HZ) / 1000); | |
115 | pTimer->expires = jiffies + timeout; | |
116 | add_timer(pTimer); | |
117 | } | |
118 | ||
119 | /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */ | |
120 | VOID RTMP_OS_Init_Timer( | |
121 | IN PRTMP_ADAPTER pAd, | |
122 | IN NDIS_MINIPORT_TIMER *pTimer, | |
123 | IN TIMER_FUNCTION function, | |
124 | IN PVOID data) | |
125 | { | |
126 | init_timer(pTimer); | |
127 | pTimer->data = (unsigned long)data; | |
128 | pTimer->function = function; | |
129 | } | |
130 | ||
131 | ||
132 | VOID RTMP_OS_Add_Timer( | |
133 | IN NDIS_MINIPORT_TIMER *pTimer, | |
134 | IN unsigned long timeout) | |
135 | { | |
136 | if (timer_pending(pTimer)) | |
137 | return; | |
138 | ||
139 | timeout = ((timeout*HZ) / 1000); | |
140 | pTimer->expires = jiffies + timeout; | |
141 | add_timer(pTimer); | |
142 | } | |
143 | ||
144 | VOID RTMP_OS_Mod_Timer( | |
145 | IN NDIS_MINIPORT_TIMER *pTimer, | |
146 | IN unsigned long timeout) | |
147 | { | |
148 | timeout = ((timeout*HZ) / 1000); | |
149 | mod_timer(pTimer, jiffies + timeout); | |
150 | } | |
151 | ||
152 | VOID RTMP_OS_Del_Timer( | |
153 | IN NDIS_MINIPORT_TIMER *pTimer, | |
154 | OUT BOOLEAN *pCancelled) | |
155 | { | |
156 | if (timer_pending(pTimer)) | |
157 | { | |
158 | *pCancelled = del_timer_sync(pTimer); | |
159 | } | |
160 | else | |
161 | { | |
162 | *pCancelled = TRUE; | |
163 | } | |
164 | ||
165 | } | |
166 | ||
167 | VOID RTMP_OS_Release_Packet( | |
168 | IN PRTMP_ADAPTER pAd, | |
169 | IN PQUEUE_ENTRY pEntry) | |
170 | { | |
171 | //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); | |
172 | } | |
173 | ||
174 | // Unify all delay routine by using udelay | |
175 | VOID RTMPusecDelay( | |
176 | IN ULONG usec) | |
177 | { | |
178 | ULONG i; | |
179 | ||
180 | for (i = 0; i < (usec / 50); i++) | |
181 | udelay(50); | |
182 | ||
183 | if (usec % 50) | |
184 | udelay(usec % 50); | |
185 | } | |
186 | ||
187 | void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time) | |
188 | { | |
189 | time->u.LowPart = jiffies; | |
190 | } | |
191 | ||
192 | // pAd MUST allow to be NULL | |
193 | NDIS_STATUS os_alloc_mem( | |
194 | IN PRTMP_ADAPTER pAd, | |
195 | OUT PUCHAR *mem, | |
196 | IN ULONG size) | |
197 | { | |
198 | *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC); | |
199 | if (*mem) | |
200 | return (NDIS_STATUS_SUCCESS); | |
201 | else | |
202 | return (NDIS_STATUS_FAILURE); | |
203 | } | |
204 | ||
205 | // pAd MUST allow to be NULL | |
206 | NDIS_STATUS os_free_mem( | |
207 | IN PRTMP_ADAPTER pAd, | |
208 | IN PUCHAR mem) | |
209 | { | |
210 | ||
211 | ASSERT(mem); | |
212 | kfree(mem); | |
213 | return (NDIS_STATUS_SUCCESS); | |
214 | } | |
215 | ||
216 | ||
217 | PNDIS_PACKET RTMP_AllocateFragPacketBuffer( | |
218 | IN PRTMP_ADAPTER pAd, | |
219 | IN ULONG Length) | |
220 | { | |
221 | struct sk_buff *pkt; | |
222 | ||
223 | pkt = dev_alloc_skb(Length); | |
224 | ||
225 | if (pkt == NULL) | |
226 | { | |
227 | DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length)); | |
228 | } | |
229 | ||
230 | if (pkt) | |
231 | { | |
232 | RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); | |
233 | } | |
234 | ||
235 | return (PNDIS_PACKET) pkt; | |
236 | } | |
237 | ||
238 | ||
239 | PNDIS_PACKET RTMP_AllocateTxPacketBuffer( | |
240 | IN PRTMP_ADAPTER pAd, | |
241 | IN ULONG Length, | |
242 | IN BOOLEAN Cached, | |
243 | OUT PVOID *VirtualAddress) | |
244 | { | |
245 | struct sk_buff *pkt; | |
246 | ||
247 | pkt = dev_alloc_skb(Length); | |
248 | ||
249 | if (pkt == NULL) | |
250 | { | |
251 | DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length)); | |
252 | } | |
253 | ||
254 | if (pkt) | |
255 | { | |
256 | RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); | |
257 | *VirtualAddress = (PVOID) pkt->data; | |
258 | } | |
259 | else | |
260 | { | |
261 | *VirtualAddress = (PVOID) NULL; | |
262 | } | |
263 | ||
264 | return (PNDIS_PACKET) pkt; | |
265 | } | |
266 | ||
267 | ||
268 | VOID build_tx_packet( | |
269 | IN PRTMP_ADAPTER pAd, | |
270 | IN PNDIS_PACKET pPacket, | |
271 | IN PUCHAR pFrame, | |
272 | IN ULONG FrameLen) | |
273 | { | |
274 | ||
275 | struct sk_buff *pTxPkt; | |
276 | ||
277 | ASSERT(pPacket); | |
278 | pTxPkt = RTPKT_TO_OSPKT(pPacket); | |
279 | ||
280 | NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen); | |
281 | } | |
282 | ||
283 | VOID RTMPFreeAdapter( | |
284 | IN PRTMP_ADAPTER pAd) | |
285 | { | |
286 | POS_COOKIE os_cookie; | |
287 | int index; | |
288 | ||
289 | os_cookie=(POS_COOKIE)pAd->OS_Cookie; | |
290 | ||
291 | kfree(pAd->BeaconBuf); | |
292 | ||
293 | ||
294 | NdisFreeSpinLock(&pAd->MgmtRingLock); | |
295 | ||
296 | #ifdef RT2860 | |
297 | NdisFreeSpinLock(&pAd->RxRingLock); | |
298 | #endif // RT2860 // | |
299 | ||
300 | for (index =0 ; index < NUM_OF_TX_RING; index++) | |
301 | { | |
302 | NdisFreeSpinLock(&pAd->TxSwQueueLock[index]); | |
303 | NdisFreeSpinLock(&pAd->DeQueueLock[index]); | |
304 | pAd->DeQueueRunning[index] = FALSE; | |
305 | } | |
306 | ||
307 | NdisFreeSpinLock(&pAd->irq_lock); | |
308 | ||
309 | vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa); | |
310 | kfree(os_cookie); | |
311 | } | |
312 | ||
313 | BOOLEAN OS_Need_Clone_Packet(void) | |
314 | { | |
315 | return (FALSE); | |
316 | } | |
317 | ||
318 | ||
319 | ||
320 | /* | |
321 | ======================================================================== | |
322 | ||
323 | Routine Description: | |
324 | clone an input NDIS PACKET to another one. The new internally created NDIS PACKET | |
325 | must have only one NDIS BUFFER | |
326 | return - byte copied. 0 means can't create NDIS PACKET | |
327 | NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket | |
328 | ||
329 | Arguments: | |
330 | pAd Pointer to our adapter | |
331 | pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU. | |
332 | *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet. | |
333 | ||
334 | Return Value: | |
335 | NDIS_STATUS_SUCCESS | |
336 | NDIS_STATUS_FAILURE | |
337 | ||
338 | Note: | |
339 | ||
340 | ======================================================================== | |
341 | */ | |
342 | NDIS_STATUS RTMPCloneNdisPacket( | |
343 | IN PRTMP_ADAPTER pAd, | |
344 | IN BOOLEAN pInsAMSDUHdr, | |
345 | IN PNDIS_PACKET pInPacket, | |
346 | OUT PNDIS_PACKET *ppOutPacket) | |
347 | { | |
348 | ||
349 | struct sk_buff *pkt; | |
350 | ||
351 | ASSERT(pInPacket); | |
352 | ASSERT(ppOutPacket); | |
353 | ||
354 | // 1. Allocate a packet | |
355 | pkt = dev_alloc_skb(2048); | |
356 | ||
357 | if (pkt == NULL) | |
358 | { | |
359 | return NDIS_STATUS_FAILURE; | |
360 | } | |
361 | ||
362 | skb_put(pkt, GET_OS_PKT_LEN(pInPacket)); | |
363 | NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket)); | |
364 | *ppOutPacket = OSPKT_TO_RTPKT(pkt); | |
365 | ||
366 | ||
367 | RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); | |
368 | ||
369 | printk("###Clone###\n"); | |
370 | ||
371 | return NDIS_STATUS_SUCCESS; | |
372 | } | |
373 | ||
374 | ||
375 | // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() | |
376 | NDIS_STATUS RTMPAllocateNdisPacket( | |
377 | IN PRTMP_ADAPTER pAd, | |
378 | OUT PNDIS_PACKET *ppPacket, | |
379 | IN PUCHAR pHeader, | |
380 | IN UINT HeaderLen, | |
381 | IN PUCHAR pData, | |
382 | IN UINT DataLen) | |
383 | { | |
384 | PNDIS_PACKET pPacket; | |
385 | ASSERT(pData); | |
386 | ASSERT(DataLen); | |
387 | ||
388 | // 1. Allocate a packet | |
389 | pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE); | |
390 | if (pPacket == NULL) | |
391 | { | |
392 | *ppPacket = NULL; | |
393 | #ifdef DEBUG | |
394 | printk("RTMPAllocateNdisPacket Fail\n\n"); | |
395 | #endif | |
396 | return NDIS_STATUS_FAILURE; | |
397 | } | |
398 | ||
399 | // 2. clone the frame content | |
400 | if (HeaderLen > 0) | |
401 | NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen); | |
402 | if (DataLen > 0) | |
403 | NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen); | |
404 | ||
405 | // 3. update length of packet | |
406 | skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen); | |
407 | ||
408 | RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); | |
d599edca | 409 | // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); |
91980990 GKH |
410 | *ppPacket = pPacket; |
411 | return NDIS_STATUS_SUCCESS; | |
412 | } | |
413 | ||
414 | /* | |
415 | ======================================================================== | |
416 | Description: | |
417 | This routine frees a miniport internally allocated NDIS_PACKET and its | |
418 | corresponding NDIS_BUFFER and allocated memory. | |
419 | ======================================================================== | |
420 | */ | |
421 | VOID RTMPFreeNdisPacket( | |
422 | IN PRTMP_ADAPTER pAd, | |
423 | IN PNDIS_PACKET pPacket) | |
424 | { | |
425 | dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket)); | |
426 | } | |
427 | ||
428 | ||
429 | // IRQL = DISPATCH_LEVEL | |
430 | // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same | |
431 | // scatter gather buffer | |
432 | NDIS_STATUS Sniff2BytesFromNdisBuffer( | |
433 | IN PNDIS_BUFFER pFirstBuffer, | |
434 | IN UCHAR DesiredOffset, | |
435 | OUT PUCHAR pByte0, | |
436 | OUT PUCHAR pByte1) | |
437 | { | |
438 | *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset); | |
439 | *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1); | |
440 | ||
441 | return NDIS_STATUS_SUCCESS; | |
442 | } | |
443 | ||
444 | ||
445 | void RTMP_QueryPacketInfo( | |
446 | IN PNDIS_PACKET pPacket, | |
447 | OUT PACKET_INFO *pPacketInfo, | |
448 | OUT PUCHAR *pSrcBufVA, | |
449 | OUT UINT *pSrcBufLen) | |
450 | { | |
451 | pPacketInfo->BufferCount = 1; | |
452 | pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); | |
453 | pPacketInfo->PhysicalBufferCount = 1; | |
454 | pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); | |
455 | ||
456 | *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); | |
457 | *pSrcBufLen = GET_OS_PKT_LEN(pPacket); | |
458 | } | |
459 | ||
460 | void RTMP_QueryNextPacketInfo( | |
461 | IN PNDIS_PACKET *ppPacket, | |
462 | OUT PACKET_INFO *pPacketInfo, | |
463 | OUT PUCHAR *pSrcBufVA, | |
464 | OUT UINT *pSrcBufLen) | |
465 | { | |
466 | PNDIS_PACKET pPacket = NULL; | |
467 | ||
468 | if (*ppPacket) | |
469 | pPacket = GET_OS_PKT_NEXT(*ppPacket); | |
470 | ||
471 | if (pPacket) | |
472 | { | |
473 | pPacketInfo->BufferCount = 1; | |
474 | pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); | |
475 | pPacketInfo->PhysicalBufferCount = 1; | |
476 | pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); | |
477 | ||
478 | *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); | |
479 | *pSrcBufLen = GET_OS_PKT_LEN(pPacket); | |
480 | *ppPacket = GET_OS_PKT_NEXT(pPacket); | |
481 | } | |
482 | else | |
483 | { | |
484 | pPacketInfo->BufferCount = 0; | |
485 | pPacketInfo->pFirstBuffer = NULL; | |
486 | pPacketInfo->PhysicalBufferCount = 0; | |
487 | pPacketInfo->TotalPacketLength = 0; | |
488 | ||
489 | *pSrcBufVA = NULL; | |
490 | *pSrcBufLen = 0; | |
491 | *ppPacket = NULL; | |
492 | } | |
493 | } | |
494 | ||
495 | // not yet support MBSS | |
496 | PNET_DEV get_netdev_from_bssid( | |
497 | IN PRTMP_ADAPTER pAd, | |
498 | IN UCHAR FromWhichBSSID) | |
499 | { | |
500 | PNET_DEV dev_p = NULL; | |
501 | ||
502 | #ifdef CONFIG_STA_SUPPORT | |
503 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | |
504 | { | |
505 | dev_p = pAd->net_dev; | |
506 | } | |
507 | #endif // CONFIG_STA_SUPPORT // | |
508 | ||
509 | ASSERT(dev_p); | |
510 | return dev_p; /* return one of MBSS */ | |
511 | } | |
512 | ||
513 | PNDIS_PACKET DuplicatePacket( | |
514 | IN PRTMP_ADAPTER pAd, | |
515 | IN PNDIS_PACKET pPacket, | |
516 | IN UCHAR FromWhichBSSID) | |
517 | { | |
518 | struct sk_buff *skb; | |
519 | PNDIS_PACKET pRetPacket = NULL; | |
520 | USHORT DataSize; | |
521 | UCHAR *pData; | |
522 | ||
523 | DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); | |
524 | pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); | |
525 | ||
526 | ||
527 | skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); | |
528 | if (skb) | |
529 | { | |
530 | skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); | |
531 | pRetPacket = OSPKT_TO_RTPKT(skb); | |
532 | } | |
533 | ||
534 | return pRetPacket; | |
535 | ||
536 | } | |
537 | ||
538 | PNDIS_PACKET duplicate_pkt( | |
539 | IN PRTMP_ADAPTER pAd, | |
540 | IN PUCHAR pHeader802_3, | |
541 | IN UINT HdrLen, | |
542 | IN PUCHAR pData, | |
543 | IN ULONG DataSize, | |
544 | IN UCHAR FromWhichBSSID) | |
545 | { | |
546 | struct sk_buff *skb; | |
547 | PNDIS_PACKET pPacket = NULL; | |
548 | ||
549 | ||
550 | if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) | |
551 | { | |
552 | skb_reserve(skb, 2); | |
553 | NdisMoveMemory(skb->tail, pHeader802_3, HdrLen); | |
554 | skb_put(skb, HdrLen); | |
555 | NdisMoveMemory(skb->tail, pData, DataSize); | |
556 | skb_put(skb, DataSize); | |
557 | skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); | |
558 | pPacket = OSPKT_TO_RTPKT(skb); | |
559 | } | |
560 | ||
561 | return pPacket; | |
562 | } | |
563 | ||
564 | ||
565 | #define TKIP_TX_MIC_SIZE 8 | |
566 | PNDIS_PACKET duplicate_pkt_with_TKIP_MIC( | |
567 | IN PRTMP_ADAPTER pAd, | |
568 | IN PNDIS_PACKET pPacket) | |
569 | { | |
570 | struct sk_buff *skb, *newskb; | |
571 | ||
572 | ||
573 | skb = RTPKT_TO_OSPKT(pPacket); | |
574 | if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) | |
575 | { | |
576 | // alloc a new skb and copy the packet | |
577 | newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC); | |
578 | dev_kfree_skb_any(skb); | |
579 | if (newskb == NULL) | |
580 | { | |
581 | DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n")); | |
582 | return NULL; | |
583 | } | |
584 | skb = newskb; | |
585 | } | |
586 | ||
587 | return OSPKT_TO_RTPKT(skb); | |
588 | } | |
589 | ||
590 | ||
591 | ||
592 | ||
593 | PNDIS_PACKET ClonePacket( | |
594 | IN PRTMP_ADAPTER pAd, | |
595 | IN PNDIS_PACKET pPacket, | |
596 | IN PUCHAR pData, | |
597 | IN ULONG DataSize) | |
598 | { | |
599 | struct sk_buff *pRxPkt; | |
600 | struct sk_buff *pClonedPkt; | |
601 | ||
602 | ASSERT(pPacket); | |
603 | pRxPkt = RTPKT_TO_OSPKT(pPacket); | |
604 | ||
605 | // clone the packet | |
606 | pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG); | |
607 | ||
608 | if (pClonedPkt) | |
609 | { | |
610 | // set the correct dataptr and data len | |
611 | pClonedPkt->dev = pRxPkt->dev; | |
612 | pClonedPkt->data = pData; | |
613 | pClonedPkt->len = DataSize; | |
614 | pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len; | |
615 | ASSERT(DataSize < 1530); | |
616 | } | |
617 | return pClonedPkt; | |
618 | } | |
619 | ||
620 | // | |
621 | // change OS packet DataPtr and DataLen | |
622 | // | |
623 | void update_os_packet_info( | |
624 | IN PRTMP_ADAPTER pAd, | |
625 | IN RX_BLK *pRxBlk, | |
626 | IN UCHAR FromWhichBSSID) | |
627 | { | |
628 | struct sk_buff *pOSPkt; | |
629 | ||
630 | ASSERT(pRxBlk->pRxPacket); | |
631 | pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); | |
632 | ||
633 | pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); | |
634 | pOSPkt->data = pRxBlk->pData; | |
635 | pOSPkt->len = pRxBlk->DataSize; | |
636 | pOSPkt->tail = pOSPkt->data + pOSPkt->len; | |
637 | } | |
638 | ||
639 | ||
640 | void wlan_802_11_to_802_3_packet( | |
641 | IN PRTMP_ADAPTER pAd, | |
642 | IN RX_BLK *pRxBlk, | |
643 | IN PUCHAR pHeader802_3, | |
644 | IN UCHAR FromWhichBSSID) | |
645 | { | |
646 | struct sk_buff *pOSPkt; | |
647 | ||
648 | ASSERT(pRxBlk->pRxPacket); | |
649 | ASSERT(pHeader802_3); | |
650 | ||
651 | pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); | |
652 | ||
653 | pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); | |
654 | pOSPkt->data = pRxBlk->pData; | |
655 | pOSPkt->len = pRxBlk->DataSize; | |
656 | pOSPkt->tail = pOSPkt->data + pOSPkt->len; | |
657 | ||
658 | // | |
659 | // copy 802.3 header | |
660 | // | |
661 | // | |
662 | ||
663 | #ifdef CONFIG_STA_SUPPORT | |
664 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | |
665 | NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3); | |
666 | #endif // CONFIG_STA_SUPPORT // | |
667 | } | |
668 | ||
669 | ||
670 | ||
671 | void announce_802_3_packet( | |
672 | IN PRTMP_ADAPTER pAd, | |
673 | IN PNDIS_PACKET pPacket) | |
674 | { | |
675 | ||
676 | struct sk_buff *pRxPkt; | |
677 | ||
678 | ASSERT(pPacket); | |
679 | ||
680 | pRxPkt = RTPKT_TO_OSPKT(pPacket); | |
681 | ||
682 | /* Push up the protocol stack */ | |
683 | #ifdef IKANOS_VX_1X0 | |
684 | IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len); | |
685 | #else | |
686 | pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); | |
687 | ||
688 | netif_rx(pRxPkt); | |
689 | #endif // IKANOS_VX_1X0 // | |
690 | } | |
691 | ||
692 | ||
693 | PRTMP_SCATTER_GATHER_LIST | |
694 | rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg) | |
695 | { | |
696 | sg->NumberOfElements = 1; | |
697 | sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket); | |
698 | sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket); | |
699 | return (sg); | |
700 | } | |
701 | ||
702 | void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen) | |
703 | { | |
704 | unsigned char *pt; | |
705 | int x; | |
706 | ||
707 | if (RTDebugLevel < RT_DEBUG_TRACE) | |
708 | return; | |
709 | ||
710 | pt = pSrcBufVA; | |
711 | printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen); | |
712 | for (x=0; x<SrcBufLen; x++) | |
713 | { | |
714 | if (x % 16 == 0) | |
715 | printk("0x%04x : ", x); | |
716 | printk("%02x ", ((unsigned char)pt[x])); | |
717 | if (x%16 == 15) printk("\n"); | |
718 | } | |
719 | printk("\n"); | |
720 | } | |
721 | ||
722 | /* | |
723 | ======================================================================== | |
724 | ||
725 | Routine Description: | |
726 | Send log message through wireless event | |
727 | ||
728 | Support standard iw_event with IWEVCUSTOM. It is used below. | |
729 | ||
730 | iwreq_data.data.flags is used to store event_flag that is defined by user. | |
731 | iwreq_data.data.length is the length of the event log. | |
732 | ||
733 | The format of the event log is composed of the entry's MAC address and | |
734 | the desired log message (refer to pWirelessEventText). | |
735 | ||
736 | ex: 11:22:33:44:55:66 has associated successfully | |
737 | ||
738 | p.s. The requirement of Wireless Extension is v15 or newer. | |
739 | ||
740 | ======================================================================== | |
741 | */ | |
742 | VOID RTMPSendWirelessEvent( | |
743 | IN PRTMP_ADAPTER pAd, | |
744 | IN USHORT Event_flag, | |
745 | IN PUCHAR pAddr, | |
746 | IN UCHAR BssIdx, | |
747 | IN CHAR Rssi) | |
748 | { | |
749 | #if WIRELESS_EXT >= 15 | |
750 | ||
751 | union iwreq_data wrqu; | |
752 | PUCHAR pBuf = NULL, pBufPtr = NULL; | |
753 | USHORT event, type, BufLen; | |
754 | UCHAR event_table_len = 0; | |
755 | ||
756 | type = Event_flag & 0xFF00; | |
757 | event = Event_flag & 0x00FF; | |
758 | ||
759 | switch (type) | |
760 | { | |
761 | case IW_SYS_EVENT_FLAG_START: | |
762 | event_table_len = IW_SYS_EVENT_TYPE_NUM; | |
763 | break; | |
764 | ||
765 | case IW_SPOOF_EVENT_FLAG_START: | |
766 | event_table_len = IW_SPOOF_EVENT_TYPE_NUM; | |
767 | break; | |
768 | ||
769 | case IW_FLOOD_EVENT_FLAG_START: | |
770 | event_table_len = IW_FLOOD_EVENT_TYPE_NUM; | |
771 | break; | |
772 | } | |
773 | ||
774 | if (event_table_len == 0) | |
775 | { | |
d599edca | 776 | DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type)); |
91980990 GKH |
777 | return; |
778 | } | |
779 | ||
780 | if (event >= event_table_len) | |
781 | { | |
d599edca | 782 | DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event)); |
91980990 GKH |
783 | return; |
784 | } | |
785 | ||
786 | //Allocate memory and copy the msg. | |
787 | if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) | |
788 | { | |
789 | //Prepare the payload | |
790 | memset(pBuf, 0, IW_CUSTOM_MAX_LEN); | |
791 | ||
792 | pBufPtr = pBuf; | |
793 | ||
794 | if (pAddr) | |
795 | pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr)); | |
796 | else if (BssIdx < MAX_MBSSID_NUM) | |
797 | pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx); | |
798 | else | |
799 | pBufPtr += sprintf(pBufPtr, "(RT2860) "); | |
800 | ||
801 | if (type == IW_SYS_EVENT_FLAG_START) | |
802 | pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]); | |
803 | else if (type == IW_SPOOF_EVENT_FLAG_START) | |
804 | pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi); | |
805 | else if (type == IW_FLOOD_EVENT_FLAG_START) | |
806 | pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]); | |
807 | else | |
808 | pBufPtr += sprintf(pBufPtr, "%s", "unknown event"); | |
809 | ||
810 | pBufPtr[pBufPtr - pBuf] = '\0'; | |
811 | BufLen = pBufPtr - pBuf; | |
812 | ||
813 | memset(&wrqu, 0, sizeof(wrqu)); | |
814 | wrqu.data.flags = Event_flag; | |
815 | wrqu.data.length = BufLen; | |
816 | ||
817 | //send wireless event | |
818 | wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf); | |
819 | ||
d599edca | 820 | //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); |
91980990 GKH |
821 | |
822 | kfree(pBuf); | |
823 | } | |
824 | else | |
d599edca | 825 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__)); |
91980990 | 826 | #else |
d599edca | 827 | DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__)); |
91980990 GKH |
828 | #endif /* WIRELESS_EXT >= 15 */ |
829 | } | |
830 | ||
831 | ||
832 | #ifdef CONFIG_STA_SUPPORT | |
833 | void send_monitor_packets( | |
834 | IN PRTMP_ADAPTER pAd, | |
835 | IN RX_BLK *pRxBlk) | |
836 | { | |
837 | struct sk_buff *pOSPkt; | |
838 | wlan_ng_prism2_header *ph; | |
839 | int rate_index = 0; | |
840 | USHORT header_len = 0; | |
841 | UCHAR temp_header[40] = {0}; | |
842 | ||
843 | 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 | |
844 | 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10, | |
845 | 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80}; | |
846 | ||
847 | ||
848 | ASSERT(pRxBlk->pRxPacket); | |
849 | if (pRxBlk->DataSize < 10) | |
850 | { | |
d599edca | 851 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize)); |
91980990 GKH |
852 | goto err_free_sk_buff; |
853 | } | |
854 | ||
855 | if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) | |
856 | { | |
d599edca | 857 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); |
91980990 GKH |
858 | goto err_free_sk_buff; |
859 | } | |
860 | ||
861 | pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); | |
862 | pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0); | |
863 | if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) | |
864 | { | |
865 | pRxBlk->DataSize -= LENGTH_802_11; | |
866 | if ((pRxBlk->pHeader->FC.ToDs == 1) && | |
867 | (pRxBlk->pHeader->FC.FrDs == 1)) | |
868 | header_len = LENGTH_802_11_WITH_ADDR4; | |
869 | else | |
870 | header_len = LENGTH_802_11; | |
871 | ||
872 | // QOS | |
873 | if (pRxBlk->pHeader->FC.SubType & 0x08) | |
874 | { | |
875 | header_len += 2; | |
876 | // Data skip QOS contorl field | |
877 | pRxBlk->DataSize -=2; | |
878 | } | |
879 | ||
880 | // Order bit: A-Ralink or HTC+ | |
881 | if (pRxBlk->pHeader->FC.Order) | |
882 | { | |
883 | header_len += 4; | |
884 | // Data skip HTC contorl field | |
885 | pRxBlk->DataSize -= 4; | |
886 | } | |
887 | ||
888 | // Copy Header | |
889 | if (header_len <= 40) | |
890 | NdisMoveMemory(temp_header, pRxBlk->pData, header_len); | |
891 | ||
892 | // skip HW padding | |
893 | if (pRxBlk->RxD.L2PAD) | |
894 | pRxBlk->pData += (header_len + 2); | |
895 | else | |
896 | pRxBlk->pData += header_len; | |
897 | } //end if | |
898 | ||
899 | ||
900 | if (pRxBlk->DataSize < pOSPkt->len) { | |
901 | skb_trim(pOSPkt,pRxBlk->DataSize); | |
902 | } else { | |
903 | skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len)); | |
904 | } //end if | |
905 | ||
906 | if ((pRxBlk->pData - pOSPkt->data) > 0) { | |
907 | skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data)); | |
908 | skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data)); | |
909 | } //end if | |
910 | ||
911 | if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) { | |
912 | if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) { | |
d599edca | 913 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__)); |
91980990 GKH |
914 | goto err_free_sk_buff; |
915 | } //end if | |
916 | } //end if | |
917 | ||
918 | if (header_len > 0) | |
919 | NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len); | |
920 | ||
921 | ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header)); | |
922 | NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header)); | |
923 | ||
924 | ph->msgcode = DIDmsg_lnxind_wlansniffrm; | |
925 | ph->msglen = sizeof(wlan_ng_prism2_header); | |
926 | strcpy(ph->devname, pAd->net_dev->name); | |
927 | ||
928 | ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; | |
929 | ph->hosttime.status = 0; | |
930 | ph->hosttime.len = 4; | |
931 | ph->hosttime.data = jiffies; | |
932 | ||
933 | ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; | |
934 | ph->mactime.status = 0; | |
935 | ph->mactime.len = 0; | |
936 | ph->mactime.data = 0; | |
937 | ||
938 | ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx; | |
939 | ph->istx.status = 0; | |
940 | ph->istx.len = 0; | |
941 | ph->istx.data = 0; | |
942 | ||
943 | ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel; | |
944 | ph->channel.status = 0; | |
945 | ph->channel.len = 4; | |
946 | ||
947 | ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel; | |
948 | ||
949 | ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; | |
950 | ph->rssi.status = 0; | |
951 | ph->rssi.len = 4; | |
952 | ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));; | |
953 | ||
954 | ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; | |
955 | ph->signal.status = 0; | |
956 | ph->signal.len = 4; | |
957 | ph->signal.data = 0; //rssi + noise; | |
958 | ||
959 | ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; | |
960 | ph->noise.status = 0; | |
961 | ph->noise.len = 4; | |
962 | ph->noise.data = 0; | |
963 | ||
964 | #ifdef DOT11_N_SUPPORT | |
965 | if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) | |
966 | { | |
967 | rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS); | |
968 | } | |
969 | else | |
970 | #endif // DOT11_N_SUPPORT // | |
971 | if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM) | |
972 | rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4; | |
973 | else | |
974 | rate_index = (UCHAR)(pRxBlk->pRxWI->MCS); | |
975 | if (rate_index < 0) | |
976 | rate_index = 0; | |
977 | if (rate_index > 255) | |
978 | rate_index = 255; | |
979 | ||
980 | ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; | |
981 | ph->rate.status = 0; | |
982 | ph->rate.len = 4; | |
983 | ph->rate.data = ralinkrate[rate_index]; | |
984 | ||
985 | ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; | |
986 | ph->frmlen.status = 0; | |
987 | ph->frmlen.len = 4; | |
988 | ph->frmlen.data = (u_int32_t)pRxBlk->DataSize; | |
989 | ||
990 | ||
991 | pOSPkt->pkt_type = PACKET_OTHERHOST; | |
992 | pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev); | |
993 | pOSPkt->ip_summed = CHECKSUM_NONE; | |
994 | netif_rx(pOSPkt); | |
995 | ||
996 | return; | |
997 | ||
998 | err_free_sk_buff: | |
999 | RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); | |
1000 | return; | |
1001 | ||
1002 | } | |
1003 | #endif // CONFIG_STA_SUPPORT // | |
1004 | ||
1005 | ||
1006 | void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify) | |
1007 | { | |
1008 | ||
1009 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | |
1010 | daemonize(pThreadName /*"%s",pAd->net_dev->name*/); | |
1011 | ||
1012 | allow_signal(SIGTERM); | |
1013 | allow_signal(SIGKILL); | |
1014 | current->flags |= PF_NOFREEZE; | |
1015 | #else | |
1016 | unsigned long flags; | |
1017 | ||
1018 | daemonize(); | |
1019 | reparent_to_init(); | |
1020 | strcpy(current->comm, pThreadName); | |
1021 | ||
1022 | siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); | |
1023 | ||
1024 | /* Allow interception of SIGKILL only | |
1025 | * Don't allow other signals to interrupt the transmission */ | |
1026 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) | |
1027 | spin_lock_irqsave(¤t->sigmask_lock, flags); | |
1028 | flush_signals(current); | |
1029 | recalc_sigpending(current); | |
1030 | spin_unlock_irqrestore(¤t->sigmask_lock, flags); | |
1031 | #endif | |
1032 | #endif | |
1033 | ||
1034 | /* signal that we've started the thread */ | |
1035 | complete(pNotify); | |
1036 | ||
1037 | } | |
1038 | ||
1039 | void RTMP_IndicateMediaState( | |
1040 | IN PRTMP_ADAPTER pAd) | |
1041 | { | |
1042 | if (pAd->CommonCfg.bWirelessEvent) | |
1043 | { | |
1044 | if (pAd->IndicateMediaState == NdisMediaStateConnected) | |
1045 | { | |
1046 | RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); | |
1047 | } | |
1048 | else | |
1049 | { | |
1050 | RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); | |
1051 | } | |
1052 | } | |
1053 | } | |
1054 |