• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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