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