1/*
2 * Copyright (c) 2012-2015 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 "wil6210.h"
19#include "wmi.h"
20
21#define CHAN60G(_channel, _flags) {				\
22	.band			= IEEE80211_BAND_60GHZ,		\
23	.center_freq		= 56160 + (2160 * (_channel)),	\
24	.hw_value		= (_channel),			\
25	.flags			= (_flags),			\
26	.max_antenna_gain	= 0,				\
27	.max_power		= 40,				\
28}
29
30static struct ieee80211_channel wil_60ghz_channels[] = {
31	CHAN60G(1, 0),
32	CHAN60G(2, 0),
33	CHAN60G(3, 0),
34/* channel 4 not supported yet */
35};
36
37static struct ieee80211_supported_band wil_band_60ghz = {
38	.channels = wil_60ghz_channels,
39	.n_channels = ARRAY_SIZE(wil_60ghz_channels),
40	.ht_cap = {
41		.ht_supported = true,
42		.cap = 0, /* TODO */
43		.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */
44		.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */
45		.mcs = {
46				/* MCS 1..12 - SC PHY */
47			.rx_mask = {0xfe, 0x1f}, /* 1..12 */
48			.tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */
49		},
50	},
51};
52
53static const struct ieee80211_txrx_stypes
54wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
55	[NL80211_IFTYPE_STATION] = {
56		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
57		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
58		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
59		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
60	},
61	[NL80211_IFTYPE_AP] = {
62		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
63		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
64		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
65		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
66	},
67	[NL80211_IFTYPE_P2P_CLIENT] = {
68		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
69		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
70		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
71		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
72	},
73	[NL80211_IFTYPE_P2P_GO] = {
74		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
75		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
76		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
77		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
78	},
79};
80
81static const u32 wil_cipher_suites[] = {
82	WLAN_CIPHER_SUITE_GCMP,
83};
84
85int wil_iftype_nl2wmi(enum nl80211_iftype type)
86{
87	static const struct {
88		enum nl80211_iftype nl;
89		enum wmi_network_type wmi;
90	} __nl2wmi[] = {
91		{NL80211_IFTYPE_ADHOC,		WMI_NETTYPE_ADHOC},
92		{NL80211_IFTYPE_STATION,	WMI_NETTYPE_INFRA},
93		{NL80211_IFTYPE_AP,		WMI_NETTYPE_AP},
94		{NL80211_IFTYPE_P2P_CLIENT,	WMI_NETTYPE_P2P},
95		{NL80211_IFTYPE_P2P_GO,		WMI_NETTYPE_P2P},
96		{NL80211_IFTYPE_MONITOR,	WMI_NETTYPE_ADHOC}, /* FIXME */
97	};
98	uint i;
99
100	for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) {
101		if (__nl2wmi[i].nl == type)
102			return __nl2wmi[i].wmi;
103	}
104
105	return -EOPNOTSUPP;
106}
107
108int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
109		       struct station_info *sinfo)
110{
111	struct wmi_notify_req_cmd cmd = {
112		.cid = cid,
113		.interval_usec = 0,
114	};
115	struct {
116		struct wil6210_mbox_hdr_wmi wmi;
117		struct wmi_notify_req_done_event evt;
118	} __packed reply;
119	struct wil_net_stats *stats = &wil->sta[cid].stats;
120	int rc;
121
122	rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
123		      WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
124	if (rc)
125		return rc;
126
127	wil_dbg_wmi(wil, "Link status for CID %d: {\n"
128		    "  MCS %d TSF 0x%016llx\n"
129		    "  BF status 0x%08x SNR 0x%08x SQI %d%%\n"
130		    "  Tx Tpt %d goodput %d Rx goodput %d\n"
131		    "  Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
132		    cid, le16_to_cpu(reply.evt.bf_mcs),
133		    le64_to_cpu(reply.evt.tsf), reply.evt.status,
134		    le32_to_cpu(reply.evt.snr_val),
135		    reply.evt.sqi,
136		    le32_to_cpu(reply.evt.tx_tpt),
137		    le32_to_cpu(reply.evt.tx_goodput),
138		    le32_to_cpu(reply.evt.rx_goodput),
139		    le16_to_cpu(reply.evt.my_rx_sector),
140		    le16_to_cpu(reply.evt.my_tx_sector),
141		    le16_to_cpu(reply.evt.other_rx_sector),
142		    le16_to_cpu(reply.evt.other_tx_sector));
143
144	sinfo->generation = wil->sinfo_gen;
145
146	sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) |
147			BIT(NL80211_STA_INFO_TX_BYTES) |
148			BIT(NL80211_STA_INFO_RX_PACKETS) |
149			BIT(NL80211_STA_INFO_TX_PACKETS) |
150			BIT(NL80211_STA_INFO_RX_BITRATE) |
151			BIT(NL80211_STA_INFO_TX_BITRATE) |
152			BIT(NL80211_STA_INFO_RX_DROP_MISC) |
153			BIT(NL80211_STA_INFO_TX_FAILED);
154
155	sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
156	sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
157	sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
158	sinfo->rxrate.mcs = stats->last_mcs_rx;
159	sinfo->rx_bytes = stats->rx_bytes;
160	sinfo->rx_packets = stats->rx_packets;
161	sinfo->rx_dropped_misc = stats->rx_dropped;
162	sinfo->tx_bytes = stats->tx_bytes;
163	sinfo->tx_packets = stats->tx_packets;
164	sinfo->tx_failed = stats->tx_errors;
165
166	if (test_bit(wil_status_fwconnected, wil->status)) {
167		sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
168		sinfo->signal = reply.evt.sqi;
169	}
170
171	return rc;
172}
173
174static int wil_cfg80211_get_station(struct wiphy *wiphy,
175				    struct net_device *ndev,
176				    const u8 *mac, struct station_info *sinfo)
177{
178	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
179	int rc;
180
181	int cid = wil_find_cid(wil, mac);
182
183	wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
184	if (cid < 0)
185		return cid;
186
187	rc = wil_cid_fill_sinfo(wil, cid, sinfo);
188
189	return rc;
190}
191
192/*
193 * Find @idx-th active STA for station dump.
194 */
195static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx)
196{
197	int i;
198
199	for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
200		if (wil->sta[i].status == wil_sta_unused)
201			continue;
202		if (idx == 0)
203			return i;
204		idx--;
205	}
206
207	return -ENOENT;
208}
209
210static int wil_cfg80211_dump_station(struct wiphy *wiphy,
211				     struct net_device *dev, int idx,
212				     u8 *mac, struct station_info *sinfo)
213{
214	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
215	int rc;
216	int cid = wil_find_cid_by_idx(wil, idx);
217
218	if (cid < 0)
219		return -ENOENT;
220
221	ether_addr_copy(mac, wil->sta[cid].addr);
222	wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
223
224	rc = wil_cid_fill_sinfo(wil, cid, sinfo);
225
226	return rc;
227}
228
229static int wil_cfg80211_change_iface(struct wiphy *wiphy,
230				     struct net_device *ndev,
231				     enum nl80211_iftype type, u32 *flags,
232				     struct vif_params *params)
233{
234	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
235	struct wireless_dev *wdev = wil->wdev;
236
237	switch (type) {
238	case NL80211_IFTYPE_STATION:
239	case NL80211_IFTYPE_AP:
240	case NL80211_IFTYPE_P2P_CLIENT:
241	case NL80211_IFTYPE_P2P_GO:
242		break;
243	case NL80211_IFTYPE_MONITOR:
244		if (flags)
245			wil->monitor_flags = *flags;
246		else
247			wil->monitor_flags = 0;
248
249		break;
250	default:
251		return -EOPNOTSUPP;
252	}
253
254	wdev->iftype = type;
255
256	return 0;
257}
258
259static int wil_cfg80211_scan(struct wiphy *wiphy,
260			     struct cfg80211_scan_request *request)
261{
262	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
263	struct wireless_dev *wdev = wil->wdev;
264	struct {
265		struct wmi_start_scan_cmd cmd;
266		u16 chnl[4];
267	} __packed cmd;
268	uint i, n;
269	int rc;
270
271	if (wil->scan_request) {
272		wil_err(wil, "Already scanning\n");
273		return -EAGAIN;
274	}
275
276	/* check we are client side */
277	switch (wdev->iftype) {
278	case NL80211_IFTYPE_STATION:
279	case NL80211_IFTYPE_P2P_CLIENT:
280		break;
281	default:
282		return -EOPNOTSUPP;
283	}
284
285	/* FW don't support scan after connection attempt */
286	if (test_bit(wil_status_dontscan, wil->status)) {
287		wil_err(wil, "Can't scan now\n");
288		return -EBUSY;
289	}
290
291	wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
292	wil->scan_request = request;
293	mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
294
295	memset(&cmd, 0, sizeof(cmd));
296	cmd.cmd.num_channels = 0;
297	n = min(request->n_channels, 4U);
298	for (i = 0; i < n; i++) {
299		int ch = request->channels[i]->hw_value;
300
301		if (ch == 0) {
302			wil_err(wil,
303				"Scan requested for unknown frequency %dMhz\n",
304				request->channels[i]->center_freq);
305			continue;
306		}
307		/* 0-based channel indexes */
308		cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
309		wil_dbg_misc(wil, "Scan for ch %d  : %d MHz\n", ch,
310			     request->channels[i]->center_freq);
311	}
312
313	if (request->ie_len)
314		print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET,
315				     request->ie, request->ie_len);
316	else
317		wil_dbg_misc(wil, "Scan has no IE's\n");
318
319	rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len,
320			request->ie);
321	if (rc) {
322		wil_err(wil, "Aborting scan, set_ie failed: %d\n", rc);
323		goto out;
324	}
325
326	rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
327			cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
328
329out:
330	if (rc) {
331		del_timer_sync(&wil->scan_timer);
332		wil->scan_request = NULL;
333	}
334
335	return rc;
336}
337
338static void wil_print_crypto(struct wil6210_priv *wil,
339			     struct cfg80211_crypto_settings *c)
340{
341	int i, n;
342
343	wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
344		     c->wpa_versions, c->cipher_group);
345	wil_dbg_misc(wil, "Pairwise ciphers [%d] {\n", c->n_ciphers_pairwise);
346	n = min_t(int, c->n_ciphers_pairwise, ARRAY_SIZE(c->ciphers_pairwise));
347	for (i = 0; i < n; i++)
348		wil_dbg_misc(wil, "  [%d] = 0x%08x\n", i,
349			     c->ciphers_pairwise[i]);
350	wil_dbg_misc(wil, "}\n");
351	wil_dbg_misc(wil, "AKM suites [%d] {\n", c->n_akm_suites);
352	n = min_t(int, c->n_akm_suites, ARRAY_SIZE(c->akm_suites));
353	for (i = 0; i < n; i++)
354		wil_dbg_misc(wil, "  [%d] = 0x%08x\n", i,
355			     c->akm_suites[i]);
356	wil_dbg_misc(wil, "}\n");
357	wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
358		     c->control_port, be16_to_cpu(c->control_port_ethertype),
359		     c->control_port_no_encrypt);
360}
361
362static void wil_print_connect_params(struct wil6210_priv *wil,
363				     struct cfg80211_connect_params *sme)
364{
365	wil_info(wil, "Connecting to:\n");
366	if (sme->channel) {
367		wil_info(wil, "  Channel: %d freq %d\n",
368			 sme->channel->hw_value, sme->channel->center_freq);
369	}
370	if (sme->bssid)
371		wil_info(wil, "  BSSID: %pM\n", sme->bssid);
372	if (sme->ssid)
373		print_hex_dump(KERN_INFO, "  SSID: ", DUMP_PREFIX_OFFSET,
374			       16, 1, sme->ssid, sme->ssid_len, true);
375	wil_info(wil, "  Privacy: %s\n", sme->privacy ? "secure" : "open");
376	wil_print_crypto(wil, &sme->crypto);
377}
378
379static int wil_cfg80211_connect(struct wiphy *wiphy,
380				struct net_device *ndev,
381				struct cfg80211_connect_params *sme)
382{
383	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
384	struct cfg80211_bss *bss;
385	struct wmi_connect_cmd conn;
386	const u8 *ssid_eid;
387	const u8 *rsn_eid;
388	int ch;
389	int rc = 0;
390
391	wil_print_connect_params(wil, sme);
392
393	if (test_bit(wil_status_fwconnecting, wil->status) ||
394	    test_bit(wil_status_fwconnected, wil->status))
395		return -EALREADY;
396
397	if (sme->ie_len > WMI_MAX_IE_LEN) {
398		wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
399		return -ERANGE;
400	}
401
402	rsn_eid = sme->ie ?
403			cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
404			NULL;
405
406	if (sme->privacy && !rsn_eid) {
407		wil_err(wil, "Missing RSN IE for secure connection\n");
408		return -EINVAL;
409	}
410
411	bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
412			       sme->ssid, sme->ssid_len,
413			       IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
414	if (!bss) {
415		wil_err(wil, "Unable to find BSS\n");
416		return -ENOENT;
417	}
418
419	ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
420	if (!ssid_eid) {
421		wil_err(wil, "No SSID\n");
422		rc = -ENOENT;
423		goto out;
424	}
425	wil->privacy = sme->privacy;
426
427	if (wil->privacy) {
428		/* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */
429		rc = wmi_del_cipher_key(wil, 0, bss->bssid);
430		if (rc) {
431			wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n");
432			goto out;
433		}
434	}
435
436	/* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info
437	 * elements. Send it also in case it's empty, to erase previously set
438	 * ies in FW.
439	 */
440	rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
441	if (rc) {
442		wil_err(wil, "WMI_SET_APPIE_CMD failed\n");
443		goto out;
444	}
445
446	/* WMI_CONNECT_CMD */
447	memset(&conn, 0, sizeof(conn));
448	switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
449	case WLAN_CAPABILITY_DMG_TYPE_AP:
450		conn.network_type = WMI_NETTYPE_INFRA;
451		break;
452	case WLAN_CAPABILITY_DMG_TYPE_PBSS:
453		conn.network_type = WMI_NETTYPE_P2P;
454		break;
455	default:
456		wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
457			bss->capability);
458		goto out;
459	}
460	if (wil->privacy) {
461		conn.dot11_auth_mode = WMI_AUTH11_SHARED;
462		conn.auth_mode = WMI_AUTH_WPA2_PSK;
463		conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
464		conn.pairwise_crypto_len = 16;
465	} else {
466		conn.dot11_auth_mode = WMI_AUTH11_OPEN;
467		conn.auth_mode = WMI_AUTH_NONE;
468	}
469
470	conn.ssid_len = min_t(u8, ssid_eid[1], 32);
471	memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
472
473	ch = bss->channel->hw_value;
474	if (ch == 0) {
475		wil_err(wil, "BSS at unknown frequency %dMhz\n",
476			bss->channel->center_freq);
477		rc = -EOPNOTSUPP;
478		goto out;
479	}
480	conn.channel = ch - 1;
481
482	ether_addr_copy(conn.bssid, bss->bssid);
483	ether_addr_copy(conn.dst_mac, bss->bssid);
484
485	set_bit(wil_status_fwconnecting, wil->status);
486
487	rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
488	if (rc == 0) {
489		netif_carrier_on(ndev);
490		/* Connect can take lots of time */
491		mod_timer(&wil->connect_timer,
492			  jiffies + msecs_to_jiffies(2000));
493	} else {
494		clear_bit(wil_status_fwconnecting, wil->status);
495	}
496
497 out:
498	cfg80211_put_bss(wiphy, bss);
499
500	return rc;
501}
502
503static int wil_cfg80211_disconnect(struct wiphy *wiphy,
504				   struct net_device *ndev,
505				   u16 reason_code)
506{
507	int rc;
508	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
509
510	rc = wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
511
512	return rc;
513}
514
515int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
516			 struct cfg80211_mgmt_tx_params *params,
517			 u64 *cookie)
518{
519	const u8 *buf = params->buf;
520	size_t len = params->len;
521	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
522	int rc;
523	bool tx_status = false;
524	struct ieee80211_mgmt *mgmt_frame = (void *)buf;
525	struct wmi_sw_tx_req_cmd *cmd;
526	struct {
527		struct wil6210_mbox_hdr_wmi wmi;
528		struct wmi_sw_tx_complete_event evt;
529	} __packed evt;
530
531	cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
532	if (!cmd) {
533		rc = -ENOMEM;
534		goto out;
535	}
536
537	memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
538	cmd->len = cpu_to_le16(len);
539	memcpy(cmd->payload, buf, len);
540
541	rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
542		      WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
543	if (rc == 0)
544		tx_status = !evt.evt.status;
545
546	kfree(cmd);
547 out:
548	cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
549				tx_status, GFP_KERNEL);
550	return rc;
551}
552
553static int wil_cfg80211_set_channel(struct wiphy *wiphy,
554				    struct cfg80211_chan_def *chandef)
555{
556	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
557	struct wireless_dev *wdev = wil->wdev;
558
559	wdev->preset_chandef = *chandef;
560
561	return 0;
562}
563
564static int wil_cfg80211_add_key(struct wiphy *wiphy,
565				struct net_device *ndev,
566				u8 key_index, bool pairwise,
567				const u8 *mac_addr,
568				struct key_params *params)
569{
570	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
571
572	/* group key is not used */
573	if (!pairwise)
574		return 0;
575
576	return wmi_add_cipher_key(wil, key_index, mac_addr,
577				  params->key_len, params->key);
578}
579
580static int wil_cfg80211_del_key(struct wiphy *wiphy,
581				struct net_device *ndev,
582				u8 key_index, bool pairwise,
583				const u8 *mac_addr)
584{
585	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
586
587	/* group key is not used */
588	if (!pairwise)
589		return 0;
590
591	return wmi_del_cipher_key(wil, key_index, mac_addr);
592}
593
594/* Need to be present or wiphy_new() will WARN */
595static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
596					struct net_device *ndev,
597					u8 key_index, bool unicast,
598					bool multicast)
599{
600	return 0;
601}
602
603static int wil_remain_on_channel(struct wiphy *wiphy,
604				 struct wireless_dev *wdev,
605				 struct ieee80211_channel *chan,
606				 unsigned int duration,
607				 u64 *cookie)
608{
609	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
610	int rc;
611
612	/* TODO: handle duration */
613	wil_info(wil, "%s(%d, %d ms)\n", __func__, chan->center_freq, duration);
614
615	rc = wmi_set_channel(wil, chan->hw_value);
616	if (rc)
617		return rc;
618
619	rc = wmi_rxon(wil, true);
620
621	return rc;
622}
623
624static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
625					struct wireless_dev *wdev,
626					u64 cookie)
627{
628	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
629	int rc;
630
631	wil_info(wil, "%s()\n", __func__);
632
633	rc = wmi_rxon(wil, false);
634
635	return rc;
636}
637
638static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
639{
640	print_hex_dump_bytes("head     ", DUMP_PREFIX_OFFSET,
641			     b->head, b->head_len);
642	print_hex_dump_bytes("tail     ", DUMP_PREFIX_OFFSET,
643			     b->tail, b->tail_len);
644	print_hex_dump_bytes("BCON IE  ", DUMP_PREFIX_OFFSET,
645			     b->beacon_ies, b->beacon_ies_len);
646	print_hex_dump_bytes("PROBE    ", DUMP_PREFIX_OFFSET,
647			     b->probe_resp, b->probe_resp_len);
648	print_hex_dump_bytes("PROBE IE ", DUMP_PREFIX_OFFSET,
649			     b->proberesp_ies, b->proberesp_ies_len);
650	print_hex_dump_bytes("ASSOC IE ", DUMP_PREFIX_OFFSET,
651			     b->assocresp_ies, b->assocresp_ies_len);
652}
653
654static int wil_fix_bcon(struct wil6210_priv *wil,
655			struct cfg80211_beacon_data *bcon)
656{
657	struct ieee80211_mgmt *f = (struct ieee80211_mgmt *)bcon->probe_resp;
658	size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
659	int rc = 0;
660
661	if (bcon->probe_resp_len <= hlen)
662		return 0;
663
664	if (!bcon->proberesp_ies) {
665		bcon->proberesp_ies = f->u.probe_resp.variable;
666		bcon->proberesp_ies_len = bcon->probe_resp_len - hlen;
667		rc = 1;
668	}
669	if (!bcon->assocresp_ies) {
670		bcon->assocresp_ies = f->u.probe_resp.variable;
671		bcon->assocresp_ies_len = bcon->probe_resp_len - hlen;
672		rc = 1;
673	}
674
675	return rc;
676}
677
678static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
679				      struct net_device *ndev,
680				      struct cfg80211_beacon_data *bcon)
681{
682	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
683	int rc;
684
685	wil_dbg_misc(wil, "%s()\n", __func__);
686
687	if (wil_fix_bcon(wil, bcon)) {
688		wil_dbg_misc(wil, "Fixed bcon\n");
689		wil_print_bcon_data(bcon);
690	}
691
692	/* FW do not form regular beacon, so bcon IE's are not set
693	 * For the DMG bcon, when it will be supported, bcon IE's will
694	 * be reused; add something like:
695	 * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
696	 * bcon->beacon_ies);
697	 */
698	rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP,
699			bcon->proberesp_ies_len,
700			bcon->proberesp_ies);
701	if (rc) {
702		wil_err(wil, "set_ie(PROBE_RESP) failed\n");
703		return rc;
704	}
705
706	rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP,
707			bcon->assocresp_ies_len,
708			bcon->assocresp_ies);
709	if (rc) {
710		wil_err(wil, "set_ie(ASSOC_RESP) failed\n");
711		return rc;
712	}
713
714	return 0;
715}
716
717static int wil_cfg80211_start_ap(struct wiphy *wiphy,
718				 struct net_device *ndev,
719				 struct cfg80211_ap_settings *info)
720{
721	int rc = 0;
722	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
723	struct wireless_dev *wdev = ndev->ieee80211_ptr;
724	struct ieee80211_channel *channel = info->chandef.chan;
725	struct cfg80211_beacon_data *bcon = &info->beacon;
726	struct cfg80211_crypto_settings *crypto = &info->crypto;
727	u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
728
729	wil_dbg_misc(wil, "%s()\n", __func__);
730
731	if (!channel) {
732		wil_err(wil, "AP: No channel???\n");
733		return -EINVAL;
734	}
735
736	wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
737		     channel->center_freq, info->privacy ? "secure" : "open");
738	wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
739		     info->privacy, info->auth_type);
740	wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
741		     info->dtim_period);
742	print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
743			     info->ssid, info->ssid_len);
744	wil_print_bcon_data(bcon);
745	wil_print_crypto(wil, crypto);
746
747	if (wil_fix_bcon(wil, bcon)) {
748		wil_dbg_misc(wil, "Fixed bcon\n");
749		wil_print_bcon_data(bcon);
750	}
751
752	wil_set_recovery_state(wil, fw_recovery_idle);
753
754	mutex_lock(&wil->mutex);
755
756	__wil_down(wil);
757	rc = __wil_up(wil);
758	if (rc)
759		goto out;
760
761	rc = wmi_set_ssid(wil, info->ssid_len, info->ssid);
762	if (rc)
763		goto out;
764
765	/* IE's */
766	/* bcon 'head IE's are not relevant for 60g band */
767	/*
768	 * FW do not form regular beacon, so bcon IE's are not set
769	 * For the DMG bcon, when it will be supported, bcon IE's will
770	 * be reused; add something like:
771	 * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
772	 * bcon->beacon_ies);
773	 */
774	wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len,
775		   bcon->proberesp_ies);
776	wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
777		   bcon->assocresp_ies);
778
779	wil->privacy = info->privacy;
780
781	netif_carrier_on(ndev);
782
783	rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
784			   channel->hw_value);
785	if (rc)
786		goto err_pcp_start;
787
788	rc = wil_bcast_init(wil);
789	if (rc)
790		goto err_bcast;
791
792	goto out; /* success */
793err_bcast:
794	wmi_pcp_stop(wil);
795err_pcp_start:
796	netif_carrier_off(ndev);
797out:
798	mutex_unlock(&wil->mutex);
799	return rc;
800}
801
802static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
803				struct net_device *ndev)
804{
805	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
806
807	wil_dbg_misc(wil, "%s()\n", __func__);
808
809	netif_carrier_off(ndev);
810	wil_set_recovery_state(wil, fw_recovery_idle);
811
812	mutex_lock(&wil->mutex);
813
814	wmi_pcp_stop(wil);
815
816	__wil_down(wil);
817	__wil_up(wil);
818
819	mutex_unlock(&wil->mutex);
820
821	/* some functions above might fail (e.g. __wil_up). Nevertheless, we
822	 * return success because AP has stopped
823	 */
824	return 0;
825}
826
827static int wil_cfg80211_del_station(struct wiphy *wiphy,
828				    struct net_device *dev,
829				    struct station_del_parameters *params)
830{
831	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
832
833	mutex_lock(&wil->mutex);
834	wil6210_disconnect(wil, params->mac, params->reason_code, false);
835	mutex_unlock(&wil->mutex);
836
837	return 0;
838}
839
840/* probe_client handling */
841static void wil_probe_client_handle(struct wil6210_priv *wil,
842				    struct wil_probe_client_req *req)
843{
844	struct net_device *ndev = wil_to_ndev(wil);
845	struct wil_sta_info *sta = &wil->sta[req->cid];
846	/* assume STA is alive if it is still connected,
847	 * else FW will disconnect it
848	 */
849	bool alive = (sta->status == wil_sta_connected);
850
851	cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, GFP_KERNEL);
852}
853
854static struct list_head *next_probe_client(struct wil6210_priv *wil)
855{
856	struct list_head *ret = NULL;
857
858	mutex_lock(&wil->probe_client_mutex);
859
860	if (!list_empty(&wil->probe_client_pending)) {
861		ret = wil->probe_client_pending.next;
862		list_del(ret);
863	}
864
865	mutex_unlock(&wil->probe_client_mutex);
866
867	return ret;
868}
869
870void wil_probe_client_worker(struct work_struct *work)
871{
872	struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
873						probe_client_worker);
874	struct wil_probe_client_req *req;
875	struct list_head *lh;
876
877	while ((lh = next_probe_client(wil)) != NULL) {
878		req = list_entry(lh, struct wil_probe_client_req, list);
879
880		wil_probe_client_handle(wil, req);
881		kfree(req);
882	}
883}
884
885void wil_probe_client_flush(struct wil6210_priv *wil)
886{
887	struct wil_probe_client_req *req, *t;
888
889	wil_dbg_misc(wil, "%s()\n", __func__);
890
891	mutex_lock(&wil->probe_client_mutex);
892
893	list_for_each_entry_safe(req, t, &wil->probe_client_pending, list) {
894		list_del(&req->list);
895		kfree(req);
896	}
897
898	mutex_unlock(&wil->probe_client_mutex);
899}
900
901static int wil_cfg80211_probe_client(struct wiphy *wiphy,
902				     struct net_device *dev,
903				     const u8 *peer, u64 *cookie)
904{
905	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
906	struct wil_probe_client_req *req;
907	int cid = wil_find_cid(wil, peer);
908
909	wil_dbg_misc(wil, "%s(%pM => CID %d)\n", __func__, peer, cid);
910
911	if (cid < 0)
912		return -ENOLINK;
913
914	req = kzalloc(sizeof(*req), GFP_KERNEL);
915	if (!req)
916		return -ENOMEM;
917
918	req->cid = cid;
919	req->cookie = cid;
920
921	mutex_lock(&wil->probe_client_mutex);
922	list_add_tail(&req->list, &wil->probe_client_pending);
923	mutex_unlock(&wil->probe_client_mutex);
924
925	*cookie = req->cookie;
926	queue_work(wil->wq_service, &wil->probe_client_worker);
927	return 0;
928}
929
930static int wil_cfg80211_change_bss(struct wiphy *wiphy,
931				   struct net_device *dev,
932				   struct bss_parameters *params)
933{
934	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
935
936	if (params->ap_isolate >= 0) {
937		wil_dbg_misc(wil, "%s(ap_isolate %d => %d)\n", __func__,
938			     wil->ap_isolate, params->ap_isolate);
939		wil->ap_isolate = params->ap_isolate;
940	}
941
942	return 0;
943}
944
945static struct cfg80211_ops wil_cfg80211_ops = {
946	.scan = wil_cfg80211_scan,
947	.connect = wil_cfg80211_connect,
948	.disconnect = wil_cfg80211_disconnect,
949	.change_virtual_intf = wil_cfg80211_change_iface,
950	.get_station = wil_cfg80211_get_station,
951	.dump_station = wil_cfg80211_dump_station,
952	.remain_on_channel = wil_remain_on_channel,
953	.cancel_remain_on_channel = wil_cancel_remain_on_channel,
954	.mgmt_tx = wil_cfg80211_mgmt_tx,
955	.set_monitor_channel = wil_cfg80211_set_channel,
956	.add_key = wil_cfg80211_add_key,
957	.del_key = wil_cfg80211_del_key,
958	.set_default_key = wil_cfg80211_set_default_key,
959	/* AP mode */
960	.change_beacon = wil_cfg80211_change_beacon,
961	.start_ap = wil_cfg80211_start_ap,
962	.stop_ap = wil_cfg80211_stop_ap,
963	.del_station = wil_cfg80211_del_station,
964	.probe_client = wil_cfg80211_probe_client,
965	.change_bss = wil_cfg80211_change_bss,
966};
967
968static void wil_wiphy_init(struct wiphy *wiphy)
969{
970	/* TODO: set real value */
971	wiphy->max_scan_ssids = 10;
972	wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
973	wiphy->max_num_pmkids = 0 /* TODO: */;
974	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
975				 BIT(NL80211_IFTYPE_AP) |
976				 BIT(NL80211_IFTYPE_MONITOR);
977	/* TODO: enable P2P when integrated with supplicant:
978	 * BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO)
979	 */
980	wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
981			WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
982	dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
983		__func__, wiphy->flags);
984	wiphy->probe_resp_offload =
985		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
986		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
987		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
988
989	wiphy->bands[IEEE80211_BAND_60GHZ] = &wil_band_60ghz;
990
991	/* TODO: figure this out */
992	wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
993
994	wiphy->cipher_suites = wil_cipher_suites;
995	wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
996	wiphy->mgmt_stypes = wil_mgmt_stypes;
997	wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
998}
999
1000struct wireless_dev *wil_cfg80211_init(struct device *dev)
1001{
1002	int rc = 0;
1003	struct wireless_dev *wdev;
1004
1005	dev_dbg(dev, "%s()\n", __func__);
1006
1007	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
1008	if (!wdev)
1009		return ERR_PTR(-ENOMEM);
1010
1011	wdev->wiphy = wiphy_new(&wil_cfg80211_ops,
1012				sizeof(struct wil6210_priv));
1013	if (!wdev->wiphy) {
1014		rc = -ENOMEM;
1015		goto out;
1016	}
1017
1018	set_wiphy_dev(wdev->wiphy, dev);
1019	wil_wiphy_init(wdev->wiphy);
1020
1021	rc = wiphy_register(wdev->wiphy);
1022	if (rc < 0)
1023		goto out_failed_reg;
1024
1025	return wdev;
1026
1027out_failed_reg:
1028	wiphy_free(wdev->wiphy);
1029out:
1030	kfree(wdev);
1031
1032	return ERR_PTR(rc);
1033}
1034
1035void wil_wdev_free(struct wil6210_priv *wil)
1036{
1037	struct wireless_dev *wdev = wil_to_wdev(wil);
1038
1039	dev_dbg(wil_to_dev(wil), "%s()\n", __func__);
1040
1041	if (!wdev)
1042		return;
1043
1044	wiphy_unregister(wdev->wiphy);
1045	wiphy_free(wdev->wiphy);
1046	kfree(wdev);
1047}
1048