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