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