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 5.3. Major changes:

ath10k

* enable SDIO support, first one being QCA6174 hw3.2

+1018 -251
+1 -1
drivers/net/wireless/ath/ath10k/ahb.c
··· 740 740 enum ath10k_hw_rev hw_rev; 741 741 size_t size; 742 742 int ret; 743 - struct ath10k_bus_params bus_params; 743 + struct ath10k_bus_params bus_params = {}; 744 744 745 745 of_id = of_match_device(ath10k_ahb_of_match, &pdev->dev); 746 746 if (!of_id) {
+44 -4
drivers/net/wireless/ath/ath10k/core.c
··· 154 154 .fw_diag_ce_download = false, 155 155 }, 156 156 { 157 + .id = QCA6174_HW_3_2_VERSION, 158 + .dev_id = QCA6174_3_2_DEVICE_ID, 159 + .bus = ATH10K_BUS_SDIO, 160 + .name = "qca6174 hw3.2 sdio", 161 + .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, 162 + .uart_pin = 19, 163 + .otp_exe_param = 0, 164 + .channel_counters_freq_hz = 88000, 165 + .max_probe_resp_desc_thres = 0, 166 + .cal_data_len = 0, 167 + .fw = { 168 + .dir = QCA6174_HW_3_0_FW_DIR, 169 + .board = QCA6174_HW_3_0_BOARD_DATA_FILE, 170 + .board_size = QCA6174_BOARD_DATA_SZ, 171 + .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, 172 + }, 173 + .hw_ops = &qca6174_ops, 174 + .hw_clk = qca6174_clk, 175 + .target_cpu_freq = 176000000, 176 + .decap_align_bytes = 4, 177 + .n_cipher_suites = 8, 178 + .num_peers = 10, 179 + .ast_skid_limit = 0x10, 180 + .num_wds_entries = 0x20, 181 + .uart_pin_workaround = true, 182 + }, 183 + { 157 184 .id = QCA6174_HW_2_1_VERSION, 158 185 .dev_id = QCA6164_2_1_DEVICE_ID, 159 186 .bus = ATH10K_BUS_PCI, ··· 656 629 complete(&ar->target_suspend); 657 630 } 658 631 659 - static void ath10k_init_sdio(struct ath10k *ar) 632 + static void ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode) 660 633 { 661 634 u32 param = 0; 662 635 ··· 673 646 * not big enough for mac80211 / native wifi frames. disable it 674 647 */ 675 648 param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE; 676 - param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET; 649 + 650 + if (mode == ATH10K_FIRMWARE_MODE_UTF) 651 + param &= ~HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET; 652 + else 653 + param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET; 654 + 677 655 ath10k_bmi_write32(ar, hi_acs_flags, param); 678 656 679 657 /* Explicitly set fwlog prints to zero as target may turn it on ··· 2097 2065 return ret; 2098 2066 } 2099 2067 2100 - if (!uart_print) 2068 + if (!uart_print && ar->hw_params.uart_pin_workaround) { 2069 + ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 2070 + ar->hw_params.uart_pin); 2071 + if (ret) { 2072 + ath10k_warn(ar, "failed to set UART TX pin: %d", ret); 2073 + return ret; 2074 + } 2075 + 2101 2076 return 0; 2077 + } 2102 2078 2103 2079 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin); 2104 2080 if (ret) { ··· 2541 2501 goto err; 2542 2502 2543 2503 if (ar->hif.bus == ATH10K_BUS_SDIO) 2544 - ath10k_init_sdio(ar); 2504 + ath10k_init_sdio(ar, mode); 2545 2505 } 2546 2506 2547 2507 ar->htc.htc_ops.target_send_suspend_complete =
+11 -1
drivers/net/wireless/ath/ath10k/core.h
··· 196 196 struct list_head list; 197 197 198 198 u8 peer_macaddr[ETH_ALEN]; 199 - u32 rx_duration; 199 + u64 rx_duration; 200 200 }; 201 201 202 202 struct ath10k_fw_stats_vdev { ··· 400 400 401 401 /* protected by ar->data_lock */ 402 402 struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; 403 + union htt_rx_pn_t tids_last_pn[ATH10K_TXRX_NUM_EXT_TIDS]; 404 + bool tids_last_pn_valid[ATH10K_TXRX_NUM_EXT_TIDS]; 405 + union htt_rx_pn_t frag_tids_last_pn[ATH10K_TXRX_NUM_EXT_TIDS]; 406 + u32 frag_tids_seq[ATH10K_TXRX_NUM_EXT_TIDS]; 407 + struct { 408 + enum htt_security_types sec_type; 409 + int pn_len; 410 + } rx_pn[ATH10K_HTT_TXRX_PEER_SECURITY_MAX]; 403 411 }; 404 412 405 413 struct ath10k_txq { ··· 622 614 bool fw_stats_done; 623 615 624 616 unsigned long htt_stats_mask; 617 + unsigned long reset_htt_stats; 625 618 struct delayed_work htt_stats_dwork; 626 619 struct ath10k_dfs_stats dfs_stats; 627 620 struct ath_dfs_pool_stats dfs_pool_stats; ··· 928 919 u32 chip_id; 929 920 enum ath10k_dev_type dev_type; 930 921 bool link_can_suspend; 922 + bool hl_msdu_ids; 931 923 }; 932 924 933 925 struct ath10k {
+2 -2
drivers/net/wireless/ath/ath10k/coredump.c
··· 1192 1192 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask)) { 1193 1193 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); 1194 1194 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA); 1195 - dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) + 1196 - CE_COUNT * sizeof(ce_hdr->entries[0])); 1195 + dump_tlv->tlv_len = cpu_to_le32(struct_size(ce_hdr, entries, 1196 + CE_COUNT)); 1197 1197 ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data); 1198 1198 ce_hdr->ce_count = cpu_to_le32(CE_COUNT); 1199 1199 memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
+47 -3
drivers/net/wireless/ath/ath10k/debug.c
··· 305 305 if (is_end) 306 306 ar->debug.fw_stats_done = true; 307 307 308 + if (stats.extended) 309 + ar->debug.fw_stats.extended = true; 310 + 308 311 is_started = !list_empty(&ar->debug.fw_stats.pdevs); 309 312 310 313 if (is_started && !is_end) { ··· 876 873 cookie = get_jiffies_64(); 877 874 878 875 ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, 879 - cookie); 876 + ar->debug.reset_htt_stats, cookie); 880 877 if (ret) { 881 878 ath10k_warn(ar, "failed to send htt stats request: %d\n", ret); 882 879 return ret; ··· 925 922 if (ret) 926 923 return ret; 927 924 928 - /* max 8 bit masks (for now) */ 929 - if (mask > 0xff) 925 + /* max 17 bit masks (for now) */ 926 + if (mask > HTT_STATS_BIT_MASK) 930 927 return -E2BIG; 931 928 932 929 mutex_lock(&ar->conf_mutex); ··· 2472 2469 .llseek = default_llseek, 2473 2470 }; 2474 2471 2472 + static ssize_t ath10k_write_reset_htt_stats(struct file *file, 2473 + const char __user *user_buf, 2474 + size_t count, loff_t *ppos) 2475 + { 2476 + struct ath10k *ar = file->private_data; 2477 + unsigned long reset; 2478 + int ret; 2479 + 2480 + ret = kstrtoul_from_user(user_buf, count, 0, &reset); 2481 + if (ret) 2482 + return ret; 2483 + 2484 + if (reset == 0 || reset > 0x1ffff) 2485 + return -EINVAL; 2486 + 2487 + mutex_lock(&ar->conf_mutex); 2488 + 2489 + ar->debug.reset_htt_stats = reset; 2490 + 2491 + ret = ath10k_debug_htt_stats_req(ar); 2492 + if (ret) 2493 + goto out; 2494 + 2495 + ar->debug.reset_htt_stats = 0; 2496 + ret = count; 2497 + 2498 + out: 2499 + mutex_unlock(&ar->conf_mutex); 2500 + return ret; 2501 + } 2502 + 2503 + static const struct file_operations fops_reset_htt_stats = { 2504 + .write = ath10k_write_reset_htt_stats, 2505 + .owner = THIS_MODULE, 2506 + .open = simple_open, 2507 + .llseek = default_llseek, 2508 + }; 2509 + 2475 2510 int ath10k_debug_create(struct ath10k *ar) 2476 2511 { 2477 2512 ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN); ··· 2649 2608 2650 2609 debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_phy, ar, 2651 2610 &fops_ps_state_enable); 2611 + 2612 + debugfs_create_file("reset_htt_stats", 0200, ar->debug.debugfs_phy, ar, 2613 + &fops_reset_htt_stats); 2652 2614 2653 2615 return 0; 2654 2616 }
+7
drivers/net/wireless/ath/ath10k/debugfs_sta.c
··· 663 663 664 664 mutex_lock(&ar->conf_mutex); 665 665 666 + if (!arsta->tx_stats) { 667 + ath10k_warn(ar, "failed to get tx stats"); 668 + mutex_unlock(&ar->conf_mutex); 669 + kfree(buf); 670 + return 0; 671 + } 672 + 666 673 spin_lock_bh(&ar->data_lock); 667 674 for (k = 0; k < ATH10K_STATS_TYPE_MAX; k++) { 668 675 for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++) {
+1
drivers/net/wireless/ath/ath10k/htc.c
··· 73 73 struct ath10k_htc_hdr *hdr; 74 74 75 75 hdr = (struct ath10k_htc_hdr *)skb->data; 76 + memset(hdr, 0, sizeof(struct ath10k_htc_hdr)); 76 77 77 78 hdr->eid = ep->eid; 78 79 hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
+55 -5
drivers/net/wireless/ath/ath10k/htt.h
··· 315 315 } __packed; 316 316 317 317 #define HTT_STATS_REQ_CFG_STAT_TYPE_INVALID 0xff 318 + #define HTT_STATS_BIT_MASK GENMASK(16, 0) 318 319 319 320 /* 320 321 * htt_oob_sync_req - request out-of-band sync ··· 734 733 struct htt_rx_indication_mpdu_range mpdu_ranges[0]; 735 734 } __packed; 736 735 736 + struct htt_hl_rx_desc { 737 + __le32 info; 738 + __le32 pn_31_0; 739 + union { 740 + struct { 741 + __le16 pn_47_32; 742 + __le16 pn_63_48; 743 + } pn16; 744 + __le32 pn_63_32; 745 + } u0; 746 + __le32 pn_95_64; 747 + __le32 pn_127_96; 748 + } __packed; 749 + 737 750 static inline struct htt_rx_indication_mpdu_range * 738 751 htt_rx_ind_get_mpdu_ranges(struct htt_rx_indication *rx_ind) 739 752 { ··· 805 790 __le16 peer_id; 806 791 } __packed; 807 792 793 + enum htt_txrx_sec_cast_type { 794 + HTT_TXRX_SEC_MCAST = 0, 795 + HTT_TXRX_SEC_UCAST 796 + }; 797 + 798 + enum htt_rx_pn_check_type { 799 + HTT_RX_NON_PN_CHECK = 0, 800 + HTT_RX_PN_CHECK 801 + }; 802 + 803 + enum htt_rx_tkip_demic_type { 804 + HTT_RX_NON_TKIP_MIC = 0, 805 + HTT_RX_TKIP_MIC 806 + }; 807 + 808 808 enum htt_security_types { 809 809 HTT_SECURITY_NONE, 810 810 HTT_SECURITY_WEP128, ··· 832 802 833 803 HTT_NUM_SECURITY_TYPES /* keep this last! */ 834 804 }; 805 + 806 + #define ATH10K_HTT_TXRX_PEER_SECURITY_MAX 2 807 + #define ATH10K_TXRX_NUM_EXT_TIDS 19 835 808 836 809 enum htt_security_flags { 837 810 #define HTT_SECURITY_TYPE_MASK 0x7F ··· 1042 1009 1043 1010 u8 fw_msdu_rx_desc[0]; 1044 1011 } __packed; 1012 + 1013 + #define ATH10K_IEEE80211_EXTIV BIT(5) 1014 + #define ATH10K_IEEE80211_TKIP_MICLEN 8 /* trailing MIC */ 1015 + 1016 + #define HTT_RX_FRAG_IND_INFO0_HEADER_LEN 16 1045 1017 1046 1018 #define HTT_RX_FRAG_IND_INFO0_EXT_TID_MASK 0x1F 1047 1019 #define HTT_RX_FRAG_IND_INFO0_EXT_TID_LSB 0 ··· 2093 2055 int idx); 2094 2056 void* (*htt_get_vaddr_ring)(struct ath10k_htt *htt); 2095 2057 void (*htt_reset_paddrs_ring)(struct ath10k_htt *htt, int idx); 2058 + bool (*htt_rx_proc_rx_frag_ind)(struct ath10k_htt *htt, 2059 + struct htt_rx_fragment_indication *rx, 2060 + struct sk_buff *skb); 2096 2061 }; 2097 2062 2098 2063 static inline size_t ath10k_htt_get_rx_ring_size(struct ath10k_htt *htt) ··· 2135 2094 htt->rx_ops->htt_reset_paddrs_ring(htt, idx); 2136 2095 } 2137 2096 2097 + static inline bool ath10k_htt_rx_proc_rx_frag_ind(struct ath10k_htt *htt, 2098 + struct htt_rx_fragment_indication *rx, 2099 + struct sk_buff *skb) 2100 + { 2101 + if (!htt->rx_ops->htt_rx_proc_rx_frag_ind) 2102 + return true; 2103 + 2104 + return htt->rx_ops->htt_rx_proc_rx_frag_ind(htt, rx, skb); 2105 + } 2106 + 2138 2107 #define RX_HTT_HDR_STATUS_LEN 64 2139 2108 2140 2109 /* This structure layout is programmed via rx ring setup ··· 2179 2128 #define HTT_RX_DESC_HL_INFO_ENCRYPTED_LSB 12 2180 2129 #define HTT_RX_DESC_HL_INFO_CHAN_INFO_PRESENT_MASK 0x00002000 2181 2130 #define HTT_RX_DESC_HL_INFO_CHAN_INFO_PRESENT_LSB 13 2182 - #define HTT_RX_DESC_HL_INFO_MCAST_BCAST_MASK 0x00008000 2183 - #define HTT_RX_DESC_HL_INFO_MCAST_BCAST_LSB 15 2184 - #define HTT_RX_DESC_HL_INFO_FRAGMENT_MASK 0x00010000 2185 - #define HTT_RX_DESC_HL_INFO_FRAGMENT_LSB 16 2131 + #define HTT_RX_DESC_HL_INFO_MCAST_BCAST_MASK 0x00010000 2132 + #define HTT_RX_DESC_HL_INFO_MCAST_BCAST_LSB 16 2186 2133 #define HTT_RX_DESC_HL_INFO_KEY_ID_OCT_MASK 0x01fe0000 2187 2134 #define HTT_RX_DESC_HL_INFO_KEY_ID_OCT_LSB 17 2188 2135 ··· 2244 2195 void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); 2245 2196 bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); 2246 2197 int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); 2247 - int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); 2198 + int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u32 mask, u32 reset_mask, 2199 + u64 cookie); 2248 2200 int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, 2249 2201 u8 max_subfrms_ampdu, 2250 2202 u8 max_subfrms_amsdu);
+378 -9
drivers/net/wireless/ath/ath10k/htt_rx.c
··· 2061 2061 return 0; 2062 2062 } 2063 2063 2064 + static void ath10k_htt_rx_mpdu_desc_pn_hl(struct htt_hl_rx_desc *rx_desc, 2065 + union htt_rx_pn_t *pn, 2066 + int pn_len_bits) 2067 + { 2068 + switch (pn_len_bits) { 2069 + case 48: 2070 + pn->pn48 = __le32_to_cpu(rx_desc->pn_31_0) + 2071 + ((u64)(__le32_to_cpu(rx_desc->u0.pn_63_32) & 0xFFFF) << 32); 2072 + break; 2073 + case 24: 2074 + pn->pn24 = __le32_to_cpu(rx_desc->pn_31_0); 2075 + break; 2076 + }; 2077 + } 2078 + 2079 + static bool ath10k_htt_rx_pn_cmp48(union htt_rx_pn_t *new_pn, 2080 + union htt_rx_pn_t *old_pn) 2081 + { 2082 + return ((new_pn->pn48 & 0xffffffffffffULL) <= 2083 + (old_pn->pn48 & 0xffffffffffffULL)); 2084 + } 2085 + 2086 + static bool ath10k_htt_rx_pn_check_replay_hl(struct ath10k *ar, 2087 + struct ath10k_peer *peer, 2088 + struct htt_rx_indication_hl *rx) 2089 + { 2090 + bool last_pn_valid, pn_invalid = false; 2091 + enum htt_txrx_sec_cast_type sec_index; 2092 + enum htt_security_types sec_type; 2093 + union htt_rx_pn_t new_pn = {0}; 2094 + struct htt_hl_rx_desc *rx_desc; 2095 + union htt_rx_pn_t *last_pn; 2096 + u32 rx_desc_info, tid; 2097 + int num_mpdu_ranges; 2098 + 2099 + lockdep_assert_held(&ar->data_lock); 2100 + 2101 + if (!peer) 2102 + return false; 2103 + 2104 + if (!(rx->fw_desc.flags & FW_RX_DESC_FLAGS_FIRST_MSDU)) 2105 + return false; 2106 + 2107 + num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1), 2108 + HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); 2109 + 2110 + rx_desc = (struct htt_hl_rx_desc *)&rx->mpdu_ranges[num_mpdu_ranges]; 2111 + rx_desc_info = __le32_to_cpu(rx_desc->info); 2112 + 2113 + if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) 2114 + return false; 2115 + 2116 + tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID); 2117 + last_pn_valid = peer->tids_last_pn_valid[tid]; 2118 + last_pn = &peer->tids_last_pn[tid]; 2119 + 2120 + if (MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST)) 2121 + sec_index = HTT_TXRX_SEC_MCAST; 2122 + else 2123 + sec_index = HTT_TXRX_SEC_UCAST; 2124 + 2125 + sec_type = peer->rx_pn[sec_index].sec_type; 2126 + ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len); 2127 + 2128 + if (sec_type != HTT_SECURITY_AES_CCMP && 2129 + sec_type != HTT_SECURITY_TKIP && 2130 + sec_type != HTT_SECURITY_TKIP_NOMIC) 2131 + return false; 2132 + 2133 + if (last_pn_valid) 2134 + pn_invalid = ath10k_htt_rx_pn_cmp48(&new_pn, last_pn); 2135 + else 2136 + peer->tids_last_pn_valid[tid] = 1; 2137 + 2138 + if (!pn_invalid) 2139 + last_pn->pn48 = new_pn.pn48; 2140 + 2141 + return pn_invalid; 2142 + } 2143 + 2064 2144 static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt, 2065 2145 struct htt_rx_indication_hl *rx, 2066 - struct sk_buff *skb) 2146 + struct sk_buff *skb, 2147 + enum htt_rx_pn_check_type check_pn_type, 2148 + enum htt_rx_tkip_demic_type tkip_mic_type) 2067 2149 { 2068 2150 struct ath10k *ar = htt->ar; 2069 2151 struct ath10k_peer *peer; ··· 2189 2107 goto err; 2190 2108 } 2191 2109 2110 + if (check_pn_type == HTT_RX_PN_CHECK && 2111 + ath10k_htt_rx_pn_check_replay_hl(ar, peer, rx)) 2112 + goto err; 2113 + 2192 2114 /* Strip off all headers before the MAC header before delivery to 2193 2115 * mac80211 2194 2116 */ ··· 2200 2114 sizeof(rx->ppdu) + sizeof(rx->prefix) + 2201 2115 sizeof(rx->fw_desc) + 2202 2116 sizeof(*mpdu_ranges) * num_mpdu_ranges + rx_desc_len; 2117 + 2203 2118 skb_pull(skb, tot_hdr_len); 2204 2119 2205 2120 hdr = (struct ieee80211_hdr *)skb->data; ··· 2249 2162 RX_FLAG_MMIC_STRIPPED; 2250 2163 } 2251 2164 2165 + if (tkip_mic_type == HTT_RX_TKIP_MIC) 2166 + rx_status->flag &= ~RX_FLAG_IV_STRIPPED & 2167 + ~RX_FLAG_MMIC_STRIPPED; 2168 + 2252 2169 ieee80211_rx_ni(ar->hw, skb); 2253 2170 2254 2171 /* We have delivered the skb to the upper layers (mac80211) so we ··· 2260 2169 */ 2261 2170 return false; 2262 2171 err: 2172 + /* Tell the caller that it must free the skb since we have not 2173 + * consumed it 2174 + */ 2175 + return true; 2176 + } 2177 + 2178 + static int ath10k_htt_rx_frag_tkip_decap_nomic(struct sk_buff *skb, 2179 + u16 head_len, 2180 + u16 hdr_len) 2181 + { 2182 + u8 *ivp, *orig_hdr; 2183 + 2184 + orig_hdr = skb->data; 2185 + ivp = orig_hdr + hdr_len + head_len; 2186 + 2187 + /* the ExtIV bit is always set to 1 for TKIP */ 2188 + if (!(ivp[IEEE80211_WEP_IV_LEN - 1] & ATH10K_IEEE80211_EXTIV)) 2189 + return -EINVAL; 2190 + 2191 + memmove(orig_hdr + IEEE80211_TKIP_IV_LEN, orig_hdr, head_len + hdr_len); 2192 + skb_pull(skb, IEEE80211_TKIP_IV_LEN); 2193 + skb_trim(skb, skb->len - ATH10K_IEEE80211_TKIP_MICLEN); 2194 + return 0; 2195 + } 2196 + 2197 + static int ath10k_htt_rx_frag_tkip_decap_withmic(struct sk_buff *skb, 2198 + u16 head_len, 2199 + u16 hdr_len) 2200 + { 2201 + u8 *ivp, *orig_hdr; 2202 + 2203 + orig_hdr = skb->data; 2204 + ivp = orig_hdr + hdr_len + head_len; 2205 + 2206 + /* the ExtIV bit is always set to 1 for TKIP */ 2207 + if (!(ivp[IEEE80211_WEP_IV_LEN - 1] & ATH10K_IEEE80211_EXTIV)) 2208 + return -EINVAL; 2209 + 2210 + memmove(orig_hdr + IEEE80211_TKIP_IV_LEN, orig_hdr, head_len + hdr_len); 2211 + skb_pull(skb, IEEE80211_TKIP_IV_LEN); 2212 + skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN); 2213 + return 0; 2214 + } 2215 + 2216 + static int ath10k_htt_rx_frag_ccmp_decap(struct sk_buff *skb, 2217 + u16 head_len, 2218 + u16 hdr_len) 2219 + { 2220 + u8 *ivp, *orig_hdr; 2221 + 2222 + orig_hdr = skb->data; 2223 + ivp = orig_hdr + hdr_len + head_len; 2224 + 2225 + /* the ExtIV bit is always set to 1 for CCMP */ 2226 + if (!(ivp[IEEE80211_WEP_IV_LEN - 1] & ATH10K_IEEE80211_EXTIV)) 2227 + return -EINVAL; 2228 + 2229 + skb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN); 2230 + memmove(orig_hdr + IEEE80211_CCMP_HDR_LEN, orig_hdr, head_len + hdr_len); 2231 + skb_pull(skb, IEEE80211_CCMP_HDR_LEN); 2232 + return 0; 2233 + } 2234 + 2235 + static int ath10k_htt_rx_frag_wep_decap(struct sk_buff *skb, 2236 + u16 head_len, 2237 + u16 hdr_len) 2238 + { 2239 + u8 *orig_hdr; 2240 + 2241 + orig_hdr = skb->data; 2242 + 2243 + memmove(orig_hdr + IEEE80211_WEP_IV_LEN, 2244 + orig_hdr, head_len + hdr_len); 2245 + skb_pull(skb, IEEE80211_WEP_IV_LEN); 2246 + skb_trim(skb, skb->len - IEEE80211_WEP_ICV_LEN); 2247 + return 0; 2248 + } 2249 + 2250 + static bool ath10k_htt_rx_proc_rx_frag_ind_hl(struct ath10k_htt *htt, 2251 + struct htt_rx_fragment_indication *rx, 2252 + struct sk_buff *skb) 2253 + { 2254 + struct ath10k *ar = htt->ar; 2255 + enum htt_rx_tkip_demic_type tkip_mic = HTT_RX_NON_TKIP_MIC; 2256 + enum htt_txrx_sec_cast_type sec_index; 2257 + struct htt_rx_indication_hl *rx_hl; 2258 + enum htt_security_types sec_type; 2259 + u32 tid, frag, seq, rx_desc_info; 2260 + union htt_rx_pn_t new_pn = {0}; 2261 + struct htt_hl_rx_desc *rx_desc; 2262 + u16 peer_id, sc, hdr_space; 2263 + union htt_rx_pn_t *last_pn; 2264 + struct ieee80211_hdr *hdr; 2265 + int ret, num_mpdu_ranges; 2266 + struct ath10k_peer *peer; 2267 + struct htt_resp *resp; 2268 + size_t tot_hdr_len; 2269 + 2270 + resp = (struct htt_resp *)(skb->data + HTT_RX_FRAG_IND_INFO0_HEADER_LEN); 2271 + skb_pull(skb, HTT_RX_FRAG_IND_INFO0_HEADER_LEN); 2272 + skb_trim(skb, skb->len - FCS_LEN); 2273 + 2274 + peer_id = __le16_to_cpu(rx->peer_id); 2275 + rx_hl = (struct htt_rx_indication_hl *)(&resp->rx_ind_hl); 2276 + 2277 + spin_lock_bh(&ar->data_lock); 2278 + peer = ath10k_peer_find_by_id(ar, peer_id); 2279 + if (!peer) { 2280 + ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid peer: %u\n", peer_id); 2281 + goto err; 2282 + } 2283 + 2284 + num_mpdu_ranges = MS(__le32_to_cpu(rx_hl->hdr.info1), 2285 + HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); 2286 + 2287 + tot_hdr_len = sizeof(struct htt_resp_hdr) + 2288 + sizeof(rx_hl->hdr) + 2289 + sizeof(rx_hl->ppdu) + 2290 + sizeof(rx_hl->prefix) + 2291 + sizeof(rx_hl->fw_desc) + 2292 + sizeof(struct htt_rx_indication_mpdu_range) * num_mpdu_ranges; 2293 + 2294 + tid = MS(rx_hl->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID); 2295 + rx_desc = (struct htt_hl_rx_desc *)(skb->data + tot_hdr_len); 2296 + rx_desc_info = __le32_to_cpu(rx_desc->info); 2297 + 2298 + if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) { 2299 + spin_unlock_bh(&ar->data_lock); 2300 + return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb, 2301 + HTT_RX_NON_PN_CHECK, 2302 + HTT_RX_NON_TKIP_MIC); 2303 + } 2304 + 2305 + hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); 2306 + 2307 + if (ieee80211_has_retry(hdr->frame_control)) 2308 + goto err; 2309 + 2310 + hdr_space = ieee80211_hdrlen(hdr->frame_control); 2311 + sc = __le16_to_cpu(hdr->seq_ctrl); 2312 + seq = (sc & IEEE80211_SCTL_SEQ) >> 4; 2313 + frag = sc & IEEE80211_SCTL_FRAG; 2314 + 2315 + sec_index = MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST) ? 2316 + HTT_TXRX_SEC_MCAST : HTT_TXRX_SEC_UCAST; 2317 + sec_type = peer->rx_pn[sec_index].sec_type; 2318 + ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len); 2319 + 2320 + switch (sec_type) { 2321 + case HTT_SECURITY_TKIP: 2322 + tkip_mic = HTT_RX_TKIP_MIC; 2323 + ret = ath10k_htt_rx_frag_tkip_decap_withmic(skb, 2324 + tot_hdr_len + 2325 + rx_hl->fw_desc.len, 2326 + hdr_space); 2327 + if (ret) 2328 + goto err; 2329 + break; 2330 + case HTT_SECURITY_TKIP_NOMIC: 2331 + ret = ath10k_htt_rx_frag_tkip_decap_nomic(skb, 2332 + tot_hdr_len + 2333 + rx_hl->fw_desc.len, 2334 + hdr_space); 2335 + if (ret) 2336 + goto err; 2337 + break; 2338 + case HTT_SECURITY_AES_CCMP: 2339 + ret = ath10k_htt_rx_frag_ccmp_decap(skb, 2340 + tot_hdr_len + rx_hl->fw_desc.len, 2341 + hdr_space); 2342 + if (ret) 2343 + goto err; 2344 + break; 2345 + case HTT_SECURITY_WEP128: 2346 + case HTT_SECURITY_WEP104: 2347 + case HTT_SECURITY_WEP40: 2348 + ret = ath10k_htt_rx_frag_wep_decap(skb, 2349 + tot_hdr_len + rx_hl->fw_desc.len, 2350 + hdr_space); 2351 + if (ret) 2352 + goto err; 2353 + break; 2354 + default: 2355 + break; 2356 + } 2357 + 2358 + resp = (struct htt_resp *)(skb->data); 2359 + 2360 + if (sec_type != HTT_SECURITY_AES_CCMP && 2361 + sec_type != HTT_SECURITY_TKIP && 2362 + sec_type != HTT_SECURITY_TKIP_NOMIC) { 2363 + spin_unlock_bh(&ar->data_lock); 2364 + return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb, 2365 + HTT_RX_NON_PN_CHECK, 2366 + HTT_RX_NON_TKIP_MIC); 2367 + } 2368 + 2369 + last_pn = &peer->frag_tids_last_pn[tid]; 2370 + 2371 + if (frag == 0) { 2372 + if (ath10k_htt_rx_pn_check_replay_hl(ar, peer, &resp->rx_ind_hl)) 2373 + goto err; 2374 + 2375 + last_pn->pn48 = new_pn.pn48; 2376 + peer->frag_tids_seq[tid] = seq; 2377 + } else if (sec_type == HTT_SECURITY_AES_CCMP) { 2378 + if (seq != peer->frag_tids_seq[tid]) 2379 + goto err; 2380 + 2381 + if (new_pn.pn48 != last_pn->pn48 + 1) 2382 + goto err; 2383 + 2384 + last_pn->pn48 = new_pn.pn48; 2385 + last_pn = &peer->tids_last_pn[tid]; 2386 + last_pn->pn48 = new_pn.pn48; 2387 + } 2388 + 2389 + spin_unlock_bh(&ar->data_lock); 2390 + 2391 + return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb, 2392 + HTT_RX_NON_PN_CHECK, tkip_mic); 2393 + 2394 + err: 2395 + spin_unlock_bh(&ar->data_lock); 2396 + 2263 2397 /* Tell the caller that it must free the skb since we have not 2264 2398 * consumed it 2265 2399 */ ··· 2509 2193 mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); 2510 2194 2511 2195 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", 2512 - rx, sizeof(*rx) + 2513 - (sizeof(struct htt_rx_indication_mpdu_range) * 2514 - num_mpdu_ranges)); 2196 + rx, struct_size(rx, mpdu_ranges, num_mpdu_ranges)); 2515 2197 2516 2198 for (i = 0; i < num_mpdu_ranges; i++) 2517 2199 mpdu_count += mpdu_ranges[i].mpdu_count; ··· 2591 2277 * Note that with only one concurrent reader and one concurrent 2592 2278 * writer, you don't need extra locking to use these macro. 2593 2279 */ 2594 - if (!kfifo_put(&htt->txdone_fifo, tx_done)) { 2280 + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) { 2281 + ath10k_txrx_tx_unref(htt, &tx_done); 2282 + } else if (!kfifo_put(&htt->txdone_fifo, tx_done)) { 2595 2283 ath10k_warn(ar, "txdone fifo overrun, msdu_id %d status %d\n", 2596 2284 tx_done.msdu_id, tx_done.status); 2597 2285 ath10k_txrx_tx_unref(htt, &tx_done); ··· 3254 2938 3255 2939 #define STATS_OP_FMT(name) tx_stats->stats[ATH10K_STATS_TYPE_##name] 3256 2940 3257 - if (txrate->flags == RATE_INFO_FLAGS_VHT_MCS) { 2941 + if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) { 3258 2942 STATS_OP_FMT(SUCC).vht[0][mcs] += pstats->succ_bytes; 3259 2943 STATS_OP_FMT(SUCC).vht[1][mcs] += pstats->succ_pkts; 3260 2944 STATS_OP_FMT(FAIL).vht[0][mcs] += pstats->failed_bytes; 3261 2945 STATS_OP_FMT(FAIL).vht[1][mcs] += pstats->failed_pkts; 3262 2946 STATS_OP_FMT(RETRY).vht[0][mcs] += pstats->retry_bytes; 3263 2947 STATS_OP_FMT(RETRY).vht[1][mcs] += pstats->retry_pkts; 3264 - } else if (txrate->flags == RATE_INFO_FLAGS_MCS) { 2948 + } else if (txrate->flags & RATE_INFO_FLAGS_MCS) { 3265 2949 STATS_OP_FMT(SUCC).ht[0][ht_idx] += pstats->succ_bytes; 3266 2950 STATS_OP_FMT(SUCC).ht[1][ht_idx] += pstats->succ_pkts; 3267 2951 STATS_OP_FMT(FAIL).ht[0][ht_idx] += pstats->failed_bytes; ··· 3282 2966 if (ATH10K_HW_AMPDU(pstats->flags)) { 3283 2967 tx_stats->ba_fails += ATH10K_HW_BA_FAIL(pstats->flags); 3284 2968 3285 - if (txrate->flags == RATE_INFO_FLAGS_MCS) { 2969 + if (txrate->flags & RATE_INFO_FLAGS_MCS) { 3286 2970 STATS_OP_FMT(AMPDU).ht[0][ht_idx] += 3287 2971 pstats->succ_bytes + pstats->retry_bytes; 3288 2972 STATS_OP_FMT(AMPDU).ht[1][ht_idx] += ··· 3581 3265 rcu_read_unlock(); 3582 3266 } 3583 3267 3268 + static int ath10k_htt_rx_pn_len(enum htt_security_types sec_type) 3269 + { 3270 + switch (sec_type) { 3271 + case HTT_SECURITY_TKIP: 3272 + case HTT_SECURITY_TKIP_NOMIC: 3273 + case HTT_SECURITY_AES_CCMP: 3274 + return 48; 3275 + default: 3276 + return 0; 3277 + } 3278 + } 3279 + 3280 + static void ath10k_htt_rx_sec_ind_handler(struct ath10k *ar, 3281 + struct htt_security_indication *ev) 3282 + { 3283 + enum htt_txrx_sec_cast_type sec_index; 3284 + enum htt_security_types sec_type; 3285 + struct ath10k_peer *peer; 3286 + 3287 + spin_lock_bh(&ar->data_lock); 3288 + 3289 + peer = ath10k_peer_find_by_id(ar, __le16_to_cpu(ev->peer_id)); 3290 + if (!peer) { 3291 + ath10k_warn(ar, "failed to find peer id %d for security indication", 3292 + __le16_to_cpu(ev->peer_id)); 3293 + goto out; 3294 + } 3295 + 3296 + sec_type = MS(ev->flags, HTT_SECURITY_TYPE); 3297 + 3298 + if (ev->flags & HTT_SECURITY_IS_UNICAST) 3299 + sec_index = HTT_TXRX_SEC_UCAST; 3300 + else 3301 + sec_index = HTT_TXRX_SEC_MCAST; 3302 + 3303 + peer->rx_pn[sec_index].sec_type = sec_type; 3304 + peer->rx_pn[sec_index].pn_len = ath10k_htt_rx_pn_len(sec_type); 3305 + 3306 + memset(peer->tids_last_pn_valid, 0, sizeof(peer->tids_last_pn_valid)); 3307 + memset(peer->tids_last_pn, 0, sizeof(peer->tids_last_pn)); 3308 + 3309 + out: 3310 + spin_unlock_bh(&ar->data_lock); 3311 + } 3312 + 3584 3313 bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) 3585 3314 { 3586 3315 struct ath10k_htt *htt = &ar->htt; ··· 3657 3296 if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) 3658 3297 return ath10k_htt_rx_proc_rx_ind_hl(htt, 3659 3298 &resp->rx_ind_hl, 3660 - skb); 3299 + skb, 3300 + HTT_RX_PN_CHECK, 3301 + HTT_RX_NON_TKIP_MIC); 3661 3302 else 3662 3303 ath10k_htt_rx_proc_rx_ind_ll(htt, &resp->rx_ind); 3663 3304 break; ··· 3721 3358 struct ath10k *ar = htt->ar; 3722 3359 struct htt_security_indication *ev = &resp->security_indication; 3723 3360 3361 + ath10k_htt_rx_sec_ind_handler(ar, ev); 3724 3362 ath10k_dbg(ar, ATH10K_DBG_HTT, 3725 3363 "sec ind peer_id %d unicast %d type %d\n", 3726 3364 __le16_to_cpu(ev->peer_id), ··· 3734 3370 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", 3735 3371 skb->data, skb->len); 3736 3372 atomic_inc(&htt->num_mpdus_ready); 3373 + 3374 + return ath10k_htt_rx_proc_rx_frag_ind(htt, 3375 + &resp->rx_frag_ind, 3376 + skb); 3737 3377 break; 3738 3378 } 3739 3379 case HTT_T2H_MSG_TYPE_TEST: ··· 3951 3583 }; 3952 3584 3953 3585 static const struct ath10k_htt_rx_ops htt_rx_ops_hl = { 3586 + .htt_rx_proc_rx_frag_ind = ath10k_htt_rx_proc_rx_frag_ind_hl, 3954 3587 }; 3955 3588 3956 3589 void ath10k_htt_set_rx_ops(struct ath10k_htt *htt)
+24 -5
drivers/net/wireless/ath/ath10k/htt_tx.c
··· 580 580 return 0; 581 581 } 582 582 583 - int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) 583 + int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u32 mask, u32 reset_mask, 584 + u64 cookie) 584 585 { 585 586 struct ath10k *ar = htt->ar; 586 587 struct htt_stats_req *req; ··· 604 603 605 604 memset(req, 0, sizeof(*req)); 606 605 607 - /* currently we support only max 8 bit masks so no need to worry 606 + /* currently we support only max 24 bit masks so no need to worry 608 607 * about endian support 609 608 */ 610 - req->upload_types[0] = mask; 611 - req->reset_types[0] = mask; 609 + memcpy(req->upload_types, &mask, 3); 610 + memcpy(req->reset_types, &reset_mask, 3); 612 611 req->stat_type = HTT_STATS_REQ_CFG_STAT_TYPE_INVALID; 613 612 req->cookie_lsb = cpu_to_le32(cookie & 0xffffffff); 614 613 req->cookie_msb = cpu_to_le32((cookie & 0xffffffff00000000ULL) >> 32); ··· 1245 1244 u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth); 1246 1245 u8 flags0 = 0; 1247 1246 u16 flags1 = 0; 1247 + u16 msdu_id = 0; 1248 1248 1249 1249 data_len = msdu->len; 1250 1250 ··· 1293 1291 } 1294 1292 } 1295 1293 1294 + if (ar->bus_param.hl_msdu_ids) { 1295 + flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED; 1296 + res = ath10k_htt_tx_alloc_msdu_id(htt, msdu); 1297 + if (res < 0) { 1298 + ath10k_err(ar, "msdu_id allocation failed %d\n", res); 1299 + goto out; 1300 + } 1301 + msdu_id = res; 1302 + } 1303 + 1304 + /* As msdu is freed by mac80211 (in ieee80211_tx_status()) and by 1305 + * ath10k (in ath10k_htt_htc_tx_complete()) we have to increase 1306 + * reference by one to avoid a use-after-free case and a double 1307 + * free. 1308 + */ 1309 + skb_get(msdu); 1310 + 1296 1311 skb_push(msdu, sizeof(*cmd_hdr)); 1297 1312 skb_push(msdu, sizeof(*tx_desc)); 1298 1313 cmd_hdr = (struct htt_cmd_hdr *)msdu->data; ··· 1319 1300 tx_desc->flags0 = flags0; 1320 1301 tx_desc->flags1 = __cpu_to_le16(flags1); 1321 1302 tx_desc->len = __cpu_to_le16(data_len); 1322 - tx_desc->id = 0; 1303 + tx_desc->id = __cpu_to_le16(msdu_id); 1323 1304 tx_desc->frags_paddr = 0; /* always zero */ 1324 1305 /* Initialize peer_id to INVALID_PEER because this is NOT 1325 1306 * Reinjection path
+6
drivers/net/wireless/ath/ath10k/hw.h
··· 24 24 #define QCA988X_2_0_DEVICE_ID (0x003c) 25 25 #define QCA6164_2_1_DEVICE_ID (0x0041) 26 26 #define QCA6174_2_1_DEVICE_ID (0x003e) 27 + #define QCA6174_3_2_DEVICE_ID (0x0042) 27 28 #define QCA99X0_2_0_DEVICE_ID (0x0040) 28 29 #define QCA9888_2_0_DEVICE_ID (0x0056) 29 30 #define QCA9984_1_0_DEVICE_ID (0x0046) ··· 607 606 608 607 /* target supporting fw download via diag ce */ 609 608 bool fw_diag_ce_download; 609 + 610 + /* need to set uart pin if disable uart print, workaround for a 611 + * firmware bug 612 + */ 613 + bool uart_pin_workaround; 610 614 }; 611 615 612 616 struct htt_rx_desc;
+11 -3
drivers/net/wireless/ath/ath10k/mac.c
··· 1630 1630 if (arvif->vdev_type != WMI_VDEV_TYPE_AP) 1631 1631 return 0; 1632 1632 1633 + /* For mesh, probe response and beacon share the same template */ 1634 + if (ieee80211_vif_is_mesh(vif)) 1635 + return 0; 1636 + 1633 1637 prb = ieee80211_proberesp_get(hw, vif); 1634 1638 if (!prb) { 1635 1639 ath10k_warn(ar, "failed to get probe resp template from mac80211\n"); ··· 5592 5588 struct cfg80211_chan_def def; 5593 5589 u32 vdev_param, pdev_param, slottime, preamble; 5594 5590 u16 bitrate, hw_value; 5595 - u8 rate, basic_rate_idx; 5596 - int rateidx, ret = 0, hw_rate_code; 5591 + u8 rate, basic_rate_idx, rateidx; 5592 + int ret = 0, hw_rate_code, mcast_rate; 5597 5593 enum nl80211_band band; 5598 5594 const struct ieee80211_supported_band *sband; 5599 5595 ··· 5780 5776 if (changed & BSS_CHANGED_MCAST_RATE && 5781 5777 !ath10k_mac_vif_chan(arvif->vif, &def)) { 5782 5778 band = def.chan->band; 5783 - rateidx = vif->bss_conf.mcast_rate[band] - 1; 5779 + mcast_rate = vif->bss_conf.mcast_rate[band]; 5780 + if (mcast_rate > 0) 5781 + rateidx = mcast_rate - 1; 5782 + else 5783 + rateidx = ffs(vif->bss_conf.basic_rates) - 1; 5784 5784 5785 5785 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) 5786 5786 rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
+1 -1
drivers/net/wireless/ath/ath10k/pci.c
··· 3492 3492 struct ath10k *ar; 3493 3493 struct ath10k_pci *ar_pci; 3494 3494 enum ath10k_hw_rev hw_rev; 3495 - struct ath10k_bus_params bus_params; 3495 + struct ath10k_bus_params bus_params = {}; 3496 3496 bool pci_ps; 3497 3497 int (*pci_soft_reset)(struct ath10k *ar); 3498 3498 int (*pci_hard_reset)(struct ath10k *ar);
+8 -7
drivers/net/wireless/ath/ath10k/qmi.c
··· 506 506 struct wlfw_cap_resp_msg_v01 *resp; 507 507 struct wlfw_cap_req_msg_v01 req = {}; 508 508 struct ath10k *ar = qmi->ar; 509 + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 509 510 struct qmi_txn txn; 510 511 int ret; 511 512 ··· 561 560 strlcpy(qmi->fw_build_id, resp->fw_build_id, 562 561 MAX_BUILD_ID_LEN + 1); 563 562 564 - ath10k_dbg(ar, ATH10K_DBG_QMI, 565 - "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x", 566 - qmi->chip_info.chip_id, qmi->chip_info.chip_family, 567 - qmi->board_info.board_id, qmi->soc_info.soc_id); 568 - ath10k_dbg(ar, ATH10K_DBG_QMI, 569 - "qmi fw_version 0x%x fw_build_timestamp %s fw_build_id %s", 570 - qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id); 563 + if (!test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) { 564 + ath10k_info(ar, "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x", 565 + qmi->chip_info.chip_id, qmi->chip_info.chip_family, 566 + qmi->board_info.board_id, qmi->soc_info.soc_id); 567 + ath10k_info(ar, "qmi fw_version 0x%x fw_build_timestamp %s fw_build_id %s", 568 + qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id); 569 + } 571 570 572 571 kfree(resp); 573 572 return 0;
+14 -4
drivers/net/wireless/ath/ath10k/sdio.c
··· 584 584 act_len, 585 585 &bndl_cnt); 586 586 587 + if (ret) { 588 + ath10k_warn(ar, "alloc_bundle error %d\n", ret); 589 + goto err; 590 + } 591 + 587 592 n_lookaheads += bndl_cnt; 588 593 i += bndl_cnt; 589 594 /*Next buffer will be the last in the bundle */ ··· 1642 1637 ath10k_dbg(ar, ATH10K_DBG_SDIO, 1643 1638 "sdio mailbox swap service enabled\n"); 1644 1639 ar_sdio->swap_mbox = true; 1640 + } else { 1641 + ath10k_dbg(ar, ATH10K_DBG_SDIO, 1642 + "sdio mailbox swap service disabled\n"); 1643 + ar_sdio->swap_mbox = false; 1645 1644 } 1645 + 1646 1646 return 0; 1647 1647 } 1648 1648 ··· 1964 1954 struct ath10k *ar; 1965 1955 enum ath10k_hw_rev hw_rev; 1966 1956 u32 dev_id_base; 1967 - struct ath10k_bus_params bus_params; 1957 + struct ath10k_bus_params bus_params = {}; 1968 1958 int ret, i; 1969 1959 1970 1960 /* Assumption: All SDIO based chipsets (so far) are QCA6174 based. ··· 2055 2045 bus_params.dev_type = ATH10K_DEV_TYPE_HL; 2056 2046 /* TODO: don't know yet how to get chip_id with SDIO */ 2057 2047 bus_params.chip_id = 0; 2048 + bus_params.hl_msdu_ids = true; 2049 + 2058 2050 ret = ath10k_core_register(ar, &bus_params); 2059 2051 if (ret) { 2060 2052 ath10k_err(ar, "failed to register driver core: %d\n", ret); ··· 2064 2052 } 2065 2053 2066 2054 /* TODO: remove this once SDIO support is fully implemented */ 2067 - ath10k_warn(ar, "WARNING: ath10k SDIO support is incomplete, don't expect anything to work!\n"); 2055 + ath10k_warn(ar, "WARNING: ath10k SDIO support is work-in-progress, problems may arise!\n"); 2068 2056 2069 2057 return 0; 2070 2058 ··· 2085 2073 "sdio removed func %d vendor 0x%x device 0x%x\n", 2086 2074 func->num, func->vendor, func->device); 2087 2075 2088 - (void)ath10k_sdio_hif_disable_intrs(ar); 2089 - cancel_work_sync(&ar_sdio->wr_async_work); 2090 2076 ath10k_core_unregister(ar); 2091 2077 ath10k_core_destroy(ar); 2092 2078 }
+2 -2
drivers/net/wireless/ath/ath10k/snoc.c
··· 165 165 /* CE4: host->target HTT */ 166 166 { 167 167 .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, 168 - .src_nentries = 256, 168 + .src_nentries = 2048, 169 169 .src_sz_max = 256, 170 170 .dest_nentries = 0, 171 171 .send_cb = ath10k_snoc_htt_tx_cb, ··· 1249 1249 int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type) 1250 1250 { 1251 1251 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1252 - struct ath10k_bus_params bus_params; 1252 + struct ath10k_bus_params bus_params = {}; 1253 1253 int ret; 1254 1254 1255 1255 if (test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags))
+3
drivers/net/wireless/ath/ath10k/txrx.c
··· 150 150 { 151 151 struct ath10k_peer *peer; 152 152 153 + if (peer_id >= BITS_PER_TYPE(peer->peer_ids)) 154 + return NULL; 155 + 153 156 lockdep_assert_held(&ar->data_lock); 154 157 155 158 list_for_each_entry(peer, &ar->peers, list)
+1 -1
drivers/net/wireless/ath/ath10k/usb.c
··· 973 973 struct usb_device *dev = interface_to_usbdev(interface); 974 974 int ret, vendor_id, product_id; 975 975 enum ath10k_hw_rev hw_rev; 976 - struct ath10k_bus_params bus_params; 976 + struct ath10k_bus_params bus_params = {}; 977 977 978 978 /* Assumption: All USB based chipsets (so far) are QCA9377 based. 979 979 * If there will be newer chipsets that does not use the hw reg
+26 -2
drivers/net/wireless/ath/ath10k/wmi-tlv.c
··· 1905 1905 return skb; 1906 1906 } 1907 1907 1908 + static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar, 1909 + enum wmi_vdev_subtype subtype) 1910 + { 1911 + switch (subtype) { 1912 + case WMI_VDEV_SUBTYPE_NONE: 1913 + return WMI_TLV_VDEV_SUBTYPE_NONE; 1914 + case WMI_VDEV_SUBTYPE_P2P_DEVICE: 1915 + return WMI_TLV_VDEV_SUBTYPE_P2P_DEV; 1916 + case WMI_VDEV_SUBTYPE_P2P_CLIENT: 1917 + return WMI_TLV_VDEV_SUBTYPE_P2P_CLI; 1918 + case WMI_VDEV_SUBTYPE_P2P_GO: 1919 + return WMI_TLV_VDEV_SUBTYPE_P2P_GO; 1920 + case WMI_VDEV_SUBTYPE_PROXY_STA: 1921 + return WMI_TLV_VDEV_SUBTYPE_PROXY_STA; 1922 + case WMI_VDEV_SUBTYPE_MESH_11S: 1923 + return WMI_TLV_VDEV_SUBTYPE_MESH_11S; 1924 + case WMI_VDEV_SUBTYPE_MESH_NON_11S: 1925 + return -ENOTSUPP; 1926 + } 1927 + return -ENOTSUPP; 1928 + } 1929 + 1908 1930 static struct sk_buff * 1909 1931 ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, 1910 1932 u32 vdev_id, ··· 2862 2840 if ((ieee80211_is_action(hdr->frame_control) || 2863 2841 ieee80211_is_deauth(hdr->frame_control) || 2864 2842 ieee80211_is_disassoc(hdr->frame_control)) && 2865 - ieee80211_has_protected(hdr->frame_control)) 2843 + ieee80211_has_protected(hdr->frame_control)) { 2844 + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); 2866 2845 buf_len += IEEE80211_CCMP_MIC_LEN; 2846 + } 2867 2847 2868 2848 buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN); 2869 2849 buf_len = round_up(buf_len, 4); ··· 4329 4305 .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, 4330 4306 .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, 4331 4307 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 4332 - .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, 4308 + .get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype, 4333 4309 .gen_echo = ath10k_wmi_tlv_op_gen_echo, 4334 4310 .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, 4335 4311 .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
+12
drivers/net/wireless/ath/ath10k/wmi-tlv.h
··· 1567 1567 WMI_SERVICE_SAP_AUTH_OFFLOAD, len); 1568 1568 SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI, 1569 1569 WMI_SERVICE_MGMT_TX_WMI, len); 1570 + SVCMAP(WMI_TLV_SERVICE_MESH_11S, 1571 + WMI_SERVICE_MESH_11S, len); 1570 1572 } 1571 1573 1572 1574 static inline void ··· 1776 1774 struct wmi_mac_addr mac_addr; 1777 1775 struct wmi_mac_addr mac_mask; 1778 1776 } __packed; 1777 + 1778 + enum wmi_tlv_vdev_subtype { 1779 + WMI_TLV_VDEV_SUBTYPE_NONE = 0, 1780 + WMI_TLV_VDEV_SUBTYPE_P2P_DEV = 1, 1781 + WMI_TLV_VDEV_SUBTYPE_P2P_CLI = 2, 1782 + WMI_TLV_VDEV_SUBTYPE_P2P_GO = 3, 1783 + WMI_TLV_VDEV_SUBTYPE_PROXY_STA = 4, 1784 + WMI_TLV_VDEV_SUBTYPE_MESH = 5, 1785 + WMI_TLV_VDEV_SUBTYPE_MESH_11S = 6, 1786 + }; 1779 1787 1780 1788 struct wmi_tlv_vdev_start_cmd { 1781 1789 __le32 vdev_id;
+31 -6
drivers/net/wireless/ath/ath10k/wmi.c
··· 8309 8309 8310 8310 static void 8311 8311 ath10k_wmi_fw_peer_stats_fill(const struct ath10k_fw_stats_peer *peer, 8312 - char *buf, u32 *length) 8312 + char *buf, u32 *length, bool extended_peer) 8313 8313 { 8314 8314 u32 len = *length; 8315 8315 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; ··· 8322 8322 "Peer TX rate", peer->peer_tx_rate); 8323 8323 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 8324 8324 "Peer RX rate", peer->peer_rx_rate); 8325 - len += scnprintf(buf + len, buf_len - len, "%30s %llu\n", 8326 - "Peer RX duration", peer->rx_duration); 8325 + if (!extended_peer) 8326 + len += scnprintf(buf + len, buf_len - len, "%30s %llu\n", 8327 + "Peer RX duration", peer->rx_duration); 8327 8328 8328 8329 len += scnprintf(buf + len, buf_len - len, "\n"); 8329 8330 *length = len; 8331 + } 8332 + 8333 + static void 8334 + ath10k_wmi_fw_extd_peer_stats_fill(const struct ath10k_fw_extd_stats_peer *peer, 8335 + char *buf, u32 *length) 8336 + { 8337 + u32 len = *length; 8338 + u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; 8339 + 8340 + len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", 8341 + "Peer MAC address", peer->peer_macaddr); 8342 + len += scnprintf(buf + len, buf_len - len, "%30s %llu\n", 8343 + "Peer RX duration", peer->rx_duration); 8330 8344 } 8331 8345 8332 8346 void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar, ··· 8388 8374 "================="); 8389 8375 8390 8376 list_for_each_entry(peer, &fw_stats->peers, list) { 8391 - ath10k_wmi_fw_peer_stats_fill(peer, buf, &len); 8377 + ath10k_wmi_fw_peer_stats_fill(peer, buf, &len, 8378 + fw_stats->extended); 8392 8379 } 8393 8380 8394 8381 unlock: ··· 8447 8432 "================="); 8448 8433 8449 8434 list_for_each_entry(peer, &fw_stats->peers, list) { 8450 - ath10k_wmi_fw_peer_stats_fill(peer, buf, &len); 8435 + ath10k_wmi_fw_peer_stats_fill(peer, buf, &len, 8436 + fw_stats->extended); 8451 8437 } 8452 8438 8453 8439 unlock: ··· 8557 8541 const struct ath10k_fw_stats_pdev *pdev; 8558 8542 const struct ath10k_fw_stats_vdev_extd *vdev; 8559 8543 const struct ath10k_fw_stats_peer *peer; 8544 + const struct ath10k_fw_extd_stats_peer *extd_peer; 8560 8545 size_t num_peers; 8561 8546 size_t num_vdevs; 8562 8547 ··· 8620 8603 "================="); 8621 8604 8622 8605 list_for_each_entry(peer, &fw_stats->peers, list) { 8623 - ath10k_wmi_fw_peer_stats_fill(peer, buf, &len); 8606 + ath10k_wmi_fw_peer_stats_fill(peer, buf, &len, 8607 + fw_stats->extended); 8608 + } 8609 + 8610 + if (fw_stats->extended) { 8611 + list_for_each_entry(extd_peer, &fw_stats->peers_extd, list) { 8612 + ath10k_wmi_fw_extd_peer_stats_fill(extd_peer, buf, 8613 + &len); 8614 + } 8624 8615 } 8625 8616 8626 8617 unlock:
+4 -3
drivers/net/wireless/ath/ath10k/wmi.h
··· 4535 4535 }; 4536 4536 4537 4537 enum wmi_tlv_stats_id { 4538 - WMI_TLV_STAT_PDEV = BIT(0), 4539 - WMI_TLV_STAT_VDEV = BIT(1), 4540 - WMI_TLV_STAT_PEER = BIT(2), 4538 + WMI_TLV_STAT_PEER = BIT(0), 4539 + WMI_TLV_STAT_AP = BIT(1), 4540 + WMI_TLV_STAT_PDEV = BIT(2), 4541 + WMI_TLV_STAT_VDEV = BIT(3), 4541 4542 WMI_TLV_STAT_PEER_EXTD = BIT(10), 4542 4543 }; 4543 4544
+1 -2
drivers/net/wireless/ath/ath6kl/debug.c
··· 1132 1132 1133 1133 tbl = (const struct wmi_target_roam_tbl *) buf; 1134 1134 num_entries = le16_to_cpu(tbl->num_entries); 1135 - if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) > 1136 - len) 1135 + if (struct_size(tbl, info, num_entries) > len) 1137 1136 return -EINVAL; 1138 1137 1139 1138 if (ar->debug.roam_tbl == NULL ||
-3
drivers/net/wireless/ath/ath6kl/htc_pipe.c
··· 898 898 break; 899 899 } 900 900 901 - if (status != 0) 902 - break; 903 - 904 901 /* advance buffer past this record for next time around */ 905 902 buffer += record->len; 906 903 len -= record->len;
+10 -3
drivers/net/wireless/ath/ath6kl/wmi.c
··· 1176 1176 return -EINVAL; 1177 1177 1178 1178 ev = (struct wmi_pstream_timeout_event *) datap; 1179 + if (ev->traffic_class >= WMM_NUM_AC) { 1180 + ath6kl_err("invalid traffic class: %d\n", ev->traffic_class); 1181 + return -EINVAL; 1182 + } 1179 1183 1180 1184 /* 1181 1185 * When the pstream (fat pipe == AC) timesout, it means there were ··· 1299 1295 if (len < sizeof(*ev)) 1300 1296 return -EINVAL; 1301 1297 ev = (struct wmi_neighbor_report_event *) datap; 1302 - if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info) 1303 - > len) { 1298 + if (struct_size(ev, neighbor, ev->num_neighbors) > len) { 1304 1299 ath6kl_dbg(ATH6KL_DBG_WMI, 1305 1300 "truncated neighbor event (num=%d len=%d)\n", 1306 1301 ev->num_neighbors, len); ··· 1520 1517 return -EINVAL; 1521 1518 1522 1519 reply = (struct wmi_cac_event *) datap; 1520 + if (reply->ac >= WMM_NUM_AC) { 1521 + ath6kl_err("invalid AC: %d\n", reply->ac); 1522 + return -EINVAL; 1523 + } 1523 1524 1524 1525 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) && 1525 1526 (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) { ··· 2640 2633 u16 active_tsids = 0; 2641 2634 int ret; 2642 2635 2643 - if (traffic_class > 3) { 2636 + if (traffic_class >= WMM_NUM_AC) { 2644 2637 ath6kl_err("invalid traffic class: %d\n", traffic_class); 2645 2638 return -EINVAL; 2646 2639 }
+3 -21
drivers/net/wireless/ath/ath9k/ar9003_phy.c
··· 157 157 freq = centers.synth_center; 158 158 159 159 if (freq < 4800) { /* 2 GHz, fractional mode */ 160 - if (AR_SREV_9330(ah)) { 160 + if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || 161 + AR_SREV_9531(ah) || AR_SREV_9550(ah) || 162 + AR_SREV_9561(ah) || AR_SREV_9565(ah)) { 161 163 if (ah->is_clk_25mhz) 162 164 div = 75; 163 165 else ··· 167 165 168 166 channelSel = (freq * 4) / div; 169 167 chan_frac = (((freq * 4) % div) * 0x20000) / div; 170 - channelSel = (channelSel << 17) | chan_frac; 171 - } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { 172 - /* 173 - * freq_ref = 40 / (refdiva >> amoderefsel); 174 - * where refdiva=1 and amoderefsel=0 175 - * ndiv = ((chan_mhz * 4) / 3) / freq_ref; 176 - * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 177 - */ 178 - channelSel = (freq * 4) / 120; 179 - chan_frac = (((freq * 4) % 120) * 0x20000) / 120; 180 168 channelSel = (channelSel << 17) | chan_frac; 181 169 } else if (AR_SREV_9340(ah)) { 182 170 if (ah->is_clk_25mhz) { ··· 176 184 } else { 177 185 channelSel = CHANSEL_2G(freq) >> 1; 178 186 } 179 - } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || 180 - AR_SREV_9561(ah)) { 181 - if (ah->is_clk_25mhz) 182 - div = 75; 183 - else 184 - div = 120; 185 - 186 - channelSel = (freq * 4) / div; 187 - chan_frac = (((freq * 4) % div) * 0x20000) / div; 188 - channelSel = (channelSel << 17) | chan_frac; 189 187 } else { 190 188 channelSel = CHANSEL_2G(freq); 191 189 }
+1 -1
drivers/net/wireless/ath/ath9k/eeprom.c
··· 428 428 else 429 429 power_limit = 0; 430 430 431 - return power_limit; 431 + return min_t(u16, power_limit, MAX_RATE_POWER); 432 432 } 433 433 434 434 void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
+1
drivers/net/wireless/ath/ath9k/eeprom_4k.c
··· 424 424 ath9k_hw_get_channel_centers(ah, chan, &centers); 425 425 426 426 scaledPower = powerLimit - antenna_reduction; 427 + scaledPower = min_t(u16, scaledPower, MAX_RATE_POWER); 427 428 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 428 429 pCtlMode = ctlModesFor11g; 429 430
+27 -13
drivers/net/wireless/ath/ath9k/hw.c
··· 252 252 /* Chip Revisions */ 253 253 /******************/ 254 254 255 - static void ath9k_hw_read_revisions(struct ath_hw *ah) 255 + static bool ath9k_hw_read_revisions(struct ath_hw *ah) 256 256 { 257 + u32 srev; 257 258 u32 val; 258 259 259 260 if (ah->get_mac_revision) ··· 270 269 val = REG_READ(ah, AR_SREV); 271 270 ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); 272 271 } 273 - return; 272 + return true; 274 273 case AR9300_DEVID_AR9340: 275 274 ah->hw_version.macVersion = AR_SREV_VERSION_9340; 276 - return; 275 + return true; 277 276 case AR9300_DEVID_QCA955X: 278 277 ah->hw_version.macVersion = AR_SREV_VERSION_9550; 279 - return; 278 + return true; 280 279 case AR9300_DEVID_AR953X: 281 280 ah->hw_version.macVersion = AR_SREV_VERSION_9531; 282 - return; 281 + return true; 283 282 case AR9300_DEVID_QCA956X: 284 283 ah->hw_version.macVersion = AR_SREV_VERSION_9561; 285 - return; 284 + return true; 286 285 } 287 286 288 - val = REG_READ(ah, AR_SREV) & AR_SREV_ID; 287 + srev = REG_READ(ah, AR_SREV); 288 + 289 + if (srev == -EIO) { 290 + ath_err(ath9k_hw_common(ah), 291 + "Failed to read SREV register"); 292 + return false; 293 + } 294 + 295 + val = srev & AR_SREV_ID; 289 296 290 297 if (val == 0xFF) { 291 - val = REG_READ(ah, AR_SREV); 298 + val = srev; 292 299 ah->hw_version.macVersion = 293 300 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; 294 301 ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); ··· 315 306 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) 316 307 ah->is_pciexpress = true; 317 308 } 309 + 310 + return true; 318 311 } 319 312 320 313 /************************************/ ··· 457 446 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 458 447 459 448 regulatory->country_code = CTRY_DEFAULT; 460 - regulatory->power_limit = MAX_RATE_POWER; 449 + regulatory->power_limit = MAX_COMBINED_POWER; 461 450 462 451 ah->hw_version.magic = AR5416_MAGIC; 463 452 ah->hw_version.subvendorid = 0; ··· 570 559 struct ath_common *common = ath9k_hw_common(ah); 571 560 int r = 0; 572 561 573 - ath9k_hw_read_revisions(ah); 562 + if (!ath9k_hw_read_revisions(ah)) { 563 + ath_err(common, "Could not read hardware revisions"); 564 + return -EOPNOTSUPP; 565 + } 574 566 575 567 switch (ah->hw_version.macVersion) { 576 568 case AR_SREV_VERSION_5416_PCI: ··· 2966 2952 ctl = ath9k_regd_get_ctl(reg, chan); 2967 2953 2968 2954 channel = chan->chan; 2969 - chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); 2955 + chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); 2970 2956 new_pwr = min_t(int, chan_pwr, reg->power_limit); 2971 2957 2972 2958 ah->eep_ops->set_txpower(ah, chan, ctl, ··· 2979 2965 struct ath9k_channel *chan = ah->curchan; 2980 2966 struct ieee80211_channel *channel = chan->chan; 2981 2967 2982 - reg->power_limit = min_t(u32, limit, MAX_RATE_POWER); 2968 + reg->power_limit = min_t(u32, limit, MAX_COMBINED_POWER); 2983 2969 if (test) 2984 - channel->max_power = MAX_RATE_POWER / 2; 2970 + channel->max_power = MAX_COMBINED_POWER / 2; 2985 2971 2986 2972 ath9k_hw_apply_txpower(ah, chan, test); 2987 2973
+1
drivers/net/wireless/ath/ath9k/hw.h
··· 173 173 #define ATH9K_NUM_QUEUES 10 174 174 175 175 #define MAX_RATE_POWER 63 176 + #define MAX_COMBINED_POWER 254 /* 128 dBm, chosen to fit in u8 */ 176 177 #define AH_WAIT_TIMEOUT 100000 /* (us) */ 177 178 #define AH_TSF_WRITE_TIMEOUT 100 /* (us) */ 178 179 #define AH_TIME_QUANTUM 10
+1 -1
drivers/net/wireless/ath/ath9k/init.c
··· 805 805 ah->curchan = &ah->channels[chan->hw_value]; 806 806 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20); 807 807 ath9k_cmn_get_channel(sc->hw, ah, &chandef); 808 - ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); 808 + ath9k_hw_set_txpowerlimit(ah, MAX_COMBINED_POWER, true); 809 809 } 810 810 } 811 811
+4 -14
drivers/net/wireless/ath/ath9k/xmit.c
··· 410 410 struct ath_tx_status *ts, int txok, 411 411 int *nframes, int *nbad) 412 412 { 413 - struct ath_frame_info *fi; 414 413 u16 seq_st = 0; 415 414 u32 ba[WME_BA_BMP_SIZE >> 5]; 416 415 int ba_index; ··· 425 426 } 426 427 427 428 while (bf) { 428 - fi = get_frame_info(bf->bf_mpdu); 429 429 ba_index = ATH_BA_INDEX(seq_st, bf->bf_state.seqno); 430 430 431 431 (*nframes)++; ··· 444 446 { 445 447 struct ath_node *an = NULL; 446 448 struct sk_buff *skb; 447 - struct ieee80211_hdr *hdr; 448 449 struct ieee80211_tx_info *tx_info; 449 450 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 450 451 struct list_head bf_head; ··· 460 463 int bar_index = -1; 461 464 462 465 skb = bf->bf_mpdu; 463 - hdr = (struct ieee80211_hdr *)skb->data; 464 - 465 466 tx_info = IEEE80211_SKB_CB(skb); 466 467 467 468 memcpy(rates, bf->rates, sizeof(rates)); ··· 663 668 static void ath_tx_count_airtime(struct ath_softc *sc, 664 669 struct ieee80211_sta *sta, 665 670 struct ath_buf *bf, 666 - struct ath_tx_status *ts) 671 + struct ath_tx_status *ts, 672 + u8 tid) 667 673 { 668 674 u32 airtime = 0; 669 675 int i; ··· 675 679 airtime += rate_dur * bf->rates[i].count; 676 680 } 677 681 678 - ieee80211_sta_register_airtime(sta, ts->tid, airtime, 0); 682 + ieee80211_sta_register_airtime(sta, tid, airtime, 0); 679 683 } 680 684 681 685 static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, ··· 705 709 if (sta) { 706 710 struct ath_node *an = (struct ath_node *)sta->drv_priv; 707 711 tid = ath_get_skb_tid(sc, an, bf->bf_mpdu); 708 - ath_tx_count_airtime(sc, sta, bf, ts); 712 + ath_tx_count_airtime(sc, sta, bf, ts, tid->tidno); 709 713 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) 710 714 tid->clear_ps_filter = true; 711 715 } ··· 2265 2269 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, 2266 2270 struct ath_tx_control *txctl) 2267 2271 { 2268 - struct ieee80211_hdr *hdr; 2269 2272 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2270 2273 struct ieee80211_sta *sta = txctl->sta; 2271 2274 struct ieee80211_vif *vif = info->control.vif; 2272 2275 struct ath_frame_info *fi = get_frame_info(skb); 2273 - struct ath_vif *avp = NULL; 2274 2276 struct ath_softc *sc = hw->priv; 2275 2277 struct ath_txq *txq = txctl->txq; 2276 2278 struct ath_atx_tid *tid = NULL; ··· 2277 2283 bool ps_resp; 2278 2284 int q, ret; 2279 2285 2280 - if (vif) 2281 - avp = (void *)vif->drv_priv; 2282 - 2283 2286 ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); 2284 2287 2285 2288 ret = ath_tx_prepare(hw, skb, txctl); 2286 2289 if (ret) 2287 2290 return ret; 2288 2291 2289 - hdr = (struct ieee80211_hdr *) skb->data; 2290 2292 /* 2291 2293 * At this point, the vif, hw_key and sta pointers in the tx control 2292 2294 * info are no longer valid (overwritten by the ath_frame_info data.
+1 -1
drivers/net/wireless/ath/carl9170/mac.c
··· 519 519 power = ar->power_5G_leg[0] & 0x3f; 520 520 break; 521 521 default: 522 - BUG_ON(1); 522 + BUG(); 523 523 } 524 524 525 525 power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
+1 -1
drivers/net/wireless/ath/carl9170/rx.c
··· 795 795 break; 796 796 797 797 default: 798 - BUG_ON(1); 798 + BUG(); 799 799 break; 800 800 } 801 801
+1 -1
drivers/net/wireless/ath/dfs_pattern_detector.c
··· 111 111 JP_PATTERN(0, 0, 1, 1428, 1428, 1, 18, 29, false), 112 112 JP_PATTERN(1, 2, 3, 3846, 3846, 1, 18, 29, false), 113 113 JP_PATTERN(2, 0, 1, 1388, 1388, 1, 18, 50, false), 114 - JP_PATTERN(3, 1, 2, 4000, 4000, 1, 18, 50, false), 114 + JP_PATTERN(3, 0, 4, 4000, 4000, 1, 18, 50, false), 115 115 JP_PATTERN(4, 0, 5, 150, 230, 1, 23, 50, false), 116 116 JP_PATTERN(5, 6, 10, 200, 500, 1, 16, 50, false), 117 117 JP_PATTERN(6, 11, 20, 200, 500, 1, 12, 50, false),
-1
drivers/net/wireless/ath/regd.h
··· 28 28 CTL_ETSI = 0x30, 29 29 }; 30 30 31 - #define NO_CTL 0xff 32 31 #define SD_NO_CTL 0xE0 33 32 #define NO_CTL 0xff 34 33 #define CTL_11A 0
+2 -2
drivers/net/wireless/ath/wil6210/cfg80211.c
··· 395 395 { 396 396 int i; 397 397 398 - for (i = 0; i < max_assoc_sta; i++) { 398 + for (i = 0; i < wil->max_assoc_sta; i++) { 399 399 if (wil->sta[i].status == wil_sta_unused) 400 400 continue; 401 401 if (wil->sta[i].mid != mid) ··· 3022 3022 wil, vif->mid, WMI_INVALID_RF_SECTOR_INDEX, 3023 3023 sector_type, WIL_CID_ALL); 3024 3024 if (rc == -EINVAL) { 3025 - for (i = 0; i < max_assoc_sta; i++) { 3025 + for (i = 0; i < wil->max_assoc_sta; i++) { 3026 3026 if (wil->sta[i].mid != vif->mid) 3027 3027 continue; 3028 3028 rc = wil_rf_sector_wmi_set_selected(
+49 -21
drivers/net/wireless/ath/wil6210/debugfs.c
··· 63 63 &ring->va[idx].rx.enhanced; 64 64 u16 buff_id = le16_to_cpu(rx_d->mac.buff_id); 65 65 66 - has_skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; 66 + if (wil->rx_buff_mgmt.buff_arr && 67 + wil_val_in_range(buff_id, 0, wil->rx_buff_mgmt.size)) 68 + has_skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; 67 69 seq_printf(s, "%c", (has_skb) ? _h : _s); 68 70 } else { 69 71 struct wil_tx_enhanced_desc *d = ··· 73 71 &ring->va[idx].tx.enhanced; 74 72 75 73 num_of_descs = (u8)d->mac.d[2]; 76 - has_skb = ring->ctx[idx].skb; 74 + has_skb = ring->ctx && ring->ctx[idx].skb; 77 75 if (num_of_descs >= 1) 78 - seq_printf(s, "%c", ring->ctx[idx].skb ? _h : _s); 76 + seq_printf(s, "%c", has_skb ? _h : _s); 79 77 else 80 78 /* num_of_descs == 0, it's a frag in a list of descs */ 81 79 seq_printf(s, "%c", has_skb ? 'h' : _s); ··· 86 84 const char *name, struct wil_ring *ring, 87 85 char _s, char _h) 88 86 { 89 - void __iomem *x = wmi_addr(wil, ring->hwtail); 87 + void __iomem *x; 90 88 u32 v; 91 89 92 90 seq_printf(s, "RING %s = {\n", name); ··· 98 96 else 99 97 seq_printf(s, " swtail = %d\n", ring->swtail); 100 98 seq_printf(s, " swhead = %d\n", ring->swhead); 99 + if (wil->use_enhanced_dma_hw) { 100 + int ring_id = ring->is_rx ? 101 + WIL_RX_DESC_RING_ID : ring - wil->ring_tx; 102 + /* SUBQ_CONS is a table of 32 entries, one for each Q pair. 103 + * lower 16bits are for even ring_id and upper 16bits are for 104 + * odd ring_id 105 + */ 106 + x = wmi_addr(wil, RGF_DMA_SCM_SUBQ_CONS + 4 * (ring_id / 2)); 107 + v = readl_relaxed(x); 108 + 109 + v = (ring_id % 2 ? (v >> 16) : (v & 0xffff)); 110 + seq_printf(s, " hwhead = %u\n", v); 111 + } 101 112 seq_printf(s, " hwtail = [0x%08x] -> ", ring->hwtail); 113 + x = wmi_addr(wil, ring->hwtail); 102 114 if (x) { 103 115 v = readl(x); 104 116 seq_printf(s, "0x%08x = %d\n", v, v); ··· 178 162 179 163 snprintf(name, sizeof(name), "tx_%2d", i); 180 164 181 - if (cid < max_assoc_sta) 165 + if (cid < wil->max_assoc_sta) 182 166 seq_printf(s, 183 167 "\n%pM CID %d TID %d 1x%s BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n", 184 168 wil->sta[cid].addr, cid, tid, ··· 204 188 static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil, 205 189 struct wil_status_ring *sring) 206 190 { 207 - void __iomem *x = wmi_addr(wil, sring->hwtail); 191 + void __iomem *x; 208 192 int sring_idx = sring - wil->srings; 209 193 u32 v; 210 194 ··· 215 199 seq_printf(s, " size = %d\n", sring->size); 216 200 seq_printf(s, " elem_size = %zu\n", sring->elem_size); 217 201 seq_printf(s, " swhead = %d\n", sring->swhead); 202 + if (wil->use_enhanced_dma_hw) { 203 + /* COMPQ_PROD is a table of 32 entries, one for each Q pair. 204 + * lower 16bits are for even ring_id and upper 16bits are for 205 + * odd ring_id 206 + */ 207 + x = wmi_addr(wil, RGF_DMA_SCM_COMPQ_PROD + 4 * (sring_idx / 2)); 208 + v = readl_relaxed(x); 209 + 210 + v = (sring_idx % 2 ? (v >> 16) : (v & 0xffff)); 211 + seq_printf(s, " hwhead = %u\n", v); 212 + } 218 213 seq_printf(s, " hwtail = [0x%08x] -> ", sring->hwtail); 214 + x = wmi_addr(wil, sring->hwtail); 219 215 if (x) { 220 216 v = readl_relaxed(x); 221 217 seq_printf(s, "0x%08x = %d\n", v, v); ··· 839 811 "BACK: del_rx require at least 2 params\n"); 840 812 return -EINVAL; 841 813 } 842 - if (p1 < 0 || p1 >= max_assoc_sta) { 814 + if (p1 < 0 || p1 >= wil->max_assoc_sta) { 843 815 wil_err(wil, "BACK: invalid CID %d\n", p1); 844 816 return -EINVAL; 845 817 } ··· 1119 1091 1120 1092 if (wil->use_enhanced_dma_hw) { 1121 1093 if (tx) { 1122 - skb = ring->ctx[txdesc_idx].skb; 1123 - } else { 1094 + skb = ring->ctx ? ring->ctx[txdesc_idx].skb : NULL; 1095 + } else if (wil->rx_buff_mgmt.buff_arr) { 1124 1096 struct wil_rx_enhanced_desc *rx_d = 1125 1097 (struct wil_rx_enhanced_desc *) 1126 1098 &ring->va[txdesc_idx].rx.enhanced; 1127 1099 u16 buff_id = le16_to_cpu(rx_d->mac.buff_id); 1128 1100 1129 1101 if (!wil_val_in_range(buff_id, 0, 1130 - wil->rx_buff_mgmt.size)) { 1102 + wil->rx_buff_mgmt.size)) 1131 1103 seq_printf(s, "invalid buff_id %d\n", buff_id); 1132 - return 0; 1133 - } 1134 - skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; 1104 + else 1105 + skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; 1135 1106 } 1136 1107 } else { 1137 1108 skb = ring->ctx[txdesc_idx].skb; ··· 1163 1136 struct wil6210_priv *wil = s->private; 1164 1137 int sring_idx = dbg_sring_index; 1165 1138 struct wil_status_ring *sring; 1166 - bool tx = sring_idx == wil->tx_sring_idx ? 1 : 0; 1139 + bool tx; 1167 1140 u32 status_msg_idx = dbg_status_msg_index; 1168 1141 u32 *u; 1169 1142 ··· 1173 1146 } 1174 1147 1175 1148 sring = &wil->srings[sring_idx]; 1149 + tx = !sring->is_rx; 1176 1150 1177 1151 if (!sring->va) { 1178 1152 seq_printf(s, "No %cX status ring\n", tx ? 'T' : 'R'); ··· 1290 1262 1291 1263 memset(&reply, 0, sizeof(reply)); 1292 1264 1293 - for (i = 0; i < max_assoc_sta; i++) { 1265 + for (i = 0; i < wil->max_assoc_sta; i++) { 1294 1266 u32 status; 1295 1267 1296 1268 cmd.cid = i; ··· 1387 1359 if (!sinfo) 1388 1360 return -ENOMEM; 1389 1361 1390 - for (i = 0; i < max_assoc_sta; i++) { 1362 + for (i = 0; i < wil->max_assoc_sta; i++) { 1391 1363 struct wil_sta_info *p = &wil->sta[i]; 1392 1364 char *status = "unknown"; 1393 1365 struct wil6210_vif *vif; ··· 1589 1561 struct wil6210_priv *wil = s->private; 1590 1562 int i, tid, mcs; 1591 1563 1592 - for (i = 0; i < max_assoc_sta; i++) { 1564 + for (i = 0; i < wil->max_assoc_sta; i++) { 1593 1565 struct wil_sta_info *p = &wil->sta[i]; 1594 1566 char *status = "unknown"; 1595 1567 u8 aid = 0; ··· 1698 1670 struct wil6210_priv *wil = s->private; 1699 1671 int i, bin; 1700 1672 1701 - for (i = 0; i < max_assoc_sta; i++) { 1673 + for (i = 0; i < wil->max_assoc_sta; i++) { 1702 1674 struct wil_sta_info *p = &wil->sta[i]; 1703 1675 char *status = "unknown"; 1704 1676 u8 aid = 0; ··· 1787 1759 size_t sz = sizeof(u64) * WIL_NUM_LATENCY_BINS; 1788 1760 1789 1761 wil->tx_latency_res = val; 1790 - for (i = 0; i < max_assoc_sta; i++) { 1762 + for (i = 0; i < wil->max_assoc_sta; i++) { 1791 1763 struct wil_sta_info *sta = &wil->sta[i]; 1792 1764 1793 1765 kfree(sta->tx_latency_bins); ··· 1872 1844 } 1873 1845 1874 1846 seq_printf(s, "TSF %lld\n", vif->fw_stats_tsf); 1875 - for (i = 0; i < max_assoc_sta; i++) { 1847 + for (i = 0; i < wil->max_assoc_sta; i++) { 1876 1848 if (wil->sta[i].status == wil_sta_unused) 1877 1849 continue; 1878 1850 if (wil->sta[i].mid != vif->mid) ··· 2488 2460 wil->debug = NULL; 2489 2461 2490 2462 kfree(wil->dbg_data.data_arr); 2491 - for (i = 0; i < max_assoc_sta; i++) 2463 + for (i = 0; i < wil->max_assoc_sta; i++) 2492 2464 kfree(wil->sta[i].tx_latency_bins); 2493 2465 2494 2466 /* free pmc memory without sending command to fw, as it will
+8 -3
drivers/net/wireless/ath/wil6210/fw.h
··· 1 1 /* 2 2 * Copyright (c) 2014,2016 Qualcomm Atheros, Inc. 3 - * Copyright (c) 2018, The Linux Foundation. All rights reserved. 3 + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 4 4 * 5 5 * Permission to use, copy, modify, and/or distribute this software for any 6 6 * purpose with or without fee is hereby granted, provided that the above ··· 109 109 110 110 /* brd file info encoded inside a comment record */ 111 111 #define WIL_BRD_FILE_MAGIC (0xabcddcbb) 112 + 113 + struct brd_info { 114 + __le32 base_addr; 115 + __le32 max_size_bytes; 116 + } __packed; 117 + 112 118 struct wil_fw_record_brd_file { /* type == wil_fw_type_comment */ 113 119 /* identifies brd file record */ 114 120 struct wil_fw_record_comment_hdr hdr; 115 121 __le32 version; 116 - __le32 base_addr; 117 - __le32 max_size_bytes; 122 + struct brd_info brd_info[0]; 118 123 } __packed; 119 124 120 125 /* perform action
+110 -40
drivers/net/wireless/ath/wil6210/fw_inc.c
··· 156 156 size_t size) 157 157 { 158 158 const struct wil_fw_record_brd_file *rec = data; 159 + u32 max_num_ent, i, ent_size; 159 160 160 - if (size < sizeof(*rec)) { 161 - wil_err_fw(wil, "brd_file record too short: %zu\n", size); 162 - return 0; 161 + if (size <= offsetof(struct wil_fw_record_brd_file, brd_info)) { 162 + wil_err(wil, "board record too short, size %zu\n", size); 163 + return -EINVAL; 163 164 } 164 165 165 - wil->brd_file_addr = le32_to_cpu(rec->base_addr); 166 - wil->brd_file_max_size = le32_to_cpu(rec->max_size_bytes); 166 + ent_size = size - offsetof(struct wil_fw_record_brd_file, brd_info); 167 + max_num_ent = ent_size / sizeof(struct brd_info); 167 168 168 - wil_dbg_fw(wil, "brd_file_addr 0x%x, brd_file_max_size %d\n", 169 - wil->brd_file_addr, wil->brd_file_max_size); 169 + if (!max_num_ent) { 170 + wil_err(wil, "brd info entries are missing\n"); 171 + return -EINVAL; 172 + } 173 + 174 + wil->brd_info = kcalloc(max_num_ent, sizeof(struct wil_brd_info), 175 + GFP_KERNEL); 176 + if (!wil->brd_info) 177 + return -ENOMEM; 178 + 179 + for (i = 0; i < max_num_ent; i++) { 180 + wil->brd_info[i].file_addr = 181 + le32_to_cpu(rec->brd_info[i].base_addr); 182 + wil->brd_info[i].file_max_size = 183 + le32_to_cpu(rec->brd_info[i].max_size_bytes); 184 + 185 + if (!wil->brd_info[i].file_addr) 186 + break; 187 + 188 + wil_dbg_fw(wil, 189 + "brd info %d: file_addr 0x%x, file_max_size %d\n", 190 + i, wil->brd_info[i].file_addr, 191 + wil->brd_info[i].file_max_size); 192 + } 193 + 194 + wil->num_of_brd_entries = i; 195 + if (wil->num_of_brd_entries == 0) { 196 + kfree(wil->brd_info); 197 + wil->brd_info = NULL; 198 + wil_dbg_fw(wil, 199 + "no valid brd info entries, using brd file addr\n"); 200 + 201 + } else { 202 + wil_dbg_fw(wil, "num of brd info entries %d\n", 203 + wil->num_of_brd_entries); 204 + } 170 205 171 206 return 0; 172 207 } ··· 669 634 } 670 635 wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size); 671 636 637 + /* re-initialize board info params */ 638 + wil->num_of_brd_entries = 0; 639 + kfree(wil->brd_info); 640 + wil->brd_info = NULL; 641 + 672 642 for (sz = fw->size, d = fw->data; sz; sz -= rc1, d += rc1) { 673 643 rc1 = wil_fw_verify(wil, d, sz); 674 644 if (rc1 < 0) { ··· 702 662 { 703 663 int rc = 0; 704 664 const struct wil_fw_record_head *hdr = data; 705 - size_t s, hdr_sz; 665 + size_t s, hdr_sz = 0; 706 666 u16 type; 667 + int i = 0; 707 668 708 - /* Assuming the board file includes only one header record and one data 709 - * record. Each record starts with wil_fw_record_head. 669 + /* Assuming the board file includes only one file header 670 + * and one or several data records. 671 + * Each record starts with wil_fw_record_head. 710 672 */ 711 673 if (size < sizeof(*hdr)) 712 674 return -EINVAL; ··· 716 674 if (s > size) 717 675 return -EINVAL; 718 676 719 - /* Skip the header record and handle the data record */ 720 - hdr = (const void *)hdr + s; 677 + /* Skip the header record and handle the data records */ 721 678 size -= s; 722 - if (size < sizeof(*hdr)) 723 - return -EINVAL; 724 - hdr_sz = le32_to_cpu(hdr->size); 725 679 726 - if (wil->brd_file_max_size && hdr_sz > wil->brd_file_max_size) 727 - return -EINVAL; 728 - if (sizeof(*hdr) + hdr_sz > size) 729 - return -EINVAL; 730 - if (hdr_sz % 4) { 731 - wil_err_fw(wil, "unaligned record size: %zu\n", 732 - hdr_sz); 680 + for (hdr = data + s;; hdr = (const void *)hdr + s, size -= s, i++) { 681 + if (size < sizeof(*hdr)) 682 + break; 683 + 684 + if (i >= wil->num_of_brd_entries) { 685 + wil_err_fw(wil, 686 + "Too many brd records: %d, num of expected entries %d\n", 687 + i, wil->num_of_brd_entries); 688 + break; 689 + } 690 + 691 + hdr_sz = le32_to_cpu(hdr->size); 692 + s = sizeof(*hdr) + hdr_sz; 693 + if (wil->brd_info[i].file_max_size && 694 + hdr_sz > wil->brd_info[i].file_max_size) 695 + return -EINVAL; 696 + if (sizeof(*hdr) + hdr_sz > size) 697 + return -EINVAL; 698 + if (hdr_sz % 4) { 699 + wil_err_fw(wil, "unaligned record size: %zu\n", 700 + hdr_sz); 701 + return -EINVAL; 702 + } 703 + type = le16_to_cpu(hdr->type); 704 + if (type != wil_fw_type_data) { 705 + wil_err_fw(wil, 706 + "invalid record type for board file: %d\n", 707 + type); 708 + return -EINVAL; 709 + } 710 + if (hdr_sz < sizeof(struct wil_fw_record_data)) { 711 + wil_err_fw(wil, "data record too short: %zu\n", hdr_sz); 712 + return -EINVAL; 713 + } 714 + 715 + wil_dbg_fw(wil, 716 + "using info from fw file for record %d: addr[0x%08x], max size %d\n", 717 + i, wil->brd_info[i].file_addr, 718 + wil->brd_info[i].file_max_size); 719 + 720 + rc = __fw_handle_data(wil, &hdr[1], hdr_sz, 721 + cpu_to_le32(wil->brd_info[i].file_addr)); 722 + if (rc) 723 + return rc; 724 + } 725 + 726 + if (size) { 727 + wil_err_fw(wil, "unprocessed bytes: %zu\n", size); 728 + if (size >= sizeof(*hdr)) { 729 + wil_err_fw(wil, 730 + "Stop at offset %ld record type %d [%zd bytes]\n", 731 + (long)((const void *)hdr - data), 732 + le16_to_cpu(hdr->type), hdr_sz); 733 + } 733 734 return -EINVAL; 734 735 } 735 - type = le16_to_cpu(hdr->type); 736 - if (type != wil_fw_type_data) { 737 - wil_err_fw(wil, "invalid record type for board file: %d\n", 738 - type); 739 - return -EINVAL; 740 - } 741 - if (hdr_sz < sizeof(struct wil_fw_record_data)) { 742 - wil_err_fw(wil, "data record too short: %zu\n", hdr_sz); 743 - return -EINVAL; 744 - } 745 736 746 - wil_dbg_fw(wil, "using addr from fw file: [0x%08x]\n", 747 - wil->brd_file_addr); 748 - 749 - rc = __fw_handle_data(wil, &hdr[1], hdr_sz, 750 - cpu_to_le32(wil->brd_file_addr)); 751 - 752 - return rc; 737 + return 0; 753 738 } 754 739 755 740 /** ··· 807 738 rc = dlen; 808 739 goto out; 809 740 } 810 - /* Process the data record */ 741 + 742 + /* Process the data records */ 811 743 rc = wil_brd_process(wil, brd->data, dlen); 812 744 813 745 out:
+41 -26
drivers/net/wireless/ath/wil6210/interrupt.c
··· 296 296 static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 297 297 { 298 298 struct wil6210_priv *wil = cookie; 299 - u32 isr = wil_ioread32_and_clear(wil->csr + 300 - HOSTADDR(RGF_DMA_EP_RX_ICR) + 301 - offsetof(struct RGF_ICR, ICR)); 299 + u32 isr; 302 300 bool need_unmask = true; 301 + 302 + wil6210_mask_irq_rx(wil); 303 + 304 + isr = wil_ioread32_and_clear(wil->csr + 305 + HOSTADDR(RGF_DMA_EP_RX_ICR) + 306 + offsetof(struct RGF_ICR, ICR)); 303 307 304 308 trace_wil6210_irq_rx(isr); 305 309 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 306 310 307 311 if (unlikely(!isr)) { 308 312 wil_err_ratelimited(wil, "spurious IRQ: RX\n"); 313 + wil6210_unmask_irq_rx(wil); 309 314 return IRQ_NONE; 310 315 } 311 - 312 - wil6210_mask_irq_rx(wil); 313 316 314 317 /* RX_DONE and RX_HTRSH interrupts are the same if interrupt 315 318 * moderation is not used. Interrupt moderation may cause RX ··· 358 355 static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) 359 356 { 360 357 struct wil6210_priv *wil = cookie; 361 - u32 isr = wil_ioread32_and_clear(wil->csr + 362 - HOSTADDR(RGF_INT_GEN_RX_ICR) + 363 - offsetof(struct RGF_ICR, ICR)); 358 + u32 isr; 364 359 bool need_unmask = true; 360 + 361 + wil6210_mask_irq_rx_edma(wil); 362 + 363 + isr = wil_ioread32_and_clear(wil->csr + 364 + HOSTADDR(RGF_INT_GEN_RX_ICR) + 365 + offsetof(struct RGF_ICR, ICR)); 365 366 366 367 trace_wil6210_irq_rx(isr); 367 368 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 368 369 369 370 if (unlikely(!isr)) { 370 371 wil_err(wil, "spurious IRQ: RX\n"); 372 + wil6210_unmask_irq_rx_edma(wil); 371 373 return IRQ_NONE; 372 374 } 373 - 374 - wil6210_mask_irq_rx_edma(wil); 375 375 376 376 if (likely(isr & BIT_RX_STATUS_IRQ)) { 377 377 wil_dbg_irq(wil, "RX status ring\n"); ··· 409 403 static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) 410 404 { 411 405 struct wil6210_priv *wil = cookie; 412 - u32 isr = wil_ioread32_and_clear(wil->csr + 413 - HOSTADDR(RGF_INT_GEN_TX_ICR) + 414 - offsetof(struct RGF_ICR, ICR)); 406 + u32 isr; 415 407 bool need_unmask = true; 408 + 409 + wil6210_mask_irq_tx_edma(wil); 410 + 411 + isr = wil_ioread32_and_clear(wil->csr + 412 + HOSTADDR(RGF_INT_GEN_TX_ICR) + 413 + offsetof(struct RGF_ICR, ICR)); 416 414 417 415 trace_wil6210_irq_tx(isr); 418 416 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 419 417 420 418 if (unlikely(!isr)) { 421 419 wil_err(wil, "spurious IRQ: TX\n"); 420 + wil6210_unmask_irq_tx_edma(wil); 422 421 return IRQ_NONE; 423 422 } 424 - 425 - wil6210_mask_irq_tx_edma(wil); 426 423 427 424 if (likely(isr & BIT_TX_STATUS_IRQ)) { 428 425 wil_dbg_irq(wil, "TX status ring\n"); ··· 455 446 static irqreturn_t wil6210_irq_tx(int irq, void *cookie) 456 447 { 457 448 struct wil6210_priv *wil = cookie; 458 - u32 isr = wil_ioread32_and_clear(wil->csr + 459 - HOSTADDR(RGF_DMA_EP_TX_ICR) + 460 - offsetof(struct RGF_ICR, ICR)); 449 + u32 isr; 461 450 bool need_unmask = true; 451 + 452 + wil6210_mask_irq_tx(wil); 453 + 454 + isr = wil_ioread32_and_clear(wil->csr + 455 + HOSTADDR(RGF_DMA_EP_TX_ICR) + 456 + offsetof(struct RGF_ICR, ICR)); 462 457 463 458 trace_wil6210_irq_tx(isr); 464 459 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 465 460 466 461 if (unlikely(!isr)) { 467 462 wil_err_ratelimited(wil, "spurious IRQ: TX\n"); 463 + wil6210_unmask_irq_tx(wil); 468 464 return IRQ_NONE; 469 465 } 470 - 471 - wil6210_mask_irq_tx(wil); 472 466 473 467 if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) { 474 468 wil_dbg_irq(wil, "TX done\n"); ··· 544 532 static irqreturn_t wil6210_irq_misc(int irq, void *cookie) 545 533 { 546 534 struct wil6210_priv *wil = cookie; 547 - u32 isr = wil_ioread32_and_clear(wil->csr + 548 - HOSTADDR(RGF_DMA_EP_MISC_ICR) + 549 - offsetof(struct RGF_ICR, ICR)); 535 + u32 isr; 536 + 537 + wil6210_mask_irq_misc(wil, false); 538 + 539 + isr = wil_ioread32_and_clear(wil->csr + 540 + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 541 + offsetof(struct RGF_ICR, ICR)); 550 542 551 543 trace_wil6210_irq_misc(isr); 552 544 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr); 553 545 554 546 if (!isr) { 555 547 wil_err(wil, "spurious IRQ: MISC\n"); 548 + wil6210_unmask_irq_misc(wil, false); 556 549 return IRQ_NONE; 557 550 } 558 - 559 - wil6210_mask_irq_misc(wil, false); 560 551 561 552 if (isr & ISR_MISC_FW_ERROR) { 562 553 u32 fw_assert_code = wil_r(wil, wil->rgf_fw_assert_code_addr); ··· 595 580 /* no need to handle HALP ICRs until next vote */ 596 581 wil->halp.handle_icr = false; 597 582 wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n"); 598 - wil6210_mask_halp(wil); 583 + wil6210_mask_irq_misc(wil, true); 599 584 complete(&wil->halp.comp); 600 585 } 601 586 }
+13 -5
drivers/net/wireless/ath/wil6210/main.c
··· 241 241 { 242 242 int i; 243 243 244 - for (i = 0; i < max_assoc_sta; i++) { 244 + for (i = 0; i < wil->max_assoc_sta; i++) { 245 245 if (wil->sta[i].mid == mid && 246 246 wil->sta[i].status == wil_sta_connected) 247 247 return true; ··· 344 344 wil_disconnect_cid_complete(vif, cid, reason_code); 345 345 } else { /* all */ 346 346 wil_dbg_misc(wil, "Disconnect complete all\n"); 347 - for (cid = 0; cid < max_assoc_sta; cid++) 347 + for (cid = 0; cid < wil->max_assoc_sta; cid++) 348 348 wil_disconnect_cid_complete(vif, cid, reason_code); 349 349 } 350 350 ··· 456 456 wil_disconnect_cid(vif, cid, reason_code); 457 457 } else { /* all */ 458 458 wil_dbg_misc(wil, "Disconnect all\n"); 459 - for (cid = 0; cid < max_assoc_sta; cid++) 459 + for (cid = 0; cid < wil->max_assoc_sta; cid++) 460 460 wil_disconnect_cid(vif, cid, reason_code); 461 461 } 462 462 ··· 753 753 754 754 wil->reply_mid = U8_MAX; 755 755 wil->max_vifs = 1; 756 + wil->max_assoc_sta = max_assoc_sta; 756 757 757 758 /* edma configuration can be updated via debugfs before allocation */ 758 759 wil->num_rx_status_rings = WIL_DEFAULT_NUM_RX_STATUS_RINGS; ··· 839 838 wmi_event_flush(wil); 840 839 destroy_workqueue(wil->wq_service); 841 840 destroy_workqueue(wil->wmi_wq); 841 + kfree(wil->brd_info); 842 842 } 843 843 844 844 static void wil_shutdown_bl(struct wil6210_priv *wil) ··· 1711 1709 rc = wil_request_firmware(wil, wil->wil_fw_name, true); 1712 1710 if (rc) 1713 1711 goto out; 1714 - if (wil->brd_file_addr) 1712 + if (wil->num_of_brd_entries) 1715 1713 rc = wil_request_board(wil, board_file); 1716 1714 else 1717 1715 rc = wil_request_firmware(wil, board_file, true); ··· 1923 1921 int i; 1924 1922 int rc = -ENOENT; 1925 1923 1926 - for (i = 0; i < max_assoc_sta; i++) { 1924 + for (i = 0; i < wil->max_assoc_sta; i++) { 1927 1925 if (wil->sta[i].mid == mid && 1928 1926 wil->sta[i].status != wil_sta_unused && 1929 1927 ether_addr_equal(wil->sta[i].addr, mac)) { ··· 1939 1937 { 1940 1938 unsigned long rc; 1941 1939 unsigned long to_jiffies = msecs_to_jiffies(WAIT_FOR_HALP_VOTE_MS); 1940 + 1941 + if (wil->hw_version >= HW_VER_TALYN_MB) 1942 + return; 1942 1943 1943 1944 mutex_lock(&wil->halp.lock); 1944 1945 ··· 1974 1969 1975 1970 void wil_halp_unvote(struct wil6210_priv *wil) 1976 1971 { 1972 + if (wil->hw_version >= HW_VER_TALYN_MB) 1973 + return; 1974 + 1977 1975 WARN_ON(wil->halp.ref_cnt == 0); 1978 1976 1979 1977 mutex_lock(&wil->halp.lock);
+2
drivers/net/wireless/ath/wil6210/pcie_bus.c
··· 142 142 min(sizeof(wil->platform_capa), sizeof(platform_capa))); 143 143 } 144 144 145 + wil_info(wil, "platform_capa 0x%lx\n", *wil->platform_capa); 146 + 145 147 /* extract FW capabilities from file without loading the FW */ 146 148 wil_request_firmware(wil, wil->wil_fw_name, false); 147 149 wil_refresh_fw_capabilities(wil);
+1 -1
drivers/net/wireless/ath/wil6210/rx_reorder.c
··· 336 336 might_sleep(); 337 337 338 338 /* sanity checks */ 339 - if (cid >= max_assoc_sta) { 339 + if (cid >= wil->max_assoc_sta) { 340 340 wil_err(wil, "BACK: invalid CID %d\n", cid); 341 341 rc = -EINVAL; 342 342 goto out;
+15 -11
drivers/net/wireless/ath/wil6210/txrx.c
··· 411 411 ta = hdr->addr2; 412 412 } 413 413 414 - if (max_assoc_sta <= WIL6210_RX_DESC_MAX_CID) 414 + if (wil->max_assoc_sta <= WIL6210_RX_DESC_MAX_CID) 415 415 return cid; 416 416 417 417 /* assuming no concurrency between AP interfaces and STA interfaces. ··· 426 426 * to find the real cid, compare transmitter address with the stored 427 427 * stations mac address in the driver sta array 428 428 */ 429 - for (i = cid; i < max_assoc_sta; i += WIL6210_RX_DESC_MAX_CID) { 429 + for (i = cid; i < wil->max_assoc_sta; i += WIL6210_RX_DESC_MAX_CID) { 430 430 if (wil->sta[i].status != wil_sta_unused && 431 431 ether_addr_equal(wil->sta[i].addr, ta)) { 432 432 cid = i; 433 433 break; 434 434 } 435 435 } 436 - if (i >= max_assoc_sta) { 436 + if (i >= wil->max_assoc_sta) { 437 437 wil_err_ratelimited(wil, "Could not find cid for frame with transmit addr = %pM, iftype = %d, frametype = %d, len = %d\n", 438 438 ta, vif->wdev.iftype, ftype, skb->len); 439 439 cid = -ENOENT; ··· 750 750 [GRO_HELD] = "GRO_HELD", 751 751 [GRO_NORMAL] = "GRO_NORMAL", 752 752 [GRO_DROP] = "GRO_DROP", 753 + [GRO_CONSUMED] = "GRO_CONSUMED", 753 754 }; 754 755 755 756 wil->txrx_ops.get_netif_rx_params(skb, &cid, &security); ··· 1064 1063 txdata->enabled = 0; 1065 1064 spin_unlock_bh(&txdata->lock); 1066 1065 wil_vring_free(wil, vring); 1067 - wil->ring2cid_tid[id][0] = max_assoc_sta; 1066 + wil->ring2cid_tid[id][0] = wil->max_assoc_sta; 1068 1067 wil->ring2cid_tid[id][1] = 0; 1069 1068 1070 1069 out: ··· 1149 1148 txdata->dot1x_open = false; 1150 1149 txdata->enabled = 0; 1151 1150 spin_unlock_bh(&txdata->lock); 1152 - wil->ring2cid_tid[ring_id][0] = max_assoc_sta; 1151 + wil->ring2cid_tid[ring_id][0] = wil->max_assoc_sta; 1153 1152 wil->ring2cid_tid[ring_id][1] = 0; 1154 1153 return rc; 1155 1154 } ··· 1196 1195 if (rc) 1197 1196 goto out; 1198 1197 1199 - wil->ring2cid_tid[id][0] = max_assoc_sta; /* CID */ 1198 + wil->ring2cid_tid[id][0] = wil->max_assoc_sta; /* CID */ 1200 1199 wil->ring2cid_tid[id][1] = 0; /* TID */ 1201 1200 1202 1201 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); ··· 1244 1243 1245 1244 cid = wil_find_cid(wil, vif->mid, da); 1246 1245 1247 - if (cid < 0 || cid >= max_assoc_sta) 1246 + if (cid < 0 || cid >= wil->max_assoc_sta) 1248 1247 return NULL; 1249 1248 1250 1249 /* TODO: fix for multiple TID */ ··· 1296 1295 continue; 1297 1296 1298 1297 cid = wil->ring2cid_tid[i][0]; 1299 - if (cid >= max_assoc_sta) /* skip BCAST */ 1298 + if (cid >= wil->max_assoc_sta) /* skip BCAST */ 1300 1299 continue; 1301 1300 1302 1301 if (!wil->ring_tx_data[i].dot1x_open && ··· 1374 1373 continue; 1375 1374 1376 1375 cid = wil->ring2cid_tid[i][0]; 1377 - if (cid >= max_assoc_sta) /* skip BCAST */ 1376 + if (cid >= wil->max_assoc_sta) /* skip BCAST */ 1378 1377 continue; 1379 1378 if (!wil->ring_tx_data[i].dot1x_open && 1380 1379 skb->protocol != cpu_to_be16(ETH_P_PAE)) ··· 1402 1401 if (!v2->va || txdata2->mid != vif->mid) 1403 1402 continue; 1404 1403 cid = wil->ring2cid_tid[i][0]; 1405 - if (cid >= max_assoc_sta) /* skip BCAST */ 1404 + if (cid >= wil->max_assoc_sta) /* skip BCAST */ 1406 1405 continue; 1407 1406 if (!wil->ring_tx_data[i].dot1x_open && 1408 1407 skb->protocol != cpu_to_be16(ETH_P_PAE)) ··· 1760 1759 *_desc = *d; 1761 1760 } 1762 1761 } 1762 + 1763 + if (!_desc) 1764 + goto mem_error; 1763 1765 1764 1766 /* first descriptor may also be the last. 1765 1767 * in this case d pointer is invalid ··· 2258 2254 2259 2255 used_before_complete = wil_ring_used_tx(vring); 2260 2256 2261 - if (cid < max_assoc_sta) 2257 + if (cid < wil->max_assoc_sta) 2262 2258 stats = &wil->sta[cid].stats; 2263 2259 2264 2260 while (!wil_ring_is_empty(vring)) {
+7 -3
drivers/net/wireless/ath/wil6210/txrx_edma.c
··· 269 269 struct list_head *active = &wil->rx_buff_mgmt.active; 270 270 dma_addr_t pa; 271 271 272 + if (!wil->rx_buff_mgmt.buff_arr) 273 + return; 274 + 272 275 while (!list_empty(active)) { 273 276 struct wil_rx_buff *rx_buff = 274 277 list_first_entry(active, struct wil_rx_buff, list); ··· 737 734 txdata->enabled = 0; 738 735 spin_unlock_bh(&txdata->lock); 739 736 wil_ring_free_edma(wil, ring); 740 - wil->ring2cid_tid[ring_id][0] = max_assoc_sta; 737 + wil->ring2cid_tid[ring_id][0] = wil->max_assoc_sta; 741 738 wil->ring2cid_tid[ring_id][1] = 0; 742 739 743 740 out: ··· 947 944 eop = wil_rx_status_get_eop(msg); 948 945 949 946 cid = wil_rx_status_get_cid(msg); 950 - if (unlikely(!wil_val_in_range(cid, 0, max_assoc_sta))) { 947 + if (unlikely(!wil_val_in_range(cid, 0, wil->max_assoc_sta))) { 951 948 wil_err(wil, "Corrupt cid=%d, sring->swhead=%d\n", 952 949 cid, sring->swhead); 953 950 rxdata->skipping = true; ··· 1202 1199 ndev = vif_to_ndev(vif); 1203 1200 1204 1201 cid = wil->ring2cid_tid[ring_id][0]; 1205 - stats = (cid < max_assoc_sta ? &wil->sta[cid].stats : NULL); 1202 + stats = (cid < wil->max_assoc_sta) ? &wil->sta[cid].stats : 1203 + NULL; 1206 1204 1207 1205 wil_dbg_txrx(wil, 1208 1206 "tx_status: completed desc_ring (%d), num_descs (%d)\n",
+22 -11
drivers/net/wireless/ath/wil6210/wil6210.h
··· 335 335 #define BIT_BOOT_FROM_ROM BIT(31) 336 336 337 337 /* eDMA */ 338 + #define RGF_SCM_PTRS_SUBQ_RD_PTR (0x8b4000) 339 + #define RGF_SCM_PTRS_COMPQ_RD_PTR (0x8b4100) 340 + #define RGF_DMA_SCM_SUBQ_CONS (0x8b60ec) 341 + #define RGF_DMA_SCM_COMPQ_PROD (0x8b616c) 342 + 338 343 #define RGF_INT_COUNT_ON_SPECIAL_EVT (0x8b62d8) 339 344 340 345 #define RGF_INT_CTRL_INT_GEN_CFG_0 (0x8bc000) ··· 459 454 { 460 455 *cid = cidxtid & 0xf; 461 456 *tid = (cidxtid >> 4) & 0xf; 462 - } 463 - 464 - /** 465 - * wil_cid_valid - check cid is valid 466 - * @cid: CID value 467 - */ 468 - static inline bool wil_cid_valid(u8 cid) 469 - { 470 - return (cid >= 0 && cid < max_assoc_sta); 471 457 } 472 458 473 459 struct wil6210_mbox_ring { ··· 909 913 struct wmi_link_stats_global stats; 910 914 }; 911 915 916 + struct wil_brd_info { 917 + u32 file_addr; 918 + u32 file_max_size; 919 + }; 920 + 912 921 struct wil6210_priv { 913 922 struct pci_dev *pdev; 914 923 u32 bar_size; ··· 928 927 const char *hw_name; 929 928 const char *wil_fw_name; 930 929 char *board_file; 931 - u32 brd_file_addr; 932 - u32 brd_file_max_size; 930 + u32 num_of_brd_entries; 931 + struct wil_brd_info *brd_info; 933 932 DECLARE_BITMAP(hw_capa, hw_capa_last); 934 933 DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX); 935 934 DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX); ··· 941 940 struct wil6210_vif *vifs[WIL_MAX_VIFS]; 942 941 struct mutex vif_mutex; /* protects access to VIF entries */ 943 942 atomic_t connected_vifs; 943 + u32 max_assoc_sta; /* max sta's supported by the driver and the FW */ 944 + 944 945 /* profile */ 945 946 struct cfg80211_chan_def monitor_chandef; 946 947 u32 monitor_flags; ··· 1138 1135 static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val) 1139 1136 { 1140 1137 wil_w(wil, reg, wil_r(wil, reg) & ~val); 1138 + } 1139 + 1140 + /** 1141 + * wil_cid_valid - check cid is valid 1142 + */ 1143 + static inline bool wil_cid_valid(struct wil6210_priv *wil, u8 cid) 1144 + { 1145 + return (cid >= 0 && cid < wil->max_assoc_sta); 1141 1146 } 1142 1147 1143 1148 void wil_get_board_file(struct wil6210_priv *wil, char *buf, size_t len);
+7 -7
drivers/net/wireless/ath/wil6210/wmi.c
··· 806 806 } 807 807 } 808 808 809 - max_assoc_sta = min_t(uint, max_assoc_sta, fw_max_assoc_sta); 810 - wil_dbg_wmi(wil, "setting max assoc sta to %d\n", max_assoc_sta); 809 + wil->max_assoc_sta = min_t(uint, max_assoc_sta, fw_max_assoc_sta); 810 + wil_dbg_wmi(wil, "setting max assoc sta to %d\n", wil->max_assoc_sta); 811 811 812 812 wil_set_recovery_state(wil, fw_recovery_idle); 813 813 set_bit(wil_status_fwready, wil->status); ··· 974 974 evt->assoc_req_len, evt->assoc_resp_len); 975 975 return; 976 976 } 977 - if (evt->cid >= max_assoc_sta) { 977 + if (evt->cid >= wil->max_assoc_sta) { 978 978 wil_err(wil, "Connect CID invalid : %d\n", evt->cid); 979 979 return; 980 980 } ··· 1236 1236 return; 1237 1237 1238 1238 cid = wil->ring2cid_tid[vri][0]; 1239 - if (!wil_cid_valid(cid)) { 1239 + if (!wil_cid_valid(wil, cid)) { 1240 1240 wil_err(wil, "invalid cid %d for vring %d\n", cid, vri); 1241 1241 return; 1242 1242 } ··· 1439 1439 u8 cid = basic->cid; 1440 1440 struct wil_sta_info *sta; 1441 1441 1442 - if (cid < 0 || cid >= max_assoc_sta) { 1442 + if (cid < 0 || cid >= wil->max_assoc_sta) { 1443 1443 wil_err(wil, "invalid cid %d\n", cid); 1444 1444 return; 1445 1445 } ··· 1589 1589 continue; 1590 1590 1591 1591 lcid = wil->ring2cid_tid[i][0]; 1592 - if (lcid >= max_assoc_sta) /* skip BCAST */ 1592 + if (lcid >= wil->max_assoc_sta) /* skip BCAST */ 1593 1593 continue; 1594 1594 1595 1595 wil_dbg_wmi(wil, "find sta -> ringid %d cid %d\n", i, lcid); ··· 2135 2135 .network_type = wmi_nettype, 2136 2136 .disable_sec_offload = 1, 2137 2137 .channel = chan - 1, 2138 - .pcp_max_assoc_sta = max_assoc_sta, 2138 + .pcp_max_assoc_sta = wil->max_assoc_sta, 2139 2139 .hidden_ssid = hidden_ssid, 2140 2140 .is_go = is_go, 2141 2141 .ap_sme_offload_mode = disable_ap_sme ?