.. | .. |
---|
| 1 | +// SPDX-License-Identifier: ISC |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. |
---|
3 | | - * Copyright (c) 2018, The Linux Foundation. All rights reserved. |
---|
4 | | - * |
---|
5 | | - * Permission to use, copy, modify, and/or distribute this software for any |
---|
6 | | - * purpose with or without fee is hereby granted, provided that the above |
---|
7 | | - * copyright notice and this permission notice appear in all copies. |
---|
8 | | - * |
---|
9 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
10 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
11 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
12 | | - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
13 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
14 | | - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
15 | | - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
| 4 | + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. |
---|
16 | 5 | */ |
---|
17 | 6 | |
---|
18 | 7 | #include <linux/moduleparam.h> |
---|
.. | .. |
---|
24 | 13 | #include "wmi.h" |
---|
25 | 14 | #include "trace.h" |
---|
26 | 15 | |
---|
27 | | -static uint max_assoc_sta = WIL6210_MAX_CID; |
---|
28 | | -module_param(max_assoc_sta, uint, 0644); |
---|
| 16 | +/* set the default max assoc sta to max supported by driver */ |
---|
| 17 | +uint max_assoc_sta = WIL6210_MAX_CID; |
---|
| 18 | +module_param(max_assoc_sta, uint, 0444); |
---|
29 | 19 | MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP"); |
---|
30 | 20 | |
---|
31 | 21 | int agg_wsize; /* = 0; */ |
---|
.. | .. |
---|
39 | 29 | " 60G device led enablement. Set the led ID (0-2) to enable"); |
---|
40 | 30 | |
---|
41 | 31 | #define WIL_WAIT_FOR_SUSPEND_RESUME_COMP 200 |
---|
42 | | -#define WIL_WMI_CALL_GENERAL_TO_MS 100 |
---|
| 32 | +#define WIL_WMI_PCP_STOP_TO_MS 5000 |
---|
43 | 33 | |
---|
44 | 34 | /** |
---|
45 | | - * WMI event receiving - theory of operations |
---|
| 35 | + * DOC: WMI event receiving - theory of operations |
---|
46 | 36 | * |
---|
47 | 37 | * When firmware about to report WMI event, it fills memory area |
---|
48 | 38 | * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for |
---|
.. | .. |
---|
59 | 49 | */ |
---|
60 | 50 | |
---|
61 | 51 | /** |
---|
62 | | - * Addressing - theory of operations |
---|
| 52 | + * DOC: Addressing - theory of operations |
---|
63 | 53 | * |
---|
64 | 54 | * There are several buses present on the WIL6210 card. |
---|
65 | 55 | * Same memory areas are visible at different address on |
---|
.. | .. |
---|
76 | 66 | * AHB address must be used. |
---|
77 | 67 | */ |
---|
78 | 68 | |
---|
79 | | -/** |
---|
80 | | - * @sparrow_fw_mapping provides memory remapping table for sparrow |
---|
| 69 | +/* sparrow_fw_mapping provides memory remapping table for sparrow |
---|
81 | 70 | * |
---|
82 | 71 | * array size should be in sync with the declaration in the wil6210.h |
---|
83 | 72 | * |
---|
.. | .. |
---|
113 | 102 | {0x800000, 0x804000, 0x940000, "uc_data", false, false}, |
---|
114 | 103 | }; |
---|
115 | 104 | |
---|
116 | | -/** |
---|
117 | | - * @sparrow_d0_mac_rgf_ext - mac_rgf_ext section for Sparrow D0 |
---|
| 105 | +/* sparrow_d0_mac_rgf_ext - mac_rgf_ext section for Sparrow D0 |
---|
118 | 106 | * it is a bit larger to support extra features |
---|
119 | 107 | */ |
---|
120 | 108 | const struct fw_map sparrow_d0_mac_rgf_ext = { |
---|
121 | 109 | 0x88c000, 0x88c500, 0x88c000, "mac_rgf_ext", true, true |
---|
122 | 110 | }; |
---|
123 | 111 | |
---|
124 | | -/** |
---|
125 | | - * @talyn_fw_mapping provides memory remapping table for Talyn |
---|
| 112 | +/* talyn_fw_mapping provides memory remapping table for Talyn |
---|
126 | 113 | * |
---|
127 | 114 | * array size should be in sync with the declaration in the wil6210.h |
---|
128 | 115 | * |
---|
.. | .. |
---|
164 | 151 | {0x800000, 0x808000, 0xa78000, "uc_data", false, false}, |
---|
165 | 152 | }; |
---|
166 | 153 | |
---|
167 | | -/** |
---|
168 | | - * @talyn_mb_fw_mapping provides memory remapping table for Talyn-MB |
---|
| 154 | +/* talyn_mb_fw_mapping provides memory remapping table for Talyn-MB |
---|
169 | 155 | * |
---|
170 | 156 | * array size should be in sync with the declaration in the wil6210.h |
---|
171 | 157 | * |
---|
.. | .. |
---|
206 | 192 | {0x8c0000, 0x8c0210, 0x8c0000, "dum_user_rgf", true, true}, |
---|
207 | 193 | /* DMA OFU 296b */ |
---|
208 | 194 | {0x8c2000, 0x8c2128, 0x8c2000, "dma_ofu", true, true}, |
---|
209 | | - /* ucode debug 4k */ |
---|
210 | | - {0x8c3000, 0x8c4000, 0x8c3000, "ucode_debug", true, true}, |
---|
| 195 | + /* ucode debug 256b */ |
---|
| 196 | + {0x8c3000, 0x8c3100, 0x8c3000, "ucode_debug", true, true}, |
---|
211 | 197 | /* upper area 1536k */ |
---|
212 | 198 | {0x900000, 0xa80000, 0x900000, "upper", true, true}, |
---|
213 | 199 | /* UCODE areas - accessible by debugfs blobs but not by |
---|
.. | .. |
---|
227 | 213 | {WIL_LED_BLINK_ON_FAST_MS, WIL_LED_BLINK_OFF_FAST_MS}, |
---|
228 | 214 | }; |
---|
229 | 215 | |
---|
| 216 | +struct auth_no_hdr { |
---|
| 217 | + __le16 auth_alg; |
---|
| 218 | + __le16 auth_transaction; |
---|
| 219 | + __le16 status_code; |
---|
| 220 | + /* possibly followed by Challenge text */ |
---|
| 221 | + u8 variable[]; |
---|
| 222 | +} __packed; |
---|
| 223 | + |
---|
230 | 224 | u8 led_polarity = LED_POLARITY_LOW_ACTIVE; |
---|
231 | 225 | |
---|
232 | 226 | /** |
---|
233 | 227 | * return AHB address for given firmware internal (linker) address |
---|
234 | | - * @x - internal address |
---|
| 228 | + * @x: internal address |
---|
235 | 229 | * If address have no valid AHB mapping, return 0 |
---|
236 | 230 | */ |
---|
237 | 231 | static u32 wmi_addr_remap(u32 x) |
---|
.. | .. |
---|
249 | 243 | |
---|
250 | 244 | /** |
---|
251 | 245 | * find fw_mapping entry by section name |
---|
252 | | - * @section - section name |
---|
| 246 | + * @section: section name |
---|
253 | 247 | * |
---|
254 | 248 | * Return pointer to section or NULL if not found |
---|
255 | 249 | */ |
---|
.. | .. |
---|
267 | 261 | |
---|
268 | 262 | /** |
---|
269 | 263 | * Check address validity for WMI buffer; remap if needed |
---|
270 | | - * @ptr - internal (linker) fw/ucode address |
---|
271 | | - * @size - if non zero, validate the block does not |
---|
| 264 | + * @wil: driver data |
---|
| 265 | + * @ptr: internal (linker) fw/ucode address |
---|
| 266 | + * @size: if non zero, validate the block does not |
---|
272 | 267 | * exceed the device memory (bar) |
---|
273 | 268 | * |
---|
274 | 269 | * Valid buffer should be DWORD aligned |
---|
.. | .. |
---|
302 | 297 | return wmi_buffer_block(wil, ptr_, 0); |
---|
303 | 298 | } |
---|
304 | 299 | |
---|
305 | | -/** |
---|
306 | | - * Check address validity |
---|
307 | | - */ |
---|
| 300 | +/* Check address validity */ |
---|
308 | 301 | void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr) |
---|
309 | 302 | { |
---|
310 | 303 | u32 off; |
---|
.. | .. |
---|
468 | 461 | return "WMI_LINK_STATS_CMD"; |
---|
469 | 462 | case WMI_SW_TX_REQ_EXT_CMDID: |
---|
470 | 463 | return "WMI_SW_TX_REQ_EXT_CMDID"; |
---|
| 464 | + case WMI_FT_AUTH_CMDID: |
---|
| 465 | + return "WMI_FT_AUTH_CMD"; |
---|
| 466 | + case WMI_FT_REASSOC_CMDID: |
---|
| 467 | + return "WMI_FT_REASSOC_CMD"; |
---|
| 468 | + case WMI_UPDATE_FT_IES_CMDID: |
---|
| 469 | + return "WMI_UPDATE_FT_IES_CMD"; |
---|
| 470 | + case WMI_RBUFCAP_CFG_CMDID: |
---|
| 471 | + return "WMI_RBUFCAP_CFG_CMD"; |
---|
| 472 | + case WMI_TEMP_SENSE_ALL_CMDID: |
---|
| 473 | + return "WMI_TEMP_SENSE_ALL_CMDID"; |
---|
| 474 | + case WMI_SET_LINK_MONITOR_CMDID: |
---|
| 475 | + return "WMI_SET_LINK_MONITOR_CMD"; |
---|
471 | 476 | default: |
---|
472 | 477 | return "Untracked CMD"; |
---|
473 | 478 | } |
---|
.. | .. |
---|
606 | 611 | return "WMI_LINK_STATS_CONFIG_DONE_EVENT"; |
---|
607 | 612 | case WMI_LINK_STATS_EVENTID: |
---|
608 | 613 | return "WMI_LINK_STATS_EVENT"; |
---|
| 614 | + case WMI_COMMAND_NOT_SUPPORTED_EVENTID: |
---|
| 615 | + return "WMI_COMMAND_NOT_SUPPORTED_EVENT"; |
---|
| 616 | + case WMI_FT_AUTH_STATUS_EVENTID: |
---|
| 617 | + return "WMI_FT_AUTH_STATUS_EVENT"; |
---|
| 618 | + case WMI_FT_REASSOC_STATUS_EVENTID: |
---|
| 619 | + return "WMI_FT_REASSOC_STATUS_EVENT"; |
---|
| 620 | + case WMI_RBUFCAP_CFG_EVENTID: |
---|
| 621 | + return "WMI_RBUFCAP_CFG_EVENT"; |
---|
| 622 | + case WMI_TEMP_SENSE_ALL_DONE_EVENTID: |
---|
| 623 | + return "WMI_TEMP_SENSE_ALL_DONE_EVENTID"; |
---|
| 624 | + case WMI_SET_LINK_MONITOR_EVENTID: |
---|
| 625 | + return "WMI_SET_LINK_MONITOR_EVENT"; |
---|
| 626 | + case WMI_LINK_MONITOR_EVENTID: |
---|
| 627 | + return "WMI_LINK_MONITOR_EVENT"; |
---|
609 | 628 | default: |
---|
610 | 629 | return "Untracked EVENT"; |
---|
611 | 630 | } |
---|
.. | .. |
---|
750 | 769 | struct wil6210_priv *wil = vif_to_wil(vif); |
---|
751 | 770 | struct wiphy *wiphy = wil_to_wiphy(wil); |
---|
752 | 771 | struct wmi_ready_event *evt = d; |
---|
| 772 | + u8 fw_max_assoc_sta; |
---|
753 | 773 | |
---|
754 | 774 | wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n", |
---|
755 | 775 | wil->fw_version, le32_to_cpu(evt->sw_version), |
---|
.. | .. |
---|
767 | 787 | evt->rfc_read_calib_result); |
---|
768 | 788 | wil->fw_calib_result = evt->rfc_read_calib_result; |
---|
769 | 789 | } |
---|
| 790 | + |
---|
| 791 | + fw_max_assoc_sta = WIL6210_RX_DESC_MAX_CID; |
---|
| 792 | + if (len > offsetof(struct wmi_ready_event, max_assoc_sta) && |
---|
| 793 | + evt->max_assoc_sta > 0) { |
---|
| 794 | + fw_max_assoc_sta = evt->max_assoc_sta; |
---|
| 795 | + wil_dbg_wmi(wil, "fw reported max assoc sta %d\n", |
---|
| 796 | + fw_max_assoc_sta); |
---|
| 797 | + |
---|
| 798 | + if (fw_max_assoc_sta > WIL6210_MAX_CID) { |
---|
| 799 | + wil_dbg_wmi(wil, |
---|
| 800 | + "fw max assoc sta %d exceeds max driver supported %d\n", |
---|
| 801 | + fw_max_assoc_sta, WIL6210_MAX_CID); |
---|
| 802 | + fw_max_assoc_sta = WIL6210_MAX_CID; |
---|
| 803 | + } |
---|
| 804 | + } |
---|
| 805 | + |
---|
| 806 | + wil->max_assoc_sta = min_t(uint, max_assoc_sta, fw_max_assoc_sta); |
---|
| 807 | + wil_dbg_wmi(wil, "setting max assoc sta to %d\n", wil->max_assoc_sta); |
---|
| 808 | + |
---|
770 | 809 | wil_set_recovery_state(wil, fw_recovery_idle); |
---|
771 | 810 | set_bit(wil_status_fwready, wil->status); |
---|
772 | 811 | /* let the reset sequence continue */ |
---|
.. | .. |
---|
829 | 868 | |
---|
830 | 869 | if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { |
---|
831 | 870 | struct cfg80211_bss *bss; |
---|
| 871 | + struct cfg80211_inform_bss bss_data = { |
---|
| 872 | + .chan = channel, |
---|
| 873 | + .scan_width = NL80211_BSS_CHAN_WIDTH_20, |
---|
| 874 | + .signal = signal, |
---|
| 875 | + .boottime_ns = ktime_to_ns(ktime_get_boottime()), |
---|
| 876 | + }; |
---|
832 | 877 | u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); |
---|
833 | 878 | u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); |
---|
834 | 879 | u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); |
---|
.. | .. |
---|
843 | 888 | |
---|
844 | 889 | wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); |
---|
845 | 890 | |
---|
846 | | - bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, |
---|
847 | | - d_len, signal, GFP_KERNEL); |
---|
| 891 | + bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data, |
---|
| 892 | + rx_mgmt_frame, |
---|
| 893 | + d_len, GFP_KERNEL); |
---|
848 | 894 | if (bss) { |
---|
849 | 895 | wil_dbg_wmi(wil, "Added BSS %pM\n", |
---|
850 | 896 | rx_mgmt_frame->bssid); |
---|
.. | .. |
---|
932 | 978 | evt->assoc_req_len, evt->assoc_resp_len); |
---|
933 | 979 | return; |
---|
934 | 980 | } |
---|
935 | | - if (evt->cid >= WIL6210_MAX_CID) { |
---|
| 981 | + if (evt->cid >= wil->max_assoc_sta) { |
---|
936 | 982 | wil_err(wil, "Connect CID invalid : %d\n", evt->cid); |
---|
937 | 983 | return; |
---|
938 | 984 | } |
---|
.. | .. |
---|
998 | 1044 | wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n", |
---|
999 | 1045 | evt->cid, rc); |
---|
1000 | 1046 | wmi_disconnect_sta(vif, wil->sta[evt->cid].addr, |
---|
1001 | | - WLAN_REASON_UNSPECIFIED, false, false); |
---|
| 1047 | + WLAN_REASON_UNSPECIFIED, false); |
---|
1002 | 1048 | } else { |
---|
1003 | 1049 | wil_info(wil, "successful connection to CID %d\n", evt->cid); |
---|
1004 | 1050 | } |
---|
.. | .. |
---|
1092 | 1138 | } |
---|
1093 | 1139 | |
---|
1094 | 1140 | mutex_lock(&wil->mutex); |
---|
1095 | | - wil6210_disconnect(vif, evt->bssid, reason_code, true); |
---|
| 1141 | + wil6210_disconnect_complete(vif, evt->bssid, reason_code); |
---|
| 1142 | + if (disable_ap_sme) { |
---|
| 1143 | + struct wireless_dev *wdev = vif_to_wdev(vif); |
---|
| 1144 | + struct net_device *ndev = vif_to_ndev(vif); |
---|
| 1145 | + |
---|
| 1146 | + /* disconnect event in disable_ap_sme mode means link loss */ |
---|
| 1147 | + switch (wdev->iftype) { |
---|
| 1148 | + /* AP-like interface */ |
---|
| 1149 | + case NL80211_IFTYPE_AP: |
---|
| 1150 | + case NL80211_IFTYPE_P2P_GO: |
---|
| 1151 | + /* notify hostapd about link loss */ |
---|
| 1152 | + cfg80211_cqm_pktloss_notify(ndev, evt->bssid, 0, |
---|
| 1153 | + GFP_KERNEL); |
---|
| 1154 | + break; |
---|
| 1155 | + default: |
---|
| 1156 | + break; |
---|
| 1157 | + } |
---|
| 1158 | + } |
---|
1096 | 1159 | mutex_unlock(&wil->mutex); |
---|
1097 | 1160 | } |
---|
1098 | 1161 | |
---|
.. | .. |
---|
1156 | 1219 | struct wmi_ring_en_event *evt = d; |
---|
1157 | 1220 | u8 vri = evt->ring_index; |
---|
1158 | 1221 | struct wireless_dev *wdev = vif_to_wdev(vif); |
---|
| 1222 | + struct wil_sta_info *sta; |
---|
| 1223 | + u8 cid; |
---|
| 1224 | + struct key_params params; |
---|
1159 | 1225 | |
---|
1160 | 1226 | wil_dbg_wmi(wil, "Enable vring %d MID %d\n", vri, vif->mid); |
---|
1161 | 1227 | |
---|
.. | .. |
---|
1164 | 1230 | return; |
---|
1165 | 1231 | } |
---|
1166 | 1232 | |
---|
1167 | | - if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme) |
---|
1168 | | - /* in AP mode with disable_ap_sme, this is done by |
---|
1169 | | - * wil_cfg80211_change_station() |
---|
| 1233 | + if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme || |
---|
| 1234 | + test_bit(wil_vif_ft_roam, vif->status)) |
---|
| 1235 | + /* in AP mode with disable_ap_sme that is not FT, |
---|
| 1236 | + * this is done by wil_cfg80211_change_station() |
---|
1170 | 1237 | */ |
---|
1171 | 1238 | wil->ring_tx_data[vri].dot1x_open = true; |
---|
1172 | 1239 | if (vri == vif->bcast_ring) /* no BA for bcast */ |
---|
1173 | 1240 | return; |
---|
| 1241 | + |
---|
| 1242 | + cid = wil->ring2cid_tid[vri][0]; |
---|
| 1243 | + if (!wil_cid_valid(wil, cid)) { |
---|
| 1244 | + wil_err(wil, "invalid cid %d for vring %d\n", cid, vri); |
---|
| 1245 | + return; |
---|
| 1246 | + } |
---|
| 1247 | + |
---|
| 1248 | + /* In FT mode we get key but not store it as it is received |
---|
| 1249 | + * before WMI_CONNECT_EVENT received from FW. |
---|
| 1250 | + * wil_set_crypto_rx is called here to reset the security PN |
---|
| 1251 | + */ |
---|
| 1252 | + sta = &wil->sta[cid]; |
---|
| 1253 | + if (test_bit(wil_vif_ft_roam, vif->status)) { |
---|
| 1254 | + memset(¶ms, 0, sizeof(params)); |
---|
| 1255 | + wil_set_crypto_rx(0, WMI_KEY_USE_PAIRWISE, sta, ¶ms); |
---|
| 1256 | + if (wdev->iftype != NL80211_IFTYPE_AP) |
---|
| 1257 | + clear_bit(wil_vif_ft_roam, vif->status); |
---|
| 1258 | + } |
---|
| 1259 | + |
---|
1174 | 1260 | if (agg_wsize >= 0) |
---|
1175 | 1261 | wil_addba_tx_request(wil, vri, agg_wsize); |
---|
1176 | 1262 | } |
---|
.. | .. |
---|
1211 | 1297 | void *d, int len) |
---|
1212 | 1298 | { |
---|
1213 | 1299 | struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 1300 | + u8 cid, tid; |
---|
1214 | 1301 | struct wmi_rcp_addba_req_event *evt = d; |
---|
1215 | 1302 | |
---|
1216 | | - wil_addba_rx_request(wil, vif->mid, evt->cidxtid, evt->dialog_token, |
---|
| 1303 | + if (evt->cidxtid != CIDXTID_EXTENDED_CID_TID) { |
---|
| 1304 | + parse_cidxtid(evt->cidxtid, &cid, &tid); |
---|
| 1305 | + } else { |
---|
| 1306 | + cid = evt->cid; |
---|
| 1307 | + tid = evt->tid; |
---|
| 1308 | + } |
---|
| 1309 | + wil_addba_rx_request(wil, vif->mid, cid, tid, evt->dialog_token, |
---|
1217 | 1310 | evt->ba_param_set, evt->ba_timeout, |
---|
1218 | 1311 | evt->ba_seq_ctrl); |
---|
1219 | 1312 | } |
---|
.. | .. |
---|
1229 | 1322 | struct wil_tid_ampdu_rx *r; |
---|
1230 | 1323 | |
---|
1231 | 1324 | might_sleep(); |
---|
1232 | | - parse_cidxtid(evt->cidxtid, &cid, &tid); |
---|
| 1325 | + |
---|
| 1326 | + if (evt->cidxtid != CIDXTID_EXTENDED_CID_TID) { |
---|
| 1327 | + parse_cidxtid(evt->cidxtid, &cid, &tid); |
---|
| 1328 | + } else { |
---|
| 1329 | + cid = evt->cid; |
---|
| 1330 | + tid = evt->tid; |
---|
| 1331 | + } |
---|
| 1332 | + |
---|
| 1333 | + if (!wil_cid_valid(wil, cid)) { |
---|
| 1334 | + wil_err(wil, "DELBA: Invalid CID %d\n", cid); |
---|
| 1335 | + return; |
---|
| 1336 | + } |
---|
| 1337 | + |
---|
1233 | 1338 | wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n", |
---|
1234 | 1339 | vif->mid, cid, tid, |
---|
1235 | 1340 | evt->from_initiator ? "originator" : "recipient", |
---|
.. | .. |
---|
1283 | 1388 | __le16 fc; |
---|
1284 | 1389 | u32 d_len; |
---|
1285 | 1390 | struct cfg80211_bss *bss; |
---|
| 1391 | + struct cfg80211_inform_bss bss_data = { |
---|
| 1392 | + .scan_width = NL80211_BSS_CHAN_WIDTH_20, |
---|
| 1393 | + .boottime_ns = ktime_to_ns(ktime_get_boottime()), |
---|
| 1394 | + }; |
---|
1286 | 1395 | |
---|
1287 | 1396 | if (flen < 0) { |
---|
1288 | 1397 | wil_err(wil, "sched scan result event too short, len %d\n", |
---|
.. | .. |
---|
1325 | 1434 | return; |
---|
1326 | 1435 | } |
---|
1327 | 1436 | |
---|
1328 | | - bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, |
---|
1329 | | - d_len, signal, GFP_KERNEL); |
---|
| 1437 | + bss_data.signal = signal; |
---|
| 1438 | + bss_data.chan = channel; |
---|
| 1439 | + bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data, rx_mgmt_frame, |
---|
| 1440 | + d_len, GFP_KERNEL); |
---|
1330 | 1441 | if (bss) { |
---|
1331 | 1442 | wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid); |
---|
1332 | 1443 | cfg80211_put_bss(wiphy, bss); |
---|
.. | .. |
---|
1344 | 1455 | u8 cid = basic->cid; |
---|
1345 | 1456 | struct wil_sta_info *sta; |
---|
1346 | 1457 | |
---|
1347 | | - if (cid < 0 || cid >= WIL6210_MAX_CID) { |
---|
| 1458 | + if (cid < 0 || cid >= wil->max_assoc_sta) { |
---|
1348 | 1459 | wil_err(wil, "invalid cid %d\n", cid); |
---|
1349 | 1460 | return; |
---|
1350 | 1461 | } |
---|
.. | .. |
---|
1397 | 1508 | if (vif->fw_stats_ready) { |
---|
1398 | 1509 | /* clean old statistics */ |
---|
1399 | 1510 | vif->fw_stats_tsf = 0; |
---|
1400 | | - vif->fw_stats_ready = 0; |
---|
| 1511 | + vif->fw_stats_ready = false; |
---|
1401 | 1512 | } |
---|
1402 | 1513 | |
---|
1403 | 1514 | wil_link_stats_store_basic(vif, payload + hdr_size); |
---|
1404 | 1515 | |
---|
1405 | 1516 | if (!has_next) { |
---|
1406 | 1517 | vif->fw_stats_tsf = tsf; |
---|
1407 | | - vif->fw_stats_ready = 1; |
---|
| 1518 | + vif->fw_stats_ready = true; |
---|
1408 | 1519 | } |
---|
1409 | 1520 | |
---|
1410 | 1521 | break; |
---|
.. | .. |
---|
1419 | 1530 | if (wil->fw_stats_global.ready) { |
---|
1420 | 1531 | /* clean old statistics */ |
---|
1421 | 1532 | wil->fw_stats_global.tsf = 0; |
---|
1422 | | - wil->fw_stats_global.ready = 0; |
---|
| 1533 | + wil->fw_stats_global.ready = false; |
---|
1423 | 1534 | } |
---|
1424 | 1535 | |
---|
1425 | 1536 | wil_link_stats_store_global(vif, payload + hdr_size); |
---|
1426 | 1537 | |
---|
1427 | 1538 | if (!has_next) { |
---|
1428 | 1539 | wil->fw_stats_global.tsf = tsf; |
---|
1429 | | - wil->fw_stats_global.ready = 1; |
---|
| 1540 | + wil->fw_stats_global.ready = true; |
---|
1430 | 1541 | } |
---|
1431 | 1542 | |
---|
1432 | 1543 | break; |
---|
.. | .. |
---|
1461 | 1572 | evt->payload, payload_size); |
---|
1462 | 1573 | } |
---|
1463 | 1574 | |
---|
1464 | | -/** |
---|
1465 | | - * Some events are ignored for purpose; and need not be interpreted as |
---|
| 1575 | +/* find cid and ringid for the station vif |
---|
| 1576 | + * |
---|
| 1577 | + * return error, if other interfaces are used or ring was not found |
---|
| 1578 | + */ |
---|
| 1579 | +static int wil_find_cid_ringid_sta(struct wil6210_priv *wil, |
---|
| 1580 | + struct wil6210_vif *vif, |
---|
| 1581 | + int *cid, |
---|
| 1582 | + int *ringid) |
---|
| 1583 | +{ |
---|
| 1584 | + struct wil_ring *ring; |
---|
| 1585 | + struct wil_ring_tx_data *txdata; |
---|
| 1586 | + int min_ring_id = wil_get_min_tx_ring_id(wil); |
---|
| 1587 | + int i; |
---|
| 1588 | + u8 lcid; |
---|
| 1589 | + |
---|
| 1590 | + if (!(vif->wdev.iftype == NL80211_IFTYPE_STATION || |
---|
| 1591 | + vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { |
---|
| 1592 | + wil_err(wil, "invalid interface type %d\n", vif->wdev.iftype); |
---|
| 1593 | + return -EINVAL; |
---|
| 1594 | + } |
---|
| 1595 | + |
---|
| 1596 | + /* In the STA mode, it is expected to have only one ring |
---|
| 1597 | + * for the AP we are connected to. |
---|
| 1598 | + * find it and return the cid associated with it. |
---|
| 1599 | + */ |
---|
| 1600 | + for (i = min_ring_id; i < WIL6210_MAX_TX_RINGS; i++) { |
---|
| 1601 | + ring = &wil->ring_tx[i]; |
---|
| 1602 | + txdata = &wil->ring_tx_data[i]; |
---|
| 1603 | + if (!ring->va || !txdata->enabled || txdata->mid != vif->mid) |
---|
| 1604 | + continue; |
---|
| 1605 | + |
---|
| 1606 | + lcid = wil->ring2cid_tid[i][0]; |
---|
| 1607 | + if (lcid >= wil->max_assoc_sta) /* skip BCAST */ |
---|
| 1608 | + continue; |
---|
| 1609 | + |
---|
| 1610 | + wil_dbg_wmi(wil, "find sta -> ringid %d cid %d\n", i, lcid); |
---|
| 1611 | + *cid = lcid; |
---|
| 1612 | + *ringid = i; |
---|
| 1613 | + return 0; |
---|
| 1614 | + } |
---|
| 1615 | + |
---|
| 1616 | + wil_dbg_wmi(wil, "find sta cid while no rings active?\n"); |
---|
| 1617 | + |
---|
| 1618 | + return -ENOENT; |
---|
| 1619 | +} |
---|
| 1620 | + |
---|
| 1621 | +static void |
---|
| 1622 | +wmi_evt_auth_status(struct wil6210_vif *vif, int id, void *d, int len) |
---|
| 1623 | +{ |
---|
| 1624 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 1625 | + struct net_device *ndev = vif_to_ndev(vif); |
---|
| 1626 | + struct wmi_ft_auth_status_event *data = d; |
---|
| 1627 | + int ie_len = len - offsetof(struct wmi_ft_auth_status_event, ie_info); |
---|
| 1628 | + int rc, cid = 0, ringid = 0; |
---|
| 1629 | + struct cfg80211_ft_event_params ft; |
---|
| 1630 | + u16 d_len; |
---|
| 1631 | + /* auth_alg(u16) + auth_transaction(u16) + status_code(u16) */ |
---|
| 1632 | + const size_t auth_ie_offset = sizeof(u16) * 3; |
---|
| 1633 | + struct auth_no_hdr *auth = (struct auth_no_hdr *)data->ie_info; |
---|
| 1634 | + |
---|
| 1635 | + /* check the status */ |
---|
| 1636 | + if (ie_len >= 0 && data->status != WMI_FW_STATUS_SUCCESS) { |
---|
| 1637 | + wil_err(wil, "FT: auth failed. status %d\n", data->status); |
---|
| 1638 | + goto fail; |
---|
| 1639 | + } |
---|
| 1640 | + |
---|
| 1641 | + if (ie_len < auth_ie_offset) { |
---|
| 1642 | + wil_err(wil, "FT: auth event too short, len %d\n", len); |
---|
| 1643 | + goto fail; |
---|
| 1644 | + } |
---|
| 1645 | + |
---|
| 1646 | + d_len = le16_to_cpu(data->ie_len); |
---|
| 1647 | + if (d_len != ie_len) { |
---|
| 1648 | + wil_err(wil, |
---|
| 1649 | + "FT: auth ie length mismatch, d_len %d should be %d\n", |
---|
| 1650 | + d_len, ie_len); |
---|
| 1651 | + goto fail; |
---|
| 1652 | + } |
---|
| 1653 | + |
---|
| 1654 | + if (!test_bit(wil_vif_ft_roam, wil->status)) { |
---|
| 1655 | + wil_err(wil, "FT: Not in roaming state\n"); |
---|
| 1656 | + goto fail; |
---|
| 1657 | + } |
---|
| 1658 | + |
---|
| 1659 | + if (le16_to_cpu(auth->auth_transaction) != 2) { |
---|
| 1660 | + wil_err(wil, "FT: auth error. auth_transaction %d\n", |
---|
| 1661 | + le16_to_cpu(auth->auth_transaction)); |
---|
| 1662 | + goto fail; |
---|
| 1663 | + } |
---|
| 1664 | + |
---|
| 1665 | + if (le16_to_cpu(auth->auth_alg) != WLAN_AUTH_FT) { |
---|
| 1666 | + wil_err(wil, "FT: auth error. auth_alg %d\n", |
---|
| 1667 | + le16_to_cpu(auth->auth_alg)); |
---|
| 1668 | + goto fail; |
---|
| 1669 | + } |
---|
| 1670 | + |
---|
| 1671 | + wil_dbg_wmi(wil, "FT: Auth to %pM successfully\n", data->mac_addr); |
---|
| 1672 | + wil_hex_dump_wmi("FT Auth ies : ", DUMP_PREFIX_OFFSET, 16, 1, |
---|
| 1673 | + data->ie_info, d_len, true); |
---|
| 1674 | + |
---|
| 1675 | + /* find cid and ringid */ |
---|
| 1676 | + rc = wil_find_cid_ringid_sta(wil, vif, &cid, &ringid); |
---|
| 1677 | + if (rc) { |
---|
| 1678 | + wil_err(wil, "No valid cid found\n"); |
---|
| 1679 | + goto fail; |
---|
| 1680 | + } |
---|
| 1681 | + |
---|
| 1682 | + if (vif->privacy) { |
---|
| 1683 | + /* For secure assoc, remove old keys */ |
---|
| 1684 | + rc = wmi_del_cipher_key(vif, 0, wil->sta[cid].addr, |
---|
| 1685 | + WMI_KEY_USE_PAIRWISE); |
---|
| 1686 | + if (rc) { |
---|
| 1687 | + wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n"); |
---|
| 1688 | + goto fail; |
---|
| 1689 | + } |
---|
| 1690 | + rc = wmi_del_cipher_key(vif, 0, wil->sta[cid].addr, |
---|
| 1691 | + WMI_KEY_USE_RX_GROUP); |
---|
| 1692 | + if (rc) { |
---|
| 1693 | + wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n"); |
---|
| 1694 | + goto fail; |
---|
| 1695 | + } |
---|
| 1696 | + } |
---|
| 1697 | + |
---|
| 1698 | + memset(&ft, 0, sizeof(ft)); |
---|
| 1699 | + ft.ies = data->ie_info + auth_ie_offset; |
---|
| 1700 | + ft.ies_len = d_len - auth_ie_offset; |
---|
| 1701 | + ft.target_ap = data->mac_addr; |
---|
| 1702 | + cfg80211_ft_event(ndev, &ft); |
---|
| 1703 | + |
---|
| 1704 | + return; |
---|
| 1705 | + |
---|
| 1706 | +fail: |
---|
| 1707 | + wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID); |
---|
| 1708 | +} |
---|
| 1709 | + |
---|
| 1710 | +static void |
---|
| 1711 | +wmi_evt_reassoc_status(struct wil6210_vif *vif, int id, void *d, int len) |
---|
| 1712 | +{ |
---|
| 1713 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 1714 | + struct net_device *ndev = vif_to_ndev(vif); |
---|
| 1715 | + struct wiphy *wiphy = wil_to_wiphy(wil); |
---|
| 1716 | + struct wmi_ft_reassoc_status_event *data = d; |
---|
| 1717 | + int ies_len = len - offsetof(struct wmi_ft_reassoc_status_event, |
---|
| 1718 | + ie_info); |
---|
| 1719 | + int rc = -ENOENT, cid = 0, ringid = 0; |
---|
| 1720 | + int ch; /* channel number (primary) */ |
---|
| 1721 | + size_t assoc_req_ie_len = 0, assoc_resp_ie_len = 0; |
---|
| 1722 | + u8 *assoc_req_ie = NULL, *assoc_resp_ie = NULL; |
---|
| 1723 | + /* capinfo(u16) + listen_interval(u16) + current_ap mac addr + IEs */ |
---|
| 1724 | + const size_t assoc_req_ie_offset = sizeof(u16) * 2 + ETH_ALEN; |
---|
| 1725 | + /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ |
---|
| 1726 | + const size_t assoc_resp_ie_offset = sizeof(u16) * 3; |
---|
| 1727 | + u16 d_len; |
---|
| 1728 | + int freq; |
---|
| 1729 | + struct cfg80211_roam_info info; |
---|
| 1730 | + |
---|
| 1731 | + if (ies_len < 0) { |
---|
| 1732 | + wil_err(wil, "ft reassoc event too short, len %d\n", len); |
---|
| 1733 | + goto fail; |
---|
| 1734 | + } |
---|
| 1735 | + |
---|
| 1736 | + wil_dbg_wmi(wil, "Reasoc Status event: status=%d, aid=%d", |
---|
| 1737 | + data->status, data->aid); |
---|
| 1738 | + wil_dbg_wmi(wil, " mac_addr=%pM, beacon_ie_len=%d", |
---|
| 1739 | + data->mac_addr, data->beacon_ie_len); |
---|
| 1740 | + wil_dbg_wmi(wil, " reassoc_req_ie_len=%d, reassoc_resp_ie_len=%d", |
---|
| 1741 | + le16_to_cpu(data->reassoc_req_ie_len), |
---|
| 1742 | + le16_to_cpu(data->reassoc_resp_ie_len)); |
---|
| 1743 | + |
---|
| 1744 | + d_len = le16_to_cpu(data->beacon_ie_len) + |
---|
| 1745 | + le16_to_cpu(data->reassoc_req_ie_len) + |
---|
| 1746 | + le16_to_cpu(data->reassoc_resp_ie_len); |
---|
| 1747 | + if (d_len != ies_len) { |
---|
| 1748 | + wil_err(wil, |
---|
| 1749 | + "ft reassoc ie length mismatch, d_len %d should be %d\n", |
---|
| 1750 | + d_len, ies_len); |
---|
| 1751 | + goto fail; |
---|
| 1752 | + } |
---|
| 1753 | + |
---|
| 1754 | + /* check the status */ |
---|
| 1755 | + if (data->status != WMI_FW_STATUS_SUCCESS) { |
---|
| 1756 | + wil_err(wil, "ft reassoc failed. status %d\n", data->status); |
---|
| 1757 | + goto fail; |
---|
| 1758 | + } |
---|
| 1759 | + |
---|
| 1760 | + /* find cid and ringid */ |
---|
| 1761 | + rc = wil_find_cid_ringid_sta(wil, vif, &cid, &ringid); |
---|
| 1762 | + if (rc) { |
---|
| 1763 | + wil_err(wil, "No valid cid found\n"); |
---|
| 1764 | + goto fail; |
---|
| 1765 | + } |
---|
| 1766 | + |
---|
| 1767 | + ch = data->channel + 1; |
---|
| 1768 | + wil_info(wil, "FT: Roam %pM channel [%d] cid %d aid %d\n", |
---|
| 1769 | + data->mac_addr, ch, cid, data->aid); |
---|
| 1770 | + |
---|
| 1771 | + wil_hex_dump_wmi("reassoc AI : ", DUMP_PREFIX_OFFSET, 16, 1, |
---|
| 1772 | + data->ie_info, len - sizeof(*data), true); |
---|
| 1773 | + |
---|
| 1774 | + /* figure out IE's */ |
---|
| 1775 | + if (le16_to_cpu(data->reassoc_req_ie_len) > assoc_req_ie_offset) { |
---|
| 1776 | + assoc_req_ie = &data->ie_info[assoc_req_ie_offset]; |
---|
| 1777 | + assoc_req_ie_len = le16_to_cpu(data->reassoc_req_ie_len) - |
---|
| 1778 | + assoc_req_ie_offset; |
---|
| 1779 | + } |
---|
| 1780 | + if (le16_to_cpu(data->reassoc_resp_ie_len) <= assoc_resp_ie_offset) { |
---|
| 1781 | + wil_err(wil, "FT: reassoc resp ie len is too short, len %d\n", |
---|
| 1782 | + le16_to_cpu(data->reassoc_resp_ie_len)); |
---|
| 1783 | + goto fail; |
---|
| 1784 | + } |
---|
| 1785 | + |
---|
| 1786 | + assoc_resp_ie = &data->ie_info[le16_to_cpu(data->reassoc_req_ie_len) + |
---|
| 1787 | + assoc_resp_ie_offset]; |
---|
| 1788 | + assoc_resp_ie_len = le16_to_cpu(data->reassoc_resp_ie_len) - |
---|
| 1789 | + assoc_resp_ie_offset; |
---|
| 1790 | + |
---|
| 1791 | + if (test_bit(wil_status_resetting, wil->status) || |
---|
| 1792 | + !test_bit(wil_status_fwready, wil->status)) { |
---|
| 1793 | + wil_err(wil, "FT: status_resetting, cancel reassoc event\n"); |
---|
| 1794 | + /* no need for cleanup, wil_reset will do that */ |
---|
| 1795 | + return; |
---|
| 1796 | + } |
---|
| 1797 | + |
---|
| 1798 | + mutex_lock(&wil->mutex); |
---|
| 1799 | + |
---|
| 1800 | + /* ring modify to set the ring for the roamed AP settings */ |
---|
| 1801 | + wil_dbg_wmi(wil, |
---|
| 1802 | + "ft modify tx config for connection CID %d ring %d\n", |
---|
| 1803 | + cid, ringid); |
---|
| 1804 | + |
---|
| 1805 | + rc = wil->txrx_ops.tx_ring_modify(vif, ringid, cid, 0); |
---|
| 1806 | + if (rc) { |
---|
| 1807 | + wil_err(wil, "modify TX for CID %d MID %d ring %d failed (%d)\n", |
---|
| 1808 | + cid, vif->mid, ringid, rc); |
---|
| 1809 | + mutex_unlock(&wil->mutex); |
---|
| 1810 | + goto fail; |
---|
| 1811 | + } |
---|
| 1812 | + |
---|
| 1813 | + /* Update the driver STA members with the new bss */ |
---|
| 1814 | + wil->sta[cid].aid = data->aid; |
---|
| 1815 | + wil->sta[cid].stats.ft_roams++; |
---|
| 1816 | + ether_addr_copy(wil->sta[cid].addr, vif->bss->bssid); |
---|
| 1817 | + mutex_unlock(&wil->mutex); |
---|
| 1818 | + del_timer_sync(&vif->connect_timer); |
---|
| 1819 | + |
---|
| 1820 | + cfg80211_ref_bss(wiphy, vif->bss); |
---|
| 1821 | + freq = ieee80211_channel_to_frequency(ch, NL80211_BAND_60GHZ); |
---|
| 1822 | + |
---|
| 1823 | + memset(&info, 0, sizeof(info)); |
---|
| 1824 | + info.channel = ieee80211_get_channel(wiphy, freq); |
---|
| 1825 | + info.bss = vif->bss; |
---|
| 1826 | + info.req_ie = assoc_req_ie; |
---|
| 1827 | + info.req_ie_len = assoc_req_ie_len; |
---|
| 1828 | + info.resp_ie = assoc_resp_ie; |
---|
| 1829 | + info.resp_ie_len = assoc_resp_ie_len; |
---|
| 1830 | + cfg80211_roamed(ndev, &info, GFP_KERNEL); |
---|
| 1831 | + vif->bss = NULL; |
---|
| 1832 | + |
---|
| 1833 | + return; |
---|
| 1834 | + |
---|
| 1835 | +fail: |
---|
| 1836 | + wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID); |
---|
| 1837 | +} |
---|
| 1838 | + |
---|
| 1839 | +static void |
---|
| 1840 | +wmi_evt_link_monitor(struct wil6210_vif *vif, int id, void *d, int len) |
---|
| 1841 | +{ |
---|
| 1842 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 1843 | + struct net_device *ndev = vif_to_ndev(vif); |
---|
| 1844 | + struct wmi_link_monitor_event *evt = d; |
---|
| 1845 | + enum nl80211_cqm_rssi_threshold_event event_type; |
---|
| 1846 | + |
---|
| 1847 | + if (len < sizeof(*evt)) { |
---|
| 1848 | + wil_err(wil, "link monitor event too short %d\n", len); |
---|
| 1849 | + return; |
---|
| 1850 | + } |
---|
| 1851 | + |
---|
| 1852 | + wil_dbg_wmi(wil, "link monitor event, type %d rssi %d (stored %d)\n", |
---|
| 1853 | + evt->type, evt->rssi_level, wil->cqm_rssi_thold); |
---|
| 1854 | + |
---|
| 1855 | + if (evt->type != WMI_LINK_MONITOR_NOTIF_RSSI_THRESHOLD_EVT) |
---|
| 1856 | + /* ignore */ |
---|
| 1857 | + return; |
---|
| 1858 | + |
---|
| 1859 | + event_type = (evt->rssi_level > wil->cqm_rssi_thold ? |
---|
| 1860 | + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH : |
---|
| 1861 | + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW); |
---|
| 1862 | + cfg80211_cqm_rssi_notify(ndev, event_type, evt->rssi_level, GFP_KERNEL); |
---|
| 1863 | +} |
---|
| 1864 | + |
---|
| 1865 | +/* Some events are ignored for purpose; and need not be interpreted as |
---|
1466 | 1866 | * "unhandled events" |
---|
1467 | 1867 | */ |
---|
1468 | 1868 | static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len) |
---|
.. | .. |
---|
1492 | 1892 | {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_ignore}, |
---|
1493 | 1893 | {WMI_SCHED_SCAN_RESULT_EVENTID, wmi_evt_sched_scan_result}, |
---|
1494 | 1894 | {WMI_LINK_STATS_EVENTID, wmi_evt_link_stats}, |
---|
| 1895 | + {WMI_FT_AUTH_STATUS_EVENTID, wmi_evt_auth_status}, |
---|
| 1896 | + {WMI_FT_REASSOC_STATUS_EVENTID, wmi_evt_reassoc_status}, |
---|
| 1897 | + {WMI_LINK_MONITOR_EVENTID, wmi_evt_link_monitor}, |
---|
1495 | 1898 | }; |
---|
1496 | 1899 | |
---|
1497 | 1900 | /* |
---|
.. | .. |
---|
1689 | 2092 | }; |
---|
1690 | 2093 | |
---|
1691 | 2094 | return wmi_call(wil, WMI_ECHO_CMDID, vif->mid, &cmd, sizeof(cmd), |
---|
1692 | | - WMI_ECHO_RSP_EVENTID, NULL, 0, 50); |
---|
| 2095 | + WMI_ECHO_RSP_EVENTID, NULL, 0, |
---|
| 2096 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
1693 | 2097 | } |
---|
1694 | 2098 | |
---|
1695 | 2099 | int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) |
---|
.. | .. |
---|
1748 | 2152 | |
---|
1749 | 2153 | rc = wmi_call(wil, WMI_LED_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
---|
1750 | 2154 | WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), |
---|
1751 | | - 100); |
---|
| 2155 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
1752 | 2156 | if (rc) |
---|
1753 | 2157 | goto out; |
---|
1754 | 2158 | |
---|
.. | .. |
---|
1762 | 2166 | return rc; |
---|
1763 | 2167 | } |
---|
1764 | 2168 | |
---|
1765 | | -int wmi_pcp_start(struct wil6210_vif *vif, |
---|
1766 | | - int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go) |
---|
| 2169 | +int wmi_rbufcap_cfg(struct wil6210_priv *wil, bool enable, u16 threshold) |
---|
| 2170 | +{ |
---|
| 2171 | + struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); |
---|
| 2172 | + int rc; |
---|
| 2173 | + |
---|
| 2174 | + struct wmi_rbufcap_cfg_cmd cmd = { |
---|
| 2175 | + .enable = enable, |
---|
| 2176 | + .rx_desc_threshold = cpu_to_le16(threshold), |
---|
| 2177 | + }; |
---|
| 2178 | + struct { |
---|
| 2179 | + struct wmi_cmd_hdr wmi; |
---|
| 2180 | + struct wmi_rbufcap_cfg_event evt; |
---|
| 2181 | + } __packed reply = { |
---|
| 2182 | + .evt = {.status = WMI_FW_STATUS_FAILURE}, |
---|
| 2183 | + }; |
---|
| 2184 | + |
---|
| 2185 | + rc = wmi_call(wil, WMI_RBUFCAP_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
---|
| 2186 | + WMI_RBUFCAP_CFG_EVENTID, &reply, sizeof(reply), |
---|
| 2187 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
| 2188 | + if (rc) |
---|
| 2189 | + return rc; |
---|
| 2190 | + |
---|
| 2191 | + if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { |
---|
| 2192 | + wil_err(wil, "RBUFCAP_CFG failed. status %d\n", |
---|
| 2193 | + reply.evt.status); |
---|
| 2194 | + rc = -EINVAL; |
---|
| 2195 | + } |
---|
| 2196 | + |
---|
| 2197 | + return rc; |
---|
| 2198 | +} |
---|
| 2199 | + |
---|
| 2200 | +int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, |
---|
| 2201 | + u8 chan, u8 wmi_edmg_chan, u8 hidden_ssid, u8 is_go) |
---|
1767 | 2202 | { |
---|
1768 | 2203 | struct wil6210_priv *wil = vif_to_wil(vif); |
---|
1769 | 2204 | int rc; |
---|
.. | .. |
---|
1773 | 2208 | .network_type = wmi_nettype, |
---|
1774 | 2209 | .disable_sec_offload = 1, |
---|
1775 | 2210 | .channel = chan - 1, |
---|
1776 | | - .pcp_max_assoc_sta = max_assoc_sta, |
---|
| 2211 | + .edmg_channel = wmi_edmg_chan, |
---|
| 2212 | + .pcp_max_assoc_sta = wil->max_assoc_sta, |
---|
1777 | 2213 | .hidden_ssid = hidden_ssid, |
---|
1778 | 2214 | .is_go = is_go, |
---|
1779 | 2215 | .ap_sme_offload_mode = disable_ap_sme ? |
---|
.. | .. |
---|
1793 | 2229 | |
---|
1794 | 2230 | if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || |
---|
1795 | 2231 | (cmd.pcp_max_assoc_sta <= 0)) { |
---|
1796 | | - wil_info(wil, |
---|
1797 | | - "Requested connection limit %u, valid values are 1 - %d. Setting to %d\n", |
---|
1798 | | - max_assoc_sta, WIL6210_MAX_CID, WIL6210_MAX_CID); |
---|
1799 | | - cmd.pcp_max_assoc_sta = WIL6210_MAX_CID; |
---|
| 2232 | + wil_err(wil, "unexpected max_assoc_sta %d\n", |
---|
| 2233 | + cmd.pcp_max_assoc_sta); |
---|
| 2234 | + return -EOPNOTSUPP; |
---|
1800 | 2235 | } |
---|
1801 | 2236 | |
---|
1802 | 2237 | if (disable_ap_sme && |
---|
.. | .. |
---|
1835 | 2270 | return rc; |
---|
1836 | 2271 | |
---|
1837 | 2272 | return wmi_call(wil, WMI_PCP_STOP_CMDID, vif->mid, NULL, 0, |
---|
1838 | | - WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); |
---|
| 2273 | + WMI_PCP_STOPPED_EVENTID, NULL, 0, |
---|
| 2274 | + WIL_WMI_PCP_STOP_TO_MS); |
---|
1839 | 2275 | } |
---|
1840 | 2276 | |
---|
1841 | 2277 | int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid) |
---|
.. | .. |
---|
1866 | 2302 | memset(&reply, 0, sizeof(reply)); |
---|
1867 | 2303 | |
---|
1868 | 2304 | rc = wmi_call(wil, WMI_GET_SSID_CMDID, vif->mid, NULL, 0, |
---|
1869 | | - WMI_GET_SSID_EVENTID, &reply, sizeof(reply), 20); |
---|
| 2305 | + WMI_GET_SSID_EVENTID, &reply, sizeof(reply), |
---|
| 2306 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
1870 | 2307 | if (rc) |
---|
1871 | 2308 | return rc; |
---|
1872 | 2309 | |
---|
.. | .. |
---|
1903 | 2340 | memset(&reply, 0, sizeof(reply)); |
---|
1904 | 2341 | |
---|
1905 | 2342 | rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, vif->mid, NULL, 0, |
---|
1906 | | - WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20); |
---|
| 2343 | + WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), |
---|
| 2344 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
1907 | 2345 | if (rc) |
---|
1908 | 2346 | return rc; |
---|
1909 | 2347 | |
---|
.. | .. |
---|
1999 | 2437 | wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n"); |
---|
2000 | 2438 | |
---|
2001 | 2439 | rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0, |
---|
2002 | | - WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 100); |
---|
| 2440 | + WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, |
---|
| 2441 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2003 | 2442 | |
---|
2004 | 2443 | if (rc) |
---|
2005 | 2444 | wil_err(wil, "Failed to stop discovery\n"); |
---|
.. | .. |
---|
2033 | 2472 | .key_len = key_len, |
---|
2034 | 2473 | }; |
---|
2035 | 2474 | |
---|
2036 | | - if (!key || (key_len > sizeof(cmd.key))) |
---|
| 2475 | + if (key_len > sizeof(cmd.key)) |
---|
2037 | 2476 | return -EINVAL; |
---|
2038 | 2477 | |
---|
2039 | | - memcpy(cmd.key, key, key_len); |
---|
| 2478 | + /* key len = 0 is allowed only for usage of WMI_KEY_USE_APPLY */ |
---|
| 2479 | + if ((key_len == 0 || !key) && |
---|
| 2480 | + key_usage != WMI_KEY_USE_APPLY_PTK) |
---|
| 2481 | + return -EINVAL; |
---|
| 2482 | + |
---|
| 2483 | + if (key) |
---|
| 2484 | + memcpy(cmd.key, key, key_len); |
---|
| 2485 | + |
---|
2040 | 2486 | if (mac_addr) |
---|
2041 | 2487 | memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); |
---|
2042 | 2488 | |
---|
.. | .. |
---|
2074 | 2520 | cmd->mgmt_frm_type = type; |
---|
2075 | 2521 | /* BUG: FW API define ieLen as u8. Will fix FW */ |
---|
2076 | 2522 | cmd->ie_len = cpu_to_le16(ie_len); |
---|
2077 | | - memcpy(cmd->ie_info, ie, ie_len); |
---|
| 2523 | + if (ie_len) |
---|
| 2524 | + memcpy(cmd->ie_info, ie, ie_len); |
---|
2078 | 2525 | rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len); |
---|
2079 | 2526 | kfree(cmd); |
---|
2080 | 2527 | out: |
---|
.. | .. |
---|
2087 | 2534 | return rc; |
---|
2088 | 2535 | } |
---|
2089 | 2536 | |
---|
| 2537 | +int wmi_update_ft_ies(struct wil6210_vif *vif, u16 ie_len, const void *ie) |
---|
| 2538 | +{ |
---|
| 2539 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 2540 | + u16 len; |
---|
| 2541 | + struct wmi_update_ft_ies_cmd *cmd; |
---|
| 2542 | + int rc; |
---|
| 2543 | + |
---|
| 2544 | + if (!ie) |
---|
| 2545 | + ie_len = 0; |
---|
| 2546 | + |
---|
| 2547 | + len = sizeof(struct wmi_update_ft_ies_cmd) + ie_len; |
---|
| 2548 | + if (len < ie_len) { |
---|
| 2549 | + wil_err(wil, "wraparound. ie len %d\n", ie_len); |
---|
| 2550 | + return -EINVAL; |
---|
| 2551 | + } |
---|
| 2552 | + |
---|
| 2553 | + cmd = kzalloc(len, GFP_KERNEL); |
---|
| 2554 | + if (!cmd) { |
---|
| 2555 | + rc = -ENOMEM; |
---|
| 2556 | + goto out; |
---|
| 2557 | + } |
---|
| 2558 | + |
---|
| 2559 | + cmd->ie_len = cpu_to_le16(ie_len); |
---|
| 2560 | + if (ie_len) |
---|
| 2561 | + memcpy(cmd->ie_info, ie, ie_len); |
---|
| 2562 | + rc = wmi_send(wil, WMI_UPDATE_FT_IES_CMDID, vif->mid, cmd, len); |
---|
| 2563 | + kfree(cmd); |
---|
| 2564 | + |
---|
| 2565 | +out: |
---|
| 2566 | + if (rc) |
---|
| 2567 | + wil_err(wil, "update ft ies failed : %d\n", rc); |
---|
| 2568 | + |
---|
| 2569 | + return rc; |
---|
| 2570 | +} |
---|
| 2571 | + |
---|
2090 | 2572 | /** |
---|
2091 | 2573 | * wmi_rxon - turn radio on/off |
---|
| 2574 | + * @wil: driver data |
---|
2092 | 2575 | * @on: turn on if true, off otherwise |
---|
2093 | 2576 | * |
---|
2094 | 2577 | * Only switch radio. Channel should be set separately. |
---|
.. | .. |
---|
2111 | 2594 | if (on) { |
---|
2112 | 2595 | rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0, |
---|
2113 | 2596 | WMI_LISTEN_STARTED_EVENTID, |
---|
2114 | | - &reply, sizeof(reply), 100); |
---|
| 2597 | + &reply, sizeof(reply), |
---|
| 2598 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2115 | 2599 | if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS)) |
---|
2116 | 2600 | rc = -EINVAL; |
---|
2117 | 2601 | } else { |
---|
2118 | 2602 | rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0, |
---|
2119 | | - WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20); |
---|
| 2603 | + WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, |
---|
| 2604 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2120 | 2605 | } |
---|
2121 | 2606 | |
---|
2122 | 2607 | return rc; |
---|
.. | .. |
---|
2155 | 2640 | if (ch) |
---|
2156 | 2641 | cmd.sniffer_cfg.channel = ch->hw_value - 1; |
---|
2157 | 2642 | cmd.sniffer_cfg.phy_info_mode = |
---|
2158 | | - cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP); |
---|
| 2643 | + cpu_to_le32(WMI_SNIFFER_PHY_INFO_DISABLED); |
---|
2159 | 2644 | cmd.sniffer_cfg.phy_support = |
---|
2160 | 2645 | cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL) |
---|
2161 | 2646 | ? WMI_SNIFFER_CP : WMI_SNIFFER_BOTH_PHYS); |
---|
.. | .. |
---|
2205 | 2690 | memset(&reply, 0, sizeof(reply)); |
---|
2206 | 2691 | |
---|
2207 | 2692 | rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, vif->mid, &cmd, sizeof(cmd), |
---|
2208 | | - WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100); |
---|
| 2693 | + WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), |
---|
| 2694 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2209 | 2695 | if (rc) |
---|
2210 | 2696 | return rc; |
---|
2211 | 2697 | |
---|
.. | .. |
---|
2217 | 2703 | return 0; |
---|
2218 | 2704 | } |
---|
2219 | 2705 | |
---|
2220 | | -int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, |
---|
2221 | | - u16 reason, bool full_disconnect, bool del_sta) |
---|
| 2706 | +int wmi_get_all_temperatures(struct wil6210_priv *wil, |
---|
| 2707 | + struct wmi_temp_sense_all_done_event |
---|
| 2708 | + *sense_all_evt) |
---|
| 2709 | +{ |
---|
| 2710 | + struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); |
---|
| 2711 | + int rc; |
---|
| 2712 | + struct wmi_temp_sense_all_cmd cmd = { |
---|
| 2713 | + .measure_baseband_en = true, |
---|
| 2714 | + .measure_rf_en = true, |
---|
| 2715 | + .measure_mode = TEMPERATURE_MEASURE_NOW, |
---|
| 2716 | + }; |
---|
| 2717 | + struct { |
---|
| 2718 | + struct wmi_cmd_hdr wmi; |
---|
| 2719 | + struct wmi_temp_sense_all_done_event evt; |
---|
| 2720 | + } __packed reply; |
---|
| 2721 | + |
---|
| 2722 | + if (!sense_all_evt) { |
---|
| 2723 | + wil_err(wil, "Invalid sense_all_evt value\n"); |
---|
| 2724 | + return -EINVAL; |
---|
| 2725 | + } |
---|
| 2726 | + |
---|
| 2727 | + memset(&reply, 0, sizeof(reply)); |
---|
| 2728 | + reply.evt.status = WMI_FW_STATUS_FAILURE; |
---|
| 2729 | + rc = wmi_call(wil, WMI_TEMP_SENSE_ALL_CMDID, vif->mid, &cmd, |
---|
| 2730 | + sizeof(cmd), WMI_TEMP_SENSE_ALL_DONE_EVENTID, |
---|
| 2731 | + &reply, sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); |
---|
| 2732 | + if (rc) |
---|
| 2733 | + return rc; |
---|
| 2734 | + |
---|
| 2735 | + if (reply.evt.status == WMI_FW_STATUS_FAILURE) { |
---|
| 2736 | + wil_err(wil, "Failed getting TEMP_SENSE_ALL\n"); |
---|
| 2737 | + return -EINVAL; |
---|
| 2738 | + } |
---|
| 2739 | + |
---|
| 2740 | + memcpy(sense_all_evt, &reply.evt, sizeof(reply.evt)); |
---|
| 2741 | + return 0; |
---|
| 2742 | +} |
---|
| 2743 | + |
---|
| 2744 | +int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, u16 reason, |
---|
| 2745 | + bool del_sta) |
---|
2222 | 2746 | { |
---|
2223 | 2747 | struct wil6210_priv *wil = vif_to_wil(vif); |
---|
2224 | 2748 | int rc; |
---|
2225 | | - u16 reason_code; |
---|
2226 | 2749 | struct wmi_disconnect_sta_cmd disc_sta_cmd = { |
---|
2227 | 2750 | .disconnect_reason = cpu_to_le16(reason), |
---|
2228 | 2751 | }; |
---|
.. | .. |
---|
2255 | 2778 | wil_fw_error_recovery(wil); |
---|
2256 | 2779 | return rc; |
---|
2257 | 2780 | } |
---|
| 2781 | + wil->sinfo_gen++; |
---|
2258 | 2782 | |
---|
2259 | | - if (full_disconnect) { |
---|
2260 | | - /* call event handler manually after processing wmi_call, |
---|
2261 | | - * to avoid deadlock - disconnect event handler acquires |
---|
2262 | | - * wil->mutex while it is already held here |
---|
2263 | | - */ |
---|
2264 | | - reason_code = le16_to_cpu(reply.evt.protocol_reason_status); |
---|
2265 | | - |
---|
2266 | | - wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n", |
---|
2267 | | - reply.evt.bssid, reason_code, |
---|
2268 | | - reply.evt.disconnect_reason); |
---|
2269 | | - |
---|
2270 | | - wil->sinfo_gen++; |
---|
2271 | | - wil6210_disconnect(vif, reply.evt.bssid, reason_code, true); |
---|
2272 | | - } |
---|
2273 | 2783 | return 0; |
---|
2274 | 2784 | } |
---|
2275 | 2785 | |
---|
.. | .. |
---|
2304 | 2814 | return wmi_send(wil, WMI_RING_BA_DIS_CMDID, mid, &cmd, sizeof(cmd)); |
---|
2305 | 2815 | } |
---|
2306 | 2816 | |
---|
2307 | | -int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason) |
---|
| 2817 | +int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid, u16 reason) |
---|
2308 | 2818 | { |
---|
2309 | 2819 | struct wmi_rcp_delba_cmd cmd = { |
---|
2310 | | - .cidxtid = cidxtid, |
---|
2311 | 2820 | .reason = cpu_to_le16(reason), |
---|
2312 | 2821 | }; |
---|
2313 | 2822 | |
---|
2314 | | - wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf, |
---|
2315 | | - (cidxtid >> 4) & 0xf, reason); |
---|
| 2823 | + if (cid >= WIL6210_RX_DESC_MAX_CID) { |
---|
| 2824 | + cmd.cidxtid = CIDXTID_EXTENDED_CID_TID; |
---|
| 2825 | + cmd.cid = cid; |
---|
| 2826 | + cmd.tid = tid; |
---|
| 2827 | + } else { |
---|
| 2828 | + cmd.cidxtid = mk_cidxtid(cid, tid); |
---|
| 2829 | + } |
---|
| 2830 | + |
---|
| 2831 | + wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cid, |
---|
| 2832 | + tid, reason); |
---|
2316 | 2833 | |
---|
2317 | 2834 | return wmi_send(wil, WMI_RCP_DELBA_CMDID, mid, &cmd, sizeof(cmd)); |
---|
2318 | 2835 | } |
---|
.. | .. |
---|
2323 | 2840 | { |
---|
2324 | 2841 | int rc; |
---|
2325 | 2842 | struct wmi_rcp_addba_resp_cmd cmd = { |
---|
2326 | | - .cidxtid = mk_cidxtid(cid, tid), |
---|
2327 | 2843 | .dialog_token = token, |
---|
2328 | 2844 | .status_code = cpu_to_le16(status), |
---|
2329 | 2845 | /* bit 0: A-MSDU supported |
---|
2330 | | - * bit 1: policy (should be 0 for us) |
---|
| 2846 | + * bit 1: policy (controlled by FW) |
---|
2331 | 2847 | * bits 2..5: TID |
---|
2332 | 2848 | * bits 6..15: buffer size |
---|
2333 | 2849 | */ |
---|
.. | .. |
---|
2342 | 2858 | .evt = {.status = cpu_to_le16(WMI_FW_STATUS_FAILURE)}, |
---|
2343 | 2859 | }; |
---|
2344 | 2860 | |
---|
| 2861 | + if (cid >= WIL6210_RX_DESC_MAX_CID) { |
---|
| 2862 | + cmd.cidxtid = CIDXTID_EXTENDED_CID_TID; |
---|
| 2863 | + cmd.cid = cid; |
---|
| 2864 | + cmd.tid = tid; |
---|
| 2865 | + } else { |
---|
| 2866 | + cmd.cidxtid = mk_cidxtid(cid, tid); |
---|
| 2867 | + } |
---|
| 2868 | + |
---|
2345 | 2869 | wil_dbg_wmi(wil, |
---|
2346 | 2870 | "ADDBA response for MID %d CID %d TID %d size %d timeout %d status %d AMSDU%s\n", |
---|
2347 | 2871 | mid, cid, tid, agg_wsize, |
---|
.. | .. |
---|
2349 | 2873 | |
---|
2350 | 2874 | rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, mid, &cmd, sizeof(cmd), |
---|
2351 | 2875 | WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), |
---|
2352 | | - 100); |
---|
| 2876 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2353 | 2877 | if (rc) |
---|
2354 | 2878 | return rc; |
---|
2355 | 2879 | |
---|
.. | .. |
---|
2373 | 2897 | .dialog_token = token, |
---|
2374 | 2898 | .status_code = cpu_to_le16(status), |
---|
2375 | 2899 | /* bit 0: A-MSDU supported |
---|
2376 | | - * bit 1: policy (should be 0 for us) |
---|
| 2900 | + * bit 1: policy (controlled by FW) |
---|
2377 | 2901 | * bits 2..5: TID |
---|
2378 | 2902 | * bits 6..15: buffer size |
---|
2379 | 2903 | */ |
---|
.. | .. |
---|
2431 | 2955 | rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, vif->mid, |
---|
2432 | 2956 | &cmd, sizeof(cmd), |
---|
2433 | 2957 | WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), |
---|
2434 | | - 100); |
---|
| 2958 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2435 | 2959 | if (rc) |
---|
2436 | 2960 | return rc; |
---|
2437 | 2961 | |
---|
.. | .. |
---|
2468 | 2992 | rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, vif->mid, |
---|
2469 | 2993 | &cmd, sizeof(cmd), |
---|
2470 | 2994 | WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), |
---|
2471 | | - 100); |
---|
| 2995 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2472 | 2996 | if (rc) |
---|
2473 | 2997 | return rc; |
---|
2474 | 2998 | |
---|
.. | .. |
---|
2498 | 3022 | memset(&reply, 0, sizeof(reply)); |
---|
2499 | 3023 | rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, vif->mid, NULL, 0, |
---|
2500 | 3024 | WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), |
---|
2501 | | - 100); |
---|
| 3025 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
2502 | 3026 | if (rc) |
---|
2503 | 3027 | return rc; |
---|
2504 | 3028 | |
---|
.. | .. |
---|
2563 | 3087 | switch (status) { |
---|
2564 | 3088 | case WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE: |
---|
2565 | 3089 | return "LINK_NOT_IDLE"; |
---|
| 3090 | + case WMI_TRAFFIC_SUSPEND_REJECTED_DISCONNECT: |
---|
| 3091 | + return "DISCONNECT"; |
---|
| 3092 | + case WMI_TRAFFIC_SUSPEND_REJECTED_OTHER: |
---|
| 3093 | + return "OTHER"; |
---|
2566 | 3094 | default: |
---|
2567 | 3095 | return "Untracked status"; |
---|
2568 | 3096 | } |
---|
.. | .. |
---|
2652 | 3180 | |
---|
2653 | 3181 | if (triggers & WMI_RESUME_TRIGGER_WMI_EVT) |
---|
2654 | 3182 | strlcat(string, " WMI_EVT", str_size); |
---|
| 3183 | + |
---|
| 3184 | + if (triggers & WMI_RESUME_TRIGGER_DISCONNECT) |
---|
| 3185 | + strlcat(string, " DISCONNECT", str_size); |
---|
2655 | 3186 | } |
---|
2656 | 3187 | |
---|
2657 | 3188 | int wmi_resume(struct wil6210_priv *wil) |
---|
.. | .. |
---|
2802 | 3333 | |
---|
2803 | 3334 | if (mid == MID_BROADCAST) |
---|
2804 | 3335 | mid = 0; |
---|
2805 | | - if (mid >= ARRAY_SIZE(wil->vifs) || mid >= wil->max_vifs) { |
---|
| 3336 | + if (mid >= GET_MAX_VIFS(wil)) { |
---|
2806 | 3337 | wil_dbg_wmi(wil, "invalid mid %d, event skipped\n", |
---|
2807 | 3338 | mid); |
---|
2808 | 3339 | return; |
---|
.. | .. |
---|
3408 | 3939 | .ring_size = cpu_to_le16(ring->size), |
---|
3409 | 3940 | .ring_id = ring_id, |
---|
3410 | 3941 | }, |
---|
| 3942 | + .max_msdu_size = cpu_to_le16(wil_mtu2macbuf(mtu_max)), |
---|
3411 | 3943 | .status_ring_id = wil->tx_sring_idx, |
---|
3412 | 3944 | .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, |
---|
3413 | 3945 | }; |
---|
.. | .. |
---|
3476 | 4008 | |
---|
3477 | 4009 | return 0; |
---|
3478 | 4010 | } |
---|
| 4011 | + |
---|
| 4012 | +int wmi_set_cqm_rssi_config(struct wil6210_priv *wil, |
---|
| 4013 | + s32 rssi_thold, u32 rssi_hyst) |
---|
| 4014 | +{ |
---|
| 4015 | + struct net_device *ndev = wil->main_ndev; |
---|
| 4016 | + struct wil6210_vif *vif = ndev_to_vif(ndev); |
---|
| 4017 | + int rc; |
---|
| 4018 | + struct { |
---|
| 4019 | + struct wmi_set_link_monitor_cmd cmd; |
---|
| 4020 | + s8 rssi_thold; |
---|
| 4021 | + } __packed cmd = { |
---|
| 4022 | + .cmd = { |
---|
| 4023 | + .rssi_hyst = rssi_hyst, |
---|
| 4024 | + .rssi_thresholds_list_size = 1, |
---|
| 4025 | + }, |
---|
| 4026 | + .rssi_thold = rssi_thold, |
---|
| 4027 | + }; |
---|
| 4028 | + struct { |
---|
| 4029 | + struct wmi_cmd_hdr hdr; |
---|
| 4030 | + struct wmi_set_link_monitor_event evt; |
---|
| 4031 | + } __packed reply = { |
---|
| 4032 | + .evt = {.status = WMI_FW_STATUS_FAILURE}, |
---|
| 4033 | + }; |
---|
| 4034 | + |
---|
| 4035 | + if (rssi_thold > S8_MAX || rssi_thold < S8_MIN || rssi_hyst > U8_MAX) |
---|
| 4036 | + return -EINVAL; |
---|
| 4037 | + |
---|
| 4038 | + rc = wmi_call(wil, WMI_SET_LINK_MONITOR_CMDID, vif->mid, &cmd, |
---|
| 4039 | + sizeof(cmd), WMI_SET_LINK_MONITOR_EVENTID, |
---|
| 4040 | + &reply, sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); |
---|
| 4041 | + if (rc) { |
---|
| 4042 | + wil_err(wil, "WMI_SET_LINK_MONITOR_CMDID failed, rc %d\n", rc); |
---|
| 4043 | + return rc; |
---|
| 4044 | + } |
---|
| 4045 | + |
---|
| 4046 | + if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { |
---|
| 4047 | + wil_err(wil, "WMI_SET_LINK_MONITOR_CMDID failed, status %d\n", |
---|
| 4048 | + reply.evt.status); |
---|
| 4049 | + return -EINVAL; |
---|
| 4050 | + } |
---|
| 4051 | + |
---|
| 4052 | + return 0; |
---|
| 4053 | +} |
---|