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 #define QTNF_SCAN_TIME_AUTO 0 15 16 /* Let device itself to select best values for current conditions */ 17 #define QTNF_SCAN_DWELL_ACTIVE_DEFAULT QTNF_SCAN_TIME_AUTO 18 #define QTNF_SCAN_DWELL_PASSIVE_DEFAULT QTNF_SCAN_TIME_AUTO 19 #define QTNF_SCAN_SAMPLE_DURATION_DEFAULT QTNF_SCAN_TIME_AUTO 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 static void qtnf_cmd_scan_set_dwell(struct qtnf_wmac *mac, 2015 struct sk_buff *cmd_skb) 2016 { 2017 struct cfg80211_scan_request *scan_req = mac->scan_req; 2018 u16 dwell_active = QTNF_SCAN_DWELL_ACTIVE_DEFAULT; 2019 u16 dwell_passive = QTNF_SCAN_DWELL_PASSIVE_DEFAULT; 2020 u16 duration = QTNF_SCAN_SAMPLE_DURATION_DEFAULT; 2021 2022 if (scan_req->duration) { 2023 dwell_active = scan_req->duration; 2024 dwell_passive = scan_req->duration; 2025 } 2026 2027 pr_debug("MAC%u: %s scan dwell active=%u, passive=%u, duration=%u\n", 2028 mac->macid, 2029 scan_req->duration_mandatory ? "mandatory" : "max", 2030 dwell_active, dwell_passive, duration); 2031 2032 qtnf_cmd_skb_put_tlv_u32(cmd_skb, 2033 QTN_TLV_ID_SCAN_DWELL_ACTIVE, 2034 dwell_active); 2035 qtnf_cmd_skb_put_tlv_u32(cmd_skb, 2036 QTN_TLV_ID_SCAN_DWELL_PASSIVE, 2037 dwell_passive); 2038 qtnf_cmd_skb_put_tlv_u32(cmd_skb, 2039 QTN_TLV_ID_SCAN_SAMPLE_DURATION, 2040 duration); 2041 } 2042 2043 int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 2044 { 2045 struct sk_buff *cmd_skb; 2046 struct ieee80211_channel *sc; 2047 struct cfg80211_scan_request *scan_req = mac->scan_req; 2048 int n_channels; 2049 int count = 0; 2050 int ret; 2051 2052 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2053 QLINK_CMD_SCAN, 2054 sizeof(struct qlink_cmd)); 2055 if (!cmd_skb) 2056 return -ENOMEM; 2057 2058 qtnf_bus_lock(mac->bus); 2059 2060 if (scan_req->n_ssids != 0) { 2061 while (count < scan_req->n_ssids) { 2062 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, 2063 scan_req->ssids[count].ssid, 2064 scan_req->ssids[count].ssid_len); 2065 count++; 2066 } 2067 } 2068 2069 if (scan_req->ie_len != 0) 2070 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ, 2071 scan_req->ie, scan_req->ie_len); 2072 2073 if (scan_req->n_channels) { 2074 n_channels = scan_req->n_channels; 2075 count = 0; 2076 2077 while (n_channels != 0) { 2078 sc = scan_req->channels[count]; 2079 if (sc->flags & IEEE80211_CHAN_DISABLED) { 2080 n_channels--; 2081 continue; 2082 } 2083 2084 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n", 2085 mac->macid, sc->hw_value, sc->center_freq, 2086 sc->flags); 2087 2088 qtnf_cmd_channel_tlv_add(cmd_skb, sc); 2089 n_channels--; 2090 count++; 2091 } 2092 } 2093 2094 qtnf_cmd_scan_set_dwell(mac, cmd_skb); 2095 2096 if (scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 2097 pr_debug("MAC%u: scan with random addr=%pM, mask=%pM\n", 2098 mac->macid, 2099 scan_req->mac_addr, scan_req->mac_addr_mask); 2100 2101 qtnf_cmd_randmac_tlv_add(cmd_skb, scan_req->mac_addr, 2102 scan_req->mac_addr_mask); 2103 } 2104 2105 if (scan_req->flags & NL80211_SCAN_FLAG_FLUSH) { 2106 pr_debug("MAC%u: flush cache before scan\n", mac->macid); 2107 2108 qtnf_cmd_skb_put_tlv_tag(cmd_skb, QTN_TLV_ID_SCAN_FLUSH); 2109 } 2110 2111 ret = qtnf_cmd_send(mac->bus, cmd_skb); 2112 if (ret) 2113 goto out; 2114 2115 out: 2116 qtnf_bus_unlock(mac->bus); 2117 2118 return ret; 2119 } 2120 2121 int qtnf_cmd_send_connect(struct qtnf_vif *vif, 2122 struct cfg80211_connect_params *sme) 2123 { 2124 struct sk_buff *cmd_skb; 2125 struct qlink_cmd_connect *cmd; 2126 struct qlink_auth_encr *aen; 2127 int ret; 2128 int i; 2129 u32 connect_flags = 0; 2130 2131 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2132 QLINK_CMD_CONNECT, 2133 sizeof(*cmd)); 2134 if (!cmd_skb) 2135 return -ENOMEM; 2136 2137 cmd = (struct qlink_cmd_connect *)cmd_skb->data; 2138 2139 ether_addr_copy(cmd->bssid, vif->bssid); 2140 2141 if (sme->bssid_hint) 2142 ether_addr_copy(cmd->bssid_hint, sme->bssid_hint); 2143 else 2144 eth_zero_addr(cmd->bssid_hint); 2145 2146 if (sme->prev_bssid) 2147 ether_addr_copy(cmd->prev_bssid, sme->prev_bssid); 2148 else 2149 eth_zero_addr(cmd->prev_bssid); 2150 2151 if ((sme->bg_scan_period >= 0) && 2152 (sme->bg_scan_period <= SHRT_MAX)) 2153 cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period); 2154 else 2155 cmd->bg_scan_period = cpu_to_le16(-1); /* use default value */ 2156 2157 if (sme->flags & ASSOC_REQ_DISABLE_HT) 2158 connect_flags |= QLINK_STA_CONNECT_DISABLE_HT; 2159 if (sme->flags & ASSOC_REQ_DISABLE_VHT) 2160 connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT; 2161 if (sme->flags & ASSOC_REQ_USE_RRM) 2162 connect_flags |= QLINK_STA_CONNECT_USE_RRM; 2163 2164 cmd->flags = cpu_to_le32(connect_flags); 2165 memcpy(&cmd->ht_capa, &sme->ht_capa, sizeof(cmd->ht_capa)); 2166 memcpy(&cmd->ht_capa_mask, &sme->ht_capa_mask, 2167 sizeof(cmd->ht_capa_mask)); 2168 memcpy(&cmd->vht_capa, &sme->vht_capa, sizeof(cmd->vht_capa)); 2169 memcpy(&cmd->vht_capa_mask, &sme->vht_capa_mask, 2170 sizeof(cmd->vht_capa_mask)); 2171 cmd->pbss = sme->pbss; 2172 2173 aen = &cmd->aen; 2174 aen->auth_type = sme->auth_type; 2175 aen->privacy = !!sme->privacy; 2176 cmd->mfp = sme->mfp; 2177 aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions); 2178 aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group); 2179 aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise); 2180 2181 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 2182 aen->ciphers_pairwise[i] = 2183 cpu_to_le32(sme->crypto.ciphers_pairwise[i]); 2184 2185 aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites); 2186 2187 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 2188 aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]); 2189 2190 aen->control_port = sme->crypto.control_port; 2191 aen->control_port_no_encrypt = 2192 sme->crypto.control_port_no_encrypt; 2193 aen->control_port_ethertype = 2194 cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype)); 2195 2196 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid, 2197 sme->ssid_len); 2198 2199 if (sme->ie_len != 0) 2200 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ, 2201 sme->ie, sme->ie_len); 2202 2203 if (sme->channel) 2204 qtnf_cmd_channel_tlv_add(cmd_skb, sme->channel); 2205 2206 qtnf_bus_lock(vif->mac->bus); 2207 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2208 if (ret) 2209 goto out; 2210 2211 out: 2212 qtnf_bus_unlock(vif->mac->bus); 2213 2214 return ret; 2215 } 2216 2217 int qtnf_cmd_send_external_auth(struct qtnf_vif *vif, 2218 struct cfg80211_external_auth_params *auth) 2219 { 2220 struct sk_buff *cmd_skb; 2221 struct qlink_cmd_external_auth *cmd; 2222 int ret; 2223 2224 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2225 QLINK_CMD_EXTERNAL_AUTH, 2226 sizeof(*cmd)); 2227 if (!cmd_skb) 2228 return -ENOMEM; 2229 2230 cmd = (struct qlink_cmd_external_auth *)cmd_skb->data; 2231 2232 ether_addr_copy(cmd->bssid, auth->bssid); 2233 cmd->status = cpu_to_le16(auth->status); 2234 2235 qtnf_bus_lock(vif->mac->bus); 2236 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2237 if (ret) 2238 goto out; 2239 2240 out: 2241 qtnf_bus_unlock(vif->mac->bus); 2242 2243 return ret; 2244 } 2245 2246 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code) 2247 { 2248 struct sk_buff *cmd_skb; 2249 struct qlink_cmd_disconnect *cmd; 2250 int ret; 2251 2252 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2253 QLINK_CMD_DISCONNECT, 2254 sizeof(*cmd)); 2255 if (!cmd_skb) 2256 return -ENOMEM; 2257 2258 qtnf_bus_lock(vif->mac->bus); 2259 2260 cmd = (struct qlink_cmd_disconnect *)cmd_skb->data; 2261 cmd->reason = cpu_to_le16(reason_code); 2262 2263 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2264 if (ret) 2265 goto out; 2266 2267 out: 2268 qtnf_bus_unlock(vif->mac->bus); 2269 2270 return ret; 2271 } 2272 2273 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up) 2274 { 2275 struct sk_buff *cmd_skb; 2276 struct qlink_cmd_updown *cmd; 2277 int ret; 2278 2279 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2280 QLINK_CMD_UPDOWN_INTF, 2281 sizeof(*cmd)); 2282 if (!cmd_skb) 2283 return -ENOMEM; 2284 2285 cmd = (struct qlink_cmd_updown *)cmd_skb->data; 2286 cmd->if_up = !!up; 2287 2288 qtnf_bus_lock(vif->mac->bus); 2289 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb); 2290 if (ret) 2291 goto out; 2292 2293 out: 2294 qtnf_bus_unlock(vif->mac->bus); 2295 2296 return ret; 2297 } 2298 2299 int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req, 2300 bool slave_radar, bool dfs_offload) 2301 { 2302 struct wiphy *wiphy = priv_to_wiphy(mac); 2303 struct qtnf_bus *bus = mac->bus; 2304 struct sk_buff *cmd_skb; 2305 int ret; 2306 struct qlink_cmd_reg_notify *cmd; 2307 enum nl80211_band band; 2308 const struct ieee80211_supported_band *cfg_band; 2309 2310 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2311 QLINK_CMD_REG_NOTIFY, 2312 sizeof(*cmd)); 2313 if (!cmd_skb) 2314 return -ENOMEM; 2315 2316 cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data; 2317 cmd->alpha2[0] = req->alpha2[0]; 2318 cmd->alpha2[1] = req->alpha2[1]; 2319 2320 switch (req->initiator) { 2321 case NL80211_REGDOM_SET_BY_CORE: 2322 cmd->initiator = QLINK_REGDOM_SET_BY_CORE; 2323 break; 2324 case NL80211_REGDOM_SET_BY_USER: 2325 cmd->initiator = QLINK_REGDOM_SET_BY_USER; 2326 break; 2327 case NL80211_REGDOM_SET_BY_DRIVER: 2328 cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER; 2329 break; 2330 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2331 cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE; 2332 break; 2333 } 2334 2335 switch (req->user_reg_hint_type) { 2336 case NL80211_USER_REG_HINT_USER: 2337 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER; 2338 break; 2339 case NL80211_USER_REG_HINT_CELL_BASE: 2340 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE; 2341 break; 2342 case NL80211_USER_REG_HINT_INDOOR: 2343 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR; 2344 break; 2345 } 2346 2347 switch (req->dfs_region) { 2348 case NL80211_DFS_FCC: 2349 cmd->dfs_region = QLINK_DFS_FCC; 2350 break; 2351 case NL80211_DFS_ETSI: 2352 cmd->dfs_region = QLINK_DFS_ETSI; 2353 break; 2354 case NL80211_DFS_JP: 2355 cmd->dfs_region = QLINK_DFS_JP; 2356 break; 2357 default: 2358 cmd->dfs_region = QLINK_DFS_UNSET; 2359 break; 2360 } 2361 2362 cmd->slave_radar = slave_radar; 2363 cmd->dfs_offload = dfs_offload; 2364 cmd->num_channels = 0; 2365 2366 for (band = 0; band < NUM_NL80211_BANDS; band++) { 2367 unsigned int i; 2368 2369 cfg_band = wiphy->bands[band]; 2370 if (!cfg_band) 2371 continue; 2372 2373 cmd->num_channels += cfg_band->n_channels; 2374 2375 for (i = 0; i < cfg_band->n_channels; ++i) { 2376 qtnf_cmd_channel_tlv_add(cmd_skb, 2377 &cfg_band->channels[i]); 2378 } 2379 } 2380 2381 qtnf_bus_lock(bus); 2382 ret = qtnf_cmd_send(bus, cmd_skb); 2383 qtnf_bus_unlock(bus); 2384 2385 return ret; 2386 } 2387 2388 static int 2389 qtnf_cmd_resp_proc_chan_stat_info(struct survey_info *survey, 2390 const u8 *payload, size_t payload_len) 2391 { 2392 const struct qlink_chan_stats *stats = NULL; 2393 const struct qlink_tlv_hdr *tlv; 2394 u16 tlv_value_len; 2395 u16 tlv_type; 2396 const u8 *map = NULL; 2397 unsigned int map_len = 0; 2398 unsigned int stats_len = 0; 2399 2400 qlink_for_each_tlv(tlv, payload, payload_len) { 2401 tlv_type = le16_to_cpu(tlv->type); 2402 tlv_value_len = le16_to_cpu(tlv->len); 2403 2404 switch (tlv_type) { 2405 case QTN_TLV_ID_BITMAP: 2406 map = tlv->val; 2407 map_len = tlv_value_len; 2408 break; 2409 case QTN_TLV_ID_CHANNEL_STATS: 2410 stats = (struct qlink_chan_stats *)tlv->val; 2411 stats_len = tlv_value_len; 2412 break; 2413 default: 2414 pr_info("Unknown TLV type: %#x\n", tlv_type); 2415 break; 2416 } 2417 } 2418 2419 if (!qlink_tlv_parsing_ok(tlv, payload, payload_len)) { 2420 pr_err("Malformed TLV buffer\n"); 2421 return -EINVAL; 2422 } 2423 2424 if (!map || !stats) 2425 return 0; 2426 2427 #define qtnf_chan_stat_avail(stat_name, bitn) \ 2428 (qtnf_utils_is_bit_set(map, bitn, map_len) && \ 2429 (offsetofend(struct qlink_chan_stats, stat_name) <= stats_len)) 2430 2431 if (qtnf_chan_stat_avail(time_on, QLINK_CHAN_STAT_TIME_ON)) { 2432 survey->filled |= SURVEY_INFO_TIME; 2433 survey->time = le64_to_cpu(stats->time_on); 2434 } 2435 2436 if (qtnf_chan_stat_avail(time_tx, QLINK_CHAN_STAT_TIME_TX)) { 2437 survey->filled |= SURVEY_INFO_TIME_TX; 2438 survey->time_tx = le64_to_cpu(stats->time_tx); 2439 } 2440 2441 if (qtnf_chan_stat_avail(time_rx, QLINK_CHAN_STAT_TIME_RX)) { 2442 survey->filled |= SURVEY_INFO_TIME_RX; 2443 survey->time_rx = le64_to_cpu(stats->time_rx); 2444 } 2445 2446 if (qtnf_chan_stat_avail(cca_busy, QLINK_CHAN_STAT_CCA_BUSY)) { 2447 survey->filled |= SURVEY_INFO_TIME_BUSY; 2448 survey->time_busy = le64_to_cpu(stats->cca_busy); 2449 } 2450 2451 if (qtnf_chan_stat_avail(cca_busy_ext, QLINK_CHAN_STAT_CCA_BUSY_EXT)) { 2452 survey->filled |= SURVEY_INFO_TIME_EXT_BUSY; 2453 survey->time_ext_busy = le64_to_cpu(stats->cca_busy_ext); 2454 } 2455 2456 if (qtnf_chan_stat_avail(time_scan, QLINK_CHAN_STAT_TIME_SCAN)) { 2457 survey->filled |= SURVEY_INFO_TIME_SCAN; 2458 survey->time_scan = le64_to_cpu(stats->time_scan); 2459 } 2460 2461 if (qtnf_chan_stat_avail(chan_noise, QLINK_CHAN_STAT_CHAN_NOISE)) { 2462 survey->filled |= SURVEY_INFO_NOISE_DBM; 2463 survey->noise = stats->chan_noise; 2464 } 2465 2466 #undef qtnf_chan_stat_avail 2467 2468 return 0; 2469 } 2470 2471 int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u32 chan_freq, 2472 struct survey_info *survey) 2473 { 2474 struct sk_buff *cmd_skb, *resp_skb = NULL; 2475 struct qlink_cmd_get_chan_stats *cmd; 2476 struct qlink_resp_get_chan_stats *resp; 2477 size_t var_data_len = 0; 2478 int ret = 0; 2479 2480 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2481 QLINK_CMD_CHAN_STATS, 2482 sizeof(*cmd)); 2483 if (!cmd_skb) 2484 return -ENOMEM; 2485 2486 cmd = (struct qlink_cmd_get_chan_stats *)cmd_skb->data; 2487 cmd->channel_freq = cpu_to_le32(chan_freq); 2488 2489 qtnf_bus_lock(mac->bus); 2490 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, 2491 sizeof(*resp), &var_data_len); 2492 qtnf_bus_unlock(mac->bus); 2493 2494 if (ret) 2495 goto out; 2496 2497 resp = (struct qlink_resp_get_chan_stats *)resp_skb->data; 2498 2499 if (le32_to_cpu(resp->chan_freq) != chan_freq) { 2500 pr_err("[MAC%u] channel stats freq %u != requested %u\n", 2501 mac->macid, le32_to_cpu(resp->chan_freq), chan_freq); 2502 ret = -EINVAL; 2503 goto out; 2504 } 2505 2506 ret = qtnf_cmd_resp_proc_chan_stat_info(survey, resp->info, 2507 var_data_len); 2508 2509 out: 2510 consume_skb(resp_skb); 2511 2512 return ret; 2513 } 2514 2515 int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif, 2516 struct cfg80211_csa_settings *params) 2517 { 2518 struct qtnf_wmac *mac = vif->mac; 2519 struct qlink_cmd_chan_switch *cmd; 2520 struct sk_buff *cmd_skb; 2521 int ret; 2522 2523 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid, 2524 QLINK_CMD_CHAN_SWITCH, 2525 sizeof(*cmd)); 2526 if (!cmd_skb) 2527 return -ENOMEM; 2528 2529 qtnf_bus_lock(mac->bus); 2530 2531 cmd = (struct qlink_cmd_chan_switch *)cmd_skb->data; 2532 cmd->channel = cpu_to_le16(params->chandef.chan->hw_value); 2533 cmd->radar_required = params->radar_required; 2534 cmd->block_tx = params->block_tx; 2535 cmd->beacon_count = params->count; 2536 2537 ret = qtnf_cmd_send(mac->bus, cmd_skb); 2538 if (ret) 2539 goto out; 2540 2541 out: 2542 qtnf_bus_unlock(mac->bus); 2543 2544 return ret; 2545 } 2546 2547 int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef) 2548 { 2549 struct qtnf_bus *bus = vif->mac->bus; 2550 const struct qlink_resp_channel_get *resp; 2551 struct sk_buff *cmd_skb; 2552 struct sk_buff *resp_skb = NULL; 2553 int ret; 2554 2555 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2556 QLINK_CMD_CHAN_GET, 2557 sizeof(struct qlink_cmd)); 2558 if (!cmd_skb) 2559 return -ENOMEM; 2560 2561 qtnf_bus_lock(bus); 2562 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2563 sizeof(*resp), NULL); 2564 if (ret) 2565 goto out; 2566 2567 resp = (const struct qlink_resp_channel_get *)resp_skb->data; 2568 qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef); 2569 2570 out: 2571 qtnf_bus_unlock(bus); 2572 consume_skb(resp_skb); 2573 2574 return ret; 2575 } 2576 2577 int qtnf_cmd_start_cac(const struct qtnf_vif *vif, 2578 const struct cfg80211_chan_def *chdef, 2579 u32 cac_time_ms) 2580 { 2581 struct qtnf_bus *bus = vif->mac->bus; 2582 struct sk_buff *cmd_skb; 2583 struct qlink_cmd_start_cac *cmd; 2584 int ret; 2585 2586 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2587 QLINK_CMD_START_CAC, 2588 sizeof(*cmd)); 2589 if (!cmd_skb) 2590 return -ENOMEM; 2591 2592 cmd = (struct qlink_cmd_start_cac *)cmd_skb->data; 2593 cmd->cac_time_ms = cpu_to_le32(cac_time_ms); 2594 qlink_chandef_cfg2q(chdef, &cmd->chan); 2595 2596 qtnf_bus_lock(bus); 2597 ret = qtnf_cmd_send(bus, cmd_skb); 2598 if (ret) 2599 goto out; 2600 2601 out: 2602 qtnf_bus_unlock(bus); 2603 2604 return ret; 2605 } 2606 2607 int qtnf_cmd_set_mac_acl(const struct qtnf_vif *vif, 2608 const struct cfg80211_acl_data *params) 2609 { 2610 struct qtnf_bus *bus = vif->mac->bus; 2611 struct sk_buff *cmd_skb; 2612 struct qlink_tlv_hdr *tlv; 2613 size_t acl_size = struct_size(params, mac_addrs, params->n_acl_entries); 2614 int ret; 2615 2616 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2617 QLINK_CMD_SET_MAC_ACL, 2618 sizeof(struct qlink_cmd)); 2619 if (!cmd_skb) 2620 return -ENOMEM; 2621 2622 tlv = skb_put(cmd_skb, sizeof(*tlv) + round_up(acl_size, QLINK_ALIGN)); 2623 tlv->type = cpu_to_le16(QTN_TLV_ID_ACL_DATA); 2624 tlv->len = cpu_to_le16(acl_size); 2625 qlink_acl_data_cfg2q(params, (struct qlink_acl_data *)tlv->val); 2626 2627 qtnf_bus_lock(bus); 2628 ret = qtnf_cmd_send(bus, cmd_skb); 2629 if (ret) 2630 goto out; 2631 2632 out: 2633 qtnf_bus_unlock(bus); 2634 2635 return ret; 2636 } 2637 2638 int qtnf_cmd_send_pm_set(const struct qtnf_vif *vif, u8 pm_mode, int timeout) 2639 { 2640 struct qtnf_bus *bus = vif->mac->bus; 2641 struct sk_buff *cmd_skb; 2642 struct qlink_cmd_pm_set *cmd; 2643 int ret = 0; 2644 2645 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2646 QLINK_CMD_PM_SET, sizeof(*cmd)); 2647 if (!cmd_skb) 2648 return -ENOMEM; 2649 2650 cmd = (struct qlink_cmd_pm_set *)cmd_skb->data; 2651 cmd->pm_mode = pm_mode; 2652 cmd->pm_standby_timer = cpu_to_le32(timeout); 2653 2654 qtnf_bus_lock(bus); 2655 2656 ret = qtnf_cmd_send(bus, cmd_skb); 2657 if (ret) 2658 goto out; 2659 2660 out: 2661 qtnf_bus_unlock(bus); 2662 2663 return ret; 2664 } 2665 2666 int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm) 2667 { 2668 struct qtnf_bus *bus = vif->mac->bus; 2669 const struct qlink_resp_txpwr *resp; 2670 struct sk_buff *resp_skb = NULL; 2671 struct qlink_cmd_txpwr *cmd; 2672 struct sk_buff *cmd_skb; 2673 int ret = 0; 2674 2675 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2676 QLINK_CMD_TXPWR, sizeof(*cmd)); 2677 if (!cmd_skb) 2678 return -ENOMEM; 2679 2680 cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; 2681 cmd->op_type = QLINK_TXPWR_GET; 2682 2683 qtnf_bus_lock(bus); 2684 2685 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2686 sizeof(*resp), NULL); 2687 if (ret) 2688 goto out; 2689 2690 resp = (const struct qlink_resp_txpwr *)resp_skb->data; 2691 *dbm = MBM_TO_DBM(le32_to_cpu(resp->txpwr)); 2692 2693 out: 2694 qtnf_bus_unlock(bus); 2695 consume_skb(resp_skb); 2696 2697 return ret; 2698 } 2699 2700 int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif, 2701 enum nl80211_tx_power_setting type, int mbm) 2702 { 2703 struct qtnf_bus *bus = vif->mac->bus; 2704 const struct qlink_resp_txpwr *resp; 2705 struct sk_buff *resp_skb = NULL; 2706 struct qlink_cmd_txpwr *cmd; 2707 struct sk_buff *cmd_skb; 2708 int ret = 0; 2709 2710 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2711 QLINK_CMD_TXPWR, sizeof(*cmd)); 2712 if (!cmd_skb) 2713 return -ENOMEM; 2714 2715 cmd = (struct qlink_cmd_txpwr *)cmd_skb->data; 2716 cmd->op_type = QLINK_TXPWR_SET; 2717 cmd->txpwr_setting = type; 2718 cmd->txpwr = cpu_to_le32(mbm); 2719 2720 qtnf_bus_lock(bus); 2721 2722 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, 2723 sizeof(*resp), NULL); 2724 2725 qtnf_bus_unlock(bus); 2726 consume_skb(resp_skb); 2727 2728 return ret; 2729 } 2730 2731 int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif, 2732 const struct cfg80211_wowlan *wowl) 2733 { 2734 struct qtnf_bus *bus = vif->mac->bus; 2735 struct sk_buff *cmd_skb; 2736 struct qlink_cmd_wowlan_set *cmd; 2737 u32 triggers = 0; 2738 int count = 0; 2739 int ret = 0; 2740 2741 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2742 QLINK_CMD_WOWLAN_SET, sizeof(*cmd)); 2743 if (!cmd_skb) 2744 return -ENOMEM; 2745 2746 qtnf_bus_lock(bus); 2747 2748 cmd = (struct qlink_cmd_wowlan_set *)cmd_skb->data; 2749 2750 if (wowl) { 2751 if (wowl->disconnect) 2752 triggers |= QLINK_WOWLAN_TRIG_DISCONNECT; 2753 2754 if (wowl->magic_pkt) 2755 triggers |= QLINK_WOWLAN_TRIG_MAGIC_PKT; 2756 2757 if (wowl->n_patterns && wowl->patterns) { 2758 triggers |= QLINK_WOWLAN_TRIG_PATTERN_PKT; 2759 while (count < wowl->n_patterns) { 2760 qtnf_cmd_skb_put_tlv_arr(cmd_skb, 2761 QTN_TLV_ID_WOWLAN_PATTERN, 2762 wowl->patterns[count].pattern, 2763 wowl->patterns[count].pattern_len); 2764 count++; 2765 } 2766 } 2767 } 2768 2769 cmd->triggers = cpu_to_le32(triggers); 2770 2771 ret = qtnf_cmd_send(bus, cmd_skb); 2772 if (ret) 2773 goto out; 2774 2775 out: 2776 qtnf_bus_unlock(bus); 2777 return ret; 2778 } 2779 2780 int qtnf_cmd_netdev_changeupper(const struct qtnf_vif *vif, int br_domain) 2781 { 2782 struct qtnf_bus *bus = vif->mac->bus; 2783 struct sk_buff *cmd_skb; 2784 struct qlink_cmd_ndev_changeupper *cmd; 2785 int ret; 2786 2787 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2788 QLINK_CMD_NDEV_EVENT, 2789 sizeof(*cmd)); 2790 if (!cmd_skb) 2791 return -ENOMEM; 2792 2793 pr_debug("[VIF%u.%u] set broadcast domain to %d\n", 2794 vif->mac->macid, vif->vifid, br_domain); 2795 2796 cmd = (struct qlink_cmd_ndev_changeupper *)cmd_skb->data; 2797 cmd->nehdr.event = cpu_to_le16(QLINK_NDEV_EVENT_CHANGEUPPER); 2798 cmd->upper_type = QLINK_NDEV_UPPER_TYPE_BRIDGE; 2799 cmd->br_domain = cpu_to_le32(br_domain); 2800 2801 qtnf_bus_lock(bus); 2802 ret = qtnf_cmd_send(bus, cmd_skb); 2803 qtnf_bus_unlock(bus); 2804 2805 if (ret) 2806 pr_err("[VIF%u.%u] failed to set broadcast domain\n", 2807 vif->mac->macid, vif->vifid); 2808 2809 return ret; 2810 } 2811