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 ret = -EINVAL; 873 goto out; 874 } 875 876 eth_zero_addr(cmd->intf_info.mac_addr); 877 878 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 879 if (ret) 880 goto out; 881 882 out: 883 qtnf_bus_unlock(vif->mac->bus); 884 return ret; 885 } 886 887 static int 888 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, 889 const struct qlink_resp_get_hw_info *resp, 890 size_t info_len) 891 { 892 struct qtnf_hw_info *hwinfo = &bus->hw_info; 893 const struct qlink_tlv_hdr *tlv; 894 const char *bld_name = NULL; 895 const char *bld_rev = NULL; 896 const char *bld_type = NULL; 897 const char *bld_label = NULL; 898 u32 bld_tmstamp = 0; 899 u32 plat_id = 0; 900 const char *hw_id = NULL; 901 const char *calibration_ver = NULL; 902 const char *uboot_ver = NULL; 903 u32 hw_ver = 0; 904 u16 tlv_type; 905 u16 tlv_len; 906 907 hwinfo->num_mac = resp->num_mac; 908 hwinfo->mac_bitmap = resp->mac_bitmap; 909 hwinfo->fw_ver = le32_to_cpu(resp->fw_ver); 910 hwinfo->total_tx_chain = resp->total_tx_chain; 911 hwinfo->total_rx_chain = resp->total_rx_chain; 912 913 bld_tmstamp = le32_to_cpu(resp->bld_tmstamp); 914 plat_id = le32_to_cpu(resp->plat_id); 915 hw_ver = le32_to_cpu(resp->hw_ver); 916 917 qlink_for_each_tlv(tlv, resp->info, info_len) { 918 tlv_type = le16_to_cpu(tlv->type); 919 tlv_len = le16_to_cpu(tlv->len); 920 921 switch (tlv_type) { 922 case QTN_TLV_ID_BUILD_NAME: 923 bld_name = (const void *)tlv->val; 924 break; 925 case QTN_TLV_ID_BUILD_REV: 926 bld_rev = (const void *)tlv->val; 927 break; 928 case QTN_TLV_ID_BUILD_TYPE: 929 bld_type = (const void *)tlv->val; 930 break; 931 case QTN_TLV_ID_BUILD_LABEL: 932 bld_label = (const void *)tlv->val; 933 break; 934 case QTN_TLV_ID_HW_ID: 935 hw_id = (const void *)tlv->val; 936 break; 937 case QTN_TLV_ID_CALIBRATION_VER: 938 calibration_ver = (const void *)tlv->val; 939 break; 940 case QTN_TLV_ID_UBOOT_VER: 941 uboot_ver = (const void *)tlv->val; 942 break; 943 case QTN_TLV_ID_BITMAP: 944 memcpy(hwinfo->hw_capab, tlv->val, 945 min(sizeof(hwinfo->hw_capab), (size_t)tlv_len)); 946 break; 947 default: 948 break; 949 } 950 } 951 952 if (!qlink_tlv_parsing_ok(tlv, resp->info, info_len)) { 953 pr_err("Malformed TLV buffer\n"); 954 return -EINVAL; 955 } 956 957 pr_info("\nBuild name: %s\n" 958 "Build revision: %s\n" 959 "Build type: %s\n" 960 "Build label: %s\n" 961 "Build timestamp: %lu\n" 962 "Platform ID: %lu\n" 963 "Hardware ID: %s\n" 964 "Calibration version: %s\n" 965 "U-Boot version: %s\n" 966 "Hardware version: 0x%08x\n" 967 "Qlink ver: %u.%u\n" 968 "MACs map: %#x\n" 969 "Chains Rx-Tx: %ux%u\n" 970 "FW version: 0x%x\n", 971 bld_name, bld_rev, bld_type, bld_label, 972 (unsigned long)bld_tmstamp, 973 (unsigned long)plat_id, 974 hw_id, calibration_ver, uboot_ver, hw_ver, 975 QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver), 976 QLINK_VER_MINOR(bus->hw_info.ql_proto_ver), 977 hwinfo->mac_bitmap, 978 hwinfo->total_rx_chain, hwinfo->total_tx_chain, 979 hwinfo->fw_ver); 980 981 strlcpy(hwinfo->fw_version, bld_label, sizeof(hwinfo->fw_version)); 982 hwinfo->hw_version = hw_ver; 983 984 return 0; 985 } 986 987 static void 988 qtnf_parse_wowlan_info(struct qtnf_wmac *mac, 989 const struct qlink_wowlan_capab_data *wowlan) 990 { 991 struct qtnf_mac_info *mac_info = &mac->macinfo; 992 const struct qlink_wowlan_support *data1; 993 struct wiphy_wowlan_support *supp; 994 995 supp = kzalloc(sizeof(*supp), GFP_KERNEL); 996 if (!supp) 997 return; 998 999 switch (le16_to_cpu(wowlan->version)) { 1000 case 0x1: 1001 data1 = (struct qlink_wowlan_support *)wowlan->data; 1002 1003 supp->flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT; 1004 supp->n_patterns = le32_to_cpu(data1->n_patterns); 1005 supp->pattern_max_len = le32_to_cpu(data1->pattern_max_len); 1006 supp->pattern_min_len = le32_to_cpu(data1->pattern_min_len); 1007 1008 mac_info->wowlan = supp; 1009 break; 1010 default: 1011 pr_warn("MAC%u: unsupported WoWLAN version 0x%x\n", 1012 mac->macid, le16_to_cpu(wowlan->version)); 1013 kfree(supp); 1014 break; 1015 } 1016 } 1017 1018 static int 1019 qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, 1020 const struct qlink_resp_get_mac_info *resp, 1021 size_t tlv_buf_size) 1022 { 1023 struct ieee80211_iface_combination *comb = mac->macinfo.if_comb; 1024 size_t n_comb = 0; 1025 struct ieee80211_iface_limit *limits; 1026 const struct qlink_iface_limit_record *rec; 1027 const struct qlink_iface_limit *lim; 1028 const struct qlink_wowlan_capab_data *wowlan; 1029 u16 rec_len; 1030 u16 tlv_type; 1031 u16 tlv_value_len; 1032 const struct qlink_tlv_hdr *tlv; 1033 u8 *ext_capa = NULL; 1034 u8 *ext_capa_mask = NULL; 1035 u8 ext_capa_len = 0; 1036 u8 ext_capa_mask_len = 0; 1037 int i = 0; 1038 struct ieee80211_reg_rule *rule; 1039 unsigned int rule_idx = 0; 1040 const struct qlink_tlv_reg_rule *tlv_rule; 1041 1042 if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) 1043 return -E2BIG; 1044 1045 mac->rd = kzalloc(struct_size(mac->rd, reg_rules, resp->n_reg_rules), 1046 GFP_KERNEL); 1047 if (!mac->rd) 1048 return -ENOMEM; 1049 1050 mac->rd->n_reg_rules = resp->n_reg_rules; 1051 mac->rd->alpha2[0] = resp->alpha2[0]; 1052 mac->rd->alpha2[1] = resp->alpha2[1]; 1053 1054 switch (resp->dfs_region) { 1055 case QLINK_DFS_FCC: 1056 mac->rd->dfs_region = NL80211_DFS_FCC; 1057 break; 1058 case QLINK_DFS_ETSI: 1059 mac->rd->dfs_region = NL80211_DFS_ETSI; 1060 break; 1061 case QLINK_DFS_JP: 1062 mac->rd->dfs_region = NL80211_DFS_JP; 1063 break; 1064 case QLINK_DFS_UNSET: 1065 default: 1066 mac->rd->dfs_region = NL80211_DFS_UNSET; 1067 break; 1068 } 1069 1070 qlink_for_each_tlv(tlv, resp->var_info, tlv_buf_size) { 1071 tlv_type = le16_to_cpu(tlv->type); 1072 tlv_value_len = le16_to_cpu(tlv->len); 1073 1074 switch (tlv_type) { 1075 case QTN_TLV_ID_IFACE_LIMIT: 1076 if (unlikely(!comb)) { 1077 pr_warn("MAC%u: no combinations advertised\n", 1078 mac->macid); 1079 return -EINVAL; 1080 } 1081 1082 if (n_comb >= mac->macinfo.n_if_comb) { 1083 pr_warn("MAC%u: combinations count exceeded\n", 1084 mac->macid); 1085 n_comb++; 1086 break; 1087 } 1088 1089 rec = (void *)tlv->val; 1090 rec_len = sizeof(*rec) + rec->n_limits * sizeof(*lim); 1091 1092 if (unlikely(tlv_value_len != rec_len)) { 1093 pr_warn("MAC%u: record %zu size mismatch\n", 1094 mac->macid, n_comb); 1095 return -EINVAL; 1096 } 1097 1098 limits = kcalloc(rec->n_limits, sizeof(*limits), 1099 GFP_KERNEL); 1100 if (!limits) 1101 return -ENOMEM; 1102 1103 comb[n_comb].num_different_channels = 1104 rec->num_different_channels; 1105 comb[n_comb].max_interfaces = 1106 le16_to_cpu(rec->max_interfaces); 1107 comb[n_comb].n_limits = rec->n_limits; 1108 comb[n_comb].limits = limits; 1109 1110 for (i = 0; i < rec->n_limits; i++) { 1111 lim = &rec->limits[i]; 1112 limits[i].max = le16_to_cpu(lim->max_num); 1113 limits[i].types = 1114 qlink_iface_type_to_nl_mask(le16_to_cpu(lim->type)); 1115 pr_debug("MAC%u: comb[%zu]: MAX:%u TYPES:%.4X\n", 1116 mac->macid, n_comb, 1117 limits[i].max, limits[i].types); 1118 } 1119 1120 n_comb++; 1121 break; 1122 case WLAN_EID_EXT_CAPABILITY: 1123 if (unlikely(tlv_value_len > U8_MAX)) 1124 return -EINVAL; 1125 ext_capa = (u8 *)tlv->val; 1126 ext_capa_len = tlv_value_len; 1127 break; 1128 case QTN_TLV_ID_EXT_CAPABILITY_MASK: 1129 if (unlikely(tlv_value_len > U8_MAX)) 1130 return -EINVAL; 1131 ext_capa_mask = (u8 *)tlv->val; 1132 ext_capa_mask_len = tlv_value_len; 1133 break; 1134 case QTN_TLV_ID_WOWLAN_CAPAB: 1135 if (tlv_value_len < sizeof(*wowlan)) 1136 return -EINVAL; 1137 1138 wowlan = (void *)tlv->val; 1139 if (!le16_to_cpu(wowlan->len)) { 1140 pr_warn("MAC%u: skip empty WoWLAN data\n", 1141 mac->macid); 1142 break; 1143 } 1144 1145 rec_len = sizeof(*wowlan) + le16_to_cpu(wowlan->len); 1146 if (unlikely(tlv_value_len != rec_len)) { 1147 pr_warn("MAC%u: WoWLAN data size mismatch\n", 1148 mac->macid); 1149 return -EINVAL; 1150 } 1151 1152 kfree(mac->macinfo.wowlan); 1153 mac->macinfo.wowlan = NULL; 1154 qtnf_parse_wowlan_info(mac, wowlan); 1155 break; 1156 case QTN_TLV_ID_REG_RULE: 1157 if (rule_idx >= resp->n_reg_rules) { 1158 pr_warn("unexpected number of rules: %u\n", 1159 resp->n_reg_rules); 1160 return -EINVAL; 1161 } 1162 1163 if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) { 1164 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 1165 tlv_type, tlv_value_len); 1166 return -EINVAL; 1167 } 1168 1169 tlv_rule = (const struct qlink_tlv_reg_rule *)tlv; 1170 rule = &mac->rd->reg_rules[rule_idx++]; 1171 qlink_utils_regrule_q2nl(rule, tlv_rule); 1172 break; 1173 default: 1174 pr_warn("MAC%u: unknown TLV type %u\n", 1175 mac->macid, tlv_type); 1176 break; 1177 } 1178 } 1179 1180 if (!qlink_tlv_parsing_ok(tlv, resp->var_info, tlv_buf_size)) { 1181 pr_err("Malformed TLV buffer\n"); 1182 return -EINVAL; 1183 } 1184 1185 if (mac->macinfo.n_if_comb != n_comb) { 1186 pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n", 1187 mac->macid, mac->macinfo.n_if_comb, n_comb); 1188 return -EINVAL; 1189 } 1190 1191 if (ext_capa_len != ext_capa_mask_len) { 1192 pr_err("MAC%u: ext_capa/_mask lengths mismatch: %u != %u\n", 1193 mac->macid, ext_capa_len, ext_capa_mask_len); 1194 return -EINVAL; 1195 } 1196 1197 if (rule_idx != resp->n_reg_rules) { 1198 pr_warn("unexpected number of rules: expected %u got %u\n", 1199 resp->n_reg_rules, rule_idx); 1200 return -EINVAL; 1201 } 1202 1203 if (ext_capa_len > 0) { 1204 ext_capa = kmemdup(ext_capa, ext_capa_len, GFP_KERNEL); 1205 if (!ext_capa) 1206 return -ENOMEM; 1207 1208 ext_capa_mask = 1209 kmemdup(ext_capa_mask, ext_capa_mask_len, GFP_KERNEL); 1210 if (!ext_capa_mask) { 1211 kfree(ext_capa); 1212 return -ENOMEM; 1213 } 1214 } else { 1215 ext_capa = NULL; 1216 ext_capa_mask = NULL; 1217 } 1218 1219 qtnf_mac_ext_caps_free(mac); 1220 mac->macinfo.extended_capabilities = ext_capa; 1221 mac->macinfo.extended_capabilities_mask = ext_capa_mask; 1222 mac->macinfo.extended_capabilities_len = ext_capa_len; 1223 1224 return 0; 1225 } 1226 1227 static int 1228 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, 1229 const struct qlink_resp_get_mac_info *resp_info) 1230 { 1231 struct qtnf_mac_info *mac_info; 1232 struct qtnf_vif *vif; 1233 1234 qtnf_mac_iface_comb_free(mac); 1235 1236 mac_info = &mac->macinfo; 1237 1238 mac_info->bands_cap = resp_info->bands_cap; 1239 ether_addr_copy(mac->macaddr, resp_info->dev_mac); 1240 1241 vif = qtnf_mac_get_base_vif(mac); 1242 if (vif) 1243 ether_addr_copy(vif->mac_addr, mac->macaddr); 1244 else 1245 pr_err("could not get valid base vif\n"); 1246 1247 mac_info->num_tx_chain = resp_info->num_tx_chain; 1248 mac_info->num_rx_chain = resp_info->num_rx_chain; 1249 1250 mac_info->max_ap_assoc_sta = le16_to_cpu(resp_info->max_ap_assoc_sta); 1251 mac_info->radar_detect_widths = 1252 qlink_chan_width_mask_to_nl(le16_to_cpu( 1253 resp_info->radar_detect_widths)); 1254 mac_info->max_acl_mac_addrs = le16_to_cpu(resp_info->max_acl_mac_addrs); 1255 mac_info->frag_thr = le32_to_cpu(resp_info->frag_threshold); 1256 mac_info->rts_thr = le32_to_cpu(resp_info->rts_threshold); 1257 mac_info->sretry_limit = resp_info->retry_short; 1258 mac_info->lretry_limit = resp_info->retry_long; 1259 mac_info->coverage_class = resp_info->coverage_class; 1260 mac_info->max_scan_ssids = resp_info->max_scan_ssids; 1261 1262 memcpy(&mac_info->ht_cap_mod_mask, &resp_info->ht_cap_mod_mask, 1263 sizeof(mac_info->ht_cap_mod_mask)); 1264 memcpy(&mac_info->vht_cap_mod_mask, &resp_info->vht_cap_mod_mask, 1265 sizeof(mac_info->vht_cap_mod_mask)); 1266 1267 mac_info->n_if_comb = resp_info->n_iface_combinations; 1268 mac_info->if_comb = kcalloc(mac->macinfo.n_if_comb, 1269 sizeof(*mac->macinfo.if_comb), 1270 GFP_KERNEL); 1271 1272 if (!mac->macinfo.if_comb) 1273 return -ENOMEM; 1274 1275 return 0; 1276 } 1277 1278 static void qtnf_cmd_resp_band_fill_htcap(const u8 *info, 1279 struct ieee80211_sta_ht_cap *bcap) 1280 { 1281 const struct ieee80211_ht_cap *ht_cap = 1282 (const struct ieee80211_ht_cap *)info; 1283 1284 bcap->ht_supported = true; 1285 bcap->cap = le16_to_cpu(ht_cap->cap_info); 1286 bcap->ampdu_factor = 1287 ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR; 1288 bcap->ampdu_density = 1289 (ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 1290 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; 1291 memcpy(&bcap->mcs, &ht_cap->mcs, sizeof(bcap->mcs)); 1292 } 1293 1294 static void qtnf_cmd_resp_band_fill_vhtcap(const u8 *info, 1295 struct ieee80211_sta_vht_cap *bcap) 1296 { 1297 const struct ieee80211_vht_cap *vht_cap = 1298 (const struct ieee80211_vht_cap *)info; 1299 1300 bcap->vht_supported = true; 1301 bcap->cap = le32_to_cpu(vht_cap->vht_cap_info); 1302 memcpy(&bcap->vht_mcs, &vht_cap->supp_mcs, sizeof(bcap->vht_mcs)); 1303 } 1304 1305 static void qtnf_cmd_conv_iftype(struct ieee80211_sband_iftype_data 1306 *iftype_data, 1307 const struct qlink_sband_iftype_data 1308 *qlink_data) 1309 { 1310 iftype_data->types_mask = le16_to_cpu(qlink_data->types_mask); 1311 1312 iftype_data->he_cap.has_he = true; 1313 memcpy(&iftype_data->he_cap.he_cap_elem, &qlink_data->he_cap_elem, 1314 sizeof(qlink_data->he_cap_elem)); 1315 memcpy(iftype_data->he_cap.ppe_thres, qlink_data->ppe_thres, 1316 ARRAY_SIZE(qlink_data->ppe_thres)); 1317 1318 iftype_data->he_cap.he_mcs_nss_supp.rx_mcs_80 = 1319 qlink_data->he_mcs_nss_supp.rx_mcs_80; 1320 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 = 1321 qlink_data->he_mcs_nss_supp.tx_mcs_80; 1322 iftype_data->he_cap.he_mcs_nss_supp.rx_mcs_160 = 1323 qlink_data->he_mcs_nss_supp.rx_mcs_160; 1324 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 = 1325 qlink_data->he_mcs_nss_supp.tx_mcs_160; 1326 iftype_data->he_cap.he_mcs_nss_supp.rx_mcs_80p80 = 1327 qlink_data->he_mcs_nss_supp.rx_mcs_80p80; 1328 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 = 1329 qlink_data->he_mcs_nss_supp.tx_mcs_80p80; 1330 } 1331 1332 static int qtnf_cmd_band_fill_iftype(const u8 *data, 1333 struct ieee80211_supported_band *band) 1334 { 1335 unsigned int i; 1336 struct ieee80211_sband_iftype_data *iftype_data; 1337 const struct qlink_tlv_iftype_data *tlv = 1338 (const struct qlink_tlv_iftype_data *)data; 1339 size_t payload_len = tlv->n_iftype_data * sizeof(*tlv->iftype_data) + 1340 sizeof(*tlv) - 1341 sizeof(struct qlink_tlv_hdr); 1342 1343 if (tlv->hdr.len != cpu_to_le16(payload_len)) { 1344 pr_err("bad IFTYPE_DATA TLV len %u\n", tlv->hdr.len); 1345 return -EINVAL; 1346 } 1347 1348 kfree(band->iftype_data); 1349 band->iftype_data = NULL; 1350 band->n_iftype_data = tlv->n_iftype_data; 1351 if (band->n_iftype_data == 0) 1352 return 0; 1353 1354 iftype_data = kcalloc(band->n_iftype_data, sizeof(*iftype_data), 1355 GFP_KERNEL); 1356 if (!iftype_data) { 1357 band->n_iftype_data = 0; 1358 return -ENOMEM; 1359 } 1360 band->iftype_data = iftype_data; 1361 1362 for (i = 0; i < band->n_iftype_data; i++) 1363 qtnf_cmd_conv_iftype(iftype_data++, &tlv->iftype_data[i]); 1364 1365 return 0; 1366 } 1367 1368 static int 1369 qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band *band, 1370 struct qlink_resp_band_info_get *resp, 1371 size_t payload_len) 1372 { 1373 u16 tlv_type; 1374 size_t tlv_dlen; 1375 const struct qlink_tlv_hdr *tlv; 1376 const struct qlink_channel *qchan; 1377 struct ieee80211_channel *chan; 1378 unsigned int chidx = 0; 1379 u32 qflags; 1380 int ret = -EINVAL; 1381 1382 memset(&band->ht_cap, 0, sizeof(band->ht_cap)); 1383 memset(&band->vht_cap, 0, sizeof(band->vht_cap)); 1384 1385 if (band->channels) { 1386 if (band->n_channels == resp->num_chans) { 1387 memset(band->channels, 0, 1388 sizeof(*band->channels) * band->n_channels); 1389 } else { 1390 kfree(band->channels); 1391 band->n_channels = 0; 1392 band->channels = NULL; 1393 } 1394 } 1395 1396 band->n_channels = resp->num_chans; 1397 if (band->n_channels == 0) 1398 return 0; 1399 1400 if (!band->channels) 1401 band->channels = kcalloc(band->n_channels, sizeof(*chan), 1402 GFP_KERNEL); 1403 if (!band->channels) { 1404 band->n_channels = 0; 1405 return -ENOMEM; 1406 } 1407 1408 qlink_for_each_tlv(tlv, resp->info, payload_len) { 1409 tlv_type = le16_to_cpu(tlv->type); 1410 tlv_dlen = le16_to_cpu(tlv->len); 1411 1412 switch (tlv_type) { 1413 case QTN_TLV_ID_CHANNEL: 1414 if (unlikely(tlv_dlen != sizeof(*qchan))) { 1415 pr_err("invalid channel TLV len %zu\n", 1416 tlv_dlen); 1417 goto error_ret; 1418 } 1419 1420 if (chidx == band->n_channels) { 1421 pr_err("too many channel TLVs\n"); 1422 goto error_ret; 1423 } 1424 1425 qchan = (const struct qlink_channel *)tlv->val; 1426 chan = &band->channels[chidx++]; 1427 qflags = le32_to_cpu(qchan->flags); 1428 1429 chan->hw_value = le16_to_cpu(qchan->hw_value); 1430 chan->band = band->band; 1431 chan->center_freq = le16_to_cpu(qchan->center_freq); 1432 chan->max_antenna_gain = (int)qchan->max_antenna_gain; 1433 chan->max_power = (int)qchan->max_power; 1434 chan->max_reg_power = (int)qchan->max_reg_power; 1435 chan->beacon_found = qchan->beacon_found; 1436 chan->dfs_cac_ms = le32_to_cpu(qchan->dfs_cac_ms); 1437 chan->flags = 0; 1438 1439 if (qflags & QLINK_CHAN_DISABLED) 1440 chan->flags |= IEEE80211_CHAN_DISABLED; 1441 1442 if (qflags & QLINK_CHAN_NO_IR) 1443 chan->flags |= IEEE80211_CHAN_NO_IR; 1444 1445 if (qflags & QLINK_CHAN_NO_HT40PLUS) 1446 chan->flags |= IEEE80211_CHAN_NO_HT40PLUS; 1447 1448 if (qflags & QLINK_CHAN_NO_HT40MINUS) 1449 chan->flags |= IEEE80211_CHAN_NO_HT40MINUS; 1450 1451 if (qflags & QLINK_CHAN_NO_OFDM) 1452 chan->flags |= IEEE80211_CHAN_NO_OFDM; 1453 1454 if (qflags & QLINK_CHAN_NO_80MHZ) 1455 chan->flags |= IEEE80211_CHAN_NO_80MHZ; 1456 1457 if (qflags & QLINK_CHAN_NO_160MHZ) 1458 chan->flags |= IEEE80211_CHAN_NO_160MHZ; 1459 1460 if (qflags & QLINK_CHAN_INDOOR_ONLY) 1461 chan->flags |= IEEE80211_CHAN_INDOOR_ONLY; 1462 1463 if (qflags & QLINK_CHAN_IR_CONCURRENT) 1464 chan->flags |= IEEE80211_CHAN_IR_CONCURRENT; 1465 1466 if (qflags & QLINK_CHAN_NO_20MHZ) 1467 chan->flags |= IEEE80211_CHAN_NO_20MHZ; 1468 1469 if (qflags & QLINK_CHAN_NO_10MHZ) 1470 chan->flags |= IEEE80211_CHAN_NO_10MHZ; 1471 1472 if (qflags & QLINK_CHAN_RADAR) { 1473 chan->flags |= IEEE80211_CHAN_RADAR; 1474 chan->dfs_state_entered = jiffies; 1475 1476 if (qchan->dfs_state == QLINK_DFS_USABLE) 1477 chan->dfs_state = NL80211_DFS_USABLE; 1478 else if (qchan->dfs_state == 1479 QLINK_DFS_AVAILABLE) 1480 chan->dfs_state = NL80211_DFS_AVAILABLE; 1481 else 1482 chan->dfs_state = 1483 NL80211_DFS_UNAVAILABLE; 1484 } 1485 1486 pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n", 1487 chan->hw_value, chan->flags, chan->max_power, 1488 chan->max_reg_power); 1489 break; 1490 case WLAN_EID_HT_CAPABILITY: 1491 if (unlikely(tlv_dlen != 1492 sizeof(struct ieee80211_ht_cap))) { 1493 pr_err("bad HTCAP TLV len %zu\n", tlv_dlen); 1494 goto error_ret; 1495 } 1496 1497 qtnf_cmd_resp_band_fill_htcap(tlv->val, &band->ht_cap); 1498 break; 1499 case WLAN_EID_VHT_CAPABILITY: 1500 if (unlikely(tlv_dlen != 1501 sizeof(struct ieee80211_vht_cap))) { 1502 pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen); 1503 goto error_ret; 1504 } 1505 1506 qtnf_cmd_resp_band_fill_vhtcap(tlv->val, 1507 &band->vht_cap); 1508 break; 1509 case QTN_TLV_ID_IFTYPE_DATA: 1510 ret = qtnf_cmd_band_fill_iftype((const uint8_t *)tlv, 1511 band); 1512 if (ret) 1513 goto error_ret; 1514 break; 1515 default: 1516 pr_warn("unknown TLV type: %#x\n", tlv_type); 1517 break; 1518 } 1519 } 1520 1521 if (!qlink_tlv_parsing_ok(tlv, resp->info, payload_len)) { 1522 pr_err("Malformed TLV buffer\n"); 1523 goto error_ret; 1524 } 1525 1526 if (band->n_channels != chidx) { 1527 pr_err("channel count mismatch: reported=%d, parsed=%d\n", 1528 band->n_channels, chidx); 1529 goto error_ret; 1530 } 1531 1532 return 0; 1533 1534 error_ret: 1535 kfree(band->channels); 1536 band->channels = NULL; 1537 band->n_channels = 0; 1538 1539 return ret; 1540 } 1541 1542 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac) 1543 { 1544 struct sk_buff *cmd_skb, *resp_skb = NULL; 1545 const struct qlink_resp_get_mac_info *resp; 1546 size_t var_data_len = 0; 1547 int ret = 0; 1548 1549 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1550 QLINK_CMD_MAC_INFO, 1551 sizeof(struct qlink_cmd)); 1552 if (!cmd_skb) 1553 return -ENOMEM; 1554 1555 qtnf_bus_lock(mac->bus); 1556 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 1557 sizeof(*resp), &var_data_len); 1558 if (ret) 1559 goto out; 1560 1561 resp = (const struct qlink_resp_get_mac_info *)resp_skb->data; 1562 ret = qtnf_cmd_resp_proc_mac_info(mac, resp); 1563 if (ret) 1564 goto out; 1565 1566 ret = qtnf_parse_variable_mac_info(mac, resp, var_data_len); 1567 1568 out: 1569 qtnf_bus_unlock(mac->bus); 1570 consume_skb(resp_skb); 1571 1572 return ret; 1573 } 1574 1575 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus) 1576 { 1577 struct sk_buff *cmd_skb, *resp_skb = NULL; 1578 const struct qlink_resp_get_hw_info *resp; 1579 size_t info_len = 0; 1580 int ret = 0; 1581 1582 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1583 QLINK_CMD_GET_HW_INFO, 1584 sizeof(struct qlink_cmd)); 1585 if (!cmd_skb) 1586 return -ENOMEM; 1587 1588 qtnf_bus_lock(bus); 1589 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 1590 sizeof(*resp), &info_len); 1591 if (ret) 1592 goto out; 1593 1594 resp = (const struct qlink_resp_get_hw_info *)resp_skb->data; 1595 ret = qtnf_cmd_resp_proc_hw_info(bus, resp, info_len); 1596 1597 out: 1598 qtnf_bus_unlock(bus); 1599 consume_skb(resp_skb); 1600 1601 return ret; 1602 } 1603 1604 int qtnf_cmd_band_info_get(struct qtnf_wmac *mac, 1605 struct ieee80211_supported_band *band) 1606 { 1607 struct sk_buff *cmd_skb, *resp_skb = NULL; 1608 struct qlink_cmd_band_info_get *cmd; 1609 struct qlink_resp_band_info_get *resp; 1610 size_t info_len = 0; 1611 int ret = 0; 1612 u8 qband = qlink_utils_band_cfg2q(band->band); 1613 1614 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1615 QLINK_CMD_BAND_INFO_GET, 1616 sizeof(*cmd)); 1617 if (!cmd_skb) 1618 return -ENOMEM; 1619 1620 cmd = (struct qlink_cmd_band_info_get *)cmd_skb->data; 1621 cmd->band = qband; 1622 1623 qtnf_bus_lock(mac->bus); 1624 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 1625 sizeof(*resp), &info_len); 1626 if (ret) 1627 goto out; 1628 1629 resp = (struct qlink_resp_band_info_get *)resp_skb->data; 1630 if (resp->band != qband) { 1631 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, 1632 resp->band, qband); 1633 ret = -EINVAL; 1634 goto out; 1635 } 1636 1637 ret = qtnf_cmd_resp_fill_band_info(band, resp, info_len); 1638 1639 out: 1640 qtnf_bus_unlock(mac->bus); 1641 consume_skb(resp_skb); 1642 1643 return ret; 1644 } 1645 1646 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed) 1647 { 1648 struct wiphy *wiphy = priv_to_wiphy(mac); 1649 struct sk_buff *cmd_skb; 1650 int ret = 0; 1651 1652 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1653 QLINK_CMD_PHY_PARAMS_SET, 1654 sizeof(struct qlink_cmd)); 1655 if (!cmd_skb) 1656 return -ENOMEM; 1657 1658 qtnf_bus_lock(mac->bus); 1659 1660 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 1661 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_FRAG_THRESH, 1662 wiphy->frag_threshold); 1663 if (changed & WIPHY_PARAM_RTS_THRESHOLD) 1664 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_RTS_THRESH, 1665 wiphy->rts_threshold); 1666 if (changed & WIPHY_PARAM_COVERAGE_CLASS) 1667 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS, 1668 wiphy->coverage_class); 1669 1670 if (changed & WIPHY_PARAM_RETRY_LONG) 1671 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_LRETRY_LIMIT, 1672 wiphy->retry_long); 1673 1674 if (changed & WIPHY_PARAM_RETRY_SHORT) 1675 qtnf_cmd_skb_put_tlv_u32(cmd_skb, QTN_TLV_ID_SRETRY_LIMIT, 1676 wiphy->retry_short); 1677 1678 ret = qtnf_cmd_send(mac->bus, cmd_skb); 1679 if (ret) 1680 goto out; 1681 1682 out: 1683 qtnf_bus_unlock(mac->bus); 1684 1685 return ret; 1686 } 1687 1688 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus) 1689 { 1690 struct sk_buff *resp_skb = NULL; 1691 struct qlink_resp_init_fw *resp; 1692 struct qlink_cmd_init_fw *cmd; 1693 struct sk_buff *cmd_skb; 1694 size_t info_len = 0; 1695 int ret; 1696 1697 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1698 QLINK_CMD_FW_INIT, 1699 sizeof(*cmd)); 1700 if (!cmd_skb) 1701 return -ENOMEM; 1702 1703 cmd = (struct qlink_cmd_init_fw *)cmd_skb->data; 1704 cmd->qlink_proto_ver = cpu_to_le32(QLINK_PROTO_VER); 1705 1706 qtnf_bus_lock(bus); 1707 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 1708 sizeof(*resp), &info_len); 1709 qtnf_bus_unlock(bus); 1710 1711 if (ret) 1712 goto out; 1713 1714 resp = (struct qlink_resp_init_fw *)resp_skb->data; 1715 bus->hw_info.ql_proto_ver = le32_to_cpu(resp->qlink_proto_ver); 1716 1717 out: 1718 consume_skb(resp_skb); 1719 return ret; 1720 } 1721 1722 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus) 1723 { 1724 struct sk_buff *cmd_skb; 1725 1726 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1727 QLINK_CMD_FW_DEINIT, 1728 sizeof(struct qlink_cmd)); 1729 if (!cmd_skb) 1730 return; 1731 1732 qtnf_bus_lock(bus); 1733 qtnf_cmd_send(bus, cmd_skb); 1734 qtnf_bus_unlock(bus); 1735 } 1736 1737 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1738 const u8 *mac_addr, struct key_params *params) 1739 { 1740 struct sk_buff *cmd_skb; 1741 struct qlink_cmd_add_key *cmd; 1742 int ret = 0; 1743 1744 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1745 QLINK_CMD_ADD_KEY, 1746 sizeof(*cmd)); 1747 if (!cmd_skb) 1748 return -ENOMEM; 1749 1750 qtnf_bus_lock(vif->mac->bus); 1751 1752 cmd = (struct qlink_cmd_add_key *)cmd_skb->data; 1753 1754 if (mac_addr) 1755 ether_addr_copy(cmd->addr, mac_addr); 1756 else 1757 eth_broadcast_addr(cmd->addr); 1758 1759 cmd->cipher = cpu_to_le32(params->cipher); 1760 cmd->key_index = key_index; 1761 cmd->pairwise = pairwise; 1762 1763 if (params->key && params->key_len > 0) 1764 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY, 1765 params->key, 1766 params->key_len); 1767 1768 if (params->seq && params->seq_len > 0) 1769 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ, 1770 params->seq, 1771 params->seq_len); 1772 1773 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1774 if (ret) 1775 goto out; 1776 1777 out: 1778 qtnf_bus_unlock(vif->mac->bus); 1779 1780 return ret; 1781 } 1782 1783 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1784 const u8 *mac_addr) 1785 { 1786 struct sk_buff *cmd_skb; 1787 struct qlink_cmd_del_key *cmd; 1788 int ret = 0; 1789 1790 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1791 QLINK_CMD_DEL_KEY, 1792 sizeof(*cmd)); 1793 if (!cmd_skb) 1794 return -ENOMEM; 1795 1796 qtnf_bus_lock(vif->mac->bus); 1797 1798 cmd = (struct qlink_cmd_del_key *)cmd_skb->data; 1799 1800 if (mac_addr) 1801 ether_addr_copy(cmd->addr, mac_addr); 1802 else 1803 eth_broadcast_addr(cmd->addr); 1804 1805 cmd->key_index = key_index; 1806 cmd->pairwise = pairwise; 1807 1808 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1809 if (ret) 1810 goto out; 1811 1812 out: 1813 qtnf_bus_unlock(vif->mac->bus); 1814 1815 return ret; 1816 } 1817 1818 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index, 1819 bool unicast, bool multicast) 1820 { 1821 struct sk_buff *cmd_skb; 1822 struct qlink_cmd_set_def_key *cmd; 1823 int ret = 0; 1824 1825 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1826 QLINK_CMD_SET_DEFAULT_KEY, 1827 sizeof(*cmd)); 1828 if (!cmd_skb) 1829 return -ENOMEM; 1830 1831 qtnf_bus_lock(vif->mac->bus); 1832 1833 cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data; 1834 cmd->key_index = key_index; 1835 cmd->unicast = unicast; 1836 cmd->multicast = multicast; 1837 1838 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1839 if (ret) 1840 goto out; 1841 1842 out: 1843 qtnf_bus_unlock(vif->mac->bus); 1844 1845 return ret; 1846 } 1847 1848 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index) 1849 { 1850 struct sk_buff *cmd_skb; 1851 struct qlink_cmd_set_def_mgmt_key *cmd; 1852 int ret = 0; 1853 1854 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1855 QLINK_CMD_SET_DEFAULT_MGMT_KEY, 1856 sizeof(*cmd)); 1857 if (!cmd_skb) 1858 return -ENOMEM; 1859 1860 qtnf_bus_lock(vif->mac->bus); 1861 1862 cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data; 1863 cmd->key_index = key_index; 1864 1865 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1866 if (ret) 1867 goto out; 1868 1869 out: 1870 qtnf_bus_unlock(vif->mac->bus); 1871 1872 return ret; 1873 } 1874 1875 static u32 qtnf_encode_sta_flags(u32 flags) 1876 { 1877 u32 code = 0; 1878 1879 if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED)) 1880 code |= QLINK_STA_FLAG_AUTHORIZED; 1881 if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 1882 code |= QLINK_STA_FLAG_SHORT_PREAMBLE; 1883 if (flags & BIT(NL80211_STA_FLAG_WME)) 1884 code |= QLINK_STA_FLAG_WME; 1885 if (flags & BIT(NL80211_STA_FLAG_MFP)) 1886 code |= QLINK_STA_FLAG_MFP; 1887 if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED)) 1888 code |= QLINK_STA_FLAG_AUTHENTICATED; 1889 if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER)) 1890 code |= QLINK_STA_FLAG_TDLS_PEER; 1891 if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED)) 1892 code |= QLINK_STA_FLAG_ASSOCIATED; 1893 return code; 1894 } 1895 1896 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac, 1897 struct station_parameters *params) 1898 { 1899 struct sk_buff *cmd_skb; 1900 struct qlink_cmd_change_sta *cmd; 1901 int ret = 0; 1902 1903 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1904 QLINK_CMD_CHANGE_STA, 1905 sizeof(*cmd)); 1906 if (!cmd_skb) 1907 return -ENOMEM; 1908 1909 qtnf_bus_lock(vif->mac->bus); 1910 1911 cmd = (struct qlink_cmd_change_sta *)cmd_skb->data; 1912 ether_addr_copy(cmd->sta_addr, mac); 1913 cmd->flag_update.mask = 1914 cpu_to_le32(qtnf_encode_sta_flags(params->sta_flags_mask)); 1915 cmd->flag_update.value = 1916 cpu_to_le32(qtnf_encode_sta_flags(params->sta_flags_set)); 1917 1918 switch (vif->wdev.iftype) { 1919 case NL80211_IFTYPE_AP: 1920 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_AP); 1921 break; 1922 case NL80211_IFTYPE_STATION: 1923 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 1924 break; 1925 default: 1926 pr_err("unsupported iftype %d\n", vif->wdev.iftype); 1927 ret = -EINVAL; 1928 goto out; 1929 } 1930 1931 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1932 if (ret) 1933 goto out; 1934 1935 out: 1936 qtnf_bus_unlock(vif->mac->bus); 1937 1938 return ret; 1939 } 1940 1941 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif, 1942 struct station_del_parameters *params) 1943 { 1944 struct sk_buff *cmd_skb; 1945 struct qlink_cmd_del_sta *cmd; 1946 int ret = 0; 1947 1948 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1949 QLINK_CMD_DEL_STA, 1950 sizeof(*cmd)); 1951 if (!cmd_skb) 1952 return -ENOMEM; 1953 1954 qtnf_bus_lock(vif->mac->bus); 1955 1956 cmd = (struct qlink_cmd_del_sta *)cmd_skb->data; 1957 1958 if (params->mac) 1959 ether_addr_copy(cmd->sta_addr, params->mac); 1960 else 1961 eth_broadcast_addr(cmd->sta_addr); /* flush all stations */ 1962 1963 cmd->subtype = params->subtype; 1964 cmd->reason_code = cpu_to_le16(params->reason_code); 1965 1966 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 1967 if (ret) 1968 goto out; 1969 1970 out: 1971 qtnf_bus_unlock(vif->mac->bus); 1972 1973 return ret; 1974 } 1975 1976 static void qtnf_cmd_channel_tlv_add(struct sk_buff *cmd_skb, 1977 const struct ieee80211_channel *sc) 1978 { 1979 struct qlink_tlv_channel *tlv; 1980 struct qlink_channel *qch; 1981 1982 tlv = skb_put_zero(cmd_skb, sizeof(*tlv)); 1983 qch = &tlv->chan; 1984 tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); 1985 tlv->hdr.len = cpu_to_le16(sizeof(*qch)); 1986 1987 qch->center_freq = cpu_to_le16(sc->center_freq); 1988 qch->hw_value = cpu_to_le16(sc->hw_value); 1989 qch->band = qlink_utils_band_cfg2q(sc->band); 1990 qch->max_power = sc->max_power; 1991 qch->max_reg_power = sc->max_reg_power; 1992 qch->max_antenna_gain = sc->max_antenna_gain; 1993 qch->beacon_found = sc->beacon_found; 1994 qch->dfs_state = qlink_utils_dfs_state_cfg2q(sc->dfs_state); 1995 qch->flags = cpu_to_le32(qlink_utils_chflags_cfg2q(sc->flags)); 1996 } 1997 1998 static void qtnf_cmd_randmac_tlv_add(struct sk_buff *cmd_skb, 1999 const u8 *mac_addr, 2000 const u8 *mac_addr_mask) 2001 { 2002 struct qlink_random_mac_addr *randmac; 2003 struct qlink_tlv_hdr *hdr = 2004 skb_put(cmd_skb, sizeof(*hdr) + sizeof(*randmac)); 2005 2006 hdr->type = cpu_to_le16(QTN_TLV_ID_RANDOM_MAC_ADDR); 2007 hdr->len = cpu_to_le16(sizeof(*randmac)); 2008 randmac = (struct qlink_random_mac_addr *)hdr->val; 2009 2010 memcpy(randmac->mac_addr, mac_addr, ETH_ALEN); 2011 memcpy(randmac->mac_addr_mask, mac_addr_mask, ETH_ALEN); 2012 } 2013 2014 int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 2015 { 2016 struct cfg80211_scan_request *scan_req = mac->scan_req; 2017 u16 dwell_passive = QTNF_SCAN_DWELL_PASSIVE_DEFAULT; 2018 u16 dwell_active = QTNF_SCAN_DWELL_ACTIVE_DEFAULT; 2019 struct wireless_dev *wdev = scan_req->wdev; 2020 struct ieee80211_channel *sc; 2021 struct qlink_cmd_scan *cmd; 2022 struct sk_buff *cmd_skb; 2023 int n_channels = 0; 2024 u64 flags = 0; 2025 int count; 2026 int ret; 2027 2028 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2029 QLINK_CMD_SCAN, 2030 sizeof(*cmd)); 2031 if (!cmd_skb) 2032 return -ENOMEM; 2033 2034 cmd = (struct qlink_cmd_scan *)cmd_skb->data; 2035 2036 if (scan_req->duration) { 2037 dwell_active = scan_req->duration; 2038 dwell_passive = scan_req->duration; 2039 } else if (wdev->iftype == NL80211_IFTYPE_STATION && 2040 wdev->current_bss) { 2041 /* let device select dwell based on traffic conditions */ 2042 dwell_active = QTNF_SCAN_TIME_AUTO; 2043 dwell_passive = QTNF_SCAN_TIME_AUTO; 2044 } 2045 2046 cmd->n_ssids = cpu_to_le16(scan_req->n_ssids); 2047 for (count = 0; count < scan_req->n_ssids; ++count) { 2048 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, 2049 scan_req->ssids[count].ssid, 2050 scan_req->ssids[count].ssid_len); 2051 } 2052 2053 if (scan_req->ie_len != 0) 2054 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ, 2055 scan_req->ie, scan_req->ie_len); 2056 2057 for (count = 0; count < scan_req->n_channels; ++count) { 2058 sc = scan_req->channels[count]; 2059 if (sc->flags & IEEE80211_CHAN_DISABLED) 2060 continue; 2061 2062 pr_debug("[MAC%u] scan chan=%d, freq=%d, flags=%#x\n", 2063 mac->macid, sc->hw_value, sc->center_freq, 2064 sc->flags); 2065 2066 qtnf_cmd_channel_tlv_add(cmd_skb, sc); 2067 ++n_channels; 2068 } 2069 2070 if (scan_req->flags & NL80211_SCAN_FLAG_FLUSH) 2071 flags |= QLINK_SCAN_FLAG_FLUSH; 2072 2073 if (scan_req->duration_mandatory) 2074 flags |= QLINK_SCAN_FLAG_DURATION_MANDATORY; 2075 2076 cmd->n_channels = cpu_to_le16(n_channels); 2077 cmd->active_dwell = cpu_to_le16(dwell_active); 2078 cmd->passive_dwell = cpu_to_le16(dwell_passive); 2079 cmd->sample_duration = cpu_to_le16(QTNF_SCAN_SAMPLE_DURATION_DEFAULT); 2080 cmd->flags = cpu_to_le64(flags); 2081 2082 pr_debug("[MAC%u] %s scan dwell active=%u passive=%u duration=%u\n", 2083 mac->macid, 2084 scan_req->duration_mandatory ? "mandatory" : "max", 2085 dwell_active, dwell_passive, 2086 QTNF_SCAN_SAMPLE_DURATION_DEFAULT); 2087 2088 if (scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 2089 pr_debug("[MAC%u] scan with random addr=%pM, mask=%pM\n", 2090 mac->macid, 2091 scan_req->mac_addr, scan_req->mac_addr_mask); 2092 qtnf_cmd_randmac_tlv_add(cmd_skb, scan_req->mac_addr, 2093 scan_req->mac_addr_mask); 2094 } 2095 2096 qtnf_bus_lock(mac->bus); 2097 ret = qtnf_cmd_send(mac->bus, cmd_skb); 2098 qtnf_bus_unlock(mac->bus); 2099 2100 return ret; 2101 } 2102 2103 int qtnf_cmd_send_connect(struct qtnf_vif *vif, 2104 struct cfg80211_connect_params *sme) 2105 { 2106 struct sk_buff *cmd_skb; 2107 struct qlink_cmd_connect *cmd; 2108 struct qlink_auth_encr *aen; 2109 int ret; 2110 int i; 2111 u32 connect_flags = 0; 2112 2113 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2114 QLINK_CMD_CONNECT, 2115 sizeof(*cmd)); 2116 if (!cmd_skb) 2117 return -ENOMEM; 2118 2119 cmd = (struct qlink_cmd_connect *)cmd_skb->data; 2120 2121 ether_addr_copy(cmd->bssid, vif->bssid); 2122 2123 if (sme->bssid_hint) 2124 ether_addr_copy(cmd->bssid_hint, sme->bssid_hint); 2125 else 2126 eth_zero_addr(cmd->bssid_hint); 2127 2128 if (sme->prev_bssid) 2129 ether_addr_copy(cmd->prev_bssid, sme->prev_bssid); 2130 else 2131 eth_zero_addr(cmd->prev_bssid); 2132 2133 if ((sme->bg_scan_period >= 0) && 2134 (sme->bg_scan_period <= SHRT_MAX)) 2135 cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period); 2136 else 2137 cmd->bg_scan_period = cpu_to_le16(-1); /* use default value */ 2138 2139 if (sme->flags & ASSOC_REQ_DISABLE_HT) 2140 connect_flags |= QLINK_STA_CONNECT_DISABLE_HT; 2141 if (sme->flags & ASSOC_REQ_DISABLE_VHT) 2142 connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT; 2143 if (sme->flags & ASSOC_REQ_USE_RRM) 2144 connect_flags |= QLINK_STA_CONNECT_USE_RRM; 2145 2146 cmd->flags = cpu_to_le32(connect_flags); 2147 memcpy(&cmd->ht_capa, &sme->ht_capa, sizeof(cmd->ht_capa)); 2148 memcpy(&cmd->ht_capa_mask, &sme->ht_capa_mask, 2149 sizeof(cmd->ht_capa_mask)); 2150 memcpy(&cmd->vht_capa, &sme->vht_capa, sizeof(cmd->vht_capa)); 2151 memcpy(&cmd->vht_capa_mask, &sme->vht_capa_mask, 2152 sizeof(cmd->vht_capa_mask)); 2153 cmd->pbss = sme->pbss; 2154 2155 aen = &cmd->aen; 2156 aen->auth_type = sme->auth_type; 2157 aen->privacy = !!sme->privacy; 2158 cmd->mfp = sme->mfp; 2159 aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions); 2160 aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group); 2161 aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise); 2162 2163 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 2164 aen->ciphers_pairwise[i] = 2165 cpu_to_le32(sme->crypto.ciphers_pairwise[i]); 2166 2167 aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites); 2168 2169 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 2170 aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]); 2171 2172 aen->control_port = sme->crypto.control_port; 2173 aen->control_port_no_encrypt = 2174 sme->crypto.control_port_no_encrypt; 2175 aen->control_port_ethertype = 2176 cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype)); 2177 2178 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid, 2179 sme->ssid_len); 2180 2181 if (sme->ie_len != 0) 2182 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ, 2183 sme->ie, sme->ie_len); 2184 2185 if (sme->channel) 2186 qtnf_cmd_channel_tlv_add(cmd_skb, sme->channel); 2187 2188 qtnf_bus_lock(vif->mac->bus); 2189 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2190 if (ret) 2191 goto out; 2192 2193 out: 2194 qtnf_bus_unlock(vif->mac->bus); 2195 2196 return ret; 2197 } 2198 2199 int qtnf_cmd_send_external_auth(struct qtnf_vif *vif, 2200 struct cfg80211_external_auth_params *auth) 2201 { 2202 struct sk_buff *cmd_skb; 2203 struct qlink_cmd_external_auth *cmd; 2204 int ret; 2205 2206 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2207 QLINK_CMD_EXTERNAL_AUTH, 2208 sizeof(*cmd)); 2209 if (!cmd_skb) 2210 return -ENOMEM; 2211 2212 cmd = (struct qlink_cmd_external_auth *)cmd_skb->data; 2213 2214 ether_addr_copy(cmd->peer, auth->bssid); 2215 cmd->status = cpu_to_le16(auth->status); 2216 2217 qtnf_bus_lock(vif->mac->bus); 2218 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2219 if (ret) 2220 goto out; 2221 2222 out: 2223 qtnf_bus_unlock(vif->mac->bus); 2224 2225 return ret; 2226 } 2227 2228 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code) 2229 { 2230 struct sk_buff *cmd_skb; 2231 struct qlink_cmd_disconnect *cmd; 2232 int ret; 2233 2234 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2235 QLINK_CMD_DISCONNECT, 2236 sizeof(*cmd)); 2237 if (!cmd_skb) 2238 return -ENOMEM; 2239 2240 qtnf_bus_lock(vif->mac->bus); 2241 2242 cmd = (struct qlink_cmd_disconnect *)cmd_skb->data; 2243 cmd->reason = cpu_to_le16(reason_code); 2244 2245 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2246 if (ret) 2247 goto out; 2248 2249 out: 2250 qtnf_bus_unlock(vif->mac->bus); 2251 2252 return ret; 2253 } 2254 2255 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up) 2256 { 2257 struct sk_buff *cmd_skb; 2258 struct qlink_cmd_updown *cmd; 2259 int ret; 2260 2261 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2262 QLINK_CMD_UPDOWN_INTF, 2263 sizeof(*cmd)); 2264 if (!cmd_skb) 2265 return -ENOMEM; 2266 2267 cmd = (struct qlink_cmd_updown *)cmd_skb->data; 2268 cmd->if_up = !!up; 2269 2270 qtnf_bus_lock(vif->mac->bus); 2271 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2272 if (ret) 2273 goto out; 2274 2275 out: 2276 qtnf_bus_unlock(vif->mac->bus); 2277 2278 return ret; 2279 } 2280 2281 int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req, 2282 bool slave_radar, bool dfs_offload) 2283 { 2284 struct wiphy *wiphy = priv_to_wiphy(mac); 2285 struct qtnf_bus *bus = mac->bus; 2286 struct sk_buff *cmd_skb; 2287 int ret; 2288 struct qlink_cmd_reg_notify *cmd; 2289 enum nl80211_band band; 2290 const struct ieee80211_supported_band *cfg_band; 2291 2292 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2293 QLINK_CMD_REG_NOTIFY, 2294 sizeof(*cmd)); 2295 if (!cmd_skb) 2296 return -ENOMEM; 2297 2298 cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data; 2299 cmd->alpha2[0] = req->alpha2[0]; 2300 cmd->alpha2[1] = req->alpha2[1]; 2301 2302 switch (req->initiator) { 2303 case NL80211_REGDOM_SET_BY_CORE: 2304 cmd->initiator = QLINK_REGDOM_SET_BY_CORE; 2305 break; 2306 case NL80211_REGDOM_SET_BY_USER: 2307 cmd->initiator = QLINK_REGDOM_SET_BY_USER; 2308 break; 2309 case NL80211_REGDOM_SET_BY_DRIVER: 2310 cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER; 2311 break; 2312 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2313 cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE; 2314 break; 2315 } 2316 2317 switch (req->user_reg_hint_type) { 2318 case NL80211_USER_REG_HINT_USER: 2319 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER; 2320 break; 2321 case NL80211_USER_REG_HINT_CELL_BASE: 2322 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE; 2323 break; 2324 case NL80211_USER_REG_HINT_INDOOR: 2325 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR; 2326 break; 2327 } 2328 2329 switch (req->dfs_region) { 2330 case NL80211_DFS_FCC: 2331 cmd->dfs_region = QLINK_DFS_FCC; 2332 break; 2333 case NL80211_DFS_ETSI: 2334 cmd->dfs_region = QLINK_DFS_ETSI; 2335 break; 2336 case NL80211_DFS_JP: 2337 cmd->dfs_region = QLINK_DFS_JP; 2338 break; 2339 default: 2340 cmd->dfs_region = QLINK_DFS_UNSET; 2341 break; 2342 } 2343 2344 cmd->slave_radar = slave_radar; 2345 cmd->dfs_offload = dfs_offload; 2346 cmd->num_channels = 0; 2347 2348 for (band = 0; band < NUM_NL80211_BANDS; band++) { 2349 unsigned int i; 2350 2351 cfg_band = wiphy->bands[band]; 2352 if (!cfg_band) 2353 continue; 2354 2355 cmd->num_channels += cfg_band->n_channels; 2356 2357 for (i = 0; i < cfg_band->n_channels; ++i) { 2358 qtnf_cmd_channel_tlv_add(cmd_skb, 2359 &cfg_band->channels[i]); 2360 } 2361 } 2362 2363 qtnf_bus_lock(bus); 2364 ret = qtnf_cmd_send(bus, cmd_skb); 2365 qtnf_bus_unlock(bus); 2366 2367 return ret; 2368 } 2369 2370 static int 2371 qtnf_cmd_resp_proc_chan_stat_info(struct survey_info *survey, 2372 const u8 *payload, size_t payload_len) 2373 { 2374 const struct qlink_chan_stats *stats = NULL; 2375 const struct qlink_tlv_hdr *tlv; 2376 u16 tlv_value_len; 2377 u16 tlv_type; 2378 const u8 *map = NULL; 2379 unsigned int map_len = 0; 2380 unsigned int stats_len = 0; 2381 2382 qlink_for_each_tlv(tlv, payload, payload_len) { 2383 tlv_type = le16_to_cpu(tlv->type); 2384 tlv_value_len = le16_to_cpu(tlv->len); 2385 2386 switch (tlv_type) { 2387 case QTN_TLV_ID_BITMAP: 2388 map = tlv->val; 2389 map_len = tlv_value_len; 2390 break; 2391 case QTN_TLV_ID_CHANNEL_STATS: 2392 stats = (struct qlink_chan_stats *)tlv->val; 2393 stats_len = tlv_value_len; 2394 break; 2395 default: 2396 pr_info("Unknown TLV type: %#x\n", tlv_type); 2397 break; 2398 } 2399 } 2400 2401 if (!qlink_tlv_parsing_ok(tlv, payload, payload_len)) { 2402 pr_err("Malformed TLV buffer\n"); 2403 return -EINVAL; 2404 } 2405 2406 if (!map || !stats) 2407 return 0; 2408 2409 #define qtnf_chan_stat_avail(stat_name, bitn) \ 2410 (qtnf_utils_is_bit_set(map, bitn, map_len) && \ 2411 (offsetofend(struct qlink_chan_stats, stat_name) <= stats_len)) 2412 2413 if (qtnf_chan_stat_avail(time_on, QLINK_CHAN_STAT_TIME_ON)) { 2414 survey->filled |= SURVEY_INFO_TIME; 2415 survey->time = le64_to_cpu(stats->time_on); 2416 } 2417 2418 if (qtnf_chan_stat_avail(time_tx, QLINK_CHAN_STAT_TIME_TX)) { 2419 survey->filled |= SURVEY_INFO_TIME_TX; 2420 survey->time_tx = le64_to_cpu(stats->time_tx); 2421 } 2422 2423 if (qtnf_chan_stat_avail(time_rx, QLINK_CHAN_STAT_TIME_RX)) { 2424 survey->filled |= SURVEY_INFO_TIME_RX; 2425 survey->time_rx = le64_to_cpu(stats->time_rx); 2426 } 2427 2428 if (qtnf_chan_stat_avail(cca_busy, QLINK_CHAN_STAT_CCA_BUSY)) { 2429 survey->filled |= SURVEY_INFO_TIME_BUSY; 2430 survey->time_busy = le64_to_cpu(stats->cca_busy); 2431 } 2432 2433 if (qtnf_chan_stat_avail(cca_busy_ext, QLINK_CHAN_STAT_CCA_BUSY_EXT)) { 2434 survey->filled |= SURVEY_INFO_TIME_EXT_BUSY; 2435 survey->time_ext_busy = le64_to_cpu(stats->cca_busy_ext); 2436 } 2437 2438 if (qtnf_chan_stat_avail(time_scan, QLINK_CHAN_STAT_TIME_SCAN)) { 2439 survey->filled |= SURVEY_INFO_TIME_SCAN; 2440 survey->time_scan = le64_to_cpu(stats->time_scan); 2441 } 2442 2443 if (qtnf_chan_stat_avail(chan_noise, QLINK_CHAN_STAT_CHAN_NOISE)) { 2444 survey->filled |= SURVEY_INFO_NOISE_DBM; 2445 survey->noise = stats->chan_noise; 2446 } 2447 2448 #undef qtnf_chan_stat_avail 2449 2450 return 0; 2451 } 2452 2453 int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u32 chan_freq, 2454 struct survey_info *survey) 2455 { 2456 struct sk_buff *cmd_skb, *resp_skb = NULL; 2457 struct qlink_cmd_get_chan_stats *cmd; 2458 struct qlink_resp_get_chan_stats *resp; 2459 size_t var_data_len = 0; 2460 int ret = 0; 2461 2462 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2463 QLINK_CMD_CHAN_STATS, 2464 sizeof(*cmd)); 2465 if (!cmd_skb) 2466 return -ENOMEM; 2467 2468 cmd = (struct qlink_cmd_get_chan_stats *)cmd_skb->data; 2469 cmd->channel_freq = cpu_to_le32(chan_freq); 2470 2471 qtnf_bus_lock(mac->bus); 2472 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 2473 sizeof(*resp), &var_data_len); 2474 qtnf_bus_unlock(mac->bus); 2475 2476 if (ret) 2477 goto out; 2478 2479 resp = (struct qlink_resp_get_chan_stats *)resp_skb->data; 2480 2481 if (le32_to_cpu(resp->chan_freq) != chan_freq) { 2482 pr_err("[MAC%u] channel stats freq %u != requested %u\n", 2483 mac->macid, le32_to_cpu(resp->chan_freq), chan_freq); 2484 ret = -EINVAL; 2485 goto out; 2486 } 2487 2488 ret = qtnf_cmd_resp_proc_chan_stat_info(survey, resp->info, 2489 var_data_len); 2490 2491 out: 2492 consume_skb(resp_skb); 2493 2494 return ret; 2495 } 2496 2497 int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif, 2498 struct cfg80211_csa_settings *params) 2499 { 2500 struct qtnf_wmac *mac = vif->mac; 2501 struct qlink_cmd_chan_switch *cmd; 2502 struct sk_buff *cmd_skb; 2503 int ret; 2504 u64 flags = 0; 2505 2506 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid, 2507 QLINK_CMD_CHAN_SWITCH, 2508 sizeof(*cmd)); 2509 if (!cmd_skb) 2510 return -ENOMEM; 2511 2512 if (params->radar_required) 2513 flags |= QLINK_CHAN_SW_RADAR_REQUIRED; 2514 2515 if (params->block_tx) 2516 flags |= QLINK_CHAN_SW_BLOCK_TX; 2517 2518 cmd = (struct qlink_cmd_chan_switch *)cmd_skb->data; 2519 qlink_chandef_cfg2q(¶ms->chandef, &cmd->channel); 2520 cmd->flags = cpu_to_le64(flags); 2521 cmd->beacon_count = params->count; 2522 2523 qtnf_bus_lock(mac->bus); 2524 ret = qtnf_cmd_send(mac->bus, cmd_skb); 2525 qtnf_bus_unlock(mac->bus); 2526 2527 return ret; 2528 } 2529 2530 int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef) 2531 { 2532 struct qtnf_bus *bus = vif->mac->bus; 2533 const struct qlink_resp_channel_get *resp; 2534 struct sk_buff *cmd_skb; 2535 struct sk_buff *resp_skb = NULL; 2536 int ret; 2537 2538 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2539 QLINK_CMD_CHAN_GET, 2540 sizeof(struct qlink_cmd)); 2541 if (!cmd_skb) 2542 return -ENOMEM; 2543 2544 qtnf_bus_lock(bus); 2545 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2546 sizeof(*resp), NULL); 2547 if (ret) 2548 goto out; 2549 2550 resp = (const struct qlink_resp_channel_get *)resp_skb->data; 2551 qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef); 2552 2553 out: 2554 qtnf_bus_unlock(bus); 2555 consume_skb(resp_skb); 2556 2557 return ret; 2558 } 2559 2560 int qtnf_cmd_start_cac(const struct qtnf_vif *vif, 2561 const struct cfg80211_chan_def *chdef, 2562 u32 cac_time_ms) 2563 { 2564 struct qtnf_bus *bus = vif->mac->bus; 2565 struct sk_buff *cmd_skb; 2566 struct qlink_cmd_start_cac *cmd; 2567 int ret; 2568 2569 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2570 QLINK_CMD_START_CAC, 2571 sizeof(*cmd)); 2572 if (!cmd_skb) 2573 return -ENOMEM; 2574 2575 cmd = (struct qlink_cmd_start_cac *)cmd_skb->data; 2576 cmd->cac_time_ms = cpu_to_le32(cac_time_ms); 2577 qlink_chandef_cfg2q(chdef, &cmd->chan); 2578 2579 qtnf_bus_lock(bus); 2580 ret = qtnf_cmd_send(bus, cmd_skb); 2581 if (ret) 2582 goto out; 2583 2584 out: 2585 qtnf_bus_unlock(bus); 2586 2587 return ret; 2588 } 2589 2590 int qtnf_cmd_set_mac_acl(const struct qtnf_vif *vif, 2591 const struct cfg80211_acl_data *params) 2592 { 2593 struct qtnf_bus *bus = vif->mac->bus; 2594 struct sk_buff *cmd_skb; 2595 struct qlink_tlv_hdr *tlv; 2596 size_t acl_size = struct_size(params, mac_addrs, params->n_acl_entries); 2597 int ret; 2598 2599 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2600 QLINK_CMD_SET_MAC_ACL, 2601 sizeof(struct qlink_cmd)); 2602 if (!cmd_skb) 2603 return -ENOMEM; 2604 2605 tlv = skb_put(cmd_skb, sizeof(*tlv) + round_up(acl_size, QLINK_ALIGN)); 2606 tlv->type = cpu_to_le16(QTN_TLV_ID_ACL_DATA); 2607 tlv->len = cpu_to_le16(acl_size); 2608 qlink_acl_data_cfg2q(params, (struct qlink_acl_data *)tlv->val); 2609 2610 qtnf_bus_lock(bus); 2611 ret = qtnf_cmd_send(bus, cmd_skb); 2612 if (ret) 2613 goto out; 2614 2615 out: 2616 qtnf_bus_unlock(bus); 2617 2618 return ret; 2619 } 2620 2621 int qtnf_cmd_send_pm_set(const struct qtnf_vif *vif, u8 pm_mode, int timeout) 2622 { 2623 struct qtnf_bus *bus = vif->mac->bus; 2624 struct sk_buff *cmd_skb; 2625 struct qlink_cmd_pm_set *cmd; 2626 int ret = 0; 2627 2628 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2629 QLINK_CMD_PM_SET, sizeof(*cmd)); 2630 if (!cmd_skb) 2631 return -ENOMEM; 2632 2633 cmd = (struct qlink_cmd_pm_set *)cmd_skb->data; 2634 cmd->pm_mode = pm_mode; 2635 cmd->pm_standby_timer = cpu_to_le32(timeout); 2636 2637 qtnf_bus_lock(bus); 2638 2639 ret = qtnf_cmd_send(bus, cmd_skb); 2640 if (ret) 2641 goto out; 2642 2643 out: 2644 qtnf_bus_unlock(bus); 2645 2646 return ret; 2647 } 2648 2649 int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm) 2650 { 2651 struct qtnf_bus *bus = vif->mac->bus; 2652 const struct qlink_resp_txpwr *resp; 2653 struct sk_buff *resp_skb = NULL; 2654 struct qlink_cmd_txpwr *cmd; 2655 struct sk_buff *cmd_skb; 2656 int ret = 0; 2657 2658 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2659 QLINK_CMD_TXPWR, sizeof(*cmd)); 2660 if (!cmd_skb) 2661 return -ENOMEM; 2662 2663 cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; 2664 cmd->op_type = QLINK_TXPWR_GET; 2665 2666 qtnf_bus_lock(bus); 2667 2668 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2669 sizeof(*resp), NULL); 2670 if (ret) 2671 goto out; 2672 2673 resp = (const struct qlink_resp_txpwr *)resp_skb->data; 2674 *dbm = MBM_TO_DBM(le32_to_cpu(resp->txpwr)); 2675 2676 out: 2677 qtnf_bus_unlock(bus); 2678 consume_skb(resp_skb); 2679 2680 return ret; 2681 } 2682 2683 int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif, 2684 enum nl80211_tx_power_setting type, int mbm) 2685 { 2686 struct qtnf_bus *bus = vif->mac->bus; 2687 const struct qlink_resp_txpwr *resp; 2688 struct sk_buff *resp_skb = NULL; 2689 struct qlink_cmd_txpwr *cmd; 2690 struct sk_buff *cmd_skb; 2691 int ret = 0; 2692 2693 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2694 QLINK_CMD_TXPWR, sizeof(*cmd)); 2695 if (!cmd_skb) 2696 return -ENOMEM; 2697 2698 cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; 2699 cmd->op_type = QLINK_TXPWR_SET; 2700 cmd->txpwr_setting = type; 2701 cmd->txpwr = cpu_to_le32(mbm); 2702 2703 qtnf_bus_lock(bus); 2704 2705 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2706 sizeof(*resp), NULL); 2707 2708 qtnf_bus_unlock(bus); 2709 consume_skb(resp_skb); 2710 2711 return ret; 2712 } 2713 2714 int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif, 2715 const struct cfg80211_wowlan *wowl) 2716 { 2717 struct qtnf_bus *bus = vif->mac->bus; 2718 struct sk_buff *cmd_skb; 2719 struct qlink_cmd_wowlan_set *cmd; 2720 u32 triggers = 0; 2721 int count = 0; 2722 int ret = 0; 2723 2724 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2725 QLINK_CMD_WOWLAN_SET, sizeof(*cmd)); 2726 if (!cmd_skb) 2727 return -ENOMEM; 2728 2729 qtnf_bus_lock(bus); 2730 2731 cmd = (struct qlink_cmd_wowlan_set *)cmd_skb->data; 2732 2733 if (wowl) { 2734 if (wowl->disconnect) 2735 triggers |= QLINK_WOWLAN_TRIG_DISCONNECT; 2736 2737 if (wowl->magic_pkt) 2738 triggers |= QLINK_WOWLAN_TRIG_MAGIC_PKT; 2739 2740 if (wowl->n_patterns && wowl->patterns) { 2741 triggers |= QLINK_WOWLAN_TRIG_PATTERN_PKT; 2742 while (count < wowl->n_patterns) { 2743 qtnf_cmd_skb_put_tlv_arr(cmd_skb, 2744 QTN_TLV_ID_WOWLAN_PATTERN, 2745 wowl->patterns[count].pattern, 2746 wowl->patterns[count].pattern_len); 2747 count++; 2748 } 2749 } 2750 } 2751 2752 cmd->triggers = cpu_to_le32(triggers); 2753 2754 ret = qtnf_cmd_send(bus, cmd_skb); 2755 if (ret) 2756 goto out; 2757 2758 out: 2759 qtnf_bus_unlock(bus); 2760 return ret; 2761 } 2762 2763 int qtnf_cmd_netdev_changeupper(const struct qtnf_vif *vif, int br_domain) 2764 { 2765 struct qtnf_bus *bus = vif->mac->bus; 2766 struct sk_buff *cmd_skb; 2767 struct qlink_cmd_ndev_changeupper *cmd; 2768 int ret; 2769 2770 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2771 QLINK_CMD_NDEV_EVENT, 2772 sizeof(*cmd)); 2773 if (!cmd_skb) 2774 return -ENOMEM; 2775 2776 pr_debug("[VIF%u.%u] set broadcast domain to %d\n", 2777 vif->mac->macid, vif->vifid, br_domain); 2778 2779 cmd = (struct qlink_cmd_ndev_changeupper *)cmd_skb->data; 2780 cmd->nehdr.event = cpu_to_le16(QLINK_NDEV_EVENT_CHANGEUPPER); 2781 cmd->upper_type = QLINK_NDEV_UPPER_TYPE_BRIDGE; 2782 cmd->br_domain = cpu_to_le32(br_domain); 2783 2784 qtnf_bus_lock(bus); 2785 ret = qtnf_cmd_send(bus, cmd_skb); 2786 qtnf_bus_unlock(bus); 2787 2788 if (ret) 2789 pr_err("[VIF%u.%u] failed to set broadcast domain\n", 2790 vif->mac->macid, vif->vifid); 2791 2792 return ret; 2793 } 2794 2795 int qtnf_cmd_send_update_owe(struct qtnf_vif *vif, 2796 struct cfg80211_update_owe_info *owe) 2797 { 2798 struct qlink_cmd_update_owe *cmd; 2799 struct sk_buff *cmd_skb; 2800 int ret; 2801 2802 if (sizeof(*cmd) + owe->ie_len > QTNF_MAX_CMD_BUF_SIZE) { 2803 pr_warn("VIF%u.%u: OWE update IEs too big: %zu\n", 2804 vif->mac->macid, vif->vifid, owe->ie_len); 2805 return -E2BIG; 2806 } 2807 2808 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2809 QLINK_CMD_UPDATE_OWE, 2810 sizeof(*cmd)); 2811 if (!cmd_skb) 2812 return -ENOMEM; 2813 2814 cmd = (struct qlink_cmd_update_owe *)cmd_skb->data; 2815 ether_addr_copy(cmd->peer, owe->peer); 2816 cmd->status = cpu_to_le16(owe->status); 2817 if (owe->ie_len && owe->ie) 2818 qtnf_cmd_skb_put_buffer(cmd_skb, owe->ie, owe->ie_len); 2819 2820 qtnf_bus_lock(vif->mac->bus); 2821 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2822 if (ret) 2823 goto out; 2824 2825 out: 2826 qtnf_bus_unlock(vif->mac->bus); 2827 2828 return ret; 2829 } 2830