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 int qtnf_cmd_send_start_ap(struct qtnf_vif *vif)
151 {
152 	struct sk_buff *cmd_skb;
153 	u16 res_code = QLINK_CMD_RESULT_OK;
154 	int ret;
155 
156 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
157 					    QLINK_CMD_START_AP,
158 					    sizeof(struct qlink_cmd));
159 	if (unlikely(!cmd_skb))
160 		return -ENOMEM;
161 
162 	qtnf_bus_lock(vif->mac->bus);
163 
164 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
165 
166 	if (unlikely(ret))
167 		goto out;
168 
169 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
170 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
171 		       vif->vifid, res_code);
172 		ret = -EFAULT;
173 		goto out;
174 	}
175 
176 	vif->bss_status |= QTNF_STATE_AP_START;
177 	netif_carrier_on(vif->netdev);
178 
179 out:
180 	qtnf_bus_unlock(vif->mac->bus);
181 	return ret;
182 }
183 
184 int qtnf_cmd_send_regulatory_config(struct qtnf_wmac *mac, const char *alpha2)
185 {
186 	struct sk_buff *cmd_skb;
187 	u16 res_code = QLINK_CMD_RESULT_OK;
188 	int ret;
189 
190 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
191 					    QLINK_CMD_REG_REGION,
192 					    sizeof(struct qlink_cmd));
193 	if (unlikely(!cmd_skb))
194 		return -ENOMEM;
195 
196 	qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_COUNTRY, alpha2,
197 				 QTNF_MAX_ALPHA_LEN);
198 
199 	ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code);
200 
201 	if (unlikely(ret))
202 		goto out;
203 
204 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
205 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
206 		ret = -EFAULT;
207 		goto out;
208 	}
209 
210 	memcpy(mac->bus->hw_info.alpha2_code, alpha2,
211 	       sizeof(mac->bus->hw_info.alpha2_code));
212 out:
213 	return ret;
214 }
215 
216 int qtnf_cmd_send_config_ap(struct qtnf_vif *vif)
217 {
218 	struct sk_buff *cmd_skb;
219 	struct qtnf_bss_config *bss_cfg = &vif->bss_cfg;
220 	struct cfg80211_chan_def *chandef = &bss_cfg->chandef;
221 	struct qlink_tlv_channel *qchan;
222 	struct qlink_auth_encr aen;
223 	u16 res_code = QLINK_CMD_RESULT_OK;
224 	int ret;
225 	int i;
226 
227 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
228 					    QLINK_CMD_CONFIG_AP,
229 					    sizeof(struct qlink_cmd));
230 	if (unlikely(!cmd_skb))
231 		return -ENOMEM;
232 
233 	qtnf_bus_lock(vif->mac->bus);
234 
235 	qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid,
236 				 bss_cfg->ssid_len);
237 	qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_BCN_PERIOD,
238 				 bss_cfg->bcn_period);
239 	qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_DTIM, bss_cfg->dtim);
240 
241 	qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
242 	qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
243 	qchan->hdr.len = cpu_to_le16(sizeof(*qchan) -
244 			sizeof(struct qlink_tlv_hdr));
245 	qchan->hw_value = cpu_to_le16(
246 		ieee80211_frequency_to_channel(chandef->chan->center_freq));
247 
248 	memset(&aen, 0, sizeof(aen));
249 	aen.auth_type = bss_cfg->auth_type;
250 	aen.privacy = !!bss_cfg->privacy;
251 	aen.mfp = bss_cfg->mfp;
252 	aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions);
253 	aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group);
254 	aen.n_ciphers_pairwise = cpu_to_le32(
255 					bss_cfg->crypto.n_ciphers_pairwise);
256 	for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
257 		aen.ciphers_pairwise[i] = cpu_to_le32(
258 					bss_cfg->crypto.ciphers_pairwise[i]);
259 	aen.n_akm_suites = cpu_to_le32(
260 					bss_cfg->crypto.n_akm_suites);
261 	for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
262 		aen.akm_suites[i] = cpu_to_le32(
263 					bss_cfg->crypto.akm_suites[i]);
264 	aen.control_port = bss_cfg->crypto.control_port;
265 	aen.control_port_no_encrypt =
266 			bss_cfg->crypto.control_port_no_encrypt;
267 	aen.control_port_ethertype = cpu_to_le16(be16_to_cpu(
268 				bss_cfg->crypto.control_port_ethertype));
269 
270 	qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen,
271 				 sizeof(aen));
272 
273 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
274 
275 	if (unlikely(ret))
276 		goto out;
277 
278 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
279 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
280 		       vif->vifid, res_code);
281 		ret = -EFAULT;
282 		goto out;
283 	}
284 
285 	vif->bss_status |= QTNF_STATE_AP_CONFIG;
286 
287 out:
288 	qtnf_bus_unlock(vif->mac->bus);
289 	return ret;
290 }
291 
292 int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif)
293 {
294 	struct sk_buff *cmd_skb;
295 	u16 res_code = QLINK_CMD_RESULT_OK;
296 	int ret;
297 
298 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
299 					    QLINK_CMD_STOP_AP,
300 					    sizeof(struct qlink_cmd));
301 	if (unlikely(!cmd_skb))
302 		return -ENOMEM;
303 
304 	qtnf_bus_lock(vif->mac->bus);
305 
306 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
307 
308 	if (unlikely(ret))
309 		goto out;
310 
311 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
312 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
313 		       vif->vifid, res_code);
314 		ret = -EFAULT;
315 		goto out;
316 	}
317 
318 	vif->bss_status &= ~QTNF_STATE_AP_START;
319 	vif->bss_status &= ~QTNF_STATE_AP_CONFIG;
320 
321 	netif_carrier_off(vif->netdev);
322 
323 out:
324 	qtnf_bus_unlock(vif->mac->bus);
325 	return ret;
326 }
327 
328 int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg)
329 {
330 	struct sk_buff *cmd_skb;
331 	struct qlink_cmd_mgmt_frame_register *cmd;
332 	u16 res_code = QLINK_CMD_RESULT_OK;
333 	int ret;
334 
335 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
336 					    QLINK_CMD_REGISTER_MGMT,
337 					    sizeof(*cmd));
338 	if (unlikely(!cmd_skb))
339 		return -ENOMEM;
340 
341 	qtnf_bus_lock(vif->mac->bus);
342 
343 	cmd = (struct qlink_cmd_mgmt_frame_register *)cmd_skb->data;
344 	cmd->frame_type = cpu_to_le16(frame_type);
345 	cmd->do_register = reg;
346 
347 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
348 
349 	if (unlikely(ret))
350 		goto out;
351 
352 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
353 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
354 		       vif->vifid, res_code);
355 		ret = -EFAULT;
356 		goto out;
357 	}
358 
359 out:
360 	qtnf_bus_unlock(vif->mac->bus);
361 	return ret;
362 }
363 
364 int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
365 			     u16 freq, const u8 *buf, size_t len)
366 {
367 	struct sk_buff *cmd_skb;
368 	struct qlink_cmd_mgmt_frame_tx *cmd;
369 	u16 res_code = QLINK_CMD_RESULT_OK;
370 	int ret;
371 
372 	if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) {
373 		pr_warn("VIF%u.%u: frame is too big: %zu\n", vif->mac->macid,
374 			vif->vifid, len);
375 		return -E2BIG;
376 	}
377 
378 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
379 					    QLINK_CMD_SEND_MGMT_FRAME,
380 					    sizeof(*cmd));
381 	if (unlikely(!cmd_skb))
382 		return -ENOMEM;
383 
384 	qtnf_bus_lock(vif->mac->bus);
385 
386 	cmd = (struct qlink_cmd_mgmt_frame_tx *)cmd_skb->data;
387 	cmd->cookie = cpu_to_le32(cookie);
388 	cmd->freq = cpu_to_le16(freq);
389 	cmd->flags = cpu_to_le16(flags);
390 
391 	if (len && buf)
392 		qtnf_cmd_skb_put_buffer(cmd_skb, buf, len);
393 
394 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
395 
396 	if (unlikely(ret))
397 		goto out;
398 
399 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
400 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
401 		       vif->vifid, res_code);
402 		ret = -EFAULT;
403 		goto out;
404 	}
405 
406 out:
407 	qtnf_bus_unlock(vif->mac->bus);
408 	return ret;
409 }
410 
411 int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type,
412 				 const u8 *buf, size_t len)
413 {
414 	struct sk_buff *cmd_skb;
415 	struct qlink_cmd_mgmt_append_ie *cmd;
416 	u16 res_code = QLINK_CMD_RESULT_OK;
417 	int ret;
418 
419 	if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) {
420 		pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid,
421 			vif->vifid, frame_type, len);
422 		return -E2BIG;
423 	}
424 
425 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
426 					    QLINK_CMD_MGMT_SET_APPIE,
427 					    sizeof(*cmd));
428 	if (unlikely(!cmd_skb))
429 		return -ENOMEM;
430 
431 	qtnf_bus_lock(vif->mac->bus);
432 
433 	cmd = (struct qlink_cmd_mgmt_append_ie *)cmd_skb->data;
434 	cmd->type = frame_type;
435 	cmd->flags = 0;
436 
437 	/* If len == 0 then IE buf for specified frame type
438 	 * should be cleared on EP.
439 	 */
440 	if (len && buf)
441 		qtnf_cmd_skb_put_buffer(cmd_skb, buf, len);
442 
443 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
444 
445 	if (unlikely(ret))
446 		goto out;
447 
448 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
449 		pr_err("VIF%u.%u frame %u: CMD failed: %u\n", vif->mac->macid,
450 		       vif->vifid, frame_type, res_code);
451 		ret = -EFAULT;
452 		goto out;
453 	}
454 
455 out:
456 	qtnf_bus_unlock(vif->mac->bus);
457 	return ret;
458 }
459 
460 static void
461 qtnf_sta_info_parse_basic_counters(struct station_info *sinfo,
462 		const struct qlink_sta_stat_basic_counters *counters)
463 {
464 	sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES) |
465 			 BIT(NL80211_STA_INFO_TX_BYTES);
466 	sinfo->rx_bytes = get_unaligned_le64(&counters->rx_bytes);
467 	sinfo->tx_bytes = get_unaligned_le64(&counters->tx_bytes);
468 
469 	sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
470 			 BIT(NL80211_STA_INFO_TX_PACKETS) |
471 			 BIT(NL80211_STA_INFO_BEACON_RX);
472 	sinfo->rx_packets = get_unaligned_le32(&counters->rx_packets);
473 	sinfo->tx_packets = get_unaligned_le32(&counters->tx_packets);
474 	sinfo->rx_beacon = get_unaligned_le64(&counters->rx_beacons);
475 
476 	sinfo->filled |= BIT(NL80211_STA_INFO_RX_DROP_MISC) |
477 			 BIT(NL80211_STA_INFO_TX_FAILED);
478 	sinfo->rx_dropped_misc = get_unaligned_le32(&counters->rx_dropped);
479 	sinfo->tx_failed = get_unaligned_le32(&counters->tx_failed);
480 }
481 
482 static void
483 qtnf_sta_info_parse_rate(struct rate_info *rate_dst,
484 			 const struct  qlink_sta_info_rate *rate_src)
485 {
486 	rate_dst->legacy = get_unaligned_le16(&rate_src->rate) * 10;
487 
488 	rate_dst->mcs = rate_src->mcs;
489 	rate_dst->nss = rate_src->nss;
490 	rate_dst->flags = 0;
491 
492 	switch (rate_src->bw) {
493 	case QLINK_STA_INFO_RATE_BW_5:
494 		rate_dst->bw = RATE_INFO_BW_5;
495 		break;
496 	case QLINK_STA_INFO_RATE_BW_10:
497 		rate_dst->bw = RATE_INFO_BW_10;
498 		break;
499 	case QLINK_STA_INFO_RATE_BW_20:
500 		rate_dst->bw = RATE_INFO_BW_20;
501 		break;
502 	case QLINK_STA_INFO_RATE_BW_40:
503 		rate_dst->bw = RATE_INFO_BW_40;
504 		break;
505 	case QLINK_STA_INFO_RATE_BW_80:
506 		rate_dst->bw = RATE_INFO_BW_80;
507 		break;
508 	case QLINK_STA_INFO_RATE_BW_160:
509 		rate_dst->bw = RATE_INFO_BW_160;
510 		break;
511 	default:
512 		rate_dst->bw = 0;
513 		break;
514 	}
515 
516 	if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_HT_MCS)
517 		rate_dst->flags |= RATE_INFO_FLAGS_MCS;
518 	else if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_VHT_MCS)
519 		rate_dst->flags |= RATE_INFO_FLAGS_VHT_MCS;
520 }
521 
522 static void
523 qtnf_sta_info_parse_flags(struct nl80211_sta_flag_update *dst,
524 			  const struct qlink_sta_info_state *src)
525 {
526 	u32 mask, value;
527 
528 	dst->mask = 0;
529 	dst->set = 0;
530 
531 	mask = le32_to_cpu(src->mask);
532 	value = le32_to_cpu(src->value);
533 
534 	if (mask & QLINK_STA_FLAG_AUTHORIZED) {
535 		dst->mask |= BIT(NL80211_STA_FLAG_AUTHORIZED);
536 		if (value & QLINK_STA_FLAG_AUTHORIZED)
537 			dst->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
538 	}
539 
540 	if (mask & QLINK_STA_FLAG_SHORT_PREAMBLE) {
541 		dst->mask |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
542 		if (value & QLINK_STA_FLAG_SHORT_PREAMBLE)
543 			dst->set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
544 	}
545 
546 	if (mask & QLINK_STA_FLAG_WME) {
547 		dst->mask |= BIT(NL80211_STA_FLAG_WME);
548 		if (value & QLINK_STA_FLAG_WME)
549 			dst->set |= BIT(NL80211_STA_FLAG_WME);
550 	}
551 
552 	if (mask & QLINK_STA_FLAG_MFP) {
553 		dst->mask |= BIT(NL80211_STA_FLAG_MFP);
554 		if (value & QLINK_STA_FLAG_MFP)
555 			dst->set |= BIT(NL80211_STA_FLAG_MFP);
556 	}
557 
558 	if (mask & QLINK_STA_FLAG_AUTHENTICATED) {
559 		dst->mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
560 		if (value & QLINK_STA_FLAG_AUTHENTICATED)
561 			dst->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
562 	}
563 
564 	if (mask & QLINK_STA_FLAG_TDLS_PEER) {
565 		dst->mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
566 		if (value & QLINK_STA_FLAG_TDLS_PEER)
567 			dst->set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
568 	}
569 
570 	if (mask & QLINK_STA_FLAG_ASSOCIATED) {
571 		dst->mask |= BIT(NL80211_STA_FLAG_ASSOCIATED);
572 		if (value & QLINK_STA_FLAG_ASSOCIATED)
573 			dst->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
574 	}
575 }
576 
577 static void
578 qtnf_sta_info_parse_generic_info(struct station_info *sinfo,
579 				 const struct qlink_sta_info_generic *info)
580 {
581 	sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME) |
582 			 BIT(NL80211_STA_INFO_INACTIVE_TIME);
583 	sinfo->connected_time = get_unaligned_le32(&info->connected_time);
584 	sinfo->inactive_time = get_unaligned_le32(&info->inactive_time);
585 
586 	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
587 			 BIT(NL80211_STA_INFO_SIGNAL_AVG);
588 	sinfo->signal = info->rssi - 120;
589 	sinfo->signal_avg = info->rssi_avg - QLINK_RSSI_OFFSET;
590 
591 	if (info->rx_rate.rate) {
592 		sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
593 		qtnf_sta_info_parse_rate(&sinfo->rxrate, &info->rx_rate);
594 	}
595 
596 	if (info->tx_rate.rate) {
597 		sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
598 		qtnf_sta_info_parse_rate(&sinfo->txrate, &info->tx_rate);
599 	}
600 
601 	sinfo->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
602 	qtnf_sta_info_parse_flags(&sinfo->sta_flags, &info->state);
603 }
604 
605 static int qtnf_cmd_sta_info_parse(struct station_info *sinfo,
606 				   const u8 *payload, size_t payload_size)
607 {
608 	const struct qlink_sta_stat_basic_counters *counters;
609 	const struct qlink_sta_info_generic *sta_info;
610 	u16 tlv_type;
611 	u16 tlv_value_len;
612 	size_t tlv_full_len;
613 	const struct qlink_tlv_hdr *tlv;
614 
615 	sinfo->filled = 0;
616 
617 	tlv = (const struct qlink_tlv_hdr *)payload;
618 	while (payload_size >= sizeof(struct qlink_tlv_hdr)) {
619 		tlv_type = le16_to_cpu(tlv->type);
620 		tlv_value_len = le16_to_cpu(tlv->len);
621 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
622 		if (tlv_full_len > payload_size) {
623 			pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
624 				tlv_type, tlv_value_len);
625 			return -EINVAL;
626 		}
627 		switch (tlv_type) {
628 		case QTN_TLV_ID_STA_BASIC_COUNTERS:
629 			if (unlikely(tlv_value_len < sizeof(*counters))) {
630 				pr_err("invalid TLV size %.4X: %u\n",
631 				       tlv_type, tlv_value_len);
632 				break;
633 			}
634 
635 			counters = (void *)tlv->val;
636 			qtnf_sta_info_parse_basic_counters(sinfo, counters);
637 			break;
638 		case QTN_TLV_ID_STA_GENERIC_INFO:
639 			if (unlikely(tlv_value_len < sizeof(*sta_info)))
640 				break;
641 
642 			sta_info = (void *)tlv->val;
643 			qtnf_sta_info_parse_generic_info(sinfo, sta_info);
644 			break;
645 		default:
646 			pr_warn("unexpected TLV type: %.4X\n", tlv_type);
647 			break;
648 		}
649 		payload_size -= tlv_full_len;
650 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
651 	}
652 
653 	if (payload_size) {
654 		pr_warn("malformed TLV buf; bytes left: %zu\n", payload_size);
655 		return -EINVAL;
656 	}
657 
658 	return 0;
659 }
660 
661 int qtnf_cmd_get_sta_info(struct qtnf_vif *vif, const u8 *sta_mac,
662 			  struct station_info *sinfo)
663 {
664 	struct sk_buff *cmd_skb, *resp_skb = NULL;
665 	struct qlink_cmd_get_sta_info *cmd;
666 	const struct qlink_resp_get_sta_info *resp;
667 	size_t var_resp_len;
668 	u16 res_code = QLINK_CMD_RESULT_OK;
669 	int ret = 0;
670 
671 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
672 					    QLINK_CMD_GET_STA_INFO,
673 					    sizeof(*cmd));
674 
675 	if (unlikely(!cmd_skb))
676 		return -ENOMEM;
677 
678 	qtnf_bus_lock(vif->mac->bus);
679 
680 	cmd = (struct qlink_cmd_get_sta_info *)cmd_skb->data;
681 	ether_addr_copy(cmd->sta_addr, sta_mac);
682 
683 	ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb,
684 				       &res_code, sizeof(*resp),
685 				       &var_resp_len);
686 
687 	if (unlikely(ret))
688 		goto out;
689 
690 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
691 		switch (res_code) {
692 		case QLINK_CMD_RESULT_ENOTFOUND:
693 			pr_warn("VIF%u.%u: %pM STA not found\n",
694 				vif->mac->macid, vif->vifid, sta_mac);
695 			ret = -ENOENT;
696 			break;
697 		default:
698 			pr_err("VIF%u.%u: can't get info for %pM: %u\n",
699 			       vif->mac->macid, vif->vifid, sta_mac, res_code);
700 			ret = -EFAULT;
701 			break;
702 		}
703 		goto out;
704 	}
705 
706 	resp = (const struct qlink_resp_get_sta_info *)resp_skb->data;
707 
708 	if (unlikely(!ether_addr_equal(sta_mac, resp->sta_addr))) {
709 		pr_err("VIF%u.%u: wrong mac in reply: %pM != %pM\n",
710 		       vif->mac->macid, vif->vifid, resp->sta_addr, sta_mac);
711 		ret = -EINVAL;
712 		goto out;
713 	}
714 
715 	ret = qtnf_cmd_sta_info_parse(sinfo, resp->info, var_resp_len);
716 
717 out:
718 	qtnf_bus_unlock(vif->mac->bus);
719 	consume_skb(resp_skb);
720 
721 	return ret;
722 }
723 
724 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
725 					 enum nl80211_iftype iftype,
726 					 u8 *mac_addr,
727 					 enum qlink_cmd_type cmd_type)
728 {
729 	struct sk_buff *cmd_skb, *resp_skb = NULL;
730 	struct qlink_cmd_manage_intf *cmd;
731 	const struct qlink_resp_manage_intf *resp;
732 	u16 res_code = QLINK_CMD_RESULT_OK;
733 	int ret = 0;
734 
735 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
736 					    cmd_type,
737 					    sizeof(*cmd));
738 	if (unlikely(!cmd_skb))
739 		return -ENOMEM;
740 
741 	qtnf_bus_lock(vif->mac->bus);
742 
743 	cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
744 
745 	switch (iftype) {
746 	case NL80211_IFTYPE_AP:
747 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP);
748 		break;
749 	case NL80211_IFTYPE_STATION:
750 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION);
751 		break;
752 	default:
753 		pr_err("VIF%u.%u: unsupported type %d\n", vif->mac->macid,
754 		       vif->vifid, iftype);
755 		ret = -EINVAL;
756 		goto out;
757 	}
758 
759 	if (mac_addr)
760 		ether_addr_copy(cmd->intf_info.mac_addr, mac_addr);
761 	else
762 		eth_zero_addr(cmd->intf_info.mac_addr);
763 
764 	ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb,
765 				       &res_code, sizeof(*resp), NULL);
766 
767 	if (unlikely(ret))
768 		goto out;
769 
770 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
771 		pr_err("VIF%u.%u: CMD %d failed: %u\n", vif->mac->macid,
772 		       vif->vifid, cmd_type, res_code);
773 		ret = -EFAULT;
774 		goto out;
775 	}
776 
777 	resp = (const struct qlink_resp_manage_intf *)resp_skb->data;
778 	ether_addr_copy(vif->mac_addr, resp->intf_info.mac_addr);
779 
780 out:
781 	qtnf_bus_unlock(vif->mac->bus);
782 	consume_skb(resp_skb);
783 
784 	return ret;
785 }
786 
787 int qtnf_cmd_send_add_intf(struct qtnf_vif *vif,
788 			   enum nl80211_iftype iftype, u8 *mac_addr)
789 {
790 	return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr,
791 			QLINK_CMD_ADD_INTF);
792 }
793 
794 int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
795 				   enum nl80211_iftype iftype, u8 *mac_addr)
796 {
797 	return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr,
798 					     QLINK_CMD_CHANGE_INTF);
799 }
800 
801 int qtnf_cmd_send_del_intf(struct qtnf_vif *vif)
802 {
803 	struct sk_buff *cmd_skb;
804 	struct qlink_cmd_manage_intf *cmd;
805 	u16 res_code = QLINK_CMD_RESULT_OK;
806 	int ret = 0;
807 
808 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
809 					    QLINK_CMD_DEL_INTF,
810 					    sizeof(*cmd));
811 	if (unlikely(!cmd_skb))
812 		return -ENOMEM;
813 
814 	qtnf_bus_lock(vif->mac->bus);
815 
816 	cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
817 
818 	switch (vif->wdev.iftype) {
819 	case NL80211_IFTYPE_AP:
820 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP);
821 		break;
822 	case NL80211_IFTYPE_STATION:
823 		cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION);
824 		break;
825 	default:
826 		pr_warn("VIF%u.%u: unsupported iftype %d\n", vif->mac->macid,
827 			vif->vifid, vif->wdev.iftype);
828 		ret = -EINVAL;
829 		goto out;
830 	}
831 
832 	eth_zero_addr(cmd->intf_info.mac_addr);
833 
834 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
835 
836 	if (unlikely(ret))
837 		goto out;
838 
839 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
840 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
841 		       vif->vifid, res_code);
842 		ret = -EFAULT;
843 		goto out;
844 	}
845 
846 out:
847 	qtnf_bus_unlock(vif->mac->bus);
848 	return ret;
849 }
850 
851 static int
852 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
853 			   const struct qlink_resp_get_hw_info *resp)
854 {
855 	struct qtnf_hw_info *hwinfo = &bus->hw_info;
856 
857 	hwinfo->num_mac = resp->num_mac;
858 	hwinfo->mac_bitmap = resp->mac_bitmap;
859 	hwinfo->fw_ver = le32_to_cpu(resp->fw_ver);
860 	hwinfo->ql_proto_ver = le16_to_cpu(resp->ql_proto_ver);
861 	memcpy(hwinfo->alpha2_code, resp->alpha2_code,
862 	       sizeof(hwinfo->alpha2_code));
863 	hwinfo->total_tx_chain = resp->total_tx_chain;
864 	hwinfo->total_rx_chain = resp->total_rx_chain;
865 	hwinfo->hw_capab = le32_to_cpu(resp->hw_capab);
866 
867 	pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u\n",
868 		hwinfo->fw_ver, hwinfo->mac_bitmap,
869 		hwinfo->alpha2_code[0], hwinfo->alpha2_code[1],
870 		hwinfo->total_tx_chain, hwinfo->total_rx_chain);
871 
872 	return 0;
873 }
874 
875 static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
876 					const u8 *tlv_buf, size_t tlv_buf_size)
877 {
878 	struct ieee80211_iface_limit *limits = NULL;
879 	const struct qlink_iface_limit *limit_record;
880 	size_t record_count = 0, rec = 0;
881 	u16 tlv_type, tlv_value_len, mask;
882 	struct qlink_iface_comb_num *comb;
883 	size_t tlv_full_len;
884 	const struct qlink_tlv_hdr *tlv;
885 
886 	mac->macinfo.n_limits = 0;
887 
888 	tlv = (const struct qlink_tlv_hdr *)tlv_buf;
889 	while (tlv_buf_size >= sizeof(struct qlink_tlv_hdr)) {
890 		tlv_type = le16_to_cpu(tlv->type);
891 		tlv_value_len = le16_to_cpu(tlv->len);
892 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
893 		if (tlv_full_len > tlv_buf_size) {
894 			pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n",
895 				mac->macid, tlv_type, tlv_value_len);
896 			return -EINVAL;
897 		}
898 
899 		switch (tlv_type) {
900 		case QTN_TLV_ID_NUM_IFACE_COMB:
901 			if (unlikely(tlv_value_len != sizeof(*comb)))
902 				return -EINVAL;
903 
904 			comb = (void *)tlv->val;
905 			record_count = le16_to_cpu(comb->iface_comb_num);
906 
907 			mac->macinfo.n_limits = record_count;
908 			/* free earlier iface limits memory */
909 			kfree(mac->macinfo.limits);
910 			mac->macinfo.limits =
911 				kzalloc(sizeof(*mac->macinfo.limits) *
912 					record_count, GFP_KERNEL);
913 
914 			if (unlikely(!mac->macinfo.limits))
915 				return -ENOMEM;
916 
917 			limits = mac->macinfo.limits;
918 			break;
919 		case QTN_TLV_ID_IFACE_LIMIT:
920 			if (unlikely(!limits)) {
921 				pr_warn("MAC%u: limits are not inited\n",
922 					mac->macid);
923 				return -EINVAL;
924 			}
925 
926 			if (unlikely(tlv_value_len != sizeof(*limit_record))) {
927 				pr_warn("MAC%u: record size mismatch\n",
928 					mac->macid);
929 				return -EINVAL;
930 			}
931 
932 			limit_record = (void *)tlv->val;
933 			limits[rec].max = le16_to_cpu(limit_record->max_num);
934 			mask = le16_to_cpu(limit_record->type_mask);
935 			limits[rec].types = qlink_iface_type_mask_to_nl(mask);
936 			/* only AP and STA modes are supported */
937 			limits[rec].types &= BIT(NL80211_IFTYPE_AP) |
938 					     BIT(NL80211_IFTYPE_STATION);
939 
940 			pr_debug("MAC%u: MAX: %u; TYPES: %.4X\n", mac->macid,
941 				 limits[rec].max, limits[rec].types);
942 
943 			if (limits[rec].types)
944 				rec++;
945 			break;
946 		default:
947 			break;
948 		}
949 		tlv_buf_size -= tlv_full_len;
950 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
951 	}
952 
953 	if (tlv_buf_size) {
954 		pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n",
955 			mac->macid, tlv_buf_size);
956 		return -EINVAL;
957 	}
958 
959 	if (mac->macinfo.n_limits != rec) {
960 		pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n",
961 		       mac->macid, mac->macinfo.n_limits, rec);
962 		return -EINVAL;
963 	}
964 
965 	return 0;
966 }
967 
968 static void
969 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac,
970 			    const struct qlink_resp_get_mac_info *resp_info)
971 {
972 	struct qtnf_mac_info *mac_info;
973 	struct qtnf_vif *vif;
974 
975 	mac_info = &mac->macinfo;
976 
977 	mac_info->bands_cap = resp_info->bands_cap;
978 	mac_info->phymode_cap = resp_info->phymode_cap;
979 	memcpy(&mac_info->dev_mac, &resp_info->dev_mac,
980 	       sizeof(mac_info->dev_mac));
981 
982 	ether_addr_copy(mac->macaddr, mac_info->dev_mac);
983 
984 	vif = qtnf_mac_get_base_vif(mac);
985 	if (vif)
986 		ether_addr_copy(vif->mac_addr, mac->macaddr);
987 	else
988 		pr_err("could not get valid base vif\n");
989 
990 	mac_info->num_tx_chain = resp_info->num_tx_chain;
991 	mac_info->num_rx_chain = resp_info->num_rx_chain;
992 
993 	mac_info->max_ap_assoc_sta = le16_to_cpu(resp_info->max_ap_assoc_sta);
994 	mac_info->radar_detect_widths =
995 			qlink_chan_width_mask_to_nl(le16_to_cpu(
996 					resp_info->radar_detect_widths));
997 
998 	memcpy(&mac_info->ht_cap, &resp_info->ht_cap, sizeof(mac_info->ht_cap));
999 	memcpy(&mac_info->vht_cap, &resp_info->vht_cap,
1000 	       sizeof(mac_info->vht_cap));
1001 }
1002 
1003 static int
1004 qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band,
1005 				 struct qlink_resp_get_chan_info *resp,
1006 				 size_t payload_len)
1007 {
1008 	u16 tlv_type;
1009 	size_t tlv_len;
1010 	const struct qlink_tlv_hdr *tlv;
1011 	const struct qlink_tlv_channel *qchan;
1012 	struct ieee80211_channel *chan;
1013 	unsigned int chidx = 0;
1014 	u32 qflags;
1015 
1016 	kfree(band->channels);
1017 	band->channels = NULL;
1018 
1019 	band->n_channels = resp->num_chans;
1020 	if (band->n_channels == 0)
1021 		return 0;
1022 
1023 	band->channels = kcalloc(band->n_channels, sizeof(*chan), GFP_KERNEL);
1024 	if (!band->channels) {
1025 		band->n_channels = 0;
1026 		return -ENOMEM;
1027 	}
1028 
1029 	tlv = (struct qlink_tlv_hdr *)resp->info;
1030 
1031 	while (payload_len >= sizeof(*tlv)) {
1032 		tlv_type = le16_to_cpu(tlv->type);
1033 		tlv_len = le16_to_cpu(tlv->len) + sizeof(*tlv);
1034 
1035 		if (tlv_len > payload_len) {
1036 			pr_warn("malformed TLV 0x%.2X; LEN: %zu\n",
1037 				tlv_type, tlv_len);
1038 			goto error_ret;
1039 		}
1040 
1041 		switch (tlv_type) {
1042 		case QTN_TLV_ID_CHANNEL:
1043 			if (unlikely(tlv_len != sizeof(*qchan))) {
1044 				pr_err("invalid channel TLV len %zu\n",
1045 				       tlv_len);
1046 				goto error_ret;
1047 			}
1048 
1049 			if (chidx == band->n_channels) {
1050 				pr_err("too many channel TLVs\n");
1051 				goto error_ret;
1052 			}
1053 
1054 			qchan = (const struct qlink_tlv_channel *)tlv;
1055 			chan = &band->channels[chidx++];
1056 			qflags = le32_to_cpu(qchan->flags);
1057 
1058 			chan->hw_value = le16_to_cpu(qchan->hw_value);
1059 			chan->band = band->band;
1060 			chan->center_freq = le16_to_cpu(qchan->center_freq);
1061 			chan->max_antenna_gain = (int)qchan->max_antenna_gain;
1062 			chan->max_power = (int)qchan->max_power;
1063 			chan->max_reg_power = (int)qchan->max_reg_power;
1064 			chan->beacon_found = qchan->beacon_found;
1065 			chan->dfs_cac_ms = le32_to_cpu(qchan->dfs_cac_ms);
1066 			chan->flags = 0;
1067 
1068 			if (qflags & QLINK_CHAN_DISABLED)
1069 				chan->flags |= IEEE80211_CHAN_DISABLED;
1070 
1071 			if (qflags & QLINK_CHAN_NO_IR)
1072 				chan->flags |= IEEE80211_CHAN_NO_IR;
1073 
1074 			if (qflags & QLINK_CHAN_NO_HT40PLUS)
1075 				chan->flags |= IEEE80211_CHAN_NO_HT40PLUS;
1076 
1077 			if (qflags & QLINK_CHAN_NO_HT40MINUS)
1078 				chan->flags |= IEEE80211_CHAN_NO_HT40MINUS;
1079 
1080 			if (qflags & QLINK_CHAN_NO_OFDM)
1081 				chan->flags |= IEEE80211_CHAN_NO_OFDM;
1082 
1083 			if (qflags & QLINK_CHAN_NO_80MHZ)
1084 				chan->flags |= IEEE80211_CHAN_NO_80MHZ;
1085 
1086 			if (qflags & QLINK_CHAN_NO_160MHZ)
1087 				chan->flags |= IEEE80211_CHAN_NO_160MHZ;
1088 
1089 			if (qflags & QLINK_CHAN_INDOOR_ONLY)
1090 				chan->flags |= IEEE80211_CHAN_INDOOR_ONLY;
1091 
1092 			if (qflags & QLINK_CHAN_IR_CONCURRENT)
1093 				chan->flags |= IEEE80211_CHAN_IR_CONCURRENT;
1094 
1095 			if (qflags & QLINK_CHAN_NO_20MHZ)
1096 				chan->flags |= IEEE80211_CHAN_NO_20MHZ;
1097 
1098 			if (qflags & QLINK_CHAN_NO_10MHZ)
1099 				chan->flags |= IEEE80211_CHAN_NO_10MHZ;
1100 
1101 			if (qflags & QLINK_CHAN_RADAR) {
1102 				chan->flags |= IEEE80211_CHAN_RADAR;
1103 				chan->dfs_state_entered = jiffies;
1104 
1105 				if (qchan->dfs_state == QLINK_DFS_USABLE)
1106 					chan->dfs_state = NL80211_DFS_USABLE;
1107 				else if (qchan->dfs_state ==
1108 					QLINK_DFS_AVAILABLE)
1109 					chan->dfs_state = NL80211_DFS_AVAILABLE;
1110 				else
1111 					chan->dfs_state =
1112 						NL80211_DFS_UNAVAILABLE;
1113 			}
1114 
1115 			pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n",
1116 				 chan->hw_value, chan->flags, chan->max_power,
1117 				 chan->max_reg_power);
1118 			break;
1119 		default:
1120 			pr_warn("unknown TLV type: %#x\n", tlv_type);
1121 			break;
1122 		}
1123 
1124 		payload_len -= tlv_len;
1125 		tlv = (struct qlink_tlv_hdr *)((u8 *)tlv + tlv_len);
1126 	}
1127 
1128 	if (payload_len) {
1129 		pr_err("malformed TLV buf; bytes left: %zu\n", payload_len);
1130 		goto error_ret;
1131 	}
1132 
1133 	if (band->n_channels != chidx) {
1134 		pr_err("channel count mismatch: reported=%d, parsed=%d\n",
1135 		       band->n_channels, chidx);
1136 		goto error_ret;
1137 	}
1138 
1139 	return 0;
1140 
1141 error_ret:
1142 	kfree(band->channels);
1143 	band->channels = NULL;
1144 	band->n_channels = 0;
1145 
1146 	return -EINVAL;
1147 }
1148 
1149 static int qtnf_cmd_resp_proc_phy_params(struct qtnf_wmac *mac,
1150 					 const u8 *payload, size_t payload_len)
1151 {
1152 	struct qtnf_mac_info *mac_info;
1153 	struct qlink_tlv_frag_rts_thr *phy_thr;
1154 	struct qlink_tlv_rlimit *limit;
1155 	struct qlink_tlv_cclass *class;
1156 	u16 tlv_type;
1157 	u16 tlv_value_len;
1158 	size_t tlv_full_len;
1159 	const struct qlink_tlv_hdr *tlv;
1160 
1161 	mac_info = &mac->macinfo;
1162 
1163 	tlv = (struct qlink_tlv_hdr *)payload;
1164 	while (payload_len >= sizeof(struct qlink_tlv_hdr)) {
1165 		tlv_type = le16_to_cpu(tlv->type);
1166 		tlv_value_len = le16_to_cpu(tlv->len);
1167 		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
1168 
1169 		if (tlv_full_len > payload_len) {
1170 			pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n",
1171 				mac->macid, tlv_type, tlv_value_len);
1172 			return -EINVAL;
1173 		}
1174 
1175 		switch (tlv_type) {
1176 		case QTN_TLV_ID_FRAG_THRESH:
1177 			phy_thr = (void *)tlv;
1178 			mac_info->frag_thr = (u32)le16_to_cpu(phy_thr->thr);
1179 			break;
1180 		case QTN_TLV_ID_RTS_THRESH:
1181 			phy_thr = (void *)tlv;
1182 			mac_info->rts_thr = (u32)le16_to_cpu(phy_thr->thr);
1183 			break;
1184 		case QTN_TLV_ID_SRETRY_LIMIT:
1185 			limit = (void *)tlv;
1186 			mac_info->sretry_limit = limit->rlimit;
1187 			break;
1188 		case QTN_TLV_ID_LRETRY_LIMIT:
1189 			limit = (void *)tlv;
1190 			mac_info->lretry_limit = limit->rlimit;
1191 			break;
1192 		case QTN_TLV_ID_COVERAGE_CLASS:
1193 			class = (void *)tlv;
1194 			mac_info->coverage_class = class->cclass;
1195 			break;
1196 		default:
1197 			pr_err("MAC%u: Unknown TLV type: %#x\n", mac->macid,
1198 			       le16_to_cpu(tlv->type));
1199 			break;
1200 		}
1201 
1202 		payload_len -= tlv_full_len;
1203 		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
1204 	}
1205 
1206 	if (payload_len) {
1207 		pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n",
1208 			mac->macid, payload_len);
1209 		return -EINVAL;
1210 	}
1211 
1212 	return 0;
1213 }
1214 
1215 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac)
1216 {
1217 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1218 	const struct qlink_resp_get_mac_info *resp;
1219 	size_t var_data_len;
1220 	u16 res_code = QLINK_CMD_RESULT_OK;
1221 	int ret = 0;
1222 
1223 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
1224 					    QLINK_CMD_MAC_INFO,
1225 					    sizeof(struct qlink_cmd));
1226 	if (unlikely(!cmd_skb))
1227 		return -ENOMEM;
1228 
1229 	qtnf_bus_lock(mac->bus);
1230 
1231 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
1232 				       sizeof(*resp), &var_data_len);
1233 	if (unlikely(ret))
1234 		goto out;
1235 
1236 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1237 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1238 		ret = -EFAULT;
1239 		goto out;
1240 	}
1241 
1242 	resp = (const struct qlink_resp_get_mac_info *)resp_skb->data;
1243 	qtnf_cmd_resp_proc_mac_info(mac, resp);
1244 	ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len);
1245 
1246 out:
1247 	qtnf_bus_unlock(mac->bus);
1248 	consume_skb(resp_skb);
1249 
1250 	return ret;
1251 }
1252 
1253 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus)
1254 {
1255 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1256 	const struct qlink_resp_get_hw_info *resp;
1257 	u16 res_code = QLINK_CMD_RESULT_OK;
1258 	int ret = 0;
1259 
1260 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
1261 					    QLINK_CMD_GET_HW_INFO,
1262 					    sizeof(struct qlink_cmd));
1263 	if (unlikely(!cmd_skb))
1264 		return -ENOMEM;
1265 
1266 	qtnf_bus_lock(bus);
1267 
1268 	ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code,
1269 				       sizeof(*resp), NULL);
1270 
1271 	if (unlikely(ret))
1272 		goto out;
1273 
1274 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1275 		pr_err("cmd exec failed: 0x%.4X\n", res_code);
1276 		ret = -EFAULT;
1277 		goto out;
1278 	}
1279 
1280 	resp = (const struct qlink_resp_get_hw_info *)resp_skb->data;
1281 	ret = qtnf_cmd_resp_proc_hw_info(bus, resp);
1282 
1283 out:
1284 	qtnf_bus_unlock(bus);
1285 	consume_skb(resp_skb);
1286 
1287 	return ret;
1288 }
1289 
1290 int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac,
1291 			       struct ieee80211_supported_band *band)
1292 {
1293 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1294 	size_t info_len;
1295 	struct qlink_cmd_chans_info_get *cmd;
1296 	struct qlink_resp_get_chan_info *resp;
1297 	u16 res_code = QLINK_CMD_RESULT_OK;
1298 	int ret = 0;
1299 	u8 qband;
1300 
1301 	switch (band->band) {
1302 	case NL80211_BAND_2GHZ:
1303 		qband = QLINK_BAND_2GHZ;
1304 		break;
1305 	case NL80211_BAND_5GHZ:
1306 		qband = QLINK_BAND_5GHZ;
1307 		break;
1308 	case NL80211_BAND_60GHZ:
1309 		qband = QLINK_BAND_60GHZ;
1310 		break;
1311 	default:
1312 		return -EINVAL;
1313 	}
1314 
1315 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1316 					    QLINK_CMD_CHANS_INFO_GET,
1317 					    sizeof(*cmd));
1318 	if (!cmd_skb)
1319 		return -ENOMEM;
1320 
1321 	cmd = (struct qlink_cmd_chans_info_get *)cmd_skb->data;
1322 	cmd->band = qband;
1323 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
1324 				       sizeof(*resp), &info_len);
1325 
1326 	if (unlikely(ret))
1327 		goto out;
1328 
1329 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1330 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1331 		ret = -EFAULT;
1332 		goto out;
1333 	}
1334 
1335 	resp = (struct qlink_resp_get_chan_info *)resp_skb->data;
1336 	if (resp->band != qband) {
1337 		pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid,
1338 		       resp->band, qband);
1339 		ret = -EINVAL;
1340 		goto out;
1341 	}
1342 
1343 	ret = qtnf_cmd_resp_fill_channels_info(band, resp, info_len);
1344 
1345 out:
1346 	consume_skb(resp_skb);
1347 
1348 	return ret;
1349 }
1350 
1351 int qtnf_cmd_send_get_phy_params(struct qtnf_wmac *mac)
1352 {
1353 	struct sk_buff *cmd_skb, *resp_skb = NULL;
1354 	size_t response_size;
1355 	struct qlink_resp_phy_params *resp;
1356 	u16 res_code = QLINK_CMD_RESULT_OK;
1357 	int ret = 0;
1358 
1359 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1360 					    QLINK_CMD_PHY_PARAMS_GET,
1361 					    sizeof(struct qlink_cmd));
1362 	if (!cmd_skb)
1363 		return -ENOMEM;
1364 
1365 	qtnf_bus_lock(mac->bus);
1366 
1367 	ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code,
1368 				       sizeof(*resp), &response_size);
1369 
1370 	if (unlikely(ret))
1371 		goto out;
1372 
1373 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1374 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1375 		ret = -EFAULT;
1376 		goto out;
1377 	}
1378 
1379 	resp = (struct qlink_resp_phy_params *)resp_skb->data;
1380 	ret = qtnf_cmd_resp_proc_phy_params(mac, resp->info, response_size);
1381 
1382 out:
1383 	qtnf_bus_unlock(mac->bus);
1384 	consume_skb(resp_skb);
1385 
1386 	return ret;
1387 }
1388 
1389 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed)
1390 {
1391 	struct wiphy *wiphy = priv_to_wiphy(mac);
1392 	struct sk_buff *cmd_skb;
1393 	u16 res_code = QLINK_CMD_RESULT_OK;
1394 	int ret = 0;
1395 
1396 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1397 					    QLINK_CMD_PHY_PARAMS_SET,
1398 					    sizeof(struct qlink_cmd));
1399 	if (!cmd_skb)
1400 		return -ENOMEM;
1401 
1402 	qtnf_bus_lock(mac->bus);
1403 
1404 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
1405 		qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_FRAG_THRESH,
1406 					 wiphy->frag_threshold);
1407 	if (changed & WIPHY_PARAM_RTS_THRESHOLD)
1408 		qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_RTS_THRESH,
1409 					 wiphy->rts_threshold);
1410 	if (changed & WIPHY_PARAM_COVERAGE_CLASS)
1411 		qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS,
1412 					wiphy->coverage_class);
1413 
1414 	ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code);
1415 
1416 	if (unlikely(ret))
1417 		goto out;
1418 
1419 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1420 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1421 		ret = -EFAULT;
1422 		goto out;
1423 	}
1424 
1425 out:
1426 	qtnf_bus_unlock(mac->bus);
1427 	return ret;
1428 }
1429 
1430 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus)
1431 {
1432 	struct sk_buff *cmd_skb;
1433 	u16 res_code = QLINK_CMD_RESULT_OK;
1434 	int ret = 0;
1435 
1436 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
1437 					    QLINK_CMD_FW_INIT,
1438 					    sizeof(struct qlink_cmd));
1439 	if (unlikely(!cmd_skb))
1440 		return -ENOMEM;
1441 
1442 	qtnf_bus_lock(bus);
1443 
1444 	ret = qtnf_cmd_send(bus, cmd_skb, &res_code);
1445 
1446 	if (unlikely(ret))
1447 		goto out;
1448 
1449 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1450 		pr_err("cmd exec failed: 0x%.4X\n", res_code);
1451 		ret = -EFAULT;
1452 		goto out;
1453 	}
1454 
1455 out:
1456 	qtnf_bus_unlock(bus);
1457 	return ret;
1458 }
1459 
1460 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus)
1461 {
1462 	struct sk_buff *cmd_skb;
1463 
1464 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
1465 					    QLINK_CMD_FW_DEINIT,
1466 					    sizeof(struct qlink_cmd));
1467 	if (!cmd_skb)
1468 		return;
1469 
1470 	qtnf_bus_lock(bus);
1471 
1472 	qtnf_cmd_send(bus, cmd_skb, NULL);
1473 
1474 	qtnf_bus_unlock(bus);
1475 }
1476 
1477 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise,
1478 			  const u8 *mac_addr, struct key_params *params)
1479 {
1480 	struct sk_buff *cmd_skb;
1481 	struct qlink_cmd_add_key *cmd;
1482 	u16 res_code = QLINK_CMD_RESULT_OK;
1483 	int ret = 0;
1484 
1485 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1486 					    QLINK_CMD_ADD_KEY,
1487 					    sizeof(*cmd));
1488 	if (unlikely(!cmd_skb))
1489 		return -ENOMEM;
1490 
1491 	qtnf_bus_lock(vif->mac->bus);
1492 
1493 	cmd = (struct qlink_cmd_add_key *)cmd_skb->data;
1494 
1495 	if (mac_addr)
1496 		ether_addr_copy(cmd->addr, mac_addr);
1497 	else
1498 		eth_broadcast_addr(cmd->addr);
1499 
1500 	cmd->cipher = cpu_to_le32(params->cipher);
1501 	cmd->key_index = key_index;
1502 	cmd->pairwise = pairwise;
1503 
1504 	if (params->key && params->key_len > 0)
1505 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY,
1506 					 params->key,
1507 					 params->key_len);
1508 
1509 	if (params->seq && params->seq_len > 0)
1510 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ,
1511 					 params->seq,
1512 					 params->seq_len);
1513 
1514 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1515 	if (unlikely(ret))
1516 		goto out;
1517 
1518 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1519 		pr_err("VIF%u.%u: CMD failed: %u\n",
1520 		       vif->mac->macid, vif->vifid, res_code);
1521 		ret = -EFAULT;
1522 		goto out;
1523 	}
1524 
1525 out:
1526 	qtnf_bus_unlock(vif->mac->bus);
1527 	return ret;
1528 }
1529 
1530 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise,
1531 			  const u8 *mac_addr)
1532 {
1533 	struct sk_buff *cmd_skb;
1534 	struct qlink_cmd_del_key *cmd;
1535 	u16 res_code = QLINK_CMD_RESULT_OK;
1536 	int ret = 0;
1537 
1538 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1539 					    QLINK_CMD_DEL_KEY,
1540 					    sizeof(*cmd));
1541 	if (unlikely(!cmd_skb))
1542 		return -ENOMEM;
1543 
1544 	qtnf_bus_lock(vif->mac->bus);
1545 
1546 	cmd = (struct qlink_cmd_del_key *)cmd_skb->data;
1547 
1548 	if (mac_addr)
1549 		ether_addr_copy(cmd->addr, mac_addr);
1550 	else
1551 		eth_broadcast_addr(cmd->addr);
1552 
1553 	cmd->key_index = key_index;
1554 	cmd->pairwise = pairwise;
1555 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1556 	if (unlikely(ret))
1557 		goto out;
1558 
1559 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1560 		pr_err("VIF%u.%u: CMD failed: %u\n",
1561 		       vif->mac->macid, vif->vifid, res_code);
1562 		ret = -EFAULT;
1563 		goto out;
1564 	}
1565 
1566 out:
1567 	qtnf_bus_unlock(vif->mac->bus);
1568 	return ret;
1569 }
1570 
1571 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index,
1572 				  bool unicast, bool multicast)
1573 {
1574 	struct sk_buff *cmd_skb;
1575 	struct qlink_cmd_set_def_key *cmd;
1576 	u16 res_code = QLINK_CMD_RESULT_OK;
1577 	int ret = 0;
1578 
1579 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1580 					    QLINK_CMD_SET_DEFAULT_KEY,
1581 					    sizeof(*cmd));
1582 	if (unlikely(!cmd_skb))
1583 		return -ENOMEM;
1584 
1585 	qtnf_bus_lock(vif->mac->bus);
1586 
1587 	cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data;
1588 	cmd->key_index = key_index;
1589 	cmd->unicast = unicast;
1590 	cmd->multicast = multicast;
1591 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1592 	if (unlikely(ret))
1593 		goto out;
1594 
1595 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1596 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1597 		       vif->vifid, res_code);
1598 		ret = -EFAULT;
1599 		goto out;
1600 	}
1601 
1602 out:
1603 	qtnf_bus_unlock(vif->mac->bus);
1604 	return ret;
1605 }
1606 
1607 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index)
1608 {
1609 	struct sk_buff *cmd_skb;
1610 	struct qlink_cmd_set_def_mgmt_key *cmd;
1611 	u16 res_code = QLINK_CMD_RESULT_OK;
1612 	int ret = 0;
1613 
1614 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1615 					    QLINK_CMD_SET_DEFAULT_MGMT_KEY,
1616 					    sizeof(*cmd));
1617 	if (unlikely(!cmd_skb))
1618 		return -ENOMEM;
1619 
1620 	qtnf_bus_lock(vif->mac->bus);
1621 
1622 	cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data;
1623 	cmd->key_index = key_index;
1624 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1625 	if (unlikely(ret))
1626 		goto out;
1627 
1628 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1629 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1630 		       vif->vifid, res_code);
1631 		ret = -EFAULT;
1632 		goto out;
1633 	}
1634 
1635 out:
1636 	qtnf_bus_unlock(vif->mac->bus);
1637 	return ret;
1638 }
1639 
1640 static u32 qtnf_encode_sta_flags(u32 flags)
1641 {
1642 	u32 code = 0;
1643 
1644 	if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED))
1645 		code |= QLINK_STA_FLAG_AUTHORIZED;
1646 	if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
1647 		code |= QLINK_STA_FLAG_SHORT_PREAMBLE;
1648 	if (flags & BIT(NL80211_STA_FLAG_WME))
1649 		code |= QLINK_STA_FLAG_WME;
1650 	if (flags & BIT(NL80211_STA_FLAG_MFP))
1651 		code |= QLINK_STA_FLAG_MFP;
1652 	if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED))
1653 		code |= QLINK_STA_FLAG_AUTHENTICATED;
1654 	if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER))
1655 		code |= QLINK_STA_FLAG_TDLS_PEER;
1656 	if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED))
1657 		code |= QLINK_STA_FLAG_ASSOCIATED;
1658 	return code;
1659 }
1660 
1661 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac,
1662 			     struct station_parameters *params)
1663 {
1664 	struct sk_buff *cmd_skb;
1665 	struct qlink_cmd_change_sta *cmd;
1666 	u16 res_code = QLINK_CMD_RESULT_OK;
1667 	int ret = 0;
1668 
1669 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1670 					    QLINK_CMD_CHANGE_STA,
1671 					    sizeof(*cmd));
1672 	if (unlikely(!cmd_skb))
1673 		return -ENOMEM;
1674 
1675 	qtnf_bus_lock(vif->mac->bus);
1676 
1677 	cmd = (struct qlink_cmd_change_sta *)cmd_skb->data;
1678 	ether_addr_copy(cmd->sta_addr, mac);
1679 	cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags(
1680 					  params->sta_flags_mask));
1681 	cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags(
1682 					 params->sta_flags_set));
1683 
1684 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1685 	if (unlikely(ret))
1686 		goto out;
1687 
1688 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1689 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1690 		       vif->vifid, res_code);
1691 		ret = -EFAULT;
1692 		goto out;
1693 	}
1694 
1695 out:
1696 	qtnf_bus_unlock(vif->mac->bus);
1697 	return ret;
1698 }
1699 
1700 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif,
1701 			  struct station_del_parameters *params)
1702 {
1703 	struct sk_buff *cmd_skb;
1704 	struct qlink_cmd_del_sta *cmd;
1705 	u16 res_code = QLINK_CMD_RESULT_OK;
1706 	int ret = 0;
1707 
1708 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1709 					    QLINK_CMD_DEL_STA,
1710 					    sizeof(*cmd));
1711 	if (unlikely(!cmd_skb))
1712 		return -ENOMEM;
1713 
1714 	qtnf_bus_lock(vif->mac->bus);
1715 
1716 	cmd = (struct qlink_cmd_del_sta *)cmd_skb->data;
1717 
1718 	if (params->mac)
1719 		ether_addr_copy(cmd->sta_addr, params->mac);
1720 	else
1721 		eth_broadcast_addr(cmd->sta_addr);	/* flush all stations */
1722 
1723 	cmd->subtype = params->subtype;
1724 	cmd->reason_code = cpu_to_le16(params->reason_code);
1725 
1726 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1727 	if (unlikely(ret))
1728 		goto out;
1729 
1730 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1731 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1732 		       vif->vifid, res_code);
1733 		ret = -EFAULT;
1734 		goto out;
1735 	}
1736 
1737 out:
1738 	qtnf_bus_unlock(vif->mac->bus);
1739 	return ret;
1740 }
1741 
1742 int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
1743 {
1744 	struct sk_buff *cmd_skb;
1745 	u16 res_code = QLINK_CMD_RESULT_OK;
1746 	struct ieee80211_channel *sc;
1747 	struct cfg80211_scan_request *scan_req = mac->scan_req;
1748 	struct qlink_tlv_channel *qchan;
1749 	int n_channels;
1750 	int count = 0;
1751 	int ret;
1752 	u32 flags;
1753 
1754 	if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) {
1755 		pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid);
1756 		return -EINVAL;
1757 	}
1758 
1759 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
1760 					    QLINK_CMD_SCAN,
1761 					    sizeof(struct qlink_cmd));
1762 	if (unlikely(!cmd_skb))
1763 		return -ENOMEM;
1764 
1765 	qtnf_bus_lock(mac->bus);
1766 
1767 	if (scan_req->n_ssids != 0) {
1768 		while (count < scan_req->n_ssids) {
1769 			qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID,
1770 				scan_req->ssids[count].ssid,
1771 				scan_req->ssids[count].ssid_len);
1772 			count++;
1773 		}
1774 	}
1775 
1776 	if (scan_req->ie_len != 0)
1777 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET,
1778 					 scan_req->ie,
1779 					 scan_req->ie_len);
1780 
1781 	if (scan_req->n_channels) {
1782 		n_channels = scan_req->n_channels;
1783 		count = 0;
1784 
1785 		while (n_channels != 0) {
1786 			sc = scan_req->channels[count];
1787 			if (sc->flags & IEEE80211_CHAN_DISABLED) {
1788 				n_channels--;
1789 				continue;
1790 			}
1791 
1792 			pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n",
1793 				 mac->macid, sc->hw_value, sc->center_freq,
1794 				 sc->flags);
1795 			qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
1796 			flags = 0;
1797 
1798 			qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
1799 			qchan->hdr.len = cpu_to_le16(sizeof(*qchan) -
1800 					sizeof(struct qlink_tlv_hdr));
1801 			qchan->center_freq = cpu_to_le16(sc->center_freq);
1802 			qchan->hw_value = cpu_to_le16(sc->hw_value);
1803 
1804 			if (sc->flags & IEEE80211_CHAN_NO_IR)
1805 				flags |= QLINK_CHAN_NO_IR;
1806 
1807 			if (sc->flags & IEEE80211_CHAN_RADAR)
1808 				flags |= QLINK_CHAN_RADAR;
1809 
1810 			qchan->flags = cpu_to_le32(flags);
1811 			n_channels--;
1812 			count++;
1813 		}
1814 	}
1815 
1816 	ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code);
1817 
1818 	if (unlikely(ret))
1819 		goto out;
1820 
1821 	pr_debug("MAC%u: scan started\n", mac->macid);
1822 
1823 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1824 		pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code);
1825 		ret = -EFAULT;
1826 		goto out;
1827 	}
1828 out:
1829 	qtnf_bus_unlock(mac->bus);
1830 	return ret;
1831 }
1832 
1833 int qtnf_cmd_send_connect(struct qtnf_vif *vif,
1834 			  struct cfg80211_connect_params *sme)
1835 {
1836 	struct sk_buff *cmd_skb;
1837 	struct qlink_cmd_connect *cmd;
1838 	struct qtnf_bss_config *bss_cfg = &vif->bss_cfg;
1839 	struct qlink_auth_encr aen;
1840 	u16 res_code = QLINK_CMD_RESULT_OK;
1841 	int ret;
1842 	int i;
1843 
1844 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1845 					    QLINK_CMD_CONNECT,
1846 					    sizeof(*cmd));
1847 	if (unlikely(!cmd_skb))
1848 		return -ENOMEM;
1849 
1850 	qtnf_bus_lock(vif->mac->bus);
1851 
1852 	cmd = (struct qlink_cmd_connect *)cmd_skb->data;
1853 
1854 	ether_addr_copy(cmd->bssid, bss_cfg->bssid);
1855 
1856 	if (bss_cfg->chandef.chan)
1857 		cmd->freq = cpu_to_le16(bss_cfg->chandef.chan->center_freq);
1858 
1859 	cmd->bg_scan_period = cpu_to_le16(bss_cfg->bg_scan_period);
1860 
1861 	memset(&aen, 0, sizeof(aen));
1862 	aen.auth_type = bss_cfg->auth_type;
1863 	aen.privacy = !!bss_cfg->privacy;
1864 	aen.mfp = bss_cfg->mfp;
1865 	aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions);
1866 	aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group);
1867 	aen.n_ciphers_pairwise = cpu_to_le32(
1868 					bss_cfg->crypto.n_ciphers_pairwise);
1869 
1870 	for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
1871 		aen.ciphers_pairwise[i] = cpu_to_le32(
1872 					bss_cfg->crypto.ciphers_pairwise[i]);
1873 
1874 	aen.n_akm_suites = cpu_to_le32(bss_cfg->crypto.n_akm_suites);
1875 
1876 	for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
1877 		aen.akm_suites[i] = cpu_to_le32(
1878 					bss_cfg->crypto.akm_suites[i]);
1879 
1880 	aen.control_port = bss_cfg->crypto.control_port;
1881 	aen.control_port_no_encrypt =
1882 			bss_cfg->crypto.control_port_no_encrypt;
1883 	aen.control_port_ethertype = cpu_to_le16(be16_to_cpu(
1884 				bss_cfg->crypto.control_port_ethertype));
1885 
1886 	qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid,
1887 				 bss_cfg->ssid_len);
1888 	qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen,
1889 				 sizeof(aen));
1890 
1891 	if (sme->ie_len != 0)
1892 		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET,
1893 					 sme->ie,
1894 					 sme->ie_len);
1895 
1896 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1897 
1898 	if (unlikely(ret))
1899 		goto out;
1900 
1901 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1902 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1903 		       vif->vifid, res_code);
1904 		ret = -EFAULT;
1905 		goto out;
1906 	}
1907 out:
1908 	qtnf_bus_unlock(vif->mac->bus);
1909 	return ret;
1910 }
1911 
1912 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code)
1913 {
1914 	struct sk_buff *cmd_skb;
1915 	struct qlink_cmd_disconnect *cmd;
1916 	u16 res_code = QLINK_CMD_RESULT_OK;
1917 	int ret;
1918 
1919 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1920 					    QLINK_CMD_DISCONNECT,
1921 					    sizeof(*cmd));
1922 	if (unlikely(!cmd_skb))
1923 		return -ENOMEM;
1924 
1925 	qtnf_bus_lock(vif->mac->bus);
1926 
1927 	cmd = (struct qlink_cmd_disconnect *)cmd_skb->data;
1928 	cmd->reason = cpu_to_le16(reason_code);
1929 
1930 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1931 
1932 	if (unlikely(ret))
1933 		goto out;
1934 
1935 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1936 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1937 		       vif->vifid, res_code);
1938 		ret = -EFAULT;
1939 		goto out;
1940 	}
1941 out:
1942 	qtnf_bus_unlock(vif->mac->bus);
1943 	return ret;
1944 }
1945 
1946 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up)
1947 {
1948 	struct sk_buff *cmd_skb;
1949 	struct qlink_cmd_updown *cmd;
1950 	u16 res_code = QLINK_CMD_RESULT_OK;
1951 	int ret;
1952 
1953 	cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
1954 					    QLINK_CMD_UPDOWN_INTF,
1955 					    sizeof(*cmd));
1956 	if (unlikely(!cmd_skb))
1957 		return -ENOMEM;
1958 
1959 	cmd = (struct qlink_cmd_updown *)cmd_skb->data;
1960 	cmd->if_up = !!up;
1961 
1962 	qtnf_bus_lock(vif->mac->bus);
1963 
1964 	ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
1965 
1966 	if (unlikely(ret))
1967 		goto out;
1968 
1969 	if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
1970 		pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid,
1971 		       vif->vifid, res_code);
1972 		ret = -EFAULT;
1973 		goto out;
1974 	}
1975 out:
1976 	qtnf_bus_unlock(vif->mac->bus);
1977 	return ret;
1978 }
1979