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