]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/wireless/quantenna/qtnfmac/core.c
treewide: setup_timer() -> timer_setup()
[mirror_ubuntu-bionic-kernel.git] / drivers / net / wireless / quantenna / qtnfmac / core.c
CommitLineData
98f44cb0
IM
1/*
2 * Copyright (c) 2015-2016 Quantenna Communications, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/if_ether.h>
20
21#include "core.h"
22#include "bus.h"
23#include "trans.h"
24#include "commands.h"
25#include "cfg80211.h"
26#include "event.h"
27#include "util.h"
28
29#define QTNF_DMP_MAX_LEN 48
30#define QTNF_PRIMARY_VIF_IDX 0
31
32struct qtnf_frame_meta_info {
33 u8 magic_s;
34 u8 ifidx;
35 u8 macid;
36 u8 magic_e;
37} __packed;
38
39struct qtnf_wmac *qtnf_core_get_mac(const struct qtnf_bus *bus, u8 macid)
40{
41 struct qtnf_wmac *mac = NULL;
42
43 if (unlikely(macid >= QTNF_MAX_MAC)) {
44 pr_err("invalid MAC index %u\n", macid);
45 return NULL;
46 }
47
48 mac = bus->mac[macid];
49
50 if (unlikely(!mac)) {
51 pr_err("MAC%u: not initialized\n", macid);
52 return NULL;
53 }
54
55 return mac;
56}
57
58/* Netdev handler for open.
59 */
60static int qtnf_netdev_open(struct net_device *ndev)
61{
62 netif_carrier_off(ndev);
63 qtnf_netdev_updown(ndev, 1);
64 return 0;
65}
66
67/* Netdev handler for close.
68 */
69static int qtnf_netdev_close(struct net_device *ndev)
70{
71 netif_carrier_off(ndev);
72 qtnf_virtual_intf_cleanup(ndev);
73 qtnf_netdev_updown(ndev, 0);
74 return 0;
75}
76
77/* Netdev handler for data transmission.
78 */
79static int
80qtnf_netdev_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
81{
82 struct qtnf_vif *vif;
83 struct qtnf_wmac *mac;
84
85 vif = qtnf_netdev_get_priv(ndev);
86
87 if (unlikely(skb->dev != ndev)) {
88 pr_err_ratelimited("invalid skb->dev");
89 dev_kfree_skb_any(skb);
90 return 0;
91 }
92
93 if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) {
94 pr_err_ratelimited("%s: VIF not initialized\n", ndev->name);
95 dev_kfree_skb_any(skb);
96 return 0;
97 }
98
99 mac = vif->mac;
100 if (unlikely(!mac)) {
101 pr_err_ratelimited("%s: NULL mac pointer", ndev->name);
102 dev_kfree_skb_any(skb);
103 return 0;
104 }
105
106 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
107 pr_err_ratelimited("%s: invalid skb len %d\n", ndev->name,
108 skb->len);
109 dev_kfree_skb_any(skb);
110 ndev->stats.tx_dropped++;
111 return 0;
112 }
113
114 /* tx path is enabled: reset vif timeout */
115 vif->cons_tx_timeout_cnt = 0;
116
117 return qtnf_bus_data_tx(mac->bus, skb);
118}
119
120/* Netdev handler for getting stats.
121 */
122static struct net_device_stats *qtnf_netdev_get_stats(struct net_device *dev)
123{
124 return &dev->stats;
125}
126
127/* Netdev handler for transmission timeout.
128 */
129static void qtnf_netdev_tx_timeout(struct net_device *ndev)
130{
131 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
132 struct qtnf_wmac *mac;
133 struct qtnf_bus *bus;
134
135 if (unlikely(!vif || !vif->mac || !vif->mac->bus))
136 return;
137
138 mac = vif->mac;
139 bus = mac->bus;
140
141 pr_warn("VIF%u.%u: Tx timeout- %lu\n", mac->macid, vif->vifid, jiffies);
142
143 qtnf_bus_data_tx_timeout(bus, ndev);
144 ndev->stats.tx_errors++;
145
146 if (++vif->cons_tx_timeout_cnt > QTNF_TX_TIMEOUT_TRSHLD) {
147 pr_err("Tx timeout threshold exceeded !\n");
148 pr_err("schedule interface %s reset !\n", netdev_name(ndev));
149 queue_work(bus->workqueue, &vif->reset_work);
150 }
151}
152
153/* Network device ops handlers */
154const struct net_device_ops qtnf_netdev_ops = {
155 .ndo_open = qtnf_netdev_open,
156 .ndo_stop = qtnf_netdev_close,
157 .ndo_start_xmit = qtnf_netdev_hard_start_xmit,
158 .ndo_tx_timeout = qtnf_netdev_tx_timeout,
159 .ndo_get_stats = qtnf_netdev_get_stats,
160};
161
162static int qtnf_mac_init_single_band(struct wiphy *wiphy,
163 struct qtnf_wmac *mac,
164 enum nl80211_band band)
165{
166 int ret;
167
168 wiphy->bands[band] = kzalloc(sizeof(*wiphy->bands[band]), GFP_KERNEL);
169 if (!wiphy->bands[band])
170 return -ENOMEM;
171
172 wiphy->bands[band]->band = band;
173
e294cbfd 174 ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]);
98f44cb0
IM
175 if (ret) {
176 pr_err("MAC%u: band %u: failed to get chans info: %d\n",
177 mac->macid, band, ret);
178 return ret;
179 }
180
181 qtnf_band_init_rates(wiphy->bands[band]);
98f44cb0
IM
182
183 return 0;
184}
185
186static int qtnf_mac_init_bands(struct qtnf_wmac *mac)
187{
188 struct wiphy *wiphy = priv_to_wiphy(mac);
189 int ret = 0;
190
191 if (mac->macinfo.bands_cap & QLINK_BAND_2GHZ) {
192 ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_2GHZ);
193 if (ret)
194 goto out;
195 }
196
197 if (mac->macinfo.bands_cap & QLINK_BAND_5GHZ) {
198 ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_5GHZ);
199 if (ret)
200 goto out;
201 }
202
203 if (mac->macinfo.bands_cap & QLINK_BAND_60GHZ)
204 ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_60GHZ);
205
206out:
207 return ret;
208}
209
210struct qtnf_vif *qtnf_mac_get_free_vif(struct qtnf_wmac *mac)
211{
212 struct qtnf_vif *vif;
213 int i;
214
215 for (i = 0; i < QTNF_MAX_INTF; i++) {
216 vif = &mac->iflist[i];
217 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
218 return vif;
219 }
220
221 return NULL;
222}
223
224struct qtnf_vif *qtnf_mac_get_base_vif(struct qtnf_wmac *mac)
225{
226 struct qtnf_vif *vif;
227
228 vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX];
229
230 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
231 return NULL;
232
233 return vif;
234}
235
236static void qtnf_vif_reset_handler(struct work_struct *work)
237{
238 struct qtnf_vif *vif = container_of(work, struct qtnf_vif, reset_work);
239
240 rtnl_lock();
241
242 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {
243 rtnl_unlock();
244 return;
245 }
246
247 /* stop tx completely */
248 netif_tx_stop_all_queues(vif->netdev);
249 if (netif_carrier_ok(vif->netdev))
250 netif_carrier_off(vif->netdev);
251
252 qtnf_cfg80211_vif_reset(vif);
253
254 rtnl_unlock();
255}
256
257static void qtnf_mac_init_primary_intf(struct qtnf_wmac *mac)
258{
259 struct qtnf_vif *vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX];
260
261 vif->wdev.iftype = NL80211_IFTYPE_AP;
262 vif->bss_priority = QTNF_DEF_BSS_PRIORITY;
263 vif->wdev.wiphy = priv_to_wiphy(mac);
264 INIT_WORK(&vif->reset_work, qtnf_vif_reset_handler);
265 vif->cons_tx_timeout_cnt = 0;
266}
267
268static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
269 unsigned int macid)
270{
271 struct wiphy *wiphy;
272 struct qtnf_wmac *mac;
273 unsigned int i;
274
275 wiphy = qtnf_wiphy_allocate(bus);
276 if (!wiphy)
277 return ERR_PTR(-ENOMEM);
278
279 mac = wiphy_priv(wiphy);
280
281 mac->macid = macid;
282 mac->bus = bus;
283
284 for (i = 0; i < QTNF_MAX_INTF; i++) {
285 memset(&mac->iflist[i], 0, sizeof(struct qtnf_vif));
286 mac->iflist[i].wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
287 mac->iflist[i].mac = mac;
288 mac->iflist[i].vifid = i;
289 qtnf_sta_list_init(&mac->iflist[i].sta_list);
c7ead2ab 290 mutex_init(&mac->mac_lock);
e99e88a9 291 timer_setup(&mac->scan_timeout, NULL, 0);
98f44cb0
IM
292 }
293
294 qtnf_mac_init_primary_intf(mac);
295 bus->mac[macid] = mac;
296
297 return mac;
298}
299
300int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,
301 const char *name, unsigned char name_assign_type,
302 enum nl80211_iftype iftype)
303{
304 struct wiphy *wiphy = priv_to_wiphy(mac);
305 struct net_device *dev;
306 void *qdev_vif;
307 int ret;
308
309 dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name,
310 name_assign_type, ether_setup, 1, 1);
311 if (!dev) {
312 memset(&vif->wdev, 0, sizeof(vif->wdev));
313 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
314 return -ENOMEM;
315 }
316
317 vif->netdev = dev;
318
319 dev->netdev_ops = &qtnf_netdev_ops;
0ddead90 320 dev->needs_free_netdev = true;
98f44cb0
IM
321 dev_net_set(dev, wiphy_net(wiphy));
322 dev->ieee80211_ptr = &vif->wdev;
323 dev->ieee80211_ptr->iftype = iftype;
324 ether_addr_copy(dev->dev_addr, vif->mac_addr);
325 SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
326 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
327 dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT;
328 dev->tx_queue_len = 100;
329
330 qdev_vif = netdev_priv(dev);
331 *((void **)qdev_vif) = vif;
332
333 SET_NETDEV_DEV(dev, mac->bus->dev);
334
335 ret = register_netdevice(dev);
336 if (ret) {
337 free_netdev(dev);
338 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
339 }
340
341 return ret;
342}
343
344static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid)
345{
346 struct qtnf_wmac *mac;
347 struct wiphy *wiphy;
348 struct qtnf_vif *vif;
349 unsigned int i;
350 enum nl80211_band band;
351
352 mac = bus->mac[macid];
353
354 if (!mac)
355 return;
356
357 wiphy = priv_to_wiphy(mac);
358
359 for (i = 0; i < QTNF_MAX_INTF; i++) {
360 vif = &mac->iflist[i];
361 rtnl_lock();
362 if (vif->netdev &&
363 vif->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) {
364 qtnf_virtual_intf_cleanup(vif->netdev);
365 qtnf_del_virtual_intf(wiphy, &vif->wdev);
366 }
367 rtnl_unlock();
368 qtnf_sta_list_free(&vif->sta_list);
369 }
370
371 if (mac->wiphy_registered)
372 wiphy_unregister(wiphy);
373
374 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; ++band) {
375 if (!wiphy->bands[band])
376 continue;
377
378 kfree(wiphy->bands[band]->channels);
379 wiphy->bands[band]->n_channels = 0;
380
381 kfree(wiphy->bands[band]);
382 wiphy->bands[band] = NULL;
383 }
384
385 kfree(mac->macinfo.limits);
386 kfree(wiphy->iface_combinations);
387 wiphy_free(wiphy);
388 bus->mac[macid] = NULL;
389}
390
391static int qtnf_core_mac_attach(struct qtnf_bus *bus, unsigned int macid)
392{
393 struct qtnf_wmac *mac;
394 struct qtnf_vif *vif;
395 int ret;
396
397 if (!(bus->hw_info.mac_bitmap & BIT(macid))) {
398 pr_info("MAC%u is not active in FW\n", macid);
399 return 0;
400 }
401
402 mac = qtnf_core_mac_alloc(bus, macid);
403 if (IS_ERR(mac)) {
404 pr_err("MAC%u allocation failed\n", macid);
405 return PTR_ERR(mac);
406 }
407
408 ret = qtnf_cmd_get_mac_info(mac);
409 if (ret) {
410 pr_err("MAC%u: failed to get info\n", macid);
411 goto error;
412 }
413
414 vif = qtnf_mac_get_base_vif(mac);
415 if (!vif) {
416 pr_err("MAC%u: primary VIF is not ready\n", macid);
417 ret = -EFAULT;
418 goto error;
419 }
420
421 ret = qtnf_cmd_send_add_intf(vif, NL80211_IFTYPE_AP, vif->mac_addr);
422 if (ret) {
423 pr_err("MAC%u: failed to add VIF\n", macid);
424 goto error;
425 }
426
427 ret = qtnf_cmd_send_get_phy_params(mac);
428 if (ret) {
429 pr_err("MAC%u: failed to get PHY settings\n", macid);
430 goto error;
431 }
432
433 ret = qtnf_mac_init_bands(mac);
434 if (ret) {
435 pr_err("MAC%u: failed to init bands\n", macid);
436 goto error;
437 }
438
439 ret = qtnf_wiphy_register(&bus->hw_info, mac);
440 if (ret) {
441 pr_err("MAC%u: wiphy registration failed\n", macid);
442 goto error;
443 }
444
445 mac->wiphy_registered = 1;
446
447 rtnl_lock();
448
449 ret = qtnf_core_net_attach(mac, vif, "wlan%d", NET_NAME_ENUM,
450 NL80211_IFTYPE_AP);
451 rtnl_unlock();
452
453 if (ret) {
454 pr_err("MAC%u: failed to attach netdev\n", macid);
455 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
456 vif->netdev = NULL;
457 goto error;
458 }
459
460 pr_debug("MAC%u initialized\n", macid);
461
462 return 0;
463
464error:
465 qtnf_core_mac_detach(bus, macid);
466 return ret;
467}
468
469int qtnf_core_attach(struct qtnf_bus *bus)
470{
471 unsigned int i;
472 int ret;
473
474 qtnf_trans_init(bus);
475
476 bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
477 qtnf_bus_data_rx_start(bus);
478
479 bus->workqueue = alloc_ordered_workqueue("QTNF_BUS", 0);
480 if (!bus->workqueue) {
481 pr_err("failed to alloc main workqueue\n");
482 ret = -ENOMEM;
483 goto error;
484 }
485
486 INIT_WORK(&bus->event_work, qtnf_event_work_handler);
487
488 ret = qtnf_cmd_send_init_fw(bus);
489 if (ret) {
490 pr_err("failed to init FW: %d\n", ret);
491 goto error;
492 }
493
494 bus->fw_state = QTNF_FW_STATE_ACTIVE;
495
496 ret = qtnf_cmd_get_hw_info(bus);
497 if (ret) {
498 pr_err("failed to get HW info: %d\n", ret);
499 goto error;
500 }
501
502 if (bus->hw_info.ql_proto_ver != QLINK_PROTO_VER) {
503 pr_err("qlink version mismatch %u != %u\n",
504 QLINK_PROTO_VER, bus->hw_info.ql_proto_ver);
505 ret = -EPROTONOSUPPORT;
506 goto error;
507 }
508
509 if (bus->hw_info.num_mac > QTNF_MAX_MAC) {
510 pr_err("no support for number of MACs=%u\n",
511 bus->hw_info.num_mac);
512 ret = -ERANGE;
513 goto error;
514 }
515
516 for (i = 0; i < bus->hw_info.num_mac; i++) {
517 ret = qtnf_core_mac_attach(bus, i);
518
519 if (ret) {
520 pr_err("MAC%u: attach failed: %d\n", i, ret);
521 goto error;
522 }
523 }
524
525 return 0;
526
527error:
528 qtnf_core_detach(bus);
529
530 return ret;
531}
532EXPORT_SYMBOL_GPL(qtnf_core_attach);
533
534void qtnf_core_detach(struct qtnf_bus *bus)
535{
536 unsigned int macid;
537
538 qtnf_bus_data_rx_stop(bus);
539
540 for (macid = 0; macid < QTNF_MAX_MAC; macid++)
541 qtnf_core_mac_detach(bus, macid);
542
543 if (bus->fw_state == QTNF_FW_STATE_ACTIVE)
544 qtnf_cmd_send_deinit_fw(bus);
545
546 bus->fw_state = QTNF_FW_STATE_DEAD;
547
548 if (bus->workqueue) {
549 flush_workqueue(bus->workqueue);
550 destroy_workqueue(bus->workqueue);
551 }
552
4dd07d2b
SM
553 kfree(bus->hw_info.rd);
554 bus->hw_info.rd = NULL;
555
98f44cb0
IM
556 qtnf_trans_free(bus);
557}
558EXPORT_SYMBOL_GPL(qtnf_core_detach);
559
560static inline int qtnf_is_frame_meta_magic_valid(struct qtnf_frame_meta_info *m)
561{
562 return m->magic_s == 0xAB && m->magic_e == 0xBA;
563}
564
565struct net_device *qtnf_classify_skb(struct qtnf_bus *bus, struct sk_buff *skb)
566{
567 struct qtnf_frame_meta_info *meta;
568 struct net_device *ndev = NULL;
569 struct qtnf_wmac *mac;
570 struct qtnf_vif *vif;
571
572 meta = (struct qtnf_frame_meta_info *)
573 (skb_tail_pointer(skb) - sizeof(*meta));
574
575 if (unlikely(!qtnf_is_frame_meta_magic_valid(meta))) {
576 pr_err_ratelimited("invalid magic 0x%x:0x%x\n",
577 meta->magic_s, meta->magic_e);
578 goto out;
579 }
580
581 if (unlikely(meta->macid >= QTNF_MAX_MAC)) {
582 pr_err_ratelimited("invalid mac(%u)\n", meta->macid);
583 goto out;
584 }
585
586 if (unlikely(meta->ifidx >= QTNF_MAX_INTF)) {
587 pr_err_ratelimited("invalid vif(%u)\n", meta->ifidx);
588 goto out;
589 }
590
591 mac = bus->mac[meta->macid];
592
593 if (unlikely(!mac)) {
594 pr_err_ratelimited("mac(%d) does not exist\n", meta->macid);
595 goto out;
596 }
597
598 vif = &mac->iflist[meta->ifidx];
599
600 if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) {
601 pr_err_ratelimited("vif(%u) does not exists\n", meta->ifidx);
602 goto out;
603 }
604
605 ndev = vif->netdev;
606
607 if (unlikely(!ndev)) {
608 pr_err_ratelimited("netdev for wlan%u.%u does not exists\n",
609 meta->macid, meta->ifidx);
610 goto out;
611 }
612
613 __skb_trim(skb, skb->len - sizeof(*meta));
614
615out:
616 return ndev;
617}
618EXPORT_SYMBOL_GPL(qtnf_classify_skb);
619
c35c0d54
SM
620void qtnf_wake_all_queues(struct net_device *ndev)
621{
622 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
623 struct qtnf_wmac *mac;
624 struct qtnf_bus *bus;
625 int macid;
626 int i;
627
628 if (unlikely(!vif || !vif->mac || !vif->mac->bus))
629 return;
630
631 bus = vif->mac->bus;
632
633 for (macid = 0; macid < QTNF_MAX_MAC; macid++) {
634 if (!(bus->hw_info.mac_bitmap & BIT(macid)))
635 continue;
636
637 mac = bus->mac[macid];
638 for (i = 0; i < QTNF_MAX_INTF; i++) {
639 vif = &mac->iflist[i];
640 if (vif->netdev && netif_queue_stopped(vif->netdev))
641 netif_tx_wake_all_queues(vif->netdev);
642 }
643 }
644}
645EXPORT_SYMBOL_GPL(qtnf_wake_all_queues);
646
98f44cb0
IM
647MODULE_AUTHOR("Quantenna Communications");
648MODULE_DESCRIPTION("Quantenna 802.11 wireless LAN FullMAC driver.");
649MODULE_LICENSE("GPL");