1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */ 3 4 #include <linux/types.h> 5 #include <linux/skbuff.h> 6 7 #include "cfg80211.h" 8 #include "core.h" 9 #include "qlink.h" 10 #include "qlink_util.h" 11 #include "bus.h" 12 #include "commands.h" 13 14 /* Let device itself to select best values for current conditions */ 15 #define QTNF_SCAN_TIME_AUTO 0 16 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 20 21 static int qtnf_cmd_check_reply_header(const struct qlink_resp *resp, 22 u16 cmd_id, u8 mac_id, u8 vif_id, 23 size_t resp_size) 24 { 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)); 28 return -EINVAL; 29 } 30 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); 34 return -EINVAL; 35 } 36 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); 40 return -EINVAL; 41 } 42 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); 47 return -ENOSPC; 48 } 49 50 return 0; 51 } 52 53 static int qtnf_cmd_resp_result_decode(enum qlink_cmd_result qcode) 54 { 55 switch (qcode) { 56 case QLINK_CMD_RESULT_OK: 57 return 0; 58 case QLINK_CMD_RESULT_INVALID: 59 return -EINVAL; 60 case QLINK_CMD_RESULT_ENOTSUPP: 61 return -ENOTSUPP; 62 case QLINK_CMD_RESULT_ENOTFOUND: 63 return -ENOENT; 64 case QLINK_CMD_RESULT_EALREADY: 65 return -EALREADY; 66 case QLINK_CMD_RESULT_EADDRINUSE: 67 return -EADDRINUSE; 68 case QLINK_CMD_RESULT_EADDRNOTAVAIL: 69 return -EADDRNOTAVAIL; 70 case QLINK_CMD_RESULT_EBUSY: 71 return -EBUSY; 72 default: 73 return -EFAULT; 74 } 75 } 76 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) 82 { 83 struct qlink_cmd *cmd; 84 struct qlink_resp *resp = NULL; 85 struct sk_buff *resp_skb = NULL; 86 int resp_res = 0; 87 u16 cmd_id; 88 u8 mac_id; 89 u8 vif_id; 90 int ret; 91 92 cmd = (struct qlink_cmd *)cmd_skb->data; 93 cmd_id = le16_to_cpu(cmd->cmd_id); 94 mac_id = cmd->macid; 95 vif_id = cmd->vifid; 96 cmd->mhdr.len = cpu_to_le16(cmd_skb->len); 97 98 pr_debug("VIF%u.%u cmd=0x%.4X\n", mac_id, vif_id, cmd_id); 99 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); 104 return -ENODEV; 105 } 106 107 ret = qtnf_trans_send_cmd_with_resp(bus, cmd_skb, &resp_skb); 108 if (ret) 109 goto out; 110 111 if (WARN_ON(!resp_skb || !resp_skb->data)) { 112 ret = -EFAULT; 113 goto out; 114 } 115 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, 119 const_resp_size); 120 if (ret) 121 goto out; 122 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; 126 127 out: 128 if (response_skb) 129 *response_skb = resp_skb; 130 else 131 consume_skb(resp_skb); 132 133 if (!ret) 134 return qtnf_cmd_resp_result_decode(resp_res); 135 136 pr_warn("VIF%u.%u: cmd 0x%.4X failed: %d\n", 137 mac_id, vif_id, cmd_id, ret); 138 139 return ret; 140 } 141 142 static inline int qtnf_cmd_send(struct qtnf_bus *bus, struct sk_buff *cmd_skb) 143 { 144 return qtnf_cmd_send_with_reply(bus, cmd_skb, NULL, 145 sizeof(struct qlink_resp), NULL); 146 } 147 148 static struct sk_buff *qtnf_cmd_alloc_new_cmdskb(u8 macid, u8 vifid, u16 cmd_no, 149 size_t cmd_size) 150 { 151 struct qlink_cmd *cmd; 152 struct sk_buff *cmd_skb; 153 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); 158 return NULL; 159 } 160 161 skb_put_zero(cmd_skb, cmd_size); 162 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); 167 cmd->macid = macid; 168 cmd->vifid = vifid; 169 170 return cmd_skb; 171 } 172 173 static void qtnf_cmd_tlv_ie_set_add(struct sk_buff *cmd_skb, u8 frame_type, 174 const u8 *buf, size_t len) 175 { 176 struct qlink_tlv_ie_set *tlv; 177 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; 183 tlv->flags = 0; 184 185 if (len && buf) 186 memcpy(tlv->ie_data, buf, len); 187 } 188 189 static bool qtnf_cmd_start_ap_can_fit(const struct qtnf_vif *vif, 190 const struct cfg80211_ap_settings *s) 191 { 192 unsigned int len = sizeof(struct qlink_cmd_start_ap); 193 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); 201 202 if (cfg80211_chandef_valid(&s->chandef)) 203 len += sizeof(struct qlink_tlv_chandef); 204 205 if (s->acl) { 206 unsigned int acl_len = struct_size(s->acl, mac_addrs, 207 s->acl->n_acl_entries); 208 209 len += sizeof(struct qlink_tlv_hdr) + 210 round_up(acl_len, QLINK_ALIGN); 211 } 212 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); 216 return false; 217 } 218 219 return true; 220 } 221 222 static void qtnf_cmd_tlv_ie_ext_add(struct sk_buff *cmd_skb, u8 eid_ext, 223 const void *buf, size_t len) 224 { 225 struct qlink_tlv_ext_ie *tlv; 226 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; 231 232 if (len && buf) 233 memcpy(tlv->ie_data, buf, len); 234 } 235 236 int qtnf_cmd_send_start_ap(struct qtnf_vif *vif, 237 const struct cfg80211_ap_settings *s) 238 { 239 struct sk_buff *cmd_skb; 240 struct qlink_cmd_start_ap *cmd; 241 struct qlink_auth_encr *aen; 242 int ret; 243 int i; 244 245 if (!qtnf_cmd_start_ap_can_fit(vif, s)) 246 return -E2BIG; 247 248 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 249 QLINK_CMD_START_AP, 250 sizeof(*cmd)); 251 if (!cmd_skb) 252 return -ENOMEM; 253 254 cmd = (struct qlink_cmd_start_ap *)cmd_skb->data; 255 cmd->dtim_period = s->dtim_period; 256 cmd->beacon_interval = cpu_to_le16(s->beacon_interval); 257 cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid); 258 cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout); 259 cmd->smps_mode = s->smps_mode; 260 cmd->p2p_ctwindow = s->p2p_ctwindow; 261 cmd->p2p_opp_ps = s->p2p_opp_ps; 262 cmd->pbss = s->pbss; 263 cmd->ht_required = s->ht_required; 264 cmd->vht_required = s->vht_required; 265 cmd->twt_responder = s->twt_responder; 266 if (s->he_obss_pd.enable) { 267 cmd->sr_params.sr_control |= QLINK_SR_SRG_INFORMATION_PRESENT; 268 cmd->sr_params.srg_obss_pd_min_offset = 269 s->he_obss_pd.min_offset; 270 cmd->sr_params.srg_obss_pd_max_offset = 271 s->he_obss_pd.max_offset; 272 } 273 274 aen = &cmd->aen; 275 aen->auth_type = s->auth_type; 276 aen->privacy = !!s->privacy; 277 aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions); 278 aen->cipher_group = cpu_to_le32(s->crypto.cipher_group); 279 aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise); 280 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 281 aen->ciphers_pairwise[i] = 282 cpu_to_le32(s->crypto.ciphers_pairwise[i]); 283 aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites); 284 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 285 aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]); 286 aen->control_port = s->crypto.control_port; 287 aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt; 288 aen->control_port_ethertype = 289 cpu_to_le16(be16_to_cpu(s->crypto.control_port_ethertype)); 290 291 if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN) 292 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid, 293 s->ssid_len); 294 295 if (cfg80211_chandef_valid(&s->chandef)) { 296 struct qlink_tlv_chandef *chtlv = 297 (struct qlink_tlv_chandef *)skb_put(cmd_skb, 298 sizeof(*chtlv)); 299 300 chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF); 301 chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) - 302 sizeof(chtlv->hdr)); 303 qlink_chandef_cfg2q(&s->chandef, &chtlv->chdef); 304 } 305 306 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_HEAD, 307 s->beacon.head, s->beacon.head_len); 308 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_TAIL, 309 s->beacon.tail, s->beacon.tail_len); 310 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_IES, 311 s->beacon.beacon_ies, s->beacon.beacon_ies_len); 312 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP, 313 s->beacon.probe_resp, s->beacon.probe_resp_len); 314 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP_IES, 315 s->beacon.proberesp_ies, 316 s->beacon.proberesp_ies_len); 317 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_RESP, 318 s->beacon.assocresp_ies, 319 s->beacon.assocresp_ies_len); 320 321 if (s->ht_cap) { 322 struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *) 323 skb_put(cmd_skb, sizeof(*tlv) + 324 round_up(sizeof(*s->ht_cap), QLINK_ALIGN)); 325 326 tlv->type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); 327 tlv->len = cpu_to_le16(sizeof(*s->ht_cap)); 328 memcpy(tlv->val, s->ht_cap, sizeof(*s->ht_cap)); 329 } 330 331 if (s->vht_cap) { 332 struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *) 333 skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->vht_cap)); 334 335 tlv->type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY); 336 tlv->len = cpu_to_le16(sizeof(*s->vht_cap)); 337 memcpy(tlv->val, s->vht_cap, sizeof(*s->vht_cap)); 338 } 339 340 if (s->he_cap) 341 qtnf_cmd_tlv_ie_ext_add(cmd_skb, WLAN_EID_EXT_HE_CAPABILITY, 342 s->he_cap, sizeof(*s->he_cap)); 343 344 if (s->acl) { 345 size_t acl_size = struct_size(s->acl, mac_addrs, 346 s->acl->n_acl_entries); 347 struct qlink_tlv_hdr *tlv = 348 skb_put(cmd_skb, 349 sizeof(*tlv) + round_up(acl_size, QLINK_ALIGN)); 350 351 tlv->type = cpu_to_le16(QTN_TLV_ID_ACL_DATA); 352 tlv->len = cpu_to_le16(acl_size); 353 qlink_acl_data_cfg2q(s->acl, (struct qlink_acl_data *)tlv->val); 354 } 355 356 qtnf_bus_lock(vif->mac->bus); 357 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 358 if (ret) 359 goto out; 360 361 netif_carrier_on(vif->netdev); 362 363 out: 364 qtnf_bus_unlock(vif->mac->bus); 365 366 return ret; 367 } 368 369 int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif) 370 { 371 struct sk_buff *cmd_skb; 372 int ret; 373 374 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 375 QLINK_CMD_STOP_AP, 376 sizeof(struct qlink_cmd)); 377 if (!cmd_skb) 378 return -ENOMEM; 379 380 qtnf_bus_lock(vif->mac->bus); 381 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 382 if (ret) 383 goto out; 384 385 out: 386 qtnf_bus_unlock(vif->mac->bus); 387 388 return ret; 389 } 390 391 int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg) 392 { 393 struct sk_buff *cmd_skb; 394 struct qlink_cmd_mgmt_frame_register *cmd; 395 int ret; 396 397 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 398 QLINK_CMD_REGISTER_MGMT, 399 sizeof(*cmd)); 400 if (!cmd_skb) 401 return -ENOMEM; 402 403 qtnf_bus_lock(vif->mac->bus); 404 405 cmd = (struct qlink_cmd_mgmt_frame_register *)cmd_skb->data; 406 cmd->frame_type = cpu_to_le16(frame_type); 407 cmd->do_register = reg; 408 409 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 410 if (ret) 411 goto out; 412 413 out: 414 qtnf_bus_unlock(vif->mac->bus); 415 416 return ret; 417 } 418 419 int qtnf_cmd_send_frame(struct qtnf_vif *vif, u32 cookie, u16 flags, 420 u16 freq, const u8 *buf, size_t len) 421 { 422 struct sk_buff *cmd_skb; 423 struct qlink_cmd_frame_tx *cmd; 424 int ret; 425 426 if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) { 427 pr_warn("VIF%u.%u: frame is too big: %zu\n", vif->mac->macid, 428 vif->vifid, len); 429 return -E2BIG; 430 } 431 432 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 433 QLINK_CMD_SEND_FRAME, 434 sizeof(*cmd)); 435 if (!cmd_skb) 436 return -ENOMEM; 437 438 qtnf_bus_lock(vif->mac->bus); 439 440 cmd = (struct qlink_cmd_frame_tx *)cmd_skb->data; 441 cmd->cookie = cpu_to_le32(cookie); 442 cmd->freq = cpu_to_le16(freq); 443 cmd->flags = cpu_to_le16(flags); 444 445 if (len && buf) 446 qtnf_cmd_skb_put_buffer(cmd_skb, buf, len); 447 448 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 449 if (ret) 450 goto out; 451 452 out: 453 qtnf_bus_unlock(vif->mac->bus); 454 455 return ret; 456 } 457 458 int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type, 459 const u8 *buf, size_t len) 460 { 461 struct sk_buff *cmd_skb; 462 int ret; 463 464 if (len > QTNF_MAX_CMD_BUF_SIZE) { 465 pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid, 466 vif->vifid, frame_type, len); 467 return -E2BIG; 468 } 469 470 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 471 QLINK_CMD_MGMT_SET_APPIE, 472 sizeof(struct qlink_cmd)); 473 if (!cmd_skb) 474 return -ENOMEM; 475 476 qtnf_cmd_tlv_ie_set_add(cmd_skb, frame_type, buf, len); 477 478 qtnf_bus_lock(vif->mac->bus); 479 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 480 if (ret) 481 goto out; 482 483 out: 484 qtnf_bus_unlock(vif->mac->bus); 485 486 return ret; 487 } 488 489 static void 490 qtnf_sta_info_parse_rate(struct rate_info *rate_dst, 491 const struct qlink_sta_info_rate *rate_src) 492 { 493 rate_dst->legacy = get_unaligned_le16(&rate_src->rate) * 10; 494 495 rate_dst->mcs = rate_src->mcs; 496 rate_dst->nss = rate_src->nss; 497 rate_dst->flags = 0; 498 499 switch (rate_src->bw) { 500 case QLINK_CHAN_WIDTH_5: 501 rate_dst->bw = RATE_INFO_BW_5; 502 break; 503 case QLINK_CHAN_WIDTH_10: 504 rate_dst->bw = RATE_INFO_BW_10; 505 break; 506 case QLINK_CHAN_WIDTH_20: 507 case QLINK_CHAN_WIDTH_20_NOHT: 508 rate_dst->bw = RATE_INFO_BW_20; 509 break; 510 case QLINK_CHAN_WIDTH_40: 511 rate_dst->bw = RATE_INFO_BW_40; 512 break; 513 case QLINK_CHAN_WIDTH_80: 514 rate_dst->bw = RATE_INFO_BW_80; 515 break; 516 case QLINK_CHAN_WIDTH_160: 517 rate_dst->bw = RATE_INFO_BW_160; 518 break; 519 default: 520 rate_dst->bw = 0; 521 break; 522 } 523 524 if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_HT_MCS) 525 rate_dst->flags |= RATE_INFO_FLAGS_MCS; 526 else if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_VHT_MCS) 527 rate_dst->flags |= RATE_INFO_FLAGS_VHT_MCS; 528 else if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_HE_MCS) 529 rate_dst->flags |= RATE_INFO_FLAGS_HE_MCS; 530 531 if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_SHORT_GI) 532 rate_dst->flags |= RATE_INFO_FLAGS_SHORT_GI; 533 } 534 535 static void 536 qtnf_sta_info_parse_flags(struct nl80211_sta_flag_update *dst, 537 const struct qlink_sta_info_state *src) 538 { 539 u32 mask, value; 540 541 dst->mask = 0; 542 dst->set = 0; 543 544 mask = le32_to_cpu(src->mask); 545 value = le32_to_cpu(src->value); 546 547 if (mask & QLINK_STA_FLAG_AUTHORIZED) { 548 dst->mask |= BIT(NL80211_STA_FLAG_AUTHORIZED); 549 if (value & QLINK_STA_FLAG_AUTHORIZED) 550 dst->set |= BIT(NL80211_STA_FLAG_AUTHORIZED); 551 } 552 553 if (mask & QLINK_STA_FLAG_SHORT_PREAMBLE) { 554 dst->mask |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); 555 if (value & QLINK_STA_FLAG_SHORT_PREAMBLE) 556 dst->set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); 557 } 558 559 if (mask & QLINK_STA_FLAG_WME) { 560 dst->mask |= BIT(NL80211_STA_FLAG_WME); 561 if (value & QLINK_STA_FLAG_WME) 562 dst->set |= BIT(NL80211_STA_FLAG_WME); 563 } 564 565 if (mask & QLINK_STA_FLAG_MFP) { 566 dst->mask |= BIT(NL80211_STA_FLAG_MFP); 567 if (value & QLINK_STA_FLAG_MFP) 568 dst->set |= BIT(NL80211_STA_FLAG_MFP); 569 } 570 571 if (mask & QLINK_STA_FLAG_AUTHENTICATED) { 572 dst->mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED); 573 if (value & QLINK_STA_FLAG_AUTHENTICATED) 574 dst->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); 575 } 576 577 if (mask & QLINK_STA_FLAG_TDLS_PEER) { 578 dst->mask |= BIT(NL80211_STA_FLAG_TDLS_PEER); 579 if (value & QLINK_STA_FLAG_TDLS_PEER) 580 dst->set |= BIT(NL80211_STA_FLAG_TDLS_PEER); 581 } 582 583 if (mask & QLINK_STA_FLAG_ASSOCIATED) { 584 dst->mask |= BIT(NL80211_STA_FLAG_ASSOCIATED); 585 if (value & QLINK_STA_FLAG_ASSOCIATED) 586 dst->set |= BIT(NL80211_STA_FLAG_ASSOCIATED); 587 } 588 } 589 590 static void 591 qtnf_cmd_sta_info_parse(struct station_info *sinfo, const u8 *data, 592 size_t resp_size) 593 { 594 const struct qlink_tlv_hdr *tlv; 595 const struct qlink_sta_stats *stats = NULL; 596 const u8 *map = NULL; 597 unsigned int map_len = 0; 598 unsigned int stats_len = 0; 599 u16 tlv_len; 600 601 #define qtnf_sta_stat_avail(stat_name, bitn) \ 602 (qtnf_utils_is_bit_set(map, bitn, map_len) && \ 603 (offsetofend(struct qlink_sta_stats, stat_name) <= stats_len)) 604 605 qlink_for_each_tlv(tlv, data, resp_size) { 606 tlv_len = le16_to_cpu(tlv->len); 607 608 switch (le16_to_cpu(tlv->type)) { 609 case QTN_TLV_ID_BITMAP: 610 map_len = tlv_len; 611 map = tlv->val; 612 break; 613 case QTN_TLV_ID_STA_STATS: 614 stats_len = tlv_len; 615 stats = (const struct qlink_sta_stats *)tlv->val; 616 break; 617 default: 618 break; 619 } 620 } 621 622 if (!qlink_tlv_parsing_ok(tlv, data, resp_size)) { 623 pr_err("Malformed TLV buffer\n"); 624 return; 625 } 626 627 if (!map || !stats) 628 return; 629 630 if (qtnf_sta_stat_avail(inactive_time, QLINK_STA_INFO_INACTIVE_TIME)) { 631 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME); 632 sinfo->inactive_time = le32_to_cpu(stats->inactive_time); 633 } 634 635 if (qtnf_sta_stat_avail(connected_time, 636 QLINK_STA_INFO_CONNECTED_TIME)) { 637 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME); 638 sinfo->connected_time = le32_to_cpu(stats->connected_time); 639 } 640 641 if (qtnf_sta_stat_avail(signal, QLINK_STA_INFO_SIGNAL)) { 642 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); 643 sinfo->signal = stats->signal - QLINK_RSSI_OFFSET; 644 } 645 646 if (qtnf_sta_stat_avail(signal_avg, QLINK_STA_INFO_SIGNAL_AVG)) { 647 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); 648 sinfo->signal_avg = stats->signal_avg - QLINK_RSSI_OFFSET; 649 } 650 651 if (qtnf_sta_stat_avail(rxrate, QLINK_STA_INFO_RX_BITRATE)) { 652 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); 653 qtnf_sta_info_parse_rate(&sinfo->rxrate, &stats->rxrate); 654 } 655 656 if (qtnf_sta_stat_avail(txrate, QLINK_STA_INFO_TX_BITRATE)) { 657 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); 658 qtnf_sta_info_parse_rate(&sinfo->txrate, &stats->txrate); 659 } 660 661 if (qtnf_sta_stat_avail(sta_flags, QLINK_STA_INFO_STA_FLAGS)) { 662 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS); 663 qtnf_sta_info_parse_flags(&sinfo->sta_flags, &stats->sta_flags); 664 } 665 666 if (qtnf_sta_stat_avail(rx_bytes, QLINK_STA_INFO_RX_BYTES)) { 667 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); 668 sinfo->rx_bytes = le64_to_cpu(stats->rx_bytes); 669 } 670 671 if (qtnf_sta_stat_avail(tx_bytes, QLINK_STA_INFO_TX_BYTES)) { 672 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES); 673 sinfo->tx_bytes = le64_to_cpu(stats->tx_bytes); 674 } 675 676 if (qtnf_sta_stat_avail(rx_bytes, QLINK_STA_INFO_RX_BYTES64)) { 677 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); 678 sinfo->rx_bytes = le64_to_cpu(stats->rx_bytes); 679 } 680 681 if (qtnf_sta_stat_avail(tx_bytes, QLINK_STA_INFO_TX_BYTES64)) { 682 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); 683 sinfo->tx_bytes = le64_to_cpu(stats->tx_bytes); 684 } 685 686 if (qtnf_sta_stat_avail(rx_packets, QLINK_STA_INFO_RX_PACKETS)) { 687 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); 688 sinfo->rx_packets = le32_to_cpu(stats->rx_packets); 689 } 690 691 if (qtnf_sta_stat_avail(tx_packets, QLINK_STA_INFO_TX_PACKETS)) { 692 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); 693 sinfo->tx_packets = le32_to_cpu(stats->tx_packets); 694 } 695 696 if (qtnf_sta_stat_avail(rx_beacon, QLINK_STA_INFO_BEACON_RX)) { 697 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX); 698 sinfo->rx_beacon = le64_to_cpu(stats->rx_beacon); 699 } 700 701 if (qtnf_sta_stat_avail(rx_dropped_misc, QLINK_STA_INFO_RX_DROP_MISC)) { 702 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); 703 sinfo->rx_dropped_misc = le32_to_cpu(stats->rx_dropped_misc); 704 } 705 706 if (qtnf_sta_stat_avail(tx_failed, QLINK_STA_INFO_TX_FAILED)) { 707 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); 708 sinfo->tx_failed = le32_to_cpu(stats->tx_failed); 709 } 710 711 #undef qtnf_sta_stat_avail 712 } 713 714 int qtnf_cmd_get_sta_info(struct qtnf_vif *vif, const u8 *sta_mac, 715 struct station_info *sinfo) 716 { 717 struct sk_buff *cmd_skb, *resp_skb = NULL; 718 struct qlink_cmd_get_sta_info *cmd; 719 const struct qlink_resp_get_sta_info *resp; 720 size_t var_resp_len = 0; 721 int ret = 0; 722 723 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 724 QLINK_CMD_GET_STA_INFO, 725 sizeof(*cmd)); 726 if (!cmd_skb) 727 return -ENOMEM; 728 729 qtnf_bus_lock(vif->mac->bus); 730 731 cmd = (struct qlink_cmd_get_sta_info *)cmd_skb->data; 732 ether_addr_copy(cmd->sta_addr, sta_mac); 733 734 ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb, 735 sizeof(*resp), &var_resp_len); 736 if (ret) 737 goto out; 738 739 resp = (const struct qlink_resp_get_sta_info *)resp_skb->data; 740 741 if (!ether_addr_equal(sta_mac, resp->sta_addr)) { 742 pr_err("VIF%u.%u: wrong mac in reply: %pM != %pM\n", 743 vif->mac->macid, vif->vifid, resp->sta_addr, sta_mac); 744 ret = -EINVAL; 745 goto out; 746 } 747 748 qtnf_cmd_sta_info_parse(sinfo, resp->info, var_resp_len); 749 750 out: 751 qtnf_bus_unlock(vif->mac->bus); 752 consume_skb(resp_skb); 753 754 return ret; 755 } 756 757 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif, 758 enum nl80211_iftype iftype, 759 int use4addr, 760 u8 *mac_addr, 761 enum qlink_cmd_type cmd_type) 762 { 763 struct sk_buff *cmd_skb, *resp_skb = NULL; 764 struct qlink_cmd_manage_intf *cmd; 765 const struct qlink_resp_manage_intf *resp; 766 int ret = 0; 767 768 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 769 cmd_type, 770 sizeof(*cmd)); 771 if (!cmd_skb) 772 return -ENOMEM; 773 774 qtnf_bus_lock(vif->mac->bus); 775 776 cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data; 777 cmd->intf_info.use4addr = use4addr; 778 779 switch (iftype) { 780 case NL80211_IFTYPE_AP: 781 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP); 782 break; 783 case NL80211_IFTYPE_STATION: 784 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 785 break; 786 default: 787 pr_err("VIF%u.%u: unsupported type %d\n", vif->mac->macid, 788 vif->vifid, iftype); 789 ret = -EINVAL; 790 goto out; 791 } 792 793 if (mac_addr) 794 ether_addr_copy(cmd->intf_info.mac_addr, mac_addr); 795 else 796 eth_zero_addr(cmd->intf_info.mac_addr); 797 798 ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb, 799 sizeof(*resp), NULL); 800 if (ret) 801 goto out; 802 803 resp = (const struct qlink_resp_manage_intf *)resp_skb->data; 804 ether_addr_copy(vif->mac_addr, resp->intf_info.mac_addr); 805 806 out: 807 qtnf_bus_unlock(vif->mac->bus); 808 consume_skb(resp_skb); 809 810 return ret; 811 } 812 813 int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, enum nl80211_iftype iftype, 814 int use4addr, u8 *mac_addr) 815 { 816 return qtnf_cmd_send_add_change_intf(vif, iftype, use4addr, mac_addr, 817 QLINK_CMD_ADD_INTF); 818 } 819 820 int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif, 821 enum nl80211_iftype iftype, 822 int use4addr, 823 u8 *mac_addr) 824 { 825 int ret; 826 827 ret = qtnf_cmd_send_add_change_intf(vif, iftype, use4addr, mac_addr, 828 QLINK_CMD_CHANGE_INTF); 829 830 /* Regulatory settings may be different for different interface types */ 831 if (ret == 0 && vif->wdev.iftype != iftype) { 832 enum nl80211_band band; 833 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 834 835 for (band = 0; band < NUM_NL80211_BANDS; ++band) { 836 if (!wiphy->bands[band]) 837 continue; 838 839 qtnf_cmd_band_info_get(vif->mac, wiphy->bands[band]); 840 } 841 } 842 843 return ret; 844 } 845 846 int qtnf_cmd_send_del_intf(struct qtnf_vif *vif) 847 { 848 struct sk_buff *cmd_skb; 849 struct qlink_cmd_manage_intf *cmd; 850 int ret = 0; 851 852 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 853 QLINK_CMD_DEL_INTF, 854 sizeof(*cmd)); 855 if (!cmd_skb) 856 return -ENOMEM; 857 858 qtnf_bus_lock(vif->mac->bus); 859 860 cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data; 861 862 switch (vif->wdev.iftype) { 863 case NL80211_IFTYPE_AP: 864 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP); 865 break; 866 case NL80211_IFTYPE_STATION: 867 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 868 break; 869 default: 870 pr_warn("VIF%u.%u: unsupported iftype %d\n", vif->mac->macid, 871 vif->vifid, vif->wdev.iftype); 872 dev_kfree_skb(cmd_skb); 873 ret = -EINVAL; 874 goto out; 875 } 876 877 eth_zero_addr(cmd->intf_info.mac_addr); 878 879 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 880 if (ret) 881 goto out; 882 883 out: 884 qtnf_bus_unlock(vif->mac->bus); 885 return ret; 886 } 887 888 static int 889 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, 890 const struct qlink_resp_get_hw_info *resp, 891 size_t info_len) 892 { 893 struct qtnf_hw_info *hwinfo = &bus->hw_info; 894 const struct qlink_tlv_hdr *tlv; 895 const char *bld_name = NULL; 896 const char *bld_rev = NULL; 897 const char *bld_type = NULL; 898 const char *bld_label = NULL; 899 u32 bld_tmstamp = 0; 900 u32 plat_id = 0; 901 const char *hw_id = NULL; 902 const char *calibration_ver = NULL; 903 const char *uboot_ver = NULL; 904 u32 hw_ver = 0; 905 u16 tlv_type; 906 u16 tlv_len; 907 908 hwinfo->num_mac = resp->num_mac; 909 hwinfo->mac_bitmap = resp->mac_bitmap; 910 hwinfo->fw_ver = le32_to_cpu(resp->fw_ver); 911 hwinfo->total_tx_chain = resp->total_tx_chain; 912 hwinfo->total_rx_chain = resp->total_rx_chain; 913 914 bld_tmstamp = le32_to_cpu(resp->bld_tmstamp); 915 plat_id = le32_to_cpu(resp->plat_id); 916 hw_ver = le32_to_cpu(resp->hw_ver); 917 918 qlink_for_each_tlv(tlv, resp->info, info_len) { 919 tlv_type = le16_to_cpu(tlv->type); 920 tlv_len = le16_to_cpu(tlv->len); 921 922 switch (tlv_type) { 923 case QTN_TLV_ID_BUILD_NAME: 924 bld_name = (const void *)tlv->val; 925 break; 926 case QTN_TLV_ID_BUILD_REV: 927 bld_rev = (const void *)tlv->val; 928 break; 929 case QTN_TLV_ID_BUILD_TYPE: 930 bld_type = (const void *)tlv->val; 931 break; 932 case QTN_TLV_ID_BUILD_LABEL: 933 bld_label = (const void *)tlv->val; 934 break; 935 case QTN_TLV_ID_HW_ID: 936 hw_id = (const void *)tlv->val; 937 break; 938 case QTN_TLV_ID_CALIBRATION_VER: 939 calibration_ver = (const void *)tlv->val; 940 break; 941 case QTN_TLV_ID_UBOOT_VER: 942 uboot_ver = (const void *)tlv->val; 943 break; 944 case QTN_TLV_ID_BITMAP: 945 memcpy(hwinfo->hw_capab, tlv->val, 946 min(sizeof(hwinfo->hw_capab), (size_t)tlv_len)); 947 break; 948 default: 949 break; 950 } 951 } 952 953 if (!qlink_tlv_parsing_ok(tlv, resp->info, info_len)) { 954 pr_err("Malformed TLV buffer\n"); 955 return -EINVAL; 956 } 957 958 pr_info("\nBuild name: %s\n" 959 "Build revision: %s\n" 960 "Build type: %s\n" 961 "Build label: %s\n" 962 "Build timestamp: %lu\n" 963 "Platform ID: %lu\n" 964 "Hardware ID: %s\n" 965 "Calibration version: %s\n" 966 "U-Boot version: %s\n" 967 "Hardware version: 0x%08x\n" 968 "Qlink ver: %u.%u\n" 969 "MACs map: %#x\n" 970 "Chains Rx-Tx: %ux%u\n" 971 "FW version: 0x%x\n", 972 bld_name, bld_rev, bld_type, bld_label, 973 (unsigned long)bld_tmstamp, 974 (unsigned long)plat_id, 975 hw_id, calibration_ver, uboot_ver, hw_ver, 976 QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver), 977 QLINK_VER_MINOR(bus->hw_info.ql_proto_ver), 978 hwinfo->mac_bitmap, 979 hwinfo->total_rx_chain, hwinfo->total_tx_chain, 980 hwinfo->fw_ver); 981 982 strlcpy(hwinfo->fw_version, bld_label, sizeof(hwinfo->fw_version)); 983 hwinfo->hw_version = hw_ver; 984 985 return 0; 986 } 987 988 static void 989 qtnf_parse_wowlan_info(struct qtnf_wmac *mac, 990 const struct qlink_wowlan_capab_data *wowlan) 991 { 992 struct qtnf_mac_info *mac_info = &mac->macinfo; 993 const struct qlink_wowlan_support *data1; 994 struct wiphy_wowlan_support *supp; 995 996 supp = kzalloc(sizeof(*supp), GFP_KERNEL); 997 if (!supp) 998 return; 999 1000 switch (le16_to_cpu(wowlan->version)) { 1001 case 0x1: 1002 data1 = (struct qlink_wowlan_support *)wowlan->data; 1003 1004 supp->flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT; 1005 supp->n_patterns = le32_to_cpu(data1->n_patterns); 1006 supp->pattern_max_len = le32_to_cpu(data1->pattern_max_len); 1007 supp->pattern_min_len = le32_to_cpu(data1->pattern_min_len); 1008 1009 mac_info->wowlan = supp; 1010 break; 1011 default: 1012 pr_warn("MAC%u: unsupported WoWLAN version 0x%x\n", 1013 mac->macid, le16_to_cpu(wowlan->version)); 1014 kfree(supp); 1015 break; 1016 } 1017 } 1018 1019 static int 1020 qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, 1021 const struct qlink_resp_get_mac_info *resp, 1022 size_t tlv_buf_size) 1023 { 1024 struct ieee80211_iface_combination *comb = mac->macinfo.if_comb; 1025 size_t n_comb = 0; 1026 struct ieee80211_iface_limit *limits; 1027 const struct qlink_iface_limit_record *rec; 1028 const struct qlink_iface_limit *lim; 1029 const struct qlink_wowlan_capab_data *wowlan; 1030 u16 rec_len; 1031 u16 tlv_type; 1032 u16 tlv_value_len; 1033 const struct qlink_tlv_hdr *tlv; 1034 u8 *ext_capa = NULL; 1035 u8 *ext_capa_mask = NULL; 1036 u8 ext_capa_len = 0; 1037 u8 ext_capa_mask_len = 0; 1038 int i = 0; 1039 struct ieee80211_reg_rule *rule; 1040 unsigned int rule_idx = 0; 1041 const struct qlink_tlv_reg_rule *tlv_rule; 1042 1043 if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) 1044 return -E2BIG; 1045 1046 mac->rd = kzalloc(struct_size(mac->rd, reg_rules, resp->n_reg_rules), 1047 GFP_KERNEL); 1048 if (!mac->rd) 1049 return -ENOMEM; 1050 1051 mac->rd->n_reg_rules = resp->n_reg_rules; 1052 mac->rd->alpha2[0] = resp->alpha2[0]; 1053 mac->rd->alpha2[1] = resp->alpha2[1]; 1054 1055 switch (resp->dfs_region) { 1056 case QLINK_DFS_FCC: 1057 mac->rd->dfs_region = NL80211_DFS_FCC; 1058 break; 1059 case QLINK_DFS_ETSI: 1060 mac->rd->dfs_region = NL80211_DFS_ETSI; 1061 break; 1062 case QLINK_DFS_JP: 1063 mac->rd->dfs_region = NL80211_DFS_JP; 1064 break; 1065 case QLINK_DFS_UNSET: 1066 default: 1067 mac->rd->dfs_region = NL80211_DFS_UNSET; 1068 break; 1069 } 1070 1071 qlink_for_each_tlv(tlv, resp->var_info, tlv_buf_size) { 1072 tlv_type = le16_to_cpu(tlv->type); 1073 tlv_value_len = le16_to_cpu(tlv->len); 1074 1075 switch (tlv_type) { 1076 case QTN_TLV_ID_IFACE_LIMIT: 1077 if (unlikely(!comb)) { 1078 pr_warn("MAC%u: no combinations advertised\n", 1079 mac->macid); 1080 return -EINVAL; 1081 } 1082 1083 if (n_comb >= mac->macinfo.n_if_comb) { 1084 pr_warn("MAC%u: combinations count exceeded\n", 1085 mac->macid); 1086 n_comb++; 1087 break; 1088 } 1089 1090 rec = (void *)tlv->val; 1091 rec_len = sizeof(*rec) + rec->n_limits * sizeof(*lim); 1092 1093 if (unlikely(tlv_value_len != rec_len)) { 1094 pr_warn("MAC%u: record %zu size mismatch\n", 1095 mac->macid, n_comb); 1096 return -EINVAL; 1097 } 1098 1099 limits = kcalloc(rec->n_limits, sizeof(*limits), 1100 GFP_KERNEL); 1101 if (!limits) 1102 return -ENOMEM; 1103 1104 comb[n_comb].num_different_channels = 1105 rec->num_different_channels; 1106 comb[n_comb].max_interfaces = 1107 le16_to_cpu(rec->max_interfaces); 1108 comb[n_comb].n_limits = rec->n_limits; 1109 comb[n_comb].limits = limits; 1110 1111 for (i = 0; i < rec->n_limits; i++) { 1112 lim = &rec->limits[i]; 1113 limits[i].max = le16_to_cpu(lim->max_num); 1114 limits[i].types = 1115 qlink_iface_type_to_nl_mask(le16_to_cpu(lim->type)); 1116 pr_debug("MAC%u: comb[%zu]: MAX:%u TYPES:%.4X\n", 1117 mac->macid, n_comb, 1118 limits[i].max, limits[i].types); 1119 } 1120 1121 n_comb++; 1122 break; 1123 case WLAN_EID_EXT_CAPABILITY: 1124 if (unlikely(tlv_value_len > U8_MAX)) 1125 return -EINVAL; 1126 ext_capa = (u8 *)tlv->val; 1127 ext_capa_len = tlv_value_len; 1128 break; 1129 case QTN_TLV_ID_EXT_CAPABILITY_MASK: 1130 if (unlikely(tlv_value_len > U8_MAX)) 1131 return -EINVAL; 1132 ext_capa_mask = (u8 *)tlv->val; 1133 ext_capa_mask_len = tlv_value_len; 1134 break; 1135 case QTN_TLV_ID_WOWLAN_CAPAB: 1136 if (tlv_value_len < sizeof(*wowlan)) 1137 return -EINVAL; 1138 1139 wowlan = (void *)tlv->val; 1140 if (!le16_to_cpu(wowlan->len)) { 1141 pr_warn("MAC%u: skip empty WoWLAN data\n", 1142 mac->macid); 1143 break; 1144 } 1145 1146 rec_len = sizeof(*wowlan) + le16_to_cpu(wowlan->len); 1147 if (unlikely(tlv_value_len != rec_len)) { 1148 pr_warn("MAC%u: WoWLAN data size mismatch\n", 1149 mac->macid); 1150 return -EINVAL; 1151 } 1152 1153 kfree(mac->macinfo.wowlan); 1154 mac->macinfo.wowlan = NULL; 1155 qtnf_parse_wowlan_info(mac, wowlan); 1156 break; 1157 case QTN_TLV_ID_REG_RULE: 1158 if (rule_idx >= resp->n_reg_rules) { 1159 pr_warn("unexpected number of rules: %u\n", 1160 resp->n_reg_rules); 1161 return -EINVAL; 1162 } 1163 1164 if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) { 1165 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 1166 tlv_type, tlv_value_len); 1167 return -EINVAL; 1168 } 1169 1170 tlv_rule = (const struct qlink_tlv_reg_rule *)tlv; 1171 rule = &mac->rd->reg_rules[rule_idx++]; 1172 qlink_utils_regrule_q2nl(rule, tlv_rule); 1173 break; 1174 default: 1175 pr_warn("MAC%u: unknown TLV type %u\n", 1176 mac->macid, tlv_type); 1177 break; 1178 } 1179 } 1180 1181 if (!qlink_tlv_parsing_ok(tlv, resp->var_info, tlv_buf_size)) { 1182 pr_err("Malformed TLV buffer\n"); 1183 return -EINVAL; 1184 } 1185 1186 if (mac->macinfo.n_if_comb != n_comb) { 1187 pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n", 1188 mac->macid, mac->macinfo.n_if_comb, n_comb); 1189 return -EINVAL; 1190 } 1191 1192 if (ext_capa_len != ext_capa_mask_len) { 1193 pr_err("MAC%u: ext_capa/_mask lengths mismatch: %u != %u\n", 1194 mac->macid, ext_capa_len, ext_capa_mask_len); 1195 return -EINVAL; 1196 } 1197 1198 if (rule_idx != resp->n_reg_rules) { 1199 pr_warn("unexpected number of rules: expected %u got %u\n", 1200 resp->n_reg_rules, rule_idx); 1201 return -EINVAL; 1202 } 1203 1204 if (ext_capa_len > 0) { 1205 ext_capa = kmemdup(ext_capa, ext_capa_len, GFP_KERNEL); 1206 if (!ext_capa) 1207 return -ENOMEM; 1208 1209 ext_capa_mask = 1210 kmemdup(ext_capa_mask, ext_capa_mask_len, GFP_KERNEL); 1211 if (!ext_capa_mask) { 1212 kfree(ext_capa); 1213 return -ENOMEM; 1214 } 1215 } else { 1216 ext_capa = NULL; 1217 ext_capa_mask = NULL; 1218 } 1219 1220 qtnf_mac_ext_caps_free(mac); 1221 mac->macinfo.extended_capabilities = ext_capa; 1222 mac->macinfo.extended_capabilities_mask = ext_capa_mask; 1223 mac->macinfo.extended_capabilities_len = ext_capa_len; 1224 1225 return 0; 1226 } 1227 1228 static int 1229 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, 1230 const struct qlink_resp_get_mac_info *resp_info) 1231 { 1232 struct qtnf_mac_info *mac_info; 1233 struct qtnf_vif *vif; 1234 1235 qtnf_mac_iface_comb_free(mac); 1236 1237 mac_info = &mac->macinfo; 1238 1239 mac_info->bands_cap = resp_info->bands_cap; 1240 ether_addr_copy(mac->macaddr, resp_info->dev_mac); 1241 1242 vif = qtnf_mac_get_base_vif(mac); 1243 if (vif) 1244 ether_addr_copy(vif->mac_addr, mac->macaddr); 1245 else 1246 pr_err("could not get valid base vif\n"); 1247 1248 mac_info->num_tx_chain = resp_info->num_tx_chain; 1249 mac_info->num_rx_chain = resp_info->num_rx_chain; 1250 1251 mac_info->max_ap_assoc_sta = le16_to_cpu(resp_info->max_ap_assoc_sta); 1252 mac_info->radar_detect_widths = 1253 qlink_chan_width_mask_to_nl(le16_to_cpu( 1254 resp_info->radar_detect_widths)); 1255 mac_info->max_acl_mac_addrs = le16_to_cpu(resp_info->max_acl_mac_addrs); 1256 mac_info->frag_thr = le32_to_cpu(resp_info->frag_threshold); 1257 mac_info->rts_thr = le32_to_cpu(resp_info->rts_threshold); 1258 mac_info->sretry_limit = resp_info->retry_short; 1259 mac_info->lretry_limit = resp_info->retry_long; 1260 mac_info->coverage_class = resp_info->coverage_class; 1261 mac_info->max_scan_ssids = resp_info->max_scan_ssids; 1262 1263 memcpy(&mac_info->ht_cap_mod_mask, &resp_info->ht_cap_mod_mask, 1264 sizeof(mac_info->ht_cap_mod_mask)); 1265 memcpy(&mac_info->vht_cap_mod_mask, &resp_info->vht_cap_mod_mask, 1266 sizeof(mac_info->vht_cap_mod_mask)); 1267 1268 mac_info->n_if_comb = resp_info->n_iface_combinations; 1269 mac_info->if_comb = kcalloc(mac->macinfo.n_if_comb, 1270 sizeof(*mac->macinfo.if_comb), 1271 GFP_KERNEL); 1272 1273 if (!mac->macinfo.if_comb) 1274 return -ENOMEM; 1275 1276 return 0; 1277 } 1278 1279 static void qtnf_cmd_resp_band_fill_htcap(const u8 *info, 1280 struct ieee80211_sta_ht_cap *bcap) 1281 { 1282 const struct ieee80211_ht_cap *ht_cap = 1283 (const struct ieee80211_ht_cap *)info; 1284 1285 bcap->ht_supported = true; 1286 bcap->cap = le16_to_cpu(ht_cap->cap_info); 1287 bcap->ampdu_factor = 1288 ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR; 1289 bcap->ampdu_density = 1290 (ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 1291 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; 1292 memcpy(&bcap->mcs, &ht_cap->mcs, sizeof(bcap->mcs)); 1293 } 1294 1295 static void qtnf_cmd_resp_band_fill_vhtcap(const u8 *info, 1296 struct ieee80211_sta_vht_cap *bcap) 1297 { 1298 const struct ieee80211_vht_cap *vht_cap = 1299 (const struct ieee80211_vht_cap *)info; 1300 1301 bcap->vht_supported = true; 1302 bcap->cap = le32_to_cpu(vht_cap->vht_cap_info); 1303 memcpy(&bcap->vht_mcs, &vht_cap->supp_mcs, sizeof(bcap->vht_mcs)); 1304 } 1305 1306 static void qtnf_cmd_conv_iftype(struct ieee80211_sband_iftype_data 1307 *iftype_data, 1308 const struct qlink_sband_iftype_data 1309 *qlink_data) 1310 { 1311 iftype_data->types_mask = le16_to_cpu(qlink_data->types_mask); 1312 1313 iftype_data->he_cap.has_he = true; 1314 memcpy(&iftype_data->he_cap.he_cap_elem, &qlink_data->he_cap_elem, 1315 sizeof(qlink_data->he_cap_elem)); 1316 memcpy(iftype_data->he_cap.ppe_thres, qlink_data->ppe_thres, 1317 ARRAY_SIZE(qlink_data->ppe_thres)); 1318 1319 iftype_data->he_cap.he_mcs_nss_supp.rx_mcs_80 = 1320 qlink_data->he_mcs_nss_supp.rx_mcs_80; 1321 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 = 1322 qlink_data->he_mcs_nss_supp.tx_mcs_80; 1323 iftype_data->he_cap.he_mcs_nss_supp.rx_mcs_160 = 1324 qlink_data->he_mcs_nss_supp.rx_mcs_160; 1325 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 = 1326 qlink_data->he_mcs_nss_supp.tx_mcs_160; 1327 iftype_data->he_cap.he_mcs_nss_supp.rx_mcs_80p80 = 1328 qlink_data->he_mcs_nss_supp.rx_mcs_80p80; 1329 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 = 1330 qlink_data->he_mcs_nss_supp.tx_mcs_80p80; 1331 } 1332 1333 static int qtnf_cmd_band_fill_iftype(const u8 *data, 1334 struct ieee80211_supported_band *band) 1335 { 1336 unsigned int i; 1337 struct ieee80211_sband_iftype_data *iftype_data; 1338 const struct qlink_tlv_iftype_data *tlv = 1339 (const struct qlink_tlv_iftype_data *)data; 1340 size_t payload_len = tlv->n_iftype_data * sizeof(*tlv->iftype_data) + 1341 sizeof(*tlv) - 1342 sizeof(struct qlink_tlv_hdr); 1343 1344 if (tlv->hdr.len != cpu_to_le16(payload_len)) { 1345 pr_err("bad IFTYPE_DATA TLV len %u\n", tlv->hdr.len); 1346 return -EINVAL; 1347 } 1348 1349 kfree(band->iftype_data); 1350 band->iftype_data = NULL; 1351 band->n_iftype_data = tlv->n_iftype_data; 1352 if (band->n_iftype_data == 0) 1353 return 0; 1354 1355 iftype_data = kcalloc(band->n_iftype_data, sizeof(*iftype_data), 1356 GFP_KERNEL); 1357 if (!iftype_data) { 1358 band->n_iftype_data = 0; 1359 return -ENOMEM; 1360 } 1361 band->iftype_data = iftype_data; 1362 1363 for (i = 0; i < band->n_iftype_data; i++) 1364 qtnf_cmd_conv_iftype(iftype_data++, &tlv->iftype_data[i]); 1365 1366 return 0; 1367 } 1368 1369 static int 1370 qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band *band, 1371 struct qlink_resp_band_info_get *resp, 1372 size_t payload_len) 1373 { 1374 u16 tlv_type; 1375 size_t tlv_dlen; 1376 const struct qlink_tlv_hdr *tlv; 1377 const struct qlink_channel *qchan; 1378 struct ieee80211_channel *chan; 1379 unsigned int chidx = 0; 1380 u32 qflags; 1381 int ret = -EINVAL; 1382 1383 memset(&band->ht_cap, 0, sizeof(band->ht_cap)); 1384 memset(&band->vht_cap, 0, sizeof(band->vht_cap)); 1385 1386 if (band->channels) { 1387 if (band->n_channels == resp->num_chans) { 1388 memset(band->channels, 0, 1389 sizeof(*band->channels) * band->n_channels); 1390 } else { 1391 kfree(band->channels); 1392 band->n_channels = 0; 1393 band->channels = NULL; 1394 } 1395 } 1396 1397 band->n_channels = resp->num_chans; 1398 if (band->n_channels == 0) 1399 return 0; 1400 1401 if (!band->channels) 1402 band->channels = kcalloc(band->n_channels, sizeof(*chan), 1403 GFP_KERNEL); 1404 if (!band->channels) { 1405 band->n_channels = 0; 1406 return -ENOMEM; 1407 } 1408 1409 qlink_for_each_tlv(tlv, resp->info, payload_len) { 1410 tlv_type = le16_to_cpu(tlv->type); 1411 tlv_dlen = le16_to_cpu(tlv->len); 1412 1413 switch (tlv_type) { 1414 case QTN_TLV_ID_CHANNEL: 1415 if (unlikely(tlv_dlen != sizeof(*qchan))) { 1416 pr_err("invalid channel TLV len %zu\n", 1417 tlv_dlen); 1418 goto error_ret; 1419 } 1420 1421 if (chidx == band->n_channels) { 1422 pr_err("too many channel TLVs\n"); 1423 goto error_ret; 1424 } 1425 1426 qchan = (const struct qlink_channel *)tlv->val; 1427 chan = &band->channels[chidx++]; 1428 qflags = le32_to_cpu(qchan->flags); 1429 1430 chan->hw_value = le16_to_cpu(qchan->hw_value); 1431 chan->band = band->band; 1432 chan->center_freq = le16_to_cpu(qchan->center_freq); 1433 chan->max_antenna_gain = (int)qchan->max_antenna_gain; 1434 chan->max_power = (int)qchan->max_power; 1435 chan->max_reg_power = (int)qchan->max_reg_power; 1436 chan->beacon_found = qchan->beacon_found; 1437 chan->dfs_cac_ms = le32_to_cpu(qchan->dfs_cac_ms); 1438 chan->flags = 0; 1439 1440 if (qflags & QLINK_CHAN_DISABLED) 1441 chan->flags |= IEEE80211_CHAN_DISABLED; 1442 1443 if (qflags & QLINK_CHAN_NO_IR) 1444 chan->flags |= IEEE80211_CHAN_NO_IR; 1445 1446 if (qflags & QLINK_CHAN_NO_HT40PLUS) 1447 chan->flags |= IEEE80211_CHAN_NO_HT40PLUS; 1448 1449 if (qflags & QLINK_CHAN_NO_HT40MINUS) 1450 chan->flags |= IEEE80211_CHAN_NO_HT40MINUS; 1451 1452 if (qflags & QLINK_CHAN_NO_OFDM) 1453 chan->flags |= IEEE80211_CHAN_NO_OFDM; 1454 1455 if (qflags & QLINK_CHAN_NO_80MHZ) 1456 chan->flags |= IEEE80211_CHAN_NO_80MHZ; 1457 1458 if (qflags & QLINK_CHAN_NO_160MHZ) 1459 chan->flags |= IEEE80211_CHAN_NO_160MHZ; 1460 1461 if (qflags & QLINK_CHAN_INDOOR_ONLY) 1462 chan->flags |= IEEE80211_CHAN_INDOOR_ONLY; 1463 1464 if (qflags & QLINK_CHAN_IR_CONCURRENT) 1465 chan->flags |= IEEE80211_CHAN_IR_CONCURRENT; 1466 1467 if (qflags & QLINK_CHAN_NO_20MHZ) 1468 chan->flags |= IEEE80211_CHAN_NO_20MHZ; 1469 1470 if (qflags & QLINK_CHAN_NO_10MHZ) 1471 chan->flags |= IEEE80211_CHAN_NO_10MHZ; 1472 1473 if (qflags & QLINK_CHAN_RADAR) { 1474 chan->flags |= IEEE80211_CHAN_RADAR; 1475 chan->dfs_state_entered = jiffies; 1476 1477 if (qchan->dfs_state == QLINK_DFS_USABLE) 1478 chan->dfs_state = NL80211_DFS_USABLE; 1479 else if (qchan->dfs_state == 1480 QLINK_DFS_AVAILABLE) 1481 chan->dfs_state = NL80211_DFS_AVAILABLE; 1482 else 1483 chan->dfs_state = 1484 NL80211_DFS_UNAVAILABLE; 1485 } 1486 1487 pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n", 1488 chan->hw_value, chan->flags, chan->max_power, 1489 chan->max_reg_power); 1490 break; 1491 case WLAN_EID_HT_CAPABILITY: 1492 if (unlikely(tlv_dlen != 1493 sizeof(struct ieee80211_ht_cap))) { 1494 pr_err("bad HTCAP TLV len %zu\n", tlv_dlen); 1495 goto error_ret; 1496 } 1497 1498 qtnf_cmd_resp_band_fill_htcap(tlv->val, &band->ht_cap); 1499 break; 1500 case WLAN_EID_VHT_CAPABILITY: 1501 if (unlikely(tlv_dlen != 1502 sizeof(struct ieee80211_vht_cap))) { 1503 pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen); 1504 goto error_ret; 1505 } 1506 1507 qtnf_cmd_resp_band_fill_vhtcap(tlv->val, 1508 &band->vht_cap); 1509 break; 1510 case QTN_TLV_ID_IFTYPE_DATA: 1511 ret = qtnf_cmd_band_fill_iftype((const uint8_t *)tlv, 1512 band); 1513 if (ret) 1514 goto error_ret; 1515 break; 1516 default: 1517 pr_warn("unknown TLV type: %#x\n", tlv_type); 1518 break; 1519 } 1520 } 1521 1522 if (!qlink_tlv_parsing_ok(tlv, resp->info, payload_len)) { 1523 pr_err("Malformed TLV buffer\n"); 1524 goto error_ret; 1525 } 1526 1527 if (band->n_channels != chidx) { 1528 pr_err("channel count mismatch: reported=%d, parsed=%d\n", 1529 band->n_channels, chidx); 1530 goto error_ret; 1531 } 1532 1533 return 0; 1534 1535 error_ret: 1536 kfree(band->channels); 1537 band->channels = NULL; 1538 band->n_channels = 0; 1539 1540 return ret; 1541 } 1542 1543 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac) 1544 { 1545 struct sk_buff *cmd_skb, *resp_skb = NULL; 1546 const struct qlink_resp_get_mac_info *resp; 1547 size_t var_data_len = 0; 1548 int ret = 0; 1549 1550 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1551 QLINK_CMD_MAC_INFO, 1552 sizeof(struct qlink_cmd)); 1553 if (!cmd_skb) 1554 return -ENOMEM; 1555 1556 qtnf_bus_lock(mac->bus); 1557 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 1558 sizeof(*resp), &var_data_len); 1559 if (ret) 1560 goto out; 1561 1562 resp = (const struct qlink_resp_get_mac_info *)resp_skb->data; 1563 ret = qtnf_cmd_resp_proc_mac_info(mac, resp); 1564 if (ret) 1565 goto out; 1566 1567 ret = qtnf_parse_variable_mac_info(mac, resp, var_data_len); 1568 1569 out: 1570 qtnf_bus_unlock(mac->bus); 1571 consume_skb(resp_skb); 1572 1573 return ret; 1574 } 1575 1576 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus) 1577 { 1578 struct sk_buff *cmd_skb, *resp_skb = NULL; 1579 const struct qlink_resp_get_hw_info *resp; 1580 size_t info_len = 0; 1581 int ret = 0; 1582 1583 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1584 QLINK_CMD_GET_HW_INFO, 1585 sizeof(struct qlink_cmd)); 1586 if (!cmd_skb) 1587 return -ENOMEM; 1588 1589 qtnf_bus_lock(bus); 1590 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 1591 sizeof(*resp), &info_len); 1592 if (ret) 1593 goto out; 1594 1595 resp = (const struct qlink_resp_get_hw_info *)resp_skb->data; 1596 ret = qtnf_cmd_resp_proc_hw_info(bus, resp, info_len); 1597 1598 out: 1599 qtnf_bus_unlock(bus); 1600 consume_skb(resp_skb); 1601 1602 return ret; 1603 } 1604 1605 int qtnf_cmd_band_info_get(struct qtnf_wmac *mac, 1606 struct ieee80211_supported_band *band) 1607 { 1608 struct sk_buff *cmd_skb, *resp_skb = NULL; 1609 struct qlink_cmd_band_info_get *cmd; 1610 struct qlink_resp_band_info_get *resp; 1611 size_t info_len = 0; 1612 int ret = 0; 1613 u8 qband = qlink_utils_band_cfg2q(band->band); 1614 1615 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1616 QLINK_CMD_BAND_INFO_GET, 1617 sizeof(*cmd)); 1618 if (!cmd_skb) 1619 return -ENOMEM; 1620 1621 cmd = (struct qlink_cmd_band_info_get *)cmd_skb->data; 1622 cmd->band = qband; 1623 1624 qtnf_bus_lock(mac->bus); 1625 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 1626 sizeof(*resp), &info_len); 1627 if (ret) 1628 goto out; 1629 1630 resp = (struct qlink_resp_band_info_get *)resp_skb->data; 1631 if (resp->band != qband) { 1632 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, 1633 resp->band, qband); 1634 ret = -EINVAL; 1635 goto out; 1636 } 1637 1638 ret = qtnf_cmd_resp_fill_band_info(band, resp, info_len); 1639 1640 out: 1641 qtnf_bus_unlock(mac->bus); 1642 consume_skb(resp_skb); 1643 1644 return ret; 1645 } 1646 1647 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed) 1648 { 1649 struct wiphy *wiphy = priv_to_wiphy(mac); 1650 struct sk_buff *cmd_skb; 1651 int ret = 0; 1652 1653 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1654 QLINK_CMD_PHY_PARAMS_SET, 1655 sizeof(struct qlink_cmd)); 1656 if (!cmd_skb) 1657 return -ENOMEM; 1658 1659 qtnf_bus_lock(mac->bus); 1660 1661 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 1662 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_FRAG_THRESH, 1663 wiphy->frag_threshold); 1664 if (changed & WIPHY_PARAM_RTS_THRESHOLD) 1665 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_RTS_THRESH, 1666 wiphy->rts_threshold); 1667 if (changed & WIPHY_PARAM_COVERAGE_CLASS) 1668 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS, 1669 wiphy->coverage_class); 1670 1671 if (changed & WIPHY_PARAM_RETRY_LONG) 1672 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_LRETRY_LIMIT, 1673 wiphy->retry_long); 1674 1675 if (changed & WIPHY_PARAM_RETRY_SHORT) 1676 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_SRETRY_LIMIT, 1677 wiphy->retry_short); 1678 1679 ret = qtnf_cmd_send(mac->bus, cmd_skb); 1680 if (ret) 1681 goto out; 1682 1683 out: 1684 qtnf_bus_unlock(mac->bus); 1685 1686 return ret; 1687 } 1688 1689 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus) 1690 { 1691 struct sk_buff *resp_skb = NULL; 1692 struct qlink_resp_init_fw *resp; 1693 struct qlink_cmd_init_fw *cmd; 1694 struct sk_buff *cmd_skb; 1695 size_t info_len = 0; 1696 int ret; 1697 1698 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1699 QLINK_CMD_FW_INIT, 1700 sizeof(*cmd)); 1701 if (!cmd_skb) 1702 return -ENOMEM; 1703 1704 cmd = (struct qlink_cmd_init_fw *)cmd_skb->data; 1705 cmd->qlink_proto_ver = cpu_to_le32(QLINK_PROTO_VER); 1706 1707 qtnf_bus_lock(bus); 1708 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 1709 sizeof(*resp), &info_len); 1710 qtnf_bus_unlock(bus); 1711 1712 if (ret) 1713 goto out; 1714 1715 resp = (struct qlink_resp_init_fw *)resp_skb->data; 1716 bus->hw_info.ql_proto_ver = le32_to_cpu(resp->qlink_proto_ver); 1717 1718 out: 1719 consume_skb(resp_skb); 1720 return ret; 1721 } 1722 1723 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus) 1724 { 1725 struct sk_buff *cmd_skb; 1726 1727 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1728 QLINK_CMD_FW_DEINIT, 1729 sizeof(struct qlink_cmd)); 1730 if (!cmd_skb) 1731 return; 1732 1733 qtnf_bus_lock(bus); 1734 qtnf_cmd_send(bus, cmd_skb); 1735 qtnf_bus_unlock(bus); 1736 } 1737 1738 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1739 const u8 *mac_addr, struct key_params *params) 1740 { 1741 struct sk_buff *cmd_skb; 1742 struct qlink_cmd_add_key *cmd; 1743 int ret = 0; 1744 1745 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1746 QLINK_CMD_ADD_KEY, 1747 sizeof(*cmd)); 1748 if (!cmd_skb) 1749 return -ENOMEM; 1750 1751 qtnf_bus_lock(vif->mac->bus); 1752 1753 cmd = (struct qlink_cmd_add_key *)cmd_skb->data; 1754 1755 if (mac_addr) 1756 ether_addr_copy(cmd->addr, mac_addr); 1757 else 1758 eth_broadcast_addr(cmd->addr); 1759 1760 cmd->cipher = cpu_to_le32(params->cipher); 1761 cmd->key_index = key_index; 1762 cmd->pairwise = pairwise; 1763 1764 if (params->key && params->key_len > 0) 1765 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY, 1766 params->key, 1767 params->key_len); 1768 1769 if (params->seq && params->seq_len > 0) 1770 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ, 1771 params->seq, 1772 params->seq_len); 1773 1774 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1775 if (ret) 1776 goto out; 1777 1778 out: 1779 qtnf_bus_unlock(vif->mac->bus); 1780 1781 return ret; 1782 } 1783 1784 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1785 const u8 *mac_addr) 1786 { 1787 struct sk_buff *cmd_skb; 1788 struct qlink_cmd_del_key *cmd; 1789 int ret = 0; 1790 1791 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1792 QLINK_CMD_DEL_KEY, 1793 sizeof(*cmd)); 1794 if (!cmd_skb) 1795 return -ENOMEM; 1796 1797 qtnf_bus_lock(vif->mac->bus); 1798 1799 cmd = (struct qlink_cmd_del_key *)cmd_skb->data; 1800 1801 if (mac_addr) 1802 ether_addr_copy(cmd->addr, mac_addr); 1803 else 1804 eth_broadcast_addr(cmd->addr); 1805 1806 cmd->key_index = key_index; 1807 cmd->pairwise = pairwise; 1808 1809 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1810 if (ret) 1811 goto out; 1812 1813 out: 1814 qtnf_bus_unlock(vif->mac->bus); 1815 1816 return ret; 1817 } 1818 1819 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index, 1820 bool unicast, bool multicast) 1821 { 1822 struct sk_buff *cmd_skb; 1823 struct qlink_cmd_set_def_key *cmd; 1824 int ret = 0; 1825 1826 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1827 QLINK_CMD_SET_DEFAULT_KEY, 1828 sizeof(*cmd)); 1829 if (!cmd_skb) 1830 return -ENOMEM; 1831 1832 qtnf_bus_lock(vif->mac->bus); 1833 1834 cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data; 1835 cmd->key_index = key_index; 1836 cmd->unicast = unicast; 1837 cmd->multicast = multicast; 1838 1839 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1840 if (ret) 1841 goto out; 1842 1843 out: 1844 qtnf_bus_unlock(vif->mac->bus); 1845 1846 return ret; 1847 } 1848 1849 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index) 1850 { 1851 struct sk_buff *cmd_skb; 1852 struct qlink_cmd_set_def_mgmt_key *cmd; 1853 int ret = 0; 1854 1855 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1856 QLINK_CMD_SET_DEFAULT_MGMT_KEY, 1857 sizeof(*cmd)); 1858 if (!cmd_skb) 1859 return -ENOMEM; 1860 1861 qtnf_bus_lock(vif->mac->bus); 1862 1863 cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data; 1864 cmd->key_index = key_index; 1865 1866 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1867 if (ret) 1868 goto out; 1869 1870 out: 1871 qtnf_bus_unlock(vif->mac->bus); 1872 1873 return ret; 1874 } 1875 1876 static u32 qtnf_encode_sta_flags(u32 flags) 1877 { 1878 u32 code = 0; 1879 1880 if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED)) 1881 code |= QLINK_STA_FLAG_AUTHORIZED; 1882 if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 1883 code |= QLINK_STA_FLAG_SHORT_PREAMBLE; 1884 if (flags & BIT(NL80211_STA_FLAG_WME)) 1885 code |= QLINK_STA_FLAG_WME; 1886 if (flags & BIT(NL80211_STA_FLAG_MFP)) 1887 code |= QLINK_STA_FLAG_MFP; 1888 if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED)) 1889 code |= QLINK_STA_FLAG_AUTHENTICATED; 1890 if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER)) 1891 code |= QLINK_STA_FLAG_TDLS_PEER; 1892 if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED)) 1893 code |= QLINK_STA_FLAG_ASSOCIATED; 1894 return code; 1895 } 1896 1897 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac, 1898 struct station_parameters *params) 1899 { 1900 struct sk_buff *cmd_skb; 1901 struct qlink_cmd_change_sta *cmd; 1902 int ret = 0; 1903 1904 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1905 QLINK_CMD_CHANGE_STA, 1906 sizeof(*cmd)); 1907 if (!cmd_skb) 1908 return -ENOMEM; 1909 1910 qtnf_bus_lock(vif->mac->bus); 1911 1912 cmd = (struct qlink_cmd_change_sta *)cmd_skb->data; 1913 ether_addr_copy(cmd->sta_addr, mac); 1914 cmd->flag_update.mask = 1915 cpu_to_le32(qtnf_encode_sta_flags(params->sta_flags_mask)); 1916 cmd->flag_update.value = 1917 cpu_to_le32(qtnf_encode_sta_flags(params->sta_flags_set)); 1918 1919 switch (vif->wdev.iftype) { 1920 case NL80211_IFTYPE_AP: 1921 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_AP); 1922 break; 1923 case NL80211_IFTYPE_STATION: 1924 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 1925 break; 1926 default: 1927 pr_err("unsupported iftype %d\n", vif->wdev.iftype); 1928 dev_kfree_skb(cmd_skb); 1929 ret = -EINVAL; 1930 goto out; 1931 } 1932 1933 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1934 if (ret) 1935 goto out; 1936 1937 out: 1938 qtnf_bus_unlock(vif->mac->bus); 1939 1940 return ret; 1941 } 1942 1943 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif, 1944 struct station_del_parameters *params) 1945 { 1946 struct sk_buff *cmd_skb; 1947 struct qlink_cmd_del_sta *cmd; 1948 int ret = 0; 1949 1950 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1951 QLINK_CMD_DEL_STA, 1952 sizeof(*cmd)); 1953 if (!cmd_skb) 1954 return -ENOMEM; 1955 1956 qtnf_bus_lock(vif->mac->bus); 1957 1958 cmd = (struct qlink_cmd_del_sta *)cmd_skb->data; 1959 1960 if (params->mac) 1961 ether_addr_copy(cmd->sta_addr, params->mac); 1962 else 1963 eth_broadcast_addr(cmd->sta_addr); /* flush all stations */ 1964 1965 cmd->subtype = params->subtype; 1966 cmd->reason_code = cpu_to_le16(params->reason_code); 1967 1968 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1969 if (ret) 1970 goto out; 1971 1972 out: 1973 qtnf_bus_unlock(vif->mac->bus); 1974 1975 return ret; 1976 } 1977 1978 static void qtnf_cmd_channel_tlv_add(struct sk_buff *cmd_skb, 1979 const struct ieee80211_channel *sc) 1980 { 1981 struct qlink_tlv_channel *tlv; 1982 struct qlink_channel *qch; 1983 1984 tlv = skb_put_zero(cmd_skb, sizeof(*tlv)); 1985 qch = &tlv->chan; 1986 tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); 1987 tlv->hdr.len = cpu_to_le16(sizeof(*qch)); 1988 1989 qch->center_freq = cpu_to_le16(sc->center_freq); 1990 qch->hw_value = cpu_to_le16(sc->hw_value); 1991 qch->band = qlink_utils_band_cfg2q(sc->band); 1992 qch->max_power = sc->max_power; 1993 qch->max_reg_power = sc->max_reg_power; 1994 qch->max_antenna_gain = sc->max_antenna_gain; 1995 qch->beacon_found = sc->beacon_found; 1996 qch->dfs_state = qlink_utils_dfs_state_cfg2q(sc->dfs_state); 1997 qch->flags = cpu_to_le32(qlink_utils_chflags_cfg2q(sc->flags)); 1998 } 1999 2000 static void qtnf_cmd_randmac_tlv_add(struct sk_buff *cmd_skb, 2001 const u8 *mac_addr, 2002 const u8 *mac_addr_mask) 2003 { 2004 struct qlink_random_mac_addr *randmac; 2005 struct qlink_tlv_hdr *hdr = 2006 skb_put(cmd_skb, sizeof(*hdr) + sizeof(*randmac)); 2007 2008 hdr->type = cpu_to_le16(QTN_TLV_ID_RANDOM_MAC_ADDR); 2009 hdr->len = cpu_to_le16(sizeof(*randmac)); 2010 randmac = (struct qlink_random_mac_addr *)hdr->val; 2011 2012 memcpy(randmac->mac_addr, mac_addr, ETH_ALEN); 2013 memcpy(randmac->mac_addr_mask, mac_addr_mask, ETH_ALEN); 2014 } 2015 2016 int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 2017 { 2018 struct cfg80211_scan_request *scan_req = mac->scan_req; 2019 u16 dwell_passive = QTNF_SCAN_DWELL_PASSIVE_DEFAULT; 2020 u16 dwell_active = QTNF_SCAN_DWELL_ACTIVE_DEFAULT; 2021 struct wireless_dev *wdev = scan_req->wdev; 2022 struct ieee80211_channel *sc; 2023 struct qlink_cmd_scan *cmd; 2024 struct sk_buff *cmd_skb; 2025 int n_channels = 0; 2026 u64 flags = 0; 2027 int count; 2028 int ret; 2029 2030 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2031 QLINK_CMD_SCAN, 2032 sizeof(*cmd)); 2033 if (!cmd_skb) 2034 return -ENOMEM; 2035 2036 cmd = (struct qlink_cmd_scan *)cmd_skb->data; 2037 2038 if (scan_req->duration) { 2039 dwell_active = scan_req->duration; 2040 dwell_passive = scan_req->duration; 2041 } else if (wdev->iftype == NL80211_IFTYPE_STATION && 2042 wdev->current_bss) { 2043 /* let device select dwell based on traffic conditions */ 2044 dwell_active = QTNF_SCAN_TIME_AUTO; 2045 dwell_passive = QTNF_SCAN_TIME_AUTO; 2046 } 2047 2048 cmd->n_ssids = cpu_to_le16(scan_req->n_ssids); 2049 for (count = 0; count < scan_req->n_ssids; ++count) { 2050 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, 2051 scan_req->ssids[count].ssid, 2052 scan_req->ssids[count].ssid_len); 2053 } 2054 2055 if (scan_req->ie_len != 0) 2056 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ, 2057 scan_req->ie, scan_req->ie_len); 2058 2059 for (count = 0; count < scan_req->n_channels; ++count) { 2060 sc = scan_req->channels[count]; 2061 if (sc->flags & IEEE80211_CHAN_DISABLED) 2062 continue; 2063 2064 pr_debug("[MAC%u] scan chan=%d, freq=%d, flags=%#x\n", 2065 mac->macid, sc->hw_value, sc->center_freq, 2066 sc->flags); 2067 2068 qtnf_cmd_channel_tlv_add(cmd_skb, sc); 2069 ++n_channels; 2070 } 2071 2072 if (scan_req->flags & NL80211_SCAN_FLAG_FLUSH) 2073 flags |= QLINK_SCAN_FLAG_FLUSH; 2074 2075 if (scan_req->duration_mandatory) 2076 flags |= QLINK_SCAN_FLAG_DURATION_MANDATORY; 2077 2078 cmd->n_channels = cpu_to_le16(n_channels); 2079 cmd->active_dwell = cpu_to_le16(dwell_active); 2080 cmd->passive_dwell = cpu_to_le16(dwell_passive); 2081 cmd->sample_duration = cpu_to_le16(QTNF_SCAN_SAMPLE_DURATION_DEFAULT); 2082 cmd->flags = cpu_to_le64(flags); 2083 2084 pr_debug("[MAC%u] %s scan dwell active=%u passive=%u duration=%u\n", 2085 mac->macid, 2086 scan_req->duration_mandatory ? "mandatory" : "max", 2087 dwell_active, dwell_passive, 2088 QTNF_SCAN_SAMPLE_DURATION_DEFAULT); 2089 2090 if (scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 2091 pr_debug("[MAC%u] scan with random addr=%pM, mask=%pM\n", 2092 mac->macid, 2093 scan_req->mac_addr, scan_req->mac_addr_mask); 2094 qtnf_cmd_randmac_tlv_add(cmd_skb, scan_req->mac_addr, 2095 scan_req->mac_addr_mask); 2096 } 2097 2098 qtnf_bus_lock(mac->bus); 2099 ret = qtnf_cmd_send(mac->bus, cmd_skb); 2100 qtnf_bus_unlock(mac->bus); 2101 2102 return ret; 2103 } 2104 2105 int qtnf_cmd_send_connect(struct qtnf_vif *vif, 2106 struct cfg80211_connect_params *sme) 2107 { 2108 struct sk_buff *cmd_skb; 2109 struct qlink_cmd_connect *cmd; 2110 struct qlink_auth_encr *aen; 2111 int ret; 2112 int i; 2113 u32 connect_flags = 0; 2114 2115 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2116 QLINK_CMD_CONNECT, 2117 sizeof(*cmd)); 2118 if (!cmd_skb) 2119 return -ENOMEM; 2120 2121 cmd = (struct qlink_cmd_connect *)cmd_skb->data; 2122 2123 ether_addr_copy(cmd->bssid, vif->bssid); 2124 2125 if (sme->bssid_hint) 2126 ether_addr_copy(cmd->bssid_hint, sme->bssid_hint); 2127 else 2128 eth_zero_addr(cmd->bssid_hint); 2129 2130 if (sme->prev_bssid) 2131 ether_addr_copy(cmd->prev_bssid, sme->prev_bssid); 2132 else 2133 eth_zero_addr(cmd->prev_bssid); 2134 2135 if ((sme->bg_scan_period >= 0) && 2136 (sme->bg_scan_period <= SHRT_MAX)) 2137 cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period); 2138 else 2139 cmd->bg_scan_period = cpu_to_le16(-1); /* use default value */ 2140 2141 if (sme->flags & ASSOC_REQ_DISABLE_HT) 2142 connect_flags |= QLINK_STA_CONNECT_DISABLE_HT; 2143 if (sme->flags & ASSOC_REQ_DISABLE_VHT) 2144 connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT; 2145 if (sme->flags & ASSOC_REQ_USE_RRM) 2146 connect_flags |= QLINK_STA_CONNECT_USE_RRM; 2147 2148 cmd->flags = cpu_to_le32(connect_flags); 2149 memcpy(&cmd->ht_capa, &sme->ht_capa, sizeof(cmd->ht_capa)); 2150 memcpy(&cmd->ht_capa_mask, &sme->ht_capa_mask, 2151 sizeof(cmd->ht_capa_mask)); 2152 memcpy(&cmd->vht_capa, &sme->vht_capa, sizeof(cmd->vht_capa)); 2153 memcpy(&cmd->vht_capa_mask, &sme->vht_capa_mask, 2154 sizeof(cmd->vht_capa_mask)); 2155 cmd->pbss = sme->pbss; 2156 2157 aen = &cmd->aen; 2158 aen->auth_type = sme->auth_type; 2159 aen->privacy = !!sme->privacy; 2160 cmd->mfp = sme->mfp; 2161 aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions); 2162 aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group); 2163 aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise); 2164 2165 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 2166 aen->ciphers_pairwise[i] = 2167 cpu_to_le32(sme->crypto.ciphers_pairwise[i]); 2168 2169 aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites); 2170 2171 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 2172 aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]); 2173 2174 aen->control_port = sme->crypto.control_port; 2175 aen->control_port_no_encrypt = 2176 sme->crypto.control_port_no_encrypt; 2177 aen->control_port_ethertype = 2178 cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype)); 2179 2180 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid, 2181 sme->ssid_len); 2182 2183 if (sme->ie_len != 0) 2184 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ, 2185 sme->ie, sme->ie_len); 2186 2187 if (sme->channel) 2188 qtnf_cmd_channel_tlv_add(cmd_skb, sme->channel); 2189 2190 qtnf_bus_lock(vif->mac->bus); 2191 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2192 if (ret) 2193 goto out; 2194 2195 out: 2196 qtnf_bus_unlock(vif->mac->bus); 2197 2198 return ret; 2199 } 2200 2201 int qtnf_cmd_send_external_auth(struct qtnf_vif *vif, 2202 struct cfg80211_external_auth_params *auth) 2203 { 2204 struct sk_buff *cmd_skb; 2205 struct qlink_cmd_external_auth *cmd; 2206 int ret; 2207 2208 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2209 QLINK_CMD_EXTERNAL_AUTH, 2210 sizeof(*cmd)); 2211 if (!cmd_skb) 2212 return -ENOMEM; 2213 2214 cmd = (struct qlink_cmd_external_auth *)cmd_skb->data; 2215 2216 ether_addr_copy(cmd->peer, auth->bssid); 2217 cmd->status = cpu_to_le16(auth->status); 2218 2219 qtnf_bus_lock(vif->mac->bus); 2220 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2221 if (ret) 2222 goto out; 2223 2224 out: 2225 qtnf_bus_unlock(vif->mac->bus); 2226 2227 return ret; 2228 } 2229 2230 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code) 2231 { 2232 struct sk_buff *cmd_skb; 2233 struct qlink_cmd_disconnect *cmd; 2234 int ret; 2235 2236 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2237 QLINK_CMD_DISCONNECT, 2238 sizeof(*cmd)); 2239 if (!cmd_skb) 2240 return -ENOMEM; 2241 2242 qtnf_bus_lock(vif->mac->bus); 2243 2244 cmd = (struct qlink_cmd_disconnect *)cmd_skb->data; 2245 cmd->reason = cpu_to_le16(reason_code); 2246 2247 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2248 if (ret) 2249 goto out; 2250 2251 out: 2252 qtnf_bus_unlock(vif->mac->bus); 2253 2254 return ret; 2255 } 2256 2257 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up) 2258 { 2259 struct sk_buff *cmd_skb; 2260 struct qlink_cmd_updown *cmd; 2261 int ret; 2262 2263 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2264 QLINK_CMD_UPDOWN_INTF, 2265 sizeof(*cmd)); 2266 if (!cmd_skb) 2267 return -ENOMEM; 2268 2269 cmd = (struct qlink_cmd_updown *)cmd_skb->data; 2270 cmd->if_up = !!up; 2271 2272 qtnf_bus_lock(vif->mac->bus); 2273 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2274 if (ret) 2275 goto out; 2276 2277 out: 2278 qtnf_bus_unlock(vif->mac->bus); 2279 2280 return ret; 2281 } 2282 2283 int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req, 2284 bool slave_radar, bool dfs_offload) 2285 { 2286 struct wiphy *wiphy = priv_to_wiphy(mac); 2287 struct qtnf_bus *bus = mac->bus; 2288 struct sk_buff *cmd_skb; 2289 int ret; 2290 struct qlink_cmd_reg_notify *cmd; 2291 enum nl80211_band band; 2292 const struct ieee80211_supported_band *cfg_band; 2293 2294 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2295 QLINK_CMD_REG_NOTIFY, 2296 sizeof(*cmd)); 2297 if (!cmd_skb) 2298 return -ENOMEM; 2299 2300 cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data; 2301 cmd->alpha2[0] = req->alpha2[0]; 2302 cmd->alpha2[1] = req->alpha2[1]; 2303 2304 switch (req->initiator) { 2305 case NL80211_REGDOM_SET_BY_CORE: 2306 cmd->initiator = QLINK_REGDOM_SET_BY_CORE; 2307 break; 2308 case NL80211_REGDOM_SET_BY_USER: 2309 cmd->initiator = QLINK_REGDOM_SET_BY_USER; 2310 break; 2311 case NL80211_REGDOM_SET_BY_DRIVER: 2312 cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER; 2313 break; 2314 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2315 cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE; 2316 break; 2317 } 2318 2319 switch (req->user_reg_hint_type) { 2320 case NL80211_USER_REG_HINT_USER: 2321 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER; 2322 break; 2323 case NL80211_USER_REG_HINT_CELL_BASE: 2324 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE; 2325 break; 2326 case NL80211_USER_REG_HINT_INDOOR: 2327 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR; 2328 break; 2329 } 2330 2331 switch (req->dfs_region) { 2332 case NL80211_DFS_FCC: 2333 cmd->dfs_region = QLINK_DFS_FCC; 2334 break; 2335 case NL80211_DFS_ETSI: 2336 cmd->dfs_region = QLINK_DFS_ETSI; 2337 break; 2338 case NL80211_DFS_JP: 2339 cmd->dfs_region = QLINK_DFS_JP; 2340 break; 2341 default: 2342 cmd->dfs_region = QLINK_DFS_UNSET; 2343 break; 2344 } 2345 2346 cmd->slave_radar = slave_radar; 2347 cmd->dfs_offload = dfs_offload; 2348 cmd->num_channels = 0; 2349 2350 for (band = 0; band < NUM_NL80211_BANDS; band++) { 2351 unsigned int i; 2352 2353 cfg_band = wiphy->bands[band]; 2354 if (!cfg_band) 2355 continue; 2356 2357 cmd->num_channels += cfg_band->n_channels; 2358 2359 for (i = 0; i < cfg_band->n_channels; ++i) { 2360 qtnf_cmd_channel_tlv_add(cmd_skb, 2361 &cfg_band->channels[i]); 2362 } 2363 } 2364 2365 qtnf_bus_lock(bus); 2366 ret = qtnf_cmd_send(bus, cmd_skb); 2367 qtnf_bus_unlock(bus); 2368 2369 return ret; 2370 } 2371 2372 static int 2373 qtnf_cmd_resp_proc_chan_stat_info(struct survey_info *survey, 2374 const u8 *payload, size_t payload_len) 2375 { 2376 const struct qlink_chan_stats *stats = NULL; 2377 const struct qlink_tlv_hdr *tlv; 2378 u16 tlv_value_len; 2379 u16 tlv_type; 2380 const u8 *map = NULL; 2381 unsigned int map_len = 0; 2382 unsigned int stats_len = 0; 2383 2384 qlink_for_each_tlv(tlv, payload, payload_len) { 2385 tlv_type = le16_to_cpu(tlv->type); 2386 tlv_value_len = le16_to_cpu(tlv->len); 2387 2388 switch (tlv_type) { 2389 case QTN_TLV_ID_BITMAP: 2390 map = tlv->val; 2391 map_len = tlv_value_len; 2392 break; 2393 case QTN_TLV_ID_CHANNEL_STATS: 2394 stats = (struct qlink_chan_stats *)tlv->val; 2395 stats_len = tlv_value_len; 2396 break; 2397 default: 2398 pr_info("Unknown TLV type: %#x\n", tlv_type); 2399 break; 2400 } 2401 } 2402 2403 if (!qlink_tlv_parsing_ok(tlv, payload, payload_len)) { 2404 pr_err("Malformed TLV buffer\n"); 2405 return -EINVAL; 2406 } 2407 2408 if (!map || !stats) 2409 return 0; 2410 2411 #define qtnf_chan_stat_avail(stat_name, bitn) \ 2412 (qtnf_utils_is_bit_set(map, bitn, map_len) && \ 2413 (offsetofend(struct qlink_chan_stats, stat_name) <= stats_len)) 2414 2415 if (qtnf_chan_stat_avail(time_on, QLINK_CHAN_STAT_TIME_ON)) { 2416 survey->filled |= SURVEY_INFO_TIME; 2417 survey->time = le64_to_cpu(stats->time_on); 2418 } 2419 2420 if (qtnf_chan_stat_avail(time_tx, QLINK_CHAN_STAT_TIME_TX)) { 2421 survey->filled |= SURVEY_INFO_TIME_TX; 2422 survey->time_tx = le64_to_cpu(stats->time_tx); 2423 } 2424 2425 if (qtnf_chan_stat_avail(time_rx, QLINK_CHAN_STAT_TIME_RX)) { 2426 survey->filled |= SURVEY_INFO_TIME_RX; 2427 survey->time_rx = le64_to_cpu(stats->time_rx); 2428 } 2429 2430 if (qtnf_chan_stat_avail(cca_busy, QLINK_CHAN_STAT_CCA_BUSY)) { 2431 survey->filled |= SURVEY_INFO_TIME_BUSY; 2432 survey->time_busy = le64_to_cpu(stats->cca_busy); 2433 } 2434 2435 if (qtnf_chan_stat_avail(cca_busy_ext, QLINK_CHAN_STAT_CCA_BUSY_EXT)) { 2436 survey->filled |= SURVEY_INFO_TIME_EXT_BUSY; 2437 survey->time_ext_busy = le64_to_cpu(stats->cca_busy_ext); 2438 } 2439 2440 if (qtnf_chan_stat_avail(time_scan, QLINK_CHAN_STAT_TIME_SCAN)) { 2441 survey->filled |= SURVEY_INFO_TIME_SCAN; 2442 survey->time_scan = le64_to_cpu(stats->time_scan); 2443 } 2444 2445 if (qtnf_chan_stat_avail(chan_noise, QLINK_CHAN_STAT_CHAN_NOISE)) { 2446 survey->filled |= SURVEY_INFO_NOISE_DBM; 2447 survey->noise = stats->chan_noise; 2448 } 2449 2450 #undef qtnf_chan_stat_avail 2451 2452 return 0; 2453 } 2454 2455 int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u32 chan_freq, 2456 struct survey_info *survey) 2457 { 2458 struct sk_buff *cmd_skb, *resp_skb = NULL; 2459 struct qlink_cmd_get_chan_stats *cmd; 2460 struct qlink_resp_get_chan_stats *resp; 2461 size_t var_data_len = 0; 2462 int ret = 0; 2463 2464 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2465 QLINK_CMD_CHAN_STATS, 2466 sizeof(*cmd)); 2467 if (!cmd_skb) 2468 return -ENOMEM; 2469 2470 cmd = (struct qlink_cmd_get_chan_stats *)cmd_skb->data; 2471 cmd->channel_freq = cpu_to_le32(chan_freq); 2472 2473 qtnf_bus_lock(mac->bus); 2474 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 2475 sizeof(*resp), &var_data_len); 2476 qtnf_bus_unlock(mac->bus); 2477 2478 if (ret) 2479 goto out; 2480 2481 resp = (struct qlink_resp_get_chan_stats *)resp_skb->data; 2482 2483 if (le32_to_cpu(resp->chan_freq) != chan_freq) { 2484 pr_err("[MAC%u] channel stats freq %u != requested %u\n", 2485 mac->macid, le32_to_cpu(resp->chan_freq), chan_freq); 2486 ret = -EINVAL; 2487 goto out; 2488 } 2489 2490 ret = qtnf_cmd_resp_proc_chan_stat_info(survey, resp->info, 2491 var_data_len); 2492 2493 out: 2494 consume_skb(resp_skb); 2495 2496 return ret; 2497 } 2498 2499 int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif, 2500 struct cfg80211_csa_settings *params) 2501 { 2502 struct qtnf_wmac *mac = vif->mac; 2503 struct qlink_cmd_chan_switch *cmd; 2504 struct sk_buff *cmd_skb; 2505 int ret; 2506 u64 flags = 0; 2507 2508 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid, 2509 QLINK_CMD_CHAN_SWITCH, 2510 sizeof(*cmd)); 2511 if (!cmd_skb) 2512 return -ENOMEM; 2513 2514 if (params->radar_required) 2515 flags |= QLINK_CHAN_SW_RADAR_REQUIRED; 2516 2517 if (params->block_tx) 2518 flags |= QLINK_CHAN_SW_BLOCK_TX; 2519 2520 cmd = (struct qlink_cmd_chan_switch *)cmd_skb->data; 2521 qlink_chandef_cfg2q(¶ms->chandef, &cmd->channel); 2522 cmd->flags = cpu_to_le64(flags); 2523 cmd->beacon_count = params->count; 2524 2525 qtnf_bus_lock(mac->bus); 2526 ret = qtnf_cmd_send(mac->bus, cmd_skb); 2527 qtnf_bus_unlock(mac->bus); 2528 2529 return ret; 2530 } 2531 2532 int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef) 2533 { 2534 struct qtnf_bus *bus = vif->mac->bus; 2535 const struct qlink_resp_channel_get *resp; 2536 struct sk_buff *cmd_skb; 2537 struct sk_buff *resp_skb = NULL; 2538 int ret; 2539 2540 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2541 QLINK_CMD_CHAN_GET, 2542 sizeof(struct qlink_cmd)); 2543 if (!cmd_skb) 2544 return -ENOMEM; 2545 2546 qtnf_bus_lock(bus); 2547 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2548 sizeof(*resp), NULL); 2549 if (ret) 2550 goto out; 2551 2552 resp = (const struct qlink_resp_channel_get *)resp_skb->data; 2553 qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef); 2554 2555 out: 2556 qtnf_bus_unlock(bus); 2557 consume_skb(resp_skb); 2558 2559 return ret; 2560 } 2561 2562 int qtnf_cmd_start_cac(const struct qtnf_vif *vif, 2563 const struct cfg80211_chan_def *chdef, 2564 u32 cac_time_ms) 2565 { 2566 struct qtnf_bus *bus = vif->mac->bus; 2567 struct sk_buff *cmd_skb; 2568 struct qlink_cmd_start_cac *cmd; 2569 int ret; 2570 2571 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2572 QLINK_CMD_START_CAC, 2573 sizeof(*cmd)); 2574 if (!cmd_skb) 2575 return -ENOMEM; 2576 2577 cmd = (struct qlink_cmd_start_cac *)cmd_skb->data; 2578 cmd->cac_time_ms = cpu_to_le32(cac_time_ms); 2579 qlink_chandef_cfg2q(chdef, &cmd->chan); 2580 2581 qtnf_bus_lock(bus); 2582 ret = qtnf_cmd_send(bus, cmd_skb); 2583 if (ret) 2584 goto out; 2585 2586 out: 2587 qtnf_bus_unlock(bus); 2588 2589 return ret; 2590 } 2591 2592 int qtnf_cmd_set_mac_acl(const struct qtnf_vif *vif, 2593 const struct cfg80211_acl_data *params) 2594 { 2595 struct qtnf_bus *bus = vif->mac->bus; 2596 struct sk_buff *cmd_skb; 2597 struct qlink_tlv_hdr *tlv; 2598 size_t acl_size = struct_size(params, mac_addrs, params->n_acl_entries); 2599 int ret; 2600 2601 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2602 QLINK_CMD_SET_MAC_ACL, 2603 sizeof(struct qlink_cmd)); 2604 if (!cmd_skb) 2605 return -ENOMEM; 2606 2607 tlv = skb_put(cmd_skb, sizeof(*tlv) + round_up(acl_size, QLINK_ALIGN)); 2608 tlv->type = cpu_to_le16(QTN_TLV_ID_ACL_DATA); 2609 tlv->len = cpu_to_le16(acl_size); 2610 qlink_acl_data_cfg2q(params, (struct qlink_acl_data *)tlv->val); 2611 2612 qtnf_bus_lock(bus); 2613 ret = qtnf_cmd_send(bus, cmd_skb); 2614 if (ret) 2615 goto out; 2616 2617 out: 2618 qtnf_bus_unlock(bus); 2619 2620 return ret; 2621 } 2622 2623 int qtnf_cmd_send_pm_set(const struct qtnf_vif *vif, u8 pm_mode, int timeout) 2624 { 2625 struct qtnf_bus *bus = vif->mac->bus; 2626 struct sk_buff *cmd_skb; 2627 struct qlink_cmd_pm_set *cmd; 2628 int ret = 0; 2629 2630 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2631 QLINK_CMD_PM_SET, sizeof(*cmd)); 2632 if (!cmd_skb) 2633 return -ENOMEM; 2634 2635 cmd = (struct qlink_cmd_pm_set *)cmd_skb->data; 2636 cmd->pm_mode = pm_mode; 2637 cmd->pm_standby_timer = cpu_to_le32(timeout); 2638 2639 qtnf_bus_lock(bus); 2640 2641 ret = qtnf_cmd_send(bus, cmd_skb); 2642 if (ret) 2643 goto out; 2644 2645 out: 2646 qtnf_bus_unlock(bus); 2647 2648 return ret; 2649 } 2650 2651 int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm) 2652 { 2653 struct qtnf_bus *bus = vif->mac->bus; 2654 const struct qlink_resp_txpwr *resp; 2655 struct sk_buff *resp_skb = NULL; 2656 struct qlink_cmd_txpwr *cmd; 2657 struct sk_buff *cmd_skb; 2658 int ret = 0; 2659 2660 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2661 QLINK_CMD_TXPWR, sizeof(*cmd)); 2662 if (!cmd_skb) 2663 return -ENOMEM; 2664 2665 cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; 2666 cmd->op_type = QLINK_TXPWR_GET; 2667 2668 qtnf_bus_lock(bus); 2669 2670 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2671 sizeof(*resp), NULL); 2672 if (ret) 2673 goto out; 2674 2675 resp = (const struct qlink_resp_txpwr *)resp_skb->data; 2676 *dbm = MBM_TO_DBM(le32_to_cpu(resp->txpwr)); 2677 2678 out: 2679 qtnf_bus_unlock(bus); 2680 consume_skb(resp_skb); 2681 2682 return ret; 2683 } 2684 2685 int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif, 2686 enum nl80211_tx_power_setting type, int mbm) 2687 { 2688 struct qtnf_bus *bus = vif->mac->bus; 2689 const struct qlink_resp_txpwr *resp; 2690 struct sk_buff *resp_skb = NULL; 2691 struct qlink_cmd_txpwr *cmd; 2692 struct sk_buff *cmd_skb; 2693 int ret = 0; 2694 2695 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2696 QLINK_CMD_TXPWR, sizeof(*cmd)); 2697 if (!cmd_skb) 2698 return -ENOMEM; 2699 2700 cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; 2701 cmd->op_type = QLINK_TXPWR_SET; 2702 cmd->txpwr_setting = type; 2703 cmd->txpwr = cpu_to_le32(mbm); 2704 2705 qtnf_bus_lock(bus); 2706 2707 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2708 sizeof(*resp), NULL); 2709 2710 qtnf_bus_unlock(bus); 2711 consume_skb(resp_skb); 2712 2713 return ret; 2714 } 2715 2716 int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif, 2717 const struct cfg80211_wowlan *wowl) 2718 { 2719 struct qtnf_bus *bus = vif->mac->bus; 2720 struct sk_buff *cmd_skb; 2721 struct qlink_cmd_wowlan_set *cmd; 2722 u32 triggers = 0; 2723 int count = 0; 2724 int ret = 0; 2725 2726 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2727 QLINK_CMD_WOWLAN_SET, sizeof(*cmd)); 2728 if (!cmd_skb) 2729 return -ENOMEM; 2730 2731 qtnf_bus_lock(bus); 2732 2733 cmd = (struct qlink_cmd_wowlan_set *)cmd_skb->data; 2734 2735 if (wowl) { 2736 if (wowl->disconnect) 2737 triggers |= QLINK_WOWLAN_TRIG_DISCONNECT; 2738 2739 if (wowl->magic_pkt) 2740 triggers |= QLINK_WOWLAN_TRIG_MAGIC_PKT; 2741 2742 if (wowl->n_patterns && wowl->patterns) { 2743 triggers |= QLINK_WOWLAN_TRIG_PATTERN_PKT; 2744 while (count < wowl->n_patterns) { 2745 qtnf_cmd_skb_put_tlv_arr(cmd_skb, 2746 QTN_TLV_ID_WOWLAN_PATTERN, 2747 wowl->patterns[count].pattern, 2748 wowl->patterns[count].pattern_len); 2749 count++; 2750 } 2751 } 2752 } 2753 2754 cmd->triggers = cpu_to_le32(triggers); 2755 2756 ret = qtnf_cmd_send(bus, cmd_skb); 2757 if (ret) 2758 goto out; 2759 2760 out: 2761 qtnf_bus_unlock(bus); 2762 return ret; 2763 } 2764 2765 int qtnf_cmd_netdev_changeupper(const struct qtnf_vif *vif, int br_domain) 2766 { 2767 struct qtnf_bus *bus = vif->mac->bus; 2768 struct sk_buff *cmd_skb; 2769 struct qlink_cmd_ndev_changeupper *cmd; 2770 int ret; 2771 2772 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2773 QLINK_CMD_NDEV_EVENT, 2774 sizeof(*cmd)); 2775 if (!cmd_skb) 2776 return -ENOMEM; 2777 2778 pr_debug("[VIF%u.%u] set broadcast domain to %d\n", 2779 vif->mac->macid, vif->vifid, br_domain); 2780 2781 cmd = (struct qlink_cmd_ndev_changeupper *)cmd_skb->data; 2782 cmd->nehdr.event = cpu_to_le16(QLINK_NDEV_EVENT_CHANGEUPPER); 2783 cmd->upper_type = QLINK_NDEV_UPPER_TYPE_BRIDGE; 2784 cmd->br_domain = cpu_to_le32(br_domain); 2785 2786 qtnf_bus_lock(bus); 2787 ret = qtnf_cmd_send(bus, cmd_skb); 2788 qtnf_bus_unlock(bus); 2789 2790 if (ret) 2791 pr_err("[VIF%u.%u] failed to set broadcast domain\n", 2792 vif->mac->macid, vif->vifid); 2793 2794 return ret; 2795 } 2796 2797 int qtnf_cmd_send_update_owe(struct qtnf_vif *vif, 2798 struct cfg80211_update_owe_info *owe) 2799 { 2800 struct qlink_cmd_update_owe *cmd; 2801 struct sk_buff *cmd_skb; 2802 int ret; 2803 2804 if (sizeof(*cmd) + owe->ie_len > QTNF_MAX_CMD_BUF_SIZE) { 2805 pr_warn("VIF%u.%u: OWE update IEs too big: %zu\n", 2806 vif->mac->macid, vif->vifid, owe->ie_len); 2807 return -E2BIG; 2808 } 2809 2810 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2811 QLINK_CMD_UPDATE_OWE, 2812 sizeof(*cmd)); 2813 if (!cmd_skb) 2814 return -ENOMEM; 2815 2816 cmd = (struct qlink_cmd_update_owe *)cmd_skb->data; 2817 ether_addr_copy(cmd->peer, owe->peer); 2818 cmd->status = cpu_to_le16(owe->status); 2819 if (owe->ie_len && owe->ie) 2820 qtnf_cmd_skb_put_buffer(cmd_skb, owe->ie, owe->ie_len); 2821 2822 qtnf_bus_lock(vif->mac->bus); 2823 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2824 if (ret) 2825 goto out; 2826 2827 out: 2828 qtnf_bus_unlock(vif->mac->bus); 2829 2830 return ret; 2831 } 2832