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