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