GNU Linux-libre 4.14.332-gnu1
[releases.git] / drivers / net / wireless / ath / wil6210 / cfg80211.c
1 /*
2  * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3  *
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.
7  *
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.
15  */
16
17 #include <linux/etherdevice.h>
18 #include <linux/moduleparam.h>
19 #include <net/netlink.h>
20 #include "wil6210.h"
21 #include "wmi.h"
22
23 #define WIL_MAX_ROC_DURATION_MS 5000
24
25 bool disable_ap_sme;
26 module_param(disable_ap_sme, bool, 0444);
27 MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
28
29 #ifdef CONFIG_PM
30 static struct wiphy_wowlan_support wil_wowlan_support = {
31         .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
32 };
33 #endif
34
35 #define CHAN60G(_channel, _flags) {                             \
36         .band                   = NL80211_BAND_60GHZ,           \
37         .center_freq            = 56160 + (2160 * (_channel)),  \
38         .hw_value               = (_channel),                   \
39         .flags                  = (_flags),                     \
40         .max_antenna_gain       = 0,                            \
41         .max_power              = 40,                           \
42 }
43
44 static struct ieee80211_channel wil_60ghz_channels[] = {
45         CHAN60G(1, 0),
46         CHAN60G(2, 0),
47         CHAN60G(3, 0),
48 /* channel 4 not supported yet */
49 };
50
51 /* Vendor id to be used in vendor specific command and events
52  * to user space.
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
57  */
58
59 #define QCA_NL80211_VENDOR_ID   0x001374
60
61 #define WIL_MAX_RF_SECTORS (128)
62 #define WIL_CID_ALL (0xff)
63
64 enum qca_wlan_vendor_attr_rf_sector {
65         QCA_ATTR_MAC_ADDR = 6,
66         QCA_ATTR_PAD = 13,
67         QCA_ATTR_TSF = 29,
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,
73 };
74
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
79 };
80
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,
90
91         /* keep last */
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
95 };
96
97 static const struct
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 },
104 };
105
106 static const struct
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 },
115 };
116
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,
122 };
123
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);
136
137 /* vendor specific commands */
138 static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
139         {
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
145         },
146         {
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
152         },
153         {
154                 .info.vendor_id = QCA_NL80211_VENDOR_ID,
155                 .info.subcmd =
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
160         },
161         {
162                 .info.vendor_id = QCA_NL80211_VENDOR_ID,
163                 .info.subcmd =
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
168         },
169 };
170
171 static struct ieee80211_supported_band wil_band_60ghz = {
172         .channels = wil_60ghz_channels,
173         .n_channels = ARRAY_SIZE(wil_60ghz_channels),
174         .ht_cap = {
175                 .ht_supported = true,
176                 .cap = 0, /* TODO */
177                 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */
178                 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */
179                 .mcs = {
180                                 /* MCS 1..12 - SC PHY */
181                         .rx_mask = {0xfe, 0x1f}, /* 1..12 */
182                         .tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */
183                 },
184         },
185 };
186
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)
194         },
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)
207         },
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)
213         },
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)
219         },
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)
225         },
226 };
227
228 static const u32 wil_cipher_suites[] = {
229         WLAN_CIPHER_SUITE_GCMP,
230 };
231
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",
236 };
237
238 int wil_iftype_nl2wmi(enum nl80211_iftype type)
239 {
240         static const struct {
241                 enum nl80211_iftype nl;
242                 enum wmi_network_type wmi;
243         } __nl2wmi[] = {
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 */
250         };
251         uint i;
252
253         for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) {
254                 if (__nl2wmi[i].nl == type)
255                         return __nl2wmi[i].wmi;
256         }
257
258         return -EOPNOTSUPP;
259 }
260
261 int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
262                        struct station_info *sinfo)
263 {
264         struct wmi_notify_req_cmd cmd = {
265                 .cid = cid,
266                 .interval_usec = 0,
267         };
268         struct {
269                 struct wmi_cmd_hdr wmi;
270                 struct wmi_notify_req_done_event evt;
271         } __packed reply;
272         struct wil_net_stats *stats = &wil->sta[cid].stats;
273         int rc;
274
275         rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
276                       WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
277         if (rc)
278                 return rc;
279
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,
287                     reply.evt.rssi,
288                     reply.evt.sqi,
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));
296
297         sinfo->generation = wil->sinfo_gen;
298
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);
307
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;
317
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;
323                 else
324                         sinfo->signal = reply.evt.sqi;
325         }
326
327         return rc;
328 }
329
330 static int wil_cfg80211_get_station(struct wiphy *wiphy,
331                                     struct net_device *ndev,
332                                     const u8 *mac, struct station_info *sinfo)
333 {
334         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
335         int rc;
336
337         int cid = wil_find_cid(wil, mac);
338
339         wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid);
340         if (cid < 0)
341                 return cid;
342
343         rc = wil_cid_fill_sinfo(wil, cid, sinfo);
344
345         return rc;
346 }
347
348 /*
349  * Find @idx-th active STA for station dump.
350  */
351 static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx)
352 {
353         int i;
354
355         for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
356                 if (wil->sta[i].status == wil_sta_unused)
357                         continue;
358                 if (idx == 0)
359                         return i;
360                 idx--;
361         }
362
363         return -ENOENT;
364 }
365
366 static int wil_cfg80211_dump_station(struct wiphy *wiphy,
367                                      struct net_device *dev, int idx,
368                                      u8 *mac, struct station_info *sinfo)
369 {
370         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
371         int rc;
372         int cid = wil_find_cid_by_idx(wil, idx);
373
374         if (cid < 0)
375                 return -ENOENT;
376
377         ether_addr_copy(mac, wil->sta[cid].addr);
378         wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid);
379
380         rc = wil_cid_fill_sinfo(wil, cid, sinfo);
381
382         return rc;
383 }
384
385 static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
386                                          struct wireless_dev *wdev)
387 {
388         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
389
390         wil_dbg_misc(wil, "start_p2p_device: entered\n");
391         wil->p2p.p2p_dev_started = 1;
392         return 0;
393 }
394
395 static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
396                                          struct wireless_dev *wdev)
397 {
398         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
399         struct wil_p2p_info *p2p = &wil->p2p;
400
401         if (!p2p->p2p_dev_started)
402                 return;
403
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);
411 }
412
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)
418 {
419         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
420         struct net_device *ndev = wil_to_ndev(wil);
421         struct wireless_dev *p2p_wdev;
422
423         wil_dbg_misc(wil, "add_iface\n");
424
425         if (type != NL80211_IFTYPE_P2P_DEVICE) {
426                 wil_err(wil, "unsupported iftype %d\n", type);
427                 return ERR_PTR(-EINVAL);
428         }
429
430         if (wil->p2p_wdev) {
431                 wil_err(wil, "P2P_DEVICE interface already created\n");
432                 return ERR_PTR(-EINVAL);
433         }
434
435         p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL);
436         if (!p2p_wdev)
437                 return ERR_PTR(-ENOMEM);
438
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);
443
444         wil->p2p_wdev = p2p_wdev;
445
446         return p2p_wdev;
447 }
448
449 static int wil_cfg80211_del_iface(struct wiphy *wiphy,
450                                   struct wireless_dev *wdev)
451 {
452         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
453
454         wil_dbg_misc(wil, "del_iface\n");
455
456         if (wdev != wil->p2p_wdev) {
457                 wil_err(wil, "delete of incorrect interface 0x%p\n", wdev);
458                 return -EINVAL;
459         }
460
461         wil_cfg80211_stop_p2p_device(wiphy, wdev);
462         wil_p2p_wdev_free(wil);
463
464         return 0;
465 }
466
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)
471 {
472         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
473         struct wireless_dev *wdev = wil_to_wdev(wil);
474         int rc;
475
476         wil_dbg_misc(wil, "change_iface: type=%d\n", type);
477
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);
481                 __wil_down(wil);
482                 rc = __wil_up(wil);
483                 mutex_unlock(&wil->mutex);
484
485                 if (rc)
486                         return rc;
487         }
488
489         switch (type) {
490         case NL80211_IFTYPE_STATION:
491         case NL80211_IFTYPE_AP:
492         case NL80211_IFTYPE_P2P_CLIENT:
493         case NL80211_IFTYPE_P2P_GO:
494                 break;
495         case NL80211_IFTYPE_MONITOR:
496                 if (params->flags)
497                         wil->monitor_flags = params->flags;
498                 break;
499         default:
500                 return -EOPNOTSUPP;
501         }
502
503         wdev->iftype = type;
504
505         return 0;
506 }
507
508 static int wil_cfg80211_scan(struct wiphy *wiphy,
509                              struct cfg80211_scan_request *request)
510 {
511         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
512         struct wireless_dev *wdev = request->wdev;
513         struct {
514                 struct wmi_start_scan_cmd cmd;
515                 u16 chnl[4];
516         } __packed cmd;
517         uint i, n;
518         int rc;
519
520         wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
521
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:
527                 break;
528         default:
529                 return -EOPNOTSUPP;
530         }
531
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");
535                 return -EBUSY;
536         }
537
538         mutex_lock(&wil->mutex);
539
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);
544                 rc = -EAGAIN;
545                 goto out;
546         }
547         mutex_unlock(&wil->p2p_wdev_mutex);
548
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");
552                         rc = -EIO;
553                         goto out;
554                 }
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);
560                         if (rc) {
561                                 wil->radio_wdev = wil_to_wdev(wil);
562                                 wil->scan_request = NULL;
563                         }
564                         goto out;
565                 }
566         }
567
568         (void)wil_p2p_stop_discovery(wil);
569
570         wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
571         wil_dbg_misc(wil, "SSID count: %d", request->n_ssids);
572
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);
578         }
579
580         if (request->n_ssids)
581                 rc = wmi_set_ssid(wil, request->ssids[0].ssid_len,
582                                   request->ssids[0].ssid);
583         else
584                 rc = wmi_set_ssid(wil, 0, NULL);
585
586         if (rc) {
587                 wil_err(wil, "set SSID for scan request failed: %d\n", rc);
588                 goto out;
589         }
590
591         wil->scan_request = request;
592         mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
593
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;
600
601                 if (ch == 0) {
602                         wil_err(wil,
603                                 "Scan requested for unknown frequency %dMhz\n",
604                                 request->channels[i]->center_freq);
605                         continue;
606                 }
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);
611         }
612
613         if (request->ie_len)
614                 wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET, 16, 1,
615                                   request->ie, request->ie_len, true);
616         else
617                 wil_dbg_misc(wil, "Scan has no IE's\n");
618
619         rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
620         if (rc)
621                 goto out_restore;
622
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");
626         }
627
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]));
631
632 out_restore:
633         if (rc) {
634                 del_timer_sync(&wil->scan_timer);
635                 wil->radio_wdev = wil_to_wdev(wil);
636                 wil->scan_request = NULL;
637         }
638 out:
639         mutex_unlock(&wil->mutex);
640         return rc;
641 }
642
643 static void wil_cfg80211_abort_scan(struct wiphy *wiphy,
644                                     struct wireless_dev *wdev)
645 {
646         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
647
648         wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
649
650         mutex_lock(&wil->mutex);
651         mutex_lock(&wil->p2p_wdev_mutex);
652
653         if (!wil->scan_request)
654                 goto out;
655
656         if (wdev != wil->scan_request->wdev) {
657                 wil_dbg_misc(wil, "abort scan was called on the wrong iface\n");
658                 goto out;
659         }
660
661         if (wil->radio_wdev == wil->p2p_wdev)
662                 wil_p2p_stop_radio_operations(wil);
663         else
664                 wil_abort_scan(wil, true);
665
666 out:
667         mutex_unlock(&wil->p2p_wdev_mutex);
668         mutex_unlock(&wil->mutex);
669 }
670
671 static void wil_print_crypto(struct wil6210_priv *wil,
672                              struct cfg80211_crypto_settings *c)
673 {
674         int i, n;
675
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,
688                              c->akm_suites[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);
693 }
694
695 static void wil_print_connect_params(struct wil6210_priv *wil,
696                                      struct cfg80211_connect_params *sme)
697 {
698         wil_info(wil, "Connecting to:\n");
699         if (sme->channel) {
700                 wil_info(wil, "  Channel: %d freq %d\n",
701                          sme->channel->hw_value, sme->channel->center_freq);
702         }
703         if (sme->bssid)
704                 wil_info(wil, "  BSSID: %pM\n", sme->bssid);
705         if (sme->ssid)
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);
711 }
712
713 static int wil_cfg80211_connect(struct wiphy *wiphy,
714                                 struct net_device *ndev,
715                                 struct cfg80211_connect_params *sme)
716 {
717         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
718         struct cfg80211_bss *bss;
719         struct wmi_connect_cmd conn;
720         const u8 *ssid_eid;
721         const u8 *rsn_eid;
722         int ch;
723         int rc = 0;
724         enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
725
726         wil_dbg_misc(wil, "connect\n");
727         wil_print_connect_params(wil, sme);
728
729         if (test_bit(wil_status_fwconnecting, wil->status) ||
730             test_bit(wil_status_fwconnected, wil->status))
731                 return -EALREADY;
732
733         if (sme->ie_len > WMI_MAX_IE_LEN) {
734                 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
735                 return -ERANGE;
736         }
737
738         rsn_eid = sme->ie ?
739                         cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
740                         NULL;
741         if (sme->privacy && !rsn_eid)
742                 wil_info(wil, "WSC connection\n");
743
744         if (sme->pbss)
745                 bss_type = IEEE80211_BSS_TYPE_PBSS;
746
747         bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
748                                sme->ssid, sme->ssid_len,
749                                bss_type, IEEE80211_PRIVACY_ANY);
750         if (!bss) {
751                 wil_err(wil, "Unable to find BSS\n");
752                 return -ENOENT;
753         }
754
755         ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
756         if (!ssid_eid) {
757                 wil_err(wil, "No SSID\n");
758                 rc = -ENOENT;
759                 goto out;
760         }
761         wil->privacy = sme->privacy;
762         wil->pbss = sme->pbss;
763
764         if (wil->privacy) {
765                 /* For secure assoc, remove old keys */
766                 rc = wmi_del_cipher_key(wil, 0, bss->bssid,
767                                         WMI_KEY_USE_PAIRWISE);
768                 if (rc) {
769                         wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n");
770                         goto out;
771                 }
772                 rc = wmi_del_cipher_key(wil, 0, bss->bssid,
773                                         WMI_KEY_USE_RX_GROUP);
774                 if (rc) {
775                         wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n");
776                         goto out;
777                 }
778         }
779
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
782          * ies in FW.
783          */
784         rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
785         if (rc)
786                 goto out;
787
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;
793                 break;
794         case WLAN_CAPABILITY_DMG_TYPE_PBSS:
795                 conn.network_type = WMI_NETTYPE_P2P;
796                 break;
797         default:
798                 wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
799                         bss->capability);
800                 goto out;
801         }
802         if (wil->privacy) {
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;
810                 } else { /* WSC */
811                         conn.dot11_auth_mode = WMI_AUTH11_WSC;
812                         conn.auth_mode = WMI_AUTH_NONE;
813                 }
814         } else { /* insecure connection */
815                 conn.dot11_auth_mode = WMI_AUTH11_OPEN;
816                 conn.auth_mode = WMI_AUTH_NONE;
817         }
818
819         conn.ssid_len = min_t(u8, ssid_eid[1], 32);
820         memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
821
822         ch = bss->channel->hw_value;
823         if (ch == 0) {
824                 wil_err(wil, "BSS at unknown frequency %dMhz\n",
825                         bss->channel->center_freq);
826                 rc = -EOPNOTSUPP;
827                 goto out;
828         }
829         conn.channel = ch - 1;
830
831         ether_addr_copy(conn.bssid, bss->bssid);
832         ether_addr_copy(conn.dst_mac, bss->bssid);
833
834         set_bit(wil_status_fwconnecting, wil->status);
835
836         rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
837         if (rc == 0) {
838                 netif_carrier_on(ndev);
839                 wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
840                 wil->bss = bss;
841                 /* Connect can take lots of time */
842                 mod_timer(&wil->connect_timer,
843                           jiffies + msecs_to_jiffies(5000));
844         } else {
845                 clear_bit(wil_status_fwconnecting, wil->status);
846         }
847
848  out:
849         cfg80211_put_bss(wiphy, bss);
850
851         return rc;
852 }
853
854 static int wil_cfg80211_disconnect(struct wiphy *wiphy,
855                                    struct net_device *ndev,
856                                    u16 reason_code)
857 {
858         int rc;
859         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
860
861         wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code);
862
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");
866                 return 0;
867         }
868
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);
873         if (rc)
874                 wil_err(wil, "disconnect error %d\n", rc);
875
876         return rc;
877 }
878
879 static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
880 {
881         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
882         int rc;
883
884         /* these parameters are explicitly not supported */
885         if (changed & (WIPHY_PARAM_RETRY_LONG |
886                        WIPHY_PARAM_FRAG_THRESHOLD |
887                        WIPHY_PARAM_RTS_THRESHOLD))
888                 return -ENOTSUPP;
889
890         if (changed & WIPHY_PARAM_RETRY_SHORT) {
891                 rc = wmi_set_mgmt_retry(wil, wiphy->retry_short);
892                 if (rc)
893                         return rc;
894         }
895
896         return 0;
897 }
898
899 int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
900                          struct cfg80211_mgmt_tx_params *params,
901                          u64 *cookie)
902 {
903         const u8 *buf = params->buf;
904         size_t len = params->len;
905         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
906         int rc;
907         bool tx_status = false;
908         struct ieee80211_mgmt *mgmt_frame = (void *)buf;
909         struct wmi_sw_tx_req_cmd *cmd;
910         struct {
911                 struct wmi_cmd_hdr wmi;
912                 struct wmi_sw_tx_complete_event evt;
913         } __packed evt;
914
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.
920          */
921
922         wil_dbg_misc(wil, "mgmt_tx\n");
923         wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
924                           len, true);
925
926         if (len < sizeof(struct ieee80211_hdr_3addr))
927                 return -EINVAL;
928
929         cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
930         if (!cmd) {
931                 rc = -ENOMEM;
932                 goto out;
933         }
934
935         memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
936         cmd->len = cpu_to_le16(len);
937         memcpy(cmd->payload, buf, len);
938
939         rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
940                       WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
941         if (rc == 0)
942                 tx_status = !evt.evt.status;
943
944         kfree(cmd);
945  out:
946         cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
947                                 tx_status, GFP_KERNEL);
948         return rc;
949 }
950
951 static int wil_cfg80211_set_channel(struct wiphy *wiphy,
952                                     struct cfg80211_chan_def *chandef)
953 {
954         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
955         struct wireless_dev *wdev = wil_to_wdev(wil);
956
957         wdev->preset_chandef = *chandef;
958
959         return 0;
960 }
961
962 static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
963                                                bool pairwise)
964 {
965         struct wireless_dev *wdev = wil_to_wdev(wil);
966         enum wmi_key_usage rc;
967
968         if (pairwise) {
969                 rc = WMI_KEY_USE_PAIRWISE;
970         } else {
971                 switch (wdev->iftype) {
972                 case NL80211_IFTYPE_STATION:
973                 case NL80211_IFTYPE_P2P_CLIENT:
974                         rc = WMI_KEY_USE_RX_GROUP;
975                         break;
976                 case NL80211_IFTYPE_AP:
977                 case NL80211_IFTYPE_P2P_GO:
978                         rc = WMI_KEY_USE_TX_GROUP;
979                         break;
980                 default:
981                         /* TODO: Rx GTK or Tx GTK? */
982                         wil_err(wil, "Can't determine GTK type\n");
983                         rc = WMI_KEY_USE_RX_GROUP;
984                         break;
985                 }
986         }
987         wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]);
988
989         return rc;
990 }
991
992 static struct wil_sta_info *
993 wil_find_sta_by_key_usage(struct wil6210_priv *wil,
994                           enum wmi_key_usage key_usage, const u8 *mac_addr)
995 {
996         int cid = -EINVAL;
997
998         if (key_usage == WMI_KEY_USE_TX_GROUP)
999                 return NULL; /* not needed */
1000
1001         /* supplicant provides Rx group key in STA mode with NULL MAC address */
1002         if (mac_addr)
1003                 cid = wil_find_cid(wil, mac_addr);
1004         else if (key_usage == WMI_KEY_USE_RX_GROUP)
1005                 cid = wil_find_cid_by_idx(wil, 0);
1006         if (cid < 0) {
1007                 wil_err(wil, "No CID for %pM %s\n", mac_addr,
1008                         key_usage_str[key_usage]);
1009                 return ERR_PTR(cid);
1010         }
1011
1012         return &wil->sta[cid];
1013 }
1014
1015 static void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
1016                               struct wil_sta_info *cs,
1017                               struct key_params *params)
1018 {
1019         struct wil_tid_crypto_rx_single *cc;
1020         int tid;
1021
1022         if (!cs)
1023                 return;
1024
1025         switch (key_usage) {
1026         case WMI_KEY_USE_PAIRWISE:
1027                 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
1028                         cc = &cs->tid_crypto_rx[tid].key_id[key_index];
1029                         if (params->seq)
1030                                 memcpy(cc->pn, params->seq,
1031                                        IEEE80211_GCMP_PN_LEN);
1032                         else
1033                                 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
1034                         cc->key_set = true;
1035                 }
1036                 break;
1037         case WMI_KEY_USE_RX_GROUP:
1038                 cc = &cs->group_crypto_rx.key_id[key_index];
1039                 if (params->seq)
1040                         memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
1041                 else
1042                         memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
1043                 cc->key_set = true;
1044                 break;
1045         default:
1046                 break;
1047         }
1048 }
1049
1050 static void wil_del_rx_key(u8 key_index, enum wmi_key_usage key_usage,
1051                            struct wil_sta_info *cs)
1052 {
1053         struct wil_tid_crypto_rx_single *cc;
1054         int tid;
1055
1056         if (!cs)
1057                 return;
1058
1059         switch (key_usage) {
1060         case WMI_KEY_USE_PAIRWISE:
1061                 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
1062                         cc = &cs->tid_crypto_rx[tid].key_id[key_index];
1063                         cc->key_set = false;
1064                 }
1065                 break;
1066         case WMI_KEY_USE_RX_GROUP:
1067                 cc = &cs->group_crypto_rx.key_id[key_index];
1068                 cc->key_set = false;
1069                 break;
1070         default:
1071                 break;
1072         }
1073 }
1074
1075 static int wil_cfg80211_add_key(struct wiphy *wiphy,
1076                                 struct net_device *ndev,
1077                                 u8 key_index, bool pairwise,
1078                                 const u8 *mac_addr,
1079                                 struct key_params *params)
1080 {
1081         int rc;
1082         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1083         enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
1084         struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
1085                                                             mac_addr);
1086
1087         if (!params) {
1088                 wil_err(wil, "NULL params\n");
1089                 return -EINVAL;
1090         }
1091
1092         wil_dbg_misc(wil, "add_key: %pM %s[%d] PN %*phN\n",
1093                      mac_addr, key_usage_str[key_usage], key_index,
1094                      params->seq_len, params->seq);
1095
1096         if (IS_ERR(cs)) {
1097                 wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
1098                         mac_addr, key_usage_str[key_usage], key_index,
1099                         params->seq_len, params->seq);
1100                 return -EINVAL;
1101         }
1102
1103         wil_del_rx_key(key_index, key_usage, cs);
1104
1105         if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
1106                 wil_err(wil,
1107                         "Wrong PN len %d, %pM %s[%d] PN %*phN\n",
1108                         params->seq_len, mac_addr,
1109                         key_usage_str[key_usage], key_index,
1110                         params->seq_len, params->seq);
1111                 return -EINVAL;
1112         }
1113
1114         rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len,
1115                                 params->key, key_usage);
1116         if (!rc)
1117                 wil_set_crypto_rx(key_index, key_usage, cs, params);
1118
1119         return rc;
1120 }
1121
1122 static int wil_cfg80211_del_key(struct wiphy *wiphy,
1123                                 struct net_device *ndev,
1124                                 u8 key_index, bool pairwise,
1125                                 const u8 *mac_addr)
1126 {
1127         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1128         enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
1129         struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
1130                                                             mac_addr);
1131
1132         wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
1133                      key_usage_str[key_usage], key_index);
1134
1135         if (IS_ERR(cs))
1136                 wil_info(wil, "Not connected, %pM %s[%d]\n",
1137                          mac_addr, key_usage_str[key_usage], key_index);
1138
1139         if (!IS_ERR_OR_NULL(cs))
1140                 wil_del_rx_key(key_index, key_usage, cs);
1141
1142         return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage);
1143 }
1144
1145 /* Need to be present or wiphy_new() will WARN */
1146 static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
1147                                         struct net_device *ndev,
1148                                         u8 key_index, bool unicast,
1149                                         bool multicast)
1150 {
1151         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1152
1153         wil_dbg_misc(wil, "set_default_key: entered\n");
1154         return 0;
1155 }
1156
1157 static int wil_remain_on_channel(struct wiphy *wiphy,
1158                                  struct wireless_dev *wdev,
1159                                  struct ieee80211_channel *chan,
1160                                  unsigned int duration,
1161                                  u64 *cookie)
1162 {
1163         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1164         int rc;
1165
1166         wil_dbg_misc(wil,
1167                      "remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
1168                      chan->center_freq, duration, wdev->iftype);
1169
1170         rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
1171         return rc;
1172 }
1173
1174 static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
1175                                         struct wireless_dev *wdev,
1176                                         u64 cookie)
1177 {
1178         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1179
1180         wil_dbg_misc(wil, "cancel_remain_on_channel\n");
1181
1182         return wil_p2p_cancel_listen(wil, cookie);
1183 }
1184
1185 /**
1186  * find a specific IE in a list of IEs
1187  * return a pointer to the beginning of IE in the list
1188  * or NULL if not found
1189  */
1190 static const u8 *_wil_cfg80211_find_ie(const u8 *ies, u16 ies_len, const u8 *ie,
1191                                        u16 ie_len)
1192 {
1193         struct ieee80211_vendor_ie *vie;
1194         u32 oui;
1195
1196         /* IE tag at offset 0, length at offset 1 */
1197         if (ie_len < 2 || 2 + ie[1] > ie_len)
1198                 return NULL;
1199
1200         if (ie[0] != WLAN_EID_VENDOR_SPECIFIC)
1201                 return cfg80211_find_ie(ie[0], ies, ies_len);
1202
1203         /* make sure there is room for 3 bytes OUI + 1 byte OUI type */
1204         if (ie[1] < 4)
1205                 return NULL;
1206         vie = (struct ieee80211_vendor_ie *)ie;
1207         oui = vie->oui[0] << 16 | vie->oui[1] << 8 | vie->oui[2];
1208         return cfg80211_find_vendor_ie(oui, vie->oui_type, ies,
1209                                        ies_len);
1210 }
1211
1212 /**
1213  * merge the IEs in two lists into a single list.
1214  * do not include IEs from the second list which exist in the first list.
1215  * add only vendor specific IEs from second list to keep
1216  * the merged list sorted (since vendor-specific IE has the
1217  * highest tag number)
1218  * caller must free the allocated memory for merged IEs
1219  */
1220 static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len,
1221                                          const u8 *ies2, u16 ies2_len,
1222                                          u8 **merged_ies, u16 *merged_len)
1223 {
1224         u8 *buf, *dpos;
1225         const u8 *spos;
1226
1227         if (!ies1)
1228                 ies1_len = 0;
1229
1230         if (!ies2)
1231                 ies2_len = 0;
1232
1233         if (ies1_len == 0 && ies2_len == 0) {
1234                 *merged_ies = NULL;
1235                 *merged_len = 0;
1236                 return 0;
1237         }
1238
1239         buf = kmalloc(ies1_len + ies2_len, GFP_KERNEL);
1240         if (!buf)
1241                 return -ENOMEM;
1242         if (ies1)
1243                 memcpy(buf, ies1, ies1_len);
1244         dpos = buf + ies1_len;
1245         spos = ies2;
1246         while (spos && (spos + 1 < ies2 + ies2_len)) {
1247                 /* IE tag at offset 0, length at offset 1 */
1248                 u16 ielen = 2 + spos[1];
1249
1250                 if (spos + ielen > ies2 + ies2_len)
1251                         break;
1252                 if (spos[0] == WLAN_EID_VENDOR_SPECIFIC &&
1253                     (!ies1 || !_wil_cfg80211_find_ie(ies1, ies1_len,
1254                                                      spos, ielen))) {
1255                         memcpy(dpos, spos, ielen);
1256                         dpos += ielen;
1257                 }
1258                 spos += ielen;
1259         }
1260
1261         *merged_ies = buf;
1262         *merged_len = dpos - buf;
1263         return 0;
1264 }
1265
1266 static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
1267 {
1268         wil_hex_dump_misc("head     ", DUMP_PREFIX_OFFSET, 16, 1,
1269                           b->head, b->head_len, true);
1270         wil_hex_dump_misc("tail     ", DUMP_PREFIX_OFFSET, 16, 1,
1271                           b->tail, b->tail_len, true);
1272         wil_hex_dump_misc("BCON IE  ", DUMP_PREFIX_OFFSET, 16, 1,
1273                           b->beacon_ies, b->beacon_ies_len, true);
1274         wil_hex_dump_misc("PROBE    ", DUMP_PREFIX_OFFSET, 16, 1,
1275                           b->probe_resp, b->probe_resp_len, true);
1276         wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET, 16, 1,
1277                           b->proberesp_ies, b->proberesp_ies_len, true);
1278         wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1,
1279                           b->assocresp_ies, b->assocresp_ies_len, true);
1280 }
1281
1282 /* internal functions for device reset and starting AP */
1283 static int _wil_cfg80211_set_ies(struct wiphy *wiphy,
1284                                  struct cfg80211_beacon_data *bcon)
1285 {
1286         int rc;
1287         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1288         u16 len = 0, proberesp_len = 0;
1289         u8 *ies = NULL, *proberesp = NULL;
1290
1291         if (bcon->probe_resp) {
1292                 struct ieee80211_mgmt *f =
1293                         (struct ieee80211_mgmt *)bcon->probe_resp;
1294                 size_t hlen = offsetof(struct ieee80211_mgmt,
1295                                        u.probe_resp.variable);
1296                 proberesp = f->u.probe_resp.variable;
1297                 proberesp_len = bcon->probe_resp_len - hlen;
1298         }
1299         rc = _wil_cfg80211_merge_extra_ies(proberesp,
1300                                            proberesp_len,
1301                                            bcon->proberesp_ies,
1302                                            bcon->proberesp_ies_len,
1303                                            &ies, &len);
1304
1305         if (rc)
1306                 goto out;
1307
1308         rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, len, ies);
1309         if (rc)
1310                 goto out;
1311
1312         if (bcon->assocresp_ies)
1313                 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP,
1314                                 bcon->assocresp_ies_len, bcon->assocresp_ies);
1315         else
1316                 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, len, ies);
1317 #if 0 /* to use beacon IE's, remove this #if 0 */
1318         if (rc)
1319                 goto out;
1320
1321         rc = wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->tail_len, bcon->tail);
1322 #endif
1323 out:
1324         kfree(ies);
1325         return rc;
1326 }
1327
1328 static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1329                                   struct net_device *ndev,
1330                                   const u8 *ssid, size_t ssid_len, u32 privacy,
1331                                   int bi, u8 chan,
1332                                   struct cfg80211_beacon_data *bcon,
1333                                   u8 hidden_ssid, u32 pbss)
1334 {
1335         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1336         int rc;
1337         struct wireless_dev *wdev = ndev->ieee80211_ptr;
1338         u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
1339         u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO);
1340
1341         if (pbss)
1342                 wmi_nettype = WMI_NETTYPE_P2P;
1343
1344         wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go);
1345         if (is_go && !pbss) {
1346                 wil_err(wil, "P2P GO must be in PBSS\n");
1347                 return -ENOTSUPP;
1348         }
1349
1350         wil_set_recovery_state(wil, fw_recovery_idle);
1351
1352         mutex_lock(&wil->mutex);
1353
1354         __wil_down(wil);
1355         rc = __wil_up(wil);
1356         if (rc)
1357                 goto out;
1358
1359         rc = wmi_set_ssid(wil, ssid_len, ssid);
1360         if (rc)
1361                 goto out;
1362
1363         rc = _wil_cfg80211_set_ies(wiphy, bcon);
1364         if (rc)
1365                 goto out;
1366
1367         wil->privacy = privacy;
1368         wil->channel = chan;
1369         wil->hidden_ssid = hidden_ssid;
1370         wil->pbss = pbss;
1371
1372         netif_carrier_on(ndev);
1373         wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
1374
1375         rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go);
1376         if (rc)
1377                 goto err_pcp_start;
1378
1379         rc = wil_bcast_init(wil);
1380         if (rc)
1381                 goto err_bcast;
1382
1383         goto out; /* success */
1384
1385 err_bcast:
1386         wmi_pcp_stop(wil);
1387 err_pcp_start:
1388         netif_carrier_off(ndev);
1389         wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
1390 out:
1391         mutex_unlock(&wil->mutex);
1392         return rc;
1393 }
1394
1395 static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
1396                                       struct net_device *ndev,
1397                                       struct cfg80211_beacon_data *bcon)
1398 {
1399         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1400         int rc;
1401         u32 privacy = 0;
1402
1403         wil_dbg_misc(wil, "change_beacon\n");
1404         wil_print_bcon_data(bcon);
1405
1406         if (bcon->tail &&
1407             cfg80211_find_ie(WLAN_EID_RSN, bcon->tail,
1408                              bcon->tail_len))
1409                 privacy = 1;
1410
1411         /* in case privacy has changed, need to restart the AP */
1412         if (wil->privacy != privacy) {
1413                 struct wireless_dev *wdev = ndev->ieee80211_ptr;
1414
1415                 wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n",
1416                              wil->privacy, privacy);
1417
1418                 rc = _wil_cfg80211_start_ap(wiphy, ndev, wdev->ssid,
1419                                             wdev->ssid_len, privacy,
1420                                             wdev->beacon_interval,
1421                                             wil->channel, bcon,
1422                                             wil->hidden_ssid,
1423                                             wil->pbss);
1424         } else {
1425                 rc = _wil_cfg80211_set_ies(wiphy, bcon);
1426         }
1427
1428         return rc;
1429 }
1430
1431 static int wil_cfg80211_start_ap(struct wiphy *wiphy,
1432                                  struct net_device *ndev,
1433                                  struct cfg80211_ap_settings *info)
1434 {
1435         int rc;
1436         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1437         struct ieee80211_channel *channel = info->chandef.chan;
1438         struct cfg80211_beacon_data *bcon = &info->beacon;
1439         struct cfg80211_crypto_settings *crypto = &info->crypto;
1440         u8 hidden_ssid;
1441
1442         wil_dbg_misc(wil, "start_ap\n");
1443
1444         if (!channel) {
1445                 wil_err(wil, "AP: No channel???\n");
1446                 return -EINVAL;
1447         }
1448
1449         switch (info->hidden_ssid) {
1450         case NL80211_HIDDEN_SSID_NOT_IN_USE:
1451                 hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
1452                 break;
1453
1454         case NL80211_HIDDEN_SSID_ZERO_LEN:
1455                 hidden_ssid = WMI_HIDDEN_SSID_SEND_EMPTY;
1456                 break;
1457
1458         case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
1459                 hidden_ssid = WMI_HIDDEN_SSID_CLEAR;
1460                 break;
1461
1462         default:
1463                 wil_err(wil, "AP: Invalid hidden SSID %d\n", info->hidden_ssid);
1464                 return -EOPNOTSUPP;
1465         }
1466         wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
1467                      channel->center_freq, info->privacy ? "secure" : "open");
1468         wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
1469                      info->privacy, info->auth_type);
1470         wil_dbg_misc(wil, "Hidden SSID mode: %d\n",
1471                      info->hidden_ssid);
1472         wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
1473                      info->dtim_period);
1474         wil_dbg_misc(wil, "PBSS %d\n", info->pbss);
1475         wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
1476                           info->ssid, info->ssid_len, true);
1477         wil_print_bcon_data(bcon);
1478         wil_print_crypto(wil, crypto);
1479
1480         rc = _wil_cfg80211_start_ap(wiphy, ndev,
1481                                     info->ssid, info->ssid_len, info->privacy,
1482                                     info->beacon_interval, channel->hw_value,
1483                                     bcon, hidden_ssid, info->pbss);
1484
1485         return rc;
1486 }
1487
1488 static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
1489                                 struct net_device *ndev)
1490 {
1491         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1492
1493         wil_dbg_misc(wil, "stop_ap\n");
1494
1495         netif_carrier_off(ndev);
1496         wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
1497         wil_set_recovery_state(wil, fw_recovery_idle);
1498
1499         set_bit(wil_status_resetting, wil->status);
1500
1501         mutex_lock(&wil->mutex);
1502
1503         wmi_pcp_stop(wil);
1504
1505         __wil_down(wil);
1506
1507         mutex_unlock(&wil->mutex);
1508
1509         return 0;
1510 }
1511
1512 static int wil_cfg80211_add_station(struct wiphy *wiphy,
1513                                     struct net_device *dev,
1514                                     const u8 *mac,
1515                                     struct station_parameters *params)
1516 {
1517         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1518
1519         wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid);
1520
1521         if (!disable_ap_sme) {
1522                 wil_err(wil, "not supported with AP SME enabled\n");
1523                 return -EOPNOTSUPP;
1524         }
1525
1526         if (params->aid > WIL_MAX_DMG_AID) {
1527                 wil_err(wil, "invalid aid\n");
1528                 return -EINVAL;
1529         }
1530
1531         return wmi_new_sta(wil, mac, params->aid);
1532 }
1533
1534 static int wil_cfg80211_del_station(struct wiphy *wiphy,
1535                                     struct net_device *dev,
1536                                     struct station_del_parameters *params)
1537 {
1538         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1539
1540         wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac,
1541                      params->reason_code);
1542
1543         mutex_lock(&wil->mutex);
1544         wil6210_disconnect(wil, params->mac, params->reason_code, false);
1545         mutex_unlock(&wil->mutex);
1546
1547         return 0;
1548 }
1549
1550 static int wil_cfg80211_change_station(struct wiphy *wiphy,
1551                                        struct net_device *dev,
1552                                        const u8 *mac,
1553                                        struct station_parameters *params)
1554 {
1555         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1556         int authorize;
1557         int cid, i;
1558         struct vring_tx_data *txdata = NULL;
1559
1560         wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac,
1561                      params->sta_flags_mask, params->sta_flags_set);
1562
1563         if (!disable_ap_sme) {
1564                 wil_dbg_misc(wil, "not supported with AP SME enabled\n");
1565                 return -EOPNOTSUPP;
1566         }
1567
1568         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1569                 return 0;
1570
1571         cid = wil_find_cid(wil, mac);
1572         if (cid < 0) {
1573                 wil_err(wil, "station not found\n");
1574                 return -ENOLINK;
1575         }
1576
1577         for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
1578                 if (wil->vring2cid_tid[i][0] == cid) {
1579                         txdata = &wil->vring_tx_data[i];
1580                         break;
1581                 }
1582
1583         if (!txdata) {
1584                 wil_err(wil, "vring data not found\n");
1585                 return -ENOLINK;
1586         }
1587
1588         authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
1589         txdata->dot1x_open = authorize ? 1 : 0;
1590         wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
1591                      txdata->dot1x_open);
1592
1593         return 0;
1594 }
1595
1596 /* probe_client handling */
1597 static void wil_probe_client_handle(struct wil6210_priv *wil,
1598                                     struct wil_probe_client_req *req)
1599 {
1600         struct net_device *ndev = wil_to_ndev(wil);
1601         struct wil_sta_info *sta = &wil->sta[req->cid];
1602         /* assume STA is alive if it is still connected,
1603          * else FW will disconnect it
1604          */
1605         bool alive = (sta->status == wil_sta_connected);
1606
1607         cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, GFP_KERNEL);
1608 }
1609
1610 static struct list_head *next_probe_client(struct wil6210_priv *wil)
1611 {
1612         struct list_head *ret = NULL;
1613
1614         mutex_lock(&wil->probe_client_mutex);
1615
1616         if (!list_empty(&wil->probe_client_pending)) {
1617                 ret = wil->probe_client_pending.next;
1618                 list_del(ret);
1619         }
1620
1621         mutex_unlock(&wil->probe_client_mutex);
1622
1623         return ret;
1624 }
1625
1626 void wil_probe_client_worker(struct work_struct *work)
1627 {
1628         struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
1629                                                 probe_client_worker);
1630         struct wil_probe_client_req *req;
1631         struct list_head *lh;
1632
1633         while ((lh = next_probe_client(wil)) != NULL) {
1634                 req = list_entry(lh, struct wil_probe_client_req, list);
1635
1636                 wil_probe_client_handle(wil, req);
1637                 kfree(req);
1638         }
1639 }
1640
1641 void wil_probe_client_flush(struct wil6210_priv *wil)
1642 {
1643         struct wil_probe_client_req *req, *t;
1644
1645         wil_dbg_misc(wil, "probe_client_flush\n");
1646
1647         mutex_lock(&wil->probe_client_mutex);
1648
1649         list_for_each_entry_safe(req, t, &wil->probe_client_pending, list) {
1650                 list_del(&req->list);
1651                 kfree(req);
1652         }
1653
1654         mutex_unlock(&wil->probe_client_mutex);
1655 }
1656
1657 static int wil_cfg80211_probe_client(struct wiphy *wiphy,
1658                                      struct net_device *dev,
1659                                      const u8 *peer, u64 *cookie)
1660 {
1661         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1662         struct wil_probe_client_req *req;
1663         int cid = wil_find_cid(wil, peer);
1664
1665         wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid);
1666
1667         if (cid < 0)
1668                 return -ENOLINK;
1669
1670         req = kzalloc(sizeof(*req), GFP_KERNEL);
1671         if (!req)
1672                 return -ENOMEM;
1673
1674         req->cid = cid;
1675         req->cookie = cid;
1676
1677         mutex_lock(&wil->probe_client_mutex);
1678         list_add_tail(&req->list, &wil->probe_client_pending);
1679         mutex_unlock(&wil->probe_client_mutex);
1680
1681         *cookie = req->cookie;
1682         queue_work(wil->wq_service, &wil->probe_client_worker);
1683         return 0;
1684 }
1685
1686 static int wil_cfg80211_change_bss(struct wiphy *wiphy,
1687                                    struct net_device *dev,
1688                                    struct bss_parameters *params)
1689 {
1690         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1691
1692         if (params->ap_isolate >= 0) {
1693                 wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n",
1694                              wil->ap_isolate, params->ap_isolate);
1695                 wil->ap_isolate = params->ap_isolate;
1696         }
1697
1698         return 0;
1699 }
1700
1701 static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1702                                        struct net_device *dev,
1703                                        bool enabled, int timeout)
1704 {
1705         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1706         enum wmi_ps_profile_type ps_profile;
1707
1708         wil_dbg_misc(wil, "enabled=%d, timeout=%d\n",
1709                      enabled, timeout);
1710
1711         if (enabled)
1712                 ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT;
1713         else
1714                 ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED;
1715
1716         return wil_ps_update(wil, ps_profile);
1717 }
1718
1719 static int wil_cfg80211_suspend(struct wiphy *wiphy,
1720                                 struct cfg80211_wowlan *wow)
1721 {
1722         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1723         int rc;
1724
1725         /* Setting the wakeup trigger based on wow is TBD */
1726
1727         if (test_bit(wil_status_suspended, wil->status)) {
1728                 wil_dbg_pm(wil, "trying to suspend while suspended\n");
1729                 return 0;
1730         }
1731
1732         rc = wil_can_suspend(wil, false);
1733         if (rc)
1734                 goto out;
1735
1736         wil_dbg_pm(wil, "suspending\n");
1737
1738         mutex_lock(&wil->mutex);
1739         mutex_lock(&wil->p2p_wdev_mutex);
1740         wil_p2p_stop_radio_operations(wil);
1741         wil_abort_scan(wil, true);
1742         mutex_unlock(&wil->p2p_wdev_mutex);
1743         mutex_unlock(&wil->mutex);
1744
1745 out:
1746         return rc;
1747 }
1748
1749 static int wil_cfg80211_resume(struct wiphy *wiphy)
1750 {
1751         struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1752
1753         wil_dbg_pm(wil, "resuming\n");
1754
1755         return 0;
1756 }
1757
1758 static const struct cfg80211_ops wil_cfg80211_ops = {
1759         .add_virtual_intf = wil_cfg80211_add_iface,
1760         .del_virtual_intf = wil_cfg80211_del_iface,
1761         .scan = wil_cfg80211_scan,
1762         .abort_scan = wil_cfg80211_abort_scan,
1763         .connect = wil_cfg80211_connect,
1764         .disconnect = wil_cfg80211_disconnect,
1765         .set_wiphy_params = wil_cfg80211_set_wiphy_params,
1766         .change_virtual_intf = wil_cfg80211_change_iface,
1767         .get_station = wil_cfg80211_get_station,
1768         .dump_station = wil_cfg80211_dump_station,
1769         .remain_on_channel = wil_remain_on_channel,
1770         .cancel_remain_on_channel = wil_cancel_remain_on_channel,
1771         .mgmt_tx = wil_cfg80211_mgmt_tx,
1772         .set_monitor_channel = wil_cfg80211_set_channel,
1773         .add_key = wil_cfg80211_add_key,
1774         .del_key = wil_cfg80211_del_key,
1775         .set_default_key = wil_cfg80211_set_default_key,
1776         /* AP mode */
1777         .change_beacon = wil_cfg80211_change_beacon,
1778         .start_ap = wil_cfg80211_start_ap,
1779         .stop_ap = wil_cfg80211_stop_ap,
1780         .add_station = wil_cfg80211_add_station,
1781         .del_station = wil_cfg80211_del_station,
1782         .change_station = wil_cfg80211_change_station,
1783         .probe_client = wil_cfg80211_probe_client,
1784         .change_bss = wil_cfg80211_change_bss,
1785         /* P2P device */
1786         .start_p2p_device = wil_cfg80211_start_p2p_device,
1787         .stop_p2p_device = wil_cfg80211_stop_p2p_device,
1788         .set_power_mgmt = wil_cfg80211_set_power_mgmt,
1789         .suspend = wil_cfg80211_suspend,
1790         .resume = wil_cfg80211_resume,
1791 };
1792
1793 static void wil_wiphy_init(struct wiphy *wiphy)
1794 {
1795         wiphy->max_scan_ssids = 1;
1796         wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
1797         wiphy->max_remain_on_channel_duration = WIL_MAX_ROC_DURATION_MS;
1798         wiphy->max_num_pmkids = 0 /* TODO: */;
1799         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1800                                  BIT(NL80211_IFTYPE_AP) |
1801                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
1802                                  BIT(NL80211_IFTYPE_P2P_GO) |
1803                                  BIT(NL80211_IFTYPE_P2P_DEVICE) |
1804                                  BIT(NL80211_IFTYPE_MONITOR);
1805         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
1806                         WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
1807                         WIPHY_FLAG_PS_ON_BY_DEFAULT;
1808         if (!disable_ap_sme)
1809                 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
1810         dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
1811                 __func__, wiphy->flags);
1812         wiphy->probe_resp_offload =
1813                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
1814                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
1815                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
1816
1817         wiphy->bands[NL80211_BAND_60GHZ] = &wil_band_60ghz;
1818
1819         /* may change after reading FW capabilities */
1820         wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
1821
1822         wiphy->cipher_suites = wil_cipher_suites;
1823         wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
1824         wiphy->mgmt_stypes = wil_mgmt_stypes;
1825         wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
1826
1827         wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands);
1828         wiphy->vendor_commands = wil_nl80211_vendor_commands;
1829
1830 #ifdef CONFIG_PM
1831         wiphy->wowlan = &wil_wowlan_support;
1832 #endif
1833 }
1834
1835 struct wireless_dev *wil_cfg80211_init(struct device *dev)
1836 {
1837         int rc = 0;
1838         struct wireless_dev *wdev;
1839
1840         dev_dbg(dev, "%s()\n", __func__);
1841
1842         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
1843         if (!wdev)
1844                 return ERR_PTR(-ENOMEM);
1845
1846         wdev->wiphy = wiphy_new(&wil_cfg80211_ops,
1847                                 sizeof(struct wil6210_priv));
1848         if (!wdev->wiphy) {
1849                 rc = -ENOMEM;
1850                 goto out;
1851         }
1852
1853         set_wiphy_dev(wdev->wiphy, dev);
1854         wil_wiphy_init(wdev->wiphy);
1855
1856         return wdev;
1857
1858 out:
1859         kfree(wdev);
1860
1861         return ERR_PTR(rc);
1862 }
1863
1864 void wil_wdev_free(struct wil6210_priv *wil)
1865 {
1866         struct wireless_dev *wdev = wil_to_wdev(wil);
1867
1868         dev_dbg(wil_to_dev(wil), "%s()\n", __func__);
1869
1870         if (!wdev)
1871                 return;
1872
1873         wiphy_free(wdev->wiphy);
1874         kfree(wdev);
1875 }
1876
1877 void wil_p2p_wdev_free(struct wil6210_priv *wil)
1878 {
1879         struct wireless_dev *p2p_wdev;
1880
1881         mutex_lock(&wil->p2p_wdev_mutex);
1882         p2p_wdev = wil->p2p_wdev;
1883         wil->p2p_wdev = NULL;
1884         wil->radio_wdev = wil_to_wdev(wil);
1885         mutex_unlock(&wil->p2p_wdev_mutex);
1886         if (p2p_wdev) {
1887                 cfg80211_unregister_wdev(p2p_wdev);
1888                 kfree(p2p_wdev);
1889         }
1890 }
1891
1892 static int wil_rf_sector_status_to_rc(u8 status)
1893 {
1894         switch (status) {
1895         case WMI_RF_SECTOR_STATUS_SUCCESS:
1896                 return 0;
1897         case WMI_RF_SECTOR_STATUS_BAD_PARAMETERS_ERROR:
1898                 return -EINVAL;
1899         case WMI_RF_SECTOR_STATUS_BUSY_ERROR:
1900                 return -EAGAIN;
1901         case WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR:
1902                 return -EOPNOTSUPP;
1903         default:
1904                 return -EINVAL;
1905         }
1906 }
1907
1908 static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
1909                                  struct wireless_dev *wdev,
1910                                  const void *data, int data_len)
1911 {
1912         struct wil6210_priv *wil = wdev_to_wil(wdev);
1913         int rc;
1914         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
1915         u16 sector_index;
1916         u8 sector_type;
1917         u32 rf_modules_vec;
1918         struct wmi_get_rf_sector_params_cmd cmd;
1919         struct {
1920                 struct wmi_cmd_hdr wmi;
1921                 struct wmi_get_rf_sector_params_done_event evt;
1922         } __packed reply;
1923         struct sk_buff *msg;
1924         struct nlattr *nl_cfgs, *nl_cfg;
1925         u32 i;
1926         struct wmi_rf_sector_info *si;
1927
1928         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
1929                 return -EOPNOTSUPP;
1930
1931         rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
1932                        wil_rf_sector_policy, NULL);
1933         if (rc) {
1934                 wil_err(wil, "Invalid rf sector ATTR\n");
1935                 return rc;
1936         }
1937
1938         if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
1939             !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE] ||
1940             !tb[QCA_ATTR_DMG_RF_MODULE_MASK]) {
1941                 wil_err(wil, "Invalid rf sector spec\n");
1942                 return -EINVAL;
1943         }
1944
1945         sector_index = nla_get_u16(
1946                 tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
1947         if (sector_index >= WIL_MAX_RF_SECTORS) {
1948                 wil_err(wil, "Invalid sector index %d\n", sector_index);
1949                 return -EINVAL;
1950         }
1951
1952         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
1953         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
1954                 wil_err(wil, "Invalid sector type %d\n", sector_type);
1955                 return -EINVAL;
1956         }
1957
1958         rf_modules_vec = nla_get_u32(
1959                 tb[QCA_ATTR_DMG_RF_MODULE_MASK]);
1960         if (rf_modules_vec >= BIT(WMI_MAX_RF_MODULES_NUM)) {
1961                 wil_err(wil, "Invalid rf module mask 0x%x\n", rf_modules_vec);
1962                 return -EINVAL;
1963         }
1964
1965         cmd.sector_idx = cpu_to_le16(sector_index);
1966         cmd.sector_type = sector_type;
1967         cmd.rf_modules_vec = rf_modules_vec & 0xFF;
1968         memset(&reply, 0, sizeof(reply));
1969         rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd),
1970                       WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID,
1971                       &reply, sizeof(reply),
1972                       500);
1973         if (rc)
1974                 return rc;
1975         if (reply.evt.status) {
1976                 wil_err(wil, "get rf sector cfg failed with status %d\n",
1977                         reply.evt.status);
1978                 return wil_rf_sector_status_to_rc(reply.evt.status);
1979         }
1980
1981         msg = cfg80211_vendor_cmd_alloc_reply_skb(
1982                 wiphy, 64 * WMI_MAX_RF_MODULES_NUM);
1983         if (!msg)
1984                 return -ENOMEM;
1985
1986         if (nla_put_u64_64bit(msg, QCA_ATTR_TSF,
1987                               le64_to_cpu(reply.evt.tsf),
1988                               QCA_ATTR_PAD))
1989                 goto nla_put_failure;
1990
1991         nl_cfgs = nla_nest_start(msg, QCA_ATTR_DMG_RF_SECTOR_CFG);
1992         if (!nl_cfgs)
1993                 goto nla_put_failure;
1994         for (i = 0; i < WMI_MAX_RF_MODULES_NUM; i++) {
1995                 if (!(rf_modules_vec & BIT(i)))
1996                         continue;
1997                 nl_cfg = nla_nest_start(msg, i);
1998                 if (!nl_cfg)
1999                         goto nla_put_failure;
2000                 si = &reply.evt.sectors_info[i];
2001                 if (nla_put_u8(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX,
2002                                i) ||
2003                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0,
2004                                 le32_to_cpu(si->etype0)) ||
2005                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1,
2006                                 le32_to_cpu(si->etype1)) ||
2007                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2,
2008                                 le32_to_cpu(si->etype2)) ||
2009                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI,
2010                                 le32_to_cpu(si->psh_hi)) ||
2011                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO,
2012                                 le32_to_cpu(si->psh_lo)) ||
2013                     nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16,
2014                                 le32_to_cpu(si->dtype_swch_off)))
2015                         goto nla_put_failure;
2016                 nla_nest_end(msg, nl_cfg);
2017         }
2018
2019         nla_nest_end(msg, nl_cfgs);
2020         rc = cfg80211_vendor_cmd_reply(msg);
2021         return rc;
2022 nla_put_failure:
2023         kfree_skb(msg);
2024         return -ENOBUFS;
2025 }
2026
2027 static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
2028                                  struct wireless_dev *wdev,
2029                                  const void *data, int data_len)
2030 {
2031         struct wil6210_priv *wil = wdev_to_wil(wdev);
2032         int rc, tmp;
2033         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2034         struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1];
2035         u16 sector_index, rf_module_index;
2036         u8 sector_type;
2037         u32 rf_modules_vec = 0;
2038         struct wmi_set_rf_sector_params_cmd cmd;
2039         struct {
2040                 struct wmi_cmd_hdr wmi;
2041                 struct wmi_set_rf_sector_params_done_event evt;
2042         } __packed reply;
2043         struct nlattr *nl_cfg;
2044         struct wmi_rf_sector_info *si;
2045
2046         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
2047                 return -EOPNOTSUPP;
2048
2049         rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
2050                        wil_rf_sector_policy, NULL);
2051         if (rc) {
2052                 wil_err(wil, "Invalid rf sector ATTR\n");
2053                 return rc;
2054         }
2055
2056         if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
2057             !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE] ||
2058             !tb[QCA_ATTR_DMG_RF_SECTOR_CFG]) {
2059                 wil_err(wil, "Invalid rf sector spec\n");
2060                 return -EINVAL;
2061         }
2062
2063         sector_index = nla_get_u16(
2064                 tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
2065         if (sector_index >= WIL_MAX_RF_SECTORS) {
2066                 wil_err(wil, "Invalid sector index %d\n", sector_index);
2067                 return -EINVAL;
2068         }
2069
2070         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
2071         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
2072                 wil_err(wil, "Invalid sector type %d\n", sector_type);
2073                 return -EINVAL;
2074         }
2075
2076         memset(&cmd, 0, sizeof(cmd));
2077
2078         cmd.sector_idx = cpu_to_le16(sector_index);
2079         cmd.sector_type = sector_type;
2080         nla_for_each_nested(nl_cfg, tb[QCA_ATTR_DMG_RF_SECTOR_CFG],
2081                             tmp) {
2082                 rc = nla_parse_nested(tb2, QCA_ATTR_DMG_RF_SECTOR_CFG_MAX,
2083                                       nl_cfg, wil_rf_sector_cfg_policy,
2084                                       NULL);
2085                 if (rc) {
2086                         wil_err(wil, "invalid sector cfg\n");
2087                         return -EINVAL;
2088                 }
2089
2090                 if (!tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX] ||
2091                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0] ||
2092                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1] ||
2093                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2] ||
2094                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI] ||
2095                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO] ||
2096                     !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16]) {
2097                         wil_err(wil, "missing cfg params\n");
2098                         return -EINVAL;
2099                 }
2100
2101                 rf_module_index = nla_get_u8(
2102                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX]);
2103                 if (rf_module_index >= WMI_MAX_RF_MODULES_NUM) {
2104                         wil_err(wil, "invalid RF module index %d\n",
2105                                 rf_module_index);
2106                         return -EINVAL;
2107                 }
2108                 rf_modules_vec |= BIT(rf_module_index);
2109                 si = &cmd.sectors_info[rf_module_index];
2110                 si->etype0 = cpu_to_le32(nla_get_u32(
2111                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0]));
2112                 si->etype1 = cpu_to_le32(nla_get_u32(
2113                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1]));
2114                 si->etype2 = cpu_to_le32(nla_get_u32(
2115                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2]));
2116                 si->psh_hi = cpu_to_le32(nla_get_u32(
2117                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI]));
2118                 si->psh_lo = cpu_to_le32(nla_get_u32(
2119                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO]));
2120                 si->dtype_swch_off = cpu_to_le32(nla_get_u32(
2121                         tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16]));
2122         }
2123
2124         cmd.rf_modules_vec = rf_modules_vec & 0xFF;
2125         memset(&reply, 0, sizeof(reply));
2126         rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd),
2127                       WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID,
2128                       &reply, sizeof(reply),
2129                       500);
2130         if (rc)
2131                 return rc;
2132         return wil_rf_sector_status_to_rc(reply.evt.status);
2133 }
2134
2135 static int wil_rf_sector_get_selected(struct wiphy *wiphy,
2136                                       struct wireless_dev *wdev,
2137                                       const void *data, int data_len)
2138 {
2139         struct wil6210_priv *wil = wdev_to_wil(wdev);
2140         int rc;
2141         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2142         u8 sector_type, mac_addr[ETH_ALEN];
2143         int cid = 0;
2144         struct wmi_get_selected_rf_sector_index_cmd cmd;
2145         struct {
2146                 struct wmi_cmd_hdr wmi;
2147                 struct wmi_get_selected_rf_sector_index_done_event evt;
2148         } __packed reply;
2149         struct sk_buff *msg;
2150
2151         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
2152                 return -EOPNOTSUPP;
2153
2154         rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
2155                        wil_rf_sector_policy, NULL);
2156         if (rc) {
2157                 wil_err(wil, "Invalid rf sector ATTR\n");
2158                 return rc;
2159         }
2160
2161         if (!tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]) {
2162                 wil_err(wil, "Invalid rf sector spec\n");
2163                 return -EINVAL;
2164         }
2165         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
2166         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
2167                 wil_err(wil, "Invalid sector type %d\n", sector_type);
2168                 return -EINVAL;
2169         }
2170
2171         if (tb[QCA_ATTR_MAC_ADDR]) {
2172                 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
2173                 cid = wil_find_cid(wil, mac_addr);
2174                 if (cid < 0) {
2175                         wil_err(wil, "invalid MAC address %pM\n", mac_addr);
2176                         return -ENOENT;
2177                 }
2178         } else {
2179                 if (test_bit(wil_status_fwconnected, wil->status)) {
2180                         wil_err(wil, "must specify MAC address when connected\n");
2181                         return -EINVAL;
2182                 }
2183         }
2184
2185         memset(&cmd, 0, sizeof(cmd));
2186         cmd.cid = (u8)cid;
2187         cmd.sector_type = sector_type;
2188         memset(&reply, 0, sizeof(reply));
2189         rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID,
2190                       &cmd, sizeof(cmd),
2191                       WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
2192                       &reply, sizeof(reply),
2193                       500);
2194         if (rc)
2195                 return rc;
2196         if (reply.evt.status) {
2197                 wil_err(wil, "get rf selected sector cfg failed with status %d\n",
2198                         reply.evt.status);
2199                 return wil_rf_sector_status_to_rc(reply.evt.status);
2200         }
2201
2202         msg = cfg80211_vendor_cmd_alloc_reply_skb(
2203                 wiphy, 64 * WMI_MAX_RF_MODULES_NUM);
2204         if (!msg)
2205                 return -ENOMEM;
2206
2207         if (nla_put_u64_64bit(msg, QCA_ATTR_TSF,
2208                               le64_to_cpu(reply.evt.tsf),
2209                               QCA_ATTR_PAD) ||
2210             nla_put_u16(msg, QCA_ATTR_DMG_RF_SECTOR_INDEX,
2211                         le16_to_cpu(reply.evt.sector_idx)))
2212                 goto nla_put_failure;
2213
2214         rc = cfg80211_vendor_cmd_reply(msg);
2215         return rc;
2216 nla_put_failure:
2217         kfree_skb(msg);
2218         return -ENOBUFS;
2219 }
2220
2221 static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
2222                                           u16 sector_index,
2223                                           u8 sector_type, u8 cid)
2224 {
2225         struct wmi_set_selected_rf_sector_index_cmd cmd;
2226         struct {
2227                 struct wmi_cmd_hdr wmi;
2228                 struct wmi_set_selected_rf_sector_index_done_event evt;
2229         } __packed reply;
2230         int rc;
2231
2232         memset(&cmd, 0, sizeof(cmd));
2233         cmd.sector_idx = cpu_to_le16(sector_index);
2234         cmd.sector_type = sector_type;
2235         cmd.cid = (u8)cid;
2236         memset(&reply, 0, sizeof(reply));
2237         rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID,
2238                       &cmd, sizeof(cmd),
2239                       WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
2240                       &reply, sizeof(reply),
2241                       500);
2242         if (rc)
2243                 return rc;
2244         return wil_rf_sector_status_to_rc(reply.evt.status);
2245 }
2246
2247 static int wil_rf_sector_set_selected(struct wiphy *wiphy,
2248                                       struct wireless_dev *wdev,
2249                                       const void *data, int data_len)
2250 {
2251         struct wil6210_priv *wil = wdev_to_wil(wdev);
2252         int rc;
2253         struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2254         u16 sector_index;
2255         u8 sector_type, mac_addr[ETH_ALEN], i;
2256         int cid = 0;
2257
2258         if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
2259                 return -EOPNOTSUPP;
2260
2261         rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
2262                        wil_rf_sector_policy, NULL);
2263         if (rc) {
2264                 wil_err(wil, "Invalid rf sector ATTR\n");
2265                 return rc;
2266         }
2267
2268         if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
2269             !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]) {
2270                 wil_err(wil, "Invalid rf sector spec\n");
2271                 return -EINVAL;
2272         }
2273
2274         sector_index = nla_get_u16(
2275                 tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
2276         if (sector_index >= WIL_MAX_RF_SECTORS &&
2277             sector_index != WMI_INVALID_RF_SECTOR_INDEX) {
2278                 wil_err(wil, "Invalid sector index %d\n", sector_index);
2279                 return -EINVAL;
2280         }
2281
2282         sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
2283         if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
2284                 wil_err(wil, "Invalid sector type %d\n", sector_type);
2285                 return -EINVAL;
2286         }
2287
2288         if (tb[QCA_ATTR_MAC_ADDR]) {
2289                 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
2290                 if (!is_broadcast_ether_addr(mac_addr)) {
2291                         cid = wil_find_cid(wil, mac_addr);
2292                         if (cid < 0) {
2293                                 wil_err(wil, "invalid MAC address %pM\n",
2294                                         mac_addr);
2295                                 return -ENOENT;
2296                         }
2297                 } else {
2298                         if (sector_index != WMI_INVALID_RF_SECTOR_INDEX) {
2299                                 wil_err(wil, "broadcast MAC valid only with unlocking\n");
2300                                 return -EINVAL;
2301                         }
2302                         cid = -1;
2303                 }
2304         } else {
2305                 if (test_bit(wil_status_fwconnected, wil->status)) {
2306                         wil_err(wil, "must specify MAC address when connected\n");
2307                         return -EINVAL;
2308                 }
2309                 /* otherwise, using cid=0 for unassociated station */
2310         }
2311
2312         if (cid >= 0) {
2313                 rc = wil_rf_sector_wmi_set_selected(wil, sector_index,
2314                                                     sector_type, cid);
2315         } else {
2316                 /* unlock all cids */
2317                 rc = wil_rf_sector_wmi_set_selected(
2318                         wil, WMI_INVALID_RF_SECTOR_INDEX, sector_type,
2319                         WIL_CID_ALL);
2320                 if (rc == -EINVAL) {
2321                         for (i = 0; i < WIL6210_MAX_CID; i++) {
2322                                 rc = wil_rf_sector_wmi_set_selected(
2323                                         wil, WMI_INVALID_RF_SECTOR_INDEX,
2324                                         sector_type, i);
2325                                 /* the FW will silently ignore and return
2326                                  * success for unused cid, so abort the loop
2327                                  * on any other error
2328                                  */
2329                                 if (rc) {
2330                                         wil_err(wil, "unlock cid %d failed with status %d\n",
2331                                                 i, rc);
2332                                         break;
2333                                 }
2334                         }
2335                 }
2336         }
2337
2338         return rc;
2339 }