]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/linux_wlan.c
staging: wilc1000: remove spinlock wrappers
[karo-tx-linux.git] / drivers / staging / wilc1000 / linux_wlan.c
1 #include "wilc_wfi_cfgoperations.h"
2 #include "linux_wlan_common.h"
3 #include "wilc_wlan_if.h"
4 #include "wilc_wlan.h"
5 #ifdef USE_WIRELESS
6 #include "wilc_wfi_cfgoperations.h"
7 #endif
8
9 #include "linux_wlan_common.h"
10
11 #include <linux/slab.h>
12 #include <linux/sched.h>
13 #include <linux/delay.h>
14 #include <linux/workqueue.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/gpio.h>
18
19 #include <linux/kthread.h>
20 #include <linux/firmware.h>
21 #include <linux/delay.h>
22
23 #include <linux/init.h>
24 #include <linux/netdevice.h>
25 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
26 #include <linux/inetdevice.h>
27 #endif
28 #include <linux/etherdevice.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/skbuff.h>
32
33 #include <linux/version.h>
34 #include <linux/semaphore.h>
35
36 #ifdef WILC_SDIO
37 #include "linux_wlan_sdio.h"
38 #else
39 #include "linux_wlan_spi.h"
40 #endif
41
42 #ifdef WILC_FULLY_HOSTING_AP
43 #include "wilc_host_ap.h"
44 #endif
45
46 #ifdef STATIC_MACADDRESS /* brandy_0724 [[ */
47 #include <linux/vmalloc.h>
48 #include <linux/fs.h>
49 struct task_struct *wilc_mac_thread;
50 unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2};
51 #endif /* brandy_0724 ]] */
52
53 #if defined(CUSTOMER_PLATFORM)
54 /*
55  TODO : Write power control functions as customer platform.
56  */
57 #else
58
59  #define _linux_wlan_device_power_on()          {}
60  #define _linux_wlan_device_power_off()         {}
61
62  #define _linux_wlan_device_detection()         {}
63  #define _linux_wlan_device_removal()           {}
64 #endif
65
66 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
67 extern bool g_obtainingIP;
68 #endif
69 extern u16 Set_machw_change_vir_if(bool bValue);
70 extern void resolve_disconnect_aberration(void *drvHandler);
71 extern u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
72 void wilc1000_wlan_deinit(linux_wlan_t *nic);
73 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
74 extern struct timer_list hDuringIpTimer;
75 #endif
76
77 static int linux_wlan_device_power(int on_off)
78 {
79         PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off);
80
81         if (on_off) {
82                 _linux_wlan_device_power_on();
83         } else {
84                 _linux_wlan_device_power_off();
85         }
86
87         return 0;
88 }
89
90 static int linux_wlan_device_detection(int on_off)
91 {
92         PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off);
93
94 #ifdef WILC_SDIO
95         if (on_off) {
96                 _linux_wlan_device_detection();
97         } else {
98                 _linux_wlan_device_removal();
99         }
100 #endif
101
102         return 0;
103 }
104
105 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
106 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
107
108 static struct notifier_block g_dev_notifier = {
109         .notifier_call = dev_state_ev_handler
110 };
111 #endif
112
113 #define wilc_wlan_deinit(nic)   { if (&g_linux_wlan->oup != NULL)        \
114                 if (g_linux_wlan->oup.wlan_cleanup != NULL) \
115                         g_linux_wlan->oup.wlan_cleanup(); }
116
117 #ifndef STA_FIRMWARE
118 #define STA_FIRMWARE    "wifi_firmware.bin"
119 #endif
120
121 #ifndef AP_FIRMWARE
122 #define AP_FIRMWARE             "wifi_firmware_ap.bin"
123 #endif
124
125 #ifndef P2P_CONCURRENCY_FIRMWARE
126 #define P2P_CONCURRENCY_FIRMWARE        "wifi_firmware_p2p_concurrency.bin"
127 #endif
128
129 typedef struct android_wifi_priv_cmd {
130         char *buf;
131         int used_len;
132         int total_len;
133 } android_wifi_priv_cmd;
134
135 #define IRQ_WAIT        1
136 #define IRQ_NO_WAIT     0
137 /*
138  *      to sync between mac_close and module exit.
139  *      don't initialize or de-initialize from init/deinitlocks
140  *      to be initialized from module wilc_netdev_init and
141  *      deinitialized from mdoule_exit
142  */
143 static struct semaphore close_exit_sync;
144 unsigned int int_rcvdU;
145 unsigned int int_rcvdB;
146 unsigned int int_clrd;
147
148 static int wlan_deinit_locks(linux_wlan_t *nic);
149 static void wlan_deinitialize_threads(linux_wlan_t *nic);
150 extern void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size);
151 extern void WILC_WFI_p2p_rx(struct net_device *dev, uint8_t *buff, uint32_t size);
152
153 static void linux_wlan_tx_complete(void *priv, int status);
154 void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset);
155 static int  mac_init_fn(struct net_device *ndev);
156 int  mac_xmit(struct sk_buff *skb, struct net_device *dev);
157 int  mac_open(struct net_device *ndev);
158 int  mac_close(struct net_device *ndev);
159 static struct net_device_stats *mac_stats(struct net_device *dev);
160 static int  mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
161 static void wilc_set_multicast_list(struct net_device *dev);
162
163 /*
164  * for now - in frmw_to_linux there should be private data to be passed to it
165  * and this data should be pointer to net device
166  */
167 linux_wlan_t *g_linux_wlan;
168 wilc_wlan_oup_t *gpstrWlanOps;
169 bool bEnablePS = true;
170
171 static const struct net_device_ops wilc_netdev_ops = {
172         .ndo_init = mac_init_fn,
173         .ndo_open = mac_open,
174         .ndo_stop = mac_close,
175         .ndo_start_xmit = mac_xmit,
176         .ndo_do_ioctl = mac_ioctl,
177         .ndo_get_stats = mac_stats,
178         .ndo_set_rx_mode  = wilc_set_multicast_list,
179
180 };
181
182 #ifdef DEBUG_MODE
183
184 extern volatile int timeNo;
185
186 #define DEGUG_BUFFER_LENGTH 1000
187 volatile int WatchDogdebuggerCounter;
188 char DebugBuffer[DEGUG_BUFFER_LENGTH + 20] = {0};
189 static char *ps8current = DebugBuffer;
190
191 void printk_later(const char *format, ...)
192 {
193         va_list args;
194
195         va_start(args, format);
196         ps8current += vsprintf(ps8current, format, args);
197         va_end(args);
198         if ((ps8current - DebugBuffer) > DEGUG_BUFFER_LENGTH)
199                 ps8current = DebugBuffer;
200
201 }
202
203 void dump_logs(void)
204 {
205         if (DebugBuffer[0]) {
206                 DebugBuffer[DEGUG_BUFFER_LENGTH] = 0;
207                 PRINT_INFO(GENERIC_DBG, "early printed\n");
208                 PRINT_D(GENERIC_DBG, ps8current + 1);
209                 ps8current[1] = 0;
210                 PRINT_INFO(GENERIC_DBG, "latest printed\n");
211                 PRINT_D(GENERIC_DBG, DebugBuffer);
212                 DebugBuffer[0] = 0;
213                 ps8current = DebugBuffer;
214         }
215 }
216
217 void Reset_WatchDogdebugger(void)
218 {
219         WatchDogdebuggerCounter = 0;
220 }
221
222 static int DebuggingThreadTask(void *vp)
223 {
224         while (1) {
225                 while (!WatchDogdebuggerCounter) {
226                         PRINT_D(GENERIC_DBG, "Debug Thread Running %d\n", timeNo);
227                         WatchDogdebuggerCounter = 1;
228                         msleep(10000);
229                 }
230                 dump_logs();
231                 WatchDogdebuggerCounter = 0;
232         }
233 }
234 #endif
235
236 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
237 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
238 {
239         struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
240         struct WILC_WFI_priv *priv;
241         tstrWILC_WFIDrv *pstrWFIDrv;
242         struct net_device *dev;
243         u8 *pIP_Add_buff;
244         perInterface_wlan_t *nic;
245         u8 null_ip[4] = {0};
246         char wlan_dev_name[5] = "wlan0";
247
248         if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) {
249                 PRINT_D(GENERIC_DBG, "dev_iface = NULL\n");
250                 return NOTIFY_DONE;
251         }
252
253         if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) {
254                 PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n");
255                 return NOTIFY_DONE;
256         }
257
258         dev  = (struct net_device *)dev_iface->ifa_dev->dev;
259         if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) {
260                 PRINT_D(GENERIC_DBG, "No Wireless registerd\n");
261                 return NOTIFY_DONE;
262         }
263         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
264         if (priv == NULL) {
265                 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
266                 return NOTIFY_DONE;
267         }
268         pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
269         nic = netdev_priv(dev);
270         if (nic == NULL || pstrWFIDrv == NULL) {
271                 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
272                 return NOTIFY_DONE;
273         }
274
275         PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */
276
277         switch (event) {
278         case NETDEV_UP:
279                 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev);       /* tony */
280
281                 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
282
283                 /*If we are in station mode or client mode*/
284                 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
285                         pstrWFIDrv->IFC_UP = 1;
286                         g_obtainingIP = false;
287                         del_timer(&hDuringIpTimer);
288                         PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
289                 }
290
291                 if (bEnablePS)
292                         host_int_set_power_mgmt(pstrWFIDrv, 1, 0);
293
294                 PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
295
296                 pIP_Add_buff = (char *) (&(dev_iface->ifa_address));
297                 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]);
298                 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
299
300                 break;
301
302         case NETDEV_DOWN:
303                 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev);               /* tony */
304
305                 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
306                 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
307                         pstrWFIDrv->IFC_UP = 0;
308                         g_obtainingIP = false;
309                 }
310
311                 if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
312                         host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
313
314                 resolve_disconnect_aberration(pstrWFIDrv);
315
316                 PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
317
318                 pIP_Add_buff = null_ip;
319                 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]);
320
321                 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
322
323                 break;
324
325         default:
326                 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n");        /* tony */
327                 PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
328
329                 break;
330         }
331
332         return NOTIFY_DONE;
333
334 }
335 #endif
336
337 /*
338  *      Interrupt initialization and handling functions
339  */
340
341 void linux_wlan_enable_irq(void)
342 {
343
344 #if (RX_BH_TYPE != RX_BH_THREADED_IRQ)
345 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
346         PRINT_D(INT_DBG, "Enabling IRQ ...\n");
347         enable_irq(g_linux_wlan->dev_irq_num);
348 #endif
349 #endif
350 }
351
352 void linux_wlan_disable_irq(int wait)
353 {
354 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
355         if (wait) {
356                 PRINT_D(INT_DBG, "Disabling IRQ ...\n");
357                 disable_irq(g_linux_wlan->dev_irq_num);
358         } else {
359                 PRINT_D(INT_DBG, "Disabling IRQ ...\n");
360                 disable_irq_nosync(g_linux_wlan->dev_irq_num);
361         }
362 #endif
363 }
364
365 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
366 static irqreturn_t isr_uh_routine(int irq, void *user_data)
367 {
368         int_rcvdU++;
369 #if (RX_BH_TYPE != RX_BH_THREADED_IRQ)
370         linux_wlan_disable_irq(IRQ_NO_WAIT);
371 #endif
372         PRINT_D(INT_DBG, "Interrupt received UH\n");
373
374         /*While mac is closing cacncel the handling of any interrupts received*/
375         if (g_linux_wlan->close) {
376                 PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
377         #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
378                 return IRQ_HANDLED;
379         #else
380                 return IRQ_NONE;
381         #endif
382
383         }
384 #if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
385         schedule_work(&g_linux_wlan->rx_work_queue);
386         return IRQ_HANDLED;
387 #elif (RX_BH_TYPE == RX_BH_KTHREAD)
388         up(&g_linux_wlan->rx_sem);
389         return IRQ_HANDLED;
390 #elif (RX_BH_TYPE == RX_BH_THREADED_IRQ)
391         return IRQ_WAKE_THREAD;
392 #endif
393
394 }
395 #endif
396
397 #if (RX_BH_TYPE == RX_BH_WORK_QUEUE || RX_BH_TYPE == RX_BH_THREADED_IRQ)
398
399 #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
400 irqreturn_t isr_bh_routine(int irq, void *userdata)
401 {
402         linux_wlan_t *nic;
403
404         nic = (linux_wlan_t *)userdata;
405 #else
406 static void isr_bh_routine(struct work_struct *work)
407 {
408         perInterface_wlan_t *nic;
409
410         nic = (perInterface_wlan_t *)container_of(work, linux_wlan_t, rx_work_queue);
411 #endif
412
413         /*While mac is closing cacncel the handling of any interrupts received*/
414         if (g_linux_wlan->close) {
415                 PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
416         #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
417                 return IRQ_HANDLED;
418         #else
419                 return;
420         #endif
421         }
422
423         int_rcvdB++;
424         PRINT_D(INT_DBG, "Interrupt received BH\n");
425         if (g_linux_wlan->oup.wlan_handle_rx_isr != 0)
426                 g_linux_wlan->oup.wlan_handle_rx_isr();
427         else
428                 PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n");
429
430 #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
431         return IRQ_HANDLED;
432 #endif
433 }
434 #elif (RX_BH_TYPE == RX_BH_KTHREAD)
435 static int isr_bh_routine(void *vp)
436 {
437         linux_wlan_t *nic;
438
439         nic = (linux_wlan_t *)vp;
440
441         while (1) {
442                 down(&nic->rx_sem);
443                 if (g_linux_wlan->close) {
444
445                         while (!kthread_should_stop())
446                                 schedule();
447
448                         break;
449                 }
450                 int_rcvdB++;
451                 PRINT_D(INT_DBG, "Interrupt received BH\n");
452                 if (g_linux_wlan->oup.wlan_handle_rx_isr != 0)
453                         g_linux_wlan->oup.wlan_handle_rx_isr();
454                 else
455                         PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n");
456         }
457
458         return 0;
459 }
460 #endif
461
462 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
463 static int init_irq(linux_wlan_t *p_nic)
464 {
465         int ret = 0;
466         linux_wlan_t *nic = p_nic;
467
468         /*initialize GPIO and register IRQ num*/
469         /*GPIO request*/
470         if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) &&
471             (gpio_direction_input(GPIO_NUM) == 0)) {
472 #if defined(CUSTOMER_PLATFORM)
473 /*
474  TODO : save the registerd irq number to the private wilc context in kernel.
475  *
476  * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
477  */
478 #elif defined(NM73131_0_BOARD)
479                 nic->dev_irq_num = IRQ_WILC1000;
480 #elif defined(PANDA_BOARD)
481                 gpio_export(GPIO_NUM, 1);
482                 nic->dev_irq_num = OMAP_GPIO_IRQ(GPIO_NUM);
483                 irq_set_irq_type(nic->dev_irq_num, IRQ_TYPE_LEVEL_LOW);
484 #else
485                 nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
486 #endif
487         } else {
488                 ret = -1;
489                 PRINT_ER("could not obtain gpio for WILC_INTR\n");
490         }
491
492 #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
493         if ((ret != -1) && (request_threaded_irq(nic->dev_irq_num, isr_uh_routine, isr_bh_routine,
494                                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,               /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/
495                                                   "WILC_IRQ", nic)) < 0) {
496
497 #else
498         /*Request IRQ*/
499         if ((ret != -1) && (request_irq(nic->dev_irq_num, isr_uh_routine,
500                                         IRQF_TRIGGER_LOW, "WILC_IRQ", nic) < 0)) {
501
502 #endif
503                 PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM);
504                 ret = -1;
505         } else {
506
507                 PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
508                         nic->dev_irq_num, GPIO_NUM);
509         }
510
511         return ret;
512 }
513 #endif
514
515 static void deinit_irq(linux_wlan_t *nic)
516 {
517 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
518         /* Deintialize IRQ */
519         if (&nic->dev_irq_num != 0) {
520                 free_irq(nic->dev_irq_num, g_linux_wlan);
521
522                 gpio_free(GPIO_NUM);
523         }
524 #endif
525 }
526
527 /*
528  *      OS functions
529  */
530 static void linux_wlan_msleep(uint32_t msc)
531 {
532         if (msc <= 4000000) {
533                 u32 u32Temp = msc * 1000;
534
535                 usleep_range(u32Temp, u32Temp);
536         } else {
537                 msleep(msc);
538         }
539 }
540
541 static void linux_wlan_dbg(uint8_t *buff)
542 {
543         PRINT_D(INIT_DBG, "%d\n", *buff);
544 }
545
546 static int linux_wlan_lock_timeout(void *vp, u32 timeout)
547 {
548         int error = -1;
549
550         PRINT_D(LOCK_DBG, "Locking %p\n", vp);
551         if (vp != NULL)
552                 error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout));
553         else
554                 PRINT_ER("Failed, mutex is NULL\n");
555         return error;
556 }
557
558 static void linux_wlan_mac_indicate(int flag)
559 {
560         /*I have to do it that way becuase there is no mean to encapsulate device pointer
561          * as a parameter
562          */
563         linux_wlan_t *pd = g_linux_wlan;
564         int status;
565
566         if (flag == WILC_MAC_INDICATE_STATUS) {
567                 pd->oup.wlan_cfg_get_value(WID_STATUS, (unsigned char *)&status, 4);
568                 if (pd->mac_status == WILC_MAC_STATUS_INIT) {
569                         pd->mac_status = status;
570                         up(&pd->sync_event);
571                 } else {
572                         pd->mac_status = status;
573                 }
574
575                 if (pd->mac_status == WILC_MAC_STATUS_CONNECT) {        /* Connect */
576                 }
577
578         } else if (flag == WILC_MAC_INDICATE_SCAN) {
579                 PRINT_D(GENERIC_DBG, "Scanning ...\n");
580
581         }
582
583 }
584
585 struct net_device *GetIfHandler(uint8_t *pMacHeader)
586 {
587         uint8_t *Bssid, *Bssid1;
588         int i = 0;
589
590         Bssid  = pMacHeader + 10;
591         Bssid1 = pMacHeader + 4;
592
593         for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
594                 if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) ||
595                     !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) {
596                         return g_linux_wlan->strInterfaceInfo[i].wilc_netdev;
597                 }
598         }
599         PRINT_INFO(INIT_DBG, "Invalide handle\n");
600         for (i = 0; i < 25; i++)
601                 PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]);
602         Bssid  = pMacHeader + 18;
603         Bssid1 = pMacHeader + 12;
604         for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
605                 if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) ||
606                     !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) {
607                         PRINT_D(INIT_DBG, "Ctx [%p]\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
608                         return g_linux_wlan->strInterfaceInfo[i].wilc_netdev;
609                 }
610         }
611         PRINT_INFO(INIT_DBG, "\n");
612         return NULL;
613 }
614
615 int linux_wlan_set_bssid(struct net_device *wilc_netdev, uint8_t *pBSSID)
616 {
617         int i = 0;
618         int ret = -1;
619
620         PRINT_D(INIT_DBG, "set bssid on[%p]\n", wilc_netdev);
621         for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
622                 if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev == wilc_netdev) {
623                         PRINT_D(INIT_DBG, "set bssid [%x][%x][%x]\n", pBSSID[0], pBSSID[1], pBSSID[2]);
624                         memcpy(g_linux_wlan->strInterfaceInfo[i].aBSSID, pBSSID, 6);
625                         ret = 0;
626                         break;
627                 }
628         }
629         return ret;
630 }
631
632 /*BugID_5213*/
633 /*Function to get number of connected interfaces*/
634 int linux_wlan_get_num_conn_ifcs(void)
635 {
636         uint8_t i = 0;
637         uint8_t null_bssid[6] = {0};
638         uint8_t ret_val = 0;
639
640         for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
641                 if (memcmp(g_linux_wlan->strInterfaceInfo[i].aBSSID, null_bssid, 6))
642                         ret_val++;
643         }
644         return ret_val;
645 }
646
647 static int linux_wlan_rxq_task(void *vp)
648 {
649
650         /* inform wilc1000_wlan_init that RXQ task is started. */
651         up(&g_linux_wlan->rxq_thread_started);
652         while (1) {
653                 down(&g_linux_wlan->rxq_event);
654                 /* wait_for_completion(&g_linux_wlan->rxq_event); */
655
656                 if (g_linux_wlan->close) {
657                         /*Unlock the mutex in the mac_close function to indicate the exiting of the RX thread */
658                         up(&g_linux_wlan->rxq_thread_started);
659
660                         while (!kthread_should_stop())
661                                 schedule();
662
663                         PRINT_D(RX_DBG, " RX thread stopped\n");
664                         break;
665                 }
666                 PRINT_D(RX_DBG, "Calling wlan_handle_rx_que()\n");
667
668                 g_linux_wlan->oup.wlan_handle_rx_que();
669         }
670         return 0;
671 }
672
673 #define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
674
675 static int linux_wlan_txq_task(void *vp)
676 {
677         int ret, txq_count;
678
679 #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
680 #define TX_BACKOFF_WEIGHT_INCR_STEP (1)
681 #define TX_BACKOFF_WEIGHT_DECR_STEP (1)
682 #define TX_BACKOFF_WEIGHT_MAX (7)
683 #define TX_BACKOFF_WEIGHT_MIN (0)
684 #define TX_BACKOFF_WEIGHT_UNIT_MS (10)
685         int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
686 #endif
687
688         /* inform wilc1000_wlan_init that TXQ task is started. */
689         up(&g_linux_wlan->txq_thread_started);
690         while (1) {
691
692                 PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
693                 down(&g_linux_wlan->txq_event);
694                 /* wait_for_completion(&pd->txq_event); */
695                 PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
696
697                 if (g_linux_wlan->close) {
698                         /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */
699                         up(&g_linux_wlan->txq_thread_started);
700
701                         while (!kthread_should_stop())
702                                 schedule();
703
704                         PRINT_D(TX_DBG, "TX thread stopped\n");
705                         break;
706                 }
707                 PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n");
708 #if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
709                 g_linux_wlan->oup.wlan_handle_tx_que();
710 #else
711                 do {
712                         ret = g_linux_wlan->oup.wlan_handle_tx_que(&txq_count);
713                         if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) {
714                                 PRINT_D(TX_DBG, "Waking up queue\n");
715                                 /* netif_wake_queue(pd->wilc_netdev); */
716                                 if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[0].wilc_netdev))
717                                         netif_wake_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev);
718                                 if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[1].wilc_netdev))
719                                         netif_wake_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev);
720                         }
721
722                         if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */
723                                 do {
724                                         /* Back off from sending packets for some time. */
725                                         /* schedule_timeout will allow RX task to run and free buffers.*/
726                                         /* set_current_state(TASK_UNINTERRUPTIBLE); */
727                                         /* timeout = schedule_timeout(timeout); */
728                                         msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
729                                 } while (/*timeout*/ 0);
730                                 backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
731                                 if (backoff_weight > TX_BACKOFF_WEIGHT_MAX)
732                                         backoff_weight = TX_BACKOFF_WEIGHT_MAX;
733                         } else {
734                                 if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
735                                         backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
736                                         if (backoff_weight < TX_BACKOFF_WEIGHT_MIN)
737                                                 backoff_weight = TX_BACKOFF_WEIGHT_MIN;
738                                 }
739                         }
740                         /*TODO: drop packets after a certain time/number of retry count. */
741                 } while (ret == WILC_TX_ERR_NO_BUF && !g_linux_wlan->close); /* retry sending packets if no more buffers in chip. */
742 #endif
743         }
744         return 0;
745 }
746
747 static void linux_wlan_rx_complete(void)
748 {
749         PRINT_D(RX_DBG, "RX completed\n");
750 }
751
752 int linux_wlan_get_firmware(perInterface_wlan_t *p_nic)
753 {
754
755         perInterface_wlan_t *nic = p_nic;
756         int ret = 0;
757         const struct firmware *wilc_firmware;
758         char *firmware;
759
760         if (nic->iftype == AP_MODE)
761                 firmware = AP_FIRMWARE;
762         else if (nic->iftype == STATION_MODE)
763                 firmware = STA_FIRMWARE;
764
765         /*BugID_5137*/
766         else {
767                 PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
768                 firmware = P2P_CONCURRENCY_FIRMWARE;
769         }
770
771         if (nic == NULL) {
772                 PRINT_ER("NIC is NULL\n");
773                 goto _fail_;
774         }
775
776         if (&nic->wilc_netdev->dev == NULL) {
777                 PRINT_ER("&nic->wilc_netdev->dev  is NULL\n");
778                 goto _fail_;
779         }
780
781         /*      the firmare should be located in /lib/firmware in
782          *      root file system with the name specified above */
783
784 #ifdef WILC_SDIO
785         if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) {
786                 PRINT_ER("%s - firmare not available\n", firmware);
787                 ret = -1;
788                 goto _fail_;
789         }
790 #else
791         if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) {
792                 PRINT_ER("%s - firmare not available\n", firmware);
793                 ret = -1;
794                 goto _fail_;
795         }
796 #endif
797         g_linux_wlan->wilc_firmware = wilc_firmware; /* Bug 4703 */
798
799 _fail_:
800
801         return ret;
802
803 }
804
805 #ifdef COMPLEMENT_BOOT
806 int repeat_power_cycle(perInterface_wlan_t *nic);
807 #endif
808
809 static int linux_wlan_start_firmware(perInterface_wlan_t *nic)
810 {
811
812         int ret = 0;
813         /* start firmware */
814         PRINT_D(INIT_DBG, "Starting Firmware ...\n");
815         ret = g_linux_wlan->oup.wlan_start();
816         if (ret < 0) {
817                 PRINT_ER("Failed to start Firmware\n");
818                 goto _fail_;
819         }
820
821         /* wait for mac ready */
822         PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
823         ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000);
824         if (ret) {
825 #ifdef COMPLEMENT_BOOT
826                 static int timeout = 5;
827
828                 if (timeout--) {
829                         PRINT_D(INIT_DBG, "repeat power cycle[%d]", timeout);
830                         ret = repeat_power_cycle(nic);
831                 } else {
832                         timeout = 5;
833                         ret = -1;
834                         goto _fail_;
835                 }
836 #endif
837                 PRINT_D(INIT_DBG, "Firmware start timed out");
838                 goto _fail_;
839         }
840         /*
841          *      TODO: Driver shouoldn't wait forever for firmware to get started -
842          *      in case of timeout this should be handled properly
843          */
844         PRINT_D(INIT_DBG, "Firmware successfully started\n");
845
846 _fail_:
847         return ret;
848 }
849 static int linux_wlan_firmware_download(linux_wlan_t *p_nic)
850 {
851
852         int ret = 0;
853
854         if (g_linux_wlan->wilc_firmware == NULL) {
855                 PRINT_ER("Firmware buffer is NULL\n");
856                 ret = -ENOBUFS;
857                 goto _FAIL_;
858         }
859         /**
860          *      do the firmware download
861          **/
862         PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
863         ret = g_linux_wlan->oup.wlan_firmware_download(g_linux_wlan->wilc_firmware->data, g_linux_wlan->wilc_firmware->size);
864         if (ret < 0)
865                 goto _FAIL_;
866
867         /* Freeing FW buffer */
868         PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
869         PRINT_D(INIT_DBG, "Releasing firmware\n");
870         release_firmware(g_linux_wlan->wilc_firmware);
871         g_linux_wlan->wilc_firmware = NULL;
872
873         PRINT_D(INIT_DBG, "Download Succeeded\n");
874
875 _FAIL_:
876         return ret;
877 }
878
879 /* startup configuration - could be changed later using iconfig*/
880 static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_nic)
881 {
882
883         unsigned char c_val[64];
884         #ifndef STATIC_MACADDRESS
885         unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
886         #endif
887
888         /*BugID_5077*/
889         struct WILC_WFI_priv *priv;
890         tstrWILC_WFIDrv *pstrWFIDrv;
891
892         PRINT_D(TX_DBG, "Start configuring Firmware\n");
893         #ifndef STATIC_MACADDRESS
894         get_random_bytes(&mac_add[5], 1);
895         get_random_bytes(&mac_add[4], 1);
896         #endif
897         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
898         pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
899         PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv);
900
901         PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]);
902         wilc_get_chipid(0);
903
904         if (g_linux_wlan->oup.wlan_cfg_set == NULL) {
905                 PRINT_D(INIT_DBG, "Null p[ointer\n");
906                 goto _fail_;
907         }
908
909         *(int *)c_val = 1;
910
911         if (!g_linux_wlan->oup.wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
912                 goto _fail_;
913
914         /*to tell fw that we are going to use PC test - WILC specific*/
915         c_val[0] = 0;
916         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
917                 goto _fail_;
918
919         c_val[0] = INFRASTRUCTURE;
920         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0))
921                 goto _fail_;
922
923         /* c_val[0] = RATE_AUTO; / * bug 4275: Enable autorate and limit it to 24Mbps * / */
924         c_val[0] = RATE_AUTO;
925         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
926                 goto _fail_;
927
928         c_val[0] = G_MIXED_11B_2_MODE;
929         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0))
930                 goto _fail_;
931
932         c_val[0] = 1;
933         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
934                 goto _fail_;
935
936         c_val[0] = G_SHORT_PREAMBLE;
937         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0))
938                 goto _fail_;
939
940         c_val[0] = AUTO_PROT;
941         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
942                 goto _fail_;
943
944 #ifdef SWITCH_LOG_TERMINAL
945         c_val[0] = AUTO_PROT;
946         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LOGTerminal_Switch, c_val, 1, 0, 0))
947                 goto _fail_;
948 #endif
949
950         c_val[0] = ACTIVE_SCAN;
951         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0))
952                 goto _fail_;
953
954         c_val[0] = SITE_SURVEY_OFF;
955         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0))
956                 goto _fail_;
957
958         *((int *)c_val) = 0xffff; /* Never use RTS-CTS */
959         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
960                 goto _fail_;
961
962         *((int *)c_val) = 2346;
963         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
964                 goto _fail_;
965
966         /*  SSID                                                                 */
967         /*  --------------------------------------------------------------       */
968         /*  Configuration :   String with length less than 32 bytes              */
969         /*  Values to set :   Any string with length less than 32 bytes          */
970         /*                    ( In BSS Station Set SSID to "" (null string)      */
971         /*                      to enable Broadcast SSID suppport )              */
972         /*  --------------------------------------------------------------       */
973 #ifndef USE_WIRELESS
974         strcpy(c_val, "nwifi");
975         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SSID, c_val, (strlen(c_val) + 1), 0, 0))
976                 goto _fail_;
977 #endif
978
979         c_val[0] = 0;
980         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0))
981                 goto _fail_;
982
983         c_val[0] = 1;
984         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0))
985                 goto _fail_;
986
987         c_val[0] = NO_POWERSAVE;
988         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
989                 goto _fail_;
990
991         c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */
992         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0))
993                 goto _fail_;
994
995         c_val[0] = OPEN_SYSTEM;
996         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0))
997                 goto _fail_;
998
999         /*  WEP/802 11I Configuration                                            */
1000         /*  ------------------------------------------------------------------   */
1001         /*  Configuration : WEP Key                                              */
1002         /*  Values (0x)   : 5 byte for WEP40 and 13 bytes for WEP104             */
1003         /*                  In case more than 5 bytes are passed on for WEP 40   */
1004         /*                  only first 5 bytes will be used as the key           */
1005         /*  ------------------------------------------------------------------   */
1006
1007         strcpy(c_val, "123456790abcdef1234567890");
1008         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0))
1009                 goto _fail_;
1010
1011         /*  WEP/802 11I Configuration                                            */
1012         /*  ------------------------------------------------------------------   */
1013         /*  Configuration : AES/TKIP WPA/RSNA Pre-Shared Key                     */
1014         /*  Values to set : Any string with length greater than equal to 8 bytes */
1015         /*                  and less than 64 bytes                               */
1016         /*  ------------------------------------------------------------------   */
1017         strcpy(c_val, "12345678");
1018         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0))
1019                 goto _fail_;
1020
1021         /*  IEEE802.1X Key Configuration                                         */
1022         /*  ------------------------------------------------------------------   */
1023         /*  Configuration : Radius Server Access Secret Key                      */
1024         /*  Values to set : Any string with length greater than equal to 8 bytes */
1025         /*                  and less than 65 bytes                               */
1026         /*  ------------------------------------------------------------------   */
1027         strcpy(c_val, "password");
1028         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0))
1029                 goto _fail_;
1030
1031         /*   IEEE802.1X Server Address Configuration                             */
1032         /*  ------------------------------------------------------------------   */
1033         /*  Configuration : Radius Server IP Address                             */
1034         /*  Values to set : Any valid IP Address                                 */
1035         /*  ------------------------------------------------------------------   */
1036         c_val[0] = 192;
1037         c_val[1] = 168;
1038         c_val[2] = 1;
1039         c_val[3] = 112;
1040         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
1041                 goto _fail_;
1042
1043         c_val[0] = 3;
1044         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
1045                 goto _fail_;
1046
1047         c_val[0] = 3;
1048         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
1049                 goto _fail_;
1050
1051         c_val[0] = NORMAL_ACK;
1052         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0))
1053                 goto _fail_;
1054
1055         c_val[0] = 0;
1056         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0))
1057                 goto _fail_;
1058
1059         c_val[0] = 48;
1060         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0))
1061                 goto _fail_;
1062
1063         c_val[0] = 28;
1064         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0))
1065                 goto _fail_;
1066
1067         /*  Beacon Interval                                                      */
1068         /*  -------------------------------------------------------------------- */
1069         /*  Configuration : Sets the beacon interval value                       */
1070         /*  Values to set : Any 16-bit value                                     */
1071         /*  -------------------------------------------------------------------- */
1072
1073         *((int *)c_val) = 100;
1074         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
1075                 goto _fail_;
1076
1077         c_val[0] = REKEY_DISABLE;
1078         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0))
1079                 goto _fail_;
1080
1081         /*  Rekey Time (s) (Used only when the Rekey policy is 2 or 4)           */
1082         /*  -------------------------------------------------------------------- */
1083         /*  Configuration : Sets the Rekey Time (s)                              */
1084         /*  Values to set : 32-bit value                                         */
1085         /*  -------------------------------------------------------------------- */
1086         *((int *)c_val) = 84600;
1087         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
1088                 goto _fail_;
1089
1090         /*  Rekey Packet Count (in 1000s; used when Rekey Policy is 3)           */
1091         /*  -------------------------------------------------------------------- */
1092         /*  Configuration : Sets Rekey Group Packet count                        */
1093         /*  Values to set : 32-bit Value                                         */
1094         /*  -------------------------------------------------------------------- */
1095         *((int *)c_val) = 500;
1096         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0))
1097                 goto _fail_;
1098
1099         c_val[0] = 1;
1100         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0))
1101                 goto _fail_;
1102
1103         c_val[0] = G_SELF_CTS_PROT;
1104         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
1105                 goto _fail_;
1106
1107         c_val[0] = 1;  /* Enable N */
1108         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0))
1109                 goto _fail_;
1110
1111         c_val[0] = HT_MIXED_MODE;
1112         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0))
1113                 goto _fail_;
1114
1115         c_val[0] = 1;   /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */
1116         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0))
1117                 goto _fail_;
1118
1119         memcpy(c_val, mac_add, 6);
1120
1121         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0))
1122                 goto _fail_;
1123
1124         /**
1125          *      AP only
1126          **/
1127         c_val[0] = DETECT_PROTECT_REPORT;
1128         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0))
1129                 goto _fail_;
1130
1131         c_val[0] = RTS_CTS_NONHT_PROT;
1132         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
1133                 goto _fail_;
1134
1135         c_val[0] = 0;
1136         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0))
1137                 goto _fail_;
1138
1139         c_val[0] = MIMO_MODE;
1140         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
1141                 goto _fail_;
1142
1143         c_val[0] = 7;
1144         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0))
1145                 goto _fail_;
1146
1147         c_val[0] = 1; /* Enable N with immediate block ack. */
1148         if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1))
1149                 goto _fail_;
1150
1151         return 0;
1152
1153 _fail_:
1154         return -1;
1155 }
1156
1157 /**************************/
1158 void wilc1000_wlan_deinit(linux_wlan_t *nic)
1159 {
1160
1161         if (g_linux_wlan->wilc1000_initialized) {
1162
1163                 printk("Deinitializing wilc1000  ...\n");
1164
1165                 if (nic == NULL) {
1166                         PRINT_ER("nic is NULL\n");
1167                         return;
1168                 }
1169
1170 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
1171                 /* johnny : remove */
1172                 PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n");
1173 #else
1174                 wilc_bus_set_default_speed();
1175 #endif
1176
1177                 PRINT_D(INIT_DBG, "Disabling IRQ\n");
1178                 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1179                 linux_wlan_disable_irq(IRQ_WAIT);
1180                 #else
1181                   #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
1182
1183                   #else
1184                 mutex_lock(&g_linux_wlan->hif_cs);
1185                 disable_sdio_interrupt();
1186                 mutex_unlock(&g_linux_wlan->hif_cs);
1187                   #endif
1188                 #endif
1189
1190                 /* not sure if the following unlocks are needed or not*/
1191                 if (&g_linux_wlan->rxq_event != NULL)
1192                         up(&g_linux_wlan->rxq_event);
1193
1194                 if (&g_linux_wlan->txq_event != NULL)
1195                         up(&g_linux_wlan->txq_event);
1196
1197         #if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
1198                 /*Removing the work struct from the linux kernel workqueue*/
1199                 if (&g_linux_wlan->rx_work_queue != NULL)
1200                         flush_work(&g_linux_wlan->rx_work_queue);
1201
1202         #elif (RX_BH_TYPE == RX_BH_KTHREAD)
1203                 /* if(&nic->rx_sem != NULL) */
1204                 /* up(&nic->rx_sem); */
1205         #endif
1206
1207                 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
1208                 wlan_deinitialize_threads(nic);
1209
1210                 PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
1211                 deinit_irq(g_linux_wlan);
1212
1213                 if (&g_linux_wlan->oup != NULL) {
1214                         if (g_linux_wlan->oup.wlan_stop != NULL)
1215                                 g_linux_wlan->oup.wlan_stop();
1216                 }
1217
1218                 PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
1219                 wilc_wlan_deinit(nic);
1220 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1221   #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
1222                 PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
1223
1224                 mutex_lock(&g_linux_wlan->hif_cs);
1225                 disable_sdio_interrupt();
1226                 mutex_unlock(&g_linux_wlan->hif_cs);
1227   #endif
1228 #endif
1229
1230                 /*De-Initialize locks*/
1231                 PRINT_D(INIT_DBG, "Deinitializing Locks\n");
1232                 wlan_deinit_locks(g_linux_wlan);
1233
1234                 /* announce that wilc1000 is not initialized */
1235                 g_linux_wlan->wilc1000_initialized = 0;
1236
1237                 PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n");
1238
1239         } else {
1240                 PRINT_D(INIT_DBG, "wilc1000 is not initialized\n");
1241         }
1242 }
1243
1244 int wlan_init_locks(linux_wlan_t *p_nic)
1245 {
1246
1247         PRINT_D(INIT_DBG, "Initializing Locks ...\n");
1248
1249         mutex_init(&g_linux_wlan->hif_cs);
1250         mutex_init(&g_linux_wlan->rxq_cs);
1251         mutex_init(&g_linux_wlan->txq_cs);
1252
1253         /*Added by Amr - BugID_4720*/
1254         spin_lock_init(&g_linux_wlan->txq_spinlock);
1255         sema_init(&g_linux_wlan->txq_add_to_head_cs, 1);
1256
1257         sema_init(&g_linux_wlan->txq_event, 0);
1258         sema_init(&g_linux_wlan->rxq_event, 0);
1259
1260         sema_init(&g_linux_wlan->cfg_event, 0);
1261         sema_init(&g_linux_wlan->sync_event, 0);
1262
1263         sema_init(&g_linux_wlan->rxq_thread_started, 0);
1264         sema_init(&g_linux_wlan->txq_thread_started, 0);
1265
1266         #if (RX_BH_TYPE == RX_BH_KTHREAD)
1267         sema_init(&g_linux_wlan->rx_sem, 0);
1268         #endif
1269
1270         return 0;
1271 }
1272
1273 static int wlan_deinit_locks(linux_wlan_t *nic)
1274 {
1275         PRINT_D(INIT_DBG, "De-Initializing Locks\n");
1276
1277         if (&g_linux_wlan->hif_cs != NULL)
1278                 mutex_destroy(&g_linux_wlan->hif_cs);
1279
1280         if (&g_linux_wlan->rxq_cs != NULL)
1281                 mutex_destroy(&g_linux_wlan->rxq_cs);
1282
1283         if (&g_linux_wlan->txq_cs != NULL)
1284                 mutex_destroy(&g_linux_wlan->txq_cs);
1285
1286         return 0;
1287 }
1288 void linux_to_wlan(wilc_wlan_inp_t *nwi, linux_wlan_t *nic)
1289 {
1290
1291         PRINT_D(INIT_DBG, "Linux to Wlan services ...\n");
1292
1293         nwi->os_context.hif_critical_section = (void *)&g_linux_wlan->hif_cs;
1294         nwi->os_context.os_private = (void *)nic;
1295         nwi->os_context.tx_buffer_size = LINUX_TX_SIZE;
1296         nwi->os_context.txq_critical_section = (void *)&g_linux_wlan->txq_cs;
1297
1298         /*Added by Amr - BugID_4720*/
1299         nwi->os_context.txq_add_to_head_critical_section = (void *)&g_linux_wlan->txq_add_to_head_cs;
1300
1301         /*Added by Amr - BugID_4720*/
1302         nwi->os_context.txq_spin_lock = (void *)&g_linux_wlan->txq_spinlock;
1303
1304         nwi->os_context.txq_wait_event = (void *)&g_linux_wlan->txq_event;
1305
1306 #if defined(MEMORY_STATIC)
1307         nwi->os_context.rx_buffer_size = LINUX_RX_SIZE;
1308 #endif
1309         nwi->os_context.rxq_critical_section = (void *)&g_linux_wlan->rxq_cs;
1310         nwi->os_context.rxq_wait_event = (void *)&g_linux_wlan->rxq_event;
1311         nwi->os_context.cfg_wait_event = (void *)&g_linux_wlan->cfg_event;
1312
1313         nwi->os_func.os_sleep = linux_wlan_msleep;
1314         nwi->os_func.os_debug = linux_wlan_dbg;
1315         nwi->os_func.os_wait = linux_wlan_lock_timeout;
1316
1317 #ifdef WILC_SDIO
1318         nwi->io_func.io_type = HIF_SDIO;
1319         nwi->io_func.io_init = linux_sdio_init;
1320         nwi->io_func.io_deinit = linux_sdio_deinit;
1321         nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52;
1322         nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53;
1323         nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed;
1324         nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed;
1325 #else
1326         nwi->io_func.io_type = HIF_SPI;
1327         nwi->io_func.io_init = linux_spi_init;
1328         nwi->io_func.io_deinit = linux_spi_deinit;
1329         nwi->io_func.u.spi.spi_tx = linux_spi_write;
1330         nwi->io_func.u.spi.spi_rx = linux_spi_read;
1331         nwi->io_func.u.spi.spi_trx = linux_spi_write_read;
1332         nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed;
1333 #endif
1334
1335         /*for now - to be revised*/
1336         #ifdef WILC_FULLY_HOSTING_AP
1337         /* incase of Fully hosted AP, all non cfg pkts are processed here*/
1338         nwi->net_func.rx_indicate = WILC_Process_rx_frame;
1339         #else
1340         nwi->net_func.rx_indicate = frmw_to_linux;
1341         #endif
1342         nwi->net_func.rx_complete = linux_wlan_rx_complete;
1343         nwi->indicate_func.mac_indicate = linux_wlan_mac_indicate;
1344 }
1345
1346 int wlan_initialize_threads(perInterface_wlan_t *nic)
1347 {
1348
1349         int ret = 0;
1350
1351         PRINT_D(INIT_DBG, "Initializing Threads ...\n");
1352
1353 #if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
1354         /*Initialize rx work queue task*/
1355         INIT_WORK(&g_linux_wlan->rx_work_queue, isr_bh_routine);
1356 #elif (RX_BH_TYPE == RX_BH_KTHREAD)
1357         PRINT_D(INIT_DBG, "Creating kthread for Rxq BH\n");
1358         g_linux_wlan->rx_bh_thread = kthread_run(isr_bh_routine, (void *)g_linux_wlan, "K_RXQ_BH");
1359         if (g_linux_wlan->rx_bh_thread == 0) {
1360                 PRINT_ER("couldn't create RX BH thread\n");
1361                 ret = -ENOBUFS;
1362                 goto _fail_;
1363         }
1364 #endif
1365
1366 #ifndef TCP_ENHANCEMENTS
1367         /* create rx task */
1368         PRINT_D(INIT_DBG, "Creating kthread for reception\n");
1369         g_linux_wlan->rxq_thread = kthread_run(linux_wlan_rxq_task, (void *)g_linux_wlan, "K_RXQ_TASK");
1370         if (g_linux_wlan->rxq_thread == 0) {
1371                 PRINT_ER("couldn't create RXQ thread\n");
1372                 ret = -ENOBUFS;
1373                 goto _fail_1;
1374         }
1375
1376         /* wait for RXQ task to start. */
1377         down(&g_linux_wlan->rxq_thread_started);
1378
1379 #endif
1380
1381         /* create tx task */
1382         PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
1383         g_linux_wlan->txq_thread = kthread_run(linux_wlan_txq_task, (void *)g_linux_wlan, "K_TXQ_TASK");
1384         if (g_linux_wlan->txq_thread == 0) {
1385                 PRINT_ER("couldn't create TXQ thread\n");
1386                 ret = -ENOBUFS;
1387                 goto _fail_2;
1388         }
1389 #ifdef DEBUG_MODE
1390         PRINT_D(INIT_DBG, "Creating kthread for Debugging\n");
1391         g_linux_wlan->txq_thread = kthread_run(DebuggingThreadTask, (void *)g_linux_wlan, "DebugThread");
1392         if (g_linux_wlan->txq_thread == 0) {
1393                 PRINT_ER("couldn't create TXQ thread\n");
1394                 ret = -ENOBUFS;
1395                 goto _fail_2;
1396         }
1397 #endif
1398         /* wait for TXQ task to start. */
1399         down(&g_linux_wlan->txq_thread_started);
1400
1401         return 0;
1402
1403 _fail_2:
1404         /*De-Initialize 2nd thread*/
1405         g_linux_wlan->close = 1;
1406         up(&g_linux_wlan->rxq_event);
1407         kthread_stop(g_linux_wlan->rxq_thread);
1408
1409 #ifndef TCP_ENHANCEMENTS
1410 _fail_1:
1411 #endif
1412         #if (RX_BH_TYPE == RX_BH_KTHREAD)
1413         /*De-Initialize 1st thread*/
1414         g_linux_wlan->close = 1;
1415         up(&g_linux_wlan->rx_sem);
1416         kthread_stop(g_linux_wlan->rx_bh_thread);
1417 _fail_:
1418         #endif
1419         g_linux_wlan->close = 0;
1420         return ret;
1421 }
1422
1423 static void wlan_deinitialize_threads(linux_wlan_t *nic)
1424 {
1425
1426         g_linux_wlan->close = 1;
1427         PRINT_D(INIT_DBG, "Deinitializing Threads\n");
1428         if (&g_linux_wlan->rxq_event != NULL)
1429                 up(&g_linux_wlan->rxq_event);
1430
1431         if (g_linux_wlan->rxq_thread != NULL) {
1432                 kthread_stop(g_linux_wlan->rxq_thread);
1433                 g_linux_wlan->rxq_thread = NULL;
1434         }
1435
1436         if (&g_linux_wlan->txq_event != NULL)
1437                 up(&g_linux_wlan->txq_event);
1438
1439         if (g_linux_wlan->txq_thread != NULL) {
1440                 kthread_stop(g_linux_wlan->txq_thread);
1441                 g_linux_wlan->txq_thread = NULL;
1442         }
1443
1444         #if (RX_BH_TYPE == RX_BH_KTHREAD)
1445         if (&g_linux_wlan->rx_sem != NULL)
1446                 up(&g_linux_wlan->rx_sem);
1447
1448         if (g_linux_wlan->rx_bh_thread != NULL) {
1449                 kthread_stop(g_linux_wlan->rx_bh_thread);
1450                 g_linux_wlan->rx_bh_thread = NULL;
1451         }
1452         #endif
1453 }
1454
1455 #ifdef STATIC_MACADDRESS
1456 const char *path_string[] = {
1457         "/etc/wlan",
1458         "/data/wlan",
1459 };
1460
1461 static int linux_wlan_read_mac_addr(void *vp)
1462 {
1463         int ret = 0;
1464         struct file *fp = (struct file *)-ENOENT;
1465         mm_segment_t old_fs;
1466         loff_t pos = 0;
1467         int index;
1468         int array_size = ARRAY_SIZE(path_string);
1469
1470         /* change to KERNEL_DS address limit */
1471         old_fs = get_fs();
1472         set_fs(KERNEL_DS);
1473
1474         for (index = 0; index < array_size; index++) {
1475                 fp = filp_open(path_string[index], O_WRONLY, 0640);
1476                 if (!fp) {
1477                         ret = -1;
1478                         goto exit;
1479                 }
1480
1481                 /*No such file or directory */
1482                 if (IS_ERR(fp) || !fp->f_op) {
1483                         get_random_bytes(&mac_add[3], 3);
1484                         /* open file to write */
1485                         fp = filp_open(path_string[index], O_WRONLY | O_CREAT, 0640);
1486
1487                         if (!fp || IS_ERR(fp)) {
1488                                 ret = -1;
1489                                 continue;
1490                         } else {
1491                                 /* write buf to file */
1492                                 fp->f_op->write(fp, mac_add, 6, &pos);
1493                                 break;
1494                         }
1495                 } else {
1496                         /* read file to buf */
1497                         fp->f_op->read(fp, mac_add, 6, &pos);
1498                         break;
1499                 }
1500         }
1501
1502         if (index == array_size)
1503                 PRINT_ER("random MAC\n");
1504
1505 exit:
1506         if (fp && !IS_ERR(fp))
1507                 filp_close(fp, NULL);
1508
1509         set_fs(old_fs);
1510
1511         return ret;
1512 }
1513 #endif
1514
1515 #ifdef COMPLEMENT_BOOT
1516
1517 extern volatile int probe;
1518 extern uint8_t core_11b_ready(void);
1519
1520 #define READY_CHECK_THRESHOLD           30
1521 extern void wilc_wlan_global_reset(void);
1522 uint8_t wilc1000_prepare_11b_core(wilc_wlan_inp_t *nwi, wilc_wlan_oup_t *nwo, linux_wlan_t *nic)
1523 {
1524         uint8_t trials = 0;
1525
1526         while ((core_11b_ready() && (READY_CHECK_THRESHOLD > (trials++)))) {
1527                 PRINT_D(INIT_DBG, "11b core not ready yet: %u\n", trials);
1528                 wilc_wlan_deinit(nic);
1529                 wilc_wlan_global_reset();
1530                 sdio_unregister_driver(&wilc_bus);
1531
1532                 linux_wlan_device_detection(0);
1533
1534                 mdelay(100);
1535
1536                 linux_wlan_device_detection(1);
1537
1538                 sdio_register_driver(&wilc_bus);
1539
1540                 while (!probe)
1541                         msleep(100);
1542                 probe = 0;
1543                 g_linux_wlan->wilc_sdio_func = local_sdio_func;
1544                 linux_to_wlan(nwi, nic);
1545                 wilc_wlan_init(nwi, nwo);
1546         }
1547
1548         if (READY_CHECK_THRESHOLD <= trials)
1549                 return 1;
1550         else
1551                 return 0;
1552
1553 }
1554
1555 int repeat_power_cycle(perInterface_wlan_t *nic)
1556 {
1557         int ret = 0;
1558         wilc_wlan_inp_t nwi;
1559         wilc_wlan_oup_t nwo;
1560
1561         sdio_unregister_driver(&wilc_bus);
1562
1563         linux_wlan_device_detection(0);
1564         linux_wlan_device_power(0);
1565         msleep(100);
1566         linux_wlan_device_power(1);
1567         msleep(80);
1568         linux_wlan_device_detection(1);
1569         msleep(20);
1570
1571         sdio_register_driver(&wilc_bus);
1572
1573         /* msleep(1000); */
1574         while (!probe)
1575                 msleep(100);
1576         probe = 0;
1577         g_linux_wlan->wilc_sdio_func = local_sdio_func;
1578         linux_to_wlan(&nwi, g_linux_wlan);
1579         ret = wilc_wlan_init(&nwi, &nwo);
1580
1581         g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT;
1582         #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1583         enable_sdio_interrupt();
1584         #endif
1585
1586         if (linux_wlan_get_firmware(nic)) {
1587                 PRINT_ER("Can't get firmware\n");
1588                 ret = -1;
1589                 goto __fail__;
1590         }
1591
1592         /*Download firmware*/
1593         ret = linux_wlan_firmware_download(g_linux_wlan);
1594         if (ret < 0) {
1595                 PRINT_ER("Failed to download firmware\n");
1596                 goto __fail__;
1597         }
1598         /* Start firmware*/
1599         ret = linux_wlan_start_firmware(nic);
1600         if (ret < 0)
1601                 PRINT_ER("Failed to start firmware\n");
1602 __fail__:
1603         return ret;
1604 }
1605 #endif
1606
1607 int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
1608 {
1609         wilc_wlan_inp_t nwi;
1610         wilc_wlan_oup_t nwo;
1611         perInterface_wlan_t *nic = p_nic;
1612         int ret = 0;
1613
1614         if (!g_linux_wlan->wilc1000_initialized) {
1615                 g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT;
1616                 g_linux_wlan->close = 0;
1617                 g_linux_wlan->wilc1000_initialized = 0;
1618
1619                 wlan_init_locks(g_linux_wlan);
1620
1621 #ifdef STATIC_MACADDRESS
1622                 wilc_mac_thread = kthread_run(linux_wlan_read_mac_addr, NULL, "wilc_mac_thread");
1623                 if (wilc_mac_thread < 0)
1624                         PRINT_ER("couldn't create Mac addr thread\n");
1625 #endif
1626
1627                 linux_to_wlan(&nwi, g_linux_wlan);
1628
1629                 ret = wilc_wlan_init(&nwi, &nwo);
1630                 if (ret < 0) {
1631                         PRINT_ER("Initializing WILC_Wlan FAILED\n");
1632                         ret = -EIO;
1633                         goto _fail_locks_;
1634                 }
1635                 memcpy(&g_linux_wlan->oup, &nwo, sizeof(wilc_wlan_oup_t));
1636
1637                 /*Save the oup structre into global pointer*/
1638                 gpstrWlanOps = &g_linux_wlan->oup;
1639
1640                 ret = wlan_initialize_threads(nic);
1641                 if (ret < 0) {
1642                         PRINT_ER("Initializing Threads FAILED\n");
1643                         ret = -EIO;
1644                         goto _fail_wilc_wlan_;
1645                 }
1646
1647 #if (defined WILC_SDIO) && (defined COMPLEMENT_BOOT)
1648                 if (wilc1000_prepare_11b_core(&nwi, &nwo, g_linux_wlan)) {
1649                         PRINT_ER("11b Core is not ready\n");
1650                         ret = -EIO;
1651                         goto _fail_threads_;
1652                 }
1653 #endif
1654
1655 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1656                 if (init_irq(g_linux_wlan)) {
1657                         PRINT_ER("couldn't initialize IRQ\n");
1658                         ret = -EIO;
1659                         goto _fail_threads_;
1660                 }
1661 #endif
1662
1663 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1664                 if (enable_sdio_interrupt()) {
1665                         PRINT_ER("couldn't initialize IRQ\n");
1666                         ret = -EIO;
1667                         goto _fail_irq_init_;
1668                 }
1669 #endif
1670
1671                 if (linux_wlan_get_firmware(nic)) {
1672                         PRINT_ER("Can't get firmware\n");
1673                         ret = -EIO;
1674                         goto _fail_irq_enable_;
1675                 }
1676
1677                 /*Download firmware*/
1678                 ret = linux_wlan_firmware_download(g_linux_wlan);
1679                 if (ret < 0) {
1680                         PRINT_ER("Failed to download firmware\n");
1681                         ret = -EIO;
1682                         goto _fail_irq_enable_;
1683                 }
1684
1685                 /* Start firmware*/
1686                 ret = linux_wlan_start_firmware(nic);
1687                 if (ret < 0) {
1688                         PRINT_ER("Failed to start firmware\n");
1689                         ret = -EIO;
1690                         goto _fail_irq_enable_;
1691                 }
1692
1693                 wilc_bus_set_max_speed();
1694
1695                 if (g_linux_wlan->oup.wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) {
1696                         int size;
1697                         char Firmware_ver[20];
1698
1699                         size = g_linux_wlan->oup.wlan_cfg_get_value(
1700                                         WID_FIRMWARE_VERSION,
1701                                         Firmware_ver, sizeof(Firmware_ver));
1702                         Firmware_ver[size] = '\0';
1703                         PRINT_D(INIT_DBG, "***** Firmware Ver = %s  *******\n", Firmware_ver);
1704                 }
1705                 /* Initialize firmware with default configuration */
1706                 ret = linux_wlan_init_test_config(dev, g_linux_wlan);
1707
1708                 if (ret < 0) {
1709                         PRINT_ER("Failed to configure firmware\n");
1710                         ret = -EIO;
1711                         goto _fail_fw_start_;
1712                 }
1713
1714                 g_linux_wlan->wilc1000_initialized = 1;
1715                 return 0; /*success*/
1716
1717 _fail_fw_start_:
1718                 if (&g_linux_wlan->oup != NULL) {
1719                         if (g_linux_wlan->oup.wlan_stop != NULL)
1720                                 g_linux_wlan->oup.wlan_stop();
1721                 }
1722
1723 _fail_irq_enable_:
1724 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1725                 disable_sdio_interrupt();
1726 _fail_irq_init_:
1727 #endif
1728 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1729                 deinit_irq(g_linux_wlan);
1730
1731 #endif
1732 _fail_threads_:
1733                 wlan_deinitialize_threads(g_linux_wlan);
1734 _fail_wilc_wlan_:
1735                 wilc_wlan_deinit(g_linux_wlan);
1736 _fail_locks_:
1737                 wlan_deinit_locks(g_linux_wlan);
1738                 PRINT_ER("WLAN Iinitialization FAILED\n");
1739         } else {
1740                 PRINT_D(INIT_DBG, "wilc1000 already initialized\n");
1741         }
1742         return ret;
1743 }
1744
1745 /*
1746  *      - this function will be called automatically by OS when module inserted.
1747  */
1748
1749 #if !defined(NM73131_0_BOARD)
1750 int mac_init_fn(struct net_device *ndev)
1751 {
1752
1753         /*Why we do this !!!*/
1754         netif_start_queue(ndev); /* ma */
1755         netif_stop_queue(ndev); /* ma */
1756
1757         return 0;
1758 }
1759 #else
1760 int mac_init_fn(struct net_device *ndev)
1761 {
1762
1763         unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x00};
1764         /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
1765         memcpy(ndev->dev_addr, mac_add, 6);
1766
1767         if (!is_valid_ether_addr(ndev->dev_addr)) {
1768                 PRINT_ER("Error: Wrong MAC address\n");
1769                 return -EINVAL;
1770         }
1771
1772         return 0;
1773 }
1774 #endif
1775
1776 void    WILC_WFI_frame_register(struct wiphy *wiphy, struct net_device *dev,
1777                                 u16 frame_type, bool reg);
1778
1779 /* This fn is called, when this device is setup using ifconfig */
1780 #if !defined(NM73131_0_BOARD)
1781 int mac_open(struct net_device *ndev)
1782 {
1783         perInterface_wlan_t *nic;
1784
1785         /*BugID_5213*/
1786         /*No need for setting mac address here anymore,*/
1787         /*Just set it in init_test_config()*/
1788         unsigned char mac_add[ETH_ALEN] = {0};
1789         int ret = 0;
1790         int i = 0;
1791         struct WILC_WFI_priv *priv;
1792
1793         nic = netdev_priv(ndev);
1794         priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1795         PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
1796
1797         #ifdef USE_WIRELESS
1798         ret = WILC_WFI_InitHostInt(ndev);
1799         if (ret < 0) {
1800                 PRINT_ER("Failed to initialize host interface\n");
1801
1802                 return ret;
1803         }
1804         #endif
1805
1806         /*initialize platform*/
1807         PRINT_D(INIT_DBG, "*** re-init ***\n");
1808         ret = wilc1000_wlan_init(ndev, nic);
1809         if (ret < 0) {
1810                 PRINT_ER("Failed to initialize wilc1000\n");
1811                 WILC_WFI_DeInitHostInt(ndev);
1812                 return ret;
1813         }
1814
1815         Set_machw_change_vir_if(false);
1816
1817         host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add);
1818         PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
1819
1820         /* loop through the NUM of supported devices and set the MAC address */
1821         for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
1822                 if (ndev == g_linux_wlan->strInterfaceInfo[i].wilc_netdev) {
1823                         memcpy(g_linux_wlan->strInterfaceInfo[i].aSrcAddress, mac_add, ETH_ALEN);
1824                         g_linux_wlan->strInterfaceInfo[i].drvHandler = priv->hWILCWFIDrv;
1825                         break;
1826                 }
1827         }
1828
1829         /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
1830         memcpy(ndev->dev_addr, g_linux_wlan->strInterfaceInfo[i].aSrcAddress, ETH_ALEN);
1831
1832         if (!is_valid_ether_addr(ndev->dev_addr)) {
1833                 PRINT_ER("Error: Wrong MAC address\n");
1834                 ret = -EINVAL;
1835                 goto _err_;
1836         }
1837
1838         WILC_WFI_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev,
1839                                 nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg);
1840         WILC_WFI_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev,
1841                                 nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg);
1842         netif_wake_queue(ndev);
1843         g_linux_wlan->open_ifcs++;
1844         nic->mac_opened = 1;
1845         return 0;
1846
1847 _err_:
1848         WILC_WFI_DeInitHostInt(ndev);
1849         wilc1000_wlan_deinit(g_linux_wlan);
1850         return ret;
1851 }
1852 #else
1853 int mac_open(struct net_device *ndev)
1854 {
1855
1856         linux_wlan_t *nic;
1857
1858         nic = netdev_priv(ndev);
1859
1860         /*initialize platform*/
1861         if (wilc1000_wlan_init(nic)) {
1862                 PRINT_ER("Failed to initialize platform\n");
1863                 return 1;
1864         }
1865         /* Start the network interface queue for this device */
1866         PRINT_D(INIT_DBG, "Starting netifQ\n");
1867         netif_start_queue(ndev);
1868 /*      down(&close_exit_sync); */
1869         return 0;
1870 }
1871 #endif
1872
1873 struct net_device_stats *mac_stats(struct net_device *dev)
1874 {
1875         perInterface_wlan_t *nic = netdev_priv(dev);
1876
1877         return &nic->netstats;
1878 }
1879
1880 /* Setup the multicast filter */
1881 static void wilc_set_multicast_list(struct net_device *dev)
1882 {
1883
1884         struct netdev_hw_addr *ha;
1885         struct WILC_WFI_priv *priv;
1886         tstrWILC_WFIDrv *pstrWFIDrv;
1887         int i = 0;
1888
1889         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1890         pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
1891
1892         if (!dev)
1893                 return;
1894
1895         PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", dev->mc.count);
1896
1897         if (dev->flags & IFF_PROMISC) {
1898                 /* Normally, we should configure the chip to retrive all packets
1899                  * but we don't wanna support this right now */
1900                 /* TODO: add promiscuous mode support */
1901                 PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n");
1902                 return;
1903         }
1904
1905         /* If there's more addresses than we handle, get all multicast
1906          * packets and sort them out in software. */
1907         if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
1908                 PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
1909                 /* get all multicast packets */
1910                 host_int_setup_multicast_filter(pstrWFIDrv, false, 0);
1911                 return;
1912         }
1913
1914         /* No multicast?  Just get our own stuff */
1915         if ((dev->mc.count) == 0) {
1916                 PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
1917                 host_int_setup_multicast_filter(pstrWFIDrv, true, 0);
1918                 return;
1919         }
1920
1921         /* Store all of the multicast addresses in the hardware filter */
1922         netdev_for_each_mc_addr(ha, dev)
1923         {
1924                 memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN);
1925                 PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
1926                         gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]);
1927                 i++;
1928         }
1929
1930         host_int_setup_multicast_filter(pstrWFIDrv, true, (dev->mc.count));
1931
1932         return;
1933
1934 }
1935
1936 static void linux_wlan_tx_complete(void *priv, int status)
1937 {
1938
1939         struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
1940
1941         if (status == 1)
1942                 PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1943         else
1944                 PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1945         /* Free the SK Buffer, its work is done */
1946         dev_kfree_skb(pv_data->skb);
1947         kfree(pv_data);
1948 }
1949
1950 int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
1951 {
1952         perInterface_wlan_t *nic;
1953         struct tx_complete_data *tx_data = NULL;
1954         int QueueCount;
1955         char *pu8UdpBuffer;
1956         struct iphdr *ih;
1957         struct ethhdr *eth_h;
1958
1959         nic = netdev_priv(ndev);
1960
1961         PRINT_D(INT_DBG, "\n========\n IntUH: %d - IntBH: %d - IntCld: %d\n========\n", int_rcvdU, int_rcvdB, int_clrd);
1962         PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
1963
1964         /* Stop the network interface queue */
1965         if (skb->dev != ndev) {
1966                 PRINT_ER("Packet not destined to this device\n");
1967                 return 0;
1968         }
1969
1970         tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC);
1971         if (tx_data == NULL) {
1972                 PRINT_ER("Failed to allocate memory for tx_data structure\n");
1973                 dev_kfree_skb(skb);
1974                 netif_wake_queue(ndev);
1975                 return 0;
1976         }
1977
1978         tx_data->buff = skb->data;
1979         tx_data->size = skb->len;
1980         tx_data->skb  = skb;
1981
1982         eth_h = (struct ethhdr *)(skb->data);
1983         if (eth_h->h_proto == 0x8e88)
1984                 PRINT_D(INIT_DBG, "EAPOL transmitted\n");
1985
1986         /*get source and dest ip addresses*/
1987         ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1988
1989         pu8UdpBuffer = (char *)ih + sizeof(struct iphdr);
1990         if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68))
1991                 PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]);
1992
1993         PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
1994
1995         /* Send packet to MAC HW - for now the tx_complete function will be just status
1996          * indicator. still not sure if I need to suspend host transmission till the tx_complete
1997          * function called or not?
1998          * allocated buffer will be freed in tx_complete function.
1999          */
2000         PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
2001         nic->netstats.tx_packets++;
2002         nic->netstats.tx_bytes += tx_data->size;
2003         tx_data->pBssid = g_linux_wlan->strInterfaceInfo[nic->u8IfIdx].aBSSID;
2004         #ifndef WILC_FULLY_HOSTING_AP
2005         QueueCount = g_linux_wlan->oup.wlan_add_to_tx_que((void *)tx_data,
2006                                                           tx_data->buff,
2007                                                           tx_data->size,
2008                                                           linux_wlan_tx_complete);
2009         #else
2010         QueueCount = WILC_Xmit_data((void *)tx_data, HOST_TO_WLAN);
2011         #endif /* WILC_FULLY_HOSTING_AP */
2012
2013         if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) {
2014                 netif_stop_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev);
2015                 netif_stop_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev);
2016         }
2017
2018         return 0;
2019 }
2020
2021 int mac_close(struct net_device *ndev)
2022 {
2023         struct WILC_WFI_priv *priv;
2024         perInterface_wlan_t *nic;
2025         tstrWILC_WFIDrv *pstrWFIDrv;
2026
2027         nic = netdev_priv(ndev);
2028
2029         if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) {
2030                 PRINT_ER("nic = NULL\n");
2031                 return 0;
2032         }
2033
2034         priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
2035
2036         if (priv == NULL) {
2037                 PRINT_ER("priv = NULL\n");
2038                 return 0;
2039         }
2040
2041         pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
2042
2043         PRINT_D(GENERIC_DBG, "Mac close\n");
2044
2045         if (g_linux_wlan == NULL) {
2046                 PRINT_ER("g_linux_wlan = NULL\n");
2047                 return 0;
2048         }
2049
2050         if (pstrWFIDrv == NULL) {
2051                 PRINT_ER("pstrWFIDrv = NULL\n");
2052                 return 0;
2053         }
2054
2055         if ((g_linux_wlan->open_ifcs) > 0) {
2056                 g_linux_wlan->open_ifcs--;
2057         } else {
2058                 PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n");
2059                 return 0;
2060         }
2061
2062         if (nic->wilc_netdev != NULL) {
2063                 /* Stop the network interface queue */
2064                 netif_stop_queue(nic->wilc_netdev);
2065
2066                 #ifdef USE_WIRELESS
2067                 WILC_WFI_DeInitHostInt(nic->wilc_netdev);
2068                 #endif
2069         }
2070
2071         if (g_linux_wlan->open_ifcs == 0) {
2072                 PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
2073                 g_linux_wlan->close = 1;
2074                 wilc1000_wlan_deinit(g_linux_wlan);
2075                 #ifdef USE_WIRELESS
2076                 #ifdef WILC_AP_EXTERNAL_MLME
2077                 WILC_WFI_deinit_mon_interface();
2078                 #endif
2079                 #endif
2080         }
2081
2082         up(&close_exit_sync);
2083         nic->mac_opened = 0;
2084
2085         return 0;
2086 }
2087
2088 int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
2089 {
2090
2091         u8 *buff = NULL;
2092         s8 rssi;
2093         u32 size = 0, length = 0;
2094         perInterface_wlan_t *nic;
2095         struct WILC_WFI_priv *priv;
2096         s32 s32Error = WILC_SUCCESS;
2097
2098         /* struct iwreq *wrq = (struct iwreq *) req;    // tony moved to case SIOCSIWPRIV */
2099         #ifdef USE_WIRELESS
2100         nic = netdev_priv(ndev);
2101
2102         if (!g_linux_wlan->wilc1000_initialized)
2103                 return 0;
2104
2105         #endif
2106
2107         switch (cmd) {
2108
2109         /* ]] 2013-06-24 */
2110         case SIOCSIWPRIV:
2111         {
2112                 struct iwreq *wrq = (struct iwreq *) req;               /* added by tony */
2113
2114                 size = wrq->u.data.length;
2115
2116                 if (size && wrq->u.data.pointer) {
2117
2118                         buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length);
2119                         if (IS_ERR(buff)) {
2120                                 s32Error = PTR_ERR(buff);
2121                                 goto done;
2122                         }
2123
2124                         if (strncasecmp(buff, "RSSI", length) == 0) {
2125
2126                                         #ifdef USE_WIRELESS
2127                                 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
2128                                 s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi));
2129                                 if (s32Error)
2130                                         PRINT_ER("Failed to send get rssi param's message queue ");
2131                                         #endif
2132                                 PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
2133
2134                                 /*Rounding up the rssi negative value*/
2135                                 rssi += 5;
2136
2137                                 snprintf(buff, size, "rssi %d", rssi);
2138
2139                                 if (copy_to_user(wrq->u.data.pointer, buff, size)) {
2140                                         PRINT_ER("%s: failed to copy data to user buffer\n", __func__);
2141                                         s32Error = -EFAULT;
2142                                         goto done;
2143                                 }
2144                         }
2145                 }
2146         }
2147         break;
2148
2149         default:
2150         {
2151                 PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd);
2152                 s32Error = -EOPNOTSUPP;
2153                 goto done;
2154         }
2155         }
2156
2157 done:
2158
2159         kfree(buff);
2160
2161         return s32Error;
2162 }
2163
2164 void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset)
2165 {
2166
2167         unsigned int frame_len = 0;
2168         int stats;
2169         unsigned char *buff_to_send = NULL;
2170         struct sk_buff *skb;
2171 #ifndef TCP_ENHANCEMENTS
2172         char *pu8UdpBuffer;
2173         struct iphdr *ih;
2174 #endif
2175         struct net_device *wilc_netdev;
2176         perInterface_wlan_t *nic;
2177
2178         wilc_netdev = GetIfHandler(buff);
2179         if (wilc_netdev == NULL)
2180                 return;
2181
2182         buff += pkt_offset;
2183         nic = netdev_priv(wilc_netdev);
2184
2185         if (size > 0) {
2186
2187                 frame_len = size;
2188                 buff_to_send = buff;
2189
2190                 /* Need to send the packet up to the host, allocate a skb buffer */
2191                 skb = dev_alloc_skb(frame_len);
2192                 if (skb == NULL) {
2193                         PRINT_ER("Low memory - packet droped\n");
2194                         return;
2195                 }
2196
2197                 skb_reserve(skb, (unsigned int)skb->data & 0x3);
2198
2199                 if (g_linux_wlan == NULL || wilc_netdev == NULL)
2200                         PRINT_ER("wilc_netdev in g_linux_wlan is NULL");
2201                 skb->dev = wilc_netdev;
2202
2203                 if (skb->dev == NULL)
2204                         PRINT_ER("skb->dev is NULL\n");
2205
2206                 /*
2207                  * for(i=0;i<40;i++)
2208                  * {
2209                  *      if(i<frame_len)
2210                  *              WILC_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]);
2211                  *
2212                  * }*/
2213
2214                 /* skb_put(skb, frame_len); */
2215                 memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
2216
2217                 /* WILC_PRINTF("After MEM_CPY\n"); */
2218
2219                 /* nic = netdev_priv(wilc_netdev); */
2220
2221 #ifdef USE_WIRELESS
2222                 /*      if(nic->monitor_flag)
2223                  *      {
2224                  *              WILC_WFI_monitor_rx(nic->wilc_netdev,skb);
2225                  *              return;
2226                  *      }*/
2227 #endif
2228                 skb->protocol = eth_type_trans(skb, wilc_netdev);
2229                         #ifndef TCP_ENHANCEMENTS
2230                 /*get source and dest ip addresses*/
2231                 ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
2232
2233                 pu8UdpBuffer = (char *)ih + sizeof(struct iphdr);
2234                 if (buff_to_send[35] == 67 && buff_to_send[37] == 68)
2235                         PRINT_D(RX_DBG, "DHCP Message received\n");
2236                 if (buff_to_send[12] == 0x88 && buff_to_send[13] == 0x8e)
2237                         PRINT_D(GENERIC_DBG, "eapol received\n");
2238                         #endif
2239                 /* Send the packet to the stack by giving it to the bridge */
2240                 nic->netstats.rx_packets++;
2241                 nic->netstats.rx_bytes += frame_len;
2242                 skb->ip_summed = CHECKSUM_UNNECESSARY;
2243                 stats = netif_rx(skb);
2244                 PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
2245         }
2246                 #ifndef TCP_ENHANCEMENTS
2247         else
2248                 PRINT_ER("Discard sending packet with len = %d\n", size);
2249                 #endif
2250 }
2251
2252 void WILC_WFI_mgmt_rx(uint8_t *buff, uint32_t size)
2253 {
2254         int i = 0;
2255         perInterface_wlan_t *nic;
2256
2257         /*BugID_5450*/
2258         /*Pass the frame on the monitor interface, if any.*/
2259         /*Otherwise, pass it on p2p0 netdev, if registered on it*/
2260         for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
2261                 nic = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2262                 if (nic->monitor_flag) {
2263                         WILC_WFI_monitor_rx(buff, size);
2264                         return;
2265                 }
2266         }
2267
2268         #ifdef WILC_P2P
2269         nic = netdev_priv(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); /* p2p0 */
2270         if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) ||
2271             (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg))
2272                 WILC_WFI_p2p_rx(g_linux_wlan->strInterfaceInfo[1].wilc_netdev, buff, size);
2273         #endif
2274 }
2275
2276 int wilc_netdev_init(void)
2277 {
2278
2279         int i;
2280         perInterface_wlan_t *nic;
2281         struct net_device *ndev;
2282
2283         sema_init(&close_exit_sync, 0);
2284
2285         /*create the common structure*/
2286         g_linux_wlan = WILC_MALLOC(sizeof(linux_wlan_t));
2287         memset(g_linux_wlan, 0, sizeof(linux_wlan_t));
2288
2289         /*Reset interrupt count debug*/
2290         int_rcvdU = 0;
2291         int_rcvdB = 0;
2292         int_clrd = 0;
2293         #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
2294         register_inetaddr_notifier(&g_dev_notifier);
2295         #endif
2296
2297         for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
2298                 /*allocate first ethernet device with perinterface_wlan_t as its private data*/
2299                 ndev = alloc_etherdev(sizeof(perInterface_wlan_t));
2300                 if (!ndev) {
2301                         PRINT_ER("Failed to allocate ethernet dev\n");
2302                         return -1;
2303                 }
2304
2305                 nic = netdev_priv(ndev);
2306                 memset(nic, 0, sizeof(perInterface_wlan_t));
2307
2308                 /*Name the Devices*/
2309                 if (i == 0) {
2310                 #if defined(NM73131)    /* tony, 2012-09-20 */
2311                         strcpy(ndev->name, "wilc_eth%d");
2312                 #elif defined(PLAT_CLM9722)                     /* rachel */
2313                         strcpy(ndev->name, "eth%d");
2314                 #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */
2315                         strcpy(ndev->name, "wlan%d");
2316                 #endif
2317                 } else
2318                         strcpy(ndev->name, "p2p%d");
2319
2320                 nic->u8IfIdx = g_linux_wlan->u8NoIfcs;
2321                 nic->wilc_netdev = ndev;
2322                 g_linux_wlan->strInterfaceInfo[g_linux_wlan->u8NoIfcs].wilc_netdev = ndev;
2323                 g_linux_wlan->u8NoIfcs++;
2324                 ndev->netdev_ops = &wilc_netdev_ops;
2325
2326                 #ifdef USE_WIRELESS
2327                 {
2328                         struct wireless_dev *wdev;
2329                         /*Register WiFi*/
2330                         wdev = WILC_WFI_WiphyRegister(ndev);
2331
2332                         #ifdef WILC_SDIO
2333                         /* set netdev, tony */
2334                         SET_NETDEV_DEV(ndev, &local_sdio_func->dev);
2335                         #endif
2336
2337                         if (wdev == NULL) {
2338                                 PRINT_ER("Can't register WILC Wiphy\n");
2339                                 return -1;
2340                         }
2341
2342                         /*linking the wireless_dev structure with the netdevice*/
2343                         nic->wilc_netdev->ieee80211_ptr = wdev;
2344                         nic->wilc_netdev->ml_priv = nic;
2345                         wdev->netdev = nic->wilc_netdev;
2346                         nic->netstats.rx_packets = 0;
2347                         nic->netstats.tx_packets = 0;
2348                         nic->netstats.rx_bytes = 0;
2349                         nic->netstats.tx_bytes = 0;
2350
2351                 }
2352                 #endif
2353
2354                 if (register_netdev(ndev)) {
2355                         PRINT_ER("Device couldn't be registered - %s\n", ndev->name);
2356                         return -1; /* ERROR */
2357                 }
2358
2359                 nic->iftype = STATION_MODE;
2360                 nic->mac_opened = 0;
2361
2362         }
2363
2364         #ifndef WILC_SDIO
2365         if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) {
2366                 PRINT_ER("Can't initialize SPI\n");
2367                 return -1; /* ERROR */
2368         }
2369         g_linux_wlan->wilc_spidev = wilc_spi_dev;
2370         #else
2371         g_linux_wlan->wilc_sdio_func = local_sdio_func;
2372         #endif
2373
2374         return 0;
2375 }
2376
2377 /*The 1st function called after module inserted*/
2378 static int __init init_wilc_driver(void)
2379 {
2380 #if defined(WILC_DEBUGFS)
2381         if (wilc_debugfs_init() < 0) {
2382                 PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n");
2383                 return -1;
2384         }
2385 #endif
2386
2387         printk("IN INIT FUNCTION\n");
2388         printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n");
2389
2390         linux_wlan_device_power(1);
2391         msleep(100);
2392         linux_wlan_device_detection(1);
2393
2394 #ifdef WILC_SDIO
2395         {
2396                 int ret;
2397
2398                 ret = sdio_register_driver(&wilc_bus);
2399                 if (ret < 0)
2400                         PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n");
2401
2402                 return ret;
2403         }
2404 #else
2405         PRINT_D(INIT_DBG, "Initializing netdev\n");
2406         if (wilc_netdev_init())
2407                 PRINT_ER("Couldn't initialize netdev\n");
2408         return 0;
2409 #endif
2410 }
2411 late_initcall(init_wilc_driver);
2412
2413 static void __exit exit_wilc_driver(void)
2414 {
2415         int i = 0;
2416         perInterface_wlan_t *nic[NUM_CONCURRENT_IFC] = {NULL,};
2417         #define CLOSE_TIMEOUT (12 * 1000)
2418
2419         if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL)
2420                                        || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) {
2421         #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
2422                 unregister_inetaddr_notifier(&g_dev_notifier);
2423         #endif
2424
2425                 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
2426                         nic[i] = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2427         }
2428
2429         if ((g_linux_wlan != NULL) && g_linux_wlan->wilc_firmware != NULL) {
2430                 release_firmware(g_linux_wlan->wilc_firmware);
2431                 g_linux_wlan->wilc_firmware = NULL;
2432         }
2433
2434         if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL)
2435                                        || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) {
2436                 PRINT_D(INIT_DBG, "Waiting for mac_close ....\n");
2437
2438                 if (linux_wlan_lock_timeout(&close_exit_sync, CLOSE_TIMEOUT) < 0)
2439                         PRINT_D(INIT_DBG, "Closed TimedOUT\n");
2440                 else
2441                         PRINT_D(INIT_DBG, "mac_closed\n");
2442
2443                 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
2444                         /* close all opened interfaces */
2445                         if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev != NULL) {
2446                                 if (nic[i]->mac_opened)
2447                                         mac_close(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2448                         }
2449                 }
2450                 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
2451                         PRINT_D(INIT_DBG, "Unregistering netdev %p\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2452                         unregister_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2453                         #ifdef USE_WIRELESS
2454                         PRINT_D(INIT_DBG, "Freeing Wiphy...\n");
2455                         WILC_WFI_WiphyFree(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2456                         #endif
2457                         PRINT_D(INIT_DBG, "Freeing netdev...\n");
2458                         free_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
2459                 }
2460         }
2461
2462 #ifdef USE_WIRELESS
2463 #ifdef WILC_AP_EXTERNAL_MLME
2464         /* Bug 4600 : WILC_WFI_deinit_mon_interface was already called at mac_close */
2465         /* WILC_WFI_deinit_mon_interface(); */
2466 #endif
2467 #endif
2468
2469         /* if(g_linux_wlan->open_ifcs==0) */
2470         {
2471         #ifndef WILC_SDIO
2472                 PRINT_D(INIT_DBG, "SPI unregsiter...\n");
2473                 spi_unregister_driver(&wilc_bus);
2474         #else
2475                 PRINT_D(INIT_DBG, "SDIO unregsiter...\n");
2476                 sdio_unregister_driver(&wilc_bus);
2477         #endif
2478
2479                 if (g_linux_wlan != NULL) {
2480                         kfree(g_linux_wlan);
2481                         g_linux_wlan = NULL;
2482                 }
2483                 printk("Module_exit Done.\n");
2484
2485 #if defined(WILC_DEBUGFS)
2486                 wilc_debugfs_remove();
2487 #endif
2488
2489                 linux_wlan_device_detection(0);
2490                 linux_wlan_device_power(0);
2491         }
2492 }
2493 module_exit(exit_wilc_driver);
2494
2495 MODULE_LICENSE("GPL");