1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 6 */ 7 #include "core.h" 8 #include "debug.h" 9 #include "mac.h" 10 #include "hw.h" 11 #include "wmi.h" 12 #include "wmi-ops.h" 13 #include "wmi-tlv.h" 14 #include "p2p.h" 15 #include "testmode.h" 16 #include <linux/bitfield.h> 17 18 /***************/ 19 /* TLV helpers */ 20 /**************/ 21 22 struct wmi_tlv_policy { 23 size_t min_len; 24 }; 25 26 static const struct wmi_tlv_policy wmi_tlv_policies[] = { 27 [WMI_TLV_TAG_ARRAY_BYTE] 28 = { .min_len = 0 }, 29 [WMI_TLV_TAG_ARRAY_UINT32] 30 = { .min_len = 0 }, 31 [WMI_TLV_TAG_STRUCT_SCAN_EVENT] 32 = { .min_len = sizeof(struct wmi_scan_event) }, 33 [WMI_TLV_TAG_STRUCT_MGMT_RX_HDR] 34 = { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) }, 35 [WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT] 36 = { .min_len = sizeof(struct wmi_chan_info_event) }, 37 [WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT] 38 = { .min_len = sizeof(struct wmi_vdev_start_response_event) }, 39 [WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT] 40 = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) }, 41 [WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT] 42 = { .min_len = sizeof(struct wmi_host_swba_event) }, 43 [WMI_TLV_TAG_STRUCT_TIM_INFO] 44 = { .min_len = sizeof(struct wmi_tim_info) }, 45 [WMI_TLV_TAG_STRUCT_P2P_NOA_INFO] 46 = { .min_len = sizeof(struct wmi_p2p_noa_info) }, 47 [WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT] 48 = { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) }, 49 [WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES] 50 = { .min_len = sizeof(struct hal_reg_capabilities) }, 51 [WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ] 52 = { .min_len = sizeof(struct wlan_host_mem_req) }, 53 [WMI_TLV_TAG_STRUCT_READY_EVENT] 54 = { .min_len = sizeof(struct wmi_tlv_rdy_ev) }, 55 [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT] 56 = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) }, 57 [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT] 58 = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) }, 59 [WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT] 60 = { .min_len = sizeof(struct wmi_tlv_p2p_noa_ev) }, 61 [WMI_TLV_TAG_STRUCT_ROAM_EVENT] 62 = { .min_len = sizeof(struct wmi_tlv_roam_ev) }, 63 [WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO] 64 = { .min_len = sizeof(struct wmi_tlv_wow_event_info) }, 65 [WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT] 66 = { .min_len = sizeof(struct wmi_tlv_tx_pause_ev) }, 67 }; 68 69 static int 70 #if defined(__linux__) 71 ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len, 72 #elif defined(__FreeBSD__) 73 ath10k_wmi_tlv_iter(struct ath10k *ar, const u8 *ptr, size_t len, 74 #endif 75 int (*iter)(struct ath10k *ar, u16 tag, u16 len, 76 const void *ptr, void *data), 77 void *data) 78 { 79 #if defined(__linux__) 80 const void *begin = ptr; 81 #elif defined(__FreeBSD__) 82 const u8 *begin = ptr; 83 #endif 84 const struct wmi_tlv *tlv; 85 u16 tlv_tag, tlv_len; 86 int ret; 87 88 while (len > 0) { 89 if (len < sizeof(*tlv)) { 90 ath10k_dbg(ar, ATH10K_DBG_WMI, 91 "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", 92 ptr - begin, len, sizeof(*tlv)); 93 return -EINVAL; 94 } 95 96 #if defined(__linux__) 97 tlv = ptr; 98 #elif defined(__FreeBSD__) 99 tlv = (const void *)ptr; 100 #endif 101 tlv_tag = __le16_to_cpu(tlv->tag); 102 tlv_len = __le16_to_cpu(tlv->len); 103 ptr += sizeof(*tlv); 104 len -= sizeof(*tlv); 105 106 if (tlv_len > len) { 107 ath10k_dbg(ar, ATH10K_DBG_WMI, 108 "wmi tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", 109 tlv_tag, ptr - begin, len, tlv_len); 110 return -EINVAL; 111 } 112 113 if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) && 114 wmi_tlv_policies[tlv_tag].min_len && 115 wmi_tlv_policies[tlv_tag].min_len > tlv_len) { 116 ath10k_dbg(ar, ATH10K_DBG_WMI, 117 "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n", 118 tlv_tag, ptr - begin, tlv_len, 119 wmi_tlv_policies[tlv_tag].min_len); 120 return -EINVAL; 121 } 122 123 ret = iter(ar, tlv_tag, tlv_len, ptr, data); 124 if (ret) 125 return ret; 126 127 ptr += tlv_len; 128 len -= tlv_len; 129 } 130 131 return 0; 132 } 133 134 static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len, 135 const void *ptr, void *data) 136 { 137 const void **tb = data; 138 139 if (tag < WMI_TLV_TAG_MAX) 140 tb[tag] = ptr; 141 142 return 0; 143 } 144 145 static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb, 146 const void *ptr, size_t len) 147 { 148 return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse, 149 (void *)tb); 150 } 151 152 static const void ** 153 ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr, 154 size_t len, gfp_t gfp) 155 { 156 const void **tb; 157 int ret; 158 159 tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp); 160 if (!tb) 161 return ERR_PTR(-ENOMEM); 162 163 ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len); 164 if (ret) { 165 kfree(tb); 166 return ERR_PTR(ret); 167 } 168 169 return tb; 170 } 171 172 static u16 ath10k_wmi_tlv_len(const void *ptr) 173 { 174 return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len); 175 } 176 177 /**************/ 178 /* TLV events */ 179 /**************/ 180 static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, 181 struct sk_buff *skb) 182 { 183 const void **tb; 184 const struct wmi_tlv_bcn_tx_status_ev *ev; 185 struct ath10k_vif *arvif; 186 u32 vdev_id, tx_status; 187 int ret; 188 189 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 190 if (IS_ERR(tb)) { 191 ret = PTR_ERR(tb); 192 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 193 return ret; 194 } 195 196 ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]; 197 if (!ev) { 198 kfree(tb); 199 return -EPROTO; 200 } 201 202 tx_status = __le32_to_cpu(ev->tx_status); 203 vdev_id = __le32_to_cpu(ev->vdev_id); 204 205 switch (tx_status) { 206 case WMI_TLV_BCN_TX_STATUS_OK: 207 break; 208 case WMI_TLV_BCN_TX_STATUS_XRETRY: 209 case WMI_TLV_BCN_TX_STATUS_DROP: 210 case WMI_TLV_BCN_TX_STATUS_FILTERED: 211 /* FIXME: It's probably worth telling mac80211 to stop the 212 * interface as it is crippled. 213 */ 214 ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d", 215 vdev_id, tx_status); 216 break; 217 } 218 219 arvif = ath10k_get_arvif(ar, vdev_id); 220 if (arvif && arvif->is_up && arvif->vif->bss_conf.csa_active) 221 ieee80211_queue_work(ar->hw, &arvif->ap_csa_work); 222 223 kfree(tb); 224 return 0; 225 } 226 227 static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar, 228 struct sk_buff *skb) 229 { 230 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n"); 231 complete(&ar->vdev_delete_done); 232 } 233 234 static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16 len, 235 const void *ptr, void *data) 236 { 237 const struct wmi_tlv_peer_stats_info *stat = ptr; 238 struct ieee80211_sta *sta; 239 struct ath10k_sta *arsta; 240 241 if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO) 242 return -EPROTO; 243 244 ath10k_dbg(ar, ATH10K_DBG_WMI, 245 "wmi tlv stats peer addr %pMF rx rate code 0x%x bit rate %d kbps\n", 246 stat->peer_macaddr.addr, 247 __le32_to_cpu(stat->last_rx_rate_code), 248 __le32_to_cpu(stat->last_rx_bitrate_kbps)); 249 250 ath10k_dbg(ar, ATH10K_DBG_WMI, 251 "wmi tlv stats tx rate code 0x%x bit rate %d kbps\n", 252 __le32_to_cpu(stat->last_tx_rate_code), 253 __le32_to_cpu(stat->last_tx_bitrate_kbps)); 254 255 rcu_read_lock(); 256 sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL); 257 if (!sta) { 258 rcu_read_unlock(); 259 ath10k_warn(ar, "not found station for peer stats\n"); 260 return -EINVAL; 261 } 262 263 arsta = (struct ath10k_sta *)sta->drv_priv; 264 arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code); 265 arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps); 266 arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code); 267 arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps); 268 rcu_read_unlock(); 269 270 return 0; 271 } 272 273 static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar, 274 struct sk_buff *skb) 275 { 276 const void **tb; 277 const struct wmi_tlv_peer_stats_info_ev *ev; 278 const void *data; 279 u32 num_peer_stats; 280 int ret; 281 282 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 283 if (IS_ERR(tb)) { 284 ret = PTR_ERR(tb); 285 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 286 return ret; 287 } 288 289 ev = tb[WMI_TLV_TAG_STRUCT_PEER_STATS_INFO_EVENT]; 290 data = tb[WMI_TLV_TAG_ARRAY_STRUCT]; 291 292 if (!ev || !data) { 293 kfree(tb); 294 return -EPROTO; 295 } 296 297 num_peer_stats = __le32_to_cpu(ev->num_peers); 298 299 ath10k_dbg(ar, ATH10K_DBG_WMI, 300 "wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n", 301 __le32_to_cpu(ev->vdev_id), 302 num_peer_stats, 303 __le32_to_cpu(ev->more_data)); 304 305 ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data), 306 ath10k_wmi_tlv_parse_peer_stats_info, NULL); 307 if (ret) 308 ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret); 309 310 kfree(tb); 311 return 0; 312 } 313 314 static void ath10k_wmi_tlv_event_peer_stats_info(struct ath10k *ar, 315 struct sk_buff *skb) 316 { 317 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PEER_STATS_INFO_EVENTID\n"); 318 ath10k_wmi_tlv_op_pull_peer_stats_info(ar, skb); 319 complete(&ar->peer_stats_info_complete); 320 } 321 322 static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, 323 struct sk_buff *skb) 324 { 325 const void **tb; 326 const struct wmi_tlv_diag_data_ev *ev; 327 const struct wmi_tlv_diag_item *item; 328 #if defined(__linux__) 329 const void *data; 330 #elif defined(__FreeBSD__) 331 const u8 *data; 332 #endif 333 int ret, num_items, len; 334 335 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 336 if (IS_ERR(tb)) { 337 ret = PTR_ERR(tb); 338 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 339 return ret; 340 } 341 342 ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]; 343 data = tb[WMI_TLV_TAG_ARRAY_BYTE]; 344 if (!ev || !data) { 345 kfree(tb); 346 return -EPROTO; 347 } 348 349 num_items = __le32_to_cpu(ev->num_items); 350 len = ath10k_wmi_tlv_len(data); 351 352 while (num_items--) { 353 if (len == 0) 354 break; 355 if (len < sizeof(*item)) { 356 ath10k_warn(ar, "failed to parse diag data: can't fit item header\n"); 357 break; 358 } 359 360 #if defined(__linux__) 361 item = data; 362 #elif defined(__FreeBSD__) 363 item = (const void *)data; 364 #endif 365 366 if (len < sizeof(*item) + __le16_to_cpu(item->len)) { 367 ath10k_warn(ar, "failed to parse diag data: item is too long\n"); 368 break; 369 } 370 371 trace_ath10k_wmi_diag_container(ar, 372 item->type, 373 __le32_to_cpu(item->timestamp), 374 __le32_to_cpu(item->code), 375 __le16_to_cpu(item->len), 376 item->payload); 377 378 len -= sizeof(*item); 379 len -= roundup(__le16_to_cpu(item->len), 4); 380 381 data += sizeof(*item); 382 data += roundup(__le16_to_cpu(item->len), 4); 383 } 384 385 if (num_items != -1 || len != 0) 386 ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n", 387 num_items, len); 388 389 kfree(tb); 390 return 0; 391 } 392 393 static int ath10k_wmi_tlv_event_diag(struct ath10k *ar, 394 struct sk_buff *skb) 395 { 396 const void **tb; 397 const void *data; 398 int ret, len; 399 400 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 401 if (IS_ERR(tb)) { 402 ret = PTR_ERR(tb); 403 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 404 return ret; 405 } 406 407 data = tb[WMI_TLV_TAG_ARRAY_BYTE]; 408 if (!data) { 409 kfree(tb); 410 return -EPROTO; 411 } 412 len = ath10k_wmi_tlv_len(data); 413 414 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len); 415 trace_ath10k_wmi_diag(ar, data, len); 416 417 kfree(tb); 418 return 0; 419 } 420 421 static int ath10k_wmi_tlv_event_p2p_noa(struct ath10k *ar, 422 struct sk_buff *skb) 423 { 424 const void **tb; 425 const struct wmi_tlv_p2p_noa_ev *ev; 426 const struct wmi_p2p_noa_info *noa; 427 int ret, vdev_id; 428 429 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 430 if (IS_ERR(tb)) { 431 ret = PTR_ERR(tb); 432 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 433 return ret; 434 } 435 436 ev = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT]; 437 noa = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]; 438 439 if (!ev || !noa) { 440 kfree(tb); 441 return -EPROTO; 442 } 443 444 vdev_id = __le32_to_cpu(ev->vdev_id); 445 446 ath10k_dbg(ar, ATH10K_DBG_WMI, 447 "wmi tlv p2p noa vdev_id %i descriptors %u\n", 448 vdev_id, noa->num_descriptors); 449 450 ath10k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa); 451 kfree(tb); 452 return 0; 453 } 454 455 static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, 456 struct sk_buff *skb) 457 { 458 const void **tb; 459 const struct wmi_tlv_tx_pause_ev *ev; 460 int ret, vdev_id; 461 u32 pause_id, action, vdev_map, peer_id, tid_map; 462 463 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 464 if (IS_ERR(tb)) { 465 ret = PTR_ERR(tb); 466 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 467 return ret; 468 } 469 470 ev = tb[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT]; 471 if (!ev) { 472 kfree(tb); 473 return -EPROTO; 474 } 475 476 pause_id = __le32_to_cpu(ev->pause_id); 477 action = __le32_to_cpu(ev->action); 478 vdev_map = __le32_to_cpu(ev->vdev_map); 479 peer_id = __le32_to_cpu(ev->peer_id); 480 tid_map = __le32_to_cpu(ev->tid_map); 481 482 ath10k_dbg(ar, ATH10K_DBG_WMI, 483 "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n", 484 pause_id, action, vdev_map, peer_id, tid_map); 485 486 switch (pause_id) { 487 case WMI_TLV_TX_PAUSE_ID_MCC: 488 case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA: 489 case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS: 490 case WMI_TLV_TX_PAUSE_ID_AP_PS: 491 case WMI_TLV_TX_PAUSE_ID_IBSS_PS: 492 for (vdev_id = 0; vdev_map; vdev_id++) { 493 if (!(vdev_map & BIT(vdev_id))) 494 continue; 495 496 vdev_map &= ~BIT(vdev_id); 497 ath10k_mac_handle_tx_pause_vdev(ar, vdev_id, pause_id, 498 action); 499 } 500 break; 501 case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS: 502 case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD: 503 case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA: 504 case WMI_TLV_TX_PAUSE_ID_HOST: 505 ath10k_dbg(ar, ATH10K_DBG_MAC, 506 "mac ignoring unsupported tx pause id %d\n", 507 pause_id); 508 break; 509 default: 510 ath10k_dbg(ar, ATH10K_DBG_MAC, 511 "mac ignoring unknown tx pause vdev %d\n", 512 pause_id); 513 break; 514 } 515 516 kfree(tb); 517 return 0; 518 } 519 520 static void ath10k_wmi_tlv_event_rfkill_state_change(struct ath10k *ar, 521 struct sk_buff *skb) 522 { 523 const struct wmi_tlv_rfkill_state_change_ev *ev; 524 const void **tb; 525 bool radio; 526 int ret; 527 528 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 529 if (IS_ERR(tb)) { 530 ret = PTR_ERR(tb); 531 ath10k_warn(ar, 532 "failed to parse rfkill state change event: %d\n", 533 ret); 534 return; 535 } 536 537 ev = tb[WMI_TLV_TAG_STRUCT_RFKILL_EVENT]; 538 if (!ev) { 539 kfree(tb); 540 return; 541 } 542 543 ath10k_dbg(ar, ATH10K_DBG_MAC, 544 "wmi tlv rfkill state change gpio %d type %d radio_state %d\n", 545 __le32_to_cpu(ev->gpio_pin_num), 546 __le32_to_cpu(ev->int_type), 547 __le32_to_cpu(ev->radio_state)); 548 549 radio = (__le32_to_cpu(ev->radio_state) == WMI_TLV_RFKILL_RADIO_STATE_ON); 550 551 spin_lock_bh(&ar->data_lock); 552 553 if (!radio) 554 ar->hw_rfkill_on = true; 555 556 spin_unlock_bh(&ar->data_lock); 557 558 /* notify cfg80211 radio state change */ 559 ath10k_mac_rfkill_enable_radio(ar, radio); 560 wiphy_rfkill_set_hw_state(ar->hw->wiphy, !radio); 561 } 562 563 static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar, 564 struct sk_buff *skb) 565 { 566 const struct wmi_tlv_pdev_temperature_event *ev; 567 568 ev = (struct wmi_tlv_pdev_temperature_event *)skb->data; 569 if (WARN_ON(skb->len < sizeof(*ev))) 570 return -EPROTO; 571 572 ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature)); 573 return 0; 574 } 575 576 static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) 577 { 578 struct ieee80211_sta *station; 579 const struct wmi_tlv_tdls_peer_event *ev; 580 const void **tb; 581 struct ath10k_vif *arvif; 582 583 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 584 if (IS_ERR(tb)) { 585 ath10k_warn(ar, "tdls peer failed to parse tlv"); 586 return; 587 } 588 ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT]; 589 if (!ev) { 590 kfree(tb); 591 ath10k_warn(ar, "tdls peer NULL event"); 592 return; 593 } 594 595 switch (__le32_to_cpu(ev->peer_reason)) { 596 case WMI_TDLS_TEARDOWN_REASON_TX: 597 case WMI_TDLS_TEARDOWN_REASON_RSSI: 598 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 599 rcu_read_lock(); 600 station = ieee80211_find_sta_by_ifaddr(ar->hw, 601 ev->peer_macaddr.addr, 602 NULL); 603 if (!station) { 604 ath10k_warn(ar, "did not find station from tdls peer event"); 605 goto exit; 606 } 607 608 arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); 609 if (!arvif) { 610 ath10k_warn(ar, "no vif for vdev_id %d found", 611 __le32_to_cpu(ev->vdev_id)); 612 goto exit; 613 } 614 615 ieee80211_tdls_oper_request( 616 arvif->vif, station->addr, 617 NL80211_TDLS_TEARDOWN, 618 WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, 619 GFP_ATOMIC 620 ); 621 break; 622 default: 623 kfree(tb); 624 return; 625 } 626 627 exit: 628 rcu_read_unlock(); 629 kfree(tb); 630 } 631 632 static int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar, 633 struct sk_buff *skb) 634 { 635 struct wmi_peer_delete_resp_ev_arg *arg; 636 struct wmi_tlv *tlv_hdr; 637 638 tlv_hdr = (struct wmi_tlv *)skb->data; 639 arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value; 640 641 ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id); 642 ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr); 643 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n"); 644 645 complete(&ar->peer_delete_done); 646 647 return 0; 648 } 649 650 /***********/ 651 /* TLV ops */ 652 /***********/ 653 654 static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) 655 { 656 struct wmi_cmd_hdr *cmd_hdr; 657 enum wmi_tlv_event_id id; 658 bool consumed; 659 660 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 661 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 662 663 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 664 goto out; 665 666 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 667 668 consumed = ath10k_tm_event_wmi(ar, id, skb); 669 670 /* Ready event must be handled normally also in UTF mode so that we 671 * know the UTF firmware has booted, others we are just bypass WMI 672 * events to testmode. 673 */ 674 if (consumed && id != WMI_TLV_READY_EVENTID) { 675 ath10k_dbg(ar, ATH10K_DBG_WMI, 676 "wmi tlv testmode consumed 0x%x\n", id); 677 goto out; 678 } 679 680 switch (id) { 681 case WMI_TLV_MGMT_RX_EVENTID: 682 ath10k_wmi_event_mgmt_rx(ar, skb); 683 /* mgmt_rx() owns the skb now! */ 684 return; 685 case WMI_TLV_SCAN_EVENTID: 686 ath10k_wmi_event_scan(ar, skb); 687 break; 688 case WMI_TLV_CHAN_INFO_EVENTID: 689 ath10k_wmi_event_chan_info(ar, skb); 690 break; 691 case WMI_TLV_ECHO_EVENTID: 692 ath10k_wmi_event_echo(ar, skb); 693 break; 694 case WMI_TLV_DEBUG_MESG_EVENTID: 695 ath10k_wmi_event_debug_mesg(ar, skb); 696 break; 697 case WMI_TLV_UPDATE_STATS_EVENTID: 698 ath10k_wmi_event_update_stats(ar, skb); 699 break; 700 case WMI_TLV_PEER_STATS_INFO_EVENTID: 701 ath10k_wmi_tlv_event_peer_stats_info(ar, skb); 702 break; 703 case WMI_TLV_VDEV_START_RESP_EVENTID: 704 ath10k_wmi_event_vdev_start_resp(ar, skb); 705 break; 706 case WMI_TLV_VDEV_STOPPED_EVENTID: 707 ath10k_wmi_event_vdev_stopped(ar, skb); 708 break; 709 case WMI_TLV_VDEV_DELETE_RESP_EVENTID: 710 ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb); 711 break; 712 case WMI_TLV_PEER_STA_KICKOUT_EVENTID: 713 ath10k_wmi_event_peer_sta_kickout(ar, skb); 714 break; 715 case WMI_TLV_HOST_SWBA_EVENTID: 716 ath10k_wmi_event_host_swba(ar, skb); 717 break; 718 case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID: 719 ath10k_wmi_event_tbttoffset_update(ar, skb); 720 break; 721 case WMI_TLV_PHYERR_EVENTID: 722 ath10k_wmi_event_phyerr(ar, skb); 723 break; 724 case WMI_TLV_ROAM_EVENTID: 725 ath10k_wmi_event_roam(ar, skb); 726 break; 727 case WMI_TLV_PROFILE_MATCH: 728 ath10k_wmi_event_profile_match(ar, skb); 729 break; 730 case WMI_TLV_DEBUG_PRINT_EVENTID: 731 ath10k_wmi_event_debug_print(ar, skb); 732 break; 733 case WMI_TLV_PDEV_QVIT_EVENTID: 734 ath10k_wmi_event_pdev_qvit(ar, skb); 735 break; 736 case WMI_TLV_WLAN_PROFILE_DATA_EVENTID: 737 ath10k_wmi_event_wlan_profile_data(ar, skb); 738 break; 739 case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID: 740 ath10k_wmi_event_rtt_measurement_report(ar, skb); 741 break; 742 case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID: 743 ath10k_wmi_event_tsf_measurement_report(ar, skb); 744 break; 745 case WMI_TLV_RTT_ERROR_REPORT_EVENTID: 746 ath10k_wmi_event_rtt_error_report(ar, skb); 747 break; 748 case WMI_TLV_WOW_WAKEUP_HOST_EVENTID: 749 ath10k_wmi_event_wow_wakeup_host(ar, skb); 750 break; 751 case WMI_TLV_DCS_INTERFERENCE_EVENTID: 752 ath10k_wmi_event_dcs_interference(ar, skb); 753 break; 754 case WMI_TLV_PDEV_TPC_CONFIG_EVENTID: 755 ath10k_wmi_event_pdev_tpc_config(ar, skb); 756 break; 757 case WMI_TLV_PDEV_FTM_INTG_EVENTID: 758 ath10k_wmi_event_pdev_ftm_intg(ar, skb); 759 break; 760 case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID: 761 ath10k_wmi_event_gtk_offload_status(ar, skb); 762 break; 763 case WMI_TLV_GTK_REKEY_FAIL_EVENTID: 764 ath10k_wmi_event_gtk_rekey_fail(ar, skb); 765 break; 766 case WMI_TLV_TX_DELBA_COMPLETE_EVENTID: 767 ath10k_wmi_event_delba_complete(ar, skb); 768 break; 769 case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID: 770 ath10k_wmi_event_addba_complete(ar, skb); 771 break; 772 case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID: 773 ath10k_wmi_event_vdev_install_key_complete(ar, skb); 774 break; 775 case WMI_TLV_SERVICE_READY_EVENTID: 776 ath10k_wmi_event_service_ready(ar, skb); 777 return; 778 case WMI_TLV_READY_EVENTID: 779 ath10k_wmi_event_ready(ar, skb); 780 break; 781 case WMI_TLV_SERVICE_AVAILABLE_EVENTID: 782 ath10k_wmi_event_service_available(ar, skb); 783 break; 784 case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID: 785 ath10k_wmi_tlv_event_bcn_tx_status(ar, skb); 786 break; 787 case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID: 788 ath10k_wmi_tlv_event_diag_data(ar, skb); 789 break; 790 case WMI_TLV_DIAG_EVENTID: 791 ath10k_wmi_tlv_event_diag(ar, skb); 792 break; 793 case WMI_TLV_P2P_NOA_EVENTID: 794 ath10k_wmi_tlv_event_p2p_noa(ar, skb); 795 break; 796 case WMI_TLV_TX_PAUSE_EVENTID: 797 ath10k_wmi_tlv_event_tx_pause(ar, skb); 798 break; 799 case WMI_TLV_RFKILL_STATE_CHANGE_EVENTID: 800 ath10k_wmi_tlv_event_rfkill_state_change(ar, skb); 801 break; 802 case WMI_TLV_PDEV_TEMPERATURE_EVENTID: 803 ath10k_wmi_tlv_event_temperature(ar, skb); 804 break; 805 case WMI_TLV_TDLS_PEER_EVENTID: 806 ath10k_wmi_event_tdls_peer(ar, skb); 807 break; 808 case WMI_TLV_PEER_DELETE_RESP_EVENTID: 809 ath10k_wmi_tlv_event_peer_delete_resp(ar, skb); 810 break; 811 case WMI_TLV_MGMT_TX_COMPLETION_EVENTID: 812 ath10k_wmi_event_mgmt_tx_compl(ar, skb); 813 break; 814 case WMI_TLV_MGMT_TX_BUNDLE_COMPLETION_EVENTID: 815 ath10k_wmi_event_mgmt_tx_bundle_compl(ar, skb); 816 break; 817 default: 818 ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id); 819 break; 820 } 821 822 out: 823 dev_kfree_skb(skb); 824 } 825 826 static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar, 827 struct sk_buff *skb, 828 struct wmi_scan_ev_arg *arg) 829 { 830 const void **tb; 831 const struct wmi_scan_event *ev; 832 int ret; 833 834 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 835 if (IS_ERR(tb)) { 836 ret = PTR_ERR(tb); 837 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 838 return ret; 839 } 840 841 ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT]; 842 if (!ev) { 843 kfree(tb); 844 return -EPROTO; 845 } 846 847 arg->event_type = ev->event_type; 848 arg->reason = ev->reason; 849 arg->channel_freq = ev->channel_freq; 850 arg->scan_req_id = ev->scan_req_id; 851 arg->scan_id = ev->scan_id; 852 arg->vdev_id = ev->vdev_id; 853 854 kfree(tb); 855 return 0; 856 } 857 858 static int 859 ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb, 860 struct wmi_tlv_mgmt_tx_compl_ev_arg *arg) 861 { 862 const void **tb; 863 const struct wmi_tlv_mgmt_tx_compl_ev *ev; 864 int ret; 865 866 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 867 if (IS_ERR(tb)) { 868 ret = PTR_ERR(tb); 869 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 870 return ret; 871 } 872 873 ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT]; 874 875 arg->desc_id = ev->desc_id; 876 arg->status = ev->status; 877 arg->pdev_id = ev->pdev_id; 878 arg->ppdu_id = ev->ppdu_id; 879 880 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) 881 arg->ack_rssi = ev->ack_rssi; 882 883 kfree(tb); 884 return 0; 885 } 886 887 struct wmi_tlv_tx_bundle_compl_parse { 888 const __le32 *num_reports; 889 const __le32 *desc_ids; 890 const __le32 *status; 891 const __le32 *ppdu_ids; 892 const __le32 *ack_rssi; 893 bool desc_ids_done; 894 bool status_done; 895 bool ppdu_ids_done; 896 bool ack_rssi_done; 897 }; 898 899 static int 900 ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse(struct ath10k *ar, u16 tag, u16 len, 901 const void *ptr, void *data) 902 { 903 struct wmi_tlv_tx_bundle_compl_parse *bundle_tx_compl = data; 904 905 switch (tag) { 906 case WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_BUNDLE_EVENT: 907 bundle_tx_compl->num_reports = ptr; 908 break; 909 case WMI_TLV_TAG_ARRAY_UINT32: 910 if (!bundle_tx_compl->desc_ids_done) { 911 bundle_tx_compl->desc_ids_done = true; 912 bundle_tx_compl->desc_ids = ptr; 913 } else if (!bundle_tx_compl->status_done) { 914 bundle_tx_compl->status_done = true; 915 bundle_tx_compl->status = ptr; 916 } else if (!bundle_tx_compl->ppdu_ids_done) { 917 bundle_tx_compl->ppdu_ids_done = true; 918 bundle_tx_compl->ppdu_ids = ptr; 919 } else if (!bundle_tx_compl->ack_rssi_done) { 920 bundle_tx_compl->ack_rssi_done = true; 921 bundle_tx_compl->ack_rssi = ptr; 922 } 923 break; 924 default: 925 break; 926 } 927 return 0; 928 } 929 930 static int ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev( 931 struct ath10k *ar, struct sk_buff *skb, 932 struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg) 933 { 934 struct wmi_tlv_tx_bundle_compl_parse bundle_tx_compl = { }; 935 int ret; 936 937 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 938 ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse, 939 &bundle_tx_compl); 940 if (ret) { 941 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 942 return ret; 943 } 944 945 if (!bundle_tx_compl.num_reports || !bundle_tx_compl.desc_ids || 946 !bundle_tx_compl.status) 947 return -EPROTO; 948 949 arg->num_reports = *bundle_tx_compl.num_reports; 950 arg->desc_ids = bundle_tx_compl.desc_ids; 951 arg->status = bundle_tx_compl.status; 952 arg->ppdu_ids = bundle_tx_compl.ppdu_ids; 953 954 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) 955 arg->ack_rssi = bundle_tx_compl.ack_rssi; 956 957 return 0; 958 } 959 960 static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar, 961 struct sk_buff *skb, 962 struct wmi_mgmt_rx_ev_arg *arg) 963 { 964 const void **tb; 965 const struct wmi_tlv_mgmt_rx_ev *ev; 966 const u8 *frame; 967 u32 msdu_len; 968 int ret, i; 969 970 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 971 if (IS_ERR(tb)) { 972 ret = PTR_ERR(tb); 973 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 974 return ret; 975 } 976 977 ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]; 978 frame = tb[WMI_TLV_TAG_ARRAY_BYTE]; 979 980 if (!ev || !frame) { 981 kfree(tb); 982 return -EPROTO; 983 } 984 985 arg->channel = ev->channel; 986 arg->buf_len = ev->buf_len; 987 arg->status = ev->status; 988 arg->snr = ev->snr; 989 arg->phy_mode = ev->phy_mode; 990 arg->rate = ev->rate; 991 992 for (i = 0; i < ARRAY_SIZE(ev->rssi); i++) 993 arg->rssi[i] = ev->rssi[i]; 994 995 msdu_len = __le32_to_cpu(arg->buf_len); 996 997 if (skb->len < (frame - skb->data) + msdu_len) { 998 kfree(tb); 999 return -EPROTO; 1000 } 1001 1002 /* shift the sk_buff to point to `frame` */ 1003 skb_trim(skb, 0); 1004 skb_put(skb, frame - skb->data); 1005 skb_pull(skb, frame - skb->data); 1006 skb_put(skb, msdu_len); 1007 1008 kfree(tb); 1009 return 0; 1010 } 1011 1012 static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar, 1013 struct sk_buff *skb, 1014 struct wmi_ch_info_ev_arg *arg) 1015 { 1016 const void **tb; 1017 const struct wmi_tlv_chan_info_event *ev; 1018 int ret; 1019 1020 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1021 if (IS_ERR(tb)) { 1022 ret = PTR_ERR(tb); 1023 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1024 return ret; 1025 } 1026 1027 ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]; 1028 if (!ev) { 1029 kfree(tb); 1030 return -EPROTO; 1031 } 1032 1033 arg->err_code = ev->err_code; 1034 arg->freq = ev->freq; 1035 arg->cmd_flags = ev->cmd_flags; 1036 arg->noise_floor = ev->noise_floor; 1037 arg->rx_clear_count = ev->rx_clear_count; 1038 arg->cycle_count = ev->cycle_count; 1039 if (test_bit(ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL, 1040 ar->running_fw->fw_file.fw_features)) 1041 arg->mac_clk_mhz = ev->mac_clk_mhz; 1042 1043 kfree(tb); 1044 return 0; 1045 } 1046 1047 static int 1048 ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb, 1049 struct wmi_vdev_start_ev_arg *arg) 1050 { 1051 const void **tb; 1052 const struct wmi_vdev_start_response_event *ev; 1053 int ret; 1054 1055 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1056 if (IS_ERR(tb)) { 1057 ret = PTR_ERR(tb); 1058 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1059 return ret; 1060 } 1061 1062 ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]; 1063 if (!ev) { 1064 kfree(tb); 1065 return -EPROTO; 1066 } 1067 1068 skb_pull(skb, sizeof(*ev)); 1069 arg->vdev_id = ev->vdev_id; 1070 arg->req_id = ev->req_id; 1071 arg->resp_type = ev->resp_type; 1072 arg->status = ev->status; 1073 1074 kfree(tb); 1075 return 0; 1076 } 1077 1078 static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar, 1079 struct sk_buff *skb, 1080 struct wmi_peer_kick_ev_arg *arg) 1081 { 1082 const void **tb; 1083 const struct wmi_peer_sta_kickout_event *ev; 1084 int ret; 1085 1086 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1087 if (IS_ERR(tb)) { 1088 ret = PTR_ERR(tb); 1089 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1090 return ret; 1091 } 1092 1093 ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]; 1094 if (!ev) { 1095 kfree(tb); 1096 return -EPROTO; 1097 } 1098 1099 arg->mac_addr = ev->peer_macaddr.addr; 1100 1101 kfree(tb); 1102 return 0; 1103 } 1104 1105 struct wmi_tlv_swba_parse { 1106 const struct wmi_host_swba_event *ev; 1107 bool tim_done; 1108 bool noa_done; 1109 size_t n_tim; 1110 size_t n_noa; 1111 struct wmi_swba_ev_arg *arg; 1112 }; 1113 1114 static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len, 1115 const void *ptr, void *data) 1116 { 1117 struct wmi_tlv_swba_parse *swba = data; 1118 struct wmi_tim_info_arg *tim_info_arg; 1119 const struct wmi_tim_info *tim_info_ev = ptr; 1120 1121 if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO) 1122 return -EPROTO; 1123 1124 if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info)) 1125 return -ENOBUFS; 1126 1127 if (__le32_to_cpu(tim_info_ev->tim_len) > 1128 sizeof(tim_info_ev->tim_bitmap)) { 1129 ath10k_warn(ar, "refusing to parse invalid swba structure\n"); 1130 return -EPROTO; 1131 } 1132 1133 tim_info_arg = &swba->arg->tim_info[swba->n_tim]; 1134 tim_info_arg->tim_len = tim_info_ev->tim_len; 1135 tim_info_arg->tim_mcast = tim_info_ev->tim_mcast; 1136 tim_info_arg->tim_bitmap = tim_info_ev->tim_bitmap; 1137 tim_info_arg->tim_changed = tim_info_ev->tim_changed; 1138 tim_info_arg->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 1139 1140 swba->n_tim++; 1141 1142 return 0; 1143 } 1144 1145 static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len, 1146 const void *ptr, void *data) 1147 { 1148 struct wmi_tlv_swba_parse *swba = data; 1149 1150 if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO) 1151 return -EPROTO; 1152 1153 if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info)) 1154 return -ENOBUFS; 1155 1156 swba->arg->noa_info[swba->n_noa++] = ptr; 1157 return 0; 1158 } 1159 1160 static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len, 1161 const void *ptr, void *data) 1162 { 1163 struct wmi_tlv_swba_parse *swba = data; 1164 int ret; 1165 1166 switch (tag) { 1167 case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT: 1168 swba->ev = ptr; 1169 break; 1170 case WMI_TLV_TAG_ARRAY_STRUCT: 1171 if (!swba->tim_done) { 1172 swba->tim_done = true; 1173 ret = ath10k_wmi_tlv_iter(ar, ptr, len, 1174 ath10k_wmi_tlv_swba_tim_parse, 1175 swba); 1176 if (ret) 1177 return ret; 1178 } else if (!swba->noa_done) { 1179 swba->noa_done = true; 1180 ret = ath10k_wmi_tlv_iter(ar, ptr, len, 1181 ath10k_wmi_tlv_swba_noa_parse, 1182 swba); 1183 if (ret) 1184 return ret; 1185 } 1186 break; 1187 default: 1188 break; 1189 } 1190 return 0; 1191 } 1192 1193 static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar, 1194 struct sk_buff *skb, 1195 struct wmi_swba_ev_arg *arg) 1196 { 1197 struct wmi_tlv_swba_parse swba = { .arg = arg }; 1198 u32 map; 1199 size_t n_vdevs; 1200 int ret; 1201 1202 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 1203 ath10k_wmi_tlv_swba_parse, &swba); 1204 if (ret) { 1205 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1206 return ret; 1207 } 1208 1209 if (!swba.ev) 1210 return -EPROTO; 1211 1212 arg->vdev_map = swba.ev->vdev_map; 1213 1214 for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1) 1215 if (map & BIT(0)) 1216 n_vdevs++; 1217 1218 if (n_vdevs != swba.n_tim || 1219 n_vdevs != swba.n_noa) 1220 return -EPROTO; 1221 1222 return 0; 1223 } 1224 1225 static int ath10k_wmi_tlv_op_pull_phyerr_ev_hdr(struct ath10k *ar, 1226 struct sk_buff *skb, 1227 struct wmi_phyerr_hdr_arg *arg) 1228 { 1229 const void **tb; 1230 const struct wmi_tlv_phyerr_ev *ev; 1231 const void *phyerrs; 1232 int ret; 1233 1234 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1235 if (IS_ERR(tb)) { 1236 ret = PTR_ERR(tb); 1237 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1238 return ret; 1239 } 1240 1241 ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR]; 1242 phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE]; 1243 1244 if (!ev || !phyerrs) { 1245 kfree(tb); 1246 return -EPROTO; 1247 } 1248 1249 arg->num_phyerrs = __le32_to_cpu(ev->num_phyerrs); 1250 arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32); 1251 arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32); 1252 arg->buf_len = __le32_to_cpu(ev->buf_len); 1253 arg->phyerrs = phyerrs; 1254 1255 kfree(tb); 1256 return 0; 1257 } 1258 1259 #define WMI_TLV_ABI_VER_NS0 0x5F414351 1260 #define WMI_TLV_ABI_VER_NS1 0x00004C4D 1261 #define WMI_TLV_ABI_VER_NS2 0x00000000 1262 #define WMI_TLV_ABI_VER_NS3 0x00000000 1263 1264 #define WMI_TLV_ABI_VER0_MAJOR 1 1265 #define WMI_TLV_ABI_VER0_MINOR 0 1266 #define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \ 1267 (((WMI_TLV_ABI_VER0_MINOR) << 0) & 0x00FFFFFF)) 1268 #define WMI_TLV_ABI_VER1 53 1269 1270 static int 1271 ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len, 1272 const void *ptr, void *data) 1273 { 1274 struct wmi_svc_rdy_ev_arg *arg = data; 1275 int i; 1276 1277 if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ) 1278 return -EPROTO; 1279 1280 for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) { 1281 if (!arg->mem_reqs[i]) { 1282 arg->mem_reqs[i] = ptr; 1283 return 0; 1284 } 1285 } 1286 1287 return -ENOMEM; 1288 } 1289 1290 struct wmi_tlv_svc_rdy_parse { 1291 const struct hal_reg_capabilities *reg; 1292 const struct wmi_tlv_svc_rdy_ev *ev; 1293 const __le32 *svc_bmap; 1294 const struct wlan_host_mem_req *mem_reqs; 1295 bool svc_bmap_done; 1296 bool dbs_hw_mode_done; 1297 }; 1298 1299 static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len, 1300 const void *ptr, void *data) 1301 { 1302 struct wmi_tlv_svc_rdy_parse *svc_rdy = data; 1303 1304 switch (tag) { 1305 case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT: 1306 svc_rdy->ev = ptr; 1307 break; 1308 case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES: 1309 svc_rdy->reg = ptr; 1310 break; 1311 case WMI_TLV_TAG_ARRAY_STRUCT: 1312 svc_rdy->mem_reqs = ptr; 1313 break; 1314 case WMI_TLV_TAG_ARRAY_UINT32: 1315 if (!svc_rdy->svc_bmap_done) { 1316 svc_rdy->svc_bmap_done = true; 1317 svc_rdy->svc_bmap = ptr; 1318 } else if (!svc_rdy->dbs_hw_mode_done) { 1319 svc_rdy->dbs_hw_mode_done = true; 1320 } 1321 break; 1322 default: 1323 break; 1324 } 1325 return 0; 1326 } 1327 1328 static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar, 1329 struct sk_buff *skb, 1330 struct wmi_svc_rdy_ev_arg *arg) 1331 { 1332 const struct hal_reg_capabilities *reg; 1333 const struct wmi_tlv_svc_rdy_ev *ev; 1334 const __le32 *svc_bmap; 1335 const struct wlan_host_mem_req *mem_reqs; 1336 struct wmi_tlv_svc_rdy_parse svc_rdy = { }; 1337 int ret; 1338 1339 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 1340 ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy); 1341 if (ret) { 1342 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1343 return ret; 1344 } 1345 1346 ev = svc_rdy.ev; 1347 reg = svc_rdy.reg; 1348 svc_bmap = svc_rdy.svc_bmap; 1349 mem_reqs = svc_rdy.mem_reqs; 1350 1351 if (!ev || !reg || !svc_bmap || !mem_reqs) 1352 return -EPROTO; 1353 1354 /* This is an internal ABI compatibility check for WMI TLV so check it 1355 * here instead of the generic WMI code. 1356 */ 1357 ath10k_dbg(ar, ATH10K_DBG_WMI, 1358 "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n", 1359 __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0, 1360 __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0, 1361 __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1, 1362 __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2, 1363 __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3); 1364 1365 if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 || 1366 __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 || 1367 __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 || 1368 __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 || 1369 __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) { 1370 return -ENOTSUPP; 1371 } 1372 1373 arg->min_tx_power = ev->hw_min_tx_power; 1374 arg->max_tx_power = ev->hw_max_tx_power; 1375 arg->ht_cap = ev->ht_cap_info; 1376 arg->vht_cap = ev->vht_cap_info; 1377 arg->vht_supp_mcs = ev->vht_supp_mcs; 1378 arg->sw_ver0 = ev->abi.abi_ver0; 1379 arg->sw_ver1 = ev->abi.abi_ver1; 1380 arg->fw_build = ev->fw_build_vers; 1381 arg->phy_capab = ev->phy_capability; 1382 arg->num_rf_chains = ev->num_rf_chains; 1383 arg->eeprom_rd = reg->eeprom_rd; 1384 arg->low_2ghz_chan = reg->low_2ghz_chan; 1385 arg->high_2ghz_chan = reg->high_2ghz_chan; 1386 arg->low_5ghz_chan = reg->low_5ghz_chan; 1387 arg->high_5ghz_chan = reg->high_5ghz_chan; 1388 arg->num_mem_reqs = ev->num_mem_reqs; 1389 arg->service_map = svc_bmap; 1390 arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap); 1391 arg->sys_cap_info = ev->sys_cap_info; 1392 1393 #if defined(__linux__) 1394 ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs), 1395 #elif defined(__FreeBSD__) 1396 ret = ath10k_wmi_tlv_iter(ar, (const u8 *)mem_reqs, ath10k_wmi_tlv_len(mem_reqs), 1397 #endif 1398 ath10k_wmi_tlv_parse_mem_reqs, arg); 1399 if (ret) { 1400 ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret); 1401 return ret; 1402 } 1403 1404 return 0; 1405 } 1406 1407 static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar, 1408 struct sk_buff *skb, 1409 struct wmi_rdy_ev_arg *arg) 1410 { 1411 const void **tb; 1412 const struct wmi_tlv_rdy_ev *ev; 1413 int ret; 1414 1415 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1416 if (IS_ERR(tb)) { 1417 ret = PTR_ERR(tb); 1418 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1419 return ret; 1420 } 1421 1422 ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT]; 1423 if (!ev) { 1424 kfree(tb); 1425 return -EPROTO; 1426 } 1427 1428 arg->sw_version = ev->abi.abi_ver0; 1429 arg->abi_version = ev->abi.abi_ver1; 1430 arg->status = ev->status; 1431 arg->mac_addr = ev->mac_addr.addr; 1432 1433 kfree(tb); 1434 return 0; 1435 } 1436 1437 static int ath10k_wmi_tlv_svc_avail_parse(struct ath10k *ar, u16 tag, u16 len, 1438 const void *ptr, void *data) 1439 { 1440 struct wmi_svc_avail_ev_arg *arg = data; 1441 1442 switch (tag) { 1443 case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT: 1444 arg->service_map_ext_valid = true; 1445 #if defined(__linux__) 1446 arg->service_map_ext_len = *(__le32 *)ptr; 1447 arg->service_map_ext = ptr + sizeof(__le32); 1448 #elif defined(__FreeBSD__) 1449 arg->service_map_ext_len = *(const __le32 *)ptr; 1450 arg->service_map_ext = (const __le32 *)((const u8 *)ptr + sizeof(__le32)); 1451 #endif 1452 return 0; 1453 default: 1454 break; 1455 } 1456 1457 return 0; 1458 } 1459 1460 static int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar, 1461 struct sk_buff *skb, 1462 struct wmi_svc_avail_ev_arg *arg) 1463 { 1464 int ret; 1465 1466 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, 1467 ath10k_wmi_tlv_svc_avail_parse, arg); 1468 1469 if (ret) { 1470 ath10k_warn(ar, "failed to parse svc_avail tlv: %d\n", ret); 1471 return ret; 1472 } 1473 1474 return 0; 1475 } 1476 1477 static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src, 1478 struct ath10k_fw_stats_vdev *dst) 1479 { 1480 int i; 1481 1482 dst->vdev_id = __le32_to_cpu(src->vdev_id); 1483 dst->beacon_snr = __le32_to_cpu(src->beacon_snr); 1484 dst->data_snr = __le32_to_cpu(src->data_snr); 1485 dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames); 1486 dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail); 1487 dst->num_rts_success = __le32_to_cpu(src->num_rts_success); 1488 dst->num_rx_err = __le32_to_cpu(src->num_rx_err); 1489 dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard); 1490 dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked); 1491 1492 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++) 1493 dst->num_tx_frames[i] = 1494 __le32_to_cpu(src->num_tx_frames[i]); 1495 1496 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++) 1497 dst->num_tx_frames_retries[i] = 1498 __le32_to_cpu(src->num_tx_frames_retries[i]); 1499 1500 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++) 1501 dst->num_tx_frames_failures[i] = 1502 __le32_to_cpu(src->num_tx_frames_failures[i]); 1503 1504 for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++) 1505 dst->tx_rate_history[i] = 1506 __le32_to_cpu(src->tx_rate_history[i]); 1507 1508 for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++) 1509 dst->beacon_rssi_history[i] = 1510 __le32_to_cpu(src->beacon_rssi_history[i]); 1511 } 1512 1513 static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, 1514 struct sk_buff *skb, 1515 struct ath10k_fw_stats *stats) 1516 { 1517 const void **tb; 1518 const struct wmi_tlv_stats_ev *ev; 1519 u32 num_peer_stats_extd; 1520 #if defined(__linux__) 1521 const void *data; 1522 #elif defined(__FreeBSD__) 1523 const u8 *data; 1524 #endif 1525 u32 num_pdev_stats; 1526 u32 num_vdev_stats; 1527 u32 num_peer_stats; 1528 u32 num_bcnflt_stats; 1529 u32 num_chan_stats; 1530 size_t data_len; 1531 u32 stats_id; 1532 int ret; 1533 int i; 1534 1535 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1536 if (IS_ERR(tb)) { 1537 ret = PTR_ERR(tb); 1538 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1539 return ret; 1540 } 1541 1542 ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT]; 1543 data = tb[WMI_TLV_TAG_ARRAY_BYTE]; 1544 1545 if (!ev || !data) { 1546 kfree(tb); 1547 return -EPROTO; 1548 } 1549 1550 data_len = ath10k_wmi_tlv_len(data); 1551 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 1552 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 1553 num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 1554 num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats); 1555 num_chan_stats = __le32_to_cpu(ev->num_chan_stats); 1556 stats_id = __le32_to_cpu(ev->stats_id); 1557 num_peer_stats_extd = __le32_to_cpu(ev->num_peer_stats_extd); 1558 1559 ath10k_dbg(ar, ATH10K_DBG_WMI, 1560 "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i peer_extd %i\n", 1561 num_pdev_stats, num_vdev_stats, num_peer_stats, 1562 num_bcnflt_stats, num_chan_stats, num_peer_stats_extd); 1563 1564 for (i = 0; i < num_pdev_stats; i++) { 1565 const struct wmi_pdev_stats *src; 1566 struct ath10k_fw_stats_pdev *dst; 1567 1568 #if defined(__linux__) 1569 src = data; 1570 #elif defined(__FreeBSD__) 1571 src = (const void *)data; 1572 #endif 1573 if (data_len < sizeof(*src)) { 1574 kfree(tb); 1575 return -EPROTO; 1576 } 1577 1578 data += sizeof(*src); 1579 data_len -= sizeof(*src); 1580 1581 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 1582 if (!dst) 1583 continue; 1584 1585 ath10k_wmi_pull_pdev_stats_base(&src->base, dst); 1586 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); 1587 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); 1588 list_add_tail(&dst->list, &stats->pdevs); 1589 } 1590 1591 for (i = 0; i < num_vdev_stats; i++) { 1592 const struct wmi_tlv_vdev_stats *src; 1593 struct ath10k_fw_stats_vdev *dst; 1594 1595 #if defined(__linux__) 1596 src = data; 1597 #elif defined(__FreeBSD__) 1598 src = (const void *)data; 1599 #endif 1600 if (data_len < sizeof(*src)) { 1601 kfree(tb); 1602 return -EPROTO; 1603 } 1604 1605 data += sizeof(*src); 1606 data_len -= sizeof(*src); 1607 1608 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 1609 if (!dst) 1610 continue; 1611 1612 ath10k_wmi_tlv_pull_vdev_stats(src, dst); 1613 list_add_tail(&dst->list, &stats->vdevs); 1614 } 1615 1616 for (i = 0; i < num_peer_stats; i++) { 1617 const struct wmi_10x_peer_stats *src; 1618 struct ath10k_fw_stats_peer *dst; 1619 1620 #if defined(__linux__) 1621 src = data; 1622 #elif defined(__FreeBSD__) 1623 src = (const void *)data; 1624 #endif 1625 if (data_len < sizeof(*src)) { 1626 kfree(tb); 1627 return -EPROTO; 1628 } 1629 1630 data += sizeof(*src); 1631 data_len -= sizeof(*src); 1632 1633 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 1634 if (!dst) 1635 continue; 1636 1637 ath10k_wmi_pull_peer_stats(&src->old, dst); 1638 dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); 1639 1640 if (stats_id & WMI_TLV_STAT_PEER_EXTD) { 1641 const struct wmi_tlv_peer_stats_extd *extd; 1642 unsigned long rx_duration_high; 1643 1644 #if defined(__linux__) 1645 extd = data + sizeof(*src) * (num_peer_stats - i - 1) 1646 + sizeof(*extd) * i; 1647 #elif defined(__FreeBSD__) 1648 extd = (const void *)(data + sizeof(*src) * (num_peer_stats - i - 1) 1649 + sizeof(*extd) * i); 1650 #endif 1651 1652 dst->rx_duration = __le32_to_cpu(extd->rx_duration); 1653 rx_duration_high = __le32_to_cpu 1654 (extd->rx_duration_high); 1655 1656 if (test_bit(WMI_TLV_PEER_RX_DURATION_HIGH_VALID_BIT, 1657 &rx_duration_high)) { 1658 rx_duration_high = 1659 FIELD_GET(WMI_TLV_PEER_RX_DURATION_HIGH_MASK, 1660 rx_duration_high); 1661 dst->rx_duration |= (u64)rx_duration_high << 1662 WMI_TLV_PEER_RX_DURATION_SHIFT; 1663 } 1664 } 1665 1666 list_add_tail(&dst->list, &stats->peers); 1667 } 1668 1669 kfree(tb); 1670 return 0; 1671 } 1672 1673 static int ath10k_wmi_tlv_op_pull_roam_ev(struct ath10k *ar, 1674 struct sk_buff *skb, 1675 struct wmi_roam_ev_arg *arg) 1676 { 1677 const void **tb; 1678 const struct wmi_tlv_roam_ev *ev; 1679 int ret; 1680 1681 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1682 if (IS_ERR(tb)) { 1683 ret = PTR_ERR(tb); 1684 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1685 return ret; 1686 } 1687 1688 ev = tb[WMI_TLV_TAG_STRUCT_ROAM_EVENT]; 1689 if (!ev) { 1690 kfree(tb); 1691 return -EPROTO; 1692 } 1693 1694 arg->vdev_id = ev->vdev_id; 1695 arg->reason = ev->reason; 1696 arg->rssi = ev->rssi; 1697 1698 kfree(tb); 1699 return 0; 1700 } 1701 1702 static int 1703 ath10k_wmi_tlv_op_pull_wow_ev(struct ath10k *ar, struct sk_buff *skb, 1704 struct wmi_wow_ev_arg *arg) 1705 { 1706 const void **tb; 1707 const struct wmi_tlv_wow_event_info *ev; 1708 int ret; 1709 1710 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1711 if (IS_ERR(tb)) { 1712 ret = PTR_ERR(tb); 1713 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1714 return ret; 1715 } 1716 1717 ev = tb[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO]; 1718 if (!ev) { 1719 kfree(tb); 1720 return -EPROTO; 1721 } 1722 1723 arg->vdev_id = __le32_to_cpu(ev->vdev_id); 1724 arg->flag = __le32_to_cpu(ev->flag); 1725 arg->wake_reason = __le32_to_cpu(ev->wake_reason); 1726 arg->data_len = __le32_to_cpu(ev->data_len); 1727 1728 kfree(tb); 1729 return 0; 1730 } 1731 1732 static int ath10k_wmi_tlv_op_pull_echo_ev(struct ath10k *ar, 1733 struct sk_buff *skb, 1734 struct wmi_echo_ev_arg *arg) 1735 { 1736 const void **tb; 1737 const struct wmi_echo_event *ev; 1738 int ret; 1739 1740 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 1741 if (IS_ERR(tb)) { 1742 ret = PTR_ERR(tb); 1743 ath10k_warn(ar, "failed to parse tlv: %d\n", ret); 1744 return ret; 1745 } 1746 1747 ev = tb[WMI_TLV_TAG_STRUCT_ECHO_EVENT]; 1748 if (!ev) { 1749 kfree(tb); 1750 return -EPROTO; 1751 } 1752 1753 arg->value = ev->value; 1754 1755 kfree(tb); 1756 return 0; 1757 } 1758 1759 static struct sk_buff * 1760 ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt) 1761 { 1762 struct wmi_tlv_pdev_suspend *cmd; 1763 struct wmi_tlv *tlv; 1764 struct sk_buff *skb; 1765 1766 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 1767 if (!skb) 1768 return ERR_PTR(-ENOMEM); 1769 1770 tlv = (void *)skb->data; 1771 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD); 1772 tlv->len = __cpu_to_le16(sizeof(*cmd)); 1773 cmd = (void *)tlv->value; 1774 cmd->opt = __cpu_to_le32(opt); 1775 1776 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n"); 1777 return skb; 1778 } 1779 1780 static struct sk_buff * 1781 ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar) 1782 { 1783 struct wmi_tlv_resume_cmd *cmd; 1784 struct wmi_tlv *tlv; 1785 struct sk_buff *skb; 1786 1787 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 1788 if (!skb) 1789 return ERR_PTR(-ENOMEM); 1790 1791 tlv = (void *)skb->data; 1792 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD); 1793 tlv->len = __cpu_to_le16(sizeof(*cmd)); 1794 cmd = (void *)tlv->value; 1795 cmd->reserved = __cpu_to_le32(0); 1796 1797 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n"); 1798 return skb; 1799 } 1800 1801 static struct sk_buff * 1802 ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar, 1803 u16 rd, u16 rd2g, u16 rd5g, 1804 u16 ctl2g, u16 ctl5g, 1805 enum wmi_dfs_region dfs_reg) 1806 { 1807 struct wmi_tlv_pdev_set_rd_cmd *cmd; 1808 struct wmi_tlv *tlv; 1809 struct sk_buff *skb; 1810 1811 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 1812 if (!skb) 1813 return ERR_PTR(-ENOMEM); 1814 1815 tlv = (void *)skb->data; 1816 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD); 1817 tlv->len = __cpu_to_le16(sizeof(*cmd)); 1818 cmd = (void *)tlv->value; 1819 cmd->regd = __cpu_to_le32(rd); 1820 cmd->regd_2ghz = __cpu_to_le32(rd2g); 1821 cmd->regd_5ghz = __cpu_to_le32(rd5g); 1822 cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g); 1823 cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g); 1824 1825 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n"); 1826 return skb; 1827 } 1828 1829 static enum wmi_txbf_conf ath10k_wmi_tlv_txbf_conf_scheme(struct ath10k *ar) 1830 { 1831 return WMI_TXBF_CONF_AFTER_ASSOC; 1832 } 1833 1834 static struct sk_buff * 1835 ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id, 1836 u32 param_value) 1837 { 1838 struct wmi_tlv_pdev_set_param_cmd *cmd; 1839 struct wmi_tlv *tlv; 1840 struct sk_buff *skb; 1841 1842 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 1843 if (!skb) 1844 return ERR_PTR(-ENOMEM); 1845 1846 tlv = (void *)skb->data; 1847 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD); 1848 tlv->len = __cpu_to_le16(sizeof(*cmd)); 1849 cmd = (void *)tlv->value; 1850 cmd->param_id = __cpu_to_le32(param_id); 1851 cmd->param_value = __cpu_to_le32(param_value); 1852 1853 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param %d value 0x%x\n", 1854 param_id, param_value); 1855 return skb; 1856 } 1857 1858 static void 1859 #if defined(__linux__) 1860 ath10k_wmi_tlv_put_host_mem_chunks(struct ath10k *ar, void *host_mem_chunks) 1861 #elif defined(__FreeBSD__) 1862 ath10k_wmi_tlv_put_host_mem_chunks(struct ath10k *ar, u8 *host_mem_chunks) 1863 #endif 1864 { 1865 struct host_memory_chunk_tlv *chunk; 1866 struct wmi_tlv *tlv; 1867 dma_addr_t paddr; 1868 int i; 1869 __le16 tlv_len, tlv_tag; 1870 1871 tlv_tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WLAN_HOST_MEMORY_CHUNK); 1872 tlv_len = __cpu_to_le16(sizeof(*chunk)); 1873 for (i = 0; i < ar->wmi.num_mem_chunks; i++) { 1874 #if defined(__linux__) 1875 tlv = host_mem_chunks; 1876 #elif defined(__FreeBSD__) 1877 tlv = (void *)host_mem_chunks; 1878 #endif 1879 tlv->tag = tlv_tag; 1880 tlv->len = tlv_len; 1881 chunk = (void *)tlv->value; 1882 1883 chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); 1884 chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len); 1885 chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); 1886 1887 if (test_bit(WMI_SERVICE_SUPPORT_EXTEND_ADDRESS, 1888 ar->wmi.svc_map)) { 1889 paddr = ar->wmi.mem_chunks[i].paddr; 1890 chunk->ptr_high = __cpu_to_le32(upper_32_bits(paddr)); 1891 } 1892 1893 ath10k_dbg(ar, ATH10K_DBG_WMI, 1894 "wmi-tlv chunk %d len %d, addr 0x%llx, id 0x%x\n", 1895 i, 1896 ar->wmi.mem_chunks[i].len, 1897 (unsigned long long)ar->wmi.mem_chunks[i].paddr, 1898 ar->wmi.mem_chunks[i].req_id); 1899 1900 host_mem_chunks += sizeof(*tlv); 1901 host_mem_chunks += sizeof(*chunk); 1902 } 1903 } 1904 1905 static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) 1906 { 1907 struct sk_buff *skb; 1908 struct wmi_tlv *tlv; 1909 struct wmi_tlv_init_cmd *cmd; 1910 struct wmi_tlv_resource_config *cfg; 1911 void *chunks; 1912 size_t len, chunks_len; 1913 #if defined(__linux__) 1914 void *ptr; 1915 #elif defined(__FreeBSD__) 1916 u8 *ptr; 1917 #endif 1918 1919 chunks_len = ar->wmi.num_mem_chunks * 1920 (sizeof(struct host_memory_chunk_tlv) + sizeof(*tlv)); 1921 len = (sizeof(*tlv) + sizeof(*cmd)) + 1922 (sizeof(*tlv) + sizeof(*cfg)) + 1923 (sizeof(*tlv) + chunks_len); 1924 1925 skb = ath10k_wmi_alloc_skb(ar, len); 1926 if (!skb) 1927 return ERR_PTR(-ENOMEM); 1928 1929 #if defined(__linux__) 1930 ptr = skb->data; 1931 1932 tlv = ptr; 1933 #elif defined(__FreeBSD__) 1934 ptr = (u8 *)skb->data; 1935 tlv = (void *)ptr; 1936 #endif 1937 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD); 1938 tlv->len = __cpu_to_le16(sizeof(*cmd)); 1939 cmd = (void *)tlv->value; 1940 ptr += sizeof(*tlv); 1941 ptr += sizeof(*cmd); 1942 1943 #if defined(__linux__) 1944 tlv = ptr; 1945 #elif defined(__FreeBSD__) 1946 tlv = (void *)ptr; 1947 #endif 1948 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG); 1949 tlv->len = __cpu_to_le16(sizeof(*cfg)); 1950 cfg = (void *)tlv->value; 1951 ptr += sizeof(*tlv); 1952 ptr += sizeof(*cfg); 1953 1954 #if defined(__linux__) 1955 tlv = ptr; 1956 #elif defined(__FreeBSD__) 1957 tlv = (void *)ptr; 1958 #endif 1959 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 1960 tlv->len = __cpu_to_le16(chunks_len); 1961 chunks = (void *)tlv->value; 1962 1963 ptr += sizeof(*tlv); 1964 ptr += chunks_len; 1965 1966 cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0); 1967 cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1); 1968 cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0); 1969 cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1); 1970 cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2); 1971 cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3); 1972 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); 1973 1974 cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 1975 1976 if (ar->hw_params.num_peers) 1977 cfg->num_peers = __cpu_to_le32(ar->hw_params.num_peers); 1978 else 1979 cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS); 1980 cfg->ast_skid_limit = __cpu_to_le32(ar->hw_params.ast_skid_limit); 1981 cfg->num_wds_entries = __cpu_to_le32(ar->hw_params.num_wds_entries); 1982 1983 if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) { 1984 cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 1985 cfg->num_offload_reorder_bufs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 1986 } else { 1987 cfg->num_offload_peers = __cpu_to_le32(0); 1988 cfg->num_offload_reorder_bufs = __cpu_to_le32(0); 1989 } 1990 1991 cfg->num_peer_keys = __cpu_to_le32(2); 1992 if (ar->hw_params.num_peers) 1993 cfg->num_tids = __cpu_to_le32(ar->hw_params.num_peers * 2); 1994 else 1995 cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS); 1996 cfg->tx_chain_mask = __cpu_to_le32(0x7); 1997 cfg->rx_chain_mask = __cpu_to_le32(0x7); 1998 cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64); 1999 cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64); 2000 cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64); 2001 cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28); 2002 cfg->rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode); 2003 cfg->scan_max_pending_reqs = __cpu_to_le32(4); 2004 cfg->bmiss_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 2005 cfg->roam_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); 2006 cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8); 2007 cfg->num_mcast_groups = __cpu_to_le32(0); 2008 cfg->num_mcast_table_elems = __cpu_to_le32(0); 2009 cfg->mcast2ucast_mode = __cpu_to_le32(0); 2010 cfg->tx_dbg_log_size = __cpu_to_le32(0x400); 2011 cfg->dma_burst_size = __cpu_to_le32(0); 2012 cfg->mac_aggr_delim = __cpu_to_le32(0); 2013 cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0); 2014 cfg->vow_config = __cpu_to_le32(0); 2015 cfg->gtk_offload_max_vdev = __cpu_to_le32(2); 2016 cfg->num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx); 2017 cfg->max_frag_entries = __cpu_to_le32(2); 2018 cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS); 2019 cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20); 2020 cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2); 2021 cfg->num_multicast_filter_entries = __cpu_to_le32(5); 2022 cfg->num_wow_filters = __cpu_to_le32(ar->wow.max_num_patterns); 2023 cfg->num_keep_alive_pattern = __cpu_to_le32(6); 2024 cfg->keep_alive_pattern_size = __cpu_to_le32(0); 2025 cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1); 2026 cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1); 2027 cfg->wmi_send_separate = __cpu_to_le32(0); 2028 cfg->num_ocb_vdevs = __cpu_to_le32(0); 2029 cfg->num_ocb_channels = __cpu_to_le32(0); 2030 cfg->num_ocb_schedules = __cpu_to_le32(0); 2031 cfg->host_capab = __cpu_to_le32(WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL); 2032 2033 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) 2034 cfg->host_capab |= __cpu_to_le32(WMI_RSRC_CFG_FLAG_TX_ACK_RSSI); 2035 2036 ath10k_wmi_tlv_put_host_mem_chunks(ar, chunks); 2037 2038 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n"); 2039 return skb; 2040 } 2041 2042 static struct sk_buff * 2043 ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar, 2044 const struct wmi_start_scan_arg *arg) 2045 { 2046 struct wmi_tlv_start_scan_cmd *cmd; 2047 struct wmi_tlv *tlv; 2048 struct sk_buff *skb; 2049 size_t len, chan_len, ssid_len, bssid_len, ie_len; 2050 __le32 *chans; 2051 struct wmi_ssid *ssids; 2052 struct wmi_mac_addr *addrs; 2053 #if defined(__linux__) 2054 void *ptr; 2055 #elif defined(__FreeBSD__) 2056 u8 *ptr; 2057 #endif 2058 int i, ret; 2059 2060 ret = ath10k_wmi_start_scan_verify(arg); 2061 if (ret) 2062 return ERR_PTR(ret); 2063 2064 chan_len = arg->n_channels * sizeof(__le32); 2065 ssid_len = arg->n_ssids * sizeof(struct wmi_ssid); 2066 bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr); 2067 ie_len = roundup(arg->ie_len, 4); 2068 len = (sizeof(*tlv) + sizeof(*cmd)) + 2069 sizeof(*tlv) + chan_len + 2070 sizeof(*tlv) + ssid_len + 2071 sizeof(*tlv) + bssid_len + 2072 sizeof(*tlv) + ie_len; 2073 2074 skb = ath10k_wmi_alloc_skb(ar, len); 2075 if (!skb) 2076 return ERR_PTR(-ENOMEM); 2077 2078 #if defined(__linux__) 2079 ptr = (void *)skb->data; 2080 tlv = ptr; 2081 #elif defined(__FreeBSD__) 2082 ptr = (u8 *)skb->data; 2083 tlv = (void *)ptr; 2084 #endif 2085 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD); 2086 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2087 cmd = (void *)tlv->value; 2088 2089 ath10k_wmi_put_start_scan_common(&cmd->common, arg); 2090 cmd->burst_duration_ms = __cpu_to_le32(arg->burst_duration_ms); 2091 cmd->num_channels = __cpu_to_le32(arg->n_channels); 2092 cmd->num_ssids = __cpu_to_le32(arg->n_ssids); 2093 cmd->num_bssids = __cpu_to_le32(arg->n_bssids); 2094 cmd->ie_len = __cpu_to_le32(arg->ie_len); 2095 cmd->num_probes = __cpu_to_le32(3); 2096 ether_addr_copy(cmd->mac_addr.addr, arg->mac_addr.addr); 2097 ether_addr_copy(cmd->mac_mask.addr, arg->mac_mask.addr); 2098 2099 /* FIXME: There are some scan flag inconsistencies across firmwares, 2100 * e.g. WMI-TLV inverts the logic behind the following flag. 2101 */ 2102 cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ); 2103 2104 ptr += sizeof(*tlv); 2105 ptr += sizeof(*cmd); 2106 2107 #if defined(__linux__) 2108 tlv = ptr; 2109 #elif defined(__FreeBSD__) 2110 tlv = (void *)ptr; 2111 #endif 2112 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 2113 tlv->len = __cpu_to_le16(chan_len); 2114 chans = (void *)tlv->value; 2115 for (i = 0; i < arg->n_channels; i++) 2116 chans[i] = __cpu_to_le32(arg->channels[i]); 2117 2118 ptr += sizeof(*tlv); 2119 ptr += chan_len; 2120 2121 #if defined(__linux__) 2122 tlv = ptr; 2123 #elif defined(__FreeBSD__) 2124 tlv = (void *)ptr; 2125 #endif 2126 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT); 2127 tlv->len = __cpu_to_le16(ssid_len); 2128 ssids = (void *)tlv->value; 2129 for (i = 0; i < arg->n_ssids; i++) { 2130 ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len); 2131 memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len); 2132 } 2133 2134 ptr += sizeof(*tlv); 2135 ptr += ssid_len; 2136 2137 #if defined(__linux__) 2138 tlv = ptr; 2139 #elif defined(__FreeBSD__) 2140 tlv = (void *)ptr; 2141 #endif 2142 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT); 2143 tlv->len = __cpu_to_le16(bssid_len); 2144 addrs = (void *)tlv->value; 2145 for (i = 0; i < arg->n_bssids; i++) 2146 ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid); 2147 2148 ptr += sizeof(*tlv); 2149 ptr += bssid_len; 2150 2151 #if defined(__linux__) 2152 tlv = ptr; 2153 #elif defined(__FreeBSD__) 2154 tlv = (void *)ptr; 2155 #endif 2156 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 2157 tlv->len = __cpu_to_le16(ie_len); 2158 memcpy(tlv->value, arg->ie, arg->ie_len); 2159 2160 #if defined(__linux__) 2161 ptr += sizeof(*tlv); 2162 ptr += ie_len; 2163 #endif 2164 2165 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n"); 2166 return skb; 2167 } 2168 2169 static struct sk_buff * 2170 ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar, 2171 const struct wmi_stop_scan_arg *arg) 2172 { 2173 struct wmi_stop_scan_cmd *cmd; 2174 struct wmi_tlv *tlv; 2175 struct sk_buff *skb; 2176 u32 scan_id; 2177 u32 req_id; 2178 2179 if (arg->req_id > 0xFFF) 2180 return ERR_PTR(-EINVAL); 2181 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) 2182 return ERR_PTR(-EINVAL); 2183 2184 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2185 if (!skb) 2186 return ERR_PTR(-ENOMEM); 2187 2188 scan_id = arg->u.scan_id; 2189 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; 2190 2191 req_id = arg->req_id; 2192 req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; 2193 2194 tlv = (void *)skb->data; 2195 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD); 2196 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2197 cmd = (void *)tlv->value; 2198 cmd->req_type = __cpu_to_le32(arg->req_type); 2199 cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id); 2200 cmd->scan_id = __cpu_to_le32(scan_id); 2201 cmd->scan_req_id = __cpu_to_le32(req_id); 2202 2203 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n"); 2204 return skb; 2205 } 2206 2207 static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar, 2208 enum wmi_vdev_subtype subtype) 2209 { 2210 switch (subtype) { 2211 case WMI_VDEV_SUBTYPE_NONE: 2212 return WMI_TLV_VDEV_SUBTYPE_NONE; 2213 case WMI_VDEV_SUBTYPE_P2P_DEVICE: 2214 return WMI_TLV_VDEV_SUBTYPE_P2P_DEV; 2215 case WMI_VDEV_SUBTYPE_P2P_CLIENT: 2216 return WMI_TLV_VDEV_SUBTYPE_P2P_CLI; 2217 case WMI_VDEV_SUBTYPE_P2P_GO: 2218 return WMI_TLV_VDEV_SUBTYPE_P2P_GO; 2219 case WMI_VDEV_SUBTYPE_PROXY_STA: 2220 return WMI_TLV_VDEV_SUBTYPE_PROXY_STA; 2221 case WMI_VDEV_SUBTYPE_MESH_11S: 2222 return WMI_TLV_VDEV_SUBTYPE_MESH_11S; 2223 case WMI_VDEV_SUBTYPE_MESH_NON_11S: 2224 return -ENOTSUPP; 2225 } 2226 return -ENOTSUPP; 2227 } 2228 2229 static struct sk_buff * 2230 ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, 2231 u32 vdev_id, 2232 enum wmi_vdev_type vdev_type, 2233 enum wmi_vdev_subtype vdev_subtype, 2234 const u8 mac_addr[ETH_ALEN]) 2235 { 2236 struct wmi_vdev_create_cmd *cmd; 2237 struct wmi_tlv *tlv; 2238 struct sk_buff *skb; 2239 2240 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2241 if (!skb) 2242 return ERR_PTR(-ENOMEM); 2243 2244 tlv = (void *)skb->data; 2245 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD); 2246 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2247 cmd = (void *)tlv->value; 2248 cmd->vdev_id = __cpu_to_le32(vdev_id); 2249 cmd->vdev_type = __cpu_to_le32(vdev_type); 2250 cmd->vdev_subtype = __cpu_to_le32(vdev_subtype); 2251 ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr); 2252 2253 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n"); 2254 return skb; 2255 } 2256 2257 static struct sk_buff * 2258 ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id) 2259 { 2260 struct wmi_vdev_delete_cmd *cmd; 2261 struct wmi_tlv *tlv; 2262 struct sk_buff *skb; 2263 2264 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2265 if (!skb) 2266 return ERR_PTR(-ENOMEM); 2267 2268 tlv = (void *)skb->data; 2269 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD); 2270 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2271 cmd = (void *)tlv->value; 2272 cmd->vdev_id = __cpu_to_le32(vdev_id); 2273 2274 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n"); 2275 return skb; 2276 } 2277 2278 static struct sk_buff * 2279 ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar, 2280 const struct wmi_vdev_start_request_arg *arg, 2281 bool restart) 2282 { 2283 struct wmi_tlv_vdev_start_cmd *cmd; 2284 struct wmi_channel *ch; 2285 struct wmi_tlv *tlv; 2286 struct sk_buff *skb; 2287 size_t len; 2288 #if defined(__linux__) 2289 void *ptr; 2290 #elif defined(__FreeBSD__) 2291 u8 *ptr; 2292 #endif 2293 u32 flags = 0; 2294 2295 if (WARN_ON(arg->hidden_ssid && !arg->ssid)) 2296 return ERR_PTR(-EINVAL); 2297 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 2298 return ERR_PTR(-EINVAL); 2299 2300 len = (sizeof(*tlv) + sizeof(*cmd)) + 2301 (sizeof(*tlv) + sizeof(*ch)) + 2302 (sizeof(*tlv) + 0); 2303 skb = ath10k_wmi_alloc_skb(ar, len); 2304 if (!skb) 2305 return ERR_PTR(-ENOMEM); 2306 2307 if (arg->hidden_ssid) 2308 flags |= WMI_VDEV_START_HIDDEN_SSID; 2309 if (arg->pmf_enabled) 2310 flags |= WMI_VDEV_START_PMF_ENABLED; 2311 2312 #if defined(__linux__) 2313 ptr = (void *)skb->data; 2314 2315 tlv = ptr; 2316 #elif defined(__FreeBSD__) 2317 ptr = (u8 *)skb->data; 2318 tlv = (void *)ptr; 2319 #endif 2320 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD); 2321 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2322 cmd = (void *)tlv->value; 2323 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 2324 cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval); 2325 cmd->dtim_period = __cpu_to_le32(arg->dtim_period); 2326 cmd->flags = __cpu_to_le32(flags); 2327 cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate); 2328 cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power); 2329 cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack); 2330 2331 if (arg->ssid) { 2332 cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len); 2333 memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); 2334 } 2335 2336 ptr += sizeof(*tlv); 2337 ptr += sizeof(*cmd); 2338 2339 #if defined(__linux__) 2340 tlv = ptr; 2341 #elif defined(__FreeBSD__) 2342 tlv = (void *)ptr; 2343 #endif 2344 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); 2345 tlv->len = __cpu_to_le16(sizeof(*ch)); 2346 ch = (void *)tlv->value; 2347 ath10k_wmi_put_wmi_channel(ar, ch, &arg->channel); 2348 2349 ptr += sizeof(*tlv); 2350 ptr += sizeof(*ch); 2351 2352 #if defined(__linux__) 2353 tlv = ptr; 2354 #elif defined(__FreeBSD__) 2355 tlv = (void *)ptr; 2356 #endif 2357 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 2358 tlv->len = 0; 2359 2360 /* Note: This is a nested TLV containing: 2361 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv].. 2362 */ 2363 2364 #if defined(__linux__) 2365 ptr += sizeof(*tlv); 2366 ptr += 0; 2367 #endif 2368 2369 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n"); 2370 return skb; 2371 } 2372 2373 static struct sk_buff * 2374 ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id) 2375 { 2376 struct wmi_vdev_stop_cmd *cmd; 2377 struct wmi_tlv *tlv; 2378 struct sk_buff *skb; 2379 2380 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2381 if (!skb) 2382 return ERR_PTR(-ENOMEM); 2383 2384 tlv = (void *)skb->data; 2385 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD); 2386 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2387 cmd = (void *)tlv->value; 2388 cmd->vdev_id = __cpu_to_le32(vdev_id); 2389 2390 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n"); 2391 return skb; 2392 } 2393 2394 static struct sk_buff * 2395 ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, 2396 const u8 *bssid) 2397 2398 { 2399 struct wmi_vdev_up_cmd *cmd; 2400 struct wmi_tlv *tlv; 2401 struct sk_buff *skb; 2402 2403 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2404 if (!skb) 2405 return ERR_PTR(-ENOMEM); 2406 2407 tlv = (void *)skb->data; 2408 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD); 2409 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2410 cmd = (void *)tlv->value; 2411 cmd->vdev_id = __cpu_to_le32(vdev_id); 2412 cmd->vdev_assoc_id = __cpu_to_le32(aid); 2413 ether_addr_copy(cmd->vdev_bssid.addr, bssid); 2414 2415 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n"); 2416 return skb; 2417 } 2418 2419 static struct sk_buff * 2420 ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id) 2421 { 2422 struct wmi_vdev_down_cmd *cmd; 2423 struct wmi_tlv *tlv; 2424 struct sk_buff *skb; 2425 2426 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2427 if (!skb) 2428 return ERR_PTR(-ENOMEM); 2429 2430 tlv = (void *)skb->data; 2431 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD); 2432 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2433 cmd = (void *)tlv->value; 2434 cmd->vdev_id = __cpu_to_le32(vdev_id); 2435 2436 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n"); 2437 return skb; 2438 } 2439 2440 static struct sk_buff * 2441 ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id, 2442 u32 param_id, u32 param_value) 2443 { 2444 struct wmi_vdev_set_param_cmd *cmd; 2445 struct wmi_tlv *tlv; 2446 struct sk_buff *skb; 2447 2448 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2449 if (!skb) 2450 return ERR_PTR(-ENOMEM); 2451 2452 tlv = (void *)skb->data; 2453 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD); 2454 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2455 cmd = (void *)tlv->value; 2456 cmd->vdev_id = __cpu_to_le32(vdev_id); 2457 cmd->param_id = __cpu_to_le32(param_id); 2458 cmd->param_value = __cpu_to_le32(param_value); 2459 2460 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev %d set param %d value 0x%x\n", 2461 vdev_id, param_id, param_value); 2462 return skb; 2463 } 2464 2465 static struct sk_buff * 2466 ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar, 2467 const struct wmi_vdev_install_key_arg *arg) 2468 { 2469 struct wmi_vdev_install_key_cmd *cmd; 2470 struct wmi_tlv *tlv; 2471 struct sk_buff *skb; 2472 size_t len; 2473 #if defined(__linux__) 2474 void *ptr; 2475 #elif defined(__FreeBSD__) 2476 u8 *ptr; 2477 #endif 2478 2479 if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] && 2480 arg->key_data) 2481 return ERR_PTR(-EINVAL); 2482 if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] && 2483 !arg->key_data) 2484 return ERR_PTR(-EINVAL); 2485 2486 len = sizeof(*tlv) + sizeof(*cmd) + 2487 sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32)); 2488 skb = ath10k_wmi_alloc_skb(ar, len); 2489 if (!skb) 2490 return ERR_PTR(-ENOMEM); 2491 2492 #if defined(__linux__) 2493 ptr = (void *)skb->data; 2494 tlv = ptr; 2495 #elif defined(__FreeBSD__) 2496 ptr = (u8 *)skb->data; 2497 tlv = (void *)ptr; 2498 #endif 2499 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD); 2500 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2501 cmd = (void *)tlv->value; 2502 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 2503 cmd->key_idx = __cpu_to_le32(arg->key_idx); 2504 cmd->key_flags = __cpu_to_le32(arg->key_flags); 2505 cmd->key_cipher = __cpu_to_le32(arg->key_cipher); 2506 cmd->key_len = __cpu_to_le32(arg->key_len); 2507 cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len); 2508 cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); 2509 2510 if (arg->macaddr) 2511 ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); 2512 2513 ptr += sizeof(*tlv); 2514 ptr += sizeof(*cmd); 2515 2516 #if defined(__linux__) 2517 tlv = ptr; 2518 #elif defined(__FreeBSD__) 2519 tlv = (void *)ptr; 2520 #endif 2521 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 2522 tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32))); 2523 if (arg->key_data) 2524 memcpy(tlv->value, arg->key_data, arg->key_len); 2525 2526 #if defined(__linux__) 2527 ptr += sizeof(*tlv); 2528 ptr += roundup(arg->key_len, sizeof(__le32)); 2529 #endif 2530 2531 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n"); 2532 return skb; 2533 } 2534 2535 static void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr, 2536 const struct wmi_sta_uapsd_auto_trig_arg *arg) 2537 { 2538 struct wmi_sta_uapsd_auto_trig_param *ac; 2539 struct wmi_tlv *tlv; 2540 2541 tlv = ptr; 2542 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM); 2543 tlv->len = __cpu_to_le16(sizeof(*ac)); 2544 ac = (void *)tlv->value; 2545 2546 ac->wmm_ac = __cpu_to_le32(arg->wmm_ac); 2547 ac->user_priority = __cpu_to_le32(arg->user_priority); 2548 ac->service_interval = __cpu_to_le32(arg->service_interval); 2549 ac->suspend_interval = __cpu_to_le32(arg->suspend_interval); 2550 ac->delay_interval = __cpu_to_le32(arg->delay_interval); 2551 2552 ath10k_dbg(ar, ATH10K_DBG_WMI, 2553 "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n", 2554 ac->wmm_ac, ac->user_priority, ac->service_interval, 2555 ac->suspend_interval, ac->delay_interval); 2556 2557 #if defined(__linux__) 2558 return ptr + sizeof(*tlv) + sizeof(*ac); 2559 #elif defined(__FreeBSD__) 2560 return (u8 *)ptr + sizeof(*tlv) + sizeof(*ac); 2561 #endif 2562 } 2563 2564 static struct sk_buff * 2565 ath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id, 2566 const u8 peer_addr[ETH_ALEN], 2567 const struct wmi_sta_uapsd_auto_trig_arg *args, 2568 u32 num_ac) 2569 { 2570 struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 2571 struct wmi_sta_uapsd_auto_trig_param *ac; 2572 struct wmi_tlv *tlv; 2573 struct sk_buff *skb; 2574 size_t len; 2575 size_t ac_tlv_len; 2576 #if defined(__linux__) 2577 void *ptr; 2578 #elif defined(__FreeBSD__) 2579 u8 *ptr; 2580 #endif 2581 int i; 2582 2583 ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac)); 2584 len = sizeof(*tlv) + sizeof(*cmd) + 2585 sizeof(*tlv) + ac_tlv_len; 2586 skb = ath10k_wmi_alloc_skb(ar, len); 2587 if (!skb) 2588 return ERR_PTR(-ENOMEM); 2589 2590 #if defined(__linux__) 2591 ptr = (void *)skb->data; 2592 tlv = ptr; 2593 #elif defined(__FreeBSD__) 2594 ptr = (u8 *)skb->data; 2595 tlv = (void *)ptr; 2596 #endif 2597 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD); 2598 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2599 cmd = (void *)tlv->value; 2600 cmd->vdev_id = __cpu_to_le32(vdev_id); 2601 cmd->num_ac = __cpu_to_le32(num_ac); 2602 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 2603 2604 ptr += sizeof(*tlv); 2605 ptr += sizeof(*cmd); 2606 2607 #if defined(__linux__) 2608 tlv = ptr; 2609 #elif defined(__FreeBSD__) 2610 tlv = (void *)ptr; 2611 #endif 2612 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 2613 tlv->len = __cpu_to_le16(ac_tlv_len); 2614 ac = (void *)tlv->value; 2615 2616 ptr += sizeof(*tlv); 2617 for (i = 0; i < num_ac; i++) 2618 ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]); 2619 2620 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n"); 2621 return skb; 2622 } 2623 2624 static void *ath10k_wmi_tlv_put_wmm(void *ptr, 2625 const struct wmi_wmm_params_arg *arg) 2626 { 2627 struct wmi_wmm_params *wmm; 2628 struct wmi_tlv *tlv; 2629 2630 tlv = ptr; 2631 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS); 2632 tlv->len = __cpu_to_le16(sizeof(*wmm)); 2633 wmm = (void *)tlv->value; 2634 ath10k_wmi_set_wmm_param(wmm, arg); 2635 2636 #if defined(__linux__) 2637 return ptr + sizeof(*tlv) + sizeof(*wmm); 2638 #elif defined(__FreeBSD__) 2639 return (u8 *)ptr + sizeof(*tlv) + sizeof(*wmm); 2640 #endif 2641 } 2642 2643 static struct sk_buff * 2644 ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, 2645 const struct wmi_wmm_params_all_arg *arg) 2646 { 2647 struct wmi_tlv_vdev_set_wmm_cmd *cmd; 2648 struct wmi_tlv *tlv; 2649 struct sk_buff *skb; 2650 size_t len; 2651 void *ptr; 2652 2653 len = sizeof(*tlv) + sizeof(*cmd); 2654 skb = ath10k_wmi_alloc_skb(ar, len); 2655 if (!skb) 2656 return ERR_PTR(-ENOMEM); 2657 2658 ptr = (void *)skb->data; 2659 tlv = ptr; 2660 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD); 2661 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2662 cmd = (void *)tlv->value; 2663 cmd->vdev_id = __cpu_to_le32(vdev_id); 2664 2665 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be); 2666 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk); 2667 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi); 2668 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo); 2669 2670 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); 2671 return skb; 2672 } 2673 2674 static struct sk_buff * 2675 ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar, 2676 const struct wmi_sta_keepalive_arg *arg) 2677 { 2678 struct wmi_tlv_sta_keepalive_cmd *cmd; 2679 struct wmi_sta_keepalive_arp_resp *arp; 2680 struct sk_buff *skb; 2681 struct wmi_tlv *tlv; 2682 #if defined(__linux__) 2683 void *ptr; 2684 #elif defined(__FreeBSD__) 2685 u8 *ptr; 2686 #endif 2687 size_t len; 2688 2689 len = sizeof(*tlv) + sizeof(*cmd) + 2690 sizeof(*tlv) + sizeof(*arp); 2691 skb = ath10k_wmi_alloc_skb(ar, len); 2692 if (!skb) 2693 return ERR_PTR(-ENOMEM); 2694 2695 #if defined(__linux__) 2696 ptr = (void *)skb->data; 2697 tlv = ptr; 2698 #elif defined(__FreeBSD__) 2699 ptr = (u8 *)skb->data; 2700 tlv = (void *)ptr; 2701 #endif 2702 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD); 2703 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2704 cmd = (void *)tlv->value; 2705 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 2706 cmd->enabled = __cpu_to_le32(arg->enabled); 2707 cmd->method = __cpu_to_le32(arg->method); 2708 cmd->interval = __cpu_to_le32(arg->interval); 2709 2710 ptr += sizeof(*tlv); 2711 ptr += sizeof(*cmd); 2712 2713 #if defined(__linux__) 2714 tlv = ptr; 2715 #elif defined(__FreeBSD__) 2716 tlv = (void *)ptr; 2717 #endif 2718 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE); 2719 tlv->len = __cpu_to_le16(sizeof(*arp)); 2720 arp = (void *)tlv->value; 2721 2722 arp->src_ip4_addr = arg->src_ip4_addr; 2723 arp->dest_ip4_addr = arg->dest_ip4_addr; 2724 ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr); 2725 2726 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d interval %d\n", 2727 arg->vdev_id, arg->enabled, arg->method, arg->interval); 2728 return skb; 2729 } 2730 2731 static struct sk_buff * 2732 ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, 2733 const u8 peer_addr[ETH_ALEN], 2734 enum wmi_peer_type peer_type) 2735 { 2736 struct wmi_tlv_peer_create_cmd *cmd; 2737 struct wmi_tlv *tlv; 2738 struct sk_buff *skb; 2739 2740 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2741 if (!skb) 2742 return ERR_PTR(-ENOMEM); 2743 2744 tlv = (void *)skb->data; 2745 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD); 2746 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2747 cmd = (void *)tlv->value; 2748 cmd->vdev_id = __cpu_to_le32(vdev_id); 2749 cmd->peer_type = __cpu_to_le32(peer_type); 2750 ether_addr_copy(cmd->peer_addr.addr, peer_addr); 2751 2752 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n"); 2753 return skb; 2754 } 2755 2756 static struct sk_buff * 2757 ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id, 2758 const u8 peer_addr[ETH_ALEN]) 2759 { 2760 struct wmi_peer_delete_cmd *cmd; 2761 struct wmi_tlv *tlv; 2762 struct sk_buff *skb; 2763 2764 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2765 if (!skb) 2766 return ERR_PTR(-ENOMEM); 2767 2768 tlv = (void *)skb->data; 2769 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD); 2770 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2771 cmd = (void *)tlv->value; 2772 cmd->vdev_id = __cpu_to_le32(vdev_id); 2773 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 2774 2775 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n"); 2776 return skb; 2777 } 2778 2779 static struct sk_buff * 2780 ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id, 2781 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) 2782 { 2783 struct wmi_peer_flush_tids_cmd *cmd; 2784 struct wmi_tlv *tlv; 2785 struct sk_buff *skb; 2786 2787 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2788 if (!skb) 2789 return ERR_PTR(-ENOMEM); 2790 2791 tlv = (void *)skb->data; 2792 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD); 2793 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2794 cmd = (void *)tlv->value; 2795 cmd->vdev_id = __cpu_to_le32(vdev_id); 2796 cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); 2797 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 2798 2799 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n"); 2800 return skb; 2801 } 2802 2803 static struct sk_buff * 2804 ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id, 2805 const u8 *peer_addr, 2806 enum wmi_peer_param param_id, 2807 u32 param_value) 2808 { 2809 struct wmi_peer_set_param_cmd *cmd; 2810 struct wmi_tlv *tlv; 2811 struct sk_buff *skb; 2812 2813 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2814 if (!skb) 2815 return ERR_PTR(-ENOMEM); 2816 2817 tlv = (void *)skb->data; 2818 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD); 2819 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2820 cmd = (void *)tlv->value; 2821 cmd->vdev_id = __cpu_to_le32(vdev_id); 2822 cmd->param_id = __cpu_to_le32(param_id); 2823 cmd->param_value = __cpu_to_le32(param_value); 2824 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 2825 2826 ath10k_dbg(ar, ATH10K_DBG_WMI, 2827 "wmi tlv vdev %d peer %pM set param %d value 0x%x\n", 2828 vdev_id, peer_addr, param_id, param_value); 2829 return skb; 2830 } 2831 2832 static struct sk_buff * 2833 ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar, 2834 const struct wmi_peer_assoc_complete_arg *arg) 2835 { 2836 struct wmi_tlv_peer_assoc_cmd *cmd; 2837 struct wmi_vht_rate_set *vht_rate; 2838 struct wmi_tlv *tlv; 2839 struct sk_buff *skb; 2840 size_t len, legacy_rate_len, ht_rate_len; 2841 #if defined(__linux__) 2842 void *ptr; 2843 #elif defined(__FreeBSD__) 2844 u8 *ptr; 2845 #endif 2846 2847 if (arg->peer_mpdu_density > 16) 2848 return ERR_PTR(-EINVAL); 2849 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) 2850 return ERR_PTR(-EINVAL); 2851 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) 2852 return ERR_PTR(-EINVAL); 2853 2854 legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates, 2855 sizeof(__le32)); 2856 ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32)); 2857 len = (sizeof(*tlv) + sizeof(*cmd)) + 2858 (sizeof(*tlv) + legacy_rate_len) + 2859 (sizeof(*tlv) + ht_rate_len) + 2860 (sizeof(*tlv) + sizeof(*vht_rate)); 2861 skb = ath10k_wmi_alloc_skb(ar, len); 2862 if (!skb) 2863 return ERR_PTR(-ENOMEM); 2864 2865 #if defined(__linux__) 2866 ptr = (void *)skb->data; 2867 tlv = ptr; 2868 #elif defined(__FreeBSD__) 2869 ptr = (u8 *)skb->data; 2870 tlv = (void *)ptr; 2871 #endif 2872 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD); 2873 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2874 cmd = (void *)tlv->value; 2875 2876 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 2877 cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); 2878 cmd->assoc_id = __cpu_to_le32(arg->peer_aid); 2879 cmd->flags = __cpu_to_le32(arg->peer_flags); 2880 cmd->caps = __cpu_to_le32(arg->peer_caps); 2881 cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval); 2882 cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps); 2883 cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu); 2884 cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density); 2885 cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps); 2886 cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams); 2887 cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps); 2888 cmd->phy_mode = __cpu_to_le32(arg->peer_phymode); 2889 cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates); 2890 cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates); 2891 ether_addr_copy(cmd->mac_addr.addr, arg->addr); 2892 2893 ptr += sizeof(*tlv); 2894 ptr += sizeof(*cmd); 2895 2896 #if defined(__linux__) 2897 tlv = ptr; 2898 #elif defined(__FreeBSD__) 2899 tlv = (void *)ptr; 2900 #endif 2901 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 2902 tlv->len = __cpu_to_le16(legacy_rate_len); 2903 memcpy(tlv->value, arg->peer_legacy_rates.rates, 2904 arg->peer_legacy_rates.num_rates); 2905 2906 ptr += sizeof(*tlv); 2907 ptr += legacy_rate_len; 2908 2909 #if defined(__linux__) 2910 tlv = ptr; 2911 #elif defined(__FreeBSD__) 2912 tlv = (void *)ptr; 2913 #endif 2914 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 2915 tlv->len = __cpu_to_le16(ht_rate_len); 2916 memcpy(tlv->value, arg->peer_ht_rates.rates, 2917 arg->peer_ht_rates.num_rates); 2918 2919 ptr += sizeof(*tlv); 2920 ptr += ht_rate_len; 2921 2922 #if defined(__linux__) 2923 tlv = ptr; 2924 #elif defined(__FreeBSD__) 2925 tlv = (void *)ptr; 2926 #endif 2927 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET); 2928 tlv->len = __cpu_to_le16(sizeof(*vht_rate)); 2929 vht_rate = (void *)tlv->value; 2930 2931 vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate); 2932 vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set); 2933 vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); 2934 vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); 2935 2936 #if defined(__linux__) 2937 ptr += sizeof(*tlv); 2938 ptr += sizeof(*vht_rate); 2939 #endif 2940 2941 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n"); 2942 return skb; 2943 } 2944 2945 static struct sk_buff * 2946 ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, 2947 enum wmi_sta_ps_mode psmode) 2948 { 2949 struct wmi_sta_powersave_mode_cmd *cmd; 2950 struct wmi_tlv *tlv; 2951 struct sk_buff *skb; 2952 2953 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2954 if (!skb) 2955 return ERR_PTR(-ENOMEM); 2956 2957 tlv = (void *)skb->data; 2958 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD); 2959 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2960 cmd = (void *)tlv->value; 2961 cmd->vdev_id = __cpu_to_le32(vdev_id); 2962 cmd->sta_ps_mode = __cpu_to_le32(psmode); 2963 2964 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n"); 2965 return skb; 2966 } 2967 2968 static struct sk_buff * 2969 ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id, 2970 enum wmi_sta_powersave_param param_id, 2971 u32 param_value) 2972 { 2973 struct wmi_sta_powersave_param_cmd *cmd; 2974 struct wmi_tlv *tlv; 2975 struct sk_buff *skb; 2976 2977 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 2978 if (!skb) 2979 return ERR_PTR(-ENOMEM); 2980 2981 tlv = (void *)skb->data; 2982 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD); 2983 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2984 cmd = (void *)tlv->value; 2985 cmd->vdev_id = __cpu_to_le32(vdev_id); 2986 cmd->param_id = __cpu_to_le32(param_id); 2987 cmd->param_value = __cpu_to_le32(param_value); 2988 2989 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n"); 2990 return skb; 2991 } 2992 2993 static struct sk_buff * 2994 ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac, 2995 enum wmi_ap_ps_peer_param param_id, u32 value) 2996 { 2997 struct wmi_ap_ps_peer_cmd *cmd; 2998 struct wmi_tlv *tlv; 2999 struct sk_buff *skb; 3000 3001 if (!mac) 3002 return ERR_PTR(-EINVAL); 3003 3004 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3005 if (!skb) 3006 return ERR_PTR(-ENOMEM); 3007 3008 tlv = (void *)skb->data; 3009 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD); 3010 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3011 cmd = (void *)tlv->value; 3012 cmd->vdev_id = __cpu_to_le32(vdev_id); 3013 cmd->param_id = __cpu_to_le32(param_id); 3014 cmd->param_value = __cpu_to_le32(value); 3015 ether_addr_copy(cmd->peer_macaddr.addr, mac); 3016 3017 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n"); 3018 return skb; 3019 } 3020 3021 static struct sk_buff * 3022 ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar, 3023 const struct wmi_scan_chan_list_arg *arg) 3024 { 3025 struct wmi_tlv_scan_chan_list_cmd *cmd; 3026 struct wmi_channel *ci; 3027 struct wmi_channel_arg *ch; 3028 struct wmi_tlv *tlv; 3029 struct sk_buff *skb; 3030 size_t chans_len, len; 3031 int i; 3032 #if defined(__linux__) 3033 void *ptr, *chans; 3034 #elif defined(__FreeBSD__) 3035 u8 *ptr, *chans; 3036 #endif 3037 3038 chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci)); 3039 len = (sizeof(*tlv) + sizeof(*cmd)) + 3040 (sizeof(*tlv) + chans_len); 3041 3042 skb = ath10k_wmi_alloc_skb(ar, len); 3043 if (!skb) 3044 return ERR_PTR(-ENOMEM); 3045 3046 #if defined(__linux__) 3047 ptr = (void *)skb->data; 3048 tlv = ptr; 3049 #elif defined(__FreeBSD__) 3050 ptr = (u8 *)skb->data; 3051 tlv = (void *)ptr; 3052 #endif 3053 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD); 3054 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3055 cmd = (void *)tlv->value; 3056 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); 3057 3058 ptr += sizeof(*tlv); 3059 ptr += sizeof(*cmd); 3060 3061 #if defined(__linux__) 3062 tlv = ptr; 3063 #elif defined(__FreeBSD__) 3064 tlv = (void *)ptr; 3065 #endif 3066 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 3067 tlv->len = __cpu_to_le16(chans_len); 3068 chans = (void *)tlv->value; 3069 3070 for (i = 0; i < arg->n_channels; i++) { 3071 ch = &arg->channels[i]; 3072 3073 #if defined(__linux__) 3074 tlv = chans; 3075 #elif defined(__FreeBSD__) 3076 tlv = (void *)chans; 3077 #endif 3078 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); 3079 tlv->len = __cpu_to_le16(sizeof(*ci)); 3080 ci = (void *)tlv->value; 3081 3082 ath10k_wmi_put_wmi_channel(ar, ci, ch); 3083 3084 chans += sizeof(*tlv); 3085 chans += sizeof(*ci); 3086 } 3087 3088 #if defined(__linux__) 3089 ptr += sizeof(*tlv); 3090 ptr += chans_len; 3091 #endif 3092 3093 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n"); 3094 return skb; 3095 } 3096 3097 static struct sk_buff * 3098 ath10k_wmi_tlv_op_gen_scan_prob_req_oui(struct ath10k *ar, u32 prob_req_oui) 3099 { 3100 struct wmi_scan_prob_req_oui_cmd *cmd; 3101 struct wmi_tlv *tlv; 3102 struct sk_buff *skb; 3103 3104 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3105 if (!skb) 3106 return ERR_PTR(-ENOMEM); 3107 3108 tlv = (void *)skb->data; 3109 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD); 3110 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3111 cmd = (void *)tlv->value; 3112 cmd->prob_req_oui = __cpu_to_le32(prob_req_oui); 3113 3114 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan prob req oui\n"); 3115 return skb; 3116 } 3117 3118 static struct sk_buff * 3119 ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id, 3120 const void *bcn, size_t bcn_len, 3121 u32 bcn_paddr, bool dtim_zero, 3122 bool deliver_cab) 3123 3124 { 3125 struct wmi_bcn_tx_ref_cmd *cmd; 3126 struct wmi_tlv *tlv; 3127 struct sk_buff *skb; 3128 #if defined(__linux__) 3129 struct ieee80211_hdr *hdr; 3130 #elif defined(__FreeBSD__) 3131 const struct ieee80211_hdr *hdr; 3132 #endif 3133 u16 fc; 3134 3135 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3136 if (!skb) 3137 return ERR_PTR(-ENOMEM); 3138 3139 #if defined(__linux__) 3140 hdr = (struct ieee80211_hdr *)bcn; 3141 #elif defined(__FreeBSD__) 3142 hdr = (const struct ieee80211_hdr *)bcn; 3143 #endif 3144 fc = le16_to_cpu(hdr->frame_control); 3145 3146 tlv = (void *)skb->data; 3147 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD); 3148 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3149 cmd = (void *)tlv->value; 3150 cmd->vdev_id = __cpu_to_le32(vdev_id); 3151 cmd->data_len = __cpu_to_le32(bcn_len); 3152 cmd->data_ptr = __cpu_to_le32(bcn_paddr); 3153 cmd->msdu_id = 0; 3154 cmd->frame_control = __cpu_to_le32(fc); 3155 cmd->flags = 0; 3156 3157 if (dtim_zero) 3158 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); 3159 3160 if (deliver_cab) 3161 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); 3162 3163 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n"); 3164 return skb; 3165 } 3166 3167 static struct sk_buff * 3168 ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar, 3169 const struct wmi_wmm_params_all_arg *arg) 3170 { 3171 struct wmi_tlv_pdev_set_wmm_cmd *cmd; 3172 struct wmi_wmm_params *wmm; 3173 struct wmi_tlv *tlv; 3174 struct sk_buff *skb; 3175 size_t len; 3176 #if defined(__linux__) 3177 void *ptr; 3178 #elif defined(__FreeBSD__) 3179 u8 *ptr; 3180 #endif 3181 3182 len = (sizeof(*tlv) + sizeof(*cmd)) + 3183 (4 * (sizeof(*tlv) + sizeof(*wmm))); 3184 skb = ath10k_wmi_alloc_skb(ar, len); 3185 if (!skb) 3186 return ERR_PTR(-ENOMEM); 3187 3188 #if defined(__linux__) 3189 ptr = (void *)skb->data; 3190 3191 tlv = ptr; 3192 #elif defined(__FreeBSD__) 3193 ptr = (u8 *)skb->data; 3194 tlv = (void *)ptr; 3195 #endif 3196 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD); 3197 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3198 cmd = (void *)tlv->value; 3199 3200 /* nothing to set here */ 3201 3202 ptr += sizeof(*tlv); 3203 ptr += sizeof(*cmd); 3204 3205 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); 3206 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk); 3207 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi); 3208 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo); 3209 3210 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n"); 3211 return skb; 3212 } 3213 3214 static struct sk_buff * 3215 ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask) 3216 { 3217 struct wmi_request_stats_cmd *cmd; 3218 struct wmi_tlv *tlv; 3219 struct sk_buff *skb; 3220 3221 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3222 if (!skb) 3223 return ERR_PTR(-ENOMEM); 3224 3225 tlv = (void *)skb->data; 3226 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD); 3227 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3228 cmd = (void *)tlv->value; 3229 cmd->stats_id = __cpu_to_le32(stats_mask); 3230 3231 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n"); 3232 return skb; 3233 } 3234 3235 static struct sk_buff * 3236 ath10k_wmi_tlv_op_gen_request_peer_stats_info(struct ath10k *ar, 3237 u32 vdev_id, 3238 enum wmi_peer_stats_info_request_type type, 3239 u8 *addr, 3240 u32 reset) 3241 { 3242 struct wmi_tlv_request_peer_stats_info *cmd; 3243 struct wmi_tlv *tlv; 3244 struct sk_buff *skb; 3245 3246 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3247 if (!skb) 3248 return ERR_PTR(-ENOMEM); 3249 3250 tlv = (void *)skb->data; 3251 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_PEER_STATS_INFO_CMD); 3252 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3253 cmd = (void *)tlv->value; 3254 cmd->vdev_id = __cpu_to_le32(vdev_id); 3255 cmd->request_type = __cpu_to_le32(type); 3256 3257 if (type == WMI_REQUEST_ONE_PEER_STATS_INFO) 3258 ether_addr_copy(cmd->peer_macaddr.addr, addr); 3259 3260 cmd->reset_after_request = __cpu_to_le32(reset); 3261 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request peer stats info\n"); 3262 return skb; 3263 } 3264 3265 static int 3266 ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar, 3267 struct sk_buff *msdu) 3268 { 3269 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); 3270 struct ath10k_wmi *wmi = &ar->wmi; 3271 3272 idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id); 3273 3274 return 0; 3275 } 3276 3277 static int 3278 ath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb, 3279 dma_addr_t paddr) 3280 { 3281 struct ath10k_wmi *wmi = &ar->wmi; 3282 struct ath10k_mgmt_tx_pkt_addr *pkt_addr; 3283 int ret; 3284 3285 pkt_addr = kmalloc(sizeof(*pkt_addr), GFP_ATOMIC); 3286 if (!pkt_addr) 3287 return -ENOMEM; 3288 3289 pkt_addr->vaddr = skb; 3290 pkt_addr->paddr = paddr; 3291 3292 spin_lock_bh(&ar->data_lock); 3293 ret = idr_alloc(&wmi->mgmt_pending_tx, pkt_addr, 0, 3294 wmi->mgmt_max_num_pending_tx, GFP_ATOMIC); 3295 spin_unlock_bh(&ar->data_lock); 3296 3297 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx alloc msdu_id ret %d\n", ret); 3298 return ret; 3299 } 3300 3301 static struct sk_buff * 3302 ath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, 3303 dma_addr_t paddr) 3304 { 3305 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); 3306 struct wmi_tlv_mgmt_tx_cmd *cmd; 3307 struct ieee80211_hdr *hdr; 3308 struct ath10k_vif *arvif; 3309 u32 buf_len = msdu->len; 3310 struct wmi_tlv *tlv; 3311 struct sk_buff *skb; 3312 int len, desc_id; 3313 u32 vdev_id; 3314 #if defined(__linux__) 3315 void *ptr; 3316 #elif defined(__FreeBSD__) 3317 u8 *ptr; 3318 #endif 3319 3320 if (!cb->vif) 3321 return ERR_PTR(-EINVAL); 3322 3323 hdr = (struct ieee80211_hdr *)msdu->data; 3324 arvif = (void *)cb->vif->drv_priv; 3325 vdev_id = arvif->vdev_id; 3326 3327 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control) && 3328 (!(ieee80211_is_nullfunc(hdr->frame_control) || 3329 ieee80211_is_qos_nullfunc(hdr->frame_control))))) 3330 return ERR_PTR(-EINVAL); 3331 3332 len = sizeof(*cmd) + 2 * sizeof(*tlv); 3333 3334 if ((ieee80211_is_action(hdr->frame_control) || 3335 ieee80211_is_deauth(hdr->frame_control) || 3336 ieee80211_is_disassoc(hdr->frame_control)) && 3337 ieee80211_has_protected(hdr->frame_control)) { 3338 skb_put(msdu, IEEE80211_CCMP_MIC_LEN); 3339 buf_len += IEEE80211_CCMP_MIC_LEN; 3340 } 3341 3342 buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN); 3343 buf_len = round_up(buf_len, 4); 3344 3345 len += buf_len; 3346 len = round_up(len, 4); 3347 skb = ath10k_wmi_alloc_skb(ar, len); 3348 if (!skb) 3349 return ERR_PTR(-ENOMEM); 3350 3351 desc_id = ath10k_wmi_mgmt_tx_alloc_msdu_id(ar, msdu, paddr); 3352 if (desc_id < 0) 3353 goto err_free_skb; 3354 3355 cb->msdu_id = desc_id; 3356 3357 #if defined(__linux__) 3358 ptr = (void *)skb->data; 3359 tlv = ptr; 3360 #elif defined(__FreeBSD__) 3361 ptr = (u8 *)skb->data; 3362 tlv = (void *)ptr; 3363 #endif 3364 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD); 3365 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3366 cmd = (void *)tlv->value; 3367 cmd->vdev_id = __cpu_to_le32(vdev_id); 3368 cmd->desc_id = __cpu_to_le32(desc_id); 3369 cmd->chanfreq = 0; 3370 cmd->buf_len = __cpu_to_le32(buf_len); 3371 cmd->frame_len = __cpu_to_le32(msdu->len); 3372 cmd->paddr = __cpu_to_le64(paddr); 3373 3374 ptr += sizeof(*tlv); 3375 ptr += sizeof(*cmd); 3376 3377 #if defined(__linux__) 3378 tlv = ptr; 3379 #elif defined(__FreeBSD__) 3380 tlv = (void *)ptr; 3381 #endif 3382 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 3383 tlv->len = __cpu_to_le16(buf_len); 3384 3385 ptr += sizeof(*tlv); 3386 memcpy(ptr, msdu->data, buf_len); 3387 3388 return skb; 3389 3390 err_free_skb: 3391 dev_kfree_skb(skb); 3392 return ERR_PTR(desc_id); 3393 } 3394 3395 static struct sk_buff * 3396 ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar, 3397 enum wmi_force_fw_hang_type type, 3398 u32 delay_ms) 3399 { 3400 struct wmi_force_fw_hang_cmd *cmd; 3401 struct wmi_tlv *tlv; 3402 struct sk_buff *skb; 3403 3404 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3405 if (!skb) 3406 return ERR_PTR(-ENOMEM); 3407 3408 tlv = (void *)skb->data; 3409 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD); 3410 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3411 cmd = (void *)tlv->value; 3412 cmd->type = __cpu_to_le32(type); 3413 cmd->delay_ms = __cpu_to_le32(delay_ms); 3414 3415 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n"); 3416 return skb; 3417 } 3418 3419 static struct sk_buff * 3420 ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable, 3421 u32 log_level) 3422 { 3423 struct wmi_tlv_dbglog_cmd *cmd; 3424 struct wmi_tlv *tlv; 3425 struct sk_buff *skb; 3426 size_t len, bmap_len; 3427 u32 value; 3428 #if defined(__linux__) 3429 void *ptr; 3430 #elif defined(__FreeBSD__) 3431 u8 *ptr; 3432 #endif 3433 3434 if (module_enable) { 3435 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE( 3436 module_enable, 3437 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE); 3438 } else { 3439 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE( 3440 WMI_TLV_DBGLOG_ALL_MODULES, 3441 WMI_TLV_DBGLOG_LOG_LEVEL_WARN); 3442 } 3443 3444 bmap_len = 0; 3445 len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len; 3446 skb = ath10k_wmi_alloc_skb(ar, len); 3447 if (!skb) 3448 return ERR_PTR(-ENOMEM); 3449 3450 #if defined(__linux__) 3451 ptr = (void *)skb->data; 3452 3453 tlv = ptr; 3454 #elif defined(__FreeBSD__) 3455 ptr = (u8 *)skb->data; 3456 tlv = (void *)ptr; 3457 #endif 3458 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD); 3459 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3460 cmd = (void *)tlv->value; 3461 cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL); 3462 cmd->value = __cpu_to_le32(value); 3463 3464 ptr += sizeof(*tlv); 3465 ptr += sizeof(*cmd); 3466 3467 #if defined(__linux__) 3468 tlv = ptr; 3469 #elif defined(__FreeBSD__) 3470 tlv = (void *)ptr; 3471 #endif 3472 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 3473 tlv->len = __cpu_to_le16(bmap_len); 3474 3475 /* nothing to do here */ 3476 3477 #if defined(__linux__) 3478 ptr += sizeof(*tlv); 3479 ptr += sizeof(bmap_len); 3480 #endif 3481 3482 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value); 3483 return skb; 3484 } 3485 3486 static struct sk_buff * 3487 ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter) 3488 { 3489 struct wmi_tlv_pktlog_enable *cmd; 3490 struct wmi_tlv *tlv; 3491 struct sk_buff *skb; 3492 #if defined(__linux__) 3493 void *ptr; 3494 #elif defined(__FreeBSD__) 3495 u8 *ptr; 3496 #endif 3497 size_t len; 3498 3499 len = sizeof(*tlv) + sizeof(*cmd); 3500 skb = ath10k_wmi_alloc_skb(ar, len); 3501 if (!skb) 3502 return ERR_PTR(-ENOMEM); 3503 3504 #if defined(__linux__) 3505 ptr = (void *)skb->data; 3506 tlv = ptr; 3507 #elif defined(__FreeBSD__) 3508 ptr = (u8 *)skb->data; 3509 tlv = (void *)ptr; 3510 #endif 3511 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD); 3512 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3513 cmd = (void *)tlv->value; 3514 cmd->filter = __cpu_to_le32(filter); 3515 3516 #if defined(__linux__) 3517 ptr += sizeof(*tlv); 3518 ptr += sizeof(*cmd); 3519 #endif 3520 3521 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n", 3522 filter); 3523 return skb; 3524 } 3525 3526 static struct sk_buff * 3527 ath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar) 3528 { 3529 struct wmi_tlv_pdev_get_temp_cmd *cmd; 3530 struct wmi_tlv *tlv; 3531 struct sk_buff *skb; 3532 3533 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3534 if (!skb) 3535 return ERR_PTR(-ENOMEM); 3536 3537 tlv = (void *)skb->data; 3538 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD); 3539 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3540 cmd = (void *)tlv->value; 3541 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n"); 3542 return skb; 3543 } 3544 3545 static struct sk_buff * 3546 ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) 3547 { 3548 struct wmi_tlv_pktlog_disable *cmd; 3549 struct wmi_tlv *tlv; 3550 struct sk_buff *skb; 3551 #if defined(__linux__) 3552 void *ptr; 3553 #elif defined(__FreeBSD__) 3554 u8 *ptr; 3555 #endif 3556 size_t len; 3557 3558 len = sizeof(*tlv) + sizeof(*cmd); 3559 skb = ath10k_wmi_alloc_skb(ar, len); 3560 if (!skb) 3561 return ERR_PTR(-ENOMEM); 3562 3563 #if defined(__linux__) 3564 ptr = (void *)skb->data; 3565 tlv = ptr; 3566 #elif defined(__FreeBSD__) 3567 ptr = (u8 *)skb->data; 3568 tlv = (void *)ptr; 3569 #endif 3570 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD); 3571 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3572 cmd = (void *)tlv->value; 3573 3574 #if defined(__linux__) 3575 ptr += sizeof(*tlv); 3576 ptr += sizeof(*cmd); 3577 #endif 3578 3579 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n"); 3580 return skb; 3581 } 3582 3583 static struct sk_buff * 3584 ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id, 3585 u32 tim_ie_offset, struct sk_buff *bcn, 3586 u32 prb_caps, u32 prb_erp, void *prb_ies, 3587 size_t prb_ies_len) 3588 { 3589 struct wmi_tlv_bcn_tmpl_cmd *cmd; 3590 struct wmi_tlv_bcn_prb_info *info; 3591 struct wmi_tlv *tlv; 3592 struct sk_buff *skb; 3593 #if defined(__linux__) 3594 void *ptr; 3595 #elif defined(__FreeBSD__) 3596 u8 *ptr; 3597 #endif 3598 size_t len; 3599 3600 if (WARN_ON(prb_ies_len > 0 && !prb_ies)) 3601 return ERR_PTR(-EINVAL); 3602 3603 len = sizeof(*tlv) + sizeof(*cmd) + 3604 sizeof(*tlv) + sizeof(*info) + prb_ies_len + 3605 sizeof(*tlv) + roundup(bcn->len, 4); 3606 skb = ath10k_wmi_alloc_skb(ar, len); 3607 if (!skb) 3608 return ERR_PTR(-ENOMEM); 3609 3610 #if defined(__linux__) 3611 ptr = (void *)skb->data; 3612 tlv = ptr; 3613 #elif defined(__FreeBSD__) 3614 ptr = (u8 *)skb->data; 3615 tlv = (void *)ptr; 3616 #endif 3617 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD); 3618 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3619 cmd = (void *)tlv->value; 3620 cmd->vdev_id = __cpu_to_le32(vdev_id); 3621 cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset); 3622 cmd->buf_len = __cpu_to_le32(bcn->len); 3623 3624 ptr += sizeof(*tlv); 3625 ptr += sizeof(*cmd); 3626 3627 /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but 3628 * then it is then impossible to pass original ie len. 3629 * This chunk is not used yet so if setting probe resp template yields 3630 * problems with beaconing or crashes firmware look here. 3631 */ 3632 #if defined(__linux__) 3633 tlv = ptr; 3634 #elif defined(__FreeBSD__) 3635 tlv = (void *)ptr; 3636 #endif 3637 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO); 3638 tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len); 3639 info = (void *)tlv->value; 3640 info->caps = __cpu_to_le32(prb_caps); 3641 info->erp = __cpu_to_le32(prb_erp); 3642 memcpy(info->ies, prb_ies, prb_ies_len); 3643 3644 ptr += sizeof(*tlv); 3645 ptr += sizeof(*info); 3646 ptr += prb_ies_len; 3647 3648 #if defined(__linux__) 3649 tlv = ptr; 3650 #elif defined(__FreeBSD__) 3651 tlv = (void *)ptr; 3652 #endif 3653 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 3654 tlv->len = __cpu_to_le16(roundup(bcn->len, 4)); 3655 memcpy(tlv->value, bcn->data, bcn->len); 3656 3657 /* FIXME: Adjust TSF? */ 3658 3659 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n", 3660 vdev_id); 3661 return skb; 3662 } 3663 3664 static struct sk_buff * 3665 ath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id, 3666 struct sk_buff *prb) 3667 { 3668 struct wmi_tlv_prb_tmpl_cmd *cmd; 3669 struct wmi_tlv_bcn_prb_info *info; 3670 struct wmi_tlv *tlv; 3671 struct sk_buff *skb; 3672 #if defined(__linux__) 3673 void *ptr; 3674 #elif defined(__FreeBSD__) 3675 u8 *ptr; 3676 #endif 3677 size_t len; 3678 3679 len = sizeof(*tlv) + sizeof(*cmd) + 3680 sizeof(*tlv) + sizeof(*info) + 3681 sizeof(*tlv) + roundup(prb->len, 4); 3682 skb = ath10k_wmi_alloc_skb(ar, len); 3683 if (!skb) 3684 return ERR_PTR(-ENOMEM); 3685 3686 #if defined(__linux__) 3687 ptr = (void *)skb->data; 3688 tlv = ptr; 3689 #elif defined(__FreeBSD__) 3690 ptr = (u8 *)skb->data; 3691 tlv = (void *)ptr; 3692 #endif 3693 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD); 3694 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3695 cmd = (void *)tlv->value; 3696 cmd->vdev_id = __cpu_to_le32(vdev_id); 3697 cmd->buf_len = __cpu_to_le32(prb->len); 3698 3699 ptr += sizeof(*tlv); 3700 ptr += sizeof(*cmd); 3701 3702 #if defined(__linux__) 3703 tlv = ptr; 3704 #elif defined(__FreeBSD__) 3705 tlv = (void *)ptr; 3706 #endif 3707 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO); 3708 tlv->len = __cpu_to_le16(sizeof(*info)); 3709 info = (void *)tlv->value; 3710 info->caps = 0; 3711 info->erp = 0; 3712 3713 ptr += sizeof(*tlv); 3714 ptr += sizeof(*info); 3715 3716 #if defined(__linux__) 3717 tlv = ptr; 3718 #elif defined(__FreeBSD__) 3719 tlv = (void *)ptr; 3720 #endif 3721 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 3722 tlv->len = __cpu_to_le16(roundup(prb->len, 4)); 3723 memcpy(tlv->value, prb->data, prb->len); 3724 3725 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n", 3726 vdev_id); 3727 return skb; 3728 } 3729 3730 static struct sk_buff * 3731 ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id, 3732 const u8 *p2p_ie) 3733 { 3734 struct wmi_tlv_p2p_go_bcn_ie *cmd; 3735 struct wmi_tlv *tlv; 3736 struct sk_buff *skb; 3737 #if defined(__linux__) 3738 void *ptr; 3739 #elif defined(__FreeBSD__) 3740 u8 *ptr; 3741 #endif 3742 size_t len; 3743 3744 len = sizeof(*tlv) + sizeof(*cmd) + 3745 sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4); 3746 skb = ath10k_wmi_alloc_skb(ar, len); 3747 if (!skb) 3748 return ERR_PTR(-ENOMEM); 3749 3750 #if defined(__linux__) 3751 ptr = (void *)skb->data; 3752 tlv = ptr; 3753 #elif defined(__FreeBSD__) 3754 ptr = (u8 *)skb->data; 3755 tlv = (void *)ptr; 3756 #endif 3757 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE); 3758 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3759 cmd = (void *)tlv->value; 3760 cmd->vdev_id = __cpu_to_le32(vdev_id); 3761 cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2); 3762 3763 ptr += sizeof(*tlv); 3764 ptr += sizeof(*cmd); 3765 3766 #if defined(__linux__) 3767 tlv = ptr; 3768 #elif defined(__FreeBSD__) 3769 tlv = (void *)ptr; 3770 #endif 3771 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 3772 tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4)); 3773 memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2); 3774 3775 #if defined(__linux__) 3776 ptr += sizeof(*tlv); 3777 ptr += roundup(p2p_ie[1] + 2, 4); 3778 #endif 3779 3780 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n", 3781 vdev_id); 3782 return skb; 3783 } 3784 3785 static struct sk_buff * 3786 ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id, 3787 enum wmi_tdls_state state) 3788 { 3789 struct wmi_tdls_set_state_cmd *cmd; 3790 struct wmi_tlv *tlv; 3791 struct sk_buff *skb; 3792 #if defined(__linux__) 3793 void *ptr; 3794 #elif defined(__FreeBSD__) 3795 u8 *ptr; 3796 #endif 3797 size_t len; 3798 /* Set to options from wmi_tlv_tdls_options, 3799 * for now none of them are enabled. 3800 */ 3801 u32 options = 0; 3802 3803 if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) 3804 options |= WMI_TLV_TDLS_BUFFER_STA_EN; 3805 3806 /* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS 3807 * link inactivity detecting logic. 3808 */ 3809 if (state == WMI_TDLS_ENABLE_ACTIVE) 3810 state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL; 3811 3812 len = sizeof(*tlv) + sizeof(*cmd); 3813 skb = ath10k_wmi_alloc_skb(ar, len); 3814 if (!skb) 3815 return ERR_PTR(-ENOMEM); 3816 3817 #if defined(__linux__) 3818 ptr = (void *)skb->data; 3819 tlv = ptr; 3820 #elif defined(__FreeBSD__) 3821 ptr = (u8 *)skb->data; 3822 tlv = (void *)ptr; 3823 #endif 3824 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD); 3825 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3826 3827 cmd = (void *)tlv->value; 3828 cmd->vdev_id = __cpu_to_le32(vdev_id); 3829 cmd->state = __cpu_to_le32(state); 3830 cmd->notification_interval_ms = __cpu_to_le32(5000); 3831 cmd->tx_discovery_threshold = __cpu_to_le32(100); 3832 cmd->tx_teardown_threshold = __cpu_to_le32(5); 3833 cmd->rssi_teardown_threshold = __cpu_to_le32(-75); 3834 cmd->rssi_delta = __cpu_to_le32(-20); 3835 cmd->tdls_options = __cpu_to_le32(options); 3836 cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2); 3837 cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000); 3838 cmd->tdls_puapsd_mask = __cpu_to_le32(0xf); 3839 cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0); 3840 cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10); 3841 3842 #if defined(__linux__) 3843 ptr += sizeof(*tlv); 3844 ptr += sizeof(*cmd); 3845 #endif 3846 3847 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n", 3848 state, vdev_id); 3849 return skb; 3850 } 3851 3852 static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp) 3853 { 3854 u32 peer_qos = 0; 3855 3856 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) 3857 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO; 3858 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) 3859 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI; 3860 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) 3861 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK; 3862 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) 3863 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE; 3864 3865 peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP); 3866 3867 return peer_qos; 3868 } 3869 3870 static struct sk_buff * 3871 ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar, 3872 const struct wmi_tdls_peer_update_cmd_arg *arg, 3873 const struct wmi_tdls_peer_capab_arg *cap, 3874 const struct wmi_channel_arg *chan_arg) 3875 { 3876 struct wmi_tdls_peer_update_cmd *cmd; 3877 struct wmi_tdls_peer_capab *peer_cap; 3878 struct wmi_channel *chan; 3879 struct wmi_tlv *tlv; 3880 struct sk_buff *skb; 3881 u32 peer_qos; 3882 #if defined(__linux__) 3883 void *ptr; 3884 #elif defined(__FreeBSD__) 3885 u8 *ptr; 3886 #endif 3887 int len; 3888 int i; 3889 3890 len = sizeof(*tlv) + sizeof(*cmd) + 3891 sizeof(*tlv) + sizeof(*peer_cap) + 3892 sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan); 3893 3894 skb = ath10k_wmi_alloc_skb(ar, len); 3895 if (!skb) 3896 return ERR_PTR(-ENOMEM); 3897 3898 #if defined(__linux__) 3899 ptr = (void *)skb->data; 3900 tlv = ptr; 3901 #elif defined(__FreeBSD__) 3902 ptr = (u8 *)skb->data; 3903 tlv = (void *)ptr; 3904 #endif 3905 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD); 3906 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3907 3908 cmd = (void *)tlv->value; 3909 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 3910 ether_addr_copy(cmd->peer_macaddr.addr, arg->addr); 3911 cmd->peer_state = __cpu_to_le32(arg->peer_state); 3912 3913 ptr += sizeof(*tlv); 3914 ptr += sizeof(*cmd); 3915 3916 #if defined(__linux__) 3917 tlv = ptr; 3918 #elif defined(__FreeBSD__) 3919 tlv = (void *)ptr; 3920 #endif 3921 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES); 3922 tlv->len = __cpu_to_le16(sizeof(*peer_cap)); 3923 peer_cap = (void *)tlv->value; 3924 peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues, 3925 cap->peer_max_sp); 3926 peer_cap->peer_qos = __cpu_to_le32(peer_qos); 3927 peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support); 3928 peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support); 3929 peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass); 3930 peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass); 3931 peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len); 3932 peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len); 3933 3934 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) 3935 peer_cap->peer_operclass[i] = cap->peer_operclass[i]; 3936 3937 peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder); 3938 peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num); 3939 peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw); 3940 3941 ptr += sizeof(*tlv); 3942 ptr += sizeof(*peer_cap); 3943 3944 #if defined(__linux__) 3945 tlv = ptr; 3946 #elif defined(__FreeBSD__) 3947 tlv = (void *)ptr; 3948 #endif 3949 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 3950 tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan)); 3951 3952 ptr += sizeof(*tlv); 3953 3954 for (i = 0; i < cap->peer_chan_len; i++) { 3955 #if defined(__linux__) 3956 tlv = ptr; 3957 #elif defined(__FreeBSD__) 3958 tlv = (void *)ptr; 3959 #endif 3960 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); 3961 tlv->len = __cpu_to_le16(sizeof(*chan)); 3962 chan = (void *)tlv->value; 3963 ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]); 3964 3965 ptr += sizeof(*tlv); 3966 ptr += sizeof(*chan); 3967 } 3968 3969 ath10k_dbg(ar, ATH10K_DBG_WMI, 3970 "wmi tlv tdls peer update vdev %i state %d n_chans %u\n", 3971 arg->vdev_id, arg->peer_state, cap->peer_chan_len); 3972 return skb; 3973 } 3974 3975 static struct sk_buff * 3976 ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period, 3977 u32 duration, u32 next_offset, 3978 u32 enabled) 3979 { 3980 struct wmi_tlv_set_quiet_cmd *cmd; 3981 struct wmi_tlv *tlv; 3982 struct sk_buff *skb; 3983 3984 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); 3985 if (!skb) 3986 return ERR_PTR(-ENOMEM); 3987 3988 tlv = (void *)skb->data; 3989 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD); 3990 tlv->len = __cpu_to_le16(sizeof(*cmd)); 3991 cmd = (void *)tlv->value; 3992 3993 /* vdev_id is not in use, set to 0 */ 3994 cmd->vdev_id = __cpu_to_le32(0); 3995 cmd->period = __cpu_to_le32(period); 3996 cmd->duration = __cpu_to_le32(duration); 3997 cmd->next_start = __cpu_to_le32(next_offset); 3998 cmd->enabled = __cpu_to_le32(enabled); 3999 4000 ath10k_dbg(ar, ATH10K_DBG_WMI, 4001 "wmi tlv quiet param: period %u duration %u enabled %d\n", 4002 period, duration, enabled); 4003 return skb; 4004 } 4005 4006 static struct sk_buff * 4007 ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar) 4008 { 4009 struct wmi_tlv_wow_enable_cmd *cmd; 4010 struct wmi_tlv *tlv; 4011 struct sk_buff *skb; 4012 size_t len; 4013 4014 len = sizeof(*tlv) + sizeof(*cmd); 4015 skb = ath10k_wmi_alloc_skb(ar, len); 4016 if (!skb) 4017 return ERR_PTR(-ENOMEM); 4018 4019 tlv = (struct wmi_tlv *)skb->data; 4020 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD); 4021 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4022 cmd = (void *)tlv->value; 4023 4024 cmd->enable = __cpu_to_le32(1); 4025 if (!ar->bus_param.link_can_suspend) 4026 cmd->pause_iface_config = __cpu_to_le32(WOW_IFACE_PAUSE_DISABLED); 4027 4028 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n"); 4029 return skb; 4030 } 4031 4032 static struct sk_buff * 4033 ath10k_wmi_tlv_op_gen_wow_add_wakeup_event(struct ath10k *ar, 4034 u32 vdev_id, 4035 enum wmi_wow_wakeup_event event, 4036 u32 enable) 4037 { 4038 struct wmi_tlv_wow_add_del_event_cmd *cmd; 4039 struct wmi_tlv *tlv; 4040 struct sk_buff *skb; 4041 size_t len; 4042 4043 len = sizeof(*tlv) + sizeof(*cmd); 4044 skb = ath10k_wmi_alloc_skb(ar, len); 4045 if (!skb) 4046 return ERR_PTR(-ENOMEM); 4047 4048 tlv = (struct wmi_tlv *)skb->data; 4049 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD); 4050 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4051 cmd = (void *)tlv->value; 4052 4053 cmd->vdev_id = __cpu_to_le32(vdev_id); 4054 cmd->is_add = __cpu_to_le32(enable); 4055 cmd->event_bitmap = __cpu_to_le32(1 << event); 4056 4057 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n", 4058 wow_wakeup_event(event), enable, vdev_id); 4059 return skb; 4060 } 4061 4062 static struct sk_buff * 4063 ath10k_wmi_tlv_gen_wow_host_wakeup_ind(struct ath10k *ar) 4064 { 4065 struct wmi_tlv_wow_host_wakeup_ind *cmd; 4066 struct wmi_tlv *tlv; 4067 struct sk_buff *skb; 4068 size_t len; 4069 4070 len = sizeof(*tlv) + sizeof(*cmd); 4071 skb = ath10k_wmi_alloc_skb(ar, len); 4072 if (!skb) 4073 return ERR_PTR(-ENOMEM); 4074 4075 tlv = (struct wmi_tlv *)skb->data; 4076 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD); 4077 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4078 cmd = (void *)tlv->value; 4079 4080 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow host wakeup ind\n"); 4081 return skb; 4082 } 4083 4084 static struct sk_buff * 4085 ath10k_wmi_tlv_op_gen_wow_add_pattern(struct ath10k *ar, u32 vdev_id, 4086 u32 pattern_id, const u8 *pattern, 4087 const u8 *bitmask, int pattern_len, 4088 int pattern_offset) 4089 { 4090 struct wmi_tlv_wow_add_pattern_cmd *cmd; 4091 struct wmi_tlv_wow_bitmap_pattern *bitmap; 4092 struct wmi_tlv *tlv; 4093 struct sk_buff *skb; 4094 #if defined(__linux__) 4095 void *ptr; 4096 #elif defined(__FreeBSD__) 4097 u8 *ptr; 4098 #endif 4099 size_t len; 4100 4101 len = sizeof(*tlv) + sizeof(*cmd) + 4102 sizeof(*tlv) + /* array struct */ 4103 sizeof(*tlv) + sizeof(*bitmap) + /* bitmap */ 4104 sizeof(*tlv) + /* empty ipv4 sync */ 4105 sizeof(*tlv) + /* empty ipv6 sync */ 4106 sizeof(*tlv) + /* empty magic */ 4107 sizeof(*tlv) + /* empty info timeout */ 4108 sizeof(*tlv) + sizeof(u32); /* ratelimit interval */ 4109 4110 skb = ath10k_wmi_alloc_skb(ar, len); 4111 if (!skb) 4112 return ERR_PTR(-ENOMEM); 4113 4114 /* cmd */ 4115 #if defined(__linux__) 4116 ptr = (void *)skb->data; 4117 tlv = ptr; 4118 #elif defined(__FreeBSD__) 4119 ptr = (u8 *)skb->data; 4120 tlv = (void *)ptr; 4121 #endif 4122 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD); 4123 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4124 cmd = (void *)tlv->value; 4125 4126 cmd->vdev_id = __cpu_to_le32(vdev_id); 4127 cmd->pattern_id = __cpu_to_le32(pattern_id); 4128 cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN); 4129 4130 ptr += sizeof(*tlv); 4131 ptr += sizeof(*cmd); 4132 4133 /* bitmap */ 4134 #if defined(__linux__) 4135 tlv = ptr; 4136 #elif defined(__FreeBSD__) 4137 tlv = (void *)ptr; 4138 #endif 4139 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 4140 tlv->len = __cpu_to_le16(sizeof(*tlv) + sizeof(*bitmap)); 4141 4142 ptr += sizeof(*tlv); 4143 4144 #if defined(__linux__) 4145 tlv = ptr; 4146 #elif defined(__FreeBSD__) 4147 tlv = (void *)ptr; 4148 #endif 4149 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T); 4150 tlv->len = __cpu_to_le16(sizeof(*bitmap)); 4151 bitmap = (void *)tlv->value; 4152 4153 memcpy(bitmap->patternbuf, pattern, pattern_len); 4154 memcpy(bitmap->bitmaskbuf, bitmask, pattern_len); 4155 bitmap->pattern_offset = __cpu_to_le32(pattern_offset); 4156 bitmap->pattern_len = __cpu_to_le32(pattern_len); 4157 bitmap->bitmask_len = __cpu_to_le32(pattern_len); 4158 bitmap->pattern_id = __cpu_to_le32(pattern_id); 4159 4160 ptr += sizeof(*tlv); 4161 ptr += sizeof(*bitmap); 4162 4163 /* ipv4 sync */ 4164 #if defined(__linux__) 4165 tlv = ptr; 4166 #elif defined(__FreeBSD__) 4167 tlv = (void *)ptr; 4168 #endif 4169 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 4170 tlv->len = __cpu_to_le16(0); 4171 4172 ptr += sizeof(*tlv); 4173 4174 /* ipv6 sync */ 4175 #if defined(__linux__) 4176 tlv = ptr; 4177 #elif defined(__FreeBSD__) 4178 tlv = (void *)ptr; 4179 #endif 4180 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 4181 tlv->len = __cpu_to_le16(0); 4182 4183 ptr += sizeof(*tlv); 4184 4185 /* magic */ 4186 #if defined(__linux__) 4187 tlv = ptr; 4188 #elif defined(__FreeBSD__) 4189 tlv = (void *)ptr; 4190 #endif 4191 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 4192 tlv->len = __cpu_to_le16(0); 4193 4194 ptr += sizeof(*tlv); 4195 4196 /* pattern info timeout */ 4197 #if defined(__linux__) 4198 tlv = ptr; 4199 #elif defined(__FreeBSD__) 4200 tlv = (void *)ptr; 4201 #endif 4202 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 4203 tlv->len = __cpu_to_le16(0); 4204 4205 ptr += sizeof(*tlv); 4206 4207 /* ratelimit interval */ 4208 #if defined(__linux__) 4209 tlv = ptr; 4210 #elif defined(__FreeBSD__) 4211 tlv = (void *)ptr; 4212 #endif 4213 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 4214 tlv->len = __cpu_to_le16(sizeof(u32)); 4215 4216 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add pattern vdev_id %d pattern_id %d, pattern_offset %d\n", 4217 vdev_id, pattern_id, pattern_offset); 4218 return skb; 4219 } 4220 4221 static struct sk_buff * 4222 ath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id, 4223 u32 pattern_id) 4224 { 4225 struct wmi_tlv_wow_del_pattern_cmd *cmd; 4226 struct wmi_tlv *tlv; 4227 struct sk_buff *skb; 4228 size_t len; 4229 4230 len = sizeof(*tlv) + sizeof(*cmd); 4231 skb = ath10k_wmi_alloc_skb(ar, len); 4232 if (!skb) 4233 return ERR_PTR(-ENOMEM); 4234 4235 tlv = (struct wmi_tlv *)skb->data; 4236 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD); 4237 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4238 cmd = (void *)tlv->value; 4239 4240 cmd->vdev_id = __cpu_to_le32(vdev_id); 4241 cmd->pattern_id = __cpu_to_le32(pattern_id); 4242 cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN); 4243 4244 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n", 4245 vdev_id, pattern_id); 4246 return skb; 4247 } 4248 4249 /* Request FW to start PNO operation */ 4250 static struct sk_buff * 4251 ath10k_wmi_tlv_op_gen_config_pno_start(struct ath10k *ar, 4252 u32 vdev_id, 4253 struct wmi_pno_scan_req *pno) 4254 { 4255 struct nlo_configured_parameters *nlo_list; 4256 struct wmi_tlv_wow_nlo_config_cmd *cmd; 4257 struct wmi_tlv *tlv; 4258 struct sk_buff *skb; 4259 __le32 *channel_list; 4260 u16 tlv_len; 4261 size_t len; 4262 #if defined(__linux__) 4263 void *ptr; 4264 #elif defined(__FreeBSD__) 4265 u8 *ptr; 4266 #endif 4267 u32 i; 4268 4269 len = sizeof(*tlv) + sizeof(*cmd) + 4270 sizeof(*tlv) + 4271 /* TLV place holder for array of structures 4272 * nlo_configured_parameters(nlo_list) 4273 */ 4274 sizeof(*tlv); 4275 /* TLV place holder for array of uint32 channel_list */ 4276 4277 len += sizeof(u32) * min_t(u8, pno->a_networks[0].channel_count, 4278 WMI_NLO_MAX_CHAN); 4279 len += sizeof(struct nlo_configured_parameters) * 4280 min_t(u8, pno->uc_networks_count, WMI_NLO_MAX_SSIDS); 4281 4282 skb = ath10k_wmi_alloc_skb(ar, len); 4283 if (!skb) 4284 return ERR_PTR(-ENOMEM); 4285 4286 #if defined(__linux__) 4287 ptr = (void *)skb->data; 4288 tlv = ptr; 4289 #elif defined(__FreeBSD__) 4290 ptr = (u8 *)skb->data; 4291 tlv = (void *)ptr; 4292 #endif 4293 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD); 4294 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4295 cmd = (void *)tlv->value; 4296 4297 /* wmi_tlv_wow_nlo_config_cmd parameters*/ 4298 cmd->vdev_id = __cpu_to_le32(pno->vdev_id); 4299 cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN); 4300 4301 /* current FW does not support min-max range for dwell time */ 4302 cmd->active_dwell_time = __cpu_to_le32(pno->active_max_time); 4303 cmd->passive_dwell_time = __cpu_to_le32(pno->passive_max_time); 4304 4305 if (pno->do_passive_scan) 4306 cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SCAN_PASSIVE); 4307 4308 /* copy scan interval */ 4309 cmd->fast_scan_period = __cpu_to_le32(pno->fast_scan_period); 4310 cmd->slow_scan_period = __cpu_to_le32(pno->slow_scan_period); 4311 cmd->fast_scan_max_cycles = __cpu_to_le32(pno->fast_scan_max_cycles); 4312 cmd->delay_start_time = __cpu_to_le32(pno->delay_start_time); 4313 4314 if (pno->enable_pno_scan_randomization) { 4315 cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 4316 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ); 4317 ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr); 4318 ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask); 4319 } 4320 4321 ptr += sizeof(*tlv); 4322 ptr += sizeof(*cmd); 4323 4324 /* nlo_configured_parameters(nlo_list) */ 4325 cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count, 4326 WMI_NLO_MAX_SSIDS)); 4327 tlv_len = __le32_to_cpu(cmd->no_of_ssids) * 4328 sizeof(struct nlo_configured_parameters); 4329 4330 #if defined(__linux__) 4331 tlv = ptr; 4332 #elif defined(__FreeBSD__) 4333 tlv = (void *)ptr; 4334 #endif 4335 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 4336 tlv->len = __cpu_to_le16(tlv_len); 4337 4338 ptr += sizeof(*tlv); 4339 #if defined(__linux__) 4340 nlo_list = ptr; 4341 #elif defined(__FreeBSD__) 4342 nlo_list = (void *)ptr; 4343 #endif 4344 for (i = 0; i < __le32_to_cpu(cmd->no_of_ssids); i++) { 4345 tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header); 4346 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); 4347 tlv->len = __cpu_to_le16(sizeof(struct nlo_configured_parameters) - 4348 sizeof(*tlv)); 4349 4350 /* copy ssid and it's length */ 4351 nlo_list[i].ssid.valid = __cpu_to_le32(true); 4352 nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len; 4353 memcpy(nlo_list[i].ssid.ssid.ssid, 4354 pno->a_networks[i].ssid.ssid, 4355 __le32_to_cpu(nlo_list[i].ssid.ssid.ssid_len)); 4356 4357 /* copy rssi threshold */ 4358 if (pno->a_networks[i].rssi_threshold && 4359 pno->a_networks[i].rssi_threshold > -300) { 4360 nlo_list[i].rssi_cond.valid = __cpu_to_le32(true); 4361 nlo_list[i].rssi_cond.rssi = 4362 __cpu_to_le32(pno->a_networks[i].rssi_threshold); 4363 } 4364 4365 nlo_list[i].bcast_nw_type.valid = __cpu_to_le32(true); 4366 nlo_list[i].bcast_nw_type.bcast_nw_type = 4367 __cpu_to_le32(pno->a_networks[i].bcast_nw_type); 4368 } 4369 4370 ptr += __le32_to_cpu(cmd->no_of_ssids) * sizeof(struct nlo_configured_parameters); 4371 4372 /* copy channel info */ 4373 cmd->num_of_channels = __cpu_to_le32(min_t(u8, 4374 pno->a_networks[0].channel_count, 4375 WMI_NLO_MAX_CHAN)); 4376 4377 #if defined(__linux__) 4378 tlv = ptr; 4379 #elif defined(__FreeBSD__) 4380 tlv = (void *)ptr; 4381 #endif 4382 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 4383 tlv->len = __cpu_to_le16(__le32_to_cpu(cmd->num_of_channels) * 4384 sizeof(u_int32_t)); 4385 ptr += sizeof(*tlv); 4386 4387 channel_list = (__le32 *)ptr; 4388 for (i = 0; i < __le32_to_cpu(cmd->num_of_channels); i++) 4389 channel_list[i] = __cpu_to_le32(pno->a_networks[0].channels[i]); 4390 4391 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start pno config vdev_id %d\n", 4392 vdev_id); 4393 4394 return skb; 4395 } 4396 4397 /* Request FW to stop ongoing PNO operation */ 4398 static struct sk_buff *ath10k_wmi_tlv_op_gen_config_pno_stop(struct ath10k *ar, 4399 u32 vdev_id) 4400 { 4401 struct wmi_tlv_wow_nlo_config_cmd *cmd; 4402 struct wmi_tlv *tlv; 4403 struct sk_buff *skb; 4404 #if defined(__linux__) 4405 void *ptr; 4406 #elif defined(__FreeBSD__) 4407 u8 *ptr; 4408 #endif 4409 size_t len; 4410 4411 len = sizeof(*tlv) + sizeof(*cmd) + 4412 sizeof(*tlv) + 4413 /* TLV place holder for array of structures 4414 * nlo_configured_parameters(nlo_list) 4415 */ 4416 sizeof(*tlv); 4417 /* TLV place holder for array of uint32 channel_list */ 4418 skb = ath10k_wmi_alloc_skb(ar, len); 4419 if (!skb) 4420 return ERR_PTR(-ENOMEM); 4421 4422 #if defined(__linux__) 4423 ptr = (void *)skb->data; 4424 tlv = ptr; 4425 #elif defined(__FreeBSD__) 4426 ptr = (u8 *)skb->data; 4427 tlv = (void *)ptr; 4428 #endif 4429 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD); 4430 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4431 cmd = (void *)tlv->value; 4432 4433 cmd->vdev_id = __cpu_to_le32(vdev_id); 4434 cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_STOP); 4435 4436 ptr += sizeof(*tlv); 4437 ptr += sizeof(*cmd); 4438 4439 /* nlo_configured_parameters(nlo_list) */ 4440 #if defined(__linux__) 4441 tlv = ptr; 4442 #elif defined(__FreeBSD__) 4443 tlv = (void *)ptr; 4444 #endif 4445 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); 4446 tlv->len = __cpu_to_le16(0); 4447 4448 ptr += sizeof(*tlv); 4449 4450 /* channel list */ 4451 #if defined(__linux__) 4452 tlv = ptr; 4453 #elif defined(__FreeBSD__) 4454 tlv = (void *)ptr; 4455 #endif 4456 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); 4457 tlv->len = __cpu_to_le16(0); 4458 4459 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop pno config vdev_id %d\n", vdev_id); 4460 return skb; 4461 } 4462 4463 static struct sk_buff * 4464 ath10k_wmi_tlv_op_gen_config_pno(struct ath10k *ar, u32 vdev_id, 4465 struct wmi_pno_scan_req *pno_scan) 4466 { 4467 if (pno_scan->enable) 4468 return ath10k_wmi_tlv_op_gen_config_pno_start(ar, vdev_id, pno_scan); 4469 else 4470 return ath10k_wmi_tlv_op_gen_config_pno_stop(ar, vdev_id); 4471 } 4472 4473 static struct sk_buff * 4474 ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable) 4475 { 4476 struct wmi_tlv_adaptive_qcs *cmd; 4477 struct wmi_tlv *tlv; 4478 struct sk_buff *skb; 4479 void *ptr; 4480 size_t len; 4481 4482 len = sizeof(*tlv) + sizeof(*cmd); 4483 skb = ath10k_wmi_alloc_skb(ar, len); 4484 if (!skb) 4485 return ERR_PTR(-ENOMEM); 4486 4487 ptr = (void *)skb->data; 4488 tlv = ptr; 4489 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD); 4490 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4491 cmd = (void *)tlv->value; 4492 cmd->enable = __cpu_to_le32(enable ? 1 : 0); 4493 4494 #if defined(__linux__) 4495 ptr += sizeof(*tlv); 4496 ptr += sizeof(*cmd); 4497 #endif 4498 4499 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv adaptive qcs %d\n", enable); 4500 return skb; 4501 } 4502 4503 static struct sk_buff * 4504 ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value) 4505 { 4506 struct wmi_echo_cmd *cmd; 4507 struct wmi_tlv *tlv; 4508 struct sk_buff *skb; 4509 void *ptr; 4510 size_t len; 4511 4512 len = sizeof(*tlv) + sizeof(*cmd); 4513 skb = ath10k_wmi_alloc_skb(ar, len); 4514 if (!skb) 4515 return ERR_PTR(-ENOMEM); 4516 4517 ptr = (void *)skb->data; 4518 tlv = ptr; 4519 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ECHO_CMD); 4520 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4521 cmd = (void *)tlv->value; 4522 cmd->value = cpu_to_le32(value); 4523 4524 #if defined(__linux__) 4525 ptr += sizeof(*tlv); 4526 ptr += sizeof(*cmd); 4527 #endif 4528 4529 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv echo value 0x%08x\n", value); 4530 return skb; 4531 } 4532 4533 static struct sk_buff * 4534 ath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar, 4535 const struct wmi_vdev_spectral_conf_arg *arg) 4536 { 4537 struct wmi_vdev_spectral_conf_cmd *cmd; 4538 struct sk_buff *skb; 4539 struct wmi_tlv *tlv; 4540 void *ptr; 4541 size_t len; 4542 4543 len = sizeof(*tlv) + sizeof(*cmd); 4544 skb = ath10k_wmi_alloc_skb(ar, len); 4545 if (!skb) 4546 return ERR_PTR(-ENOMEM); 4547 4548 ptr = (void *)skb->data; 4549 tlv = ptr; 4550 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD); 4551 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4552 cmd = (void *)tlv->value; 4553 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 4554 cmd->scan_count = __cpu_to_le32(arg->scan_count); 4555 cmd->scan_period = __cpu_to_le32(arg->scan_period); 4556 cmd->scan_priority = __cpu_to_le32(arg->scan_priority); 4557 cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size); 4558 cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena); 4559 cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena); 4560 cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref); 4561 cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay); 4562 cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr); 4563 cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr); 4564 cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode); 4565 cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode); 4566 cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr); 4567 cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format); 4568 cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode); 4569 cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale); 4570 cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); 4571 cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); 4572 4573 return skb; 4574 } 4575 4576 static struct sk_buff * 4577 ath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, 4578 u32 trigger, u32 enable) 4579 { 4580 struct wmi_vdev_spectral_enable_cmd *cmd; 4581 struct sk_buff *skb; 4582 struct wmi_tlv *tlv; 4583 void *ptr; 4584 size_t len; 4585 4586 len = sizeof(*tlv) + sizeof(*cmd); 4587 skb = ath10k_wmi_alloc_skb(ar, len); 4588 if (!skb) 4589 return ERR_PTR(-ENOMEM); 4590 4591 ptr = (void *)skb->data; 4592 tlv = ptr; 4593 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD); 4594 tlv->len = __cpu_to_le16(sizeof(*cmd)); 4595 cmd = (void *)tlv->value; 4596 cmd->vdev_id = __cpu_to_le32(vdev_id); 4597 cmd->trigger_cmd = __cpu_to_le32(trigger); 4598 cmd->enable_cmd = __cpu_to_le32(enable); 4599 4600 return skb; 4601 } 4602 4603 /****************/ 4604 /* TLV mappings */ 4605 /****************/ 4606 4607 static struct wmi_cmd_map wmi_tlv_cmd_map = { 4608 .init_cmdid = WMI_TLV_INIT_CMDID, 4609 .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID, 4610 .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID, 4611 .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID, 4612 .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID, 4613 .scan_prob_req_oui_cmdid = WMI_TLV_SCAN_PROB_REQ_OUI_CMDID, 4614 .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID, 4615 .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID, 4616 .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID, 4617 .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID, 4618 .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID, 4619 .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID, 4620 .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID, 4621 .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID, 4622 .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID, 4623 .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID, 4624 .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID, 4625 .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID, 4626 .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID, 4627 .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID, 4628 .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID, 4629 .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID, 4630 .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID, 4631 .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID, 4632 .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID, 4633 .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID, 4634 .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID, 4635 .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID, 4636 .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID, 4637 .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID, 4638 .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID, 4639 .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID, 4640 .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID, 4641 .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID, 4642 .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID, 4643 .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID, 4644 .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID, 4645 .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID, 4646 .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID, 4647 .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID, 4648 .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID, 4649 .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID, 4650 .mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD, 4651 .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID, 4652 .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID, 4653 .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID, 4654 .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID, 4655 .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID, 4656 .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID, 4657 .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID, 4658 .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID, 4659 .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID, 4660 .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID, 4661 .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID, 4662 .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID, 4663 .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE, 4664 .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD, 4665 .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD, 4666 .roam_scan_rssi_change_threshold = 4667 WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, 4668 .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE, 4669 .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE, 4670 .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE, 4671 .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD, 4672 .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO, 4673 .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY, 4674 .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE, 4675 .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE, 4676 .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID, 4677 .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID, 4678 .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID, 4679 .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID, 4680 .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID, 4681 .wlan_profile_set_hist_intvl_cmdid = 4682 WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 4683 .wlan_profile_get_profile_data_cmdid = 4684 WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 4685 .wlan_profile_enable_profile_id_cmdid = 4686 WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 4687 .wlan_profile_list_profile_id_cmdid = 4688 WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, 4689 .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID, 4690 .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID, 4691 .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID, 4692 .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID, 4693 .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID, 4694 .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID, 4695 .wow_enable_disable_wake_event_cmdid = 4696 WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, 4697 .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID, 4698 .wow_hostwakeup_from_sleep_cmdid = 4699 WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, 4700 .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID, 4701 .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID, 4702 .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID, 4703 .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID, 4704 .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID, 4705 .request_peer_stats_info_cmdid = WMI_TLV_REQUEST_PEER_STATS_INFO_CMDID, 4706 .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID, 4707 .network_list_offload_config_cmdid = 4708 WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, 4709 .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID, 4710 .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID, 4711 .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID, 4712 .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID, 4713 .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID, 4714 .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID, 4715 .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID, 4716 .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID, 4717 .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID, 4718 .echo_cmdid = WMI_TLV_ECHO_CMDID, 4719 .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID, 4720 .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID, 4721 .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID, 4722 .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID, 4723 .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID, 4724 .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID, 4725 .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, 4726 .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, 4727 .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, 4728 .pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID, 4729 .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, 4730 .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, 4731 .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, 4732 .adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID, 4733 .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED, 4734 .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED, 4735 .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED, 4736 .wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED, 4737 .wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED, 4738 .wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED, 4739 .wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED, 4740 .peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED, 4741 .peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED, 4742 .rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 4743 .oem_req_cmdid = WMI_CMD_UNSUPPORTED, 4744 .nan_cmdid = WMI_CMD_UNSUPPORTED, 4745 .vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED, 4746 .qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED, 4747 .pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED, 4748 .pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED, 4749 .peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED, 4750 .peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED, 4751 .peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED, 4752 .pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED, 4753 .pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED, 4754 .pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED, 4755 .pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED, 4756 .pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED, 4757 .pdev_fips_cmdid = WMI_CMD_UNSUPPORTED, 4758 .tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED, 4759 .fwtest_cmdid = WMI_CMD_UNSUPPORTED, 4760 .vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED, 4761 .peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED, 4762 .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED, 4763 .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED, 4764 .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED, 4765 }; 4766 4767 static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = { 4768 .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK, 4769 .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK, 4770 .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G, 4771 .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G, 4772 .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE, 4773 .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE, 4774 .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE, 4775 .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 4776 .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE, 4777 .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW, 4778 .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 4779 .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH, 4780 .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH, 4781 .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING, 4782 .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE, 4783 .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE, 4784 .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK, 4785 .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI, 4786 .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO, 4787 .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 4788 .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 4789 .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE, 4790 .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 4791 .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE, 4792 .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE, 4793 .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 4794 .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 4795 .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 4796 .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 4797 .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 4798 .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 4799 .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 4800 .bcnflt_stats_update_period = 4801 WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 4802 .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS, 4803 .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE, 4804 .dcs = WMI_TLV_PDEV_PARAM_DCS, 4805 .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE, 4806 .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD, 4807 .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD, 4808 .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL, 4809 .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL, 4810 .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN, 4811 .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA, 4812 .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG, 4813 .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP, 4814 .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED, 4815 .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR, 4816 .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE, 4817 .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, 4818 .aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED, 4819 .rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED, 4820 .smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED, 4821 .igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED, 4822 .igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED, 4823 .antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED, 4824 .rx_filter = WMI_PDEV_PARAM_UNSUPPORTED, 4825 .set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED, 4826 .proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED, 4827 .set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED, 4828 .set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, 4829 .remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED, 4830 .peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED, 4831 .igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, 4832 .block_interbss = WMI_PDEV_PARAM_UNSUPPORTED, 4833 .set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 4834 .set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 4835 .set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 4836 .txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 4837 .set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 4838 .set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED, 4839 .en_stats = WMI_PDEV_PARAM_UNSUPPORTED, 4840 .mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED, 4841 .noise_detection = WMI_PDEV_PARAM_UNSUPPORTED, 4842 .noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED, 4843 .dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED, 4844 .set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED, 4845 .atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED, 4846 .atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED, 4847 .ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED, 4848 .mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED, 4849 .sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED, 4850 .signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED, 4851 .signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED, 4852 .enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED, 4853 .enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED, 4854 .cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED, 4855 .rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED, 4856 .pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED, 4857 .wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED, 4858 .arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED, 4859 .arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED, 4860 .rfkill_config = WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG, 4861 .rfkill_enable = WMI_TLV_PDEV_PARAM_RFKILL_ENABLE, 4862 .peer_stats_info_enable = WMI_TLV_PDEV_PARAM_PEER_STATS_INFO_ENABLE, 4863 }; 4864 4865 static struct wmi_peer_param_map wmi_tlv_peer_param_map = { 4866 .smps_state = WMI_TLV_PEER_SMPS_STATE, 4867 .ampdu = WMI_TLV_PEER_AMPDU, 4868 .authorize = WMI_TLV_PEER_AUTHORIZE, 4869 .chan_width = WMI_TLV_PEER_CHAN_WIDTH, 4870 .nss = WMI_TLV_PEER_NSS, 4871 .use_4addr = WMI_TLV_PEER_USE_4ADDR, 4872 .membership = WMI_TLV_PEER_MEMBERSHIP, 4873 .user_pos = WMI_TLV_PEER_USERPOS, 4874 .crit_proto_hint_enabled = WMI_TLV_PEER_CRIT_PROTO_HINT_ENABLED, 4875 .tx_fail_cnt_thr = WMI_TLV_PEER_TX_FAIL_CNT_THR, 4876 .set_hw_retry_cts2s = WMI_TLV_PEER_SET_HW_RETRY_CTS2S, 4877 .ibss_atim_win_len = WMI_TLV_PEER_IBSS_ATIM_WINDOW_LENGTH, 4878 .phymode = WMI_TLV_PEER_PHYMODE, 4879 .use_fixed_power = WMI_TLV_PEER_USE_FIXED_PWR, 4880 .dummy_var = WMI_TLV_PEER_DUMMY_VAR, 4881 }; 4882 4883 static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { 4884 .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD, 4885 .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 4886 .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL, 4887 .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL, 4888 .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE, 4889 .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE, 4890 .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME, 4891 .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE, 4892 .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME, 4893 .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD, 4894 .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME, 4895 .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL, 4896 .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD, 4897 .wmi_vdev_oc_scheduler_air_time_limit = 4898 WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 4899 .wds = WMI_TLV_VDEV_PARAM_WDS, 4900 .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW, 4901 .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX, 4902 .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT, 4903 .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT, 4904 .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM, 4905 .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH, 4906 .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET, 4907 .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION, 4908 .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT, 4909 .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE, 4910 .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE, 4911 .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE, 4912 .sgi = WMI_TLV_VDEV_PARAM_SGI, 4913 .ldpc = WMI_TLV_VDEV_PARAM_LDPC, 4914 .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC, 4915 .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC, 4916 .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD, 4917 .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID, 4918 .nss = WMI_TLV_VDEV_PARAM_NSS, 4919 .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE, 4920 .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE, 4921 .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE, 4922 .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE, 4923 .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 4924 .ap_keepalive_min_idle_inactive_time_secs = 4925 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 4926 .ap_keepalive_max_idle_inactive_time_secs = 4927 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 4928 .ap_keepalive_max_unresponsive_time_secs = 4929 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 4930 .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS, 4931 .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED, 4932 .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS, 4933 .txbf = WMI_TLV_VDEV_PARAM_TXBF, 4934 .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE, 4935 .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY, 4936 .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE, 4937 .ap_detect_out_of_sync_sleeping_sta_time_secs = 4938 WMI_TLV_VDEV_PARAM_UNSUPPORTED, 4939 .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED, 4940 .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED, 4941 .mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED, 4942 .rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED, 4943 .vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED, 4944 .vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 4945 .early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED, 4946 .early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED, 4947 .early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED, 4948 .early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED, 4949 .early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED, 4950 .early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED, 4951 .proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED, 4952 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, 4953 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, 4954 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 4955 }; 4956 4957 static const struct wmi_ops wmi_tlv_ops = { 4958 .rx = ath10k_wmi_tlv_op_rx, 4959 .map_svc = wmi_tlv_svc_map, 4960 .map_svc_ext = wmi_tlv_svc_map_ext, 4961 4962 .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev, 4963 .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev, 4964 .pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev, 4965 .pull_mgmt_tx_bundle_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev, 4966 .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev, 4967 .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev, 4968 .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev, 4969 .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev, 4970 .pull_phyerr_hdr = ath10k_wmi_tlv_op_pull_phyerr_ev_hdr, 4971 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 4972 .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev, 4973 .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev, 4974 .pull_svc_avail = ath10k_wmi_tlv_op_pull_svc_avail, 4975 .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats, 4976 .pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev, 4977 .pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev, 4978 .pull_echo_ev = ath10k_wmi_tlv_op_pull_echo_ev, 4979 .get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme, 4980 4981 .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend, 4982 .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume, 4983 .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd, 4984 .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param, 4985 .gen_init = ath10k_wmi_tlv_op_gen_init, 4986 .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan, 4987 .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan, 4988 .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create, 4989 .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete, 4990 .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start, 4991 .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop, 4992 .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up, 4993 .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down, 4994 .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param, 4995 .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key, 4996 .gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf, 4997 .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create, 4998 .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete, 4999 .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush, 5000 .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param, 5001 .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc, 5002 .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode, 5003 .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps, 5004 .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps, 5005 .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list, 5006 .gen_scan_prob_req_oui = ath10k_wmi_tlv_op_gen_scan_prob_req_oui, 5007 .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma, 5008 .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm, 5009 .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, 5010 .gen_request_peer_stats_info = ath10k_wmi_tlv_op_gen_request_peer_stats_info, 5011 .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, 5012 /* .gen_mgmt_tx = not implemented; HTT is used */ 5013 .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send, 5014 .cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send, 5015 .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, 5016 .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, 5017 .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, 5018 .gen_pdev_set_quiet_mode = ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode, 5019 .gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature, 5020 /* .gen_addba_clear_resp not implemented */ 5021 /* .gen_addba_send not implemented */ 5022 /* .gen_addba_set_resp not implemented */ 5023 /* .gen_delba_send not implemented */ 5024 .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl, 5025 .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl, 5026 .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, 5027 .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, 5028 .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive, 5029 .gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable, 5030 .gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event, 5031 .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind, 5032 .gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern, 5033 .gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern, 5034 .gen_wow_config_pno = ath10k_wmi_tlv_op_gen_config_pno, 5035 .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state, 5036 .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, 5037 .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, 5038 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 5039 .get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype, 5040 .gen_echo = ath10k_wmi_tlv_op_gen_echo, 5041 .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, 5042 .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, 5043 }; 5044 5045 static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { 5046 .auth = WMI_TLV_PEER_AUTH, 5047 .qos = WMI_TLV_PEER_QOS, 5048 .need_ptk_4_way = WMI_TLV_PEER_NEED_PTK_4_WAY, 5049 .need_gtk_2_way = WMI_TLV_PEER_NEED_GTK_2_WAY, 5050 .apsd = WMI_TLV_PEER_APSD, 5051 .ht = WMI_TLV_PEER_HT, 5052 .bw40 = WMI_TLV_PEER_40MHZ, 5053 .stbc = WMI_TLV_PEER_STBC, 5054 .ldbc = WMI_TLV_PEER_LDPC, 5055 .dyn_mimops = WMI_TLV_PEER_DYN_MIMOPS, 5056 .static_mimops = WMI_TLV_PEER_STATIC_MIMOPS, 5057 .spatial_mux = WMI_TLV_PEER_SPATIAL_MUX, 5058 .vht = WMI_TLV_PEER_VHT, 5059 .bw80 = WMI_TLV_PEER_80MHZ, 5060 .pmf = WMI_TLV_PEER_PMF, 5061 .bw160 = WMI_TLV_PEER_160MHZ, 5062 }; 5063 5064 /************/ 5065 /* TLV init */ 5066 /************/ 5067 5068 void ath10k_wmi_tlv_attach(struct ath10k *ar) 5069 { 5070 ar->wmi.cmd = &wmi_tlv_cmd_map; 5071 ar->wmi.vdev_param = &wmi_tlv_vdev_param_map; 5072 ar->wmi.pdev_param = &wmi_tlv_pdev_param_map; 5073 ar->wmi.peer_param = &wmi_tlv_peer_param_map; 5074 ar->wmi.ops = &wmi_tlv_ops; 5075 ar->wmi.peer_flags = &wmi_tlv_peer_flags_map; 5076 } 5077