1 /* 2 * Copyright (c) 2015-2016 Quantenna Communications, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15 16 #include <linux/types.h> 17 #include <linux/skbuff.h> 18 19 #include "cfg80211.h" 20 #include "core.h" 21 #include "qlink.h" 22 #include "qlink_util.h" 23 #include "bus.h" 24 #include "commands.h" 25 26 static int qtnf_cmd_check_reply_header(const struct qlink_resp *resp, 27 u16 cmd_id, u8 mac_id, u8 vif_id, 28 size_t resp_size) 29 { 30 if (unlikely(le16_to_cpu(resp->cmd_id) != cmd_id)) { 31 pr_warn("VIF%u.%u CMD%x: bad cmd_id in response: 0x%.4X\n", 32 mac_id, vif_id, cmd_id, le16_to_cpu(resp->cmd_id)); 33 return -EINVAL; 34 } 35 36 if (unlikely(resp->macid != mac_id)) { 37 pr_warn("VIF%u.%u CMD%x: bad MAC in response: %u\n", 38 mac_id, vif_id, cmd_id, resp->macid); 39 return -EINVAL; 40 } 41 42 if (unlikely(resp->vifid != vif_id)) { 43 pr_warn("VIF%u.%u CMD%x: bad VIF in response: %u\n", 44 mac_id, vif_id, cmd_id, resp->vifid); 45 return -EINVAL; 46 } 47 48 if (unlikely(le16_to_cpu(resp->mhdr.len) < resp_size)) { 49 pr_warn("VIF%u.%u CMD%x: bad response size %u < %zu\n", 50 mac_id, vif_id, cmd_id, 51 le16_to_cpu(resp->mhdr.len), resp_size); 52 return -ENOSPC; 53 } 54 55 return 0; 56 } 57 58 static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus, 59 struct sk_buff *cmd_skb, 60 struct sk_buff **response_skb, 61 u16 *result_code, 62 size_t const_resp_size, 63 size_t *var_resp_size) 64 { 65 struct qlink_cmd *cmd; 66 const struct qlink_resp *resp; 67 struct sk_buff *resp_skb = NULL; 68 u16 cmd_id; 69 u8 mac_id, vif_id; 70 int ret; 71 72 cmd = (struct qlink_cmd *)cmd_skb->data; 73 cmd_id = le16_to_cpu(cmd->cmd_id); 74 mac_id = cmd->macid; 75 vif_id = cmd->vifid; 76 cmd->mhdr.len = cpu_to_le16(cmd_skb->len); 77 78 if (unlikely(bus->fw_state != QTNF_FW_STATE_ACTIVE && 79 le16_to_cpu(cmd->cmd_id) != QLINK_CMD_FW_INIT)) { 80 pr_warn("VIF%u.%u: drop cmd 0x%.4X in fw state %d\n", 81 mac_id, vif_id, le16_to_cpu(cmd->cmd_id), 82 bus->fw_state); 83 return -ENODEV; 84 } 85 86 pr_debug("VIF%u.%u cmd=0x%.4X\n", mac_id, vif_id, 87 le16_to_cpu(cmd->cmd_id)); 88 89 ret = qtnf_trans_send_cmd_with_resp(bus, cmd_skb, &resp_skb); 90 91 if (unlikely(ret)) 92 goto out; 93 94 resp = (const struct qlink_resp *)resp_skb->data; 95 ret = qtnf_cmd_check_reply_header(resp, cmd_id, mac_id, vif_id, 96 const_resp_size); 97 98 if (unlikely(ret)) 99 goto out; 100 101 if (likely(result_code)) 102 *result_code = le16_to_cpu(resp->result); 103 104 /* Return length of variable part of response */ 105 if (response_skb && var_resp_size) 106 *var_resp_size = le16_to_cpu(resp->mhdr.len) - const_resp_size; 107 108 out: 109 if (response_skb) 110 *response_skb = resp_skb; 111 else 112 consume_skb(resp_skb); 113 114 return ret; 115 } 116 117 static inline int qtnf_cmd_send(struct qtnf_bus *bus, 118 struct sk_buff *cmd_skb, 119 u16 *result_code) 120 { 121 return qtnf_cmd_send_with_reply(bus, cmd_skb, NULL, result_code, 122 sizeof(struct qlink_resp), NULL); 123 } 124 125 static struct sk_buff *qtnf_cmd_alloc_new_cmdskb(u8 macid, u8 vifid, u16 cmd_no, 126 size_t cmd_size) 127 { 128 struct qlink_cmd *cmd; 129 struct sk_buff *cmd_skb; 130 131 cmd_skb = __dev_alloc_skb(sizeof(*cmd) + 132 QTNF_MAX_CMD_BUF_SIZE, GFP_KERNEL); 133 if (unlikely(!cmd_skb)) { 134 pr_err("VIF%u.%u CMD %u: alloc failed\n", macid, vifid, cmd_no); 135 return NULL; 136 } 137 138 skb_put_zero(cmd_skb, cmd_size); 139 140 cmd = (struct qlink_cmd *)cmd_skb->data; 141 cmd->mhdr.len = cpu_to_le16(cmd_skb->len); 142 cmd->mhdr.type = cpu_to_le16(QLINK_MSG_TYPE_CMD); 143 cmd->cmd_id = cpu_to_le16(cmd_no); 144 cmd->macid = macid; 145 cmd->vifid = vifid; 146 147 return cmd_skb; 148 } 149 150 int qtnf_cmd_send_start_ap(struct qtnf_vif *vif) 151 { 152 struct sk_buff *cmd_skb; 153 u16 res_code = QLINK_CMD_RESULT_OK; 154 int ret; 155 156 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 157 QLINK_CMD_START_AP, 158 sizeof(struct qlink_cmd)); 159 if (unlikely(!cmd_skb)) 160 return -ENOMEM; 161 162 qtnf_bus_lock(vif->mac->bus); 163 164 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 165 166 if (unlikely(ret)) 167 goto out; 168 169 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 170 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 171 vif->vifid, res_code); 172 ret = -EFAULT; 173 goto out; 174 } 175 176 netif_carrier_on(vif->netdev); 177 178 out: 179 qtnf_bus_unlock(vif->mac->bus); 180 return ret; 181 } 182 183 int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, 184 const struct cfg80211_ap_settings *s) 185 { 186 struct sk_buff *cmd_skb; 187 struct qlink_cmd_config_ap *cmd; 188 struct qlink_auth_encr *aen; 189 u16 res_code = QLINK_CMD_RESULT_OK; 190 int ret; 191 int i; 192 193 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 194 QLINK_CMD_CONFIG_AP, 195 sizeof(*cmd)); 196 if (unlikely(!cmd_skb)) 197 return -ENOMEM; 198 199 cmd = (struct qlink_cmd_config_ap *)cmd_skb->data; 200 cmd->dtim_period = s->dtim_period; 201 cmd->beacon_interval = cpu_to_le16(s->beacon_interval); 202 cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid); 203 cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout); 204 cmd->smps_mode = s->smps_mode; 205 cmd->p2p_ctwindow = s->p2p_ctwindow; 206 cmd->p2p_opp_ps = s->p2p_opp_ps; 207 cmd->pbss = s->pbss; 208 cmd->ht_required = s->ht_required; 209 cmd->vht_required = s->vht_required; 210 211 aen = &cmd->aen; 212 aen->auth_type = s->auth_type; 213 aen->privacy = !!s->privacy; 214 aen->mfp = 0; 215 aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions); 216 aen->cipher_group = cpu_to_le32(s->crypto.cipher_group); 217 aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise); 218 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 219 aen->ciphers_pairwise[i] = 220 cpu_to_le32(s->crypto.ciphers_pairwise[i]); 221 aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites); 222 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 223 aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]); 224 aen->control_port = s->crypto.control_port; 225 aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt; 226 aen->control_port_ethertype = 227 cpu_to_le16(be16_to_cpu(s->crypto.control_port_ethertype)); 228 229 if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN) 230 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid, 231 s->ssid_len); 232 233 if (cfg80211_chandef_valid(&s->chandef)) { 234 struct qlink_tlv_chandef *chtlv = 235 (struct qlink_tlv_chandef *)skb_put(cmd_skb, 236 sizeof(*chtlv)); 237 238 chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF); 239 chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) - 240 sizeof(chtlv->hdr)); 241 qlink_chandef_cfg2q(&s->chandef, &chtlv->chan); 242 } 243 244 qtnf_bus_lock(vif->mac->bus); 245 246 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 247 248 if (unlikely(ret)) 249 goto out; 250 251 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 252 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 253 vif->vifid, res_code); 254 ret = -EFAULT; 255 goto out; 256 } 257 258 out: 259 qtnf_bus_unlock(vif->mac->bus); 260 return ret; 261 } 262 263 int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif) 264 { 265 struct sk_buff *cmd_skb; 266 u16 res_code = QLINK_CMD_RESULT_OK; 267 int ret; 268 269 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 270 QLINK_CMD_STOP_AP, 271 sizeof(struct qlink_cmd)); 272 if (unlikely(!cmd_skb)) 273 return -ENOMEM; 274 275 qtnf_bus_lock(vif->mac->bus); 276 277 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 278 279 if (unlikely(ret)) 280 goto out; 281 282 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 283 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 284 vif->vifid, res_code); 285 ret = -EFAULT; 286 goto out; 287 } 288 289 netif_carrier_off(vif->netdev); 290 291 out: 292 qtnf_bus_unlock(vif->mac->bus); 293 return ret; 294 } 295 296 int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg) 297 { 298 struct sk_buff *cmd_skb; 299 struct qlink_cmd_mgmt_frame_register *cmd; 300 u16 res_code = QLINK_CMD_RESULT_OK; 301 int ret; 302 303 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 304 QLINK_CMD_REGISTER_MGMT, 305 sizeof(*cmd)); 306 if (unlikely(!cmd_skb)) 307 return -ENOMEM; 308 309 qtnf_bus_lock(vif->mac->bus); 310 311 cmd = (struct qlink_cmd_mgmt_frame_register *)cmd_skb->data; 312 cmd->frame_type = cpu_to_le16(frame_type); 313 cmd->do_register = reg; 314 315 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 316 317 if (unlikely(ret)) 318 goto out; 319 320 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 321 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 322 vif->vifid, res_code); 323 ret = -EFAULT; 324 goto out; 325 } 326 327 out: 328 qtnf_bus_unlock(vif->mac->bus); 329 return ret; 330 } 331 332 int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags, 333 u16 freq, const u8 *buf, size_t len) 334 { 335 struct sk_buff *cmd_skb; 336 struct qlink_cmd_mgmt_frame_tx *cmd; 337 u16 res_code = QLINK_CMD_RESULT_OK; 338 int ret; 339 340 if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) { 341 pr_warn("VIF%u.%u: frame is too big: %zu\n", vif->mac->macid, 342 vif->vifid, len); 343 return -E2BIG; 344 } 345 346 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 347 QLINK_CMD_SEND_MGMT_FRAME, 348 sizeof(*cmd)); 349 if (unlikely(!cmd_skb)) 350 return -ENOMEM; 351 352 qtnf_bus_lock(vif->mac->bus); 353 354 cmd = (struct qlink_cmd_mgmt_frame_tx *)cmd_skb->data; 355 cmd->cookie = cpu_to_le32(cookie); 356 cmd->freq = cpu_to_le16(freq); 357 cmd->flags = cpu_to_le16(flags); 358 359 if (len && buf) 360 qtnf_cmd_skb_put_buffer(cmd_skb, buf, len); 361 362 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 363 364 if (unlikely(ret)) 365 goto out; 366 367 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 368 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 369 vif->vifid, res_code); 370 ret = -EFAULT; 371 goto out; 372 } 373 374 out: 375 qtnf_bus_unlock(vif->mac->bus); 376 return ret; 377 } 378 379 int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type, 380 const u8 *buf, size_t len) 381 { 382 struct sk_buff *cmd_skb; 383 struct qlink_cmd_mgmt_append_ie *cmd; 384 u16 res_code = QLINK_CMD_RESULT_OK; 385 int ret; 386 387 if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) { 388 pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid, 389 vif->vifid, frame_type, len); 390 return -E2BIG; 391 } 392 393 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 394 QLINK_CMD_MGMT_SET_APPIE, 395 sizeof(*cmd)); 396 if (unlikely(!cmd_skb)) 397 return -ENOMEM; 398 399 qtnf_bus_lock(vif->mac->bus); 400 401 cmd = (struct qlink_cmd_mgmt_append_ie *)cmd_skb->data; 402 cmd->type = frame_type; 403 cmd->flags = 0; 404 405 /* If len == 0 then IE buf for specified frame type 406 * should be cleared on EP. 407 */ 408 if (len && buf) 409 qtnf_cmd_skb_put_buffer(cmd_skb, buf, len); 410 411 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 412 413 if (unlikely(ret)) 414 goto out; 415 416 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 417 pr_err("VIF%u.%u frame %u: CMD failed: %u\n", vif->mac->macid, 418 vif->vifid, frame_type, res_code); 419 ret = -EFAULT; 420 goto out; 421 } 422 423 out: 424 qtnf_bus_unlock(vif->mac->bus); 425 return ret; 426 } 427 428 static void 429 qtnf_sta_info_parse_basic_counters(struct station_info *sinfo, 430 const struct qlink_sta_stat_basic_counters *counters) 431 { 432 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES) | 433 BIT(NL80211_STA_INFO_TX_BYTES); 434 sinfo->rx_bytes = get_unaligned_le64(&counters->rx_bytes); 435 sinfo->tx_bytes = get_unaligned_le64(&counters->tx_bytes); 436 437 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) | 438 BIT(NL80211_STA_INFO_TX_PACKETS) | 439 BIT(NL80211_STA_INFO_BEACON_RX); 440 sinfo->rx_packets = get_unaligned_le32(&counters->rx_packets); 441 sinfo->tx_packets = get_unaligned_le32(&counters->tx_packets); 442 sinfo->rx_beacon = get_unaligned_le64(&counters->rx_beacons); 443 444 sinfo->filled |= BIT(NL80211_STA_INFO_RX_DROP_MISC) | 445 BIT(NL80211_STA_INFO_TX_FAILED); 446 sinfo->rx_dropped_misc = get_unaligned_le32(&counters->rx_dropped); 447 sinfo->tx_failed = get_unaligned_le32(&counters->tx_failed); 448 } 449 450 static void 451 qtnf_sta_info_parse_rate(struct rate_info *rate_dst, 452 const struct qlink_sta_info_rate *rate_src) 453 { 454 rate_dst->legacy = get_unaligned_le16(&rate_src->rate) * 10; 455 456 rate_dst->mcs = rate_src->mcs; 457 rate_dst->nss = rate_src->nss; 458 rate_dst->flags = 0; 459 460 switch (rate_src->bw) { 461 case QLINK_STA_INFO_RATE_BW_5: 462 rate_dst->bw = RATE_INFO_BW_5; 463 break; 464 case QLINK_STA_INFO_RATE_BW_10: 465 rate_dst->bw = RATE_INFO_BW_10; 466 break; 467 case QLINK_STA_INFO_RATE_BW_20: 468 rate_dst->bw = RATE_INFO_BW_20; 469 break; 470 case QLINK_STA_INFO_RATE_BW_40: 471 rate_dst->bw = RATE_INFO_BW_40; 472 break; 473 case QLINK_STA_INFO_RATE_BW_80: 474 rate_dst->bw = RATE_INFO_BW_80; 475 break; 476 case QLINK_STA_INFO_RATE_BW_160: 477 rate_dst->bw = RATE_INFO_BW_160; 478 break; 479 default: 480 rate_dst->bw = 0; 481 break; 482 } 483 484 if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_HT_MCS) 485 rate_dst->flags |= RATE_INFO_FLAGS_MCS; 486 else if (rate_src->flags & QLINK_STA_INFO_RATE_FLAG_VHT_MCS) 487 rate_dst->flags |= RATE_INFO_FLAGS_VHT_MCS; 488 } 489 490 static void 491 qtnf_sta_info_parse_flags(struct nl80211_sta_flag_update *dst, 492 const struct qlink_sta_info_state *src) 493 { 494 u32 mask, value; 495 496 dst->mask = 0; 497 dst->set = 0; 498 499 mask = le32_to_cpu(src->mask); 500 value = le32_to_cpu(src->value); 501 502 if (mask & QLINK_STA_FLAG_AUTHORIZED) { 503 dst->mask |= BIT(NL80211_STA_FLAG_AUTHORIZED); 504 if (value & QLINK_STA_FLAG_AUTHORIZED) 505 dst->set |= BIT(NL80211_STA_FLAG_AUTHORIZED); 506 } 507 508 if (mask & QLINK_STA_FLAG_SHORT_PREAMBLE) { 509 dst->mask |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); 510 if (value & QLINK_STA_FLAG_SHORT_PREAMBLE) 511 dst->set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); 512 } 513 514 if (mask & QLINK_STA_FLAG_WME) { 515 dst->mask |= BIT(NL80211_STA_FLAG_WME); 516 if (value & QLINK_STA_FLAG_WME) 517 dst->set |= BIT(NL80211_STA_FLAG_WME); 518 } 519 520 if (mask & QLINK_STA_FLAG_MFP) { 521 dst->mask |= BIT(NL80211_STA_FLAG_MFP); 522 if (value & QLINK_STA_FLAG_MFP) 523 dst->set |= BIT(NL80211_STA_FLAG_MFP); 524 } 525 526 if (mask & QLINK_STA_FLAG_AUTHENTICATED) { 527 dst->mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED); 528 if (value & QLINK_STA_FLAG_AUTHENTICATED) 529 dst->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); 530 } 531 532 if (mask & QLINK_STA_FLAG_TDLS_PEER) { 533 dst->mask |= BIT(NL80211_STA_FLAG_TDLS_PEER); 534 if (value & QLINK_STA_FLAG_TDLS_PEER) 535 dst->set |= BIT(NL80211_STA_FLAG_TDLS_PEER); 536 } 537 538 if (mask & QLINK_STA_FLAG_ASSOCIATED) { 539 dst->mask |= BIT(NL80211_STA_FLAG_ASSOCIATED); 540 if (value & QLINK_STA_FLAG_ASSOCIATED) 541 dst->set |= BIT(NL80211_STA_FLAG_ASSOCIATED); 542 } 543 } 544 545 static void 546 qtnf_sta_info_parse_generic_info(struct station_info *sinfo, 547 const struct qlink_sta_info_generic *info) 548 { 549 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME) | 550 BIT(NL80211_STA_INFO_INACTIVE_TIME); 551 sinfo->connected_time = get_unaligned_le32(&info->connected_time); 552 sinfo->inactive_time = get_unaligned_le32(&info->inactive_time); 553 554 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) | 555 BIT(NL80211_STA_INFO_SIGNAL_AVG); 556 sinfo->signal = info->rssi - 120; 557 sinfo->signal_avg = info->rssi_avg - QLINK_RSSI_OFFSET; 558 559 if (info->rx_rate.rate) { 560 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); 561 qtnf_sta_info_parse_rate(&sinfo->rxrate, &info->rx_rate); 562 } 563 564 if (info->tx_rate.rate) { 565 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); 566 qtnf_sta_info_parse_rate(&sinfo->txrate, &info->tx_rate); 567 } 568 569 sinfo->filled |= BIT(NL80211_STA_INFO_STA_FLAGS); 570 qtnf_sta_info_parse_flags(&sinfo->sta_flags, &info->state); 571 } 572 573 static int qtnf_cmd_sta_info_parse(struct station_info *sinfo, 574 const u8 *payload, size_t payload_size) 575 { 576 const struct qlink_sta_stat_basic_counters *counters; 577 const struct qlink_sta_info_generic *sta_info; 578 u16 tlv_type; 579 u16 tlv_value_len; 580 size_t tlv_full_len; 581 const struct qlink_tlv_hdr *tlv; 582 583 sinfo->filled = 0; 584 585 tlv = (const struct qlink_tlv_hdr *)payload; 586 while (payload_size >= sizeof(struct qlink_tlv_hdr)) { 587 tlv_type = le16_to_cpu(tlv->type); 588 tlv_value_len = le16_to_cpu(tlv->len); 589 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 590 if (tlv_full_len > payload_size) { 591 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 592 tlv_type, tlv_value_len); 593 return -EINVAL; 594 } 595 switch (tlv_type) { 596 case QTN_TLV_ID_STA_BASIC_COUNTERS: 597 if (unlikely(tlv_value_len < sizeof(*counters))) { 598 pr_err("invalid TLV size %.4X: %u\n", 599 tlv_type, tlv_value_len); 600 break; 601 } 602 603 counters = (void *)tlv->val; 604 qtnf_sta_info_parse_basic_counters(sinfo, counters); 605 break; 606 case QTN_TLV_ID_STA_GENERIC_INFO: 607 if (unlikely(tlv_value_len < sizeof(*sta_info))) 608 break; 609 610 sta_info = (void *)tlv->val; 611 qtnf_sta_info_parse_generic_info(sinfo, sta_info); 612 break; 613 default: 614 pr_warn("unexpected TLV type: %.4X\n", tlv_type); 615 break; 616 } 617 payload_size -= tlv_full_len; 618 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 619 } 620 621 if (payload_size) { 622 pr_warn("malformed TLV buf; bytes left: %zu\n", payload_size); 623 return -EINVAL; 624 } 625 626 return 0; 627 } 628 629 int qtnf_cmd_get_sta_info(struct qtnf_vif *vif, const u8 *sta_mac, 630 struct station_info *sinfo) 631 { 632 struct sk_buff *cmd_skb, *resp_skb = NULL; 633 struct qlink_cmd_get_sta_info *cmd; 634 const struct qlink_resp_get_sta_info *resp; 635 size_t var_resp_len; 636 u16 res_code = QLINK_CMD_RESULT_OK; 637 int ret = 0; 638 639 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 640 QLINK_CMD_GET_STA_INFO, 641 sizeof(*cmd)); 642 643 if (unlikely(!cmd_skb)) 644 return -ENOMEM; 645 646 qtnf_bus_lock(vif->mac->bus); 647 648 cmd = (struct qlink_cmd_get_sta_info *)cmd_skb->data; 649 ether_addr_copy(cmd->sta_addr, sta_mac); 650 651 ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb, 652 &res_code, sizeof(*resp), 653 &var_resp_len); 654 655 if (unlikely(ret)) 656 goto out; 657 658 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 659 switch (res_code) { 660 case QLINK_CMD_RESULT_ENOTFOUND: 661 pr_warn("VIF%u.%u: %pM STA not found\n", 662 vif->mac->macid, vif->vifid, sta_mac); 663 ret = -ENOENT; 664 break; 665 default: 666 pr_err("VIF%u.%u: can't get info for %pM: %u\n", 667 vif->mac->macid, vif->vifid, sta_mac, res_code); 668 ret = -EFAULT; 669 break; 670 } 671 goto out; 672 } 673 674 resp = (const struct qlink_resp_get_sta_info *)resp_skb->data; 675 676 if (unlikely(!ether_addr_equal(sta_mac, resp->sta_addr))) { 677 pr_err("VIF%u.%u: wrong mac in reply: %pM != %pM\n", 678 vif->mac->macid, vif->vifid, resp->sta_addr, sta_mac); 679 ret = -EINVAL; 680 goto out; 681 } 682 683 ret = qtnf_cmd_sta_info_parse(sinfo, resp->info, var_resp_len); 684 685 out: 686 qtnf_bus_unlock(vif->mac->bus); 687 consume_skb(resp_skb); 688 689 return ret; 690 } 691 692 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif, 693 enum nl80211_iftype iftype, 694 u8 *mac_addr, 695 enum qlink_cmd_type cmd_type) 696 { 697 struct sk_buff *cmd_skb, *resp_skb = NULL; 698 struct qlink_cmd_manage_intf *cmd; 699 const struct qlink_resp_manage_intf *resp; 700 u16 res_code = QLINK_CMD_RESULT_OK; 701 int ret = 0; 702 703 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 704 cmd_type, 705 sizeof(*cmd)); 706 if (unlikely(!cmd_skb)) 707 return -ENOMEM; 708 709 qtnf_bus_lock(vif->mac->bus); 710 711 cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data; 712 713 switch (iftype) { 714 case NL80211_IFTYPE_AP: 715 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP); 716 break; 717 case NL80211_IFTYPE_STATION: 718 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 719 break; 720 default: 721 pr_err("VIF%u.%u: unsupported type %d\n", vif->mac->macid, 722 vif->vifid, iftype); 723 ret = -EINVAL; 724 goto out; 725 } 726 727 if (mac_addr) 728 ether_addr_copy(cmd->intf_info.mac_addr, mac_addr); 729 else 730 eth_zero_addr(cmd->intf_info.mac_addr); 731 732 ret = qtnf_cmd_send_with_reply(vif->mac->bus, cmd_skb, &resp_skb, 733 &res_code, sizeof(*resp), NULL); 734 735 if (unlikely(ret)) 736 goto out; 737 738 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 739 pr_err("VIF%u.%u: CMD %d failed: %u\n", vif->mac->macid, 740 vif->vifid, cmd_type, res_code); 741 ret = -EFAULT; 742 goto out; 743 } 744 745 resp = (const struct qlink_resp_manage_intf *)resp_skb->data; 746 ether_addr_copy(vif->mac_addr, resp->intf_info.mac_addr); 747 748 out: 749 qtnf_bus_unlock(vif->mac->bus); 750 consume_skb(resp_skb); 751 752 return ret; 753 } 754 755 int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, 756 enum nl80211_iftype iftype, u8 *mac_addr) 757 { 758 return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr, 759 QLINK_CMD_ADD_INTF); 760 } 761 762 int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif, 763 enum nl80211_iftype iftype, u8 *mac_addr) 764 { 765 return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr, 766 QLINK_CMD_CHANGE_INTF); 767 } 768 769 int qtnf_cmd_send_del_intf(struct qtnf_vif *vif) 770 { 771 struct sk_buff *cmd_skb; 772 struct qlink_cmd_manage_intf *cmd; 773 u16 res_code = QLINK_CMD_RESULT_OK; 774 int ret = 0; 775 776 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 777 QLINK_CMD_DEL_INTF, 778 sizeof(*cmd)); 779 if (unlikely(!cmd_skb)) 780 return -ENOMEM; 781 782 qtnf_bus_lock(vif->mac->bus); 783 784 cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data; 785 786 switch (vif->wdev.iftype) { 787 case NL80211_IFTYPE_AP: 788 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_AP); 789 break; 790 case NL80211_IFTYPE_STATION: 791 cmd->intf_info.if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 792 break; 793 default: 794 pr_warn("VIF%u.%u: unsupported iftype %d\n", vif->mac->macid, 795 vif->vifid, vif->wdev.iftype); 796 ret = -EINVAL; 797 goto out; 798 } 799 800 eth_zero_addr(cmd->intf_info.mac_addr); 801 802 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 803 804 if (unlikely(ret)) 805 goto out; 806 807 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 808 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 809 vif->vifid, res_code); 810 ret = -EFAULT; 811 goto out; 812 } 813 814 out: 815 qtnf_bus_unlock(vif->mac->bus); 816 return ret; 817 } 818 819 static u32 qtnf_cmd_resp_reg_rule_flags_parse(u32 qflags) 820 { 821 u32 flags = 0; 822 823 if (qflags & QLINK_RRF_NO_OFDM) 824 flags |= NL80211_RRF_NO_OFDM; 825 826 if (qflags & QLINK_RRF_NO_CCK) 827 flags |= NL80211_RRF_NO_CCK; 828 829 if (qflags & QLINK_RRF_NO_INDOOR) 830 flags |= NL80211_RRF_NO_INDOOR; 831 832 if (qflags & QLINK_RRF_NO_OUTDOOR) 833 flags |= NL80211_RRF_NO_OUTDOOR; 834 835 if (qflags & QLINK_RRF_DFS) 836 flags |= NL80211_RRF_DFS; 837 838 if (qflags & QLINK_RRF_PTP_ONLY) 839 flags |= NL80211_RRF_PTP_ONLY; 840 841 if (qflags & QLINK_RRF_PTMP_ONLY) 842 flags |= NL80211_RRF_PTMP_ONLY; 843 844 if (qflags & QLINK_RRF_NO_IR) 845 flags |= NL80211_RRF_NO_IR; 846 847 if (qflags & QLINK_RRF_AUTO_BW) 848 flags |= NL80211_RRF_AUTO_BW; 849 850 if (qflags & QLINK_RRF_IR_CONCURRENT) 851 flags |= NL80211_RRF_IR_CONCURRENT; 852 853 if (qflags & QLINK_RRF_NO_HT40MINUS) 854 flags |= NL80211_RRF_NO_HT40MINUS; 855 856 if (qflags & QLINK_RRF_NO_HT40PLUS) 857 flags |= NL80211_RRF_NO_HT40PLUS; 858 859 if (qflags & QLINK_RRF_NO_80MHZ) 860 flags |= NL80211_RRF_NO_80MHZ; 861 862 if (qflags & QLINK_RRF_NO_160MHZ) 863 flags |= NL80211_RRF_NO_160MHZ; 864 865 return flags; 866 } 867 868 static int 869 qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, 870 const struct qlink_resp_get_hw_info *resp, 871 size_t info_len) 872 { 873 struct qtnf_hw_info *hwinfo = &bus->hw_info; 874 const struct qlink_tlv_hdr *tlv; 875 const struct qlink_tlv_reg_rule *tlv_rule; 876 struct ieee80211_reg_rule *rule; 877 u16 tlv_type; 878 u16 tlv_value_len; 879 unsigned int rule_idx = 0; 880 881 if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) 882 return -E2BIG; 883 884 hwinfo->rd = kzalloc(sizeof(*hwinfo->rd) 885 + sizeof(struct ieee80211_reg_rule) 886 * resp->n_reg_rules, GFP_KERNEL); 887 888 if (!hwinfo->rd) 889 return -ENOMEM; 890 891 hwinfo->num_mac = resp->num_mac; 892 hwinfo->mac_bitmap = resp->mac_bitmap; 893 hwinfo->fw_ver = le32_to_cpu(resp->fw_ver); 894 hwinfo->ql_proto_ver = le16_to_cpu(resp->ql_proto_ver); 895 hwinfo->total_tx_chain = resp->total_tx_chain; 896 hwinfo->total_rx_chain = resp->total_rx_chain; 897 hwinfo->hw_capab = le32_to_cpu(resp->hw_capab); 898 hwinfo->rd->n_reg_rules = resp->n_reg_rules; 899 hwinfo->rd->alpha2[0] = resp->alpha2[0]; 900 hwinfo->rd->alpha2[1] = resp->alpha2[1]; 901 902 switch (resp->dfs_region) { 903 case QLINK_DFS_FCC: 904 hwinfo->rd->dfs_region = NL80211_DFS_FCC; 905 break; 906 case QLINK_DFS_ETSI: 907 hwinfo->rd->dfs_region = NL80211_DFS_ETSI; 908 break; 909 case QLINK_DFS_JP: 910 hwinfo->rd->dfs_region = NL80211_DFS_JP; 911 break; 912 case QLINK_DFS_UNSET: 913 default: 914 hwinfo->rd->dfs_region = NL80211_DFS_UNSET; 915 break; 916 } 917 918 tlv = (const struct qlink_tlv_hdr *)resp->info; 919 920 while (info_len >= sizeof(*tlv)) { 921 tlv_type = le16_to_cpu(tlv->type); 922 tlv_value_len = le16_to_cpu(tlv->len); 923 924 if (tlv_value_len + sizeof(*tlv) > info_len) { 925 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 926 tlv_type, tlv_value_len); 927 return -EINVAL; 928 } 929 930 switch (tlv_type) { 931 case QTN_TLV_ID_REG_RULE: 932 if (rule_idx >= resp->n_reg_rules) { 933 pr_warn("unexpected number of rules: %u\n", 934 resp->n_reg_rules); 935 return -EINVAL; 936 } 937 938 if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) { 939 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 940 tlv_type, tlv_value_len); 941 return -EINVAL; 942 } 943 944 tlv_rule = (const struct qlink_tlv_reg_rule *)tlv; 945 rule = &hwinfo->rd->reg_rules[rule_idx++]; 946 947 rule->freq_range.start_freq_khz = 948 le32_to_cpu(tlv_rule->start_freq_khz); 949 rule->freq_range.end_freq_khz = 950 le32_to_cpu(tlv_rule->end_freq_khz); 951 rule->freq_range.max_bandwidth_khz = 952 le32_to_cpu(tlv_rule->max_bandwidth_khz); 953 rule->power_rule.max_antenna_gain = 954 le32_to_cpu(tlv_rule->max_antenna_gain); 955 rule->power_rule.max_eirp = 956 le32_to_cpu(tlv_rule->max_eirp); 957 rule->dfs_cac_ms = 958 le32_to_cpu(tlv_rule->dfs_cac_ms); 959 rule->flags = qtnf_cmd_resp_reg_rule_flags_parse( 960 le32_to_cpu(tlv_rule->flags)); 961 break; 962 default: 963 break; 964 } 965 966 info_len -= tlv_value_len + sizeof(*tlv); 967 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 968 } 969 970 if (rule_idx != resp->n_reg_rules) { 971 pr_warn("unexpected number of rules: expected %u got %u\n", 972 resp->n_reg_rules, rule_idx); 973 kfree(hwinfo->rd); 974 hwinfo->rd = NULL; 975 return -EINVAL; 976 } 977 978 pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u, capab=0x%x\n", 979 hwinfo->fw_ver, hwinfo->mac_bitmap, 980 hwinfo->rd->alpha2[0], hwinfo->rd->alpha2[1], 981 hwinfo->total_tx_chain, hwinfo->total_rx_chain, 982 hwinfo->hw_capab); 983 984 return 0; 985 } 986 987 static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, 988 const u8 *tlv_buf, size_t tlv_buf_size) 989 { 990 struct ieee80211_iface_limit *limits = NULL; 991 const struct qlink_iface_limit *limit_record; 992 size_t record_count = 0, rec = 0; 993 u16 tlv_type, tlv_value_len; 994 struct qlink_iface_comb_num *comb; 995 size_t tlv_full_len; 996 const struct qlink_tlv_hdr *tlv; 997 998 mac->macinfo.n_limits = 0; 999 1000 tlv = (const struct qlink_tlv_hdr *)tlv_buf; 1001 while (tlv_buf_size >= sizeof(struct qlink_tlv_hdr)) { 1002 tlv_type = le16_to_cpu(tlv->type); 1003 tlv_value_len = le16_to_cpu(tlv->len); 1004 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 1005 if (tlv_full_len > tlv_buf_size) { 1006 pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n", 1007 mac->macid, tlv_type, tlv_value_len); 1008 return -EINVAL; 1009 } 1010 1011 switch (tlv_type) { 1012 case QTN_TLV_ID_NUM_IFACE_COMB: 1013 if (unlikely(tlv_value_len != sizeof(*comb))) 1014 return -EINVAL; 1015 1016 comb = (void *)tlv->val; 1017 record_count = le16_to_cpu(comb->iface_comb_num); 1018 1019 mac->macinfo.n_limits = record_count; 1020 /* free earlier iface limits memory */ 1021 kfree(mac->macinfo.limits); 1022 mac->macinfo.limits = 1023 kzalloc(sizeof(*mac->macinfo.limits) * 1024 record_count, GFP_KERNEL); 1025 1026 if (unlikely(!mac->macinfo.limits)) 1027 return -ENOMEM; 1028 1029 limits = mac->macinfo.limits; 1030 break; 1031 case QTN_TLV_ID_IFACE_LIMIT: 1032 if (unlikely(!limits)) { 1033 pr_warn("MAC%u: limits are not inited\n", 1034 mac->macid); 1035 return -EINVAL; 1036 } 1037 1038 if (unlikely(tlv_value_len != sizeof(*limit_record))) { 1039 pr_warn("MAC%u: record size mismatch\n", 1040 mac->macid); 1041 return -EINVAL; 1042 } 1043 1044 limit_record = (void *)tlv->val; 1045 limits[rec].max = le16_to_cpu(limit_record->max_num); 1046 limits[rec].types = qlink_iface_type_to_nl_mask( 1047 le16_to_cpu(limit_record->type)); 1048 1049 /* supported modes: STA, AP */ 1050 limits[rec].types &= BIT(NL80211_IFTYPE_AP) | 1051 BIT(NL80211_IFTYPE_AP_VLAN) | 1052 BIT(NL80211_IFTYPE_STATION); 1053 1054 pr_debug("MAC%u: MAX: %u; TYPES: %.4X\n", mac->macid, 1055 limits[rec].max, limits[rec].types); 1056 1057 if (limits[rec].types) 1058 rec++; 1059 break; 1060 default: 1061 break; 1062 } 1063 1064 tlv_buf_size -= tlv_full_len; 1065 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 1066 } 1067 1068 if (tlv_buf_size) { 1069 pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n", 1070 mac->macid, tlv_buf_size); 1071 return -EINVAL; 1072 } 1073 1074 if (mac->macinfo.n_limits != rec) { 1075 pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n", 1076 mac->macid, mac->macinfo.n_limits, rec); 1077 return -EINVAL; 1078 } 1079 1080 return 0; 1081 } 1082 1083 static void 1084 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, 1085 const struct qlink_resp_get_mac_info *resp_info) 1086 { 1087 struct qtnf_mac_info *mac_info; 1088 struct qtnf_vif *vif; 1089 1090 mac_info = &mac->macinfo; 1091 1092 mac_info->bands_cap = resp_info->bands_cap; 1093 mac_info->phymode_cap = resp_info->phymode_cap; 1094 memcpy(&mac_info->dev_mac, &resp_info->dev_mac, 1095 sizeof(mac_info->dev_mac)); 1096 1097 ether_addr_copy(mac->macaddr, mac_info->dev_mac); 1098 1099 vif = qtnf_mac_get_base_vif(mac); 1100 if (vif) 1101 ether_addr_copy(vif->mac_addr, mac->macaddr); 1102 else 1103 pr_err("could not get valid base vif\n"); 1104 1105 mac_info->num_tx_chain = resp_info->num_tx_chain; 1106 mac_info->num_rx_chain = resp_info->num_rx_chain; 1107 1108 mac_info->max_ap_assoc_sta = le16_to_cpu(resp_info->max_ap_assoc_sta); 1109 mac_info->radar_detect_widths = 1110 qlink_chan_width_mask_to_nl(le16_to_cpu( 1111 resp_info->radar_detect_widths)); 1112 1113 memcpy(&mac_info->ht_cap, &resp_info->ht_cap, sizeof(mac_info->ht_cap)); 1114 memcpy(&mac_info->vht_cap, &resp_info->vht_cap, 1115 sizeof(mac_info->vht_cap)); 1116 } 1117 1118 static int 1119 qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band, 1120 struct qlink_resp_get_chan_info *resp, 1121 size_t payload_len) 1122 { 1123 u16 tlv_type; 1124 size_t tlv_len; 1125 const struct qlink_tlv_hdr *tlv; 1126 const struct qlink_tlv_channel *qchan; 1127 struct ieee80211_channel *chan; 1128 unsigned int chidx = 0; 1129 u32 qflags; 1130 1131 if (band->channels) { 1132 if (band->n_channels == resp->num_chans) { 1133 memset(band->channels, 0, 1134 sizeof(*band->channels) * band->n_channels); 1135 } else { 1136 kfree(band->channels); 1137 band->n_channels = 0; 1138 band->channels = NULL; 1139 } 1140 } 1141 1142 band->n_channels = resp->num_chans; 1143 if (band->n_channels == 0) 1144 return 0; 1145 1146 if (!band->channels) 1147 band->channels = kcalloc(band->n_channels, sizeof(*chan), 1148 GFP_KERNEL); 1149 if (!band->channels) { 1150 band->n_channels = 0; 1151 return -ENOMEM; 1152 } 1153 1154 tlv = (struct qlink_tlv_hdr *)resp->info; 1155 1156 while (payload_len >= sizeof(*tlv)) { 1157 tlv_type = le16_to_cpu(tlv->type); 1158 tlv_len = le16_to_cpu(tlv->len) + sizeof(*tlv); 1159 1160 if (tlv_len > payload_len) { 1161 pr_warn("malformed TLV 0x%.2X; LEN: %zu\n", 1162 tlv_type, tlv_len); 1163 goto error_ret; 1164 } 1165 1166 switch (tlv_type) { 1167 case QTN_TLV_ID_CHANNEL: 1168 if (unlikely(tlv_len != sizeof(*qchan))) { 1169 pr_err("invalid channel TLV len %zu\n", 1170 tlv_len); 1171 goto error_ret; 1172 } 1173 1174 if (chidx == band->n_channels) { 1175 pr_err("too many channel TLVs\n"); 1176 goto error_ret; 1177 } 1178 1179 qchan = (const struct qlink_tlv_channel *)tlv; 1180 chan = &band->channels[chidx++]; 1181 qflags = le32_to_cpu(qchan->flags); 1182 1183 chan->hw_value = le16_to_cpu(qchan->hw_value); 1184 chan->band = band->band; 1185 chan->center_freq = le16_to_cpu(qchan->center_freq); 1186 chan->max_antenna_gain = (int)qchan->max_antenna_gain; 1187 chan->max_power = (int)qchan->max_power; 1188 chan->max_reg_power = (int)qchan->max_reg_power; 1189 chan->beacon_found = qchan->beacon_found; 1190 chan->dfs_cac_ms = le32_to_cpu(qchan->dfs_cac_ms); 1191 chan->flags = 0; 1192 1193 if (qflags & QLINK_CHAN_DISABLED) 1194 chan->flags |= IEEE80211_CHAN_DISABLED; 1195 1196 if (qflags & QLINK_CHAN_NO_IR) 1197 chan->flags |= IEEE80211_CHAN_NO_IR; 1198 1199 if (qflags & QLINK_CHAN_NO_HT40PLUS) 1200 chan->flags |= IEEE80211_CHAN_NO_HT40PLUS; 1201 1202 if (qflags & QLINK_CHAN_NO_HT40MINUS) 1203 chan->flags |= IEEE80211_CHAN_NO_HT40MINUS; 1204 1205 if (qflags & QLINK_CHAN_NO_OFDM) 1206 chan->flags |= IEEE80211_CHAN_NO_OFDM; 1207 1208 if (qflags & QLINK_CHAN_NO_80MHZ) 1209 chan->flags |= IEEE80211_CHAN_NO_80MHZ; 1210 1211 if (qflags & QLINK_CHAN_NO_160MHZ) 1212 chan->flags |= IEEE80211_CHAN_NO_160MHZ; 1213 1214 if (qflags & QLINK_CHAN_INDOOR_ONLY) 1215 chan->flags |= IEEE80211_CHAN_INDOOR_ONLY; 1216 1217 if (qflags & QLINK_CHAN_IR_CONCURRENT) 1218 chan->flags |= IEEE80211_CHAN_IR_CONCURRENT; 1219 1220 if (qflags & QLINK_CHAN_NO_20MHZ) 1221 chan->flags |= IEEE80211_CHAN_NO_20MHZ; 1222 1223 if (qflags & QLINK_CHAN_NO_10MHZ) 1224 chan->flags |= IEEE80211_CHAN_NO_10MHZ; 1225 1226 if (qflags & QLINK_CHAN_RADAR) { 1227 chan->flags |= IEEE80211_CHAN_RADAR; 1228 chan->dfs_state_entered = jiffies; 1229 1230 if (qchan->dfs_state == QLINK_DFS_USABLE) 1231 chan->dfs_state = NL80211_DFS_USABLE; 1232 else if (qchan->dfs_state == 1233 QLINK_DFS_AVAILABLE) 1234 chan->dfs_state = NL80211_DFS_AVAILABLE; 1235 else 1236 chan->dfs_state = 1237 NL80211_DFS_UNAVAILABLE; 1238 } 1239 1240 pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n", 1241 chan->hw_value, chan->flags, chan->max_power, 1242 chan->max_reg_power); 1243 break; 1244 default: 1245 pr_warn("unknown TLV type: %#x\n", tlv_type); 1246 break; 1247 } 1248 1249 payload_len -= tlv_len; 1250 tlv = (struct qlink_tlv_hdr *)((u8 *)tlv + tlv_len); 1251 } 1252 1253 if (payload_len) { 1254 pr_err("malformed TLV buf; bytes left: %zu\n", payload_len); 1255 goto error_ret; 1256 } 1257 1258 if (band->n_channels != chidx) { 1259 pr_err("channel count mismatch: reported=%d, parsed=%d\n", 1260 band->n_channels, chidx); 1261 goto error_ret; 1262 } 1263 1264 return 0; 1265 1266 error_ret: 1267 kfree(band->channels); 1268 band->channels = NULL; 1269 band->n_channels = 0; 1270 1271 return -EINVAL; 1272 } 1273 1274 static int qtnf_cmd_resp_proc_phy_params(struct qtnf_wmac *mac, 1275 const u8 *payload, size_t payload_len) 1276 { 1277 struct qtnf_mac_info *mac_info; 1278 struct qlink_tlv_frag_rts_thr *phy_thr; 1279 struct qlink_tlv_rlimit *limit; 1280 struct qlink_tlv_cclass *class; 1281 u16 tlv_type; 1282 u16 tlv_value_len; 1283 size_t tlv_full_len; 1284 const struct qlink_tlv_hdr *tlv; 1285 1286 mac_info = &mac->macinfo; 1287 1288 tlv = (struct qlink_tlv_hdr *)payload; 1289 while (payload_len >= sizeof(struct qlink_tlv_hdr)) { 1290 tlv_type = le16_to_cpu(tlv->type); 1291 tlv_value_len = le16_to_cpu(tlv->len); 1292 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 1293 1294 if (tlv_full_len > payload_len) { 1295 pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n", 1296 mac->macid, tlv_type, tlv_value_len); 1297 return -EINVAL; 1298 } 1299 1300 switch (tlv_type) { 1301 case QTN_TLV_ID_FRAG_THRESH: 1302 phy_thr = (void *)tlv; 1303 mac_info->frag_thr = (u32)le16_to_cpu(phy_thr->thr); 1304 break; 1305 case QTN_TLV_ID_RTS_THRESH: 1306 phy_thr = (void *)tlv; 1307 mac_info->rts_thr = (u32)le16_to_cpu(phy_thr->thr); 1308 break; 1309 case QTN_TLV_ID_SRETRY_LIMIT: 1310 limit = (void *)tlv; 1311 mac_info->sretry_limit = limit->rlimit; 1312 break; 1313 case QTN_TLV_ID_LRETRY_LIMIT: 1314 limit = (void *)tlv; 1315 mac_info->lretry_limit = limit->rlimit; 1316 break; 1317 case QTN_TLV_ID_COVERAGE_CLASS: 1318 class = (void *)tlv; 1319 mac_info->coverage_class = class->cclass; 1320 break; 1321 default: 1322 pr_err("MAC%u: Unknown TLV type: %#x\n", mac->macid, 1323 le16_to_cpu(tlv->type)); 1324 break; 1325 } 1326 1327 payload_len -= tlv_full_len; 1328 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 1329 } 1330 1331 if (payload_len) { 1332 pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n", 1333 mac->macid, payload_len); 1334 return -EINVAL; 1335 } 1336 1337 return 0; 1338 } 1339 1340 static int 1341 qtnf_cmd_resp_proc_chan_stat_info(struct qtnf_chan_stats *stats, 1342 const u8 *payload, size_t payload_len) 1343 { 1344 struct qlink_chan_stats *qlink_stats; 1345 const struct qlink_tlv_hdr *tlv; 1346 size_t tlv_full_len; 1347 u16 tlv_value_len; 1348 u16 tlv_type; 1349 1350 tlv = (struct qlink_tlv_hdr *)payload; 1351 while (payload_len >= sizeof(struct qlink_tlv_hdr)) { 1352 tlv_type = le16_to_cpu(tlv->type); 1353 tlv_value_len = le16_to_cpu(tlv->len); 1354 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 1355 if (tlv_full_len > payload_len) { 1356 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 1357 tlv_type, tlv_value_len); 1358 return -EINVAL; 1359 } 1360 switch (tlv_type) { 1361 case QTN_TLV_ID_CHANNEL_STATS: 1362 if (unlikely(tlv_value_len != sizeof(*qlink_stats))) { 1363 pr_err("invalid CHANNEL_STATS entry size\n"); 1364 return -EINVAL; 1365 } 1366 1367 qlink_stats = (void *)tlv->val; 1368 1369 stats->chan_num = le32_to_cpu(qlink_stats->chan_num); 1370 stats->cca_tx = le32_to_cpu(qlink_stats->cca_tx); 1371 stats->cca_rx = le32_to_cpu(qlink_stats->cca_rx); 1372 stats->cca_busy = le32_to_cpu(qlink_stats->cca_busy); 1373 stats->cca_try = le32_to_cpu(qlink_stats->cca_try); 1374 stats->chan_noise = qlink_stats->chan_noise; 1375 1376 pr_debug("chan(%u) try(%u) busy(%u) noise(%d)\n", 1377 stats->chan_num, stats->cca_try, 1378 stats->cca_busy, stats->chan_noise); 1379 break; 1380 default: 1381 pr_warn("Unknown TLV type: %#x\n", 1382 le16_to_cpu(tlv->type)); 1383 } 1384 payload_len -= tlv_full_len; 1385 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 1386 } 1387 1388 if (payload_len) { 1389 pr_warn("malformed TLV buf; bytes left: %zu\n", payload_len); 1390 return -EINVAL; 1391 } 1392 1393 return 0; 1394 } 1395 1396 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac) 1397 { 1398 struct sk_buff *cmd_skb, *resp_skb = NULL; 1399 const struct qlink_resp_get_mac_info *resp; 1400 size_t var_data_len; 1401 u16 res_code = QLINK_CMD_RESULT_OK; 1402 int ret = 0; 1403 1404 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1405 QLINK_CMD_MAC_INFO, 1406 sizeof(struct qlink_cmd)); 1407 if (unlikely(!cmd_skb)) 1408 return -ENOMEM; 1409 1410 qtnf_bus_lock(mac->bus); 1411 1412 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1413 sizeof(*resp), &var_data_len); 1414 if (unlikely(ret)) 1415 goto out; 1416 1417 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1418 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1419 ret = -EFAULT; 1420 goto out; 1421 } 1422 1423 resp = (const struct qlink_resp_get_mac_info *)resp_skb->data; 1424 qtnf_cmd_resp_proc_mac_info(mac, resp); 1425 ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len); 1426 1427 out: 1428 qtnf_bus_unlock(mac->bus); 1429 consume_skb(resp_skb); 1430 1431 return ret; 1432 } 1433 1434 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus) 1435 { 1436 struct sk_buff *cmd_skb, *resp_skb = NULL; 1437 const struct qlink_resp_get_hw_info *resp; 1438 u16 res_code = QLINK_CMD_RESULT_OK; 1439 int ret = 0; 1440 size_t info_len; 1441 1442 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1443 QLINK_CMD_GET_HW_INFO, 1444 sizeof(struct qlink_cmd)); 1445 if (unlikely(!cmd_skb)) 1446 return -ENOMEM; 1447 1448 qtnf_bus_lock(bus); 1449 1450 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code, 1451 sizeof(*resp), &info_len); 1452 1453 if (unlikely(ret)) 1454 goto out; 1455 1456 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1457 pr_err("cmd exec failed: 0x%.4X\n", res_code); 1458 ret = -EFAULT; 1459 goto out; 1460 } 1461 1462 resp = (const struct qlink_resp_get_hw_info *)resp_skb->data; 1463 ret = qtnf_cmd_resp_proc_hw_info(bus, resp, info_len); 1464 1465 out: 1466 qtnf_bus_unlock(bus); 1467 consume_skb(resp_skb); 1468 1469 return ret; 1470 } 1471 1472 int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, 1473 struct ieee80211_supported_band *band) 1474 { 1475 struct sk_buff *cmd_skb, *resp_skb = NULL; 1476 size_t info_len; 1477 struct qlink_cmd_chans_info_get *cmd; 1478 struct qlink_resp_get_chan_info *resp; 1479 u16 res_code = QLINK_CMD_RESULT_OK; 1480 int ret = 0; 1481 u8 qband; 1482 1483 switch (band->band) { 1484 case NL80211_BAND_2GHZ: 1485 qband = QLINK_BAND_2GHZ; 1486 break; 1487 case NL80211_BAND_5GHZ: 1488 qband = QLINK_BAND_5GHZ; 1489 break; 1490 case NL80211_BAND_60GHZ: 1491 qband = QLINK_BAND_60GHZ; 1492 break; 1493 default: 1494 return -EINVAL; 1495 } 1496 1497 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1498 QLINK_CMD_CHANS_INFO_GET, 1499 sizeof(*cmd)); 1500 if (!cmd_skb) 1501 return -ENOMEM; 1502 1503 cmd = (struct qlink_cmd_chans_info_get *)cmd_skb->data; 1504 cmd->band = qband; 1505 1506 qtnf_bus_lock(mac->bus); 1507 1508 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1509 sizeof(*resp), &info_len); 1510 1511 if (unlikely(ret)) 1512 goto out; 1513 1514 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1515 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1516 ret = -EFAULT; 1517 goto out; 1518 } 1519 1520 resp = (struct qlink_resp_get_chan_info *)resp_skb->data; 1521 if (resp->band != qband) { 1522 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, 1523 resp->band, qband); 1524 ret = -EINVAL; 1525 goto out; 1526 } 1527 1528 ret = qtnf_cmd_resp_fill_channels_info(band, resp, info_len); 1529 1530 out: 1531 qtnf_bus_unlock(mac->bus); 1532 consume_skb(resp_skb); 1533 1534 return ret; 1535 } 1536 1537 int qtnf_cmd_send_get_phy_params(struct qtnf_wmac *mac) 1538 { 1539 struct sk_buff *cmd_skb, *resp_skb = NULL; 1540 size_t response_size; 1541 struct qlink_resp_phy_params *resp; 1542 u16 res_code = QLINK_CMD_RESULT_OK; 1543 int ret = 0; 1544 1545 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1546 QLINK_CMD_PHY_PARAMS_GET, 1547 sizeof(struct qlink_cmd)); 1548 if (!cmd_skb) 1549 return -ENOMEM; 1550 1551 qtnf_bus_lock(mac->bus); 1552 1553 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1554 sizeof(*resp), &response_size); 1555 1556 if (unlikely(ret)) 1557 goto out; 1558 1559 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1560 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1561 ret = -EFAULT; 1562 goto out; 1563 } 1564 1565 resp = (struct qlink_resp_phy_params *)resp_skb->data; 1566 ret = qtnf_cmd_resp_proc_phy_params(mac, resp->info, response_size); 1567 1568 out: 1569 qtnf_bus_unlock(mac->bus); 1570 consume_skb(resp_skb); 1571 1572 return ret; 1573 } 1574 1575 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed) 1576 { 1577 struct wiphy *wiphy = priv_to_wiphy(mac); 1578 struct sk_buff *cmd_skb; 1579 u16 res_code = QLINK_CMD_RESULT_OK; 1580 int ret = 0; 1581 1582 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1583 QLINK_CMD_PHY_PARAMS_SET, 1584 sizeof(struct qlink_cmd)); 1585 if (!cmd_skb) 1586 return -ENOMEM; 1587 1588 qtnf_bus_lock(mac->bus); 1589 1590 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 1591 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_FRAG_THRESH, 1592 wiphy->frag_threshold); 1593 if (changed & WIPHY_PARAM_RTS_THRESHOLD) 1594 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_RTS_THRESH, 1595 wiphy->rts_threshold); 1596 if (changed & WIPHY_PARAM_COVERAGE_CLASS) 1597 qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS, 1598 wiphy->coverage_class); 1599 1600 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 1601 1602 if (unlikely(ret)) 1603 goto out; 1604 1605 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1606 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1607 ret = -EFAULT; 1608 goto out; 1609 } 1610 1611 out: 1612 qtnf_bus_unlock(mac->bus); 1613 return ret; 1614 } 1615 1616 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus) 1617 { 1618 struct sk_buff *cmd_skb; 1619 u16 res_code = QLINK_CMD_RESULT_OK; 1620 int ret = 0; 1621 1622 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1623 QLINK_CMD_FW_INIT, 1624 sizeof(struct qlink_cmd)); 1625 if (unlikely(!cmd_skb)) 1626 return -ENOMEM; 1627 1628 qtnf_bus_lock(bus); 1629 1630 ret = qtnf_cmd_send(bus, cmd_skb, &res_code); 1631 1632 if (unlikely(ret)) 1633 goto out; 1634 1635 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1636 pr_err("cmd exec failed: 0x%.4X\n", res_code); 1637 ret = -EFAULT; 1638 goto out; 1639 } 1640 1641 out: 1642 qtnf_bus_unlock(bus); 1643 return ret; 1644 } 1645 1646 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus) 1647 { 1648 struct sk_buff *cmd_skb; 1649 1650 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1651 QLINK_CMD_FW_DEINIT, 1652 sizeof(struct qlink_cmd)); 1653 if (!cmd_skb) 1654 return; 1655 1656 qtnf_bus_lock(bus); 1657 1658 qtnf_cmd_send(bus, cmd_skb, NULL); 1659 1660 qtnf_bus_unlock(bus); 1661 } 1662 1663 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1664 const u8 *mac_addr, struct key_params *params) 1665 { 1666 struct sk_buff *cmd_skb; 1667 struct qlink_cmd_add_key *cmd; 1668 u16 res_code = QLINK_CMD_RESULT_OK; 1669 int ret = 0; 1670 1671 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1672 QLINK_CMD_ADD_KEY, 1673 sizeof(*cmd)); 1674 if (unlikely(!cmd_skb)) 1675 return -ENOMEM; 1676 1677 qtnf_bus_lock(vif->mac->bus); 1678 1679 cmd = (struct qlink_cmd_add_key *)cmd_skb->data; 1680 1681 if (mac_addr) 1682 ether_addr_copy(cmd->addr, mac_addr); 1683 else 1684 eth_broadcast_addr(cmd->addr); 1685 1686 cmd->cipher = cpu_to_le32(params->cipher); 1687 cmd->key_index = key_index; 1688 cmd->pairwise = pairwise; 1689 1690 if (params->key && params->key_len > 0) 1691 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY, 1692 params->key, 1693 params->key_len); 1694 1695 if (params->seq && params->seq_len > 0) 1696 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ, 1697 params->seq, 1698 params->seq_len); 1699 1700 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1701 if (unlikely(ret)) 1702 goto out; 1703 1704 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1705 pr_err("VIF%u.%u: CMD failed: %u\n", 1706 vif->mac->macid, vif->vifid, res_code); 1707 ret = -EFAULT; 1708 goto out; 1709 } 1710 1711 out: 1712 qtnf_bus_unlock(vif->mac->bus); 1713 return ret; 1714 } 1715 1716 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1717 const u8 *mac_addr) 1718 { 1719 struct sk_buff *cmd_skb; 1720 struct qlink_cmd_del_key *cmd; 1721 u16 res_code = QLINK_CMD_RESULT_OK; 1722 int ret = 0; 1723 1724 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1725 QLINK_CMD_DEL_KEY, 1726 sizeof(*cmd)); 1727 if (unlikely(!cmd_skb)) 1728 return -ENOMEM; 1729 1730 qtnf_bus_lock(vif->mac->bus); 1731 1732 cmd = (struct qlink_cmd_del_key *)cmd_skb->data; 1733 1734 if (mac_addr) 1735 ether_addr_copy(cmd->addr, mac_addr); 1736 else 1737 eth_broadcast_addr(cmd->addr); 1738 1739 cmd->key_index = key_index; 1740 cmd->pairwise = pairwise; 1741 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1742 if (unlikely(ret)) 1743 goto out; 1744 1745 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1746 pr_err("VIF%u.%u: CMD failed: %u\n", 1747 vif->mac->macid, vif->vifid, res_code); 1748 ret = -EFAULT; 1749 goto out; 1750 } 1751 1752 out: 1753 qtnf_bus_unlock(vif->mac->bus); 1754 return ret; 1755 } 1756 1757 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index, 1758 bool unicast, bool multicast) 1759 { 1760 struct sk_buff *cmd_skb; 1761 struct qlink_cmd_set_def_key *cmd; 1762 u16 res_code = QLINK_CMD_RESULT_OK; 1763 int ret = 0; 1764 1765 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1766 QLINK_CMD_SET_DEFAULT_KEY, 1767 sizeof(*cmd)); 1768 if (unlikely(!cmd_skb)) 1769 return -ENOMEM; 1770 1771 qtnf_bus_lock(vif->mac->bus); 1772 1773 cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data; 1774 cmd->key_index = key_index; 1775 cmd->unicast = unicast; 1776 cmd->multicast = multicast; 1777 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1778 if (unlikely(ret)) 1779 goto out; 1780 1781 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1782 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1783 vif->vifid, res_code); 1784 ret = -EFAULT; 1785 goto out; 1786 } 1787 1788 out: 1789 qtnf_bus_unlock(vif->mac->bus); 1790 return ret; 1791 } 1792 1793 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index) 1794 { 1795 struct sk_buff *cmd_skb; 1796 struct qlink_cmd_set_def_mgmt_key *cmd; 1797 u16 res_code = QLINK_CMD_RESULT_OK; 1798 int ret = 0; 1799 1800 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1801 QLINK_CMD_SET_DEFAULT_MGMT_KEY, 1802 sizeof(*cmd)); 1803 if (unlikely(!cmd_skb)) 1804 return -ENOMEM; 1805 1806 qtnf_bus_lock(vif->mac->bus); 1807 1808 cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data; 1809 cmd->key_index = key_index; 1810 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1811 if (unlikely(ret)) 1812 goto out; 1813 1814 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1815 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1816 vif->vifid, res_code); 1817 ret = -EFAULT; 1818 goto out; 1819 } 1820 1821 out: 1822 qtnf_bus_unlock(vif->mac->bus); 1823 return ret; 1824 } 1825 1826 static u32 qtnf_encode_sta_flags(u32 flags) 1827 { 1828 u32 code = 0; 1829 1830 if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED)) 1831 code |= QLINK_STA_FLAG_AUTHORIZED; 1832 if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 1833 code |= QLINK_STA_FLAG_SHORT_PREAMBLE; 1834 if (flags & BIT(NL80211_STA_FLAG_WME)) 1835 code |= QLINK_STA_FLAG_WME; 1836 if (flags & BIT(NL80211_STA_FLAG_MFP)) 1837 code |= QLINK_STA_FLAG_MFP; 1838 if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED)) 1839 code |= QLINK_STA_FLAG_AUTHENTICATED; 1840 if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER)) 1841 code |= QLINK_STA_FLAG_TDLS_PEER; 1842 if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED)) 1843 code |= QLINK_STA_FLAG_ASSOCIATED; 1844 return code; 1845 } 1846 1847 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac, 1848 struct station_parameters *params) 1849 { 1850 struct sk_buff *cmd_skb; 1851 struct qlink_cmd_change_sta *cmd; 1852 u16 res_code = QLINK_CMD_RESULT_OK; 1853 int ret = 0; 1854 1855 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1856 QLINK_CMD_CHANGE_STA, 1857 sizeof(*cmd)); 1858 if (unlikely(!cmd_skb)) 1859 return -ENOMEM; 1860 1861 qtnf_bus_lock(vif->mac->bus); 1862 1863 cmd = (struct qlink_cmd_change_sta *)cmd_skb->data; 1864 ether_addr_copy(cmd->sta_addr, mac); 1865 1866 switch (vif->wdev.iftype) { 1867 case NL80211_IFTYPE_AP: 1868 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_AP); 1869 cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags( 1870 params->sta_flags_mask)); 1871 cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags( 1872 params->sta_flags_set)); 1873 break; 1874 case NL80211_IFTYPE_STATION: 1875 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 1876 cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags( 1877 params->sta_flags_mask)); 1878 cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags( 1879 params->sta_flags_set)); 1880 break; 1881 default: 1882 pr_err("unsupported iftype %d\n", vif->wdev.iftype); 1883 ret = -EINVAL; 1884 goto out; 1885 } 1886 1887 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1888 if (unlikely(ret)) 1889 goto out; 1890 1891 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1892 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1893 vif->vifid, res_code); 1894 ret = -EFAULT; 1895 goto out; 1896 } 1897 1898 out: 1899 qtnf_bus_unlock(vif->mac->bus); 1900 return ret; 1901 } 1902 1903 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif, 1904 struct station_del_parameters *params) 1905 { 1906 struct sk_buff *cmd_skb; 1907 struct qlink_cmd_del_sta *cmd; 1908 u16 res_code = QLINK_CMD_RESULT_OK; 1909 int ret = 0; 1910 1911 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1912 QLINK_CMD_DEL_STA, 1913 sizeof(*cmd)); 1914 if (unlikely(!cmd_skb)) 1915 return -ENOMEM; 1916 1917 qtnf_bus_lock(vif->mac->bus); 1918 1919 cmd = (struct qlink_cmd_del_sta *)cmd_skb->data; 1920 1921 if (params->mac) 1922 ether_addr_copy(cmd->sta_addr, params->mac); 1923 else 1924 eth_broadcast_addr(cmd->sta_addr); /* flush all stations */ 1925 1926 cmd->subtype = params->subtype; 1927 cmd->reason_code = cpu_to_le16(params->reason_code); 1928 1929 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1930 if (unlikely(ret)) 1931 goto out; 1932 1933 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1934 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1935 vif->vifid, res_code); 1936 ret = -EFAULT; 1937 goto out; 1938 } 1939 1940 out: 1941 qtnf_bus_unlock(vif->mac->bus); 1942 return ret; 1943 } 1944 1945 int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 1946 { 1947 struct sk_buff *cmd_skb; 1948 u16 res_code = QLINK_CMD_RESULT_OK; 1949 struct ieee80211_channel *sc; 1950 struct cfg80211_scan_request *scan_req = mac->scan_req; 1951 struct qlink_tlv_channel *qchan; 1952 int n_channels; 1953 int count = 0; 1954 int ret; 1955 u32 flags; 1956 1957 if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) { 1958 pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid); 1959 return -EINVAL; 1960 } 1961 1962 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1963 QLINK_CMD_SCAN, 1964 sizeof(struct qlink_cmd)); 1965 if (unlikely(!cmd_skb)) 1966 return -ENOMEM; 1967 1968 qtnf_bus_lock(mac->bus); 1969 1970 if (scan_req->n_ssids != 0) { 1971 while (count < scan_req->n_ssids) { 1972 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, 1973 scan_req->ssids[count].ssid, 1974 scan_req->ssids[count].ssid_len); 1975 count++; 1976 } 1977 } 1978 1979 if (scan_req->ie_len != 0) 1980 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 1981 scan_req->ie, 1982 scan_req->ie_len); 1983 1984 if (scan_req->n_channels) { 1985 n_channels = scan_req->n_channels; 1986 count = 0; 1987 1988 while (n_channels != 0) { 1989 sc = scan_req->channels[count]; 1990 if (sc->flags & IEEE80211_CHAN_DISABLED) { 1991 n_channels--; 1992 continue; 1993 } 1994 1995 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n", 1996 mac->macid, sc->hw_value, sc->center_freq, 1997 sc->flags); 1998 qchan = skb_put_zero(cmd_skb, sizeof(*qchan)); 1999 flags = 0; 2000 2001 qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); 2002 qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - 2003 sizeof(struct qlink_tlv_hdr)); 2004 qchan->center_freq = cpu_to_le16(sc->center_freq); 2005 qchan->hw_value = cpu_to_le16(sc->hw_value); 2006 2007 if (sc->flags & IEEE80211_CHAN_NO_IR) 2008 flags |= QLINK_CHAN_NO_IR; 2009 2010 if (sc->flags & IEEE80211_CHAN_RADAR) 2011 flags |= QLINK_CHAN_RADAR; 2012 2013 qchan->flags = cpu_to_le32(flags); 2014 n_channels--; 2015 count++; 2016 } 2017 } 2018 2019 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 2020 2021 if (unlikely(ret)) 2022 goto out; 2023 2024 pr_debug("MAC%u: scan started\n", mac->macid); 2025 2026 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2027 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 2028 ret = -EFAULT; 2029 goto out; 2030 } 2031 out: 2032 qtnf_bus_unlock(mac->bus); 2033 return ret; 2034 } 2035 2036 int qtnf_cmd_send_connect(struct qtnf_vif *vif, 2037 struct cfg80211_connect_params *sme) 2038 { 2039 struct sk_buff *cmd_skb; 2040 struct qlink_cmd_connect *cmd; 2041 struct qlink_auth_encr *aen; 2042 u16 res_code = QLINK_CMD_RESULT_OK; 2043 int ret; 2044 int i; 2045 u32 connect_flags = 0; 2046 2047 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2048 QLINK_CMD_CONNECT, 2049 sizeof(*cmd)); 2050 if (unlikely(!cmd_skb)) 2051 return -ENOMEM; 2052 2053 cmd = (struct qlink_cmd_connect *)cmd_skb->data; 2054 2055 ether_addr_copy(cmd->bssid, vif->bssid); 2056 2057 if (sme->channel) 2058 cmd->channel = cpu_to_le16(sme->channel->hw_value); 2059 else 2060 cmd->channel = 0; 2061 2062 if ((sme->bg_scan_period > 0) && 2063 (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD)) 2064 cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period); 2065 else if (sme->bg_scan_period == -1) 2066 cmd->bg_scan_period = cpu_to_le16(QTNF_DEFAULT_BG_SCAN_PERIOD); 2067 else 2068 cmd->bg_scan_period = 0; /* disabled */ 2069 2070 if (sme->flags & ASSOC_REQ_DISABLE_HT) 2071 connect_flags |= QLINK_STA_CONNECT_DISABLE_HT; 2072 if (sme->flags & ASSOC_REQ_DISABLE_VHT) 2073 connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT; 2074 if (sme->flags & ASSOC_REQ_USE_RRM) 2075 connect_flags |= QLINK_STA_CONNECT_USE_RRM; 2076 2077 cmd->flags = cpu_to_le32(connect_flags); 2078 2079 aen = &cmd->aen; 2080 aen->auth_type = sme->auth_type; 2081 aen->privacy = !!sme->privacy; 2082 aen->mfp = sme->mfp; 2083 aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions); 2084 aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group); 2085 aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise); 2086 2087 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 2088 aen->ciphers_pairwise[i] = 2089 cpu_to_le32(sme->crypto.ciphers_pairwise[i]); 2090 2091 aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites); 2092 2093 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 2094 aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]); 2095 2096 aen->control_port = sme->crypto.control_port; 2097 aen->control_port_no_encrypt = 2098 sme->crypto.control_port_no_encrypt; 2099 aen->control_port_ethertype = 2100 cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype)); 2101 2102 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid, 2103 sme->ssid_len); 2104 2105 if (sme->ie_len != 0) 2106 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2107 sme->ie, 2108 sme->ie_len); 2109 2110 qtnf_bus_lock(vif->mac->bus); 2111 2112 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2113 2114 if (unlikely(ret)) 2115 goto out; 2116 2117 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2118 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2119 vif->vifid, res_code); 2120 ret = -EFAULT; 2121 goto out; 2122 } 2123 out: 2124 qtnf_bus_unlock(vif->mac->bus); 2125 return ret; 2126 } 2127 2128 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code) 2129 { 2130 struct sk_buff *cmd_skb; 2131 struct qlink_cmd_disconnect *cmd; 2132 u16 res_code = QLINK_CMD_RESULT_OK; 2133 int ret; 2134 2135 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2136 QLINK_CMD_DISCONNECT, 2137 sizeof(*cmd)); 2138 if (unlikely(!cmd_skb)) 2139 return -ENOMEM; 2140 2141 qtnf_bus_lock(vif->mac->bus); 2142 2143 cmd = (struct qlink_cmd_disconnect *)cmd_skb->data; 2144 cmd->reason = cpu_to_le16(reason_code); 2145 2146 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2147 2148 if (unlikely(ret)) 2149 goto out; 2150 2151 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2152 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2153 vif->vifid, res_code); 2154 ret = -EFAULT; 2155 goto out; 2156 } 2157 out: 2158 qtnf_bus_unlock(vif->mac->bus); 2159 return ret; 2160 } 2161 2162 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up) 2163 { 2164 struct sk_buff *cmd_skb; 2165 struct qlink_cmd_updown *cmd; 2166 u16 res_code = QLINK_CMD_RESULT_OK; 2167 int ret; 2168 2169 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2170 QLINK_CMD_UPDOWN_INTF, 2171 sizeof(*cmd)); 2172 if (unlikely(!cmd_skb)) 2173 return -ENOMEM; 2174 2175 cmd = (struct qlink_cmd_updown *)cmd_skb->data; 2176 cmd->if_up = !!up; 2177 2178 qtnf_bus_lock(vif->mac->bus); 2179 2180 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2181 2182 if (unlikely(ret)) 2183 goto out; 2184 2185 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2186 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2187 vif->vifid, res_code); 2188 ret = -EFAULT; 2189 goto out; 2190 } 2191 out: 2192 qtnf_bus_unlock(vif->mac->bus); 2193 return ret; 2194 } 2195 2196 int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req) 2197 { 2198 struct sk_buff *cmd_skb; 2199 int ret; 2200 u16 res_code; 2201 struct qlink_cmd_reg_notify *cmd; 2202 2203 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 2204 QLINK_CMD_REG_NOTIFY, 2205 sizeof(*cmd)); 2206 if (!cmd_skb) 2207 return -ENOMEM; 2208 2209 cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data; 2210 cmd->alpha2[0] = req->alpha2[0]; 2211 cmd->alpha2[1] = req->alpha2[1]; 2212 2213 switch (req->initiator) { 2214 case NL80211_REGDOM_SET_BY_CORE: 2215 cmd->initiator = QLINK_REGDOM_SET_BY_CORE; 2216 break; 2217 case NL80211_REGDOM_SET_BY_USER: 2218 cmd->initiator = QLINK_REGDOM_SET_BY_USER; 2219 break; 2220 case NL80211_REGDOM_SET_BY_DRIVER: 2221 cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER; 2222 break; 2223 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2224 cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE; 2225 break; 2226 } 2227 2228 switch (req->user_reg_hint_type) { 2229 case NL80211_USER_REG_HINT_USER: 2230 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER; 2231 break; 2232 case NL80211_USER_REG_HINT_CELL_BASE: 2233 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE; 2234 break; 2235 case NL80211_USER_REG_HINT_INDOOR: 2236 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR; 2237 break; 2238 } 2239 2240 qtnf_bus_lock(bus); 2241 2242 ret = qtnf_cmd_send(bus, cmd_skb, &res_code); 2243 if (ret) 2244 goto out; 2245 2246 switch (res_code) { 2247 case QLINK_CMD_RESULT_ENOTSUPP: 2248 pr_warn("reg update not supported\n"); 2249 ret = -EOPNOTSUPP; 2250 break; 2251 case QLINK_CMD_RESULT_EALREADY: 2252 pr_info("regulatory domain is already set to %c%c", 2253 req->alpha2[0], req->alpha2[1]); 2254 ret = -EALREADY; 2255 break; 2256 case QLINK_CMD_RESULT_OK: 2257 ret = 0; 2258 break; 2259 default: 2260 ret = -EFAULT; 2261 break; 2262 } 2263 2264 out: 2265 qtnf_bus_unlock(bus); 2266 2267 return ret; 2268 } 2269 2270 int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel, 2271 struct qtnf_chan_stats *stats) 2272 { 2273 struct sk_buff *cmd_skb, *resp_skb = NULL; 2274 struct qlink_cmd_get_chan_stats *cmd; 2275 struct qlink_resp_get_chan_stats *resp; 2276 size_t var_data_len; 2277 u16 res_code = QLINK_CMD_RESULT_OK; 2278 int ret = 0; 2279 2280 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2281 QLINK_CMD_CHAN_STATS, 2282 sizeof(*cmd)); 2283 if (!cmd_skb) 2284 return -ENOMEM; 2285 2286 qtnf_bus_lock(mac->bus); 2287 2288 cmd = (struct qlink_cmd_get_chan_stats *)cmd_skb->data; 2289 cmd->channel = cpu_to_le16(channel); 2290 2291 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 2292 sizeof(*resp), &var_data_len); 2293 if (unlikely(ret)) { 2294 qtnf_bus_unlock(mac->bus); 2295 return ret; 2296 } 2297 2298 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2299 switch (res_code) { 2300 case QLINK_CMD_RESULT_ENOTFOUND: 2301 ret = -ENOENT; 2302 break; 2303 default: 2304 pr_err("cmd exec failed: 0x%.4X\n", res_code); 2305 ret = -EFAULT; 2306 break; 2307 } 2308 goto out; 2309 } 2310 2311 resp = (struct qlink_resp_get_chan_stats *)resp_skb->data; 2312 ret = qtnf_cmd_resp_proc_chan_stat_info(stats, resp->info, 2313 var_data_len); 2314 2315 out: 2316 qtnf_bus_unlock(mac->bus); 2317 consume_skb(resp_skb); 2318 return ret; 2319 } 2320 2321 int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif, 2322 struct cfg80211_csa_settings *params) 2323 { 2324 struct qtnf_wmac *mac = vif->mac; 2325 struct qlink_cmd_chan_switch *cmd; 2326 struct sk_buff *cmd_skb; 2327 u16 res_code = QLINK_CMD_RESULT_OK; 2328 int ret; 2329 2330 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid, 2331 QLINK_CMD_CHAN_SWITCH, 2332 sizeof(*cmd)); 2333 2334 if (unlikely(!cmd_skb)) 2335 return -ENOMEM; 2336 2337 qtnf_bus_lock(mac->bus); 2338 2339 cmd = (struct qlink_cmd_chan_switch *)cmd_skb->data; 2340 cmd->channel = cpu_to_le16(params->chandef.chan->hw_value); 2341 cmd->radar_required = params->radar_required; 2342 cmd->block_tx = params->block_tx; 2343 cmd->beacon_count = params->count; 2344 2345 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 2346 2347 if (unlikely(ret)) 2348 goto out; 2349 2350 switch (res_code) { 2351 case QLINK_CMD_RESULT_OK: 2352 ret = 0; 2353 break; 2354 case QLINK_CMD_RESULT_ENOTFOUND: 2355 ret = -ENOENT; 2356 break; 2357 case QLINK_CMD_RESULT_ENOTSUPP: 2358 ret = -EOPNOTSUPP; 2359 break; 2360 case QLINK_CMD_RESULT_EALREADY: 2361 ret = -EALREADY; 2362 break; 2363 case QLINK_CMD_RESULT_INVALID: 2364 default: 2365 ret = -EFAULT; 2366 break; 2367 } 2368 2369 out: 2370 qtnf_bus_unlock(mac->bus); 2371 return ret; 2372 } 2373 2374 int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef) 2375 { 2376 struct qtnf_bus *bus = vif->mac->bus; 2377 const struct qlink_resp_channel_get *resp; 2378 struct sk_buff *cmd_skb; 2379 struct sk_buff *resp_skb = NULL; 2380 u16 res_code = QLINK_CMD_RESULT_OK; 2381 int ret; 2382 2383 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2384 QLINK_CMD_CHAN_GET, 2385 sizeof(struct qlink_cmd)); 2386 if (unlikely(!cmd_skb)) 2387 return -ENOMEM; 2388 2389 qtnf_bus_lock(bus); 2390 2391 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code, 2392 sizeof(*resp), NULL); 2393 2394 qtnf_bus_unlock(bus); 2395 2396 if (unlikely(ret)) 2397 goto out; 2398 2399 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2400 ret = -ENODATA; 2401 goto out; 2402 } 2403 2404 resp = (const struct qlink_resp_channel_get *)resp_skb->data; 2405 qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef); 2406 2407 out: 2408 consume_skb(resp_skb); 2409 return ret; 2410 } 2411