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