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