Linux-libre 4.4.228-gnu
[librecmc/linux-libre.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
6 #include <linux/slab.h>
7 #include <linux/sched.h>
8 #include <linux/delay.h>
9 #include <linux/workqueue.h>
10 #include <linux/interrupt.h>
11 #include <linux/irq.h>
12 #include <linux/gpio.h>
13
14 #include <linux/kthread.h>
15 #include <linux/firmware.h>
16 #include <linux/delay.h>
17
18 #include <linux/init.h>
19 #include <linux/netdevice.h>
20 #include <linux/inetdevice.h>
21 #include <linux/etherdevice.h>
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/skbuff.h>
25
26 #include <linux/version.h>
27 #include <linux/semaphore.h>
28
29 #ifdef WILC_SDIO
30 #include "linux_wlan_sdio.h"
31 #else
32 #include "linux_wlan_spi.h"
33 #endif
34
35 #if defined(CUSTOMER_PLATFORM)
36 /*
37  TODO : Write power control functions as customer platform.
38  */
39 #else
40
41  #define _linux_wlan_device_power_on()          {}
42  #define _linux_wlan_device_power_off()         {}
43
44  #define _linux_wlan_device_detection()         {}
45  #define _linux_wlan_device_removal()           {}
46 #endif
47
48 extern bool g_obtainingIP;
49 extern void resolve_disconnect_aberration(void *drvHandler);
50 extern u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
51 extern struct timer_list hDuringIpTimer;
52
53 static int linux_wlan_device_power(int on_off)
54 {
55         PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off);
56
57         if (on_off) {
58                 _linux_wlan_device_power_on();
59         } else {
60                 _linux_wlan_device_power_off();
61         }
62
63         return 0;
64 }
65
66 static int linux_wlan_device_detection(int on_off)
67 {
68         PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off);
69
70 #ifdef WILC_SDIO
71         if (on_off) {
72                 _linux_wlan_device_detection();
73         } else {
74                 _linux_wlan_device_removal();
75         }
76 #endif
77
78         return 0;
79 }
80
81 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
82
83 static struct notifier_block g_dev_notifier = {
84         .notifier_call = dev_state_ev_handler
85 };
86
87 #define IRQ_WAIT        1
88 #define IRQ_NO_WAIT     0
89 /*
90  *      to sync between mac_close and module exit.
91  *      don't initialize or de-initialize from init/deinitlocks
92  *      to be initialized from module wilc_netdev_init and
93  *      deinitialized from mdoule_exit
94  */
95 static struct semaphore close_exit_sync;
96
97 static int wlan_deinit_locks(struct net_device *dev);
98 static void wlan_deinitialize_threads(struct net_device *dev);
99 extern void WILC_WFI_monitor_rx(u8 *buff, u32 size);
100 extern void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
101
102 static void linux_wlan_tx_complete(void *priv, int status);
103 static int  mac_init_fn(struct net_device *ndev);
104 int  mac_xmit(struct sk_buff *skb, struct net_device *dev);
105 int  mac_open(struct net_device *ndev);
106 int  mac_close(struct net_device *ndev);
107 static struct net_device_stats *mac_stats(struct net_device *dev);
108 static int  mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
109 static void wilc_set_multicast_list(struct net_device *dev);
110
111 /*
112  * for now - in frmw_to_linux there should be private data to be passed to it
113  * and this data should be pointer to net device
114  */
115 struct wilc *g_linux_wlan;
116 bool bEnablePS = true;
117
118 static const struct net_device_ops wilc_netdev_ops = {
119         .ndo_init = mac_init_fn,
120         .ndo_open = mac_open,
121         .ndo_stop = mac_close,
122         .ndo_start_xmit = mac_xmit,
123         .ndo_do_ioctl = mac_ioctl,
124         .ndo_get_stats = mac_stats,
125         .ndo_set_rx_mode  = wilc_set_multicast_list,
126
127 };
128
129 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
130 {
131         struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
132         struct wilc_priv *priv;
133         struct host_if_drv *pstrWFIDrv;
134         struct net_device *dev;
135         u8 *pIP_Add_buff;
136         perInterface_wlan_t *nic;
137         u8 null_ip[4] = {0};
138         char wlan_dev_name[5] = "wlan0";
139
140         if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) {
141                 PRINT_D(GENERIC_DBG, "dev_iface = NULL\n");
142                 return NOTIFY_DONE;
143         }
144
145         if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) {
146                 PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n");
147                 return NOTIFY_DONE;
148         }
149
150         dev  = (struct net_device *)dev_iface->ifa_dev->dev;
151         if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) {
152                 PRINT_D(GENERIC_DBG, "No Wireless registerd\n");
153                 return NOTIFY_DONE;
154         }
155         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
156         if (priv == NULL) {
157                 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
158                 return NOTIFY_DONE;
159         }
160         pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
161         nic = netdev_priv(dev);
162         if (nic == NULL || pstrWFIDrv == NULL) {
163                 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
164                 return NOTIFY_DONE;
165         }
166
167         PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */
168
169         switch (event) {
170         case NETDEV_UP:
171                 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev);       /* tony */
172
173                 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
174
175                 /*If we are in station mode or client mode*/
176                 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
177                         pstrWFIDrv->IFC_UP = 1;
178                         g_obtainingIP = false;
179                         del_timer(&hDuringIpTimer);
180                         PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
181                 }
182
183                 if (bEnablePS)
184                         host_int_set_power_mgmt(pstrWFIDrv, 1, 0);
185
186                 PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
187
188                 pIP_Add_buff = (char *) (&(dev_iface->ifa_address));
189                 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]);
190                 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
191
192                 break;
193
194         case NETDEV_DOWN:
195                 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev);               /* tony */
196
197                 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
198                 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
199                         pstrWFIDrv->IFC_UP = 0;
200                         g_obtainingIP = false;
201                 }
202
203                 if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
204                         host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
205
206                 resolve_disconnect_aberration(pstrWFIDrv);
207
208                 PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
209
210                 pIP_Add_buff = null_ip;
211                 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]);
212
213                 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
214
215                 break;
216
217         default:
218                 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n");        /* tony */
219                 PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
220
221                 break;
222         }
223
224         return NOTIFY_DONE;
225
226 }
227
228 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
229 static irqreturn_t isr_uh_routine(int irq, void *user_data)
230 {
231         perInterface_wlan_t *nic;
232         struct wilc *wilc;
233         struct net_device *dev = (struct net_device *)user_data;
234
235         nic = netdev_priv(dev);
236         wilc = nic->wilc;
237         PRINT_D(INT_DBG, "Interrupt received UH\n");
238
239         /*While mac is closing cacncel the handling of any interrupts received*/
240         if (wilc->close) {
241                 PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
242                 return IRQ_HANDLED;
243         }
244         return IRQ_WAKE_THREAD;
245 }
246 #endif
247
248 irqreturn_t isr_bh_routine(int irq, void *userdata)
249 {
250         perInterface_wlan_t *nic;
251         struct wilc *wilc;
252
253         nic = netdev_priv(userdata);
254         wilc = nic->wilc;
255
256         /*While mac is closing cacncel the handling of any interrupts received*/
257         if (wilc->close) {
258                 PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
259                 return IRQ_HANDLED;
260         }
261
262         PRINT_D(INT_DBG, "Interrupt received BH\n");
263         wilc_handle_isr(wilc);
264
265         return IRQ_HANDLED;
266 }
267
268 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
269 static int init_irq(struct net_device *dev)
270 {
271         int ret = 0;
272         perInterface_wlan_t *nic;
273         struct wilc *wl;
274
275         nic = netdev_priv(dev);
276         wl = nic->wilc;
277
278         /*initialize GPIO and register IRQ num*/
279         /*GPIO request*/
280         if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) &&
281             (gpio_direction_input(GPIO_NUM) == 0)) {
282 #if defined(CUSTOMER_PLATFORM)
283 /*
284  TODO : save the registerd irq number to the private wilc context in kernel.
285  *
286  * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
287  */
288 #else
289                 wl->dev_irq_num = gpio_to_irq(GPIO_NUM);
290 #endif
291         } else {
292                 ret = -1;
293                 PRINT_ER("could not obtain gpio for WILC_INTR\n");
294         }
295
296         if ((ret != -1) && (request_threaded_irq(wl->dev_irq_num, isr_uh_routine, isr_bh_routine,
297                                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,               /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/
298                                                   "WILC_IRQ", dev)) < 0) {
299
300                 PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM);
301                 ret = -1;
302         } else {
303
304                 PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
305                         wl->dev_irq_num, GPIO_NUM);
306         }
307
308         return ret;
309 }
310 #endif
311
312 static void deinit_irq(struct net_device *dev)
313 {
314         perInterface_wlan_t *nic;
315         struct wilc *wilc;
316
317         nic = netdev_priv(dev);
318         wilc = nic->wilc;
319
320 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
321         /* Deintialize IRQ */
322         if (&wilc->dev_irq_num != 0) {
323                 free_irq(wilc->dev_irq_num, wilc);
324
325                 gpio_free(GPIO_NUM);
326         }
327 #endif
328 }
329
330 /*
331  *      OS functions
332  */
333 void linux_wlan_dbg(u8 *buff)
334 {
335         PRINT_D(INIT_DBG, "%d\n", *buff);
336 }
337
338 int linux_wlan_lock_timeout(void *vp, u32 timeout)
339 {
340         int error = -1;
341
342         PRINT_D(LOCK_DBG, "Locking %p\n", vp);
343         if (vp != NULL)
344                 error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout));
345         else
346                 PRINT_ER("Failed, mutex is NULL\n");
347         return error;
348 }
349
350 void linux_wlan_mac_indicate(struct wilc *wilc, int flag)
351 {
352         /*I have to do it that way becuase there is no mean to encapsulate device pointer
353          * as a parameter
354          */
355         int status;
356
357         if (flag == WILC_MAC_INDICATE_STATUS) {
358                 wilc_wlan_cfg_get_val(WID_STATUS, (unsigned char *)&status, 4);
359                 if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
360                         wilc->mac_status = status;
361                         up(&wilc->sync_event);
362                 } else {
363                         wilc->mac_status = status;
364                 }
365
366                 if (wilc->mac_status == WILC_MAC_STATUS_CONNECT) {        /* Connect */
367                 }
368
369         } else if (flag == WILC_MAC_INDICATE_SCAN) {
370                 PRINT_D(GENERIC_DBG, "Scanning ...\n");
371
372         }
373
374 }
375
376 struct net_device *GetIfHandler(struct wilc *wilc, u8 *pMacHeader)
377 {
378         u8 *Bssid, *Bssid1;
379         int i = 0;
380
381         Bssid  = pMacHeader + 10;
382         Bssid1 = pMacHeader + 4;
383
384         for (i = 0; i < wilc->vif_num; i++)
385                 if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) ||
386                     !memcmp(Bssid, wilc->vif[i].bssid, ETH_ALEN))
387                         return wilc->vif[i].ndev;
388
389         PRINT_INFO(INIT_DBG, "Invalide handle\n");
390         for (i = 0; i < 25; i++)
391                 PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]);
392         Bssid  = pMacHeader + 18;
393         Bssid1 = pMacHeader + 12;
394         for (i = 0; i < wilc->vif_num; i++)
395                 if (!memcmp(Bssid1, wilc->vif[i].bssid, ETH_ALEN) ||
396                     !memcmp(Bssid, wilc->vif[i].bssid, ETH_ALEN))
397                         return wilc->vif[i].ndev;
398
399         PRINT_INFO(INIT_DBG, "\n");
400         return NULL;
401 }
402
403 int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID)
404 {
405         int i = 0;
406         int ret = -1;
407         perInterface_wlan_t *nic;
408         struct wilc *wilc;
409
410         nic = netdev_priv(wilc_netdev);
411         wilc = nic->wilc;
412
413         for (i = 0; i < wilc->vif_num; i++)
414                 if (wilc->vif[i].ndev == wilc_netdev) {
415                         memcpy(wilc->vif[i].bssid, pBSSID, 6);
416                         ret = 0;
417                         break;
418                 }
419
420         return ret;
421 }
422
423 /*Function to get number of connected interfaces*/
424 int linux_wlan_get_num_conn_ifcs(void)
425 {
426         u8 i = 0;
427         u8 null_bssid[6] = {0};
428         u8 ret_val = 0;
429
430         for (i = 0; i < g_linux_wlan->vif_num; i++)
431                 if (memcmp(g_linux_wlan->vif[i].bssid, null_bssid, 6))
432                         ret_val++;
433
434         return ret_val;
435 }
436
437 #define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
438
439 static int linux_wlan_txq_task(void *vp)
440 {
441         int ret, txq_count;
442         perInterface_wlan_t *nic;
443         struct wilc *wl;
444         struct net_device *dev = vp;
445 #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
446 #define TX_BACKOFF_WEIGHT_INCR_STEP (1)
447 #define TX_BACKOFF_WEIGHT_DECR_STEP (1)
448 #define TX_BACKOFF_WEIGHT_MAX (7)
449 #define TX_BACKOFF_WEIGHT_MIN (0)
450 #define TX_BACKOFF_WEIGHT_UNIT_MS (10)
451         int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
452 #endif
453
454         nic = netdev_priv(dev);
455         wl = nic->wilc;
456
457         /* inform wilc1000_wlan_init that TXQ task is started. */
458         up(&wl->txq_thread_started);
459         while (1) {
460
461                 PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
462                 down(&wl->txq_event);
463                 /* wait_for_completion(&pd->txq_event); */
464                 PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
465
466                 if (wl->close) {
467                         /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */
468                         up(&wl->txq_thread_started);
469
470                         while (!kthread_should_stop())
471                                 schedule();
472
473                         PRINT_D(TX_DBG, "TX thread stopped\n");
474                         break;
475                 }
476                 PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n");
477 #if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
478                 ret = wilc_wlan_handle_txq(dev, &txq_count);
479 #else
480                 do {
481                         ret = wilc_wlan_handle_txq(dev, &txq_count);
482                         if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) {
483                                 PRINT_D(TX_DBG, "Waking up queue\n");
484                                 /* netif_wake_queue(pd->wilc_netdev); */
485                                 if (netif_queue_stopped(wl->vif[0].ndev))
486                                         netif_wake_queue(wl->vif[0].ndev);
487                                 if (netif_queue_stopped(wl->vif[1].ndev))
488                                         netif_wake_queue(wl->vif[1].ndev);
489                         }
490
491                         if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */
492                                 do {
493                                         /* Back off from sending packets for some time. */
494                                         /* schedule_timeout will allow RX task to run and free buffers.*/
495                                         /* set_current_state(TASK_UNINTERRUPTIBLE); */
496                                         /* timeout = schedule_timeout(timeout); */
497                                         msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
498                                 } while (/*timeout*/ 0);
499                                 backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
500                                 if (backoff_weight > TX_BACKOFF_WEIGHT_MAX)
501                                         backoff_weight = TX_BACKOFF_WEIGHT_MAX;
502                         } else {
503                                 if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
504                                         backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
505                                         if (backoff_weight < TX_BACKOFF_WEIGHT_MIN)
506                                                 backoff_weight = TX_BACKOFF_WEIGHT_MIN;
507                                 }
508                         }
509                         /*TODO: drop packets after a certain time/number of retry count. */
510                 } while (ret == WILC_TX_ERR_NO_BUF && !wl->close); /* retry sending packets if no more buffers in chip. */
511 #endif
512         }
513         return 0;
514 }
515
516 void linux_wlan_rx_complete(void)
517 {
518         PRINT_D(RX_DBG, "RX completed\n");
519 }
520
521 int linux_wlan_get_firmware(perInterface_wlan_t *p_nic)
522 {
523
524         perInterface_wlan_t *nic = p_nic;
525         int ret = 0;
526         const struct firmware *wilc_firmware;
527         char *firmware;
528
529         if (nic->iftype == AP_MODE)
530                 firmware = AP_FIRMWARE;
531         else if (nic->iftype == STATION_MODE)
532                 firmware = STA_FIRMWARE;
533
534         else {
535                 PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
536                 firmware = P2P_CONCURRENCY_FIRMWARE;
537         }
538
539         if (nic == NULL) {
540                 PRINT_ER("NIC is NULL\n");
541                 goto _fail_;
542         }
543
544         if (&nic->wilc_netdev->dev == NULL) {
545                 PRINT_ER("&nic->wilc_netdev->dev  is NULL\n");
546                 goto _fail_;
547         }
548
549         /*      the firmare should be located in /lib/firmware in
550          *      root file system with the name specified above */
551
552 #ifdef WILC_SDIO
553         if (reject_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) {
554                 PRINT_ER("%s - firmare not available\n", firmware);
555                 ret = -1;
556                 goto _fail_;
557         }
558 #else
559         if (reject_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) {
560                 PRINT_ER("%s - firmare not available\n", firmware);
561                 ret = -1;
562                 goto _fail_;
563         }
564 #endif
565         g_linux_wlan->firmware = wilc_firmware;
566
567 _fail_:
568
569         return ret;
570
571 }
572
573 static int linux_wlan_start_firmware(perInterface_wlan_t *nic)
574 {
575
576         int ret = 0;
577         /* start firmware */
578         PRINT_D(INIT_DBG, "Starting Firmware ...\n");
579         ret = wilc_wlan_start();
580         if (ret < 0) {
581                 PRINT_ER("Failed to start Firmware\n");
582                 goto _fail_;
583         }
584
585         /* wait for mac ready */
586         PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
587         ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000);
588         if (ret) {
589                 PRINT_D(INIT_DBG, "Firmware start timed out");
590                 goto _fail_;
591         }
592         /*
593          *      TODO: Driver shouoldn't wait forever for firmware to get started -
594          *      in case of timeout this should be handled properly
595          */
596         PRINT_D(INIT_DBG, "Firmware successfully started\n");
597
598 _fail_:
599         return ret;
600 }
601 static int linux_wlan_firmware_download(struct wilc *p_nic)
602 {
603
604         int ret = 0;
605
606         if (!g_linux_wlan->firmware) {
607                 PRINT_ER("Firmware buffer is NULL\n");
608                 ret = -ENOBUFS;
609                 goto _FAIL_;
610         }
611         /**
612          *      do the firmware download
613          **/
614         PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
615         ret = wilc_wlan_firmware_download(g_linux_wlan->firmware->data,
616                                           g_linux_wlan->firmware->size);
617         if (ret < 0)
618                 goto _FAIL_;
619
620         /* Freeing FW buffer */
621         PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
622         PRINT_D(INIT_DBG, "Releasing firmware\n");
623         release_firmware(g_linux_wlan->firmware);
624
625         PRINT_D(INIT_DBG, "Download Succeeded\n");
626
627 _FAIL_:
628         return ret;
629 }
630
631 /* startup configuration - could be changed later using iconfig*/
632 static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic)
633 {
634
635         unsigned char c_val[64];
636         unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
637
638         struct wilc_priv *priv;
639         struct host_if_drv *pstrWFIDrv;
640
641         PRINT_D(TX_DBG, "Start configuring Firmware\n");
642         get_random_bytes(&mac_add[5], 1);
643         get_random_bytes(&mac_add[4], 1);
644         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
645         pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
646         PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv);
647
648         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]);
649         wilc_get_chipid(0);
650
651         *(int *)c_val = 1;
652
653         if (!wilc_wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
654                 goto _fail_;
655
656         /*to tell fw that we are going to use PC test - WILC specific*/
657         c_val[0] = 0;
658         if (!wilc_wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
659                 goto _fail_;
660
661         c_val[0] = INFRASTRUCTURE;
662         if (!wilc_wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0))
663                 goto _fail_;
664
665         /* c_val[0] = RATE_AUTO; */
666         c_val[0] = RATE_AUTO;
667         if (!wilc_wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
668                 goto _fail_;
669
670         c_val[0] = G_MIXED_11B_2_MODE;
671         if (!wilc_wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0))
672                 goto _fail_;
673
674         c_val[0] = 1;
675         if (!wilc_wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
676                 goto _fail_;
677
678         c_val[0] = G_SHORT_PREAMBLE;
679         if (!wilc_wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0))
680                 goto _fail_;
681
682         c_val[0] = AUTO_PROT;
683         if (!wilc_wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
684                 goto _fail_;
685
686         c_val[0] = ACTIVE_SCAN;
687         if (!wilc_wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0))
688                 goto _fail_;
689
690         c_val[0] = SITE_SURVEY_OFF;
691         if (!wilc_wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0))
692                 goto _fail_;
693
694         *((int *)c_val) = 0xffff; /* Never use RTS-CTS */
695         if (!wilc_wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
696                 goto _fail_;
697
698         *((int *)c_val) = 2346;
699         if (!wilc_wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
700                 goto _fail_;
701
702         /*  SSID                                                                 */
703         /*  --------------------------------------------------------------       */
704         /*  Configuration :   String with length less than 32 bytes              */
705         /*  Values to set :   Any string with length less than 32 bytes          */
706         /*                    ( In BSS Station Set SSID to "" (null string)      */
707         /*                      to enable Broadcast SSID suppport )              */
708         /*  --------------------------------------------------------------       */
709         c_val[0] = 0;
710         if (!wilc_wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0))
711                 goto _fail_;
712
713         c_val[0] = 1;
714         if (!wilc_wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0))
715                 goto _fail_;
716
717         c_val[0] = NO_POWERSAVE;
718         if (!wilc_wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
719                 goto _fail_;
720
721         c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */
722         if (!wilc_wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0))
723                 goto _fail_;
724
725         c_val[0] = OPEN_SYSTEM;
726         if (!wilc_wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0))
727                 goto _fail_;
728
729         /*  WEP/802 11I Configuration                                            */
730         /*  ------------------------------------------------------------------   */
731         /*  Configuration : WEP Key                                              */
732         /*  Values (0x)   : 5 byte for WEP40 and 13 bytes for WEP104             */
733         /*                  In case more than 5 bytes are passed on for WEP 40   */
734         /*                  only first 5 bytes will be used as the key           */
735         /*  ------------------------------------------------------------------   */
736
737         strcpy(c_val, "123456790abcdef1234567890");
738         if (!wilc_wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0))
739                 goto _fail_;
740
741         /*  WEP/802 11I Configuration                                            */
742         /*  ------------------------------------------------------------------   */
743         /*  Configuration : AES/TKIP WPA/RSNA Pre-Shared Key                     */
744         /*  Values to set : Any string with length greater than equal to 8 bytes */
745         /*                  and less than 64 bytes                               */
746         /*  ------------------------------------------------------------------   */
747         strcpy(c_val, "12345678");
748         if (!wilc_wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0))
749                 goto _fail_;
750
751         /*  IEEE802.1X Key Configuration                                         */
752         /*  ------------------------------------------------------------------   */
753         /*  Configuration : Radius Server Access Secret Key                      */
754         /*  Values to set : Any string with length greater than equal to 8 bytes */
755         /*                  and less than 65 bytes                               */
756         /*  ------------------------------------------------------------------   */
757         strcpy(c_val, "password");
758         if (!wilc_wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0))
759                 goto _fail_;
760
761         /*   IEEE802.1X Server Address Configuration                             */
762         /*  ------------------------------------------------------------------   */
763         /*  Configuration : Radius Server IP Address                             */
764         /*  Values to set : Any valid IP Address                                 */
765         /*  ------------------------------------------------------------------   */
766         c_val[0] = 192;
767         c_val[1] = 168;
768         c_val[2] = 1;
769         c_val[3] = 112;
770         if (!wilc_wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
771                 goto _fail_;
772
773         c_val[0] = 3;
774         if (!wilc_wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
775                 goto _fail_;
776
777         c_val[0] = 3;
778         if (!wilc_wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
779                 goto _fail_;
780
781         c_val[0] = NORMAL_ACK;
782         if (!wilc_wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0))
783                 goto _fail_;
784
785         c_val[0] = 0;
786         if (!wilc_wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0))
787                 goto _fail_;
788
789         c_val[0] = 48;
790         if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0))
791                 goto _fail_;
792
793         c_val[0] = 28;
794         if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0))
795                 goto _fail_;
796
797         /*  Beacon Interval                                                      */
798         /*  -------------------------------------------------------------------- */
799         /*  Configuration : Sets the beacon interval value                       */
800         /*  Values to set : Any 16-bit value                                     */
801         /*  -------------------------------------------------------------------- */
802
803         *((int *)c_val) = 100;
804         if (!wilc_wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
805                 goto _fail_;
806
807         c_val[0] = REKEY_DISABLE;
808         if (!wilc_wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0))
809                 goto _fail_;
810
811         /*  Rekey Time (s) (Used only when the Rekey policy is 2 or 4)           */
812         /*  -------------------------------------------------------------------- */
813         /*  Configuration : Sets the Rekey Time (s)                              */
814         /*  Values to set : 32-bit value                                         */
815         /*  -------------------------------------------------------------------- */
816         *((int *)c_val) = 84600;
817         if (!wilc_wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
818                 goto _fail_;
819
820         /*  Rekey Packet Count (in 1000s; used when Rekey Policy is 3)           */
821         /*  -------------------------------------------------------------------- */
822         /*  Configuration : Sets Rekey Group Packet count                        */
823         /*  Values to set : 32-bit Value                                         */
824         /*  -------------------------------------------------------------------- */
825         *((int *)c_val) = 500;
826         if (!wilc_wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0))
827                 goto _fail_;
828
829         c_val[0] = 1;
830         if (!wilc_wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0))
831                 goto _fail_;
832
833         c_val[0] = G_SELF_CTS_PROT;
834         if (!wilc_wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
835                 goto _fail_;
836
837         c_val[0] = 1;  /* Enable N */
838         if (!wilc_wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0))
839                 goto _fail_;
840
841         c_val[0] = HT_MIXED_MODE;
842         if (!wilc_wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0))
843                 goto _fail_;
844
845         c_val[0] = 1;   /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */
846         if (!wilc_wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0))
847                 goto _fail_;
848
849         memcpy(c_val, mac_add, 6);
850
851         if (!wilc_wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0))
852                 goto _fail_;
853
854         /**
855          *      AP only
856          **/
857         c_val[0] = DETECT_PROTECT_REPORT;
858         if (!wilc_wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0))
859                 goto _fail_;
860
861         c_val[0] = RTS_CTS_NONHT_PROT;
862         if (!wilc_wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
863                 goto _fail_;
864
865         c_val[0] = 0;
866         if (!wilc_wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0))
867                 goto _fail_;
868
869         c_val[0] = MIMO_MODE;
870         if (!wilc_wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
871                 goto _fail_;
872
873         c_val[0] = 7;
874         if (!wilc_wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0))
875                 goto _fail_;
876
877         c_val[0] = 1; /* Enable N with immediate block ack. */
878         if (!wilc_wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1))
879                 goto _fail_;
880
881         return 0;
882
883 _fail_:
884         return -1;
885 }
886
887 /**************************/
888 void wilc1000_wlan_deinit(struct net_device *dev)
889 {
890         perInterface_wlan_t *nic;
891         struct wilc *wl;
892
893         nic = netdev_priv(dev);
894         wl = nic->wilc;
895
896         if (!wl) {
897                 netdev_err(dev, "wl is NULL\n");
898                 return;
899         }
900
901         if (wl->initialized)    {
902                 netdev_info(dev, "Deinitializing wilc1000...\n");
903
904 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
905                 /* johnny : remove */
906                 PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n");
907 #else
908                 wilc_bus_set_default_speed();
909 #endif
910
911                 PRINT_D(INIT_DBG, "Disabling IRQ\n");
912 #ifdef WILC_SDIO
913                 mutex_lock(&wl->hif_cs);
914                 disable_sdio_interrupt();
915                 mutex_unlock(&wl->hif_cs);
916 #endif
917                 if (&wl->txq_event != NULL)
918                         up(&wl->txq_event);
919
920                 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
921                 wlan_deinitialize_threads(dev);
922
923                 PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
924                 deinit_irq(dev);
925
926                 wilc_wlan_stop();
927
928                 PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
929                 wilc_wlan_cleanup(dev);
930 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
931   #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
932                 PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
933
934                 mutex_lock(&wl->hif_cs);
935                 disable_sdio_interrupt();
936                 mutex_unlock(&wl->hif_cs);
937   #endif
938 #endif
939
940                 /*De-Initialize locks*/
941                 PRINT_D(INIT_DBG, "Deinitializing Locks\n");
942                 wlan_deinit_locks(dev);
943
944                 /* announce that wilc1000 is not initialized */
945                 wl->initialized = false;
946
947                 PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n");
948
949         } else {
950                 PRINT_D(INIT_DBG, "wilc1000 is not initialized\n");
951         }
952 }
953
954 int wlan_init_locks(struct net_device *dev)
955 {
956         perInterface_wlan_t *nic;
957         struct wilc *wl;
958
959         nic = netdev_priv(dev);
960         wl = nic->wilc;
961
962         PRINT_D(INIT_DBG, "Initializing Locks ...\n");
963
964         mutex_init(&wl->hif_cs);
965         mutex_init(&wl->rxq_cs);
966
967         spin_lock_init(&wl->txq_spinlock);
968         sema_init(&wl->txq_add_to_head_cs, 1);
969
970         sema_init(&wl->txq_event, 0);
971
972         sema_init(&wl->cfg_event, 0);
973         sema_init(&wl->sync_event, 0);
974
975         sema_init(&wl->txq_thread_started, 0);
976
977         return 0;
978 }
979
980 static int wlan_deinit_locks(struct net_device *dev)
981 {
982         perInterface_wlan_t *nic;
983         struct wilc *wilc;
984
985         nic = netdev_priv(dev);
986         wilc = nic->wilc;
987
988         PRINT_D(INIT_DBG, "De-Initializing Locks\n");
989
990         if (&wilc->hif_cs != NULL)
991                 mutex_destroy(&wilc->hif_cs);
992
993         if (&wilc->rxq_cs != NULL)
994                 mutex_destroy(&wilc->rxq_cs);
995
996         return 0;
997 }
998 void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic)
999 {
1000
1001         PRINT_D(INIT_DBG, "Linux to Wlan services ...\n");
1002
1003         nwi->os_context.os_private = (void *)nic;
1004
1005 #ifdef WILC_SDIO
1006         nwi->io_func.io_type = HIF_SDIO;
1007         nwi->io_func.io_init = linux_sdio_init;
1008         nwi->io_func.io_deinit = linux_sdio_deinit;
1009         nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52;
1010         nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53;
1011         nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed;
1012         nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed;
1013 #else
1014         nwi->io_func.io_type = HIF_SPI;
1015         nwi->io_func.io_init = linux_spi_init;
1016         nwi->io_func.io_deinit = linux_spi_deinit;
1017         nwi->io_func.u.spi.spi_tx = linux_spi_write;
1018         nwi->io_func.u.spi.spi_rx = linux_spi_read;
1019         nwi->io_func.u.spi.spi_trx = linux_spi_write_read;
1020         nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed;
1021 #endif
1022 }
1023
1024 int wlan_initialize_threads(struct net_device *dev)
1025 {
1026         perInterface_wlan_t *nic;
1027         struct wilc *wilc;
1028         int ret = 0;
1029
1030         nic = netdev_priv(dev);
1031         wilc = nic->wilc;
1032
1033         PRINT_D(INIT_DBG, "Initializing Threads ...\n");
1034
1035         /* create tx task */
1036         PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
1037         wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev,
1038                                      "K_TXQ_TASK");
1039         if (!wilc->txq_thread) {
1040                 PRINT_ER("couldn't create TXQ thread\n");
1041                 ret = -ENOBUFS;
1042                 goto _fail_2;
1043         }
1044         /* wait for TXQ task to start. */
1045         down(&wilc->txq_thread_started);
1046
1047         return 0;
1048
1049 _fail_2:
1050         /*De-Initialize 2nd thread*/
1051         wilc->close = 0;
1052         return ret;
1053 }
1054
1055 static void wlan_deinitialize_threads(struct net_device *dev)
1056 {
1057         perInterface_wlan_t *nic;
1058         struct wilc *wl;
1059
1060         nic = netdev_priv(dev);
1061         wl = nic->wilc;
1062
1063         wl->close = 1;
1064         PRINT_D(INIT_DBG, "Deinitializing Threads\n");
1065
1066         if (&wl->txq_event != NULL)
1067                 up(&wl->txq_event);
1068
1069         if (wl->txq_thread != NULL) {
1070                 kthread_stop(wl->txq_thread);
1071                 wl->txq_thread = NULL;
1072         }
1073 }
1074
1075 int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
1076 {
1077         wilc_wlan_inp_t nwi;
1078         perInterface_wlan_t *nic = p_nic;
1079         int ret = 0;
1080         struct wilc *wl = nic->wilc;
1081
1082         if (!wl->initialized) {
1083                 wl->mac_status = WILC_MAC_STATUS_INIT;
1084                 wl->close = 0;
1085
1086                 wlan_init_locks(dev);
1087
1088                 linux_to_wlan(&nwi, wl);
1089
1090                 ret = wilc_wlan_init(&nwi);
1091                 if (ret < 0) {
1092                         PRINT_ER("Initializing WILC_Wlan FAILED\n");
1093                         ret = -EIO;
1094                         goto _fail_locks_;
1095                 }
1096
1097 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1098                 if (init_irq(dev)) {
1099                         PRINT_ER("couldn't initialize IRQ\n");
1100                         ret = -EIO;
1101                         goto _fail_locks_;
1102                 }
1103 #endif
1104
1105                 ret = wlan_initialize_threads(dev);
1106                 if (ret < 0) {
1107                         PRINT_ER("Initializing Threads FAILED\n");
1108                         ret = -EIO;
1109                         goto _fail_wilc_wlan_;
1110                 }
1111
1112 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1113                 if (enable_sdio_interrupt()) {
1114                         PRINT_ER("couldn't initialize IRQ\n");
1115                         ret = -EIO;
1116                         goto _fail_irq_init_;
1117                 }
1118 #endif
1119
1120                 if (linux_wlan_get_firmware(nic)) {
1121                         PRINT_ER("Can't get firmware\n");
1122                         ret = -EIO;
1123                         goto _fail_irq_enable_;
1124                 }
1125
1126                 /*Download firmware*/
1127                 ret = linux_wlan_firmware_download(wl);
1128                 if (ret < 0) {
1129                         PRINT_ER("Failed to download firmware\n");
1130                         ret = -EIO;
1131                         goto _fail_irq_enable_;
1132                 }
1133
1134                 /* Start firmware*/
1135                 ret = linux_wlan_start_firmware(nic);
1136                 if (ret < 0) {
1137                         PRINT_ER("Failed to start firmware\n");
1138                         ret = -EIO;
1139                         goto _fail_irq_enable_;
1140                 }
1141
1142                 wilc_bus_set_max_speed();
1143
1144                 if (wilc_wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) {
1145                         int size;
1146                         char Firmware_ver[20];
1147
1148                         size = wilc_wlan_cfg_get_val(
1149                                         WID_FIRMWARE_VERSION,
1150                                         Firmware_ver, sizeof(Firmware_ver));
1151                         Firmware_ver[size] = '\0';
1152                         PRINT_D(INIT_DBG, "***** Firmware Ver = %s  *******\n", Firmware_ver);
1153                 }
1154                 /* Initialize firmware with default configuration */
1155                 ret = linux_wlan_init_test_config(dev, wl);
1156
1157                 if (ret < 0) {
1158                         PRINT_ER("Failed to configure firmware\n");
1159                         ret = -EIO;
1160                         goto _fail_fw_start_;
1161                 }
1162
1163                 wl->initialized = true;
1164                 return 0; /*success*/
1165
1166 _fail_fw_start_:
1167                 wilc_wlan_stop();
1168
1169 _fail_irq_enable_:
1170 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1171                 disable_sdio_interrupt();
1172 _fail_irq_init_:
1173 #endif
1174 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1175                 deinit_irq(dev);
1176
1177 #endif
1178                 wlan_deinitialize_threads(dev);
1179 _fail_wilc_wlan_:
1180                 wilc_wlan_cleanup(dev);
1181 _fail_locks_:
1182                 wlan_deinit_locks(dev);
1183                 PRINT_ER("WLAN Iinitialization FAILED\n");
1184         } else {
1185                 PRINT_D(INIT_DBG, "wilc1000 already initialized\n");
1186         }
1187         return ret;
1188 }
1189
1190 /*
1191  *      - this function will be called automatically by OS when module inserted.
1192  */
1193
1194 int mac_init_fn(struct net_device *ndev)
1195 {
1196
1197         /*Why we do this !!!*/
1198         netif_start_queue(ndev); /* ma */
1199         netif_stop_queue(ndev); /* ma */
1200
1201         return 0;
1202 }
1203
1204 /* This fn is called, when this device is setup using ifconfig */
1205 int mac_open(struct net_device *ndev)
1206 {
1207         perInterface_wlan_t *nic;
1208
1209         /*No need for setting mac address here anymore,*/
1210         /*Just set it in init_test_config()*/
1211         unsigned char mac_add[ETH_ALEN] = {0};
1212         int ret = 0;
1213         int i = 0;
1214         struct wilc_priv *priv;
1215         struct wilc *wl;
1216
1217         nic = netdev_priv(ndev);
1218         wl = nic->wilc;
1219
1220 #ifdef WILC_SPI
1221         if (!wl|| !wl->wilc_spidev) {
1222                 netdev_err(ndev, "wilc1000: SPI device not ready\n");
1223                 return -ENODEV;
1224         }
1225 #endif
1226         nic = netdev_priv(ndev);
1227         priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1228         PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
1229
1230         ret = wilc_init_host_int(ndev);
1231         if (ret < 0) {
1232                 PRINT_ER("Failed to initialize host interface\n");
1233
1234                 return ret;
1235         }
1236
1237         /*initialize platform*/
1238         PRINT_D(INIT_DBG, "*** re-init ***\n");
1239         ret = wilc1000_wlan_init(ndev, nic);
1240         if (ret < 0) {
1241                 PRINT_ER("Failed to initialize wilc1000\n");
1242                 wilc_deinit_host_int(ndev);
1243                 return ret;
1244         }
1245
1246         Set_machw_change_vir_if(ndev, false);
1247
1248         host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add);
1249         PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
1250
1251         /* loop through the NUM of supported devices and set the MAC address */
1252         for (i = 0; i < wl->vif_num; i++) {
1253                 if (ndev == wl->vif[i].ndev) {
1254                         memcpy(wl->vif[i].src_addr, mac_add, ETH_ALEN);
1255                         wl->vif[i].hif_drv = priv->hWILCWFIDrv;
1256                         break;
1257                 }
1258         }
1259
1260         /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
1261         memcpy(ndev->dev_addr, wl->vif[i].src_addr, ETH_ALEN);
1262
1263         if (!is_valid_ether_addr(ndev->dev_addr)) {
1264                 PRINT_ER("Error: Wrong MAC address\n");
1265                 ret = -EINVAL;
1266                 goto _err_;
1267         }
1268
1269         wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr,
1270                                  nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg);
1271         wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr,
1272                                  nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg);
1273         netif_wake_queue(ndev);
1274         wl->open_ifcs++;
1275         nic->mac_opened = 1;
1276         return 0;
1277
1278 _err_:
1279         wilc_deinit_host_int(ndev);
1280         wilc1000_wlan_deinit(ndev);
1281         return ret;
1282 }
1283
1284 struct net_device_stats *mac_stats(struct net_device *dev)
1285 {
1286         perInterface_wlan_t *nic = netdev_priv(dev);
1287
1288         return &nic->netstats;
1289 }
1290
1291 /* Setup the multicast filter */
1292 static void wilc_set_multicast_list(struct net_device *dev)
1293 {
1294
1295         struct netdev_hw_addr *ha;
1296         struct wilc_priv *priv;
1297         struct host_if_drv *pstrWFIDrv;
1298         int i = 0;
1299
1300         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1301         pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
1302
1303         if (!dev)
1304                 return;
1305
1306         PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", dev->mc.count);
1307
1308         if (dev->flags & IFF_PROMISC) {
1309                 /* Normally, we should configure the chip to retrive all packets
1310                  * but we don't wanna support this right now */
1311                 /* TODO: add promiscuous mode support */
1312                 PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n");
1313                 return;
1314         }
1315
1316         /* If there's more addresses than we handle, get all multicast
1317          * packets and sort them out in software. */
1318         if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
1319                 PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
1320                 /* get all multicast packets */
1321                 host_int_setup_multicast_filter(pstrWFIDrv, false, 0);
1322                 return;
1323         }
1324
1325         /* No multicast?  Just get our own stuff */
1326         if ((dev->mc.count) == 0) {
1327                 PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
1328                 host_int_setup_multicast_filter(pstrWFIDrv, true, 0);
1329                 return;
1330         }
1331
1332         /* Store all of the multicast addresses in the hardware filter */
1333         netdev_for_each_mc_addr(ha, dev)
1334         {
1335                 memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN);
1336                 PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
1337                         gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]);
1338                 i++;
1339         }
1340
1341         host_int_setup_multicast_filter(pstrWFIDrv, true, (dev->mc.count));
1342
1343         return;
1344
1345 }
1346
1347 static void linux_wlan_tx_complete(void *priv, int status)
1348 {
1349
1350         struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
1351
1352         if (status == 1)
1353                 PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1354         else
1355                 PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1356         /* Free the SK Buffer, its work is done */
1357         dev_kfree_skb(pv_data->skb);
1358         kfree(pv_data);
1359 }
1360
1361 int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
1362 {
1363         perInterface_wlan_t *nic;
1364         struct tx_complete_data *tx_data = NULL;
1365         int QueueCount;
1366         char *pu8UdpBuffer;
1367         struct iphdr *ih;
1368         struct ethhdr *eth_h;
1369         struct wilc *wilc;
1370
1371         nic = netdev_priv(ndev);
1372         wilc = nic->wilc;
1373
1374         PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
1375
1376         /* Stop the network interface queue */
1377         if (skb->dev != ndev) {
1378                 PRINT_ER("Packet not destined to this device\n");
1379                 return 0;
1380         }
1381
1382         tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC);
1383         if (tx_data == NULL) {
1384                 PRINT_ER("Failed to allocate memory for tx_data structure\n");
1385                 dev_kfree_skb(skb);
1386                 netif_wake_queue(ndev);
1387                 return 0;
1388         }
1389
1390         tx_data->buff = skb->data;
1391         tx_data->size = skb->len;
1392         tx_data->skb  = skb;
1393
1394         eth_h = (struct ethhdr *)(skb->data);
1395         if (eth_h->h_proto == 0x8e88)
1396                 PRINT_D(INIT_DBG, "EAPOL transmitted\n");
1397
1398         /*get source and dest ip addresses*/
1399         ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1400
1401         pu8UdpBuffer = (char *)ih + sizeof(struct iphdr);
1402         if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68))
1403                 PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]);
1404
1405         PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
1406
1407         /* Send packet to MAC HW - for now the tx_complete function will be just status
1408          * indicator. still not sure if I need to suspend host transmission till the tx_complete
1409          * function called or not?
1410          * allocated buffer will be freed in tx_complete function.
1411          */
1412         PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
1413         nic->netstats.tx_packets++;
1414         nic->netstats.tx_bytes += tx_data->size;
1415         tx_data->pBssid = wilc->vif[nic->u8IfIdx].bssid;
1416         QueueCount = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
1417                                                tx_data->buff, tx_data->size,
1418                                                linux_wlan_tx_complete);
1419
1420         if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) {
1421                 netif_stop_queue(wilc->vif[0].ndev);
1422                 netif_stop_queue(wilc->vif[1].ndev);
1423         }
1424
1425         return 0;
1426 }
1427
1428 int mac_close(struct net_device *ndev)
1429 {
1430         struct wilc_priv *priv;
1431         perInterface_wlan_t *nic;
1432         struct host_if_drv *pstrWFIDrv;
1433         struct wilc *wl;
1434
1435         nic = netdev_priv(ndev);
1436
1437         if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) {
1438                 PRINT_ER("nic = NULL\n");
1439                 return 0;
1440         }
1441
1442         priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1443         wl = nic->wilc;
1444
1445         if (priv == NULL) {
1446                 PRINT_ER("priv = NULL\n");
1447                 return 0;
1448         }
1449
1450         pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
1451
1452         PRINT_D(GENERIC_DBG, "Mac close\n");
1453
1454         if (!wl) {
1455                 PRINT_ER("wl = NULL\n");
1456                 return 0;
1457         }
1458
1459         if (pstrWFIDrv == NULL) {
1460                 PRINT_ER("pstrWFIDrv = NULL\n");
1461                 return 0;
1462         }
1463
1464         if ((wl->open_ifcs) > 0) {
1465                 wl->open_ifcs--;
1466         } else {
1467                 PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n");
1468                 return 0;
1469         }
1470
1471         if (nic->wilc_netdev != NULL) {
1472                 /* Stop the network interface queue */
1473                 netif_stop_queue(nic->wilc_netdev);
1474
1475                 wilc_deinit_host_int(nic->wilc_netdev);
1476         }
1477
1478         if (wl->open_ifcs == 0) {
1479                 PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
1480                 wl->close = 1;
1481                 wilc1000_wlan_deinit(ndev);
1482                 WILC_WFI_deinit_mon_interface();
1483         }
1484
1485         up(&close_exit_sync);
1486         nic->mac_opened = 0;
1487
1488         return 0;
1489 }
1490
1491 int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1492 {
1493
1494         u8 *buff = NULL;
1495         s8 rssi;
1496         u32 size = 0, length = 0;
1497         perInterface_wlan_t *nic;
1498         struct wilc_priv *priv;
1499         s32 s32Error = 0;
1500         struct wilc *wilc;
1501
1502         /* struct iwreq *wrq = (struct iwreq *) req;    // tony moved to case SIOCSIWPRIV */
1503         nic = netdev_priv(ndev);
1504         wilc = nic->wilc;
1505
1506         if (!wilc->initialized)
1507                 return 0;
1508
1509         switch (cmd) {
1510
1511         /* ]] 2013-06-24 */
1512         case SIOCSIWPRIV:
1513         {
1514                 struct iwreq *wrq = (struct iwreq *) req;               /* added by tony */
1515
1516                 size = wrq->u.data.length;
1517
1518                 if (size && wrq->u.data.pointer) {
1519
1520                         buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length);
1521                         if (IS_ERR(buff))
1522                                 return PTR_ERR(buff);
1523
1524                         if (strncasecmp(buff, "RSSI", length) == 0) {
1525                                 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1526                                 s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi));
1527                                 if (s32Error)
1528                                         PRINT_ER("Failed to send get rssi param's message queue ");
1529                                 PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
1530
1531                                 /*Rounding up the rssi negative value*/
1532                                 rssi += 5;
1533
1534                                 snprintf(buff, size, "rssi %d", rssi);
1535
1536                                 if (copy_to_user(wrq->u.data.pointer, buff, size)) {
1537                                         PRINT_ER("%s: failed to copy data to user buffer\n", __func__);
1538                                         s32Error = -EFAULT;
1539                                         goto done;
1540                                 }
1541                         }
1542                 }
1543         }
1544         break;
1545
1546         default:
1547         {
1548                 PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd);
1549                 s32Error = -EOPNOTSUPP;
1550                 goto done;
1551         }
1552         }
1553
1554 done:
1555
1556         kfree(buff);
1557
1558         return s32Error;
1559 }
1560
1561 void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
1562 {
1563
1564         unsigned int frame_len = 0;
1565         int stats;
1566         unsigned char *buff_to_send = NULL;
1567         struct sk_buff *skb;
1568         struct net_device *wilc_netdev;
1569         perInterface_wlan_t *nic;
1570
1571         wilc_netdev = GetIfHandler(wilc, buff);
1572         if (wilc_netdev == NULL)
1573                 return;
1574
1575         buff += pkt_offset;
1576         nic = netdev_priv(wilc_netdev);
1577
1578         if (size > 0) {
1579
1580                 frame_len = size;
1581                 buff_to_send = buff;
1582
1583                 /* Need to send the packet up to the host, allocate a skb buffer */
1584                 skb = dev_alloc_skb(frame_len);
1585                 if (skb == NULL) {
1586                         PRINT_ER("Low memory - packet droped\n");
1587                         return;
1588                 }
1589
1590                 if (wilc == NULL || wilc_netdev == NULL)
1591                         PRINT_ER("wilc_netdev in wilc is NULL");
1592                 skb->dev = wilc_netdev;
1593
1594                 if (skb->dev == NULL)
1595                         PRINT_ER("skb->dev is NULL\n");
1596
1597                 /*
1598                  * for(i=0;i<40;i++)
1599                  * {
1600                  *      if(i<frame_len)
1601                  *              WILC_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]);
1602                  *
1603                  * }*/
1604
1605                 /* skb_put(skb, frame_len); */
1606                 memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
1607
1608                 /* WILC_PRINTF("After MEM_CPY\n"); */
1609
1610                 /* nic = netdev_priv(wilc_netdev); */
1611
1612                 skb->protocol = eth_type_trans(skb, wilc_netdev);
1613                 /* Send the packet to the stack by giving it to the bridge */
1614                 nic->netstats.rx_packets++;
1615                 nic->netstats.rx_bytes += frame_len;
1616                 skb->ip_summed = CHECKSUM_UNNECESSARY;
1617                 stats = netif_rx(skb);
1618                 PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
1619         }
1620 }
1621
1622 void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
1623 {
1624         int i = 0;
1625         perInterface_wlan_t *nic;
1626
1627         /*Pass the frame on the monitor interface, if any.*/
1628         /*Otherwise, pass it on p2p0 netdev, if registered on it*/
1629         for (i = 0; i < wilc->vif_num; i++) {
1630                 nic = netdev_priv(wilc->vif[i].ndev);
1631                 if (nic->monitor_flag) {
1632                         WILC_WFI_monitor_rx(buff, size);
1633                         return;
1634                 }
1635         }
1636
1637         nic = netdev_priv(wilc->vif[1].ndev); /* p2p0 */
1638         if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) ||
1639             (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg))
1640                 WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size);
1641 }
1642
1643 void wl_wlan_cleanup(void)
1644 {
1645         int i = 0;
1646         perInterface_wlan_t *nic[NUM_CONCURRENT_IFC];
1647
1648         if (g_linux_wlan &&
1649            (g_linux_wlan->vif[0].ndev || g_linux_wlan->vif[1].ndev)) {
1650                 unregister_inetaddr_notifier(&g_dev_notifier);
1651
1652                 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1653                         nic[i] = netdev_priv(g_linux_wlan->vif[i].ndev);
1654         }
1655
1656         if (g_linux_wlan && g_linux_wlan->firmware)
1657                 release_firmware(g_linux_wlan->firmware);
1658
1659         if (g_linux_wlan &&
1660            (g_linux_wlan->vif[0].ndev || g_linux_wlan->vif[1].ndev)) {
1661                 linux_wlan_lock_timeout(&close_exit_sync, 12 * 1000);
1662
1663                 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1664                         if (g_linux_wlan->vif[i].ndev)
1665                                 if (nic[i]->mac_opened)
1666                                         mac_close(g_linux_wlan->vif[i].ndev);
1667
1668                 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1669                         unregister_netdev(g_linux_wlan->vif[i].ndev);
1670                         wilc_free_wiphy(g_linux_wlan->vif[i].ndev);
1671                         free_netdev(g_linux_wlan->vif[i].ndev);
1672                 }
1673         }
1674
1675         kfree(g_linux_wlan);
1676
1677 #if defined(WILC_DEBUGFS)
1678         wilc_debugfs_remove();
1679 #endif
1680         linux_wlan_device_detection(0);
1681         linux_wlan_device_power(0);
1682 }
1683
1684 int wilc_netdev_init(struct wilc **wilc)
1685 {
1686         int i;
1687         perInterface_wlan_t *nic;
1688         struct net_device *ndev;
1689
1690         sema_init(&close_exit_sync, 0);
1691
1692         /*create the common structure*/
1693         g_linux_wlan = kzalloc(sizeof(*g_linux_wlan), GFP_KERNEL);
1694         if (!g_linux_wlan)
1695                 return -ENOMEM;
1696
1697         *wilc = g_linux_wlan;
1698
1699         register_inetaddr_notifier(&g_dev_notifier);
1700
1701         for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1702                 /*allocate first ethernet device with perinterface_wlan_t as its private data*/
1703                 ndev = alloc_etherdev(sizeof(perInterface_wlan_t));
1704                 if (!ndev) {
1705                         PRINT_ER("Failed to allocate ethernet dev\n");
1706                         return -1;
1707                 }
1708
1709                 nic = netdev_priv(ndev);
1710                 memset(nic, 0, sizeof(perInterface_wlan_t));
1711
1712                 /*Name the Devices*/
1713                 if (i == 0) {
1714                 #if defined(NM73131)    /* tony, 2012-09-20 */
1715                         strcpy(ndev->name, "wilc_eth%d");
1716                 #elif defined(PLAT_CLM9722)                     /* rachel */
1717                         strcpy(ndev->name, "eth%d");
1718                 #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */
1719                         strcpy(ndev->name, "wlan%d");
1720                 #endif
1721                 } else
1722                         strcpy(ndev->name, "p2p%d");
1723
1724                 nic->u8IfIdx = g_linux_wlan->vif_num;
1725                 nic->wilc_netdev = ndev;
1726                 nic->wilc = *wilc;
1727                 g_linux_wlan->vif[g_linux_wlan->vif_num].ndev = ndev;
1728                 g_linux_wlan->vif_num++;
1729                 ndev->netdev_ops = &wilc_netdev_ops;
1730
1731                 {
1732                         struct wireless_dev *wdev;
1733                         /*Register WiFi*/
1734                         wdev = wilc_create_wiphy(ndev);
1735
1736                         #ifdef WILC_SDIO
1737                         /* set netdev, tony */
1738                         SET_NETDEV_DEV(ndev, &local_sdio_func->dev);
1739                         #endif
1740
1741                         if (wdev == NULL) {
1742                                 PRINT_ER("Can't register WILC Wiphy\n");
1743                                 return -1;
1744                         }
1745
1746                         /*linking the wireless_dev structure with the netdevice*/
1747                         nic->wilc_netdev->ieee80211_ptr = wdev;
1748                         nic->wilc_netdev->ml_priv = nic;
1749                         wdev->netdev = nic->wilc_netdev;
1750                         nic->netstats.rx_packets = 0;
1751                         nic->netstats.tx_packets = 0;
1752                         nic->netstats.rx_bytes = 0;
1753                         nic->netstats.tx_bytes = 0;
1754
1755                 }
1756
1757                 if (register_netdev(ndev)) {
1758                         PRINT_ER("Device couldn't be registered - %s\n", ndev->name);
1759                         return -1; /* ERROR */
1760                 }
1761
1762                 nic->iftype = STATION_MODE;
1763                 nic->mac_opened = 0;
1764
1765         }
1766
1767         #ifndef WILC_SDIO
1768         if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) {
1769                 PRINT_ER("Can't initialize SPI\n");
1770                 return -1; /* ERROR */
1771         }
1772         g_linux_wlan->wilc_spidev = wilc_spi_dev;
1773         #else
1774         g_linux_wlan->wilc_sdio_func = local_sdio_func;
1775         #endif
1776
1777         return 0;
1778 }
1779
1780 /*The 1st function called after module inserted*/
1781 static int __init init_wilc_driver(void)
1782 {
1783 #ifdef WILC_SPI
1784         struct wilc *wilc;
1785 #endif
1786
1787 #if defined(WILC_DEBUGFS)
1788         if (wilc_debugfs_init() < 0) {
1789                 PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n");
1790                 return -1;
1791         }
1792 #endif
1793
1794         printk("IN INIT FUNCTION\n");
1795         printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n");
1796
1797         linux_wlan_device_power(1);
1798         msleep(100);
1799         linux_wlan_device_detection(1);
1800
1801 #ifdef WILC_SDIO
1802         {
1803                 int ret;
1804
1805                 ret = sdio_register_driver(&wilc_bus);
1806                 if (ret < 0)
1807                         PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n");
1808
1809                 return ret;
1810         }
1811 #else
1812         PRINT_D(INIT_DBG, "Initializing netdev\n");
1813         if (wilc_netdev_init(&wilc))
1814                 PRINT_ER("Couldn't initialize netdev\n");
1815         return 0;
1816 #endif
1817 }
1818 late_initcall(init_wilc_driver);
1819
1820 static void __exit exit_wilc_driver(void)
1821 {
1822 #ifndef WILC_SDIO
1823         PRINT_D(INIT_DBG, "SPI unregister...\n");
1824         spi_unregister_driver(&wilc_bus);
1825 #else
1826         PRINT_D(INIT_DBG, "SDIO unregister...\n");
1827         sdio_unregister_driver(&wilc_bus);
1828 #endif
1829 }
1830 module_exit(exit_wilc_driver);
1831
1832 MODULE_LICENSE("GPL");