2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/etherdevice.h>
18 #include <linux/moduleparam.h>
19 #include <net/netlink.h>
23 #define WIL_MAX_ROC_DURATION_MS 5000
26 module_param(disable_ap_sme
, bool, 0444);
27 MODULE_PARM_DESC(disable_ap_sme
, " let user space handle AP mode SME");
30 static struct wiphy_wowlan_support wil_wowlan_support
= {
31 .flags
= WIPHY_WOWLAN_ANY
| WIPHY_WOWLAN_DISCONNECT
,
35 #define CHAN60G(_channel, _flags) { \
36 .band = NL80211_BAND_60GHZ, \
37 .center_freq = 56160 + (2160 * (_channel)), \
38 .hw_value = (_channel), \
40 .max_antenna_gain = 0, \
44 static struct ieee80211_channel wil_60ghz_channels
[] = {
48 /* channel 4 not supported yet */
51 /* Vendor id to be used in vendor specific command and events
53 * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
54 * vendor subcmd definitions prefixed with QCA_NL80211_VENDOR_SUBCMD, and
55 * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in
56 * git://w1.fi/srv/git/hostap.git; the values here are just a copy of that
59 #define QCA_NL80211_VENDOR_ID 0x001374
61 #define WIL_MAX_RF_SECTORS (128)
62 #define WIL_CID_ALL (0xff)
64 enum qca_wlan_vendor_attr_rf_sector
{
65 QCA_ATTR_MAC_ADDR
= 6,
68 QCA_ATTR_DMG_RF_SECTOR_INDEX
= 30,
69 QCA_ATTR_DMG_RF_SECTOR_TYPE
= 31,
70 QCA_ATTR_DMG_RF_MODULE_MASK
= 32,
71 QCA_ATTR_DMG_RF_SECTOR_CFG
= 33,
72 QCA_ATTR_DMG_RF_SECTOR_MAX
,
75 enum qca_wlan_vendor_attr_dmg_rf_sector_type
{
76 QCA_ATTR_DMG_RF_SECTOR_TYPE_RX
,
77 QCA_ATTR_DMG_RF_SECTOR_TYPE_TX
,
78 QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
81 enum qca_wlan_vendor_attr_dmg_rf_sector_cfg
{
82 QCA_ATTR_DMG_RF_SECTOR_CFG_INVALID
= 0,
83 QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX
,
84 QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0
,
85 QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1
,
86 QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2
,
87 QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI
,
88 QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO
,
89 QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16
,
92 QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST
,
93 QCA_ATTR_DMG_RF_SECTOR_CFG_MAX
=
94 QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST
- 1
98 nla_policy wil_rf_sector_policy
[QCA_ATTR_DMG_RF_SECTOR_MAX
+ 1] = {
99 [QCA_ATTR_MAC_ADDR
] = { .len
= ETH_ALEN
},
100 [QCA_ATTR_DMG_RF_SECTOR_INDEX
] = { .type
= NLA_U16
},
101 [QCA_ATTR_DMG_RF_SECTOR_TYPE
] = { .type
= NLA_U8
},
102 [QCA_ATTR_DMG_RF_MODULE_MASK
] = { .type
= NLA_U32
},
103 [QCA_ATTR_DMG_RF_SECTOR_CFG
] = { .type
= NLA_NESTED
},
107 nla_policy wil_rf_sector_cfg_policy
[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX
+ 1] = {
108 [QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX
] = { .type
= NLA_U8
},
109 [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0
] = { .type
= NLA_U32
},
110 [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1
] = { .type
= NLA_U32
},
111 [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2
] = { .type
= NLA_U32
},
112 [QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI
] = { .type
= NLA_U32
},
113 [QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO
] = { .type
= NLA_U32
},
114 [QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16
] = { .type
= NLA_U32
},
117 enum qca_nl80211_vendor_subcmds
{
118 QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG
= 139,
119 QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG
= 140,
120 QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR
= 141,
121 QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR
= 142,
124 static int wil_rf_sector_get_cfg(struct wiphy
*wiphy
,
125 struct wireless_dev
*wdev
,
126 const void *data
, int data_len
);
127 static int wil_rf_sector_set_cfg(struct wiphy
*wiphy
,
128 struct wireless_dev
*wdev
,
129 const void *data
, int data_len
);
130 static int wil_rf_sector_get_selected(struct wiphy
*wiphy
,
131 struct wireless_dev
*wdev
,
132 const void *data
, int data_len
);
133 static int wil_rf_sector_set_selected(struct wiphy
*wiphy
,
134 struct wireless_dev
*wdev
,
135 const void *data
, int data_len
);
137 /* vendor specific commands */
138 static const struct wiphy_vendor_command wil_nl80211_vendor_commands
[] = {
140 .info
.vendor_id
= QCA_NL80211_VENDOR_ID
,
141 .info
.subcmd
= QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG
,
142 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
|
143 WIPHY_VENDOR_CMD_NEED_RUNNING
,
144 .doit
= wil_rf_sector_get_cfg
147 .info
.vendor_id
= QCA_NL80211_VENDOR_ID
,
148 .info
.subcmd
= QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG
,
149 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
|
150 WIPHY_VENDOR_CMD_NEED_RUNNING
,
151 .doit
= wil_rf_sector_set_cfg
154 .info
.vendor_id
= QCA_NL80211_VENDOR_ID
,
156 QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR
,
157 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
|
158 WIPHY_VENDOR_CMD_NEED_RUNNING
,
159 .doit
= wil_rf_sector_get_selected
162 .info
.vendor_id
= QCA_NL80211_VENDOR_ID
,
164 QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR
,
165 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
|
166 WIPHY_VENDOR_CMD_NEED_RUNNING
,
167 .doit
= wil_rf_sector_set_selected
171 static struct ieee80211_supported_band wil_band_60ghz
= {
172 .channels
= wil_60ghz_channels
,
173 .n_channels
= ARRAY_SIZE(wil_60ghz_channels
),
175 .ht_supported
= true,
177 .ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
, /* TODO */
178 .ampdu_density
= IEEE80211_HT_MPDU_DENSITY_8
, /* TODO */
180 /* MCS 1..12 - SC PHY */
181 .rx_mask
= {0xfe, 0x1f}, /* 1..12 */
182 .tx_params
= IEEE80211_HT_MCS_TX_DEFINED
, /* TODO */
187 static const struct ieee80211_txrx_stypes
188 wil_mgmt_stypes
[NUM_NL80211_IFTYPES
] = {
189 [NL80211_IFTYPE_STATION
] = {
190 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
191 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
192 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
193 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
195 [NL80211_IFTYPE_AP
] = {
196 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
197 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4) |
198 BIT(IEEE80211_STYPE_ASSOC_RESP
>> 4) |
199 BIT(IEEE80211_STYPE_DISASSOC
>> 4),
200 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
201 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
202 BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
203 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
204 BIT(IEEE80211_STYPE_AUTH
>> 4) |
205 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
206 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4)
208 [NL80211_IFTYPE_P2P_CLIENT
] = {
209 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
210 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
211 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
212 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
214 [NL80211_IFTYPE_P2P_GO
] = {
215 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
216 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
217 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
218 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
220 [NL80211_IFTYPE_P2P_DEVICE
] = {
221 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
222 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
223 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
224 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
228 static const u32 wil_cipher_suites
[] = {
229 WLAN_CIPHER_SUITE_GCMP
,
232 static const char * const key_usage_str
[] = {
233 [WMI_KEY_USE_PAIRWISE
] = "PTK",
234 [WMI_KEY_USE_RX_GROUP
] = "RX_GTK",
235 [WMI_KEY_USE_TX_GROUP
] = "TX_GTK",
238 int wil_iftype_nl2wmi(enum nl80211_iftype type
)
240 static const struct {
241 enum nl80211_iftype nl
;
242 enum wmi_network_type wmi
;
244 {NL80211_IFTYPE_ADHOC
, WMI_NETTYPE_ADHOC
},
245 {NL80211_IFTYPE_STATION
, WMI_NETTYPE_INFRA
},
246 {NL80211_IFTYPE_AP
, WMI_NETTYPE_AP
},
247 {NL80211_IFTYPE_P2P_CLIENT
, WMI_NETTYPE_P2P
},
248 {NL80211_IFTYPE_P2P_GO
, WMI_NETTYPE_P2P
},
249 {NL80211_IFTYPE_MONITOR
, WMI_NETTYPE_ADHOC
}, /* FIXME */
253 for (i
= 0; i
< ARRAY_SIZE(__nl2wmi
); i
++) {
254 if (__nl2wmi
[i
].nl
== type
)
255 return __nl2wmi
[i
].wmi
;
261 int wil_cid_fill_sinfo(struct wil6210_priv
*wil
, int cid
,
262 struct station_info
*sinfo
)
264 struct wmi_notify_req_cmd cmd
= {
269 struct wmi_cmd_hdr wmi
;
270 struct wmi_notify_req_done_event evt
;
272 struct wil_net_stats
*stats
= &wil
->sta
[cid
].stats
;
275 rc
= wmi_call(wil
, WMI_NOTIFY_REQ_CMDID
, &cmd
, sizeof(cmd
),
276 WMI_NOTIFY_REQ_DONE_EVENTID
, &reply
, sizeof(reply
), 20);
280 wil_dbg_wmi(wil
, "Link status for CID %d: {\n"
281 " MCS %d TSF 0x%016llx\n"
282 " BF status 0x%08x RSSI %d SQI %d%%\n"
283 " Tx Tpt %d goodput %d Rx goodput %d\n"
284 " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
285 cid
, le16_to_cpu(reply
.evt
.bf_mcs
),
286 le64_to_cpu(reply
.evt
.tsf
), reply
.evt
.status
,
289 le32_to_cpu(reply
.evt
.tx_tpt
),
290 le32_to_cpu(reply
.evt
.tx_goodput
),
291 le32_to_cpu(reply
.evt
.rx_goodput
),
292 le16_to_cpu(reply
.evt
.my_rx_sector
),
293 le16_to_cpu(reply
.evt
.my_tx_sector
),
294 le16_to_cpu(reply
.evt
.other_rx_sector
),
295 le16_to_cpu(reply
.evt
.other_tx_sector
));
297 sinfo
->generation
= wil
->sinfo_gen
;
299 sinfo
->filled
= BIT(NL80211_STA_INFO_RX_BYTES
) |
300 BIT(NL80211_STA_INFO_TX_BYTES
) |
301 BIT(NL80211_STA_INFO_RX_PACKETS
) |
302 BIT(NL80211_STA_INFO_TX_PACKETS
) |
303 BIT(NL80211_STA_INFO_RX_BITRATE
) |
304 BIT(NL80211_STA_INFO_TX_BITRATE
) |
305 BIT(NL80211_STA_INFO_RX_DROP_MISC
) |
306 BIT(NL80211_STA_INFO_TX_FAILED
);
308 sinfo
->txrate
.flags
= RATE_INFO_FLAGS_60G
;
309 sinfo
->txrate
.mcs
= le16_to_cpu(reply
.evt
.bf_mcs
);
310 sinfo
->rxrate
.mcs
= stats
->last_mcs_rx
;
311 sinfo
->rx_bytes
= stats
->rx_bytes
;
312 sinfo
->rx_packets
= stats
->rx_packets
;
313 sinfo
->rx_dropped_misc
= stats
->rx_dropped
;
314 sinfo
->tx_bytes
= stats
->tx_bytes
;
315 sinfo
->tx_packets
= stats
->tx_packets
;
316 sinfo
->tx_failed
= stats
->tx_errors
;
318 if (test_bit(wil_status_fwconnected
, wil
->status
)) {
319 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
320 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING
,
321 wil
->fw_capabilities
))
322 sinfo
->signal
= reply
.evt
.rssi
;
324 sinfo
->signal
= reply
.evt
.sqi
;
330 static int wil_cfg80211_get_station(struct wiphy
*wiphy
,
331 struct net_device
*ndev
,
332 const u8
*mac
, struct station_info
*sinfo
)
334 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
337 int cid
= wil_find_cid(wil
, mac
);
339 wil_dbg_misc(wil
, "get_station: %pM CID %d\n", mac
, cid
);
343 rc
= wil_cid_fill_sinfo(wil
, cid
, sinfo
);
349 * Find @idx-th active STA for station dump.
351 static int wil_find_cid_by_idx(struct wil6210_priv
*wil
, int idx
)
355 for (i
= 0; i
< ARRAY_SIZE(wil
->sta
); i
++) {
356 if (wil
->sta
[i
].status
== wil_sta_unused
)
366 static int wil_cfg80211_dump_station(struct wiphy
*wiphy
,
367 struct net_device
*dev
, int idx
,
368 u8
*mac
, struct station_info
*sinfo
)
370 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
372 int cid
= wil_find_cid_by_idx(wil
, idx
);
377 ether_addr_copy(mac
, wil
->sta
[cid
].addr
);
378 wil_dbg_misc(wil
, "dump_station: %pM CID %d\n", mac
, cid
);
380 rc
= wil_cid_fill_sinfo(wil
, cid
, sinfo
);
385 static int wil_cfg80211_start_p2p_device(struct wiphy
*wiphy
,
386 struct wireless_dev
*wdev
)
388 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
390 wil_dbg_misc(wil
, "start_p2p_device: entered\n");
391 wil
->p2p
.p2p_dev_started
= 1;
395 static void wil_cfg80211_stop_p2p_device(struct wiphy
*wiphy
,
396 struct wireless_dev
*wdev
)
398 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
399 struct wil_p2p_info
*p2p
= &wil
->p2p
;
401 if (!p2p
->p2p_dev_started
)
404 wil_dbg_misc(wil
, "stop_p2p_device: entered\n");
405 mutex_lock(&wil
->mutex
);
406 mutex_lock(&wil
->p2p_wdev_mutex
);
407 wil_p2p_stop_radio_operations(wil
);
408 p2p
->p2p_dev_started
= 0;
409 mutex_unlock(&wil
->p2p_wdev_mutex
);
410 mutex_unlock(&wil
->mutex
);
413 static struct wireless_dev
*
414 wil_cfg80211_add_iface(struct wiphy
*wiphy
, const char *name
,
415 unsigned char name_assign_type
,
416 enum nl80211_iftype type
,
417 struct vif_params
*params
)
419 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
420 struct net_device
*ndev
= wil_to_ndev(wil
);
421 struct wireless_dev
*p2p_wdev
;
423 wil_dbg_misc(wil
, "add_iface\n");
425 if (type
!= NL80211_IFTYPE_P2P_DEVICE
) {
426 wil_err(wil
, "unsupported iftype %d\n", type
);
427 return ERR_PTR(-EINVAL
);
431 wil_err(wil
, "P2P_DEVICE interface already created\n");
432 return ERR_PTR(-EINVAL
);
435 p2p_wdev
= kzalloc(sizeof(*p2p_wdev
), GFP_KERNEL
);
437 return ERR_PTR(-ENOMEM
);
439 p2p_wdev
->iftype
= type
;
440 p2p_wdev
->wiphy
= wiphy
;
441 /* use our primary ethernet address */
442 ether_addr_copy(p2p_wdev
->address
, ndev
->perm_addr
);
444 wil
->p2p_wdev
= p2p_wdev
;
449 static int wil_cfg80211_del_iface(struct wiphy
*wiphy
,
450 struct wireless_dev
*wdev
)
452 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
454 wil_dbg_misc(wil
, "del_iface\n");
456 if (wdev
!= wil
->p2p_wdev
) {
457 wil_err(wil
, "delete of incorrect interface 0x%p\n", wdev
);
461 wil_cfg80211_stop_p2p_device(wiphy
, wdev
);
462 wil_p2p_wdev_free(wil
);
467 static int wil_cfg80211_change_iface(struct wiphy
*wiphy
,
468 struct net_device
*ndev
,
469 enum nl80211_iftype type
,
470 struct vif_params
*params
)
472 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
473 struct wireless_dev
*wdev
= wil_to_wdev(wil
);
476 wil_dbg_misc(wil
, "change_iface: type=%d\n", type
);
478 if (netif_running(wil_to_ndev(wil
)) && !wil_is_recovery_blocked(wil
)) {
479 wil_dbg_misc(wil
, "interface is up. resetting...\n");
480 mutex_lock(&wil
->mutex
);
483 mutex_unlock(&wil
->mutex
);
490 case NL80211_IFTYPE_STATION
:
491 case NL80211_IFTYPE_AP
:
492 case NL80211_IFTYPE_P2P_CLIENT
:
493 case NL80211_IFTYPE_P2P_GO
:
495 case NL80211_IFTYPE_MONITOR
:
497 wil
->monitor_flags
= params
->flags
;
508 static int wil_cfg80211_scan(struct wiphy
*wiphy
,
509 struct cfg80211_scan_request
*request
)
511 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
512 struct wireless_dev
*wdev
= request
->wdev
;
514 struct wmi_start_scan_cmd cmd
;
520 wil_dbg_misc(wil
, "scan: wdev=0x%p iftype=%d\n", wdev
, wdev
->iftype
);
522 /* check we are client side */
523 switch (wdev
->iftype
) {
524 case NL80211_IFTYPE_STATION
:
525 case NL80211_IFTYPE_P2P_CLIENT
:
526 case NL80211_IFTYPE_P2P_DEVICE
:
532 /* FW don't support scan after connection attempt */
533 if (test_bit(wil_status_dontscan
, wil
->status
)) {
534 wil_err(wil
, "Can't scan now\n");
538 mutex_lock(&wil
->mutex
);
540 mutex_lock(&wil
->p2p_wdev_mutex
);
541 if (wil
->scan_request
|| wil
->p2p
.discovery_started
) {
542 wil_err(wil
, "Already scanning\n");
543 mutex_unlock(&wil
->p2p_wdev_mutex
);
547 mutex_unlock(&wil
->p2p_wdev_mutex
);
549 if (wdev
->iftype
== NL80211_IFTYPE_P2P_DEVICE
) {
550 if (!wil
->p2p
.p2p_dev_started
) {
551 wil_err(wil
, "P2P search requested on stopped P2P device\n");
555 /* social scan on P2P_DEVICE is handled as p2p search */
556 if (wil_p2p_is_social_scan(request
)) {
557 wil
->scan_request
= request
;
558 wil
->radio_wdev
= wdev
;
559 rc
= wil_p2p_search(wil
, request
);
561 wil
->radio_wdev
= wil_to_wdev(wil
);
562 wil
->scan_request
= NULL
;
568 (void)wil_p2p_stop_discovery(wil
);
570 wil_dbg_misc(wil
, "Start scan_request 0x%p\n", request
);
571 wil_dbg_misc(wil
, "SSID count: %d", request
->n_ssids
);
573 for (i
= 0; i
< request
->n_ssids
; i
++) {
574 wil_dbg_misc(wil
, "SSID[%d]", i
);
575 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET
, 16, 1,
576 request
->ssids
[i
].ssid
,
577 request
->ssids
[i
].ssid_len
, true);
580 if (request
->n_ssids
)
581 rc
= wmi_set_ssid(wil
, request
->ssids
[0].ssid_len
,
582 request
->ssids
[0].ssid
);
584 rc
= wmi_set_ssid(wil
, 0, NULL
);
587 wil_err(wil
, "set SSID for scan request failed: %d\n", rc
);
591 wil
->scan_request
= request
;
592 mod_timer(&wil
->scan_timer
, jiffies
+ WIL6210_SCAN_TO
);
594 memset(&cmd
, 0, sizeof(cmd
));
595 cmd
.cmd
.scan_type
= WMI_ACTIVE_SCAN
;
596 cmd
.cmd
.num_channels
= 0;
597 n
= min(request
->n_channels
, 4U);
598 for (i
= 0; i
< n
; i
++) {
599 int ch
= request
->channels
[i
]->hw_value
;
603 "Scan requested for unknown frequency %dMhz\n",
604 request
->channels
[i
]->center_freq
);
607 /* 0-based channel indexes */
608 cmd
.cmd
.channel_list
[cmd
.cmd
.num_channels
++].channel
= ch
- 1;
609 wil_dbg_misc(wil
, "Scan for ch %d : %d MHz\n", ch
,
610 request
->channels
[i
]->center_freq
);
614 wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET
, 16, 1,
615 request
->ie
, request
->ie_len
, true);
617 wil_dbg_misc(wil
, "Scan has no IE's\n");
619 rc
= wmi_set_ie(wil
, WMI_FRAME_PROBE_REQ
, request
->ie_len
, request
->ie
);
623 if (wil
->discovery_mode
&& cmd
.cmd
.scan_type
== WMI_ACTIVE_SCAN
) {
624 cmd
.cmd
.discovery_mode
= 1;
625 wil_dbg_misc(wil
, "active scan with discovery_mode=1\n");
628 wil
->radio_wdev
= wdev
;
629 rc
= wmi_send(wil
, WMI_START_SCAN_CMDID
, &cmd
, sizeof(cmd
.cmd
) +
630 cmd
.cmd
.num_channels
* sizeof(cmd
.cmd
.channel_list
[0]));
634 del_timer_sync(&wil
->scan_timer
);
635 wil
->radio_wdev
= wil_to_wdev(wil
);
636 wil
->scan_request
= NULL
;
639 mutex_unlock(&wil
->mutex
);
643 static void wil_cfg80211_abort_scan(struct wiphy
*wiphy
,
644 struct wireless_dev
*wdev
)
646 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
648 wil_dbg_misc(wil
, "wdev=0x%p iftype=%d\n", wdev
, wdev
->iftype
);
650 mutex_lock(&wil
->mutex
);
651 mutex_lock(&wil
->p2p_wdev_mutex
);
653 if (!wil
->scan_request
)
656 if (wdev
!= wil
->scan_request
->wdev
) {
657 wil_dbg_misc(wil
, "abort scan was called on the wrong iface\n");
661 if (wil
->radio_wdev
== wil
->p2p_wdev
)
662 wil_p2p_stop_radio_operations(wil
);
664 wil_abort_scan(wil
, true);
667 mutex_unlock(&wil
->p2p_wdev_mutex
);
668 mutex_unlock(&wil
->mutex
);
671 static void wil_print_crypto(struct wil6210_priv
*wil
,
672 struct cfg80211_crypto_settings
*c
)
676 wil_dbg_misc(wil
, "WPA versions: 0x%08x cipher group 0x%08x\n",
677 c
->wpa_versions
, c
->cipher_group
);
678 wil_dbg_misc(wil
, "Pairwise ciphers [%d] {\n", c
->n_ciphers_pairwise
);
679 n
= min_t(int, c
->n_ciphers_pairwise
, ARRAY_SIZE(c
->ciphers_pairwise
));
680 for (i
= 0; i
< n
; i
++)
681 wil_dbg_misc(wil
, " [%d] = 0x%08x\n", i
,
682 c
->ciphers_pairwise
[i
]);
683 wil_dbg_misc(wil
, "}\n");
684 wil_dbg_misc(wil
, "AKM suites [%d] {\n", c
->n_akm_suites
);
685 n
= min_t(int, c
->n_akm_suites
, ARRAY_SIZE(c
->akm_suites
));
686 for (i
= 0; i
< n
; i
++)
687 wil_dbg_misc(wil
, " [%d] = 0x%08x\n", i
,
689 wil_dbg_misc(wil
, "}\n");
690 wil_dbg_misc(wil
, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
691 c
->control_port
, be16_to_cpu(c
->control_port_ethertype
),
692 c
->control_port_no_encrypt
);
695 static void wil_print_connect_params(struct wil6210_priv
*wil
,
696 struct cfg80211_connect_params
*sme
)
698 wil_info(wil
, "Connecting to:\n");
700 wil_info(wil
, " Channel: %d freq %d\n",
701 sme
->channel
->hw_value
, sme
->channel
->center_freq
);
704 wil_info(wil
, " BSSID: %pM\n", sme
->bssid
);
706 print_hex_dump(KERN_INFO
, " SSID: ", DUMP_PREFIX_OFFSET
,
707 16, 1, sme
->ssid
, sme
->ssid_len
, true);
708 wil_info(wil
, " Privacy: %s\n", sme
->privacy
? "secure" : "open");
709 wil_info(wil
, " PBSS: %d\n", sme
->pbss
);
710 wil_print_crypto(wil
, &sme
->crypto
);
713 static int wil_cfg80211_connect(struct wiphy
*wiphy
,
714 struct net_device
*ndev
,
715 struct cfg80211_connect_params
*sme
)
717 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
718 struct cfg80211_bss
*bss
;
719 struct wmi_connect_cmd conn
;
724 enum ieee80211_bss_type bss_type
= IEEE80211_BSS_TYPE_ESS
;
726 wil_dbg_misc(wil
, "connect\n");
727 wil_print_connect_params(wil
, sme
);
729 if (test_bit(wil_status_fwconnecting
, wil
->status
) ||
730 test_bit(wil_status_fwconnected
, wil
->status
))
733 if (sme
->ie_len
> WMI_MAX_IE_LEN
) {
734 wil_err(wil
, "IE too large (%td bytes)\n", sme
->ie_len
);
739 cfg80211_find_ie(WLAN_EID_RSN
, sme
->ie
, sme
->ie_len
) :
741 if (sme
->privacy
&& !rsn_eid
)
742 wil_info(wil
, "WSC connection\n");
745 bss_type
= IEEE80211_BSS_TYPE_PBSS
;
747 bss
= cfg80211_get_bss(wiphy
, sme
->channel
, sme
->bssid
,
748 sme
->ssid
, sme
->ssid_len
,
749 bss_type
, IEEE80211_PRIVACY_ANY
);
751 wil_err(wil
, "Unable to find BSS\n");
755 ssid_eid
= ieee80211_bss_get_ie(bss
, WLAN_EID_SSID
);
757 wil_err(wil
, "No SSID\n");
761 wil
->privacy
= sme
->privacy
;
762 wil
->pbss
= sme
->pbss
;
765 /* For secure assoc, remove old keys */
766 rc
= wmi_del_cipher_key(wil
, 0, bss
->bssid
,
767 WMI_KEY_USE_PAIRWISE
);
769 wil_err(wil
, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n");
772 rc
= wmi_del_cipher_key(wil
, 0, bss
->bssid
,
773 WMI_KEY_USE_RX_GROUP
);
775 wil_err(wil
, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n");
780 /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info
781 * elements. Send it also in case it's empty, to erase previously set
784 rc
= wmi_set_ie(wil
, WMI_FRAME_ASSOC_REQ
, sme
->ie_len
, sme
->ie
);
788 /* WMI_CONNECT_CMD */
789 memset(&conn
, 0, sizeof(conn
));
790 switch (bss
->capability
& WLAN_CAPABILITY_DMG_TYPE_MASK
) {
791 case WLAN_CAPABILITY_DMG_TYPE_AP
:
792 conn
.network_type
= WMI_NETTYPE_INFRA
;
794 case WLAN_CAPABILITY_DMG_TYPE_PBSS
:
795 conn
.network_type
= WMI_NETTYPE_P2P
;
798 wil_err(wil
, "Unsupported BSS type, capability= 0x%04x\n",
803 if (rsn_eid
) { /* regular secure connection */
804 conn
.dot11_auth_mode
= WMI_AUTH11_SHARED
;
805 conn
.auth_mode
= WMI_AUTH_WPA2_PSK
;
806 conn
.pairwise_crypto_type
= WMI_CRYPT_AES_GCMP
;
807 conn
.pairwise_crypto_len
= 16;
808 conn
.group_crypto_type
= WMI_CRYPT_AES_GCMP
;
809 conn
.group_crypto_len
= 16;
811 conn
.dot11_auth_mode
= WMI_AUTH11_WSC
;
812 conn
.auth_mode
= WMI_AUTH_NONE
;
814 } else { /* insecure connection */
815 conn
.dot11_auth_mode
= WMI_AUTH11_OPEN
;
816 conn
.auth_mode
= WMI_AUTH_NONE
;
819 conn
.ssid_len
= min_t(u8
, ssid_eid
[1], 32);
820 memcpy(conn
.ssid
, ssid_eid
+2, conn
.ssid_len
);
822 ch
= bss
->channel
->hw_value
;
824 wil_err(wil
, "BSS at unknown frequency %dMhz\n",
825 bss
->channel
->center_freq
);
829 conn
.channel
= ch
- 1;
831 ether_addr_copy(conn
.bssid
, bss
->bssid
);
832 ether_addr_copy(conn
.dst_mac
, bss
->bssid
);
834 set_bit(wil_status_fwconnecting
, wil
->status
);
836 rc
= wmi_send(wil
, WMI_CONNECT_CMDID
, &conn
, sizeof(conn
));
838 netif_carrier_on(ndev
);
839 wil6210_bus_request(wil
, WIL_MAX_BUS_REQUEST_KBPS
);
841 /* Connect can take lots of time */
842 mod_timer(&wil
->connect_timer
,
843 jiffies
+ msecs_to_jiffies(5000));
845 clear_bit(wil_status_fwconnecting
, wil
->status
);
849 cfg80211_put_bss(wiphy
, bss
);
854 static int wil_cfg80211_disconnect(struct wiphy
*wiphy
,
855 struct net_device
*ndev
,
859 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
861 wil_dbg_misc(wil
, "disconnect: reason=%d\n", reason_code
);
863 if (!(test_bit(wil_status_fwconnecting
, wil
->status
) ||
864 test_bit(wil_status_fwconnected
, wil
->status
))) {
865 wil_err(wil
, "Disconnect was called while disconnected\n");
869 wil
->locally_generated_disc
= true;
870 rc
= wmi_call(wil
, WMI_DISCONNECT_CMDID
, NULL
, 0,
871 WMI_DISCONNECT_EVENTID
, NULL
, 0,
872 WIL6210_DISCONNECT_TO_MS
);
874 wil_err(wil
, "disconnect error %d\n", rc
);
879 static int wil_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
881 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
884 /* these parameters are explicitly not supported */
885 if (changed
& (WIPHY_PARAM_RETRY_LONG
|
886 WIPHY_PARAM_FRAG_THRESHOLD
|
887 WIPHY_PARAM_RTS_THRESHOLD
))
890 if (changed
& WIPHY_PARAM_RETRY_SHORT
) {
891 rc
= wmi_set_mgmt_retry(wil
, wiphy
->retry_short
);
899 int wil_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
900 struct cfg80211_mgmt_tx_params
*params
,
903 const u8
*buf
= params
->buf
;
904 size_t len
= params
->len
, total
;
905 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
907 bool tx_status
= false;
908 struct ieee80211_mgmt
*mgmt_frame
= (void *)buf
;
909 struct wmi_sw_tx_req_cmd
*cmd
;
911 struct wmi_cmd_hdr wmi
;
912 struct wmi_sw_tx_complete_event evt
;
915 /* Note, currently we do not support the "wait" parameter, user-space
916 * must call remain_on_channel before mgmt_tx or listen on a channel
917 * another way (AP/PCP or connected station)
918 * in addition we need to check if specified "chan" argument is
919 * different from currently "listened" channel and fail if it is.
922 wil_dbg_misc(wil
, "mgmt_tx\n");
923 wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET
, 16, 1, buf
,
926 if (len
< sizeof(struct ieee80211_hdr_3addr
))
929 total
= sizeof(*cmd
) + len
;
933 cmd
= kmalloc(total
, GFP_KERNEL
);
939 memcpy(cmd
->dst_mac
, mgmt_frame
->da
, WMI_MAC_LEN
);
940 cmd
->len
= cpu_to_le16(len
);
941 memcpy(cmd
->payload
, buf
, len
);
943 rc
= wmi_call(wil
, WMI_SW_TX_REQ_CMDID
, cmd
, total
,
944 WMI_SW_TX_COMPLETE_EVENTID
, &evt
, sizeof(evt
), 2000);
946 tx_status
= !evt
.evt
.status
;
950 cfg80211_mgmt_tx_status(wdev
, cookie
? *cookie
: 0, buf
, len
,
951 tx_status
, GFP_KERNEL
);
955 static int wil_cfg80211_set_channel(struct wiphy
*wiphy
,
956 struct cfg80211_chan_def
*chandef
)
958 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
960 wil
->monitor_chandef
= *chandef
;
965 static enum wmi_key_usage
wil_detect_key_usage(struct wil6210_priv
*wil
,
968 struct wireless_dev
*wdev
= wil_to_wdev(wil
);
969 enum wmi_key_usage rc
;
972 rc
= WMI_KEY_USE_PAIRWISE
;
974 switch (wdev
->iftype
) {
975 case NL80211_IFTYPE_STATION
:
976 case NL80211_IFTYPE_P2P_CLIENT
:
977 rc
= WMI_KEY_USE_RX_GROUP
;
979 case NL80211_IFTYPE_AP
:
980 case NL80211_IFTYPE_P2P_GO
:
981 rc
= WMI_KEY_USE_TX_GROUP
;
984 /* TODO: Rx GTK or Tx GTK? */
985 wil_err(wil
, "Can't determine GTK type\n");
986 rc
= WMI_KEY_USE_RX_GROUP
;
990 wil_dbg_misc(wil
, "detect_key_usage: -> %s\n", key_usage_str
[rc
]);
995 static struct wil_sta_info
*
996 wil_find_sta_by_key_usage(struct wil6210_priv
*wil
,
997 enum wmi_key_usage key_usage
, const u8
*mac_addr
)
1001 if (key_usage
== WMI_KEY_USE_TX_GROUP
)
1002 return NULL
; /* not needed */
1004 /* supplicant provides Rx group key in STA mode with NULL MAC address */
1006 cid
= wil_find_cid(wil
, mac_addr
);
1007 else if (key_usage
== WMI_KEY_USE_RX_GROUP
)
1008 cid
= wil_find_cid_by_idx(wil
, 0);
1010 wil_err(wil
, "No CID for %pM %s\n", mac_addr
,
1011 key_usage_str
[key_usage
]);
1012 return ERR_PTR(cid
);
1015 return &wil
->sta
[cid
];
1018 static void wil_set_crypto_rx(u8 key_index
, enum wmi_key_usage key_usage
,
1019 struct wil_sta_info
*cs
,
1020 struct key_params
*params
)
1022 struct wil_tid_crypto_rx_single
*cc
;
1028 switch (key_usage
) {
1029 case WMI_KEY_USE_PAIRWISE
:
1030 for (tid
= 0; tid
< WIL_STA_TID_NUM
; tid
++) {
1031 cc
= &cs
->tid_crypto_rx
[tid
].key_id
[key_index
];
1033 memcpy(cc
->pn
, params
->seq
,
1034 IEEE80211_GCMP_PN_LEN
);
1036 memset(cc
->pn
, 0, IEEE80211_GCMP_PN_LEN
);
1040 case WMI_KEY_USE_RX_GROUP
:
1041 cc
= &cs
->group_crypto_rx
.key_id
[key_index
];
1043 memcpy(cc
->pn
, params
->seq
, IEEE80211_GCMP_PN_LEN
);
1045 memset(cc
->pn
, 0, IEEE80211_GCMP_PN_LEN
);
1053 static void wil_del_rx_key(u8 key_index
, enum wmi_key_usage key_usage
,
1054 struct wil_sta_info
*cs
)
1056 struct wil_tid_crypto_rx_single
*cc
;
1062 switch (key_usage
) {
1063 case WMI_KEY_USE_PAIRWISE
:
1064 for (tid
= 0; tid
< WIL_STA_TID_NUM
; tid
++) {
1065 cc
= &cs
->tid_crypto_rx
[tid
].key_id
[key_index
];
1066 cc
->key_set
= false;
1069 case WMI_KEY_USE_RX_GROUP
:
1070 cc
= &cs
->group_crypto_rx
.key_id
[key_index
];
1071 cc
->key_set
= false;
1078 static int wil_cfg80211_add_key(struct wiphy
*wiphy
,
1079 struct net_device
*ndev
,
1080 u8 key_index
, bool pairwise
,
1082 struct key_params
*params
)
1085 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1086 enum wmi_key_usage key_usage
= wil_detect_key_usage(wil
, pairwise
);
1087 struct wil_sta_info
*cs
= wil_find_sta_by_key_usage(wil
, key_usage
,
1091 wil_err(wil
, "NULL params\n");
1095 wil_dbg_misc(wil
, "add_key: %pM %s[%d] PN %*phN\n",
1096 mac_addr
, key_usage_str
[key_usage
], key_index
,
1097 params
->seq_len
, params
->seq
);
1100 wil_err(wil
, "Not connected, %pM %s[%d] PN %*phN\n",
1101 mac_addr
, key_usage_str
[key_usage
], key_index
,
1102 params
->seq_len
, params
->seq
);
1106 wil_del_rx_key(key_index
, key_usage
, cs
);
1108 if (params
->seq
&& params
->seq_len
!= IEEE80211_GCMP_PN_LEN
) {
1110 "Wrong PN len %d, %pM %s[%d] PN %*phN\n",
1111 params
->seq_len
, mac_addr
,
1112 key_usage_str
[key_usage
], key_index
,
1113 params
->seq_len
, params
->seq
);
1117 rc
= wmi_add_cipher_key(wil
, key_index
, mac_addr
, params
->key_len
,
1118 params
->key
, key_usage
);
1120 wil_set_crypto_rx(key_index
, key_usage
, cs
, params
);
1125 static int wil_cfg80211_del_key(struct wiphy
*wiphy
,
1126 struct net_device
*ndev
,
1127 u8 key_index
, bool pairwise
,
1130 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1131 enum wmi_key_usage key_usage
= wil_detect_key_usage(wil
, pairwise
);
1132 struct wil_sta_info
*cs
= wil_find_sta_by_key_usage(wil
, key_usage
,
1135 wil_dbg_misc(wil
, "del_key: %pM %s[%d]\n", mac_addr
,
1136 key_usage_str
[key_usage
], key_index
);
1139 wil_info(wil
, "Not connected, %pM %s[%d]\n",
1140 mac_addr
, key_usage_str
[key_usage
], key_index
);
1142 if (!IS_ERR_OR_NULL(cs
))
1143 wil_del_rx_key(key_index
, key_usage
, cs
);
1145 return wmi_del_cipher_key(wil
, key_index
, mac_addr
, key_usage
);
1148 /* Need to be present or wiphy_new() will WARN */
1149 static int wil_cfg80211_set_default_key(struct wiphy
*wiphy
,
1150 struct net_device
*ndev
,
1151 u8 key_index
, bool unicast
,
1154 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1156 wil_dbg_misc(wil
, "set_default_key: entered\n");
1160 static int wil_remain_on_channel(struct wiphy
*wiphy
,
1161 struct wireless_dev
*wdev
,
1162 struct ieee80211_channel
*chan
,
1163 unsigned int duration
,
1166 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1170 "remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
1171 chan
->center_freq
, duration
, wdev
->iftype
);
1173 rc
= wil_p2p_listen(wil
, wdev
, duration
, chan
, cookie
);
1177 static int wil_cancel_remain_on_channel(struct wiphy
*wiphy
,
1178 struct wireless_dev
*wdev
,
1181 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1183 wil_dbg_misc(wil
, "cancel_remain_on_channel\n");
1185 return wil_p2p_cancel_listen(wil
, cookie
);
1189 * find a specific IE in a list of IEs
1190 * return a pointer to the beginning of IE in the list
1191 * or NULL if not found
1193 static const u8
*_wil_cfg80211_find_ie(const u8
*ies
, u16 ies_len
, const u8
*ie
,
1196 struct ieee80211_vendor_ie
*vie
;
1199 /* IE tag at offset 0, length at offset 1 */
1200 if (ie_len
< 2 || 2 + ie
[1] > ie_len
)
1203 if (ie
[0] != WLAN_EID_VENDOR_SPECIFIC
)
1204 return cfg80211_find_ie(ie
[0], ies
, ies_len
);
1206 /* make sure there is room for 3 bytes OUI + 1 byte OUI type */
1209 vie
= (struct ieee80211_vendor_ie
*)ie
;
1210 oui
= vie
->oui
[0] << 16 | vie
->oui
[1] << 8 | vie
->oui
[2];
1211 return cfg80211_find_vendor_ie(oui
, vie
->oui_type
, ies
,
1216 * merge the IEs in two lists into a single list.
1217 * do not include IEs from the second list which exist in the first list.
1218 * add only vendor specific IEs from second list to keep
1219 * the merged list sorted (since vendor-specific IE has the
1220 * highest tag number)
1221 * caller must free the allocated memory for merged IEs
1223 static int _wil_cfg80211_merge_extra_ies(const u8
*ies1
, u16 ies1_len
,
1224 const u8
*ies2
, u16 ies2_len
,
1225 u8
**merged_ies
, u16
*merged_len
)
1230 if (ies1_len
== 0 && ies2_len
== 0) {
1236 buf
= kmalloc(ies1_len
+ ies2_len
, GFP_KERNEL
);
1239 memcpy(buf
, ies1
, ies1_len
);
1240 dpos
= buf
+ ies1_len
;
1242 while (spos
+ 1 < ies2
+ ies2_len
) {
1243 /* IE tag at offset 0, length at offset 1 */
1244 u16 ielen
= 2 + spos
[1];
1246 if (spos
+ ielen
> ies2
+ ies2_len
)
1248 if (spos
[0] == WLAN_EID_VENDOR_SPECIFIC
&&
1249 !_wil_cfg80211_find_ie(ies1
, ies1_len
, spos
, ielen
)) {
1250 memcpy(dpos
, spos
, ielen
);
1257 *merged_len
= dpos
- buf
;
1261 static void wil_print_bcon_data(struct cfg80211_beacon_data
*b
)
1263 wil_hex_dump_misc("head ", DUMP_PREFIX_OFFSET
, 16, 1,
1264 b
->head
, b
->head_len
, true);
1265 wil_hex_dump_misc("tail ", DUMP_PREFIX_OFFSET
, 16, 1,
1266 b
->tail
, b
->tail_len
, true);
1267 wil_hex_dump_misc("BCON IE ", DUMP_PREFIX_OFFSET
, 16, 1,
1268 b
->beacon_ies
, b
->beacon_ies_len
, true);
1269 wil_hex_dump_misc("PROBE ", DUMP_PREFIX_OFFSET
, 16, 1,
1270 b
->probe_resp
, b
->probe_resp_len
, true);
1271 wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET
, 16, 1,
1272 b
->proberesp_ies
, b
->proberesp_ies_len
, true);
1273 wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET
, 16, 1,
1274 b
->assocresp_ies
, b
->assocresp_ies_len
, true);
1277 /* internal functions for device reset and starting AP */
1278 static int _wil_cfg80211_set_ies(struct wiphy
*wiphy
,
1279 struct cfg80211_beacon_data
*bcon
)
1282 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1283 u16 len
= 0, proberesp_len
= 0;
1284 u8
*ies
= NULL
, *proberesp
= NULL
;
1286 if (bcon
->probe_resp
) {
1287 struct ieee80211_mgmt
*f
=
1288 (struct ieee80211_mgmt
*)bcon
->probe_resp
;
1289 size_t hlen
= offsetof(struct ieee80211_mgmt
,
1290 u
.probe_resp
.variable
);
1291 proberesp
= f
->u
.probe_resp
.variable
;
1292 proberesp_len
= bcon
->probe_resp_len
- hlen
;
1294 rc
= _wil_cfg80211_merge_extra_ies(proberesp
,
1296 bcon
->proberesp_ies
,
1297 bcon
->proberesp_ies_len
,
1303 rc
= wmi_set_ie(wil
, WMI_FRAME_PROBE_RESP
, len
, ies
);
1307 if (bcon
->assocresp_ies
)
1308 rc
= wmi_set_ie(wil
, WMI_FRAME_ASSOC_RESP
,
1309 bcon
->assocresp_ies_len
, bcon
->assocresp_ies
);
1311 rc
= wmi_set_ie(wil
, WMI_FRAME_ASSOC_RESP
, len
, ies
);
1312 #if 0 /* to use beacon IE's, remove this #if 0 */
1316 rc
= wmi_set_ie(wil
, WMI_FRAME_BEACON
, bcon
->tail_len
, bcon
->tail
);
1323 static int _wil_cfg80211_start_ap(struct wiphy
*wiphy
,
1324 struct net_device
*ndev
,
1325 const u8
*ssid
, size_t ssid_len
, u32 privacy
,
1327 struct cfg80211_beacon_data
*bcon
,
1328 u8 hidden_ssid
, u32 pbss
)
1330 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1332 struct wireless_dev
*wdev
= ndev
->ieee80211_ptr
;
1333 u8 wmi_nettype
= wil_iftype_nl2wmi(wdev
->iftype
);
1334 u8 is_go
= (wdev
->iftype
== NL80211_IFTYPE_P2P_GO
);
1337 wmi_nettype
= WMI_NETTYPE_P2P
;
1339 wil_dbg_misc(wil
, "start_ap: is_go=%d\n", is_go
);
1340 if (is_go
&& !pbss
) {
1341 wil_err(wil
, "P2P GO must be in PBSS\n");
1345 wil_set_recovery_state(wil
, fw_recovery_idle
);
1347 mutex_lock(&wil
->mutex
);
1354 rc
= wmi_set_ssid(wil
, ssid_len
, ssid
);
1358 rc
= _wil_cfg80211_set_ies(wiphy
, bcon
);
1362 wil
->privacy
= privacy
;
1363 wil
->channel
= chan
;
1364 wil
->hidden_ssid
= hidden_ssid
;
1367 netif_carrier_on(ndev
);
1368 wil6210_bus_request(wil
, WIL_MAX_BUS_REQUEST_KBPS
);
1370 rc
= wmi_pcp_start(wil
, bi
, wmi_nettype
, chan
, hidden_ssid
, is_go
);
1374 rc
= wil_bcast_init(wil
);
1378 goto out
; /* success */
1383 netif_carrier_off(ndev
);
1384 wil6210_bus_request(wil
, WIL_DEFAULT_BUS_REQUEST_KBPS
);
1386 mutex_unlock(&wil
->mutex
);
1390 static int wil_cfg80211_change_beacon(struct wiphy
*wiphy
,
1391 struct net_device
*ndev
,
1392 struct cfg80211_beacon_data
*bcon
)
1394 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1398 wil_dbg_misc(wil
, "change_beacon\n");
1399 wil_print_bcon_data(bcon
);
1402 cfg80211_find_ie(WLAN_EID_RSN
, bcon
->tail
,
1406 /* in case privacy has changed, need to restart the AP */
1407 if (wil
->privacy
!= privacy
) {
1408 struct wireless_dev
*wdev
= ndev
->ieee80211_ptr
;
1410 wil_dbg_misc(wil
, "privacy changed %d=>%d. Restarting AP\n",
1411 wil
->privacy
, privacy
);
1413 rc
= _wil_cfg80211_start_ap(wiphy
, ndev
, wdev
->ssid
,
1414 wdev
->ssid_len
, privacy
,
1415 wdev
->beacon_interval
,
1420 rc
= _wil_cfg80211_set_ies(wiphy
, bcon
);
1426 static int wil_cfg80211_start_ap(struct wiphy
*wiphy
,
1427 struct net_device
*ndev
,
1428 struct cfg80211_ap_settings
*info
)
1431 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1432 struct ieee80211_channel
*channel
= info
->chandef
.chan
;
1433 struct cfg80211_beacon_data
*bcon
= &info
->beacon
;
1434 struct cfg80211_crypto_settings
*crypto
= &info
->crypto
;
1437 wil_dbg_misc(wil
, "start_ap\n");
1440 wil_err(wil
, "AP: No channel???\n");
1444 switch (info
->hidden_ssid
) {
1445 case NL80211_HIDDEN_SSID_NOT_IN_USE
:
1446 hidden_ssid
= WMI_HIDDEN_SSID_DISABLED
;
1449 case NL80211_HIDDEN_SSID_ZERO_LEN
:
1450 hidden_ssid
= WMI_HIDDEN_SSID_SEND_EMPTY
;
1453 case NL80211_HIDDEN_SSID_ZERO_CONTENTS
:
1454 hidden_ssid
= WMI_HIDDEN_SSID_CLEAR
;
1458 wil_err(wil
, "AP: Invalid hidden SSID %d\n", info
->hidden_ssid
);
1461 wil_dbg_misc(wil
, "AP on Channel %d %d MHz, %s\n", channel
->hw_value
,
1462 channel
->center_freq
, info
->privacy
? "secure" : "open");
1463 wil_dbg_misc(wil
, "Privacy: %d auth_type %d\n",
1464 info
->privacy
, info
->auth_type
);
1465 wil_dbg_misc(wil
, "Hidden SSID mode: %d\n",
1467 wil_dbg_misc(wil
, "BI %d DTIM %d\n", info
->beacon_interval
,
1469 wil_dbg_misc(wil
, "PBSS %d\n", info
->pbss
);
1470 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET
, 16, 1,
1471 info
->ssid
, info
->ssid_len
, true);
1472 wil_print_bcon_data(bcon
);
1473 wil_print_crypto(wil
, crypto
);
1475 rc
= _wil_cfg80211_start_ap(wiphy
, ndev
,
1476 info
->ssid
, info
->ssid_len
, info
->privacy
,
1477 info
->beacon_interval
, channel
->hw_value
,
1478 bcon
, hidden_ssid
, info
->pbss
);
1483 static int wil_cfg80211_stop_ap(struct wiphy
*wiphy
,
1484 struct net_device
*ndev
)
1486 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1488 wil_dbg_misc(wil
, "stop_ap\n");
1490 netif_carrier_off(ndev
);
1491 wil6210_bus_request(wil
, WIL_DEFAULT_BUS_REQUEST_KBPS
);
1492 wil_set_recovery_state(wil
, fw_recovery_idle
);
1494 set_bit(wil_status_resetting
, wil
->status
);
1496 mutex_lock(&wil
->mutex
);
1502 mutex_unlock(&wil
->mutex
);
1507 static int wil_cfg80211_add_station(struct wiphy
*wiphy
,
1508 struct net_device
*dev
,
1510 struct station_parameters
*params
)
1512 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1514 wil_dbg_misc(wil
, "add station %pM aid %d\n", mac
, params
->aid
);
1516 if (!disable_ap_sme
) {
1517 wil_err(wil
, "not supported with AP SME enabled\n");
1521 if (params
->aid
> WIL_MAX_DMG_AID
) {
1522 wil_err(wil
, "invalid aid\n");
1526 return wmi_new_sta(wil
, mac
, params
->aid
);
1529 static int wil_cfg80211_del_station(struct wiphy
*wiphy
,
1530 struct net_device
*dev
,
1531 struct station_del_parameters
*params
)
1533 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1535 wil_dbg_misc(wil
, "del_station: %pM, reason=%d\n", params
->mac
,
1536 params
->reason_code
);
1538 mutex_lock(&wil
->mutex
);
1539 wil6210_disconnect(wil
, params
->mac
, params
->reason_code
, false);
1540 mutex_unlock(&wil
->mutex
);
1545 static int wil_cfg80211_change_station(struct wiphy
*wiphy
,
1546 struct net_device
*dev
,
1548 struct station_parameters
*params
)
1550 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1553 struct vring_tx_data
*txdata
= NULL
;
1555 wil_dbg_misc(wil
, "change station %pM mask 0x%x set 0x%x\n", mac
,
1556 params
->sta_flags_mask
, params
->sta_flags_set
);
1558 if (!disable_ap_sme
) {
1559 wil_dbg_misc(wil
, "not supported with AP SME enabled\n");
1563 if (!(params
->sta_flags_mask
& BIT(NL80211_STA_FLAG_AUTHORIZED
)))
1566 cid
= wil_find_cid(wil
, mac
);
1568 wil_err(wil
, "station not found\n");
1572 for (i
= 0; i
< ARRAY_SIZE(wil
->vring2cid_tid
); i
++)
1573 if (wil
->vring2cid_tid
[i
][0] == cid
) {
1574 txdata
= &wil
->vring_tx_data
[i
];
1579 wil_err(wil
, "vring data not found\n");
1583 authorize
= params
->sta_flags_set
& BIT(NL80211_STA_FLAG_AUTHORIZED
);
1584 txdata
->dot1x_open
= authorize
? 1 : 0;
1585 wil_dbg_misc(wil
, "cid %d vring %d authorize %d\n", cid
, i
,
1586 txdata
->dot1x_open
);
1591 /* probe_client handling */
1592 static void wil_probe_client_handle(struct wil6210_priv
*wil
,
1593 struct wil_probe_client_req
*req
)
1595 struct net_device
*ndev
= wil_to_ndev(wil
);
1596 struct wil_sta_info
*sta
= &wil
->sta
[req
->cid
];
1597 /* assume STA is alive if it is still connected,
1598 * else FW will disconnect it
1600 bool alive
= (sta
->status
== wil_sta_connected
);
1602 cfg80211_probe_status(ndev
, sta
->addr
, req
->cookie
, alive
, GFP_KERNEL
);
1605 static struct list_head
*next_probe_client(struct wil6210_priv
*wil
)
1607 struct list_head
*ret
= NULL
;
1609 mutex_lock(&wil
->probe_client_mutex
);
1611 if (!list_empty(&wil
->probe_client_pending
)) {
1612 ret
= wil
->probe_client_pending
.next
;
1616 mutex_unlock(&wil
->probe_client_mutex
);
1621 void wil_probe_client_worker(struct work_struct
*work
)
1623 struct wil6210_priv
*wil
= container_of(work
, struct wil6210_priv
,
1624 probe_client_worker
);
1625 struct wil_probe_client_req
*req
;
1626 struct list_head
*lh
;
1628 while ((lh
= next_probe_client(wil
)) != NULL
) {
1629 req
= list_entry(lh
, struct wil_probe_client_req
, list
);
1631 wil_probe_client_handle(wil
, req
);
1636 void wil_probe_client_flush(struct wil6210_priv
*wil
)
1638 struct wil_probe_client_req
*req
, *t
;
1640 wil_dbg_misc(wil
, "probe_client_flush\n");
1642 mutex_lock(&wil
->probe_client_mutex
);
1644 list_for_each_entry_safe(req
, t
, &wil
->probe_client_pending
, list
) {
1645 list_del(&req
->list
);
1649 mutex_unlock(&wil
->probe_client_mutex
);
1652 static int wil_cfg80211_probe_client(struct wiphy
*wiphy
,
1653 struct net_device
*dev
,
1654 const u8
*peer
, u64
*cookie
)
1656 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1657 struct wil_probe_client_req
*req
;
1658 int cid
= wil_find_cid(wil
, peer
);
1660 wil_dbg_misc(wil
, "probe_client: %pM => CID %d\n", peer
, cid
);
1665 req
= kzalloc(sizeof(*req
), GFP_KERNEL
);
1672 mutex_lock(&wil
->probe_client_mutex
);
1673 list_add_tail(&req
->list
, &wil
->probe_client_pending
);
1674 mutex_unlock(&wil
->probe_client_mutex
);
1676 *cookie
= req
->cookie
;
1677 queue_work(wil
->wq_service
, &wil
->probe_client_worker
);
1681 static int wil_cfg80211_change_bss(struct wiphy
*wiphy
,
1682 struct net_device
*dev
,
1683 struct bss_parameters
*params
)
1685 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1687 if (params
->ap_isolate
>= 0) {
1688 wil_dbg_misc(wil
, "change_bss: ap_isolate %d => %d\n",
1689 wil
->ap_isolate
, params
->ap_isolate
);
1690 wil
->ap_isolate
= params
->ap_isolate
;
1696 static int wil_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
1697 struct net_device
*dev
,
1698 bool enabled
, int timeout
)
1700 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1701 enum wmi_ps_profile_type ps_profile
;
1703 wil_dbg_misc(wil
, "enabled=%d, timeout=%d\n",
1707 ps_profile
= WMI_PS_PROFILE_TYPE_DEFAULT
;
1709 ps_profile
= WMI_PS_PROFILE_TYPE_PS_DISABLED
;
1711 return wil_ps_update(wil
, ps_profile
);
1714 static int wil_cfg80211_suspend(struct wiphy
*wiphy
,
1715 struct cfg80211_wowlan
*wow
)
1717 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1720 /* Setting the wakeup trigger based on wow is TBD */
1722 if (test_bit(wil_status_suspended
, wil
->status
)) {
1723 wil_dbg_pm(wil
, "trying to suspend while suspended\n");
1727 rc
= wil_can_suspend(wil
, false);
1731 wil_dbg_pm(wil
, "suspending\n");
1733 mutex_lock(&wil
->mutex
);
1734 mutex_lock(&wil
->p2p_wdev_mutex
);
1735 wil_p2p_stop_radio_operations(wil
);
1736 wil_abort_scan(wil
, true);
1737 mutex_unlock(&wil
->p2p_wdev_mutex
);
1738 mutex_unlock(&wil
->mutex
);
1744 static int wil_cfg80211_resume(struct wiphy
*wiphy
)
1746 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1748 wil_dbg_pm(wil
, "resuming\n");
1754 wil_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
1755 struct net_device
*dev
,
1756 struct cfg80211_sched_scan_request
*request
)
1758 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1762 "sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n",
1763 request
->n_ssids
, request
->ie_len
, request
->flags
);
1764 for (i
= 0; i
< request
->n_ssids
; i
++) {
1765 wil_dbg_misc(wil
, "SSID[%d]:", i
);
1766 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET
, 16, 1,
1767 request
->ssids
[i
].ssid
,
1768 request
->ssids
[i
].ssid_len
, true);
1770 wil_dbg_misc(wil
, "channels:");
1771 for (i
= 0; i
< request
->n_channels
; i
++)
1772 wil_dbg_misc(wil
, " %d%s", request
->channels
[i
]->hw_value
,
1773 i
== request
->n_channels
- 1 ? "\n" : "");
1774 wil_dbg_misc(wil
, "n_match_sets %d, min_rssi_thold %d, delay %d\n",
1775 request
->n_match_sets
, request
->min_rssi_thold
,
1777 for (i
= 0; i
< request
->n_match_sets
; i
++) {
1778 struct cfg80211_match_set
*ms
= &request
->match_sets
[i
];
1780 wil_dbg_misc(wil
, "MATCHSET[%d]: rssi_thold %d\n",
1782 wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET
, 16, 1,
1784 ms
->ssid
.ssid_len
, true);
1786 wil_dbg_misc(wil
, "n_scan_plans %d\n", request
->n_scan_plans
);
1787 for (i
= 0; i
< request
->n_scan_plans
; i
++) {
1788 struct cfg80211_sched_scan_plan
*sp
= &request
->scan_plans
[i
];
1790 wil_dbg_misc(wil
, "SCAN PLAN[%d]: interval %d iterations %d\n",
1791 i
, sp
->interval
, sp
->iterations
);
1794 rc
= wmi_set_ie(wil
, WMI_FRAME_PROBE_REQ
, request
->ie_len
, request
->ie
);
1797 return wmi_start_sched_scan(wil
, request
);
1801 wil_cfg80211_sched_scan_stop(struct wiphy
*wiphy
, struct net_device
*dev
,
1804 struct wil6210_priv
*wil
= wiphy_to_wil(wiphy
);
1807 rc
= wmi_stop_sched_scan(wil
);
1808 /* device would return error if it thinks PNO is already stopped.
1809 * ignore the return code so user space and driver gets back in-sync
1811 wil_dbg_misc(wil
, "sched scan stopped (%d)\n", rc
);
1816 static const struct cfg80211_ops wil_cfg80211_ops
= {
1817 .add_virtual_intf
= wil_cfg80211_add_iface
,
1818 .del_virtual_intf
= wil_cfg80211_del_iface
,
1819 .scan
= wil_cfg80211_scan
,
1820 .abort_scan
= wil_cfg80211_abort_scan
,
1821 .connect
= wil_cfg80211_connect
,
1822 .disconnect
= wil_cfg80211_disconnect
,
1823 .set_wiphy_params
= wil_cfg80211_set_wiphy_params
,
1824 .change_virtual_intf
= wil_cfg80211_change_iface
,
1825 .get_station
= wil_cfg80211_get_station
,
1826 .dump_station
= wil_cfg80211_dump_station
,
1827 .remain_on_channel
= wil_remain_on_channel
,
1828 .cancel_remain_on_channel
= wil_cancel_remain_on_channel
,
1829 .mgmt_tx
= wil_cfg80211_mgmt_tx
,
1830 .set_monitor_channel
= wil_cfg80211_set_channel
,
1831 .add_key
= wil_cfg80211_add_key
,
1832 .del_key
= wil_cfg80211_del_key
,
1833 .set_default_key
= wil_cfg80211_set_default_key
,
1835 .change_beacon
= wil_cfg80211_change_beacon
,
1836 .start_ap
= wil_cfg80211_start_ap
,
1837 .stop_ap
= wil_cfg80211_stop_ap
,
1838 .add_station
= wil_cfg80211_add_station
,
1839 .del_station
= wil_cfg80211_del_station
,
1840 .change_station
= wil_cfg80211_change_station
,
1841 .probe_client
= wil_cfg80211_probe_client
,
1842 .change_bss
= wil_cfg80211_change_bss
,
1844 .start_p2p_device
= wil_cfg80211_start_p2p_device
,
1845 .stop_p2p_device
= wil_cfg80211_stop_p2p_device
,
1846 .set_power_mgmt
= wil_cfg80211_set_power_mgmt
,
1847 .suspend
= wil_cfg80211_suspend
,
1848 .resume
= wil_cfg80211_resume
,
1849 .sched_scan_start
= wil_cfg80211_sched_scan_start
,
1850 .sched_scan_stop
= wil_cfg80211_sched_scan_stop
,
1853 static void wil_wiphy_init(struct wiphy
*wiphy
)
1855 wiphy
->max_scan_ssids
= 1;
1856 wiphy
->max_scan_ie_len
= WMI_MAX_IE_LEN
;
1857 wiphy
->max_remain_on_channel_duration
= WIL_MAX_ROC_DURATION_MS
;
1858 wiphy
->max_num_pmkids
= 0 /* TODO: */;
1859 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
1860 BIT(NL80211_IFTYPE_AP
) |
1861 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
1862 BIT(NL80211_IFTYPE_P2P_GO
) |
1863 BIT(NL80211_IFTYPE_P2P_DEVICE
) |
1864 BIT(NL80211_IFTYPE_MONITOR
);
1865 wiphy
->flags
|= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
|
1866 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
|
1867 WIPHY_FLAG_PS_ON_BY_DEFAULT
;
1868 if (!disable_ap_sme
)
1869 wiphy
->flags
|= WIPHY_FLAG_HAVE_AP_SME
;
1870 dev_dbg(wiphy_dev(wiphy
), "%s : flags = 0x%08x\n",
1871 __func__
, wiphy
->flags
);
1872 wiphy
->probe_resp_offload
=
1873 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS
|
1874 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2
|
1875 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P
;
1877 wiphy
->bands
[NL80211_BAND_60GHZ
] = &wil_band_60ghz
;
1879 /* may change after reading FW capabilities */
1880 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_UNSPEC
;
1882 wiphy
->cipher_suites
= wil_cipher_suites
;
1883 wiphy
->n_cipher_suites
= ARRAY_SIZE(wil_cipher_suites
);
1884 wiphy
->mgmt_stypes
= wil_mgmt_stypes
;
1885 wiphy
->features
|= NL80211_FEATURE_SK_TX_STATUS
;
1887 wiphy
->n_vendor_commands
= ARRAY_SIZE(wil_nl80211_vendor_commands
);
1888 wiphy
->vendor_commands
= wil_nl80211_vendor_commands
;
1891 wiphy
->wowlan
= &wil_wowlan_support
;
1895 struct wireless_dev
*wil_cfg80211_init(struct device
*dev
)
1898 struct wireless_dev
*wdev
;
1900 dev_dbg(dev
, "%s()\n", __func__
);
1902 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
1904 return ERR_PTR(-ENOMEM
);
1906 wdev
->wiphy
= wiphy_new(&wil_cfg80211_ops
,
1907 sizeof(struct wil6210_priv
));
1913 set_wiphy_dev(wdev
->wiphy
, dev
);
1914 wil_wiphy_init(wdev
->wiphy
);
1924 void wil_wdev_free(struct wil6210_priv
*wil
)
1926 struct wireless_dev
*wdev
= wil_to_wdev(wil
);
1928 dev_dbg(wil_to_dev(wil
), "%s()\n", __func__
);
1933 wiphy_free(wdev
->wiphy
);
1937 void wil_p2p_wdev_free(struct wil6210_priv
*wil
)
1939 struct wireless_dev
*p2p_wdev
;
1941 mutex_lock(&wil
->p2p_wdev_mutex
);
1942 p2p_wdev
= wil
->p2p_wdev
;
1943 wil
->p2p_wdev
= NULL
;
1944 wil
->radio_wdev
= wil_to_wdev(wil
);
1945 mutex_unlock(&wil
->p2p_wdev_mutex
);
1947 cfg80211_unregister_wdev(p2p_wdev
);
1952 static int wil_rf_sector_status_to_rc(u8 status
)
1955 case WMI_RF_SECTOR_STATUS_SUCCESS
:
1957 case WMI_RF_SECTOR_STATUS_BAD_PARAMETERS_ERROR
:
1959 case WMI_RF_SECTOR_STATUS_BUSY_ERROR
:
1961 case WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR
:
1968 static int wil_rf_sector_get_cfg(struct wiphy
*wiphy
,
1969 struct wireless_dev
*wdev
,
1970 const void *data
, int data_len
)
1972 struct wil6210_priv
*wil
= wdev_to_wil(wdev
);
1974 struct nlattr
*tb
[QCA_ATTR_DMG_RF_SECTOR_MAX
+ 1];
1978 struct wmi_get_rf_sector_params_cmd cmd
;
1980 struct wmi_cmd_hdr wmi
;
1981 struct wmi_get_rf_sector_params_done_event evt
;
1983 struct sk_buff
*msg
;
1984 struct nlattr
*nl_cfgs
, *nl_cfg
;
1986 struct wmi_rf_sector_info
*si
;
1988 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS
, wil
->fw_capabilities
))
1991 rc
= nla_parse(tb
, QCA_ATTR_DMG_RF_SECTOR_MAX
, data
, data_len
,
1992 wil_rf_sector_policy
, NULL
);
1994 wil_err(wil
, "Invalid rf sector ATTR\n");
1998 if (!tb
[QCA_ATTR_DMG_RF_SECTOR_INDEX
] ||
1999 !tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
] ||
2000 !tb
[QCA_ATTR_DMG_RF_MODULE_MASK
]) {
2001 wil_err(wil
, "Invalid rf sector spec\n");
2005 sector_index
= nla_get_u16(
2006 tb
[QCA_ATTR_DMG_RF_SECTOR_INDEX
]);
2007 if (sector_index
>= WIL_MAX_RF_SECTORS
) {
2008 wil_err(wil
, "Invalid sector index %d\n", sector_index
);
2012 sector_type
= nla_get_u8(tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
]);
2013 if (sector_type
>= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
) {
2014 wil_err(wil
, "Invalid sector type %d\n", sector_type
);
2018 rf_modules_vec
= nla_get_u32(
2019 tb
[QCA_ATTR_DMG_RF_MODULE_MASK
]);
2020 if (rf_modules_vec
>= BIT(WMI_MAX_RF_MODULES_NUM
)) {
2021 wil_err(wil
, "Invalid rf module mask 0x%x\n", rf_modules_vec
);
2025 cmd
.sector_idx
= cpu_to_le16(sector_index
);
2026 cmd
.sector_type
= sector_type
;
2027 cmd
.rf_modules_vec
= rf_modules_vec
& 0xFF;
2028 memset(&reply
, 0, sizeof(reply
));
2029 rc
= wmi_call(wil
, WMI_GET_RF_SECTOR_PARAMS_CMDID
, &cmd
, sizeof(cmd
),
2030 WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID
,
2031 &reply
, sizeof(reply
),
2035 if (reply
.evt
.status
) {
2036 wil_err(wil
, "get rf sector cfg failed with status %d\n",
2038 return wil_rf_sector_status_to_rc(reply
.evt
.status
);
2041 msg
= cfg80211_vendor_cmd_alloc_reply_skb(
2042 wiphy
, 64 * WMI_MAX_RF_MODULES_NUM
);
2046 if (nla_put_u64_64bit(msg
, QCA_ATTR_TSF
,
2047 le64_to_cpu(reply
.evt
.tsf
),
2049 goto nla_put_failure
;
2051 nl_cfgs
= nla_nest_start(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG
);
2053 goto nla_put_failure
;
2054 for (i
= 0; i
< WMI_MAX_RF_MODULES_NUM
; i
++) {
2055 if (!(rf_modules_vec
& BIT(i
)))
2057 nl_cfg
= nla_nest_start(msg
, i
);
2059 goto nla_put_failure
;
2060 si
= &reply
.evt
.sectors_info
[i
];
2061 if (nla_put_u8(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX
,
2063 nla_put_u32(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0
,
2064 le32_to_cpu(si
->etype0
)) ||
2065 nla_put_u32(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1
,
2066 le32_to_cpu(si
->etype1
)) ||
2067 nla_put_u32(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2
,
2068 le32_to_cpu(si
->etype2
)) ||
2069 nla_put_u32(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI
,
2070 le32_to_cpu(si
->psh_hi
)) ||
2071 nla_put_u32(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO
,
2072 le32_to_cpu(si
->psh_lo
)) ||
2073 nla_put_u32(msg
, QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16
,
2074 le32_to_cpu(si
->dtype_swch_off
)))
2075 goto nla_put_failure
;
2076 nla_nest_end(msg
, nl_cfg
);
2079 nla_nest_end(msg
, nl_cfgs
);
2080 rc
= cfg80211_vendor_cmd_reply(msg
);
2087 static int wil_rf_sector_set_cfg(struct wiphy
*wiphy
,
2088 struct wireless_dev
*wdev
,
2089 const void *data
, int data_len
)
2091 struct wil6210_priv
*wil
= wdev_to_wil(wdev
);
2093 struct nlattr
*tb
[QCA_ATTR_DMG_RF_SECTOR_MAX
+ 1];
2094 struct nlattr
*tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX
+ 1];
2095 u16 sector_index
, rf_module_index
;
2097 u32 rf_modules_vec
= 0;
2098 struct wmi_set_rf_sector_params_cmd cmd
;
2100 struct wmi_cmd_hdr wmi
;
2101 struct wmi_set_rf_sector_params_done_event evt
;
2103 struct nlattr
*nl_cfg
;
2104 struct wmi_rf_sector_info
*si
;
2106 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS
, wil
->fw_capabilities
))
2109 rc
= nla_parse(tb
, QCA_ATTR_DMG_RF_SECTOR_MAX
, data
, data_len
,
2110 wil_rf_sector_policy
, NULL
);
2112 wil_err(wil
, "Invalid rf sector ATTR\n");
2116 if (!tb
[QCA_ATTR_DMG_RF_SECTOR_INDEX
] ||
2117 !tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
] ||
2118 !tb
[QCA_ATTR_DMG_RF_SECTOR_CFG
]) {
2119 wil_err(wil
, "Invalid rf sector spec\n");
2123 sector_index
= nla_get_u16(
2124 tb
[QCA_ATTR_DMG_RF_SECTOR_INDEX
]);
2125 if (sector_index
>= WIL_MAX_RF_SECTORS
) {
2126 wil_err(wil
, "Invalid sector index %d\n", sector_index
);
2130 sector_type
= nla_get_u8(tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
]);
2131 if (sector_type
>= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
) {
2132 wil_err(wil
, "Invalid sector type %d\n", sector_type
);
2136 memset(&cmd
, 0, sizeof(cmd
));
2138 cmd
.sector_idx
= cpu_to_le16(sector_index
);
2139 cmd
.sector_type
= sector_type
;
2140 nla_for_each_nested(nl_cfg
, tb
[QCA_ATTR_DMG_RF_SECTOR_CFG
],
2142 rc
= nla_parse_nested(tb2
, QCA_ATTR_DMG_RF_SECTOR_CFG_MAX
,
2143 nl_cfg
, wil_rf_sector_cfg_policy
,
2146 wil_err(wil
, "invalid sector cfg\n");
2150 if (!tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX
] ||
2151 !tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0
] ||
2152 !tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1
] ||
2153 !tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2
] ||
2154 !tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI
] ||
2155 !tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO
] ||
2156 !tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16
]) {
2157 wil_err(wil
, "missing cfg params\n");
2161 rf_module_index
= nla_get_u8(
2162 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX
]);
2163 if (rf_module_index
>= WMI_MAX_RF_MODULES_NUM
) {
2164 wil_err(wil
, "invalid RF module index %d\n",
2168 rf_modules_vec
|= BIT(rf_module_index
);
2169 si
= &cmd
.sectors_info
[rf_module_index
];
2170 si
->etype0
= cpu_to_le32(nla_get_u32(
2171 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0
]));
2172 si
->etype1
= cpu_to_le32(nla_get_u32(
2173 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1
]));
2174 si
->etype2
= cpu_to_le32(nla_get_u32(
2175 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2
]));
2176 si
->psh_hi
= cpu_to_le32(nla_get_u32(
2177 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI
]));
2178 si
->psh_lo
= cpu_to_le32(nla_get_u32(
2179 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO
]));
2180 si
->dtype_swch_off
= cpu_to_le32(nla_get_u32(
2181 tb2
[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16
]));
2184 cmd
.rf_modules_vec
= rf_modules_vec
& 0xFF;
2185 memset(&reply
, 0, sizeof(reply
));
2186 rc
= wmi_call(wil
, WMI_SET_RF_SECTOR_PARAMS_CMDID
, &cmd
, sizeof(cmd
),
2187 WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID
,
2188 &reply
, sizeof(reply
),
2192 return wil_rf_sector_status_to_rc(reply
.evt
.status
);
2195 static int wil_rf_sector_get_selected(struct wiphy
*wiphy
,
2196 struct wireless_dev
*wdev
,
2197 const void *data
, int data_len
)
2199 struct wil6210_priv
*wil
= wdev_to_wil(wdev
);
2201 struct nlattr
*tb
[QCA_ATTR_DMG_RF_SECTOR_MAX
+ 1];
2202 u8 sector_type
, mac_addr
[ETH_ALEN
];
2204 struct wmi_get_selected_rf_sector_index_cmd cmd
;
2206 struct wmi_cmd_hdr wmi
;
2207 struct wmi_get_selected_rf_sector_index_done_event evt
;
2209 struct sk_buff
*msg
;
2211 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS
, wil
->fw_capabilities
))
2214 rc
= nla_parse(tb
, QCA_ATTR_DMG_RF_SECTOR_MAX
, data
, data_len
,
2215 wil_rf_sector_policy
, NULL
);
2217 wil_err(wil
, "Invalid rf sector ATTR\n");
2221 if (!tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
]) {
2222 wil_err(wil
, "Invalid rf sector spec\n");
2225 sector_type
= nla_get_u8(tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
]);
2226 if (sector_type
>= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
) {
2227 wil_err(wil
, "Invalid sector type %d\n", sector_type
);
2231 if (tb
[QCA_ATTR_MAC_ADDR
]) {
2232 ether_addr_copy(mac_addr
, nla_data(tb
[QCA_ATTR_MAC_ADDR
]));
2233 cid
= wil_find_cid(wil
, mac_addr
);
2235 wil_err(wil
, "invalid MAC address %pM\n", mac_addr
);
2239 if (test_bit(wil_status_fwconnected
, wil
->status
)) {
2240 wil_err(wil
, "must specify MAC address when connected\n");
2245 memset(&cmd
, 0, sizeof(cmd
));
2247 cmd
.sector_type
= sector_type
;
2248 memset(&reply
, 0, sizeof(reply
));
2249 rc
= wmi_call(wil
, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID
,
2251 WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID
,
2252 &reply
, sizeof(reply
),
2256 if (reply
.evt
.status
) {
2257 wil_err(wil
, "get rf selected sector cfg failed with status %d\n",
2259 return wil_rf_sector_status_to_rc(reply
.evt
.status
);
2262 msg
= cfg80211_vendor_cmd_alloc_reply_skb(
2263 wiphy
, 64 * WMI_MAX_RF_MODULES_NUM
);
2267 if (nla_put_u64_64bit(msg
, QCA_ATTR_TSF
,
2268 le64_to_cpu(reply
.evt
.tsf
),
2270 nla_put_u16(msg
, QCA_ATTR_DMG_RF_SECTOR_INDEX
,
2271 le16_to_cpu(reply
.evt
.sector_idx
)))
2272 goto nla_put_failure
;
2274 rc
= cfg80211_vendor_cmd_reply(msg
);
2281 static int wil_rf_sector_wmi_set_selected(struct wil6210_priv
*wil
,
2283 u8 sector_type
, u8 cid
)
2285 struct wmi_set_selected_rf_sector_index_cmd cmd
;
2287 struct wmi_cmd_hdr wmi
;
2288 struct wmi_set_selected_rf_sector_index_done_event evt
;
2292 memset(&cmd
, 0, sizeof(cmd
));
2293 cmd
.sector_idx
= cpu_to_le16(sector_index
);
2294 cmd
.sector_type
= sector_type
;
2296 memset(&reply
, 0, sizeof(reply
));
2297 rc
= wmi_call(wil
, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID
,
2299 WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID
,
2300 &reply
, sizeof(reply
),
2304 return wil_rf_sector_status_to_rc(reply
.evt
.status
);
2307 static int wil_rf_sector_set_selected(struct wiphy
*wiphy
,
2308 struct wireless_dev
*wdev
,
2309 const void *data
, int data_len
)
2311 struct wil6210_priv
*wil
= wdev_to_wil(wdev
);
2313 struct nlattr
*tb
[QCA_ATTR_DMG_RF_SECTOR_MAX
+ 1];
2315 u8 sector_type
, mac_addr
[ETH_ALEN
], i
;
2318 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS
, wil
->fw_capabilities
))
2321 rc
= nla_parse(tb
, QCA_ATTR_DMG_RF_SECTOR_MAX
, data
, data_len
,
2322 wil_rf_sector_policy
, NULL
);
2324 wil_err(wil
, "Invalid rf sector ATTR\n");
2328 if (!tb
[QCA_ATTR_DMG_RF_SECTOR_INDEX
] ||
2329 !tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
]) {
2330 wil_err(wil
, "Invalid rf sector spec\n");
2334 sector_index
= nla_get_u16(
2335 tb
[QCA_ATTR_DMG_RF_SECTOR_INDEX
]);
2336 if (sector_index
>= WIL_MAX_RF_SECTORS
&&
2337 sector_index
!= WMI_INVALID_RF_SECTOR_INDEX
) {
2338 wil_err(wil
, "Invalid sector index %d\n", sector_index
);
2342 sector_type
= nla_get_u8(tb
[QCA_ATTR_DMG_RF_SECTOR_TYPE
]);
2343 if (sector_type
>= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
) {
2344 wil_err(wil
, "Invalid sector type %d\n", sector_type
);
2348 if (tb
[QCA_ATTR_MAC_ADDR
]) {
2349 ether_addr_copy(mac_addr
, nla_data(tb
[QCA_ATTR_MAC_ADDR
]));
2350 if (!is_broadcast_ether_addr(mac_addr
)) {
2351 cid
= wil_find_cid(wil
, mac_addr
);
2353 wil_err(wil
, "invalid MAC address %pM\n",
2358 if (sector_index
!= WMI_INVALID_RF_SECTOR_INDEX
) {
2359 wil_err(wil
, "broadcast MAC valid only with unlocking\n");
2365 if (test_bit(wil_status_fwconnected
, wil
->status
)) {
2366 wil_err(wil
, "must specify MAC address when connected\n");
2369 /* otherwise, using cid=0 for unassociated station */
2373 rc
= wil_rf_sector_wmi_set_selected(wil
, sector_index
,
2376 /* unlock all cids */
2377 rc
= wil_rf_sector_wmi_set_selected(
2378 wil
, WMI_INVALID_RF_SECTOR_INDEX
, sector_type
,
2380 if (rc
== -EINVAL
) {
2381 for (i
= 0; i
< WIL6210_MAX_CID
; i
++) {
2382 rc
= wil_rf_sector_wmi_set_selected(
2383 wil
, WMI_INVALID_RF_SECTOR_INDEX
,
2385 /* the FW will silently ignore and return
2386 * success for unused cid, so abort the loop
2387 * on any other error
2390 wil_err(wil
, "unlock cid %d failed with status %d\n",