1 /*
2  * Copyright (c) 2015-2016 Quantenna Communications, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15 
16 #include <linux/types.h>
17 #include <linux/skbuff.h>
18 
19 #include "cfg80211.h"
20 #include "core.h"
21 #include "qlink.h"
22 #include "qlink_util.h"
23 #include "bus.h"
24 #include "commands.h"
25 
26 static int qtnf_cmd_check_reply_header(const struct qlink_resp *resp,
27 				       u16 cmd_id, u8 mac_id, u8 vif_id,
28 				       size_t resp_size)
29 {
30 	if (unlikely(le16_to_cpu(resp->cmd_id) != cmd_id)) {
31 		pr_warn("VIF%u.%u CMD%x: bad cmd_id in response: 0x%.4X\n",
32 			mac_id, vif_id, cmd_id, le16_to_cpu(resp->cmd_id));
33 		return -EINVAL;
34 	}
35 
36 	if (unlikely(resp->macid != mac_id)) {
37 		pr_warn("VIF%u.%u CMD%x: bad MAC in response: %u\n",
38 			mac_id, vif_id, cmd_id, resp->macid);
39 		return -EINVAL;
40 	}
41 
42 	if (unlikely(resp->vifid != vif_id)) {
43 		pr_warn("VIF%u.%u CMD%x: bad VIF in response: %u\n",
44 			mac_id, vif_id, cmd_id, resp->vifid);
45 		return -EINVAL;
46 	}
47 
48 	if (unlikely(le16_to_cpu(resp->mhdr.len) < resp_size)) {
49 		pr_warn("VIF%u.%u CMD%x: bad response size %u < %zu\n",
50 			mac_id, vif_id, cmd_id,
51 			le16_to_cpu(resp->mhdr.len), resp_size);
52 		return -ENOSPC;
53 	}
54 
55 	return 0;
56 }
57 
58 static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus,
59 				    struct sk_buff *cmd_skb,
60 				    struct sk_buff **response_skb,
61 				    u16 *result_code,
62 				    size_t const_resp_size,
63 				    size_t *var_resp_size)
64 {
65 	struct qlink_cmd *cmd;
66 	const struct qlink_resp *resp;
67 	struct sk_buff *resp_skb = NULL;
68 	u16 cmd_id;
69 	u8 mac_id, vif_id;
70 	int ret;
71 
72 	cmd = (struct qlink_cmd *)cmd_skb->data;
73 	cmd_id = le16_to_cpu(cmd->cmd_id);
74 	mac_id = cmd->macid;
75 	vif_id = cmd->vifid;
76 	cmd->mhdr.len = cpu_to_le16(cmd_skb->len);
77 
78 	if (unlikely(bus->fw_state != QTNF_FW_STATE_ACTIVE &&
79 		     le16_to_cpu(cmd->cmd_id) != QLINK_CMD_FW_INIT)) {
80 		pr_warn("VIF%u.%u: drop cmd 0x%.4X in fw state %d\n",
81 			mac_id, vif_id, le16_to_cpu(cmd->cmd_id),
82 			bus->fw_state);
83 		return -ENODEV;
84 	}
85 
86 	pr_debug("VIF%u.%u cmd=0x%.4X\n", mac_id, vif_id,
87 		 le16_to_cpu(cmd->cmd_id));
88 
89 	ret = qtnf_trans_send_cmd_with_resp(bus, cmd_skb, &resp_skb);
90 
91 	if (unlikely(ret))
92 		goto out;
93 
94 	resp = (const struct qlink_resp *)resp_skb->data;
95 	ret = qtnf_cmd_check_reply_header(resp, cmd_id, mac_id, vif_id,
96 					  const_resp_size);
97 
98 	if (unlikely(ret))
99 		goto out;
100 
101 	if (likely(result_code))
102 		*result_code = le16_to_cpu(resp->result);
103 
104 	/* Return length of variable part of response */
105 	if (response_skb && var_resp_size)
106 		*var_resp_size = le16_to_cpu(resp->mhdr.len) - const_resp_size;
107 
108 out:
109 	if (response_skb)
110 		*response_skb = resp_skb;
111 	else
112 		consume_skb(resp_skb);
113 
114 	return ret;
115 }
116 
117 static inline int qtnf_cmd_send(struct qtnf_bus *bus,
118 				struct sk_buff *cmd_skb,
119 				u16 *result_code)
120 {
121 	return qtnf_cmd_send_with_reply(bus, cmd_skb, NULL, result_code,
122 					sizeof(struct qlink_resp), NULL);
123 }
124 
125 static struct sk_buff *qtnf_cmd_alloc_new_cmdskb(u8 macid, u8 vifid, u16 cmd_no,
126 						 size_t cmd_size)
127 {
128 	struct qlink_cmd *cmd;
129 	struct sk_buff *cmd_skb;
130 
131 	cmd_skb = __dev_alloc_skb(sizeof(*cmd) +
132 				  QTNF_MAX_CMD_BUF_SIZE, GFP_KERNEL);
133 	if (unlikely(!cmd_skb)) {
134 		pr_err("VIF%u.%u CMD %u: alloc failed\n", macid, vifid, cmd_no);
135 		return NULL;
136 	}
137 
138 	skb_put_zero(cmd_skb, cmd_size);
139 
140 	cmd = (struct qlink_cmd *)cmd_skb->data;
141 	cmd->mhdr.len = cpu_to_le16(cmd_skb->len);
142 	cmd->mhdr.type = cpu_to_le16(QLINK_MSG_TYPE_CMD);
143 	cmd->cmd_id = cpu_to_le16(cmd_no);
144 	cmd->macid = macid;
145 	cmd->vifid = vifid;
146 
147 	return cmd_skb;
148 }
149 
150 static void qtnf_cmd_tlv_ie_set_add(struct sk_buff *cmd_skb, u8 frame_type,
151 				    const u8 *buf, size_t len)
152 {
153 	struct qlink_tlv_ie_set *tlv;
154 
155 	tlv = (struct qlink_tlv_ie_set *)skb_put(cmd_skb, sizeof(*tlv) + len);
156 	tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_IE_SET);
157 	tlv->hdr.len = cpu_to_le16(len + sizeof(*tlv) - sizeof(tlv->hdr));
158 	tlv->type = frame_type;
159 	tlv->flags = 0;
160 
161 	if (len && buf)
162 		memcpy(tlv->ie_data, buf, len);
163 }
164 
165 static bool qtnf_cmd_start_ap_can_fit(const struct qtnf_vif *vif,
166 				      const struct cfg80211_ap_settings *s)
167 {
168 	unsigned int len = sizeof(struct qlink_cmd_start_ap);
169 
170 	len += s->ssid_len;
171 	len += s->beacon.head_len;
172 	len += s->beacon.tail_len;
173 	len += s->beacon.beacon_ies_len;
174 	len += s->beacon.proberesp_ies_len;
175 	len += s->beacon.assocresp_ies_len;
176 	len += s->beacon.probe_resp_len;
177 
178 	if (cfg80211_chandef_valid(&s->chandef))
179 		len += sizeof(struct qlink_tlv_chandef);
180 
181 	if (len > (sizeof(struct qlink_cmd) + QTNF_MAX_CMD_BUF_SIZE)) {
182 		pr_err("VIF%u.%u: can not fit AP settings: %u\n",
183 		       vif->mac->macid, vif->vifid, len);
184 		return false;
185 	}
186 
187 	return true;
188 }
189 
190 int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
191 			   const struct cfg80211_ap_settings *s)
192 {
193 	struct sk_buff *cmd_skb;
194 	struct qlink_cmd_start_ap *cmd;
195 	struct qlink_auth_encr *aen;
196 	u16 res_code = QLINK_CMD_RESULT_OK;
197 	int ret;
198 	int i;
199 
200 	if (!qtnf_cmd_start_ap_can_fit(vif, s))
201 		return -E2BIG;
202 
203 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
204 					    QLINK_CMD_START_AP,
205 					    sizeof(*cmd));
206 	if (unlikely(!cmd_skb))
207 		return -ENOMEM;
208 
209 	cmd = (struct qlink_cmd_start_ap *)cmd_skb->data;
210 	cmd->dtim_period = s->dtim_period;
211 	cmd->beacon_interval = cpu_to_le16(s->beacon_interval);
212 	cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid);
213 	cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout);
214 	cmd->smps_mode = s->smps_mode;
215 	cmd->p2p_ctwindow = s->p2p_ctwindow;
216 	cmd->p2p_opp_ps = s->p2p_opp_ps;
217 	cmd->pbss = s->pbss;
218 	cmd->ht_required = s->ht_required;
219 	cmd->vht_required = s->vht_required;
220 
221 	aen = &cmd->aen;
222 	aen->auth_type = s->auth_type;
223 	aen->privacy = !!s->privacy;
224 	aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions);
225 	aen->cipher_group = cpu_to_le32(s->crypto.cipher_group);
226 	aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise);
227 	for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
228 		aen->ciphers_pairwise[i] =
229 				cpu_to_le32(s->crypto.ciphers_pairwise[i]);
230 	aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites);
231 	for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
232 		aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]);
233 	aen->control_port = s->crypto.control_port;
234 	aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt;
235 	aen->control_port_ethertype =
236 		cpu_to_le16(be16_to_cpu(s->crypto.control_port_ethertype));
237 
238 	if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN)
239 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid,
240 					 s->ssid_len);
241 
242 	if (cfg80211_chandef_valid(&s->chandef)) {
243 		struct qlink_tlv_chandef *chtlv =
244 			(struct qlink_tlv_chandef *)skb_put(cmd_skb,
245 							    sizeof(*chtlv));
246 
247 		chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF);
248 		chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) -
249 					     sizeof(chtlv->hdr));
250 		qlink_chandef_cfg2q(&s->chandef, &chtlv->chan);
251 	}
252 
253 	qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_HEAD,
254 				s->beacon.head, s->beacon.head_len);
255 	qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_TAIL,
256 				s->beacon.tail, s->beacon.tail_len);
257 	qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_IES,
258 				s->beacon.beacon_ies, s->beacon.beacon_ies_len);
259 	qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP,
260 				s->beacon.probe_resp, s->beacon.probe_resp_len);
261 	qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP_IES,
262 				s->beacon.proberesp_ies,
263 				s->beacon.proberesp_ies_len);
264 	qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_RESP,
265 				s->beacon.assocresp_ies,
266 				s->beacon.assocresp_ies_len);
267 
268 	if (s->ht_cap) {
269 		struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *)
270 			skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->ht_cap));
271 
272 		tlv->type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
273 		tlv->len = cpu_to_le16(sizeof(*s->ht_cap));
274 		memcpy(tlv->val, s->ht_cap, sizeof(*s->ht_cap));
275 	}
276 
277 	if (s->vht_cap) {
278 		struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *)
279 			skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->vht_cap));
280 
281 		tlv->type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
282 		tlv->len = cpu_to_le16(sizeof(*s->vht_cap));
283 		memcpy(tlv->val, s->vht_cap, sizeof(*s->vht_cap));
284 	}
285 
286 	qtnf_bus_lock(vif->mac->bus);
287 
288 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
289 
290 	if (unlikely(ret))
291 		goto out;
292 
293 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
294 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
295 		       vif->vifid, res_code);
296 		ret = -EFAULT;
297 		goto out;
298 	}
299 
300 	netif_carrier_on(vif->netdev);
301 
302 out:
303 	qtnf_bus_unlock(vif->mac->bus);
304 	return ret;
305 }
306 
307 int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif)
308 {
309 	struct sk_buff *cmd_skb;
310 	u16 res_code = QLINK_CMD_RESULT_OK;
311 	int ret;
312 
313 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
314 					    QLINK_CMD_STOP_AP,
315 					    sizeof(struct qlink_cmd));
316 	if (unlikely(!cmd_skb))
317 		return -ENOMEM;
318 
319 	qtnf_bus_lock(vif->mac->bus);
320 
321 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
322 
323 	if (unlikely(ret))
324 		goto out;
325 
326 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
327 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
328 		       vif->vifid, res_code);
329 		ret = -EFAULT;
330 		goto out;
331 	}
332 
333 	netif_carrier_off(vif->netdev);
334 
335 out:
336 	qtnf_bus_unlock(vif->mac->bus);
337 	return ret;
338 }
339 
340 int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg)
341 {
342 	struct sk_buff *cmd_skb;
343 	struct qlink_cmd_mgmt_frame_register *cmd;
344 	u16 res_code = QLINK_CMD_RESULT_OK;
345 	int ret;
346 
347 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
348 					    QLINK_CMD_REGISTER_MGMT,
349 					    sizeof(*cmd));
350 	if (unlikely(!cmd_skb))
351 		return -ENOMEM;
352 
353 	qtnf_bus_lock(vif->mac->bus);
354 
355 	cmd = (struct qlink_cmd_mgmt_frame_register *)cmd_skb->data;
356 	cmd->frame_type = cpu_to_le16(frame_type);
357 	cmd->do_register = reg;
358 
359 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
360 
361 	if (unlikely(ret))
362 		goto out;
363 
364 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
365 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
366 		       vif->vifid, res_code);
367 		ret = -EFAULT;
368 		goto out;
369 	}
370 
371 out:
372 	qtnf_bus_unlock(vif->mac->bus);
373 	return ret;
374 }
375 
376 int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
377 			     u16 freq, const u8 *buf, size_t len)
378 {
379 	struct sk_buff *cmd_skb;
380 	struct qlink_cmd_mgmt_frame_tx *cmd;
381 	u16 res_code = QLINK_CMD_RESULT_OK;
382 	int ret;
383 
384 	if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) {
385 		pr_warn("VIF%u.%u: frame is too big: %zu\n", vif->mac->macid,
386 			vif->vifid, len);
387 		return -E2BIG;
388 	}
389 
390 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
391 					    QLINK_CMD_SEND_MGMT_FRAME,
392 					    sizeof(*cmd));
393 	if (unlikely(!cmd_skb))
394 		return -ENOMEM;
395 
396 	qtnf_bus_lock(vif->mac->bus);
397 
398 	cmd = (struct qlink_cmd_mgmt_frame_tx *)cmd_skb->data;
399 	cmd->cookie = cpu_to_le32(cookie);
400 	cmd->freq = cpu_to_le16(freq);
401 	cmd->flags = cpu_to_le16(flags);
402 
403 	if (len && buf)
404 		qtnf_cmd_skb_put_buffer(cmd_skb, buf, len);
405 
406 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
407 
408 	if (unlikely(ret))
409 		goto out;
410 
411 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
412 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
413 		       vif->vifid, res_code);
414 		ret = -EFAULT;
415 		goto out;
416 	}
417 
418 out:
419 	qtnf_bus_unlock(vif->mac->bus);
420 	return ret;
421 }
422 
423 int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type,
424 				 const u8 *buf, size_t len)
425 {
426 	struct sk_buff *cmd_skb;
427 	u16 res_code = QLINK_CMD_RESULT_OK;
428 	int ret;
429 
430 	if (len > QTNF_MAX_CMD_BUF_SIZE) {
431 		pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid,
432 			vif->vifid, frame_type, len);
433 		return -E2BIG;
434 	}
435 
436 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
437 					    QLINK_CMD_MGMT_SET_APPIE,
438 					    sizeof(struct qlink_cmd));
439 	if (unlikely(!cmd_skb))
440 		return -ENOMEM;
441 
442 	qtnf_cmd_tlv_ie_set_add(cmd_skb, frame_type, buf, len);
443 
444 	qtnf_bus_lock(vif->mac->bus);
445 
446 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
447 
448 	if (unlikely(ret))
449 		goto out;
450 
451 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
452 		pr_err("VIF%u.%u frame %u: CMD failed: %u\n", vif->mac->macid,
453 		       vif->vifid, frame_type, res_code);
454 		ret = -EFAULT;
455 		goto out;
456 	}
457 
458 out:
459 	qtnf_bus_unlock(vif->mac->bus);
460 	return ret;
461 }
462 
463 static void
464 qtnf_sta_info_parse_basic_counters(struct station_info *sinfo,
465 		const struct qlink_sta_stat_basic_counters *counters)
466 {
467 	sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES) |
468 			 BIT(NL80211_STA_INFO_TX_BYTES);
469 	sinfo->rx_bytes = get_unaligned_le64(&counters->rx_bytes);
470 	sinfo->tx_bytes = get_unaligned_le64(&counters->tx_bytes);
471 
472 	sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
473 			 BIT(NL80211_STA_INFO_TX_PACKETS) |
474 			 BIT(NL80211_STA_INFO_BEACON_RX);
475 	sinfo->rx_packets = get_unaligned_le32(&counters->rx_packets);
476 	sinfo->tx_packets = get_unaligned_le32(&counters->tx_packets);
477 	sinfo->rx_beacon = get_unaligned_le64(&counters->rx_beacons);
478 
479 	sinfo->filled |= BIT(NL80211_STA_INFO_RX_DROP_MISC) |
480 			 BIT(NL80211_STA_INFO_TX_FAILED);
481 	sinfo->rx_dropped_misc = get_unaligned_le32(&counters->rx_dropped);
482 	sinfo->tx_failed = get_unaligned_le32(&counters->tx_failed);
483 }
484 
485 static void
486 qtnf_sta_info_parse_rate(struct rate_info *rate_dst,
487 			 const struct  qlink_sta_info_rate *rate_src)
488 {
489 	rate_dst->legacy = get_unaligned_le16(&rate_src->rate) * 10;
490 
491 	rate_dst->mcs = rate_src->mcs;
492 	rate_dst->nss = rate_src->nss;
493 	rate_dst->flags = 0;
494 
495 	switch (rate_src->bw) {
496 	case QLINK_STA_INFO_RATE_BW_5:
497 		rate_dst->bw = RATE_INFO_BW_5;
498 		break;
499 	case QLINK_STA_INFO_RATE_BW_10:
500 		rate_dst->bw = RATE_INFO_BW_10;
501 		break;
502 	case QLINK_STA_INFO_RATE_BW_20:
503 		rate_dst->bw = RATE_INFO_BW_20;
504 		break;
505 	case QLINK_STA_INFO_RATE_BW_40:
506 		rate_dst->bw = RATE_INFO_BW_40;
507 		break;
508 	case QLINK_STA_INFO_RATE_BW_80:
509 		rate_dst->bw = RATE_INFO_BW_80;
510 		break;
511 	case QLINK_STA_INFO_RATE_BW_160:
512 		rate_dst->bw = RATE_INFO_BW_160;
513 		break;
514 	default:
515 		rate_dst->bw = 0;
516 		break;
517 	}
518 
519 	if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_HT_MCS)
520 		rate_dst->flags |= RATE_INFO_FLAGS_MCS;
521 	else if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_VHT_MCS)
522 		rate_dst->flags |= RATE_INFO_FLAGS_VHT_MCS;
523 }
524 
525 static void
526 qtnf_sta_info_parse_flags(struct nl80211_sta_flag_update *dst,
527 			  const struct qlink_sta_info_state *src)
528 {
529 	u32 mask, value;
530 
531 	dst->mask = 0;
532 	dst->set = 0;
533 
534 	mask = le32_to_cpu(src->mask);
535 	value = le32_to_cpu(src->value);
536 
537 	if (mask & QLINK_STA_FLAG_AUTHORIZED) {
538 		dst->mask |= BIT(NL80211_STA_FLAG_AUTHORIZED);
539 		if (value & QLINK_STA_FLAG_AUTHORIZED)
540 			dst->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
541 	}
542 
543 	if (mask & QLINK_STA_FLAG_SHORT_PREAMBLE) {
544 		dst->mask |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
545 		if (value & QLINK_STA_FLAG_SHORT_PREAMBLE)
546 			dst->set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
547 	}
548 
549 	if (mask & QLINK_STA_FLAG_WME) {
550 		dst->mask |= BIT(NL80211_STA_FLAG_WME);
551 		if (value & QLINK_STA_FLAG_WME)
552 			dst->set |= BIT(NL80211_STA_FLAG_WME);
553 	}
554 
555 	if (mask & QLINK_STA_FLAG_MFP) {
556 		dst->mask |= BIT(NL80211_STA_FLAG_MFP);
557 		if (value & QLINK_STA_FLAG_MFP)
558 			dst->set |= BIT(NL80211_STA_FLAG_MFP);
559 	}
560 
561 	if (mask & QLINK_STA_FLAG_AUTHENTICATED) {
562 		dst->mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
563 		if (value & QLINK_STA_FLAG_AUTHENTICATED)
564 			dst->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
565 	}
566 
567 	if (mask & QLINK_STA_FLAG_TDLS_PEER) {
568 		dst->mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
569 		if (value & QLINK_STA_FLAG_TDLS_PEER)
570 			dst->set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
571 	}
572 
573 	if (mask & QLINK_STA_FLAG_ASSOCIATED) {
574 		dst->mask |= BIT(NL80211_STA_FLAG_ASSOCIATED);
575 		if (value & QLINK_STA_FLAG_ASSOCIATED)
576 			dst->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
577 	}
578 }
579 
580 static void
581 qtnf_sta_info_parse_generic_info(struct station_info *sinfo,
582 				 const struct qlink_sta_info_generic *info)
583 {
584 	sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME) |
585 			 BIT(NL80211_STA_INFO_INACTIVE_TIME);
586 	sinfo->connected_time = get_unaligned_le32(&info->connected_time);
587 	sinfo->inactive_time = get_unaligned_le32(&info->inactive_time);
588 
589 	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
590 			 BIT(NL80211_STA_INFO_SIGNAL_AVG);
591 	sinfo->signal = info->rssi - 120;
592 	sinfo->signal_avg = info->rssi_avg - QLINK_RSSI_OFFSET;
593 
594 	if (info->rx_rate.rate) {
595 		sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
596 		qtnf_sta_info_parse_rate(&sinfo->rxrate, &info->rx_rate);
597 	}
598 
599 	if (info->tx_rate.rate) {
600 		sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
601 		qtnf_sta_info_parse_rate(&sinfo->txrate, &info->tx_rate);
602 	}
603 
604 	sinfo->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
605 	qtnf_sta_info_parse_flags(&sinfo->sta_flags, &info->state);
606 }
607 
608 static int qtnf_cmd_sta_info_parse(struct station_info *sinfo,
609 				   const u8 *payload, size_t payload_size)
610 {
611 	const struct qlink_sta_stat_basic_counters *counters;
612 	const struct qlink_sta_info_generic *sta_info;
613 	u16 tlv_type;
614 	u16 tlv_value_len;
615 	size_t tlv_full_len;
616 	const struct qlink_tlv_hdr *tlv;
617 
618 	sinfo->filled = 0;
619 
620 	tlv = (const struct qlink_tlv_hdr *)payload;
621 	while (payload_size >= sizeof(struct qlink_tlv_hdr)) {
622 		tlv_type = le16_to_cpu(tlv->type);
623 		tlv_value_len = le16_to_cpu(tlv->len);
624 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
625 		if (tlv_full_len > payload_size) {
626 			pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
627 				tlv_type, tlv_value_len);
628 			return -EINVAL;
629 		}
630 		switch (tlv_type) {
631 		case QTN_TLV_ID_STA_BASIC_COUNTERS:
632 			if (unlikely(tlv_value_len < sizeof(*counters))) {
633 				pr_err("invalid TLV size %.4X: %u\n",
634 				       tlv_type, tlv_value_len);
635 				break;
636 			}
637 
638 			counters = (void *)tlv->val;
639 			qtnf_sta_info_parse_basic_counters(sinfo, counters);
640 			break;
641 		case QTN_TLV_ID_STA_GENERIC_INFO:
642 			if (unlikely(tlv_value_len < sizeof(*sta_info)))
643 				break;
644 
645 			sta_info = (void *)tlv->val;
646 			qtnf_sta_info_parse_generic_info(sinfo, sta_info);
647 			break;
648 		default:
649 			pr_warn("unexpected TLV type: %.4X\n", tlv_type);
650 			break;
651 		}
652 		payload_size -= tlv_full_len;
653 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
654 	}
655 
656 	if (payload_size) {
657 		pr_warn("malformed TLV buf; bytes left: %zu\n", payload_size);
658 		return -EINVAL;
659 	}
660 
661 	return 0;
662 }
663 
664 int qtnf_cmd_get_sta_info(struct qtnf_vif *vif, const u8 *sta_mac,
665 			  struct station_info *sinfo)
666 {
667 	struct sk_buff *cmd_skb, *resp_skb = NULL;
668 	struct qlink_cmd_get_sta_info *cmd;
669 	const struct qlink_resp_get_sta_info *resp;
670 	size_t var_resp_len;
671 	u16 res_code = QLINK_CMD_RESULT_OK;
672 	int ret = 0;
673 
674 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
675 					    QLINK_CMD_GET_STA_INFO,
676 					    sizeof(*cmd));
677 
678 	if (unlikely(!cmd_skb))
679 		return -ENOMEM;
680 
681 	qtnf_bus_lock(vif->mac->bus);
682 
683 	cmd = (struct qlink_cmd_get_sta_info *)cmd_skb->data;
684 	ether_addr_copy(cmd->sta_addr, sta_mac);
685 
686 	ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb,
687 				       &res_code, sizeof(*resp),
688 				       &var_resp_len);
689 
690 	if (unlikely(ret))
691 		goto out;
692 
693 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
694 		switch (res_code) {
695 		case QLINK_CMD_RESULT_ENOTFOUND:
696 			pr_warn("VIF%u.%u: %pM STA not found\n",
697 				vif->mac->macid, vif->vifid, sta_mac);
698 			ret = -ENOENT;
699 			break;
700 		default:
701 			pr_err("VIF%u.%u: can't get info for %pM: %u\n",
702 			       vif->mac->macid, vif->vifid, sta_mac, res_code);
703 			ret = -EFAULT;
704 			break;
705 		}
706 		goto out;
707 	}
708 
709 	resp = (const struct qlink_resp_get_sta_info *)resp_skb->data;
710 
711 	if (unlikely(!ether_addr_equal(sta_mac, resp->sta_addr))) {
712 		pr_err("VIF%u.%u: wrong mac in reply: %pM != %pM\n",
713 		       vif->mac->macid, vif->vifid, resp->sta_addr, sta_mac);
714 		ret = -EINVAL;
715 		goto out;
716 	}
717 
718 	ret = qtnf_cmd_sta_info_parse(sinfo, resp->info, var_resp_len);
719 
720 out:
721 	qtnf_bus_unlock(vif->mac->bus);
722 	consume_skb(resp_skb);
723 
724 	return ret;
725 }
726 
727 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
728 					 enum nl80211_iftype iftype,
729 					 u8 *mac_addr,
730 					 enum qlink_cmd_type cmd_type)
731 {
732 	struct sk_buff *cmd_skb, *resp_skb = NULL;
733 	struct qlink_cmd_manage_intf *cmd;
734 	const struct qlink_resp_manage_intf *resp;
735 	u16 res_code = QLINK_CMD_RESULT_OK;
736 	int ret = 0;
737 
738 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
739 					    cmd_type,
740 					    sizeof(*cmd));
741 	if (unlikely(!cmd_skb))
742 		return -ENOMEM;
743 
744 	qtnf_bus_lock(vif->mac->bus);
745 
746 	cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
747 
748 	switch (iftype) {
749 	case NL80211_IFTYPE_AP:
750 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP);
751 		break;
752 	case NL80211_IFTYPE_STATION:
753 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION);
754 		break;
755 	default:
756 		pr_err("VIF%u.%u: unsupported type %d\n", vif->mac->macid,
757 		       vif->vifid, iftype);
758 		ret = -EINVAL;
759 		goto out;
760 	}
761 
762 	if (mac_addr)
763 		ether_addr_copy(cmd->intf_info.mac_addr, mac_addr);
764 	else
765 		eth_zero_addr(cmd->intf_info.mac_addr);
766 
767 	ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb,
768 				       &res_code, sizeof(*resp), NULL);
769 
770 	if (unlikely(ret))
771 		goto out;
772 
773 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
774 		pr_err("VIF%u.%u: CMD %d failed: %u\n", vif->mac->macid,
775 		       vif->vifid, cmd_type, res_code);
776 		ret = -EFAULT;
777 		goto out;
778 	}
779 
780 	resp = (const struct qlink_resp_manage_intf *)resp_skb->data;
781 	ether_addr_copy(vif->mac_addr, resp->intf_info.mac_addr);
782 
783 out:
784 	qtnf_bus_unlock(vif->mac->bus);
785 	consume_skb(resp_skb);
786 
787 	return ret;
788 }
789 
790 int qtnf_cmd_send_add_intf(struct qtnf_vif *vif,
791 			   enum nl80211_iftype iftype, u8 *mac_addr)
792 {
793 	return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr,
794 			QLINK_CMD_ADD_INTF);
795 }
796 
797 int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
798 				   enum nl80211_iftype iftype, u8 *mac_addr)
799 {
800 	return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr,
801 					     QLINK_CMD_CHANGE_INTF);
802 }
803 
804 int qtnf_cmd_send_del_intf(struct qtnf_vif *vif)
805 {
806 	struct sk_buff *cmd_skb;
807 	struct qlink_cmd_manage_intf *cmd;
808 	u16 res_code = QLINK_CMD_RESULT_OK;
809 	int ret = 0;
810 
811 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
812 					    QLINK_CMD_DEL_INTF,
813 					    sizeof(*cmd));
814 	if (unlikely(!cmd_skb))
815 		return -ENOMEM;
816 
817 	qtnf_bus_lock(vif->mac->bus);
818 
819 	cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
820 
821 	switch (vif->wdev.iftype) {
822 	case NL80211_IFTYPE_AP:
823 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP);
824 		break;
825 	case NL80211_IFTYPE_STATION:
826 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION);
827 		break;
828 	default:
829 		pr_warn("VIF%u.%u: unsupported iftype %d\n", vif->mac->macid,
830 			vif->vifid, vif->wdev.iftype);
831 		ret = -EINVAL;
832 		goto out;
833 	}
834 
835 	eth_zero_addr(cmd->intf_info.mac_addr);
836 
837 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
838 
839 	if (unlikely(ret))
840 		goto out;
841 
842 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
843 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
844 		       vif->vifid, res_code);
845 		ret = -EFAULT;
846 		goto out;
847 	}
848 
849 out:
850 	qtnf_bus_unlock(vif->mac->bus);
851 	return ret;
852 }
853 
854 static u32 qtnf_cmd_resp_reg_rule_flags_parse(u32 qflags)
855 {
856 	u32 flags = 0;
857 
858 	if (qflags & QLINK_RRF_NO_OFDM)
859 		flags |= NL80211_RRF_NO_OFDM;
860 
861 	if (qflags & QLINK_RRF_NO_CCK)
862 		flags |= NL80211_RRF_NO_CCK;
863 
864 	if (qflags & QLINK_RRF_NO_INDOOR)
865 		flags |= NL80211_RRF_NO_INDOOR;
866 
867 	if (qflags & QLINK_RRF_NO_OUTDOOR)
868 		flags |= NL80211_RRF_NO_OUTDOOR;
869 
870 	if (qflags & QLINK_RRF_DFS)
871 		flags |= NL80211_RRF_DFS;
872 
873 	if (qflags & QLINK_RRF_PTP_ONLY)
874 		flags |= NL80211_RRF_PTP_ONLY;
875 
876 	if (qflags & QLINK_RRF_PTMP_ONLY)
877 		flags |= NL80211_RRF_PTMP_ONLY;
878 
879 	if (qflags & QLINK_RRF_NO_IR)
880 		flags |= NL80211_RRF_NO_IR;
881 
882 	if (qflags & QLINK_RRF_AUTO_BW)
883 		flags |= NL80211_RRF_AUTO_BW;
884 
885 	if (qflags & QLINK_RRF_IR_CONCURRENT)
886 		flags |= NL80211_RRF_IR_CONCURRENT;
887 
888 	if (qflags & QLINK_RRF_NO_HT40MINUS)
889 		flags |= NL80211_RRF_NO_HT40MINUS;
890 
891 	if (qflags & QLINK_RRF_NO_HT40PLUS)
892 		flags |= NL80211_RRF_NO_HT40PLUS;
893 
894 	if (qflags & QLINK_RRF_NO_80MHZ)
895 		flags |= NL80211_RRF_NO_80MHZ;
896 
897 	if (qflags & QLINK_RRF_NO_160MHZ)
898 		flags |= NL80211_RRF_NO_160MHZ;
899 
900 	return flags;
901 }
902 
903 static int
904 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
905 			   const struct qlink_resp_get_hw_info *resp,
906 			   size_t info_len)
907 {
908 	struct qtnf_hw_info *hwinfo = &bus->hw_info;
909 	const struct qlink_tlv_hdr *tlv;
910 	const struct qlink_tlv_reg_rule *tlv_rule;
911 	struct ieee80211_reg_rule *rule;
912 	u16 tlv_type;
913 	u16 tlv_value_len;
914 	unsigned int rule_idx = 0;
915 
916 	if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES))
917 		return -E2BIG;
918 
919 	hwinfo->rd = kzalloc(sizeof(*hwinfo->rd)
920 			     + sizeof(struct ieee80211_reg_rule)
921 			     * resp->n_reg_rules, GFP_KERNEL);
922 
923 	if (!hwinfo->rd)
924 		return -ENOMEM;
925 
926 	hwinfo->num_mac = resp->num_mac;
927 	hwinfo->mac_bitmap = resp->mac_bitmap;
928 	hwinfo->fw_ver = le32_to_cpu(resp->fw_ver);
929 	hwinfo->ql_proto_ver = le16_to_cpu(resp->ql_proto_ver);
930 	hwinfo->total_tx_chain = resp->total_tx_chain;
931 	hwinfo->total_rx_chain = resp->total_rx_chain;
932 	hwinfo->hw_capab = le32_to_cpu(resp->hw_capab);
933 	hwinfo->rd->n_reg_rules = resp->n_reg_rules;
934 	hwinfo->rd->alpha2[0] = resp->alpha2[0];
935 	hwinfo->rd->alpha2[1] = resp->alpha2[1];
936 
937 	switch (resp->dfs_region) {
938 	case QLINK_DFS_FCC:
939 		hwinfo->rd->dfs_region = NL80211_DFS_FCC;
940 		break;
941 	case QLINK_DFS_ETSI:
942 		hwinfo->rd->dfs_region = NL80211_DFS_ETSI;
943 		break;
944 	case QLINK_DFS_JP:
945 		hwinfo->rd->dfs_region = NL80211_DFS_JP;
946 		break;
947 	case QLINK_DFS_UNSET:
948 	default:
949 		hwinfo->rd->dfs_region = NL80211_DFS_UNSET;
950 		break;
951 	}
952 
953 	tlv = (const struct qlink_tlv_hdr *)resp->info;
954 
955 	while (info_len >= sizeof(*tlv)) {
956 		tlv_type = le16_to_cpu(tlv->type);
957 		tlv_value_len = le16_to_cpu(tlv->len);
958 
959 		if (tlv_value_len + sizeof(*tlv) > info_len) {
960 			pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
961 				tlv_type, tlv_value_len);
962 			return -EINVAL;
963 		}
964 
965 		switch (tlv_type) {
966 		case QTN_TLV_ID_REG_RULE:
967 			if (rule_idx >= resp->n_reg_rules) {
968 				pr_warn("unexpected number of rules: %u\n",
969 					resp->n_reg_rules);
970 				return -EINVAL;
971 			}
972 
973 			if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) {
974 				pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
975 					tlv_type, tlv_value_len);
976 				return -EINVAL;
977 			}
978 
979 			tlv_rule = (const struct qlink_tlv_reg_rule *)tlv;
980 			rule = &hwinfo->rd->reg_rules[rule_idx++];
981 
982 			rule->freq_range.start_freq_khz =
983 				le32_to_cpu(tlv_rule->start_freq_khz);
984 			rule->freq_range.end_freq_khz =
985 				le32_to_cpu(tlv_rule->end_freq_khz);
986 			rule->freq_range.max_bandwidth_khz =
987 				le32_to_cpu(tlv_rule->max_bandwidth_khz);
988 			rule->power_rule.max_antenna_gain =
989 				le32_to_cpu(tlv_rule->max_antenna_gain);
990 			rule->power_rule.max_eirp =
991 				le32_to_cpu(tlv_rule->max_eirp);
992 			rule->dfs_cac_ms =
993 				le32_to_cpu(tlv_rule->dfs_cac_ms);
994 			rule->flags = qtnf_cmd_resp_reg_rule_flags_parse(
995 					le32_to_cpu(tlv_rule->flags));
996 			break;
997 		default:
998 			break;
999 		}
1000 
1001 		info_len -= tlv_value_len + sizeof(*tlv);
1002 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
1003 	}
1004 
1005 	if (rule_idx != resp->n_reg_rules) {
1006 		pr_warn("unexpected number of rules: expected %u got %u\n",
1007 			resp->n_reg_rules, rule_idx);
1008 		kfree(hwinfo->rd);
1009 		hwinfo->rd = NULL;
1010 		return -EINVAL;
1011 	}
1012 
1013 	pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u, capab=0x%x\n",
1014 		hwinfo->fw_ver, hwinfo->mac_bitmap,
1015 		hwinfo->rd->alpha2[0], hwinfo->rd->alpha2[1],
1016 		hwinfo->total_tx_chain, hwinfo->total_rx_chain,
1017 		hwinfo->hw_capab);
1018 
1019 	return 0;
1020 }
1021 
1022 static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
1023 					const u8 *tlv_buf, size_t tlv_buf_size)
1024 {
1025 	struct ieee80211_iface_limit *limits = NULL;
1026 	const struct qlink_iface_limit *limit_record;
1027 	size_t record_count = 0, rec = 0;
1028 	u16 tlv_type, tlv_value_len;
1029 	struct qlink_iface_comb_num *comb;
1030 	size_t tlv_full_len;
1031 	const struct qlink_tlv_hdr *tlv;
1032 
1033 	mac->macinfo.n_limits = 0;
1034 
1035 	tlv = (const struct qlink_tlv_hdr *)tlv_buf;
1036 	while (tlv_buf_size >= sizeof(struct qlink_tlv_hdr)) {
1037 		tlv_type = le16_to_cpu(tlv->type);
1038 		tlv_value_len = le16_to_cpu(tlv->len);
1039 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
1040 		if (tlv_full_len > tlv_buf_size) {
1041 			pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n",
1042 				mac->macid, tlv_type, tlv_value_len);
1043 			return -EINVAL;
1044 		}
1045 
1046 		switch (tlv_type) {
1047 		case QTN_TLV_ID_NUM_IFACE_COMB:
1048 			if (unlikely(tlv_value_len != sizeof(*comb)))
1049 				return -EINVAL;
1050 
1051 			comb = (void *)tlv->val;
1052 			record_count = le16_to_cpu(comb->iface_comb_num);
1053 
1054 			mac->macinfo.n_limits = record_count;
1055 			/* free earlier iface limits memory */
1056 			kfree(mac->macinfo.limits);
1057 			mac->macinfo.limits =
1058 				kzalloc(sizeof(*mac->macinfo.limits) *
1059 					record_count, GFP_KERNEL);
1060 
1061 			if (unlikely(!mac->macinfo.limits))
1062 				return -ENOMEM;
1063 
1064 			limits = mac->macinfo.limits;
1065 			break;
1066 		case QTN_TLV_ID_IFACE_LIMIT:
1067 			if (unlikely(!limits)) {
1068 				pr_warn("MAC%u: limits are not inited\n",
1069 					mac->macid);
1070 				return -EINVAL;
1071 			}
1072 
1073 			if (unlikely(tlv_value_len != sizeof(*limit_record))) {
1074 				pr_warn("MAC%u: record size mismatch\n",
1075 					mac->macid);
1076 				return -EINVAL;
1077 			}
1078 
1079 			limit_record = (void *)tlv->val;
1080 			limits[rec].max = le16_to_cpu(limit_record->max_num);
1081 			limits[rec].types = qlink_iface_type_to_nl_mask(
1082 				le16_to_cpu(limit_record->type));
1083 
1084 			/* supported modes: STA, AP */
1085 			limits[rec].types &= BIT(NL80211_IFTYPE_AP) |
1086 					     BIT(NL80211_IFTYPE_AP_VLAN) |
1087 					     BIT(NL80211_IFTYPE_STATION);
1088 
1089 			pr_debug("MAC%u: MAX: %u; TYPES: %.4X\n", mac->macid,
1090 				 limits[rec].max, limits[rec].types);
1091 
1092 			if (limits[rec].types)
1093 				rec++;
1094 			break;
1095 		default:
1096 			break;
1097 		}
1098 
1099 		tlv_buf_size -= tlv_full_len;
1100 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
1101 	}
1102 
1103 	if (tlv_buf_size) {
1104 		pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n",
1105 			mac->macid, tlv_buf_size);
1106 		return -EINVAL;
1107 	}
1108 
1109 	if (mac->macinfo.n_limits != rec) {
1110 		pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n",
1111 		       mac->macid, mac->macinfo.n_limits, rec);
1112 		return -EINVAL;
1113 	}
1114 
1115 	return 0;
1116 }
1117 
1118 static void
1119 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac,
1120 			    const struct qlink_resp_get_mac_info *resp_info)
1121 {
1122 	struct qtnf_mac_info *mac_info;
1123 	struct qtnf_vif *vif;
1124 
1125 	mac_info = &mac->macinfo;
1126 
1127 	mac_info->bands_cap = resp_info->bands_cap;
1128 	memcpy(&mac_info->dev_mac, &resp_info->dev_mac,
1129 	       sizeof(mac_info->dev_mac));
1130 
1131 	ether_addr_copy(mac->macaddr, mac_info->dev_mac);
1132 
1133 	vif = qtnf_mac_get_base_vif(mac);
1134 	if (vif)
1135 		ether_addr_copy(vif->mac_addr, mac->macaddr);
1136 	else
1137 		pr_err("could not get valid base vif\n");
1138 
1139 	mac_info->num_tx_chain = resp_info->num_tx_chain;
1140 	mac_info->num_rx_chain = resp_info->num_rx_chain;
1141 
1142 	mac_info->max_ap_assoc_sta = le16_to_cpu(resp_info->max_ap_assoc_sta);
1143 	mac_info->radar_detect_widths =
1144 			qlink_chan_width_mask_to_nl(le16_to_cpu(
1145 					resp_info->radar_detect_widths));
1146 
1147 	memcpy(&mac_info->ht_cap_mod_mask, &resp_info->ht_cap_mod_mask,
1148 	       sizeof(mac_info->ht_cap_mod_mask));
1149 	memcpy(&mac_info->vht_cap_mod_mask, &resp_info->vht_cap_mod_mask,
1150 	       sizeof(mac_info->vht_cap_mod_mask));
1151 }
1152 
1153 static void qtnf_cmd_resp_band_fill_htcap(const u8 *info,
1154 					  struct ieee80211_sta_ht_cap *bcap)
1155 {
1156 	const struct ieee80211_ht_cap *ht_cap =
1157 		(const struct ieee80211_ht_cap *)info;
1158 
1159 	bcap->ht_supported = true;
1160 	bcap->cap = le16_to_cpu(ht_cap->cap_info);
1161 	bcap->ampdu_factor =
1162 		ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR;
1163 	bcap->ampdu_density =
1164 		(ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >>
1165 		IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
1166 	memcpy(&bcap->mcs, &ht_cap->mcs, sizeof(bcap->mcs));
1167 }
1168 
1169 static void qtnf_cmd_resp_band_fill_vhtcap(const u8 *info,
1170 					   struct ieee80211_sta_vht_cap *bcap)
1171 {
1172 	const struct ieee80211_vht_cap *vht_cap =
1173 		(const struct ieee80211_vht_cap *)info;
1174 
1175 	bcap->vht_supported = true;
1176 	bcap->cap = le32_to_cpu(vht_cap->vht_cap_info);
1177 	memcpy(&bcap->vht_mcs, &vht_cap->supp_mcs, sizeof(bcap->vht_mcs));
1178 }
1179 
1180 static int
1181 qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band *band,
1182 			     struct qlink_resp_band_info_get *resp,
1183 			     size_t payload_len)
1184 {
1185 	u16 tlv_type;
1186 	size_t tlv_len;
1187 	size_t tlv_dlen;
1188 	const struct qlink_tlv_hdr *tlv;
1189 	const struct qlink_tlv_channel *qchan;
1190 	struct ieee80211_channel *chan;
1191 	unsigned int chidx = 0;
1192 	u32 qflags;
1193 
1194 	memset(&band->ht_cap, 0, sizeof(band->ht_cap));
1195 	memset(&band->vht_cap, 0, sizeof(band->vht_cap));
1196 
1197 	if (band->channels) {
1198 		if (band->n_channels == resp->num_chans) {
1199 			memset(band->channels, 0,
1200 			       sizeof(*band->channels) * band->n_channels);
1201 		} else {
1202 			kfree(band->channels);
1203 			band->n_channels = 0;
1204 			band->channels = NULL;
1205 		}
1206 	}
1207 
1208 	band->n_channels = resp->num_chans;
1209 	if (band->n_channels == 0)
1210 		return 0;
1211 
1212 	if (!band->channels)
1213 		band->channels = kcalloc(band->n_channels, sizeof(*chan),
1214 					 GFP_KERNEL);
1215 	if (!band->channels) {
1216 		band->n_channels = 0;
1217 		return -ENOMEM;
1218 	}
1219 
1220 	tlv = (struct qlink_tlv_hdr *)resp->info;
1221 
1222 	while (payload_len >= sizeof(*tlv)) {
1223 		tlv_type = le16_to_cpu(tlv->type);
1224 		tlv_dlen = le16_to_cpu(tlv->len);
1225 		tlv_len = tlv_dlen + sizeof(*tlv);
1226 
1227 		if (tlv_len > payload_len) {
1228 			pr_warn("malformed TLV 0x%.2X; LEN: %zu\n",
1229 				tlv_type, tlv_len);
1230 			goto error_ret;
1231 		}
1232 
1233 		switch (tlv_type) {
1234 		case QTN_TLV_ID_CHANNEL:
1235 			if (unlikely(tlv_len != sizeof(*qchan))) {
1236 				pr_err("invalid channel TLV len %zu\n",
1237 				       tlv_len);
1238 				goto error_ret;
1239 			}
1240 
1241 			if (chidx == band->n_channels) {
1242 				pr_err("too many channel TLVs\n");
1243 				goto error_ret;
1244 			}
1245 
1246 			qchan = (const struct qlink_tlv_channel *)tlv;
1247 			chan = &band->channels[chidx++];
1248 			qflags = le32_to_cpu(qchan->flags);
1249 
1250 			chan->hw_value = le16_to_cpu(qchan->hw_value);
1251 			chan->band = band->band;
1252 			chan->center_freq = le16_to_cpu(qchan->center_freq);
1253 			chan->max_antenna_gain = (int)qchan->max_antenna_gain;
1254 			chan->max_power = (int)qchan->max_power;
1255 			chan->max_reg_power = (int)qchan->max_reg_power;
1256 			chan->beacon_found = qchan->beacon_found;
1257 			chan->dfs_cac_ms = le32_to_cpu(qchan->dfs_cac_ms);
1258 			chan->flags = 0;
1259 
1260 			if (qflags & QLINK_CHAN_DISABLED)
1261 				chan->flags |= IEEE80211_CHAN_DISABLED;
1262 
1263 			if (qflags & QLINK_CHAN_NO_IR)
1264 				chan->flags |= IEEE80211_CHAN_NO_IR;
1265 
1266 			if (qflags & QLINK_CHAN_NO_HT40PLUS)
1267 				chan->flags |= IEEE80211_CHAN_NO_HT40PLUS;
1268 
1269 			if (qflags & QLINK_CHAN_NO_HT40MINUS)
1270 				chan->flags |= IEEE80211_CHAN_NO_HT40MINUS;
1271 
1272 			if (qflags & QLINK_CHAN_NO_OFDM)
1273 				chan->flags |= IEEE80211_CHAN_NO_OFDM;
1274 
1275 			if (qflags & QLINK_CHAN_NO_80MHZ)
1276 				chan->flags |= IEEE80211_CHAN_NO_80MHZ;
1277 
1278 			if (qflags & QLINK_CHAN_NO_160MHZ)
1279 				chan->flags |= IEEE80211_CHAN_NO_160MHZ;
1280 
1281 			if (qflags & QLINK_CHAN_INDOOR_ONLY)
1282 				chan->flags |= IEEE80211_CHAN_INDOOR_ONLY;
1283 
1284 			if (qflags & QLINK_CHAN_IR_CONCURRENT)
1285 				chan->flags |= IEEE80211_CHAN_IR_CONCURRENT;
1286 
1287 			if (qflags & QLINK_CHAN_NO_20MHZ)
1288 				chan->flags |= IEEE80211_CHAN_NO_20MHZ;
1289 
1290 			if (qflags & QLINK_CHAN_NO_10MHZ)
1291 				chan->flags |= IEEE80211_CHAN_NO_10MHZ;
1292 
1293 			if (qflags & QLINK_CHAN_RADAR) {
1294 				chan->flags |= IEEE80211_CHAN_RADAR;
1295 				chan->dfs_state_entered = jiffies;
1296 
1297 				if (qchan->dfs_state == QLINK_DFS_USABLE)
1298 					chan->dfs_state = NL80211_DFS_USABLE;
1299 				else if (qchan->dfs_state ==
1300 					QLINK_DFS_AVAILABLE)
1301 					chan->dfs_state = NL80211_DFS_AVAILABLE;
1302 				else
1303 					chan->dfs_state =
1304 						NL80211_DFS_UNAVAILABLE;
1305 			}
1306 
1307 			pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n",
1308 				 chan->hw_value, chan->flags, chan->max_power,
1309 				 chan->max_reg_power);
1310 			break;
1311 		case WLAN_EID_HT_CAPABILITY:
1312 			if (unlikely(tlv_dlen !=
1313 				     sizeof(struct ieee80211_ht_cap))) {
1314 				pr_err("bad HTCAP TLV len %zu\n", tlv_dlen);
1315 				goto error_ret;
1316 			}
1317 
1318 			qtnf_cmd_resp_band_fill_htcap(tlv->val, &band->ht_cap);
1319 			break;
1320 		case WLAN_EID_VHT_CAPABILITY:
1321 			if (unlikely(tlv_dlen !=
1322 				     sizeof(struct ieee80211_vht_cap))) {
1323 				pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen);
1324 				goto error_ret;
1325 			}
1326 
1327 			qtnf_cmd_resp_band_fill_vhtcap(tlv->val,
1328 						       &band->vht_cap);
1329 			break;
1330 		default:
1331 			pr_warn("unknown TLV type: %#x\n", tlv_type);
1332 			break;
1333 		}
1334 
1335 		payload_len -= tlv_len;
1336 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_dlen);
1337 	}
1338 
1339 	if (payload_len) {
1340 		pr_err("malformed TLV buf; bytes left: %zu\n", payload_len);
1341 		goto error_ret;
1342 	}
1343 
1344 	if (band->n_channels != chidx) {
1345 		pr_err("channel count mismatch: reported=%d, parsed=%d\n",
1346 		       band->n_channels, chidx);
1347 		goto error_ret;
1348 	}
1349 
1350 	return 0;
1351 
1352 error_ret:
1353 	kfree(band->channels);
1354 	band->channels = NULL;
1355 	band->n_channels = 0;
1356 
1357 	return -EINVAL;
1358 }
1359 
1360 static int qtnf_cmd_resp_proc_phy_params(struct qtnf_wmac *mac,
1361 					 const u8 *payload, size_t payload_len)
1362 {
1363 	struct qtnf_mac_info *mac_info;
1364 	struct qlink_tlv_frag_rts_thr *phy_thr;
1365 	struct qlink_tlv_rlimit *limit;
1366 	struct qlink_tlv_cclass *class;
1367 	u16 tlv_type;
1368 	u16 tlv_value_len;
1369 	size_t tlv_full_len;
1370 	const struct qlink_tlv_hdr *tlv;
1371 
1372 	mac_info = &mac->macinfo;
1373 
1374 	tlv = (struct qlink_tlv_hdr *)payload;
1375 	while (payload_len >= sizeof(struct qlink_tlv_hdr)) {
1376 		tlv_type = le16_to_cpu(tlv->type);
1377 		tlv_value_len = le16_to_cpu(tlv->len);
1378 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
1379 
1380 		if (tlv_full_len > payload_len) {
1381 			pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n",
1382 				mac->macid, tlv_type, tlv_value_len);
1383 			return -EINVAL;
1384 		}
1385 
1386 		switch (tlv_type) {
1387 		case QTN_TLV_ID_FRAG_THRESH:
1388 			phy_thr = (void *)tlv;
1389 			mac_info->frag_thr = (u32)le16_to_cpu(phy_thr->thr);
1390 			break;
1391 		case QTN_TLV_ID_RTS_THRESH:
1392 			phy_thr = (void *)tlv;
1393 			mac_info->rts_thr = (u32)le16_to_cpu(phy_thr->thr);
1394 			break;
1395 		case QTN_TLV_ID_SRETRY_LIMIT:
1396 			limit = (void *)tlv;
1397 			mac_info->sretry_limit = limit->rlimit;
1398 			break;
1399 		case QTN_TLV_ID_LRETRY_LIMIT:
1400 			limit = (void *)tlv;
1401 			mac_info->lretry_limit = limit->rlimit;
1402 			break;
1403 		case QTN_TLV_ID_COVERAGE_CLASS:
1404 			class = (void *)tlv;
1405 			mac_info->coverage_class = class->cclass;
1406 			break;
1407 		default:
1408 			pr_err("MAC%u: Unknown TLV type: %#x\n", mac->macid,
1409 			       le16_to_cpu(tlv->type));
1410 			break;
1411 		}
1412 
1413 		payload_len -= tlv_full_len;
1414 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
1415 	}
1416 
1417 	if (payload_len) {
1418 		pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n",
1419 			mac->macid, payload_len);
1420 		return -EINVAL;
1421 	}
1422 
1423 	return 0;
1424 }
1425 
1426 static int
1427 qtnf_cmd_resp_proc_chan_stat_info(struct qtnf_chan_stats *stats,
1428 				  const u8 *payload, size_t payload_len)
1429 {
1430 	struct qlink_chan_stats *qlink_stats;
1431 	const struct qlink_tlv_hdr *tlv;
1432 	size_t tlv_full_len;
1433 	u16 tlv_value_len;
1434 	u16 tlv_type;
1435 
1436 	tlv = (struct qlink_tlv_hdr *)payload;
1437 	while (payload_len >= sizeof(struct qlink_tlv_hdr)) {
1438 		tlv_type = le16_to_cpu(tlv->type);
1439 		tlv_value_len = le16_to_cpu(tlv->len);
1440 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
1441 		if (tlv_full_len > payload_len) {
1442 			pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
1443 				tlv_type, tlv_value_len);
1444 			return -EINVAL;
1445 		}
1446 		switch (tlv_type) {
1447 		case QTN_TLV_ID_CHANNEL_STATS:
1448 			if (unlikely(tlv_value_len != sizeof(*qlink_stats))) {
1449 				pr_err("invalid CHANNEL_STATS entry size\n");
1450 				return -EINVAL;
1451 			}
1452 
1453 			qlink_stats = (void *)tlv->val;
1454 
1455 			stats->chan_num = le32_to_cpu(qlink_stats->chan_num);
1456 			stats->cca_tx = le32_to_cpu(qlink_stats->cca_tx);
1457 			stats->cca_rx = le32_to_cpu(qlink_stats->cca_rx);
1458 			stats->cca_busy = le32_to_cpu(qlink_stats->cca_busy);
1459 			stats->cca_try = le32_to_cpu(qlink_stats->cca_try);
1460 			stats->chan_noise = qlink_stats->chan_noise;
1461 
1462 			pr_debug("chan(%u) try(%u) busy(%u) noise(%d)\n",
1463 				 stats->chan_num, stats->cca_try,
1464 				 stats->cca_busy, stats->chan_noise);
1465 			break;
1466 		default:
1467 			pr_warn("Unknown TLV type: %#x\n",
1468 				le16_to_cpu(tlv->type));
1469 		}
1470 		payload_len -= tlv_full_len;
1471 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
1472 	}
1473 
1474 	if (payload_len) {
1475 		pr_warn("malformed TLV buf; bytes left: %zu\n", payload_len);
1476 		return -EINVAL;
1477 	}
1478 
1479 	return 0;
1480 }
1481 
1482 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac)
1483 {
1484 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1485 	const struct qlink_resp_get_mac_info *resp;
1486 	size_t var_data_len;
1487 	u16 res_code = QLINK_CMD_RESULT_OK;
1488 	int ret = 0;
1489 
1490 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
1491 					    QLINK_CMD_MAC_INFO,
1492 					    sizeof(struct qlink_cmd));
1493 	if (unlikely(!cmd_skb))
1494 		return -ENOMEM;
1495 
1496 	qtnf_bus_lock(mac->bus);
1497 
1498 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
1499 				       sizeof(*resp), &var_data_len);
1500 	if (unlikely(ret))
1501 		goto out;
1502 
1503 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1504 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1505 		ret = -EFAULT;
1506 		goto out;
1507 	}
1508 
1509 	resp = (const struct qlink_resp_get_mac_info *)resp_skb->data;
1510 	qtnf_cmd_resp_proc_mac_info(mac, resp);
1511 	ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len);
1512 
1513 out:
1514 	qtnf_bus_unlock(mac->bus);
1515 	consume_skb(resp_skb);
1516 
1517 	return ret;
1518 }
1519 
1520 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus)
1521 {
1522 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1523 	const struct qlink_resp_get_hw_info *resp;
1524 	u16 res_code = QLINK_CMD_RESULT_OK;
1525 	int ret = 0;
1526 	size_t info_len;
1527 
1528 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
1529 					    QLINK_CMD_GET_HW_INFO,
1530 					    sizeof(struct qlink_cmd));
1531 	if (unlikely(!cmd_skb))
1532 		return -ENOMEM;
1533 
1534 	qtnf_bus_lock(bus);
1535 
1536 	ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code,
1537 				       sizeof(*resp), &info_len);
1538 
1539 	if (unlikely(ret))
1540 		goto out;
1541 
1542 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1543 		pr_err("cmd exec failed: 0x%.4X\n", res_code);
1544 		ret = -EFAULT;
1545 		goto out;
1546 	}
1547 
1548 	resp = (const struct qlink_resp_get_hw_info *)resp_skb->data;
1549 	ret = qtnf_cmd_resp_proc_hw_info(bus, resp, info_len);
1550 
1551 out:
1552 	qtnf_bus_unlock(bus);
1553 	consume_skb(resp_skb);
1554 
1555 	return ret;
1556 }
1557 
1558 int qtnf_cmd_band_info_get(struct qtnf_wmac *mac,
1559 			   struct ieee80211_supported_band *band)
1560 {
1561 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1562 	size_t info_len;
1563 	struct qlink_cmd_band_info_get *cmd;
1564 	struct qlink_resp_band_info_get *resp;
1565 	u16 res_code = QLINK_CMD_RESULT_OK;
1566 	int ret = 0;
1567 	u8 qband;
1568 
1569 	switch (band->band) {
1570 	case NL80211_BAND_2GHZ:
1571 		qband = QLINK_BAND_2GHZ;
1572 		break;
1573 	case NL80211_BAND_5GHZ:
1574 		qband = QLINK_BAND_5GHZ;
1575 		break;
1576 	case NL80211_BAND_60GHZ:
1577 		qband = QLINK_BAND_60GHZ;
1578 		break;
1579 	default:
1580 		return -EINVAL;
1581 	}
1582 
1583 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1584 					    QLINK_CMD_BAND_INFO_GET,
1585 					    sizeof(*cmd));
1586 	if (!cmd_skb)
1587 		return -ENOMEM;
1588 
1589 	cmd = (struct qlink_cmd_band_info_get *)cmd_skb->data;
1590 	cmd->band = qband;
1591 
1592 	qtnf_bus_lock(mac->bus);
1593 
1594 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
1595 				       sizeof(*resp), &info_len);
1596 
1597 	if (unlikely(ret))
1598 		goto out;
1599 
1600 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1601 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1602 		ret = -EFAULT;
1603 		goto out;
1604 	}
1605 
1606 	resp = (struct qlink_resp_band_info_get *)resp_skb->data;
1607 	if (resp->band != qband) {
1608 		pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid,
1609 		       resp->band, qband);
1610 		ret = -EINVAL;
1611 		goto out;
1612 	}
1613 
1614 	ret = qtnf_cmd_resp_fill_band_info(band, resp, info_len);
1615 
1616 out:
1617 	qtnf_bus_unlock(mac->bus);
1618 	consume_skb(resp_skb);
1619 
1620 	return ret;
1621 }
1622 
1623 int qtnf_cmd_send_get_phy_params(struct qtnf_wmac *mac)
1624 {
1625 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1626 	size_t response_size;
1627 	struct qlink_resp_phy_params *resp;
1628 	u16 res_code = QLINK_CMD_RESULT_OK;
1629 	int ret = 0;
1630 
1631 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1632 					    QLINK_CMD_PHY_PARAMS_GET,
1633 					    sizeof(struct qlink_cmd));
1634 	if (!cmd_skb)
1635 		return -ENOMEM;
1636 
1637 	qtnf_bus_lock(mac->bus);
1638 
1639 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
1640 				       sizeof(*resp), &response_size);
1641 
1642 	if (unlikely(ret))
1643 		goto out;
1644 
1645 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1646 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1647 		ret = -EFAULT;
1648 		goto out;
1649 	}
1650 
1651 	resp = (struct qlink_resp_phy_params *)resp_skb->data;
1652 	ret = qtnf_cmd_resp_proc_phy_params(mac, resp->info, response_size);
1653 
1654 out:
1655 	qtnf_bus_unlock(mac->bus);
1656 	consume_skb(resp_skb);
1657 
1658 	return ret;
1659 }
1660 
1661 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed)
1662 {
1663 	struct wiphy *wiphy = priv_to_wiphy(mac);
1664 	struct sk_buff *cmd_skb;
1665 	u16 res_code = QLINK_CMD_RESULT_OK;
1666 	int ret = 0;
1667 
1668 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1669 					    QLINK_CMD_PHY_PARAMS_SET,
1670 					    sizeof(struct qlink_cmd));
1671 	if (!cmd_skb)
1672 		return -ENOMEM;
1673 
1674 	qtnf_bus_lock(mac->bus);
1675 
1676 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
1677 		qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_FRAG_THRESH,
1678 					 wiphy->frag_threshold);
1679 	if (changed & WIPHY_PARAM_RTS_THRESHOLD)
1680 		qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_RTS_THRESH,
1681 					 wiphy->rts_threshold);
1682 	if (changed & WIPHY_PARAM_COVERAGE_CLASS)
1683 		qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS,
1684 					wiphy->coverage_class);
1685 
1686 	ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code);
1687 
1688 	if (unlikely(ret))
1689 		goto out;
1690 
1691 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1692 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1693 		ret = -EFAULT;
1694 		goto out;
1695 	}
1696 
1697 out:
1698 	qtnf_bus_unlock(mac->bus);
1699 	return ret;
1700 }
1701 
1702 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus)
1703 {
1704 	struct sk_buff *cmd_skb;
1705 	u16 res_code = QLINK_CMD_RESULT_OK;
1706 	int ret = 0;
1707 
1708 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
1709 					    QLINK_CMD_FW_INIT,
1710 					    sizeof(struct qlink_cmd));
1711 	if (unlikely(!cmd_skb))
1712 		return -ENOMEM;
1713 
1714 	qtnf_bus_lock(bus);
1715 
1716 	ret = qtnf_cmd_send(bus, cmd_skb, &res_code);
1717 
1718 	if (unlikely(ret))
1719 		goto out;
1720 
1721 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1722 		pr_err("cmd exec failed: 0x%.4X\n", res_code);
1723 		ret = -EFAULT;
1724 		goto out;
1725 	}
1726 
1727 out:
1728 	qtnf_bus_unlock(bus);
1729 	return ret;
1730 }
1731 
1732 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus)
1733 {
1734 	struct sk_buff *cmd_skb;
1735 
1736 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
1737 					    QLINK_CMD_FW_DEINIT,
1738 					    sizeof(struct qlink_cmd));
1739 	if (!cmd_skb)
1740 		return;
1741 
1742 	qtnf_bus_lock(bus);
1743 
1744 	qtnf_cmd_send(bus, cmd_skb, NULL);
1745 
1746 	qtnf_bus_unlock(bus);
1747 }
1748 
1749 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise,
1750 			  const u8 *mac_addr, struct key_params *params)
1751 {
1752 	struct sk_buff *cmd_skb;
1753 	struct qlink_cmd_add_key *cmd;
1754 	u16 res_code = QLINK_CMD_RESULT_OK;
1755 	int ret = 0;
1756 
1757 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1758 					    QLINK_CMD_ADD_KEY,
1759 					    sizeof(*cmd));
1760 	if (unlikely(!cmd_skb))
1761 		return -ENOMEM;
1762 
1763 	qtnf_bus_lock(vif->mac->bus);
1764 
1765 	cmd = (struct qlink_cmd_add_key *)cmd_skb->data;
1766 
1767 	if (mac_addr)
1768 		ether_addr_copy(cmd->addr, mac_addr);
1769 	else
1770 		eth_broadcast_addr(cmd->addr);
1771 
1772 	cmd->cipher = cpu_to_le32(params->cipher);
1773 	cmd->key_index = key_index;
1774 	cmd->pairwise = pairwise;
1775 
1776 	if (params->key && params->key_len > 0)
1777 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY,
1778 					 params->key,
1779 					 params->key_len);
1780 
1781 	if (params->seq && params->seq_len > 0)
1782 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ,
1783 					 params->seq,
1784 					 params->seq_len);
1785 
1786 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1787 	if (unlikely(ret))
1788 		goto out;
1789 
1790 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1791 		pr_err("VIF%u.%u: CMD failed: %u\n",
1792 		       vif->mac->macid, vif->vifid, res_code);
1793 		ret = -EFAULT;
1794 		goto out;
1795 	}
1796 
1797 out:
1798 	qtnf_bus_unlock(vif->mac->bus);
1799 	return ret;
1800 }
1801 
1802 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise,
1803 			  const u8 *mac_addr)
1804 {
1805 	struct sk_buff *cmd_skb;
1806 	struct qlink_cmd_del_key *cmd;
1807 	u16 res_code = QLINK_CMD_RESULT_OK;
1808 	int ret = 0;
1809 
1810 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1811 					    QLINK_CMD_DEL_KEY,
1812 					    sizeof(*cmd));
1813 	if (unlikely(!cmd_skb))
1814 		return -ENOMEM;
1815 
1816 	qtnf_bus_lock(vif->mac->bus);
1817 
1818 	cmd = (struct qlink_cmd_del_key *)cmd_skb->data;
1819 
1820 	if (mac_addr)
1821 		ether_addr_copy(cmd->addr, mac_addr);
1822 	else
1823 		eth_broadcast_addr(cmd->addr);
1824 
1825 	cmd->key_index = key_index;
1826 	cmd->pairwise = pairwise;
1827 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1828 	if (unlikely(ret))
1829 		goto out;
1830 
1831 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1832 		pr_err("VIF%u.%u: CMD failed: %u\n",
1833 		       vif->mac->macid, vif->vifid, res_code);
1834 		ret = -EFAULT;
1835 		goto out;
1836 	}
1837 
1838 out:
1839 	qtnf_bus_unlock(vif->mac->bus);
1840 	return ret;
1841 }
1842 
1843 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index,
1844 				  bool unicast, bool multicast)
1845 {
1846 	struct sk_buff *cmd_skb;
1847 	struct qlink_cmd_set_def_key *cmd;
1848 	u16 res_code = QLINK_CMD_RESULT_OK;
1849 	int ret = 0;
1850 
1851 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1852 					    QLINK_CMD_SET_DEFAULT_KEY,
1853 					    sizeof(*cmd));
1854 	if (unlikely(!cmd_skb))
1855 		return -ENOMEM;
1856 
1857 	qtnf_bus_lock(vif->mac->bus);
1858 
1859 	cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data;
1860 	cmd->key_index = key_index;
1861 	cmd->unicast = unicast;
1862 	cmd->multicast = multicast;
1863 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1864 	if (unlikely(ret))
1865 		goto out;
1866 
1867 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1868 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1869 		       vif->vifid, res_code);
1870 		ret = -EFAULT;
1871 		goto out;
1872 	}
1873 
1874 out:
1875 	qtnf_bus_unlock(vif->mac->bus);
1876 	return ret;
1877 }
1878 
1879 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index)
1880 {
1881 	struct sk_buff *cmd_skb;
1882 	struct qlink_cmd_set_def_mgmt_key *cmd;
1883 	u16 res_code = QLINK_CMD_RESULT_OK;
1884 	int ret = 0;
1885 
1886 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1887 					    QLINK_CMD_SET_DEFAULT_MGMT_KEY,
1888 					    sizeof(*cmd));
1889 	if (unlikely(!cmd_skb))
1890 		return -ENOMEM;
1891 
1892 	qtnf_bus_lock(vif->mac->bus);
1893 
1894 	cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data;
1895 	cmd->key_index = key_index;
1896 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1897 	if (unlikely(ret))
1898 		goto out;
1899 
1900 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1901 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1902 		       vif->vifid, res_code);
1903 		ret = -EFAULT;
1904 		goto out;
1905 	}
1906 
1907 out:
1908 	qtnf_bus_unlock(vif->mac->bus);
1909 	return ret;
1910 }
1911 
1912 static u32 qtnf_encode_sta_flags(u32 flags)
1913 {
1914 	u32 code = 0;
1915 
1916 	if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED))
1917 		code |= QLINK_STA_FLAG_AUTHORIZED;
1918 	if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
1919 		code |= QLINK_STA_FLAG_SHORT_PREAMBLE;
1920 	if (flags & BIT(NL80211_STA_FLAG_WME))
1921 		code |= QLINK_STA_FLAG_WME;
1922 	if (flags & BIT(NL80211_STA_FLAG_MFP))
1923 		code |= QLINK_STA_FLAG_MFP;
1924 	if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED))
1925 		code |= QLINK_STA_FLAG_AUTHENTICATED;
1926 	if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER))
1927 		code |= QLINK_STA_FLAG_TDLS_PEER;
1928 	if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED))
1929 		code |= QLINK_STA_FLAG_ASSOCIATED;
1930 	return code;
1931 }
1932 
1933 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac,
1934 			     struct station_parameters *params)
1935 {
1936 	struct sk_buff *cmd_skb;
1937 	struct qlink_cmd_change_sta *cmd;
1938 	u16 res_code = QLINK_CMD_RESULT_OK;
1939 	int ret = 0;
1940 
1941 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1942 					    QLINK_CMD_CHANGE_STA,
1943 					    sizeof(*cmd));
1944 	if (unlikely(!cmd_skb))
1945 		return -ENOMEM;
1946 
1947 	qtnf_bus_lock(vif->mac->bus);
1948 
1949 	cmd = (struct qlink_cmd_change_sta *)cmd_skb->data;
1950 	ether_addr_copy(cmd->sta_addr, mac);
1951 
1952 	switch (vif->wdev.iftype) {
1953 	case NL80211_IFTYPE_AP:
1954 		cmd->if_type = cpu_to_le16(QLINK_IFTYPE_AP);
1955 		cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags(
1956 						  params->sta_flags_mask));
1957 		cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags(
1958 						 params->sta_flags_set));
1959 		break;
1960 	case NL80211_IFTYPE_STATION:
1961 		cmd->if_type = cpu_to_le16(QLINK_IFTYPE_STATION);
1962 		cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags(
1963 						  params->sta_flags_mask));
1964 		cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags(
1965 						 params->sta_flags_set));
1966 		break;
1967 	default:
1968 		pr_err("unsupported iftype %d\n", vif->wdev.iftype);
1969 		ret = -EINVAL;
1970 		goto out;
1971 	}
1972 
1973 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1974 	if (unlikely(ret))
1975 		goto out;
1976 
1977 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1978 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1979 		       vif->vifid, res_code);
1980 		ret = -EFAULT;
1981 		goto out;
1982 	}
1983 
1984 out:
1985 	qtnf_bus_unlock(vif->mac->bus);
1986 	return ret;
1987 }
1988 
1989 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif,
1990 			  struct station_del_parameters *params)
1991 {
1992 	struct sk_buff *cmd_skb;
1993 	struct qlink_cmd_del_sta *cmd;
1994 	u16 res_code = QLINK_CMD_RESULT_OK;
1995 	int ret = 0;
1996 
1997 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1998 					    QLINK_CMD_DEL_STA,
1999 					    sizeof(*cmd));
2000 	if (unlikely(!cmd_skb))
2001 		return -ENOMEM;
2002 
2003 	qtnf_bus_lock(vif->mac->bus);
2004 
2005 	cmd = (struct qlink_cmd_del_sta *)cmd_skb->data;
2006 
2007 	if (params->mac)
2008 		ether_addr_copy(cmd->sta_addr, params->mac);
2009 	else
2010 		eth_broadcast_addr(cmd->sta_addr);	/* flush all stations */
2011 
2012 	cmd->subtype = params->subtype;
2013 	cmd->reason_code = cpu_to_le16(params->reason_code);
2014 
2015 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
2016 	if (unlikely(ret))
2017 		goto out;
2018 
2019 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2020 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
2021 		       vif->vifid, res_code);
2022 		ret = -EFAULT;
2023 		goto out;
2024 	}
2025 
2026 out:
2027 	qtnf_bus_unlock(vif->mac->bus);
2028 	return ret;
2029 }
2030 
2031 static void qtnf_cmd_channel_tlv_add(struct sk_buff *cmd_skb,
2032 				     const struct ieee80211_channel *sc)
2033 {
2034 	struct qlink_tlv_channel *qchan;
2035 	u32 flags = 0;
2036 
2037 	qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
2038 	qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
2039 	qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - sizeof(qchan->hdr));
2040 	qchan->center_freq = cpu_to_le16(sc->center_freq);
2041 	qchan->hw_value = cpu_to_le16(sc->hw_value);
2042 
2043 	if (sc->flags & IEEE80211_CHAN_NO_IR)
2044 		flags |= QLINK_CHAN_NO_IR;
2045 
2046 	if (sc->flags & IEEE80211_CHAN_RADAR)
2047 		flags |= QLINK_CHAN_RADAR;
2048 
2049 	qchan->flags = cpu_to_le32(flags);
2050 }
2051 
2052 int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
2053 {
2054 	struct sk_buff *cmd_skb;
2055 	u16 res_code = QLINK_CMD_RESULT_OK;
2056 	struct ieee80211_channel *sc;
2057 	struct cfg80211_scan_request *scan_req = mac->scan_req;
2058 	int n_channels;
2059 	int count = 0;
2060 	int ret;
2061 
2062 	if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) {
2063 		pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid);
2064 		return -EINVAL;
2065 	}
2066 
2067 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
2068 					    QLINK_CMD_SCAN,
2069 					    sizeof(struct qlink_cmd));
2070 	if (unlikely(!cmd_skb))
2071 		return -ENOMEM;
2072 
2073 	qtnf_bus_lock(mac->bus);
2074 
2075 	if (scan_req->n_ssids != 0) {
2076 		while (count < scan_req->n_ssids) {
2077 			qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID,
2078 				scan_req->ssids[count].ssid,
2079 				scan_req->ssids[count].ssid_len);
2080 			count++;
2081 		}
2082 	}
2083 
2084 	if (scan_req->ie_len != 0)
2085 		qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ,
2086 					scan_req->ie, scan_req->ie_len);
2087 
2088 	if (scan_req->n_channels) {
2089 		n_channels = scan_req->n_channels;
2090 		count = 0;
2091 
2092 		while (n_channels != 0) {
2093 			sc = scan_req->channels[count];
2094 			if (sc->flags & IEEE80211_CHAN_DISABLED) {
2095 				n_channels--;
2096 				continue;
2097 			}
2098 
2099 			pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n",
2100 				 mac->macid, sc->hw_value, sc->center_freq,
2101 				 sc->flags);
2102 
2103 			qtnf_cmd_channel_tlv_add(cmd_skb, sc);
2104 			n_channels--;
2105 			count++;
2106 		}
2107 	}
2108 
2109 	ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code);
2110 
2111 	if (unlikely(ret))
2112 		goto out;
2113 
2114 	pr_debug("MAC%u: scan started\n", mac->macid);
2115 
2116 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2117 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
2118 		ret = -EFAULT;
2119 		goto out;
2120 	}
2121 out:
2122 	qtnf_bus_unlock(mac->bus);
2123 	return ret;
2124 }
2125 
2126 int qtnf_cmd_send_connect(struct qtnf_vif *vif,
2127 			  struct cfg80211_connect_params *sme)
2128 {
2129 	struct sk_buff *cmd_skb;
2130 	struct qlink_cmd_connect *cmd;
2131 	struct qlink_auth_encr *aen;
2132 	u16 res_code = QLINK_CMD_RESULT_OK;
2133 	int ret;
2134 	int i;
2135 	u32 connect_flags = 0;
2136 
2137 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
2138 					    QLINK_CMD_CONNECT,
2139 					    sizeof(*cmd));
2140 	if (unlikely(!cmd_skb))
2141 		return -ENOMEM;
2142 
2143 	cmd = (struct qlink_cmd_connect *)cmd_skb->data;
2144 
2145 	ether_addr_copy(cmd->bssid, vif->bssid);
2146 
2147 	if (sme->bssid_hint)
2148 		ether_addr_copy(cmd->bssid_hint, sme->bssid_hint);
2149 	else
2150 		eth_zero_addr(cmd->bssid_hint);
2151 
2152 	if (sme->prev_bssid)
2153 		ether_addr_copy(cmd->prev_bssid, sme->prev_bssid);
2154 	else
2155 		eth_zero_addr(cmd->prev_bssid);
2156 
2157 	if ((sme->bg_scan_period > 0) &&
2158 	    (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
2159 		cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period);
2160 	else if (sme->bg_scan_period == -1)
2161 		cmd->bg_scan_period = cpu_to_le16(QTNF_DEFAULT_BG_SCAN_PERIOD);
2162 	else
2163 		cmd->bg_scan_period = 0; /* disabled */
2164 
2165 	if (sme->flags & ASSOC_REQ_DISABLE_HT)
2166 		connect_flags |= QLINK_STA_CONNECT_DISABLE_HT;
2167 	if (sme->flags & ASSOC_REQ_DISABLE_VHT)
2168 		connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT;
2169 	if (sme->flags & ASSOC_REQ_USE_RRM)
2170 		connect_flags |= QLINK_STA_CONNECT_USE_RRM;
2171 
2172 	cmd->flags = cpu_to_le32(connect_flags);
2173 	memcpy(&cmd->ht_capa, &sme->ht_capa, sizeof(cmd->ht_capa));
2174 	memcpy(&cmd->ht_capa_mask, &sme->ht_capa_mask,
2175 	       sizeof(cmd->ht_capa_mask));
2176 	memcpy(&cmd->vht_capa, &sme->vht_capa, sizeof(cmd->vht_capa));
2177 	memcpy(&cmd->vht_capa_mask, &sme->vht_capa_mask,
2178 	       sizeof(cmd->vht_capa_mask));
2179 	cmd->pbss = sme->pbss;
2180 
2181 	aen = &cmd->aen;
2182 	aen->auth_type = sme->auth_type;
2183 	aen->privacy = !!sme->privacy;
2184 	cmd->mfp = sme->mfp;
2185 	aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions);
2186 	aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group);
2187 	aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise);
2188 
2189 	for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
2190 		aen->ciphers_pairwise[i] =
2191 			cpu_to_le32(sme->crypto.ciphers_pairwise[i]);
2192 
2193 	aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites);
2194 
2195 	for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
2196 		aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]);
2197 
2198 	aen->control_port = sme->crypto.control_port;
2199 	aen->control_port_no_encrypt =
2200 		sme->crypto.control_port_no_encrypt;
2201 	aen->control_port_ethertype =
2202 		cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype));
2203 
2204 	qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid,
2205 				 sme->ssid_len);
2206 
2207 	if (sme->ie_len != 0)
2208 		qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ,
2209 					sme->ie, sme->ie_len);
2210 
2211 	if (sme->channel)
2212 		qtnf_cmd_channel_tlv_add(cmd_skb, sme->channel);
2213 
2214 	qtnf_bus_lock(vif->mac->bus);
2215 
2216 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
2217 
2218 	if (unlikely(ret))
2219 		goto out;
2220 
2221 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2222 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
2223 		       vif->vifid, res_code);
2224 		ret = -EFAULT;
2225 		goto out;
2226 	}
2227 out:
2228 	qtnf_bus_unlock(vif->mac->bus);
2229 	return ret;
2230 }
2231 
2232 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code)
2233 {
2234 	struct sk_buff *cmd_skb;
2235 	struct qlink_cmd_disconnect *cmd;
2236 	u16 res_code = QLINK_CMD_RESULT_OK;
2237 	int ret;
2238 
2239 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
2240 					    QLINK_CMD_DISCONNECT,
2241 					    sizeof(*cmd));
2242 	if (unlikely(!cmd_skb))
2243 		return -ENOMEM;
2244 
2245 	qtnf_bus_lock(vif->mac->bus);
2246 
2247 	cmd = (struct qlink_cmd_disconnect *)cmd_skb->data;
2248 	cmd->reason = cpu_to_le16(reason_code);
2249 
2250 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
2251 
2252 	if (unlikely(ret))
2253 		goto out;
2254 
2255 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2256 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
2257 		       vif->vifid, res_code);
2258 		ret = -EFAULT;
2259 		goto out;
2260 	}
2261 out:
2262 	qtnf_bus_unlock(vif->mac->bus);
2263 	return ret;
2264 }
2265 
2266 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up)
2267 {
2268 	struct sk_buff *cmd_skb;
2269 	struct qlink_cmd_updown *cmd;
2270 	u16 res_code = QLINK_CMD_RESULT_OK;
2271 	int ret;
2272 
2273 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
2274 					    QLINK_CMD_UPDOWN_INTF,
2275 					    sizeof(*cmd));
2276 	if (unlikely(!cmd_skb))
2277 		return -ENOMEM;
2278 
2279 	cmd = (struct qlink_cmd_updown *)cmd_skb->data;
2280 	cmd->if_up = !!up;
2281 
2282 	qtnf_bus_lock(vif->mac->bus);
2283 
2284 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
2285 
2286 	if (unlikely(ret))
2287 		goto out;
2288 
2289 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2290 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
2291 		       vif->vifid, res_code);
2292 		ret = -EFAULT;
2293 		goto out;
2294 	}
2295 out:
2296 	qtnf_bus_unlock(vif->mac->bus);
2297 	return ret;
2298 }
2299 
2300 int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req)
2301 {
2302 	struct sk_buff *cmd_skb;
2303 	int ret;
2304 	u16 res_code;
2305 	struct qlink_cmd_reg_notify *cmd;
2306 
2307 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
2308 					    QLINK_CMD_REG_NOTIFY,
2309 					    sizeof(*cmd));
2310 	if (!cmd_skb)
2311 		return -ENOMEM;
2312 
2313 	cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data;
2314 	cmd->alpha2[0] = req->alpha2[0];
2315 	cmd->alpha2[1] = req->alpha2[1];
2316 
2317 	switch (req->initiator) {
2318 	case NL80211_REGDOM_SET_BY_CORE:
2319 		cmd->initiator = QLINK_REGDOM_SET_BY_CORE;
2320 		break;
2321 	case NL80211_REGDOM_SET_BY_USER:
2322 		cmd->initiator = QLINK_REGDOM_SET_BY_USER;
2323 		break;
2324 	case NL80211_REGDOM_SET_BY_DRIVER:
2325 		cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER;
2326 		break;
2327 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2328 		cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE;
2329 		break;
2330 	}
2331 
2332 	switch (req->user_reg_hint_type) {
2333 	case NL80211_USER_REG_HINT_USER:
2334 		cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER;
2335 		break;
2336 	case NL80211_USER_REG_HINT_CELL_BASE:
2337 		cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE;
2338 		break;
2339 	case NL80211_USER_REG_HINT_INDOOR:
2340 		cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR;
2341 		break;
2342 	}
2343 
2344 	qtnf_bus_lock(bus);
2345 
2346 	ret = qtnf_cmd_send(bus, cmd_skb, &res_code);
2347 	if (ret)
2348 		goto out;
2349 
2350 	switch (res_code) {
2351 	case QLINK_CMD_RESULT_ENOTSUPP:
2352 		pr_warn("reg update not supported\n");
2353 		ret = -EOPNOTSUPP;
2354 		break;
2355 	case QLINK_CMD_RESULT_EALREADY:
2356 		pr_info("regulatory domain is already set to %c%c",
2357 			req->alpha2[0], req->alpha2[1]);
2358 		ret = -EALREADY;
2359 		break;
2360 	case QLINK_CMD_RESULT_OK:
2361 		ret = 0;
2362 		break;
2363 	default:
2364 		ret = -EFAULT;
2365 		break;
2366 	}
2367 
2368 out:
2369 	qtnf_bus_unlock(bus);
2370 
2371 	return ret;
2372 }
2373 
2374 int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel,
2375 			    struct qtnf_chan_stats *stats)
2376 {
2377 	struct sk_buff *cmd_skb, *resp_skb = NULL;
2378 	struct qlink_cmd_get_chan_stats *cmd;
2379 	struct qlink_resp_get_chan_stats *resp;
2380 	size_t var_data_len;
2381 	u16 res_code = QLINK_CMD_RESULT_OK;
2382 	int ret = 0;
2383 
2384 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
2385 					    QLINK_CMD_CHAN_STATS,
2386 					    sizeof(*cmd));
2387 	if (!cmd_skb)
2388 		return -ENOMEM;
2389 
2390 	qtnf_bus_lock(mac->bus);
2391 
2392 	cmd = (struct qlink_cmd_get_chan_stats *)cmd_skb->data;
2393 	cmd->channel = cpu_to_le16(channel);
2394 
2395 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
2396 				       sizeof(*resp), &var_data_len);
2397 	if (unlikely(ret)) {
2398 		qtnf_bus_unlock(mac->bus);
2399 		return ret;
2400 	}
2401 
2402 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2403 		switch (res_code) {
2404 		case QLINK_CMD_RESULT_ENOTFOUND:
2405 			ret = -ENOENT;
2406 			break;
2407 		default:
2408 			pr_err("cmd exec failed: 0x%.4X\n", res_code);
2409 			ret = -EFAULT;
2410 			break;
2411 		}
2412 		goto out;
2413 	}
2414 
2415 	resp = (struct qlink_resp_get_chan_stats *)resp_skb->data;
2416 	ret = qtnf_cmd_resp_proc_chan_stat_info(stats, resp->info,
2417 						var_data_len);
2418 
2419 out:
2420 	qtnf_bus_unlock(mac->bus);
2421 	consume_skb(resp_skb);
2422 	return ret;
2423 }
2424 
2425 int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,
2426 			      struct cfg80211_csa_settings *params)
2427 {
2428 	struct qtnf_wmac *mac = vif->mac;
2429 	struct qlink_cmd_chan_switch *cmd;
2430 	struct sk_buff *cmd_skb;
2431 	u16 res_code = QLINK_CMD_RESULT_OK;
2432 	int ret;
2433 
2434 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid,
2435 					    QLINK_CMD_CHAN_SWITCH,
2436 					    sizeof(*cmd));
2437 
2438 	if (unlikely(!cmd_skb))
2439 		return -ENOMEM;
2440 
2441 	qtnf_bus_lock(mac->bus);
2442 
2443 	cmd = (struct qlink_cmd_chan_switch *)cmd_skb->data;
2444 	cmd->channel = cpu_to_le16(params->chandef.chan->hw_value);
2445 	cmd->radar_required = params->radar_required;
2446 	cmd->block_tx = params->block_tx;
2447 	cmd->beacon_count = params->count;
2448 
2449 	ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code);
2450 
2451 	if (unlikely(ret))
2452 		goto out;
2453 
2454 	switch (res_code) {
2455 	case QLINK_CMD_RESULT_OK:
2456 		ret = 0;
2457 		break;
2458 	case QLINK_CMD_RESULT_ENOTFOUND:
2459 		ret = -ENOENT;
2460 		break;
2461 	case QLINK_CMD_RESULT_ENOTSUPP:
2462 		ret = -EOPNOTSUPP;
2463 		break;
2464 	case QLINK_CMD_RESULT_EALREADY:
2465 		ret = -EALREADY;
2466 		break;
2467 	case QLINK_CMD_RESULT_INVALID:
2468 	default:
2469 		ret = -EFAULT;
2470 		break;
2471 	}
2472 
2473 out:
2474 	qtnf_bus_unlock(mac->bus);
2475 	return ret;
2476 }
2477 
2478 int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef)
2479 {
2480 	struct qtnf_bus *bus = vif->mac->bus;
2481 	const struct qlink_resp_channel_get *resp;
2482 	struct sk_buff *cmd_skb;
2483 	struct sk_buff *resp_skb = NULL;
2484 	u16 res_code = QLINK_CMD_RESULT_OK;
2485 	int ret;
2486 
2487 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
2488 					    QLINK_CMD_CHAN_GET,
2489 					    sizeof(struct qlink_cmd));
2490 	if (unlikely(!cmd_skb))
2491 		return -ENOMEM;
2492 
2493 	qtnf_bus_lock(bus);
2494 
2495 	ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code,
2496 				       sizeof(*resp), NULL);
2497 
2498 	qtnf_bus_unlock(bus);
2499 
2500 	if (unlikely(ret))
2501 		goto out;
2502 
2503 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
2504 		ret = -ENODATA;
2505 		goto out;
2506 	}
2507 
2508 	resp = (const struct qlink_resp_channel_get *)resp_skb->data;
2509 	qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef);
2510 
2511 out:
2512 	consume_skb(resp_skb);
2513 	return ret;
2514 }
2515