1 // SPDX-License-Identifier: GPL-2.0+
2 /* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */
4 #include <linux/types.h>
5 #include <linux/skbuff.h>
10 #include "qlink_util.h"
14 /* Let device itself to select best values for current conditions */
15 #define QTNF_SCAN_TIME_AUTO 0
17 #define QTNF_SCAN_DWELL_ACTIVE_DEFAULT 90
18 #define QTNF_SCAN_DWELL_PASSIVE_DEFAULT 100
19 #define QTNF_SCAN_SAMPLE_DURATION_DEFAULT QTNF_SCAN_TIME_AUTO
21 static int qtnf_cmd_check_reply_header(const struct qlink_resp
*resp
,
22 u16 cmd_id
, u8 mac_id
, u8 vif_id
,
25 if (unlikely(le16_to_cpu(resp
->cmd_id
) != cmd_id
)) {
26 pr_warn("VIF%u.%u CMD%x: bad cmd_id in response: 0x%.4X\n",
27 mac_id
, vif_id
, cmd_id
, le16_to_cpu(resp
->cmd_id
));
31 if (unlikely(resp
->macid
!= mac_id
)) {
32 pr_warn("VIF%u.%u CMD%x: bad MAC in response: %u\n",
33 mac_id
, vif_id
, cmd_id
, resp
->macid
);
37 if (unlikely(resp
->vifid
!= vif_id
)) {
38 pr_warn("VIF%u.%u CMD%x: bad VIF in response: %u\n",
39 mac_id
, vif_id
, cmd_id
, resp
->vifid
);
43 if (unlikely(le16_to_cpu(resp
->mhdr
.len
) < resp_size
)) {
44 pr_warn("VIF%u.%u CMD%x: bad response size %u < %zu\n",
45 mac_id
, vif_id
, cmd_id
,
46 le16_to_cpu(resp
->mhdr
.len
), resp_size
);
53 static int qtnf_cmd_resp_result_decode(enum qlink_cmd_result qcode
)
56 case QLINK_CMD_RESULT_OK
:
58 case QLINK_CMD_RESULT_INVALID
:
60 case QLINK_CMD_RESULT_ENOTSUPP
:
62 case QLINK_CMD_RESULT_ENOTFOUND
:
64 case QLINK_CMD_RESULT_EALREADY
:
66 case QLINK_CMD_RESULT_EADDRINUSE
:
68 case QLINK_CMD_RESULT_EADDRNOTAVAIL
:
69 return -EADDRNOTAVAIL
;
70 case QLINK_CMD_RESULT_EBUSY
:
77 static int qtnf_cmd_send_with_reply(struct qtnf_bus
*bus
,
78 struct sk_buff
*cmd_skb
,
79 struct sk_buff
**response_skb
,
80 size_t const_resp_size
,
81 size_t *var_resp_size
)
83 struct qlink_cmd
*cmd
;
84 struct qlink_resp
*resp
= NULL
;
85 struct sk_buff
*resp_skb
= NULL
;
92 cmd
= (struct qlink_cmd
*)cmd_skb
->data
;
93 cmd_id
= le16_to_cpu(cmd
->cmd_id
);
96 cmd
->mhdr
.len
= cpu_to_le16(cmd_skb
->len
);
98 pr_debug("VIF%u.%u cmd=0x%.4X\n", mac_id
, vif_id
, cmd_id
);
100 if (!qtnf_fw_is_up(bus
) && cmd_id
!= QLINK_CMD_FW_INIT
) {
101 pr_warn("VIF%u.%u: drop cmd 0x%.4X in fw state %d\n",
102 mac_id
, vif_id
, cmd_id
, bus
->fw_state
);
103 dev_kfree_skb(cmd_skb
);
107 ret
= qtnf_trans_send_cmd_with_resp(bus
, cmd_skb
, &resp_skb
);
111 if (WARN_ON(!resp_skb
|| !resp_skb
->data
)) {
116 resp
= (struct qlink_resp
*)resp_skb
->data
;
117 resp_res
= le16_to_cpu(resp
->result
);
118 ret
= qtnf_cmd_check_reply_header(resp
, cmd_id
, mac_id
, vif_id
,
123 /* Return length of variable part of response */
124 if (response_skb
&& var_resp_size
)
125 *var_resp_size
= le16_to_cpu(resp
->mhdr
.len
) - const_resp_size
;
129 *response_skb
= resp_skb
;
131 consume_skb(resp_skb
);
134 return qtnf_cmd_resp_result_decode(resp_res
);
136 pr_warn("VIF%u.%u: cmd 0x%.4X failed: %d\n",
137 mac_id
, vif_id
, cmd_id
, ret
);
142 static inline int qtnf_cmd_send(struct qtnf_bus
*bus
, struct sk_buff
*cmd_skb
)
144 return qtnf_cmd_send_with_reply(bus
, cmd_skb
, NULL
,
145 sizeof(struct qlink_resp
), NULL
);
148 static struct sk_buff
*qtnf_cmd_alloc_new_cmdskb(u8 macid
, u8 vifid
, u16 cmd_no
,
151 struct qlink_cmd
*cmd
;
152 struct sk_buff
*cmd_skb
;
154 cmd_skb
= __dev_alloc_skb(sizeof(*cmd
) +
155 QTNF_MAX_CMD_BUF_SIZE
, GFP_KERNEL
);
156 if (unlikely(!cmd_skb
)) {
157 pr_err("VIF%u.%u CMD %u: alloc failed\n", macid
, vifid
, cmd_no
);
161 skb_put_zero(cmd_skb
, cmd_size
);
163 cmd
= (struct qlink_cmd
*)cmd_skb
->data
;
164 cmd
->mhdr
.len
= cpu_to_le16(cmd_skb
->len
);
165 cmd
->mhdr
.type
= cpu_to_le16(QLINK_MSG_TYPE_CMD
);
166 cmd
->cmd_id
= cpu_to_le16(cmd_no
);
173 static void qtnf_cmd_tlv_ie_set_add(struct sk_buff
*cmd_skb
, u8 frame_type
,
174 const u8
*buf
, size_t len
)
176 struct qlink_tlv_ie_set
*tlv
;
178 tlv
= (struct qlink_tlv_ie_set
*)skb_put(cmd_skb
, sizeof(*tlv
) +
179 round_up(len
, QLINK_ALIGN
));
180 tlv
->hdr
.type
= cpu_to_le16(QTN_TLV_ID_IE_SET
);
181 tlv
->hdr
.len
= cpu_to_le16(len
+ sizeof(*tlv
) - sizeof(tlv
->hdr
));
182 tlv
->type
= frame_type
;
186 memcpy(tlv
->ie_data
, buf
, len
);
189 static bool qtnf_cmd_start_ap_can_fit(const struct qtnf_vif
*vif
,
190 const struct cfg80211_ap_settings
*s
)
192 unsigned int len
= sizeof(struct qlink_cmd_start_ap
);
194 len
+= round_up(s
->ssid_len
, QLINK_ALIGN
);
195 len
+= round_up(s
->beacon
.head_len
, QLINK_ALIGN
);
196 len
+= round_up(s
->beacon
.tail_len
, QLINK_ALIGN
);
197 len
+= round_up(s
->beacon
.beacon_ies_len
, QLINK_ALIGN
);
198 len
+= round_up(s
->beacon
.proberesp_ies_len
, QLINK_ALIGN
);
199 len
+= round_up(s
->beacon
.assocresp_ies_len
, QLINK_ALIGN
);
200 len
+= round_up(s
->beacon
.probe_resp_len
, QLINK_ALIGN
);
202 if (cfg80211_chandef_valid(&s
->chandef
))
203 len
+= sizeof(struct qlink_tlv_chandef
);
206 unsigned int acl_len
= struct_size(s
->acl
, mac_addrs
,
207 s
->acl
->n_acl_entries
);
209 len
+= sizeof(struct qlink_tlv_hdr
) +
210 round_up(acl_len
, QLINK_ALIGN
);
213 if (len
> (sizeof(struct qlink_cmd
) + QTNF_MAX_CMD_BUF_SIZE
)) {
214 pr_err("VIF%u.%u: can not fit AP settings: %u\n",
215 vif
->mac
->macid
, vif
->vifid
, len
);
222 static void qtnf_cmd_tlv_ie_ext_add(struct sk_buff
*cmd_skb
, u8 eid_ext
,
223 const void *buf
, size_t len
)
225 struct qlink_tlv_ext_ie
*tlv
;
227 tlv
= (struct qlink_tlv_ext_ie
*)skb_put(cmd_skb
, sizeof(*tlv
) + len
);
228 tlv
->hdr
.type
= cpu_to_le16(WLAN_EID_EXTENSION
);
229 tlv
->hdr
.len
= cpu_to_le16(sizeof(*tlv
) + len
- sizeof(tlv
->hdr
));
230 tlv
->eid_ext
= eid_ext
;
233 memcpy(tlv
->ie_data
, buf
, len
);
236 int qtnf_cmd_send_start_ap(struct qtnf_vif
*vif
,
237 const struct cfg80211_ap_settings
*s
)
239 struct sk_buff
*cmd_skb
;
240 struct qlink_cmd_start_ap
*cmd
;
241 struct qlink_auth_encr
*aen
;
246 if (!qtnf_cmd_start_ap_can_fit(vif
, s
))
249 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
255 cmd
= (struct qlink_cmd_start_ap
*)cmd_skb
->data
;
256 cmd
->dtim_period
= s
->dtim_period
;
257 cmd
->beacon_interval
= cpu_to_le16(s
->beacon_interval
);
258 cmd
->hidden_ssid
= qlink_hidden_ssid_nl2q(s
->hidden_ssid
);
259 cmd
->inactivity_timeout
= cpu_to_le16(s
->inactivity_timeout
);
260 cmd
->smps_mode
= NL80211_SMPS_OFF
;
261 cmd
->p2p_ctwindow
= s
->p2p_ctwindow
;
262 cmd
->p2p_opp_ps
= s
->p2p_opp_ps
;
264 cmd
->ht_required
= s
->ht_required
;
265 cmd
->vht_required
= s
->vht_required
;
266 cmd
->twt_responder
= s
->twt_responder
;
267 if (s
->he_obss_pd
.enable
) {
268 cmd
->sr_params
.sr_control
|= QLINK_SR_SRG_INFORMATION_PRESENT
;
269 cmd
->sr_params
.srg_obss_pd_min_offset
=
270 s
->he_obss_pd
.min_offset
;
271 cmd
->sr_params
.srg_obss_pd_max_offset
=
272 s
->he_obss_pd
.max_offset
;
276 aen
->auth_type
= s
->auth_type
;
277 aen
->privacy
= !!s
->privacy
;
278 aen
->wpa_versions
= cpu_to_le32(s
->crypto
.wpa_versions
);
279 aen
->cipher_group
= cpu_to_le32(s
->crypto
.cipher_group
);
280 aen
->n_ciphers_pairwise
= cpu_to_le32(s
->crypto
.n_ciphers_pairwise
);
281 for (i
= 0; i
< QLINK_MAX_NR_CIPHER_SUITES
; i
++)
282 aen
->ciphers_pairwise
[i
] =
283 cpu_to_le32(s
->crypto
.ciphers_pairwise
[i
]);
284 n
= min(QLINK_MAX_NR_AKM_SUITES
, s
->crypto
.n_akm_suites
);
285 aen
->n_akm_suites
= cpu_to_le32(n
);
286 for (i
= 0; i
< n
; i
++)
287 aen
->akm_suites
[i
] = cpu_to_le32(s
->crypto
.akm_suites
[i
]);
288 aen
->control_port
= s
->crypto
.control_port
;
289 aen
->control_port_no_encrypt
= s
->crypto
.control_port_no_encrypt
;
290 aen
->control_port_ethertype
=
291 cpu_to_le16(be16_to_cpu(s
->crypto
.control_port_ethertype
));
293 if (s
->ssid
&& s
->ssid_len
> 0 && s
->ssid_len
<= IEEE80211_MAX_SSID_LEN
)
294 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, WLAN_EID_SSID
, s
->ssid
,
297 if (cfg80211_chandef_valid(&s
->chandef
)) {
298 struct qlink_tlv_chandef
*chtlv
=
299 (struct qlink_tlv_chandef
*)skb_put(cmd_skb
,
302 chtlv
->hdr
.type
= cpu_to_le16(QTN_TLV_ID_CHANDEF
);
303 chtlv
->hdr
.len
= cpu_to_le16(sizeof(*chtlv
) -
305 qlink_chandef_cfg2q(&s
->chandef
, &chtlv
->chdef
);
308 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_BEACON_HEAD
,
309 s
->beacon
.head
, s
->beacon
.head_len
);
310 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_BEACON_TAIL
,
311 s
->beacon
.tail
, s
->beacon
.tail_len
);
312 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_BEACON_IES
,
313 s
->beacon
.beacon_ies
, s
->beacon
.beacon_ies_len
);
314 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_PROBE_RESP
,
315 s
->beacon
.probe_resp
, s
->beacon
.probe_resp_len
);
316 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_PROBE_RESP_IES
,
317 s
->beacon
.proberesp_ies
,
318 s
->beacon
.proberesp_ies_len
);
319 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_ASSOC_RESP
,
320 s
->beacon
.assocresp_ies
,
321 s
->beacon
.assocresp_ies_len
);
324 struct qlink_tlv_hdr
*tlv
= (struct qlink_tlv_hdr
*)
325 skb_put(cmd_skb
, sizeof(*tlv
) +
326 round_up(sizeof(*s
->ht_cap
), QLINK_ALIGN
));
328 tlv
->type
= cpu_to_le16(WLAN_EID_HT_CAPABILITY
);
329 tlv
->len
= cpu_to_le16(sizeof(*s
->ht_cap
));
330 memcpy(tlv
->val
, s
->ht_cap
, sizeof(*s
->ht_cap
));
334 struct qlink_tlv_hdr
*tlv
= (struct qlink_tlv_hdr
*)
335 skb_put(cmd_skb
, sizeof(*tlv
) + sizeof(*s
->vht_cap
));
337 tlv
->type
= cpu_to_le16(WLAN_EID_VHT_CAPABILITY
);
338 tlv
->len
= cpu_to_le16(sizeof(*s
->vht_cap
));
339 memcpy(tlv
->val
, s
->vht_cap
, sizeof(*s
->vht_cap
));
343 qtnf_cmd_tlv_ie_ext_add(cmd_skb
, WLAN_EID_EXT_HE_CAPABILITY
,
344 s
->he_cap
, sizeof(*s
->he_cap
));
347 size_t acl_size
= struct_size(s
->acl
, mac_addrs
,
348 s
->acl
->n_acl_entries
);
349 struct qlink_tlv_hdr
*tlv
=
351 sizeof(*tlv
) + round_up(acl_size
, QLINK_ALIGN
));
353 tlv
->type
= cpu_to_le16(QTN_TLV_ID_ACL_DATA
);
354 tlv
->len
= cpu_to_le16(acl_size
);
355 qlink_acl_data_cfg2q(s
->acl
, (struct qlink_acl_data
*)tlv
->val
);
358 qtnf_bus_lock(vif
->mac
->bus
);
359 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
363 netif_carrier_on(vif
->netdev
);
366 qtnf_bus_unlock(vif
->mac
->bus
);
371 int qtnf_cmd_send_stop_ap(struct qtnf_vif
*vif
)
373 struct sk_buff
*cmd_skb
;
376 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
378 sizeof(struct qlink_cmd
));
382 qtnf_bus_lock(vif
->mac
->bus
);
383 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
384 qtnf_bus_unlock(vif
->mac
->bus
);
389 int qtnf_cmd_send_register_mgmt(struct qtnf_vif
*vif
, u16 frame_type
, bool reg
)
391 struct sk_buff
*cmd_skb
;
392 struct qlink_cmd_mgmt_frame_register
*cmd
;
395 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
396 QLINK_CMD_REGISTER_MGMT
,
401 qtnf_bus_lock(vif
->mac
->bus
);
403 cmd
= (struct qlink_cmd_mgmt_frame_register
*)cmd_skb
->data
;
404 cmd
->frame_type
= cpu_to_le16(frame_type
);
405 cmd
->do_register
= reg
;
407 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
409 qtnf_bus_unlock(vif
->mac
->bus
);
414 int qtnf_cmd_send_frame(struct qtnf_vif
*vif
, u32 cookie
, u16 flags
,
415 u16 freq
, const u8
*buf
, size_t len
)
417 struct sk_buff
*cmd_skb
;
418 struct qlink_cmd_frame_tx
*cmd
;
421 if (sizeof(*cmd
) + len
> QTNF_MAX_CMD_BUF_SIZE
) {
422 pr_warn("VIF%u.%u: frame is too big: %zu\n", vif
->mac
->macid
,
427 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
428 QLINK_CMD_SEND_FRAME
,
433 qtnf_bus_lock(vif
->mac
->bus
);
435 cmd
= (struct qlink_cmd_frame_tx
*)cmd_skb
->data
;
436 cmd
->cookie
= cpu_to_le32(cookie
);
437 cmd
->freq
= cpu_to_le16(freq
);
438 cmd
->flags
= cpu_to_le16(flags
);
441 qtnf_cmd_skb_put_buffer(cmd_skb
, buf
, len
);
443 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
445 qtnf_bus_unlock(vif
->mac
->bus
);
450 int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif
*vif
, u8 frame_type
,
451 const u8
*buf
, size_t len
)
453 struct sk_buff
*cmd_skb
;
456 if (len
> QTNF_MAX_CMD_BUF_SIZE
) {
457 pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif
->mac
->macid
,
458 vif
->vifid
, frame_type
, len
);
462 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
463 QLINK_CMD_MGMT_SET_APPIE
,
464 sizeof(struct qlink_cmd
));
468 qtnf_cmd_tlv_ie_set_add(cmd_skb
, frame_type
, buf
, len
);
470 qtnf_bus_lock(vif
->mac
->bus
);
471 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
472 qtnf_bus_unlock(vif
->mac
->bus
);
478 qtnf_sta_info_parse_rate(struct rate_info
*rate_dst
,
479 const struct qlink_sta_info_rate
*rate_src
)
481 rate_dst
->legacy
= get_unaligned_le16(&rate_src
->rate
) * 10;
483 rate_dst
->mcs
= rate_src
->mcs
;
484 rate_dst
->nss
= rate_src
->nss
;
487 switch (rate_src
->bw
) {
488 case QLINK_CHAN_WIDTH_5
:
489 rate_dst
->bw
= RATE_INFO_BW_5
;
491 case QLINK_CHAN_WIDTH_10
:
492 rate_dst
->bw
= RATE_INFO_BW_10
;
494 case QLINK_CHAN_WIDTH_20
:
495 case QLINK_CHAN_WIDTH_20_NOHT
:
496 rate_dst
->bw
= RATE_INFO_BW_20
;
498 case QLINK_CHAN_WIDTH_40
:
499 rate_dst
->bw
= RATE_INFO_BW_40
;
501 case QLINK_CHAN_WIDTH_80
:
502 rate_dst
->bw
= RATE_INFO_BW_80
;
504 case QLINK_CHAN_WIDTH_160
:
505 rate_dst
->bw
= RATE_INFO_BW_160
;
512 if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_HT_MCS
)
513 rate_dst
->flags
|= RATE_INFO_FLAGS_MCS
;
514 else if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_VHT_MCS
)
515 rate_dst
->flags
|= RATE_INFO_FLAGS_VHT_MCS
;
516 else if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_HE_MCS
)
517 rate_dst
->flags
|= RATE_INFO_FLAGS_HE_MCS
;
519 if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_SHORT_GI
)
520 rate_dst
->flags
|= RATE_INFO_FLAGS_SHORT_GI
;
524 qtnf_sta_info_parse_flags(struct nl80211_sta_flag_update
*dst
,
525 const struct qlink_sta_info_state
*src
)
532 mask
= le32_to_cpu(src
->mask
);
533 value
= le32_to_cpu(src
->value
);
535 if (mask
& QLINK_STA_FLAG_AUTHORIZED
) {
536 dst
->mask
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
537 if (value
& QLINK_STA_FLAG_AUTHORIZED
)
538 dst
->set
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
541 if (mask
& QLINK_STA_FLAG_SHORT_PREAMBLE
) {
542 dst
->mask
|= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
);
543 if (value
& QLINK_STA_FLAG_SHORT_PREAMBLE
)
544 dst
->set
|= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
);
547 if (mask
& QLINK_STA_FLAG_WME
) {
548 dst
->mask
|= BIT(NL80211_STA_FLAG_WME
);
549 if (value
& QLINK_STA_FLAG_WME
)
550 dst
->set
|= BIT(NL80211_STA_FLAG_WME
);
553 if (mask
& QLINK_STA_FLAG_MFP
) {
554 dst
->mask
|= BIT(NL80211_STA_FLAG_MFP
);
555 if (value
& QLINK_STA_FLAG_MFP
)
556 dst
->set
|= BIT(NL80211_STA_FLAG_MFP
);
559 if (mask
& QLINK_STA_FLAG_AUTHENTICATED
) {
560 dst
->mask
|= BIT(NL80211_STA_FLAG_AUTHENTICATED
);
561 if (value
& QLINK_STA_FLAG_AUTHENTICATED
)
562 dst
->set
|= BIT(NL80211_STA_FLAG_AUTHENTICATED
);
565 if (mask
& QLINK_STA_FLAG_TDLS_PEER
) {
566 dst
->mask
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
567 if (value
& QLINK_STA_FLAG_TDLS_PEER
)
568 dst
->set
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
571 if (mask
& QLINK_STA_FLAG_ASSOCIATED
) {
572 dst
->mask
|= BIT(NL80211_STA_FLAG_ASSOCIATED
);
573 if (value
& QLINK_STA_FLAG_ASSOCIATED
)
574 dst
->set
|= BIT(NL80211_STA_FLAG_ASSOCIATED
);
579 qtnf_cmd_sta_info_parse(struct station_info
*sinfo
, const u8
*data
,
582 const struct qlink_tlv_hdr
*tlv
;
583 const struct qlink_sta_stats
*stats
= NULL
;
584 const u8
*map
= NULL
;
585 unsigned int map_len
= 0;
586 unsigned int stats_len
= 0;
589 #define qtnf_sta_stat_avail(stat_name, bitn) \
590 (qtnf_utils_is_bit_set(map, bitn, map_len) && \
591 (offsetofend(struct qlink_sta_stats, stat_name) <= stats_len))
593 qlink_for_each_tlv(tlv
, data
, resp_size
) {
594 tlv_len
= le16_to_cpu(tlv
->len
);
596 switch (le16_to_cpu(tlv
->type
)) {
597 case QTN_TLV_ID_BITMAP
:
601 case QTN_TLV_ID_STA_STATS
:
603 stats
= (const struct qlink_sta_stats
*)tlv
->val
;
610 if (!qlink_tlv_parsing_ok(tlv
, data
, resp_size
)) {
611 pr_err("Malformed TLV buffer\n");
618 if (qtnf_sta_stat_avail(inactive_time
, QLINK_STA_INFO_INACTIVE_TIME
)) {
619 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME
);
620 sinfo
->inactive_time
= le32_to_cpu(stats
->inactive_time
);
623 if (qtnf_sta_stat_avail(connected_time
,
624 QLINK_STA_INFO_CONNECTED_TIME
)) {
625 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME
);
626 sinfo
->connected_time
= le32_to_cpu(stats
->connected_time
);
629 if (qtnf_sta_stat_avail(signal
, QLINK_STA_INFO_SIGNAL
)) {
630 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_SIGNAL
);
631 sinfo
->signal
= stats
->signal
- QLINK_RSSI_OFFSET
;
634 if (qtnf_sta_stat_avail(signal_avg
, QLINK_STA_INFO_SIGNAL_AVG
)) {
635 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG
);
636 sinfo
->signal_avg
= stats
->signal_avg
- QLINK_RSSI_OFFSET
;
639 if (qtnf_sta_stat_avail(rxrate
, QLINK_STA_INFO_RX_BITRATE
)) {
640 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_BITRATE
);
641 qtnf_sta_info_parse_rate(&sinfo
->rxrate
, &stats
->rxrate
);
644 if (qtnf_sta_stat_avail(txrate
, QLINK_STA_INFO_TX_BITRATE
)) {
645 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BITRATE
);
646 qtnf_sta_info_parse_rate(&sinfo
->txrate
, &stats
->txrate
);
649 if (qtnf_sta_stat_avail(sta_flags
, QLINK_STA_INFO_STA_FLAGS
)) {
650 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_STA_FLAGS
);
651 qtnf_sta_info_parse_flags(&sinfo
->sta_flags
, &stats
->sta_flags
);
654 if (qtnf_sta_stat_avail(rx_bytes
, QLINK_STA_INFO_RX_BYTES
)) {
655 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_BYTES
);
656 sinfo
->rx_bytes
= le64_to_cpu(stats
->rx_bytes
);
659 if (qtnf_sta_stat_avail(tx_bytes
, QLINK_STA_INFO_TX_BYTES
)) {
660 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BYTES
);
661 sinfo
->tx_bytes
= le64_to_cpu(stats
->tx_bytes
);
664 if (qtnf_sta_stat_avail(rx_bytes
, QLINK_STA_INFO_RX_BYTES64
)) {
665 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_BYTES64
);
666 sinfo
->rx_bytes
= le64_to_cpu(stats
->rx_bytes
);
669 if (qtnf_sta_stat_avail(tx_bytes
, QLINK_STA_INFO_TX_BYTES64
)) {
670 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BYTES64
);
671 sinfo
->tx_bytes
= le64_to_cpu(stats
->tx_bytes
);
674 if (qtnf_sta_stat_avail(rx_packets
, QLINK_STA_INFO_RX_PACKETS
)) {
675 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_PACKETS
);
676 sinfo
->rx_packets
= le32_to_cpu(stats
->rx_packets
);
679 if (qtnf_sta_stat_avail(tx_packets
, QLINK_STA_INFO_TX_PACKETS
)) {
680 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_PACKETS
);
681 sinfo
->tx_packets
= le32_to_cpu(stats
->tx_packets
);
684 if (qtnf_sta_stat_avail(rx_beacon
, QLINK_STA_INFO_BEACON_RX
)) {
685 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_BEACON_RX
);
686 sinfo
->rx_beacon
= le64_to_cpu(stats
->rx_beacon
);
689 if (qtnf_sta_stat_avail(rx_dropped_misc
, QLINK_STA_INFO_RX_DROP_MISC
)) {
690 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC
);
691 sinfo
->rx_dropped_misc
= le32_to_cpu(stats
->rx_dropped_misc
);
694 if (qtnf_sta_stat_avail(tx_failed
, QLINK_STA_INFO_TX_FAILED
)) {
695 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_FAILED
);
696 sinfo
->tx_failed
= le32_to_cpu(stats
->tx_failed
);
699 #undef qtnf_sta_stat_avail
702 int qtnf_cmd_get_sta_info(struct qtnf_vif
*vif
, const u8
*sta_mac
,
703 struct station_info
*sinfo
)
705 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
706 struct qlink_cmd_get_sta_info
*cmd
;
707 const struct qlink_resp_get_sta_info
*resp
;
708 size_t var_resp_len
= 0;
711 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
712 QLINK_CMD_GET_STA_INFO
,
717 qtnf_bus_lock(vif
->mac
->bus
);
719 cmd
= (struct qlink_cmd_get_sta_info
*)cmd_skb
->data
;
720 ether_addr_copy(cmd
->sta_addr
, sta_mac
);
722 ret
= qtnf_cmd_send_with_reply(vif
->mac
->bus
, cmd_skb
, &resp_skb
,
723 sizeof(*resp
), &var_resp_len
);
727 resp
= (const struct qlink_resp_get_sta_info
*)resp_skb
->data
;
729 if (!ether_addr_equal(sta_mac
, resp
->sta_addr
)) {
730 pr_err("VIF%u.%u: wrong mac in reply: %pM != %pM\n",
731 vif
->mac
->macid
, vif
->vifid
, resp
->sta_addr
, sta_mac
);
736 qtnf_cmd_sta_info_parse(sinfo
, resp
->info
, var_resp_len
);
739 qtnf_bus_unlock(vif
->mac
->bus
);
740 consume_skb(resp_skb
);
745 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif
*vif
,
746 enum nl80211_iftype iftype
,
749 enum qlink_cmd_type cmd_type
)
751 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
752 struct qlink_cmd_manage_intf
*cmd
;
753 const struct qlink_resp_manage_intf
*resp
;
756 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
762 qtnf_bus_lock(vif
->mac
->bus
);
764 cmd
= (struct qlink_cmd_manage_intf
*)cmd_skb
->data
;
765 cmd
->intf_info
.use4addr
= use4addr
;
768 case NL80211_IFTYPE_AP
:
769 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_AP
);
771 case NL80211_IFTYPE_STATION
:
772 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_STATION
);
775 pr_err("VIF%u.%u: unsupported type %d\n", vif
->mac
->macid
,
782 ether_addr_copy(cmd
->intf_info
.mac_addr
, mac_addr
);
784 eth_zero_addr(cmd
->intf_info
.mac_addr
);
786 ret
= qtnf_cmd_send_with_reply(vif
->mac
->bus
, cmd_skb
, &resp_skb
,
787 sizeof(*resp
), NULL
);
791 resp
= (const struct qlink_resp_manage_intf
*)resp_skb
->data
;
792 ether_addr_copy(vif
->mac_addr
, resp
->intf_info
.mac_addr
);
795 qtnf_bus_unlock(vif
->mac
->bus
);
796 consume_skb(resp_skb
);
801 int qtnf_cmd_send_add_intf(struct qtnf_vif
*vif
, enum nl80211_iftype iftype
,
802 int use4addr
, u8
*mac_addr
)
804 return qtnf_cmd_send_add_change_intf(vif
, iftype
, use4addr
, mac_addr
,
808 int qtnf_cmd_send_change_intf_type(struct qtnf_vif
*vif
,
809 enum nl80211_iftype iftype
,
815 ret
= qtnf_cmd_send_add_change_intf(vif
, iftype
, use4addr
, mac_addr
,
816 QLINK_CMD_CHANGE_INTF
);
818 /* Regulatory settings may be different for different interface types */
819 if (ret
== 0 && vif
->wdev
.iftype
!= iftype
) {
820 enum nl80211_band band
;
821 struct wiphy
*wiphy
= priv_to_wiphy(vif
->mac
);
823 for (band
= 0; band
< NUM_NL80211_BANDS
; ++band
) {
824 if (!wiphy
->bands
[band
])
827 qtnf_cmd_band_info_get(vif
->mac
, wiphy
->bands
[band
]);
834 int qtnf_cmd_send_del_intf(struct qtnf_vif
*vif
)
836 struct sk_buff
*cmd_skb
;
837 struct qlink_cmd_manage_intf
*cmd
;
840 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
846 qtnf_bus_lock(vif
->mac
->bus
);
848 cmd
= (struct qlink_cmd_manage_intf
*)cmd_skb
->data
;
850 switch (vif
->wdev
.iftype
) {
851 case NL80211_IFTYPE_AP
:
852 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_AP
);
854 case NL80211_IFTYPE_STATION
:
855 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_STATION
);
858 pr_warn("VIF%u.%u: unsupported iftype %d\n", vif
->mac
->macid
,
859 vif
->vifid
, vif
->wdev
.iftype
);
860 dev_kfree_skb(cmd_skb
);
865 eth_zero_addr(cmd
->intf_info
.mac_addr
);
867 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
872 qtnf_bus_unlock(vif
->mac
->bus
);
877 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus
*bus
,
878 const struct qlink_resp_get_hw_info
*resp
,
881 struct qtnf_hw_info
*hwinfo
= &bus
->hw_info
;
882 const struct qlink_tlv_hdr
*tlv
;
883 const char *bld_name
= NULL
;
884 const char *bld_rev
= NULL
;
885 const char *bld_type
= NULL
;
886 const char *bld_label
= NULL
;
889 const char *hw_id
= NULL
;
890 const char *calibration_ver
= NULL
;
891 const char *uboot_ver
= NULL
;
896 hwinfo
->num_mac
= resp
->num_mac
;
897 hwinfo
->mac_bitmap
= resp
->mac_bitmap
;
898 hwinfo
->fw_ver
= le32_to_cpu(resp
->fw_ver
);
899 hwinfo
->total_tx_chain
= resp
->total_tx_chain
;
900 hwinfo
->total_rx_chain
= resp
->total_rx_chain
;
902 bld_tmstamp
= le32_to_cpu(resp
->bld_tmstamp
);
903 plat_id
= le32_to_cpu(resp
->plat_id
);
904 hw_ver
= le32_to_cpu(resp
->hw_ver
);
906 qlink_for_each_tlv(tlv
, resp
->info
, info_len
) {
907 tlv_type
= le16_to_cpu(tlv
->type
);
908 tlv_len
= le16_to_cpu(tlv
->len
);
911 case QTN_TLV_ID_BUILD_NAME
:
912 bld_name
= (const void *)tlv
->val
;
914 case QTN_TLV_ID_BUILD_REV
:
915 bld_rev
= (const void *)tlv
->val
;
917 case QTN_TLV_ID_BUILD_TYPE
:
918 bld_type
= (const void *)tlv
->val
;
920 case QTN_TLV_ID_BUILD_LABEL
:
921 bld_label
= (const void *)tlv
->val
;
923 case QTN_TLV_ID_HW_ID
:
924 hw_id
= (const void *)tlv
->val
;
926 case QTN_TLV_ID_CALIBRATION_VER
:
927 calibration_ver
= (const void *)tlv
->val
;
929 case QTN_TLV_ID_UBOOT_VER
:
930 uboot_ver
= (const void *)tlv
->val
;
932 case QTN_TLV_ID_BITMAP
:
933 memcpy(hwinfo
->hw_capab
, tlv
->val
,
934 min(sizeof(hwinfo
->hw_capab
), (size_t)tlv_len
));
941 if (!qlink_tlv_parsing_ok(tlv
, resp
->info
, info_len
)) {
942 pr_err("Malformed TLV buffer\n");
946 pr_info("\nBuild name: %s\n"
947 "Build revision: %s\n"
950 "Build timestamp: %lu\n"
953 "Calibration version: %s\n"
954 "U-Boot version: %s\n"
955 "Hardware version: 0x%08x\n"
958 "Chains Rx-Tx: %ux%u\n"
959 "FW version: 0x%x\n",
960 bld_name
, bld_rev
, bld_type
, bld_label
,
961 (unsigned long)bld_tmstamp
,
962 (unsigned long)plat_id
,
963 hw_id
, calibration_ver
, uboot_ver
, hw_ver
,
964 QLINK_VER_MAJOR(bus
->hw_info
.ql_proto_ver
),
965 QLINK_VER_MINOR(bus
->hw_info
.ql_proto_ver
),
967 hwinfo
->total_rx_chain
, hwinfo
->total_tx_chain
,
970 strscpy(hwinfo
->fw_version
, bld_label
, sizeof(hwinfo
->fw_version
));
971 hwinfo
->hw_version
= hw_ver
;
977 qtnf_parse_wowlan_info(struct qtnf_wmac
*mac
,
978 const struct qlink_wowlan_capab_data
*wowlan
)
980 struct qtnf_mac_info
*mac_info
= &mac
->macinfo
;
981 const struct qlink_wowlan_support
*data1
;
982 struct wiphy_wowlan_support
*supp
;
984 supp
= kzalloc(sizeof(*supp
), GFP_KERNEL
);
988 switch (le16_to_cpu(wowlan
->version
)) {
990 data1
= (struct qlink_wowlan_support
*)wowlan
->data
;
992 supp
->flags
= WIPHY_WOWLAN_MAGIC_PKT
| WIPHY_WOWLAN_DISCONNECT
;
993 supp
->n_patterns
= le32_to_cpu(data1
->n_patterns
);
994 supp
->pattern_max_len
= le32_to_cpu(data1
->pattern_max_len
);
995 supp
->pattern_min_len
= le32_to_cpu(data1
->pattern_min_len
);
997 mac_info
->wowlan
= supp
;
1000 pr_warn("MAC%u: unsupported WoWLAN version 0x%x\n",
1001 mac
->macid
, le16_to_cpu(wowlan
->version
));
1008 qtnf_parse_variable_mac_info(struct qtnf_wmac
*mac
,
1009 const struct qlink_resp_get_mac_info
*resp
,
1010 size_t tlv_buf_size
)
1012 struct ieee80211_iface_combination
*comb
= mac
->macinfo
.if_comb
;
1014 struct ieee80211_iface_limit
*limits
;
1015 const struct qlink_iface_limit_record
*rec
;
1016 const struct qlink_iface_limit
*lim
;
1017 const struct qlink_wowlan_capab_data
*wowlan
;
1021 const struct qlink_tlv_hdr
*tlv
;
1022 u8
*ext_capa
= NULL
;
1023 u8
*ext_capa_mask
= NULL
;
1024 u8 ext_capa_len
= 0;
1025 u8 ext_capa_mask_len
= 0;
1027 struct ieee80211_reg_rule
*rule
;
1028 unsigned int rule_idx
= 0;
1029 const struct qlink_tlv_reg_rule
*tlv_rule
;
1031 if (WARN_ON(resp
->n_reg_rules
> NL80211_MAX_SUPP_REG_RULES
))
1034 mac
->rd
= kzalloc(struct_size(mac
->rd
, reg_rules
, resp
->n_reg_rules
),
1039 mac
->rd
->n_reg_rules
= resp
->n_reg_rules
;
1040 mac
->rd
->alpha2
[0] = resp
->alpha2
[0];
1041 mac
->rd
->alpha2
[1] = resp
->alpha2
[1];
1043 switch (resp
->dfs_region
) {
1045 mac
->rd
->dfs_region
= NL80211_DFS_FCC
;
1047 case QLINK_DFS_ETSI
:
1048 mac
->rd
->dfs_region
= NL80211_DFS_ETSI
;
1051 mac
->rd
->dfs_region
= NL80211_DFS_JP
;
1053 case QLINK_DFS_UNSET
:
1055 mac
->rd
->dfs_region
= NL80211_DFS_UNSET
;
1059 qlink_for_each_tlv(tlv
, resp
->var_info
, tlv_buf_size
) {
1060 tlv_type
= le16_to_cpu(tlv
->type
);
1061 tlv_value_len
= le16_to_cpu(tlv
->len
);
1064 case QTN_TLV_ID_IFACE_LIMIT
:
1065 if (unlikely(!comb
)) {
1066 pr_warn("MAC%u: no combinations advertised\n",
1071 if (n_comb
>= mac
->macinfo
.n_if_comb
) {
1072 pr_warn("MAC%u: combinations count exceeded\n",
1078 rec
= (void *)tlv
->val
;
1079 rec_len
= sizeof(*rec
) + rec
->n_limits
* sizeof(*lim
);
1081 if (unlikely(tlv_value_len
!= rec_len
)) {
1082 pr_warn("MAC%u: record %zu size mismatch\n",
1083 mac
->macid
, n_comb
);
1087 limits
= kcalloc(rec
->n_limits
, sizeof(*limits
),
1092 comb
[n_comb
].num_different_channels
=
1093 rec
->num_different_channels
;
1094 comb
[n_comb
].max_interfaces
=
1095 le16_to_cpu(rec
->max_interfaces
);
1096 comb
[n_comb
].n_limits
= rec
->n_limits
;
1097 comb
[n_comb
].limits
= limits
;
1099 for (i
= 0; i
< rec
->n_limits
; i
++) {
1100 lim
= &rec
->limits
[i
];
1101 limits
[i
].max
= le16_to_cpu(lim
->max_num
);
1103 qlink_iface_type_to_nl_mask(le16_to_cpu(lim
->type
));
1104 pr_debug("MAC%u: comb[%zu]: MAX:%u TYPES:%.4X\n",
1106 limits
[i
].max
, limits
[i
].types
);
1111 case WLAN_EID_EXT_CAPABILITY
:
1112 if (unlikely(tlv_value_len
> U8_MAX
))
1114 ext_capa
= (u8
*)tlv
->val
;
1115 ext_capa_len
= tlv_value_len
;
1117 case QTN_TLV_ID_EXT_CAPABILITY_MASK
:
1118 if (unlikely(tlv_value_len
> U8_MAX
))
1120 ext_capa_mask
= (u8
*)tlv
->val
;
1121 ext_capa_mask_len
= tlv_value_len
;
1123 case QTN_TLV_ID_WOWLAN_CAPAB
:
1124 if (tlv_value_len
< sizeof(*wowlan
))
1127 wowlan
= (void *)tlv
->val
;
1128 if (!le16_to_cpu(wowlan
->len
)) {
1129 pr_warn("MAC%u: skip empty WoWLAN data\n",
1134 rec_len
= sizeof(*wowlan
) + le16_to_cpu(wowlan
->len
);
1135 if (unlikely(tlv_value_len
!= rec_len
)) {
1136 pr_warn("MAC%u: WoWLAN data size mismatch\n",
1141 kfree(mac
->macinfo
.wowlan
);
1142 mac
->macinfo
.wowlan
= NULL
;
1143 qtnf_parse_wowlan_info(mac
, wowlan
);
1145 case QTN_TLV_ID_REG_RULE
:
1146 if (rule_idx
>= resp
->n_reg_rules
) {
1147 pr_warn("unexpected number of rules: %u\n",
1152 if (tlv_value_len
!= sizeof(*tlv_rule
) - sizeof(*tlv
)) {
1153 pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
1154 tlv_type
, tlv_value_len
);
1158 tlv_rule
= (const struct qlink_tlv_reg_rule
*)tlv
;
1159 rule
= &mac
->rd
->reg_rules
[rule_idx
++];
1160 qlink_utils_regrule_q2nl(rule
, tlv_rule
);
1163 pr_warn("MAC%u: unknown TLV type %u\n",
1164 mac
->macid
, tlv_type
);
1169 if (!qlink_tlv_parsing_ok(tlv
, resp
->var_info
, tlv_buf_size
)) {
1170 pr_err("Malformed TLV buffer\n");
1174 if (mac
->macinfo
.n_if_comb
!= n_comb
) {
1175 pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n",
1176 mac
->macid
, mac
->macinfo
.n_if_comb
, n_comb
);
1180 if (ext_capa_len
!= ext_capa_mask_len
) {
1181 pr_err("MAC%u: ext_capa/_mask lengths mismatch: %u != %u\n",
1182 mac
->macid
, ext_capa_len
, ext_capa_mask_len
);
1186 if (rule_idx
!= resp
->n_reg_rules
) {
1187 pr_warn("unexpected number of rules: expected %u got %u\n",
1188 resp
->n_reg_rules
, rule_idx
);
1192 if (ext_capa_len
> 0) {
1193 ext_capa
= kmemdup(ext_capa
, ext_capa_len
, GFP_KERNEL
);
1198 kmemdup(ext_capa_mask
, ext_capa_mask_len
, GFP_KERNEL
);
1199 if (!ext_capa_mask
) {
1205 ext_capa_mask
= NULL
;
1208 qtnf_mac_ext_caps_free(mac
);
1209 mac
->macinfo
.extended_capabilities
= ext_capa
;
1210 mac
->macinfo
.extended_capabilities_mask
= ext_capa_mask
;
1211 mac
->macinfo
.extended_capabilities_len
= ext_capa_len
;
1217 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac
*mac
,
1218 const struct qlink_resp_get_mac_info
*resp_info
)
1220 struct qtnf_mac_info
*mac_info
;
1221 struct qtnf_vif
*vif
;
1223 qtnf_mac_iface_comb_free(mac
);
1225 mac_info
= &mac
->macinfo
;
1227 mac_info
->bands_cap
= resp_info
->bands_cap
;
1228 ether_addr_copy(mac
->macaddr
, resp_info
->dev_mac
);
1230 vif
= qtnf_mac_get_base_vif(mac
);
1232 ether_addr_copy(vif
->mac_addr
, mac
->macaddr
);
1234 pr_err("could not get valid base vif\n");
1236 mac_info
->num_tx_chain
= resp_info
->num_tx_chain
;
1237 mac_info
->num_rx_chain
= resp_info
->num_rx_chain
;
1239 mac_info
->max_ap_assoc_sta
= le16_to_cpu(resp_info
->max_ap_assoc_sta
);
1240 mac_info
->radar_detect_widths
=
1241 qlink_chan_width_mask_to_nl(le16_to_cpu(
1242 resp_info
->radar_detect_widths
));
1243 mac_info
->max_acl_mac_addrs
= le16_to_cpu(resp_info
->max_acl_mac_addrs
);
1244 mac_info
->frag_thr
= le32_to_cpu(resp_info
->frag_threshold
);
1245 mac_info
->rts_thr
= le32_to_cpu(resp_info
->rts_threshold
);
1246 mac_info
->sretry_limit
= resp_info
->retry_short
;
1247 mac_info
->lretry_limit
= resp_info
->retry_long
;
1248 mac_info
->coverage_class
= resp_info
->coverage_class
;
1249 mac_info
->max_scan_ssids
= resp_info
->max_scan_ssids
;
1251 memcpy(&mac_info
->ht_cap_mod_mask
, &resp_info
->ht_cap_mod_mask
,
1252 sizeof(mac_info
->ht_cap_mod_mask
));
1253 memcpy(&mac_info
->vht_cap_mod_mask
, &resp_info
->vht_cap_mod_mask
,
1254 sizeof(mac_info
->vht_cap_mod_mask
));
1256 mac_info
->n_if_comb
= resp_info
->n_iface_combinations
;
1257 mac_info
->if_comb
= kcalloc(mac
->macinfo
.n_if_comb
,
1258 sizeof(*mac
->macinfo
.if_comb
),
1261 if (!mac
->macinfo
.if_comb
)
1267 static void qtnf_cmd_resp_band_fill_htcap(const u8
*info
,
1268 struct ieee80211_sta_ht_cap
*bcap
)
1270 const struct ieee80211_ht_cap
*ht_cap
=
1271 (const struct ieee80211_ht_cap
*)info
;
1273 bcap
->ht_supported
= true;
1274 bcap
->cap
= le16_to_cpu(ht_cap
->cap_info
);
1275 bcap
->ampdu_factor
=
1276 ht_cap
->ampdu_params_info
& IEEE80211_HT_AMPDU_PARM_FACTOR
;
1277 bcap
->ampdu_density
=
1278 (ht_cap
->ampdu_params_info
& IEEE80211_HT_AMPDU_PARM_DENSITY
) >>
1279 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT
;
1280 memcpy(&bcap
->mcs
, &ht_cap
->mcs
, sizeof(bcap
->mcs
));
1283 static void qtnf_cmd_resp_band_fill_vhtcap(const u8
*info
,
1284 struct ieee80211_sta_vht_cap
*bcap
)
1286 const struct ieee80211_vht_cap
*vht_cap
=
1287 (const struct ieee80211_vht_cap
*)info
;
1289 bcap
->vht_supported
= true;
1290 bcap
->cap
= le32_to_cpu(vht_cap
->vht_cap_info
);
1291 memcpy(&bcap
->vht_mcs
, &vht_cap
->supp_mcs
, sizeof(bcap
->vht_mcs
));
1294 static void qtnf_cmd_conv_iftype(struct ieee80211_sband_iftype_data
1296 const struct qlink_sband_iftype_data
1299 iftype_data
->types_mask
= le16_to_cpu(qlink_data
->types_mask
);
1301 iftype_data
->he_cap
.has_he
= true;
1302 memcpy(&iftype_data
->he_cap
.he_cap_elem
, &qlink_data
->he_cap_elem
,
1303 sizeof(qlink_data
->he_cap_elem
));
1304 memcpy(iftype_data
->he_cap
.ppe_thres
, qlink_data
->ppe_thres
,
1305 ARRAY_SIZE(qlink_data
->ppe_thres
));
1307 iftype_data
->he_cap
.he_mcs_nss_supp
.rx_mcs_80
=
1308 qlink_data
->he_mcs_nss_supp
.rx_mcs_80
;
1309 iftype_data
->he_cap
.he_mcs_nss_supp
.tx_mcs_80
=
1310 qlink_data
->he_mcs_nss_supp
.tx_mcs_80
;
1311 iftype_data
->he_cap
.he_mcs_nss_supp
.rx_mcs_160
=
1312 qlink_data
->he_mcs_nss_supp
.rx_mcs_160
;
1313 iftype_data
->he_cap
.he_mcs_nss_supp
.tx_mcs_160
=
1314 qlink_data
->he_mcs_nss_supp
.tx_mcs_160
;
1315 iftype_data
->he_cap
.he_mcs_nss_supp
.rx_mcs_80p80
=
1316 qlink_data
->he_mcs_nss_supp
.rx_mcs_80p80
;
1317 iftype_data
->he_cap
.he_mcs_nss_supp
.tx_mcs_80p80
=
1318 qlink_data
->he_mcs_nss_supp
.tx_mcs_80p80
;
1321 static int qtnf_cmd_band_fill_iftype(const u8
*data
,
1322 struct ieee80211_supported_band
*band
)
1325 struct ieee80211_sband_iftype_data
*iftype_data
;
1326 const struct qlink_tlv_iftype_data
*tlv
=
1327 (const struct qlink_tlv_iftype_data
*)data
;
1330 payload_len
= struct_size(tlv
, iftype_data
, tlv
->n_iftype_data
);
1331 payload_len
= size_sub(payload_len
, sizeof(struct qlink_tlv_hdr
));
1333 if (tlv
->hdr
.len
!= cpu_to_le16(payload_len
)) {
1334 pr_err("bad IFTYPE_DATA TLV len %u\n", tlv
->hdr
.len
);
1338 kfree((__force
void *)band
->iftype_data
);
1339 band
->iftype_data
= NULL
;
1340 band
->n_iftype_data
= tlv
->n_iftype_data
;
1341 if (band
->n_iftype_data
== 0)
1344 iftype_data
= kcalloc(band
->n_iftype_data
, sizeof(*iftype_data
),
1347 band
->n_iftype_data
= 0;
1351 _ieee80211_set_sband_iftype_data(band
, iftype_data
, tlv
->n_iftype_data
);
1353 for (i
= 0; i
< band
->n_iftype_data
; i
++)
1354 qtnf_cmd_conv_iftype(iftype_data
++, &tlv
->iftype_data
[i
]);
1360 qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band
*band
,
1361 struct qlink_resp_band_info_get
*resp
,
1366 const struct qlink_tlv_hdr
*tlv
;
1367 const struct qlink_channel
*qchan
;
1368 struct ieee80211_channel
*chan
;
1369 unsigned int chidx
= 0;
1373 memset(&band
->ht_cap
, 0, sizeof(band
->ht_cap
));
1374 memset(&band
->vht_cap
, 0, sizeof(band
->vht_cap
));
1376 if (band
->channels
) {
1377 if (band
->n_channels
== resp
->num_chans
) {
1378 memset(band
->channels
, 0,
1379 sizeof(*band
->channels
) * band
->n_channels
);
1381 kfree(band
->channels
);
1382 band
->n_channels
= 0;
1383 band
->channels
= NULL
;
1387 band
->n_channels
= resp
->num_chans
;
1388 if (band
->n_channels
== 0)
1391 if (!band
->channels
)
1392 band
->channels
= kcalloc(band
->n_channels
, sizeof(*chan
),
1394 if (!band
->channels
) {
1395 band
->n_channels
= 0;
1399 qlink_for_each_tlv(tlv
, resp
->info
, payload_len
) {
1400 tlv_type
= le16_to_cpu(tlv
->type
);
1401 tlv_dlen
= le16_to_cpu(tlv
->len
);
1404 case QTN_TLV_ID_CHANNEL
:
1405 if (unlikely(tlv_dlen
!= sizeof(*qchan
))) {
1406 pr_err("invalid channel TLV len %zu\n",
1411 if (chidx
== band
->n_channels
) {
1412 pr_err("too many channel TLVs\n");
1416 qchan
= (const struct qlink_channel
*)tlv
->val
;
1417 chan
= &band
->channels
[chidx
++];
1418 qflags
= le32_to_cpu(qchan
->flags
);
1420 chan
->hw_value
= le16_to_cpu(qchan
->hw_value
);
1421 chan
->band
= band
->band
;
1422 chan
->center_freq
= le16_to_cpu(qchan
->center_freq
);
1423 chan
->max_antenna_gain
= (int)qchan
->max_antenna_gain
;
1424 chan
->max_power
= (int)qchan
->max_power
;
1425 chan
->max_reg_power
= (int)qchan
->max_reg_power
;
1426 chan
->beacon_found
= qchan
->beacon_found
;
1427 chan
->dfs_cac_ms
= le32_to_cpu(qchan
->dfs_cac_ms
);
1430 if (qflags
& QLINK_CHAN_DISABLED
)
1431 chan
->flags
|= IEEE80211_CHAN_DISABLED
;
1433 if (qflags
& QLINK_CHAN_NO_IR
)
1434 chan
->flags
|= IEEE80211_CHAN_NO_IR
;
1436 if (qflags
& QLINK_CHAN_NO_HT40PLUS
)
1437 chan
->flags
|= IEEE80211_CHAN_NO_HT40PLUS
;
1439 if (qflags
& QLINK_CHAN_NO_HT40MINUS
)
1440 chan
->flags
|= IEEE80211_CHAN_NO_HT40MINUS
;
1442 if (qflags
& QLINK_CHAN_NO_OFDM
)
1443 chan
->flags
|= IEEE80211_CHAN_NO_OFDM
;
1445 if (qflags
& QLINK_CHAN_NO_80MHZ
)
1446 chan
->flags
|= IEEE80211_CHAN_NO_80MHZ
;
1448 if (qflags
& QLINK_CHAN_NO_160MHZ
)
1449 chan
->flags
|= IEEE80211_CHAN_NO_160MHZ
;
1451 if (qflags
& QLINK_CHAN_INDOOR_ONLY
)
1452 chan
->flags
|= IEEE80211_CHAN_INDOOR_ONLY
;
1454 if (qflags
& QLINK_CHAN_IR_CONCURRENT
)
1455 chan
->flags
|= IEEE80211_CHAN_IR_CONCURRENT
;
1457 if (qflags
& QLINK_CHAN_NO_20MHZ
)
1458 chan
->flags
|= IEEE80211_CHAN_NO_20MHZ
;
1460 if (qflags
& QLINK_CHAN_NO_10MHZ
)
1461 chan
->flags
|= IEEE80211_CHAN_NO_10MHZ
;
1463 if (qflags
& QLINK_CHAN_RADAR
) {
1464 chan
->flags
|= IEEE80211_CHAN_RADAR
;
1465 chan
->dfs_state_entered
= jiffies
;
1467 if (qchan
->dfs_state
== QLINK_DFS_USABLE
)
1468 chan
->dfs_state
= NL80211_DFS_USABLE
;
1469 else if (qchan
->dfs_state
==
1470 QLINK_DFS_AVAILABLE
)
1471 chan
->dfs_state
= NL80211_DFS_AVAILABLE
;
1474 NL80211_DFS_UNAVAILABLE
;
1477 pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n",
1478 chan
->hw_value
, chan
->flags
, chan
->max_power
,
1479 chan
->max_reg_power
);
1481 case WLAN_EID_HT_CAPABILITY
:
1482 if (unlikely(tlv_dlen
!=
1483 sizeof(struct ieee80211_ht_cap
))) {
1484 pr_err("bad HTCAP TLV len %zu\n", tlv_dlen
);
1488 qtnf_cmd_resp_band_fill_htcap(tlv
->val
, &band
->ht_cap
);
1490 case WLAN_EID_VHT_CAPABILITY
:
1491 if (unlikely(tlv_dlen
!=
1492 sizeof(struct ieee80211_vht_cap
))) {
1493 pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen
);
1497 qtnf_cmd_resp_band_fill_vhtcap(tlv
->val
,
1500 case QTN_TLV_ID_IFTYPE_DATA
:
1501 ret
= qtnf_cmd_band_fill_iftype((const uint8_t *)tlv
,
1507 pr_warn("unknown TLV type: %#x\n", tlv_type
);
1512 if (!qlink_tlv_parsing_ok(tlv
, resp
->info
, payload_len
)) {
1513 pr_err("Malformed TLV buffer\n");
1517 if (band
->n_channels
!= chidx
) {
1518 pr_err("channel count mismatch: reported=%d, parsed=%d\n",
1519 band
->n_channels
, chidx
);
1526 kfree(band
->channels
);
1527 band
->channels
= NULL
;
1528 band
->n_channels
= 0;
1533 int qtnf_cmd_get_mac_info(struct qtnf_wmac
*mac
)
1535 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1536 const struct qlink_resp_get_mac_info
*resp
;
1537 size_t var_data_len
= 0;
1540 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
1542 sizeof(struct qlink_cmd
));
1546 qtnf_bus_lock(mac
->bus
);
1547 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
1548 sizeof(*resp
), &var_data_len
);
1552 resp
= (const struct qlink_resp_get_mac_info
*)resp_skb
->data
;
1553 ret
= qtnf_cmd_resp_proc_mac_info(mac
, resp
);
1557 ret
= qtnf_parse_variable_mac_info(mac
, resp
, var_data_len
);
1560 qtnf_bus_unlock(mac
->bus
);
1561 consume_skb(resp_skb
);
1566 int qtnf_cmd_get_hw_info(struct qtnf_bus
*bus
)
1568 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1569 const struct qlink_resp_get_hw_info
*resp
;
1570 size_t info_len
= 0;
1573 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD
, QLINK_VIFID_RSVD
,
1574 QLINK_CMD_GET_HW_INFO
,
1575 sizeof(struct qlink_cmd
));
1580 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
1581 sizeof(*resp
), &info_len
);
1585 resp
= (const struct qlink_resp_get_hw_info
*)resp_skb
->data
;
1586 ret
= qtnf_cmd_resp_proc_hw_info(bus
, resp
, info_len
);
1589 qtnf_bus_unlock(bus
);
1590 consume_skb(resp_skb
);
1595 int qtnf_cmd_band_info_get(struct qtnf_wmac
*mac
,
1596 struct ieee80211_supported_band
*band
)
1598 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1599 struct qlink_cmd_band_info_get
*cmd
;
1600 struct qlink_resp_band_info_get
*resp
;
1601 size_t info_len
= 0;
1603 u8 qband
= qlink_utils_band_cfg2q(band
->band
);
1605 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, 0,
1606 QLINK_CMD_BAND_INFO_GET
,
1611 cmd
= (struct qlink_cmd_band_info_get
*)cmd_skb
->data
;
1614 qtnf_bus_lock(mac
->bus
);
1615 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
1616 sizeof(*resp
), &info_len
);
1620 resp
= (struct qlink_resp_band_info_get
*)resp_skb
->data
;
1621 if (resp
->band
!= qband
) {
1622 pr_err("MAC%u: reply band %u != cmd band %u\n", mac
->macid
,
1628 ret
= qtnf_cmd_resp_fill_band_info(band
, resp
, info_len
);
1631 qtnf_bus_unlock(mac
->bus
);
1632 consume_skb(resp_skb
);
1637 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac
*mac
, u32 changed
)
1639 struct wiphy
*wiphy
= priv_to_wiphy(mac
);
1640 struct sk_buff
*cmd_skb
;
1643 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, 0,
1644 QLINK_CMD_PHY_PARAMS_SET
,
1645 sizeof(struct qlink_cmd
));
1649 qtnf_bus_lock(mac
->bus
);
1651 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
)
1652 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_FRAG_THRESH
,
1653 wiphy
->frag_threshold
);
1654 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
)
1655 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_RTS_THRESH
,
1656 wiphy
->rts_threshold
);
1657 if (changed
& WIPHY_PARAM_COVERAGE_CLASS
)
1658 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_COVERAGE_CLASS
,
1659 wiphy
->coverage_class
);
1661 if (changed
& WIPHY_PARAM_RETRY_LONG
)
1662 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_LRETRY_LIMIT
,
1665 if (changed
& WIPHY_PARAM_RETRY_SHORT
)
1666 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_SRETRY_LIMIT
,
1667 wiphy
->retry_short
);
1669 ret
= qtnf_cmd_send(mac
->bus
, cmd_skb
);
1671 qtnf_bus_unlock(mac
->bus
);
1676 int qtnf_cmd_send_init_fw(struct qtnf_bus
*bus
)
1678 struct sk_buff
*resp_skb
= NULL
;
1679 struct qlink_resp_init_fw
*resp
;
1680 struct qlink_cmd_init_fw
*cmd
;
1681 struct sk_buff
*cmd_skb
;
1682 size_t info_len
= 0;
1685 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD
, QLINK_VIFID_RSVD
,
1691 cmd
= (struct qlink_cmd_init_fw
*)cmd_skb
->data
;
1692 cmd
->qlink_proto_ver
= cpu_to_le32(QLINK_PROTO_VER
);
1695 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
1696 sizeof(*resp
), &info_len
);
1697 qtnf_bus_unlock(bus
);
1702 resp
= (struct qlink_resp_init_fw
*)resp_skb
->data
;
1703 bus
->hw_info
.ql_proto_ver
= le32_to_cpu(resp
->qlink_proto_ver
);
1706 consume_skb(resp_skb
);
1710 void qtnf_cmd_send_deinit_fw(struct qtnf_bus
*bus
)
1712 struct sk_buff
*cmd_skb
;
1714 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD
, QLINK_VIFID_RSVD
,
1715 QLINK_CMD_FW_DEINIT
,
1716 sizeof(struct qlink_cmd
));
1721 qtnf_cmd_send(bus
, cmd_skb
);
1722 qtnf_bus_unlock(bus
);
1725 int qtnf_cmd_send_add_key(struct qtnf_vif
*vif
, u8 key_index
, bool pairwise
,
1726 const u8
*mac_addr
, struct key_params
*params
)
1728 struct sk_buff
*cmd_skb
;
1729 struct qlink_cmd_add_key
*cmd
;
1732 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1738 qtnf_bus_lock(vif
->mac
->bus
);
1740 cmd
= (struct qlink_cmd_add_key
*)cmd_skb
->data
;
1743 ether_addr_copy(cmd
->addr
, mac_addr
);
1745 eth_broadcast_addr(cmd
->addr
);
1747 cmd
->cipher
= cpu_to_le32(params
->cipher
);
1748 cmd
->key_index
= key_index
;
1749 cmd
->pairwise
= pairwise
;
1751 if (params
->key
&& params
->key_len
> 0)
1752 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, QTN_TLV_ID_KEY
,
1756 if (params
->seq
&& params
->seq_len
> 0)
1757 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, QTN_TLV_ID_SEQ
,
1761 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1763 qtnf_bus_unlock(vif
->mac
->bus
);
1768 int qtnf_cmd_send_del_key(struct qtnf_vif
*vif
, u8 key_index
, bool pairwise
,
1771 struct sk_buff
*cmd_skb
;
1772 struct qlink_cmd_del_key
*cmd
;
1775 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1781 qtnf_bus_lock(vif
->mac
->bus
);
1783 cmd
= (struct qlink_cmd_del_key
*)cmd_skb
->data
;
1786 ether_addr_copy(cmd
->addr
, mac_addr
);
1788 eth_broadcast_addr(cmd
->addr
);
1790 cmd
->key_index
= key_index
;
1791 cmd
->pairwise
= pairwise
;
1793 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1795 qtnf_bus_unlock(vif
->mac
->bus
);
1800 int qtnf_cmd_send_set_default_key(struct qtnf_vif
*vif
, u8 key_index
,
1801 bool unicast
, bool multicast
)
1803 struct sk_buff
*cmd_skb
;
1804 struct qlink_cmd_set_def_key
*cmd
;
1807 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1808 QLINK_CMD_SET_DEFAULT_KEY
,
1813 qtnf_bus_lock(vif
->mac
->bus
);
1815 cmd
= (struct qlink_cmd_set_def_key
*)cmd_skb
->data
;
1816 cmd
->key_index
= key_index
;
1817 cmd
->unicast
= unicast
;
1818 cmd
->multicast
= multicast
;
1820 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1822 qtnf_bus_unlock(vif
->mac
->bus
);
1827 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif
*vif
, u8 key_index
)
1829 struct sk_buff
*cmd_skb
;
1830 struct qlink_cmd_set_def_mgmt_key
*cmd
;
1833 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1834 QLINK_CMD_SET_DEFAULT_MGMT_KEY
,
1839 qtnf_bus_lock(vif
->mac
->bus
);
1841 cmd
= (struct qlink_cmd_set_def_mgmt_key
*)cmd_skb
->data
;
1842 cmd
->key_index
= key_index
;
1844 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1846 qtnf_bus_unlock(vif
->mac
->bus
);
1851 static u32
qtnf_encode_sta_flags(u32 flags
)
1855 if (flags
& BIT(NL80211_STA_FLAG_AUTHORIZED
))
1856 code
|= QLINK_STA_FLAG_AUTHORIZED
;
1857 if (flags
& BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
))
1858 code
|= QLINK_STA_FLAG_SHORT_PREAMBLE
;
1859 if (flags
& BIT(NL80211_STA_FLAG_WME
))
1860 code
|= QLINK_STA_FLAG_WME
;
1861 if (flags
& BIT(NL80211_STA_FLAG_MFP
))
1862 code
|= QLINK_STA_FLAG_MFP
;
1863 if (flags
& BIT(NL80211_STA_FLAG_AUTHENTICATED
))
1864 code
|= QLINK_STA_FLAG_AUTHENTICATED
;
1865 if (flags
& BIT(NL80211_STA_FLAG_TDLS_PEER
))
1866 code
|= QLINK_STA_FLAG_TDLS_PEER
;
1867 if (flags
& BIT(NL80211_STA_FLAG_ASSOCIATED
))
1868 code
|= QLINK_STA_FLAG_ASSOCIATED
;
1872 int qtnf_cmd_send_change_sta(struct qtnf_vif
*vif
, const u8
*mac
,
1873 struct station_parameters
*params
)
1875 struct sk_buff
*cmd_skb
;
1876 struct qlink_cmd_change_sta
*cmd
;
1879 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1880 QLINK_CMD_CHANGE_STA
,
1885 qtnf_bus_lock(vif
->mac
->bus
);
1887 cmd
= (struct qlink_cmd_change_sta
*)cmd_skb
->data
;
1888 ether_addr_copy(cmd
->sta_addr
, mac
);
1889 cmd
->flag_update
.mask
=
1890 cpu_to_le32(qtnf_encode_sta_flags(params
->sta_flags_mask
));
1891 cmd
->flag_update
.value
=
1892 cpu_to_le32(qtnf_encode_sta_flags(params
->sta_flags_set
));
1894 switch (vif
->wdev
.iftype
) {
1895 case NL80211_IFTYPE_AP
:
1896 cmd
->if_type
= cpu_to_le16(QLINK_IFTYPE_AP
);
1898 case NL80211_IFTYPE_STATION
:
1899 cmd
->if_type
= cpu_to_le16(QLINK_IFTYPE_STATION
);
1902 pr_err("unsupported iftype %d\n", vif
->wdev
.iftype
);
1903 dev_kfree_skb(cmd_skb
);
1908 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1911 qtnf_bus_unlock(vif
->mac
->bus
);
1916 int qtnf_cmd_send_del_sta(struct qtnf_vif
*vif
,
1917 struct station_del_parameters
*params
)
1919 struct sk_buff
*cmd_skb
;
1920 struct qlink_cmd_del_sta
*cmd
;
1923 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1929 qtnf_bus_lock(vif
->mac
->bus
);
1931 cmd
= (struct qlink_cmd_del_sta
*)cmd_skb
->data
;
1934 ether_addr_copy(cmd
->sta_addr
, params
->mac
);
1936 eth_broadcast_addr(cmd
->sta_addr
); /* flush all stations */
1938 cmd
->subtype
= params
->subtype
;
1939 cmd
->reason_code
= cpu_to_le16(params
->reason_code
);
1941 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1943 qtnf_bus_unlock(vif
->mac
->bus
);
1948 static void qtnf_cmd_channel_tlv_add(struct sk_buff
*cmd_skb
,
1949 const struct ieee80211_channel
*sc
)
1951 struct qlink_tlv_channel
*tlv
;
1952 struct qlink_channel
*qch
;
1954 tlv
= skb_put_zero(cmd_skb
, sizeof(*tlv
));
1956 tlv
->hdr
.type
= cpu_to_le16(QTN_TLV_ID_CHANNEL
);
1957 tlv
->hdr
.len
= cpu_to_le16(sizeof(*qch
));
1959 qch
->center_freq
= cpu_to_le16(sc
->center_freq
);
1960 qch
->hw_value
= cpu_to_le16(sc
->hw_value
);
1961 qch
->band
= qlink_utils_band_cfg2q(sc
->band
);
1962 qch
->max_power
= sc
->max_power
;
1963 qch
->max_reg_power
= sc
->max_reg_power
;
1964 qch
->max_antenna_gain
= sc
->max_antenna_gain
;
1965 qch
->beacon_found
= sc
->beacon_found
;
1966 qch
->dfs_state
= qlink_utils_dfs_state_cfg2q(sc
->dfs_state
);
1967 qch
->flags
= cpu_to_le32(qlink_utils_chflags_cfg2q(sc
->flags
));
1970 static void qtnf_cmd_randmac_tlv_add(struct sk_buff
*cmd_skb
,
1972 const u8
*mac_addr_mask
)
1974 struct qlink_random_mac_addr
*randmac
;
1975 struct qlink_tlv_hdr
*hdr
=
1976 skb_put(cmd_skb
, sizeof(*hdr
) + sizeof(*randmac
));
1978 hdr
->type
= cpu_to_le16(QTN_TLV_ID_RANDOM_MAC_ADDR
);
1979 hdr
->len
= cpu_to_le16(sizeof(*randmac
));
1980 randmac
= (struct qlink_random_mac_addr
*)hdr
->val
;
1982 memcpy(randmac
->mac_addr
, mac_addr
, ETH_ALEN
);
1983 memcpy(randmac
->mac_addr_mask
, mac_addr_mask
, ETH_ALEN
);
1986 int qtnf_cmd_send_scan(struct qtnf_wmac
*mac
)
1988 struct cfg80211_scan_request
*scan_req
= mac
->scan_req
;
1989 u16 dwell_passive
= QTNF_SCAN_DWELL_PASSIVE_DEFAULT
;
1990 u16 dwell_active
= QTNF_SCAN_DWELL_ACTIVE_DEFAULT
;
1991 struct wireless_dev
*wdev
= scan_req
->wdev
;
1992 struct ieee80211_channel
*sc
;
1993 struct qlink_cmd_scan
*cmd
;
1994 struct sk_buff
*cmd_skb
;
2000 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
2006 cmd
= (struct qlink_cmd_scan
*)cmd_skb
->data
;
2008 if (scan_req
->duration
) {
2009 dwell_active
= scan_req
->duration
;
2010 dwell_passive
= scan_req
->duration
;
2011 } else if (wdev
->iftype
== NL80211_IFTYPE_STATION
&&
2013 /* let device select dwell based on traffic conditions */
2014 dwell_active
= QTNF_SCAN_TIME_AUTO
;
2015 dwell_passive
= QTNF_SCAN_TIME_AUTO
;
2018 cmd
->n_ssids
= cpu_to_le16(scan_req
->n_ssids
);
2019 for (count
= 0; count
< scan_req
->n_ssids
; ++count
) {
2020 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, WLAN_EID_SSID
,
2021 scan_req
->ssids
[count
].ssid
,
2022 scan_req
->ssids
[count
].ssid_len
);
2025 if (scan_req
->ie_len
!= 0)
2026 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_PROBE_REQ
,
2027 scan_req
->ie
, scan_req
->ie_len
);
2029 for (count
= 0; count
< scan_req
->n_channels
; ++count
) {
2030 sc
= scan_req
->channels
[count
];
2031 if (sc
->flags
& IEEE80211_CHAN_DISABLED
)
2034 pr_debug("[MAC%u] scan chan=%d, freq=%d, flags=%#x\n",
2035 mac
->macid
, sc
->hw_value
, sc
->center_freq
,
2038 qtnf_cmd_channel_tlv_add(cmd_skb
, sc
);
2042 if (scan_req
->flags
& NL80211_SCAN_FLAG_FLUSH
)
2043 flags
|= QLINK_SCAN_FLAG_FLUSH
;
2045 if (scan_req
->duration_mandatory
)
2046 flags
|= QLINK_SCAN_FLAG_DURATION_MANDATORY
;
2048 cmd
->n_channels
= cpu_to_le16(n_channels
);
2049 cmd
->active_dwell
= cpu_to_le16(dwell_active
);
2050 cmd
->passive_dwell
= cpu_to_le16(dwell_passive
);
2051 cmd
->sample_duration
= cpu_to_le16(QTNF_SCAN_SAMPLE_DURATION_DEFAULT
);
2052 cmd
->flags
= cpu_to_le64(flags
);
2054 pr_debug("[MAC%u] %s scan dwell active=%u passive=%u duration=%u\n",
2056 scan_req
->duration_mandatory
? "mandatory" : "max",
2057 dwell_active
, dwell_passive
,
2058 QTNF_SCAN_SAMPLE_DURATION_DEFAULT
);
2060 if (scan_req
->flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
) {
2061 pr_debug("[MAC%u] scan with random addr=%pM, mask=%pM\n",
2063 scan_req
->mac_addr
, scan_req
->mac_addr_mask
);
2064 qtnf_cmd_randmac_tlv_add(cmd_skb
, scan_req
->mac_addr
,
2065 scan_req
->mac_addr_mask
);
2068 qtnf_bus_lock(mac
->bus
);
2069 ret
= qtnf_cmd_send(mac
->bus
, cmd_skb
);
2070 qtnf_bus_unlock(mac
->bus
);
2075 int qtnf_cmd_send_connect(struct qtnf_vif
*vif
,
2076 struct cfg80211_connect_params
*sme
)
2078 struct sk_buff
*cmd_skb
;
2079 struct qlink_cmd_connect
*cmd
;
2080 struct qlink_auth_encr
*aen
;
2084 u32 connect_flags
= 0;
2086 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2092 cmd
= (struct qlink_cmd_connect
*)cmd_skb
->data
;
2094 ether_addr_copy(cmd
->bssid
, vif
->bssid
);
2096 if (sme
->bssid_hint
)
2097 ether_addr_copy(cmd
->bssid_hint
, sme
->bssid_hint
);
2099 eth_zero_addr(cmd
->bssid_hint
);
2101 if (sme
->prev_bssid
)
2102 ether_addr_copy(cmd
->prev_bssid
, sme
->prev_bssid
);
2104 eth_zero_addr(cmd
->prev_bssid
);
2106 if ((sme
->bg_scan_period
>= 0) &&
2107 (sme
->bg_scan_period
<= SHRT_MAX
))
2108 cmd
->bg_scan_period
= cpu_to_le16(sme
->bg_scan_period
);
2110 cmd
->bg_scan_period
= cpu_to_le16(-1); /* use default value */
2112 if (sme
->flags
& ASSOC_REQ_DISABLE_HT
)
2113 connect_flags
|= QLINK_STA_CONNECT_DISABLE_HT
;
2114 if (sme
->flags
& ASSOC_REQ_DISABLE_VHT
)
2115 connect_flags
|= QLINK_STA_CONNECT_DISABLE_VHT
;
2116 if (sme
->flags
& ASSOC_REQ_USE_RRM
)
2117 connect_flags
|= QLINK_STA_CONNECT_USE_RRM
;
2119 cmd
->flags
= cpu_to_le32(connect_flags
);
2120 memcpy(&cmd
->ht_capa
, &sme
->ht_capa
, sizeof(cmd
->ht_capa
));
2121 memcpy(&cmd
->ht_capa_mask
, &sme
->ht_capa_mask
,
2122 sizeof(cmd
->ht_capa_mask
));
2123 memcpy(&cmd
->vht_capa
, &sme
->vht_capa
, sizeof(cmd
->vht_capa
));
2124 memcpy(&cmd
->vht_capa_mask
, &sme
->vht_capa_mask
,
2125 sizeof(cmd
->vht_capa_mask
));
2126 cmd
->pbss
= sme
->pbss
;
2129 aen
->auth_type
= sme
->auth_type
;
2130 aen
->privacy
= !!sme
->privacy
;
2131 cmd
->mfp
= sme
->mfp
;
2132 aen
->wpa_versions
= cpu_to_le32(sme
->crypto
.wpa_versions
);
2133 aen
->cipher_group
= cpu_to_le32(sme
->crypto
.cipher_group
);
2134 aen
->n_ciphers_pairwise
= cpu_to_le32(sme
->crypto
.n_ciphers_pairwise
);
2136 for (i
= 0; i
< QLINK_MAX_NR_CIPHER_SUITES
; i
++)
2137 aen
->ciphers_pairwise
[i
] =
2138 cpu_to_le32(sme
->crypto
.ciphers_pairwise
[i
]);
2140 n
= min(QLINK_MAX_NR_AKM_SUITES
, sme
->crypto
.n_akm_suites
);
2141 aen
->n_akm_suites
= cpu_to_le32(n
);
2143 for (i
= 0; i
< n
; i
++)
2144 aen
->akm_suites
[i
] = cpu_to_le32(sme
->crypto
.akm_suites
[i
]);
2146 aen
->control_port
= sme
->crypto
.control_port
;
2147 aen
->control_port_no_encrypt
=
2148 sme
->crypto
.control_port_no_encrypt
;
2149 aen
->control_port_ethertype
=
2150 cpu_to_le16(be16_to_cpu(sme
->crypto
.control_port_ethertype
));
2152 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, WLAN_EID_SSID
, sme
->ssid
,
2155 if (sme
->ie_len
!= 0)
2156 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_ASSOC_REQ
,
2157 sme
->ie
, sme
->ie_len
);
2160 qtnf_cmd_channel_tlv_add(cmd_skb
, sme
->channel
);
2162 qtnf_bus_lock(vif
->mac
->bus
);
2163 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2164 qtnf_bus_unlock(vif
->mac
->bus
);
2169 int qtnf_cmd_send_external_auth(struct qtnf_vif
*vif
,
2170 struct cfg80211_external_auth_params
*auth
)
2172 struct sk_buff
*cmd_skb
;
2173 struct qlink_cmd_external_auth
*cmd
;
2176 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2177 QLINK_CMD_EXTERNAL_AUTH
,
2182 cmd
= (struct qlink_cmd_external_auth
*)cmd_skb
->data
;
2184 ether_addr_copy(cmd
->peer
, auth
->bssid
);
2185 cmd
->status
= cpu_to_le16(auth
->status
);
2187 qtnf_bus_lock(vif
->mac
->bus
);
2188 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2189 qtnf_bus_unlock(vif
->mac
->bus
);
2194 int qtnf_cmd_send_disconnect(struct qtnf_vif
*vif
, u16 reason_code
)
2196 struct sk_buff
*cmd_skb
;
2197 struct qlink_cmd_disconnect
*cmd
;
2200 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2201 QLINK_CMD_DISCONNECT
,
2206 qtnf_bus_lock(vif
->mac
->bus
);
2208 cmd
= (struct qlink_cmd_disconnect
*)cmd_skb
->data
;
2209 cmd
->reason
= cpu_to_le16(reason_code
);
2211 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2213 qtnf_bus_unlock(vif
->mac
->bus
);
2218 int qtnf_cmd_send_updown_intf(struct qtnf_vif
*vif
, bool up
)
2220 struct sk_buff
*cmd_skb
;
2221 struct qlink_cmd_updown
*cmd
;
2224 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2225 QLINK_CMD_UPDOWN_INTF
,
2230 cmd
= (struct qlink_cmd_updown
*)cmd_skb
->data
;
2233 qtnf_bus_lock(vif
->mac
->bus
);
2234 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2235 qtnf_bus_unlock(vif
->mac
->bus
);
2240 int qtnf_cmd_reg_notify(struct qtnf_wmac
*mac
, struct regulatory_request
*req
,
2241 bool slave_radar
, bool dfs_offload
)
2243 struct wiphy
*wiphy
= priv_to_wiphy(mac
);
2244 struct qtnf_bus
*bus
= mac
->bus
;
2245 struct sk_buff
*cmd_skb
;
2247 struct qlink_cmd_reg_notify
*cmd
;
2248 enum nl80211_band band
;
2249 const struct ieee80211_supported_band
*cfg_band
;
2251 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
2252 QLINK_CMD_REG_NOTIFY
,
2257 cmd
= (struct qlink_cmd_reg_notify
*)cmd_skb
->data
;
2258 cmd
->alpha2
[0] = req
->alpha2
[0];
2259 cmd
->alpha2
[1] = req
->alpha2
[1];
2261 switch (req
->initiator
) {
2262 case NL80211_REGDOM_SET_BY_CORE
:
2263 cmd
->initiator
= QLINK_REGDOM_SET_BY_CORE
;
2265 case NL80211_REGDOM_SET_BY_USER
:
2266 cmd
->initiator
= QLINK_REGDOM_SET_BY_USER
;
2268 case NL80211_REGDOM_SET_BY_DRIVER
:
2269 cmd
->initiator
= QLINK_REGDOM_SET_BY_DRIVER
;
2271 case NL80211_REGDOM_SET_BY_COUNTRY_IE
:
2272 cmd
->initiator
= QLINK_REGDOM_SET_BY_COUNTRY_IE
;
2276 switch (req
->user_reg_hint_type
) {
2277 case NL80211_USER_REG_HINT_USER
:
2278 cmd
->user_reg_hint_type
= QLINK_USER_REG_HINT_USER
;
2280 case NL80211_USER_REG_HINT_CELL_BASE
:
2281 cmd
->user_reg_hint_type
= QLINK_USER_REG_HINT_CELL_BASE
;
2283 case NL80211_USER_REG_HINT_INDOOR
:
2284 cmd
->user_reg_hint_type
= QLINK_USER_REG_HINT_INDOOR
;
2288 switch (req
->dfs_region
) {
2289 case NL80211_DFS_FCC
:
2290 cmd
->dfs_region
= QLINK_DFS_FCC
;
2292 case NL80211_DFS_ETSI
:
2293 cmd
->dfs_region
= QLINK_DFS_ETSI
;
2295 case NL80211_DFS_JP
:
2296 cmd
->dfs_region
= QLINK_DFS_JP
;
2299 cmd
->dfs_region
= QLINK_DFS_UNSET
;
2303 cmd
->slave_radar
= slave_radar
;
2304 cmd
->dfs_offload
= dfs_offload
;
2305 cmd
->num_channels
= 0;
2307 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
2310 cfg_band
= wiphy
->bands
[band
];
2314 cmd
->num_channels
+= cfg_band
->n_channels
;
2316 for (i
= 0; i
< cfg_band
->n_channels
; ++i
) {
2317 qtnf_cmd_channel_tlv_add(cmd_skb
,
2318 &cfg_band
->channels
[i
]);
2323 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2324 qtnf_bus_unlock(bus
);
2330 qtnf_cmd_resp_proc_chan_stat_info(struct survey_info
*survey
,
2331 const u8
*payload
, size_t payload_len
)
2333 const struct qlink_chan_stats
*stats
= NULL
;
2334 const struct qlink_tlv_hdr
*tlv
;
2337 const u8
*map
= NULL
;
2338 unsigned int map_len
= 0;
2339 unsigned int stats_len
= 0;
2341 qlink_for_each_tlv(tlv
, payload
, payload_len
) {
2342 tlv_type
= le16_to_cpu(tlv
->type
);
2343 tlv_value_len
= le16_to_cpu(tlv
->len
);
2346 case QTN_TLV_ID_BITMAP
:
2348 map_len
= tlv_value_len
;
2350 case QTN_TLV_ID_CHANNEL_STATS
:
2351 stats
= (struct qlink_chan_stats
*)tlv
->val
;
2352 stats_len
= tlv_value_len
;
2355 pr_info("Unknown TLV type: %#x\n", tlv_type
);
2360 if (!qlink_tlv_parsing_ok(tlv
, payload
, payload_len
)) {
2361 pr_err("Malformed TLV buffer\n");
2368 #define qtnf_chan_stat_avail(stat_name, bitn) \
2369 (qtnf_utils_is_bit_set(map, bitn, map_len) && \
2370 (offsetofend(struct qlink_chan_stats, stat_name) <= stats_len))
2372 if (qtnf_chan_stat_avail(time_on
, QLINK_CHAN_STAT_TIME_ON
)) {
2373 survey
->filled
|= SURVEY_INFO_TIME
;
2374 survey
->time
= le64_to_cpu(stats
->time_on
);
2377 if (qtnf_chan_stat_avail(time_tx
, QLINK_CHAN_STAT_TIME_TX
)) {
2378 survey
->filled
|= SURVEY_INFO_TIME_TX
;
2379 survey
->time_tx
= le64_to_cpu(stats
->time_tx
);
2382 if (qtnf_chan_stat_avail(time_rx
, QLINK_CHAN_STAT_TIME_RX
)) {
2383 survey
->filled
|= SURVEY_INFO_TIME_RX
;
2384 survey
->time_rx
= le64_to_cpu(stats
->time_rx
);
2387 if (qtnf_chan_stat_avail(cca_busy
, QLINK_CHAN_STAT_CCA_BUSY
)) {
2388 survey
->filled
|= SURVEY_INFO_TIME_BUSY
;
2389 survey
->time_busy
= le64_to_cpu(stats
->cca_busy
);
2392 if (qtnf_chan_stat_avail(cca_busy_ext
, QLINK_CHAN_STAT_CCA_BUSY_EXT
)) {
2393 survey
->filled
|= SURVEY_INFO_TIME_EXT_BUSY
;
2394 survey
->time_ext_busy
= le64_to_cpu(stats
->cca_busy_ext
);
2397 if (qtnf_chan_stat_avail(time_scan
, QLINK_CHAN_STAT_TIME_SCAN
)) {
2398 survey
->filled
|= SURVEY_INFO_TIME_SCAN
;
2399 survey
->time_scan
= le64_to_cpu(stats
->time_scan
);
2402 if (qtnf_chan_stat_avail(chan_noise
, QLINK_CHAN_STAT_CHAN_NOISE
)) {
2403 survey
->filled
|= SURVEY_INFO_NOISE_DBM
;
2404 survey
->noise
= stats
->chan_noise
;
2407 #undef qtnf_chan_stat_avail
2412 int qtnf_cmd_get_chan_stats(struct qtnf_wmac
*mac
, u32 chan_freq
,
2413 struct survey_info
*survey
)
2415 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
2416 struct qlink_cmd_get_chan_stats
*cmd
;
2417 struct qlink_resp_get_chan_stats
*resp
;
2418 size_t var_data_len
= 0;
2421 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
2422 QLINK_CMD_CHAN_STATS
,
2427 cmd
= (struct qlink_cmd_get_chan_stats
*)cmd_skb
->data
;
2428 cmd
->channel_freq
= cpu_to_le32(chan_freq
);
2430 qtnf_bus_lock(mac
->bus
);
2431 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
2432 sizeof(*resp
), &var_data_len
);
2433 qtnf_bus_unlock(mac
->bus
);
2438 resp
= (struct qlink_resp_get_chan_stats
*)resp_skb
->data
;
2440 if (le32_to_cpu(resp
->chan_freq
) != chan_freq
) {
2441 pr_err("[MAC%u] channel stats freq %u != requested %u\n",
2442 mac
->macid
, le32_to_cpu(resp
->chan_freq
), chan_freq
);
2447 ret
= qtnf_cmd_resp_proc_chan_stat_info(survey
, resp
->info
,
2451 consume_skb(resp_skb
);
2456 int qtnf_cmd_send_chan_switch(struct qtnf_vif
*vif
,
2457 struct cfg80211_csa_settings
*params
)
2459 struct qtnf_wmac
*mac
= vif
->mac
;
2460 struct qlink_cmd_chan_switch
*cmd
;
2461 struct sk_buff
*cmd_skb
;
2465 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, vif
->vifid
,
2466 QLINK_CMD_CHAN_SWITCH
,
2471 if (params
->radar_required
)
2472 flags
|= QLINK_CHAN_SW_RADAR_REQUIRED
;
2474 if (params
->block_tx
)
2475 flags
|= QLINK_CHAN_SW_BLOCK_TX
;
2477 cmd
= (struct qlink_cmd_chan_switch
*)cmd_skb
->data
;
2478 qlink_chandef_cfg2q(¶ms
->chandef
, &cmd
->channel
);
2479 cmd
->flags
= cpu_to_le64(flags
);
2480 cmd
->beacon_count
= params
->count
;
2482 qtnf_bus_lock(mac
->bus
);
2483 ret
= qtnf_cmd_send(mac
->bus
, cmd_skb
);
2484 qtnf_bus_unlock(mac
->bus
);
2489 int qtnf_cmd_get_channel(struct qtnf_vif
*vif
, struct cfg80211_chan_def
*chdef
)
2491 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2492 const struct qlink_resp_channel_get
*resp
;
2493 struct sk_buff
*cmd_skb
;
2494 struct sk_buff
*resp_skb
= NULL
;
2497 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2499 sizeof(struct qlink_cmd
));
2504 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
2505 sizeof(*resp
), NULL
);
2509 resp
= (const struct qlink_resp_channel_get
*)resp_skb
->data
;
2510 qlink_chandef_q2cfg(priv_to_wiphy(vif
->mac
), &resp
->chan
, chdef
);
2513 qtnf_bus_unlock(bus
);
2514 consume_skb(resp_skb
);
2519 int qtnf_cmd_start_cac(const struct qtnf_vif
*vif
,
2520 const struct cfg80211_chan_def
*chdef
,
2523 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2524 struct sk_buff
*cmd_skb
;
2525 struct qlink_cmd_start_cac
*cmd
;
2528 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2529 QLINK_CMD_START_CAC
,
2534 cmd
= (struct qlink_cmd_start_cac
*)cmd_skb
->data
;
2535 cmd
->cac_time_ms
= cpu_to_le32(cac_time_ms
);
2536 qlink_chandef_cfg2q(chdef
, &cmd
->chan
);
2539 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2540 qtnf_bus_unlock(bus
);
2545 int qtnf_cmd_set_mac_acl(const struct qtnf_vif
*vif
,
2546 const struct cfg80211_acl_data
*params
)
2548 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2549 struct sk_buff
*cmd_skb
;
2550 struct qlink_tlv_hdr
*tlv
;
2551 size_t acl_size
= struct_size(params
, mac_addrs
, params
->n_acl_entries
);
2554 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2555 QLINK_CMD_SET_MAC_ACL
,
2556 sizeof(struct qlink_cmd
));
2560 tlv
= skb_put(cmd_skb
, sizeof(*tlv
) + round_up(acl_size
, QLINK_ALIGN
));
2561 tlv
->type
= cpu_to_le16(QTN_TLV_ID_ACL_DATA
);
2562 tlv
->len
= cpu_to_le16(acl_size
);
2563 qlink_acl_data_cfg2q(params
, (struct qlink_acl_data
*)tlv
->val
);
2566 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2567 qtnf_bus_unlock(bus
);
2572 int qtnf_cmd_send_pm_set(const struct qtnf_vif
*vif
, u8 pm_mode
, int timeout
)
2574 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2575 struct sk_buff
*cmd_skb
;
2576 struct qlink_cmd_pm_set
*cmd
;
2579 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2580 QLINK_CMD_PM_SET
, sizeof(*cmd
));
2584 cmd
= (struct qlink_cmd_pm_set
*)cmd_skb
->data
;
2585 cmd
->pm_mode
= pm_mode
;
2586 cmd
->pm_standby_timer
= cpu_to_le32(timeout
);
2590 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2592 qtnf_bus_unlock(bus
);
2597 int qtnf_cmd_get_tx_power(const struct qtnf_vif
*vif
, int *dbm
)
2599 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2600 const struct qlink_resp_txpwr
*resp
;
2601 struct sk_buff
*resp_skb
= NULL
;
2602 struct qlink_cmd_txpwr
*cmd
;
2603 struct sk_buff
*cmd_skb
;
2606 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2607 QLINK_CMD_TXPWR
, sizeof(*cmd
));
2611 cmd
= (struct qlink_cmd_txpwr
*)cmd_skb
->data
;
2612 cmd
->op_type
= QLINK_TXPWR_GET
;
2616 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
2617 sizeof(*resp
), NULL
);
2621 resp
= (const struct qlink_resp_txpwr
*)resp_skb
->data
;
2622 *dbm
= MBM_TO_DBM(le32_to_cpu(resp
->txpwr
));
2625 qtnf_bus_unlock(bus
);
2626 consume_skb(resp_skb
);
2631 int qtnf_cmd_set_tx_power(const struct qtnf_vif
*vif
,
2632 enum nl80211_tx_power_setting type
, int mbm
)
2634 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2635 const struct qlink_resp_txpwr
*resp
;
2636 struct sk_buff
*resp_skb
= NULL
;
2637 struct qlink_cmd_txpwr
*cmd
;
2638 struct sk_buff
*cmd_skb
;
2641 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2642 QLINK_CMD_TXPWR
, sizeof(*cmd
));
2646 cmd
= (struct qlink_cmd_txpwr
*)cmd_skb
->data
;
2647 cmd
->op_type
= QLINK_TXPWR_SET
;
2648 cmd
->txpwr_setting
= type
;
2649 cmd
->txpwr
= cpu_to_le32(mbm
);
2653 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
2654 sizeof(*resp
), NULL
);
2656 qtnf_bus_unlock(bus
);
2657 consume_skb(resp_skb
);
2662 int qtnf_cmd_send_wowlan_set(const struct qtnf_vif
*vif
,
2663 const struct cfg80211_wowlan
*wowl
)
2665 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2666 struct sk_buff
*cmd_skb
;
2667 struct qlink_cmd_wowlan_set
*cmd
;
2672 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2673 QLINK_CMD_WOWLAN_SET
, sizeof(*cmd
));
2679 cmd
= (struct qlink_cmd_wowlan_set
*)cmd_skb
->data
;
2682 if (wowl
->disconnect
)
2683 triggers
|= QLINK_WOWLAN_TRIG_DISCONNECT
;
2685 if (wowl
->magic_pkt
)
2686 triggers
|= QLINK_WOWLAN_TRIG_MAGIC_PKT
;
2688 if (wowl
->n_patterns
&& wowl
->patterns
) {
2689 triggers
|= QLINK_WOWLAN_TRIG_PATTERN_PKT
;
2690 while (count
< wowl
->n_patterns
) {
2691 qtnf_cmd_skb_put_tlv_arr(cmd_skb
,
2692 QTN_TLV_ID_WOWLAN_PATTERN
,
2693 wowl
->patterns
[count
].pattern
,
2694 wowl
->patterns
[count
].pattern_len
);
2700 cmd
->triggers
= cpu_to_le32(triggers
);
2702 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2704 qtnf_bus_unlock(bus
);
2708 int qtnf_cmd_netdev_changeupper(const struct qtnf_vif
*vif
, int br_domain
)
2710 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2711 struct sk_buff
*cmd_skb
;
2712 struct qlink_cmd_ndev_changeupper
*cmd
;
2715 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2716 QLINK_CMD_NDEV_EVENT
,
2721 pr_debug("[VIF%u.%u] set broadcast domain to %d\n",
2722 vif
->mac
->macid
, vif
->vifid
, br_domain
);
2724 cmd
= (struct qlink_cmd_ndev_changeupper
*)cmd_skb
->data
;
2725 cmd
->nehdr
.event
= cpu_to_le16(QLINK_NDEV_EVENT_CHANGEUPPER
);
2726 cmd
->upper_type
= QLINK_NDEV_UPPER_TYPE_BRIDGE
;
2727 cmd
->br_domain
= cpu_to_le32(br_domain
);
2730 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2731 qtnf_bus_unlock(bus
);
2734 pr_err("[VIF%u.%u] failed to set broadcast domain\n",
2735 vif
->mac
->macid
, vif
->vifid
);
2740 int qtnf_cmd_send_update_owe(struct qtnf_vif
*vif
,
2741 struct cfg80211_update_owe_info
*owe
)
2743 struct qlink_cmd_update_owe
*cmd
;
2744 struct sk_buff
*cmd_skb
;
2747 if (sizeof(*cmd
) + owe
->ie_len
> QTNF_MAX_CMD_BUF_SIZE
) {
2748 pr_warn("VIF%u.%u: OWE update IEs too big: %zu\n",
2749 vif
->mac
->macid
, vif
->vifid
, owe
->ie_len
);
2753 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2754 QLINK_CMD_UPDATE_OWE
,
2759 cmd
= (struct qlink_cmd_update_owe
*)cmd_skb
->data
;
2760 ether_addr_copy(cmd
->peer
, owe
->peer
);
2761 cmd
->status
= cpu_to_le16(owe
->status
);
2762 if (owe
->ie_len
&& owe
->ie
)
2763 qtnf_cmd_skb_put_buffer(cmd_skb
, owe
->ie
, owe
->ie_len
);
2765 qtnf_bus_lock(vif
->mac
->bus
);
2766 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2767 qtnf_bus_unlock(vif
->mac
->bus
);