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 int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac) 1337 { 1338 struct sk_buff *cmd_skb, *resp_skb = NULL; 1339 const struct qlink_resp_get_mac_info *resp; 1340 size_t var_data_len; 1341 u16 res_code = QLINK_CMD_RESULT_OK; 1342 int ret = 0; 1343 1344 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1345 QLINK_CMD_MAC_INFO, 1346 sizeof(struct qlink_cmd)); 1347 if (unlikely(!cmd_skb)) 1348 return -ENOMEM; 1349 1350 qtnf_bus_lock(mac->bus); 1351 1352 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1353 sizeof(*resp), &var_data_len); 1354 if (unlikely(ret)) 1355 goto out; 1356 1357 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1358 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1359 ret = -EFAULT; 1360 goto out; 1361 } 1362 1363 resp = (const struct qlink_resp_get_mac_info *)resp_skb->data; 1364 qtnf_cmd_resp_proc_mac_info(mac, resp); 1365 ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len); 1366 1367 out: 1368 qtnf_bus_unlock(mac->bus); 1369 consume_skb(resp_skb); 1370 1371 return ret; 1372 } 1373 1374 int qtnf_cmd_get_hw_info(struct qtnf_bus *bus) 1375 { 1376 struct sk_buff *cmd_skb, *resp_skb = NULL; 1377 const struct qlink_resp_get_hw_info *resp; 1378 u16 res_code = QLINK_CMD_RESULT_OK; 1379 int ret = 0; 1380 size_t info_len; 1381 1382 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1383 QLINK_CMD_GET_HW_INFO, 1384 sizeof(struct qlink_cmd)); 1385 if (unlikely(!cmd_skb)) 1386 return -ENOMEM; 1387 1388 qtnf_bus_lock(bus); 1389 1390 ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code, 1391 sizeof(*resp), &info_len); 1392 1393 if (unlikely(ret)) 1394 goto out; 1395 1396 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1397 pr_err("cmd exec failed: 0x%.4X\n", res_code); 1398 ret = -EFAULT; 1399 goto out; 1400 } 1401 1402 resp = (const struct qlink_resp_get_hw_info *)resp_skb->data; 1403 ret = qtnf_cmd_resp_proc_hw_info(bus, resp, info_len); 1404 1405 out: 1406 qtnf_bus_unlock(bus); 1407 consume_skb(resp_skb); 1408 1409 return ret; 1410 } 1411 1412 int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, 1413 struct ieee80211_supported_band *band) 1414 { 1415 struct sk_buff *cmd_skb, *resp_skb = NULL; 1416 size_t info_len; 1417 struct qlink_cmd_chans_info_get *cmd; 1418 struct qlink_resp_get_chan_info *resp; 1419 u16 res_code = QLINK_CMD_RESULT_OK; 1420 int ret = 0; 1421 u8 qband; 1422 1423 switch (band->band) { 1424 case NL80211_BAND_2GHZ: 1425 qband = QLINK_BAND_2GHZ; 1426 break; 1427 case NL80211_BAND_5GHZ: 1428 qband = QLINK_BAND_5GHZ; 1429 break; 1430 case NL80211_BAND_60GHZ: 1431 qband = QLINK_BAND_60GHZ; 1432 break; 1433 default: 1434 return -EINVAL; 1435 } 1436 1437 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1438 QLINK_CMD_CHANS_INFO_GET, 1439 sizeof(*cmd)); 1440 if (!cmd_skb) 1441 return -ENOMEM; 1442 1443 cmd = (struct qlink_cmd_chans_info_get *)cmd_skb->data; 1444 cmd->band = qband; 1445 1446 qtnf_bus_lock(mac->bus); 1447 1448 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1449 sizeof(*resp), &info_len); 1450 1451 if (unlikely(ret)) 1452 goto out; 1453 1454 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1455 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1456 ret = -EFAULT; 1457 goto out; 1458 } 1459 1460 resp = (struct qlink_resp_get_chan_info *)resp_skb->data; 1461 if (resp->band != qband) { 1462 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, 1463 resp->band, qband); 1464 ret = -EINVAL; 1465 goto out; 1466 } 1467 1468 ret = qtnf_cmd_resp_fill_channels_info(band, resp, info_len); 1469 1470 out: 1471 qtnf_bus_unlock(mac->bus); 1472 consume_skb(resp_skb); 1473 1474 return ret; 1475 } 1476 1477 int qtnf_cmd_send_get_phy_params(struct qtnf_wmac *mac) 1478 { 1479 struct sk_buff *cmd_skb, *resp_skb = NULL; 1480 size_t response_size; 1481 struct qlink_resp_phy_params *resp; 1482 u16 res_code = QLINK_CMD_RESULT_OK; 1483 int ret = 0; 1484 1485 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1486 QLINK_CMD_PHY_PARAMS_GET, 1487 sizeof(struct qlink_cmd)); 1488 if (!cmd_skb) 1489 return -ENOMEM; 1490 1491 qtnf_bus_lock(mac->bus); 1492 1493 ret = qtnf_cmd_send_with_reply(mac->bus, cmd_skb, &resp_skb, &res_code, 1494 sizeof(*resp), &response_size); 1495 1496 if (unlikely(ret)) 1497 goto out; 1498 1499 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1500 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1501 ret = -EFAULT; 1502 goto out; 1503 } 1504 1505 resp = (struct qlink_resp_phy_params *)resp_skb->data; 1506 ret = qtnf_cmd_resp_proc_phy_params(mac, resp->info, response_size); 1507 1508 out: 1509 qtnf_bus_unlock(mac->bus); 1510 consume_skb(resp_skb); 1511 1512 return ret; 1513 } 1514 1515 int qtnf_cmd_send_update_phy_params(struct qtnf_wmac *mac, u32 changed) 1516 { 1517 struct wiphy *wiphy = priv_to_wiphy(mac); 1518 struct sk_buff *cmd_skb; 1519 u16 res_code = QLINK_CMD_RESULT_OK; 1520 int ret = 0; 1521 1522 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1523 QLINK_CMD_PHY_PARAMS_SET, 1524 sizeof(struct qlink_cmd)); 1525 if (!cmd_skb) 1526 return -ENOMEM; 1527 1528 qtnf_bus_lock(mac->bus); 1529 1530 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) 1531 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_FRAG_THRESH, 1532 wiphy->frag_threshold); 1533 if (changed & WIPHY_PARAM_RTS_THRESHOLD) 1534 qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_RTS_THRESH, 1535 wiphy->rts_threshold); 1536 if (changed & WIPHY_PARAM_COVERAGE_CLASS) 1537 qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_COVERAGE_CLASS, 1538 wiphy->coverage_class); 1539 1540 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 1541 1542 if (unlikely(ret)) 1543 goto out; 1544 1545 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1546 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1547 ret = -EFAULT; 1548 goto out; 1549 } 1550 1551 out: 1552 qtnf_bus_unlock(mac->bus); 1553 return ret; 1554 } 1555 1556 int qtnf_cmd_send_init_fw(struct qtnf_bus *bus) 1557 { 1558 struct sk_buff *cmd_skb; 1559 u16 res_code = QLINK_CMD_RESULT_OK; 1560 int ret = 0; 1561 1562 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1563 QLINK_CMD_FW_INIT, 1564 sizeof(struct qlink_cmd)); 1565 if (unlikely(!cmd_skb)) 1566 return -ENOMEM; 1567 1568 qtnf_bus_lock(bus); 1569 1570 ret = qtnf_cmd_send(bus, cmd_skb, &res_code); 1571 1572 if (unlikely(ret)) 1573 goto out; 1574 1575 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1576 pr_err("cmd exec failed: 0x%.4X\n", res_code); 1577 ret = -EFAULT; 1578 goto out; 1579 } 1580 1581 out: 1582 qtnf_bus_unlock(bus); 1583 return ret; 1584 } 1585 1586 void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus) 1587 { 1588 struct sk_buff *cmd_skb; 1589 1590 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 1591 QLINK_CMD_FW_DEINIT, 1592 sizeof(struct qlink_cmd)); 1593 if (!cmd_skb) 1594 return; 1595 1596 qtnf_bus_lock(bus); 1597 1598 qtnf_cmd_send(bus, cmd_skb, NULL); 1599 1600 qtnf_bus_unlock(bus); 1601 } 1602 1603 int qtnf_cmd_send_add_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1604 const u8 *mac_addr, struct key_params *params) 1605 { 1606 struct sk_buff *cmd_skb; 1607 struct qlink_cmd_add_key *cmd; 1608 u16 res_code = QLINK_CMD_RESULT_OK; 1609 int ret = 0; 1610 1611 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1612 QLINK_CMD_ADD_KEY, 1613 sizeof(*cmd)); 1614 if (unlikely(!cmd_skb)) 1615 return -ENOMEM; 1616 1617 qtnf_bus_lock(vif->mac->bus); 1618 1619 cmd = (struct qlink_cmd_add_key *)cmd_skb->data; 1620 1621 if (mac_addr) 1622 ether_addr_copy(cmd->addr, mac_addr); 1623 else 1624 eth_broadcast_addr(cmd->addr); 1625 1626 cmd->cipher = cpu_to_le32(params->cipher); 1627 cmd->key_index = key_index; 1628 cmd->pairwise = pairwise; 1629 1630 if (params->key && params->key_len > 0) 1631 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_KEY, 1632 params->key, 1633 params->key_len); 1634 1635 if (params->seq && params->seq_len > 0) 1636 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_SEQ, 1637 params->seq, 1638 params->seq_len); 1639 1640 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1641 if (unlikely(ret)) 1642 goto out; 1643 1644 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1645 pr_err("VIF%u.%u: CMD failed: %u\n", 1646 vif->mac->macid, vif->vifid, res_code); 1647 ret = -EFAULT; 1648 goto out; 1649 } 1650 1651 out: 1652 qtnf_bus_unlock(vif->mac->bus); 1653 return ret; 1654 } 1655 1656 int qtnf_cmd_send_del_key(struct qtnf_vif *vif, u8 key_index, bool pairwise, 1657 const u8 *mac_addr) 1658 { 1659 struct sk_buff *cmd_skb; 1660 struct qlink_cmd_del_key *cmd; 1661 u16 res_code = QLINK_CMD_RESULT_OK; 1662 int ret = 0; 1663 1664 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1665 QLINK_CMD_DEL_KEY, 1666 sizeof(*cmd)); 1667 if (unlikely(!cmd_skb)) 1668 return -ENOMEM; 1669 1670 qtnf_bus_lock(vif->mac->bus); 1671 1672 cmd = (struct qlink_cmd_del_key *)cmd_skb->data; 1673 1674 if (mac_addr) 1675 ether_addr_copy(cmd->addr, mac_addr); 1676 else 1677 eth_broadcast_addr(cmd->addr); 1678 1679 cmd->key_index = key_index; 1680 cmd->pairwise = pairwise; 1681 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1682 if (unlikely(ret)) 1683 goto out; 1684 1685 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1686 pr_err("VIF%u.%u: CMD failed: %u\n", 1687 vif->mac->macid, vif->vifid, res_code); 1688 ret = -EFAULT; 1689 goto out; 1690 } 1691 1692 out: 1693 qtnf_bus_unlock(vif->mac->bus); 1694 return ret; 1695 } 1696 1697 int qtnf_cmd_send_set_default_key(struct qtnf_vif *vif, u8 key_index, 1698 bool unicast, bool multicast) 1699 { 1700 struct sk_buff *cmd_skb; 1701 struct qlink_cmd_set_def_key *cmd; 1702 u16 res_code = QLINK_CMD_RESULT_OK; 1703 int ret = 0; 1704 1705 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1706 QLINK_CMD_SET_DEFAULT_KEY, 1707 sizeof(*cmd)); 1708 if (unlikely(!cmd_skb)) 1709 return -ENOMEM; 1710 1711 qtnf_bus_lock(vif->mac->bus); 1712 1713 cmd = (struct qlink_cmd_set_def_key *)cmd_skb->data; 1714 cmd->key_index = key_index; 1715 cmd->unicast = unicast; 1716 cmd->multicast = multicast; 1717 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1718 if (unlikely(ret)) 1719 goto out; 1720 1721 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1722 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1723 vif->vifid, res_code); 1724 ret = -EFAULT; 1725 goto out; 1726 } 1727 1728 out: 1729 qtnf_bus_unlock(vif->mac->bus); 1730 return ret; 1731 } 1732 1733 int qtnf_cmd_send_set_default_mgmt_key(struct qtnf_vif *vif, u8 key_index) 1734 { 1735 struct sk_buff *cmd_skb; 1736 struct qlink_cmd_set_def_mgmt_key *cmd; 1737 u16 res_code = QLINK_CMD_RESULT_OK; 1738 int ret = 0; 1739 1740 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1741 QLINK_CMD_SET_DEFAULT_MGMT_KEY, 1742 sizeof(*cmd)); 1743 if (unlikely(!cmd_skb)) 1744 return -ENOMEM; 1745 1746 qtnf_bus_lock(vif->mac->bus); 1747 1748 cmd = (struct qlink_cmd_set_def_mgmt_key *)cmd_skb->data; 1749 cmd->key_index = key_index; 1750 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1751 if (unlikely(ret)) 1752 goto out; 1753 1754 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1755 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1756 vif->vifid, res_code); 1757 ret = -EFAULT; 1758 goto out; 1759 } 1760 1761 out: 1762 qtnf_bus_unlock(vif->mac->bus); 1763 return ret; 1764 } 1765 1766 static u32 qtnf_encode_sta_flags(u32 flags) 1767 { 1768 u32 code = 0; 1769 1770 if (flags & BIT(NL80211_STA_FLAG_AUTHORIZED)) 1771 code |= QLINK_STA_FLAG_AUTHORIZED; 1772 if (flags & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 1773 code |= QLINK_STA_FLAG_SHORT_PREAMBLE; 1774 if (flags & BIT(NL80211_STA_FLAG_WME)) 1775 code |= QLINK_STA_FLAG_WME; 1776 if (flags & BIT(NL80211_STA_FLAG_MFP)) 1777 code |= QLINK_STA_FLAG_MFP; 1778 if (flags & BIT(NL80211_STA_FLAG_AUTHENTICATED)) 1779 code |= QLINK_STA_FLAG_AUTHENTICATED; 1780 if (flags & BIT(NL80211_STA_FLAG_TDLS_PEER)) 1781 code |= QLINK_STA_FLAG_TDLS_PEER; 1782 if (flags & BIT(NL80211_STA_FLAG_ASSOCIATED)) 1783 code |= QLINK_STA_FLAG_ASSOCIATED; 1784 return code; 1785 } 1786 1787 int qtnf_cmd_send_change_sta(struct qtnf_vif *vif, const u8 *mac, 1788 struct station_parameters *params) 1789 { 1790 struct sk_buff *cmd_skb; 1791 struct qlink_cmd_change_sta *cmd; 1792 u16 res_code = QLINK_CMD_RESULT_OK; 1793 int ret = 0; 1794 1795 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1796 QLINK_CMD_CHANGE_STA, 1797 sizeof(*cmd)); 1798 if (unlikely(!cmd_skb)) 1799 return -ENOMEM; 1800 1801 qtnf_bus_lock(vif->mac->bus); 1802 1803 cmd = (struct qlink_cmd_change_sta *)cmd_skb->data; 1804 ether_addr_copy(cmd->sta_addr, mac); 1805 cmd->sta_flags_mask = cpu_to_le32(qtnf_encode_sta_flags( 1806 params->sta_flags_mask)); 1807 cmd->sta_flags_set = cpu_to_le32(qtnf_encode_sta_flags( 1808 params->sta_flags_set)); 1809 1810 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1811 if (unlikely(ret)) 1812 goto out; 1813 1814 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1815 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1816 vif->vifid, res_code); 1817 ret = -EFAULT; 1818 goto out; 1819 } 1820 1821 out: 1822 qtnf_bus_unlock(vif->mac->bus); 1823 return ret; 1824 } 1825 1826 int qtnf_cmd_send_del_sta(struct qtnf_vif *vif, 1827 struct station_del_parameters *params) 1828 { 1829 struct sk_buff *cmd_skb; 1830 struct qlink_cmd_del_sta *cmd; 1831 u16 res_code = QLINK_CMD_RESULT_OK; 1832 int ret = 0; 1833 1834 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1835 QLINK_CMD_DEL_STA, 1836 sizeof(*cmd)); 1837 if (unlikely(!cmd_skb)) 1838 return -ENOMEM; 1839 1840 qtnf_bus_lock(vif->mac->bus); 1841 1842 cmd = (struct qlink_cmd_del_sta *)cmd_skb->data; 1843 1844 if (params->mac) 1845 ether_addr_copy(cmd->sta_addr, params->mac); 1846 else 1847 eth_broadcast_addr(cmd->sta_addr); /* flush all stations */ 1848 1849 cmd->subtype = params->subtype; 1850 cmd->reason_code = cpu_to_le16(params->reason_code); 1851 1852 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 1853 if (unlikely(ret)) 1854 goto out; 1855 1856 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1857 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 1858 vif->vifid, res_code); 1859 ret = -EFAULT; 1860 goto out; 1861 } 1862 1863 out: 1864 qtnf_bus_unlock(vif->mac->bus); 1865 return ret; 1866 } 1867 1868 int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 1869 { 1870 struct sk_buff *cmd_skb; 1871 u16 res_code = QLINK_CMD_RESULT_OK; 1872 struct ieee80211_channel *sc; 1873 struct cfg80211_scan_request *scan_req = mac->scan_req; 1874 struct qlink_tlv_channel *qchan; 1875 int n_channels; 1876 int count = 0; 1877 int ret; 1878 u32 flags; 1879 1880 if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) { 1881 pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid); 1882 return -EINVAL; 1883 } 1884 1885 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD, 1886 QLINK_CMD_SCAN, 1887 sizeof(struct qlink_cmd)); 1888 if (unlikely(!cmd_skb)) 1889 return -ENOMEM; 1890 1891 qtnf_bus_lock(mac->bus); 1892 1893 if (scan_req->n_ssids != 0) { 1894 while (count < scan_req->n_ssids) { 1895 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, 1896 scan_req->ssids[count].ssid, 1897 scan_req->ssids[count].ssid_len); 1898 count++; 1899 } 1900 } 1901 1902 if (scan_req->ie_len != 0) 1903 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 1904 scan_req->ie, 1905 scan_req->ie_len); 1906 1907 if (scan_req->n_channels) { 1908 n_channels = scan_req->n_channels; 1909 count = 0; 1910 1911 while (n_channels != 0) { 1912 sc = scan_req->channels[count]; 1913 if (sc->flags & IEEE80211_CHAN_DISABLED) { 1914 n_channels--; 1915 continue; 1916 } 1917 1918 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n", 1919 mac->macid, sc->hw_value, sc->center_freq, 1920 sc->flags); 1921 qchan = skb_put_zero(cmd_skb, sizeof(*qchan)); 1922 flags = 0; 1923 1924 qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL); 1925 qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - 1926 sizeof(struct qlink_tlv_hdr)); 1927 qchan->center_freq = cpu_to_le16(sc->center_freq); 1928 qchan->hw_value = cpu_to_le16(sc->hw_value); 1929 1930 if (sc->flags & IEEE80211_CHAN_NO_IR) 1931 flags |= QLINK_CHAN_NO_IR; 1932 1933 if (sc->flags & IEEE80211_CHAN_RADAR) 1934 flags |= QLINK_CHAN_RADAR; 1935 1936 qchan->flags = cpu_to_le32(flags); 1937 n_channels--; 1938 count++; 1939 } 1940 } 1941 1942 ret = qtnf_cmd_send(mac->bus, cmd_skb, &res_code); 1943 1944 if (unlikely(ret)) 1945 goto out; 1946 1947 pr_debug("MAC%u: scan started\n", mac->macid); 1948 1949 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 1950 pr_err("MAC%u: CMD failed: %u\n", mac->macid, res_code); 1951 ret = -EFAULT; 1952 goto out; 1953 } 1954 out: 1955 qtnf_bus_unlock(mac->bus); 1956 return ret; 1957 } 1958 1959 int qtnf_cmd_send_connect(struct qtnf_vif *vif, 1960 struct cfg80211_connect_params *sme) 1961 { 1962 struct sk_buff *cmd_skb; 1963 struct qlink_cmd_connect *cmd; 1964 struct qtnf_bss_config *bss_cfg = &vif->bss_cfg; 1965 struct qlink_auth_encr aen; 1966 u16 res_code = QLINK_CMD_RESULT_OK; 1967 int ret; 1968 int i; 1969 1970 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 1971 QLINK_CMD_CONNECT, 1972 sizeof(*cmd)); 1973 if (unlikely(!cmd_skb)) 1974 return -ENOMEM; 1975 1976 qtnf_bus_lock(vif->mac->bus); 1977 1978 cmd = (struct qlink_cmd_connect *)cmd_skb->data; 1979 1980 ether_addr_copy(cmd->bssid, bss_cfg->bssid); 1981 1982 if (bss_cfg->chandef.chan) 1983 cmd->freq = cpu_to_le16(bss_cfg->chandef.chan->center_freq); 1984 1985 cmd->bg_scan_period = cpu_to_le16(bss_cfg->bg_scan_period); 1986 1987 memset(&aen, 0, sizeof(aen)); 1988 aen.auth_type = bss_cfg->auth_type; 1989 aen.privacy = !!bss_cfg->privacy; 1990 aen.mfp = bss_cfg->mfp; 1991 aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions); 1992 aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group); 1993 aen.n_ciphers_pairwise = cpu_to_le32( 1994 bss_cfg->crypto.n_ciphers_pairwise); 1995 1996 for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++) 1997 aen.ciphers_pairwise[i] = cpu_to_le32( 1998 bss_cfg->crypto.ciphers_pairwise[i]); 1999 2000 aen.n_akm_suites = cpu_to_le32(bss_cfg->crypto.n_akm_suites); 2001 2002 for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++) 2003 aen.akm_suites[i] = cpu_to_le32( 2004 bss_cfg->crypto.akm_suites[i]); 2005 2006 aen.control_port = bss_cfg->crypto.control_port; 2007 aen.control_port_no_encrypt = 2008 bss_cfg->crypto.control_port_no_encrypt; 2009 aen.control_port_ethertype = cpu_to_le16(be16_to_cpu( 2010 bss_cfg->crypto.control_port_ethertype)); 2011 2012 qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid, 2013 bss_cfg->ssid_len); 2014 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen, 2015 sizeof(aen)); 2016 2017 if (sme->ie_len != 0) 2018 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2019 sme->ie, 2020 sme->ie_len); 2021 2022 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2023 2024 if (unlikely(ret)) 2025 goto out; 2026 2027 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2028 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2029 vif->vifid, res_code); 2030 ret = -EFAULT; 2031 goto out; 2032 } 2033 out: 2034 qtnf_bus_unlock(vif->mac->bus); 2035 return ret; 2036 } 2037 2038 int qtnf_cmd_send_disconnect(struct qtnf_vif *vif, u16 reason_code) 2039 { 2040 struct sk_buff *cmd_skb; 2041 struct qlink_cmd_disconnect *cmd; 2042 u16 res_code = QLINK_CMD_RESULT_OK; 2043 int ret; 2044 2045 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2046 QLINK_CMD_DISCONNECT, 2047 sizeof(*cmd)); 2048 if (unlikely(!cmd_skb)) 2049 return -ENOMEM; 2050 2051 qtnf_bus_lock(vif->mac->bus); 2052 2053 cmd = (struct qlink_cmd_disconnect *)cmd_skb->data; 2054 cmd->reason = cpu_to_le16(reason_code); 2055 2056 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2057 2058 if (unlikely(ret)) 2059 goto out; 2060 2061 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2062 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2063 vif->vifid, res_code); 2064 ret = -EFAULT; 2065 goto out; 2066 } 2067 out: 2068 qtnf_bus_unlock(vif->mac->bus); 2069 return ret; 2070 } 2071 2072 int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up) 2073 { 2074 struct sk_buff *cmd_skb; 2075 struct qlink_cmd_updown *cmd; 2076 u16 res_code = QLINK_CMD_RESULT_OK; 2077 int ret; 2078 2079 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 2080 QLINK_CMD_UPDOWN_INTF, 2081 sizeof(*cmd)); 2082 if (unlikely(!cmd_skb)) 2083 return -ENOMEM; 2084 2085 cmd = (struct qlink_cmd_updown *)cmd_skb->data; 2086 cmd->if_up = !!up; 2087 2088 qtnf_bus_lock(vif->mac->bus); 2089 2090 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 2091 2092 if (unlikely(ret)) 2093 goto out; 2094 2095 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 2096 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 2097 vif->vifid, res_code); 2098 ret = -EFAULT; 2099 goto out; 2100 } 2101 out: 2102 qtnf_bus_unlock(vif->mac->bus); 2103 return ret; 2104 } 2105 2106 int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req) 2107 { 2108 struct sk_buff *cmd_skb; 2109 int ret; 2110 u16 res_code; 2111 struct qlink_cmd_reg_notify *cmd; 2112 2113 cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD, 2114 QLINK_CMD_REG_NOTIFY, 2115 sizeof(*cmd)); 2116 if (!cmd_skb) 2117 return -ENOMEM; 2118 2119 cmd = (struct qlink_cmd_reg_notify *)cmd_skb->data; 2120 cmd->alpha2[0] = req->alpha2[0]; 2121 cmd->alpha2[1] = req->alpha2[1]; 2122 2123 switch (req->initiator) { 2124 case NL80211_REGDOM_SET_BY_CORE: 2125 cmd->initiator = QLINK_REGDOM_SET_BY_CORE; 2126 break; 2127 case NL80211_REGDOM_SET_BY_USER: 2128 cmd->initiator = QLINK_REGDOM_SET_BY_USER; 2129 break; 2130 case NL80211_REGDOM_SET_BY_DRIVER: 2131 cmd->initiator = QLINK_REGDOM_SET_BY_DRIVER; 2132 break; 2133 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2134 cmd->initiator = QLINK_REGDOM_SET_BY_COUNTRY_IE; 2135 break; 2136 } 2137 2138 switch (req->user_reg_hint_type) { 2139 case NL80211_USER_REG_HINT_USER: 2140 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_USER; 2141 break; 2142 case NL80211_USER_REG_HINT_CELL_BASE: 2143 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_CELL_BASE; 2144 break; 2145 case NL80211_USER_REG_HINT_INDOOR: 2146 cmd->user_reg_hint_type = QLINK_USER_REG_HINT_INDOOR; 2147 break; 2148 } 2149 2150 qtnf_bus_lock(bus); 2151 2152 ret = qtnf_cmd_send(bus, cmd_skb, &res_code); 2153 if (ret) 2154 goto out; 2155 2156 switch (res_code) { 2157 case QLINK_CMD_RESULT_ENOTSUPP: 2158 pr_warn("reg update not supported\n"); 2159 ret = -EOPNOTSUPP; 2160 break; 2161 case QLINK_CMD_RESULT_EALREADY: 2162 pr_info("regulatory domain is already set to %c%c", 2163 req->alpha2[0], req->alpha2[1]); 2164 ret = -EALREADY; 2165 break; 2166 case QLINK_CMD_RESULT_OK: 2167 ret = 0; 2168 break; 2169 default: 2170 ret = -EFAULT; 2171 break; 2172 } 2173 2174 out: 2175 qtnf_bus_unlock(bus); 2176 2177 return ret; 2178 } 2179