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