Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git

ath.git patches for v5.16. Major changes:

ath11k

* fix QCA6390 A-MSDU handling (CVE-2020-24588)

wcn36xx

* enable hardware scan offload for 5Ghz band

* add missing 5GHz channels 136 and 144

+403 -100
+9 -2
drivers/net/wireless/ath/ath10k/core.c
··· 2690 2690 int i, ret; 2691 2691 u32 len, remaining_len; 2692 2692 2693 - hw_mem = ath10k_coredump_get_mem_layout(ar); 2693 + /* copy target iram feature must work also when 2694 + * ATH10K_FW_CRASH_DUMP_RAM_DATA is disabled, so 2695 + * _ath10k_coredump_get_mem_layout() to accomplist that 2696 + */ 2697 + hw_mem = _ath10k_coredump_get_mem_layout(ar); 2694 2698 if (!hw_mem) 2695 - return -ENOMEM; 2699 + /* if CONFIG_DEV_COREDUMP is disabled we get NULL, then 2700 + * just silently disable the feature by doing nothing 2701 + */ 2702 + return 0; 2696 2703 2697 2704 for (i = 0; i < hw_mem->region_table.size; i++) { 2698 2705 tmp = &hw_mem->region_table.regions[i];
+8 -3
drivers/net/wireless/ath/ath10k/coredump.c
··· 1447 1447 1448 1448 const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar) 1449 1449 { 1450 - int i; 1451 - 1452 1450 if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) 1453 1451 return NULL; 1452 + 1453 + return _ath10k_coredump_get_mem_layout(ar); 1454 + } 1455 + EXPORT_SYMBOL(ath10k_coredump_get_mem_layout); 1456 + 1457 + const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar) 1458 + { 1459 + int i; 1454 1460 1455 1461 if (WARN_ON(ar->target_version == 0)) 1456 1462 return NULL; ··· 1470 1464 1471 1465 return NULL; 1472 1466 } 1473 - EXPORT_SYMBOL(ath10k_coredump_get_mem_layout); 1474 1467 1475 1468 struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) 1476 1469 {
+7
drivers/net/wireless/ath/ath10k/coredump.h
··· 176 176 void ath10k_coredump_unregister(struct ath10k *ar); 177 177 void ath10k_coredump_destroy(struct ath10k *ar); 178 178 179 + const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar); 179 180 const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar); 180 181 181 182 #else /* CONFIG_DEV_COREDUMP */ ··· 211 210 212 211 static inline const struct ath10k_hw_mem_layout * 213 212 ath10k_coredump_get_mem_layout(struct ath10k *ar) 213 + { 214 + return NULL; 215 + } 216 + 217 + static inline const struct ath10k_hw_mem_layout * 218 + _ath10k_coredump_get_mem_layout(struct ath10k *ar) 214 219 { 215 220 return NULL; 216 221 }
+9 -1
drivers/net/wireless/ath/ath10k/mac.c
··· 5583 5583 if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) { 5584 5584 arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN, 5585 5585 GFP_KERNEL); 5586 - arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf; 5586 + 5587 + /* Using a kernel pointer in place of a dma_addr_t 5588 + * token can lead to undefined behavior if that 5589 + * makes it into cache management functions. Use a 5590 + * known-invalid address token instead, which 5591 + * avoids the warning and makes it easier to catch 5592 + * bugs if it does end up getting used. 5593 + */ 5594 + arvif->beacon_paddr = DMA_MAPPING_ERROR; 5587 5595 } else { 5588 5596 arvif->beacon_buf = 5589 5597 dma_alloc_coherent(ar->dev,
+6 -1
drivers/net/wireless/ath/ath10k/usb.c
··· 525 525 req, 526 526 USB_DIR_IN | USB_TYPE_VENDOR | 527 527 USB_RECIP_DEVICE, value, index, buf, 528 - size, 2 * HZ); 528 + size, 2000); 529 529 530 530 if (ret < 0) { 531 531 ath10k_warn(ar, "Failed to read usb control message: %d\n", ··· 853 853 le16_to_cpu(endpoint->wMaxPacketSize), 854 854 endpoint->bInterval); 855 855 } 856 + 857 + /* Ignore broken descriptors. */ 858 + if (usb_endpoint_maxp(endpoint) == 0) 859 + continue; 860 + 856 861 urbcount = 0; 857 862 858 863 pipe_num =
+5
drivers/net/wireless/ath/ath11k/core.c
··· 81 81 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), 82 82 .fix_l1ss = true, 83 83 .max_tx_ring = DP_TCL_NUM_RING_MAX, 84 + .hal_params = &ath11k_hw_hal_params_ipq8074, 84 85 }, 85 86 { 86 87 .hw_rev = ATH11K_HW_IPQ6018_HW10, ··· 130 129 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), 131 130 .fix_l1ss = true, 132 131 .max_tx_ring = DP_TCL_NUM_RING_MAX, 132 + .hal_params = &ath11k_hw_hal_params_ipq8074, 133 133 }, 134 134 { 135 135 .name = "qca6390 hw2.0", ··· 178 176 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), 179 177 .fix_l1ss = true, 180 178 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, 179 + .hal_params = &ath11k_hw_hal_params_qca6390, 181 180 }, 182 181 { 183 182 .name = "qcn9074 hw1.0", ··· 226 223 .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), 227 224 .fix_l1ss = true, 228 225 .max_tx_ring = DP_TCL_NUM_RING_MAX, 226 + .hal_params = &ath11k_hw_hal_params_ipq8074, 229 227 }, 230 228 { 231 229 .name = "wcn6855 hw2.0", ··· 274 270 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), 275 271 .fix_l1ss = false, 276 272 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, 273 + .hal_params = &ath11k_hw_hal_params_qca6390, 277 274 }, 278 275 }; 279 276
+3 -1
drivers/net/wireless/ath/ath11k/dp.c
··· 739 739 int budget) 740 740 { 741 741 struct napi_struct *napi = &irq_grp->napi; 742 + const struct ath11k_hw_hal_params *hal_params; 742 743 int grp_id = irq_grp->grp_id; 743 744 int work_done = 0; 744 745 int i = 0, j; ··· 822 821 struct ath11k_pdev_dp *dp = &ar->dp; 823 822 struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; 824 823 824 + hal_params = ab->hw_params.hal_params; 825 825 ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0, 826 - HAL_RX_BUF_RBM_SW3_BM); 826 + hal_params->rx_buf_rbm); 827 827 } 828 828 } 829 829 }
+18 -11
drivers/net/wireless/ath/ath11k/dp_rx.c
··· 499 499 500 500 rx_ring->bufs_max = num_entries; 501 501 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries, 502 - HAL_RX_BUF_RBM_SW3_BM); 502 + ar->ab->hw_params.hal_params->rx_buf_rbm); 503 503 return 0; 504 504 } 505 505 ··· 2756 2756 rx_ring = &ar->dp.rx_refill_buf_ring; 2757 2757 2758 2758 ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], 2759 - HAL_RX_BUF_RBM_SW3_BM); 2759 + ab->hw_params.hal_params->rx_buf_rbm); 2760 2760 } 2761 2761 2762 2762 ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list, ··· 2949 2949 int *budget, struct sk_buff_head *skb_list) 2950 2950 { 2951 2951 struct ath11k *ar; 2952 + const struct ath11k_hw_hal_params *hal_params; 2952 2953 struct ath11k_pdev_dp *dp; 2953 2954 struct dp_rxdma_ring *rx_ring; 2954 2955 struct hal_srng *srng; ··· 3020 3019 &buf_id); 3021 3020 3022 3021 if (!skb) { 3022 + hal_params = ab->hw_params.hal_params; 3023 3023 ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, 3024 - HAL_RX_BUF_RBM_SW3_BM); 3024 + hal_params->rx_buf_rbm); 3025 3025 num_buffs_reaped++; 3026 3026 break; 3027 3027 } ··· 3032 3030 FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); 3033 3031 3034 3032 ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, 3035 - cookie, HAL_RX_BUF_RBM_SW3_BM); 3033 + cookie, 3034 + ab->hw_params.hal_params->rx_buf_rbm); 3036 3035 ath11k_hal_srng_src_get_next_entry(ab, srng); 3037 3036 num_buffs_reaped++; 3038 3037 } ··· 3422 3419 cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) | 3423 3420 FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); 3424 3421 3425 - ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, HAL_RX_BUF_RBM_SW3_BM); 3422 + ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, 3423 + ab->hw_params.hal_params->rx_buf_rbm); 3426 3424 3427 3425 /* Fill mpdu details into reo entrace ring */ 3428 3426 srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id]; ··· 3800 3796 ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, 3801 3797 &rbm); 3802 3798 if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST && 3803 - rbm != HAL_RX_BUF_RBM_SW3_BM) { 3799 + rbm != ab->hw_params.hal_params->rx_buf_rbm) { 3804 3800 ab->soc_stats.invalid_rbm++; 3805 3801 ath11k_warn(ab, "invalid return buffer manager %d\n", rbm); 3806 3802 ath11k_dp_rx_link_desc_return(ab, desc, ··· 3856 3852 rx_ring = &ar->dp.rx_refill_buf_ring; 3857 3853 3858 3854 ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i], 3859 - HAL_RX_BUF_RBM_SW3_BM); 3855 + ab->hw_params.hal_params->rx_buf_rbm); 3860 3856 } 3861 3857 3862 3858 return tot_n_bufs_reaped; ··· 4152 4148 rx_ring = &ar->dp.rx_refill_buf_ring; 4153 4149 4154 4150 ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], 4155 - HAL_RX_BUF_RBM_SW3_BM); 4151 + ab->hw_params.hal_params->rx_buf_rbm); 4156 4152 } 4157 4153 4158 4154 rcu_read_lock(); ··· 4261 4257 4262 4258 if (num_buf_freed) 4263 4259 ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed, 4264 - HAL_RX_BUF_RBM_SW3_BM); 4260 + ab->hw_params.hal_params->rx_buf_rbm); 4265 4261 4266 4262 return budget - quota; 4267 4263 } ··· 4980 4976 { 4981 4977 struct ath11k_pdev_dp *dp = &ar->dp; 4982 4978 struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; 4979 + const struct ath11k_hw_hal_params *hal_params; 4983 4980 void *ring_entry; 4984 4981 void *mon_dst_srng; 4985 4982 u32 ppdu_id; ··· 5044 5039 5045 5040 if (rx_bufs_used) { 5046 5041 rx_mon_stats->dest_ppdu_done++; 5042 + hal_params = ar->ab->hw_params.hal_params; 5043 + 5047 5044 if (ar->ab->hw_params.rxdma1_enable) 5048 5045 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, 5049 5046 &dp->rxdma_mon_buf_ring, 5050 5047 rx_bufs_used, 5051 - HAL_RX_BUF_RBM_SW3_BM); 5048 + hal_params->rx_buf_rbm); 5052 5049 else 5053 5050 ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, 5054 5051 &dp->rx_refill_buf_ring, 5055 5052 rx_bufs_used, 5056 - HAL_RX_BUF_RBM_SW3_BM); 5053 + hal_params->rx_buf_rbm); 5057 5054 } 5058 5055 } 5059 5056
+4 -2
drivers/net/wireless/ath/ath11k/hal_rx.c
··· 356 356 struct hal_wbm_release_ring *wbm_desc = desc; 357 357 enum hal_wbm_rel_desc_type type; 358 358 enum hal_wbm_rel_src_module rel_src; 359 + enum hal_rx_buf_return_buf_manager ret_buf_mgr; 359 360 360 361 type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, 361 362 wbm_desc->info0); ··· 372 371 rel_src != HAL_WBM_REL_SRC_MODULE_REO) 373 372 return -EINVAL; 374 373 375 - if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 376 - wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) { 374 + ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 375 + wbm_desc->buf_addr_info.info1); 376 + if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) { 377 377 ab->soc_stats.invalid_rbm++; 378 378 return -EINVAL; 379 379 }
+10 -1
drivers/net/wireless/ath/ath11k/hw.c
··· 7 7 #include <linux/bitops.h> 8 8 #include <linux/bitfield.h> 9 9 10 - #include "hw.h" 11 10 #include "core.h" 12 11 #include "ce.h" 13 12 #include "hif.h" 13 + #include "hal.h" 14 + #include "hw.h" 14 15 15 16 /* Map from pdev index to hw mac index */ 16 17 static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx) ··· 2124 2123 /* PCIe base address */ 2125 2124 .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, 2126 2125 .pcie_pcs_osc_dtct_config_base = 0x01e0c628, 2126 + }; 2127 + 2128 + const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { 2129 + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, 2130 + }; 2131 + 2132 + const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = { 2133 + .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, 2127 2134 };
+9
drivers/net/wireless/ath/ath11k/hw.h
··· 6 6 #ifndef ATH11K_HW_H 7 7 #define ATH11K_HW_H 8 8 9 + #include "hal.h" 9 10 #include "wmi.h" 10 11 11 12 /* Target configuration defines */ ··· 120 119 u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX]; 121 120 }; 122 121 122 + struct ath11k_hw_hal_params { 123 + enum hal_rx_buf_return_buf_manager rx_buf_rbm; 124 + }; 125 + 123 126 struct ath11k_hw_params { 124 127 const char *name; 125 128 u16 hw_rev; ··· 175 170 u32 hal_desc_sz; 176 171 bool fix_l1ss; 177 172 u8 max_tx_ring; 173 + const struct ath11k_hw_hal_params *hal_params; 178 174 }; 179 175 180 176 struct ath11k_hw_ops { ··· 228 222 extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; 229 223 extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; 230 224 extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; 225 + 226 + extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074; 227 + extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390; 231 228 232 229 static inline 233 230 int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw,
+6 -1
drivers/net/wireless/ath/ath6kl/usb.c
··· 340 340 le16_to_cpu(endpoint->wMaxPacketSize), 341 341 endpoint->bInterval); 342 342 } 343 + 344 + /* Ignore broken descriptors. */ 345 + if (usb_endpoint_maxp(endpoint) == 0) 346 + continue; 347 + 343 348 urbcount = 0; 344 349 345 350 pipe_num = ··· 912 907 req, 913 908 USB_DIR_IN | USB_TYPE_VENDOR | 914 909 USB_RECIP_DEVICE, value, index, buf, 915 - size, 2 * HZ); 910 + size, 2000); 916 911 917 912 if (ret < 0) { 918 913 ath6kl_warn("Failed to read usb control message: %d\n", ret);
+26 -23
drivers/net/wireless/ath/wcn36xx/dxe.c
··· 403 403 dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, 404 404 ctl->skb->len, DMA_TO_DEVICE); 405 405 info = IEEE80211_SKB_CB(ctl->skb); 406 - if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { 407 - /* Keep frame until TX status comes */ 406 + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { 407 + if (info->flags & IEEE80211_TX_CTL_NO_ACK) { 408 + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; 409 + ieee80211_tx_status_irqsafe(wcn->hw, ctl->skb); 410 + } else { 411 + /* Wait for the TX ack indication or timeout... */ 412 + spin_lock(&wcn->dxe_lock); 413 + if (WARN_ON(wcn->tx_ack_skb)) 414 + ieee80211_free_txskb(wcn->hw, wcn->tx_ack_skb); 415 + wcn->tx_ack_skb = ctl->skb; /* Tracking ref */ 416 + mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); 417 + spin_unlock(&wcn->dxe_lock); 418 + } 419 + /* do not free, ownership transferred to mac80211 status cb */ 420 + } else { 408 421 ieee80211_free_txskb(wcn->hw, ctl->skb); 409 422 } 410 423 ··· 439 426 { 440 427 struct wcn36xx *wcn = (struct wcn36xx *)dev; 441 428 int int_src, int_reason; 442 - bool transmitted = false; 443 429 444 430 wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src); 445 431 ··· 478 466 if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK | 479 467 WCN36XX_CH_STAT_INT_ED_MASK)) { 480 468 reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); 481 - transmitted = true; 482 469 } 483 470 } 484 471 ··· 489 478 wcn36xx_dxe_write_register(wcn, 490 479 WCN36XX_DXE_0_INT_CLR, 491 480 WCN36XX_INT_MASK_CHAN_TX_L); 492 - 493 481 494 482 if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) { 495 483 wcn36xx_dxe_write_register(wcn, ··· 517 507 if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK | 518 508 WCN36XX_CH_STAT_INT_ED_MASK)) { 519 509 reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); 520 - transmitted = true; 521 510 } 522 511 } 523 - 524 - spin_lock(&wcn->dxe_lock); 525 - if (wcn->tx_ack_skb && transmitted) { 526 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(wcn->tx_ack_skb); 527 - 528 - /* TX complete, no need to wait for 802.11 ack indication */ 529 - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS && 530 - info->flags & IEEE80211_TX_CTL_NO_ACK) { 531 - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; 532 - del_timer(&wcn->tx_ack_timer); 533 - ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb); 534 - wcn->tx_ack_skb = NULL; 535 - ieee80211_wake_queues(wcn->hw); 536 - } 537 - } 538 - spin_unlock(&wcn->dxe_lock); 539 512 540 513 return IRQ_HANDLED; 541 514 } ··· 606 613 dxe = ctl->desc; 607 614 608 615 while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) { 616 + /* do not read until we own DMA descriptor */ 617 + dma_rmb(); 618 + 619 + /* read/modify DMA descriptor */ 609 620 skb = ctl->skb; 610 621 dma_addr = dxe->dst_addr_l; 611 622 ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC); ··· 620 623 dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, 621 624 DMA_FROM_DEVICE); 622 625 wcn36xx_rx_skb(wcn, skb); 623 - } /* else keep old skb not submitted and use it for rx DMA */ 626 + } 627 + /* else keep old skb not submitted and reuse it for rx DMA 628 + * (dropping the packet that it contained) 629 + */ 624 630 631 + /* flush descriptor changes before re-marking as valid */ 632 + dma_wmb(); 625 633 dxe->ctrl = ctrl; 634 + 626 635 ctl = ctl->next; 627 636 dxe = ctl->desc; 628 637 }
+32
drivers/net/wireless/ath/wcn36xx/hal.h
··· 359 359 WCN36XX_HAL_START_SCAN_OFFLOAD_RSP = 205, 360 360 WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ = 206, 361 361 WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP = 207, 362 + WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ = 208, 363 + WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP = 209, 362 364 WCN36XX_HAL_SCAN_OFFLOAD_IND = 210, 363 365 364 366 WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233, ··· 1353 1351 1354 1352 /* success or failure */ 1355 1353 u32 status; 1354 + } __packed; 1355 + 1356 + #define WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK 0x000000ff 1357 + #define WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK 0x0000ff00 1358 + #define WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK 0x00ff0000 1359 + #define WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK 0xff000000 1360 + #define WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK 0x000000ff 1361 + #define WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE BIT(7) 1362 + #define WCN36XX_HAL_CHAN_INFO_FLAG_DFS BIT(10) 1363 + #define WCN36XX_HAL_CHAN_INFO_FLAG_HT BIT(11) 1364 + #define WCN36XX_HAL_CHAN_INFO_FLAG_VHT BIT(12) 1365 + #define WCN36XX_HAL_CHAN_INFO_PHY_11A 0 1366 + #define WCN36XX_HAL_CHAN_INFO_PHY_11BG 1 1367 + #define WCN36XX_HAL_DEFAULT_ANT_GAIN 6 1368 + #define WCN36XX_HAL_DEFAULT_MIN_POWER 6 1369 + 1370 + struct wcn36xx_hal_channel_param { 1371 + u32 mhz; 1372 + u32 band_center_freq1; 1373 + u32 band_center_freq2; 1374 + u32 channel_info; 1375 + u32 reg_info_1; 1376 + u32 reg_info_2; 1377 + } __packed; 1378 + 1379 + struct wcn36xx_hal_update_channel_list_req_msg { 1380 + struct wcn36xx_hal_msg_header header; 1381 + 1382 + u8 num_channel; 1383 + struct wcn36xx_hal_channel_param channels[80]; 1356 1384 } __packed; 1357 1385 1358 1386 enum wcn36xx_hal_rate_index {
+26 -18
drivers/net/wireless/ath/wcn36xx/main.c
··· 85 85 CHAN5G(5620, 124, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 86 86 CHAN5G(5640, 128, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 87 87 CHAN5G(5660, 132, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 88 + CHAN5G(5680, 136, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 88 89 CHAN5G(5700, 140, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), 90 + CHAN5G(5720, 144, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), 89 91 CHAN5G(5745, 149, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), 90 92 CHAN5G(5765, 153, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), 91 93 CHAN5G(5785, 157, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), ··· 137 135 .cap = IEEE80211_HT_CAP_GRN_FLD | 138 136 IEEE80211_HT_CAP_SGI_20 | 139 137 IEEE80211_HT_CAP_DSSSCCK40 | 140 - IEEE80211_HT_CAP_LSIG_TXOP_PROT, 138 + IEEE80211_HT_CAP_LSIG_TXOP_PROT | 139 + IEEE80211_HT_CAP_SGI_40 | 140 + IEEE80211_HT_CAP_SUP_WIDTH_20_40, 141 141 .ht_supported = true, 142 142 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, 143 143 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ··· 617 613 } 618 614 } 619 615 } 620 - /* FIXME: Only enable bmps support when encryption is enabled. 621 - * For any reasons, when connected to open/no-security BSS, 622 - * the wcn36xx controller in bmps mode does not forward 623 - * 'wake-up' beacons despite AP sends DTIM with station AID. 624 - * It could be due to a firmware issue or to the way driver 625 - * configure the station. 626 - */ 627 - if (vif->type == NL80211_IFTYPE_STATION) 628 - vif_priv->allow_bmps = true; 629 616 break; 630 617 case DISABLE_KEY: 631 618 if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { ··· 654 659 struct ieee80211_scan_request *hw_req) 655 660 { 656 661 struct wcn36xx *wcn = hw->priv; 657 - int i; 658 662 659 663 if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { 660 664 /* fallback to mac80211 software scan */ 661 665 return 1; 662 666 } 663 667 664 - /* For unknown reason, the hardware offloaded scan only works with 665 - * 2.4Ghz channels, fallback to software scan in other cases. 668 + /* Firmware scan offload is limited to 48 channels, fallback to 669 + * software driven scanning otherwise. 666 670 */ 667 - for (i = 0; i < hw_req->req.n_channels; i++) { 668 - if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ) 669 - return 1; 671 + if (hw_req->req.n_channels > 48) { 672 + wcn36xx_warn("Offload scan aborted, n_channels=%u", 673 + hw_req->req.n_channels); 674 + return 1; 670 675 } 671 676 672 677 mutex_lock(&wcn->scan_lock); ··· 680 685 681 686 mutex_unlock(&wcn->scan_lock); 682 687 688 + wcn36xx_smd_update_channel_list(wcn, &hw_req->req); 683 689 return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req); 684 690 } 685 691 ··· 918 922 vif->addr, 919 923 bss_conf->aid); 920 924 vif_priv->sta_assoc = false; 921 - vif_priv->allow_bmps = false; 922 925 wcn36xx_smd_set_link_st(wcn, 923 926 bss_conf->bssid, 924 927 vif->addr, ··· 1127 1132 goto out; 1128 1133 ret = wcn36xx_smd_wlan_host_suspend_ind(wcn); 1129 1134 } 1135 + 1136 + /* Disable IRQ, we don't want to handle any packet before mac80211 is 1137 + * resumed and ready to receive packets. 1138 + */ 1139 + disable_irq(wcn->tx_irq); 1140 + disable_irq(wcn->rx_irq); 1141 + 1130 1142 out: 1131 1143 mutex_unlock(&wcn->conf_mutex); 1132 1144 return ret; ··· 1156 1154 wcn36xx_smd_ipv6_ns_offload(wcn, vif, false); 1157 1155 wcn36xx_smd_arp_offload(wcn, vif, false); 1158 1156 } 1157 + 1158 + enable_irq(wcn->tx_irq); 1159 + enable_irq(wcn->rx_irq); 1160 + 1159 1161 mutex_unlock(&wcn->conf_mutex); 1160 1162 1161 1163 return 0; ··· 1353 1347 ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL); 1354 1348 ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS); 1355 1349 ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS); 1356 - ieee80211_hw_set(wcn->hw, CONNECTION_MONITOR); 1357 1350 1358 1351 wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1359 1352 BIT(NL80211_IFTYPE_AP) | ··· 1504 1499 mutex_init(&wcn->conf_mutex); 1505 1500 mutex_init(&wcn->hal_mutex); 1506 1501 mutex_init(&wcn->scan_lock); 1502 + __skb_queue_head_init(&wcn->amsdu); 1507 1503 1508 1504 wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); 1509 1505 if (!wcn->hal_buf) { ··· 1581 1575 1582 1576 iounmap(wcn->dxe_base); 1583 1577 iounmap(wcn->ccu_base); 1578 + 1579 + __skb_queue_purge(&wcn->amsdu); 1584 1580 1585 1581 mutex_destroy(&wcn->hal_mutex); 1586 1582 ieee80211_free_hw(hw);
+9 -4
drivers/net/wireless/ath/wcn36xx/pmc.c
··· 18 18 19 19 #include "wcn36xx.h" 20 20 21 + #define WCN36XX_BMPS_FAIL_THREHOLD 3 22 + 21 23 int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, 22 24 struct ieee80211_vif *vif) 23 25 { 24 26 int ret = 0; 25 27 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); 26 - 27 - if (!vif_priv->allow_bmps) 28 - return -ENOTSUPP; 29 - 28 + /* TODO: Make sure the TX chain clean */ 30 29 ret = wcn36xx_smd_enter_bmps(wcn, vif); 31 30 if (!ret) { 32 31 wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n"); 33 32 vif_priv->pw_state = WCN36XX_BMPS; 33 + vif_priv->bmps_fail_ct = 0; 34 34 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; 35 35 } else { 36 36 /* ··· 39 39 * received just after auth complete 40 40 */ 41 41 wcn36xx_err("Can not enter BMPS!\n"); 42 + 43 + if (vif_priv->bmps_fail_ct++ == WCN36XX_BMPS_FAIL_THREHOLD) { 44 + ieee80211_connection_loss(vif); 45 + vif_priv->bmps_fail_ct = 0; 46 + } 42 47 } 43 48 return ret; 44 49 }
+88 -2
drivers/net/wireless/ath/wcn36xx/smd.c
··· 16 16 17 17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 18 19 + #include <linux/bitfield.h> 19 20 #include <linux/etherdevice.h> 20 21 #include <linux/firmware.h> 21 22 #include <linux/bitops.h> ··· 267 266 268 267 sta_params->max_ampdu_size = sta->ht_cap.ampdu_factor; 269 268 sta_params->max_ampdu_density = sta->ht_cap.ampdu_density; 270 - sta_params->max_amsdu_size = is_cap_supported(caps, 269 + /* max_amsdu_size: 1 : 3839 bytes, 0 : 7935 bytes (max) */ 270 + sta_params->max_amsdu_size = !is_cap_supported(caps, 271 271 IEEE80211_HT_CAP_MAX_AMSDU); 272 272 sta_params->sgi_20Mhz = is_cap_supported(caps, 273 273 IEEE80211_HT_CAP_SGI_20); ··· 925 923 goto out; 926 924 } 927 925 out: 926 + mutex_unlock(&wcn->hal_mutex); 927 + return ret; 928 + } 929 + 930 + int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req) 931 + { 932 + struct wcn36xx_hal_update_channel_list_req_msg *msg_body; 933 + int ret, i; 934 + 935 + msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL); 936 + if (!msg_body) 937 + return -ENOMEM; 938 + 939 + INIT_HAL_MSG((*msg_body), WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ); 940 + 941 + msg_body->num_channel = min_t(u8, req->n_channels, sizeof(msg_body->channels)); 942 + for (i = 0; i < msg_body->num_channel; i++) { 943 + struct wcn36xx_hal_channel_param *param = &msg_body->channels[i]; 944 + u32 min_power = WCN36XX_HAL_DEFAULT_MIN_POWER; 945 + u32 ant_gain = WCN36XX_HAL_DEFAULT_ANT_GAIN; 946 + 947 + param->mhz = req->channels[i]->center_freq; 948 + param->band_center_freq1 = req->channels[i]->center_freq; 949 + param->band_center_freq2 = 0; 950 + 951 + if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) 952 + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE; 953 + 954 + if (req->channels[i]->flags & IEEE80211_CHAN_RADAR) 955 + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_DFS; 956 + 957 + if (req->channels[i]->band == NL80211_BAND_5GHZ) { 958 + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_HT; 959 + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_VHT; 960 + param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11A; 961 + } else { 962 + param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11BG; 963 + } 964 + 965 + if (min_power > req->channels[i]->max_power) 966 + min_power = req->channels[i]->max_power; 967 + 968 + if (req->channels[i]->max_antenna_gain) 969 + ant_gain = req->channels[i]->max_antenna_gain; 970 + 971 + u32p_replace_bits(&param->reg_info_1, min_power, 972 + WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK); 973 + u32p_replace_bits(&param->reg_info_1, req->channels[i]->max_power, 974 + WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK); 975 + u32p_replace_bits(&param->reg_info_1, req->channels[i]->max_reg_power, 976 + WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK); 977 + u32p_replace_bits(&param->reg_info_1, 0, 978 + WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK); 979 + u32p_replace_bits(&param->reg_info_2, ant_gain, 980 + WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK); 981 + 982 + wcn36xx_dbg(WCN36XX_DBG_HAL, 983 + "%s: freq=%u, channel_info=%08x, reg_info1=%08x, reg_info2=%08x\n", 984 + __func__, param->mhz, param->channel_info, param->reg_info_1, 985 + param->reg_info_2); 986 + } 987 + 988 + mutex_lock(&wcn->hal_mutex); 989 + 990 + PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body)); 991 + 992 + ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len); 993 + if (ret) { 994 + wcn36xx_err("Sending hal_update_channel_list failed\n"); 995 + goto out; 996 + } 997 + 998 + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); 999 + if (ret) { 1000 + wcn36xx_err("hal_update_channel_list response failed err=%d\n", ret); 1001 + goto out; 1002 + } 1003 + 1004 + out: 1005 + kfree(msg_body); 928 1006 mutex_unlock(&wcn->hal_mutex); 929 1007 return ret; 930 1008 } ··· 2476 2394 INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ); 2477 2395 2478 2396 set_feat_caps(msg_body.feat_caps, STA_POWERSAVE); 2479 - if (wcn->rf_id == RF_IRIS_WCN3680) 2397 + if (wcn->rf_id == RF_IRIS_WCN3680) { 2480 2398 set_feat_caps(msg_body.feat_caps, DOT11AC); 2399 + set_feat_caps(msg_body.feat_caps, WLAN_CH144); 2400 + set_feat_caps(msg_body.feat_caps, ANTENNA_DIVERSITY_SELECTION); 2401 + } 2481 2402 2482 2403 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 2483 2404 ··· 3222 3137 case WCN36XX_HAL_HOST_RESUME_RSP: 3223 3138 case WCN36XX_HAL_ENTER_IMPS_RSP: 3224 3139 case WCN36XX_HAL_EXIT_IMPS_RSP: 3140 + case WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP: 3225 3141 memcpy(wcn->hal_buf, buf, len); 3226 3142 wcn->hal_rsp_len = len; 3227 3143 complete(&wcn->hal_rsp_compl);
+1
drivers/net/wireless/ath/wcn36xx/smd.h
··· 70 70 int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, 71 71 struct cfg80211_scan_request *req); 72 72 int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn); 73 + int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req); 73 74 int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); 74 75 int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); 75 76 int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index);
+120 -27
drivers/net/wireless/ath/wcn36xx/txrx.c
··· 31 31 enum rate_info_bw bw; 32 32 }; 33 33 34 + /* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used 35 + * for 11A Channels. 36 + */ 37 + static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 38 + 108, 112, 116, 120, 124, 128, 132, 136, 140, 39 + 149, 153, 157, 161, 165, 144 }; 40 + 34 41 static const struct wcn36xx_rate wcn36xx_rate_table[] = { 35 42 /* 11b rates */ 36 43 { 10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, ··· 231 224 { 4333, 9, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, 232 225 }; 233 226 227 + static struct sk_buff *wcn36xx_unchain_msdu(struct sk_buff_head *amsdu) 228 + { 229 + struct sk_buff *skb, *first; 230 + int total_len = 0; 231 + int space; 232 + 233 + first = __skb_dequeue(amsdu); 234 + 235 + skb_queue_walk(amsdu, skb) 236 + total_len += skb->len; 237 + 238 + space = total_len - skb_tailroom(first); 239 + if (space > 0 && pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0) { 240 + __skb_queue_head(amsdu, first); 241 + return NULL; 242 + } 243 + 244 + /* Walk list again, copying contents into msdu_head */ 245 + while ((skb = __skb_dequeue(amsdu))) { 246 + skb_copy_from_linear_data(skb, skb_put(first, skb->len), 247 + skb->len); 248 + dev_kfree_skb_irq(skb); 249 + } 250 + 251 + return first; 252 + } 253 + 254 + static void __skb_queue_purge_irq(struct sk_buff_head *list) 255 + { 256 + struct sk_buff *skb; 257 + 258 + while ((skb = __skb_dequeue(list)) != NULL) 259 + dev_kfree_skb_irq(skb); 260 + } 261 + 234 262 int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) 235 263 { 236 264 struct ieee80211_rx_status status; ··· 286 244 wcn36xx_dbg_dump(WCN36XX_DBG_RX_DUMP, 287 245 "BD <<< ", (char *)bd, 288 246 sizeof(struct wcn36xx_rx_bd)); 247 + 248 + if (bd->pdu.mpdu_data_off <= bd->pdu.mpdu_header_off || 249 + bd->pdu.mpdu_len < bd->pdu.mpdu_header_len) 250 + goto drop; 251 + 252 + if (bd->asf && !bd->esf) { /* chained A-MSDU chunks */ 253 + /* Sanity check */ 254 + if (bd->pdu.mpdu_data_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE) 255 + goto drop; 256 + 257 + skb_put(skb, bd->pdu.mpdu_data_off + bd->pdu.mpdu_len); 258 + skb_pull(skb, bd->pdu.mpdu_data_off); 259 + 260 + /* Only set status for first chained BD (with mac header) */ 261 + goto done; 262 + } 263 + 264 + if (bd->pdu.mpdu_header_off < sizeof(*bd) || 265 + bd->pdu.mpdu_header_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE) 266 + goto drop; 289 267 290 268 skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len); 291 269 skb_pull(skb, bd->pdu.mpdu_header_off); ··· 353 291 ieee80211_is_probe_resp(hdr->frame_control)) 354 292 status.boottime_ns = ktime_get_boottime_ns(); 355 293 294 + if (bd->scan_learn) { 295 + /* If packet originates from hardware scanning, extract the 296 + * band/channel from bd descriptor. 297 + */ 298 + u8 hwch = (bd->reserved0 << 4) + bd->rx_ch; 299 + 300 + if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) { 301 + status.band = NL80211_BAND_5GHZ; 302 + status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1], 303 + status.band); 304 + } else { 305 + status.band = NL80211_BAND_2GHZ; 306 + status.freq = ieee80211_channel_to_frequency(hwch, status.band); 307 + } 308 + } 309 + 356 310 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 357 311 358 312 if (ieee80211_is_beacon(hdr->frame_control)) { ··· 383 305 (char *)skb->data, skb->len); 384 306 } 385 307 308 + done: 309 + /* Chained AMSDU ? slow path */ 310 + if (unlikely(bd->asf && !(bd->lsf && bd->esf))) { 311 + if (bd->esf && !skb_queue_empty(&wcn->amsdu)) { 312 + wcn36xx_err("Discarding non complete chain"); 313 + __skb_queue_purge_irq(&wcn->amsdu); 314 + } 315 + 316 + __skb_queue_tail(&wcn->amsdu, skb); 317 + 318 + if (!bd->lsf) 319 + return 0; /* Not the last AMSDU, wait for more */ 320 + 321 + skb = wcn36xx_unchain_msdu(&wcn->amsdu); 322 + if (!skb) 323 + goto drop; 324 + } 325 + 386 326 ieee80211_rx_irqsafe(wcn->hw, skb); 387 327 388 328 return 0; 329 + 330 + drop: /* drop everything */ 331 + wcn36xx_err("Drop frame! skb:%p len:%u hoff:%u doff:%u asf=%u esf=%u lsf=%u\n", 332 + skb, bd->pdu.mpdu_len, bd->pdu.mpdu_header_off, 333 + bd->pdu.mpdu_data_off, bd->asf, bd->esf, bd->lsf); 334 + 335 + dev_kfree_skb_irq(skb); 336 + __skb_queue_purge_irq(&wcn->amsdu); 337 + 338 + return -EINVAL; 389 339 } 390 340 391 341 static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd, ··· 427 321 bd->pdu.mpdu_header_off; 428 322 bd->pdu.mpdu_len = len; 429 323 bd->pdu.tid = tid; 430 - /* Use seq number generated by mac80211 */ 431 - bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; 432 324 } 433 325 434 326 static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, ··· 523 419 tid = ieee80211_get_tid(hdr); 524 420 /* TID->QID is one-to-one mapping */ 525 421 bd->queue_id = tid; 422 + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS; 423 + } else { 424 + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; 526 425 } 527 426 528 427 if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT || ··· 536 429 if (ieee80211_is_any_nullfunc(hdr->frame_control)) { 537 430 /* Don't use a regular queue for null packet (no ampdu) */ 538 431 bd->queue_id = WCN36XX_TX_U_WQ_ID; 432 + bd->bd_rate = WCN36XX_BD_RATE_CTRL; 433 + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) 434 + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; 539 435 } 540 436 541 437 if (bcast) { ··· 598 488 bd->queue_id = WCN36XX_TX_U_WQ_ID; 599 489 *vif_priv = __vif_priv; 600 490 491 + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; 492 + 601 493 wcn36xx_set_tx_pdu(bd, 602 494 ieee80211_is_data_qos(hdr->frame_control) ? 603 495 sizeof(struct ieee80211_qos_hdr) : ··· 614 502 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 615 503 struct wcn36xx_vif *vif_priv = NULL; 616 504 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 617 - unsigned long flags; 618 505 bool is_low = ieee80211_is_data(hdr->frame_control); 619 506 bool bcast = is_broadcast_ether_addr(hdr->addr1) || 620 507 is_multicast_ether_addr(hdr->addr1); 508 + bool ack_ind = (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && 509 + !(info->flags & IEEE80211_TX_CTL_NO_ACK); 621 510 struct wcn36xx_tx_bd bd; 622 511 int ret; 623 512 ··· 634 521 635 522 bd.dpu_rf = WCN36XX_BMU_WQ_TX; 636 523 637 - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { 524 + if (unlikely(ack_ind)) { 638 525 wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); 639 - 640 - spin_lock_irqsave(&wcn->dxe_lock, flags); 641 - if (wcn->tx_ack_skb) { 642 - spin_unlock_irqrestore(&wcn->dxe_lock, flags); 643 - wcn36xx_warn("tx_ack_skb already set\n"); 644 - return -EINVAL; 645 - } 646 - 647 - wcn->tx_ack_skb = skb; 648 - spin_unlock_irqrestore(&wcn->dxe_lock, flags); 649 526 650 527 /* Only one at a time is supported by fw. Stop the TX queues 651 528 * until the ack status gets back. 652 529 */ 653 530 ieee80211_stop_queues(wcn->hw); 654 531 655 - /* TX watchdog if no TX irq or ack indication received */ 656 - mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); 657 - 658 532 /* Request ack indication from the firmware */ 659 - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 660 - bd.tx_comp = 1; 533 + bd.tx_comp = 1; 661 534 } 662 535 663 536 /* Data frames served first*/ ··· 657 558 bd.tx_bd_sign = 0xbdbdbdbd; 658 559 659 560 ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low); 660 - if (ret && (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { 661 - /* If the skb has not been transmitted, 662 - * don't keep a reference to it. 663 - */ 664 - spin_lock_irqsave(&wcn->dxe_lock, flags); 665 - wcn->tx_ack_skb = NULL; 666 - spin_unlock_irqrestore(&wcn->dxe_lock, flags); 667 - 561 + if (unlikely(ret && ack_ind)) { 562 + /* If the skb has not been transmitted, resume TX queue */ 668 563 ieee80211_wake_queues(wcn->hw); 669 564 } 670 565
+2 -1
drivers/net/wireless/ath/wcn36xx/txrx.h
··· 110 110 /* 0x44 */ 111 111 u32 exp_seq_num:12; 112 112 u32 cur_seq_num:12; 113 - u32 fr_type_subtype:8; 113 + u32 rf_band:2; 114 + u32 fr_type_subtype:6; 114 115 115 116 /* 0x48 */ 116 117 u32 msdu_size:16;
+5 -2
drivers/net/wireless/ath/wcn36xx/wcn36xx.h
··· 128 128 enum wcn36xx_hal_bss_type bss_type; 129 129 130 130 /* Power management */ 131 - bool allow_bmps; 132 131 enum wcn36xx_power_state pw_state; 133 132 134 133 u8 bss_index; ··· 150 151 } rekey_data; 151 152 152 153 struct list_head sta_list; 154 + 155 + int bmps_fail_ct; 153 156 }; 154 157 155 158 /** ··· 270 269 struct sk_buff *tx_ack_skb; 271 270 struct timer_list tx_ack_timer; 272 271 272 + /* For A-MSDU re-aggregation */ 273 + struct sk_buff_head amsdu; 274 + 273 275 /* RF module */ 274 276 unsigned rf_id; 275 277 ··· 280 276 /* Debug file system entry */ 281 277 struct wcn36xx_dfs_entry dfs; 282 278 #endif /* CONFIG_WCN36XX_DEBUGFS */ 283 - 284 279 }; 285 280 286 281 static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,