]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/linux_wlan.c
ipc/msg.c: use freezable blocking call
[karo-tx-linux.git] / drivers / staging / wilc1000 / linux_wlan.c
1 #include "wilc_wfi_cfgoperations.h"
2 #include "linux_wlan_common.h"
3 #include "wilc_wlan_if.h"
4 #include "wilc_wlan.h"
5
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/semaphore.h>
27
28 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
29
30 static struct notifier_block g_dev_notifier = {
31         .notifier_call = dev_state_ev_handler
32 };
33
34 #define IRQ_WAIT        1
35 #define IRQ_NO_WAIT     0
36 static struct semaphore close_exit_sync;
37
38 static int wlan_deinit_locks(struct net_device *dev);
39 static void wlan_deinitialize_threads(struct net_device *dev);
40
41 static void linux_wlan_tx_complete(void *priv, int status);
42 static int  mac_init_fn(struct net_device *ndev);
43 static struct net_device_stats *mac_stats(struct net_device *dev);
44 static int  mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
45 static void wilc_set_multicast_list(struct net_device *dev);
46
47 bool wilc_enable_ps = true;
48
49 static const struct net_device_ops wilc_netdev_ops = {
50         .ndo_init = mac_init_fn,
51         .ndo_open = wilc_mac_open,
52         .ndo_stop = wilc_mac_close,
53         .ndo_start_xmit = wilc_mac_xmit,
54         .ndo_do_ioctl = mac_ioctl,
55         .ndo_get_stats = mac_stats,
56         .ndo_set_rx_mode  = wilc_set_multicast_list,
57
58 };
59
60 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
61 {
62         struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
63         struct wilc_priv *priv;
64         struct host_if_drv *hif_drv;
65         struct net_device *dev;
66         u8 *ip_addr_buf;
67         struct wilc_vif *vif;
68         u8 null_ip[4] = {0};
69         char wlan_dev_name[5] = "wlan0";
70
71         if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) {
72                 PRINT_D(GENERIC_DBG, "dev_iface = NULL\n");
73                 return NOTIFY_DONE;
74         }
75
76         if (memcmp(dev_iface->ifa_label, "wlan0", 5) &&
77             memcmp(dev_iface->ifa_label, "p2p0", 4)) {
78                 PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n");
79                 return NOTIFY_DONE;
80         }
81
82         dev  = (struct net_device *)dev_iface->ifa_dev->dev;
83         if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) {
84                 PRINT_D(GENERIC_DBG, "No Wireless registerd\n");
85                 return NOTIFY_DONE;
86         }
87         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
88         if (!priv) {
89                 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
90                 return NOTIFY_DONE;
91         }
92         hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
93         vif = netdev_priv(dev);
94         if (!vif || !hif_drv) {
95                 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
96                 return NOTIFY_DONE;
97         }
98
99         PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n");
100
101         switch (event) {
102         case NETDEV_UP:
103                 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev);
104
105                 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
106
107                 if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
108                         hif_drv->IFC_UP = 1;
109                         wilc_optaining_ip = false;
110                         del_timer(&wilc_during_ip_timer);
111                         PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
112                 }
113
114                 if (wilc_enable_ps)
115                         wilc_set_power_mgmt(vif, 1, 0);
116
117                 PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
118
119                 ip_addr_buf = (char *)&dev_iface->ifa_address;
120                 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n",
121                         ip_addr_buf[0], ip_addr_buf[1],
122                         ip_addr_buf[2], ip_addr_buf[3]);
123                 wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx);
124
125                 break;
126
127         case NETDEV_DOWN:
128                 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev);
129
130                 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
131                 if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
132                         hif_drv->IFC_UP = 0;
133                         wilc_optaining_ip = false;
134                 }
135
136                 if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
137                         wilc_set_power_mgmt(vif, 0, 0);
138
139                 wilc_resolve_disconnect_aberration(vif);
140
141                 PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
142
143                 ip_addr_buf = null_ip;
144                 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n",
145                         ip_addr_buf[0], ip_addr_buf[1],
146                         ip_addr_buf[2], ip_addr_buf[3]);
147
148                 wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx);
149
150                 break;
151
152         default:
153                 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n");
154                 PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
155
156                 break;
157         }
158
159         return NOTIFY_DONE;
160 }
161
162 static irqreturn_t isr_uh_routine(int irq, void *user_data)
163 {
164         struct wilc_vif *vif;
165         struct wilc *wilc;
166         struct net_device *dev = (struct net_device *)user_data;
167
168         vif = netdev_priv(dev);
169         wilc = vif->wilc;
170         PRINT_D(INT_DBG, "Interrupt received UH\n");
171
172         if (wilc->close) {
173                 PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
174                 return IRQ_HANDLED;
175         }
176         return IRQ_WAKE_THREAD;
177 }
178
179 static irqreturn_t isr_bh_routine(int irq, void *userdata)
180 {
181         struct wilc_vif *vif;
182         struct wilc *wilc;
183
184         vif = netdev_priv(userdata);
185         wilc = vif->wilc;
186
187         if (wilc->close) {
188                 PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
189                 return IRQ_HANDLED;
190         }
191
192         PRINT_D(INT_DBG, "Interrupt received BH\n");
193         wilc_handle_isr(wilc);
194
195         return IRQ_HANDLED;
196 }
197
198 static int init_irq(struct net_device *dev)
199 {
200         int ret = 0;
201         struct wilc_vif *vif;
202         struct wilc *wl;
203
204         vif = netdev_priv(dev);
205         wl = vif->wilc;
206
207         if ((gpio_request(wl->gpio, "WILC_INTR") == 0) &&
208             (gpio_direction_input(wl->gpio) == 0)) {
209                 wl->dev_irq_num = gpio_to_irq(wl->gpio);
210         } else {
211                 ret = -1;
212                 PRINT_ER("could not obtain gpio for WILC_INTR\n");
213         }
214
215         if (ret != -1 && request_threaded_irq(wl->dev_irq_num,
216                                               isr_uh_routine,
217                                               isr_bh_routine,
218                                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
219                                               "WILC_IRQ", dev) < 0) {
220                 PRINT_ER("Failed to request IRQ for GPIO: %d\n", wl->gpio);
221                 gpio_free(wl->gpio);
222                 ret = -1;
223         } else {
224                 PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
225                         wl->dev_irq_num, wl->gpio);
226         }
227
228         return ret;
229 }
230
231 static void deinit_irq(struct net_device *dev)
232 {
233         struct wilc_vif *vif;
234         struct wilc *wilc;
235
236         vif = netdev_priv(dev);
237         wilc = vif->wilc;
238
239         /* Deintialize IRQ */
240         if (wilc->dev_irq_num) {
241                 free_irq(wilc->dev_irq_num, wilc);
242                 gpio_free(wilc->gpio);
243         }
244 }
245
246 void wilc_dbg(u8 *buff)
247 {
248         PRINT_D(INIT_DBG, "%d\n", *buff);
249 }
250
251 int wilc_lock_timeout(struct wilc *nic, void *vp, u32 timeout)
252 {
253         /* FIXME: replace with mutex_lock or wait_for_completion */
254         int error = -1;
255
256         PRINT_D(LOCK_DBG, "Locking %p\n", vp);
257         if (vp)
258                 error = down_timeout((struct semaphore *)vp,
259                                      msecs_to_jiffies(timeout));
260         else
261                 PRINT_ER("Failed, mutex is NULL\n");
262         return error;
263 }
264
265 void wilc_mac_indicate(struct wilc *wilc, int flag)
266 {
267         int status;
268
269         if (flag == WILC_MAC_INDICATE_STATUS) {
270                 wilc_wlan_cfg_get_val(WID_STATUS,
271                                       (unsigned char *)&status, 4);
272                 if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
273                         wilc->mac_status = status;
274                         up(&wilc->sync_event);
275                 } else {
276                         wilc->mac_status = status;
277                 }
278         } else if (flag == WILC_MAC_INDICATE_SCAN) {
279                 PRINT_D(GENERIC_DBG, "Scanning ...\n");
280         }
281 }
282
283 static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
284 {
285         u8 *bssid, *bssid1;
286         int i = 0;
287
288         bssid = mac_header + 10;
289         bssid1 = mac_header + 4;
290
291         for (i = 0; i < wilc->vif_num; i++)
292                 if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) ||
293                     !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN))
294                         return wilc->vif[i]->ndev;
295
296         PRINT_INFO(INIT_DBG, "Invalide handle\n");
297         for (i = 0; i < 25; i++)
298                 PRINT_D(INIT_DBG, "%02x ", mac_header[i]);
299         bssid = mac_header + 18;
300         bssid1 = mac_header + 12;
301         for (i = 0; i < wilc->vif_num; i++)
302                 if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) ||
303                     !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN))
304                         return wilc->vif[i]->ndev;
305
306         PRINT_INFO(INIT_DBG, "\n");
307         return NULL;
308 }
309
310 int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid)
311 {
312         int i = 0;
313         int ret = -1;
314         struct wilc_vif *vif;
315         struct wilc *wilc;
316
317         vif = netdev_priv(wilc_netdev);
318         wilc = vif->wilc;
319
320         for (i = 0; i < wilc->vif_num; i++)
321                 if (wilc->vif[i]->ndev == wilc_netdev) {
322                         memcpy(wilc->vif[i]->bssid, bssid, 6);
323                         ret = 0;
324                         break;
325                 }
326
327         return ret;
328 }
329
330 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
331 {
332         u8 i = 0;
333         u8 null_bssid[6] = {0};
334         u8 ret_val = 0;
335
336         for (i = 0; i < wilc->vif_num; i++)
337                 if (memcmp(wilc->vif[i]->bssid, null_bssid, 6))
338                         ret_val++;
339
340         return ret_val;
341 }
342
343 #define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
344
345 static int linux_wlan_txq_task(void *vp)
346 {
347         int ret, txq_count;
348         struct wilc_vif *vif;
349         struct wilc *wl;
350         struct net_device *dev = vp;
351 #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
352 #define TX_BACKOFF_WEIGHT_INCR_STEP (1)
353 #define TX_BACKOFF_WEIGHT_DECR_STEP (1)
354 #define TX_BACKOFF_WEIGHT_MAX (7)
355 #define TX_BACKOFF_WEIGHT_MIN (0)
356 #define TX_BACKOFF_WEIGHT_UNIT_MS (10)
357         int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
358 #endif
359
360         vif = netdev_priv(dev);
361         wl = vif->wilc;
362
363         up(&wl->txq_thread_started);
364         while (1) {
365                 PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
366                 down(&wl->txq_event);
367                 PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
368
369                 if (wl->close) {
370                         up(&wl->txq_thread_started);
371
372                         while (!kthread_should_stop())
373                                 schedule();
374
375                         PRINT_D(TX_DBG, "TX thread stopped\n");
376                         break;
377                 }
378                 PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n");
379 #if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
380                 ret = wilc_wlan_handle_txq(dev, &txq_count);
381 #else
382                 do {
383                         ret = wilc_wlan_handle_txq(dev, &txq_count);
384                         if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
385                                 PRINT_D(TX_DBG, "Waking up queue\n");
386
387                                 if (netif_queue_stopped(wl->vif[0]->ndev))
388                                         netif_wake_queue(wl->vif[0]->ndev);
389                                 if (netif_queue_stopped(wl->vif[1]->ndev))
390                                         netif_wake_queue(wl->vif[1]->ndev);
391                         }
392
393                         if (ret == WILC_TX_ERR_NO_BUF) {
394                                 do {
395                                         msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
396                                 } while (0);
397                                 backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
398                                 if (backoff_weight > TX_BACKOFF_WEIGHT_MAX)
399                                         backoff_weight = TX_BACKOFF_WEIGHT_MAX;
400                         } else {
401                                 if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
402                                         backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
403                                         if (backoff_weight < TX_BACKOFF_WEIGHT_MIN)
404                                                 backoff_weight = TX_BACKOFF_WEIGHT_MIN;
405                                 }
406                         }
407                 } while (ret == WILC_TX_ERR_NO_BUF && !wl->close);
408 #endif
409         }
410         return 0;
411 }
412
413 void wilc_rx_complete(struct wilc *nic)
414 {
415         PRINT_D(RX_DBG, "RX completed\n");
416 }
417
418 int wilc_wlan_get_firmware(struct net_device *dev)
419 {
420         struct wilc_vif *vif;
421         struct wilc *wilc;
422         int ret = 0;
423         const struct firmware *wilc_firmware;
424         char *firmware;
425
426         vif = netdev_priv(dev);
427         wilc = vif->wilc;
428
429         if (vif->iftype == AP_MODE) {
430                 firmware = AP_FIRMWARE;
431         } else if (vif->iftype == STATION_MODE) {
432                 firmware = STA_FIRMWARE;
433         } else {
434                 PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
435                 firmware = P2P_CONCURRENCY_FIRMWARE;
436         }
437
438         if (!vif) {
439                 PRINT_ER("vif is NULL\n");
440                 goto _fail_;
441         }
442
443         if (!(&vif->ndev->dev)) {
444                 PRINT_ER("&vif->ndev->dev  is NULL\n");
445                 goto _fail_;
446         }
447
448         if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
449                 PRINT_ER("%s - firmare not available\n", firmware);
450                 ret = -1;
451                 goto _fail_;
452         }
453         wilc->firmware = wilc_firmware;
454
455 _fail_:
456
457         return ret;
458 }
459
460 static int linux_wlan_start_firmware(struct net_device *dev)
461 {
462         struct wilc_vif *vif;
463         struct wilc *wilc;
464         int ret = 0;
465
466         vif = netdev_priv(dev);
467         wilc = vif->wilc;
468
469         PRINT_D(INIT_DBG, "Starting Firmware ...\n");
470         ret = wilc_wlan_start(wilc);
471         if (ret < 0) {
472                 PRINT_ER("Failed to start Firmware\n");
473                 return ret;
474         }
475
476         PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
477         ret = wilc_lock_timeout(wilc, &wilc->sync_event, 5000);
478         if (ret) {
479                 PRINT_D(INIT_DBG, "Firmware start timed out");
480                 return ret;
481         }
482         PRINT_D(INIT_DBG, "Firmware successfully started\n");
483
484         return 0;
485 }
486
487 static int wilc1000_firmware_download(struct net_device *dev)
488 {
489         struct wilc_vif *vif;
490         struct wilc *wilc;
491         int ret = 0;
492
493         vif = netdev_priv(dev);
494         wilc = vif->wilc;
495
496         if (!wilc->firmware) {
497                 PRINT_ER("Firmware buffer is NULL\n");
498                 return -ENOBUFS;
499         }
500         PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
501         ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
502                                           wilc->firmware->size);
503         if (ret < 0)
504                 return ret;
505
506         PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
507         PRINT_D(INIT_DBG, "Releasing firmware\n");
508         release_firmware(wilc->firmware);
509         wilc->firmware = NULL;
510
511         PRINT_D(INIT_DBG, "Download Succeeded\n");
512
513         return 0;
514 }
515
516 static int linux_wlan_init_test_config(struct net_device *dev,
517                                        struct wilc *wilc)
518 {
519         unsigned char c_val[64];
520         unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
521
522         struct wilc_priv *priv;
523         struct host_if_drv *hif_drv;
524
525         PRINT_D(TX_DBG, "Start configuring Firmware\n");
526         get_random_bytes(&mac_add[5], 1);
527         get_random_bytes(&mac_add[4], 1);
528         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
529         hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
530         PRINT_D(INIT_DBG, "Host = %p\n", hif_drv);
531
532         PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n",
533                 mac_add[0], mac_add[1], mac_add[2],
534                 mac_add[3], mac_add[4], mac_add[5]);
535         wilc_get_chipid(wilc, 0);
536
537         *(int *)c_val = 1;
538
539         if (!wilc_wlan_cfg_set(wilc, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
540                 goto _fail_;
541
542         c_val[0] = 0;
543         if (!wilc_wlan_cfg_set(wilc, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
544                 goto _fail_;
545
546         c_val[0] = INFRASTRUCTURE;
547         if (!wilc_wlan_cfg_set(wilc, 0, WID_BSS_TYPE, c_val, 1, 0, 0))
548                 goto _fail_;
549
550         c_val[0] = RATE_AUTO;
551         if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
552                 goto _fail_;
553
554         c_val[0] = G_MIXED_11B_2_MODE;
555         if (!wilc_wlan_cfg_set(wilc, 0, WID_11G_OPERATING_MODE, c_val, 1, 0,
556                                0))
557                 goto _fail_;
558
559         c_val[0] = 1;
560         if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
561                 goto _fail_;
562
563         c_val[0] = G_SHORT_PREAMBLE;
564         if (!wilc_wlan_cfg_set(wilc, 0, WID_PREAMBLE, c_val, 1, 0, 0))
565                 goto _fail_;
566
567         c_val[0] = AUTO_PROT;
568         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
569                 goto _fail_;
570
571         c_val[0] = ACTIVE_SCAN;
572         if (!wilc_wlan_cfg_set(wilc, 0, WID_SCAN_TYPE, c_val, 1, 0, 0))
573                 goto _fail_;
574
575         c_val[0] = SITE_SURVEY_OFF;
576         if (!wilc_wlan_cfg_set(wilc, 0, WID_SITE_SURVEY, c_val, 1, 0, 0))
577                 goto _fail_;
578
579         *((int *)c_val) = 0xffff;
580         if (!wilc_wlan_cfg_set(wilc, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
581                 goto _fail_;
582
583         *((int *)c_val) = 2346;
584         if (!wilc_wlan_cfg_set(wilc, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
585                 goto _fail_;
586
587         c_val[0] = 0;
588         if (!wilc_wlan_cfg_set(wilc, 0, WID_BCAST_SSID, c_val, 1, 0, 0))
589                 goto _fail_;
590
591         c_val[0] = 1;
592         if (!wilc_wlan_cfg_set(wilc, 0, WID_QOS_ENABLE, c_val, 1, 0, 0))
593                 goto _fail_;
594
595         c_val[0] = NO_POWERSAVE;
596         if (!wilc_wlan_cfg_set(wilc, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
597                 goto _fail_;
598
599         c_val[0] = NO_SECURITY; /* NO_ENCRYPT, 0x79 */
600         if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_MODE, c_val, 1, 0, 0))
601                 goto _fail_;
602
603         c_val[0] = OPEN_SYSTEM;
604         if (!wilc_wlan_cfg_set(wilc, 0, WID_AUTH_TYPE, c_val, 1, 0, 0))
605                 goto _fail_;
606
607         strcpy(c_val, "123456790abcdef1234567890");
608         if (!wilc_wlan_cfg_set(wilc, 0, WID_WEP_KEY_VALUE, c_val,
609                                (strlen(c_val) + 1), 0, 0))
610                 goto _fail_;
611
612         strcpy(c_val, "12345678");
613         if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0,
614                                0))
615                 goto _fail_;
616
617         strcpy(c_val, "password");
618         if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1),
619                                0, 0))
620                 goto _fail_;
621
622         c_val[0] = 192;
623         c_val[1] = 168;
624         c_val[2] = 1;
625         c_val[3] = 112;
626         if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
627                 goto _fail_;
628
629         c_val[0] = 3;
630         if (!wilc_wlan_cfg_set(wilc, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
631                 goto _fail_;
632
633         c_val[0] = 3;
634         if (!wilc_wlan_cfg_set(wilc, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
635                 goto _fail_;
636
637         c_val[0] = NORMAL_ACK;
638         if (!wilc_wlan_cfg_set(wilc, 0, WID_ACK_POLICY, c_val, 1, 0, 0))
639                 goto _fail_;
640
641         c_val[0] = 0;
642         if (!wilc_wlan_cfg_set(wilc, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1,
643                                0, 0))
644                 goto _fail_;
645
646         c_val[0] = 48;
647         if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0,
648                                0))
649                 goto _fail_;
650
651         c_val[0] = 28;
652         if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0,
653                                0))
654                 goto _fail_;
655
656         *((int *)c_val) = 100;
657         if (!wilc_wlan_cfg_set(wilc, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
658                 goto _fail_;
659
660         c_val[0] = REKEY_DISABLE;
661         if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_POLICY, c_val, 1, 0, 0))
662                 goto _fail_;
663
664         *((int *)c_val) = 84600;
665         if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
666                 goto _fail_;
667
668         *((int *)c_val) = 500;
669         if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0,
670                                0))
671                 goto _fail_;
672
673         c_val[0] = 1;
674         if (!wilc_wlan_cfg_set(wilc, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0,
675                                0))
676                 goto _fail_;
677
678         c_val[0] = G_SELF_CTS_PROT;
679         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
680                 goto _fail_;
681
682         c_val[0] = 1;
683         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ENABLE, c_val, 1, 0, 0))
684                 goto _fail_;
685
686         c_val[0] = HT_MIXED_MODE;
687         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OPERATING_MODE, c_val, 1, 0,
688                                0))
689                 goto _fail_;
690
691         c_val[0] = 1;
692         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0,
693                                0))
694                 goto _fail_;
695
696         memcpy(c_val, mac_add, 6);
697
698         if (!wilc_wlan_cfg_set(wilc, 0, WID_MAC_ADDR, c_val, 6, 0, 0))
699                 goto _fail_;
700
701         c_val[0] = DETECT_PROTECT_REPORT;
702         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1,
703                                0, 0))
704                 goto _fail_;
705
706         c_val[0] = RTS_CTS_NONHT_PROT;
707         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
708                 goto _fail_;
709
710         c_val[0] = 0;
711         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0,
712                                0))
713                 goto _fail_;
714
715         c_val[0] = MIMO_MODE;
716         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
717                 goto _fail_;
718
719         c_val[0] = 7;
720         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0,
721                                0))
722                 goto _fail_;
723
724         c_val[0] = 1;
725         if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1,
726                                1, 1))
727                 goto _fail_;
728
729         return 0;
730
731 _fail_:
732         return -1;
733 }
734
735 void wilc1000_wlan_deinit(struct net_device *dev)
736 {
737         struct wilc_vif *vif;
738         struct wilc *wl;
739
740         vif = netdev_priv(dev);
741         wl = vif->wilc;
742
743         if (!wl) {
744                 netdev_err(dev, "wl is NULL\n");
745                 return;
746         }
747
748         if (wl->initialized)    {
749                 netdev_info(dev, "Deinitializing wilc1000...\n");
750
751                 PRINT_D(INIT_DBG, "Disabling IRQ\n");
752                 if (!wl->dev_irq_num &&
753                     wl->hif_func->disable_interrupt) {
754                         mutex_lock(&wl->hif_cs);
755                         wl->hif_func->disable_interrupt(wl);
756                         mutex_unlock(&wl->hif_cs);
757                 }
758                 if (&wl->txq_event)
759                         up(&wl->txq_event);
760
761                 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
762                 wlan_deinitialize_threads(dev);
763
764                 PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
765                 deinit_irq(dev);
766
767                 wilc_wlan_stop(wl);
768
769                 PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
770                 wilc_wlan_cleanup(dev);
771 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
772                 if (!wl->dev_irq_num &&
773                     wl->hif_func->disable_interrupt) {
774
775                         PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
776
777                         mutex_lock(&wl->hif_cs);
778                         wl->hif_func->disable_interrupt(wl);
779                         mutex_unlock(&wl->hif_cs);
780                 }
781 #endif
782
783                 PRINT_D(INIT_DBG, "Deinitializing Locks\n");
784                 wlan_deinit_locks(dev);
785
786                 wl->initialized = false;
787
788                 PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n");
789
790         } else {
791                 PRINT_D(INIT_DBG, "wilc1000 is not initialized\n");
792         }
793 }
794
795 static int wlan_init_locks(struct net_device *dev)
796 {
797         struct wilc_vif *vif;
798         struct wilc *wl;
799
800         vif = netdev_priv(dev);
801         wl = vif->wilc;
802
803         PRINT_D(INIT_DBG, "Initializing Locks ...\n");
804
805         mutex_init(&wl->hif_cs);
806         mutex_init(&wl->rxq_cs);
807
808         spin_lock_init(&wl->txq_spinlock);
809         sema_init(&wl->txq_add_to_head_cs, 1);
810
811         sema_init(&wl->txq_event, 0);
812
813         sema_init(&wl->cfg_event, 0);
814         sema_init(&wl->sync_event, 0);
815
816         sema_init(&wl->txq_thread_started, 0);
817
818         return 0;
819 }
820
821 static int wlan_deinit_locks(struct net_device *dev)
822 {
823         struct wilc_vif *vif;
824         struct wilc *wilc;
825
826         vif = netdev_priv(dev);
827         wilc = vif->wilc;
828
829         PRINT_D(INIT_DBG, "De-Initializing Locks\n");
830
831         if (&wilc->hif_cs)
832                 mutex_destroy(&wilc->hif_cs);
833
834         if (&wilc->rxq_cs)
835                 mutex_destroy(&wilc->rxq_cs);
836
837         return 0;
838 }
839
840 static int wlan_initialize_threads(struct net_device *dev)
841 {
842         struct wilc_vif *vif;
843         struct wilc *wilc;
844
845         vif = netdev_priv(dev);
846         wilc = vif->wilc;
847
848         PRINT_D(INIT_DBG, "Initializing Threads ...\n");
849         PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
850         wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev,
851                                      "K_TXQ_TASK");
852         if (!wilc->txq_thread) {
853                 PRINT_ER("couldn't create TXQ thread\n");
854                 wilc->close = 0;
855                 return -ENOBUFS;
856         }
857         down(&wilc->txq_thread_started);
858
859         return 0;
860 }
861
862 static void wlan_deinitialize_threads(struct net_device *dev)
863 {
864         struct wilc_vif *vif;
865         struct wilc *wl;
866         vif = netdev_priv(dev);
867         wl = vif->wilc;
868
869         wl->close = 1;
870         PRINT_D(INIT_DBG, "Deinitializing Threads\n");
871
872         if (&wl->txq_event)
873                 up(&wl->txq_event);
874
875         if (wl->txq_thread) {
876                 kthread_stop(wl->txq_thread);
877                 wl->txq_thread = NULL;
878         }
879 }
880
881 int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif)
882 {
883         int ret = 0;
884         struct wilc *wl = vif->wilc;
885
886         if (!wl->initialized) {
887                 wl->mac_status = WILC_MAC_STATUS_INIT;
888                 wl->close = 0;
889
890                 wlan_init_locks(dev);
891
892                 ret = wilc_wlan_init(dev);
893                 if (ret < 0) {
894                         PRINT_ER("Initializing WILC_Wlan FAILED\n");
895                         ret = -EIO;
896                         goto _fail_locks_;
897                 }
898
899                 if (wl->gpio >= 0 && init_irq(dev)) {
900                         PRINT_ER("couldn't initialize IRQ\n");
901                         ret = -EIO;
902                         goto _fail_locks_;
903                 }
904
905                 ret = wlan_initialize_threads(dev);
906                 if (ret < 0) {
907                         PRINT_ER("Initializing Threads FAILED\n");
908                         ret = -EIO;
909                         goto _fail_wilc_wlan_;
910                 }
911
912                 if (!wl->dev_irq_num &&
913                     wl->hif_func->enable_interrupt &&
914                     wl->hif_func->enable_interrupt(wl)) {
915                         PRINT_ER("couldn't initialize IRQ\n");
916                         ret = -EIO;
917                         goto _fail_irq_init_;
918                 }
919
920                 if (wilc_wlan_get_firmware(dev)) {
921                         PRINT_ER("Can't get firmware\n");
922                         ret = -EIO;
923                         goto _fail_irq_enable_;
924                 }
925
926                 ret = wilc1000_firmware_download(dev);
927                 if (ret < 0) {
928                         PRINT_ER("Failed to download firmware\n");
929                         ret = -EIO;
930                         goto _fail_irq_enable_;
931                 }
932
933                 ret = linux_wlan_start_firmware(dev);
934                 if (ret < 0) {
935                         PRINT_ER("Failed to start firmware\n");
936                         ret = -EIO;
937                         goto _fail_irq_enable_;
938                 }
939
940                 if (wilc_wlan_cfg_get(wl, 1, WID_FIRMWARE_VERSION, 1, 0)) {
941                         int size;
942                         char Firmware_ver[20];
943
944                         size = wilc_wlan_cfg_get_val(
945                                         WID_FIRMWARE_VERSION,
946                                         Firmware_ver, sizeof(Firmware_ver));
947                         Firmware_ver[size] = '\0';
948                         PRINT_D(INIT_DBG, "***** Firmware Ver = %s  *******\n", Firmware_ver);
949                 }
950                 ret = linux_wlan_init_test_config(dev, wl);
951
952                 if (ret < 0) {
953                         PRINT_ER("Failed to configure firmware\n");
954                         ret = -EIO;
955                         goto _fail_fw_start_;
956                 }
957
958                 wl->initialized = true;
959                 return 0;
960
961 _fail_fw_start_:
962                 wilc_wlan_stop(wl);
963
964 _fail_irq_enable_:
965                 if (!wl->dev_irq_num &&
966                     wl->hif_func->disable_interrupt)
967                         wl->hif_func->disable_interrupt(wl);
968 _fail_irq_init_:
969                 if (wl->dev_irq_num)
970                         deinit_irq(dev);
971
972                 wlan_deinitialize_threads(dev);
973 _fail_wilc_wlan_:
974                 wilc_wlan_cleanup(dev);
975 _fail_locks_:
976                 wlan_deinit_locks(dev);
977                 PRINT_ER("WLAN Iinitialization FAILED\n");
978         } else {
979                 PRINT_D(INIT_DBG, "wilc1000 already initialized\n");
980         }
981         return ret;
982 }
983
984 static int mac_init_fn(struct net_device *ndev)
985 {
986         netif_start_queue(ndev);
987         netif_stop_queue(ndev);
988
989         return 0;
990 }
991
992 int wilc_mac_open(struct net_device *ndev)
993 {
994         struct wilc_vif *vif;
995         struct wilc *wilc;
996
997         unsigned char mac_add[ETH_ALEN] = {0};
998         int ret = 0;
999         int i = 0;
1000         struct wilc_priv *priv;
1001         struct wilc *wl;
1002
1003         vif = netdev_priv(ndev);
1004         wl = vif->wilc;
1005
1006         if (!wl|| !wl->dev) {
1007                 netdev_err(ndev, "wilc1000: SPI device not ready\n");
1008                 return -ENODEV;
1009         }
1010
1011         vif = netdev_priv(ndev);
1012         wilc = vif->wilc;
1013         priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1014         PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
1015
1016         ret = wilc_init_host_int(ndev);
1017         if (ret < 0) {
1018                 PRINT_ER("Failed to initialize host interface\n");
1019
1020                 return ret;
1021         }
1022
1023         PRINT_D(INIT_DBG, "*** re-init ***\n");
1024         ret = wilc1000_wlan_init(ndev, vif);
1025         if (ret < 0) {
1026                 PRINT_ER("Failed to initialize wilc1000\n");
1027                 wilc_deinit_host_int(ndev);
1028                 return ret;
1029         }
1030
1031         wilc_set_machw_change_vir_if(ndev, false);
1032
1033         wilc_get_mac_address(vif, mac_add);
1034         PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
1035
1036         for (i = 0; i < wl->vif_num; i++) {
1037                 if (ndev == wl->vif[i]->ndev) {
1038                         memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN);
1039                         break;
1040                 }
1041         }
1042
1043         memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN);
1044
1045         if (!is_valid_ether_addr(ndev->dev_addr)) {
1046                 PRINT_ER("Error: Wrong MAC address\n");
1047                 wilc_deinit_host_int(ndev);
1048                 wilc1000_wlan_deinit(ndev);
1049                 return -EINVAL;
1050         }
1051
1052         wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
1053                                  vif->ndev->ieee80211_ptr,
1054                                  vif->g_struct_frame_reg[0].frame_type,
1055                                  vif->g_struct_frame_reg[0].reg);
1056         wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
1057                                  vif->ndev->ieee80211_ptr,
1058                                  vif->g_struct_frame_reg[1].frame_type,
1059                                  vif->g_struct_frame_reg[1].reg);
1060         netif_wake_queue(ndev);
1061         wl->open_ifcs++;
1062         vif->mac_opened = 1;
1063         return 0;
1064 }
1065
1066 static struct net_device_stats *mac_stats(struct net_device *dev)
1067 {
1068         struct wilc_vif *vif= netdev_priv(dev);
1069
1070         return &vif->netstats;
1071 }
1072
1073 static void wilc_set_multicast_list(struct net_device *dev)
1074 {
1075         struct netdev_hw_addr *ha;
1076         struct wilc_priv *priv;
1077         struct host_if_drv *hif_drv;
1078         struct wilc_vif *vif;
1079         int i = 0;
1080
1081         priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1082         vif = netdev_priv(dev);
1083         hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
1084
1085         if (!dev)
1086                 return;
1087
1088         PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n",
1089                 dev->mc.count);
1090
1091         if (dev->flags & IFF_PROMISC) {
1092                 PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n");
1093                 return;
1094         }
1095
1096         if ((dev->flags & IFF_ALLMULTI) ||
1097             (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
1098                 PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
1099                 wilc_setup_multicast_filter(vif, false, 0);
1100                 return;
1101         }
1102
1103         if ((dev->mc.count) == 0) {
1104                 PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
1105                 wilc_setup_multicast_filter(vif, true, 0);
1106                 return;
1107         }
1108
1109         netdev_for_each_mc_addr(ha, dev) {
1110                 memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN);
1111                 PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
1112                         wilc_multicast_mac_addr_list[i][0],
1113                         wilc_multicast_mac_addr_list[i][1],
1114                         wilc_multicast_mac_addr_list[i][2],
1115                         wilc_multicast_mac_addr_list[i][3],
1116                         wilc_multicast_mac_addr_list[i][4],
1117                         wilc_multicast_mac_addr_list[i][5]);
1118                 i++;
1119         }
1120
1121         wilc_setup_multicast_filter(vif, true, (dev->mc.count));
1122
1123         return;
1124 }
1125
1126 static void linux_wlan_tx_complete(void *priv, int status)
1127 {
1128         struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
1129
1130         if (status == 1)
1131                 PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1132         else
1133                 PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1134         dev_kfree_skb(pv_data->skb);
1135         kfree(pv_data);
1136 }
1137
1138 int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
1139 {
1140         struct wilc_vif *vif;
1141         struct tx_complete_data *tx_data = NULL;
1142         int queue_count;
1143         char *udp_buf;
1144         struct iphdr *ih;
1145         struct ethhdr *eth_h;
1146         struct wilc *wilc;
1147
1148         vif = netdev_priv(ndev);
1149         wilc = vif->wilc;
1150
1151         PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
1152
1153         if (skb->dev != ndev) {
1154                 PRINT_ER("Packet not destined to this device\n");
1155                 return 0;
1156         }
1157
1158         tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
1159         if (!tx_data) {
1160                 PRINT_ER("Failed to allocate memory for tx_data structure\n");
1161                 dev_kfree_skb(skb);
1162                 netif_wake_queue(ndev);
1163                 return 0;
1164         }
1165
1166         tx_data->buff = skb->data;
1167         tx_data->size = skb->len;
1168         tx_data->skb  = skb;
1169
1170         eth_h = (struct ethhdr *)(skb->data);
1171         if (eth_h->h_proto == 0x8e88)
1172                 PRINT_D(INIT_DBG, "EAPOL transmitted\n");
1173
1174         ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1175
1176         udp_buf = (char *)ih + sizeof(struct iphdr);
1177         if ((udp_buf[1] == 68 && udp_buf[3] == 67) ||
1178             (udp_buf[1] == 67 && udp_buf[3] == 68))
1179                 PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n",
1180                         udp_buf[248], udp_buf[249], udp_buf[250]);
1181
1182         PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
1183         PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
1184         vif->netstats.tx_packets++;
1185         vif->netstats.tx_bytes += tx_data->size;
1186         tx_data->pBssid = wilc->vif[vif->u8IfIdx]->bssid;
1187         queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
1188                                                 tx_data->buff, tx_data->size,
1189                                                 linux_wlan_tx_complete);
1190
1191         if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
1192                 netif_stop_queue(wilc->vif[0]->ndev);
1193                 netif_stop_queue(wilc->vif[1]->ndev);
1194         }
1195
1196         return 0;
1197 }
1198
1199 int wilc_mac_close(struct net_device *ndev)
1200 {
1201         struct wilc_priv *priv;
1202         struct wilc_vif *vif;
1203         struct host_if_drv *hif_drv;
1204         struct wilc *wl;
1205
1206         vif = netdev_priv(ndev);
1207
1208         if (!vif || !vif->ndev || !vif->ndev->ieee80211_ptr ||
1209             !vif->ndev->ieee80211_ptr->wiphy) {
1210                 PRINT_ER("vif = NULL\n");
1211                 return 0;
1212         }
1213
1214         priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1215         wl = vif->wilc;
1216
1217         if (!priv) {
1218                 PRINT_ER("priv = NULL\n");
1219                 return 0;
1220         }
1221
1222         hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
1223
1224         PRINT_D(GENERIC_DBG, "Mac close\n");
1225
1226         if (!wl) {
1227                 PRINT_ER("wl = NULL\n");
1228                 return 0;
1229         }
1230
1231         if (!hif_drv) {
1232                 PRINT_ER("hif_drv = NULL\n");
1233                 return 0;
1234         }
1235
1236         if ((wl->open_ifcs) > 0) {
1237                 wl->open_ifcs--;
1238         } else {
1239                 PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n");
1240                 return 0;
1241         }
1242
1243         if (vif->ndev) {
1244                 netif_stop_queue(vif->ndev);
1245
1246                 wilc_deinit_host_int(vif->ndev);
1247         }
1248
1249         if (wl->open_ifcs == 0) {
1250                 PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
1251                 wl->close = 1;
1252                 wilc1000_wlan_deinit(ndev);
1253                 WILC_WFI_deinit_mon_interface();
1254         }
1255
1256         up(&close_exit_sync);
1257         vif->mac_opened = 0;
1258
1259         return 0;
1260 }
1261
1262 static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1263 {
1264         u8 *buff = NULL;
1265         s8 rssi;
1266         u32 size = 0, length = 0;
1267         struct wilc_vif *vif;
1268         struct wilc_priv *priv;
1269         s32 ret = 0;
1270         struct wilc *wilc;
1271
1272         vif = netdev_priv(ndev);
1273         wilc = vif->wilc;
1274
1275         if (!wilc->initialized)
1276                 return 0;
1277
1278         switch (cmd) {
1279         case SIOCSIWPRIV:
1280         {
1281                 struct iwreq *wrq = (struct iwreq *) req;
1282
1283                 size = wrq->u.data.length;
1284
1285                 if (size && wrq->u.data.pointer) {
1286                         buff = memdup_user(wrq->u.data.pointer,
1287                                            wrq->u.data.length);
1288                         if (IS_ERR(buff))
1289                                 return PTR_ERR(buff);
1290
1291                         if (strncasecmp(buff, "RSSI", length) == 0) {
1292                                 priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1293                                 ret = wilc_get_rssi(vif, &rssi);
1294                                 if (ret)
1295                                         PRINT_ER("Failed to send get rssi param's message queue ");
1296                                 PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
1297
1298                                 rssi += 5;
1299
1300                                 snprintf(buff, size, "rssi %d", rssi);
1301
1302                                 if (copy_to_user(wrq->u.data.pointer, buff, size)) {
1303                                         PRINT_ER("%s: failed to copy data to user buffer\n", __func__);
1304                                         ret = -EFAULT;
1305                                         goto done;
1306                                 }
1307                         }
1308                 }
1309         }
1310         break;
1311
1312         default:
1313         {
1314                 PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd);
1315                 ret = -EOPNOTSUPP;
1316                 goto done;
1317         }
1318         }
1319
1320 done:
1321
1322         kfree(buff);
1323
1324         return ret;
1325 }
1326
1327 void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
1328 {
1329         unsigned int frame_len = 0;
1330         int stats;
1331         unsigned char *buff_to_send = NULL;
1332         struct sk_buff *skb;
1333         struct net_device *wilc_netdev;
1334         struct wilc_vif *vif;
1335
1336         wilc_netdev = get_if_handler(wilc, buff);
1337         if (!wilc_netdev)
1338                 return;
1339
1340         buff += pkt_offset;
1341         vif = netdev_priv(wilc_netdev);
1342
1343         if (size > 0) {
1344                 frame_len = size;
1345                 buff_to_send = buff;
1346
1347                 skb = dev_alloc_skb(frame_len);
1348                 if (!skb) {
1349                         PRINT_ER("Low memory - packet droped\n");
1350                         return;
1351                 }
1352
1353                 if (!wilc || !wilc_netdev)
1354                         PRINT_ER("wilc_netdev in wilc is NULL");
1355                 skb->dev = wilc_netdev;
1356
1357                 if (!skb->dev)
1358                         PRINT_ER("skb->dev is NULL\n");
1359
1360                 memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
1361
1362                 skb->protocol = eth_type_trans(skb, wilc_netdev);
1363                 vif->netstats.rx_packets++;
1364                 vif->netstats.rx_bytes += frame_len;
1365                 skb->ip_summed = CHECKSUM_UNNECESSARY;
1366                 stats = netif_rx(skb);
1367                 PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
1368         }
1369 }
1370
1371 void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
1372 {
1373         int i = 0;
1374         struct wilc_vif *vif;
1375
1376         for (i = 0; i < wilc->vif_num; i++) {
1377                 vif = netdev_priv(wilc->vif[i]->ndev);
1378                 if (vif->monitor_flag) {
1379                         WILC_WFI_monitor_rx(buff, size);
1380                         return;
1381                 }
1382         }
1383
1384         vif = netdev_priv(wilc->vif[1]->ndev);
1385         if ((buff[0] == vif->g_struct_frame_reg[0].frame_type && vif->g_struct_frame_reg[0].reg) ||
1386             (buff[0] == vif->g_struct_frame_reg[1].frame_type && vif->g_struct_frame_reg[1].reg))
1387                 WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size);
1388 }
1389
1390 void wilc_netdev_cleanup(struct wilc *wilc)
1391 {
1392         int i = 0;
1393         struct wilc_vif *vif[NUM_CONCURRENT_IFC];
1394
1395         if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
1396                 unregister_inetaddr_notifier(&g_dev_notifier);
1397
1398                 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1399                         vif[i] = netdev_priv(wilc->vif[i]->ndev);
1400         }
1401
1402         if (wilc && wilc->firmware)
1403                 release_firmware(wilc->firmware);
1404
1405         if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
1406                 wilc_lock_timeout(wilc, &close_exit_sync, 12 * 1000);
1407
1408                 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1409                         if (wilc->vif[i]->ndev)
1410                                 if (vif[i]->mac_opened)
1411                                         wilc_mac_close(wilc->vif[i]->ndev);
1412
1413                 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1414                         unregister_netdev(wilc->vif[i]->ndev);
1415                         wilc_free_wiphy(wilc->vif[i]->ndev);
1416                         free_netdev(wilc->vif[i]->ndev);
1417                 }
1418         }
1419
1420         kfree(wilc);
1421 }
1422 EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
1423
1424 int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
1425                      int gpio, const struct wilc_hif_func *ops)
1426 {
1427         int i;
1428         struct wilc_vif *vif;
1429         struct net_device *ndev;
1430         struct wilc *wl;
1431
1432         sema_init(&close_exit_sync, 0);
1433
1434         wl = kzalloc(sizeof(*wl), GFP_KERNEL);
1435         if (!wl)
1436                 return -ENOMEM;
1437
1438         *wilc = wl;
1439         wl->io_type = io_type;
1440         wl->gpio = gpio;
1441         wl->hif_func = ops;
1442
1443         register_inetaddr_notifier(&g_dev_notifier);
1444
1445         for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1446                 ndev = alloc_etherdev(sizeof(struct wilc_vif));
1447                 if (!ndev) {
1448                         PRINT_ER("Failed to allocate ethernet dev\n");
1449                         return -1;
1450                 }
1451
1452                 vif = netdev_priv(ndev);
1453                 memset(vif, 0, sizeof(struct wilc_vif));
1454
1455                 if (i == 0)
1456                         strcpy(ndev->name, "wlan%d");
1457                 else
1458                         strcpy(ndev->name, "p2p%d");
1459
1460                 vif->u8IfIdx = wl->vif_num;
1461                 vif->wilc = *wilc;
1462                 wl->vif[i] = vif;
1463                 wl->vif[wl->vif_num]->ndev = ndev;
1464                 wl->vif_num++;
1465                 ndev->netdev_ops = &wilc_netdev_ops;
1466
1467                 {
1468                         struct wireless_dev *wdev;
1469                         wdev = wilc_create_wiphy(ndev, dev);
1470
1471                         if (dev)
1472                                 SET_NETDEV_DEV(ndev, dev);
1473
1474                         if (!wdev) {
1475                                 PRINT_ER("Can't register WILC Wiphy\n");
1476                                 return -1;
1477                         }
1478
1479                         vif->ndev->ieee80211_ptr = wdev;
1480                         vif->ndev->ml_priv = vif;
1481                         wdev->netdev = vif->ndev;
1482                         vif->netstats.rx_packets = 0;
1483                         vif->netstats.tx_packets = 0;
1484                         vif->netstats.rx_bytes = 0;
1485                         vif->netstats.tx_bytes = 0;
1486                 }
1487
1488                 if (register_netdev(ndev)) {
1489                         PRINT_ER("Device couldn't be registered - %s\n",
1490                                  ndev->name);
1491                         return -1;
1492                 }
1493
1494                 vif->iftype = STATION_MODE;
1495                 vif->mac_opened = 0;
1496         }
1497
1498         return 0;
1499 }
1500 EXPORT_SYMBOL_GPL(wilc_netdev_init);
1501
1502 MODULE_LICENSE("GPL");