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 vif->bss_status |= QTNF_STATE_AP_START; 177 netif_carrier_on(vif->netdev); 178 179 out: 180 qtnf_bus_unlock(vif->mac->bus); 181 return ret; 182 } 183 184 int qtnf_cmd_send_config_ap(struct qtnf_vif *vif) 185 { 186 struct sk_buff *cmd_skb; 187 struct qtnf_bss_config *bss_cfg = &vif->bss_cfg; 188 struct cfg80211_chan_def *chandef = &vif->mac->chandef; 189 struct qlink_tlv_channel *qchan; 190 struct qlink_auth_encr aen; 191 u16 res_code = QLINK_CMD_RESULT_OK; 192 int ret; 193 int i; 194 195 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 196 QLINK_CMD_CONFIG_AP, 197 sizeof(struct qlink_cmd)); 198 if (unlikely(!cmd_skb)) 199 return -ENOMEM; 200 201 qtnf_bus_lock(vif->mac->bus); 202 203 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid, 204 bss_cfg->ssid_len); 205 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_BCN_PERIOD, 206 bss_cfg->bcn_period); 207 qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_DTIM, bss_cfg->dtim); 208 209 qchan = skb_put_zero(cmd_skb, sizeof(*qchan)); 210 qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); 211 qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - 212 sizeof(struct qlink_tlv_hdr)); 213 qchan->hw_value = cpu_to_le16( 214 ieee80211_frequency_to_channel(chandef->chan->center_freq)); 215 216 memset(&aen, 0, sizeof(aen)); 217 aen.auth_type = bss_cfg->auth_type; 218 aen.privacy = !!bss_cfg->privacy; 219 aen.mfp = bss_cfg->mfp; 220 aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions); 221 aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group); 222 aen.n_ciphers_pairwise = cpu_to_le32( 223 bss_cfg->crypto.n_ciphers_pairwise); 224 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 225 aen.ciphers_pairwise[i] = cpu_to_le32( 226 bss_cfg->crypto.ciphers_pairwise[i]); 227 aen.n_akm_suites = cpu_to_le32( 228 bss_cfg->crypto.n_akm_suites); 229 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 230 aen.akm_suites[i] = cpu_to_le32( 231 bss_cfg->crypto.akm_suites[i]); 232 aen.control_port = bss_cfg->crypto.control_port; 233 aen.control_port_no_encrypt = 234 bss_cfg->crypto.control_port_no_encrypt; 235 aen.control_port_ethertype = cpu_to_le16(be16_to_cpu( 236 bss_cfg->crypto.control_port_ethertype)); 237 238 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen, 239 sizeof(aen)); 240 241 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 242 243 if (unlikely(ret)) 244 goto out; 245 246 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 247 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 248 vif->vifid, res_code); 249 ret = -EFAULT; 250 goto out; 251 } 252 253 vif->bss_status |= QTNF_STATE_AP_CONFIG; 254 255 out: 256 qtnf_bus_unlock(vif->mac->bus); 257 return ret; 258 } 259 260 int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif) 261 { 262 struct sk_buff *cmd_skb; 263 u16 res_code = QLINK_CMD_RESULT_OK; 264 int ret; 265 266 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 267 QLINK_CMD_STOP_AP, 268 sizeof(struct qlink_cmd)); 269 if (unlikely(!cmd_skb)) 270 return -ENOMEM; 271 272 qtnf_bus_lock(vif->mac->bus); 273 274 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 275 276 if (unlikely(ret)) 277 goto out; 278 279 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 280 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 281 vif->vifid, res_code); 282 ret = -EFAULT; 283 goto out; 284 } 285 286 vif->bss_status &= ~QTNF_STATE_AP_START; 287 vif->bss_status &= ~QTNF_STATE_AP_CONFIG; 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\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 983 return 0; 984 } 985 986 static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, 987 const u8 *tlv_buf, size_t tlv_buf_size) 988 { 989 struct ieee80211_iface_limit *limits = NULL; 990 const struct qlink_iface_limit *limit_record; 991 size_t record_count = 0, rec = 0; 992 u16 tlv_type, tlv_value_len; 993 struct qlink_iface_comb_num *comb; 994 size_t tlv_full_len; 995 const struct qlink_tlv_hdr *tlv; 996 997 mac->macinfo.n_limits = 0; 998 999 tlv = (const struct qlink_tlv_hdr *)tlv_buf; 1000 while (tlv_buf_size >= sizeof(struct qlink_tlv_hdr)) { 1001 tlv_type = le16_to_cpu(tlv->type); 1002 tlv_value_len = le16_to_cpu(tlv->len); 1003 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 1004 if (tlv_full_len > tlv_buf_size) { 1005 pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n", 1006 mac->macid, tlv_type, tlv_value_len); 1007 return -EINVAL; 1008 } 1009 1010 switch (tlv_type) { 1011 case QTN_TLV_ID_NUM_IFACE_COMB: 1012 if (unlikely(tlv_value_len != sizeof(*comb))) 1013 return -EINVAL; 1014 1015 comb = (void *)tlv->val; 1016 record_count = le16_to_cpu(comb->iface_comb_num); 1017 1018 mac->macinfo.n_limits = record_count; 1019 /* free earlier iface limits memory */ 1020 kfree(mac->macinfo.limits); 1021 mac->macinfo.limits = 1022 kzalloc(sizeof(*mac->macinfo.limits) * 1023 record_count, GFP_KERNEL); 1024 1025 if (unlikely(!mac->macinfo.limits)) 1026 return -ENOMEM; 1027 1028 limits = mac->macinfo.limits; 1029 break; 1030 case QTN_TLV_ID_IFACE_LIMIT: 1031 if (unlikely(!limits)) { 1032 pr_warn("MAC%u: limits are not inited\n", 1033 mac->macid); 1034 return -EINVAL; 1035 } 1036 1037 if (unlikely(tlv_value_len != sizeof(*limit_record))) { 1038 pr_warn("MAC%u: record size mismatch\n", 1039 mac->macid); 1040 return -EINVAL; 1041 } 1042 1043 limit_record = (void *)tlv->val; 1044 limits[rec].max = le16_to_cpu(limit_record->max_num); 1045 limits[rec].types = qlink_iface_type_to_nl_mask( 1046 le16_to_cpu(limit_record->type)); 1047 1048 /* supported modes: STA, AP */ 1049 limits[rec].types &= BIT(NL80211_IFTYPE_AP) | 1050 BIT(NL80211_IFTYPE_AP_VLAN) | 1051 BIT(NL80211_IFTYPE_STATION); 1052 1053 pr_debug("MAC%u: MAX: %u; TYPES: %.4X\n", mac->macid, 1054 limits[rec].max, limits[rec].types); 1055 1056 if (limits[rec].types) 1057 rec++; 1058 break; 1059 default: 1060 break; 1061 } 1062 1063 tlv_buf_size -= tlv_full_len; 1064 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 1065 } 1066 1067 if (tlv_buf_size) { 1068 pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n", 1069 mac->macid, tlv_buf_size); 1070 return -EINVAL; 1071 } 1072 1073 if (mac->macinfo.n_limits != rec) { 1074 pr_err("MAC%u: combination mismatch: reported=%zu parsed=%zu\n", 1075 mac->macid, mac->macinfo.n_limits, rec); 1076 return -EINVAL; 1077 } 1078 1079 return 0; 1080 } 1081 1082 static void 1083 qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, 1084 const struct qlink_resp_get_mac_info *resp_info) 1085 { 1086 struct qtnf_mac_info *mac_info; 1087 struct qtnf_vif *vif; 1088 1089 mac_info = &mac->macinfo; 1090 1091 mac_info->bands_cap = resp_info->bands_cap; 1092 mac_info->phymode_cap = resp_info->phymode_cap; 1093 memcpy(&mac_info->dev_mac, &resp_info->dev_mac, 1094 sizeof(mac_info->dev_mac)); 1095 1096 ether_addr_copy(mac->macaddr, mac_info->dev_mac); 1097 1098 vif = qtnf_mac_get_base_vif(mac); 1099 if (vif) 1100 ether_addr_copy(vif->mac_addr, mac->macaddr); 1101 else 1102 pr_err("could not get valid base vif\n"); 1103 1104 mac_info->num_tx_chain = resp_info->num_tx_chain; 1105 mac_info->num_rx_chain = resp_info->num_rx_chain; 1106 1107 mac_info->max_ap_assoc_sta = le16_to_cpu(resp_info->max_ap_assoc_sta); 1108 mac_info->radar_detect_widths = 1109 qlink_chan_width_mask_to_nl(le16_to_cpu( 1110 resp_info->radar_detect_widths)); 1111 1112 memcpy(&mac_info->ht_cap, &resp_info->ht_cap, sizeof(mac_info->ht_cap)); 1113 memcpy(&mac_info->vht_cap, &resp_info->vht_cap, 1114 sizeof(mac_info->vht_cap)); 1115 } 1116 1117 static int 1118 qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band, 1119 struct qlink_resp_get_chan_info *resp, 1120 size_t payload_len) 1121 { 1122 u16 tlv_type; 1123 size_t tlv_len; 1124 const struct qlink_tlv_hdr *tlv; 1125 const struct qlink_tlv_channel *qchan; 1126 struct ieee80211_channel *chan; 1127 unsigned int chidx = 0; 1128 u32 qflags; 1129 1130 if (band->channels) { 1131 if (band->n_channels == resp->num_chans) { 1132 memset(band->channels, 0, 1133 sizeof(*band->channels) * band->n_channels); 1134 } else { 1135 kfree(band->channels); 1136 band->n_channels = 0; 1137 band->channels = NULL; 1138 } 1139 } 1140 1141 band->n_channels = resp->num_chans; 1142 if (band->n_channels == 0) 1143 return 0; 1144 1145 if (!band->channels) 1146 band->channels = kcalloc(band->n_channels, sizeof(*chan), 1147 GFP_KERNEL); 1148 if (!band->channels) { 1149 band->n_channels = 0; 1150 return -ENOMEM; 1151 } 1152 1153 tlv = (struct qlink_tlv_hdr *)resp->info; 1154 1155 while (payload_len >= sizeof(*tlv)) { 1156 tlv_type = le16_to_cpu(tlv->type); 1157 tlv_len = le16_to_cpu(tlv->len) + sizeof(*tlv); 1158 1159 if (tlv_len > payload_len) { 1160 pr_warn("malformed TLV 0x%.2X; LEN: %zu\n", 1161 tlv_type, tlv_len); 1162 goto error_ret; 1163 } 1164 1165 switch (tlv_type) { 1166 case QTN_TLV_ID_CHANNEL: 1167 if (unlikely(tlv_len != sizeof(*qchan))) { 1168 pr_err("invalid channel TLV len %zu\n", 1169 tlv_len); 1170 goto error_ret; 1171 } 1172 1173 if (chidx == band->n_channels) { 1174 pr_err("too many channel TLVs\n"); 1175 goto error_ret; 1176 } 1177 1178 qchan = (const struct qlink_tlv_channel *)tlv; 1179 chan = &band->channels[chidx++]; 1180 qflags = le32_to_cpu(qchan->flags); 1181 1182 chan->hw_value = le16_to_cpu(qchan->hw_value); 1183 chan->band = band->band; 1184 chan->center_freq = le16_to_cpu(qchan->center_freq); 1185 chan->max_antenna_gain = (int)qchan->max_antenna_gain; 1186 chan->max_power = (int)qchan->max_power; 1187 chan->max_reg_power = (int)qchan->max_reg_power; 1188 chan->beacon_found = qchan->beacon_found; 1189 chan->dfs_cac_ms = le32_to_cpu(qchan->dfs_cac_ms); 1190 chan->flags = 0; 1191 1192 if (qflags & QLINK_CHAN_DISABLED) 1193 chan->flags |= IEEE80211_CHAN_DISABLED; 1194 1195 if (qflags & QLINK_CHAN_NO_IR) 1196 chan->flags |= IEEE80211_CHAN_NO_IR; 1197 1198 if (qflags & QLINK_CHAN_NO_HT40PLUS) 1199 chan->flags |= IEEE80211_CHAN_NO_HT40PLUS; 1200 1201 if (qflags & QLINK_CHAN_NO_HT40MINUS) 1202 chan->flags |= IEEE80211_CHAN_NO_HT40MINUS; 1203 1204 if (qflags & QLINK_CHAN_NO_OFDM) 1205 chan->flags |= IEEE80211_CHAN_NO_OFDM; 1206 1207 if (qflags & QLINK_CHAN_NO_80MHZ) 1208 chan->flags |= IEEE80211_CHAN_NO_80MHZ; 1209 1210 if (qflags & QLINK_CHAN_NO_160MHZ) 1211 chan->flags |= IEEE80211_CHAN_NO_160MHZ; 1212 1213 if (qflags & QLINK_CHAN_INDOOR_ONLY) 1214 chan->flags |= IEEE80211_CHAN_INDOOR_ONLY; 1215 1216 if (qflags & QLINK_CHAN_IR_CONCURRENT) 1217 chan->flags |= IEEE80211_CHAN_IR_CONCURRENT; 1218 1219 if (qflags & QLINK_CHAN_NO_20MHZ) 1220 chan->flags |= IEEE80211_CHAN_NO_20MHZ; 1221 1222 if (qflags & QLINK_CHAN_NO_10MHZ) 1223 chan->flags |= IEEE80211_CHAN_NO_10MHZ; 1224 1225 if (qflags & QLINK_CHAN_RADAR) { 1226 chan->flags |= IEEE80211_CHAN_RADAR; 1227 chan->dfs_state_entered = jiffies; 1228 1229 if (qchan->dfs_state == QLINK_DFS_USABLE) 1230 chan->dfs_state = NL80211_DFS_USABLE; 1231 else if (qchan->dfs_state == 1232 QLINK_DFS_AVAILABLE) 1233 chan->dfs_state = NL80211_DFS_AVAILABLE; 1234 else 1235 chan->dfs_state = 1236 NL80211_DFS_UNAVAILABLE; 1237 } 1238 1239 pr_debug("chan=%d flags=%#x max_pow=%d max_reg_pow=%d\n", 1240 chan->hw_value, chan->flags, chan->max_power, 1241 chan->max_reg_power); 1242 break; 1243 default: 1244 pr_warn("unknown TLV type: %#x\n", tlv_type); 1245 break; 1246 } 1247 1248 payload_len -= tlv_len; 1249 tlv = (struct qlink_tlv_hdr *)((u8 *)tlv + tlv_len); 1250 } 1251 1252 if (payload_len) { 1253 pr_err("malformed TLV buf; bytes left: %zu\n", payload_len); 1254 goto error_ret; 1255 } 1256 1257 if (band->n_channels != chidx) { 1258 pr_err("channel count mismatch: reported=%d, parsed=%d\n", 1259 band->n_channels, chidx); 1260 goto error_ret; 1261 } 1262 1263 return 0; 1264 1265 error_ret: 1266 kfree(band->channels); 1267 band->channels = NULL; 1268 band->n_channels = 0; 1269 1270 return -EINVAL; 1271 } 1272 1273 static int qtnf_cmd_resp_proc_phy_params(struct qtnf_wmac *mac, 1274 const u8 *payload, size_t payload_len) 1275 { 1276 struct qtnf_mac_info *mac_info; 1277 struct qlink_tlv_frag_rts_thr *phy_thr; 1278 struct qlink_tlv_rlimit *limit; 1279 struct qlink_tlv_cclass *class; 1280 u16 tlv_type; 1281 u16 tlv_value_len; 1282 size_t tlv_full_len; 1283 const struct qlink_tlv_hdr *tlv; 1284 1285 mac_info = &mac->macinfo; 1286 1287 tlv = (struct qlink_tlv_hdr *)payload; 1288 while (payload_len >= sizeof(struct qlink_tlv_hdr)) { 1289 tlv_type = le16_to_cpu(tlv->type); 1290 tlv_value_len = le16_to_cpu(tlv->len); 1291 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 1292 1293 if (tlv_full_len > payload_len) { 1294 pr_warn("MAC%u: malformed TLV 0x%.2X; LEN: %u\n", 1295 mac->macid, tlv_type, tlv_value_len); 1296 return -EINVAL; 1297 } 1298 1299 switch (tlv_type) { 1300 case QTN_TLV_ID_FRAG_THRESH: 1301 phy_thr = (void *)tlv; 1302 mac_info->frag_thr = (u32)le16_to_cpu(phy_thr->thr); 1303 break; 1304 case QTN_TLV_ID_RTS_THRESH: 1305 phy_thr = (void *)tlv; 1306 mac_info->rts_thr = (u32)le16_to_cpu(phy_thr->thr); 1307 break; 1308 case QTN_TLV_ID_SRETRY_LIMIT: 1309 limit = (void *)tlv; 1310 mac_info->sretry_limit = limit->rlimit; 1311 break; 1312 case QTN_TLV_ID_LRETRY_LIMIT: 1313 limit = (void *)tlv; 1314 mac_info->lretry_limit = limit->rlimit; 1315 break; 1316 case QTN_TLV_ID_COVERAGE_CLASS: 1317 class = (void *)tlv; 1318 mac_info->coverage_class = class->cclass; 1319 break; 1320 default: 1321 pr_err("MAC%u: Unknown TLV type: %#x\n", mac->macid, 1322 le16_to_cpu(tlv->type)); 1323 break; 1324 } 1325 1326 payload_len -= tlv_full_len; 1327 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 1328 } 1329 1330 if (payload_len) { 1331 pr_warn("MAC%u: malformed TLV buf; bytes left: %zu\n", 1332 mac->macid, payload_len); 1333 return -EINVAL; 1334 } 1335 1336 return 0; 1337 } 1338 1339 static int 1340 qtnf_cmd_resp_proc_chan_stat_info(struct qtnf_chan_stats *stats, 1341 const u8 *payload, size_t payload_len) 1342 { 1343 struct qlink_chan_stats *qlink_stats; 1344 const struct qlink_tlv_hdr *tlv; 1345 size_t tlv_full_len; 1346 u16 tlv_value_len; 1347 u16 tlv_type; 1348 1349 tlv = (struct qlink_tlv_hdr *)payload; 1350 while (payload_len >= sizeof(struct qlink_tlv_hdr)) { 1351 tlv_type = le16_to_cpu(tlv->type); 1352 tlv_value_len = le16_to_cpu(tlv->len); 1353 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 1354 if (tlv_full_len > payload_len) { 1355 pr_warn("malformed TLV 0x%.2X; LEN: %u\n", 1356 tlv_type, tlv_value_len); 1357 return -EINVAL; 1358 } 1359 switch (tlv_type) { 1360 case QTN_TLV_ID_CHANNEL_STATS: 1361 if (unlikely(tlv_value_len != sizeof(*qlink_stats))) { 1362 pr_err("invalid CHANNEL_STATS entry size\n"); 1363 return -EINVAL; 1364 } 1365 1366 qlink_stats = (void *)tlv->val; 1367 1368 stats->chan_num = le32_to_cpu(qlink_stats->chan_num); 1369 stats->cca_tx = le32_to_cpu(qlink_stats->cca_tx); 1370 stats->cca_rx = le32_to_cpu(qlink_stats->cca_rx); 1371 stats->cca_busy = le32_to_cpu(qlink_stats->cca_busy); 1372 stats->cca_try = le32_to_cpu(qlink_stats->cca_try); 1373 stats->chan_noise = qlink_stats->chan_noise; 1374 1375 pr_debug("chan(%u) try(%u) busy(%u) noise(%d)\n", 1376 stats->chan_num, stats->cca_try, 1377 stats->cca_busy, stats->chan_noise); 1378 break; 1379 default: 1380 pr_warn("Unknown TLV type: %#x\n", 1381 le16_to_cpu(tlv->type)); 1382 } 1383 payload_len -= tlv_full_len; 1384 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 1385 } 1386 1387 if (payload_len) { 1388 pr_warn("malformed TLV buf; bytes left: %zu\n", payload_len); 1389 return -EINVAL; 1390 } 1391 1392 return 0; 1393 } 1394 1395 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac) 1396 { 1397 struct sk_buff *cmd_skb, *resp_skb = NULL; 1398 const struct qlink_resp_get_mac_info *resp; 1399 size_t var_data_len; 1400 u16 res_code = QLINK_CMD_RESULT_OK; 1401 int ret = 0; 1402 1403 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1404 QLINK_CMD_MAC_INFO, 1405 sizeof(struct qlink_cmd)); 1406 if (unlikely(!cmd_skb)) 1407 return -ENOMEM; 1408 1409 qtnf_bus_lock(mac->bus); 1410 1411 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1412 sizeof(*resp), &var_data_len); 1413 if (unlikely(ret)) 1414 goto out; 1415 1416 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1417 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1418 ret = -EFAULT; 1419 goto out; 1420 } 1421 1422 resp = (const struct qlink_resp_get_mac_info *)resp_skb->data; 1423 qtnf_cmd_resp_proc_mac_info(mac, resp); 1424 ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len); 1425 1426 out: 1427 qtnf_bus_unlock(mac->bus); 1428 consume_skb(resp_skb); 1429 1430 return ret; 1431 } 1432 1433 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus) 1434 { 1435 struct sk_buff *cmd_skb, *resp_skb = NULL; 1436 const struct qlink_resp_get_hw_info *resp; 1437 u16 res_code = QLINK_CMD_RESULT_OK; 1438 int ret = 0; 1439 size_t info_len; 1440 1441 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1442 QLINK_CMD_GET_HW_INFO, 1443 sizeof(struct qlink_cmd)); 1444 if (unlikely(!cmd_skb)) 1445 return -ENOMEM; 1446 1447 qtnf_bus_lock(bus); 1448 1449 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code, 1450 sizeof(*resp), &info_len); 1451 1452 if (unlikely(ret)) 1453 goto out; 1454 1455 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1456 pr_err("cmd exec failed: 0x%.4X\n", res_code); 1457 ret = -EFAULT; 1458 goto out; 1459 } 1460 1461 resp = (const struct qlink_resp_get_hw_info *)resp_skb->data; 1462 ret = qtnf_cmd_resp_proc_hw_info(bus, resp, info_len); 1463 1464 out: 1465 qtnf_bus_unlock(bus); 1466 consume_skb(resp_skb); 1467 1468 return ret; 1469 } 1470 1471 int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, 1472 struct ieee80211_supported_band *band) 1473 { 1474 struct sk_buff *cmd_skb, *resp_skb = NULL; 1475 size_t info_len; 1476 struct qlink_cmd_chans_info_get *cmd; 1477 struct qlink_resp_get_chan_info *resp; 1478 u16 res_code = QLINK_CMD_RESULT_OK; 1479 int ret = 0; 1480 u8 qband; 1481 1482 switch (band->band) { 1483 case NL80211_BAND_2GHZ: 1484 qband = QLINK_BAND_2GHZ; 1485 break; 1486 case NL80211_BAND_5GHZ: 1487 qband = QLINK_BAND_5GHZ; 1488 break; 1489 case NL80211_BAND_60GHZ: 1490 qband = QLINK_BAND_60GHZ; 1491 break; 1492 default: 1493 return -EINVAL; 1494 } 1495 1496 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1497 QLINK_CMD_CHANS_INFO_GET, 1498 sizeof(*cmd)); 1499 if (!cmd_skb) 1500 return -ENOMEM; 1501 1502 cmd = (struct qlink_cmd_chans_info_get *)cmd_skb->data; 1503 cmd->band = qband; 1504 1505 qtnf_bus_lock(mac->bus); 1506 1507 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1508 sizeof(*resp), &info_len); 1509 1510 if (unlikely(ret)) 1511 goto out; 1512 1513 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1514 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1515 ret = -EFAULT; 1516 goto out; 1517 } 1518 1519 resp = (struct qlink_resp_get_chan_info *)resp_skb->data; 1520 if (resp->band != qband) { 1521 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, 1522 resp->band, qband); 1523 ret = -EINVAL; 1524 goto out; 1525 } 1526 1527 ret = qtnf_cmd_resp_fill_channels_info(band, resp, info_len); 1528 1529 out: 1530 qtnf_bus_unlock(mac->bus); 1531 consume_skb(resp_skb); 1532 1533 return ret; 1534 } 1535 1536 int qtnf_cmd_send_get_phy_params(struct qtnf_wmac *mac) 1537 { 1538 struct sk_buff *cmd_skb, *resp_skb = NULL; 1539 size_t response_size; 1540 struct qlink_resp_phy_params *resp; 1541 u16 res_code = QLINK_CMD_RESULT_OK; 1542 int ret = 0; 1543 1544 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1545 QLINK_CMD_PHY_PARAMS_GET, 1546 sizeof(struct qlink_cmd)); 1547 if (!cmd_skb) 1548 return -ENOMEM; 1549 1550 qtnf_bus_lock(mac->bus); 1551 1552 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1553 sizeof(*resp), &response_size); 1554 1555 if (unlikely(ret)) 1556 goto out; 1557 1558 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1559 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1560 ret = -EFAULT; 1561 goto out; 1562 } 1563 1564 resp = (struct qlink_resp_phy_params *)resp_skb->data; 1565 ret = qtnf_cmd_resp_proc_phy_params(mac, resp->info, response_size); 1566 1567 out: 1568 qtnf_bus_unlock(mac->bus); 1569 consume_skb(resp_skb); 1570 1571 return ret; 1572 } 1573 1574 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed) 1575 { 1576 struct wiphy *wiphy = priv_to_wiphy(mac); 1577 struct sk_buff *cmd_skb; 1578 u16 res_code = QLINK_CMD_RESULT_OK; 1579 int ret = 0; 1580 1581 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1582 QLINK_CMD_PHY_PARAMS_SET, 1583 sizeof(struct qlink_cmd)); 1584 if (!cmd_skb) 1585 return -ENOMEM; 1586 1587 qtnf_bus_lock(mac->bus); 1588 1589 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 1590 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_FRAG_THRESH, 1591 wiphy->frag_threshold); 1592 if (changed & WIPHY_PARAM_RTS_THRESHOLD) 1593 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_RTS_THRESH, 1594 wiphy->rts_threshold); 1595 if (changed & WIPHY_PARAM_COVERAGE_CLASS) 1596 qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS, 1597 wiphy->coverage_class); 1598 1599 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 1600 1601 if (unlikely(ret)) 1602 goto out; 1603 1604 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1605 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1606 ret = -EFAULT; 1607 goto out; 1608 } 1609 1610 out: 1611 qtnf_bus_unlock(mac->bus); 1612 return ret; 1613 } 1614 1615 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus) 1616 { 1617 struct sk_buff *cmd_skb; 1618 u16 res_code = QLINK_CMD_RESULT_OK; 1619 int ret = 0; 1620 1621 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1622 QLINK_CMD_FW_INIT, 1623 sizeof(struct qlink_cmd)); 1624 if (unlikely(!cmd_skb)) 1625 return -ENOMEM; 1626 1627 qtnf_bus_lock(bus); 1628 1629 ret = qtnf_cmd_send(bus, cmd_skb, &res_code); 1630 1631 if (unlikely(ret)) 1632 goto out; 1633 1634 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1635 pr_err("cmd exec failed: 0x%.4X\n", res_code); 1636 ret = -EFAULT; 1637 goto out; 1638 } 1639 1640 out: 1641 qtnf_bus_unlock(bus); 1642 return ret; 1643 } 1644 1645 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus) 1646 { 1647 struct sk_buff *cmd_skb; 1648 1649 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1650 QLINK_CMD_FW_DEINIT, 1651 sizeof(struct qlink_cmd)); 1652 if (!cmd_skb) 1653 return; 1654 1655 qtnf_bus_lock(bus); 1656 1657 qtnf_cmd_send(bus, cmd_skb, NULL); 1658 1659 qtnf_bus_unlock(bus); 1660 } 1661 1662 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1663 const u8 *mac_addr, struct key_params *params) 1664 { 1665 struct sk_buff *cmd_skb; 1666 struct qlink_cmd_add_key *cmd; 1667 u16 res_code = QLINK_CMD_RESULT_OK; 1668 int ret = 0; 1669 1670 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1671 QLINK_CMD_ADD_KEY, 1672 sizeof(*cmd)); 1673 if (unlikely(!cmd_skb)) 1674 return -ENOMEM; 1675 1676 qtnf_bus_lock(vif->mac->bus); 1677 1678 cmd = (struct qlink_cmd_add_key *)cmd_skb->data; 1679 1680 if (mac_addr) 1681 ether_addr_copy(cmd->addr, mac_addr); 1682 else 1683 eth_broadcast_addr(cmd->addr); 1684 1685 cmd->cipher = cpu_to_le32(params->cipher); 1686 cmd->key_index = key_index; 1687 cmd->pairwise = pairwise; 1688 1689 if (params->key && params->key_len > 0) 1690 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY, 1691 params->key, 1692 params->key_len); 1693 1694 if (params->seq && params->seq_len > 0) 1695 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ, 1696 params->seq, 1697 params->seq_len); 1698 1699 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1700 if (unlikely(ret)) 1701 goto out; 1702 1703 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1704 pr_err("VIF%u.%u: CMD failed: %u\n", 1705 vif->mac->macid, vif->vifid, res_code); 1706 ret = -EFAULT; 1707 goto out; 1708 } 1709 1710 out: 1711 qtnf_bus_unlock(vif->mac->bus); 1712 return ret; 1713 } 1714 1715 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1716 const u8 *mac_addr) 1717 { 1718 struct sk_buff *cmd_skb; 1719 struct qlink_cmd_del_key *cmd; 1720 u16 res_code = QLINK_CMD_RESULT_OK; 1721 int ret = 0; 1722 1723 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1724 QLINK_CMD_DEL_KEY, 1725 sizeof(*cmd)); 1726 if (unlikely(!cmd_skb)) 1727 return -ENOMEM; 1728 1729 qtnf_bus_lock(vif->mac->bus); 1730 1731 cmd = (struct qlink_cmd_del_key *)cmd_skb->data; 1732 1733 if (mac_addr) 1734 ether_addr_copy(cmd->addr, mac_addr); 1735 else 1736 eth_broadcast_addr(cmd->addr); 1737 1738 cmd->key_index = key_index; 1739 cmd->pairwise = pairwise; 1740 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1741 if (unlikely(ret)) 1742 goto out; 1743 1744 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1745 pr_err("VIF%u.%u: CMD failed: %u\n", 1746 vif->mac->macid, vif->vifid, res_code); 1747 ret = -EFAULT; 1748 goto out; 1749 } 1750 1751 out: 1752 qtnf_bus_unlock(vif->mac->bus); 1753 return ret; 1754 } 1755 1756 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index, 1757 bool unicast, bool multicast) 1758 { 1759 struct sk_buff *cmd_skb; 1760 struct qlink_cmd_set_def_key *cmd; 1761 u16 res_code = QLINK_CMD_RESULT_OK; 1762 int ret = 0; 1763 1764 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1765 QLINK_CMD_SET_DEFAULT_KEY, 1766 sizeof(*cmd)); 1767 if (unlikely(!cmd_skb)) 1768 return -ENOMEM; 1769 1770 qtnf_bus_lock(vif->mac->bus); 1771 1772 cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data; 1773 cmd->key_index = key_index; 1774 cmd->unicast = unicast; 1775 cmd->multicast = multicast; 1776 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1777 if (unlikely(ret)) 1778 goto out; 1779 1780 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1781 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1782 vif->vifid, res_code); 1783 ret = -EFAULT; 1784 goto out; 1785 } 1786 1787 out: 1788 qtnf_bus_unlock(vif->mac->bus); 1789 return ret; 1790 } 1791 1792 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index) 1793 { 1794 struct sk_buff *cmd_skb; 1795 struct qlink_cmd_set_def_mgmt_key *cmd; 1796 u16 res_code = QLINK_CMD_RESULT_OK; 1797 int ret = 0; 1798 1799 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1800 QLINK_CMD_SET_DEFAULT_MGMT_KEY, 1801 sizeof(*cmd)); 1802 if (unlikely(!cmd_skb)) 1803 return -ENOMEM; 1804 1805 qtnf_bus_lock(vif->mac->bus); 1806 1807 cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data; 1808 cmd->key_index = key_index; 1809 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1810 if (unlikely(ret)) 1811 goto out; 1812 1813 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1814 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1815 vif->vifid, res_code); 1816 ret = -EFAULT; 1817 goto out; 1818 } 1819 1820 out: 1821 qtnf_bus_unlock(vif->mac->bus); 1822 return ret; 1823 } 1824 1825 static u32 qtnf_encode_sta_flags(u32 flags) 1826 { 1827 u32 code = 0; 1828 1829 if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED)) 1830 code |= QLINK_STA_FLAG_AUTHORIZED; 1831 if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 1832 code |= QLINK_STA_FLAG_SHORT_PREAMBLE; 1833 if (flags & BIT(NL80211_STA_FLAG_WME)) 1834 code |= QLINK_STA_FLAG_WME; 1835 if (flags & BIT(NL80211_STA_FLAG_MFP)) 1836 code |= QLINK_STA_FLAG_MFP; 1837 if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED)) 1838 code |= QLINK_STA_FLAG_AUTHENTICATED; 1839 if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER)) 1840 code |= QLINK_STA_FLAG_TDLS_PEER; 1841 if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED)) 1842 code |= QLINK_STA_FLAG_ASSOCIATED; 1843 return code; 1844 } 1845 1846 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac, 1847 struct station_parameters *params) 1848 { 1849 struct sk_buff *cmd_skb; 1850 struct qlink_cmd_change_sta *cmd; 1851 u16 res_code = QLINK_CMD_RESULT_OK; 1852 int ret = 0; 1853 1854 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1855 QLINK_CMD_CHANGE_STA, 1856 sizeof(*cmd)); 1857 if (unlikely(!cmd_skb)) 1858 return -ENOMEM; 1859 1860 qtnf_bus_lock(vif->mac->bus); 1861 1862 cmd = (struct qlink_cmd_change_sta *)cmd_skb->data; 1863 ether_addr_copy(cmd->sta_addr, mac); 1864 1865 switch (vif->wdev.iftype) { 1866 case NL80211_IFTYPE_AP: 1867 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_AP); 1868 cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags( 1869 params->sta_flags_mask)); 1870 cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags( 1871 params->sta_flags_set)); 1872 break; 1873 case NL80211_IFTYPE_STATION: 1874 cmd->if_type = cpu_to_le16(QLINK_IFTYPE_STATION); 1875 cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags( 1876 params->sta_flags_mask)); 1877 cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags( 1878 params->sta_flags_set)); 1879 break; 1880 default: 1881 pr_err("unsupported iftype %d\n", vif->wdev.iftype); 1882 ret = -EINVAL; 1883 goto out; 1884 } 1885 1886 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1887 if (unlikely(ret)) 1888 goto out; 1889 1890 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1891 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1892 vif->vifid, res_code); 1893 ret = -EFAULT; 1894 goto out; 1895 } 1896 1897 out: 1898 qtnf_bus_unlock(vif->mac->bus); 1899 return ret; 1900 } 1901 1902 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif, 1903 struct station_del_parameters *params) 1904 { 1905 struct sk_buff *cmd_skb; 1906 struct qlink_cmd_del_sta *cmd; 1907 u16 res_code = QLINK_CMD_RESULT_OK; 1908 int ret = 0; 1909 1910 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1911 QLINK_CMD_DEL_STA, 1912 sizeof(*cmd)); 1913 if (unlikely(!cmd_skb)) 1914 return -ENOMEM; 1915 1916 qtnf_bus_lock(vif->mac->bus); 1917 1918 cmd = (struct qlink_cmd_del_sta *)cmd_skb->data; 1919 1920 if (params->mac) 1921 ether_addr_copy(cmd->sta_addr, params->mac); 1922 else 1923 eth_broadcast_addr(cmd->sta_addr); /* flush all stations */ 1924 1925 cmd->subtype = params->subtype; 1926 cmd->reason_code = cpu_to_le16(params->reason_code); 1927 1928 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1929 if (unlikely(ret)) 1930 goto out; 1931 1932 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1933 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1934 vif->vifid, res_code); 1935 ret = -EFAULT; 1936 goto out; 1937 } 1938 1939 out: 1940 qtnf_bus_unlock(vif->mac->bus); 1941 return ret; 1942 } 1943 1944 int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 1945 { 1946 struct sk_buff *cmd_skb; 1947 u16 res_code = QLINK_CMD_RESULT_OK; 1948 struct ieee80211_channel *sc; 1949 struct cfg80211_scan_request *scan_req = mac->scan_req; 1950 struct qlink_tlv_channel *qchan; 1951 int n_channels; 1952 int count = 0; 1953 int ret; 1954 u32 flags; 1955 1956 if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) { 1957 pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid); 1958 return -EINVAL; 1959 } 1960 1961 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1962 QLINK_CMD_SCAN, 1963 sizeof(struct qlink_cmd)); 1964 if (unlikely(!cmd_skb)) 1965 return -ENOMEM; 1966 1967 qtnf_bus_lock(mac->bus); 1968 1969 if (scan_req->n_ssids != 0) { 1970 while (count < scan_req->n_ssids) { 1971 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, 1972 scan_req->ssids[count].ssid, 1973 scan_req->ssids[count].ssid_len); 1974 count++; 1975 } 1976 } 1977 1978 if (scan_req->ie_len != 0) 1979 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 1980 scan_req->ie, 1981 scan_req->ie_len); 1982 1983 if (scan_req->n_channels) { 1984 n_channels = scan_req->n_channels; 1985 count = 0; 1986 1987 while (n_channels != 0) { 1988 sc = scan_req->channels[count]; 1989 if (sc->flags & IEEE80211_CHAN_DISABLED) { 1990 n_channels--; 1991 continue; 1992 } 1993 1994 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n", 1995 mac->macid, sc->hw_value, sc->center_freq, 1996 sc->flags); 1997 qchan = skb_put_zero(cmd_skb, sizeof(*qchan)); 1998 flags = 0; 1999 2000 qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); 2001 qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - 2002 sizeof(struct qlink_tlv_hdr)); 2003 qchan->center_freq = cpu_to_le16(sc->center_freq); 2004 qchan->hw_value = cpu_to_le16(sc->hw_value); 2005 2006 if (sc->flags & IEEE80211_CHAN_NO_IR) 2007 flags |= QLINK_CHAN_NO_IR; 2008 2009 if (sc->flags & IEEE80211_CHAN_RADAR) 2010 flags |= QLINK_CHAN_RADAR; 2011 2012 qchan->flags = cpu_to_le32(flags); 2013 n_channels--; 2014 count++; 2015 } 2016 } 2017 2018 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 2019 2020 if (unlikely(ret)) 2021 goto out; 2022 2023 pr_debug("MAC%u: scan started\n", mac->macid); 2024 2025 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2026 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 2027 ret = -EFAULT; 2028 goto out; 2029 } 2030 out: 2031 qtnf_bus_unlock(mac->bus); 2032 return ret; 2033 } 2034 2035 int qtnf_cmd_send_connect(struct qtnf_vif *vif, 2036 struct cfg80211_connect_params *sme) 2037 { 2038 struct sk_buff *cmd_skb; 2039 struct qlink_cmd_connect *cmd; 2040 struct qtnf_bss_config *bss_cfg = &vif->bss_cfg; 2041 struct qlink_auth_encr aen; 2042 u16 res_code = QLINK_CMD_RESULT_OK; 2043 int ret; 2044 int i; 2045 2046 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2047 QLINK_CMD_CONNECT, 2048 sizeof(*cmd)); 2049 if (unlikely(!cmd_skb)) 2050 return -ENOMEM; 2051 2052 qtnf_bus_lock(vif->mac->bus); 2053 2054 cmd = (struct qlink_cmd_connect *)cmd_skb->data; 2055 2056 ether_addr_copy(cmd->bssid, bss_cfg->bssid); 2057 2058 if (vif->mac->chandef.chan) 2059 cmd->channel = cpu_to_le16(vif->mac->chandef.chan->hw_value); 2060 2061 cmd->bg_scan_period = cpu_to_le16(bss_cfg->bg_scan_period); 2062 2063 memset(&aen, 0, sizeof(aen)); 2064 aen.auth_type = bss_cfg->auth_type; 2065 aen.privacy = !!bss_cfg->privacy; 2066 aen.mfp = bss_cfg->mfp; 2067 aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions); 2068 aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group); 2069 aen.n_ciphers_pairwise = cpu_to_le32( 2070 bss_cfg->crypto.n_ciphers_pairwise); 2071 2072 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 2073 aen.ciphers_pairwise[i] = cpu_to_le32( 2074 bss_cfg->crypto.ciphers_pairwise[i]); 2075 2076 aen.n_akm_suites = cpu_to_le32(bss_cfg->crypto.n_akm_suites); 2077 2078 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 2079 aen.akm_suites[i] = cpu_to_le32( 2080 bss_cfg->crypto.akm_suites[i]); 2081 2082 aen.control_port = bss_cfg->crypto.control_port; 2083 aen.control_port_no_encrypt = 2084 bss_cfg->crypto.control_port_no_encrypt; 2085 aen.control_port_ethertype = cpu_to_le16(be16_to_cpu( 2086 bss_cfg->crypto.control_port_ethertype)); 2087 2088 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid, 2089 bss_cfg->ssid_len); 2090 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen, 2091 sizeof(aen)); 2092 2093 if (sme->ie_len != 0) 2094 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2095 sme->ie, 2096 sme->ie_len); 2097 2098 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2099 2100 if (unlikely(ret)) 2101 goto out; 2102 2103 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2104 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2105 vif->vifid, res_code); 2106 ret = -EFAULT; 2107 goto out; 2108 } 2109 out: 2110 qtnf_bus_unlock(vif->mac->bus); 2111 return ret; 2112 } 2113 2114 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code) 2115 { 2116 struct sk_buff *cmd_skb; 2117 struct qlink_cmd_disconnect *cmd; 2118 u16 res_code = QLINK_CMD_RESULT_OK; 2119 int ret; 2120 2121 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2122 QLINK_CMD_DISCONNECT, 2123 sizeof(*cmd)); 2124 if (unlikely(!cmd_skb)) 2125 return -ENOMEM; 2126 2127 qtnf_bus_lock(vif->mac->bus); 2128 2129 cmd = (struct qlink_cmd_disconnect *)cmd_skb->data; 2130 cmd->reason = cpu_to_le16(reason_code); 2131 2132 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2133 2134 if (unlikely(ret)) 2135 goto out; 2136 2137 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2138 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2139 vif->vifid, res_code); 2140 ret = -EFAULT; 2141 goto out; 2142 } 2143 out: 2144 qtnf_bus_unlock(vif->mac->bus); 2145 return ret; 2146 } 2147 2148 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up) 2149 { 2150 struct sk_buff *cmd_skb; 2151 struct qlink_cmd_updown *cmd; 2152 u16 res_code = QLINK_CMD_RESULT_OK; 2153 int ret; 2154 2155 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2156 QLINK_CMD_UPDOWN_INTF, 2157 sizeof(*cmd)); 2158 if (unlikely(!cmd_skb)) 2159 return -ENOMEM; 2160 2161 cmd = (struct qlink_cmd_updown *)cmd_skb->data; 2162 cmd->if_up = !!up; 2163 2164 qtnf_bus_lock(vif->mac->bus); 2165 2166 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2167 2168 if (unlikely(ret)) 2169 goto out; 2170 2171 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2172 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2173 vif->vifid, res_code); 2174 ret = -EFAULT; 2175 goto out; 2176 } 2177 out: 2178 qtnf_bus_unlock(vif->mac->bus); 2179 return ret; 2180 } 2181 2182 int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req) 2183 { 2184 struct sk_buff *cmd_skb; 2185 int ret; 2186 u16 res_code; 2187 struct qlink_cmd_reg_notify *cmd; 2188 2189 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 2190 QLINK_CMD_REG_NOTIFY, 2191 sizeof(*cmd)); 2192 if (!cmd_skb) 2193 return -ENOMEM; 2194 2195 cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data; 2196 cmd->alpha2[0] = req->alpha2[0]; 2197 cmd->alpha2[1] = req->alpha2[1]; 2198 2199 switch (req->initiator) { 2200 case NL80211_REGDOM_SET_BY_CORE: 2201 cmd->initiator = QLINK_REGDOM_SET_BY_CORE; 2202 break; 2203 case NL80211_REGDOM_SET_BY_USER: 2204 cmd->initiator = QLINK_REGDOM_SET_BY_USER; 2205 break; 2206 case NL80211_REGDOM_SET_BY_DRIVER: 2207 cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER; 2208 break; 2209 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2210 cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE; 2211 break; 2212 } 2213 2214 switch (req->user_reg_hint_type) { 2215 case NL80211_USER_REG_HINT_USER: 2216 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER; 2217 break; 2218 case NL80211_USER_REG_HINT_CELL_BASE: 2219 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE; 2220 break; 2221 case NL80211_USER_REG_HINT_INDOOR: 2222 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR; 2223 break; 2224 } 2225 2226 qtnf_bus_lock(bus); 2227 2228 ret = qtnf_cmd_send(bus, cmd_skb, &res_code); 2229 if (ret) 2230 goto out; 2231 2232 switch (res_code) { 2233 case QLINK_CMD_RESULT_ENOTSUPP: 2234 pr_warn("reg update not supported\n"); 2235 ret = -EOPNOTSUPP; 2236 break; 2237 case QLINK_CMD_RESULT_EALREADY: 2238 pr_info("regulatory domain is already set to %c%c", 2239 req->alpha2[0], req->alpha2[1]); 2240 ret = -EALREADY; 2241 break; 2242 case QLINK_CMD_RESULT_OK: 2243 ret = 0; 2244 break; 2245 default: 2246 ret = -EFAULT; 2247 break; 2248 } 2249 2250 out: 2251 qtnf_bus_unlock(bus); 2252 2253 return ret; 2254 } 2255 2256 int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel, 2257 struct qtnf_chan_stats *stats) 2258 { 2259 struct sk_buff *cmd_skb, *resp_skb = NULL; 2260 struct qlink_cmd_get_chan_stats *cmd; 2261 struct qlink_resp_get_chan_stats *resp; 2262 size_t var_data_len; 2263 u16 res_code = QLINK_CMD_RESULT_OK; 2264 int ret = 0; 2265 2266 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 2267 QLINK_CMD_CHAN_STATS, 2268 sizeof(*cmd)); 2269 if (!cmd_skb) 2270 return -ENOMEM; 2271 2272 qtnf_bus_lock(mac->bus); 2273 2274 cmd = (struct qlink_cmd_get_chan_stats *)cmd_skb->data; 2275 cmd->channel = cpu_to_le16(channel); 2276 2277 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 2278 sizeof(*resp), &var_data_len); 2279 if (unlikely(ret)) { 2280 qtnf_bus_unlock(mac->bus); 2281 return ret; 2282 } 2283 2284 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2285 switch (res_code) { 2286 case QLINK_CMD_RESULT_ENOTFOUND: 2287 ret = -ENOENT; 2288 break; 2289 default: 2290 pr_err("cmd exec failed: 0x%.4X\n", res_code); 2291 ret = -EFAULT; 2292 break; 2293 } 2294 goto out; 2295 } 2296 2297 resp = (struct qlink_resp_get_chan_stats *)resp_skb->data; 2298 ret = qtnf_cmd_resp_proc_chan_stat_info(stats, resp->info, 2299 var_data_len); 2300 2301 out: 2302 qtnf_bus_unlock(mac->bus); 2303 consume_skb(resp_skb); 2304 return ret; 2305 } 2306 2307 int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac, 2308 struct cfg80211_csa_settings *params) 2309 { 2310 struct qlink_cmd_chan_switch *cmd; 2311 struct sk_buff *cmd_skb; 2312 u16 res_code = QLINK_CMD_RESULT_OK; 2313 int ret; 2314 2315 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0x0, 2316 QLINK_CMD_CHAN_SWITCH, 2317 sizeof(*cmd)); 2318 2319 if (unlikely(!cmd_skb)) 2320 return -ENOMEM; 2321 2322 qtnf_bus_lock(mac->bus); 2323 2324 cmd = (struct qlink_cmd_chan_switch *)cmd_skb->data; 2325 cmd->channel = cpu_to_le16(params->chandef.chan->hw_value); 2326 cmd->radar_required = params->radar_required; 2327 cmd->block_tx = params->block_tx; 2328 cmd->beacon_count = params->count; 2329 2330 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 2331 2332 if (unlikely(ret)) 2333 goto out; 2334 2335 switch (res_code) { 2336 case QLINK_CMD_RESULT_OK: 2337 memcpy(&mac->csa_chandef, ¶ms->chandef, 2338 sizeof(mac->csa_chandef)); 2339 mac->status |= QTNF_MAC_CSA_ACTIVE; 2340 ret = 0; 2341 break; 2342 case QLINK_CMD_RESULT_ENOTFOUND: 2343 ret = -ENOENT; 2344 break; 2345 case QLINK_CMD_RESULT_ENOTSUPP: 2346 ret = -EOPNOTSUPP; 2347 break; 2348 case QLINK_CMD_RESULT_EALREADY: 2349 ret = -EALREADY; 2350 break; 2351 case QLINK_CMD_RESULT_INVALID: 2352 default: 2353 ret = -EFAULT; 2354 break; 2355 } 2356 2357 out: 2358 qtnf_bus_unlock(mac->bus); 2359 return ret; 2360 } 2361