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 #define QTNF_SCAN_TIME_AUTO 0
16 /* Let device itself to select best values for current conditions */
17 #define QTNF_SCAN_DWELL_ACTIVE_DEFAULT QTNF_SCAN_TIME_AUTO
18 #define QTNF_SCAN_DWELL_PASSIVE_DEFAULT QTNF_SCAN_TIME_AUTO
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
;
91 cmd
= (struct qlink_cmd
*)cmd_skb
->data
;
92 cmd_id
= le16_to_cpu(cmd
->cmd_id
);
95 cmd
->mhdr
.len
= cpu_to_le16(cmd_skb
->len
);
97 pr_debug("VIF%u.%u cmd=0x%.4X\n", mac_id
, vif_id
, cmd_id
);
99 if (!qtnf_fw_is_up(bus
) && cmd_id
!= QLINK_CMD_FW_INIT
) {
100 pr_warn("VIF%u.%u: drop cmd 0x%.4X in fw state %d\n",
101 mac_id
, vif_id
, cmd_id
, bus
->fw_state
);
102 dev_kfree_skb(cmd_skb
);
106 ret
= qtnf_trans_send_cmd_with_resp(bus
, cmd_skb
, &resp_skb
);
110 if (WARN_ON(!resp_skb
|| !resp_skb
->data
)) {
115 resp
= (struct qlink_resp
*)resp_skb
->data
;
116 ret
= qtnf_cmd_check_reply_header(resp
, cmd_id
, mac_id
, vif_id
,
121 /* Return length of variable part of response */
122 if (response_skb
&& var_resp_size
)
123 *var_resp_size
= le16_to_cpu(resp
->mhdr
.len
) - const_resp_size
;
127 *response_skb
= resp_skb
;
129 consume_skb(resp_skb
);
132 return qtnf_cmd_resp_result_decode(le16_to_cpu(resp
->result
));
134 pr_warn("VIF%u.%u: cmd 0x%.4X failed: %d\n",
135 mac_id
, vif_id
, cmd_id
, ret
);
140 static inline int qtnf_cmd_send(struct qtnf_bus
*bus
, struct sk_buff
*cmd_skb
)
142 return qtnf_cmd_send_with_reply(bus
, cmd_skb
, NULL
,
143 sizeof(struct qlink_resp
), NULL
);
146 static struct sk_buff
*qtnf_cmd_alloc_new_cmdskb(u8 macid
, u8 vifid
, u16 cmd_no
,
149 struct qlink_cmd
*cmd
;
150 struct sk_buff
*cmd_skb
;
152 cmd_skb
= __dev_alloc_skb(sizeof(*cmd
) +
153 QTNF_MAX_CMD_BUF_SIZE
, GFP_KERNEL
);
154 if (unlikely(!cmd_skb
)) {
155 pr_err("VIF%u.%u CMD %u: alloc failed\n", macid
, vifid
, cmd_no
);
159 skb_put_zero(cmd_skb
, cmd_size
);
161 cmd
= (struct qlink_cmd
*)cmd_skb
->data
;
162 cmd
->mhdr
.len
= cpu_to_le16(cmd_skb
->len
);
163 cmd
->mhdr
.type
= cpu_to_le16(QLINK_MSG_TYPE_CMD
);
164 cmd
->cmd_id
= cpu_to_le16(cmd_no
);
171 static void qtnf_cmd_tlv_ie_set_add(struct sk_buff
*cmd_skb
, u8 frame_type
,
172 const u8
*buf
, size_t len
)
174 struct qlink_tlv_ie_set
*tlv
;
176 tlv
= (struct qlink_tlv_ie_set
*)skb_put(cmd_skb
, sizeof(*tlv
) + len
);
177 tlv
->hdr
.type
= cpu_to_le16(QTN_TLV_ID_IE_SET
);
178 tlv
->hdr
.len
= cpu_to_le16(len
+ sizeof(*tlv
) - sizeof(tlv
->hdr
));
179 tlv
->type
= frame_type
;
183 memcpy(tlv
->ie_data
, buf
, len
);
186 static bool qtnf_cmd_start_ap_can_fit(const struct qtnf_vif
*vif
,
187 const struct cfg80211_ap_settings
*s
)
189 unsigned int len
= sizeof(struct qlink_cmd_start_ap
);
192 len
+= s
->beacon
.head_len
;
193 len
+= s
->beacon
.tail_len
;
194 len
+= s
->beacon
.beacon_ies_len
;
195 len
+= s
->beacon
.proberesp_ies_len
;
196 len
+= s
->beacon
.assocresp_ies_len
;
197 len
+= s
->beacon
.probe_resp_len
;
199 if (cfg80211_chandef_valid(&s
->chandef
))
200 len
+= sizeof(struct qlink_tlv_chandef
);
203 len
+= sizeof(struct qlink_tlv_hdr
) +
204 struct_size(s
->acl
, mac_addrs
, s
->acl
->n_acl_entries
);
206 if (len
> (sizeof(struct qlink_cmd
) + QTNF_MAX_CMD_BUF_SIZE
)) {
207 pr_err("VIF%u.%u: can not fit AP settings: %u\n",
208 vif
->mac
->macid
, vif
->vifid
, len
);
215 int qtnf_cmd_send_start_ap(struct qtnf_vif
*vif
,
216 const struct cfg80211_ap_settings
*s
)
218 struct sk_buff
*cmd_skb
;
219 struct qlink_cmd_start_ap
*cmd
;
220 struct qlink_auth_encr
*aen
;
224 if (!qtnf_cmd_start_ap_can_fit(vif
, s
))
227 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
233 cmd
= (struct qlink_cmd_start_ap
*)cmd_skb
->data
;
234 cmd
->dtim_period
= s
->dtim_period
;
235 cmd
->beacon_interval
= cpu_to_le16(s
->beacon_interval
);
236 cmd
->hidden_ssid
= qlink_hidden_ssid_nl2q(s
->hidden_ssid
);
237 cmd
->inactivity_timeout
= cpu_to_le16(s
->inactivity_timeout
);
238 cmd
->smps_mode
= s
->smps_mode
;
239 cmd
->p2p_ctwindow
= s
->p2p_ctwindow
;
240 cmd
->p2p_opp_ps
= s
->p2p_opp_ps
;
242 cmd
->ht_required
= s
->ht_required
;
243 cmd
->vht_required
= s
->vht_required
;
246 aen
->auth_type
= s
->auth_type
;
247 aen
->privacy
= !!s
->privacy
;
248 aen
->wpa_versions
= cpu_to_le32(s
->crypto
.wpa_versions
);
249 aen
->cipher_group
= cpu_to_le32(s
->crypto
.cipher_group
);
250 aen
->n_ciphers_pairwise
= cpu_to_le32(s
->crypto
.n_ciphers_pairwise
);
251 for (i
= 0; i
< QLINK_MAX_NR_CIPHER_SUITES
; i
++)
252 aen
->ciphers_pairwise
[i
] =
253 cpu_to_le32(s
->crypto
.ciphers_pairwise
[i
]);
254 aen
->n_akm_suites
= cpu_to_le32(s
->crypto
.n_akm_suites
);
255 for (i
= 0; i
< QLINK_MAX_NR_AKM_SUITES
; i
++)
256 aen
->akm_suites
[i
] = cpu_to_le32(s
->crypto
.akm_suites
[i
]);
257 aen
->control_port
= s
->crypto
.control_port
;
258 aen
->control_port_no_encrypt
= s
->crypto
.control_port_no_encrypt
;
259 aen
->control_port_ethertype
=
260 cpu_to_le16(be16_to_cpu(s
->crypto
.control_port_ethertype
));
262 if (s
->ssid
&& s
->ssid_len
> 0 && s
->ssid_len
<= IEEE80211_MAX_SSID_LEN
)
263 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, WLAN_EID_SSID
, s
->ssid
,
266 if (cfg80211_chandef_valid(&s
->chandef
)) {
267 struct qlink_tlv_chandef
*chtlv
=
268 (struct qlink_tlv_chandef
*)skb_put(cmd_skb
,
271 chtlv
->hdr
.type
= cpu_to_le16(QTN_TLV_ID_CHANDEF
);
272 chtlv
->hdr
.len
= cpu_to_le16(sizeof(*chtlv
) -
274 qlink_chandef_cfg2q(&s
->chandef
, &chtlv
->chdef
);
277 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_BEACON_HEAD
,
278 s
->beacon
.head
, s
->beacon
.head_len
);
279 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_BEACON_TAIL
,
280 s
->beacon
.tail
, s
->beacon
.tail_len
);
281 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_BEACON_IES
,
282 s
->beacon
.beacon_ies
, s
->beacon
.beacon_ies_len
);
283 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_PROBE_RESP
,
284 s
->beacon
.probe_resp
, s
->beacon
.probe_resp_len
);
285 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_PROBE_RESP_IES
,
286 s
->beacon
.proberesp_ies
,
287 s
->beacon
.proberesp_ies_len
);
288 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_ASSOC_RESP
,
289 s
->beacon
.assocresp_ies
,
290 s
->beacon
.assocresp_ies_len
);
293 struct qlink_tlv_hdr
*tlv
= (struct qlink_tlv_hdr
*)
294 skb_put(cmd_skb
, sizeof(*tlv
) + sizeof(*s
->ht_cap
));
296 tlv
->type
= cpu_to_le16(WLAN_EID_HT_CAPABILITY
);
297 tlv
->len
= cpu_to_le16(sizeof(*s
->ht_cap
));
298 memcpy(tlv
->val
, s
->ht_cap
, sizeof(*s
->ht_cap
));
302 struct qlink_tlv_hdr
*tlv
= (struct qlink_tlv_hdr
*)
303 skb_put(cmd_skb
, sizeof(*tlv
) + sizeof(*s
->vht_cap
));
305 tlv
->type
= cpu_to_le16(WLAN_EID_VHT_CAPABILITY
);
306 tlv
->len
= cpu_to_le16(sizeof(*s
->vht_cap
));
307 memcpy(tlv
->val
, s
->vht_cap
, sizeof(*s
->vht_cap
));
311 size_t acl_size
= struct_size(s
->acl
, mac_addrs
,
312 s
->acl
->n_acl_entries
);
313 struct qlink_tlv_hdr
*tlv
=
314 skb_put(cmd_skb
, sizeof(*tlv
) + acl_size
);
316 tlv
->type
= cpu_to_le16(QTN_TLV_ID_ACL_DATA
);
317 tlv
->len
= cpu_to_le16(acl_size
);
318 qlink_acl_data_cfg2q(s
->acl
, (struct qlink_acl_data
*)tlv
->val
);
321 qtnf_bus_lock(vif
->mac
->bus
);
322 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
326 netif_carrier_on(vif
->netdev
);
329 qtnf_bus_unlock(vif
->mac
->bus
);
334 int qtnf_cmd_send_stop_ap(struct qtnf_vif
*vif
)
336 struct sk_buff
*cmd_skb
;
339 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
341 sizeof(struct qlink_cmd
));
345 qtnf_bus_lock(vif
->mac
->bus
);
346 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
351 qtnf_bus_unlock(vif
->mac
->bus
);
356 int qtnf_cmd_send_register_mgmt(struct qtnf_vif
*vif
, u16 frame_type
, bool reg
)
358 struct sk_buff
*cmd_skb
;
359 struct qlink_cmd_mgmt_frame_register
*cmd
;
362 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
363 QLINK_CMD_REGISTER_MGMT
,
368 qtnf_bus_lock(vif
->mac
->bus
);
370 cmd
= (struct qlink_cmd_mgmt_frame_register
*)cmd_skb
->data
;
371 cmd
->frame_type
= cpu_to_le16(frame_type
);
372 cmd
->do_register
= reg
;
374 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
379 qtnf_bus_unlock(vif
->mac
->bus
);
384 int qtnf_cmd_send_frame(struct qtnf_vif
*vif
, u32 cookie
, u16 flags
,
385 u16 freq
, const u8
*buf
, size_t len
)
387 struct sk_buff
*cmd_skb
;
388 struct qlink_cmd_frame_tx
*cmd
;
391 if (sizeof(*cmd
) + len
> QTNF_MAX_CMD_BUF_SIZE
) {
392 pr_warn("VIF%u.%u: frame is too big: %zu\n", vif
->mac
->macid
,
397 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
398 QLINK_CMD_SEND_FRAME
,
403 qtnf_bus_lock(vif
->mac
->bus
);
405 cmd
= (struct qlink_cmd_frame_tx
*)cmd_skb
->data
;
406 cmd
->cookie
= cpu_to_le32(cookie
);
407 cmd
->freq
= cpu_to_le16(freq
);
408 cmd
->flags
= cpu_to_le16(flags
);
411 qtnf_cmd_skb_put_buffer(cmd_skb
, buf
, len
);
413 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
418 qtnf_bus_unlock(vif
->mac
->bus
);
423 int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif
*vif
, u8 frame_type
,
424 const u8
*buf
, size_t len
)
426 struct sk_buff
*cmd_skb
;
429 if (len
> QTNF_MAX_CMD_BUF_SIZE
) {
430 pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif
->mac
->macid
,
431 vif
->vifid
, frame_type
, len
);
435 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
436 QLINK_CMD_MGMT_SET_APPIE
,
437 sizeof(struct qlink_cmd
));
441 qtnf_cmd_tlv_ie_set_add(cmd_skb
, frame_type
, buf
, len
);
443 qtnf_bus_lock(vif
->mac
->bus
);
444 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
449 qtnf_bus_unlock(vif
->mac
->bus
);
455 qtnf_sta_info_parse_rate(struct rate_info
*rate_dst
,
456 const struct qlink_sta_info_rate
*rate_src
)
458 rate_dst
->legacy
= get_unaligned_le16(&rate_src
->rate
) * 10;
460 rate_dst
->mcs
= rate_src
->mcs
;
461 rate_dst
->nss
= rate_src
->nss
;
464 switch (rate_src
->bw
) {
465 case QLINK_CHAN_WIDTH_5
:
466 rate_dst
->bw
= RATE_INFO_BW_5
;
468 case QLINK_CHAN_WIDTH_10
:
469 rate_dst
->bw
= RATE_INFO_BW_10
;
471 case QLINK_CHAN_WIDTH_20
:
472 case QLINK_CHAN_WIDTH_20_NOHT
:
473 rate_dst
->bw
= RATE_INFO_BW_20
;
475 case QLINK_CHAN_WIDTH_40
:
476 rate_dst
->bw
= RATE_INFO_BW_40
;
478 case QLINK_CHAN_WIDTH_80
:
479 rate_dst
->bw
= RATE_INFO_BW_80
;
481 case QLINK_CHAN_WIDTH_160
:
482 rate_dst
->bw
= RATE_INFO_BW_160
;
489 if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_HT_MCS
)
490 rate_dst
->flags
|= RATE_INFO_FLAGS_MCS
;
491 else if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_VHT_MCS
)
492 rate_dst
->flags
|= RATE_INFO_FLAGS_VHT_MCS
;
494 if (rate_src
->flags
& QLINK_STA_INFO_RATE_FLAG_SHORT_GI
)
495 rate_dst
->flags
|= RATE_INFO_FLAGS_SHORT_GI
;
499 qtnf_sta_info_parse_flags(struct nl80211_sta_flag_update
*dst
,
500 const struct qlink_sta_info_state
*src
)
507 mask
= le32_to_cpu(src
->mask
);
508 value
= le32_to_cpu(src
->value
);
510 if (mask
& QLINK_STA_FLAG_AUTHORIZED
) {
511 dst
->mask
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
512 if (value
& QLINK_STA_FLAG_AUTHORIZED
)
513 dst
->set
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
516 if (mask
& QLINK_STA_FLAG_SHORT_PREAMBLE
) {
517 dst
->mask
|= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
);
518 if (value
& QLINK_STA_FLAG_SHORT_PREAMBLE
)
519 dst
->set
|= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
);
522 if (mask
& QLINK_STA_FLAG_WME
) {
523 dst
->mask
|= BIT(NL80211_STA_FLAG_WME
);
524 if (value
& QLINK_STA_FLAG_WME
)
525 dst
->set
|= BIT(NL80211_STA_FLAG_WME
);
528 if (mask
& QLINK_STA_FLAG_MFP
) {
529 dst
->mask
|= BIT(NL80211_STA_FLAG_MFP
);
530 if (value
& QLINK_STA_FLAG_MFP
)
531 dst
->set
|= BIT(NL80211_STA_FLAG_MFP
);
534 if (mask
& QLINK_STA_FLAG_AUTHENTICATED
) {
535 dst
->mask
|= BIT(NL80211_STA_FLAG_AUTHENTICATED
);
536 if (value
& QLINK_STA_FLAG_AUTHENTICATED
)
537 dst
->set
|= BIT(NL80211_STA_FLAG_AUTHENTICATED
);
540 if (mask
& QLINK_STA_FLAG_TDLS_PEER
) {
541 dst
->mask
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
542 if (value
& QLINK_STA_FLAG_TDLS_PEER
)
543 dst
->set
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
546 if (mask
& QLINK_STA_FLAG_ASSOCIATED
) {
547 dst
->mask
|= BIT(NL80211_STA_FLAG_ASSOCIATED
);
548 if (value
& QLINK_STA_FLAG_ASSOCIATED
)
549 dst
->set
|= BIT(NL80211_STA_FLAG_ASSOCIATED
);
554 qtnf_cmd_sta_info_parse(struct station_info
*sinfo
,
555 const struct qlink_tlv_hdr
*tlv
,
558 const struct qlink_sta_stats
*stats
= NULL
;
559 const u8
*map
= NULL
;
560 unsigned int map_len
= 0;
561 unsigned int stats_len
= 0;
564 #define qtnf_sta_stat_avail(stat_name, bitn) \
565 (qtnf_utils_is_bit_set(map, bitn, map_len) && \
566 (offsetofend(struct qlink_sta_stats, stat_name) <= stats_len))
568 while (resp_size
>= sizeof(*tlv
)) {
569 tlv_len
= le16_to_cpu(tlv
->len
);
571 switch (le16_to_cpu(tlv
->type
)) {
572 case QTN_TLV_ID_STA_STATS_MAP
:
576 case QTN_TLV_ID_STA_STATS
:
578 stats
= (const struct qlink_sta_stats
*)tlv
->val
;
584 resp_size
-= tlv_len
+ sizeof(*tlv
);
585 tlv
= (const struct qlink_tlv_hdr
*)(tlv
->val
+ tlv_len
);
591 if (qtnf_sta_stat_avail(inactive_time
, QLINK_STA_INFO_INACTIVE_TIME
)) {
592 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME
);
593 sinfo
->inactive_time
= le32_to_cpu(stats
->inactive_time
);
596 if (qtnf_sta_stat_avail(connected_time
,
597 QLINK_STA_INFO_CONNECTED_TIME
)) {
598 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME
);
599 sinfo
->connected_time
= le32_to_cpu(stats
->connected_time
);
602 if (qtnf_sta_stat_avail(signal
, QLINK_STA_INFO_SIGNAL
)) {
603 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_SIGNAL
);
604 sinfo
->signal
= stats
->signal
- QLINK_RSSI_OFFSET
;
607 if (qtnf_sta_stat_avail(signal_avg
, QLINK_STA_INFO_SIGNAL_AVG
)) {
608 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG
);
609 sinfo
->signal_avg
= stats
->signal_avg
- QLINK_RSSI_OFFSET
;
612 if (qtnf_sta_stat_avail(rxrate
, QLINK_STA_INFO_RX_BITRATE
)) {
613 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_BITRATE
);
614 qtnf_sta_info_parse_rate(&sinfo
->rxrate
, &stats
->rxrate
);
617 if (qtnf_sta_stat_avail(txrate
, QLINK_STA_INFO_TX_BITRATE
)) {
618 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BITRATE
);
619 qtnf_sta_info_parse_rate(&sinfo
->txrate
, &stats
->txrate
);
622 if (qtnf_sta_stat_avail(sta_flags
, QLINK_STA_INFO_STA_FLAGS
)) {
623 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_STA_FLAGS
);
624 qtnf_sta_info_parse_flags(&sinfo
->sta_flags
, &stats
->sta_flags
);
627 if (qtnf_sta_stat_avail(rx_bytes
, QLINK_STA_INFO_RX_BYTES
)) {
628 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_BYTES
);
629 sinfo
->rx_bytes
= le64_to_cpu(stats
->rx_bytes
);
632 if (qtnf_sta_stat_avail(tx_bytes
, QLINK_STA_INFO_TX_BYTES
)) {
633 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BYTES
);
634 sinfo
->tx_bytes
= le64_to_cpu(stats
->tx_bytes
);
637 if (qtnf_sta_stat_avail(rx_bytes
, QLINK_STA_INFO_RX_BYTES64
)) {
638 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_BYTES64
);
639 sinfo
->rx_bytes
= le64_to_cpu(stats
->rx_bytes
);
642 if (qtnf_sta_stat_avail(tx_bytes
, QLINK_STA_INFO_TX_BYTES64
)) {
643 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_BYTES64
);
644 sinfo
->tx_bytes
= le64_to_cpu(stats
->tx_bytes
);
647 if (qtnf_sta_stat_avail(rx_packets
, QLINK_STA_INFO_RX_PACKETS
)) {
648 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_PACKETS
);
649 sinfo
->rx_packets
= le32_to_cpu(stats
->rx_packets
);
652 if (qtnf_sta_stat_avail(tx_packets
, QLINK_STA_INFO_TX_PACKETS
)) {
653 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_PACKETS
);
654 sinfo
->tx_packets
= le32_to_cpu(stats
->tx_packets
);
657 if (qtnf_sta_stat_avail(rx_beacon
, QLINK_STA_INFO_BEACON_RX
)) {
658 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_BEACON_RX
);
659 sinfo
->rx_beacon
= le64_to_cpu(stats
->rx_beacon
);
662 if (qtnf_sta_stat_avail(rx_dropped_misc
, QLINK_STA_INFO_RX_DROP_MISC
)) {
663 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC
);
664 sinfo
->rx_dropped_misc
= le32_to_cpu(stats
->rx_dropped_misc
);
667 if (qtnf_sta_stat_avail(tx_failed
, QLINK_STA_INFO_TX_FAILED
)) {
668 sinfo
->filled
|= BIT_ULL(NL80211_STA_INFO_TX_FAILED
);
669 sinfo
->tx_failed
= le32_to_cpu(stats
->tx_failed
);
672 #undef qtnf_sta_stat_avail
675 int qtnf_cmd_get_sta_info(struct qtnf_vif
*vif
, const u8
*sta_mac
,
676 struct station_info
*sinfo
)
678 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
679 struct qlink_cmd_get_sta_info
*cmd
;
680 const struct qlink_resp_get_sta_info
*resp
;
681 size_t var_resp_len
= 0;
684 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
685 QLINK_CMD_GET_STA_INFO
,
690 qtnf_bus_lock(vif
->mac
->bus
);
692 cmd
= (struct qlink_cmd_get_sta_info
*)cmd_skb
->data
;
693 ether_addr_copy(cmd
->sta_addr
, sta_mac
);
695 ret
= qtnf_cmd_send_with_reply(vif
->mac
->bus
, cmd_skb
, &resp_skb
,
696 sizeof(*resp
), &var_resp_len
);
700 resp
= (const struct qlink_resp_get_sta_info
*)resp_skb
->data
;
702 if (!ether_addr_equal(sta_mac
, resp
->sta_addr
)) {
703 pr_err("VIF%u.%u: wrong mac in reply: %pM != %pM\n",
704 vif
->mac
->macid
, vif
->vifid
, resp
->sta_addr
, sta_mac
);
709 qtnf_cmd_sta_info_parse(sinfo
,
710 (const struct qlink_tlv_hdr
*)resp
->info
,
714 qtnf_bus_unlock(vif
->mac
->bus
);
715 consume_skb(resp_skb
);
720 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif
*vif
,
721 enum nl80211_iftype iftype
,
724 enum qlink_cmd_type cmd_type
)
726 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
727 struct qlink_cmd_manage_intf
*cmd
;
728 const struct qlink_resp_manage_intf
*resp
;
731 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
737 qtnf_bus_lock(vif
->mac
->bus
);
739 cmd
= (struct qlink_cmd_manage_intf
*)cmd_skb
->data
;
740 cmd
->intf_info
.use4addr
= use4addr
;
743 case NL80211_IFTYPE_AP
:
744 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_AP
);
746 case NL80211_IFTYPE_STATION
:
747 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_STATION
);
750 pr_err("VIF%u.%u: unsupported type %d\n", vif
->mac
->macid
,
757 ether_addr_copy(cmd
->intf_info
.mac_addr
, mac_addr
);
759 eth_zero_addr(cmd
->intf_info
.mac_addr
);
761 ret
= qtnf_cmd_send_with_reply(vif
->mac
->bus
, cmd_skb
, &resp_skb
,
762 sizeof(*resp
), NULL
);
766 resp
= (const struct qlink_resp_manage_intf
*)resp_skb
->data
;
767 ether_addr_copy(vif
->mac_addr
, resp
->intf_info
.mac_addr
);
770 qtnf_bus_unlock(vif
->mac
->bus
);
771 consume_skb(resp_skb
);
776 int qtnf_cmd_send_add_intf(struct qtnf_vif
*vif
, enum nl80211_iftype iftype
,
777 int use4addr
, u8
*mac_addr
)
779 return qtnf_cmd_send_add_change_intf(vif
, iftype
, use4addr
, mac_addr
,
783 int qtnf_cmd_send_change_intf_type(struct qtnf_vif
*vif
,
784 enum nl80211_iftype iftype
,
790 ret
= qtnf_cmd_send_add_change_intf(vif
, iftype
, use4addr
, mac_addr
,
791 QLINK_CMD_CHANGE_INTF
);
793 /* Regulatory settings may be different for different interface types */
794 if (ret
== 0 && vif
->wdev
.iftype
!= iftype
) {
795 enum nl80211_band band
;
796 struct wiphy
*wiphy
= priv_to_wiphy(vif
->mac
);
798 for (band
= 0; band
< NUM_NL80211_BANDS
; ++band
) {
799 if (!wiphy
->bands
[band
])
802 qtnf_cmd_band_info_get(vif
->mac
, wiphy
->bands
[band
]);
809 int qtnf_cmd_send_del_intf(struct qtnf_vif
*vif
)
811 struct sk_buff
*cmd_skb
;
812 struct qlink_cmd_manage_intf
*cmd
;
815 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
821 qtnf_bus_lock(vif
->mac
->bus
);
823 cmd
= (struct qlink_cmd_manage_intf
*)cmd_skb
->data
;
825 switch (vif
->wdev
.iftype
) {
826 case NL80211_IFTYPE_AP
:
827 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_AP
);
829 case NL80211_IFTYPE_STATION
:
830 cmd
->intf_info
.if_type
= cpu_to_le16(QLINK_IFTYPE_STATION
);
833 pr_warn("VIF%u.%u: unsupported iftype %d\n", vif
->mac
->macid
,
834 vif
->vifid
, vif
->wdev
.iftype
);
839 eth_zero_addr(cmd
->intf_info
.mac_addr
);
841 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
846 qtnf_bus_unlock(vif
->mac
->bus
);
851 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus
*bus
,
852 const struct qlink_resp_get_hw_info
*resp
,
855 struct qtnf_hw_info
*hwinfo
= &bus
->hw_info
;
856 const struct qlink_tlv_hdr
*tlv
;
857 const char *bld_name
= NULL
;
858 const char *bld_rev
= NULL
;
859 const char *bld_type
= NULL
;
860 const char *bld_label
= NULL
;
863 const char *hw_id
= NULL
;
864 const char *calibration_ver
= NULL
;
865 const char *uboot_ver
= NULL
;
870 hwinfo
->num_mac
= resp
->num_mac
;
871 hwinfo
->mac_bitmap
= resp
->mac_bitmap
;
872 hwinfo
->fw_ver
= le32_to_cpu(resp
->fw_ver
);
873 hwinfo
->ql_proto_ver
= le16_to_cpu(resp
->ql_proto_ver
);
874 hwinfo
->total_tx_chain
= resp
->total_tx_chain
;
875 hwinfo
->total_rx_chain
= resp
->total_rx_chain
;
876 hwinfo
->hw_capab
= le32_to_cpu(resp
->hw_capab
);
878 bld_tmstamp
= le32_to_cpu(resp
->bld_tmstamp
);
879 plat_id
= le32_to_cpu(resp
->plat_id
);
880 hw_ver
= le32_to_cpu(resp
->hw_ver
);
882 tlv
= (const struct qlink_tlv_hdr
*)resp
->info
;
884 while (info_len
>= sizeof(*tlv
)) {
885 tlv_type
= le16_to_cpu(tlv
->type
);
886 tlv_value_len
= le16_to_cpu(tlv
->len
);
888 if (tlv_value_len
+ sizeof(*tlv
) > info_len
) {
889 pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
890 tlv_type
, tlv_value_len
);
895 case QTN_TLV_ID_BUILD_NAME
:
896 bld_name
= (const void *)tlv
->val
;
898 case QTN_TLV_ID_BUILD_REV
:
899 bld_rev
= (const void *)tlv
->val
;
901 case QTN_TLV_ID_BUILD_TYPE
:
902 bld_type
= (const void *)tlv
->val
;
904 case QTN_TLV_ID_BUILD_LABEL
:
905 bld_label
= (const void *)tlv
->val
;
907 case QTN_TLV_ID_HW_ID
:
908 hw_id
= (const void *)tlv
->val
;
910 case QTN_TLV_ID_CALIBRATION_VER
:
911 calibration_ver
= (const void *)tlv
->val
;
913 case QTN_TLV_ID_UBOOT_VER
:
914 uboot_ver
= (const void *)tlv
->val
;
916 case QTN_TLV_ID_MAX_SCAN_SSIDS
:
917 hwinfo
->max_scan_ssids
= *tlv
->val
;
923 info_len
-= tlv_value_len
+ sizeof(*tlv
);
924 tlv
= (struct qlink_tlv_hdr
*)(tlv
->val
+ tlv_value_len
);
927 pr_info("fw_version=%d, MACs map %#x, chains Tx=%u Rx=%u, capab=0x%x\n",
928 hwinfo
->fw_ver
, hwinfo
->mac_bitmap
,
929 hwinfo
->total_tx_chain
, hwinfo
->total_rx_chain
,
932 pr_info("\nBuild name: %s" \
933 "\nBuild revision: %s" \
935 "\nBuild label: %s" \
936 "\nBuild timestamp: %lu" \
937 "\nPlatform ID: %lu" \
938 "\nHardware ID: %s" \
939 "\nCalibration version: %s" \
940 "\nU-Boot version: %s" \
941 "\nHardware version: 0x%08x\n",
942 bld_name
, bld_rev
, bld_type
, bld_label
,
943 (unsigned long)bld_tmstamp
,
944 (unsigned long)plat_id
,
945 hw_id
, calibration_ver
, uboot_ver
, hw_ver
);
947 strlcpy(hwinfo
->fw_version
, bld_label
, sizeof(hwinfo
->fw_version
));
948 hwinfo
->hw_version
= hw_ver
;
954 qtnf_parse_wowlan_info(struct qtnf_wmac
*mac
,
955 const struct qlink_wowlan_capab_data
*wowlan
)
957 struct qtnf_mac_info
*mac_info
= &mac
->macinfo
;
958 const struct qlink_wowlan_support
*data1
;
959 struct wiphy_wowlan_support
*supp
;
961 supp
= kzalloc(sizeof(*supp
), GFP_KERNEL
);
965 switch (le16_to_cpu(wowlan
->version
)) {
967 data1
= (struct qlink_wowlan_support
*)wowlan
->data
;
969 supp
->flags
= WIPHY_WOWLAN_MAGIC_PKT
| WIPHY_WOWLAN_DISCONNECT
;
970 supp
->n_patterns
= le32_to_cpu(data1
->n_patterns
);
971 supp
->pattern_max_len
= le32_to_cpu(data1
->pattern_max_len
);
972 supp
->pattern_min_len
= le32_to_cpu(data1
->pattern_min_len
);
974 mac_info
->wowlan
= supp
;
977 pr_warn("MAC%u: unsupported WoWLAN version 0x%x\n",
978 mac
->macid
, le16_to_cpu(wowlan
->version
));
985 qtnf_parse_variable_mac_info(struct qtnf_wmac
*mac
,
986 const struct qlink_resp_get_mac_info
*resp
,
989 const u8
*tlv_buf
= resp
->var_info
;
990 struct ieee80211_iface_combination
*comb
= NULL
;
992 struct ieee80211_iface_limit
*limits
;
993 const struct qlink_iface_comb_num
*comb_num
;
994 const struct qlink_iface_limit_record
*rec
;
995 const struct qlink_iface_limit
*lim
;
996 const struct qlink_wowlan_capab_data
*wowlan
;
1000 size_t tlv_full_len
;
1001 const struct qlink_tlv_hdr
*tlv
;
1002 u8
*ext_capa
= NULL
;
1003 u8
*ext_capa_mask
= NULL
;
1004 u8 ext_capa_len
= 0;
1005 u8 ext_capa_mask_len
= 0;
1007 struct ieee80211_reg_rule
*rule
;
1008 unsigned int rule_idx
= 0;
1009 const struct qlink_tlv_reg_rule
*tlv_rule
;
1011 if (WARN_ON(resp
->n_reg_rules
> NL80211_MAX_SUPP_REG_RULES
))
1014 mac
->rd
= kzalloc(sizeof(*mac
->rd
) +
1015 sizeof(struct ieee80211_reg_rule
) *
1016 resp
->n_reg_rules
, GFP_KERNEL
);
1020 mac
->rd
->n_reg_rules
= resp
->n_reg_rules
;
1021 mac
->rd
->alpha2
[0] = resp
->alpha2
[0];
1022 mac
->rd
->alpha2
[1] = resp
->alpha2
[1];
1024 switch (resp
->dfs_region
) {
1026 mac
->rd
->dfs_region
= NL80211_DFS_FCC
;
1028 case QLINK_DFS_ETSI
:
1029 mac
->rd
->dfs_region
= NL80211_DFS_ETSI
;
1032 mac
->rd
->dfs_region
= NL80211_DFS_JP
;
1034 case QLINK_DFS_UNSET
:
1036 mac
->rd
->dfs_region
= NL80211_DFS_UNSET
;
1040 tlv
= (const struct qlink_tlv_hdr
*)tlv_buf
;
1041 while (tlv_buf_size
>= sizeof(struct qlink_tlv_hdr
)) {
1042 tlv_type
= le16_to_cpu(tlv
->type
);
1043 tlv_value_len
= le16_to_cpu(tlv
->len
);
1044 tlv_full_len
= tlv_value_len
+ sizeof(struct qlink_tlv_hdr
);
1045 if (tlv_full_len
> tlv_buf_size
) {
1046 pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n",
1047 mac
->macid
, tlv_type
, tlv_value_len
);
1052 case QTN_TLV_ID_NUM_IFACE_COMB
:
1053 if (tlv_value_len
!= sizeof(*comb_num
))
1056 comb_num
= (void *)tlv
->val
;
1058 /* free earlier iface comb memory */
1059 qtnf_mac_iface_comb_free(mac
);
1061 mac
->macinfo
.n_if_comb
=
1062 le32_to_cpu(comb_num
->iface_comb_num
);
1064 mac
->macinfo
.if_comb
=
1065 kcalloc(mac
->macinfo
.n_if_comb
,
1066 sizeof(*mac
->macinfo
.if_comb
),
1069 if (!mac
->macinfo
.if_comb
)
1072 comb
= mac
->macinfo
.if_comb
;
1074 pr_debug("MAC%u: %zu iface combinations\n",
1075 mac
->macid
, mac
->macinfo
.n_if_comb
);
1078 case QTN_TLV_ID_IFACE_LIMIT
:
1079 if (unlikely(!comb
)) {
1080 pr_warn("MAC%u: no combinations advertised\n",
1085 if (n_comb
>= mac
->macinfo
.n_if_comb
) {
1086 pr_warn("MAC%u: combinations count exceeded\n",
1092 rec
= (void *)tlv
->val
;
1093 rec_len
= sizeof(*rec
) + rec
->n_limits
* sizeof(*lim
);
1095 if (unlikely(tlv_value_len
!= rec_len
)) {
1096 pr_warn("MAC%u: record %zu size mismatch\n",
1097 mac
->macid
, n_comb
);
1101 limits
= kcalloc(rec
->n_limits
, sizeof(*limits
),
1106 comb
[n_comb
].num_different_channels
=
1107 rec
->num_different_channels
;
1108 comb
[n_comb
].max_interfaces
=
1109 le16_to_cpu(rec
->max_interfaces
);
1110 comb
[n_comb
].n_limits
= rec
->n_limits
;
1111 comb
[n_comb
].limits
= limits
;
1113 for (i
= 0; i
< rec
->n_limits
; i
++) {
1114 lim
= &rec
->limits
[i
];
1115 limits
[i
].max
= le16_to_cpu(lim
->max_num
);
1117 qlink_iface_type_to_nl_mask(le16_to_cpu(lim
->type
));
1118 pr_debug("MAC%u: comb[%zu]: MAX:%u TYPES:%.4X\n",
1120 limits
[i
].max
, limits
[i
].types
);
1125 case WLAN_EID_EXT_CAPABILITY
:
1126 if (unlikely(tlv_value_len
> U8_MAX
))
1128 ext_capa
= (u8
*)tlv
->val
;
1129 ext_capa_len
= tlv_value_len
;
1131 case QTN_TLV_ID_EXT_CAPABILITY_MASK
:
1132 if (unlikely(tlv_value_len
> U8_MAX
))
1134 ext_capa_mask
= (u8
*)tlv
->val
;
1135 ext_capa_mask_len
= tlv_value_len
;
1137 case QTN_TLV_ID_WOWLAN_CAPAB
:
1138 if (tlv_value_len
< sizeof(*wowlan
))
1141 wowlan
= (void *)tlv
->val
;
1142 if (!le16_to_cpu(wowlan
->len
)) {
1143 pr_warn("MAC%u: skip empty WoWLAN data\n",
1148 rec_len
= sizeof(*wowlan
) + le16_to_cpu(wowlan
->len
);
1149 if (unlikely(tlv_value_len
!= rec_len
)) {
1150 pr_warn("MAC%u: WoWLAN data size mismatch\n",
1155 kfree(mac
->macinfo
.wowlan
);
1156 mac
->macinfo
.wowlan
= NULL
;
1157 qtnf_parse_wowlan_info(mac
, wowlan
);
1159 case QTN_TLV_ID_REG_RULE
:
1160 if (rule_idx
>= resp
->n_reg_rules
) {
1161 pr_warn("unexpected number of rules: %u\n",
1166 if (tlv_value_len
!= sizeof(*tlv_rule
) - sizeof(*tlv
)) {
1167 pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
1168 tlv_type
, tlv_value_len
);
1172 tlv_rule
= (const struct qlink_tlv_reg_rule
*)tlv
;
1173 rule
= &mac
->rd
->reg_rules
[rule_idx
++];
1174 qlink_utils_regrule_q2nl(rule
, tlv_rule
);
1177 pr_warn("MAC%u: unknown TLV type %u\n",
1178 mac
->macid
, tlv_type
);
1182 tlv_buf_size
-= tlv_full_len
;
1183 tlv
= (struct qlink_tlv_hdr
*)(tlv
->val
+ tlv_value_len
);
1187 pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n",
1188 mac
->macid
, tlv_buf_size
);
1192 if (mac
->macinfo
.n_if_comb
!= n_comb
) {
1193 pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n",
1194 mac
->macid
, mac
->macinfo
.n_if_comb
, n_comb
);
1198 if (ext_capa_len
!= ext_capa_mask_len
) {
1199 pr_err("MAC%u: ext_capa/_mask lengths mismatch: %u != %u\n",
1200 mac
->macid
, ext_capa_len
, ext_capa_mask_len
);
1204 if (rule_idx
!= resp
->n_reg_rules
) {
1205 pr_warn("unexpected number of rules: expected %u got %u\n",
1206 resp
->n_reg_rules
, rule_idx
);
1210 if (ext_capa_len
> 0) {
1211 ext_capa
= kmemdup(ext_capa
, ext_capa_len
, GFP_KERNEL
);
1216 kmemdup(ext_capa_mask
, ext_capa_mask_len
, GFP_KERNEL
);
1217 if (!ext_capa_mask
) {
1223 ext_capa_mask
= NULL
;
1226 qtnf_mac_ext_caps_free(mac
);
1227 mac
->macinfo
.extended_capabilities
= ext_capa
;
1228 mac
->macinfo
.extended_capabilities_mask
= ext_capa_mask
;
1229 mac
->macinfo
.extended_capabilities_len
= ext_capa_len
;
1235 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac
*mac
,
1236 const struct qlink_resp_get_mac_info
*resp_info
)
1238 struct qtnf_mac_info
*mac_info
;
1239 struct qtnf_vif
*vif
;
1241 mac_info
= &mac
->macinfo
;
1243 mac_info
->bands_cap
= resp_info
->bands_cap
;
1244 memcpy(&mac_info
->dev_mac
, &resp_info
->dev_mac
,
1245 sizeof(mac_info
->dev_mac
));
1247 ether_addr_copy(mac
->macaddr
, mac_info
->dev_mac
);
1249 vif
= qtnf_mac_get_base_vif(mac
);
1251 ether_addr_copy(vif
->mac_addr
, mac
->macaddr
);
1253 pr_err("could not get valid base vif\n");
1255 mac_info
->num_tx_chain
= resp_info
->num_tx_chain
;
1256 mac_info
->num_rx_chain
= resp_info
->num_rx_chain
;
1258 mac_info
->max_ap_assoc_sta
= le16_to_cpu(resp_info
->max_ap_assoc_sta
);
1259 mac_info
->radar_detect_widths
=
1260 qlink_chan_width_mask_to_nl(le16_to_cpu(
1261 resp_info
->radar_detect_widths
));
1262 mac_info
->max_acl_mac_addrs
= le32_to_cpu(resp_info
->max_acl_mac_addrs
);
1264 memcpy(&mac_info
->ht_cap_mod_mask
, &resp_info
->ht_cap_mod_mask
,
1265 sizeof(mac_info
->ht_cap_mod_mask
));
1266 memcpy(&mac_info
->vht_cap_mod_mask
, &resp_info
->vht_cap_mod_mask
,
1267 sizeof(mac_info
->vht_cap_mod_mask
));
1270 static void qtnf_cmd_resp_band_fill_htcap(const u8
*info
,
1271 struct ieee80211_sta_ht_cap
*bcap
)
1273 const struct ieee80211_ht_cap
*ht_cap
=
1274 (const struct ieee80211_ht_cap
*)info
;
1276 bcap
->ht_supported
= true;
1277 bcap
->cap
= le16_to_cpu(ht_cap
->cap_info
);
1278 bcap
->ampdu_factor
=
1279 ht_cap
->ampdu_params_info
& IEEE80211_HT_AMPDU_PARM_FACTOR
;
1280 bcap
->ampdu_density
=
1281 (ht_cap
->ampdu_params_info
& IEEE80211_HT_AMPDU_PARM_DENSITY
) >>
1282 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT
;
1283 memcpy(&bcap
->mcs
, &ht_cap
->mcs
, sizeof(bcap
->mcs
));
1286 static void qtnf_cmd_resp_band_fill_vhtcap(const u8
*info
,
1287 struct ieee80211_sta_vht_cap
*bcap
)
1289 const struct ieee80211_vht_cap
*vht_cap
=
1290 (const struct ieee80211_vht_cap
*)info
;
1292 bcap
->vht_supported
= true;
1293 bcap
->cap
= le32_to_cpu(vht_cap
->vht_cap_info
);
1294 memcpy(&bcap
->vht_mcs
, &vht_cap
->supp_mcs
, sizeof(bcap
->vht_mcs
));
1298 qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band
*band
,
1299 struct qlink_resp_band_info_get
*resp
,
1305 const struct qlink_tlv_hdr
*tlv
;
1306 const struct qlink_channel
*qchan
;
1307 struct ieee80211_channel
*chan
;
1308 unsigned int chidx
= 0;
1311 memset(&band
->ht_cap
, 0, sizeof(band
->ht_cap
));
1312 memset(&band
->vht_cap
, 0, sizeof(band
->vht_cap
));
1314 if (band
->channels
) {
1315 if (band
->n_channels
== resp
->num_chans
) {
1316 memset(band
->channels
, 0,
1317 sizeof(*band
->channels
) * band
->n_channels
);
1319 kfree(band
->channels
);
1320 band
->n_channels
= 0;
1321 band
->channels
= NULL
;
1325 band
->n_channels
= resp
->num_chans
;
1326 if (band
->n_channels
== 0)
1329 if (!band
->channels
)
1330 band
->channels
= kcalloc(band
->n_channels
, sizeof(*chan
),
1332 if (!band
->channels
) {
1333 band
->n_channels
= 0;
1337 tlv
= (struct qlink_tlv_hdr
*)resp
->info
;
1339 while (payload_len
>= sizeof(*tlv
)) {
1340 tlv_type
= le16_to_cpu(tlv
->type
);
1341 tlv_dlen
= le16_to_cpu(tlv
->len
);
1342 tlv_len
= tlv_dlen
+ sizeof(*tlv
);
1344 if (tlv_len
> payload_len
) {
1345 pr_warn("malformed TLV 0x%.2X; LEN: %zu\n",
1351 case QTN_TLV_ID_CHANNEL
:
1352 if (unlikely(tlv_dlen
!= sizeof(*qchan
))) {
1353 pr_err("invalid channel TLV len %zu\n",
1358 if (chidx
== band
->n_channels
) {
1359 pr_err("too many channel TLVs\n");
1363 qchan
= (const struct qlink_channel
*)tlv
->val
;
1364 chan
= &band
->channels
[chidx
++];
1365 qflags
= le32_to_cpu(qchan
->flags
);
1367 chan
->hw_value
= le16_to_cpu(qchan
->hw_value
);
1368 chan
->band
= band
->band
;
1369 chan
->center_freq
= le16_to_cpu(qchan
->center_freq
);
1370 chan
->max_antenna_gain
= (int)qchan
->max_antenna_gain
;
1371 chan
->max_power
= (int)qchan
->max_power
;
1372 chan
->max_reg_power
= (int)qchan
->max_reg_power
;
1373 chan
->beacon_found
= qchan
->beacon_found
;
1374 chan
->dfs_cac_ms
= le32_to_cpu(qchan
->dfs_cac_ms
);
1377 if (qflags
& QLINK_CHAN_DISABLED
)
1378 chan
->flags
|= IEEE80211_CHAN_DISABLED
;
1380 if (qflags
& QLINK_CHAN_NO_IR
)
1381 chan
->flags
|= IEEE80211_CHAN_NO_IR
;
1383 if (qflags
& QLINK_CHAN_NO_HT40PLUS
)
1384 chan
->flags
|= IEEE80211_CHAN_NO_HT40PLUS
;
1386 if (qflags
& QLINK_CHAN_NO_HT40MINUS
)
1387 chan
->flags
|= IEEE80211_CHAN_NO_HT40MINUS
;
1389 if (qflags
& QLINK_CHAN_NO_OFDM
)
1390 chan
->flags
|= IEEE80211_CHAN_NO_OFDM
;
1392 if (qflags
& QLINK_CHAN_NO_80MHZ
)
1393 chan
->flags
|= IEEE80211_CHAN_NO_80MHZ
;
1395 if (qflags
& QLINK_CHAN_NO_160MHZ
)
1396 chan
->flags
|= IEEE80211_CHAN_NO_160MHZ
;
1398 if (qflags
& QLINK_CHAN_INDOOR_ONLY
)
1399 chan
->flags
|= IEEE80211_CHAN_INDOOR_ONLY
;
1401 if (qflags
& QLINK_CHAN_IR_CONCURRENT
)
1402 chan
->flags
|= IEEE80211_CHAN_IR_CONCURRENT
;
1404 if (qflags
& QLINK_CHAN_NO_20MHZ
)
1405 chan
->flags
|= IEEE80211_CHAN_NO_20MHZ
;
1407 if (qflags
& QLINK_CHAN_NO_10MHZ
)
1408 chan
->flags
|= IEEE80211_CHAN_NO_10MHZ
;
1410 if (qflags
& QLINK_CHAN_RADAR
) {
1411 chan
->flags
|= IEEE80211_CHAN_RADAR
;
1412 chan
->dfs_state_entered
= jiffies
;
1414 if (qchan
->dfs_state
== QLINK_DFS_USABLE
)
1415 chan
->dfs_state
= NL80211_DFS_USABLE
;
1416 else if (qchan
->dfs_state
==
1417 QLINK_DFS_AVAILABLE
)
1418 chan
->dfs_state
= NL80211_DFS_AVAILABLE
;
1421 NL80211_DFS_UNAVAILABLE
;
1424 pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n",
1425 chan
->hw_value
, chan
->flags
, chan
->max_power
,
1426 chan
->max_reg_power
);
1428 case WLAN_EID_HT_CAPABILITY
:
1429 if (unlikely(tlv_dlen
!=
1430 sizeof(struct ieee80211_ht_cap
))) {
1431 pr_err("bad HTCAP TLV len %zu\n", tlv_dlen
);
1435 qtnf_cmd_resp_band_fill_htcap(tlv
->val
, &band
->ht_cap
);
1437 case WLAN_EID_VHT_CAPABILITY
:
1438 if (unlikely(tlv_dlen
!=
1439 sizeof(struct ieee80211_vht_cap
))) {
1440 pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen
);
1444 qtnf_cmd_resp_band_fill_vhtcap(tlv
->val
,
1448 pr_warn("unknown TLV type: %#x\n", tlv_type
);
1452 payload_len
-= tlv_len
;
1453 tlv
= (struct qlink_tlv_hdr
*)(tlv
->val
+ tlv_dlen
);
1457 pr_err("malformed TLV buf; bytes left: %zu\n", payload_len
);
1461 if (band
->n_channels
!= chidx
) {
1462 pr_err("channel count mismatch: reported=%d, parsed=%d\n",
1463 band
->n_channels
, chidx
);
1470 kfree(band
->channels
);
1471 band
->channels
= NULL
;
1472 band
->n_channels
= 0;
1477 static int qtnf_cmd_resp_proc_phy_params(struct qtnf_wmac
*mac
,
1478 const u8
*payload
, size_t payload_len
)
1480 struct qtnf_mac_info
*mac_info
;
1481 struct qlink_tlv_frag_rts_thr
*phy_thr
;
1482 struct qlink_tlv_rlimit
*limit
;
1483 struct qlink_tlv_cclass
*class;
1486 size_t tlv_full_len
;
1487 const struct qlink_tlv_hdr
*tlv
;
1489 mac_info
= &mac
->macinfo
;
1491 tlv
= (struct qlink_tlv_hdr
*)payload
;
1492 while (payload_len
>= sizeof(struct qlink_tlv_hdr
)) {
1493 tlv_type
= le16_to_cpu(tlv
->type
);
1494 tlv_value_len
= le16_to_cpu(tlv
->len
);
1495 tlv_full_len
= tlv_value_len
+ sizeof(struct qlink_tlv_hdr
);
1497 if (tlv_full_len
> payload_len
) {
1498 pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n",
1499 mac
->macid
, tlv_type
, tlv_value_len
);
1504 case QTN_TLV_ID_FRAG_THRESH
:
1505 phy_thr
= (void *)tlv
;
1506 mac_info
->frag_thr
= le32_to_cpu(phy_thr
->thr
);
1508 case QTN_TLV_ID_RTS_THRESH
:
1509 phy_thr
= (void *)tlv
;
1510 mac_info
->rts_thr
= le32_to_cpu(phy_thr
->thr
);
1512 case QTN_TLV_ID_SRETRY_LIMIT
:
1513 limit
= (void *)tlv
;
1514 mac_info
->sretry_limit
= limit
->rlimit
;
1516 case QTN_TLV_ID_LRETRY_LIMIT
:
1517 limit
= (void *)tlv
;
1518 mac_info
->lretry_limit
= limit
->rlimit
;
1520 case QTN_TLV_ID_COVERAGE_CLASS
:
1521 class = (void *)tlv
;
1522 mac_info
->coverage_class
= class->cclass
;
1525 pr_err("MAC%u: Unknown TLV type: %#x\n", mac
->macid
,
1526 le16_to_cpu(tlv
->type
));
1530 payload_len
-= tlv_full_len
;
1531 tlv
= (struct qlink_tlv_hdr
*)(tlv
->val
+ tlv_value_len
);
1535 pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n",
1536 mac
->macid
, payload_len
);
1544 qtnf_cmd_resp_proc_chan_stat_info(struct qtnf_chan_stats
*stats
,
1545 const u8
*payload
, size_t payload_len
)
1547 struct qlink_chan_stats
*qlink_stats
;
1548 const struct qlink_tlv_hdr
*tlv
;
1549 size_t tlv_full_len
;
1553 tlv
= (struct qlink_tlv_hdr
*)payload
;
1554 while (payload_len
>= sizeof(struct qlink_tlv_hdr
)) {
1555 tlv_type
= le16_to_cpu(tlv
->type
);
1556 tlv_value_len
= le16_to_cpu(tlv
->len
);
1557 tlv_full_len
= tlv_value_len
+ sizeof(struct qlink_tlv_hdr
);
1558 if (tlv_full_len
> payload_len
) {
1559 pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
1560 tlv_type
, tlv_value_len
);
1564 case QTN_TLV_ID_CHANNEL_STATS
:
1565 if (unlikely(tlv_value_len
!= sizeof(*qlink_stats
))) {
1566 pr_err("invalid CHANNEL_STATS entry size\n");
1570 qlink_stats
= (void *)tlv
->val
;
1572 stats
->chan_num
= le32_to_cpu(qlink_stats
->chan_num
);
1573 stats
->cca_tx
= le32_to_cpu(qlink_stats
->cca_tx
);
1574 stats
->cca_rx
= le32_to_cpu(qlink_stats
->cca_rx
);
1575 stats
->cca_busy
= le32_to_cpu(qlink_stats
->cca_busy
);
1576 stats
->cca_try
= le32_to_cpu(qlink_stats
->cca_try
);
1577 stats
->chan_noise
= qlink_stats
->chan_noise
;
1579 pr_debug("chan(%u) try(%u) busy(%u) noise(%d)\n",
1580 stats
->chan_num
, stats
->cca_try
,
1581 stats
->cca_busy
, stats
->chan_noise
);
1584 pr_warn("Unknown TLV type: %#x\n",
1585 le16_to_cpu(tlv
->type
));
1587 payload_len
-= tlv_full_len
;
1588 tlv
= (struct qlink_tlv_hdr
*)(tlv
->val
+ tlv_value_len
);
1592 pr_warn("malformed TLV buf; bytes left: %zu\n", payload_len
);
1599 int qtnf_cmd_get_mac_info(struct qtnf_wmac
*mac
)
1601 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1602 const struct qlink_resp_get_mac_info
*resp
;
1603 size_t var_data_len
= 0;
1606 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
1608 sizeof(struct qlink_cmd
));
1612 qtnf_bus_lock(mac
->bus
);
1613 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
1614 sizeof(*resp
), &var_data_len
);
1618 resp
= (const struct qlink_resp_get_mac_info
*)resp_skb
->data
;
1619 qtnf_cmd_resp_proc_mac_info(mac
, resp
);
1620 ret
= qtnf_parse_variable_mac_info(mac
, resp
, var_data_len
);
1623 qtnf_bus_unlock(mac
->bus
);
1624 consume_skb(resp_skb
);
1629 int qtnf_cmd_get_hw_info(struct qtnf_bus
*bus
)
1631 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1632 const struct qlink_resp_get_hw_info
*resp
;
1633 size_t info_len
= 0;
1636 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD
, QLINK_VIFID_RSVD
,
1637 QLINK_CMD_GET_HW_INFO
,
1638 sizeof(struct qlink_cmd
));
1643 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
1644 sizeof(*resp
), &info_len
);
1648 resp
= (const struct qlink_resp_get_hw_info
*)resp_skb
->data
;
1649 ret
= qtnf_cmd_resp_proc_hw_info(bus
, resp
, info_len
);
1652 qtnf_bus_unlock(bus
);
1653 consume_skb(resp_skb
);
1658 int qtnf_cmd_band_info_get(struct qtnf_wmac
*mac
,
1659 struct ieee80211_supported_band
*band
)
1661 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1662 struct qlink_cmd_band_info_get
*cmd
;
1663 struct qlink_resp_band_info_get
*resp
;
1664 size_t info_len
= 0;
1666 u8 qband
= qlink_utils_band_cfg2q(band
->band
);
1668 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, 0,
1669 QLINK_CMD_BAND_INFO_GET
,
1674 cmd
= (struct qlink_cmd_band_info_get
*)cmd_skb
->data
;
1677 qtnf_bus_lock(mac
->bus
);
1678 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
1679 sizeof(*resp
), &info_len
);
1683 resp
= (struct qlink_resp_band_info_get
*)resp_skb
->data
;
1684 if (resp
->band
!= qband
) {
1685 pr_err("MAC%u: reply band %u != cmd band %u\n", mac
->macid
,
1691 ret
= qtnf_cmd_resp_fill_band_info(band
, resp
, info_len
);
1694 qtnf_bus_unlock(mac
->bus
);
1695 consume_skb(resp_skb
);
1700 int qtnf_cmd_send_get_phy_params(struct qtnf_wmac
*mac
)
1702 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
1703 struct qlink_resp_phy_params
*resp
;
1704 size_t response_size
= 0;
1707 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, 0,
1708 QLINK_CMD_PHY_PARAMS_GET
,
1709 sizeof(struct qlink_cmd
));
1713 qtnf_bus_lock(mac
->bus
);
1714 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
1715 sizeof(*resp
), &response_size
);
1719 resp
= (struct qlink_resp_phy_params
*)resp_skb
->data
;
1720 ret
= qtnf_cmd_resp_proc_phy_params(mac
, resp
->info
, response_size
);
1723 qtnf_bus_unlock(mac
->bus
);
1724 consume_skb(resp_skb
);
1729 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac
*mac
, u32 changed
)
1731 struct wiphy
*wiphy
= priv_to_wiphy(mac
);
1732 struct sk_buff
*cmd_skb
;
1735 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, 0,
1736 QLINK_CMD_PHY_PARAMS_SET
,
1737 sizeof(struct qlink_cmd
));
1741 qtnf_bus_lock(mac
->bus
);
1743 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
)
1744 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_FRAG_THRESH
,
1745 wiphy
->frag_threshold
);
1746 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
)
1747 qtnf_cmd_skb_put_tlv_u32(cmd_skb
, QTN_TLV_ID_RTS_THRESH
,
1748 wiphy
->rts_threshold
);
1749 if (changed
& WIPHY_PARAM_COVERAGE_CLASS
)
1750 qtnf_cmd_skb_put_tlv_u8(cmd_skb
, QTN_TLV_ID_COVERAGE_CLASS
,
1751 wiphy
->coverage_class
);
1753 if (changed
& WIPHY_PARAM_RETRY_LONG
)
1754 qtnf_cmd_skb_put_tlv_u8(cmd_skb
, QTN_TLV_ID_LRETRY_LIMIT
,
1757 if (changed
& WIPHY_PARAM_RETRY_SHORT
)
1758 qtnf_cmd_skb_put_tlv_u8(cmd_skb
, QTN_TLV_ID_SRETRY_LIMIT
,
1759 wiphy
->retry_short
);
1761 ret
= qtnf_cmd_send(mac
->bus
, cmd_skb
);
1766 qtnf_bus_unlock(mac
->bus
);
1771 int qtnf_cmd_send_init_fw(struct qtnf_bus
*bus
)
1773 struct sk_buff
*cmd_skb
;
1776 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD
, QLINK_VIFID_RSVD
,
1778 sizeof(struct qlink_cmd
));
1783 ret
= qtnf_cmd_send(bus
, cmd_skb
);
1788 qtnf_bus_unlock(bus
);
1793 void qtnf_cmd_send_deinit_fw(struct qtnf_bus
*bus
)
1795 struct sk_buff
*cmd_skb
;
1797 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD
, QLINK_VIFID_RSVD
,
1798 QLINK_CMD_FW_DEINIT
,
1799 sizeof(struct qlink_cmd
));
1804 qtnf_cmd_send(bus
, cmd_skb
);
1805 qtnf_bus_unlock(bus
);
1808 int qtnf_cmd_send_add_key(struct qtnf_vif
*vif
, u8 key_index
, bool pairwise
,
1809 const u8
*mac_addr
, struct key_params
*params
)
1811 struct sk_buff
*cmd_skb
;
1812 struct qlink_cmd_add_key
*cmd
;
1815 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1821 qtnf_bus_lock(vif
->mac
->bus
);
1823 cmd
= (struct qlink_cmd_add_key
*)cmd_skb
->data
;
1826 ether_addr_copy(cmd
->addr
, mac_addr
);
1828 eth_broadcast_addr(cmd
->addr
);
1830 cmd
->cipher
= cpu_to_le32(params
->cipher
);
1831 cmd
->key_index
= key_index
;
1832 cmd
->pairwise
= pairwise
;
1834 if (params
->key
&& params
->key_len
> 0)
1835 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, QTN_TLV_ID_KEY
,
1839 if (params
->seq
&& params
->seq_len
> 0)
1840 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, QTN_TLV_ID_SEQ
,
1844 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1849 qtnf_bus_unlock(vif
->mac
->bus
);
1854 int qtnf_cmd_send_del_key(struct qtnf_vif
*vif
, u8 key_index
, bool pairwise
,
1857 struct sk_buff
*cmd_skb
;
1858 struct qlink_cmd_del_key
*cmd
;
1861 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1867 qtnf_bus_lock(vif
->mac
->bus
);
1869 cmd
= (struct qlink_cmd_del_key
*)cmd_skb
->data
;
1872 ether_addr_copy(cmd
->addr
, mac_addr
);
1874 eth_broadcast_addr(cmd
->addr
);
1876 cmd
->key_index
= key_index
;
1877 cmd
->pairwise
= pairwise
;
1879 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1884 qtnf_bus_unlock(vif
->mac
->bus
);
1889 int qtnf_cmd_send_set_default_key(struct qtnf_vif
*vif
, u8 key_index
,
1890 bool unicast
, bool multicast
)
1892 struct sk_buff
*cmd_skb
;
1893 struct qlink_cmd_set_def_key
*cmd
;
1896 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1897 QLINK_CMD_SET_DEFAULT_KEY
,
1902 qtnf_bus_lock(vif
->mac
->bus
);
1904 cmd
= (struct qlink_cmd_set_def_key
*)cmd_skb
->data
;
1905 cmd
->key_index
= key_index
;
1906 cmd
->unicast
= unicast
;
1907 cmd
->multicast
= multicast
;
1909 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1914 qtnf_bus_unlock(vif
->mac
->bus
);
1919 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif
*vif
, u8 key_index
)
1921 struct sk_buff
*cmd_skb
;
1922 struct qlink_cmd_set_def_mgmt_key
*cmd
;
1925 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1926 QLINK_CMD_SET_DEFAULT_MGMT_KEY
,
1931 qtnf_bus_lock(vif
->mac
->bus
);
1933 cmd
= (struct qlink_cmd_set_def_mgmt_key
*)cmd_skb
->data
;
1934 cmd
->key_index
= key_index
;
1936 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
1941 qtnf_bus_unlock(vif
->mac
->bus
);
1946 static u32
qtnf_encode_sta_flags(u32 flags
)
1950 if (flags
& BIT(NL80211_STA_FLAG_AUTHORIZED
))
1951 code
|= QLINK_STA_FLAG_AUTHORIZED
;
1952 if (flags
& BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
))
1953 code
|= QLINK_STA_FLAG_SHORT_PREAMBLE
;
1954 if (flags
& BIT(NL80211_STA_FLAG_WME
))
1955 code
|= QLINK_STA_FLAG_WME
;
1956 if (flags
& BIT(NL80211_STA_FLAG_MFP
))
1957 code
|= QLINK_STA_FLAG_MFP
;
1958 if (flags
& BIT(NL80211_STA_FLAG_AUTHENTICATED
))
1959 code
|= QLINK_STA_FLAG_AUTHENTICATED
;
1960 if (flags
& BIT(NL80211_STA_FLAG_TDLS_PEER
))
1961 code
|= QLINK_STA_FLAG_TDLS_PEER
;
1962 if (flags
& BIT(NL80211_STA_FLAG_ASSOCIATED
))
1963 code
|= QLINK_STA_FLAG_ASSOCIATED
;
1967 int qtnf_cmd_send_change_sta(struct qtnf_vif
*vif
, const u8
*mac
,
1968 struct station_parameters
*params
)
1970 struct sk_buff
*cmd_skb
;
1971 struct qlink_cmd_change_sta
*cmd
;
1974 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
1975 QLINK_CMD_CHANGE_STA
,
1980 qtnf_bus_lock(vif
->mac
->bus
);
1982 cmd
= (struct qlink_cmd_change_sta
*)cmd_skb
->data
;
1983 ether_addr_copy(cmd
->sta_addr
, mac
);
1984 cmd
->flag_update
.mask
=
1985 cpu_to_le32(qtnf_encode_sta_flags(params
->sta_flags_mask
));
1986 cmd
->flag_update
.value
=
1987 cpu_to_le32(qtnf_encode_sta_flags(params
->sta_flags_set
));
1989 switch (vif
->wdev
.iftype
) {
1990 case NL80211_IFTYPE_AP
:
1991 cmd
->if_type
= cpu_to_le16(QLINK_IFTYPE_AP
);
1993 case NL80211_IFTYPE_STATION
:
1994 cmd
->if_type
= cpu_to_le16(QLINK_IFTYPE_STATION
);
1997 pr_err("unsupported iftype %d\n", vif
->wdev
.iftype
);
2002 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2007 qtnf_bus_unlock(vif
->mac
->bus
);
2012 int qtnf_cmd_send_del_sta(struct qtnf_vif
*vif
,
2013 struct station_del_parameters
*params
)
2015 struct sk_buff
*cmd_skb
;
2016 struct qlink_cmd_del_sta
*cmd
;
2019 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2025 qtnf_bus_lock(vif
->mac
->bus
);
2027 cmd
= (struct qlink_cmd_del_sta
*)cmd_skb
->data
;
2030 ether_addr_copy(cmd
->sta_addr
, params
->mac
);
2032 eth_broadcast_addr(cmd
->sta_addr
); /* flush all stations */
2034 cmd
->subtype
= params
->subtype
;
2035 cmd
->reason_code
= cpu_to_le16(params
->reason_code
);
2037 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2042 qtnf_bus_unlock(vif
->mac
->bus
);
2047 static void qtnf_cmd_channel_tlv_add(struct sk_buff
*cmd_skb
,
2048 const struct ieee80211_channel
*sc
)
2050 struct qlink_tlv_channel
*tlv
;
2051 struct qlink_channel
*qch
;
2053 tlv
= skb_put_zero(cmd_skb
, sizeof(*tlv
));
2055 tlv
->hdr
.type
= cpu_to_le16(QTN_TLV_ID_CHANNEL
);
2056 tlv
->hdr
.len
= cpu_to_le16(sizeof(*qch
));
2058 qch
->center_freq
= cpu_to_le16(sc
->center_freq
);
2059 qch
->hw_value
= cpu_to_le16(sc
->hw_value
);
2060 qch
->band
= qlink_utils_band_cfg2q(sc
->band
);
2061 qch
->max_power
= sc
->max_power
;
2062 qch
->max_reg_power
= sc
->max_reg_power
;
2063 qch
->max_antenna_gain
= sc
->max_antenna_gain
;
2064 qch
->beacon_found
= sc
->beacon_found
;
2065 qch
->dfs_state
= qlink_utils_dfs_state_cfg2q(sc
->dfs_state
);
2066 qch
->flags
= cpu_to_le32(qlink_utils_chflags_cfg2q(sc
->flags
));
2069 static void qtnf_cmd_randmac_tlv_add(struct sk_buff
*cmd_skb
,
2071 const u8
*mac_addr_mask
)
2073 struct qlink_random_mac_addr
*randmac
;
2074 struct qlink_tlv_hdr
*hdr
=
2075 skb_put(cmd_skb
, sizeof(*hdr
) + sizeof(*randmac
));
2077 hdr
->type
= cpu_to_le16(QTN_TLV_ID_RANDOM_MAC_ADDR
);
2078 hdr
->len
= cpu_to_le16(sizeof(*randmac
));
2079 randmac
= (struct qlink_random_mac_addr
*)hdr
->val
;
2081 memcpy(randmac
->mac_addr
, mac_addr
, ETH_ALEN
);
2082 memcpy(randmac
->mac_addr_mask
, mac_addr_mask
, ETH_ALEN
);
2085 static void qtnf_cmd_scan_set_dwell(struct qtnf_wmac
*mac
,
2086 struct sk_buff
*cmd_skb
)
2088 struct cfg80211_scan_request
*scan_req
= mac
->scan_req
;
2089 u16 dwell_active
= QTNF_SCAN_DWELL_ACTIVE_DEFAULT
;
2090 u16 dwell_passive
= QTNF_SCAN_DWELL_PASSIVE_DEFAULT
;
2091 u16 duration
= QTNF_SCAN_SAMPLE_DURATION_DEFAULT
;
2093 if (scan_req
->duration
) {
2094 dwell_active
= scan_req
->duration
;
2095 dwell_passive
= scan_req
->duration
;
2098 pr_debug("MAC%u: %s scan dwell active=%u, passive=%u, duration=%u\n",
2100 scan_req
->duration_mandatory
? "mandatory" : "max",
2101 dwell_active
, dwell_passive
, duration
);
2103 qtnf_cmd_skb_put_tlv_u16(cmd_skb
,
2104 QTN_TLV_ID_SCAN_DWELL_ACTIVE
,
2106 qtnf_cmd_skb_put_tlv_u16(cmd_skb
,
2107 QTN_TLV_ID_SCAN_DWELL_PASSIVE
,
2109 qtnf_cmd_skb_put_tlv_u16(cmd_skb
,
2110 QTN_TLV_ID_SCAN_SAMPLE_DURATION
,
2114 int qtnf_cmd_send_scan(struct qtnf_wmac
*mac
)
2116 struct sk_buff
*cmd_skb
;
2117 struct ieee80211_channel
*sc
;
2118 struct cfg80211_scan_request
*scan_req
= mac
->scan_req
;
2123 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
2125 sizeof(struct qlink_cmd
));
2129 qtnf_bus_lock(mac
->bus
);
2131 if (scan_req
->n_ssids
!= 0) {
2132 while (count
< scan_req
->n_ssids
) {
2133 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, WLAN_EID_SSID
,
2134 scan_req
->ssids
[count
].ssid
,
2135 scan_req
->ssids
[count
].ssid_len
);
2140 if (scan_req
->ie_len
!= 0)
2141 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_PROBE_REQ
,
2142 scan_req
->ie
, scan_req
->ie_len
);
2144 if (scan_req
->n_channels
) {
2145 n_channels
= scan_req
->n_channels
;
2148 while (n_channels
!= 0) {
2149 sc
= scan_req
->channels
[count
];
2150 if (sc
->flags
& IEEE80211_CHAN_DISABLED
) {
2155 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n",
2156 mac
->macid
, sc
->hw_value
, sc
->center_freq
,
2159 qtnf_cmd_channel_tlv_add(cmd_skb
, sc
);
2165 qtnf_cmd_scan_set_dwell(mac
, cmd_skb
);
2167 if (scan_req
->flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
) {
2168 pr_debug("MAC%u: scan with random addr=%pM, mask=%pM\n",
2170 scan_req
->mac_addr
, scan_req
->mac_addr_mask
);
2172 qtnf_cmd_randmac_tlv_add(cmd_skb
, scan_req
->mac_addr
,
2173 scan_req
->mac_addr_mask
);
2176 if (scan_req
->flags
& NL80211_SCAN_FLAG_FLUSH
) {
2177 pr_debug("MAC%u: flush cache before scan\n", mac
->macid
);
2179 qtnf_cmd_skb_put_tlv_tag(cmd_skb
, QTN_TLV_ID_SCAN_FLUSH
);
2182 ret
= qtnf_cmd_send(mac
->bus
, cmd_skb
);
2187 qtnf_bus_unlock(mac
->bus
);
2192 int qtnf_cmd_send_connect(struct qtnf_vif
*vif
,
2193 struct cfg80211_connect_params
*sme
)
2195 struct sk_buff
*cmd_skb
;
2196 struct qlink_cmd_connect
*cmd
;
2197 struct qlink_auth_encr
*aen
;
2200 u32 connect_flags
= 0;
2202 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2208 cmd
= (struct qlink_cmd_connect
*)cmd_skb
->data
;
2210 ether_addr_copy(cmd
->bssid
, vif
->bssid
);
2212 if (sme
->bssid_hint
)
2213 ether_addr_copy(cmd
->bssid_hint
, sme
->bssid_hint
);
2215 eth_zero_addr(cmd
->bssid_hint
);
2217 if (sme
->prev_bssid
)
2218 ether_addr_copy(cmd
->prev_bssid
, sme
->prev_bssid
);
2220 eth_zero_addr(cmd
->prev_bssid
);
2222 if ((sme
->bg_scan_period
>= 0) &&
2223 (sme
->bg_scan_period
<= SHRT_MAX
))
2224 cmd
->bg_scan_period
= cpu_to_le16(sme
->bg_scan_period
);
2226 cmd
->bg_scan_period
= cpu_to_le16(-1); /* use default value */
2228 if (sme
->flags
& ASSOC_REQ_DISABLE_HT
)
2229 connect_flags
|= QLINK_STA_CONNECT_DISABLE_HT
;
2230 if (sme
->flags
& ASSOC_REQ_DISABLE_VHT
)
2231 connect_flags
|= QLINK_STA_CONNECT_DISABLE_VHT
;
2232 if (sme
->flags
& ASSOC_REQ_USE_RRM
)
2233 connect_flags
|= QLINK_STA_CONNECT_USE_RRM
;
2235 cmd
->flags
= cpu_to_le32(connect_flags
);
2236 memcpy(&cmd
->ht_capa
, &sme
->ht_capa
, sizeof(cmd
->ht_capa
));
2237 memcpy(&cmd
->ht_capa_mask
, &sme
->ht_capa_mask
,
2238 sizeof(cmd
->ht_capa_mask
));
2239 memcpy(&cmd
->vht_capa
, &sme
->vht_capa
, sizeof(cmd
->vht_capa
));
2240 memcpy(&cmd
->vht_capa_mask
, &sme
->vht_capa_mask
,
2241 sizeof(cmd
->vht_capa_mask
));
2242 cmd
->pbss
= sme
->pbss
;
2245 aen
->auth_type
= sme
->auth_type
;
2246 aen
->privacy
= !!sme
->privacy
;
2247 cmd
->mfp
= sme
->mfp
;
2248 aen
->wpa_versions
= cpu_to_le32(sme
->crypto
.wpa_versions
);
2249 aen
->cipher_group
= cpu_to_le32(sme
->crypto
.cipher_group
);
2250 aen
->n_ciphers_pairwise
= cpu_to_le32(sme
->crypto
.n_ciphers_pairwise
);
2252 for (i
= 0; i
< QLINK_MAX_NR_CIPHER_SUITES
; i
++)
2253 aen
->ciphers_pairwise
[i
] =
2254 cpu_to_le32(sme
->crypto
.ciphers_pairwise
[i
]);
2256 aen
->n_akm_suites
= cpu_to_le32(sme
->crypto
.n_akm_suites
);
2258 for (i
= 0; i
< QLINK_MAX_NR_AKM_SUITES
; i
++)
2259 aen
->akm_suites
[i
] = cpu_to_le32(sme
->crypto
.akm_suites
[i
]);
2261 aen
->control_port
= sme
->crypto
.control_port
;
2262 aen
->control_port_no_encrypt
=
2263 sme
->crypto
.control_port_no_encrypt
;
2264 aen
->control_port_ethertype
=
2265 cpu_to_le16(be16_to_cpu(sme
->crypto
.control_port_ethertype
));
2267 qtnf_cmd_skb_put_tlv_arr(cmd_skb
, WLAN_EID_SSID
, sme
->ssid
,
2270 if (sme
->ie_len
!= 0)
2271 qtnf_cmd_tlv_ie_set_add(cmd_skb
, QLINK_IE_SET_ASSOC_REQ
,
2272 sme
->ie
, sme
->ie_len
);
2275 qtnf_cmd_channel_tlv_add(cmd_skb
, sme
->channel
);
2277 qtnf_bus_lock(vif
->mac
->bus
);
2278 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2283 qtnf_bus_unlock(vif
->mac
->bus
);
2288 int qtnf_cmd_send_external_auth(struct qtnf_vif
*vif
,
2289 struct cfg80211_external_auth_params
*auth
)
2291 struct sk_buff
*cmd_skb
;
2292 struct qlink_cmd_external_auth
*cmd
;
2295 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2296 QLINK_CMD_EXTERNAL_AUTH
,
2301 cmd
= (struct qlink_cmd_external_auth
*)cmd_skb
->data
;
2303 ether_addr_copy(cmd
->bssid
, auth
->bssid
);
2304 cmd
->status
= cpu_to_le16(auth
->status
);
2306 qtnf_bus_lock(vif
->mac
->bus
);
2307 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2312 qtnf_bus_unlock(vif
->mac
->bus
);
2317 int qtnf_cmd_send_disconnect(struct qtnf_vif
*vif
, u16 reason_code
)
2319 struct sk_buff
*cmd_skb
;
2320 struct qlink_cmd_disconnect
*cmd
;
2323 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2324 QLINK_CMD_DISCONNECT
,
2329 qtnf_bus_lock(vif
->mac
->bus
);
2331 cmd
= (struct qlink_cmd_disconnect
*)cmd_skb
->data
;
2332 cmd
->reason
= cpu_to_le16(reason_code
);
2334 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2339 qtnf_bus_unlock(vif
->mac
->bus
);
2344 int qtnf_cmd_send_updown_intf(struct qtnf_vif
*vif
, bool up
)
2346 struct sk_buff
*cmd_skb
;
2347 struct qlink_cmd_updown
*cmd
;
2350 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2351 QLINK_CMD_UPDOWN_INTF
,
2356 cmd
= (struct qlink_cmd_updown
*)cmd_skb
->data
;
2359 qtnf_bus_lock(vif
->mac
->bus
);
2360 ret
= qtnf_cmd_send(vif
->mac
->bus
, cmd_skb
);
2365 qtnf_bus_unlock(vif
->mac
->bus
);
2370 int qtnf_cmd_reg_notify(struct qtnf_wmac
*mac
, struct regulatory_request
*req
,
2373 struct wiphy
*wiphy
= priv_to_wiphy(mac
);
2374 struct qtnf_bus
*bus
= mac
->bus
;
2375 struct sk_buff
*cmd_skb
;
2377 struct qlink_cmd_reg_notify
*cmd
;
2378 enum nl80211_band band
;
2379 const struct ieee80211_supported_band
*cfg_band
;
2381 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
2382 QLINK_CMD_REG_NOTIFY
,
2387 cmd
= (struct qlink_cmd_reg_notify
*)cmd_skb
->data
;
2388 cmd
->alpha2
[0] = req
->alpha2
[0];
2389 cmd
->alpha2
[1] = req
->alpha2
[1];
2391 switch (req
->initiator
) {
2392 case NL80211_REGDOM_SET_BY_CORE
:
2393 cmd
->initiator
= QLINK_REGDOM_SET_BY_CORE
;
2395 case NL80211_REGDOM_SET_BY_USER
:
2396 cmd
->initiator
= QLINK_REGDOM_SET_BY_USER
;
2398 case NL80211_REGDOM_SET_BY_DRIVER
:
2399 cmd
->initiator
= QLINK_REGDOM_SET_BY_DRIVER
;
2401 case NL80211_REGDOM_SET_BY_COUNTRY_IE
:
2402 cmd
->initiator
= QLINK_REGDOM_SET_BY_COUNTRY_IE
;
2406 switch (req
->user_reg_hint_type
) {
2407 case NL80211_USER_REG_HINT_USER
:
2408 cmd
->user_reg_hint_type
= QLINK_USER_REG_HINT_USER
;
2410 case NL80211_USER_REG_HINT_CELL_BASE
:
2411 cmd
->user_reg_hint_type
= QLINK_USER_REG_HINT_CELL_BASE
;
2413 case NL80211_USER_REG_HINT_INDOOR
:
2414 cmd
->user_reg_hint_type
= QLINK_USER_REG_HINT_INDOOR
;
2418 switch (req
->dfs_region
) {
2419 case NL80211_DFS_FCC
:
2420 cmd
->dfs_region
= QLINK_DFS_FCC
;
2422 case NL80211_DFS_ETSI
:
2423 cmd
->dfs_region
= QLINK_DFS_ETSI
;
2425 case NL80211_DFS_JP
:
2426 cmd
->dfs_region
= QLINK_DFS_JP
;
2429 cmd
->dfs_region
= QLINK_DFS_UNSET
;
2433 cmd
->slave_radar
= slave_radar
;
2434 cmd
->num_channels
= 0;
2436 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
2439 cfg_band
= wiphy
->bands
[band
];
2443 cmd
->num_channels
+= cfg_band
->n_channels
;
2445 for (i
= 0; i
< cfg_band
->n_channels
; ++i
) {
2446 qtnf_cmd_channel_tlv_add(cmd_skb
,
2447 &cfg_band
->channels
[i
]);
2452 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2453 qtnf_bus_unlock(bus
);
2458 int qtnf_cmd_get_chan_stats(struct qtnf_wmac
*mac
, u16 channel
,
2459 struct qtnf_chan_stats
*stats
)
2461 struct sk_buff
*cmd_skb
, *resp_skb
= NULL
;
2462 struct qlink_cmd_get_chan_stats
*cmd
;
2463 struct qlink_resp_get_chan_stats
*resp
;
2464 size_t var_data_len
= 0;
2467 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, QLINK_VIFID_RSVD
,
2468 QLINK_CMD_CHAN_STATS
,
2473 qtnf_bus_lock(mac
->bus
);
2475 cmd
= (struct qlink_cmd_get_chan_stats
*)cmd_skb
->data
;
2476 cmd
->channel
= cpu_to_le16(channel
);
2478 ret
= qtnf_cmd_send_with_reply(mac
->bus
, cmd_skb
, &resp_skb
,
2479 sizeof(*resp
), &var_data_len
);
2483 resp
= (struct qlink_resp_get_chan_stats
*)resp_skb
->data
;
2484 ret
= qtnf_cmd_resp_proc_chan_stat_info(stats
, resp
->info
,
2488 qtnf_bus_unlock(mac
->bus
);
2489 consume_skb(resp_skb
);
2494 int qtnf_cmd_send_chan_switch(struct qtnf_vif
*vif
,
2495 struct cfg80211_csa_settings
*params
)
2497 struct qtnf_wmac
*mac
= vif
->mac
;
2498 struct qlink_cmd_chan_switch
*cmd
;
2499 struct sk_buff
*cmd_skb
;
2502 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(mac
->macid
, vif
->vifid
,
2503 QLINK_CMD_CHAN_SWITCH
,
2508 qtnf_bus_lock(mac
->bus
);
2510 cmd
= (struct qlink_cmd_chan_switch
*)cmd_skb
->data
;
2511 cmd
->channel
= cpu_to_le16(params
->chandef
.chan
->hw_value
);
2512 cmd
->radar_required
= params
->radar_required
;
2513 cmd
->block_tx
= params
->block_tx
;
2514 cmd
->beacon_count
= params
->count
;
2516 ret
= qtnf_cmd_send(mac
->bus
, cmd_skb
);
2521 qtnf_bus_unlock(mac
->bus
);
2526 int qtnf_cmd_get_channel(struct qtnf_vif
*vif
, struct cfg80211_chan_def
*chdef
)
2528 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2529 const struct qlink_resp_channel_get
*resp
;
2530 struct sk_buff
*cmd_skb
;
2531 struct sk_buff
*resp_skb
= NULL
;
2534 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2536 sizeof(struct qlink_cmd
));
2541 ret
= qtnf_cmd_send_with_reply(bus
, cmd_skb
, &resp_skb
,
2542 sizeof(*resp
), NULL
);
2546 resp
= (const struct qlink_resp_channel_get
*)resp_skb
->data
;
2547 qlink_chandef_q2cfg(priv_to_wiphy(vif
->mac
), &resp
->chan
, chdef
);
2550 qtnf_bus_unlock(bus
);
2551 consume_skb(resp_skb
);
2556 int qtnf_cmd_start_cac(const struct qtnf_vif
*vif
,
2557 const struct cfg80211_chan_def
*chdef
,
2560 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2561 struct sk_buff
*cmd_skb
;
2562 struct qlink_cmd_start_cac
*cmd
;
2565 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2566 QLINK_CMD_START_CAC
,
2571 cmd
= (struct qlink_cmd_start_cac
*)cmd_skb
->data
;
2572 cmd
->cac_time_ms
= cpu_to_le32(cac_time_ms
);
2573 qlink_chandef_cfg2q(chdef
, &cmd
->chan
);
2576 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2581 qtnf_bus_unlock(bus
);
2586 int qtnf_cmd_set_mac_acl(const struct qtnf_vif
*vif
,
2587 const struct cfg80211_acl_data
*params
)
2589 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2590 struct sk_buff
*cmd_skb
;
2591 struct qlink_tlv_hdr
*tlv
;
2592 size_t acl_size
= struct_size(params
, mac_addrs
, params
->n_acl_entries
);
2595 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2596 QLINK_CMD_SET_MAC_ACL
,
2597 sizeof(struct qlink_cmd
));
2601 tlv
= skb_put(cmd_skb
, sizeof(*tlv
) + acl_size
);
2602 tlv
->type
= cpu_to_le16(QTN_TLV_ID_ACL_DATA
);
2603 tlv
->len
= cpu_to_le16(acl_size
);
2604 qlink_acl_data_cfg2q(params
, (struct qlink_acl_data
*)tlv
->val
);
2607 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2612 qtnf_bus_unlock(bus
);
2617 int qtnf_cmd_send_pm_set(const struct qtnf_vif
*vif
, u8 pm_mode
, int timeout
)
2619 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2620 struct sk_buff
*cmd_skb
;
2621 struct qlink_cmd_pm_set
*cmd
;
2624 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2625 QLINK_CMD_PM_SET
, sizeof(*cmd
));
2629 cmd
= (struct qlink_cmd_pm_set
*)cmd_skb
->data
;
2630 cmd
->pm_mode
= pm_mode
;
2631 cmd
->pm_standby_timer
= cpu_to_le32(timeout
);
2635 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2640 qtnf_bus_unlock(bus
);
2645 int qtnf_cmd_send_wowlan_set(const struct qtnf_vif
*vif
,
2646 const struct cfg80211_wowlan
*wowl
)
2648 struct qtnf_bus
*bus
= vif
->mac
->bus
;
2649 struct sk_buff
*cmd_skb
;
2650 struct qlink_cmd_wowlan_set
*cmd
;
2655 cmd_skb
= qtnf_cmd_alloc_new_cmdskb(vif
->mac
->macid
, vif
->vifid
,
2656 QLINK_CMD_WOWLAN_SET
, sizeof(*cmd
));
2662 cmd
= (struct qlink_cmd_wowlan_set
*)cmd_skb
->data
;
2665 if (wowl
->disconnect
)
2666 triggers
|= QLINK_WOWLAN_TRIG_DISCONNECT
;
2668 if (wowl
->magic_pkt
)
2669 triggers
|= QLINK_WOWLAN_TRIG_MAGIC_PKT
;
2671 if (wowl
->n_patterns
&& wowl
->patterns
) {
2672 triggers
|= QLINK_WOWLAN_TRIG_PATTERN_PKT
;
2673 while (count
< wowl
->n_patterns
) {
2674 qtnf_cmd_skb_put_tlv_arr(cmd_skb
,
2675 QTN_TLV_ID_WOWLAN_PATTERN
,
2676 wowl
->patterns
[count
].pattern
,
2677 wowl
->patterns
[count
].pattern_len
);
2683 cmd
->triggers
= cpu_to_le32(triggers
);
2685 ret
= qtnf_cmd_send(bus
, cmd_skb
);
2690 qtnf_bus_unlock(bus
);