Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 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(MlmeRssiReportExec); |
| 34 | BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout); |
| 35 | BUILD_TIMER_FUNCTION(APSDPeriodicExec); |
| 36 | BUILD_TIMER_FUNCTION(AsicRfTuningExec); |
| 37 | #ifdef RT2870 |
| 38 | BUILD_TIMER_FUNCTION(BeaconUpdateExec); |
| 39 | #endif // RT2870 // |
| 40 | |
| 41 | |
| 42 | #ifdef CONFIG_STA_SUPPORT |
| 43 | BUILD_TIMER_FUNCTION(BeaconTimeout); |
| 44 | BUILD_TIMER_FUNCTION(ScanTimeout); |
| 45 | BUILD_TIMER_FUNCTION(AuthTimeout); |
| 46 | BUILD_TIMER_FUNCTION(AssocTimeout); |
| 47 | BUILD_TIMER_FUNCTION(ReassocTimeout); |
| 48 | BUILD_TIMER_FUNCTION(DisassocTimeout); |
| 49 | BUILD_TIMER_FUNCTION(LinkDownExec); |
| 50 | #ifdef LEAP_SUPPORT |
| 51 | BUILD_TIMER_FUNCTION(LeapAuthTimeout); |
| 52 | #endif |
| 53 | BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); |
| 54 | BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); |
| 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 | |
| 297 | for (index =0 ; index < NUM_OF_TX_RING; index++) |
| 298 | { |
| 299 | NdisFreeSpinLock(&pAd->TxSwQueueLock[index]); |
| 300 | NdisFreeSpinLock(&pAd->DeQueueLock[index]); |
| 301 | pAd->DeQueueRunning[index] = FALSE; |
| 302 | } |
| 303 | |
| 304 | NdisFreeSpinLock(&pAd->irq_lock); |
| 305 | |
| 306 | |
| 307 | vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa); |
| 308 | kfree(os_cookie); |
| 309 | } |
| 310 | |
| 311 | BOOLEAN OS_Need_Clone_Packet(void) |
| 312 | { |
| 313 | return (FALSE); |
| 314 | } |
| 315 | |
| 316 | |
| 317 | |
| 318 | /* |
| 319 | ======================================================================== |
| 320 | |
| 321 | Routine Description: |
| 322 | clone an input NDIS PACKET to another one. The new internally created NDIS PACKET |
| 323 | must have only one NDIS BUFFER |
| 324 | return - byte copied. 0 means can't create NDIS PACKET |
| 325 | NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket |
| 326 | |
| 327 | Arguments: |
| 328 | pAd Pointer to our adapter |
| 329 | pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU. |
| 330 | *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet. |
| 331 | |
| 332 | Return Value: |
| 333 | NDIS_STATUS_SUCCESS |
| 334 | NDIS_STATUS_FAILURE |
| 335 | |
| 336 | Note: |
| 337 | |
| 338 | ======================================================================== |
| 339 | */ |
| 340 | NDIS_STATUS RTMPCloneNdisPacket( |
| 341 | IN PRTMP_ADAPTER pAd, |
| 342 | IN BOOLEAN pInsAMSDUHdr, |
| 343 | IN PNDIS_PACKET pInPacket, |
| 344 | OUT PNDIS_PACKET *ppOutPacket) |
| 345 | { |
| 346 | |
| 347 | struct sk_buff *pkt; |
| 348 | |
| 349 | ASSERT(pInPacket); |
| 350 | ASSERT(ppOutPacket); |
| 351 | |
| 352 | // 1. Allocate a packet |
| 353 | pkt = dev_alloc_skb(2048); |
| 354 | |
| 355 | if (pkt == NULL) |
| 356 | { |
| 357 | return NDIS_STATUS_FAILURE; |
| 358 | } |
| 359 | |
| 360 | skb_put(pkt, GET_OS_PKT_LEN(pInPacket)); |
| 361 | NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket)); |
| 362 | *ppOutPacket = OSPKT_TO_RTPKT(pkt); |
| 363 | |
| 364 | |
| 365 | RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); |
| 366 | |
| 367 | printk("###Clone###\n"); |
| 368 | |
| 369 | return NDIS_STATUS_SUCCESS; |
| 370 | } |
| 371 | |
| 372 | |
| 373 | // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() |
| 374 | NDIS_STATUS RTMPAllocateNdisPacket( |
| 375 | IN PRTMP_ADAPTER pAd, |
| 376 | OUT PNDIS_PACKET *ppPacket, |
| 377 | IN PUCHAR pHeader, |
| 378 | IN UINT HeaderLen, |
| 379 | IN PUCHAR pData, |
| 380 | IN UINT DataLen) |
| 381 | { |
| 382 | PNDIS_PACKET pPacket; |
| 383 | ASSERT(pData); |
| 384 | ASSERT(DataLen); |
| 385 | |
| 386 | // 1. Allocate a packet |
| 387 | pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE); |
| 388 | if (pPacket == NULL) |
| 389 | { |
| 390 | *ppPacket = NULL; |
| 391 | #ifdef DEBUG |
| 392 | printk("RTMPAllocateNdisPacket Fail\n\n"); |
| 393 | #endif |
| 394 | return NDIS_STATUS_FAILURE; |
| 395 | } |
| 396 | |
| 397 | // 2. clone the frame content |
| 398 | if (HeaderLen > 0) |
| 399 | NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen); |
| 400 | if (DataLen > 0) |
| 401 | NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen); |
| 402 | |
| 403 | // 3. update length of packet |
| 404 | skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen); |
| 405 | |
| 406 | RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 407 | // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 408 | *ppPacket = pPacket; |
| 409 | return NDIS_STATUS_SUCCESS; |
| 410 | } |
| 411 | |
| 412 | /* |
| 413 | ======================================================================== |
| 414 | Description: |
| 415 | This routine frees a miniport internally allocated NDIS_PACKET and its |
| 416 | corresponding NDIS_BUFFER and allocated memory. |
| 417 | ======================================================================== |
| 418 | */ |
| 419 | VOID RTMPFreeNdisPacket( |
| 420 | IN PRTMP_ADAPTER pAd, |
| 421 | IN PNDIS_PACKET pPacket) |
| 422 | { |
| 423 | dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket)); |
| 424 | } |
| 425 | |
| 426 | |
| 427 | // IRQL = DISPATCH_LEVEL |
| 428 | // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same |
| 429 | // scatter gather buffer |
| 430 | NDIS_STATUS Sniff2BytesFromNdisBuffer( |
| 431 | IN PNDIS_BUFFER pFirstBuffer, |
| 432 | IN UCHAR DesiredOffset, |
| 433 | OUT PUCHAR pByte0, |
| 434 | OUT PUCHAR pByte1) |
| 435 | { |
| 436 | *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset); |
| 437 | *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1); |
| 438 | |
| 439 | return NDIS_STATUS_SUCCESS; |
| 440 | } |
| 441 | |
| 442 | |
| 443 | void RTMP_QueryPacketInfo( |
| 444 | IN PNDIS_PACKET pPacket, |
| 445 | OUT PACKET_INFO *pPacketInfo, |
| 446 | OUT PUCHAR *pSrcBufVA, |
| 447 | OUT UINT *pSrcBufLen) |
| 448 | { |
| 449 | pPacketInfo->BufferCount = 1; |
| 450 | pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); |
| 451 | pPacketInfo->PhysicalBufferCount = 1; |
| 452 | pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); |
| 453 | |
| 454 | *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); |
| 455 | *pSrcBufLen = GET_OS_PKT_LEN(pPacket); |
| 456 | } |
| 457 | |
| 458 | void RTMP_QueryNextPacketInfo( |
| 459 | IN PNDIS_PACKET *ppPacket, |
| 460 | OUT PACKET_INFO *pPacketInfo, |
| 461 | OUT PUCHAR *pSrcBufVA, |
| 462 | OUT UINT *pSrcBufLen) |
| 463 | { |
| 464 | PNDIS_PACKET pPacket = NULL; |
| 465 | |
| 466 | if (*ppPacket) |
| 467 | pPacket = GET_OS_PKT_NEXT(*ppPacket); |
| 468 | |
| 469 | if (pPacket) |
| 470 | { |
| 471 | pPacketInfo->BufferCount = 1; |
| 472 | pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); |
| 473 | pPacketInfo->PhysicalBufferCount = 1; |
| 474 | pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); |
| 475 | |
| 476 | *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); |
| 477 | *pSrcBufLen = GET_OS_PKT_LEN(pPacket); |
| 478 | *ppPacket = GET_OS_PKT_NEXT(pPacket); |
| 479 | } |
| 480 | else |
| 481 | { |
| 482 | pPacketInfo->BufferCount = 0; |
| 483 | pPacketInfo->pFirstBuffer = NULL; |
| 484 | pPacketInfo->PhysicalBufferCount = 0; |
| 485 | pPacketInfo->TotalPacketLength = 0; |
| 486 | |
| 487 | *pSrcBufVA = NULL; |
| 488 | *pSrcBufLen = 0; |
| 489 | *ppPacket = NULL; |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | // not yet support MBSS |
| 494 | PNET_DEV get_netdev_from_bssid( |
| 495 | IN PRTMP_ADAPTER pAd, |
| 496 | IN UCHAR FromWhichBSSID) |
| 497 | { |
| 498 | PNET_DEV dev_p = NULL; |
| 499 | |
| 500 | |
| 501 | #ifdef CONFIG_STA_SUPPORT |
| 502 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) |
| 503 | { |
| 504 | dev_p = pAd->net_dev; |
| 505 | } |
| 506 | #endif // CONFIG_STA_SUPPORT // |
| 507 | |
| 508 | ASSERT(dev_p); |
| 509 | return dev_p; /* return one of MBSS */ |
| 510 | } |
| 511 | |
| 512 | PNDIS_PACKET DuplicatePacket( |
| 513 | IN PRTMP_ADAPTER pAd, |
| 514 | IN PNDIS_PACKET pPacket, |
| 515 | IN UCHAR FromWhichBSSID) |
| 516 | { |
| 517 | struct sk_buff *skb; |
| 518 | PNDIS_PACKET pRetPacket = NULL; |
| 519 | USHORT DataSize; |
| 520 | UCHAR *pData; |
| 521 | |
| 522 | DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); |
| 523 | pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); |
| 524 | |
| 525 | |
| 526 | skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); |
| 527 | if (skb) |
| 528 | { |
| 529 | skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); |
| 530 | pRetPacket = OSPKT_TO_RTPKT(skb); |
| 531 | } |
| 532 | |
| 533 | #if 0 |
| 534 | if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL) |
| 535 | { |
| 536 | skb_reserve(skb, 2+32); |
| 537 | NdisMoveMemory(skb->tail, pData, DataSize); |
| 538 | skb_put(skb, DataSize); |
| 539 | skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); |
| 540 | pRetPacket = OSPKT_TO_RTPKT(skb); |
| 541 | } |
| 542 | #endif |
| 543 | |
| 544 | return pRetPacket; |
| 545 | |
| 546 | } |
| 547 | |
| 548 | PNDIS_PACKET duplicate_pkt( |
| 549 | IN PRTMP_ADAPTER pAd, |
| 550 | IN PUCHAR pHeader802_3, |
| 551 | IN UINT HdrLen, |
| 552 | IN PUCHAR pData, |
| 553 | IN ULONG DataSize, |
| 554 | IN UCHAR FromWhichBSSID) |
| 555 | { |
| 556 | struct sk_buff *skb; |
| 557 | PNDIS_PACKET pPacket = NULL; |
| 558 | |
| 559 | |
| 560 | if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) |
| 561 | { |
| 562 | skb_reserve(skb, 2); |
| 563 | NdisMoveMemory(skb->tail, pHeader802_3, HdrLen); |
| 564 | skb_put(skb, HdrLen); |
| 565 | NdisMoveMemory(skb->tail, pData, DataSize); |
| 566 | skb_put(skb, DataSize); |
| 567 | skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); |
| 568 | pPacket = OSPKT_TO_RTPKT(skb); |
| 569 | } |
| 570 | |
| 571 | return pPacket; |
| 572 | } |
| 573 | |
| 574 | |
| 575 | #define TKIP_TX_MIC_SIZE 8 |
| 576 | PNDIS_PACKET duplicate_pkt_with_TKIP_MIC( |
| 577 | IN PRTMP_ADAPTER pAd, |
| 578 | IN PNDIS_PACKET pPacket) |
| 579 | { |
| 580 | struct sk_buff *skb, *newskb; |
| 581 | |
| 582 | |
| 583 | skb = RTPKT_TO_OSPKT(pPacket); |
| 584 | if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) |
| 585 | { |
| 586 | // alloc a new skb and copy the packet |
| 587 | newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC); |
| 588 | dev_kfree_skb_any(skb); |
| 589 | if (newskb == NULL) |
| 590 | { |
| 591 | DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n")); |
| 592 | return NULL; |
| 593 | } |
| 594 | skb = newskb; |
| 595 | } |
| 596 | |
| 597 | return OSPKT_TO_RTPKT(skb); |
| 598 | |
| 599 | #if 0 |
| 600 | if ((data = skb_put(skb, TKIP_TX_MIC_SIZE)) != NULL) |
| 601 | { // If we can extend it, well, copy it first. |
| 602 | NdisMoveMemory(data, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE); |
| 603 | } |
| 604 | else |
| 605 | { |
| 606 | // Otherwise, copy the packet. |
| 607 | newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC); |
| 608 | dev_kfree_skb_any(skb); |
| 609 | if (newskb == NULL) |
| 610 | { |
| 611 | DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC to packet failed!, dropping packet\n")); |
| 612 | return NULL; |
| 613 | } |
| 614 | skb = newskb; |
| 615 | |
| 616 | NdisMoveMemory(skb->tail, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE); |
| 617 | skb_put(skb, TKIP_TX_MIC_SIZE); |
| 618 | } |
| 619 | |
| 620 | return OSPKT_TO_RTPKT(skb); |
| 621 | #endif |
| 622 | |
| 623 | } |
| 624 | |
| 625 | |
| 626 | |
| 627 | |
| 628 | PNDIS_PACKET ClonePacket( |
| 629 | IN PRTMP_ADAPTER pAd, |
| 630 | IN PNDIS_PACKET pPacket, |
| 631 | IN PUCHAR pData, |
| 632 | IN ULONG DataSize) |
| 633 | { |
| 634 | struct sk_buff *pRxPkt; |
| 635 | struct sk_buff *pClonedPkt; |
| 636 | |
| 637 | ASSERT(pPacket); |
| 638 | pRxPkt = RTPKT_TO_OSPKT(pPacket); |
| 639 | |
| 640 | // clone the packet |
| 641 | pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG); |
| 642 | |
| 643 | if (pClonedPkt) |
| 644 | { |
| 645 | // set the correct dataptr and data len |
| 646 | pClonedPkt->dev = pRxPkt->dev; |
| 647 | pClonedPkt->data = pData; |
| 648 | pClonedPkt->len = DataSize; |
| 649 | pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len; |
| 650 | ASSERT(DataSize < 1530); |
| 651 | } |
| 652 | return pClonedPkt; |
| 653 | } |
| 654 | |
| 655 | // |
| 656 | // change OS packet DataPtr and DataLen |
| 657 | // |
| 658 | void update_os_packet_info( |
| 659 | IN PRTMP_ADAPTER pAd, |
| 660 | IN RX_BLK *pRxBlk, |
| 661 | IN UCHAR FromWhichBSSID) |
| 662 | { |
| 663 | struct sk_buff *pOSPkt; |
| 664 | |
| 665 | ASSERT(pRxBlk->pRxPacket); |
| 666 | pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); |
| 667 | |
| 668 | pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); |
| 669 | pOSPkt->data = pRxBlk->pData; |
| 670 | pOSPkt->len = pRxBlk->DataSize; |
| 671 | pOSPkt->tail = pOSPkt->data + pOSPkt->len; |
| 672 | } |
| 673 | |
| 674 | |
| 675 | void wlan_802_11_to_802_3_packet( |
| 676 | IN PRTMP_ADAPTER pAd, |
| 677 | IN RX_BLK *pRxBlk, |
| 678 | IN PUCHAR pHeader802_3, |
| 679 | IN UCHAR FromWhichBSSID) |
| 680 | { |
| 681 | struct sk_buff *pOSPkt; |
| 682 | |
| 683 | ASSERT(pRxBlk->pRxPacket); |
| 684 | ASSERT(pHeader802_3); |
| 685 | |
| 686 | pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); |
| 687 | |
| 688 | pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); |
| 689 | pOSPkt->data = pRxBlk->pData; |
| 690 | pOSPkt->len = pRxBlk->DataSize; |
| 691 | pOSPkt->tail = pOSPkt->data + pOSPkt->len; |
| 692 | |
| 693 | // |
| 694 | // copy 802.3 header |
| 695 | // |
| 696 | // |
| 697 | |
| 698 | #ifdef CONFIG_STA_SUPPORT |
| 699 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) |
| 700 | NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3); |
| 701 | #endif // CONFIG_STA_SUPPORT // |
| 702 | } |
| 703 | |
| 704 | |
| 705 | |
| 706 | void announce_802_3_packet( |
| 707 | IN PRTMP_ADAPTER pAd, |
| 708 | IN PNDIS_PACKET pPacket) |
| 709 | { |
| 710 | |
| 711 | struct sk_buff *pRxPkt; |
| 712 | |
| 713 | ASSERT(pPacket); |
| 714 | |
| 715 | pRxPkt = RTPKT_TO_OSPKT(pPacket); |
| 716 | |
| 717 | #ifdef CONFIG_STA_SUPPORT |
| 718 | #endif // CONFIG_STA_SUPPORT // |
| 719 | |
| 720 | /* Push up the protocol stack */ |
| 721 | #ifdef IKANOS_VX_1X0 |
| 722 | IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len); |
| 723 | #else |
| 724 | pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); |
| 725 | |
| 726 | //#ifdef CONFIG_5VT_ENHANCE |
| 727 | // *(int*)(pRxPkt->cb) = BRIDGE_TAG; |
| 728 | //#endif |
| 729 | netif_rx(pRxPkt); |
| 730 | #endif // IKANOS_VX_1X0 // |
| 731 | } |
| 732 | |
| 733 | |
| 734 | PRTMP_SCATTER_GATHER_LIST |
| 735 | rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg) |
| 736 | { |
| 737 | sg->NumberOfElements = 1; |
| 738 | sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket); |
| 739 | sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket); |
| 740 | return (sg); |
| 741 | } |
| 742 | |
| 743 | void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen) |
| 744 | { |
| 745 | unsigned char *pt; |
| 746 | int x; |
| 747 | |
| 748 | if (RTDebugLevel < RT_DEBUG_TRACE) |
| 749 | return; |
| 750 | |
| 751 | pt = pSrcBufVA; |
| 752 | printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen); |
| 753 | for (x=0; x<SrcBufLen; x++) |
| 754 | { |
| 755 | if (x % 16 == 0) |
| 756 | printk("0x%04x : ", x); |
| 757 | printk("%02x ", ((unsigned char)pt[x])); |
| 758 | if (x%16 == 15) printk("\n"); |
| 759 | } |
| 760 | printk("\n"); |
| 761 | } |
| 762 | |
| 763 | /* |
| 764 | ======================================================================== |
| 765 | |
| 766 | Routine Description: |
| 767 | Send log message through wireless event |
| 768 | |
| 769 | Support standard iw_event with IWEVCUSTOM. It is used below. |
| 770 | |
| 771 | iwreq_data.data.flags is used to store event_flag that is defined by user. |
| 772 | iwreq_data.data.length is the length of the event log. |
| 773 | |
| 774 | The format of the event log is composed of the entry's MAC address and |
| 775 | the desired log message (refer to pWirelessEventText). |
| 776 | |
| 777 | ex: 11:22:33:44:55:66 has associated successfully |
| 778 | |
| 779 | p.s. The requirement of Wireless Extension is v15 or newer. |
| 780 | |
| 781 | ======================================================================== |
| 782 | */ |
| 783 | VOID RTMPSendWirelessEvent( |
| 784 | IN PRTMP_ADAPTER pAd, |
| 785 | IN USHORT Event_flag, |
| 786 | IN PUCHAR pAddr, |
| 787 | IN UCHAR BssIdx, |
| 788 | IN CHAR Rssi) |
| 789 | { |
| 790 | #if WIRELESS_EXT >= 15 |
| 791 | |
| 792 | union iwreq_data wrqu; |
| 793 | PUCHAR pBuf = NULL, pBufPtr = NULL; |
| 794 | USHORT event, type, BufLen; |
| 795 | UCHAR event_table_len = 0; |
| 796 | |
| 797 | type = Event_flag & 0xFF00; |
| 798 | event = Event_flag & 0x00FF; |
| 799 | |
| 800 | switch (type) |
| 801 | { |
| 802 | case IW_SYS_EVENT_FLAG_START: |
| 803 | event_table_len = IW_SYS_EVENT_TYPE_NUM; |
| 804 | break; |
| 805 | |
| 806 | case IW_SPOOF_EVENT_FLAG_START: |
| 807 | event_table_len = IW_SPOOF_EVENT_TYPE_NUM; |
| 808 | break; |
| 809 | |
| 810 | case IW_FLOOD_EVENT_FLAG_START: |
| 811 | event_table_len = IW_FLOOD_EVENT_TYPE_NUM; |
| 812 | break; |
| 813 | } |
| 814 | |
| 815 | if (event_table_len == 0) |
| 816 | { |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 817 | DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 818 | return; |
| 819 | } |
| 820 | |
| 821 | if (event >= event_table_len) |
| 822 | { |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 823 | DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 824 | return; |
| 825 | } |
| 826 | |
| 827 | //Allocate memory and copy the msg. |
| 828 | if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) |
| 829 | { |
| 830 | //Prepare the payload |
| 831 | memset(pBuf, 0, IW_CUSTOM_MAX_LEN); |
| 832 | |
| 833 | pBufPtr = pBuf; |
| 834 | |
| 835 | if (pAddr) |
| 836 | pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr)); |
| 837 | else if (BssIdx < MAX_MBSSID_NUM) |
| 838 | pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx); |
| 839 | else |
| 840 | pBufPtr += sprintf(pBufPtr, "(RT2860) "); |
| 841 | |
| 842 | if (type == IW_SYS_EVENT_FLAG_START) |
| 843 | pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]); |
| 844 | else if (type == IW_SPOOF_EVENT_FLAG_START) |
| 845 | pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi); |
| 846 | else if (type == IW_FLOOD_EVENT_FLAG_START) |
| 847 | pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]); |
| 848 | else |
| 849 | pBufPtr += sprintf(pBufPtr, "%s", "unknown event"); |
| 850 | |
| 851 | pBufPtr[pBufPtr - pBuf] = '\0'; |
| 852 | BufLen = pBufPtr - pBuf; |
| 853 | |
| 854 | memset(&wrqu, 0, sizeof(wrqu)); |
| 855 | wrqu.data.flags = Event_flag; |
| 856 | wrqu.data.length = BufLen; |
| 857 | |
| 858 | //send wireless event |
| 859 | wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf); |
| 860 | |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 861 | //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 862 | |
| 863 | kfree(pBuf); |
| 864 | } |
| 865 | else |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 866 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 867 | #else |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 868 | DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 869 | #endif /* WIRELESS_EXT >= 15 */ |
| 870 | } |
| 871 | |
| 872 | |
| 873 | #ifdef CONFIG_STA_SUPPORT |
| 874 | void send_monitor_packets( |
| 875 | IN PRTMP_ADAPTER pAd, |
| 876 | IN RX_BLK *pRxBlk) |
| 877 | { |
| 878 | struct sk_buff *pOSPkt; |
| 879 | wlan_ng_prism2_header *ph; |
| 880 | int rate_index = 0; |
| 881 | USHORT header_len = 0; |
| 882 | UCHAR temp_header[40] = {0}; |
| 883 | |
| 884 | 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 |
| 885 | 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, |
| 886 | 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}; |
| 887 | |
| 888 | |
| 889 | ASSERT(pRxBlk->pRxPacket); |
| 890 | if (pRxBlk->DataSize < 10) |
| 891 | { |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 892 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 893 | goto err_free_sk_buff; |
| 894 | } |
| 895 | |
| 896 | if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) |
| 897 | { |
Randy Dunlap | f4b44e7 | 2009-02-11 13:18:22 -0800 | [diff] [blame] | 898 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 899 | goto err_free_sk_buff; |
| 900 | } |
| 901 | |
| 902 | pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); |
| 903 | pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0); |
| 904 | if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) |
| 905 | { |
| 906 | pRxBlk->DataSize -= LENGTH_802_11; |
| 907 | if ((pRxBlk->pHeader->FC.ToDs == 1) && |
| 908 | (pRxBlk->pHeader->FC.FrDs == 1)) |
| 909 | header_len = LENGTH_802_11_WITH_ADDR4; |
| 910 | else |
| 911 | header_len = LENGTH_802_11; |
| 912 | |
| 913 | // QOS |
| 914 | if (pRxBlk->pHeader->FC.SubType & 0x08) |
| 915 | { |
| 916 | header_len += 2; |
| 917 | // Data skip QOS contorl field |
| 918 | pRxBlk->DataSize -=2; |
| 919 | } |
| 920 | |
| 921 | // Order bit: A-Ralink or HTC+ |
| 922 | if (pRxBlk->pHeader->FC.Order) |
| 923 | { |
| 924 | header_len += 4; |
| 925 | // Data skip HTC contorl field |
| 926 | pRxBlk->DataSize -= 4; |
| 927 | } |
| 928 | |
| 929 | // Copy Header |
| 930 | if (header_len <= 40) |
| 931 | NdisMoveMemory(temp_header, pRxBlk->pData, header_len); |
| 932 | |
| 933 | // skip HW padding |
| 934 | if (pRxBlk->RxD.L2PAD) |
| 935 | pRxBlk->pData += (header_len + 2); |
| 936 | else |
| 937 | pRxBlk->pData += header_len; |
| 938 | } //end if |
| 939 | |
| 940 | |
| 941 | if (pRxBlk->DataSize < pOSPkt->len) { |
| 942 | skb_trim(pOSPkt,pRxBlk->DataSize); |
| 943 | } else { |
| 944 | skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len)); |
| 945 | } //end if |
| 946 | |
| 947 | if ((pRxBlk->pData - pOSPkt->data) > 0) { |
| 948 | skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data)); |
| 949 | skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data)); |
| 950 | } //end if |
| 951 | |
| 952 | if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) { |
| 953 | if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) { |
Harvey Harrison | d599edc | 2009-01-07 14:31:57 -0800 | [diff] [blame] | 954 | DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__)); |
Greg Kroah-Hartman | c55519f | 2008-12-17 17:04:23 -0800 | [diff] [blame] | 955 | goto err_free_sk_buff; |
| 956 | } //end if |
| 957 | } //end if |
| 958 | |
| 959 | if (header_len > 0) |
| 960 | NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len); |
| 961 | |
| 962 | ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header)); |
| 963 | NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header)); |
| 964 | |
| 965 | ph->msgcode = DIDmsg_lnxind_wlansniffrm; |
| 966 | ph->msglen = sizeof(wlan_ng_prism2_header); |
| 967 | strcpy(ph->devname, pAd->net_dev->name); |
| 968 | |
| 969 | ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; |
| 970 | ph->hosttime.status = 0; |
| 971 | ph->hosttime.len = 4; |
| 972 | ph->hosttime.data = jiffies; |
| 973 | |
| 974 | ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; |
| 975 | ph->mactime.status = 0; |
| 976 | ph->mactime.len = 0; |
| 977 | ph->mactime.data = 0; |
| 978 | |
| 979 | ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx; |
| 980 | ph->istx.status = 0; |
| 981 | ph->istx.len = 0; |
| 982 | ph->istx.data = 0; |
| 983 | |
| 984 | ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel; |
| 985 | ph->channel.status = 0; |
| 986 | ph->channel.len = 4; |
| 987 | |
| 988 | ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel; |
| 989 | |
| 990 | ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; |
| 991 | ph->rssi.status = 0; |
| 992 | ph->rssi.len = 4; |
| 993 | 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));; |
| 994 | |
| 995 | ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; |
| 996 | ph->signal.status = 0; |
| 997 | ph->signal.len = 4; |
| 998 | ph->signal.data = 0; //rssi + noise; |
| 999 | |
| 1000 | ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; |
| 1001 | ph->noise.status = 0; |
| 1002 | ph->noise.len = 4; |
| 1003 | ph->noise.data = 0; |
| 1004 | |
| 1005 | #ifdef DOT11_N_SUPPORT |
| 1006 | if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) |
| 1007 | { |
| 1008 | rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS); |
| 1009 | } |
| 1010 | else |
| 1011 | #endif // DOT11_N_SUPPORT // |
| 1012 | if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM) |
| 1013 | rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4; |
| 1014 | else |
| 1015 | rate_index = (UCHAR)(pRxBlk->pRxWI->MCS); |
| 1016 | if (rate_index < 0) |
| 1017 | rate_index = 0; |
| 1018 | if (rate_index > 255) |
| 1019 | rate_index = 255; |
| 1020 | |
| 1021 | ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; |
| 1022 | ph->rate.status = 0; |
| 1023 | ph->rate.len = 4; |
| 1024 | ph->rate.data = ralinkrate[rate_index]; |
| 1025 | |
| 1026 | ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; |
| 1027 | ph->frmlen.status = 0; |
| 1028 | ph->frmlen.len = 4; |
| 1029 | ph->frmlen.data = (u_int32_t)pRxBlk->DataSize; |
| 1030 | |
| 1031 | |
| 1032 | pOSPkt->pkt_type = PACKET_OTHERHOST; |
| 1033 | pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev); |
| 1034 | pOSPkt->ip_summed = CHECKSUM_NONE; |
| 1035 | netif_rx(pOSPkt); |
| 1036 | |
| 1037 | return; |
| 1038 | |
| 1039 | err_free_sk_buff: |
| 1040 | RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); |
| 1041 | return; |
| 1042 | |
| 1043 | } |
| 1044 | #endif // CONFIG_STA_SUPPORT // |
| 1045 | |
| 1046 | |
| 1047 | void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify) |
| 1048 | { |
| 1049 | |
| 1050 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) |
| 1051 | daemonize(pThreadName /*"%s",pAd->net_dev->name*/); |
| 1052 | |
| 1053 | allow_signal(SIGTERM); |
| 1054 | allow_signal(SIGKILL); |
| 1055 | current->flags |= PF_NOFREEZE; |
| 1056 | #else |
| 1057 | unsigned long flags; |
| 1058 | |
| 1059 | daemonize(); |
| 1060 | reparent_to_init(); |
| 1061 | strcpy(current->comm, pThreadName); |
| 1062 | |
| 1063 | siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); |
| 1064 | |
| 1065 | /* Allow interception of SIGKILL only |
| 1066 | * Don't allow other signals to interrupt the transmission */ |
| 1067 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) |
| 1068 | spin_lock_irqsave(¤t->sigmask_lock, flags); |
| 1069 | flush_signals(current); |
| 1070 | recalc_sigpending(current); |
| 1071 | spin_unlock_irqrestore(¤t->sigmask_lock, flags); |
| 1072 | #endif |
| 1073 | #endif |
| 1074 | |
| 1075 | /* signal that we've started the thread */ |
| 1076 | complete(pNotify); |
| 1077 | |
| 1078 | } |
| 1079 | |
| 1080 | void RTMP_IndicateMediaState( |
| 1081 | IN PRTMP_ADAPTER pAd) |
| 1082 | { |
| 1083 | if (pAd->CommonCfg.bWirelessEvent) |
| 1084 | { |
| 1085 | if (pAd->IndicateMediaState == NdisMediaStateConnected) |
| 1086 | { |
| 1087 | RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); |
| 1088 | } |
| 1089 | else |
| 1090 | { |
| 1091 | RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); |
| 1092 | } |
| 1093 | } |
| 1094 | } |
| 1095 | |