1 /**************************************************************************** 2 **+-----------------------------------------------------------------------+** 3 **| |** 4 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |** 5 **| All rights reserved. |** 6 **| |** 7 **| Redistribution and use in source and binary forms, with or without |** 8 **| modification, are permitted provided that the following conditions |** 9 **| are met: |** 10 **| |** 11 **| * Redistributions of source code must retain the above copyright |** 12 **| notice, this list of conditions and the following disclaimer. |** 13 **| * Redistributions in binary form must reproduce the above copyright |** 14 **| notice, this list of conditions and the following disclaimer in |** 15 **| the documentation and/or other materials provided with the |** 16 **| distribution. |** 17 **| * Neither the name Texas Instruments nor the names of its |** 18 **| contributors may be used to endorse or promote products derived |** 19 **| from this software without specific prior written permission. |** 20 **| |** 21 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |** 22 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |** 23 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |** 24 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |** 25 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |** 26 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |** 27 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |** 28 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |** 29 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |** 30 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |** 31 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |** 32 **| |** 33 **+-----------------------------------------------------------------------+** 34 ****************************************************************************/ 35 36 #include <linux/module.h> 37 #include <linux/kernel.h> 38 #include <linux/version.h> 39 #include <net/sock.h> 40 #include <linux/init.h> 41 #include <linux/fs.h> 42 #include <linux/netdevice.h> 43 #include <linux/ioctl.h> 44 #include <linux/wireless.h> 45 #include <linux/etherdevice.h> 46 #include <linux/netlink.h> 47 #include <linux/completion.h> 48 49 #ifdef TIWLAN_CARDBUS 50 #include <linux/pci.h> 51 #else 52 #ifdef TIWLAN_OMAP1610 53 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 54 #include <asm/arch-omap/tc.h> 55 #else 56 #include <mach/tc.h> 57 #endif 58 #endif 59 #ifdef TIWLAN_MSM7000 60 #include <linux/mmc/core.h> 61 #include <linux/mmc/card.h> 62 #include <linux/mmc/sdio_func.h> 63 #include <linux/mmc/sdio_ids.h> 64 #endif 65 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 66 #include <asm/arch/io.h> 67 #include <asm/arch/hardware.h> 68 #include <asm/arch/irqs.h> 69 #else 70 #include <mach/io.h> 71 #include <mach/hardware.h> 72 #include <mach/irqs.h> 73 #endif 74 #endif /* !TIWLAN_CARDBUS */ 75 76 #include <linux/list.h> 77 #include <linux/spinlock.h> 78 #include <linux/if_arp.h> 79 #include <linux/proc_fs.h> 80 #include <linux/mm.h> 81 #include <linux/delay.h> 82 #include <linux/vmalloc.h> 83 #include <linux/irq.h> 84 85 #include <asm/io.h> 86 #include <asm/uaccess.h> 87 #include <asm/pgtable.h> 88 89 #include "esta_drv.h" 90 #include "srcApi.h" 91 #include "osApi.h" 92 #include "whalHwRegs.h" 93 94 #if defined(DEBUG_UNKNOWN_INTERRUPT) 95 #define _STRING_H 96 #include "configMgr.h" 97 #include "whalCtrl.h" 98 #endif 99 100 #include "bmtrace.h" 101 #include "osrgstry_parser.h" 102 #include "osClsfr.h" 103 #include "TI_IPC_Api.h" 104 #include "802_11Defs.h" 105 #include "Ethernet.h" 106 #include "tiwlan_profile.h" 107 108 #if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK) 109 #define RX_RATE_INTERVAL_SEC 10 110 unsigned long num_rx_pkt_new = 0; 111 static unsigned long num_rx_pkt_last = 0; 112 #endif 113 114 #ifdef TIWLAN_MSM7000 115 extern unsigned char *get_wifi_nvs_ram(void); 116 extern void SDIO_SetFunc( struct sdio_func * ); 117 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)) 118 static struct proc_dir_entry *tiwlan_calibration; 119 #endif 120 static struct completion sdio_wait; 121 #ifdef CONFIG_WIFI_CONTROL_FUNC 122 static struct wifi_platform_data *wifi_control_data = NULL; 123 #endif 124 #endif 125 126 /* WiFi chip information functions */ 127 int export_wifi_fw_version( tiwlan_net_dev_t *drv ); 128 int export_wifi_chip_id( void ); 129 130 /* Drivers list */ 131 static LIST_HEAD(tiwlan_drv_list); 132 133 /* debug memory access */ 134 static struct proc_dir_entry *tiwlan_deb_entry; 135 static __u32 memdebug_addr; 136 static __u32 memdebug_size=1; 137 static __u32 memdebug_trans_size; 138 139 #define DRV_SHUTDOWN_TEST_DELAY_INTERVAL 100 /* Time in msec to "delay"(/sleep) while waiting for SME to shutdown */ 140 #define DRV_SHUTDOWN_TEST_MAX_COUNTER 20 /* How many delay/sleep iterations to perform while waiting for SME to shutdown) */ 141 142 MODULE_DESCRIPTION("TI WLAN Embedded Station Driver"); 143 MODULE_LICENSE("GPL"); 144 145 extern int packed_struct_tst(void); 146 extern int proc_stat_init(TI_HANDLE); 147 extern int proc_stat_destroy(void); 148 149 typedef void (* tiwlan_drv_isr_t)(int, void *, struct pt_regs *); 150 151 /* network device driver interface */ 152 static int tiwlan_drv_net_open(struct net_device * dev); 153 static int tiwlan_drv_net_stop(struct net_device * dev); 154 static int tiwlan_drv_net_xmit(struct sk_buff * skb, struct net_device * dev); 155 static int tiwlan_drv_dummy_net_xmit(struct sk_buff * skb, struct net_device * dev); 156 static struct net_device_stats * tiwlan_drv_net_get_stats(struct net_device * dev); 157 int ti1610_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 158 159 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) 160 static struct net_device_ops tiwlan_ops_pri = { 161 .ndo_open = tiwlan_drv_net_open, 162 .ndo_stop = tiwlan_drv_net_stop, 163 .ndo_get_stats = tiwlan_drv_net_get_stats, 164 .ndo_do_ioctl = ti1610_do_ioctl, 165 .ndo_start_xmit = tiwlan_drv_net_xmit, 166 }; 167 168 static struct net_device_ops tiwlan_ops_dummy = { 169 .ndo_open = tiwlan_drv_net_open, 170 .ndo_stop = tiwlan_drv_net_stop, 171 .ndo_get_stats = tiwlan_drv_net_get_stats, 172 .ndo_do_ioctl = ti1610_do_ioctl, 173 .ndo_start_xmit = tiwlan_drv_dummy_net_xmit, 174 }; 175 #endif 176 177 #define OS_WRITE_REG(drv,reg,val) \ 178 os_hwWriteMemRegisterUINT32(drv, (UINT32 *)((unsigned long)drv->acx_reg.va + reg), (__u32)(val)) 179 180 #define OS_READ_REG(drv,reg,val) \ 181 os_hwReadMemRegisterUINT32(drv, (UINT32 *)((unsigned long)drv->acx_reg.va + reg), &val) 182 183 #ifdef TIWLAN_OMAP1610 184 static void omap_memif_init(void) 185 { 186 printk ("First function offset is: %p\n", omap_memif_init); 187 #if defined(TIWLAN_OMAP1610_INNOVATOR) 188 print_info("Setting CS1 Ref Clock = TC/4. \n"); 189 omap_writel(0x00000004, 0xFFFECC40 ); /* wlan change for cs2 to dynamic wait state */ 190 omap_writel(0x0000113a, 0xFFFECC18 ); /* EMIFS (nCS2) configuration */ 191 #elif defined(TIWLAN_OMAP1610_WIPP) || defined(TIWLAN_OMAP1610_CRTWIPP) 192 193 #if defined(TIWLAN_OMAP1610_CRTWIPP) 194 /* 195 Init the GPIO to output*/ 196 197 /* Set OMAP pin H19 to GPIO57*/ 198 199 omap_writel(omap_readl(0xFFFE1014) | 0x00E00000, 0xFFFE1014 ); 200 201 /*ELP_REQ (GPIO_57) by GPIO_DIRECTION - set it as output*/ 202 omap_writel(omap_readl(0xFFFBBC34) & (~0x00000200), 0xFFFBBC34 ); 203 #endif /* TIWLAN_OMAP1610_CRTWIPP */ 204 205 /* The below configuration enables GPIO25 and GPIO_27 as output GPIOs - for debug purposes */ 206 #if defined(TIWLAN_OMAP1610_CRTWIPP_GPIO_DEBUG) 207 208 omap_writel(omap_readl(0xFFFE1030) | 0x00000E00, 0xFFFE1030 );/* enable GPIO25 */ 209 omap_writel(omap_readl(0xFFFE1030) | 0x00000038, 0xFFFE1030 );/* enable GPIO27 */ 210 211 omap_writel(omap_readl(0xFFFBEC34) & (~0x00000200), 0xFFFBEC34 );/* Setting direction (as output) for GPIO25 */ 212 omap_writel(omap_readl(0xFFFBEC34) & (~0x00000800), 0xFFFBEC34 );/* Setting direction (as output) for GPIO27 */ 213 #endif /* TIWLAN_OMAP1610_CRTWIPP_GPIO_DEBUG */ 214 215 216 /* RECOVERY*/ 217 print_info("Hard reset,perform PMEN toggle\n"); 218 os_hardResetTnetw(); 219 220 print_info("Setting CS2 Ref Clock = TC/2. \n"); 221 __raw_writel(0x1, TIWLAN_OMAP1610_REGBASE+0x4cc); /* CLK=80MHz */ 222 omap_writel(0x20, EMIF_CFG_DYNAMIC_WS); /* Full handshake on CS2 */ 223 omap_writel(0x2441, EMIFS_CS2_CONFIG); /* 0x2021 on reworked board */ 224 omap_writel(0, EMIFS_ACS2); 225 226 print_info("%x=0x%lx\n", 0xFFFECC40, omap_readl(0xFFFECC40) ); 227 print_info("%x=0x%lx\n", 0xFFFECC18, omap_readl(0xFFFECC18) ); 228 print_info("%x=0x%lx\n", 0xFFFECC58, omap_readl(0xFFFECC58) ); 229 #endif /* WIPP, CRTWIPP */ 230 } 231 #endif 232 233 static int tiwlan_register_events(tiwlan_net_dev_t *drv) 234 { 235 IPC_EVENT_PARAMS evParams; 236 int i = 0; 237 238 evParams.uDeliveryType = DELIVERY_PUSH; 239 evParams.uProcessID = 0; 240 evParams.uEventID = 0; 241 evParams.hUserParam = drv; 242 evParams.pfEventCallback = os_IndicateEvent; 243 244 245 for (;i < IPC_EVENT_MAX_OS_EVENT;i++) 246 { 247 evParams.uEventType = i; 248 249 configMgr_RegisterEvent(drv->adapter.CoreHalCtx,(PUCHAR) &evParams,sizeof(IPC_EVENT_PARAMS)); 250 } 251 252 return OK; 253 } 254 255 static int tiwlan_deb_read_proc(char *page, char **start, off_t off, 256 int count, int *eof, void *data) 257 { 258 __u32 addr=memdebug_addr; 259 __u32 size=memdebug_size; 260 __u32 trans_size=memdebug_trans_size; 261 __u32 end; 262 int in_line=0, max_in_line; 263 int limit=count-80; 264 int i=0; 265 static int toggle; 266 267 *eof = 1; 268 if (!addr || !trans_size) 269 return 0; 270 271 /* fixme: add address validation */ 272 273 if (!size) 274 size=1; 275 276 end = addr + size*trans_size; 277 if (trans_size==4) 278 max_in_line = 4; 279 else if (trans_size==2) 280 max_in_line = 8; 281 else 282 max_in_line = 16; 283 284 while(i<limit && addr<end) 285 { 286 if (!in_line) 287 i += sprintf(page+i, "0x%08x: ", addr); 288 if (trans_size==4) 289 { 290 i += sprintf(page+i, "0x%08x", *(__u32 *)addr); 291 addr += 4; 292 } 293 else if (trans_size==2) 294 { 295 i += sprintf(page+i, "0x%04x", *(__u16 *)addr); 296 addr += 2; 297 } 298 else 299 { 300 i += sprintf(page+i, "0x%02x", *(__u8 *)addr); 301 addr += 1; 302 } 303 if (++in_line < max_in_line) 304 *(page+i++)=' '; 305 else 306 { 307 *(page+i++)='\n'; 308 in_line = 0; 309 } 310 } 311 *(page+i++)='\n'; 312 /* For some reason read proc is get called twice for 313 each "cat" operation 314 */ 315 if (toggle) 316 memdebug_addr = addr; 317 toggle = !toggle; 318 319 return i; 320 } 321 322 static char *rm_get_token(const char **p_buffer, unsigned long *p_buffer_len, 323 char *token, unsigned long token_len, 324 char del) 325 { 326 const char *buffer=*p_buffer; 327 __u32 buffer_len = *p_buffer_len; 328 329 while(buffer_len && token_len && *buffer!=del && *buffer) 330 { 331 *token++ = *buffer++; 332 --buffer_len; 333 --token_len; 334 } 335 while (buffer_len && *buffer==del) 336 { 337 ++buffer; 338 --buffer_len; 339 } 340 *token = 0; 341 *p_buffer = buffer; 342 *p_buffer_len = buffer_len; 343 return token; 344 } 345 346 static int tiwlan_deb_write_proc(struct file *file, const char *buffer, 347 unsigned long count, void *data) 348 { 349 __u32 addr, size; 350 char token[15]; 351 __u32 value; 352 char *end; 353 int buflen=count; 354 355 /* buffer format is: 356 d{w,h,b} addr[/size] 357 s{w,h,b} addr=value 358 */ 359 /* Parse string */ 360 rm_get_token(&buffer, &count, token, sizeof(token)-1, ' '); 361 if (token[0]=='d') 362 { 363 /* Display */ 364 if (!strcmp(token, "dw")) 365 memdebug_trans_size = 4; 366 else if (!strcmp(token, "dh")) 367 memdebug_trans_size = 2; 368 else if (!strcmp(token, "db")) 369 memdebug_trans_size = 1; 370 else 371 { 372 printk(KERN_INFO "rm: mem file write op is dw|dh|db|sw|sh|sb\n"); 373 return buflen; 374 } 375 /* Get address */ 376 rm_get_token(&buffer, &count, token, sizeof(token)-1, '/'); 377 addr = simple_strtoul(token, &end, 0); 378 if ((end && *end) /* || !iopa(addr)*/) 379 { 380 printk(KERN_INFO "rm: address <%s> is invalid\n", token); 381 return buflen; 382 } 383 if ((addr & (memdebug_trans_size-1))) 384 { 385 printk(KERN_INFO "rm: warning: address 0x%x is not aligned to size %u\n", 386 addr, memdebug_trans_size); 387 } 388 memdebug_addr = addr; 389 if (count) 390 { 391 /* Get size */ 392 rm_get_token(&buffer, &count, token, sizeof(token)-1, ' '); 393 size = simple_strtoul(token, &end, 0); 394 if (end && *end) 395 { 396 printk(KERN_INFO "rm: size <%s> is invalid. end=<%s>\n", 397 token, end); 398 return buflen; 399 } 400 memdebug_size = size; 401 } 402 return buflen; 403 } 404 if (token[0]=='s') 405 { 406 /* Display */ 407 if (!strcmp(token, "sw")) 408 size = 4; 409 else if (!strcmp(token, "sh")) 410 size = 2; 411 else if (!strcmp(token, "sb")) 412 size = 1; 413 else 414 { 415 printk(KERN_INFO "rm: mem file write op is dw|dh|db|sw|sh|sb\n"); 416 return buflen; 417 } 418 /* Get address */ 419 rm_get_token(&buffer, &count, token, sizeof(token)-1, ' '); 420 addr = simple_strtoul(token, &end, 0); 421 if ((end && *end) /*|| !iopa(addr)*/) 422 { 423 printk(KERN_INFO "rm: address <%s> is invalid\n", token); 424 return buflen; 425 } 426 if ((addr & (size-1))) 427 { 428 printk(KERN_INFO "rm: warning: address 0x%x is not aligned to size %u\n", 429 addr, size); 430 } 431 432 /* Get value */ 433 rm_get_token(&buffer, &count, token, sizeof(token)-1, ' '); 434 value = simple_strtoul(token, &end, 0); 435 if (end && *end) 436 { 437 printk(KERN_INFO "rm: value <%s> is invalid. end <%s>\n", 438 token, end); 439 return buflen; 440 } 441 if (size==4) 442 *(__u32 *)addr = value; 443 else if (size==2) 444 { 445 if (value > 0xffff) 446 { 447 printk(KERN_INFO "rm: value <%s> is out of range\n", token); 448 return buflen; 449 } 450 *(__u16 *)addr = value; 451 } 452 else 453 { 454 if (value > 0xff) 455 { 456 printk(KERN_INFO "rm: value <%s> is out of range\n", token); 457 return buflen; 458 } 459 *(__u8 *)addr = value; 460 } 461 memdebug_addr = addr; 462 memdebug_size = 1; 463 memdebug_trans_size = size; 464 } 465 else 466 printk(KERN_INFO "rm: operation <%s> is not supported\n", token); 467 return buflen; 468 } 469 470 #ifdef TIWLAN_MSM7000 471 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)) 472 #define WIFI_NVS_LEN_OFFSET 0x0C 473 #define WIFI_NVS_DATA_OFFSET 0x40 474 #define WIFI_NVS_MAX_SIZE 0x800UL 475 476 static unsigned long tiwlan_get_nvs_size( void ) 477 { 478 unsigned char *ptr; 479 unsigned long len; 480 481 ptr = get_wifi_nvs_ram(); 482 if( ptr == NULL ) { 483 return 0; 484 } 485 /* Size in format LE assumed */ 486 memcpy( (void *)&len, (void *)(ptr + WIFI_NVS_LEN_OFFSET), sizeof(len) ); 487 len = min( len, (WIFI_NVS_MAX_SIZE-WIFI_NVS_DATA_OFFSET) ); 488 return len; 489 } 490 491 static int tiwlan_calibration_read_proc(char *page, char **start, off_t off, 492 int count, int *eof, void *data) 493 { 494 unsigned char *ptr; 495 unsigned long len; 496 497 ptr = get_wifi_nvs_ram(); 498 if( ptr == NULL ) { 499 return 0; 500 } 501 len = tiwlan_get_nvs_size(); 502 /* i += sprintf(page+i, "WiFi Calibration Size = %lu %x bytes\n", len); */ 503 memcpy( (void *)page, (void *)(ptr + WIFI_NVS_DATA_OFFSET), len ); 504 return len; 505 } 506 507 static int tiwlan_calibration_write_proc(struct file *file, const char *buffer, 508 unsigned long count, void *data) 509 { 510 return 0; 511 } 512 #endif 513 #endif 514 515 /*********************************************************************************************/ 516 /* Impelementation */ 517 /*********************************************************************************************/ 518 519 static int tiwlan_drv_net_open(struct net_device * dev) 520 { 521 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev); 522 523 ti_nodprintf(TIWLAN_LOG_INFO, "tiwlan_drv_net_open()\n"); 524 525 if (!drv->adapter.CoreHalCtx) 526 return -ENODEV; 527 528 netif_start_queue(dev); 529 530 return 0; 531 } 532 533 534 static int tiwlan_drv_net_stop(struct net_device * dev) 535 { 536 ti_nodprintf(TIWLAN_LOG_ERROR, "tiwlan_drv_net_stop()\n"); 537 538 netif_stop_queue(dev); 539 540 return 0; 541 } 542 543 544 /* dummy send packet from Linux TCP/IP stack to WLAN 545 Used when driver is not initialized 546 */ 547 static int tiwlan_drv_dummy_net_xmit(struct sk_buff *skb, struct net_device *dev) 548 { 549 /* Network stack takes care of deallocation */ 550 return -ENODEV; 551 } 552 553 void sendFreeFunc(TI_HANDLE pSkb, TI_HANDLE dummy1, TI_STATUS status) 554 { 555 struct sk_buff *skb = (struct sk_buff *) pSkb; 556 557 /* print_deb("^^^ free %p %d bytes (%s)\n", skb->data, skb->len, (status==OK) ? "OK" : "ERROR" ); */ 558 dev_kfree_skb(skb); 559 } 560 561 #ifdef DM_USE_WORKQUEUE 562 void tiwlan_add_msdu(tiwlan_net_dev_t *drv, mem_MSDU_T *pMsdu) 563 { 564 if( pMsdu == NULL ) 565 return; 566 pMsdu->msdu_next = NULL; 567 if( drv->txmit_msdu_next != NULL ) { 568 drv->txmit_msdu_last->msdu_next = pMsdu; 569 } 570 else { 571 drv->txmit_msdu_next = pMsdu; 572 } 573 drv->txmit_msdu_last = pMsdu; 574 } 575 576 mem_MSDU_T *tiwlan_del_msdu(tiwlan_net_dev_t *drv) 577 { 578 mem_MSDU_T *pMsdu = NULL; 579 580 if( drv->txmit_msdu_next != NULL ) { 581 pMsdu = drv->txmit_msdu_next; 582 drv->txmit_msdu_next = pMsdu->msdu_next; 583 if( drv->txmit_msdu_next == NULL ) { /* Last MSDU */ 584 drv->txmit_msdu_last = NULL; 585 } 586 } 587 return( pMsdu ); 588 } 589 590 static void tiwlan_xmit_handler( struct work_struct *work ) 591 { 592 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( work, struct tiwlan_net_dev, txmit ); 593 mem_MSDU_T *pMsdu; 594 unsigned long flags; 595 596 #ifdef CONFIG_ANDROID_POWER 597 android_lock_suspend( &drv->exec_wake_lock ); 598 android_unlock_suspend( &drv->xmit_wake_lock ); 599 #endif 600 /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */ 601 do { 602 spin_lock_irqsave(&drv->lock, flags); 603 pMsdu = tiwlan_del_msdu(drv); 604 spin_unlock_irqrestore(&drv->lock, flags); 605 if( pMsdu ) { 606 configMgr_sendMsdu(drv->adapter.CoreHalCtx, pMsdu, 0); 607 } 608 } while( pMsdu != NULL ); 609 #ifdef CONFIG_ANDROID_POWER 610 android_unlock_suspend( &drv->exec_wake_lock ); 611 #endif 612 } 613 #endif 614 615 /* send packet from Linux TCP/IP stack to WLAN 616 */ 617 static int tiwlan_drv_net_xmit(struct sk_buff *skb, struct net_device *dev) 618 { 619 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev); 620 int status; 621 mem_MSDU_T *pMsdu; 622 UINT32 packetHeaderLength; 623 624 #ifndef NO_COPY_SKB 625 char *pMsduData; 626 #else 627 mem_BD_T *pCurBd=0; 628 #endif 629 630 #ifdef DRIVER_PROFILE 631 os_profile (drv, 0, 0); 632 #endif 633 bm_trace(20, skb->len, 0); 634 635 #ifdef NO_COPY_SKB 636 637 status = configMgr_allocMSDUBufferOnly(drv->adapter.CoreHalCtx, &pMsdu, OS_ABS_TX_MODULE); 638 if(status != OK) 639 { 640 ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocMSDUBufferOnly failed !!!\n"); 641 ++drv->alloc_msdu_failures; 642 return -ENOMEM; 643 } 644 /* print_deb("$$$ configMgr_allocMSDUBufferOnly()=OK pMsdu=%p\n", pMsdu ); */ 645 646 status = configMgr_allocBDs(drv->adapter.CoreHalCtx, 1, &pCurBd); 647 648 if(status != OK) { 649 ++drv->alloc_msdu_failures; 650 ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocBDs failed !!!\n"); 651 configMgr_memMngrFreeMSDU(drv->adapter.CoreHalCtx, pMsdu->handle); 652 return -ENOMEM; 653 } 654 /* print_deb("$$$ configMgr_allocBDs()=OK pCurBd=%p first=%p\n", pCurBd, pMsdu->firstBDPtr ); */ 655 656 pMsdu->freeFunc = sendFreeFunc; 657 pMsdu->freeArgs[0] = (UINT32) skb; 658 pMsdu->dataLen = skb->len; 659 pMsdu->firstBDPtr = pCurBd; 660 pCurBd->dataOffset = skb->data-skb->head; 661 pCurBd->length = skb->len; 662 pCurBd->data = skb->head; 663 664 drv->stats.tx_packets++; 665 drv->stats.tx_bytes += skb->len; 666 667 #else /* NO_COPY_SKB */ 668 669 /* 670 * Retrieve the Packet Header length 671 * from QoS Manager (through configMgr) 672 * (Header type is determined upon association) 673 */ 674 packetHeaderLength = configMgr_getPacketHeaderLength(drv->adapter.CoreHalCtx,skb->data,TX_DATA_DATA_MSDU); 675 676 /* 677 * need to reserve enough space for header translation 678 * in the same first Bd. 679 * Allocate enough place also for 802.11 header (24 bytes or 26 for QoS) and LLC (8 bytes) 680 * to replace the Ethernet header (14 bytes) 681 */ 682 status = configMgr_allocMSDU(drv->adapter.CoreHalCtx, &pMsdu, 683 skb->len + packetHeaderLength, OS_ABS_TX_MODULE); 684 685 if(status != OK) 686 { 687 /*ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocMSDU failed !!!\n");*/ 688 ++drv->alloc_msdu_failures; 689 return -ENOMEM; 690 } 691 692 /* 693 * case 1: only legacy wlan header 694 * 695 * case 2: only QoS wlan header 696 * 697 * case 3: only legacy wlan header with new snap 698 * 699 * case 4: only QoS wlan header with new snap 700 */ 701 pMsdu->firstBDPtr->dataOffset = packetHeaderLength - ETHERNET_HDR_LEN; 702 pMsduData = pMsdu->firstBDPtr->data + pMsdu->firstBDPtr->dataOffset; 703 memcpy(pMsduData, skb->data, skb->len); 704 pMsdu->dataLen = skb->len; 705 pMsdu->firstBDPtr->length = pMsdu->dataLen + pMsdu->firstBDPtr->dataOffset; 706 707 drv->stats.tx_packets++; 708 drv->stats.tx_bytes += skb->len; 709 dev_kfree_skb(skb); 710 #endif /* NO_COPY_SKB */ 711 712 pMsdu->txFlags |= TX_DATA_FROM_OS; 713 pMsdu->qosTag = 0; 714 status = OK; 715 716 #ifdef TI_DBG 717 /* Set packet-os-in time stamp */ 718 /* TODO: the skb time stamp is not good */ 719 /* printk ("\n### sec=%u, usec=%u", skb->stamp.tv_sec, skb->stamp.tv_usec);*/ 720 /* pMsdu->timeStamp[0] = skb->stamp.tv_sec * 1000000 + skb->stamp.tv_usec; */ 721 /* pMsdu->timeStampNum = 1; */ 722 #endif 723 724 bm_trace(21, 0, 0); 725 /* 726 * Propagate Msdu through Config Manager. 727 * Set DTag to zero 728 * (note that classification is further handled in the Core) 729 */ 730 if (status == OK) { 731 #ifdef DM_USE_WORKQUEUE 732 unsigned long flags; 733 734 spin_lock_irqsave(&drv->lock, flags); 735 tiwlan_add_msdu(drv, pMsdu); 736 spin_unlock_irqrestore(&drv->lock, flags); 737 /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */ 738 #ifdef CONFIG_ANDROID_POWER 739 android_lock_suspend( &drv->xmit_wake_lock ); 740 #endif 741 queue_work( drv->tiwlan_wq, &drv->txmit ); 742 #else 743 status = configMgr_sendMsdu(drv->adapter.CoreHalCtx, pMsdu, 0); 744 #endif 745 } 746 else 747 configMgr_memMngrFreeMSDU (drv->adapter.CoreHalCtx, (UINT32) pMsdu); /* If status != OK , we won't send the MSDU, so we need to free it */ 748 749 if(unlikely(status != OK)) 750 { 751 drv->stats.tx_errors++; 752 #ifdef NO_COPY_SKB 753 dev_kfree_skb(skb); 754 #endif 755 } 756 757 bm_trace(22, 0, 0); 758 #ifdef DRIVER_PROFILE 759 os_profile (drv, 1, 0); 760 #endif 761 762 return 0; 763 } 764 765 struct net_device_stats * tiwlan_drv_net_get_stats(struct net_device * dev) 766 { 767 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev); 768 ti_dprintf(TIWLAN_LOG_OTHER, "tiwlan_drv_net_get_stats()\n"); 769 770 return &drv->stats; 771 } 772 773 774 static int setup_netif(tiwlan_net_dev_t *drv) 775 { 776 struct net_device *dev; 777 int res; 778 779 dev = alloc_etherdev(0); 780 if (dev == NULL) 781 { 782 ti_dprintf(TIWLAN_LOG_ERROR, "alloc_etherdev() failed\n"); 783 return -ENOMEM; 784 } 785 ether_setup(dev); 786 NETDEV_SET_PRIVATE(dev, drv); 787 drv->netdev = dev; 788 strcpy(dev->name, TIWLAN_DRV_IF_NAME); 789 netif_carrier_off(dev); 790 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) 791 dev->open = tiwlan_drv_net_open; 792 dev->stop = tiwlan_drv_net_stop; 793 dev->hard_start_xmit = tiwlan_drv_dummy_net_xmit; 794 dev->get_stats = tiwlan_drv_net_get_stats; 795 #else 796 dev->netdev_ops = &tiwlan_ops_dummy; 797 #endif 798 dev->tx_queue_len = 100; 799 800 res = tiwlan_ioctl_init(dev); 801 if( res < 0 ) 802 { 803 ti_dprintf(TIWLAN_LOG_ERROR, "tiwlan_ioctl_init() failed : %d\n", res); 804 kfree(dev); 805 return res; 806 } 807 808 res = register_netdev(dev); 809 if (res != 0) 810 { 811 ti_dprintf(TIWLAN_LOG_ERROR, "register_netdev() failed : %d\n", res); 812 kfree(dev); 813 return res; 814 } 815 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 816 SET_MODULE_OWNER(dev); 817 #endif 818 return 0; 819 } 820 821 822 /* tiwlan_interrupt 823 TIWLAN interrupt handler. Disables interrupts and awakes tasklet. 824 */ 825 #if !(defined(HW_ACCESS_SDIO)||defined(HW_ACCESS_WSPI)) 826 static irqreturn_t tiwlan_interrupt (int irq, void *netdrv, struct pt_regs *cpu_regs) 827 { 828 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)netdrv; 829 830 /* 831 * Workaround for the Linux 2.6 pending IRQ bug: 832 * If a pending IRQ is handled on a WLAN ISR, the ISR is called again 833 * even though it disabled itself in the first call. To protect against 834 * re-entrance, this flag is checked, and if it is already set (meaning 835 * that the ISR is called twice before the tasklet was called) nothing is done. 836 */ 837 if (drv->interrupt_pending == 0) 838 { 839 UINT32 interruptVector; 840 841 interruptVector = configMgr_checkInterrupts(drv->adapter.CoreHalCtx); 842 if (interruptVector != 0) 843 { 844 configMgr_disableInterrupts(drv->adapter.CoreHalCtx); 845 drv->interrupt_pending = 1; 846 tasklet_schedule (&drv->tl); 847 } 848 else 849 { 850 #if DEBUG_UNKNOWN_INTERRUPT 851 ti_dprintf (TIWLAN_LOG_ERROR, 852 "%s - ERROR - interrupt isn't TNET interrupt! interrupt vector = 0x%08X\n", 853 __FUNCTION__, interruptVector); 854 #endif 855 } 856 } 857 return IRQ_HANDLED; 858 } 859 860 #else 861 862 static irqreturn_t tiwlan_interrupt (int irq, void *netdrv, struct pt_regs *cpu_regs) 863 { 864 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)netdrv; 865 866 /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */ 867 drv->interrupt_pending = 1; 868 #ifdef DM_USE_WORKQUEUE 869 #ifdef CONFIG_ANDROID_POWER 870 android_lock_suspend( &drv->irq_wake_lock ); 871 #endif 872 queue_work( drv->tiwlan_wq, &drv->tirq ); 873 /* disable_irq( drv->irq ); Dm: No need, we can loose IRQ */ 874 #else 875 tasklet_schedule( &drv->tl ); 876 #endif 877 return IRQ_HANDLED; 878 } 879 #endif 880 881 882 static void tiwlan_poll_irq_handler(unsigned long parm) 883 { 884 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)parm; 885 bm_trace(2, 0, 0); 886 887 tiwlan_interrupt(0, drv, NULL); 888 mod_timer(&drv->poll_timer, jiffies + TIWLAN_IRQ_POLL_INTERVAL); 889 } 890 891 static void tiwlan_handle_control_requests( tiwlan_net_dev_t *drv ) 892 { 893 bm_trace(4, 0, 0); 894 895 /* Handle control requests (timers, ioctls) */ 896 while(!list_empty(&drv->request_q)) 897 { 898 struct list_head *entry = drv->request_q.next; 899 tiwlan_req_t *req = list_entry(entry, tiwlan_req_t, list); 900 tiwlan_req_t tmp_req; 901 unsigned long flags; 902 903 spin_lock_irqsave(&drv->lock, flags); 904 list_del_init(entry); 905 spin_unlock_irqrestore(&drv->lock, flags); 906 907 ti_nodprintf(TIWLAN_LOG_INFO, "%s: f=0x%x req=0x%x reply_expected=%d\n", 908 __FUNCTION__, req->u.req.f, req, req->u.req.reply_expected); 909 910 tmp_req.u.req.p1 = 0x1234; 911 tmp_req.u.req.p2 = 0x4321; 912 tmp_req.u.req.p3 = 0x1221; 913 tmp_req.u.req.p4 = 0x4334; 914 tmp_req.u.req.reply_expected = 0x50; 915 916 req->u.reply = req->u.req.f(req); 917 918 if ((tmp_req.u.req.p1 != 0x1234) || (tmp_req.u.req.p2 != 0x4321) || (tmp_req.u.req.p3 != 0x1221) || (tmp_req.u.req.p4 != 0x4334) || (tmp_req.u.req.reply_expected != 0x50)) 919 { 920 printk("\n\n !!! ERROR: STACK CORRUPTION !!! : \nf=%p\n", tmp_req.u.req.f); 921 if (!req->u.req.reply_expected) 922 printk("timer handler: %p\n", (void *)tmp_req.u.req.p1); 923 } 924 925 ti_nodprintf(TIWLAN_LOG_INFO, "%s: f=0x%x req=0x%x reply_expected=%d reply=%d\n", 926 __FUNCTION__, req->u.req.f, req, req->u.req.reply_expected, req->u.reply); 927 if (req->u.req.reply_expected) 928 { 929 ti_nodprintf(TIWLAN_LOG_INFO, "%s: about to awake task\n", __FUNCTION__); 930 complete(&req->u.req.comp); 931 } 932 } 933 934 bm_trace(5, 0, 0); 935 936 /* DbgCB_Insert(0, DBG_MODULE_OS, DBG_TYPE_TASKLET, 1)*/ 937 } 938 939 #ifdef DM_USE_WORKQUEUE 940 static void tiwlan_irq_handler( struct work_struct *work ) 941 { 942 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( work, struct tiwlan_net_dev, tirq ); 943 944 /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */ 945 #ifdef CONFIG_ANDROID_POWER 946 android_lock_suspend( &drv->exec_wake_lock ); 947 android_unlock_suspend( &drv->irq_wake_lock ); 948 #endif 949 /* if the driver was unloaded by that time we need to ignore all the timers */ 950 if (drv->unload_driver) { 951 #ifdef CONFIG_ANDROID_POWER 952 android_unlock_suspend( &drv->exec_wake_lock ); 953 #endif 954 /* enable_irq( drv->irq ); */ 955 return; 956 } 957 configMgr_handleInterrupts( drv->adapter.CoreHalCtx ); 958 tiwlan_handle_control_requests( drv ); 959 #ifdef CONFIG_ANDROID_POWER 960 if( drv->receive_packet ) { 961 drv->receive_packet = 0; 962 /* Keep awake for 500 ms to give a chance to network stack */ 963 android_lock_suspend_auto_expire( &drv->rx_wake_lock, HZ ); 964 } 965 android_unlock_suspend( &drv->exec_wake_lock ); 966 #endif 967 /* enable_irq( drv->irq ); */ 968 } 969 #endif 970 971 /* tiwlan_tasklet_handler 972 WLAN protocol tasklet. Most of work happens in the 973 context of this tasklet. 974 */ 975 #ifdef DM_USE_WORKQUEUE 976 static void tiwlan_work_handler( struct work_struct *work ) 977 #else 978 static void tiwlan_tasklet_handler( unsigned long netdrv ) 979 #endif 980 { 981 #ifdef DM_USE_WORKQUEUE 982 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( work, struct tiwlan_net_dev, tw ); 983 #else 984 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)netdrv; 985 #endif 986 #ifdef STACK_PROFILE 987 unsigned int curr1, base1; 988 unsigned int curr2, base2; 989 static unsigned int maximum_stack = 0; 990 #endif 991 992 /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */ 993 #ifdef CONFIG_ANDROID_POWER 994 android_lock_suspend( &drv->exec_wake_lock ); 995 android_unlock_suspend( &drv->timer_wake_lock ); 996 #endif 997 998 /* if the driver was unloaded by that time we need to ignore all the timers */ 999 if (drv->unload_driver) { 1000 #ifdef CONFIG_ANDROID_POWER 1001 android_unlock_suspend( &drv->exec_wake_lock ); 1002 #endif 1003 return; 1004 } 1005 #if 0 1006 ti_dprintf(TIWLAN_LOG_INFO, "%s in\n" , __FUNCTION__); 1007 #endif 1008 1009 #ifdef DRIVER_PROFILE 1010 os_profile (drv, 0, 0); 1011 #endif 1012 bm_trace(3, 0, 0); 1013 1014 #ifdef STACK_PROFILE 1015 curr1 = check_stack_start(&base1); 1016 #endif 1017 1018 /* Handle bus transaction interrupts */ 1019 if (drv->dma_done) 1020 { 1021 drv->dma_done = 0; 1022 configMgr_HandleBusTxn_Complete(drv->adapter.CoreHalCtx); 1023 } 1024 1025 /* don't call for "Handle interrupts, timers, ioctls" while recovery process */ 1026 if (configMgr_areInputsFromOsDisabled(drv->adapter.CoreHalCtx) == TRUE) { 1027 #ifdef CONFIG_ANDROID_POWER 1028 android_unlock_suspend( &drv->exec_wake_lock ); 1029 #endif 1030 return; 1031 } 1032 1033 /* Handle firmware interrupts */ 1034 #ifndef DM_USE_WORKQUEUE 1035 if (drv->interrupt_pending) 1036 { 1037 drv->interrupt_pending = 0; 1038 configMgr_handleInterrupts(drv->adapter.CoreHalCtx); 1039 } 1040 #endif 1041 1042 tiwlan_handle_control_requests( drv ); 1043 1044 #ifdef STACK_PROFILE 1045 curr2 = check_stack_stop(&base2); 1046 1047 if (base2 == base1) 1048 { 1049 /* if the current measurement is bigger then the maximum store it and print*/ 1050 if ((curr1 - curr2) > maximum_stack) 1051 { 1052 printk("STACK PROFILER GOT THE LOCAL MAXIMMUM!!!! \n"); 1053 printk("current operation stack use =%d \n",(curr1 - curr2)); 1054 printk("total stack use=%d \n",8192 - curr2 + base2); 1055 printk("total stack usage= %d percent \n",100 * (8192 - curr2 + base2) / 8192); 1056 maximum_stack = curr1 - curr2; 1057 } 1058 } 1059 #endif 1060 1061 #ifdef DRIVER_PROFILE 1062 os_profile (drv, 1, 0); 1063 #endif 1064 1065 #if 0 1066 ti_dprintf(TIWLAN_LOG_INFO, "%s out\n" , __FUNCTION__); 1067 #endif 1068 #ifdef CONFIG_ANDROID_POWER 1069 android_unlock_suspend( &drv->exec_wake_lock ); 1070 #endif 1071 } 1072 1073 #if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK) 1074 static void tiwlan_rx_watchdog(struct work_struct *work) 1075 { 1076 struct delayed_work *dwork = (struct delayed_work *) container_of(work, struct delayed_work, work); 1077 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( dwork, struct tiwlan_net_dev, trxw ); 1078 1079 unsigned long num_rx_pkts = num_rx_pkt_new - num_rx_pkt_last; 1080 /* Contribute 10mA (200mA x 5%) for 1 pkt/sec, and plus 8mA base. */ 1081 unsigned percent = (5 * num_rx_pkts / RX_RATE_INTERVAL_SEC) + PWRSINK_WIFI_PERCENT_BASE; 1082 1083 if (drv->unload_driver) 1084 return; 1085 1086 percent = (percent > 100) ? 100 : percent; 1087 /* printk(KERN_INFO "num_rx_pkts=%ld, percent=%d\n", num_rx_pkts, percent); */ 1088 #ifdef CONFIG_HTC_PWRSINK 1089 htc_pwrsink_set(PWRSINK_WIFI, percent); 1090 #else 1091 trout_pwrsink_set(PWRSINK_WIFI, percent); 1092 #endif 1093 1094 num_rx_pkt_last = num_rx_pkt_new; 1095 1096 if (drv && drv->tiwlan_wq) 1097 queue_delayed_work(drv->tiwlan_wq, &drv->trxw, msecs_to_jiffies(MSEC_PER_SEC * RX_RATE_INTERVAL_SEC)); 1098 } 1099 #endif 1100 1101 /* tiwlan_send_wait_reply 1102 This internal interface function creates request and sends 1103 it to the control tasklet for processing. 1104 The calling process is blocked until the request is replied. 1105 Function f is being called in the context of the control tasklet. 1106 The request block that is passed to the function as a parameter 1107 contains p1, p2, p3, p4. 1108 The function return code is propagated back to the caller. 1109 tiwlan_send_req_and_wait returns (*f) return code or 1110 -ENOMEM if failed to allocate a request. 1111 */ 1112 int tiwlan_send_wait_reply(tiwlan_net_dev_t *drv, 1113 int (*f)(tiwlan_req_t *req), 1114 unsigned long p1, 1115 unsigned long p2, 1116 unsigned long p3, 1117 unsigned long p4) 1118 { 1119 tiwlan_req_t req; 1120 unsigned long flags; 1121 1122 /* Send request to tiwlan_tasklet and wait for reply */ 1123 if (!drv->adapter.CoreHalCtx) { 1124 return STATION_IS_NOT_RUNNING; 1125 } 1126 1127 req.drv = drv; 1128 req.u.req.f = f; 1129 req.u.req.p1 = p1; 1130 req.u.req.p2 = p2; 1131 req.u.req.p3 = p3; 1132 req.u.req.p4 = p4; 1133 req.u.req.reply_expected = 1; 1134 init_completion(&req.u.req.comp); 1135 1136 spin_lock_irqsave(&drv->lock, flags); 1137 list_add_tail(&req.list, &drv->request_q); 1138 spin_unlock_irqrestore(&drv->lock, flags); 1139 1140 #ifdef DM_USE_WORKQUEUE 1141 /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */ 1142 #ifdef CONFIG_ANDROID_POWER 1143 android_lock_suspend( &drv->timer_wake_lock ); 1144 #endif 1145 queue_work( drv->tiwlan_wq, &drv->tw ); 1146 #else 1147 tasklet_schedule( &drv->tl ); 1148 #endif 1149 wait_for_completion(&req.u.req.comp); 1150 1151 return req.u.reply; 1152 } 1153 1154 1155 #define WLAN_PCMCIA_CFG_REG 0x0524 1156 /* tiwlan_set_hw_access */ 1157 static int tiwlan_set_hw_access(tiwlan_net_dev_t *drv) 1158 { 1159 #ifdef TIWLAN_OMAP1610 1160 OS_WRITE_REG(drv, HI_CFG, 0x00000a00); 1161 1162 #if ! ((defined(HW_ACCESS_SDIO)||defined(HW_ACCESS_WSPI)) && defined(TNETW1150)) 1163 OS_WRITE_REG(drv, WLAN_PCMCIA_CFG_REG, 0xC6880000); 1164 OS_WRITE_REG(drv, PCI_ARB_CFG, 0x2); 1165 #endif 1166 1167 #endif 1168 return 0; 1169 } 1170 1171 1172 /* tiwlan_free_drv 1173 Unmap h/w regions and free driver's structure 1174 */ 1175 static void tiwlan_free_drv(tiwlan_net_dev_t *drv) 1176 { 1177 #ifdef TIWLAN_OMAP1610 1178 if (drv->acx_mem.pa && drv->acx_mem.va) 1179 iounmap(drv->acx_mem.va); 1180 if (drv->acx_reg.pa && drv->acx_reg.va && drv->acx_reg.va != drv->acx_reg.va) 1181 iounmap(drv->acx_reg.va); 1182 #endif 1183 kfree(drv); 1184 } 1185 1186 1187 /* tiwlan_alloc_drv 1188 Allocate driver's structure and map h/w regions 1189 */ 1190 static tiwlan_net_dev_t * 1191 tiwlan_alloc_drv(unsigned long reg_start, unsigned long reg_size, 1192 unsigned long mem_start, unsigned long mem_size, 1193 int map_io, int irq) 1194 { 1195 static tiwlan_net_dev_t *drv; 1196 drv = kmalloc(sizeof(tiwlan_net_dev_t), GFP_KERNEL); 1197 #ifdef TI_MEM_ALLOC_TRACE 1198 os_printf("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(tiwlan_net_dev_t), GFP_KERNEL, sizeof(tiwlan_net_dev_t)); 1199 #endif/*I_MEM_ALLOC_TRACE*/ 1200 1201 if (!drv) 1202 return NULL; 1203 memset(drv, 0, sizeof(tiwlan_net_dev_t)); 1204 drv->acx_mem.size = mem_size; 1205 drv->acx_reg.size = reg_size; 1206 #ifdef TIWLAN_OMAP1610 1207 if (map_io) 1208 { 1209 drv->acx_mem.pa = mem_start; 1210 drv->acx_reg.pa = reg_start; 1211 drv->acx_mem.va = ioremap(drv->acx_mem.pa, drv->acx_mem.size); 1212 if (drv->acx_mem.pa!=drv->acx_reg.pa || drv->acx_mem.size!=drv->acx_reg.size) 1213 drv->acx_reg.va = ioremap(drv->acx_reg.pa, drv->acx_reg.size); 1214 else 1215 drv->acx_reg.va = drv->acx_mem.va; 1216 } 1217 else 1218 { 1219 /* Memory is already mapped */ 1220 drv->acx_mem.va = (void *)mem_start; 1221 drv->acx_reg.va = (void *)reg_start; 1222 } 1223 #endif /* Dm: */ 1224 drv->irq = irq; 1225 return drv; 1226 } 1227 1228 1229 /* tiwlan_init_drv 1230 Called in process context 1231 */ 1232 int tiwlan_init_drv (tiwlan_net_dev_t *drv, tiwlan_dev_init_t *init_info) 1233 { 1234 initTable_t *init_table; 1235 int rc; 1236 void *pWLAN_Images[4]; 1237 1238 /* printk("%s\n", __FUNCTION__); */ 1239 /* It is OK if already initialized */ 1240 if (drv->adapter.CoreHalCtx) 1241 return 0; 1242 1243 init_table = os_memoryAlloc (drv, sizeof(initTable_t)); 1244 1245 #ifdef TI_MEM_ALLOC_TRACE 1246 osPrintf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(initTable_t), GFP_KERNEL, sizeof(initTable_t)); 1247 #endif/*I_MEM_ALLOC_TRACE*/ 1248 if (!init_table) 1249 { 1250 ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate init_table\n"); 1251 return -ENOMEM; 1252 } 1253 1254 if (init_info) 1255 { 1256 drv->eeprom_image.size = init_info->eeprom_image_length; 1257 if (drv->eeprom_image.size) 1258 { 1259 drv->eeprom_image.va = os_memoryAlloc (drv, drv->eeprom_image.size); 1260 1261 #ifdef TI_MEM_ALLOC_TRACE 1262 osPrintf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, drv->eeprom_image.size, GFP_KERNEL, drv->eeprom_image.size); 1263 #endif 1264 if (!drv->eeprom_image.va) 1265 { 1266 ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for eeprom image\n"); 1267 drv->eeprom_image.size = 0; 1268 return -ENOMEM; 1269 } 1270 memcpy (drv->eeprom_image.va, &init_info->data[0], drv->eeprom_image.size ); 1271 } 1272 1273 #ifdef FIRMWARE_DYNAMIC_LOAD 1274 drv->firmware_image.size = init_info->firmware_image_length; 1275 if (!drv->firmware_image.size) 1276 { 1277 ti_dprintf (TIWLAN_LOG_ERROR, "No firmware image\n"); 1278 return -EINVAL; 1279 } 1280 drv->firmware_image.va = os_memoryAlloc (drv,drv->firmware_image.size); 1281 #ifdef TI_MEM_ALLOC_TRACE 1282 osPrintf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, drv->firmware_image.size, GFP_KERNEL, drv->firmware_image.size); 1283 #endif 1284 if (!drv->firmware_image.va) 1285 { 1286 ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate buffer for firmware image\n"); 1287 drv->firmware_image.size = 0; 1288 if (drv->eeprom_image.va) 1289 os_memoryFree (drv, drv->eeprom_image.va, drv->eeprom_image.size); 1290 return -ENOMEM; 1291 } 1292 memcpy (drv->firmware_image.va, 1293 &init_info->data[init_info->eeprom_image_length], 1294 drv->firmware_image.size); 1295 #else 1296 extern unsigned char tiwlan_fwimage[]; 1297 extern unsigned int sizeof_tiwlan_fwimage; 1298 1299 drv->firmware_image.size = sizeof_tiwlan_fwimage; 1300 drv->firmware_image.va = tiwlan_fwimage; 1301 #endif 1302 } 1303 1304 print_deb ("--------- Eeeprom=%p(%lu), Firmware=%p(%lu)\n", 1305 drv->eeprom_image.va, 1306 drv->eeprom_image.size, 1307 drv->firmware_image.va, 1308 drv->firmware_image.size); 1309 1310 /* Init defaults */ 1311 if ((rc = osInitTable_IniFile (drv, 1312 init_table, 1313 (init_info && init_info->init_file_length) ? 1314 &init_info->data[init_info->eeprom_image_length+init_info->firmware_image_length] : NULL, 1315 init_info ? init_info->init_file_length : 0))) 1316 { 1317 ti_dprintf (TIWLAN_LOG_ERROR, "osInitTable_IniFile failed :cannot initialize defaults\n"); 1318 os_memoryFree (drv, init_table, sizeof(initTable_t)); 1319 1320 #ifdef TI_MEM_ALLOC_TRACE 1321 os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, sizeof(initTable_t), -sizeof(initTable_t)); 1322 #endif 1323 return rc; 1324 } 1325 1326 pWLAN_Images[0] = (void *)drv->firmware_image.va; 1327 pWLAN_Images[1] = (void *)drv->firmware_image.size; 1328 pWLAN_Images[2] = (void *)drv->eeprom_image.va; 1329 pWLAN_Images[3] = (void *)drv->eeprom_image.size; 1330 1331 drv->adapter.CoreHalCtx = configMgr_create (drv, 1332 pWLAN_Images, 1333 init_table, 1334 (macAddress_t *) &drv->adapter.CurrentAddr); 1335 if (!(drv->adapter.CoreHalCtx)) 1336 { 1337 #ifdef FIRMWARE_DYNAMIC_LOAD 1338 os_memoryFree(drv,drv->firmware_image.va, drv->firmware_image.size); 1339 os_memoryFree (drv, drv->eeprom_image.va, drv->eeprom_image.size); 1340 #endif 1341 os_memoryFree (drv, init_table, sizeof(initTable_t)); 1342 ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate CoreHalCtx\n"); 1343 return -ENOMEM; 1344 } 1345 1346 drv->interrupt_pending = 0; 1347 drv->dma_done = 0; 1348 1349 if (drv->irq) 1350 { 1351 #ifndef PRIODIC_INTERRUPT 1352 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1353 unsigned long flags; 1354 /* 1355 * Disable all interrupts for not to catch the tiwlan irq 1356 * between request_irq and disable_irq 1357 */ 1358 spin_lock_irqsave (&(drv->lock), flags); 1359 if ((rc = request_irq (drv->irq, tiwlan_interrupt, SA_SHIRQ, drv->netdev->name, drv))) 1360 #else 1361 if ((rc = request_irq (drv->irq, (irq_handler_t)tiwlan_interrupt, IRQF_SHARED | IRQF_TRIGGER_FALLING /*Dm:*/, drv->netdev->name, drv))) 1362 #endif 1363 { 1364 print_err ("TIWLAN: Failed to register interrupt handler\n"); 1365 configMgr_stop (drv->adapter.CoreHalCtx); 1366 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1367 spin_unlock_irqrestore (&drv->lock, flags); 1368 #endif 1369 return rc; 1370 } 1371 #ifdef CONFIG_ANDROID_POWER 1372 set_irq_wake(drv->irq, 1); 1373 #endif 1374 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1375 set_irq_type (drv->irq, IRQT_FALLING); 1376 #else 1377 set_irq_type (drv->irq, IRQ_TYPE_EDGE_FALLING); 1378 #endif 1379 disable_irq (drv->irq); 1380 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1381 spin_unlock_irqrestore (&drv->lock, flags); 1382 #endif 1383 #else 1384 printk (" tiwlan_init_drv :PRIODIC_INTERRUPT drv->irq %x\n",drv->irq); 1385 #endif 1386 } 1387 else 1388 { 1389 /* Debug mode: polling */ 1390 mod_timer (&drv->poll_timer, jiffies + TIWLAN_IRQ_POLL_INTERVAL); 1391 } 1392 1393 /* 1394 * Now that all parts of the driver have been created and handles linked 1395 * proceed to download the FW code 1396 */ 1397 configMgr_init (drv, 1398 drv->adapter.CoreHalCtx, 1399 pWLAN_Images, 1400 init_table, 1401 (macAddress_t *) &drv->adapter.CurrentAddr); 1402 1403 /* Wait for the download to complete */ 1404 os_WaitComplete ((void *)drv); 1405 1406 os_memoryFree (drv, init_table, sizeof(initTable_t)); 1407 1408 if (rc == OK) 1409 { 1410 proc_stat_init (drv->adapter.CoreHalCtx); 1411 #ifdef TI_MEM_ALLOC_TRACE 1412 osPrintf ("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, sizeof(initTable_t), -sizeof(initTable_t)); 1413 #endif/*I_MEM_ALLOC_TRACE*/ 1414 1415 if (drv->adapter.CoreHalCtx == NULL) 1416 { 1417 ti_dprintf (TIWLAN_LOG_ERROR, "configMgr_create failed\n"); 1418 return -ENODEV; 1419 } 1420 1421 /* eeprom buffer is going to be deallocated by the caller. It is no longer needed anyway */ 1422 #if 0 1423 drv->eeprom_image.va = NULL; 1424 drv->eeprom_image.size = 0; 1425 #endif 1426 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 1427 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1428 drv->wl_sock = netlink_kernel_create(NETLINK_USERSOCK, 0, NULL, THIS_MODULE); /* Dm: */ 1429 #else 1430 drv->wl_sock = netlink_kernel_create(NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE); /* Dm: */ 1431 #endif 1432 #else 1433 drv->wl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE); /* Dm: */ 1434 #endif 1435 if (drv->wl_sock == NULL) 1436 { 1437 ti_dprintf(TIWLAN_LOG_ERROR, "netlink_kernel_create() failed !\n"); 1438 /* TODO: free in destroy */ 1439 return -EINVAL; 1440 } 1441 1442 /* Finalize network interface setup */ 1443 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)) 1444 drv->netdev->hard_start_xmit = tiwlan_drv_net_xmit; 1445 #else 1446 drv->netdev->netdev_ops = &tiwlan_ops_pri; 1447 #endif 1448 memcpy (drv->netdev->dev_addr, drv->adapter.CurrentAddr, MAC_ADDR_LEN); 1449 drv->netdev->addr_len = MAC_ADDR_LEN; 1450 1451 /* Register the relevant events with the event handler */ 1452 tiwlan_register_events (drv); 1453 1454 /* Mark that init stage has succeded */ 1455 drv->initialized = 1; 1456 1457 return 0; 1458 } 1459 1460 return -ENODEV; 1461 } 1462 1463 #ifdef CONFIG_ANDROID_POWER 1464 #ifndef CONFIG_HAS_WAKELOCK 1465 /* Wrapper for Init wake lock */ 1466 static void android_init_suspend_wakelock(android_suspend_lock_t *lp,char *nm) 1467 { 1468 lp->name = nm; 1469 android_init_suspend_lock( lp ); 1470 } 1471 #endif 1472 #endif 1473 1474 /* tiwlan_start_drv 1475 */ 1476 int tiwlan_start_drv(tiwlan_net_dev_t *drv) 1477 { 1478 /* printk("%s\n", __FUNCTION__); */ 1479 if (!drv->initialized) 1480 { 1481 ti_dprintf(TIWLAN_LOG_ERROR, "Attempt to start driver before initilization has succeeded\n"); 1482 return -ENODEV; 1483 } 1484 if (!drv->adapter.CoreHalCtx) 1485 { 1486 ti_dprintf(TIWLAN_LOG_ERROR, "Attempt to start driver before creating config_manager\n"); 1487 return -ENODEV; 1488 } 1489 if (drv->started) 1490 { 1491 /*ti_dprintf(TIWLAN_LOG_ERROR, "Attempt to start driver that has already started\n");*/ 1492 return -EALREADY; 1493 } 1494 if (configMgr_start(drv->adapter.CoreHalCtx) != OK) 1495 { 1496 print_err("TIWLAN: Failed to start config manager\n"); 1497 return -EINVAL; 1498 } 1499 drv->started = 1; 1500 1501 #ifdef SDIO_INTERRUPT_HANDLING_ON 1502 configMgr_SlaveAckMaskNotification(drv->adapter.CoreHalCtx); 1503 #endif 1504 if (drv->netdev) 1505 netif_start_queue(drv->netdev); 1506 #ifdef CONFIG_TROUT_PWRSINK 1507 trout_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE); 1508 #endif 1509 #ifdef CONFIG_HTC_PWRSINK 1510 htc_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE); 1511 #endif 1512 export_wifi_fw_version(drv); 1513 return 0; 1514 } 1515 1516 1517 /* tiwlan_destroy_drc 1518 */ 1519 static void tiwlan_destroy_drv(tiwlan_net_dev_t *drv) 1520 { 1521 int waitShutdownCounter; 1522 1523 /* close the ipc_kernel socket*/ 1524 if (drv && drv->wl_sock) { 1525 sock_release(drv->wl_sock->sk_socket); 1526 } 1527 1528 bm_destroy(); 1529 1530 if (drv->started) 1531 tiwlan_send_wait_reply(drv, tiwlan_stop_and_destroy_drv_request, 0, 0, 0, 0); 1532 else 1533 tiwlan_stop_and_destroy_drv(drv); 1534 1535 #ifdef DM_USE_WORKQUEUE 1536 while( tiwlan_del_msdu(drv) != NULL ); 1537 #endif 1538 if (drv->adapter.CoreHalCtx) 1539 { 1540 /* Delay return to OS until all driver components (HAL/SME) are shutdown */ 1541 for (waitShutdownCounter=1; waitShutdownCounter<=DRV_SHUTDOWN_TEST_MAX_COUNTER; waitShutdownCounter++) 1542 { 1543 /* Check if HAL/SME are stopped - If so - exit loop and return to OS */ 1544 if (configMgr_DriverShutdownStatus(drv->adapter.CoreHalCtx) == DRIVER_SHUTDOWN_COMPLETE) 1545 { 1546 break; 1547 } 1548 /* Delay of 100ms between shutdown test */ 1549 mdelay ( DRV_SHUTDOWN_TEST_DELAY_INTERVAL ); 1550 } 1551 1552 /* If driver was not shutdown properly - destroy all timers "manually" and exit*/ 1553 if ( waitShutdownCounter == DRV_SHUTDOWN_TEST_MAX_COUNTER+1 ) 1554 { 1555 os_printf("Timeout while waiting for driver to shutdown...Shutdown status flag=0x%x\n",configMgr_DriverShutdownStatus(drv->adapter.CoreHalCtx)); 1556 } 1557 1558 /* drv->unload_driver = 1; Dm: moved to tiwlan_stop_and_destroy_drv */ 1559 1560 proc_stat_destroy(); 1561 if (drv->irq) { 1562 #ifdef CONFIG_ANDROID_POWER 1563 set_irq_wake(drv->irq, 0); 1564 #endif 1565 free_irq(drv->irq, drv); 1566 } 1567 else 1568 del_timer_sync(&drv->poll_timer); 1569 #ifdef DM_USE_WORKQUEUE 1570 flush_work(&drv->tirq); 1571 flush_work(&drv->tw); 1572 flush_work(&drv->txmit); 1573 #if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK) 1574 cancel_delayed_work_sync(&drv->trxw); 1575 #endif 1576 #endif 1577 /* Unload all modules (free memory) & destroy timers */ 1578 configMgr_UnloadModules (drv->adapter.CoreHalCtx); 1579 1580 #ifdef FIRMWARE_DYNAMIC_LOAD 1581 if( drv->firmware_image.va ) { 1582 os_memoryFree(drv,drv->firmware_image.va, drv->firmware_image.size); 1583 #ifdef TI_MEM_ALLOC_TRACE 1584 os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, drv->firmware_image.size, -drv->firmware_image.size); 1585 #endif /*I_MEM_ALLOC_TRACE*/ 1586 } 1587 if( drv->eeprom_image.va ) 1588 { 1589 os_memoryFree (drv, drv->eeprom_image.va, drv->eeprom_image.size); 1590 #ifdef TI_MEM_ALLOC_TRACE 1591 os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, drv->eeprom_image.size, -drv->eeprom_image.size); 1592 #endif /*I_MEM_ALLOC_TRACE*/ 1593 } 1594 #endif /*FIRMWARE_DYNAMIC_LOAD*/ 1595 } 1596 #ifdef DM_USE_WORKQUEUE 1597 #if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK) 1598 cancel_delayed_work_sync(&drv->trxw); 1599 #endif 1600 destroy_workqueue(drv->tiwlan_wq); 1601 #endif 1602 #ifdef CONFIG_TROUT_PWRSINK 1603 trout_pwrsink_set(PWRSINK_WIFI, 0); 1604 #endif 1605 #ifdef CONFIG_HTC_PWRSINK 1606 htc_pwrsink_set(PWRSINK_WIFI, 0); 1607 #endif 1608 #ifdef CONFIG_ANDROID_POWER 1609 android_uninit_suspend_lock(&drv->irq_wake_lock); 1610 android_uninit_suspend_lock(&drv->xmit_wake_lock); 1611 android_uninit_suspend_lock(&drv->timer_wake_lock); 1612 android_uninit_suspend_lock(&drv->rx_wake_lock); 1613 android_uninit_suspend_lock(&drv->exec_wake_lock); 1614 #endif 1615 unregister_netdev(drv->netdev); 1616 tiwlan_free_drv(drv); 1617 } 1618 1619 1620 /* tiwlan_create_dev 1621 Create tiwlan device instance. 1622 Returns 0 if OK 1623 */ 1624 static int 1625 tiwlan_create_drv(unsigned long reg_start, unsigned long reg_size, 1626 unsigned long mem_start, unsigned long mem_size, 1627 int map_io, int irq, 1628 void *priv, tiwlan_net_dev_t **p_drv) 1629 { 1630 tiwlan_net_dev_t *drv; 1631 int rc; 1632 1633 /* printk("%s\n", __FUNCTION__); */ 1634 /* Allocate device and map h/w regions */ 1635 drv = tiwlan_alloc_drv(reg_start, reg_size, mem_start, mem_size, map_io, irq); 1636 if (!drv) 1637 return -ENOMEM; 1638 1639 /* Check h/w access */ 1640 if (tiwlan_set_hw_access(drv)) 1641 { 1642 tiwlan_free_drv(drv); 1643 return -ENODEV; 1644 } 1645 1646 #ifdef DM_USE_WORKQUEUE 1647 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 1648 drv->tiwlan_wq = create_singlethread_workqueue("tiwlan_wifi_wq"); 1649 #else 1650 drv->tiwlan_wq = create_freezeable_workqueue("tiwlan_wifi_wq"); 1651 #endif 1652 if( !(drv->tiwlan_wq) ) { 1653 tiwlan_free_drv(drv); 1654 printk(KERN_ERR "Failed to create workqueue\n"); 1655 return -EINVAL; 1656 } 1657 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1658 INIT_WORK( &drv->tw, tiwlan_work_handler, &drv->tw ); 1659 INIT_WORK( &drv->txmit, tiwlan_xmit_handler, &drv->txmit ); 1660 INIT_WORK( &drv->tirq, tiwlan_irq_handler, &drv->tirq ); 1661 #else 1662 INIT_WORK( &drv->tw, tiwlan_work_handler ); 1663 INIT_WORK( &drv->txmit, tiwlan_xmit_handler ); 1664 INIT_WORK( &drv->tirq, tiwlan_irq_handler ); 1665 #endif 1666 drv->txmit_msdu_next = drv->txmit_msdu_last = NULL; 1667 #else 1668 tasklet_init( &drv->tl, tiwlan_tasklet_handler, (unsigned long)drv ); 1669 #endif 1670 1671 #if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK) 1672 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) 1673 INIT_DELAYED_WORK( &drv->trxw, tiwlan_rx_watchdog, &drv->trxw ); 1674 #else 1675 INIT_DELAYED_WORK( &drv->trxw, tiwlan_rx_watchdog ); 1676 #endif 1677 #endif 1678 1679 #ifdef CONFIG_ANDROID_POWER 1680 drv->receive_packet = 0; 1681 android_init_suspend_wakelock(&drv->irq_wake_lock,"tiwlan_irq_wake"); 1682 android_init_suspend_wakelock(&drv->xmit_wake_lock,"tiwlan_xmit_wake"); 1683 android_init_suspend_wakelock(&drv->timer_wake_lock,"tiwlan_timer_wake"); 1684 android_init_suspend_wakelock(&drv->rx_wake_lock,"tiwlan_rx_wake"); 1685 android_init_suspend_wakelock(&drv->exec_wake_lock,"tiwlan_exec_wake"); 1686 #endif 1687 spin_lock_init(&drv->lock); 1688 INIT_LIST_HEAD(&drv->request_q); 1689 init_timer(&drv->poll_timer); 1690 drv->poll_timer.function = tiwlan_poll_irq_handler; 1691 drv->poll_timer.data = (unsigned long)drv; 1692 1693 /* Init the completion obhect needed for init async purpose */ 1694 init_completion(&drv->comp); 1695 1696 /* Register network device */ 1697 rc = setup_netif(drv); 1698 if (rc) 1699 { 1700 tiwlan_free_drv(drv); 1701 return rc; 1702 } 1703 drv->priv = priv; 1704 1705 list_add(&drv->list, &tiwlan_drv_list); 1706 if (p_drv) 1707 *p_drv = drv; 1708 1709 drv->initialized = 0; 1710 1711 /* Profiler */ 1712 #ifdef DRIVER_PROFILING 1713 tiwlan_profile_create (drv); 1714 #endif 1715 1716 bm_init(drv); 1717 1718 #ifdef NO_USERMODE_WORKAROUND 1719 rc = tiwlan_init_drv(drv, NULL); 1720 rc = rc ? rc : tiwlan_start_drv(drv); 1721 #endif 1722 1723 return 0; 1724 } 1725 1726 /* tiwlan_stop_driver 1727 */ 1728 int tiwlan_stop_drv(tiwlan_net_dev_t *drv) 1729 { 1730 /* printk("%s\n", __FUNCTION__); */ 1731 if (!drv->adapter.CoreHalCtx) 1732 return 0; 1733 1734 if (drv->netdev) 1735 netif_stop_queue(drv->netdev); 1736 1737 drv->started = 0; 1738 configMgr_stop(drv->adapter.CoreHalCtx); 1739 1740 #ifdef CONFIG_TROUT_PWRSINK 1741 trout_pwrsink_set(PWRSINK_WIFI, 0); 1742 #endif 1743 #ifdef CONFIG_HTC_PWRSINK 1744 htc_pwrsink_set(PWRSINK_WIFI, 0); 1745 #endif 1746 return 0; 1747 } 1748 1749 /* tiwlan_stop__and_destroy_driver 1750 */ 1751 int tiwlan_stop_and_destroy_drv(tiwlan_net_dev_t *drv) 1752 { 1753 if (!drv->adapter.CoreHalCtx) 1754 return 0; 1755 1756 if (drv->netdev) 1757 netif_stop_queue(drv->netdev); 1758 1759 /* Start unload process by calling smeSm_stop, and halting the HAL */ 1760 /* SmeSm_stop finish notification will be one by setting flags */ 1761 configMgr_InitiateUnload(drv->adapter.CoreHalCtx); 1762 drv->started = 0; 1763 drv->unload_driver = 1; 1764 return 0; 1765 } 1766 1767 /* tiwlan_stop__and_destroy_driver from workqueue 1768 */ 1769 int tiwlan_stop_and_destroy_drv_request(tiwlan_req_t *req) 1770 { 1771 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)(req->drv); 1772 printk("%s: Called\n",__FUNCTION__); 1773 return tiwlan_stop_and_destroy_drv(drv); 1774 } 1775 1776 void *wifi_kernel_prealloc(int section, unsigned long size) 1777 { 1778 #ifdef CONFIG_WIFI_CONTROL_FUNC 1779 if( wifi_control_data && wifi_control_data->mem_prealloc ) 1780 return wifi_control_data->mem_prealloc( section, size ); 1781 else 1782 #endif 1783 return NULL; 1784 } 1785 1786 #ifdef TIWLAN_CARDBUS 1787 1788 static struct pci_device_id tnetw1130_pci_tbl[] __devinitdata = 1789 { 1790 { VENDOR_ID_TI, DEVICE_ID_TI_WLAN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 1791 { 0, } 1792 }; 1793 1794 static int __devinit 1795 tnetw1130_pci_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) 1796 { 1797 tiwlan_net_dev_t *drv; 1798 int rc; 1799 1800 print_info("tnetw1130_pci_init_one:\n"); 1801 /* IT: for some reason interrupt doesn't work. 1802 use poling mode for now (comments around 1803 pcidev->irq below) 1804 */ 1805 rc = tiwlan_create_drv(pcidev->resource[0].start, 1806 pcidev->resource[0].end - pcidev->resource[0].start, 1807 pcidev->resource[1].start, 1808 pcidev->resource[1].end - pcidev->resource[1].start, 1809 1, 1810 0/*pcidev->irq*/, pcidev, &drv); 1811 if (!rc) 1812 pcidev->driver_data = drv; 1813 return rc; 1814 } 1815 1816 void tnetw1130_pci_remove(struct pci_dev *dev) 1817 { 1818 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)dev->driver_data; 1819 if (drv) 1820 { 1821 dev->driver_data = NULL; 1822 tiwlan_destroy_drv(drv); 1823 } 1824 } 1825 1826 static struct pci_driver tnetw1130_pci_driver = { 1827 .name = "tnetw1130", 1828 .id_table = tnetw1130_pci_tbl, 1829 .probe = tnetw1130_pci_init_one, 1830 .remove = tnetw1130_pci_remove 1831 }; 1832 1833 #endif /* #ifdef TIWLAN_CARDBUS */ 1834 1835 #ifdef TIWLAN_OMAP1610 1836 int omap1610_drv_create(void) 1837 { 1838 omap_memif_init(); 1839 return tiwlan_create_drv(TIWLAN_OMAP1610_REGBASE, TIWLAN_OMAP1610_REGSIZE, 1840 TIWLAN_OMAP1610_MEMBASE, TIWLAN_OMAP1610_MEMSIZE, 1841 0, TIWLAN_OMAP1610_IRQ, NULL, NULL); 1842 } 1843 #endif /* #ifdef TIWLAN_OMAP1610 */ 1844 1845 #ifdef TIWLAN_MSM7000 1846 1847 #define TROUT_IRQ MSM_GPIO_TO_INT(29) 1848 1849 #ifdef SDIO_INTERRUPT_HANDLING_ON 1850 static void tiwlan_sdio_irq(struct sdio_func *func) 1851 { 1852 printk("%s:\n", __FUNCTION__); 1853 } 1854 #endif 1855 1856 static const struct sdio_device_id tiwlan_sdio_ids[] = { 1857 { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) }, 1858 { }, 1859 }; 1860 1861 MODULE_DEVICE_TABLE(sdio, tiwlan_sdio_ids); 1862 1863 int tiwlan_sdio_init(struct sdio_func *func) 1864 { 1865 int rc; 1866 1867 rc = sdio_enable_func(func); 1868 if (rc) 1869 return rc; 1870 1871 rc = sdio_set_block_size(func, 512); 1872 if( rc ) { 1873 sdio_disable_func(func); 1874 } 1875 return rc; 1876 } 1877 1878 static int tiwlan_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) 1879 { 1880 int rc; 1881 1882 SDIO_SetFunc( NULL ); 1883 if (func->vendor != VENDOR_ID_TI || func->device != DEVICE_ID_TI_WLAN) 1884 return -ENODEV; 1885 1886 printk(KERN_INFO 1887 "TIWLAN: Found SDIO controller (vendor 0x%x, device 0x%x)\n", 1888 func->vendor, func->device); 1889 1890 #ifdef CONFIG_TROUT_PWRSINK 1891 trout_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE); 1892 #endif 1893 #ifdef CONFIG_HTC_PWRSINK 1894 htc_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE); 1895 #endif 1896 1897 sdio_claim_host(func); 1898 1899 rc = tiwlan_sdio_init(func); 1900 if (rc) 1901 goto err2; 1902 #ifdef SDIO_INTERRUPT_HANDLING_ON 1903 rc = sdio_claim_irq(func, tiwlan_sdio_irq); 1904 if (rc) 1905 goto err1; 1906 #endif 1907 SDIO_SetFunc( func ); 1908 1909 rc = tiwlan_create_drv(0, 0, 0, 0, 0, TROUT_IRQ, NULL, NULL); 1910 1911 printk(KERN_INFO "TIWLAN: Driver initialized (rc %d)\n", rc); 1912 complete(&sdio_wait); 1913 return rc; 1914 #ifdef SDIO_INTERRUPT_HANDLING_ON 1915 err1: 1916 sdio_disable_func(func); 1917 #endif 1918 err2: 1919 sdio_release_host(func); 1920 complete(&sdio_wait); 1921 printk(KERN_ERR "TIWLAN: SDIO failure (err %d)\n", rc); 1922 return rc; 1923 } 1924 1925 static void tiwlan_sdio_remove(struct sdio_func *func) 1926 { 1927 printk(KERN_DEBUG "TIWLAN: Releasing SDIO resources\n"); 1928 #ifdef SDIO_INTERRUPT_HANDLING_ON 1929 sdio_release_irq(func); 1930 #endif 1931 sdio_disable_func(func); 1932 sdio_release_host(func); 1933 printk(KERN_DEBUG "TIWLAN: SDIO resources released\n"); 1934 } 1935 1936 static struct sdio_driver tiwlan_sdio_drv = { 1937 .probe = tiwlan_sdio_probe, 1938 .remove = tiwlan_sdio_remove, 1939 .name = "sdio_tiwlan", 1940 .id_table = tiwlan_sdio_ids, 1941 }; 1942 1943 #ifdef CONFIG_WIFI_CONTROL_FUNC 1944 static int wifi_probe( struct platform_device *pdev ) 1945 { 1946 struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); 1947 1948 printk("%s\n", __FUNCTION__); 1949 if( wifi_ctrl ) { 1950 wifi_control_data = wifi_ctrl; 1951 if( wifi_ctrl->set_power ) 1952 wifi_ctrl->set_power(1); /* Power On */ 1953 if( wifi_ctrl->set_reset ) 1954 wifi_ctrl->set_reset(0); /* Reset clear */ 1955 if( wifi_ctrl->set_carddetect ) 1956 wifi_ctrl->set_carddetect(1); /* CardDetect (0->1) */ 1957 } 1958 return 0; 1959 } 1960 1961 static int wifi_remove( struct platform_device *pdev ) 1962 { 1963 struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); 1964 1965 printk("%s\n", __FUNCTION__); 1966 if( wifi_ctrl ) { 1967 if( wifi_ctrl->set_carddetect ) 1968 wifi_ctrl->set_carddetect(0); /* CardDetect (1->0) */ 1969 if( wifi_ctrl->set_reset ) 1970 wifi_ctrl->set_reset(1); /* Reset active */ 1971 if( wifi_ctrl->set_power ) 1972 wifi_ctrl->set_power(0); /* Power Off */ 1973 } 1974 return 0; 1975 } 1976 1977 static struct platform_driver wifi_device = { 1978 .probe = wifi_probe, 1979 .remove = wifi_remove, 1980 .suspend = NULL, 1981 .resume = NULL, 1982 .driver = { 1983 .name = "msm_wifi", 1984 }, 1985 }; 1986 1987 static int wifi_add_dev( void ) 1988 { 1989 return platform_driver_register( &wifi_device ); 1990 } 1991 1992 static void wifi_del_dev( void ) 1993 { 1994 platform_driver_unregister( &wifi_device ); 1995 } 1996 1997 int msm_wifi_power( int on ) 1998 { 1999 printk("%s\n", __FUNCTION__); 2000 if( wifi_control_data && wifi_control_data->set_power ) { 2001 wifi_control_data->set_power(on); 2002 } 2003 return 0; 2004 } 2005 2006 int msm_wifi_reset( int on ) 2007 { 2008 printk("%s\n", __FUNCTION__); 2009 if( wifi_control_data && wifi_control_data->set_reset ) { 2010 wifi_control_data->set_reset(on); 2011 } 2012 return 0; 2013 } 2014 #endif 2015 #endif /* TIWLAN_MSM7000 */ 2016 2017 static int __init tiwlan_module_init(void) 2018 { 2019 int rc = 0; 2020 2021 printk(KERN_INFO "TIWLAN: Driver loading\n"); 2022 /* Check sizes of basic structures to ensure that compilation 2023 options are OK 2024 */ 2025 if (packed_struct_tst()) 2026 ;/*IT: return -EINVAL; */ 2027 2028 tiwlan_deb_entry = create_proc_entry(TIWLAN_DBG_PROC, 0644, NULL); 2029 if (tiwlan_deb_entry == NULL) 2030 return -EINVAL; 2031 tiwlan_deb_entry->read_proc = tiwlan_deb_read_proc; 2032 tiwlan_deb_entry->write_proc = tiwlan_deb_write_proc; 2033 #ifdef TIWLAN_MSM7000 2034 init_completion(&sdio_wait); 2035 #endif 2036 #ifdef TIWLAN_CARDBUS 2037 if ((rc=pci_register_driver(&tnetw1130_pci_driver)) < 0) 2038 print_err("TIWLAN: PCMCIA driver failed to register\n"); 2039 remove_proc_entry(TIWLAN_DBG_PROC, NULL); 2040 return rc; 2041 } 2042 printk(KERN_INFO "TIWLAN: Driver loaded\n"); 2043 return 0; 2044 2045 #elif defined(TIWLAN_OMAP1610) 2046 rc = omap1610_drv_create(); 2047 export_wifi_chip_id(); 2048 printk(KERN_INFO "TIWLAN: Driver loaded\n"); 2049 return rc; 2050 2051 #elif defined(TIWLAN_MSM7000) 2052 #ifdef CONFIG_WIFI_CONTROL_FUNC 2053 wifi_add_dev(); 2054 #else 2055 trout_wifi_power(1); /* Power On */ 2056 trout_wifi_reset(0); /* Reset clear */ 2057 trout_wifi_set_carddetect(1); /* CardDetect (0->1) */ 2058 #endif 2059 2060 /* Register ourselves as an SDIO driver */ 2061 rc = sdio_register_driver(&tiwlan_sdio_drv); 2062 if (rc < 0) { 2063 printk(KERN_ERR "sdio register failed (%d)\n", rc); 2064 remove_proc_entry(TIWLAN_DBG_PROC, NULL); 2065 return rc; 2066 } 2067 /* rc = tiwlan_create_drv(0, 0, 0, 0, 0, TROUT_IRQ, NULL, NULL); -- Called in probe */ 2068 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)) 2069 tiwlan_calibration = create_proc_entry("calibration", 0644, NULL); 2070 if (tiwlan_calibration) { 2071 tiwlan_calibration->size = tiwlan_get_nvs_size(); 2072 tiwlan_calibration->read_proc = tiwlan_calibration_read_proc; 2073 tiwlan_calibration->write_proc = tiwlan_calibration_write_proc; 2074 } 2075 #endif 2076 if (!wait_for_completion_timeout(&sdio_wait, msecs_to_jiffies(10000))) { 2077 printk(KERN_ERR "%s: Timed out waiting for device detect\n", __func__); 2078 remove_proc_entry(TIWLAN_DBG_PROC, NULL); 2079 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)) 2080 if (tiwlan_calibration) 2081 remove_proc_entry("calibration", NULL); 2082 #endif 2083 sdio_unregister_driver(&tiwlan_sdio_drv); 2084 #ifdef CONFIG_WIFI_CONTROL_FUNC 2085 wifi_del_dev(); 2086 #else 2087 trout_wifi_set_carddetect(0); /* CardDetect (1->0) */ 2088 trout_wifi_reset(1); /* Reset active */ 2089 trout_wifi_power(0); /* Power Off */ 2090 #endif 2091 return -ENODEV; 2092 } 2093 export_wifi_chip_id(); 2094 printk(KERN_INFO "TIWLAN: Driver loaded\n"); 2095 return 0; 2096 2097 #else 2098 2099 #error Either TIWLAN_CARDBUS, TIWLAN_OMAP1610 or TIWLAN_MSM7000 must be defined 2100 2101 #endif 2102 } 2103 2104 static void __exit tiwlan_module_cleanup(void) 2105 { 2106 struct list_head *l; 2107 struct list_head *tmp; 2108 2109 printk(KERN_INFO "TIWLAN: Driver unloading\n"); 2110 #ifdef TIWLAN_CARDBUS 2111 pci_unregister_driver(&tnetw1130_pci_driver); 2112 #endif 2113 list_for_each_safe(l, tmp, &tiwlan_drv_list) 2114 { 2115 tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)list_entry(l, tiwlan_net_dev_t, list); 2116 list_del(l); 2117 tiwlan_destroy_drv(drv); 2118 } 2119 remove_proc_entry(TIWLAN_DBG_PROC, NULL); 2120 #ifdef TIWLAN_MSM7000 2121 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)) 2122 if(tiwlan_calibration) 2123 remove_proc_entry("calibration", NULL); 2124 #endif 2125 sdio_unregister_driver(&tiwlan_sdio_drv); 2126 #ifdef CONFIG_WIFI_CONTROL_FUNC 2127 wifi_del_dev(); 2128 #else 2129 trout_wifi_set_carddetect(0); /* CardDetect (1->0) */ 2130 trout_wifi_reset(1); /* Reset active */ 2131 trout_wifi_power(0); /* Power Off */ 2132 #endif 2133 #endif 2134 printk(KERN_INFO "TIWLAN: Driver unloaded\n"); 2135 } 2136 2137 module_init(tiwlan_module_init); 2138 module_exit(tiwlan_module_cleanup); 2139