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