2 * Copyright (c) 2012-2012 Quantenna Communications, Inc.
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.
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.
17 #include <linux/kernel.h>
18 #include <linux/etherdevice.h>
19 #include <linux/vmalloc.h>
20 #include <linux/ieee80211.h>
21 #include <net/cfg80211.h>
22 #include <net/netlink.h>
30 /* Supported rates to be advertised to the cfg80211 */
31 static struct ieee80211_rate qtnf_rates_2g
[] = {
32 {.bitrate
= 10, .hw_value
= 2, },
33 {.bitrate
= 20, .hw_value
= 4, },
34 {.bitrate
= 55, .hw_value
= 11, },
35 {.bitrate
= 110, .hw_value
= 22, },
36 {.bitrate
= 60, .hw_value
= 12, },
37 {.bitrate
= 90, .hw_value
= 18, },
38 {.bitrate
= 120, .hw_value
= 24, },
39 {.bitrate
= 180, .hw_value
= 36, },
40 {.bitrate
= 240, .hw_value
= 48, },
41 {.bitrate
= 360, .hw_value
= 72, },
42 {.bitrate
= 480, .hw_value
= 96, },
43 {.bitrate
= 540, .hw_value
= 108, },
46 /* Supported rates to be advertised to the cfg80211 */
47 static struct ieee80211_rate qtnf_rates_5g
[] = {
48 {.bitrate
= 60, .hw_value
= 12, },
49 {.bitrate
= 90, .hw_value
= 18, },
50 {.bitrate
= 120, .hw_value
= 24, },
51 {.bitrate
= 180, .hw_value
= 36, },
52 {.bitrate
= 240, .hw_value
= 48, },
53 {.bitrate
= 360, .hw_value
= 72, },
54 {.bitrate
= 480, .hw_value
= 96, },
55 {.bitrate
= 540, .hw_value
= 108, },
58 /* Supported crypto cipher suits to be advertised to cfg80211 */
59 static const u32 qtnf_cipher_suites
[] = {
60 WLAN_CIPHER_SUITE_TKIP
,
61 WLAN_CIPHER_SUITE_CCMP
,
62 WLAN_CIPHER_SUITE_AES_CMAC
,
65 /* Supported mgmt frame types to be advertised to cfg80211 */
66 static const struct ieee80211_txrx_stypes
67 qtnf_mgmt_stypes
[NUM_NL80211_IFTYPES
] = {
68 [NL80211_IFTYPE_STATION
] = {
69 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4),
70 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
71 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4),
73 [NL80211_IFTYPE_AP
] = {
74 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4),
75 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
76 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
77 BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
78 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
79 BIT(IEEE80211_STYPE_AUTH
>> 4),
84 qtnf_change_virtual_intf(struct wiphy
*wiphy
,
85 struct net_device
*dev
,
86 enum nl80211_iftype type
,
87 struct vif_params
*params
)
89 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
94 mac_addr
= params
->macaddr
;
98 qtnf_scan_done(vif
->mac
, true);
100 ret
= qtnf_cmd_send_change_intf_type(vif
, type
, mac_addr
);
102 pr_err("VIF%u.%u: failed to change VIF type: %d\n",
103 vif
->mac
->macid
, vif
->vifid
, ret
);
107 vif
->wdev
.iftype
= type
;
111 int qtnf_del_virtual_intf(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
113 struct net_device
*netdev
= wdev
->netdev
;
114 struct qtnf_vif
*vif
;
116 if (WARN_ON(!netdev
))
119 vif
= qtnf_netdev_get_priv(wdev
->netdev
);
121 qtnf_scan_done(vif
->mac
, true);
123 if (qtnf_cmd_send_del_intf(vif
))
124 pr_err("VIF%u.%u: failed to delete VIF\n", vif
->mac
->macid
,
128 netif_tx_stop_all_queues(netdev
);
129 if (netif_carrier_ok(netdev
))
130 netif_carrier_off(netdev
);
132 if (netdev
->reg_state
== NETREG_REGISTERED
)
133 unregister_netdevice(netdev
);
135 vif
->netdev
->ieee80211_ptr
= NULL
;
137 vif
->wdev
.iftype
= NL80211_IFTYPE_UNSPECIFIED
;
138 eth_zero_addr(vif
->mac_addr
);
139 eth_zero_addr(vif
->bssid
);
144 static struct wireless_dev
*qtnf_add_virtual_intf(struct wiphy
*wiphy
,
146 unsigned char name_assign_t
,
147 enum nl80211_iftype type
,
148 struct vif_params
*params
)
150 struct qtnf_wmac
*mac
;
151 struct qtnf_vif
*vif
;
154 mac
= wiphy_priv(wiphy
);
157 return ERR_PTR(-EFAULT
);
160 case NL80211_IFTYPE_STATION
:
161 case NL80211_IFTYPE_AP
:
162 vif
= qtnf_mac_get_free_vif(mac
);
164 pr_err("MAC%u: no free VIF available\n", mac
->macid
);
165 return ERR_PTR(-EFAULT
);
168 eth_zero_addr(vif
->mac_addr
);
169 vif
->bss_priority
= QTNF_DEF_BSS_PRIORITY
;
170 vif
->wdev
.wiphy
= wiphy
;
171 vif
->wdev
.iftype
= type
;
172 vif
->sta_state
= QTNF_STA_DISCONNECTED
;
175 pr_err("MAC%u: unsupported IF type %d\n", mac
->macid
, type
);
176 return ERR_PTR(-ENOTSUPP
);
180 mac_addr
= params
->macaddr
;
182 if (qtnf_cmd_send_add_intf(vif
, type
, mac_addr
)) {
183 pr_err("VIF%u.%u: failed to add VIF\n", mac
->macid
, vif
->vifid
);
187 if (!is_valid_ether_addr(vif
->mac_addr
)) {
188 pr_err("VIF%u.%u: FW reported bad MAC: %pM\n",
189 mac
->macid
, vif
->vifid
, vif
->mac_addr
);
193 if (qtnf_core_net_attach(mac
, vif
, name
, name_assign_t
, type
)) {
194 pr_err("VIF%u.%u: failed to attach netdev\n", mac
->macid
,
199 vif
->wdev
.netdev
= vif
->netdev
;
205 qtnf_cmd_send_del_intf(vif
);
207 vif
->wdev
.iftype
= NL80211_IFTYPE_UNSPECIFIED
;
208 eth_zero_addr(vif
->mac_addr
);
209 eth_zero_addr(vif
->bssid
);
211 return ERR_PTR(-EFAULT
);
214 static int qtnf_mgmt_set_appie(struct qtnf_vif
*vif
,
215 const struct cfg80211_beacon_data
*info
)
219 if (!info
->beacon_ies
|| !info
->beacon_ies_len
) {
220 ret
= qtnf_cmd_send_mgmt_set_appie(vif
, QLINK_IE_SET_BEACON_IES
,
223 ret
= qtnf_cmd_send_mgmt_set_appie(vif
, QLINK_IE_SET_BEACON_IES
,
225 info
->beacon_ies_len
);
231 if (!info
->proberesp_ies
|| !info
->proberesp_ies_len
) {
232 ret
= qtnf_cmd_send_mgmt_set_appie(vif
,
233 QLINK_IE_SET_PROBE_RESP_IES
,
236 ret
= qtnf_cmd_send_mgmt_set_appie(vif
,
237 QLINK_IE_SET_PROBE_RESP_IES
,
239 info
->proberesp_ies_len
);
245 if (!info
->assocresp_ies
|| !info
->assocresp_ies_len
) {
246 ret
= qtnf_cmd_send_mgmt_set_appie(vif
,
247 QLINK_IE_SET_ASSOC_RESP
,
250 ret
= qtnf_cmd_send_mgmt_set_appie(vif
,
251 QLINK_IE_SET_ASSOC_RESP
,
253 info
->assocresp_ies_len
);
260 static int qtnf_change_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
261 struct cfg80211_beacon_data
*info
)
263 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
265 return qtnf_mgmt_set_appie(vif
, info
);
268 static int qtnf_start_ap(struct wiphy
*wiphy
, struct net_device
*dev
,
269 struct cfg80211_ap_settings
*settings
)
271 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
274 ret
= qtnf_cmd_send_start_ap(vif
, settings
);
276 pr_err("VIF%u.%u: failed to start AP\n", vif
->mac
->macid
,
282 static int qtnf_stop_ap(struct wiphy
*wiphy
, struct net_device
*dev
)
284 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
287 qtnf_scan_done(vif
->mac
, true);
289 ret
= qtnf_cmd_send_stop_ap(vif
);
291 pr_err("VIF%u.%u: failed to stop AP operation in FW\n",
292 vif
->mac
->macid
, vif
->vifid
);
294 netif_carrier_off(vif
->netdev
);
300 static int qtnf_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
302 struct qtnf_wmac
*mac
= wiphy_priv(wiphy
);
303 struct qtnf_vif
*vif
;
306 vif
= qtnf_mac_get_base_vif(mac
);
308 pr_err("MAC%u: primary VIF is not configured\n", mac
->macid
);
312 if (changed
& (WIPHY_PARAM_RETRY_LONG
| WIPHY_PARAM_RETRY_SHORT
)) {
313 pr_err("MAC%u: can't modify retry params\n", mac
->macid
);
317 ret
= qtnf_cmd_send_update_phy_params(mac
, changed
);
319 pr_err("MAC%u: failed to update PHY params\n", mac
->macid
);
325 qtnf_mgmt_frame_register(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
326 u16 frame_type
, bool reg
)
328 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(wdev
->netdev
);
331 u16 qlink_frame_type
= 0;
333 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
336 new_mask
= vif
->mgmt_frames_bitmask
| BIT(mgmt_type
);
338 new_mask
= vif
->mgmt_frames_bitmask
& ~BIT(mgmt_type
);
340 if (new_mask
== vif
->mgmt_frames_bitmask
)
343 switch (frame_type
& IEEE80211_FCTL_STYPE
) {
344 case IEEE80211_STYPE_REASSOC_REQ
:
345 case IEEE80211_STYPE_ASSOC_REQ
:
346 qlink_frame_type
= QLINK_MGMT_FRAME_ASSOC_REQ
;
348 case IEEE80211_STYPE_AUTH
:
349 qlink_frame_type
= QLINK_MGMT_FRAME_AUTH
;
351 case IEEE80211_STYPE_PROBE_REQ
:
352 qlink_frame_type
= QLINK_MGMT_FRAME_PROBE_REQ
;
354 case IEEE80211_STYPE_ACTION
:
355 qlink_frame_type
= QLINK_MGMT_FRAME_ACTION
;
358 pr_warn("VIF%u.%u: unsupported frame type: %X\n",
359 vif
->mac
->macid
, vif
->vifid
,
360 (frame_type
& IEEE80211_FCTL_STYPE
) >> 4);
364 if (qtnf_cmd_send_register_mgmt(vif
, qlink_frame_type
, reg
)) {
365 pr_warn("VIF%u.%u: failed to %sregister mgmt frame type 0x%x\n",
366 vif
->mac
->macid
, vif
->vifid
, reg
? "" : "un",
371 vif
->mgmt_frames_bitmask
= new_mask
;
372 pr_debug("VIF%u.%u: %sregistered mgmt frame type 0x%x\n",
373 vif
->mac
->macid
, vif
->vifid
, reg
? "" : "un", frame_type
);
377 qtnf_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
378 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
380 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(wdev
->netdev
);
381 const struct ieee80211_mgmt
*mgmt_frame
= (void *)params
->buf
;
382 u32 short_cookie
= prandom_u32();
385 *cookie
= short_cookie
;
388 flags
|= QLINK_MGMT_FRAME_TX_FLAG_OFFCHAN
;
391 flags
|= QLINK_MGMT_FRAME_TX_FLAG_NO_CCK
;
393 if (params
->dont_wait_for_ack
)
394 flags
|= QLINK_MGMT_FRAME_TX_FLAG_ACK_NOWAIT
;
396 pr_debug("%s freq:%u; FC:%.4X; DA:%pM; len:%zu; C:%.8X; FL:%.4X\n",
397 wdev
->netdev
->name
, params
->chan
->center_freq
,
398 le16_to_cpu(mgmt_frame
->frame_control
), mgmt_frame
->da
,
399 params
->len
, short_cookie
, flags
);
401 return qtnf_cmd_send_mgmt_frame(vif
, short_cookie
, flags
,
402 params
->chan
->center_freq
,
403 params
->buf
, params
->len
);
407 qtnf_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
408 const u8
*mac
, struct station_info
*sinfo
)
410 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
412 return qtnf_cmd_get_sta_info(vif
, mac
, sinfo
);
416 qtnf_dump_station(struct wiphy
*wiphy
, struct net_device
*dev
,
417 int idx
, u8
*mac
, struct station_info
*sinfo
)
419 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
420 const struct qtnf_sta_node
*sta_node
;
423 sta_node
= qtnf_sta_list_lookup_index(&vif
->sta_list
, idx
);
425 if (unlikely(!sta_node
))
428 ether_addr_copy(mac
, sta_node
->mac_addr
);
430 ret
= qtnf_cmd_get_sta_info(vif
, sta_node
->mac_addr
, sinfo
);
432 if (unlikely(ret
== -ENOENT
)) {
433 qtnf_sta_list_del(&vif
->sta_list
, mac
);
434 cfg80211_del_sta(vif
->netdev
, mac
, GFP_KERNEL
);
441 static int qtnf_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
442 u8 key_index
, bool pairwise
, const u8
*mac_addr
,
443 struct key_params
*params
)
445 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
448 ret
= qtnf_cmd_send_add_key(vif
, key_index
, pairwise
, mac_addr
, params
);
450 pr_err("VIF%u.%u: failed to add key: cipher=%x idx=%u pw=%u\n",
451 vif
->mac
->macid
, vif
->vifid
, params
->cipher
, key_index
,
457 static int qtnf_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
458 u8 key_index
, bool pairwise
, const u8
*mac_addr
)
460 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
463 ret
= qtnf_cmd_send_del_key(vif
, key_index
, pairwise
, mac_addr
);
465 pr_err("VIF%u.%u: failed to delete key: idx=%u pw=%u\n",
466 vif
->mac
->macid
, vif
->vifid
, key_index
, pairwise
);
471 static int qtnf_set_default_key(struct wiphy
*wiphy
, struct net_device
*dev
,
472 u8 key_index
, bool unicast
, bool multicast
)
474 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
477 ret
= qtnf_cmd_send_set_default_key(vif
, key_index
, unicast
, multicast
);
479 pr_err("VIF%u.%u: failed to set dflt key: idx=%u uc=%u mc=%u\n",
480 vif
->mac
->macid
, vif
->vifid
, key_index
, unicast
,
487 qtnf_set_default_mgmt_key(struct wiphy
*wiphy
, struct net_device
*dev
,
490 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
493 ret
= qtnf_cmd_send_set_default_mgmt_key(vif
, key_index
);
495 pr_err("VIF%u.%u: failed to set default MGMT key: idx=%u\n",
496 vif
->mac
->macid
, vif
->vifid
, key_index
);
502 qtnf_change_station(struct wiphy
*wiphy
, struct net_device
*dev
,
503 const u8
*mac
, struct station_parameters
*params
)
505 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
508 ret
= qtnf_cmd_send_change_sta(vif
, mac
, params
);
510 pr_err("VIF%u.%u: failed to change STA %pM\n",
511 vif
->mac
->macid
, vif
->vifid
, mac
);
517 qtnf_del_station(struct wiphy
*wiphy
, struct net_device
*dev
,
518 struct station_del_parameters
*params
)
520 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
524 (vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) &&
525 !is_broadcast_ether_addr(params
->mac
) &&
526 !qtnf_sta_list_lookup(&vif
->sta_list
, params
->mac
))
529 ret
= qtnf_cmd_send_del_sta(vif
, params
);
531 pr_err("VIF%u.%u: failed to delete STA %pM\n",
532 vif
->mac
->macid
, vif
->vifid
, params
->mac
);
536 static void qtnf_scan_timeout(struct timer_list
*t
)
538 struct qtnf_wmac
*mac
= from_timer(mac
, t
, scan_timeout
);
540 pr_warn("mac%d scan timed out\n", mac
->macid
);
541 qtnf_scan_done(mac
, true);
545 qtnf_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
547 struct qtnf_wmac
*mac
= wiphy_priv(wiphy
);
549 mac
->scan_req
= request
;
551 if (qtnf_cmd_send_scan(mac
)) {
552 pr_err("MAC%u: failed to start scan\n", mac
->macid
);
553 mac
->scan_req
= NULL
;
557 mac
->scan_timeout
.function
= qtnf_scan_timeout
;
558 mod_timer(&mac
->scan_timeout
,
559 jiffies
+ QTNF_SCAN_TIMEOUT_SEC
* HZ
);
565 qtnf_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
566 struct cfg80211_connect_params
*sme
)
568 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
571 if (vif
->wdev
.iftype
!= NL80211_IFTYPE_STATION
)
574 if (vif
->sta_state
!= QTNF_STA_DISCONNECTED
)
578 ether_addr_copy(vif
->bssid
, sme
->bssid
);
580 eth_zero_addr(vif
->bssid
);
582 ret
= qtnf_cmd_send_connect(vif
, sme
);
584 pr_err("VIF%u.%u: failed to connect\n", vif
->mac
->macid
,
589 vif
->sta_state
= QTNF_STA_CONNECTING
;
594 qtnf_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
597 struct qtnf_wmac
*mac
= wiphy_priv(wiphy
);
598 struct qtnf_vif
*vif
;
601 vif
= qtnf_mac_get_base_vif(mac
);
603 pr_err("MAC%u: primary VIF is not configured\n", mac
->macid
);
607 if (vif
->wdev
.iftype
!= NL80211_IFTYPE_STATION
)
610 if (vif
->sta_state
== QTNF_STA_DISCONNECTED
)
613 ret
= qtnf_cmd_send_disconnect(vif
, reason_code
);
615 pr_err("VIF%u.%u: failed to disconnect\n", mac
->macid
,
620 vif
->sta_state
= QTNF_STA_DISCONNECTED
;
625 qtnf_dump_survey(struct wiphy
*wiphy
, struct net_device
*dev
,
626 int idx
, struct survey_info
*survey
)
628 struct qtnf_wmac
*mac
= wiphy_priv(wiphy
);
629 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
630 struct ieee80211_supported_band
*sband
;
631 const struct cfg80211_chan_def
*chandef
= &wdev
->chandef
;
632 struct ieee80211_channel
*chan
;
633 struct qtnf_chan_stats stats
;
634 struct qtnf_vif
*vif
;
637 vif
= qtnf_netdev_get_priv(dev
);
639 sband
= wiphy
->bands
[NL80211_BAND_2GHZ
];
640 if (sband
&& idx
>= sband
->n_channels
) {
641 idx
-= sband
->n_channels
;
646 sband
= wiphy
->bands
[NL80211_BAND_5GHZ
];
648 if (!sband
|| idx
>= sband
->n_channels
)
651 chan
= &sband
->channels
[idx
];
652 memset(&stats
, 0, sizeof(stats
));
654 survey
->channel
= chan
;
655 survey
->filled
= 0x0;
658 if (chan
->hw_value
== chandef
->chan
->hw_value
)
659 survey
->filled
= SURVEY_INFO_IN_USE
;
662 ret
= qtnf_cmd_get_chan_stats(mac
, chan
->hw_value
, &stats
);
665 if (unlikely(stats
.chan_num
!= chan
->hw_value
)) {
666 pr_err("received stats for channel %d instead of %d\n",
667 stats
.chan_num
, chan
->hw_value
);
672 survey
->filled
|= SURVEY_INFO_TIME
|
673 SURVEY_INFO_TIME_SCAN
|
674 SURVEY_INFO_TIME_BUSY
|
675 SURVEY_INFO_TIME_RX
|
676 SURVEY_INFO_TIME_TX
|
677 SURVEY_INFO_NOISE_DBM
;
679 survey
->time_scan
= stats
.cca_try
;
680 survey
->time
= stats
.cca_try
;
681 survey
->time_tx
= stats
.cca_tx
;
682 survey
->time_rx
= stats
.cca_rx
;
683 survey
->time_busy
= stats
.cca_busy
;
684 survey
->noise
= stats
.chan_noise
;
687 pr_debug("no stats for channel %u\n", chan
->hw_value
);
691 pr_debug("failed to get chan(%d) stats from card\n",
701 qtnf_get_channel(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
702 struct cfg80211_chan_def
*chandef
)
704 struct net_device
*ndev
= wdev
->netdev
;
705 struct qtnf_vif
*vif
;
711 vif
= qtnf_netdev_get_priv(wdev
->netdev
);
713 ret
= qtnf_cmd_get_channel(vif
, chandef
);
715 pr_err("%s: failed to get channel: %d\n", ndev
->name
, ret
);
719 if (!cfg80211_chandef_valid(chandef
)) {
720 pr_err("%s: bad chan freq1=%u freq2=%u bw=%u\n", ndev
->name
,
721 chandef
->center_freq1
, chandef
->center_freq2
,
730 static int qtnf_channel_switch(struct wiphy
*wiphy
, struct net_device
*dev
,
731 struct cfg80211_csa_settings
*params
)
733 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(dev
);
736 pr_debug("%s: chan(%u) count(%u) radar(%u) block_tx(%u)\n", dev
->name
,
737 params
->chandef
.chan
->hw_value
, params
->count
,
738 params
->radar_required
, params
->block_tx
);
740 if (!cfg80211_chandef_valid(¶ms
->chandef
)) {
741 pr_err("%s: invalid channel\n", dev
->name
);
745 ret
= qtnf_cmd_send_chan_switch(vif
, params
);
747 pr_warn("%s: failed to switch to channel (%u)\n",
748 dev
->name
, params
->chandef
.chan
->hw_value
);
753 static struct cfg80211_ops qtn_cfg80211_ops
= {
754 .add_virtual_intf
= qtnf_add_virtual_intf
,
755 .change_virtual_intf
= qtnf_change_virtual_intf
,
756 .del_virtual_intf
= qtnf_del_virtual_intf
,
757 .start_ap
= qtnf_start_ap
,
758 .change_beacon
= qtnf_change_beacon
,
759 .stop_ap
= qtnf_stop_ap
,
760 .set_wiphy_params
= qtnf_set_wiphy_params
,
761 .mgmt_frame_register
= qtnf_mgmt_frame_register
,
762 .mgmt_tx
= qtnf_mgmt_tx
,
763 .change_station
= qtnf_change_station
,
764 .del_station
= qtnf_del_station
,
765 .get_station
= qtnf_get_station
,
766 .dump_station
= qtnf_dump_station
,
767 .add_key
= qtnf_add_key
,
768 .del_key
= qtnf_del_key
,
769 .set_default_key
= qtnf_set_default_key
,
770 .set_default_mgmt_key
= qtnf_set_default_mgmt_key
,
772 .connect
= qtnf_connect
,
773 .disconnect
= qtnf_disconnect
,
774 .dump_survey
= qtnf_dump_survey
,
775 .get_channel
= qtnf_get_channel
,
776 .channel_switch
= qtnf_channel_switch
779 static void qtnf_cfg80211_reg_notifier(struct wiphy
*wiphy_in
,
780 struct regulatory_request
*req
)
782 struct qtnf_wmac
*mac
= wiphy_priv(wiphy_in
);
783 struct qtnf_bus
*bus
= mac
->bus
;
785 unsigned int mac_idx
;
786 enum nl80211_band band
;
789 pr_debug("MAC%u: initiator=%d alpha=%c%c\n", mac
->macid
, req
->initiator
,
790 req
->alpha2
[0], req
->alpha2
[1]);
792 ret
= qtnf_cmd_reg_notify(bus
, req
);
794 if (ret
!= -EOPNOTSUPP
&& ret
!= -EALREADY
)
795 pr_err("failed to update reg domain to %c%c\n",
796 req
->alpha2
[0], req
->alpha2
[1]);
800 for (mac_idx
= 0; mac_idx
< QTNF_MAX_MAC
; ++mac_idx
) {
801 if (!(bus
->hw_info
.mac_bitmap
& (1 << mac_idx
)))
804 mac
= bus
->mac
[mac_idx
];
805 wiphy
= priv_to_wiphy(mac
);
807 for (band
= 0; band
< NUM_NL80211_BANDS
; ++band
) {
808 if (!wiphy
->bands
[band
])
811 ret
= qtnf_cmd_band_info_get(mac
, wiphy
->bands
[band
]);
813 pr_err("failed to get chan info for mac %u band %u\n",
819 struct wiphy
*qtnf_wiphy_allocate(struct qtnf_bus
*bus
)
823 wiphy
= wiphy_new(&qtn_cfg80211_ops
, sizeof(struct qtnf_wmac
));
827 set_wiphy_dev(wiphy
, bus
->dev
);
832 static int qtnf_wiphy_setup_if_comb(struct wiphy
*wiphy
,
833 struct ieee80211_iface_combination
*if_comb
,
834 const struct qtnf_mac_info
*mac_info
)
836 size_t max_interfaces
= 0;
837 u16 interface_modes
= 0;
840 if (unlikely(!mac_info
->limits
|| !mac_info
->n_limits
))
843 if_comb
->limits
= mac_info
->limits
;
844 if_comb
->n_limits
= mac_info
->n_limits
;
846 for (i
= 0; i
< mac_info
->n_limits
; i
++) {
847 max_interfaces
+= mac_info
->limits
[i
].max
;
848 interface_modes
|= mac_info
->limits
[i
].types
;
851 if_comb
->num_different_channels
= 1;
852 if_comb
->beacon_int_infra_match
= true;
853 if_comb
->max_interfaces
= max_interfaces
;
854 if_comb
->radar_detect_widths
= mac_info
->radar_detect_widths
;
855 wiphy
->interface_modes
= interface_modes
;
860 int qtnf_wiphy_register(struct qtnf_hw_info
*hw_info
, struct qtnf_wmac
*mac
)
862 struct wiphy
*wiphy
= priv_to_wiphy(mac
);
863 struct ieee80211_iface_combination
*iface_comb
= NULL
;
867 pr_err("invalid wiphy pointer\n");
871 iface_comb
= kzalloc(sizeof(*iface_comb
), GFP_KERNEL
);
875 ret
= qtnf_wiphy_setup_if_comb(wiphy
, iface_comb
, &mac
->macinfo
);
879 wiphy
->frag_threshold
= mac
->macinfo
.frag_thr
;
880 wiphy
->rts_threshold
= mac
->macinfo
.rts_thr
;
881 wiphy
->retry_short
= mac
->macinfo
.sretry_limit
;
882 wiphy
->retry_long
= mac
->macinfo
.lretry_limit
;
883 wiphy
->coverage_class
= mac
->macinfo
.coverage_class
;
885 wiphy
->max_scan_ssids
= QTNF_MAX_SSID_LIST_LENGTH
;
886 wiphy
->max_scan_ie_len
= QTNF_MAX_VSIE_LEN
;
887 wiphy
->mgmt_stypes
= qtnf_mgmt_stypes
;
888 wiphy
->max_remain_on_channel_duration
= 5000;
890 wiphy
->iface_combinations
= iface_comb
;
891 wiphy
->n_iface_combinations
= 1;
892 wiphy
->max_num_csa_counters
= 2;
894 /* Initialize cipher suits */
895 wiphy
->cipher_suites
= qtnf_cipher_suites
;
896 wiphy
->n_cipher_suites
= ARRAY_SIZE(qtnf_cipher_suites
);
897 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
898 wiphy
->flags
|= WIPHY_FLAG_HAVE_AP_SME
|
899 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
|
900 WIPHY_FLAG_AP_UAPSD
|
901 WIPHY_FLAG_HAS_CHANNEL_SWITCH
;
903 wiphy
->probe_resp_offload
= NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS
|
904 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2
;
906 wiphy
->available_antennas_tx
= mac
->macinfo
.num_tx_chain
;
907 wiphy
->available_antennas_rx
= mac
->macinfo
.num_rx_chain
;
909 wiphy
->max_ap_assoc_sta
= mac
->macinfo
.max_ap_assoc_sta
;
910 wiphy
->ht_capa_mod_mask
= &mac
->macinfo
.ht_cap_mod_mask
;
911 wiphy
->vht_capa_mod_mask
= &mac
->macinfo
.vht_cap_mod_mask
;
913 ether_addr_copy(wiphy
->perm_addr
, mac
->macaddr
);
915 if (hw_info
->hw_capab
& QLINK_HW_CAPAB_STA_INACT_TIMEOUT
)
916 wiphy
->features
|= NL80211_FEATURE_INACTIVITY_TIMER
;
918 if (hw_info
->hw_capab
& QLINK_HW_CAPAB_REG_UPDATE
) {
919 wiphy
->regulatory_flags
|= REGULATORY_STRICT_REG
|
920 REGULATORY_CUSTOM_REG
;
921 wiphy
->reg_notifier
= qtnf_cfg80211_reg_notifier
;
922 wiphy_apply_custom_regulatory(wiphy
, hw_info
->rd
);
924 wiphy
->regulatory_flags
|= REGULATORY_WIPHY_SELF_MANAGED
;
927 ret
= wiphy_register(wiphy
);
931 if (wiphy
->regulatory_flags
& REGULATORY_WIPHY_SELF_MANAGED
)
932 ret
= regulatory_set_wiphy_regd(wiphy
, hw_info
->rd
);
933 else if (isalpha(hw_info
->rd
->alpha2
[0]) &&
934 isalpha(hw_info
->rd
->alpha2
[1]))
935 ret
= regulatory_hint(wiphy
, hw_info
->rd
->alpha2
);
946 void qtnf_netdev_updown(struct net_device
*ndev
, bool up
)
948 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(ndev
);
950 if (qtnf_cmd_send_updown_intf(vif
, up
))
951 pr_err("failed to send up/down command to FW\n");
954 void qtnf_virtual_intf_cleanup(struct net_device
*ndev
)
956 struct qtnf_vif
*vif
= qtnf_netdev_get_priv(ndev
);
957 struct qtnf_wmac
*mac
= wiphy_priv(vif
->wdev
.wiphy
);
959 if (vif
->wdev
.iftype
== NL80211_IFTYPE_STATION
) {
960 switch (vif
->sta_state
) {
961 case QTNF_STA_DISCONNECTED
:
963 case QTNF_STA_CONNECTING
:
964 cfg80211_connect_result(vif
->netdev
,
967 WLAN_STATUS_UNSPECIFIED_FAILURE
,
969 qtnf_disconnect(vif
->wdev
.wiphy
, ndev
,
970 WLAN_REASON_DEAUTH_LEAVING
);
972 case QTNF_STA_CONNECTED
:
973 cfg80211_disconnected(vif
->netdev
,
974 WLAN_REASON_DEAUTH_LEAVING
,
975 NULL
, 0, 1, GFP_KERNEL
);
976 qtnf_disconnect(vif
->wdev
.wiphy
, ndev
,
977 WLAN_REASON_DEAUTH_LEAVING
);
981 vif
->sta_state
= QTNF_STA_DISCONNECTED
;
984 qtnf_scan_done(mac
, true);
987 void qtnf_cfg80211_vif_reset(struct qtnf_vif
*vif
)
989 if (vif
->wdev
.iftype
== NL80211_IFTYPE_STATION
) {
990 switch (vif
->sta_state
) {
991 case QTNF_STA_CONNECTING
:
992 cfg80211_connect_result(vif
->netdev
,
995 WLAN_STATUS_UNSPECIFIED_FAILURE
,
998 case QTNF_STA_CONNECTED
:
999 cfg80211_disconnected(vif
->netdev
,
1000 WLAN_REASON_DEAUTH_LEAVING
,
1001 NULL
, 0, 1, GFP_KERNEL
);
1003 case QTNF_STA_DISCONNECTED
:
1008 cfg80211_shutdown_all_interfaces(vif
->wdev
.wiphy
);
1009 vif
->sta_state
= QTNF_STA_DISCONNECTED
;
1012 void qtnf_band_init_rates(struct ieee80211_supported_band
*band
)
1014 switch (band
->band
) {
1015 case NL80211_BAND_2GHZ
:
1016 band
->bitrates
= qtnf_rates_2g
;
1017 band
->n_bitrates
= ARRAY_SIZE(qtnf_rates_2g
);
1019 case NL80211_BAND_5GHZ
:
1020 band
->bitrates
= qtnf_rates_5g
;
1021 band
->n_bitrates
= ARRAY_SIZE(qtnf_rates_5g
);
1024 band
->bitrates
= NULL
;
1025 band
->n_bitrates
= 0;