15e3dd157SKalle Valo /* 25e3dd157SKalle Valo * Copyright (c) 2005-2011 Atheros Communications Inc. 35e3dd157SKalle Valo * Copyright (c) 2011-2013 Qualcomm Atheros, Inc. 45e3dd157SKalle Valo * 55e3dd157SKalle Valo * Permission to use, copy, modify, and/or distribute this software for any 65e3dd157SKalle Valo * purpose with or without fee is hereby granted, provided that the above 75e3dd157SKalle Valo * copyright notice and this permission notice appear in all copies. 85e3dd157SKalle Valo * 95e3dd157SKalle Valo * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 105e3dd157SKalle Valo * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 115e3dd157SKalle Valo * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 125e3dd157SKalle Valo * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 135e3dd157SKalle Valo * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 145e3dd157SKalle Valo * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 155e3dd157SKalle Valo * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 165e3dd157SKalle Valo */ 175e3dd157SKalle Valo 185e3dd157SKalle Valo #include <linux/skbuff.h> 192fe5288cSKalle Valo #include <linux/ctype.h> 205e3dd157SKalle Valo 215e3dd157SKalle Valo #include "core.h" 225e3dd157SKalle Valo #include "htc.h" 235e3dd157SKalle Valo #include "debug.h" 245e3dd157SKalle Valo #include "wmi.h" 25ca996ec5SMichal Kazior #include "wmi-tlv.h" 265e3dd157SKalle Valo #include "mac.h" 2743d2a30fSKalle Valo #include "testmode.h" 28d7579d12SMichal Kazior #include "wmi-ops.h" 295e3dd157SKalle Valo 30ce42870eSBartosz Markowski /* MAIN WMI cmd track */ 31ce42870eSBartosz Markowski static struct wmi_cmd_map wmi_cmd_map = { 32ce42870eSBartosz Markowski .init_cmdid = WMI_INIT_CMDID, 33ce42870eSBartosz Markowski .start_scan_cmdid = WMI_START_SCAN_CMDID, 34ce42870eSBartosz Markowski .stop_scan_cmdid = WMI_STOP_SCAN_CMDID, 35ce42870eSBartosz Markowski .scan_chan_list_cmdid = WMI_SCAN_CHAN_LIST_CMDID, 36ce42870eSBartosz Markowski .scan_sch_prio_tbl_cmdid = WMI_SCAN_SCH_PRIO_TBL_CMDID, 37ce42870eSBartosz Markowski .pdev_set_regdomain_cmdid = WMI_PDEV_SET_REGDOMAIN_CMDID, 38ce42870eSBartosz Markowski .pdev_set_channel_cmdid = WMI_PDEV_SET_CHANNEL_CMDID, 39ce42870eSBartosz Markowski .pdev_set_param_cmdid = WMI_PDEV_SET_PARAM_CMDID, 40ce42870eSBartosz Markowski .pdev_pktlog_enable_cmdid = WMI_PDEV_PKTLOG_ENABLE_CMDID, 41ce42870eSBartosz Markowski .pdev_pktlog_disable_cmdid = WMI_PDEV_PKTLOG_DISABLE_CMDID, 42ce42870eSBartosz Markowski .pdev_set_wmm_params_cmdid = WMI_PDEV_SET_WMM_PARAMS_CMDID, 43ce42870eSBartosz Markowski .pdev_set_ht_cap_ie_cmdid = WMI_PDEV_SET_HT_CAP_IE_CMDID, 44ce42870eSBartosz Markowski .pdev_set_vht_cap_ie_cmdid = WMI_PDEV_SET_VHT_CAP_IE_CMDID, 45ce42870eSBartosz Markowski .pdev_set_dscp_tid_map_cmdid = WMI_PDEV_SET_DSCP_TID_MAP_CMDID, 46ce42870eSBartosz Markowski .pdev_set_quiet_mode_cmdid = WMI_PDEV_SET_QUIET_MODE_CMDID, 47ce42870eSBartosz Markowski .pdev_green_ap_ps_enable_cmdid = WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, 48ce42870eSBartosz Markowski .pdev_get_tpc_config_cmdid = WMI_PDEV_GET_TPC_CONFIG_CMDID, 49ce42870eSBartosz Markowski .pdev_set_base_macaddr_cmdid = WMI_PDEV_SET_BASE_MACADDR_CMDID, 50ce42870eSBartosz Markowski .vdev_create_cmdid = WMI_VDEV_CREATE_CMDID, 51ce42870eSBartosz Markowski .vdev_delete_cmdid = WMI_VDEV_DELETE_CMDID, 52ce42870eSBartosz Markowski .vdev_start_request_cmdid = WMI_VDEV_START_REQUEST_CMDID, 53ce42870eSBartosz Markowski .vdev_restart_request_cmdid = WMI_VDEV_RESTART_REQUEST_CMDID, 54ce42870eSBartosz Markowski .vdev_up_cmdid = WMI_VDEV_UP_CMDID, 55ce42870eSBartosz Markowski .vdev_stop_cmdid = WMI_VDEV_STOP_CMDID, 56ce42870eSBartosz Markowski .vdev_down_cmdid = WMI_VDEV_DOWN_CMDID, 57ce42870eSBartosz Markowski .vdev_set_param_cmdid = WMI_VDEV_SET_PARAM_CMDID, 58ce42870eSBartosz Markowski .vdev_install_key_cmdid = WMI_VDEV_INSTALL_KEY_CMDID, 59ce42870eSBartosz Markowski .peer_create_cmdid = WMI_PEER_CREATE_CMDID, 60ce42870eSBartosz Markowski .peer_delete_cmdid = WMI_PEER_DELETE_CMDID, 61ce42870eSBartosz Markowski .peer_flush_tids_cmdid = WMI_PEER_FLUSH_TIDS_CMDID, 62ce42870eSBartosz Markowski .peer_set_param_cmdid = WMI_PEER_SET_PARAM_CMDID, 63ce42870eSBartosz Markowski .peer_assoc_cmdid = WMI_PEER_ASSOC_CMDID, 64ce42870eSBartosz Markowski .peer_add_wds_entry_cmdid = WMI_PEER_ADD_WDS_ENTRY_CMDID, 65ce42870eSBartosz Markowski .peer_remove_wds_entry_cmdid = WMI_PEER_REMOVE_WDS_ENTRY_CMDID, 66ce42870eSBartosz Markowski .peer_mcast_group_cmdid = WMI_PEER_MCAST_GROUP_CMDID, 67ce42870eSBartosz Markowski .bcn_tx_cmdid = WMI_BCN_TX_CMDID, 68ce42870eSBartosz Markowski .pdev_send_bcn_cmdid = WMI_PDEV_SEND_BCN_CMDID, 69ce42870eSBartosz Markowski .bcn_tmpl_cmdid = WMI_BCN_TMPL_CMDID, 70ce42870eSBartosz Markowski .bcn_filter_rx_cmdid = WMI_BCN_FILTER_RX_CMDID, 71ce42870eSBartosz Markowski .prb_req_filter_rx_cmdid = WMI_PRB_REQ_FILTER_RX_CMDID, 72ce42870eSBartosz Markowski .mgmt_tx_cmdid = WMI_MGMT_TX_CMDID, 73ce42870eSBartosz Markowski .prb_tmpl_cmdid = WMI_PRB_TMPL_CMDID, 74ce42870eSBartosz Markowski .addba_clear_resp_cmdid = WMI_ADDBA_CLEAR_RESP_CMDID, 75ce42870eSBartosz Markowski .addba_send_cmdid = WMI_ADDBA_SEND_CMDID, 76ce42870eSBartosz Markowski .addba_status_cmdid = WMI_ADDBA_STATUS_CMDID, 77ce42870eSBartosz Markowski .delba_send_cmdid = WMI_DELBA_SEND_CMDID, 78ce42870eSBartosz Markowski .addba_set_resp_cmdid = WMI_ADDBA_SET_RESP_CMDID, 79ce42870eSBartosz Markowski .send_singleamsdu_cmdid = WMI_SEND_SINGLEAMSDU_CMDID, 80ce42870eSBartosz Markowski .sta_powersave_mode_cmdid = WMI_STA_POWERSAVE_MODE_CMDID, 81ce42870eSBartosz Markowski .sta_powersave_param_cmdid = WMI_STA_POWERSAVE_PARAM_CMDID, 82ce42870eSBartosz Markowski .sta_mimo_ps_mode_cmdid = WMI_STA_MIMO_PS_MODE_CMDID, 83ce42870eSBartosz Markowski .pdev_dfs_enable_cmdid = WMI_PDEV_DFS_ENABLE_CMDID, 84ce42870eSBartosz Markowski .pdev_dfs_disable_cmdid = WMI_PDEV_DFS_DISABLE_CMDID, 85ce42870eSBartosz Markowski .roam_scan_mode = WMI_ROAM_SCAN_MODE, 86ce42870eSBartosz Markowski .roam_scan_rssi_threshold = WMI_ROAM_SCAN_RSSI_THRESHOLD, 87ce42870eSBartosz Markowski .roam_scan_period = WMI_ROAM_SCAN_PERIOD, 88ce42870eSBartosz Markowski .roam_scan_rssi_change_threshold = WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, 89ce42870eSBartosz Markowski .roam_ap_profile = WMI_ROAM_AP_PROFILE, 90ce42870eSBartosz Markowski .ofl_scan_add_ap_profile = WMI_ROAM_AP_PROFILE, 91ce42870eSBartosz Markowski .ofl_scan_remove_ap_profile = WMI_OFL_SCAN_REMOVE_AP_PROFILE, 92ce42870eSBartosz Markowski .ofl_scan_period = WMI_OFL_SCAN_PERIOD, 93ce42870eSBartosz Markowski .p2p_dev_set_device_info = WMI_P2P_DEV_SET_DEVICE_INFO, 94ce42870eSBartosz Markowski .p2p_dev_set_discoverability = WMI_P2P_DEV_SET_DISCOVERABILITY, 95ce42870eSBartosz Markowski .p2p_go_set_beacon_ie = WMI_P2P_GO_SET_BEACON_IE, 96ce42870eSBartosz Markowski .p2p_go_set_probe_resp_ie = WMI_P2P_GO_SET_PROBE_RESP_IE, 97ce42870eSBartosz Markowski .p2p_set_vendor_ie_data_cmdid = WMI_P2P_SET_VENDOR_IE_DATA_CMDID, 98ce42870eSBartosz Markowski .ap_ps_peer_param_cmdid = WMI_AP_PS_PEER_PARAM_CMDID, 99ce42870eSBartosz Markowski .ap_ps_peer_uapsd_coex_cmdid = WMI_AP_PS_PEER_UAPSD_COEX_CMDID, 100ce42870eSBartosz Markowski .peer_rate_retry_sched_cmdid = WMI_PEER_RATE_RETRY_SCHED_CMDID, 101ce42870eSBartosz Markowski .wlan_profile_trigger_cmdid = WMI_WLAN_PROFILE_TRIGGER_CMDID, 102ce42870eSBartosz Markowski .wlan_profile_set_hist_intvl_cmdid = 103ce42870eSBartosz Markowski WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 104ce42870eSBartosz Markowski .wlan_profile_get_profile_data_cmdid = 105ce42870eSBartosz Markowski WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 106ce42870eSBartosz Markowski .wlan_profile_enable_profile_id_cmdid = 107ce42870eSBartosz Markowski WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 108ce42870eSBartosz Markowski .wlan_profile_list_profile_id_cmdid = 109ce42870eSBartosz Markowski WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, 110ce42870eSBartosz Markowski .pdev_suspend_cmdid = WMI_PDEV_SUSPEND_CMDID, 111ce42870eSBartosz Markowski .pdev_resume_cmdid = WMI_PDEV_RESUME_CMDID, 112ce42870eSBartosz Markowski .add_bcn_filter_cmdid = WMI_ADD_BCN_FILTER_CMDID, 113ce42870eSBartosz Markowski .rmv_bcn_filter_cmdid = WMI_RMV_BCN_FILTER_CMDID, 114ce42870eSBartosz Markowski .wow_add_wake_pattern_cmdid = WMI_WOW_ADD_WAKE_PATTERN_CMDID, 115ce42870eSBartosz Markowski .wow_del_wake_pattern_cmdid = WMI_WOW_DEL_WAKE_PATTERN_CMDID, 116ce42870eSBartosz Markowski .wow_enable_disable_wake_event_cmdid = 117ce42870eSBartosz Markowski WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, 118ce42870eSBartosz Markowski .wow_enable_cmdid = WMI_WOW_ENABLE_CMDID, 119ce42870eSBartosz Markowski .wow_hostwakeup_from_sleep_cmdid = WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, 120ce42870eSBartosz Markowski .rtt_measreq_cmdid = WMI_RTT_MEASREQ_CMDID, 121ce42870eSBartosz Markowski .rtt_tsf_cmdid = WMI_RTT_TSF_CMDID, 122ce42870eSBartosz Markowski .vdev_spectral_scan_configure_cmdid = 123ce42870eSBartosz Markowski WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, 124ce42870eSBartosz Markowski .vdev_spectral_scan_enable_cmdid = WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, 125ce42870eSBartosz Markowski .request_stats_cmdid = WMI_REQUEST_STATS_CMDID, 126ce42870eSBartosz Markowski .set_arp_ns_offload_cmdid = WMI_SET_ARP_NS_OFFLOAD_CMDID, 127ce42870eSBartosz Markowski .network_list_offload_config_cmdid = 128ce42870eSBartosz Markowski WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, 129ce42870eSBartosz Markowski .gtk_offload_cmdid = WMI_GTK_OFFLOAD_CMDID, 130ce42870eSBartosz Markowski .csa_offload_enable_cmdid = WMI_CSA_OFFLOAD_ENABLE_CMDID, 131ce42870eSBartosz Markowski .csa_offload_chanswitch_cmdid = WMI_CSA_OFFLOAD_CHANSWITCH_CMDID, 132ce42870eSBartosz Markowski .chatter_set_mode_cmdid = WMI_CHATTER_SET_MODE_CMDID, 133ce42870eSBartosz Markowski .peer_tid_addba_cmdid = WMI_PEER_TID_ADDBA_CMDID, 134ce42870eSBartosz Markowski .peer_tid_delba_cmdid = WMI_PEER_TID_DELBA_CMDID, 135ce42870eSBartosz Markowski .sta_dtim_ps_method_cmdid = WMI_STA_DTIM_PS_METHOD_CMDID, 136ce42870eSBartosz Markowski .sta_uapsd_auto_trig_cmdid = WMI_STA_UAPSD_AUTO_TRIG_CMDID, 137ce42870eSBartosz Markowski .sta_keepalive_cmd = WMI_STA_KEEPALIVE_CMD, 138ce42870eSBartosz Markowski .echo_cmdid = WMI_ECHO_CMDID, 139ce42870eSBartosz Markowski .pdev_utf_cmdid = WMI_PDEV_UTF_CMDID, 140ce42870eSBartosz Markowski .dbglog_cfg_cmdid = WMI_DBGLOG_CFG_CMDID, 141ce42870eSBartosz Markowski .pdev_qvit_cmdid = WMI_PDEV_QVIT_CMDID, 142ce42870eSBartosz Markowski .pdev_ftm_intg_cmdid = WMI_PDEV_FTM_INTG_CMDID, 143ce42870eSBartosz Markowski .vdev_set_keepalive_cmdid = WMI_VDEV_SET_KEEPALIVE_CMDID, 144ce42870eSBartosz Markowski .vdev_get_keepalive_cmdid = WMI_VDEV_GET_KEEPALIVE_CMDID, 145ce42870eSBartosz Markowski .force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID, 146ce42870eSBartosz Markowski .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID, 147ce42870eSBartosz Markowski .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID, 148a57a6a27SRajkumar Manoharan .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, 149ce42870eSBartosz Markowski }; 150ce42870eSBartosz Markowski 151b7e3adf9SBartosz Markowski /* 10.X WMI cmd track */ 152b7e3adf9SBartosz Markowski static struct wmi_cmd_map wmi_10x_cmd_map = { 153b7e3adf9SBartosz Markowski .init_cmdid = WMI_10X_INIT_CMDID, 154b7e3adf9SBartosz Markowski .start_scan_cmdid = WMI_10X_START_SCAN_CMDID, 155b7e3adf9SBartosz Markowski .stop_scan_cmdid = WMI_10X_STOP_SCAN_CMDID, 156b7e3adf9SBartosz Markowski .scan_chan_list_cmdid = WMI_10X_SCAN_CHAN_LIST_CMDID, 15734957b25SBartosz Markowski .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, 158b7e3adf9SBartosz Markowski .pdev_set_regdomain_cmdid = WMI_10X_PDEV_SET_REGDOMAIN_CMDID, 159b7e3adf9SBartosz Markowski .pdev_set_channel_cmdid = WMI_10X_PDEV_SET_CHANNEL_CMDID, 160b7e3adf9SBartosz Markowski .pdev_set_param_cmdid = WMI_10X_PDEV_SET_PARAM_CMDID, 161b7e3adf9SBartosz Markowski .pdev_pktlog_enable_cmdid = WMI_10X_PDEV_PKTLOG_ENABLE_CMDID, 162b7e3adf9SBartosz Markowski .pdev_pktlog_disable_cmdid = WMI_10X_PDEV_PKTLOG_DISABLE_CMDID, 163b7e3adf9SBartosz Markowski .pdev_set_wmm_params_cmdid = WMI_10X_PDEV_SET_WMM_PARAMS_CMDID, 164b7e3adf9SBartosz Markowski .pdev_set_ht_cap_ie_cmdid = WMI_10X_PDEV_SET_HT_CAP_IE_CMDID, 165b7e3adf9SBartosz Markowski .pdev_set_vht_cap_ie_cmdid = WMI_10X_PDEV_SET_VHT_CAP_IE_CMDID, 166b7e3adf9SBartosz Markowski .pdev_set_dscp_tid_map_cmdid = WMI_10X_PDEV_SET_DSCP_TID_MAP_CMDID, 167b7e3adf9SBartosz Markowski .pdev_set_quiet_mode_cmdid = WMI_10X_PDEV_SET_QUIET_MODE_CMDID, 168b7e3adf9SBartosz Markowski .pdev_green_ap_ps_enable_cmdid = WMI_10X_PDEV_GREEN_AP_PS_ENABLE_CMDID, 169b7e3adf9SBartosz Markowski .pdev_get_tpc_config_cmdid = WMI_10X_PDEV_GET_TPC_CONFIG_CMDID, 170b7e3adf9SBartosz Markowski .pdev_set_base_macaddr_cmdid = WMI_10X_PDEV_SET_BASE_MACADDR_CMDID, 171b7e3adf9SBartosz Markowski .vdev_create_cmdid = WMI_10X_VDEV_CREATE_CMDID, 172b7e3adf9SBartosz Markowski .vdev_delete_cmdid = WMI_10X_VDEV_DELETE_CMDID, 173b7e3adf9SBartosz Markowski .vdev_start_request_cmdid = WMI_10X_VDEV_START_REQUEST_CMDID, 174b7e3adf9SBartosz Markowski .vdev_restart_request_cmdid = WMI_10X_VDEV_RESTART_REQUEST_CMDID, 175b7e3adf9SBartosz Markowski .vdev_up_cmdid = WMI_10X_VDEV_UP_CMDID, 176b7e3adf9SBartosz Markowski .vdev_stop_cmdid = WMI_10X_VDEV_STOP_CMDID, 177b7e3adf9SBartosz Markowski .vdev_down_cmdid = WMI_10X_VDEV_DOWN_CMDID, 178b7e3adf9SBartosz Markowski .vdev_set_param_cmdid = WMI_10X_VDEV_SET_PARAM_CMDID, 179b7e3adf9SBartosz Markowski .vdev_install_key_cmdid = WMI_10X_VDEV_INSTALL_KEY_CMDID, 180b7e3adf9SBartosz Markowski .peer_create_cmdid = WMI_10X_PEER_CREATE_CMDID, 181b7e3adf9SBartosz Markowski .peer_delete_cmdid = WMI_10X_PEER_DELETE_CMDID, 182b7e3adf9SBartosz Markowski .peer_flush_tids_cmdid = WMI_10X_PEER_FLUSH_TIDS_CMDID, 183b7e3adf9SBartosz Markowski .peer_set_param_cmdid = WMI_10X_PEER_SET_PARAM_CMDID, 184b7e3adf9SBartosz Markowski .peer_assoc_cmdid = WMI_10X_PEER_ASSOC_CMDID, 185b7e3adf9SBartosz Markowski .peer_add_wds_entry_cmdid = WMI_10X_PEER_ADD_WDS_ENTRY_CMDID, 186b7e3adf9SBartosz Markowski .peer_remove_wds_entry_cmdid = WMI_10X_PEER_REMOVE_WDS_ENTRY_CMDID, 187b7e3adf9SBartosz Markowski .peer_mcast_group_cmdid = WMI_10X_PEER_MCAST_GROUP_CMDID, 188b7e3adf9SBartosz Markowski .bcn_tx_cmdid = WMI_10X_BCN_TX_CMDID, 189b7e3adf9SBartosz Markowski .pdev_send_bcn_cmdid = WMI_10X_PDEV_SEND_BCN_CMDID, 19034957b25SBartosz Markowski .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, 191b7e3adf9SBartosz Markowski .bcn_filter_rx_cmdid = WMI_10X_BCN_FILTER_RX_CMDID, 192b7e3adf9SBartosz Markowski .prb_req_filter_rx_cmdid = WMI_10X_PRB_REQ_FILTER_RX_CMDID, 193b7e3adf9SBartosz Markowski .mgmt_tx_cmdid = WMI_10X_MGMT_TX_CMDID, 19434957b25SBartosz Markowski .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, 195b7e3adf9SBartosz Markowski .addba_clear_resp_cmdid = WMI_10X_ADDBA_CLEAR_RESP_CMDID, 196b7e3adf9SBartosz Markowski .addba_send_cmdid = WMI_10X_ADDBA_SEND_CMDID, 197b7e3adf9SBartosz Markowski .addba_status_cmdid = WMI_10X_ADDBA_STATUS_CMDID, 198b7e3adf9SBartosz Markowski .delba_send_cmdid = WMI_10X_DELBA_SEND_CMDID, 199b7e3adf9SBartosz Markowski .addba_set_resp_cmdid = WMI_10X_ADDBA_SET_RESP_CMDID, 200b7e3adf9SBartosz Markowski .send_singleamsdu_cmdid = WMI_10X_SEND_SINGLEAMSDU_CMDID, 201b7e3adf9SBartosz Markowski .sta_powersave_mode_cmdid = WMI_10X_STA_POWERSAVE_MODE_CMDID, 202b7e3adf9SBartosz Markowski .sta_powersave_param_cmdid = WMI_10X_STA_POWERSAVE_PARAM_CMDID, 203b7e3adf9SBartosz Markowski .sta_mimo_ps_mode_cmdid = WMI_10X_STA_MIMO_PS_MODE_CMDID, 204b7e3adf9SBartosz Markowski .pdev_dfs_enable_cmdid = WMI_10X_PDEV_DFS_ENABLE_CMDID, 205b7e3adf9SBartosz Markowski .pdev_dfs_disable_cmdid = WMI_10X_PDEV_DFS_DISABLE_CMDID, 206b7e3adf9SBartosz Markowski .roam_scan_mode = WMI_10X_ROAM_SCAN_MODE, 207b7e3adf9SBartosz Markowski .roam_scan_rssi_threshold = WMI_10X_ROAM_SCAN_RSSI_THRESHOLD, 208b7e3adf9SBartosz Markowski .roam_scan_period = WMI_10X_ROAM_SCAN_PERIOD, 209b7e3adf9SBartosz Markowski .roam_scan_rssi_change_threshold = 210b7e3adf9SBartosz Markowski WMI_10X_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, 211b7e3adf9SBartosz Markowski .roam_ap_profile = WMI_10X_ROAM_AP_PROFILE, 212b7e3adf9SBartosz Markowski .ofl_scan_add_ap_profile = WMI_10X_OFL_SCAN_ADD_AP_PROFILE, 213b7e3adf9SBartosz Markowski .ofl_scan_remove_ap_profile = WMI_10X_OFL_SCAN_REMOVE_AP_PROFILE, 214b7e3adf9SBartosz Markowski .ofl_scan_period = WMI_10X_OFL_SCAN_PERIOD, 215b7e3adf9SBartosz Markowski .p2p_dev_set_device_info = WMI_10X_P2P_DEV_SET_DEVICE_INFO, 216b7e3adf9SBartosz Markowski .p2p_dev_set_discoverability = WMI_10X_P2P_DEV_SET_DISCOVERABILITY, 217b7e3adf9SBartosz Markowski .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE, 218b7e3adf9SBartosz Markowski .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE, 21934957b25SBartosz Markowski .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, 220542fb174SJanusz Dziedzic .ap_ps_peer_param_cmdid = WMI_10X_AP_PS_PEER_PARAM_CMDID, 22134957b25SBartosz Markowski .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, 222b7e3adf9SBartosz Markowski .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID, 223b7e3adf9SBartosz Markowski .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID, 224b7e3adf9SBartosz Markowski .wlan_profile_set_hist_intvl_cmdid = 225b7e3adf9SBartosz Markowski WMI_10X_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 226b7e3adf9SBartosz Markowski .wlan_profile_get_profile_data_cmdid = 227b7e3adf9SBartosz Markowski WMI_10X_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 228b7e3adf9SBartosz Markowski .wlan_profile_enable_profile_id_cmdid = 229b7e3adf9SBartosz Markowski WMI_10X_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 230b7e3adf9SBartosz Markowski .wlan_profile_list_profile_id_cmdid = 231b7e3adf9SBartosz Markowski WMI_10X_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, 232b7e3adf9SBartosz Markowski .pdev_suspend_cmdid = WMI_10X_PDEV_SUSPEND_CMDID, 233b7e3adf9SBartosz Markowski .pdev_resume_cmdid = WMI_10X_PDEV_RESUME_CMDID, 234b7e3adf9SBartosz Markowski .add_bcn_filter_cmdid = WMI_10X_ADD_BCN_FILTER_CMDID, 235b7e3adf9SBartosz Markowski .rmv_bcn_filter_cmdid = WMI_10X_RMV_BCN_FILTER_CMDID, 236b7e3adf9SBartosz Markowski .wow_add_wake_pattern_cmdid = WMI_10X_WOW_ADD_WAKE_PATTERN_CMDID, 237b7e3adf9SBartosz Markowski .wow_del_wake_pattern_cmdid = WMI_10X_WOW_DEL_WAKE_PATTERN_CMDID, 238b7e3adf9SBartosz Markowski .wow_enable_disable_wake_event_cmdid = 239b7e3adf9SBartosz Markowski WMI_10X_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, 240b7e3adf9SBartosz Markowski .wow_enable_cmdid = WMI_10X_WOW_ENABLE_CMDID, 241b7e3adf9SBartosz Markowski .wow_hostwakeup_from_sleep_cmdid = 242b7e3adf9SBartosz Markowski WMI_10X_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, 243b7e3adf9SBartosz Markowski .rtt_measreq_cmdid = WMI_10X_RTT_MEASREQ_CMDID, 244b7e3adf9SBartosz Markowski .rtt_tsf_cmdid = WMI_10X_RTT_TSF_CMDID, 245b7e3adf9SBartosz Markowski .vdev_spectral_scan_configure_cmdid = 246b7e3adf9SBartosz Markowski WMI_10X_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, 247b7e3adf9SBartosz Markowski .vdev_spectral_scan_enable_cmdid = 248b7e3adf9SBartosz Markowski WMI_10X_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, 249b7e3adf9SBartosz Markowski .request_stats_cmdid = WMI_10X_REQUEST_STATS_CMDID, 25034957b25SBartosz Markowski .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, 25134957b25SBartosz Markowski .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, 25234957b25SBartosz Markowski .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, 25334957b25SBartosz Markowski .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, 25434957b25SBartosz Markowski .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, 25534957b25SBartosz Markowski .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, 25634957b25SBartosz Markowski .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, 25734957b25SBartosz Markowski .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, 25834957b25SBartosz Markowski .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, 25934957b25SBartosz Markowski .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, 26034957b25SBartosz Markowski .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, 261b7e3adf9SBartosz Markowski .echo_cmdid = WMI_10X_ECHO_CMDID, 262b7e3adf9SBartosz Markowski .pdev_utf_cmdid = WMI_10X_PDEV_UTF_CMDID, 263b7e3adf9SBartosz Markowski .dbglog_cfg_cmdid = WMI_10X_DBGLOG_CFG_CMDID, 264b7e3adf9SBartosz Markowski .pdev_qvit_cmdid = WMI_10X_PDEV_QVIT_CMDID, 26534957b25SBartosz Markowski .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, 26634957b25SBartosz Markowski .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 26734957b25SBartosz Markowski .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 26834957b25SBartosz Markowski .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, 269b7e3adf9SBartosz Markowski .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID, 270b7e3adf9SBartosz Markowski .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID, 271a57a6a27SRajkumar Manoharan .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, 272b7e3adf9SBartosz Markowski }; 273ce42870eSBartosz Markowski 2744a16fbecSRajkumar Manoharan /* 10.2.4 WMI cmd track */ 2754a16fbecSRajkumar Manoharan static struct wmi_cmd_map wmi_10_2_4_cmd_map = { 2764a16fbecSRajkumar Manoharan .init_cmdid = WMI_10_2_INIT_CMDID, 2774a16fbecSRajkumar Manoharan .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID, 2784a16fbecSRajkumar Manoharan .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID, 2794a16fbecSRajkumar Manoharan .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID, 2804a16fbecSRajkumar Manoharan .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, 2814a16fbecSRajkumar Manoharan .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, 2824a16fbecSRajkumar Manoharan .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID, 2834a16fbecSRajkumar Manoharan .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID, 2844a16fbecSRajkumar Manoharan .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, 2854a16fbecSRajkumar Manoharan .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, 2864a16fbecSRajkumar Manoharan .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, 2874a16fbecSRajkumar Manoharan .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, 2884a16fbecSRajkumar Manoharan .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, 2894a16fbecSRajkumar Manoharan .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, 2904a16fbecSRajkumar Manoharan .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, 2914a16fbecSRajkumar Manoharan .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, 2924a16fbecSRajkumar Manoharan .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, 2934a16fbecSRajkumar Manoharan .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID, 2944a16fbecSRajkumar Manoharan .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID, 2954a16fbecSRajkumar Manoharan .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID, 2964a16fbecSRajkumar Manoharan .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID, 2974a16fbecSRajkumar Manoharan .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID, 2984a16fbecSRajkumar Manoharan .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID, 2994a16fbecSRajkumar Manoharan .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID, 3004a16fbecSRajkumar Manoharan .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID, 3014a16fbecSRajkumar Manoharan .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID, 3024a16fbecSRajkumar Manoharan .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID, 3034a16fbecSRajkumar Manoharan .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID, 3044a16fbecSRajkumar Manoharan .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID, 3054a16fbecSRajkumar Manoharan .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID, 3064a16fbecSRajkumar Manoharan .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID, 3074a16fbecSRajkumar Manoharan .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, 3084a16fbecSRajkumar Manoharan .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, 3094a16fbecSRajkumar Manoharan .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID, 3104a16fbecSRajkumar Manoharan .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID, 3114a16fbecSRajkumar Manoharan .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID, 3124a16fbecSRajkumar Manoharan .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, 3134a16fbecSRajkumar Manoharan .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID, 3144a16fbecSRajkumar Manoharan .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID, 3154a16fbecSRajkumar Manoharan .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID, 3164a16fbecSRajkumar Manoharan .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, 3174a16fbecSRajkumar Manoharan .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID, 3184a16fbecSRajkumar Manoharan .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID, 3194a16fbecSRajkumar Manoharan .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID, 3204a16fbecSRajkumar Manoharan .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID, 3214a16fbecSRajkumar Manoharan .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID, 3224a16fbecSRajkumar Manoharan .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID, 3234a16fbecSRajkumar Manoharan .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID, 3244a16fbecSRajkumar Manoharan .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID, 3254a16fbecSRajkumar Manoharan .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID, 3264a16fbecSRajkumar Manoharan .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID, 3274a16fbecSRajkumar Manoharan .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID, 3284a16fbecSRajkumar Manoharan .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE, 3294a16fbecSRajkumar Manoharan .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, 3304a16fbecSRajkumar Manoharan .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD, 3314a16fbecSRajkumar Manoharan .roam_scan_rssi_change_threshold = 3324a16fbecSRajkumar Manoharan WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, 3334a16fbecSRajkumar Manoharan .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE, 3344a16fbecSRajkumar Manoharan .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, 3354a16fbecSRajkumar Manoharan .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, 3364a16fbecSRajkumar Manoharan .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD, 3374a16fbecSRajkumar Manoharan .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO, 3384a16fbecSRajkumar Manoharan .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, 3394a16fbecSRajkumar Manoharan .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE, 3404a16fbecSRajkumar Manoharan .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, 3414a16fbecSRajkumar Manoharan .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, 3424a16fbecSRajkumar Manoharan .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID, 3434a16fbecSRajkumar Manoharan .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, 3444a16fbecSRajkumar Manoharan .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, 3454a16fbecSRajkumar Manoharan .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, 3464a16fbecSRajkumar Manoharan .wlan_profile_set_hist_intvl_cmdid = 3474a16fbecSRajkumar Manoharan WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 3484a16fbecSRajkumar Manoharan .wlan_profile_get_profile_data_cmdid = 3494a16fbecSRajkumar Manoharan WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 3504a16fbecSRajkumar Manoharan .wlan_profile_enable_profile_id_cmdid = 3514a16fbecSRajkumar Manoharan WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 3524a16fbecSRajkumar Manoharan .wlan_profile_list_profile_id_cmdid = 3534a16fbecSRajkumar Manoharan WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, 3544a16fbecSRajkumar Manoharan .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID, 3554a16fbecSRajkumar Manoharan .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID, 3564a16fbecSRajkumar Manoharan .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID, 3574a16fbecSRajkumar Manoharan .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID, 3584a16fbecSRajkumar Manoharan .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, 3594a16fbecSRajkumar Manoharan .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, 3604a16fbecSRajkumar Manoharan .wow_enable_disable_wake_event_cmdid = 3614a16fbecSRajkumar Manoharan WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, 3624a16fbecSRajkumar Manoharan .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID, 3634a16fbecSRajkumar Manoharan .wow_hostwakeup_from_sleep_cmdid = 3644a16fbecSRajkumar Manoharan WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, 3654a16fbecSRajkumar Manoharan .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID, 3664a16fbecSRajkumar Manoharan .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID, 3674a16fbecSRajkumar Manoharan .vdev_spectral_scan_configure_cmdid = 3684a16fbecSRajkumar Manoharan WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, 3694a16fbecSRajkumar Manoharan .vdev_spectral_scan_enable_cmdid = 3704a16fbecSRajkumar Manoharan WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, 3714a16fbecSRajkumar Manoharan .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID, 3724a16fbecSRajkumar Manoharan .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, 3734a16fbecSRajkumar Manoharan .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, 3744a16fbecSRajkumar Manoharan .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, 3754a16fbecSRajkumar Manoharan .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, 3764a16fbecSRajkumar Manoharan .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, 3774a16fbecSRajkumar Manoharan .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, 3784a16fbecSRajkumar Manoharan .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, 3794a16fbecSRajkumar Manoharan .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, 3804a16fbecSRajkumar Manoharan .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, 3814a16fbecSRajkumar Manoharan .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, 3824a16fbecSRajkumar Manoharan .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, 3834a16fbecSRajkumar Manoharan .echo_cmdid = WMI_10_2_ECHO_CMDID, 3844a16fbecSRajkumar Manoharan .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID, 3854a16fbecSRajkumar Manoharan .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID, 3864a16fbecSRajkumar Manoharan .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID, 3874a16fbecSRajkumar Manoharan .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, 3884a16fbecSRajkumar Manoharan .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 3894a16fbecSRajkumar Manoharan .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 3904a16fbecSRajkumar Manoharan .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, 3914a16fbecSRajkumar Manoharan .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, 3924a16fbecSRajkumar Manoharan .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, 393a57a6a27SRajkumar Manoharan .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID, 3944a16fbecSRajkumar Manoharan }; 3954a16fbecSRajkumar Manoharan 3966d1506e7SBartosz Markowski /* MAIN WMI VDEV param map */ 3976d1506e7SBartosz Markowski static struct wmi_vdev_param_map wmi_vdev_param_map = { 3986d1506e7SBartosz Markowski .rts_threshold = WMI_VDEV_PARAM_RTS_THRESHOLD, 3996d1506e7SBartosz Markowski .fragmentation_threshold = WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 4006d1506e7SBartosz Markowski .beacon_interval = WMI_VDEV_PARAM_BEACON_INTERVAL, 4016d1506e7SBartosz Markowski .listen_interval = WMI_VDEV_PARAM_LISTEN_INTERVAL, 4026d1506e7SBartosz Markowski .multicast_rate = WMI_VDEV_PARAM_MULTICAST_RATE, 4036d1506e7SBartosz Markowski .mgmt_tx_rate = WMI_VDEV_PARAM_MGMT_TX_RATE, 4046d1506e7SBartosz Markowski .slot_time = WMI_VDEV_PARAM_SLOT_TIME, 4056d1506e7SBartosz Markowski .preamble = WMI_VDEV_PARAM_PREAMBLE, 4066d1506e7SBartosz Markowski .swba_time = WMI_VDEV_PARAM_SWBA_TIME, 4076d1506e7SBartosz Markowski .wmi_vdev_stats_update_period = WMI_VDEV_STATS_UPDATE_PERIOD, 4086d1506e7SBartosz Markowski .wmi_vdev_pwrsave_ageout_time = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 4096d1506e7SBartosz Markowski .wmi_vdev_host_swba_interval = WMI_VDEV_HOST_SWBA_INTERVAL, 4106d1506e7SBartosz Markowski .dtim_period = WMI_VDEV_PARAM_DTIM_PERIOD, 4116d1506e7SBartosz Markowski .wmi_vdev_oc_scheduler_air_time_limit = 4126d1506e7SBartosz Markowski WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 4136d1506e7SBartosz Markowski .wds = WMI_VDEV_PARAM_WDS, 4146d1506e7SBartosz Markowski .atim_window = WMI_VDEV_PARAM_ATIM_WINDOW, 4156d1506e7SBartosz Markowski .bmiss_count_max = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 4166d1506e7SBartosz Markowski .bmiss_first_bcnt = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 4176d1506e7SBartosz Markowski .bmiss_final_bcnt = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 4186d1506e7SBartosz Markowski .feature_wmm = WMI_VDEV_PARAM_FEATURE_WMM, 4196d1506e7SBartosz Markowski .chwidth = WMI_VDEV_PARAM_CHWIDTH, 4206d1506e7SBartosz Markowski .chextoffset = WMI_VDEV_PARAM_CHEXTOFFSET, 4216d1506e7SBartosz Markowski .disable_htprotection = WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 4226d1506e7SBartosz Markowski .sta_quickkickout = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 4236d1506e7SBartosz Markowski .mgmt_rate = WMI_VDEV_PARAM_MGMT_RATE, 4246d1506e7SBartosz Markowski .protection_mode = WMI_VDEV_PARAM_PROTECTION_MODE, 4256d1506e7SBartosz Markowski .fixed_rate = WMI_VDEV_PARAM_FIXED_RATE, 4266d1506e7SBartosz Markowski .sgi = WMI_VDEV_PARAM_SGI, 4276d1506e7SBartosz Markowski .ldpc = WMI_VDEV_PARAM_LDPC, 4286d1506e7SBartosz Markowski .tx_stbc = WMI_VDEV_PARAM_TX_STBC, 4296d1506e7SBartosz Markowski .rx_stbc = WMI_VDEV_PARAM_RX_STBC, 4306d1506e7SBartosz Markowski .intra_bss_fwd = WMI_VDEV_PARAM_INTRA_BSS_FWD, 4316d1506e7SBartosz Markowski .def_keyid = WMI_VDEV_PARAM_DEF_KEYID, 4326d1506e7SBartosz Markowski .nss = WMI_VDEV_PARAM_NSS, 4336d1506e7SBartosz Markowski .bcast_data_rate = WMI_VDEV_PARAM_BCAST_DATA_RATE, 4346d1506e7SBartosz Markowski .mcast_data_rate = WMI_VDEV_PARAM_MCAST_DATA_RATE, 4356d1506e7SBartosz Markowski .mcast_indicate = WMI_VDEV_PARAM_MCAST_INDICATE, 4366d1506e7SBartosz Markowski .dhcp_indicate = WMI_VDEV_PARAM_DHCP_INDICATE, 4376d1506e7SBartosz Markowski .unknown_dest_indicate = WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 4386d1506e7SBartosz Markowski .ap_keepalive_min_idle_inactive_time_secs = 4396d1506e7SBartosz Markowski WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 4406d1506e7SBartosz Markowski .ap_keepalive_max_idle_inactive_time_secs = 4416d1506e7SBartosz Markowski WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 4426d1506e7SBartosz Markowski .ap_keepalive_max_unresponsive_time_secs = 4436d1506e7SBartosz Markowski WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 4446d1506e7SBartosz Markowski .ap_enable_nawds = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 4456d1506e7SBartosz Markowski .mcast2ucast_set = WMI_VDEV_PARAM_UNSUPPORTED, 4466d1506e7SBartosz Markowski .enable_rtscts = WMI_VDEV_PARAM_ENABLE_RTSCTS, 4476d1506e7SBartosz Markowski .txbf = WMI_VDEV_PARAM_TXBF, 4486d1506e7SBartosz Markowski .packet_powersave = WMI_VDEV_PARAM_PACKET_POWERSAVE, 4496d1506e7SBartosz Markowski .drop_unencry = WMI_VDEV_PARAM_DROP_UNENCRY, 4506d1506e7SBartosz Markowski .tx_encap_type = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 4516d1506e7SBartosz Markowski .ap_detect_out_of_sync_sleeping_sta_time_secs = 4526d1506e7SBartosz Markowski WMI_VDEV_PARAM_UNSUPPORTED, 4536d1506e7SBartosz Markowski }; 4546d1506e7SBartosz Markowski 4556d1506e7SBartosz Markowski /* 10.X WMI VDEV param map */ 4566d1506e7SBartosz Markowski static struct wmi_vdev_param_map wmi_10x_vdev_param_map = { 4576d1506e7SBartosz Markowski .rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD, 4586d1506e7SBartosz Markowski .fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 4596d1506e7SBartosz Markowski .beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL, 4606d1506e7SBartosz Markowski .listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL, 4616d1506e7SBartosz Markowski .multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE, 4626d1506e7SBartosz Markowski .mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE, 4636d1506e7SBartosz Markowski .slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME, 4646d1506e7SBartosz Markowski .preamble = WMI_10X_VDEV_PARAM_PREAMBLE, 4656d1506e7SBartosz Markowski .swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME, 4666d1506e7SBartosz Markowski .wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD, 4676d1506e7SBartosz Markowski .wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME, 4686d1506e7SBartosz Markowski .wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL, 4696d1506e7SBartosz Markowski .dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD, 4706d1506e7SBartosz Markowski .wmi_vdev_oc_scheduler_air_time_limit = 4716d1506e7SBartosz Markowski WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 4726d1506e7SBartosz Markowski .wds = WMI_10X_VDEV_PARAM_WDS, 4736d1506e7SBartosz Markowski .atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW, 4746d1506e7SBartosz Markowski .bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX, 4756d1506e7SBartosz Markowski .bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, 4766d1506e7SBartosz Markowski .bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, 4776d1506e7SBartosz Markowski .feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM, 4786d1506e7SBartosz Markowski .chwidth = WMI_10X_VDEV_PARAM_CHWIDTH, 4796d1506e7SBartosz Markowski .chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET, 4806d1506e7SBartosz Markowski .disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION, 4816d1506e7SBartosz Markowski .sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT, 4826d1506e7SBartosz Markowski .mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE, 4836d1506e7SBartosz Markowski .protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE, 4846d1506e7SBartosz Markowski .fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE, 4856d1506e7SBartosz Markowski .sgi = WMI_10X_VDEV_PARAM_SGI, 4866d1506e7SBartosz Markowski .ldpc = WMI_10X_VDEV_PARAM_LDPC, 4876d1506e7SBartosz Markowski .tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC, 4886d1506e7SBartosz Markowski .rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC, 4896d1506e7SBartosz Markowski .intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD, 4906d1506e7SBartosz Markowski .def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID, 4916d1506e7SBartosz Markowski .nss = WMI_10X_VDEV_PARAM_NSS, 4926d1506e7SBartosz Markowski .bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE, 4936d1506e7SBartosz Markowski .mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE, 4946d1506e7SBartosz Markowski .mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE, 4956d1506e7SBartosz Markowski .dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE, 4966d1506e7SBartosz Markowski .unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 4976d1506e7SBartosz Markowski .ap_keepalive_min_idle_inactive_time_secs = 4986d1506e7SBartosz Markowski WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 4996d1506e7SBartosz Markowski .ap_keepalive_max_idle_inactive_time_secs = 5006d1506e7SBartosz Markowski WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 5016d1506e7SBartosz Markowski .ap_keepalive_max_unresponsive_time_secs = 5026d1506e7SBartosz Markowski WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 5036d1506e7SBartosz Markowski .ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS, 5046d1506e7SBartosz Markowski .mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET, 5056d1506e7SBartosz Markowski .enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, 5066d1506e7SBartosz Markowski .txbf = WMI_VDEV_PARAM_UNSUPPORTED, 5076d1506e7SBartosz Markowski .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED, 5086d1506e7SBartosz Markowski .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED, 5096d1506e7SBartosz Markowski .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, 5106d1506e7SBartosz Markowski .ap_detect_out_of_sync_sleeping_sta_time_secs = 5116d1506e7SBartosz Markowski WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 5126d1506e7SBartosz Markowski }; 5136d1506e7SBartosz Markowski 5144a16fbecSRajkumar Manoharan static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { 5154a16fbecSRajkumar Manoharan .rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD, 5164a16fbecSRajkumar Manoharan .fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 5174a16fbecSRajkumar Manoharan .beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL, 5184a16fbecSRajkumar Manoharan .listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL, 5194a16fbecSRajkumar Manoharan .multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE, 5204a16fbecSRajkumar Manoharan .mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE, 5214a16fbecSRajkumar Manoharan .slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME, 5224a16fbecSRajkumar Manoharan .preamble = WMI_10X_VDEV_PARAM_PREAMBLE, 5234a16fbecSRajkumar Manoharan .swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME, 5244a16fbecSRajkumar Manoharan .wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD, 5254a16fbecSRajkumar Manoharan .wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME, 5264a16fbecSRajkumar Manoharan .wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL, 5274a16fbecSRajkumar Manoharan .dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD, 5284a16fbecSRajkumar Manoharan .wmi_vdev_oc_scheduler_air_time_limit = 5294a16fbecSRajkumar Manoharan WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 5304a16fbecSRajkumar Manoharan .wds = WMI_10X_VDEV_PARAM_WDS, 5314a16fbecSRajkumar Manoharan .atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW, 5324a16fbecSRajkumar Manoharan .bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX, 5334a16fbecSRajkumar Manoharan .bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, 5344a16fbecSRajkumar Manoharan .bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, 5354a16fbecSRajkumar Manoharan .feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM, 5364a16fbecSRajkumar Manoharan .chwidth = WMI_10X_VDEV_PARAM_CHWIDTH, 5374a16fbecSRajkumar Manoharan .chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET, 5384a16fbecSRajkumar Manoharan .disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION, 5394a16fbecSRajkumar Manoharan .sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT, 5404a16fbecSRajkumar Manoharan .mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE, 5414a16fbecSRajkumar Manoharan .protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE, 5424a16fbecSRajkumar Manoharan .fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE, 5434a16fbecSRajkumar Manoharan .sgi = WMI_10X_VDEV_PARAM_SGI, 5444a16fbecSRajkumar Manoharan .ldpc = WMI_10X_VDEV_PARAM_LDPC, 5454a16fbecSRajkumar Manoharan .tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC, 5464a16fbecSRajkumar Manoharan .rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC, 5474a16fbecSRajkumar Manoharan .intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD, 5484a16fbecSRajkumar Manoharan .def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID, 5494a16fbecSRajkumar Manoharan .nss = WMI_10X_VDEV_PARAM_NSS, 5504a16fbecSRajkumar Manoharan .bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE, 5514a16fbecSRajkumar Manoharan .mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE, 5524a16fbecSRajkumar Manoharan .mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE, 5534a16fbecSRajkumar Manoharan .dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE, 5544a16fbecSRajkumar Manoharan .unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 5554a16fbecSRajkumar Manoharan .ap_keepalive_min_idle_inactive_time_secs = 5564a16fbecSRajkumar Manoharan WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 5574a16fbecSRajkumar Manoharan .ap_keepalive_max_idle_inactive_time_secs = 5584a16fbecSRajkumar Manoharan WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 5594a16fbecSRajkumar Manoharan .ap_keepalive_max_unresponsive_time_secs = 5604a16fbecSRajkumar Manoharan WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 5614a16fbecSRajkumar Manoharan .ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS, 5624a16fbecSRajkumar Manoharan .mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET, 5634a16fbecSRajkumar Manoharan .enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, 5644a16fbecSRajkumar Manoharan .txbf = WMI_VDEV_PARAM_UNSUPPORTED, 5654a16fbecSRajkumar Manoharan .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED, 5664a16fbecSRajkumar Manoharan .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED, 5674a16fbecSRajkumar Manoharan .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, 5684a16fbecSRajkumar Manoharan .ap_detect_out_of_sync_sleeping_sta_time_secs = 5694a16fbecSRajkumar Manoharan WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 5704a16fbecSRajkumar Manoharan }; 5714a16fbecSRajkumar Manoharan 572226a339bSBartosz Markowski static struct wmi_pdev_param_map wmi_pdev_param_map = { 573226a339bSBartosz Markowski .tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK, 574226a339bSBartosz Markowski .rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK, 575226a339bSBartosz Markowski .txpower_limit2g = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 576226a339bSBartosz Markowski .txpower_limit5g = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 577226a339bSBartosz Markowski .txpower_scale = WMI_PDEV_PARAM_TXPOWER_SCALE, 578226a339bSBartosz Markowski .beacon_gen_mode = WMI_PDEV_PARAM_BEACON_GEN_MODE, 579226a339bSBartosz Markowski .beacon_tx_mode = WMI_PDEV_PARAM_BEACON_TX_MODE, 580226a339bSBartosz Markowski .resmgr_offchan_mode = WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 581226a339bSBartosz Markowski .protection_mode = WMI_PDEV_PARAM_PROTECTION_MODE, 582226a339bSBartosz Markowski .dynamic_bw = WMI_PDEV_PARAM_DYNAMIC_BW, 583226a339bSBartosz Markowski .non_agg_sw_retry_th = WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 584226a339bSBartosz Markowski .agg_sw_retry_th = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 585226a339bSBartosz Markowski .sta_kickout_th = WMI_PDEV_PARAM_STA_KICKOUT_TH, 586226a339bSBartosz Markowski .ac_aggrsize_scaling = WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 587226a339bSBartosz Markowski .ltr_enable = WMI_PDEV_PARAM_LTR_ENABLE, 588226a339bSBartosz Markowski .ltr_ac_latency_be = WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 589226a339bSBartosz Markowski .ltr_ac_latency_bk = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 590226a339bSBartosz Markowski .ltr_ac_latency_vi = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 591226a339bSBartosz Markowski .ltr_ac_latency_vo = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 592226a339bSBartosz Markowski .ltr_ac_latency_timeout = WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 593226a339bSBartosz Markowski .ltr_sleep_override = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 594226a339bSBartosz Markowski .ltr_rx_override = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 595226a339bSBartosz Markowski .ltr_tx_activity_timeout = WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 596226a339bSBartosz Markowski .l1ss_enable = WMI_PDEV_PARAM_L1SS_ENABLE, 597226a339bSBartosz Markowski .dsleep_enable = WMI_PDEV_PARAM_DSLEEP_ENABLE, 598226a339bSBartosz Markowski .pcielp_txbuf_flush = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 599226a339bSBartosz Markowski .pcielp_txbuf_watermark = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 600226a339bSBartosz Markowski .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 601226a339bSBartosz Markowski .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 602226a339bSBartosz Markowski .pdev_stats_update_period = WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 603226a339bSBartosz Markowski .vdev_stats_update_period = WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 604226a339bSBartosz Markowski .peer_stats_update_period = WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 605226a339bSBartosz Markowski .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 606226a339bSBartosz Markowski .pmf_qos = WMI_PDEV_PARAM_PMF_QOS, 607226a339bSBartosz Markowski .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 608226a339bSBartosz Markowski .dcs = WMI_PDEV_PARAM_DCS, 609226a339bSBartosz Markowski .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE, 610226a339bSBartosz Markowski .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 611226a339bSBartosz Markowski .ani_listen_period = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 612226a339bSBartosz Markowski .ani_ofdm_level = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 613226a339bSBartosz Markowski .ani_cck_level = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 614226a339bSBartosz Markowski .dyntxchain = WMI_PDEV_PARAM_DYNTXCHAIN, 615226a339bSBartosz Markowski .proxy_sta = WMI_PDEV_PARAM_PROXY_STA, 616226a339bSBartosz Markowski .idle_ps_config = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 617226a339bSBartosz Markowski .power_gating_sleep = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 618226a339bSBartosz Markowski .fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED, 619226a339bSBartosz Markowski .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED, 620226a339bSBartosz Markowski .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED, 621a7bd3e99SPeter Oh .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, 622226a339bSBartosz Markowski }; 623226a339bSBartosz Markowski 624226a339bSBartosz Markowski static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { 625226a339bSBartosz Markowski .tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK, 626226a339bSBartosz Markowski .rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK, 627226a339bSBartosz Markowski .txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G, 628226a339bSBartosz Markowski .txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G, 629226a339bSBartosz Markowski .txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE, 630226a339bSBartosz Markowski .beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE, 631226a339bSBartosz Markowski .beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE, 632226a339bSBartosz Markowski .resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 633226a339bSBartosz Markowski .protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE, 634226a339bSBartosz Markowski .dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW, 635226a339bSBartosz Markowski .non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 636226a339bSBartosz Markowski .agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH, 637226a339bSBartosz Markowski .sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH, 638226a339bSBartosz Markowski .ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING, 639226a339bSBartosz Markowski .ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE, 640226a339bSBartosz Markowski .ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE, 641226a339bSBartosz Markowski .ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK, 642226a339bSBartosz Markowski .ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI, 643226a339bSBartosz Markowski .ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO, 644226a339bSBartosz Markowski .ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 645226a339bSBartosz Markowski .ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 646226a339bSBartosz Markowski .ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE, 647226a339bSBartosz Markowski .ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 648226a339bSBartosz Markowski .l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE, 649226a339bSBartosz Markowski .dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE, 650226a339bSBartosz Markowski .pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED, 651226a339bSBartosz Markowski .pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED, 652226a339bSBartosz Markowski .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED, 653226a339bSBartosz Markowski .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED, 654226a339bSBartosz Markowski .pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 655226a339bSBartosz Markowski .vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 656226a339bSBartosz Markowski .peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 657226a339bSBartosz Markowski .bcnflt_stats_update_period = 658226a339bSBartosz Markowski WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 659226a339bSBartosz Markowski .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, 660ab6258edSMarek Puzyniak .arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE, 661226a339bSBartosz Markowski .dcs = WMI_10X_PDEV_PARAM_DCS, 662226a339bSBartosz Markowski .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, 663226a339bSBartosz Markowski .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, 664226a339bSBartosz Markowski .ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD, 665226a339bSBartosz Markowski .ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL, 666226a339bSBartosz Markowski .ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL, 667226a339bSBartosz Markowski .dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN, 668226a339bSBartosz Markowski .proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED, 669226a339bSBartosz Markowski .idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED, 670226a339bSBartosz Markowski .power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED, 671226a339bSBartosz Markowski .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, 672226a339bSBartosz Markowski .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, 673226a339bSBartosz Markowski .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, 674a7bd3e99SPeter Oh .cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD, 675226a339bSBartosz Markowski }; 676226a339bSBartosz Markowski 6774a16fbecSRajkumar Manoharan static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = { 6784a16fbecSRajkumar Manoharan .tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK, 6794a16fbecSRajkumar Manoharan .rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK, 6804a16fbecSRajkumar Manoharan .txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G, 6814a16fbecSRajkumar Manoharan .txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G, 6824a16fbecSRajkumar Manoharan .txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE, 6834a16fbecSRajkumar Manoharan .beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE, 6844a16fbecSRajkumar Manoharan .beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE, 6854a16fbecSRajkumar Manoharan .resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 6864a16fbecSRajkumar Manoharan .protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE, 6874a16fbecSRajkumar Manoharan .dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW, 6884a16fbecSRajkumar Manoharan .non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 6894a16fbecSRajkumar Manoharan .agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH, 6904a16fbecSRajkumar Manoharan .sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH, 6914a16fbecSRajkumar Manoharan .ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING, 6924a16fbecSRajkumar Manoharan .ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE, 6934a16fbecSRajkumar Manoharan .ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE, 6944a16fbecSRajkumar Manoharan .ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK, 6954a16fbecSRajkumar Manoharan .ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI, 6964a16fbecSRajkumar Manoharan .ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO, 6974a16fbecSRajkumar Manoharan .ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 6984a16fbecSRajkumar Manoharan .ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 6994a16fbecSRajkumar Manoharan .ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE, 7004a16fbecSRajkumar Manoharan .ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 7014a16fbecSRajkumar Manoharan .l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE, 7024a16fbecSRajkumar Manoharan .dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE, 7034a16fbecSRajkumar Manoharan .pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED, 7044a16fbecSRajkumar Manoharan .pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED, 7054a16fbecSRajkumar Manoharan .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED, 7064a16fbecSRajkumar Manoharan .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED, 7074a16fbecSRajkumar Manoharan .pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 7084a16fbecSRajkumar Manoharan .vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 7094a16fbecSRajkumar Manoharan .peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 7104a16fbecSRajkumar Manoharan .bcnflt_stats_update_period = 7114a16fbecSRajkumar Manoharan WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 7124a16fbecSRajkumar Manoharan .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, 7134a16fbecSRajkumar Manoharan .arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE, 7144a16fbecSRajkumar Manoharan .dcs = WMI_10X_PDEV_PARAM_DCS, 7154a16fbecSRajkumar Manoharan .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, 7164a16fbecSRajkumar Manoharan .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, 7174a16fbecSRajkumar Manoharan .ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD, 7184a16fbecSRajkumar Manoharan .ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL, 7194a16fbecSRajkumar Manoharan .ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL, 7204a16fbecSRajkumar Manoharan .dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN, 7214a16fbecSRajkumar Manoharan .proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED, 7224a16fbecSRajkumar Manoharan .idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED, 7234a16fbecSRajkumar Manoharan .power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED, 7244a16fbecSRajkumar Manoharan .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, 7254a16fbecSRajkumar Manoharan .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, 7264a16fbecSRajkumar Manoharan .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, 7274a16fbecSRajkumar Manoharan .cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD, 7284a16fbecSRajkumar Manoharan }; 7294a16fbecSRajkumar Manoharan 73024c88f78SMichal Kazior /* firmware 10.2 specific mappings */ 73124c88f78SMichal Kazior static struct wmi_cmd_map wmi_10_2_cmd_map = { 73224c88f78SMichal Kazior .init_cmdid = WMI_10_2_INIT_CMDID, 73324c88f78SMichal Kazior .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID, 73424c88f78SMichal Kazior .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID, 73524c88f78SMichal Kazior .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID, 73624c88f78SMichal Kazior .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, 73724c88f78SMichal Kazior .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, 73824c88f78SMichal Kazior .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID, 73924c88f78SMichal Kazior .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID, 74024c88f78SMichal Kazior .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, 74124c88f78SMichal Kazior .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, 74224c88f78SMichal Kazior .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, 74324c88f78SMichal Kazior .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, 74424c88f78SMichal Kazior .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, 74524c88f78SMichal Kazior .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, 74624c88f78SMichal Kazior .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, 74724c88f78SMichal Kazior .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, 74824c88f78SMichal Kazior .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, 74924c88f78SMichal Kazior .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID, 75024c88f78SMichal Kazior .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID, 75124c88f78SMichal Kazior .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID, 75224c88f78SMichal Kazior .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID, 75324c88f78SMichal Kazior .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID, 75424c88f78SMichal Kazior .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID, 75524c88f78SMichal Kazior .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID, 75624c88f78SMichal Kazior .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID, 75724c88f78SMichal Kazior .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID, 75824c88f78SMichal Kazior .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID, 75924c88f78SMichal Kazior .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID, 76024c88f78SMichal Kazior .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID, 76124c88f78SMichal Kazior .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID, 76224c88f78SMichal Kazior .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID, 76324c88f78SMichal Kazior .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, 76424c88f78SMichal Kazior .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, 76524c88f78SMichal Kazior .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID, 76624c88f78SMichal Kazior .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID, 76724c88f78SMichal Kazior .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID, 76824c88f78SMichal Kazior .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, 76924c88f78SMichal Kazior .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID, 77024c88f78SMichal Kazior .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID, 77124c88f78SMichal Kazior .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID, 77224c88f78SMichal Kazior .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, 77324c88f78SMichal Kazior .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID, 77424c88f78SMichal Kazior .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID, 77524c88f78SMichal Kazior .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID, 77624c88f78SMichal Kazior .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID, 77724c88f78SMichal Kazior .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID, 77824c88f78SMichal Kazior .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID, 77924c88f78SMichal Kazior .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID, 78024c88f78SMichal Kazior .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID, 78124c88f78SMichal Kazior .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID, 78224c88f78SMichal Kazior .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID, 78324c88f78SMichal Kazior .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID, 78424c88f78SMichal Kazior .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE, 78524c88f78SMichal Kazior .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, 78624c88f78SMichal Kazior .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD, 78724c88f78SMichal Kazior .roam_scan_rssi_change_threshold = 78824c88f78SMichal Kazior WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, 78924c88f78SMichal Kazior .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE, 79024c88f78SMichal Kazior .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, 79124c88f78SMichal Kazior .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, 79224c88f78SMichal Kazior .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD, 79324c88f78SMichal Kazior .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO, 79424c88f78SMichal Kazior .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, 79524c88f78SMichal Kazior .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE, 79624c88f78SMichal Kazior .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, 79724c88f78SMichal Kazior .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, 79824c88f78SMichal Kazior .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID, 79924c88f78SMichal Kazior .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, 80024c88f78SMichal Kazior .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, 80124c88f78SMichal Kazior .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, 80224c88f78SMichal Kazior .wlan_profile_set_hist_intvl_cmdid = 80324c88f78SMichal Kazior WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 80424c88f78SMichal Kazior .wlan_profile_get_profile_data_cmdid = 80524c88f78SMichal Kazior WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 80624c88f78SMichal Kazior .wlan_profile_enable_profile_id_cmdid = 80724c88f78SMichal Kazior WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 80824c88f78SMichal Kazior .wlan_profile_list_profile_id_cmdid = 80924c88f78SMichal Kazior WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, 81024c88f78SMichal Kazior .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID, 81124c88f78SMichal Kazior .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID, 81224c88f78SMichal Kazior .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID, 81324c88f78SMichal Kazior .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID, 81424c88f78SMichal Kazior .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, 81524c88f78SMichal Kazior .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, 81624c88f78SMichal Kazior .wow_enable_disable_wake_event_cmdid = 81724c88f78SMichal Kazior WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, 81824c88f78SMichal Kazior .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID, 81924c88f78SMichal Kazior .wow_hostwakeup_from_sleep_cmdid = 82024c88f78SMichal Kazior WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, 82124c88f78SMichal Kazior .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID, 82224c88f78SMichal Kazior .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID, 82324c88f78SMichal Kazior .vdev_spectral_scan_configure_cmdid = 82424c88f78SMichal Kazior WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, 82524c88f78SMichal Kazior .vdev_spectral_scan_enable_cmdid = 82624c88f78SMichal Kazior WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, 82724c88f78SMichal Kazior .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID, 82824c88f78SMichal Kazior .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, 82924c88f78SMichal Kazior .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, 83024c88f78SMichal Kazior .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, 83124c88f78SMichal Kazior .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, 83224c88f78SMichal Kazior .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, 83324c88f78SMichal Kazior .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, 83424c88f78SMichal Kazior .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, 83524c88f78SMichal Kazior .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, 83624c88f78SMichal Kazior .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, 83724c88f78SMichal Kazior .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, 83824c88f78SMichal Kazior .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, 83924c88f78SMichal Kazior .echo_cmdid = WMI_10_2_ECHO_CMDID, 84024c88f78SMichal Kazior .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID, 84124c88f78SMichal Kazior .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID, 84224c88f78SMichal Kazior .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID, 84324c88f78SMichal Kazior .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, 84424c88f78SMichal Kazior .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 84524c88f78SMichal Kazior .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, 84624c88f78SMichal Kazior .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, 84724c88f78SMichal Kazior .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, 84824c88f78SMichal Kazior .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, 849a57a6a27SRajkumar Manoharan .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, 85024c88f78SMichal Kazior }; 85124c88f78SMichal Kazior 8520226d602SMichal Kazior void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, 8532d66721cSMichal Kazior const struct wmi_channel_arg *arg) 8542d66721cSMichal Kazior { 8552d66721cSMichal Kazior u32 flags = 0; 8562d66721cSMichal Kazior 8572d66721cSMichal Kazior memset(ch, 0, sizeof(*ch)); 8582d66721cSMichal Kazior 8592d66721cSMichal Kazior if (arg->passive) 8602d66721cSMichal Kazior flags |= WMI_CHAN_FLAG_PASSIVE; 8612d66721cSMichal Kazior if (arg->allow_ibss) 8622d66721cSMichal Kazior flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED; 8632d66721cSMichal Kazior if (arg->allow_ht) 8642d66721cSMichal Kazior flags |= WMI_CHAN_FLAG_ALLOW_HT; 8652d66721cSMichal Kazior if (arg->allow_vht) 8662d66721cSMichal Kazior flags |= WMI_CHAN_FLAG_ALLOW_VHT; 8672d66721cSMichal Kazior if (arg->ht40plus) 8682d66721cSMichal Kazior flags |= WMI_CHAN_FLAG_HT40_PLUS; 8692d66721cSMichal Kazior if (arg->chan_radar) 8702d66721cSMichal Kazior flags |= WMI_CHAN_FLAG_DFS; 8712d66721cSMichal Kazior 8722d66721cSMichal Kazior ch->mhz = __cpu_to_le32(arg->freq); 8732d66721cSMichal Kazior ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); 8742d66721cSMichal Kazior ch->band_center_freq2 = 0; 8752d66721cSMichal Kazior ch->min_power = arg->min_power; 8762d66721cSMichal Kazior ch->max_power = arg->max_power; 8772d66721cSMichal Kazior ch->reg_power = arg->max_reg_power; 8782d66721cSMichal Kazior ch->antenna_max = arg->max_antenna_gain; 8792d66721cSMichal Kazior 8802d66721cSMichal Kazior /* mode & flags share storage */ 8812d66721cSMichal Kazior ch->mode = arg->mode; 8822d66721cSMichal Kazior ch->flags |= __cpu_to_le32(flags); 8832d66721cSMichal Kazior } 8842d66721cSMichal Kazior 8855e3dd157SKalle Valo int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) 8865e3dd157SKalle Valo { 8875e3dd157SKalle Valo int ret; 888af762c0bSKalle Valo 8895e3dd157SKalle Valo ret = wait_for_completion_timeout(&ar->wmi.service_ready, 8905e3dd157SKalle Valo WMI_SERVICE_READY_TIMEOUT_HZ); 8915e3dd157SKalle Valo return ret; 8925e3dd157SKalle Valo } 8935e3dd157SKalle Valo 8945e3dd157SKalle Valo int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) 8955e3dd157SKalle Valo { 8965e3dd157SKalle Valo int ret; 897af762c0bSKalle Valo 8985e3dd157SKalle Valo ret = wait_for_completion_timeout(&ar->wmi.unified_ready, 8995e3dd157SKalle Valo WMI_UNIFIED_READY_TIMEOUT_HZ); 9005e3dd157SKalle Valo return ret; 9015e3dd157SKalle Valo } 9025e3dd157SKalle Valo 903666a73f3SKalle Valo struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len) 9045e3dd157SKalle Valo { 9055e3dd157SKalle Valo struct sk_buff *skb; 9065e3dd157SKalle Valo u32 round_len = roundup(len, 4); 9075e3dd157SKalle Valo 9087aa7a72aSMichal Kazior skb = ath10k_htc_alloc_skb(ar, WMI_SKB_HEADROOM + round_len); 9095e3dd157SKalle Valo if (!skb) 9105e3dd157SKalle Valo return NULL; 9115e3dd157SKalle Valo 9125e3dd157SKalle Valo skb_reserve(skb, WMI_SKB_HEADROOM); 9135e3dd157SKalle Valo if (!IS_ALIGNED((unsigned long)skb->data, 4)) 9147aa7a72aSMichal Kazior ath10k_warn(ar, "Unaligned WMI skb\n"); 9155e3dd157SKalle Valo 9165e3dd157SKalle Valo skb_put(skb, round_len); 9175e3dd157SKalle Valo memset(skb->data, 0, round_len); 9185e3dd157SKalle Valo 9195e3dd157SKalle Valo return skb; 9205e3dd157SKalle Valo } 9215e3dd157SKalle Valo 9225e3dd157SKalle Valo static void ath10k_wmi_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) 9235e3dd157SKalle Valo { 9245e3dd157SKalle Valo dev_kfree_skb(skb); 9255e3dd157SKalle Valo } 9265e3dd157SKalle Valo 927d7579d12SMichal Kazior int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, 928ce42870eSBartosz Markowski u32 cmd_id) 9295e3dd157SKalle Valo { 9305e3dd157SKalle Valo struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); 9315e3dd157SKalle Valo struct wmi_cmd_hdr *cmd_hdr; 932be8b3943SMichal Kazior int ret; 9335e3dd157SKalle Valo u32 cmd = 0; 9345e3dd157SKalle Valo 9355e3dd157SKalle Valo if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 9365e3dd157SKalle Valo return -ENOMEM; 9375e3dd157SKalle Valo 9385e3dd157SKalle Valo cmd |= SM(cmd_id, WMI_CMD_HDR_CMD_ID); 9395e3dd157SKalle Valo 9405e3dd157SKalle Valo cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 9415e3dd157SKalle Valo cmd_hdr->cmd_id = __cpu_to_le32(cmd); 9425e3dd157SKalle Valo 9435e3dd157SKalle Valo memset(skb_cb, 0, sizeof(*skb_cb)); 944be8b3943SMichal Kazior ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); 945d35a6c18SMichal Kazior trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret); 9465e3dd157SKalle Valo 947be8b3943SMichal Kazior if (ret) 948be8b3943SMichal Kazior goto err_pull; 9495e3dd157SKalle Valo 9505e3dd157SKalle Valo return 0; 951be8b3943SMichal Kazior 952be8b3943SMichal Kazior err_pull: 953be8b3943SMichal Kazior skb_pull(skb, sizeof(struct wmi_cmd_hdr)); 954be8b3943SMichal Kazior return ret; 955be8b3943SMichal Kazior } 956be8b3943SMichal Kazior 957ed54388aSMichal Kazior static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) 958ed54388aSMichal Kazior { 959ed54388aSMichal Kazior int ret; 960ed54388aSMichal Kazior 961ed54388aSMichal Kazior lockdep_assert_held(&arvif->ar->data_lock); 962ed54388aSMichal Kazior 963ed54388aSMichal Kazior if (arvif->beacon == NULL) 964ed54388aSMichal Kazior return; 965ed54388aSMichal Kazior 966748afc47SMichal Kazior if (arvif->beacon_sent) 967748afc47SMichal Kazior return; 968ed54388aSMichal Kazior 969748afc47SMichal Kazior ret = ath10k_wmi_beacon_send_ref_nowait(arvif); 970ed54388aSMichal Kazior if (ret) 971ed54388aSMichal Kazior return; 972ed54388aSMichal Kazior 973748afc47SMichal Kazior /* We need to retain the arvif->beacon reference for DMA unmapping and 974748afc47SMichal Kazior * freeing the skbuff later. */ 975748afc47SMichal Kazior arvif->beacon_sent = true; 976ed54388aSMichal Kazior } 977ed54388aSMichal Kazior 978ed54388aSMichal Kazior static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, 979ed54388aSMichal Kazior struct ieee80211_vif *vif) 980ed54388aSMichal Kazior { 981ed54388aSMichal Kazior struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 982ed54388aSMichal Kazior 983ed54388aSMichal Kazior ath10k_wmi_tx_beacon_nowait(arvif); 984ed54388aSMichal Kazior } 985ed54388aSMichal Kazior 986ed54388aSMichal Kazior static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar) 987ed54388aSMichal Kazior { 988ed54388aSMichal Kazior spin_lock_bh(&ar->data_lock); 989ed54388aSMichal Kazior ieee80211_iterate_active_interfaces_atomic(ar->hw, 990ed54388aSMichal Kazior IEEE80211_IFACE_ITER_NORMAL, 991ed54388aSMichal Kazior ath10k_wmi_tx_beacons_iter, 992ed54388aSMichal Kazior NULL); 993ed54388aSMichal Kazior spin_unlock_bh(&ar->data_lock); 994ed54388aSMichal Kazior } 995ed54388aSMichal Kazior 99612acbc43SMichal Kazior static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) 997be8b3943SMichal Kazior { 998ed54388aSMichal Kazior /* try to send pending beacons first. they take priority */ 999ed54388aSMichal Kazior ath10k_wmi_tx_beacons_nowait(ar); 1000ed54388aSMichal Kazior 1001be8b3943SMichal Kazior wake_up(&ar->wmi.tx_credits_wq); 1002be8b3943SMichal Kazior } 1003be8b3943SMichal Kazior 1004666a73f3SKalle Valo int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id) 1005be8b3943SMichal Kazior { 100634957b25SBartosz Markowski int ret = -EOPNOTSUPP; 1007be8b3943SMichal Kazior 100856b84287SKalle Valo might_sleep(); 100956b84287SKalle Valo 101034957b25SBartosz Markowski if (cmd_id == WMI_CMD_UNSUPPORTED) { 10117aa7a72aSMichal Kazior ath10k_warn(ar, "wmi command %d is not supported by firmware\n", 101255321559SBartosz Markowski cmd_id); 101355321559SBartosz Markowski return ret; 101455321559SBartosz Markowski } 1015be8b3943SMichal Kazior 1016be8b3943SMichal Kazior wait_event_timeout(ar->wmi.tx_credits_wq, ({ 1017ed54388aSMichal Kazior /* try to send pending beacons first. they take priority */ 1018ed54388aSMichal Kazior ath10k_wmi_tx_beacons_nowait(ar); 1019ed54388aSMichal Kazior 1020be8b3943SMichal Kazior ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id); 10217962b0d8SMichal Kazior 10227962b0d8SMichal Kazior if (ret && test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) 10237962b0d8SMichal Kazior ret = -ESHUTDOWN; 10247962b0d8SMichal Kazior 1025be8b3943SMichal Kazior (ret != -EAGAIN); 1026be8b3943SMichal Kazior }), 3*HZ); 1027be8b3943SMichal Kazior 1028be8b3943SMichal Kazior if (ret) 1029be8b3943SMichal Kazior dev_kfree_skb_any(skb); 1030be8b3943SMichal Kazior 1031be8b3943SMichal Kazior return ret; 10325e3dd157SKalle Valo } 10335e3dd157SKalle Valo 1034d7579d12SMichal Kazior static struct sk_buff * 1035d7579d12SMichal Kazior ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) 10365e00d31aSBartosz Markowski { 10375e00d31aSBartosz Markowski struct wmi_mgmt_tx_cmd *cmd; 10385e00d31aSBartosz Markowski struct ieee80211_hdr *hdr; 1039d7579d12SMichal Kazior struct sk_buff *skb; 10405e00d31aSBartosz Markowski int len; 1041d7579d12SMichal Kazior u32 buf_len = msdu->len; 10425e00d31aSBartosz Markowski u16 fc; 10435e00d31aSBartosz Markowski 1044d7579d12SMichal Kazior hdr = (struct ieee80211_hdr *)msdu->data; 10455e00d31aSBartosz Markowski fc = le16_to_cpu(hdr->frame_control); 10465e00d31aSBartosz Markowski 10475e00d31aSBartosz Markowski if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) 1048d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 10495e00d31aSBartosz Markowski 1050d7579d12SMichal Kazior len = sizeof(cmd->hdr) + msdu->len; 1051eeab266cSMarek Kwaczynski 1052eeab266cSMarek Kwaczynski if ((ieee80211_is_action(hdr->frame_control) || 1053eeab266cSMarek Kwaczynski ieee80211_is_deauth(hdr->frame_control) || 1054eeab266cSMarek Kwaczynski ieee80211_is_disassoc(hdr->frame_control)) && 1055eeab266cSMarek Kwaczynski ieee80211_has_protected(hdr->frame_control)) { 1056eeab266cSMarek Kwaczynski len += IEEE80211_CCMP_MIC_LEN; 1057eeab266cSMarek Kwaczynski buf_len += IEEE80211_CCMP_MIC_LEN; 1058eeab266cSMarek Kwaczynski } 1059eeab266cSMarek Kwaczynski 10605e00d31aSBartosz Markowski len = round_up(len, 4); 10615e00d31aSBartosz Markowski 1062d7579d12SMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 1063d7579d12SMichal Kazior if (!skb) 1064d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 10655e00d31aSBartosz Markowski 1066d7579d12SMichal Kazior cmd = (struct wmi_mgmt_tx_cmd *)skb->data; 10675e00d31aSBartosz Markowski 1068d7579d12SMichal Kazior cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id); 10695e00d31aSBartosz Markowski cmd->hdr.tx_rate = 0; 10705e00d31aSBartosz Markowski cmd->hdr.tx_power = 0; 1071eeab266cSMarek Kwaczynski cmd->hdr.buf_len = __cpu_to_le32(buf_len); 10725e00d31aSBartosz Markowski 1073b25f32cbSKalle Valo ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr)); 1074d7579d12SMichal Kazior memcpy(cmd->buf, msdu->data, msdu->len); 10755e00d31aSBartosz Markowski 10767aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", 1077d7579d12SMichal Kazior msdu, skb->len, fc & IEEE80211_FCTL_FTYPE, 10785e00d31aSBartosz Markowski fc & IEEE80211_FCTL_STYPE); 10795ce8e7fdSRajkumar Manoharan trace_ath10k_tx_hdr(ar, skb->data, skb->len); 10805ce8e7fdSRajkumar Manoharan trace_ath10k_tx_payload(ar, skb->data, skb->len); 10815e00d31aSBartosz Markowski 1082d7579d12SMichal Kazior return skb; 10835e00d31aSBartosz Markowski } 10845e00d31aSBartosz Markowski 10855c81c7fdSMichal Kazior static void ath10k_wmi_event_scan_started(struct ath10k *ar) 10865c81c7fdSMichal Kazior { 10875c81c7fdSMichal Kazior lockdep_assert_held(&ar->data_lock); 10885c81c7fdSMichal Kazior 10895c81c7fdSMichal Kazior switch (ar->scan.state) { 10905c81c7fdSMichal Kazior case ATH10K_SCAN_IDLE: 10915c81c7fdSMichal Kazior case ATH10K_SCAN_RUNNING: 10925c81c7fdSMichal Kazior case ATH10K_SCAN_ABORTING: 10937aa7a72aSMichal Kazior ath10k_warn(ar, "received scan started event in an invalid scan state: %s (%d)\n", 10945c81c7fdSMichal Kazior ath10k_scan_state_str(ar->scan.state), 10955c81c7fdSMichal Kazior ar->scan.state); 10965c81c7fdSMichal Kazior break; 10975c81c7fdSMichal Kazior case ATH10K_SCAN_STARTING: 10985c81c7fdSMichal Kazior ar->scan.state = ATH10K_SCAN_RUNNING; 10995c81c7fdSMichal Kazior 11005c81c7fdSMichal Kazior if (ar->scan.is_roc) 11015c81c7fdSMichal Kazior ieee80211_ready_on_channel(ar->hw); 11025c81c7fdSMichal Kazior 11035c81c7fdSMichal Kazior complete(&ar->scan.started); 11045c81c7fdSMichal Kazior break; 11055c81c7fdSMichal Kazior } 11065c81c7fdSMichal Kazior } 11075c81c7fdSMichal Kazior 11085c81c7fdSMichal Kazior static void ath10k_wmi_event_scan_completed(struct ath10k *ar) 11095c81c7fdSMichal Kazior { 11105c81c7fdSMichal Kazior lockdep_assert_held(&ar->data_lock); 11115c81c7fdSMichal Kazior 11125c81c7fdSMichal Kazior switch (ar->scan.state) { 11135c81c7fdSMichal Kazior case ATH10K_SCAN_IDLE: 11145c81c7fdSMichal Kazior case ATH10K_SCAN_STARTING: 11155c81c7fdSMichal Kazior /* One suspected reason scan can be completed while starting is 11165c81c7fdSMichal Kazior * if firmware fails to deliver all scan events to the host, 11175c81c7fdSMichal Kazior * e.g. when transport pipe is full. This has been observed 11185c81c7fdSMichal Kazior * with spectral scan phyerr events starving wmi transport 11195c81c7fdSMichal Kazior * pipe. In such case the "scan completed" event should be (and 11205c81c7fdSMichal Kazior * is) ignored by the host as it may be just firmware's scan 11215c81c7fdSMichal Kazior * state machine recovering. 11225c81c7fdSMichal Kazior */ 11237aa7a72aSMichal Kazior ath10k_warn(ar, "received scan completed event in an invalid scan state: %s (%d)\n", 11245c81c7fdSMichal Kazior ath10k_scan_state_str(ar->scan.state), 11255c81c7fdSMichal Kazior ar->scan.state); 11265c81c7fdSMichal Kazior break; 11275c81c7fdSMichal Kazior case ATH10K_SCAN_RUNNING: 11285c81c7fdSMichal Kazior case ATH10K_SCAN_ABORTING: 11295c81c7fdSMichal Kazior __ath10k_scan_finish(ar); 11305c81c7fdSMichal Kazior break; 11315c81c7fdSMichal Kazior } 11325c81c7fdSMichal Kazior } 11335c81c7fdSMichal Kazior 11345c81c7fdSMichal Kazior static void ath10k_wmi_event_scan_bss_chan(struct ath10k *ar) 11355c81c7fdSMichal Kazior { 11365c81c7fdSMichal Kazior lockdep_assert_held(&ar->data_lock); 11375c81c7fdSMichal Kazior 11385c81c7fdSMichal Kazior switch (ar->scan.state) { 11395c81c7fdSMichal Kazior case ATH10K_SCAN_IDLE: 11405c81c7fdSMichal Kazior case ATH10K_SCAN_STARTING: 11417aa7a72aSMichal Kazior ath10k_warn(ar, "received scan bss chan event in an invalid scan state: %s (%d)\n", 11425c81c7fdSMichal Kazior ath10k_scan_state_str(ar->scan.state), 11435c81c7fdSMichal Kazior ar->scan.state); 11445c81c7fdSMichal Kazior break; 11455c81c7fdSMichal Kazior case ATH10K_SCAN_RUNNING: 11465c81c7fdSMichal Kazior case ATH10K_SCAN_ABORTING: 11475c81c7fdSMichal Kazior ar->scan_channel = NULL; 11485c81c7fdSMichal Kazior break; 11495c81c7fdSMichal Kazior } 11505c81c7fdSMichal Kazior } 11515c81c7fdSMichal Kazior 11525c81c7fdSMichal Kazior static void ath10k_wmi_event_scan_foreign_chan(struct ath10k *ar, u32 freq) 11535c81c7fdSMichal Kazior { 11545c81c7fdSMichal Kazior lockdep_assert_held(&ar->data_lock); 11555c81c7fdSMichal Kazior 11565c81c7fdSMichal Kazior switch (ar->scan.state) { 11575c81c7fdSMichal Kazior case ATH10K_SCAN_IDLE: 11585c81c7fdSMichal Kazior case ATH10K_SCAN_STARTING: 11597aa7a72aSMichal Kazior ath10k_warn(ar, "received scan foreign chan event in an invalid scan state: %s (%d)\n", 11605c81c7fdSMichal Kazior ath10k_scan_state_str(ar->scan.state), 11615c81c7fdSMichal Kazior ar->scan.state); 11625c81c7fdSMichal Kazior break; 11635c81c7fdSMichal Kazior case ATH10K_SCAN_RUNNING: 11645c81c7fdSMichal Kazior case ATH10K_SCAN_ABORTING: 11655c81c7fdSMichal Kazior ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); 11665c81c7fdSMichal Kazior 11675c81c7fdSMichal Kazior if (ar->scan.is_roc && ar->scan.roc_freq == freq) 11685c81c7fdSMichal Kazior complete(&ar->scan.on_channel); 11695c81c7fdSMichal Kazior break; 11705c81c7fdSMichal Kazior } 11715c81c7fdSMichal Kazior } 11725c81c7fdSMichal Kazior 11739ff8b724SMichal Kazior static const char * 11749ff8b724SMichal Kazior ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, 11759ff8b724SMichal Kazior enum wmi_scan_completion_reason reason) 11769ff8b724SMichal Kazior { 11779ff8b724SMichal Kazior switch (type) { 11789ff8b724SMichal Kazior case WMI_SCAN_EVENT_STARTED: 11799ff8b724SMichal Kazior return "started"; 11809ff8b724SMichal Kazior case WMI_SCAN_EVENT_COMPLETED: 11819ff8b724SMichal Kazior switch (reason) { 11829ff8b724SMichal Kazior case WMI_SCAN_REASON_COMPLETED: 11839ff8b724SMichal Kazior return "completed"; 11849ff8b724SMichal Kazior case WMI_SCAN_REASON_CANCELLED: 11859ff8b724SMichal Kazior return "completed [cancelled]"; 11869ff8b724SMichal Kazior case WMI_SCAN_REASON_PREEMPTED: 11879ff8b724SMichal Kazior return "completed [preempted]"; 11889ff8b724SMichal Kazior case WMI_SCAN_REASON_TIMEDOUT: 11899ff8b724SMichal Kazior return "completed [timedout]"; 11909ff8b724SMichal Kazior case WMI_SCAN_REASON_MAX: 11919ff8b724SMichal Kazior break; 11929ff8b724SMichal Kazior } 11939ff8b724SMichal Kazior return "completed [unknown]"; 11949ff8b724SMichal Kazior case WMI_SCAN_EVENT_BSS_CHANNEL: 11959ff8b724SMichal Kazior return "bss channel"; 11969ff8b724SMichal Kazior case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 11979ff8b724SMichal Kazior return "foreign channel"; 11989ff8b724SMichal Kazior case WMI_SCAN_EVENT_DEQUEUED: 11999ff8b724SMichal Kazior return "dequeued"; 12009ff8b724SMichal Kazior case WMI_SCAN_EVENT_PREEMPTED: 12019ff8b724SMichal Kazior return "preempted"; 12029ff8b724SMichal Kazior case WMI_SCAN_EVENT_START_FAILED: 12039ff8b724SMichal Kazior return "start failed"; 12049ff8b724SMichal Kazior default: 12059ff8b724SMichal Kazior return "unknown"; 12069ff8b724SMichal Kazior } 12079ff8b724SMichal Kazior } 12089ff8b724SMichal Kazior 1209d7579d12SMichal Kazior static int ath10k_wmi_op_pull_scan_ev(struct ath10k *ar, struct sk_buff *skb, 121032653cf1SMichal Kazior struct wmi_scan_ev_arg *arg) 121132653cf1SMichal Kazior { 121232653cf1SMichal Kazior struct wmi_scan_event *ev = (void *)skb->data; 121332653cf1SMichal Kazior 121432653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 121532653cf1SMichal Kazior return -EPROTO; 121632653cf1SMichal Kazior 121732653cf1SMichal Kazior skb_pull(skb, sizeof(*ev)); 121832653cf1SMichal Kazior arg->event_type = ev->event_type; 121932653cf1SMichal Kazior arg->reason = ev->reason; 122032653cf1SMichal Kazior arg->channel_freq = ev->channel_freq; 122132653cf1SMichal Kazior arg->scan_req_id = ev->scan_req_id; 122232653cf1SMichal Kazior arg->scan_id = ev->scan_id; 122332653cf1SMichal Kazior arg->vdev_id = ev->vdev_id; 122432653cf1SMichal Kazior 122532653cf1SMichal Kazior return 0; 122632653cf1SMichal Kazior } 122732653cf1SMichal Kazior 12280226d602SMichal Kazior int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) 12295e3dd157SKalle Valo { 123032653cf1SMichal Kazior struct wmi_scan_ev_arg arg = {}; 12315e3dd157SKalle Valo enum wmi_scan_event_type event_type; 12325e3dd157SKalle Valo enum wmi_scan_completion_reason reason; 12335e3dd157SKalle Valo u32 freq; 12345e3dd157SKalle Valo u32 req_id; 12355e3dd157SKalle Valo u32 scan_id; 12365e3dd157SKalle Valo u32 vdev_id; 123732653cf1SMichal Kazior int ret; 12385e3dd157SKalle Valo 1239d7579d12SMichal Kazior ret = ath10k_wmi_pull_scan(ar, skb, &arg); 124032653cf1SMichal Kazior if (ret) { 124132653cf1SMichal Kazior ath10k_warn(ar, "failed to parse scan event: %d\n", ret); 124232653cf1SMichal Kazior return ret; 124332653cf1SMichal Kazior } 124432653cf1SMichal Kazior 124532653cf1SMichal Kazior event_type = __le32_to_cpu(arg.event_type); 124632653cf1SMichal Kazior reason = __le32_to_cpu(arg.reason); 124732653cf1SMichal Kazior freq = __le32_to_cpu(arg.channel_freq); 124832653cf1SMichal Kazior req_id = __le32_to_cpu(arg.scan_req_id); 124932653cf1SMichal Kazior scan_id = __le32_to_cpu(arg.scan_id); 125032653cf1SMichal Kazior vdev_id = __le32_to_cpu(arg.vdev_id); 12515e3dd157SKalle Valo 12525e3dd157SKalle Valo spin_lock_bh(&ar->data_lock); 12535e3dd157SKalle Valo 12547aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 12555c81c7fdSMichal Kazior "scan event %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n", 12565c81c7fdSMichal Kazior ath10k_wmi_event_scan_type_str(event_type, reason), 12575c81c7fdSMichal Kazior event_type, reason, freq, req_id, scan_id, vdev_id, 12585c81c7fdSMichal Kazior ath10k_scan_state_str(ar->scan.state), ar->scan.state); 12595c81c7fdSMichal Kazior 12605e3dd157SKalle Valo switch (event_type) { 12615e3dd157SKalle Valo case WMI_SCAN_EVENT_STARTED: 12625c81c7fdSMichal Kazior ath10k_wmi_event_scan_started(ar); 12635e3dd157SKalle Valo break; 12645e3dd157SKalle Valo case WMI_SCAN_EVENT_COMPLETED: 12655c81c7fdSMichal Kazior ath10k_wmi_event_scan_completed(ar); 12665e3dd157SKalle Valo break; 12675e3dd157SKalle Valo case WMI_SCAN_EVENT_BSS_CHANNEL: 12685c81c7fdSMichal Kazior ath10k_wmi_event_scan_bss_chan(ar); 12695e3dd157SKalle Valo break; 12705e3dd157SKalle Valo case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 12715c81c7fdSMichal Kazior ath10k_wmi_event_scan_foreign_chan(ar, freq); 12725c81c7fdSMichal Kazior break; 12735c81c7fdSMichal Kazior case WMI_SCAN_EVENT_START_FAILED: 12747aa7a72aSMichal Kazior ath10k_warn(ar, "received scan start failure event\n"); 12755e3dd157SKalle Valo break; 12765e3dd157SKalle Valo case WMI_SCAN_EVENT_DEQUEUED: 12775e3dd157SKalle Valo case WMI_SCAN_EVENT_PREEMPTED: 12785e3dd157SKalle Valo default: 12795e3dd157SKalle Valo break; 12805e3dd157SKalle Valo } 12815e3dd157SKalle Valo 12825e3dd157SKalle Valo spin_unlock_bh(&ar->data_lock); 12835e3dd157SKalle Valo return 0; 12845e3dd157SKalle Valo } 12855e3dd157SKalle Valo 12865e3dd157SKalle Valo static inline enum ieee80211_band phy_mode_to_band(u32 phy_mode) 12875e3dd157SKalle Valo { 12885e3dd157SKalle Valo enum ieee80211_band band; 12895e3dd157SKalle Valo 12905e3dd157SKalle Valo switch (phy_mode) { 12915e3dd157SKalle Valo case MODE_11A: 12925e3dd157SKalle Valo case MODE_11NA_HT20: 12935e3dd157SKalle Valo case MODE_11NA_HT40: 12945e3dd157SKalle Valo case MODE_11AC_VHT20: 12955e3dd157SKalle Valo case MODE_11AC_VHT40: 12965e3dd157SKalle Valo case MODE_11AC_VHT80: 12975e3dd157SKalle Valo band = IEEE80211_BAND_5GHZ; 12985e3dd157SKalle Valo break; 12995e3dd157SKalle Valo case MODE_11G: 13005e3dd157SKalle Valo case MODE_11B: 13015e3dd157SKalle Valo case MODE_11GONLY: 13025e3dd157SKalle Valo case MODE_11NG_HT20: 13035e3dd157SKalle Valo case MODE_11NG_HT40: 13045e3dd157SKalle Valo case MODE_11AC_VHT20_2G: 13055e3dd157SKalle Valo case MODE_11AC_VHT40_2G: 13065e3dd157SKalle Valo case MODE_11AC_VHT80_2G: 13075e3dd157SKalle Valo default: 13085e3dd157SKalle Valo band = IEEE80211_BAND_2GHZ; 13095e3dd157SKalle Valo } 13105e3dd157SKalle Valo 13115e3dd157SKalle Valo return band; 13125e3dd157SKalle Valo } 13135e3dd157SKalle Valo 13145e3dd157SKalle Valo static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band) 13155e3dd157SKalle Valo { 13165e3dd157SKalle Valo u8 rate_idx = 0; 13175e3dd157SKalle Valo 13185e3dd157SKalle Valo /* rate in Kbps */ 13195e3dd157SKalle Valo switch (rate) { 13205e3dd157SKalle Valo case 1000: 13215e3dd157SKalle Valo rate_idx = 0; 13225e3dd157SKalle Valo break; 13235e3dd157SKalle Valo case 2000: 13245e3dd157SKalle Valo rate_idx = 1; 13255e3dd157SKalle Valo break; 13265e3dd157SKalle Valo case 5500: 13275e3dd157SKalle Valo rate_idx = 2; 13285e3dd157SKalle Valo break; 13295e3dd157SKalle Valo case 11000: 13305e3dd157SKalle Valo rate_idx = 3; 13315e3dd157SKalle Valo break; 13325e3dd157SKalle Valo case 6000: 13335e3dd157SKalle Valo rate_idx = 4; 13345e3dd157SKalle Valo break; 13355e3dd157SKalle Valo case 9000: 13365e3dd157SKalle Valo rate_idx = 5; 13375e3dd157SKalle Valo break; 13385e3dd157SKalle Valo case 12000: 13395e3dd157SKalle Valo rate_idx = 6; 13405e3dd157SKalle Valo break; 13415e3dd157SKalle Valo case 18000: 13425e3dd157SKalle Valo rate_idx = 7; 13435e3dd157SKalle Valo break; 13445e3dd157SKalle Valo case 24000: 13455e3dd157SKalle Valo rate_idx = 8; 13465e3dd157SKalle Valo break; 13475e3dd157SKalle Valo case 36000: 13485e3dd157SKalle Valo rate_idx = 9; 13495e3dd157SKalle Valo break; 13505e3dd157SKalle Valo case 48000: 13515e3dd157SKalle Valo rate_idx = 10; 13525e3dd157SKalle Valo break; 13535e3dd157SKalle Valo case 54000: 13545e3dd157SKalle Valo rate_idx = 11; 13555e3dd157SKalle Valo break; 13565e3dd157SKalle Valo default: 13575e3dd157SKalle Valo break; 13585e3dd157SKalle Valo } 13595e3dd157SKalle Valo 13605e3dd157SKalle Valo if (band == IEEE80211_BAND_5GHZ) { 13615e3dd157SKalle Valo if (rate_idx > 3) 13625e3dd157SKalle Valo /* Omit CCK rates */ 13635e3dd157SKalle Valo rate_idx -= 4; 13645e3dd157SKalle Valo else 13655e3dd157SKalle Valo rate_idx = 0; 13665e3dd157SKalle Valo } 13675e3dd157SKalle Valo 13685e3dd157SKalle Valo return rate_idx; 13695e3dd157SKalle Valo } 13705e3dd157SKalle Valo 1371504f6cdfSSujith Manoharan /* If keys are configured, HW decrypts all frames 1372504f6cdfSSujith Manoharan * with protected bit set. Mark such frames as decrypted. 1373504f6cdfSSujith Manoharan */ 1374504f6cdfSSujith Manoharan static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar, 1375504f6cdfSSujith Manoharan struct sk_buff *skb, 1376504f6cdfSSujith Manoharan struct ieee80211_rx_status *status) 1377504f6cdfSSujith Manoharan { 1378504f6cdfSSujith Manoharan struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1379504f6cdfSSujith Manoharan unsigned int hdrlen; 1380504f6cdfSSujith Manoharan bool peer_key; 1381504f6cdfSSujith Manoharan u8 *addr, keyidx; 1382504f6cdfSSujith Manoharan 1383504f6cdfSSujith Manoharan if (!ieee80211_is_auth(hdr->frame_control) || 1384504f6cdfSSujith Manoharan !ieee80211_has_protected(hdr->frame_control)) 1385504f6cdfSSujith Manoharan return; 1386504f6cdfSSujith Manoharan 1387504f6cdfSSujith Manoharan hdrlen = ieee80211_hdrlen(hdr->frame_control); 1388504f6cdfSSujith Manoharan if (skb->len < (hdrlen + IEEE80211_WEP_IV_LEN)) 1389504f6cdfSSujith Manoharan return; 1390504f6cdfSSujith Manoharan 1391504f6cdfSSujith Manoharan keyidx = skb->data[hdrlen + (IEEE80211_WEP_IV_LEN - 1)] >> WEP_KEYID_SHIFT; 1392504f6cdfSSujith Manoharan addr = ieee80211_get_SA(hdr); 1393504f6cdfSSujith Manoharan 1394504f6cdfSSujith Manoharan spin_lock_bh(&ar->data_lock); 1395504f6cdfSSujith Manoharan peer_key = ath10k_mac_is_peer_wep_key_set(ar, addr, keyidx); 1396504f6cdfSSujith Manoharan spin_unlock_bh(&ar->data_lock); 1397504f6cdfSSujith Manoharan 1398504f6cdfSSujith Manoharan if (peer_key) { 1399504f6cdfSSujith Manoharan ath10k_dbg(ar, ATH10K_DBG_MAC, 1400504f6cdfSSujith Manoharan "mac wep key present for peer %pM\n", addr); 1401504f6cdfSSujith Manoharan status->flag |= RX_FLAG_DECRYPTED; 1402504f6cdfSSujith Manoharan } 1403504f6cdfSSujith Manoharan } 1404504f6cdfSSujith Manoharan 1405d7579d12SMichal Kazior static int ath10k_wmi_op_pull_mgmt_rx_ev(struct ath10k *ar, struct sk_buff *skb, 1406d7579d12SMichal Kazior struct wmi_mgmt_rx_ev_arg *arg) 14075e3dd157SKalle Valo { 14080d9b0438SMichal Kazior struct wmi_mgmt_rx_event_v1 *ev_v1; 14090d9b0438SMichal Kazior struct wmi_mgmt_rx_event_v2 *ev_v2; 14100d9b0438SMichal Kazior struct wmi_mgmt_rx_hdr_v1 *ev_hdr; 141132653cf1SMichal Kazior size_t pull_len; 141232653cf1SMichal Kazior u32 msdu_len; 14135e3dd157SKalle Valo 14140d9b0438SMichal Kazior if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { 14150d9b0438SMichal Kazior ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; 14160d9b0438SMichal Kazior ev_hdr = &ev_v2->hdr.v1; 14170d9b0438SMichal Kazior pull_len = sizeof(*ev_v2); 14180d9b0438SMichal Kazior } else { 14190d9b0438SMichal Kazior ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data; 14200d9b0438SMichal Kazior ev_hdr = &ev_v1->hdr; 14210d9b0438SMichal Kazior pull_len = sizeof(*ev_v1); 14220d9b0438SMichal Kazior } 14230d9b0438SMichal Kazior 142432653cf1SMichal Kazior if (skb->len < pull_len) 142532653cf1SMichal Kazior return -EPROTO; 142632653cf1SMichal Kazior 142732653cf1SMichal Kazior skb_pull(skb, pull_len); 142832653cf1SMichal Kazior arg->channel = ev_hdr->channel; 142932653cf1SMichal Kazior arg->buf_len = ev_hdr->buf_len; 143032653cf1SMichal Kazior arg->status = ev_hdr->status; 143132653cf1SMichal Kazior arg->snr = ev_hdr->snr; 143232653cf1SMichal Kazior arg->phy_mode = ev_hdr->phy_mode; 143332653cf1SMichal Kazior arg->rate = ev_hdr->rate; 143432653cf1SMichal Kazior 143532653cf1SMichal Kazior msdu_len = __le32_to_cpu(arg->buf_len); 143632653cf1SMichal Kazior if (skb->len < msdu_len) 143732653cf1SMichal Kazior return -EPROTO; 143832653cf1SMichal Kazior 143932653cf1SMichal Kazior /* the WMI buffer might've ended up being padded to 4 bytes due to HTC 144032653cf1SMichal Kazior * trailer with credit update. Trim the excess garbage. 144132653cf1SMichal Kazior */ 144232653cf1SMichal Kazior skb_trim(skb, msdu_len); 144332653cf1SMichal Kazior 144432653cf1SMichal Kazior return 0; 144532653cf1SMichal Kazior } 144632653cf1SMichal Kazior 14470226d602SMichal Kazior int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) 144832653cf1SMichal Kazior { 144932653cf1SMichal Kazior struct wmi_mgmt_rx_ev_arg arg = {}; 145032653cf1SMichal Kazior struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 145132653cf1SMichal Kazior struct ieee80211_hdr *hdr; 145232653cf1SMichal Kazior u32 rx_status; 145332653cf1SMichal Kazior u32 channel; 145432653cf1SMichal Kazior u32 phy_mode; 145532653cf1SMichal Kazior u32 snr; 145632653cf1SMichal Kazior u32 rate; 145732653cf1SMichal Kazior u32 buf_len; 145832653cf1SMichal Kazior u16 fc; 145932653cf1SMichal Kazior int ret; 146032653cf1SMichal Kazior 1461d7579d12SMichal Kazior ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg); 146232653cf1SMichal Kazior if (ret) { 146332653cf1SMichal Kazior ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret); 146432653cf1SMichal Kazior return ret; 146532653cf1SMichal Kazior } 146632653cf1SMichal Kazior 146732653cf1SMichal Kazior channel = __le32_to_cpu(arg.channel); 146832653cf1SMichal Kazior buf_len = __le32_to_cpu(arg.buf_len); 146932653cf1SMichal Kazior rx_status = __le32_to_cpu(arg.status); 147032653cf1SMichal Kazior snr = __le32_to_cpu(arg.snr); 147132653cf1SMichal Kazior phy_mode = __le32_to_cpu(arg.phy_mode); 147232653cf1SMichal Kazior rate = __le32_to_cpu(arg.rate); 14735e3dd157SKalle Valo 14745e3dd157SKalle Valo memset(status, 0, sizeof(*status)); 14755e3dd157SKalle Valo 14767aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, 14775e3dd157SKalle Valo "event mgmt rx status %08x\n", rx_status); 14785e3dd157SKalle Valo 1479e8a50f8bSMarek Puzyniak if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { 1480e8a50f8bSMarek Puzyniak dev_kfree_skb(skb); 1481e8a50f8bSMarek Puzyniak return 0; 1482e8a50f8bSMarek Puzyniak } 1483e8a50f8bSMarek Puzyniak 14845e3dd157SKalle Valo if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) { 14855e3dd157SKalle Valo dev_kfree_skb(skb); 14865e3dd157SKalle Valo return 0; 14875e3dd157SKalle Valo } 14885e3dd157SKalle Valo 14895e3dd157SKalle Valo if (rx_status & WMI_RX_STATUS_ERR_KEY_CACHE_MISS) { 14905e3dd157SKalle Valo dev_kfree_skb(skb); 14915e3dd157SKalle Valo return 0; 14925e3dd157SKalle Valo } 14935e3dd157SKalle Valo 1494d67d0a02SMichal Kazior if (rx_status & WMI_RX_STATUS_ERR_CRC) { 1495d67d0a02SMichal Kazior dev_kfree_skb(skb); 1496d67d0a02SMichal Kazior return 0; 1497d67d0a02SMichal Kazior } 1498d67d0a02SMichal Kazior 14995e3dd157SKalle Valo if (rx_status & WMI_RX_STATUS_ERR_MIC) 15005e3dd157SKalle Valo status->flag |= RX_FLAG_MMIC_ERROR; 15015e3dd157SKalle Valo 150221040bf9SMichal Kazior /* Hardware can Rx CCK rates on 5GHz. In that case phy_mode is set to 1503453cdb61SMichal Kazior * MODE_11B. This means phy_mode is not a reliable source for the band 150421040bf9SMichal Kazior * of mgmt rx. 150521040bf9SMichal Kazior */ 150621040bf9SMichal Kazior if (channel >= 1 && channel <= 14) { 150721040bf9SMichal Kazior status->band = IEEE80211_BAND_2GHZ; 150821040bf9SMichal Kazior } else if (channel >= 36 && channel <= 165) { 150921040bf9SMichal Kazior status->band = IEEE80211_BAND_5GHZ; 1510453cdb61SMichal Kazior } else { 151121040bf9SMichal Kazior /* Shouldn't happen unless list of advertised channels to 151221040bf9SMichal Kazior * mac80211 has been changed. 151321040bf9SMichal Kazior */ 151421040bf9SMichal Kazior WARN_ON_ONCE(1); 151521040bf9SMichal Kazior dev_kfree_skb(skb); 151621040bf9SMichal Kazior return 0; 1517453cdb61SMichal Kazior } 1518453cdb61SMichal Kazior 151921040bf9SMichal Kazior if (phy_mode == MODE_11B && status->band == IEEE80211_BAND_5GHZ) 152021040bf9SMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); 152121040bf9SMichal Kazior 15225e3dd157SKalle Valo status->freq = ieee80211_channel_to_frequency(channel, status->band); 15235e3dd157SKalle Valo status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; 15245e3dd157SKalle Valo status->rate_idx = get_rate_idx(rate, status->band); 15255e3dd157SKalle Valo 15265e3dd157SKalle Valo hdr = (struct ieee80211_hdr *)skb->data; 15275e3dd157SKalle Valo fc = le16_to_cpu(hdr->frame_control); 15285e3dd157SKalle Valo 1529504f6cdfSSujith Manoharan ath10k_wmi_handle_wep_reauth(ar, skb, status); 1530504f6cdfSSujith Manoharan 15312b6a6a90SMichal Kazior /* FW delivers WEP Shared Auth frame with Protected Bit set and 15322b6a6a90SMichal Kazior * encrypted payload. However in case of PMF it delivers decrypted 15332b6a6a90SMichal Kazior * frames with Protected Bit set. */ 15342b6a6a90SMichal Kazior if (ieee80211_has_protected(hdr->frame_control) && 15352b6a6a90SMichal Kazior !ieee80211_is_auth(hdr->frame_control)) { 1536eeab266cSMarek Kwaczynski status->flag |= RX_FLAG_DECRYPTED; 1537eeab266cSMarek Kwaczynski 1538eeab266cSMarek Kwaczynski if (!ieee80211_is_action(hdr->frame_control) && 1539eeab266cSMarek Kwaczynski !ieee80211_is_deauth(hdr->frame_control) && 1540eeab266cSMarek Kwaczynski !ieee80211_is_disassoc(hdr->frame_control)) { 1541eeab266cSMarek Kwaczynski status->flag |= RX_FLAG_IV_STRIPPED | 15425e3dd157SKalle Valo RX_FLAG_MMIC_STRIPPED; 15435e3dd157SKalle Valo hdr->frame_control = __cpu_to_le16(fc & 15445e3dd157SKalle Valo ~IEEE80211_FCTL_PROTECTED); 15455e3dd157SKalle Valo } 1546eeab266cSMarek Kwaczynski } 15475e3dd157SKalle Valo 15487aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, 15495e3dd157SKalle Valo "event mgmt rx skb %p len %d ftype %02x stype %02x\n", 15505e3dd157SKalle Valo skb, skb->len, 15515e3dd157SKalle Valo fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); 15525e3dd157SKalle Valo 15537aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, 15545e3dd157SKalle Valo "event mgmt rx freq %d band %d snr %d, rate_idx %d\n", 15555e3dd157SKalle Valo status->freq, status->band, status->signal, 15565e3dd157SKalle Valo status->rate_idx); 15575e3dd157SKalle Valo 15585e3dd157SKalle Valo ieee80211_rx(ar->hw, skb); 15595e3dd157SKalle Valo return 0; 15605e3dd157SKalle Valo } 15615e3dd157SKalle Valo 15622e1dea40SMichal Kazior static int freq_to_idx(struct ath10k *ar, int freq) 15632e1dea40SMichal Kazior { 15642e1dea40SMichal Kazior struct ieee80211_supported_band *sband; 15652e1dea40SMichal Kazior int band, ch, idx = 0; 15662e1dea40SMichal Kazior 15672e1dea40SMichal Kazior for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 15682e1dea40SMichal Kazior sband = ar->hw->wiphy->bands[band]; 15692e1dea40SMichal Kazior if (!sband) 15702e1dea40SMichal Kazior continue; 15712e1dea40SMichal Kazior 15722e1dea40SMichal Kazior for (ch = 0; ch < sband->n_channels; ch++, idx++) 15732e1dea40SMichal Kazior if (sband->channels[ch].center_freq == freq) 15742e1dea40SMichal Kazior goto exit; 15752e1dea40SMichal Kazior } 15762e1dea40SMichal Kazior 15772e1dea40SMichal Kazior exit: 15782e1dea40SMichal Kazior return idx; 15792e1dea40SMichal Kazior } 15802e1dea40SMichal Kazior 1581d7579d12SMichal Kazior static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb, 158232653cf1SMichal Kazior struct wmi_ch_info_ev_arg *arg) 158332653cf1SMichal Kazior { 158432653cf1SMichal Kazior struct wmi_chan_info_event *ev = (void *)skb->data; 158532653cf1SMichal Kazior 158632653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 158732653cf1SMichal Kazior return -EPROTO; 158832653cf1SMichal Kazior 158932653cf1SMichal Kazior skb_pull(skb, sizeof(*ev)); 159032653cf1SMichal Kazior arg->err_code = ev->err_code; 159132653cf1SMichal Kazior arg->freq = ev->freq; 159232653cf1SMichal Kazior arg->cmd_flags = ev->cmd_flags; 159332653cf1SMichal Kazior arg->noise_floor = ev->noise_floor; 159432653cf1SMichal Kazior arg->rx_clear_count = ev->rx_clear_count; 159532653cf1SMichal Kazior arg->cycle_count = ev->cycle_count; 159632653cf1SMichal Kazior 159732653cf1SMichal Kazior return 0; 159832653cf1SMichal Kazior } 159932653cf1SMichal Kazior 16000226d602SMichal Kazior void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) 16015e3dd157SKalle Valo { 160232653cf1SMichal Kazior struct wmi_ch_info_ev_arg arg = {}; 16032e1dea40SMichal Kazior struct survey_info *survey; 16042e1dea40SMichal Kazior u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count; 160532653cf1SMichal Kazior int idx, ret; 16062e1dea40SMichal Kazior 1607d7579d12SMichal Kazior ret = ath10k_wmi_pull_ch_info(ar, skb, &arg); 160832653cf1SMichal Kazior if (ret) { 160932653cf1SMichal Kazior ath10k_warn(ar, "failed to parse chan info event: %d\n", ret); 161032653cf1SMichal Kazior return; 161132653cf1SMichal Kazior } 16122e1dea40SMichal Kazior 161332653cf1SMichal Kazior err_code = __le32_to_cpu(arg.err_code); 161432653cf1SMichal Kazior freq = __le32_to_cpu(arg.freq); 161532653cf1SMichal Kazior cmd_flags = __le32_to_cpu(arg.cmd_flags); 161632653cf1SMichal Kazior noise_floor = __le32_to_cpu(arg.noise_floor); 161732653cf1SMichal Kazior rx_clear_count = __le32_to_cpu(arg.rx_clear_count); 161832653cf1SMichal Kazior cycle_count = __le32_to_cpu(arg.cycle_count); 16192e1dea40SMichal Kazior 16207aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 16212e1dea40SMichal Kazior "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n", 16222e1dea40SMichal Kazior err_code, freq, cmd_flags, noise_floor, rx_clear_count, 16232e1dea40SMichal Kazior cycle_count); 16242e1dea40SMichal Kazior 16252e1dea40SMichal Kazior spin_lock_bh(&ar->data_lock); 16262e1dea40SMichal Kazior 16275c81c7fdSMichal Kazior switch (ar->scan.state) { 16285c81c7fdSMichal Kazior case ATH10K_SCAN_IDLE: 16295c81c7fdSMichal Kazior case ATH10K_SCAN_STARTING: 16307aa7a72aSMichal Kazior ath10k_warn(ar, "received chan info event without a scan request, ignoring\n"); 16312e1dea40SMichal Kazior goto exit; 16325c81c7fdSMichal Kazior case ATH10K_SCAN_RUNNING: 16335c81c7fdSMichal Kazior case ATH10K_SCAN_ABORTING: 16345c81c7fdSMichal Kazior break; 16352e1dea40SMichal Kazior } 16362e1dea40SMichal Kazior 16372e1dea40SMichal Kazior idx = freq_to_idx(ar, freq); 16382e1dea40SMichal Kazior if (idx >= ARRAY_SIZE(ar->survey)) { 16397aa7a72aSMichal Kazior ath10k_warn(ar, "chan info: invalid frequency %d (idx %d out of bounds)\n", 16402e1dea40SMichal Kazior freq, idx); 16412e1dea40SMichal Kazior goto exit; 16422e1dea40SMichal Kazior } 16432e1dea40SMichal Kazior 16442e1dea40SMichal Kazior if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) { 16452e1dea40SMichal Kazior /* During scanning chan info is reported twice for each 16462e1dea40SMichal Kazior * visited channel. The reported cycle count is global 16472e1dea40SMichal Kazior * and per-channel cycle count must be calculated */ 16482e1dea40SMichal Kazior 16492e1dea40SMichal Kazior cycle_count -= ar->survey_last_cycle_count; 16502e1dea40SMichal Kazior rx_clear_count -= ar->survey_last_rx_clear_count; 16512e1dea40SMichal Kazior 16522e1dea40SMichal Kazior survey = &ar->survey[idx]; 16532e1dea40SMichal Kazior survey->channel_time = WMI_CHAN_INFO_MSEC(cycle_count); 16542e1dea40SMichal Kazior survey->channel_time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count); 16552e1dea40SMichal Kazior survey->noise = noise_floor; 16562e1dea40SMichal Kazior survey->filled = SURVEY_INFO_CHANNEL_TIME | 16572e1dea40SMichal Kazior SURVEY_INFO_CHANNEL_TIME_RX | 16582e1dea40SMichal Kazior SURVEY_INFO_NOISE_DBM; 16592e1dea40SMichal Kazior } 16602e1dea40SMichal Kazior 16612e1dea40SMichal Kazior ar->survey_last_rx_clear_count = rx_clear_count; 16622e1dea40SMichal Kazior ar->survey_last_cycle_count = cycle_count; 16632e1dea40SMichal Kazior 16642e1dea40SMichal Kazior exit: 16652e1dea40SMichal Kazior spin_unlock_bh(&ar->data_lock); 16665e3dd157SKalle Valo } 16675e3dd157SKalle Valo 16680226d602SMichal Kazior void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) 16695e3dd157SKalle Valo { 16707aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); 16715e3dd157SKalle Valo } 16725e3dd157SKalle Valo 16730226d602SMichal Kazior int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) 16745e3dd157SKalle Valo { 16757aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", 1676869526b9SKalle Valo skb->len); 1677869526b9SKalle Valo 1678d35a6c18SMichal Kazior trace_ath10k_wmi_dbglog(ar, skb->data, skb->len); 1679869526b9SKalle Valo 1680869526b9SKalle Valo return 0; 16815e3dd157SKalle Valo } 16825e3dd157SKalle Valo 16830226d602SMichal Kazior void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, 16845326849aSMichal Kazior struct ath10k_fw_stats_pdev *dst) 1685d15fb520SMichal Kazior { 1686d15fb520SMichal Kazior const struct wal_dbg_tx_stats *tx = &src->wal.tx; 1687d15fb520SMichal Kazior const struct wal_dbg_rx_stats *rx = &src->wal.rx; 1688d15fb520SMichal Kazior 1689d15fb520SMichal Kazior dst->ch_noise_floor = __le32_to_cpu(src->chan_nf); 1690d15fb520SMichal Kazior dst->tx_frame_count = __le32_to_cpu(src->tx_frame_count); 1691d15fb520SMichal Kazior dst->rx_frame_count = __le32_to_cpu(src->rx_frame_count); 1692d15fb520SMichal Kazior dst->rx_clear_count = __le32_to_cpu(src->rx_clear_count); 1693d15fb520SMichal Kazior dst->cycle_count = __le32_to_cpu(src->cycle_count); 1694d15fb520SMichal Kazior dst->phy_err_count = __le32_to_cpu(src->phy_err_count); 1695d15fb520SMichal Kazior dst->chan_tx_power = __le32_to_cpu(src->chan_tx_pwr); 1696d15fb520SMichal Kazior 1697d15fb520SMichal Kazior dst->comp_queued = __le32_to_cpu(tx->comp_queued); 1698d15fb520SMichal Kazior dst->comp_delivered = __le32_to_cpu(tx->comp_delivered); 1699d15fb520SMichal Kazior dst->msdu_enqued = __le32_to_cpu(tx->msdu_enqued); 1700d15fb520SMichal Kazior dst->mpdu_enqued = __le32_to_cpu(tx->mpdu_enqued); 1701d15fb520SMichal Kazior dst->wmm_drop = __le32_to_cpu(tx->wmm_drop); 1702d15fb520SMichal Kazior dst->local_enqued = __le32_to_cpu(tx->local_enqued); 1703d15fb520SMichal Kazior dst->local_freed = __le32_to_cpu(tx->local_freed); 1704d15fb520SMichal Kazior dst->hw_queued = __le32_to_cpu(tx->hw_queued); 1705d15fb520SMichal Kazior dst->hw_reaped = __le32_to_cpu(tx->hw_reaped); 1706d15fb520SMichal Kazior dst->underrun = __le32_to_cpu(tx->underrun); 1707d15fb520SMichal Kazior dst->tx_abort = __le32_to_cpu(tx->tx_abort); 1708d15fb520SMichal Kazior dst->mpdus_requed = __le32_to_cpu(tx->mpdus_requed); 1709d15fb520SMichal Kazior dst->tx_ko = __le32_to_cpu(tx->tx_ko); 1710d15fb520SMichal Kazior dst->data_rc = __le32_to_cpu(tx->data_rc); 1711d15fb520SMichal Kazior dst->self_triggers = __le32_to_cpu(tx->self_triggers); 1712d15fb520SMichal Kazior dst->sw_retry_failure = __le32_to_cpu(tx->sw_retry_failure); 1713d15fb520SMichal Kazior dst->illgl_rate_phy_err = __le32_to_cpu(tx->illgl_rate_phy_err); 1714d15fb520SMichal Kazior dst->pdev_cont_xretry = __le32_to_cpu(tx->pdev_cont_xretry); 1715d15fb520SMichal Kazior dst->pdev_tx_timeout = __le32_to_cpu(tx->pdev_tx_timeout); 1716d15fb520SMichal Kazior dst->pdev_resets = __le32_to_cpu(tx->pdev_resets); 1717d15fb520SMichal Kazior dst->phy_underrun = __le32_to_cpu(tx->phy_underrun); 1718d15fb520SMichal Kazior dst->txop_ovf = __le32_to_cpu(tx->txop_ovf); 1719d15fb520SMichal Kazior 1720d15fb520SMichal Kazior dst->mid_ppdu_route_change = __le32_to_cpu(rx->mid_ppdu_route_change); 1721d15fb520SMichal Kazior dst->status_rcvd = __le32_to_cpu(rx->status_rcvd); 1722d15fb520SMichal Kazior dst->r0_frags = __le32_to_cpu(rx->r0_frags); 1723d15fb520SMichal Kazior dst->r1_frags = __le32_to_cpu(rx->r1_frags); 1724d15fb520SMichal Kazior dst->r2_frags = __le32_to_cpu(rx->r2_frags); 1725d15fb520SMichal Kazior dst->r3_frags = __le32_to_cpu(rx->r3_frags); 1726d15fb520SMichal Kazior dst->htt_msdus = __le32_to_cpu(rx->htt_msdus); 1727d15fb520SMichal Kazior dst->htt_mpdus = __le32_to_cpu(rx->htt_mpdus); 1728d15fb520SMichal Kazior dst->loc_msdus = __le32_to_cpu(rx->loc_msdus); 1729d15fb520SMichal Kazior dst->loc_mpdus = __le32_to_cpu(rx->loc_mpdus); 1730d15fb520SMichal Kazior dst->oversize_amsdu = __le32_to_cpu(rx->oversize_amsdu); 1731d15fb520SMichal Kazior dst->phy_errs = __le32_to_cpu(rx->phy_errs); 1732d15fb520SMichal Kazior dst->phy_err_drop = __le32_to_cpu(rx->phy_err_drop); 1733d15fb520SMichal Kazior dst->mpdu_errs = __le32_to_cpu(rx->mpdu_errs); 1734d15fb520SMichal Kazior } 1735d15fb520SMichal Kazior 17360226d602SMichal Kazior void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, 173760ef401aSMichal Kazior struct ath10k_fw_stats_peer *dst) 1738d15fb520SMichal Kazior { 1739d15fb520SMichal Kazior ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); 1740d15fb520SMichal Kazior dst->peer_rssi = __le32_to_cpu(src->peer_rssi); 1741d15fb520SMichal Kazior dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate); 1742d15fb520SMichal Kazior } 1743d15fb520SMichal Kazior 1744d7579d12SMichal Kazior static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, 1745d15fb520SMichal Kazior struct sk_buff *skb, 174660ef401aSMichal Kazior struct ath10k_fw_stats *stats) 1747d15fb520SMichal Kazior { 1748d15fb520SMichal Kazior const struct wmi_stats_event *ev = (void *)skb->data; 1749d15fb520SMichal Kazior u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 1750d15fb520SMichal Kazior int i; 1751d15fb520SMichal Kazior 1752d15fb520SMichal Kazior if (!skb_pull(skb, sizeof(*ev))) 1753d15fb520SMichal Kazior return -EPROTO; 1754d15fb520SMichal Kazior 1755d15fb520SMichal Kazior num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 1756d15fb520SMichal Kazior num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 1757d15fb520SMichal Kazior num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 1758d15fb520SMichal Kazior 17595326849aSMichal Kazior for (i = 0; i < num_pdev_stats; i++) { 1760d15fb520SMichal Kazior const struct wmi_pdev_stats *src; 17615326849aSMichal Kazior struct ath10k_fw_stats_pdev *dst; 1762d15fb520SMichal Kazior 1763d15fb520SMichal Kazior src = (void *)skb->data; 1764d15fb520SMichal Kazior if (!skb_pull(skb, sizeof(*src))) 1765d15fb520SMichal Kazior return -EPROTO; 1766d15fb520SMichal Kazior 17675326849aSMichal Kazior dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 17685326849aSMichal Kazior if (!dst) 17695326849aSMichal Kazior continue; 17705326849aSMichal Kazior 17715326849aSMichal Kazior ath10k_wmi_pull_pdev_stats(src, dst); 17725326849aSMichal Kazior list_add_tail(&dst->list, &stats->pdevs); 1773d15fb520SMichal Kazior } 1774d15fb520SMichal Kazior 1775d15fb520SMichal Kazior /* fw doesn't implement vdev stats */ 1776d15fb520SMichal Kazior 1777d15fb520SMichal Kazior for (i = 0; i < num_peer_stats; i++) { 1778d15fb520SMichal Kazior const struct wmi_peer_stats *src; 17795326849aSMichal Kazior struct ath10k_fw_stats_peer *dst; 1780d15fb520SMichal Kazior 1781d15fb520SMichal Kazior src = (void *)skb->data; 1782d15fb520SMichal Kazior if (!skb_pull(skb, sizeof(*src))) 1783d15fb520SMichal Kazior return -EPROTO; 1784d15fb520SMichal Kazior 17855326849aSMichal Kazior dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 17865326849aSMichal Kazior if (!dst) 17875326849aSMichal Kazior continue; 17885326849aSMichal Kazior 17895326849aSMichal Kazior ath10k_wmi_pull_peer_stats(src, dst); 17905326849aSMichal Kazior list_add_tail(&dst->list, &stats->peers); 1791d15fb520SMichal Kazior } 1792d15fb520SMichal Kazior 1793d15fb520SMichal Kazior return 0; 1794d15fb520SMichal Kazior } 1795d15fb520SMichal Kazior 1796d7579d12SMichal Kazior static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar, 1797d15fb520SMichal Kazior struct sk_buff *skb, 179860ef401aSMichal Kazior struct ath10k_fw_stats *stats) 1799d15fb520SMichal Kazior { 1800d15fb520SMichal Kazior const struct wmi_stats_event *ev = (void *)skb->data; 1801d15fb520SMichal Kazior u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 1802d15fb520SMichal Kazior int i; 1803d15fb520SMichal Kazior 1804d15fb520SMichal Kazior if (!skb_pull(skb, sizeof(*ev))) 1805d15fb520SMichal Kazior return -EPROTO; 1806d15fb520SMichal Kazior 1807d15fb520SMichal Kazior num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 1808d15fb520SMichal Kazior num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 1809d15fb520SMichal Kazior num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 1810d15fb520SMichal Kazior 18115326849aSMichal Kazior for (i = 0; i < num_pdev_stats; i++) { 1812d15fb520SMichal Kazior const struct wmi_10x_pdev_stats *src; 18135326849aSMichal Kazior struct ath10k_fw_stats_pdev *dst; 1814d15fb520SMichal Kazior 1815d15fb520SMichal Kazior src = (void *)skb->data; 1816d15fb520SMichal Kazior if (!skb_pull(skb, sizeof(*src))) 1817d15fb520SMichal Kazior return -EPROTO; 1818d15fb520SMichal Kazior 18195326849aSMichal Kazior dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 18205326849aSMichal Kazior if (!dst) 18215326849aSMichal Kazior continue; 1822d15fb520SMichal Kazior 18235326849aSMichal Kazior ath10k_wmi_pull_pdev_stats(&src->old, dst); 18245326849aSMichal Kazior 18255326849aSMichal Kazior dst->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad); 18265326849aSMichal Kazior dst->rts_bad = __le32_to_cpu(src->rts_bad); 18275326849aSMichal Kazior dst->rts_good = __le32_to_cpu(src->rts_good); 18285326849aSMichal Kazior dst->fcs_bad = __le32_to_cpu(src->fcs_bad); 18295326849aSMichal Kazior dst->no_beacons = __le32_to_cpu(src->no_beacons); 18305326849aSMichal Kazior dst->mib_int_count = __le32_to_cpu(src->mib_int_count); 18315326849aSMichal Kazior 18325326849aSMichal Kazior list_add_tail(&dst->list, &stats->pdevs); 1833d15fb520SMichal Kazior } 1834d15fb520SMichal Kazior 1835d15fb520SMichal Kazior /* fw doesn't implement vdev stats */ 1836d15fb520SMichal Kazior 1837d15fb520SMichal Kazior for (i = 0; i < num_peer_stats; i++) { 1838d15fb520SMichal Kazior const struct wmi_10x_peer_stats *src; 18395326849aSMichal Kazior struct ath10k_fw_stats_peer *dst; 1840d15fb520SMichal Kazior 1841d15fb520SMichal Kazior src = (void *)skb->data; 1842d15fb520SMichal Kazior if (!skb_pull(skb, sizeof(*src))) 1843d15fb520SMichal Kazior return -EPROTO; 1844d15fb520SMichal Kazior 18455326849aSMichal Kazior dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 18465326849aSMichal Kazior if (!dst) 18475326849aSMichal Kazior continue; 1848d15fb520SMichal Kazior 18495326849aSMichal Kazior ath10k_wmi_pull_peer_stats(&src->old, dst); 18505326849aSMichal Kazior 18515326849aSMichal Kazior dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); 18525326849aSMichal Kazior 18535326849aSMichal Kazior list_add_tail(&dst->list, &stats->peers); 1854d15fb520SMichal Kazior } 1855d15fb520SMichal Kazior 1856d15fb520SMichal Kazior return 0; 1857d15fb520SMichal Kazior } 1858d15fb520SMichal Kazior 18590226d602SMichal Kazior void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb) 18605e3dd157SKalle Valo { 18617aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); 186260ef401aSMichal Kazior ath10k_debug_fw_stats_process(ar, skb); 18635e3dd157SKalle Valo } 18645e3dd157SKalle Valo 1865d7579d12SMichal Kazior static int 1866d7579d12SMichal Kazior ath10k_wmi_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb, 186732653cf1SMichal Kazior struct wmi_vdev_start_ev_arg *arg) 186832653cf1SMichal Kazior { 186932653cf1SMichal Kazior struct wmi_vdev_start_response_event *ev = (void *)skb->data; 187032653cf1SMichal Kazior 187132653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 187232653cf1SMichal Kazior return -EPROTO; 187332653cf1SMichal Kazior 187432653cf1SMichal Kazior skb_pull(skb, sizeof(*ev)); 187532653cf1SMichal Kazior arg->vdev_id = ev->vdev_id; 187632653cf1SMichal Kazior arg->req_id = ev->req_id; 187732653cf1SMichal Kazior arg->resp_type = ev->resp_type; 187832653cf1SMichal Kazior arg->status = ev->status; 187932653cf1SMichal Kazior 188032653cf1SMichal Kazior return 0; 188132653cf1SMichal Kazior } 188232653cf1SMichal Kazior 18830226d602SMichal Kazior void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb) 18845e3dd157SKalle Valo { 188532653cf1SMichal Kazior struct wmi_vdev_start_ev_arg arg = {}; 188632653cf1SMichal Kazior int ret; 18875e3dd157SKalle Valo 18887aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); 18895e3dd157SKalle Valo 1890d7579d12SMichal Kazior ret = ath10k_wmi_pull_vdev_start(ar, skb, &arg); 189132653cf1SMichal Kazior if (ret) { 189232653cf1SMichal Kazior ath10k_warn(ar, "failed to parse vdev start event: %d\n", ret); 189332653cf1SMichal Kazior return; 189432653cf1SMichal Kazior } 18955e3dd157SKalle Valo 189632653cf1SMichal Kazior if (WARN_ON(__le32_to_cpu(arg.status))) 18975e3dd157SKalle Valo return; 18985e3dd157SKalle Valo 18995e3dd157SKalle Valo complete(&ar->vdev_setup_done); 19005e3dd157SKalle Valo } 19015e3dd157SKalle Valo 19020226d602SMichal Kazior void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb) 19035e3dd157SKalle Valo { 19047aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); 19055e3dd157SKalle Valo complete(&ar->vdev_setup_done); 19065e3dd157SKalle Valo } 19075e3dd157SKalle Valo 1908d7579d12SMichal Kazior static int 1909d7579d12SMichal Kazior ath10k_wmi_op_pull_peer_kick_ev(struct ath10k *ar, struct sk_buff *skb, 191032653cf1SMichal Kazior struct wmi_peer_kick_ev_arg *arg) 191132653cf1SMichal Kazior { 191232653cf1SMichal Kazior struct wmi_peer_sta_kickout_event *ev = (void *)skb->data; 191332653cf1SMichal Kazior 191432653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 191532653cf1SMichal Kazior return -EPROTO; 191632653cf1SMichal Kazior 191732653cf1SMichal Kazior skb_pull(skb, sizeof(*ev)); 191832653cf1SMichal Kazior arg->mac_addr = ev->peer_macaddr.addr; 191932653cf1SMichal Kazior 192032653cf1SMichal Kazior return 0; 192132653cf1SMichal Kazior } 192232653cf1SMichal Kazior 19230226d602SMichal Kazior void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb) 19245e3dd157SKalle Valo { 192532653cf1SMichal Kazior struct wmi_peer_kick_ev_arg arg = {}; 19265a13e76eSKalle Valo struct ieee80211_sta *sta; 192732653cf1SMichal Kazior int ret; 19285a13e76eSKalle Valo 1929d7579d12SMichal Kazior ret = ath10k_wmi_pull_peer_kick(ar, skb, &arg); 193032653cf1SMichal Kazior if (ret) { 193132653cf1SMichal Kazior ath10k_warn(ar, "failed to parse peer kickout event: %d\n", 193232653cf1SMichal Kazior ret); 193332653cf1SMichal Kazior return; 193432653cf1SMichal Kazior } 19355a13e76eSKalle Valo 19367aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", 193732653cf1SMichal Kazior arg.mac_addr); 19385a13e76eSKalle Valo 19395a13e76eSKalle Valo rcu_read_lock(); 19405a13e76eSKalle Valo 194132653cf1SMichal Kazior sta = ieee80211_find_sta_by_ifaddr(ar->hw, arg.mac_addr, NULL); 19425a13e76eSKalle Valo if (!sta) { 19437aa7a72aSMichal Kazior ath10k_warn(ar, "Spurious quick kickout for STA %pM\n", 194432653cf1SMichal Kazior arg.mac_addr); 19455a13e76eSKalle Valo goto exit; 19465a13e76eSKalle Valo } 19475a13e76eSKalle Valo 19485a13e76eSKalle Valo ieee80211_report_low_ack(sta, 10); 19495a13e76eSKalle Valo 19505a13e76eSKalle Valo exit: 19515a13e76eSKalle Valo rcu_read_unlock(); 19525e3dd157SKalle Valo } 19535e3dd157SKalle Valo 19545e3dd157SKalle Valo /* 19555e3dd157SKalle Valo * FIXME 19565e3dd157SKalle Valo * 19575e3dd157SKalle Valo * We don't report to mac80211 sleep state of connected 19585e3dd157SKalle Valo * stations. Due to this mac80211 can't fill in TIM IE 19595e3dd157SKalle Valo * correctly. 19605e3dd157SKalle Valo * 19615e3dd157SKalle Valo * I know of no way of getting nullfunc frames that contain 19625e3dd157SKalle Valo * sleep transition from connected stations - these do not 19635e3dd157SKalle Valo * seem to be sent from the target to the host. There also 19645e3dd157SKalle Valo * doesn't seem to be a dedicated event for that. So the 19655e3dd157SKalle Valo * only way left to do this would be to read tim_bitmap 19665e3dd157SKalle Valo * during SWBA. 19675e3dd157SKalle Valo * 19685e3dd157SKalle Valo * We could probably try using tim_bitmap from SWBA to tell 19695e3dd157SKalle Valo * mac80211 which stations are asleep and which are not. The 19705e3dd157SKalle Valo * problem here is calling mac80211 functions so many times 19715e3dd157SKalle Valo * could take too long and make us miss the time to submit 19725e3dd157SKalle Valo * the beacon to the target. 19735e3dd157SKalle Valo * 19745e3dd157SKalle Valo * So as a workaround we try to extend the TIM IE if there 19755e3dd157SKalle Valo * is unicast buffered for stations with aid > 7 and fill it 19765e3dd157SKalle Valo * in ourselves. 19775e3dd157SKalle Valo */ 19785e3dd157SKalle Valo static void ath10k_wmi_update_tim(struct ath10k *ar, 19795e3dd157SKalle Valo struct ath10k_vif *arvif, 19805e3dd157SKalle Valo struct sk_buff *bcn, 198132653cf1SMichal Kazior const struct wmi_tim_info *tim_info) 19825e3dd157SKalle Valo { 19835e3dd157SKalle Valo struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data; 19845e3dd157SKalle Valo struct ieee80211_tim_ie *tim; 19855e3dd157SKalle Valo u8 *ies, *ie; 19865e3dd157SKalle Valo u8 ie_len, pvm_len; 1987af762c0bSKalle Valo __le32 t; 1988af762c0bSKalle Valo u32 v; 19895e3dd157SKalle Valo 19905e3dd157SKalle Valo /* if next SWBA has no tim_changed the tim_bitmap is garbage. 19915e3dd157SKalle Valo * we must copy the bitmap upon change and reuse it later */ 199232653cf1SMichal Kazior if (__le32_to_cpu(tim_info->tim_changed)) { 19935e3dd157SKalle Valo int i; 19945e3dd157SKalle Valo 19955e3dd157SKalle Valo BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) != 199632653cf1SMichal Kazior sizeof(tim_info->tim_bitmap)); 19975e3dd157SKalle Valo 19985e3dd157SKalle Valo for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { 199932653cf1SMichal Kazior t = tim_info->tim_bitmap[i / 4]; 2000af762c0bSKalle Valo v = __le32_to_cpu(t); 20015e3dd157SKalle Valo arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; 20025e3dd157SKalle Valo } 20035e3dd157SKalle Valo 20045e3dd157SKalle Valo /* FW reports either length 0 or 16 20055e3dd157SKalle Valo * so we calculate this on our own */ 20065e3dd157SKalle Valo arvif->u.ap.tim_len = 0; 20075e3dd157SKalle Valo for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) 20085e3dd157SKalle Valo if (arvif->u.ap.tim_bitmap[i]) 20095e3dd157SKalle Valo arvif->u.ap.tim_len = i; 20105e3dd157SKalle Valo 20115e3dd157SKalle Valo arvif->u.ap.tim_len++; 20125e3dd157SKalle Valo } 20135e3dd157SKalle Valo 20145e3dd157SKalle Valo ies = bcn->data; 20155e3dd157SKalle Valo ies += ieee80211_hdrlen(hdr->frame_control); 20165e3dd157SKalle Valo ies += 12; /* fixed parameters */ 20175e3dd157SKalle Valo 20185e3dd157SKalle Valo ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies, 20195e3dd157SKalle Valo (u8 *)skb_tail_pointer(bcn) - ies); 20205e3dd157SKalle Valo if (!ie) { 202109af8f85SMichal Kazior if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS) 20227aa7a72aSMichal Kazior ath10k_warn(ar, "no tim ie found;\n"); 20235e3dd157SKalle Valo return; 20245e3dd157SKalle Valo } 20255e3dd157SKalle Valo 20265e3dd157SKalle Valo tim = (void *)ie + 2; 20275e3dd157SKalle Valo ie_len = ie[1]; 20285e3dd157SKalle Valo pvm_len = ie_len - 3; /* exclude dtim count, dtim period, bmap ctl */ 20295e3dd157SKalle Valo 20305e3dd157SKalle Valo if (pvm_len < arvif->u.ap.tim_len) { 20315e3dd157SKalle Valo int expand_size = sizeof(arvif->u.ap.tim_bitmap) - pvm_len; 20325e3dd157SKalle Valo int move_size = skb_tail_pointer(bcn) - (ie + 2 + ie_len); 20335e3dd157SKalle Valo void *next_ie = ie + 2 + ie_len; 20345e3dd157SKalle Valo 20355e3dd157SKalle Valo if (skb_put(bcn, expand_size)) { 20365e3dd157SKalle Valo memmove(next_ie + expand_size, next_ie, move_size); 20375e3dd157SKalle Valo 20385e3dd157SKalle Valo ie[1] += expand_size; 20395e3dd157SKalle Valo ie_len += expand_size; 20405e3dd157SKalle Valo pvm_len += expand_size; 20415e3dd157SKalle Valo } else { 20427aa7a72aSMichal Kazior ath10k_warn(ar, "tim expansion failed\n"); 20435e3dd157SKalle Valo } 20445e3dd157SKalle Valo } 20455e3dd157SKalle Valo 20465e3dd157SKalle Valo if (pvm_len > sizeof(arvif->u.ap.tim_bitmap)) { 20477aa7a72aSMichal Kazior ath10k_warn(ar, "tim pvm length is too great (%d)\n", pvm_len); 20485e3dd157SKalle Valo return; 20495e3dd157SKalle Valo } 20505e3dd157SKalle Valo 205132653cf1SMichal Kazior tim->bitmap_ctrl = !!__le32_to_cpu(tim_info->tim_mcast); 20525e3dd157SKalle Valo memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); 20535e3dd157SKalle Valo 2054748afc47SMichal Kazior if (tim->dtim_count == 0) { 2055748afc47SMichal Kazior ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true; 2056748afc47SMichal Kazior 205732653cf1SMichal Kazior if (__le32_to_cpu(tim_info->tim_mcast) == 1) 2058748afc47SMichal Kazior ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; 2059748afc47SMichal Kazior } 2060748afc47SMichal Kazior 20617aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", 20625e3dd157SKalle Valo tim->dtim_count, tim->dtim_period, 20635e3dd157SKalle Valo tim->bitmap_ctrl, pvm_len); 20645e3dd157SKalle Valo } 20655e3dd157SKalle Valo 20665e3dd157SKalle Valo static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len, 206732653cf1SMichal Kazior const struct wmi_p2p_noa_info *noa) 20685e3dd157SKalle Valo { 20695e3dd157SKalle Valo struct ieee80211_p2p_noa_attr *noa_attr; 20705e3dd157SKalle Valo u8 ctwindow_oppps = noa->ctwindow_oppps; 20715e3dd157SKalle Valo u8 ctwindow = ctwindow_oppps >> WMI_P2P_OPPPS_CTWINDOW_OFFSET; 20725e3dd157SKalle Valo bool oppps = !!(ctwindow_oppps & WMI_P2P_OPPPS_ENABLE_BIT); 20735e3dd157SKalle Valo __le16 *noa_attr_len; 20745e3dd157SKalle Valo u16 attr_len; 20755e3dd157SKalle Valo u8 noa_descriptors = noa->num_descriptors; 20765e3dd157SKalle Valo int i; 20775e3dd157SKalle Valo 20785e3dd157SKalle Valo /* P2P IE */ 20795e3dd157SKalle Valo data[0] = WLAN_EID_VENDOR_SPECIFIC; 20805e3dd157SKalle Valo data[1] = len - 2; 20815e3dd157SKalle Valo data[2] = (WLAN_OUI_WFA >> 16) & 0xff; 20825e3dd157SKalle Valo data[3] = (WLAN_OUI_WFA >> 8) & 0xff; 20835e3dd157SKalle Valo data[4] = (WLAN_OUI_WFA >> 0) & 0xff; 20845e3dd157SKalle Valo data[5] = WLAN_OUI_TYPE_WFA_P2P; 20855e3dd157SKalle Valo 20865e3dd157SKalle Valo /* NOA ATTR */ 20875e3dd157SKalle Valo data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE; 20885e3dd157SKalle Valo noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */ 20895e3dd157SKalle Valo noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9]; 20905e3dd157SKalle Valo 20915e3dd157SKalle Valo noa_attr->index = noa->index; 20925e3dd157SKalle Valo noa_attr->oppps_ctwindow = ctwindow; 20935e3dd157SKalle Valo if (oppps) 20945e3dd157SKalle Valo noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT; 20955e3dd157SKalle Valo 20965e3dd157SKalle Valo for (i = 0; i < noa_descriptors; i++) { 20975e3dd157SKalle Valo noa_attr->desc[i].count = 20985e3dd157SKalle Valo __le32_to_cpu(noa->descriptors[i].type_count); 20995e3dd157SKalle Valo noa_attr->desc[i].duration = noa->descriptors[i].duration; 21005e3dd157SKalle Valo noa_attr->desc[i].interval = noa->descriptors[i].interval; 21015e3dd157SKalle Valo noa_attr->desc[i].start_time = noa->descriptors[i].start_time; 21025e3dd157SKalle Valo } 21035e3dd157SKalle Valo 21045e3dd157SKalle Valo attr_len = 2; /* index + oppps_ctwindow */ 21055e3dd157SKalle Valo attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc); 21065e3dd157SKalle Valo *noa_attr_len = __cpu_to_le16(attr_len); 21075e3dd157SKalle Valo } 21085e3dd157SKalle Valo 210932653cf1SMichal Kazior static u32 ath10k_p2p_calc_noa_ie_len(const struct wmi_p2p_noa_info *noa) 21105e3dd157SKalle Valo { 21115e3dd157SKalle Valo u32 len = 0; 21125e3dd157SKalle Valo u8 noa_descriptors = noa->num_descriptors; 21135e3dd157SKalle Valo u8 opp_ps_info = noa->ctwindow_oppps; 21145e3dd157SKalle Valo bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT); 21155e3dd157SKalle Valo 21165e3dd157SKalle Valo if (!noa_descriptors && !opps_enabled) 21175e3dd157SKalle Valo return len; 21185e3dd157SKalle Valo 21195e3dd157SKalle Valo len += 1 + 1 + 4; /* EID + len + OUI */ 21205e3dd157SKalle Valo len += 1 + 2; /* noa attr + attr len */ 21215e3dd157SKalle Valo len += 1 + 1; /* index + oppps_ctwindow */ 21225e3dd157SKalle Valo len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc); 21235e3dd157SKalle Valo 21245e3dd157SKalle Valo return len; 21255e3dd157SKalle Valo } 21265e3dd157SKalle Valo 21275e3dd157SKalle Valo static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, 21285e3dd157SKalle Valo struct sk_buff *bcn, 212932653cf1SMichal Kazior const struct wmi_p2p_noa_info *noa) 21305e3dd157SKalle Valo { 21315e3dd157SKalle Valo u8 *new_data, *old_data = arvif->u.ap.noa_data; 21325e3dd157SKalle Valo u32 new_len; 21335e3dd157SKalle Valo 21345e3dd157SKalle Valo if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) 21355e3dd157SKalle Valo return; 21365e3dd157SKalle Valo 21377aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); 21385e3dd157SKalle Valo if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) { 21395e3dd157SKalle Valo new_len = ath10k_p2p_calc_noa_ie_len(noa); 21405e3dd157SKalle Valo if (!new_len) 21415e3dd157SKalle Valo goto cleanup; 21425e3dd157SKalle Valo 21435e3dd157SKalle Valo new_data = kmalloc(new_len, GFP_ATOMIC); 21445e3dd157SKalle Valo if (!new_data) 21455e3dd157SKalle Valo goto cleanup; 21465e3dd157SKalle Valo 21475e3dd157SKalle Valo ath10k_p2p_fill_noa_ie(new_data, new_len, noa); 21485e3dd157SKalle Valo 21495e3dd157SKalle Valo spin_lock_bh(&ar->data_lock); 21505e3dd157SKalle Valo arvif->u.ap.noa_data = new_data; 21515e3dd157SKalle Valo arvif->u.ap.noa_len = new_len; 21525e3dd157SKalle Valo spin_unlock_bh(&ar->data_lock); 21535e3dd157SKalle Valo kfree(old_data); 21545e3dd157SKalle Valo } 21555e3dd157SKalle Valo 21565e3dd157SKalle Valo if (arvif->u.ap.noa_data) 21575e3dd157SKalle Valo if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC)) 21585e3dd157SKalle Valo memcpy(skb_put(bcn, arvif->u.ap.noa_len), 21595e3dd157SKalle Valo arvif->u.ap.noa_data, 21605e3dd157SKalle Valo arvif->u.ap.noa_len); 21615e3dd157SKalle Valo return; 21625e3dd157SKalle Valo 21635e3dd157SKalle Valo cleanup: 21645e3dd157SKalle Valo spin_lock_bh(&ar->data_lock); 21655e3dd157SKalle Valo arvif->u.ap.noa_data = NULL; 21665e3dd157SKalle Valo arvif->u.ap.noa_len = 0; 21675e3dd157SKalle Valo spin_unlock_bh(&ar->data_lock); 21685e3dd157SKalle Valo kfree(old_data); 21695e3dd157SKalle Valo } 21705e3dd157SKalle Valo 2171d7579d12SMichal Kazior static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb, 217232653cf1SMichal Kazior struct wmi_swba_ev_arg *arg) 217332653cf1SMichal Kazior { 217432653cf1SMichal Kazior struct wmi_host_swba_event *ev = (void *)skb->data; 217532653cf1SMichal Kazior u32 map; 217632653cf1SMichal Kazior size_t i; 217732653cf1SMichal Kazior 217832653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 217932653cf1SMichal Kazior return -EPROTO; 218032653cf1SMichal Kazior 218132653cf1SMichal Kazior skb_pull(skb, sizeof(*ev)); 218232653cf1SMichal Kazior arg->vdev_map = ev->vdev_map; 218332653cf1SMichal Kazior 218432653cf1SMichal Kazior for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) { 218532653cf1SMichal Kazior if (!(map & BIT(0))) 218632653cf1SMichal Kazior continue; 218732653cf1SMichal Kazior 218832653cf1SMichal Kazior /* If this happens there were some changes in firmware and 218932653cf1SMichal Kazior * ath10k should update the max size of tim_info array. 219032653cf1SMichal Kazior */ 219132653cf1SMichal Kazior if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info))) 219232653cf1SMichal Kazior break; 219332653cf1SMichal Kazior 219432653cf1SMichal Kazior arg->tim_info[i] = &ev->bcn_info[i].tim_info; 219532653cf1SMichal Kazior arg->noa_info[i] = &ev->bcn_info[i].p2p_noa_info; 219632653cf1SMichal Kazior i++; 219732653cf1SMichal Kazior } 219832653cf1SMichal Kazior 219932653cf1SMichal Kazior return 0; 220032653cf1SMichal Kazior } 220132653cf1SMichal Kazior 22020226d602SMichal Kazior void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) 22035e3dd157SKalle Valo { 220432653cf1SMichal Kazior struct wmi_swba_ev_arg arg = {}; 22055e3dd157SKalle Valo u32 map; 22065e3dd157SKalle Valo int i = -1; 220732653cf1SMichal Kazior const struct wmi_tim_info *tim_info; 220832653cf1SMichal Kazior const struct wmi_p2p_noa_info *noa_info; 22095e3dd157SKalle Valo struct ath10k_vif *arvif; 22105e3dd157SKalle Valo struct sk_buff *bcn; 221164badcb6SMichal Kazior dma_addr_t paddr; 2212767d34fcSMichal Kazior int ret, vdev_id = 0; 22135e3dd157SKalle Valo 2214d7579d12SMichal Kazior ret = ath10k_wmi_pull_swba(ar, skb, &arg); 221532653cf1SMichal Kazior if (ret) { 221632653cf1SMichal Kazior ath10k_warn(ar, "failed to parse swba event: %d\n", ret); 221732653cf1SMichal Kazior return; 221832653cf1SMichal Kazior } 221932653cf1SMichal Kazior 222032653cf1SMichal Kazior map = __le32_to_cpu(arg.vdev_map); 22215e3dd157SKalle Valo 22227aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", 222332653cf1SMichal Kazior map); 22245e3dd157SKalle Valo 22255e3dd157SKalle Valo for (; map; map >>= 1, vdev_id++) { 22265e3dd157SKalle Valo if (!(map & 0x1)) 22275e3dd157SKalle Valo continue; 22285e3dd157SKalle Valo 22295e3dd157SKalle Valo i++; 22305e3dd157SKalle Valo 22315e3dd157SKalle Valo if (i >= WMI_MAX_AP_VDEV) { 22327aa7a72aSMichal Kazior ath10k_warn(ar, "swba has corrupted vdev map\n"); 22335e3dd157SKalle Valo break; 22345e3dd157SKalle Valo } 22355e3dd157SKalle Valo 223632653cf1SMichal Kazior tim_info = arg.tim_info[i]; 223732653cf1SMichal Kazior noa_info = arg.noa_info[i]; 22385e3dd157SKalle Valo 22397aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_MGMT, 22407a8a396bSKalle Valo "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n", 22415e3dd157SKalle Valo i, 224232653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_len), 224332653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_mcast), 224432653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_changed), 224532653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_num_ps_pending), 224632653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_bitmap[3]), 224732653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_bitmap[2]), 224832653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_bitmap[1]), 224932653cf1SMichal Kazior __le32_to_cpu(tim_info->tim_bitmap[0])); 22505e3dd157SKalle Valo 22515e3dd157SKalle Valo arvif = ath10k_get_arvif(ar, vdev_id); 22525e3dd157SKalle Valo if (arvif == NULL) { 22537aa7a72aSMichal Kazior ath10k_warn(ar, "no vif for vdev_id %d found\n", 22547aa7a72aSMichal Kazior vdev_id); 22555e3dd157SKalle Valo continue; 22565e3dd157SKalle Valo } 22575e3dd157SKalle Valo 2258c2df44b3SMichal Kazior /* There are no completions for beacons so wait for next SWBA 2259c2df44b3SMichal Kazior * before telling mac80211 to decrement CSA counter 2260c2df44b3SMichal Kazior * 2261c2df44b3SMichal Kazior * Once CSA counter is completed stop sending beacons until 2262c2df44b3SMichal Kazior * actual channel switch is done */ 2263c2df44b3SMichal Kazior if (arvif->vif->csa_active && 2264c2df44b3SMichal Kazior ieee80211_csa_is_complete(arvif->vif)) { 2265c2df44b3SMichal Kazior ieee80211_csa_finish(arvif->vif); 2266c2df44b3SMichal Kazior continue; 2267c2df44b3SMichal Kazior } 2268c2df44b3SMichal Kazior 22695e3dd157SKalle Valo bcn = ieee80211_beacon_get(ar->hw, arvif->vif); 22705e3dd157SKalle Valo if (!bcn) { 22717aa7a72aSMichal Kazior ath10k_warn(ar, "could not get mac80211 beacon\n"); 22725e3dd157SKalle Valo continue; 22735e3dd157SKalle Valo } 22745e3dd157SKalle Valo 22754b604558SMichal Kazior ath10k_tx_h_seq_no(arvif->vif, bcn); 227632653cf1SMichal Kazior ath10k_wmi_update_tim(ar, arvif, bcn, tim_info); 227732653cf1SMichal Kazior ath10k_wmi_update_noa(ar, arvif, bcn, noa_info); 22785e3dd157SKalle Valo 2279ed54388aSMichal Kazior spin_lock_bh(&ar->data_lock); 2280748afc47SMichal Kazior 2281ed54388aSMichal Kazior if (arvif->beacon) { 2282748afc47SMichal Kazior if (!arvif->beacon_sent) 22837aa7a72aSMichal Kazior ath10k_warn(ar, "SWBA overrun on vdev %d\n", 2284ed54388aSMichal Kazior arvif->vdev_id); 2285748afc47SMichal Kazior 228664badcb6SMichal Kazior ath10k_mac_vif_beacon_free(arvif); 2287ed54388aSMichal Kazior } 22885e3dd157SKalle Valo 228964badcb6SMichal Kazior if (!arvif->beacon_buf) { 229064badcb6SMichal Kazior paddr = dma_map_single(arvif->ar->dev, bcn->data, 229164badcb6SMichal Kazior bcn->len, DMA_TO_DEVICE); 229264badcb6SMichal Kazior ret = dma_mapping_error(arvif->ar->dev, paddr); 2293767d34fcSMichal Kazior if (ret) { 229464badcb6SMichal Kazior ath10k_warn(ar, "failed to map beacon: %d\n", 229564badcb6SMichal Kazior ret); 2296ad3d2153SMichal Kazior dev_kfree_skb_any(bcn); 2297767d34fcSMichal Kazior goto skip; 2298767d34fcSMichal Kazior } 2299748afc47SMichal Kazior 230064badcb6SMichal Kazior ATH10K_SKB_CB(bcn)->paddr = paddr; 230164badcb6SMichal Kazior } else { 230264badcb6SMichal Kazior if (bcn->len > IEEE80211_MAX_FRAME_LEN) { 230364badcb6SMichal Kazior ath10k_warn(ar, "trimming beacon %d -> %d bytes!\n", 230464badcb6SMichal Kazior bcn->len, IEEE80211_MAX_FRAME_LEN); 230564badcb6SMichal Kazior skb_trim(bcn, IEEE80211_MAX_FRAME_LEN); 230664badcb6SMichal Kazior } 230764badcb6SMichal Kazior memcpy(arvif->beacon_buf, bcn->data, bcn->len); 230864badcb6SMichal Kazior ATH10K_SKB_CB(bcn)->paddr = arvif->beacon_paddr; 230964badcb6SMichal Kazior } 231064badcb6SMichal Kazior 2311ed54388aSMichal Kazior arvif->beacon = bcn; 2312748afc47SMichal Kazior arvif->beacon_sent = false; 23135e3dd157SKalle Valo 23145ce8e7fdSRajkumar Manoharan trace_ath10k_tx_hdr(ar, bcn->data, bcn->len); 23155ce8e7fdSRajkumar Manoharan trace_ath10k_tx_payload(ar, bcn->data, bcn->len); 23165ce8e7fdSRajkumar Manoharan 2317ed54388aSMichal Kazior ath10k_wmi_tx_beacon_nowait(arvif); 2318767d34fcSMichal Kazior skip: 2319ed54388aSMichal Kazior spin_unlock_bh(&ar->data_lock); 23205e3dd157SKalle Valo } 23215e3dd157SKalle Valo } 23225e3dd157SKalle Valo 23230226d602SMichal Kazior void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb) 23245e3dd157SKalle Valo { 23257aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); 23265e3dd157SKalle Valo } 23275e3dd157SKalle Valo 23289702c686SJanusz Dziedzic static void ath10k_dfs_radar_report(struct ath10k *ar, 23292332d0aeSMichal Kazior const struct wmi_phyerr *phyerr, 23302332d0aeSMichal Kazior const struct phyerr_radar_report *rr, 23319702c686SJanusz Dziedzic u64 tsf) 23329702c686SJanusz Dziedzic { 23339702c686SJanusz Dziedzic u32 reg0, reg1, tsf32l; 23349702c686SJanusz Dziedzic struct pulse_event pe; 23359702c686SJanusz Dziedzic u64 tsf64; 23369702c686SJanusz Dziedzic u8 rssi, width; 23379702c686SJanusz Dziedzic 23389702c686SJanusz Dziedzic reg0 = __le32_to_cpu(rr->reg0); 23399702c686SJanusz Dziedzic reg1 = __le32_to_cpu(rr->reg1); 23409702c686SJanusz Dziedzic 23417aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 23429702c686SJanusz Dziedzic "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n", 23439702c686SJanusz Dziedzic MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP), 23449702c686SJanusz Dziedzic MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH), 23459702c686SJanusz Dziedzic MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN), 23469702c686SJanusz Dziedzic MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF)); 23477aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 23489702c686SJanusz Dziedzic "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n", 23499702c686SJanusz Dziedzic MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK), 23509702c686SJanusz Dziedzic MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX), 23519702c686SJanusz Dziedzic MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID), 23529702c686SJanusz Dziedzic MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN), 23539702c686SJanusz Dziedzic MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK)); 23547aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 23559702c686SJanusz Dziedzic "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n", 23569702c686SJanusz Dziedzic MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET), 23579702c686SJanusz Dziedzic MS(reg1, RADAR_REPORT_REG1_PULSE_DUR)); 23589702c686SJanusz Dziedzic 23599702c686SJanusz Dziedzic if (!ar->dfs_detector) 23609702c686SJanusz Dziedzic return; 23619702c686SJanusz Dziedzic 23629702c686SJanusz Dziedzic /* report event to DFS pattern detector */ 23632332d0aeSMichal Kazior tsf32l = __le32_to_cpu(phyerr->tsf_timestamp); 23649702c686SJanusz Dziedzic tsf64 = tsf & (~0xFFFFFFFFULL); 23659702c686SJanusz Dziedzic tsf64 |= tsf32l; 23669702c686SJanusz Dziedzic 23679702c686SJanusz Dziedzic width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR); 23682332d0aeSMichal Kazior rssi = phyerr->rssi_combined; 23699702c686SJanusz Dziedzic 23709702c686SJanusz Dziedzic /* hardware store this as 8 bit signed value, 23719702c686SJanusz Dziedzic * set to zero if negative number 23729702c686SJanusz Dziedzic */ 23739702c686SJanusz Dziedzic if (rssi & 0x80) 23749702c686SJanusz Dziedzic rssi = 0; 23759702c686SJanusz Dziedzic 23769702c686SJanusz Dziedzic pe.ts = tsf64; 23779702c686SJanusz Dziedzic pe.freq = ar->hw->conf.chandef.chan->center_freq; 23789702c686SJanusz Dziedzic pe.width = width; 23799702c686SJanusz Dziedzic pe.rssi = rssi; 23809702c686SJanusz Dziedzic 23817aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 23829702c686SJanusz Dziedzic "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n", 23839702c686SJanusz Dziedzic pe.freq, pe.width, pe.rssi, pe.ts); 23849702c686SJanusz Dziedzic 23859702c686SJanusz Dziedzic ATH10K_DFS_STAT_INC(ar, pulses_detected); 23869702c686SJanusz Dziedzic 23879702c686SJanusz Dziedzic if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) { 23887aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 23899702c686SJanusz Dziedzic "dfs no pulse pattern detected, yet\n"); 23909702c686SJanusz Dziedzic return; 23919702c686SJanusz Dziedzic } 23929702c686SJanusz Dziedzic 23937aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n"); 23949702c686SJanusz Dziedzic ATH10K_DFS_STAT_INC(ar, radar_detected); 23957d9b40b4SMarek Puzyniak 23967d9b40b4SMarek Puzyniak /* Control radar events reporting in debugfs file 23977d9b40b4SMarek Puzyniak dfs_block_radar_events */ 23987d9b40b4SMarek Puzyniak if (ar->dfs_block_radar_events) { 23997aa7a72aSMichal Kazior ath10k_info(ar, "DFS Radar detected, but ignored as requested\n"); 24007d9b40b4SMarek Puzyniak return; 24017d9b40b4SMarek Puzyniak } 24027d9b40b4SMarek Puzyniak 24039702c686SJanusz Dziedzic ieee80211_radar_detected(ar->hw); 24049702c686SJanusz Dziedzic } 24059702c686SJanusz Dziedzic 24069702c686SJanusz Dziedzic static int ath10k_dfs_fft_report(struct ath10k *ar, 24072332d0aeSMichal Kazior const struct wmi_phyerr *phyerr, 24082332d0aeSMichal Kazior const struct phyerr_fft_report *fftr, 24099702c686SJanusz Dziedzic u64 tsf) 24109702c686SJanusz Dziedzic { 24119702c686SJanusz Dziedzic u32 reg0, reg1; 24129702c686SJanusz Dziedzic u8 rssi, peak_mag; 24139702c686SJanusz Dziedzic 24149702c686SJanusz Dziedzic reg0 = __le32_to_cpu(fftr->reg0); 24159702c686SJanusz Dziedzic reg1 = __le32_to_cpu(fftr->reg1); 24162332d0aeSMichal Kazior rssi = phyerr->rssi_combined; 24179702c686SJanusz Dziedzic 24187aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 24199702c686SJanusz Dziedzic "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n", 24209702c686SJanusz Dziedzic MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB), 24219702c686SJanusz Dziedzic MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB), 24229702c686SJanusz Dziedzic MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX), 24239702c686SJanusz Dziedzic MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX)); 24247aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 24259702c686SJanusz Dziedzic "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n", 24269702c686SJanusz Dziedzic MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB), 24279702c686SJanusz Dziedzic MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB), 24289702c686SJanusz Dziedzic MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG), 24299702c686SJanusz Dziedzic MS(reg1, SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB)); 24309702c686SJanusz Dziedzic 24319702c686SJanusz Dziedzic peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG); 24329702c686SJanusz Dziedzic 24339702c686SJanusz Dziedzic /* false event detection */ 24349702c686SJanusz Dziedzic if (rssi == DFS_RSSI_POSSIBLY_FALSE && 24359702c686SJanusz Dziedzic peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) { 24367aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs false pulse detected\n"); 24379702c686SJanusz Dziedzic ATH10K_DFS_STAT_INC(ar, pulses_discarded); 24389702c686SJanusz Dziedzic return -EINVAL; 24399702c686SJanusz Dziedzic } 24409702c686SJanusz Dziedzic 24419702c686SJanusz Dziedzic return 0; 24429702c686SJanusz Dziedzic } 24439702c686SJanusz Dziedzic 24440226d602SMichal Kazior void ath10k_wmi_event_dfs(struct ath10k *ar, 24452332d0aeSMichal Kazior const struct wmi_phyerr *phyerr, 24469702c686SJanusz Dziedzic u64 tsf) 24479702c686SJanusz Dziedzic { 24489702c686SJanusz Dziedzic int buf_len, tlv_len, res, i = 0; 24492332d0aeSMichal Kazior const struct phyerr_tlv *tlv; 24502332d0aeSMichal Kazior const struct phyerr_radar_report *rr; 24512332d0aeSMichal Kazior const struct phyerr_fft_report *fftr; 24522332d0aeSMichal Kazior const u8 *tlv_buf; 24539702c686SJanusz Dziedzic 24542332d0aeSMichal Kazior buf_len = __le32_to_cpu(phyerr->buf_len); 24557aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 24569702c686SJanusz Dziedzic "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n", 24572332d0aeSMichal Kazior phyerr->phy_err_code, phyerr->rssi_combined, 24582332d0aeSMichal Kazior __le32_to_cpu(phyerr->tsf_timestamp), tsf, buf_len); 24599702c686SJanusz Dziedzic 24609702c686SJanusz Dziedzic /* Skip event if DFS disabled */ 24619702c686SJanusz Dziedzic if (!config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) 24629702c686SJanusz Dziedzic return; 24639702c686SJanusz Dziedzic 24649702c686SJanusz Dziedzic ATH10K_DFS_STAT_INC(ar, pulses_total); 24659702c686SJanusz Dziedzic 24669702c686SJanusz Dziedzic while (i < buf_len) { 24679702c686SJanusz Dziedzic if (i + sizeof(*tlv) > buf_len) { 24687aa7a72aSMichal Kazior ath10k_warn(ar, "too short buf for tlv header (%d)\n", 24697aa7a72aSMichal Kazior i); 24709702c686SJanusz Dziedzic return; 24719702c686SJanusz Dziedzic } 24729702c686SJanusz Dziedzic 24732332d0aeSMichal Kazior tlv = (struct phyerr_tlv *)&phyerr->buf[i]; 24749702c686SJanusz Dziedzic tlv_len = __le16_to_cpu(tlv->len); 24752332d0aeSMichal Kazior tlv_buf = &phyerr->buf[i + sizeof(*tlv)]; 24767aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 24779702c686SJanusz Dziedzic "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n", 24789702c686SJanusz Dziedzic tlv_len, tlv->tag, tlv->sig); 24799702c686SJanusz Dziedzic 24809702c686SJanusz Dziedzic switch (tlv->tag) { 24819702c686SJanusz Dziedzic case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY: 24829702c686SJanusz Dziedzic if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) { 24837aa7a72aSMichal Kazior ath10k_warn(ar, "too short radar pulse summary (%d)\n", 24849702c686SJanusz Dziedzic i); 24859702c686SJanusz Dziedzic return; 24869702c686SJanusz Dziedzic } 24879702c686SJanusz Dziedzic 24889702c686SJanusz Dziedzic rr = (struct phyerr_radar_report *)tlv_buf; 24892332d0aeSMichal Kazior ath10k_dfs_radar_report(ar, phyerr, rr, tsf); 24909702c686SJanusz Dziedzic break; 24919702c686SJanusz Dziedzic case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: 24929702c686SJanusz Dziedzic if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) { 24937aa7a72aSMichal Kazior ath10k_warn(ar, "too short fft report (%d)\n", 24947aa7a72aSMichal Kazior i); 24959702c686SJanusz Dziedzic return; 24969702c686SJanusz Dziedzic } 24979702c686SJanusz Dziedzic 24989702c686SJanusz Dziedzic fftr = (struct phyerr_fft_report *)tlv_buf; 24992332d0aeSMichal Kazior res = ath10k_dfs_fft_report(ar, phyerr, fftr, tsf); 25009702c686SJanusz Dziedzic if (res) 25019702c686SJanusz Dziedzic return; 25029702c686SJanusz Dziedzic break; 25039702c686SJanusz Dziedzic } 25049702c686SJanusz Dziedzic 25059702c686SJanusz Dziedzic i += sizeof(*tlv) + tlv_len; 25069702c686SJanusz Dziedzic } 25079702c686SJanusz Dziedzic } 25089702c686SJanusz Dziedzic 25090226d602SMichal Kazior void ath10k_wmi_event_spectral_scan(struct ath10k *ar, 25102332d0aeSMichal Kazior const struct wmi_phyerr *phyerr, 25119702c686SJanusz Dziedzic u64 tsf) 25129702c686SJanusz Dziedzic { 2513855aed12SSimon Wunderlich int buf_len, tlv_len, res, i = 0; 2514855aed12SSimon Wunderlich struct phyerr_tlv *tlv; 25152332d0aeSMichal Kazior const void *tlv_buf; 25162332d0aeSMichal Kazior const struct phyerr_fft_report *fftr; 2517855aed12SSimon Wunderlich size_t fftr_len; 2518855aed12SSimon Wunderlich 25192332d0aeSMichal Kazior buf_len = __le32_to_cpu(phyerr->buf_len); 2520855aed12SSimon Wunderlich 2521855aed12SSimon Wunderlich while (i < buf_len) { 2522855aed12SSimon Wunderlich if (i + sizeof(*tlv) > buf_len) { 25237aa7a72aSMichal Kazior ath10k_warn(ar, "failed to parse phyerr tlv header at byte %d\n", 2524855aed12SSimon Wunderlich i); 2525855aed12SSimon Wunderlich return; 2526855aed12SSimon Wunderlich } 2527855aed12SSimon Wunderlich 25282332d0aeSMichal Kazior tlv = (struct phyerr_tlv *)&phyerr->buf[i]; 2529855aed12SSimon Wunderlich tlv_len = __le16_to_cpu(tlv->len); 25302332d0aeSMichal Kazior tlv_buf = &phyerr->buf[i + sizeof(*tlv)]; 2531855aed12SSimon Wunderlich 2532855aed12SSimon Wunderlich if (i + sizeof(*tlv) + tlv_len > buf_len) { 25337aa7a72aSMichal Kazior ath10k_warn(ar, "failed to parse phyerr tlv payload at byte %d\n", 2534855aed12SSimon Wunderlich i); 2535855aed12SSimon Wunderlich return; 2536855aed12SSimon Wunderlich } 2537855aed12SSimon Wunderlich 2538855aed12SSimon Wunderlich switch (tlv->tag) { 2539855aed12SSimon Wunderlich case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: 2540855aed12SSimon Wunderlich if (sizeof(*fftr) > tlv_len) { 25417aa7a72aSMichal Kazior ath10k_warn(ar, "failed to parse fft report at byte %d\n", 2542855aed12SSimon Wunderlich i); 2543855aed12SSimon Wunderlich return; 2544855aed12SSimon Wunderlich } 2545855aed12SSimon Wunderlich 2546855aed12SSimon Wunderlich fftr_len = tlv_len - sizeof(*fftr); 25472332d0aeSMichal Kazior fftr = tlv_buf; 25482332d0aeSMichal Kazior res = ath10k_spectral_process_fft(ar, phyerr, 2549855aed12SSimon Wunderlich fftr, fftr_len, 2550855aed12SSimon Wunderlich tsf); 2551855aed12SSimon Wunderlich if (res < 0) { 25527aa7a72aSMichal Kazior ath10k_warn(ar, "failed to process fft report: %d\n", 2553855aed12SSimon Wunderlich res); 2554855aed12SSimon Wunderlich return; 2555855aed12SSimon Wunderlich } 2556855aed12SSimon Wunderlich break; 2557855aed12SSimon Wunderlich } 2558855aed12SSimon Wunderlich 2559855aed12SSimon Wunderlich i += sizeof(*tlv) + tlv_len; 2560855aed12SSimon Wunderlich } 25619702c686SJanusz Dziedzic } 25629702c686SJanusz Dziedzic 2563d7579d12SMichal Kazior static int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, struct sk_buff *skb, 256432653cf1SMichal Kazior struct wmi_phyerr_ev_arg *arg) 256532653cf1SMichal Kazior { 256632653cf1SMichal Kazior struct wmi_phyerr_event *ev = (void *)skb->data; 256732653cf1SMichal Kazior 256832653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 256932653cf1SMichal Kazior return -EPROTO; 257032653cf1SMichal Kazior 257132653cf1SMichal Kazior arg->num_phyerrs = ev->num_phyerrs; 257232653cf1SMichal Kazior arg->tsf_l32 = ev->tsf_l32; 257332653cf1SMichal Kazior arg->tsf_u32 = ev->tsf_u32; 257432653cf1SMichal Kazior arg->buf_len = __cpu_to_le32(skb->len - sizeof(*ev)); 257532653cf1SMichal Kazior arg->phyerrs = ev->phyerrs; 257632653cf1SMichal Kazior 257732653cf1SMichal Kazior return 0; 257832653cf1SMichal Kazior } 257932653cf1SMichal Kazior 25800226d602SMichal Kazior void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) 25815e3dd157SKalle Valo { 258232653cf1SMichal Kazior struct wmi_phyerr_ev_arg arg = {}; 25832332d0aeSMichal Kazior const struct wmi_phyerr *phyerr; 25849702c686SJanusz Dziedzic u32 count, i, buf_len, phy_err_code; 25859702c686SJanusz Dziedzic u64 tsf; 258632653cf1SMichal Kazior int left_len, ret; 25879702c686SJanusz Dziedzic 25889702c686SJanusz Dziedzic ATH10K_DFS_STAT_INC(ar, phy_errors); 25899702c686SJanusz Dziedzic 2590d7579d12SMichal Kazior ret = ath10k_wmi_pull_phyerr(ar, skb, &arg); 259132653cf1SMichal Kazior if (ret) { 259232653cf1SMichal Kazior ath10k_warn(ar, "failed to parse phyerr event: %d\n", ret); 25939702c686SJanusz Dziedzic return; 25949702c686SJanusz Dziedzic } 25959702c686SJanusz Dziedzic 259632653cf1SMichal Kazior left_len = __le32_to_cpu(arg.buf_len); 25979702c686SJanusz Dziedzic 25989702c686SJanusz Dziedzic /* Check number of included events */ 259932653cf1SMichal Kazior count = __le32_to_cpu(arg.num_phyerrs); 26009702c686SJanusz Dziedzic 260132653cf1SMichal Kazior tsf = __le32_to_cpu(arg.tsf_u32); 26029702c686SJanusz Dziedzic tsf <<= 32; 260332653cf1SMichal Kazior tsf |= __le32_to_cpu(arg.tsf_l32); 26049702c686SJanusz Dziedzic 26057aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 26069702c686SJanusz Dziedzic "wmi event phyerr count %d tsf64 0x%llX\n", 26079702c686SJanusz Dziedzic count, tsf); 26089702c686SJanusz Dziedzic 260932653cf1SMichal Kazior phyerr = arg.phyerrs; 26109702c686SJanusz Dziedzic for (i = 0; i < count; i++) { 26119702c686SJanusz Dziedzic /* Check if we can read event header */ 26122332d0aeSMichal Kazior if (left_len < sizeof(*phyerr)) { 26137aa7a72aSMichal Kazior ath10k_warn(ar, "single event (%d) wrong head len\n", 26147aa7a72aSMichal Kazior i); 26159702c686SJanusz Dziedzic return; 26169702c686SJanusz Dziedzic } 26179702c686SJanusz Dziedzic 26182332d0aeSMichal Kazior left_len -= sizeof(*phyerr); 26199702c686SJanusz Dziedzic 26202332d0aeSMichal Kazior buf_len = __le32_to_cpu(phyerr->buf_len); 26212332d0aeSMichal Kazior phy_err_code = phyerr->phy_err_code; 26229702c686SJanusz Dziedzic 26239702c686SJanusz Dziedzic if (left_len < buf_len) { 26247aa7a72aSMichal Kazior ath10k_warn(ar, "single event (%d) wrong buf len\n", i); 26259702c686SJanusz Dziedzic return; 26269702c686SJanusz Dziedzic } 26279702c686SJanusz Dziedzic 26289702c686SJanusz Dziedzic left_len -= buf_len; 26299702c686SJanusz Dziedzic 26309702c686SJanusz Dziedzic switch (phy_err_code) { 26319702c686SJanusz Dziedzic case PHY_ERROR_RADAR: 26322332d0aeSMichal Kazior ath10k_wmi_event_dfs(ar, phyerr, tsf); 26339702c686SJanusz Dziedzic break; 26349702c686SJanusz Dziedzic case PHY_ERROR_SPECTRAL_SCAN: 26352332d0aeSMichal Kazior ath10k_wmi_event_spectral_scan(ar, phyerr, tsf); 26369702c686SJanusz Dziedzic break; 26379702c686SJanusz Dziedzic case PHY_ERROR_FALSE_RADAR_EXT: 26382332d0aeSMichal Kazior ath10k_wmi_event_dfs(ar, phyerr, tsf); 26392332d0aeSMichal Kazior ath10k_wmi_event_spectral_scan(ar, phyerr, tsf); 26409702c686SJanusz Dziedzic break; 26419702c686SJanusz Dziedzic default: 26429702c686SJanusz Dziedzic break; 26439702c686SJanusz Dziedzic } 26449702c686SJanusz Dziedzic 26452332d0aeSMichal Kazior phyerr = (void *)phyerr + sizeof(*phyerr) + buf_len; 26469702c686SJanusz Dziedzic } 26475e3dd157SKalle Valo } 26485e3dd157SKalle Valo 26490226d602SMichal Kazior void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) 26505e3dd157SKalle Valo { 26517aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); 26525e3dd157SKalle Valo } 26535e3dd157SKalle Valo 26540226d602SMichal Kazior void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb) 26555e3dd157SKalle Valo { 26567aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); 26575e3dd157SKalle Valo } 26585e3dd157SKalle Valo 26590226d602SMichal Kazior void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb) 26605e3dd157SKalle Valo { 26612fe5288cSKalle Valo char buf[101], c; 26622fe5288cSKalle Valo int i; 26632fe5288cSKalle Valo 26642fe5288cSKalle Valo for (i = 0; i < sizeof(buf) - 1; i++) { 26652fe5288cSKalle Valo if (i >= skb->len) 26662fe5288cSKalle Valo break; 26672fe5288cSKalle Valo 26682fe5288cSKalle Valo c = skb->data[i]; 26692fe5288cSKalle Valo 26702fe5288cSKalle Valo if (c == '\0') 26712fe5288cSKalle Valo break; 26722fe5288cSKalle Valo 26732fe5288cSKalle Valo if (isascii(c) && isprint(c)) 26742fe5288cSKalle Valo buf[i] = c; 26752fe5288cSKalle Valo else 26762fe5288cSKalle Valo buf[i] = '.'; 26772fe5288cSKalle Valo } 26782fe5288cSKalle Valo 26792fe5288cSKalle Valo if (i == sizeof(buf) - 1) 26807aa7a72aSMichal Kazior ath10k_warn(ar, "wmi debug print truncated: %d\n", skb->len); 26812fe5288cSKalle Valo 26822fe5288cSKalle Valo /* for some reason the debug prints end with \n, remove that */ 26832fe5288cSKalle Valo if (skb->data[i - 1] == '\n') 26842fe5288cSKalle Valo i--; 26852fe5288cSKalle Valo 26862fe5288cSKalle Valo /* the last byte is always reserved for the null character */ 26872fe5288cSKalle Valo buf[i] = '\0'; 26882fe5288cSKalle Valo 26893be004c3SBen Greear ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf); 26905e3dd157SKalle Valo } 26915e3dd157SKalle Valo 26920226d602SMichal Kazior void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) 26935e3dd157SKalle Valo { 26947aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); 26955e3dd157SKalle Valo } 26965e3dd157SKalle Valo 26970226d602SMichal Kazior void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb) 26985e3dd157SKalle Valo { 26997aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); 27005e3dd157SKalle Valo } 27015e3dd157SKalle Valo 27020226d602SMichal Kazior void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, 27035e3dd157SKalle Valo struct sk_buff *skb) 27045e3dd157SKalle Valo { 27057aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); 27065e3dd157SKalle Valo } 27075e3dd157SKalle Valo 27080226d602SMichal Kazior void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, 27095e3dd157SKalle Valo struct sk_buff *skb) 27105e3dd157SKalle Valo { 27117aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); 27125e3dd157SKalle Valo } 27135e3dd157SKalle Valo 27140226d602SMichal Kazior void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb) 27155e3dd157SKalle Valo { 27167aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); 27175e3dd157SKalle Valo } 27185e3dd157SKalle Valo 27190226d602SMichal Kazior void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb) 27205e3dd157SKalle Valo { 27217aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); 27225e3dd157SKalle Valo } 27235e3dd157SKalle Valo 27240226d602SMichal Kazior void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb) 27255e3dd157SKalle Valo { 27267aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); 27275e3dd157SKalle Valo } 27285e3dd157SKalle Valo 27290226d602SMichal Kazior void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) 27305e3dd157SKalle Valo { 27317aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); 27325e3dd157SKalle Valo } 27335e3dd157SKalle Valo 27340226d602SMichal Kazior void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb) 27355e3dd157SKalle Valo { 27367aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); 27375e3dd157SKalle Valo } 27385e3dd157SKalle Valo 27390226d602SMichal Kazior void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, struct sk_buff *skb) 27405e3dd157SKalle Valo { 27417aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); 27425e3dd157SKalle Valo } 27435e3dd157SKalle Valo 27440226d602SMichal Kazior void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb) 27455e3dd157SKalle Valo { 27467aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); 27475e3dd157SKalle Valo } 27485e3dd157SKalle Valo 27490226d602SMichal Kazior void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb) 27505e3dd157SKalle Valo { 27517aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); 27525e3dd157SKalle Valo } 27535e3dd157SKalle Valo 27540226d602SMichal Kazior void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb) 27555e3dd157SKalle Valo { 27567aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); 27575e3dd157SKalle Valo } 27585e3dd157SKalle Valo 27590226d602SMichal Kazior void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, 27605e3dd157SKalle Valo struct sk_buff *skb) 27615e3dd157SKalle Valo { 27627aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); 27635e3dd157SKalle Valo } 27645e3dd157SKalle Valo 27650226d602SMichal Kazior void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb) 27668a6618b0SBartosz Markowski { 27677aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); 27688a6618b0SBartosz Markowski } 27698a6618b0SBartosz Markowski 27700226d602SMichal Kazior void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb) 27718a6618b0SBartosz Markowski { 27727aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); 27738a6618b0SBartosz Markowski } 27748a6618b0SBartosz Markowski 27750226d602SMichal Kazior void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb) 27768a6618b0SBartosz Markowski { 27777aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); 27788a6618b0SBartosz Markowski } 27798a6618b0SBartosz Markowski 2780b3effe61SBartosz Markowski static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, 2781b3effe61SBartosz Markowski u32 num_units, u32 unit_len) 2782b3effe61SBartosz Markowski { 2783b3effe61SBartosz Markowski dma_addr_t paddr; 2784b3effe61SBartosz Markowski u32 pool_size; 2785b3effe61SBartosz Markowski int idx = ar->wmi.num_mem_chunks; 2786b3effe61SBartosz Markowski 2787b3effe61SBartosz Markowski pool_size = num_units * round_up(unit_len, 4); 2788b3effe61SBartosz Markowski 2789b3effe61SBartosz Markowski if (!pool_size) 2790b3effe61SBartosz Markowski return -EINVAL; 2791b3effe61SBartosz Markowski 2792b3effe61SBartosz Markowski ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev, 2793b3effe61SBartosz Markowski pool_size, 2794b3effe61SBartosz Markowski &paddr, 2795b3effe61SBartosz Markowski GFP_ATOMIC); 2796b3effe61SBartosz Markowski if (!ar->wmi.mem_chunks[idx].vaddr) { 27977aa7a72aSMichal Kazior ath10k_warn(ar, "failed to allocate memory chunk\n"); 2798b3effe61SBartosz Markowski return -ENOMEM; 2799b3effe61SBartosz Markowski } 2800b3effe61SBartosz Markowski 2801b3effe61SBartosz Markowski memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size); 2802b3effe61SBartosz Markowski 2803b3effe61SBartosz Markowski ar->wmi.mem_chunks[idx].paddr = paddr; 2804b3effe61SBartosz Markowski ar->wmi.mem_chunks[idx].len = pool_size; 2805b3effe61SBartosz Markowski ar->wmi.mem_chunks[idx].req_id = req_id; 2806b3effe61SBartosz Markowski ar->wmi.num_mem_chunks++; 2807b3effe61SBartosz Markowski 2808b3effe61SBartosz Markowski return 0; 2809b3effe61SBartosz Markowski } 2810b3effe61SBartosz Markowski 2811d7579d12SMichal Kazior static int 2812d7579d12SMichal Kazior ath10k_wmi_main_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb, 28135c01aa3dSMichal Kazior struct wmi_svc_rdy_ev_arg *arg) 28145c01aa3dSMichal Kazior { 28155c01aa3dSMichal Kazior struct wmi_service_ready_event *ev; 28165c01aa3dSMichal Kazior size_t i, n; 28175c01aa3dSMichal Kazior 28185c01aa3dSMichal Kazior if (skb->len < sizeof(*ev)) 28195c01aa3dSMichal Kazior return -EPROTO; 28205c01aa3dSMichal Kazior 28215c01aa3dSMichal Kazior ev = (void *)skb->data; 28225c01aa3dSMichal Kazior skb_pull(skb, sizeof(*ev)); 28235c01aa3dSMichal Kazior arg->min_tx_power = ev->hw_min_tx_power; 28245c01aa3dSMichal Kazior arg->max_tx_power = ev->hw_max_tx_power; 28255c01aa3dSMichal Kazior arg->ht_cap = ev->ht_cap_info; 28265c01aa3dSMichal Kazior arg->vht_cap = ev->vht_cap_info; 28275c01aa3dSMichal Kazior arg->sw_ver0 = ev->sw_version; 28285c01aa3dSMichal Kazior arg->sw_ver1 = ev->sw_version_1; 28295c01aa3dSMichal Kazior arg->phy_capab = ev->phy_capability; 28305c01aa3dSMichal Kazior arg->num_rf_chains = ev->num_rf_chains; 28315c01aa3dSMichal Kazior arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd; 28325c01aa3dSMichal Kazior arg->num_mem_reqs = ev->num_mem_reqs; 28335c01aa3dSMichal Kazior arg->service_map = ev->wmi_service_bitmap; 28342a3e60d3SMichal Kazior arg->service_map_len = sizeof(ev->wmi_service_bitmap); 28355c01aa3dSMichal Kazior 28365c01aa3dSMichal Kazior n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), 28375c01aa3dSMichal Kazior ARRAY_SIZE(arg->mem_reqs)); 28385c01aa3dSMichal Kazior for (i = 0; i < n; i++) 28395c01aa3dSMichal Kazior arg->mem_reqs[i] = &ev->mem_reqs[i]; 28405c01aa3dSMichal Kazior 28415c01aa3dSMichal Kazior if (skb->len < 28425c01aa3dSMichal Kazior __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0])) 28435c01aa3dSMichal Kazior return -EPROTO; 28445c01aa3dSMichal Kazior 28455c01aa3dSMichal Kazior return 0; 28465c01aa3dSMichal Kazior } 28475c01aa3dSMichal Kazior 2848d7579d12SMichal Kazior static int 2849d7579d12SMichal Kazior ath10k_wmi_10x_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb, 28505c01aa3dSMichal Kazior struct wmi_svc_rdy_ev_arg *arg) 28515c01aa3dSMichal Kazior { 28525c01aa3dSMichal Kazior struct wmi_10x_service_ready_event *ev; 28535c01aa3dSMichal Kazior int i, n; 28545c01aa3dSMichal Kazior 28555c01aa3dSMichal Kazior if (skb->len < sizeof(*ev)) 28565c01aa3dSMichal Kazior return -EPROTO; 28575c01aa3dSMichal Kazior 28585c01aa3dSMichal Kazior ev = (void *)skb->data; 28595c01aa3dSMichal Kazior skb_pull(skb, sizeof(*ev)); 28605c01aa3dSMichal Kazior arg->min_tx_power = ev->hw_min_tx_power; 28615c01aa3dSMichal Kazior arg->max_tx_power = ev->hw_max_tx_power; 28625c01aa3dSMichal Kazior arg->ht_cap = ev->ht_cap_info; 28635c01aa3dSMichal Kazior arg->vht_cap = ev->vht_cap_info; 28645c01aa3dSMichal Kazior arg->sw_ver0 = ev->sw_version; 28655c01aa3dSMichal Kazior arg->phy_capab = ev->phy_capability; 28665c01aa3dSMichal Kazior arg->num_rf_chains = ev->num_rf_chains; 28675c01aa3dSMichal Kazior arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd; 28685c01aa3dSMichal Kazior arg->num_mem_reqs = ev->num_mem_reqs; 28695c01aa3dSMichal Kazior arg->service_map = ev->wmi_service_bitmap; 28702a3e60d3SMichal Kazior arg->service_map_len = sizeof(ev->wmi_service_bitmap); 28715c01aa3dSMichal Kazior 28725c01aa3dSMichal Kazior n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), 28735c01aa3dSMichal Kazior ARRAY_SIZE(arg->mem_reqs)); 28745c01aa3dSMichal Kazior for (i = 0; i < n; i++) 28755c01aa3dSMichal Kazior arg->mem_reqs[i] = &ev->mem_reqs[i]; 28765c01aa3dSMichal Kazior 28775c01aa3dSMichal Kazior if (skb->len < 28785c01aa3dSMichal Kazior __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0])) 28795c01aa3dSMichal Kazior return -EPROTO; 28805c01aa3dSMichal Kazior 28815c01aa3dSMichal Kazior return 0; 28825c01aa3dSMichal Kazior } 28835c01aa3dSMichal Kazior 28840226d602SMichal Kazior void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb) 28855e3dd157SKalle Valo { 28865c01aa3dSMichal Kazior struct wmi_svc_rdy_ev_arg arg = {}; 28875c01aa3dSMichal Kazior u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; 28885c01aa3dSMichal Kazior int ret; 28895e3dd157SKalle Valo 2890d7579d12SMichal Kazior ret = ath10k_wmi_pull_svc_rdy(ar, skb, &arg); 28915c01aa3dSMichal Kazior if (ret) { 28925c01aa3dSMichal Kazior ath10k_warn(ar, "failed to parse service ready: %d\n", ret); 28935e3dd157SKalle Valo return; 28945e3dd157SKalle Valo } 28955e3dd157SKalle Valo 2896d7579d12SMichal Kazior memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map)); 2897d7579d12SMichal Kazior ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map, 2898d7579d12SMichal Kazior arg.service_map_len); 2899d7579d12SMichal Kazior 29005c01aa3dSMichal Kazior ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power); 29015c01aa3dSMichal Kazior ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power); 29025c01aa3dSMichal Kazior ar->ht_cap_info = __le32_to_cpu(arg.ht_cap); 29035c01aa3dSMichal Kazior ar->vht_cap_info = __le32_to_cpu(arg.vht_cap); 29045e3dd157SKalle Valo ar->fw_version_major = 29055c01aa3dSMichal Kazior (__le32_to_cpu(arg.sw_ver0) & 0xff000000) >> 24; 29065c01aa3dSMichal Kazior ar->fw_version_minor = (__le32_to_cpu(arg.sw_ver0) & 0x00ffffff); 29075e3dd157SKalle Valo ar->fw_version_release = 29085c01aa3dSMichal Kazior (__le32_to_cpu(arg.sw_ver1) & 0xffff0000) >> 16; 29095c01aa3dSMichal Kazior ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff); 29105c01aa3dSMichal Kazior ar->phy_capability = __le32_to_cpu(arg.phy_capab); 29115c01aa3dSMichal Kazior ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains); 29125c01aa3dSMichal Kazior ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd); 29135c01aa3dSMichal Kazior 29145c01aa3dSMichal Kazior ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", 29152a3e60d3SMichal Kazior arg.service_map, arg.service_map_len); 29168865bee4SMichal Kazior 29171a222435SKalle Valo /* only manually set fw features when not using FW IE format */ 29181a222435SKalle Valo if (ar->fw_api == 1 && ar->fw_version_build > 636) 29190d9b0438SMichal Kazior set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); 29200d9b0438SMichal Kazior 29218865bee4SMichal Kazior if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { 29227aa7a72aSMichal Kazior ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", 29238865bee4SMichal Kazior ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); 29248865bee4SMichal Kazior ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; 29258865bee4SMichal Kazior } 29265e3dd157SKalle Valo 2927fdb959c7SMichal Kazior ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; 2928fdb959c7SMichal Kazior ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; 2929fdb959c7SMichal Kazior 29305e3dd157SKalle Valo if (strlen(ar->hw->wiphy->fw_version) == 0) { 29315e3dd157SKalle Valo snprintf(ar->hw->wiphy->fw_version, 29325e3dd157SKalle Valo sizeof(ar->hw->wiphy->fw_version), 29335e3dd157SKalle Valo "%u.%u.%u.%u", 29345e3dd157SKalle Valo ar->fw_version_major, 29355e3dd157SKalle Valo ar->fw_version_minor, 29365e3dd157SKalle Valo ar->fw_version_release, 29375e3dd157SKalle Valo ar->fw_version_build); 29385e3dd157SKalle Valo } 29395e3dd157SKalle Valo 29405c01aa3dSMichal Kazior num_mem_reqs = __le32_to_cpu(arg.num_mem_reqs); 29415c01aa3dSMichal Kazior if (num_mem_reqs > WMI_MAX_MEM_REQS) { 29427aa7a72aSMichal Kazior ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n", 2943b3effe61SBartosz Markowski num_mem_reqs); 2944b3effe61SBartosz Markowski return; 29456f97d256SBartosz Markowski } 29466f97d256SBartosz Markowski 2947b3effe61SBartosz Markowski for (i = 0; i < num_mem_reqs; ++i) { 29485c01aa3dSMichal Kazior req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id); 29495c01aa3dSMichal Kazior num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units); 29505c01aa3dSMichal Kazior unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size); 29515c01aa3dSMichal Kazior num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info); 2952b3effe61SBartosz Markowski 2953b3effe61SBartosz Markowski if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) 2954b3effe61SBartosz Markowski /* number of units to allocate is number of 2955b3effe61SBartosz Markowski * peers, 1 extra for self peer on target */ 2956b3effe61SBartosz Markowski /* this needs to be tied, host and target 2957b3effe61SBartosz Markowski * can get out of sync */ 2958ec6a73f0SBartosz Markowski num_units = TARGET_10X_NUM_PEERS + 1; 2959b3effe61SBartosz Markowski else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) 2960ec6a73f0SBartosz Markowski num_units = TARGET_10X_NUM_VDEVS + 1; 2961b3effe61SBartosz Markowski 29627aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 2963b3effe61SBartosz Markowski "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", 2964b3effe61SBartosz Markowski req_id, 29655c01aa3dSMichal Kazior __le32_to_cpu(arg.mem_reqs[i]->num_units), 2966b3effe61SBartosz Markowski num_unit_info, 2967b3effe61SBartosz Markowski unit_size, 2968b3effe61SBartosz Markowski num_units); 2969b3effe61SBartosz Markowski 2970b3effe61SBartosz Markowski ret = ath10k_wmi_alloc_host_mem(ar, req_id, num_units, 2971b3effe61SBartosz Markowski unit_size); 2972b3effe61SBartosz Markowski if (ret) 2973b3effe61SBartosz Markowski return; 2974b3effe61SBartosz Markowski } 2975b3effe61SBartosz Markowski 29767aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 2977ca996ec5SMichal Kazior "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x fw_build 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n", 29785c01aa3dSMichal Kazior __le32_to_cpu(arg.min_tx_power), 29795c01aa3dSMichal Kazior __le32_to_cpu(arg.max_tx_power), 29805c01aa3dSMichal Kazior __le32_to_cpu(arg.ht_cap), 29815c01aa3dSMichal Kazior __le32_to_cpu(arg.vht_cap), 29825c01aa3dSMichal Kazior __le32_to_cpu(arg.sw_ver0), 29835c01aa3dSMichal Kazior __le32_to_cpu(arg.sw_ver1), 2984ca996ec5SMichal Kazior __le32_to_cpu(arg.fw_build), 29855c01aa3dSMichal Kazior __le32_to_cpu(arg.phy_capab), 29865c01aa3dSMichal Kazior __le32_to_cpu(arg.num_rf_chains), 29875c01aa3dSMichal Kazior __le32_to_cpu(arg.eeprom_rd), 29885c01aa3dSMichal Kazior __le32_to_cpu(arg.num_mem_reqs)); 29896f97d256SBartosz Markowski 29906f97d256SBartosz Markowski complete(&ar->wmi.service_ready); 29916f97d256SBartosz Markowski } 29926f97d256SBartosz Markowski 2993d7579d12SMichal Kazior static int ath10k_wmi_op_pull_rdy_ev(struct ath10k *ar, struct sk_buff *skb, 299432653cf1SMichal Kazior struct wmi_rdy_ev_arg *arg) 299532653cf1SMichal Kazior { 299632653cf1SMichal Kazior struct wmi_ready_event *ev = (void *)skb->data; 299732653cf1SMichal Kazior 299832653cf1SMichal Kazior if (skb->len < sizeof(*ev)) 299932653cf1SMichal Kazior return -EPROTO; 300032653cf1SMichal Kazior 300132653cf1SMichal Kazior skb_pull(skb, sizeof(*ev)); 300232653cf1SMichal Kazior arg->sw_version = ev->sw_version; 300332653cf1SMichal Kazior arg->abi_version = ev->abi_version; 300432653cf1SMichal Kazior arg->status = ev->status; 300532653cf1SMichal Kazior arg->mac_addr = ev->mac_addr.addr; 300632653cf1SMichal Kazior 300732653cf1SMichal Kazior return 0; 300832653cf1SMichal Kazior } 300932653cf1SMichal Kazior 30100226d602SMichal Kazior int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) 30115e3dd157SKalle Valo { 301232653cf1SMichal Kazior struct wmi_rdy_ev_arg arg = {}; 301332653cf1SMichal Kazior int ret; 30145e3dd157SKalle Valo 3015d7579d12SMichal Kazior ret = ath10k_wmi_pull_rdy(ar, skb, &arg); 301632653cf1SMichal Kazior if (ret) { 301732653cf1SMichal Kazior ath10k_warn(ar, "failed to parse ready event: %d\n", ret); 301832653cf1SMichal Kazior return ret; 301932653cf1SMichal Kazior } 30205e3dd157SKalle Valo 30217aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 302232653cf1SMichal Kazior "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n", 302332653cf1SMichal Kazior __le32_to_cpu(arg.sw_version), 302432653cf1SMichal Kazior __le32_to_cpu(arg.abi_version), 302532653cf1SMichal Kazior arg.mac_addr, 302632653cf1SMichal Kazior __le32_to_cpu(arg.status)); 30275e3dd157SKalle Valo 302832653cf1SMichal Kazior ether_addr_copy(ar->mac_addr, arg.mac_addr); 30295e3dd157SKalle Valo complete(&ar->wmi.unified_ready); 30305e3dd157SKalle Valo return 0; 30315e3dd157SKalle Valo } 30325e3dd157SKalle Valo 3033a57a6a27SRajkumar Manoharan static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb) 3034a57a6a27SRajkumar Manoharan { 3035a57a6a27SRajkumar Manoharan const struct wmi_pdev_temperature_event *ev; 3036a57a6a27SRajkumar Manoharan 3037a57a6a27SRajkumar Manoharan ev = (struct wmi_pdev_temperature_event *)skb->data; 3038a57a6a27SRajkumar Manoharan if (WARN_ON(skb->len < sizeof(*ev))) 3039a57a6a27SRajkumar Manoharan return -EPROTO; 3040a57a6a27SRajkumar Manoharan 3041ac2953fcSRajkumar Manoharan ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature)); 3042a57a6a27SRajkumar Manoharan return 0; 3043a57a6a27SRajkumar Manoharan } 3044a57a6a27SRajkumar Manoharan 3045d7579d12SMichal Kazior static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) 30465e3dd157SKalle Valo { 30475e3dd157SKalle Valo struct wmi_cmd_hdr *cmd_hdr; 30485e3dd157SKalle Valo enum wmi_event_id id; 30495e3dd157SKalle Valo 30505e3dd157SKalle Valo cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 30515e3dd157SKalle Valo id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 30525e3dd157SKalle Valo 30535e3dd157SKalle Valo if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 30545e3dd157SKalle Valo return; 30555e3dd157SKalle Valo 3056d35a6c18SMichal Kazior trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 30575e3dd157SKalle Valo 30585e3dd157SKalle Valo switch (id) { 30595e3dd157SKalle Valo case WMI_MGMT_RX_EVENTID: 30605e3dd157SKalle Valo ath10k_wmi_event_mgmt_rx(ar, skb); 30615e3dd157SKalle Valo /* mgmt_rx() owns the skb now! */ 30625e3dd157SKalle Valo return; 30635e3dd157SKalle Valo case WMI_SCAN_EVENTID: 30645e3dd157SKalle Valo ath10k_wmi_event_scan(ar, skb); 30655e3dd157SKalle Valo break; 30665e3dd157SKalle Valo case WMI_CHAN_INFO_EVENTID: 30675e3dd157SKalle Valo ath10k_wmi_event_chan_info(ar, skb); 30685e3dd157SKalle Valo break; 30695e3dd157SKalle Valo case WMI_ECHO_EVENTID: 30705e3dd157SKalle Valo ath10k_wmi_event_echo(ar, skb); 30715e3dd157SKalle Valo break; 30725e3dd157SKalle Valo case WMI_DEBUG_MESG_EVENTID: 30735e3dd157SKalle Valo ath10k_wmi_event_debug_mesg(ar, skb); 30745e3dd157SKalle Valo break; 30755e3dd157SKalle Valo case WMI_UPDATE_STATS_EVENTID: 30765e3dd157SKalle Valo ath10k_wmi_event_update_stats(ar, skb); 30775e3dd157SKalle Valo break; 30785e3dd157SKalle Valo case WMI_VDEV_START_RESP_EVENTID: 30795e3dd157SKalle Valo ath10k_wmi_event_vdev_start_resp(ar, skb); 30805e3dd157SKalle Valo break; 30815e3dd157SKalle Valo case WMI_VDEV_STOPPED_EVENTID: 30825e3dd157SKalle Valo ath10k_wmi_event_vdev_stopped(ar, skb); 30835e3dd157SKalle Valo break; 30845e3dd157SKalle Valo case WMI_PEER_STA_KICKOUT_EVENTID: 30855e3dd157SKalle Valo ath10k_wmi_event_peer_sta_kickout(ar, skb); 30865e3dd157SKalle Valo break; 30875e3dd157SKalle Valo case WMI_HOST_SWBA_EVENTID: 30885e3dd157SKalle Valo ath10k_wmi_event_host_swba(ar, skb); 30895e3dd157SKalle Valo break; 30905e3dd157SKalle Valo case WMI_TBTTOFFSET_UPDATE_EVENTID: 30915e3dd157SKalle Valo ath10k_wmi_event_tbttoffset_update(ar, skb); 30925e3dd157SKalle Valo break; 30935e3dd157SKalle Valo case WMI_PHYERR_EVENTID: 30945e3dd157SKalle Valo ath10k_wmi_event_phyerr(ar, skb); 30955e3dd157SKalle Valo break; 30965e3dd157SKalle Valo case WMI_ROAM_EVENTID: 30975e3dd157SKalle Valo ath10k_wmi_event_roam(ar, skb); 30985e3dd157SKalle Valo break; 30995e3dd157SKalle Valo case WMI_PROFILE_MATCH: 31005e3dd157SKalle Valo ath10k_wmi_event_profile_match(ar, skb); 31015e3dd157SKalle Valo break; 31025e3dd157SKalle Valo case WMI_DEBUG_PRINT_EVENTID: 31035e3dd157SKalle Valo ath10k_wmi_event_debug_print(ar, skb); 31045e3dd157SKalle Valo break; 31055e3dd157SKalle Valo case WMI_PDEV_QVIT_EVENTID: 31065e3dd157SKalle Valo ath10k_wmi_event_pdev_qvit(ar, skb); 31075e3dd157SKalle Valo break; 31085e3dd157SKalle Valo case WMI_WLAN_PROFILE_DATA_EVENTID: 31095e3dd157SKalle Valo ath10k_wmi_event_wlan_profile_data(ar, skb); 31105e3dd157SKalle Valo break; 31115e3dd157SKalle Valo case WMI_RTT_MEASUREMENT_REPORT_EVENTID: 31125e3dd157SKalle Valo ath10k_wmi_event_rtt_measurement_report(ar, skb); 31135e3dd157SKalle Valo break; 31145e3dd157SKalle Valo case WMI_TSF_MEASUREMENT_REPORT_EVENTID: 31155e3dd157SKalle Valo ath10k_wmi_event_tsf_measurement_report(ar, skb); 31165e3dd157SKalle Valo break; 31175e3dd157SKalle Valo case WMI_RTT_ERROR_REPORT_EVENTID: 31185e3dd157SKalle Valo ath10k_wmi_event_rtt_error_report(ar, skb); 31195e3dd157SKalle Valo break; 31205e3dd157SKalle Valo case WMI_WOW_WAKEUP_HOST_EVENTID: 31215e3dd157SKalle Valo ath10k_wmi_event_wow_wakeup_host(ar, skb); 31225e3dd157SKalle Valo break; 31235e3dd157SKalle Valo case WMI_DCS_INTERFERENCE_EVENTID: 31245e3dd157SKalle Valo ath10k_wmi_event_dcs_interference(ar, skb); 31255e3dd157SKalle Valo break; 31265e3dd157SKalle Valo case WMI_PDEV_TPC_CONFIG_EVENTID: 31275e3dd157SKalle Valo ath10k_wmi_event_pdev_tpc_config(ar, skb); 31285e3dd157SKalle Valo break; 31295e3dd157SKalle Valo case WMI_PDEV_FTM_INTG_EVENTID: 31305e3dd157SKalle Valo ath10k_wmi_event_pdev_ftm_intg(ar, skb); 31315e3dd157SKalle Valo break; 31325e3dd157SKalle Valo case WMI_GTK_OFFLOAD_STATUS_EVENTID: 31335e3dd157SKalle Valo ath10k_wmi_event_gtk_offload_status(ar, skb); 31345e3dd157SKalle Valo break; 31355e3dd157SKalle Valo case WMI_GTK_REKEY_FAIL_EVENTID: 31365e3dd157SKalle Valo ath10k_wmi_event_gtk_rekey_fail(ar, skb); 31375e3dd157SKalle Valo break; 31385e3dd157SKalle Valo case WMI_TX_DELBA_COMPLETE_EVENTID: 31395e3dd157SKalle Valo ath10k_wmi_event_delba_complete(ar, skb); 31405e3dd157SKalle Valo break; 31415e3dd157SKalle Valo case WMI_TX_ADDBA_COMPLETE_EVENTID: 31425e3dd157SKalle Valo ath10k_wmi_event_addba_complete(ar, skb); 31435e3dd157SKalle Valo break; 31445e3dd157SKalle Valo case WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID: 31455e3dd157SKalle Valo ath10k_wmi_event_vdev_install_key_complete(ar, skb); 31465e3dd157SKalle Valo break; 31475e3dd157SKalle Valo case WMI_SERVICE_READY_EVENTID: 3148b34d2b3dSMichal Kazior ath10k_wmi_event_service_ready(ar, skb); 31495e3dd157SKalle Valo break; 31505e3dd157SKalle Valo case WMI_READY_EVENTID: 3151b34d2b3dSMichal Kazior ath10k_wmi_event_ready(ar, skb); 31525e3dd157SKalle Valo break; 31535e3dd157SKalle Valo default: 31547aa7a72aSMichal Kazior ath10k_warn(ar, "Unknown eventid: %d\n", id); 31555e3dd157SKalle Valo break; 31565e3dd157SKalle Valo } 31575e3dd157SKalle Valo 31585e3dd157SKalle Valo dev_kfree_skb(skb); 31595e3dd157SKalle Valo } 31605e3dd157SKalle Valo 3161d7579d12SMichal Kazior static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb) 31628a6618b0SBartosz Markowski { 31638a6618b0SBartosz Markowski struct wmi_cmd_hdr *cmd_hdr; 31648a6618b0SBartosz Markowski enum wmi_10x_event_id id; 316543d2a30fSKalle Valo bool consumed; 31668a6618b0SBartosz Markowski 31678a6618b0SBartosz Markowski cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 31688a6618b0SBartosz Markowski id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 31698a6618b0SBartosz Markowski 31708a6618b0SBartosz Markowski if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 31718a6618b0SBartosz Markowski return; 31728a6618b0SBartosz Markowski 3173d35a6c18SMichal Kazior trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 31748a6618b0SBartosz Markowski 317543d2a30fSKalle Valo consumed = ath10k_tm_event_wmi(ar, id, skb); 317643d2a30fSKalle Valo 317743d2a30fSKalle Valo /* Ready event must be handled normally also in UTF mode so that we 317843d2a30fSKalle Valo * know the UTF firmware has booted, others we are just bypass WMI 317943d2a30fSKalle Valo * events to testmode. 318043d2a30fSKalle Valo */ 318143d2a30fSKalle Valo if (consumed && id != WMI_10X_READY_EVENTID) { 318243d2a30fSKalle Valo ath10k_dbg(ar, ATH10K_DBG_WMI, 318343d2a30fSKalle Valo "wmi testmode consumed 0x%x\n", id); 318443d2a30fSKalle Valo goto out; 318543d2a30fSKalle Valo } 318643d2a30fSKalle Valo 31878a6618b0SBartosz Markowski switch (id) { 31888a6618b0SBartosz Markowski case WMI_10X_MGMT_RX_EVENTID: 31898a6618b0SBartosz Markowski ath10k_wmi_event_mgmt_rx(ar, skb); 31908a6618b0SBartosz Markowski /* mgmt_rx() owns the skb now! */ 31918a6618b0SBartosz Markowski return; 31928a6618b0SBartosz Markowski case WMI_10X_SCAN_EVENTID: 31938a6618b0SBartosz Markowski ath10k_wmi_event_scan(ar, skb); 31948a6618b0SBartosz Markowski break; 31958a6618b0SBartosz Markowski case WMI_10X_CHAN_INFO_EVENTID: 31968a6618b0SBartosz Markowski ath10k_wmi_event_chan_info(ar, skb); 31978a6618b0SBartosz Markowski break; 31988a6618b0SBartosz Markowski case WMI_10X_ECHO_EVENTID: 31998a6618b0SBartosz Markowski ath10k_wmi_event_echo(ar, skb); 32008a6618b0SBartosz Markowski break; 32018a6618b0SBartosz Markowski case WMI_10X_DEBUG_MESG_EVENTID: 32028a6618b0SBartosz Markowski ath10k_wmi_event_debug_mesg(ar, skb); 32038a6618b0SBartosz Markowski break; 32048a6618b0SBartosz Markowski case WMI_10X_UPDATE_STATS_EVENTID: 32058a6618b0SBartosz Markowski ath10k_wmi_event_update_stats(ar, skb); 32068a6618b0SBartosz Markowski break; 32078a6618b0SBartosz Markowski case WMI_10X_VDEV_START_RESP_EVENTID: 32088a6618b0SBartosz Markowski ath10k_wmi_event_vdev_start_resp(ar, skb); 32098a6618b0SBartosz Markowski break; 32108a6618b0SBartosz Markowski case WMI_10X_VDEV_STOPPED_EVENTID: 32118a6618b0SBartosz Markowski ath10k_wmi_event_vdev_stopped(ar, skb); 32128a6618b0SBartosz Markowski break; 32138a6618b0SBartosz Markowski case WMI_10X_PEER_STA_KICKOUT_EVENTID: 32148a6618b0SBartosz Markowski ath10k_wmi_event_peer_sta_kickout(ar, skb); 32158a6618b0SBartosz Markowski break; 32168a6618b0SBartosz Markowski case WMI_10X_HOST_SWBA_EVENTID: 32178a6618b0SBartosz Markowski ath10k_wmi_event_host_swba(ar, skb); 32188a6618b0SBartosz Markowski break; 32198a6618b0SBartosz Markowski case WMI_10X_TBTTOFFSET_UPDATE_EVENTID: 32208a6618b0SBartosz Markowski ath10k_wmi_event_tbttoffset_update(ar, skb); 32218a6618b0SBartosz Markowski break; 32228a6618b0SBartosz Markowski case WMI_10X_PHYERR_EVENTID: 32238a6618b0SBartosz Markowski ath10k_wmi_event_phyerr(ar, skb); 32248a6618b0SBartosz Markowski break; 32258a6618b0SBartosz Markowski case WMI_10X_ROAM_EVENTID: 32268a6618b0SBartosz Markowski ath10k_wmi_event_roam(ar, skb); 32278a6618b0SBartosz Markowski break; 32288a6618b0SBartosz Markowski case WMI_10X_PROFILE_MATCH: 32298a6618b0SBartosz Markowski ath10k_wmi_event_profile_match(ar, skb); 32308a6618b0SBartosz Markowski break; 32318a6618b0SBartosz Markowski case WMI_10X_DEBUG_PRINT_EVENTID: 32328a6618b0SBartosz Markowski ath10k_wmi_event_debug_print(ar, skb); 32338a6618b0SBartosz Markowski break; 32348a6618b0SBartosz Markowski case WMI_10X_PDEV_QVIT_EVENTID: 32358a6618b0SBartosz Markowski ath10k_wmi_event_pdev_qvit(ar, skb); 32368a6618b0SBartosz Markowski break; 32378a6618b0SBartosz Markowski case WMI_10X_WLAN_PROFILE_DATA_EVENTID: 32388a6618b0SBartosz Markowski ath10k_wmi_event_wlan_profile_data(ar, skb); 32398a6618b0SBartosz Markowski break; 32408a6618b0SBartosz Markowski case WMI_10X_RTT_MEASUREMENT_REPORT_EVENTID: 32418a6618b0SBartosz Markowski ath10k_wmi_event_rtt_measurement_report(ar, skb); 32428a6618b0SBartosz Markowski break; 32438a6618b0SBartosz Markowski case WMI_10X_TSF_MEASUREMENT_REPORT_EVENTID: 32448a6618b0SBartosz Markowski ath10k_wmi_event_tsf_measurement_report(ar, skb); 32458a6618b0SBartosz Markowski break; 32468a6618b0SBartosz Markowski case WMI_10X_RTT_ERROR_REPORT_EVENTID: 32478a6618b0SBartosz Markowski ath10k_wmi_event_rtt_error_report(ar, skb); 32488a6618b0SBartosz Markowski break; 32498a6618b0SBartosz Markowski case WMI_10X_WOW_WAKEUP_HOST_EVENTID: 32508a6618b0SBartosz Markowski ath10k_wmi_event_wow_wakeup_host(ar, skb); 32518a6618b0SBartosz Markowski break; 32528a6618b0SBartosz Markowski case WMI_10X_DCS_INTERFERENCE_EVENTID: 32538a6618b0SBartosz Markowski ath10k_wmi_event_dcs_interference(ar, skb); 32548a6618b0SBartosz Markowski break; 32558a6618b0SBartosz Markowski case WMI_10X_PDEV_TPC_CONFIG_EVENTID: 32568a6618b0SBartosz Markowski ath10k_wmi_event_pdev_tpc_config(ar, skb); 32578a6618b0SBartosz Markowski break; 32588a6618b0SBartosz Markowski case WMI_10X_INST_RSSI_STATS_EVENTID: 32598a6618b0SBartosz Markowski ath10k_wmi_event_inst_rssi_stats(ar, skb); 32608a6618b0SBartosz Markowski break; 32618a6618b0SBartosz Markowski case WMI_10X_VDEV_STANDBY_REQ_EVENTID: 32628a6618b0SBartosz Markowski ath10k_wmi_event_vdev_standby_req(ar, skb); 32638a6618b0SBartosz Markowski break; 32648a6618b0SBartosz Markowski case WMI_10X_VDEV_RESUME_REQ_EVENTID: 32658a6618b0SBartosz Markowski ath10k_wmi_event_vdev_resume_req(ar, skb); 32668a6618b0SBartosz Markowski break; 32678a6618b0SBartosz Markowski case WMI_10X_SERVICE_READY_EVENTID: 3268b34d2b3dSMichal Kazior ath10k_wmi_event_service_ready(ar, skb); 32698a6618b0SBartosz Markowski break; 32708a6618b0SBartosz Markowski case WMI_10X_READY_EVENTID: 3271b34d2b3dSMichal Kazior ath10k_wmi_event_ready(ar, skb); 32728a6618b0SBartosz Markowski break; 327343d2a30fSKalle Valo case WMI_10X_PDEV_UTF_EVENTID: 327443d2a30fSKalle Valo /* ignore utf events */ 327543d2a30fSKalle Valo break; 32768a6618b0SBartosz Markowski default: 32777aa7a72aSMichal Kazior ath10k_warn(ar, "Unknown eventid: %d\n", id); 32788a6618b0SBartosz Markowski break; 32798a6618b0SBartosz Markowski } 32808a6618b0SBartosz Markowski 328143d2a30fSKalle Valo out: 32828a6618b0SBartosz Markowski dev_kfree_skb(skb); 32838a6618b0SBartosz Markowski } 32848a6618b0SBartosz Markowski 3285d7579d12SMichal Kazior static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb) 328624c88f78SMichal Kazior { 328724c88f78SMichal Kazior struct wmi_cmd_hdr *cmd_hdr; 328824c88f78SMichal Kazior enum wmi_10_2_event_id id; 328924c88f78SMichal Kazior 329024c88f78SMichal Kazior cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 329124c88f78SMichal Kazior id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 329224c88f78SMichal Kazior 329324c88f78SMichal Kazior if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 329424c88f78SMichal Kazior return; 329524c88f78SMichal Kazior 3296d35a6c18SMichal Kazior trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 329724c88f78SMichal Kazior 329824c88f78SMichal Kazior switch (id) { 329924c88f78SMichal Kazior case WMI_10_2_MGMT_RX_EVENTID: 330024c88f78SMichal Kazior ath10k_wmi_event_mgmt_rx(ar, skb); 330124c88f78SMichal Kazior /* mgmt_rx() owns the skb now! */ 330224c88f78SMichal Kazior return; 330324c88f78SMichal Kazior case WMI_10_2_SCAN_EVENTID: 330424c88f78SMichal Kazior ath10k_wmi_event_scan(ar, skb); 330524c88f78SMichal Kazior break; 330624c88f78SMichal Kazior case WMI_10_2_CHAN_INFO_EVENTID: 330724c88f78SMichal Kazior ath10k_wmi_event_chan_info(ar, skb); 330824c88f78SMichal Kazior break; 330924c88f78SMichal Kazior case WMI_10_2_ECHO_EVENTID: 331024c88f78SMichal Kazior ath10k_wmi_event_echo(ar, skb); 331124c88f78SMichal Kazior break; 331224c88f78SMichal Kazior case WMI_10_2_DEBUG_MESG_EVENTID: 331324c88f78SMichal Kazior ath10k_wmi_event_debug_mesg(ar, skb); 331424c88f78SMichal Kazior break; 331524c88f78SMichal Kazior case WMI_10_2_UPDATE_STATS_EVENTID: 331624c88f78SMichal Kazior ath10k_wmi_event_update_stats(ar, skb); 331724c88f78SMichal Kazior break; 331824c88f78SMichal Kazior case WMI_10_2_VDEV_START_RESP_EVENTID: 331924c88f78SMichal Kazior ath10k_wmi_event_vdev_start_resp(ar, skb); 332024c88f78SMichal Kazior break; 332124c88f78SMichal Kazior case WMI_10_2_VDEV_STOPPED_EVENTID: 332224c88f78SMichal Kazior ath10k_wmi_event_vdev_stopped(ar, skb); 332324c88f78SMichal Kazior break; 332424c88f78SMichal Kazior case WMI_10_2_PEER_STA_KICKOUT_EVENTID: 332524c88f78SMichal Kazior ath10k_wmi_event_peer_sta_kickout(ar, skb); 332624c88f78SMichal Kazior break; 332724c88f78SMichal Kazior case WMI_10_2_HOST_SWBA_EVENTID: 332824c88f78SMichal Kazior ath10k_wmi_event_host_swba(ar, skb); 332924c88f78SMichal Kazior break; 333024c88f78SMichal Kazior case WMI_10_2_TBTTOFFSET_UPDATE_EVENTID: 333124c88f78SMichal Kazior ath10k_wmi_event_tbttoffset_update(ar, skb); 333224c88f78SMichal Kazior break; 333324c88f78SMichal Kazior case WMI_10_2_PHYERR_EVENTID: 333424c88f78SMichal Kazior ath10k_wmi_event_phyerr(ar, skb); 333524c88f78SMichal Kazior break; 333624c88f78SMichal Kazior case WMI_10_2_ROAM_EVENTID: 333724c88f78SMichal Kazior ath10k_wmi_event_roam(ar, skb); 333824c88f78SMichal Kazior break; 333924c88f78SMichal Kazior case WMI_10_2_PROFILE_MATCH: 334024c88f78SMichal Kazior ath10k_wmi_event_profile_match(ar, skb); 334124c88f78SMichal Kazior break; 334224c88f78SMichal Kazior case WMI_10_2_DEBUG_PRINT_EVENTID: 334324c88f78SMichal Kazior ath10k_wmi_event_debug_print(ar, skb); 334424c88f78SMichal Kazior break; 334524c88f78SMichal Kazior case WMI_10_2_PDEV_QVIT_EVENTID: 334624c88f78SMichal Kazior ath10k_wmi_event_pdev_qvit(ar, skb); 334724c88f78SMichal Kazior break; 334824c88f78SMichal Kazior case WMI_10_2_WLAN_PROFILE_DATA_EVENTID: 334924c88f78SMichal Kazior ath10k_wmi_event_wlan_profile_data(ar, skb); 335024c88f78SMichal Kazior break; 335124c88f78SMichal Kazior case WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID: 335224c88f78SMichal Kazior ath10k_wmi_event_rtt_measurement_report(ar, skb); 335324c88f78SMichal Kazior break; 335424c88f78SMichal Kazior case WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID: 335524c88f78SMichal Kazior ath10k_wmi_event_tsf_measurement_report(ar, skb); 335624c88f78SMichal Kazior break; 335724c88f78SMichal Kazior case WMI_10_2_RTT_ERROR_REPORT_EVENTID: 335824c88f78SMichal Kazior ath10k_wmi_event_rtt_error_report(ar, skb); 335924c88f78SMichal Kazior break; 336024c88f78SMichal Kazior case WMI_10_2_WOW_WAKEUP_HOST_EVENTID: 336124c88f78SMichal Kazior ath10k_wmi_event_wow_wakeup_host(ar, skb); 336224c88f78SMichal Kazior break; 336324c88f78SMichal Kazior case WMI_10_2_DCS_INTERFERENCE_EVENTID: 336424c88f78SMichal Kazior ath10k_wmi_event_dcs_interference(ar, skb); 336524c88f78SMichal Kazior break; 336624c88f78SMichal Kazior case WMI_10_2_PDEV_TPC_CONFIG_EVENTID: 336724c88f78SMichal Kazior ath10k_wmi_event_pdev_tpc_config(ar, skb); 336824c88f78SMichal Kazior break; 336924c88f78SMichal Kazior case WMI_10_2_INST_RSSI_STATS_EVENTID: 337024c88f78SMichal Kazior ath10k_wmi_event_inst_rssi_stats(ar, skb); 337124c88f78SMichal Kazior break; 337224c88f78SMichal Kazior case WMI_10_2_VDEV_STANDBY_REQ_EVENTID: 337324c88f78SMichal Kazior ath10k_wmi_event_vdev_standby_req(ar, skb); 337424c88f78SMichal Kazior break; 337524c88f78SMichal Kazior case WMI_10_2_VDEV_RESUME_REQ_EVENTID: 337624c88f78SMichal Kazior ath10k_wmi_event_vdev_resume_req(ar, skb); 337724c88f78SMichal Kazior break; 337824c88f78SMichal Kazior case WMI_10_2_SERVICE_READY_EVENTID: 3379b34d2b3dSMichal Kazior ath10k_wmi_event_service_ready(ar, skb); 338024c88f78SMichal Kazior break; 338124c88f78SMichal Kazior case WMI_10_2_READY_EVENTID: 3382b34d2b3dSMichal Kazior ath10k_wmi_event_ready(ar, skb); 338324c88f78SMichal Kazior break; 3384a57a6a27SRajkumar Manoharan case WMI_10_2_PDEV_TEMPERATURE_EVENTID: 3385a57a6a27SRajkumar Manoharan ath10k_wmi_event_temperature(ar, skb); 3386a57a6a27SRajkumar Manoharan break; 338724c88f78SMichal Kazior case WMI_10_2_RTT_KEEPALIVE_EVENTID: 338824c88f78SMichal Kazior case WMI_10_2_GPIO_INPUT_EVENTID: 338924c88f78SMichal Kazior case WMI_10_2_PEER_RATECODE_LIST_EVENTID: 339024c88f78SMichal Kazior case WMI_10_2_GENERIC_BUFFER_EVENTID: 339124c88f78SMichal Kazior case WMI_10_2_MCAST_BUF_RELEASE_EVENTID: 339224c88f78SMichal Kazior case WMI_10_2_MCAST_LIST_AGEOUT_EVENTID: 339324c88f78SMichal Kazior case WMI_10_2_WDS_PEER_EVENTID: 33947aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 339524c88f78SMichal Kazior "received event id %d not implemented\n", id); 339624c88f78SMichal Kazior break; 339724c88f78SMichal Kazior default: 33987aa7a72aSMichal Kazior ath10k_warn(ar, "Unknown eventid: %d\n", id); 339924c88f78SMichal Kazior break; 340024c88f78SMichal Kazior } 340124c88f78SMichal Kazior 340224c88f78SMichal Kazior dev_kfree_skb(skb); 340324c88f78SMichal Kazior } 34048a6618b0SBartosz Markowski 3405ce42870eSBartosz Markowski static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) 3406ce42870eSBartosz Markowski { 3407d7579d12SMichal Kazior int ret; 3408d7579d12SMichal Kazior 3409d7579d12SMichal Kazior ret = ath10k_wmi_rx(ar, skb); 3410d7579d12SMichal Kazior if (ret) 3411d7579d12SMichal Kazior ath10k_warn(ar, "failed to process wmi rx: %d\n", ret); 341224c88f78SMichal Kazior } 3413ce42870eSBartosz Markowski 341495bf21f9SMichal Kazior int ath10k_wmi_connect(struct ath10k *ar) 34155e3dd157SKalle Valo { 34165e3dd157SKalle Valo int status; 34175e3dd157SKalle Valo struct ath10k_htc_svc_conn_req conn_req; 34185e3dd157SKalle Valo struct ath10k_htc_svc_conn_resp conn_resp; 34195e3dd157SKalle Valo 34205e3dd157SKalle Valo memset(&conn_req, 0, sizeof(conn_req)); 34215e3dd157SKalle Valo memset(&conn_resp, 0, sizeof(conn_resp)); 34225e3dd157SKalle Valo 34235e3dd157SKalle Valo /* these fields are the same for all service endpoints */ 34245e3dd157SKalle Valo conn_req.ep_ops.ep_tx_complete = ath10k_wmi_htc_tx_complete; 34255e3dd157SKalle Valo conn_req.ep_ops.ep_rx_complete = ath10k_wmi_process_rx; 3426be8b3943SMichal Kazior conn_req.ep_ops.ep_tx_credits = ath10k_wmi_op_ep_tx_credits; 34275e3dd157SKalle Valo 34285e3dd157SKalle Valo /* connect to control service */ 34295e3dd157SKalle Valo conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL; 34305e3dd157SKalle Valo 3431cd003fadSMichal Kazior status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp); 34325e3dd157SKalle Valo if (status) { 34337aa7a72aSMichal Kazior ath10k_warn(ar, "failed to connect to WMI CONTROL service status: %d\n", 34345e3dd157SKalle Valo status); 34355e3dd157SKalle Valo return status; 34365e3dd157SKalle Valo } 34375e3dd157SKalle Valo 34385e3dd157SKalle Valo ar->wmi.eid = conn_resp.eid; 34395e3dd157SKalle Valo return 0; 34405e3dd157SKalle Valo } 34415e3dd157SKalle Valo 3442d7579d12SMichal Kazior static struct sk_buff * 3443d7579d12SMichal Kazior ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g, 3444d7579d12SMichal Kazior u16 ctl2g, u16 ctl5g, 3445d7579d12SMichal Kazior enum wmi_dfs_region dfs_reg) 34465e3dd157SKalle Valo { 34475e3dd157SKalle Valo struct wmi_pdev_set_regdomain_cmd *cmd; 34485e3dd157SKalle Valo struct sk_buff *skb; 34495e3dd157SKalle Valo 34507aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 34515e3dd157SKalle Valo if (!skb) 3452d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 34535e3dd157SKalle Valo 34545e3dd157SKalle Valo cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data; 34555e3dd157SKalle Valo cmd->reg_domain = __cpu_to_le32(rd); 34565e3dd157SKalle Valo cmd->reg_domain_2G = __cpu_to_le32(rd2g); 34575e3dd157SKalle Valo cmd->reg_domain_5G = __cpu_to_le32(rd5g); 34585e3dd157SKalle Valo cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g); 34595e3dd157SKalle Valo cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); 34605e3dd157SKalle Valo 34617aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 34625e3dd157SKalle Valo "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", 34635e3dd157SKalle Valo rd, rd2g, rd5g, ctl2g, ctl5g); 3464d7579d12SMichal Kazior return skb; 34655e3dd157SKalle Valo } 34665e3dd157SKalle Valo 3467d7579d12SMichal Kazior static struct sk_buff * 3468d7579d12SMichal Kazior ath10k_wmi_10x_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 3469d7579d12SMichal Kazior rd5g, u16 ctl2g, u16 ctl5g, 3470821af6aeSMarek Puzyniak enum wmi_dfs_region dfs_reg) 3471821af6aeSMarek Puzyniak { 3472821af6aeSMarek Puzyniak struct wmi_pdev_set_regdomain_cmd_10x *cmd; 3473821af6aeSMarek Puzyniak struct sk_buff *skb; 3474821af6aeSMarek Puzyniak 34757aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3476821af6aeSMarek Puzyniak if (!skb) 3477d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 3478821af6aeSMarek Puzyniak 3479821af6aeSMarek Puzyniak cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data; 3480821af6aeSMarek Puzyniak cmd->reg_domain = __cpu_to_le32(rd); 3481821af6aeSMarek Puzyniak cmd->reg_domain_2G = __cpu_to_le32(rd2g); 3482821af6aeSMarek Puzyniak cmd->reg_domain_5G = __cpu_to_le32(rd5g); 3483821af6aeSMarek Puzyniak cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g); 3484821af6aeSMarek Puzyniak cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); 3485821af6aeSMarek Puzyniak cmd->dfs_domain = __cpu_to_le32(dfs_reg); 3486821af6aeSMarek Puzyniak 34877aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 3488821af6aeSMarek Puzyniak "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n", 3489821af6aeSMarek Puzyniak rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg); 3490d7579d12SMichal Kazior return skb; 3491821af6aeSMarek Puzyniak } 3492821af6aeSMarek Puzyniak 3493d7579d12SMichal Kazior static struct sk_buff * 3494d7579d12SMichal Kazior ath10k_wmi_op_gen_pdev_suspend(struct ath10k *ar, u32 suspend_opt) 34955e3dd157SKalle Valo { 34965e3dd157SKalle Valo struct wmi_pdev_suspend_cmd *cmd; 34975e3dd157SKalle Valo struct sk_buff *skb; 34985e3dd157SKalle Valo 34997aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 35005e3dd157SKalle Valo if (!skb) 3501d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 35025e3dd157SKalle Valo 35035e3dd157SKalle Valo cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 350400f5482bSMarek Puzyniak cmd->suspend_opt = __cpu_to_le32(suspend_opt); 35055e3dd157SKalle Valo 3506d7579d12SMichal Kazior return skb; 35075e3dd157SKalle Valo } 35085e3dd157SKalle Valo 3509d7579d12SMichal Kazior static struct sk_buff * 3510d7579d12SMichal Kazior ath10k_wmi_op_gen_pdev_resume(struct ath10k *ar) 35115e3dd157SKalle Valo { 35125e3dd157SKalle Valo struct sk_buff *skb; 35135e3dd157SKalle Valo 35147aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, 0); 3515d7579d12SMichal Kazior if (!skb) 3516d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 35175e3dd157SKalle Valo 3518d7579d12SMichal Kazior return skb; 35195e3dd157SKalle Valo } 35205e3dd157SKalle Valo 3521d7579d12SMichal Kazior static struct sk_buff * 3522d7579d12SMichal Kazior ath10k_wmi_op_gen_pdev_set_param(struct ath10k *ar, u32 id, u32 value) 35235e3dd157SKalle Valo { 35245e3dd157SKalle Valo struct wmi_pdev_set_param_cmd *cmd; 35255e3dd157SKalle Valo struct sk_buff *skb; 35265e3dd157SKalle Valo 3527226a339bSBartosz Markowski if (id == WMI_PDEV_PARAM_UNSUPPORTED) { 35287aa7a72aSMichal Kazior ath10k_warn(ar, "pdev param %d not supported by firmware\n", 35297aa7a72aSMichal Kazior id); 3530d7579d12SMichal Kazior return ERR_PTR(-EOPNOTSUPP); 3531226a339bSBartosz Markowski } 3532226a339bSBartosz Markowski 35337aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 35345e3dd157SKalle Valo if (!skb) 3535d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 35365e3dd157SKalle Valo 35375e3dd157SKalle Valo cmd = (struct wmi_pdev_set_param_cmd *)skb->data; 35385e3dd157SKalle Valo cmd->param_id = __cpu_to_le32(id); 35395e3dd157SKalle Valo cmd->param_value = __cpu_to_le32(value); 35405e3dd157SKalle Valo 35417aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", 35425e3dd157SKalle Valo id, value); 3543d7579d12SMichal Kazior return skb; 35445e3dd157SKalle Valo } 35455e3dd157SKalle Valo 35460226d602SMichal Kazior void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar, 3547cf9fca8fSMichal Kazior struct wmi_host_mem_chunks *chunks) 3548cf9fca8fSMichal Kazior { 3549cf9fca8fSMichal Kazior struct host_memory_chunk *chunk; 3550cf9fca8fSMichal Kazior int i; 3551cf9fca8fSMichal Kazior 3552cf9fca8fSMichal Kazior chunks->count = __cpu_to_le32(ar->wmi.num_mem_chunks); 3553cf9fca8fSMichal Kazior 3554cf9fca8fSMichal Kazior for (i = 0; i < ar->wmi.num_mem_chunks; i++) { 3555cf9fca8fSMichal Kazior chunk = &chunks->items[i]; 3556cf9fca8fSMichal Kazior chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); 3557cf9fca8fSMichal Kazior chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len); 3558cf9fca8fSMichal Kazior chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); 3559cf9fca8fSMichal Kazior 3560cf9fca8fSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 3561cf9fca8fSMichal Kazior "wmi chunk %d len %d requested, addr 0x%llx\n", 3562cf9fca8fSMichal Kazior i, 3563cf9fca8fSMichal Kazior ar->wmi.mem_chunks[i].len, 3564cf9fca8fSMichal Kazior (unsigned long long)ar->wmi.mem_chunks[i].paddr); 3565cf9fca8fSMichal Kazior } 3566cf9fca8fSMichal Kazior } 3567cf9fca8fSMichal Kazior 3568d7579d12SMichal Kazior static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar) 35695e3dd157SKalle Valo { 35705e3dd157SKalle Valo struct wmi_init_cmd *cmd; 35715e3dd157SKalle Valo struct sk_buff *buf; 35725e3dd157SKalle Valo struct wmi_resource_config config = {}; 3573b3effe61SBartosz Markowski u32 len, val; 35745e3dd157SKalle Valo 35755e3dd157SKalle Valo config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); 3576cfd1061eSMichal Kazior config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS); 35775e3dd157SKalle Valo config.num_offload_peers = __cpu_to_le32(TARGET_NUM_OFFLOAD_PEERS); 35785e3dd157SKalle Valo 35795e3dd157SKalle Valo config.num_offload_reorder_bufs = 35805e3dd157SKalle Valo __cpu_to_le32(TARGET_NUM_OFFLOAD_REORDER_BUFS); 35815e3dd157SKalle Valo 35825e3dd157SKalle Valo config.num_peer_keys = __cpu_to_le32(TARGET_NUM_PEER_KEYS); 35835e3dd157SKalle Valo config.num_tids = __cpu_to_le32(TARGET_NUM_TIDS); 35845e3dd157SKalle Valo config.ast_skid_limit = __cpu_to_le32(TARGET_AST_SKID_LIMIT); 35855e3dd157SKalle Valo config.tx_chain_mask = __cpu_to_le32(TARGET_TX_CHAIN_MASK); 35865e3dd157SKalle Valo config.rx_chain_mask = __cpu_to_le32(TARGET_RX_CHAIN_MASK); 35875e3dd157SKalle Valo config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI); 35885e3dd157SKalle Valo config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI); 35895e3dd157SKalle Valo config.rx_timeout_pri_be = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI); 35905e3dd157SKalle Valo config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_RX_TIMEOUT_HI_PRI); 35915e3dd157SKalle Valo config.rx_decap_mode = __cpu_to_le32(TARGET_RX_DECAP_MODE); 35925e3dd157SKalle Valo 35935e3dd157SKalle Valo config.scan_max_pending_reqs = 35945e3dd157SKalle Valo __cpu_to_le32(TARGET_SCAN_MAX_PENDING_REQS); 35955e3dd157SKalle Valo 35965e3dd157SKalle Valo config.bmiss_offload_max_vdev = 35975e3dd157SKalle Valo __cpu_to_le32(TARGET_BMISS_OFFLOAD_MAX_VDEV); 35985e3dd157SKalle Valo 35995e3dd157SKalle Valo config.roam_offload_max_vdev = 36005e3dd157SKalle Valo __cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_VDEV); 36015e3dd157SKalle Valo 36025e3dd157SKalle Valo config.roam_offload_max_ap_profiles = 36035e3dd157SKalle Valo __cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES); 36045e3dd157SKalle Valo 36055e3dd157SKalle Valo config.num_mcast_groups = __cpu_to_le32(TARGET_NUM_MCAST_GROUPS); 36065e3dd157SKalle Valo config.num_mcast_table_elems = 36075e3dd157SKalle Valo __cpu_to_le32(TARGET_NUM_MCAST_TABLE_ELEMS); 36085e3dd157SKalle Valo 36095e3dd157SKalle Valo config.mcast2ucast_mode = __cpu_to_le32(TARGET_MCAST2UCAST_MODE); 36105e3dd157SKalle Valo config.tx_dbg_log_size = __cpu_to_le32(TARGET_TX_DBG_LOG_SIZE); 36115e3dd157SKalle Valo config.num_wds_entries = __cpu_to_le32(TARGET_NUM_WDS_ENTRIES); 36125e3dd157SKalle Valo config.dma_burst_size = __cpu_to_le32(TARGET_DMA_BURST_SIZE); 36135e3dd157SKalle Valo config.mac_aggr_delim = __cpu_to_le32(TARGET_MAC_AGGR_DELIM); 36145e3dd157SKalle Valo 36155e3dd157SKalle Valo val = TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; 36165e3dd157SKalle Valo config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); 36175e3dd157SKalle Valo 36185e3dd157SKalle Valo config.vow_config = __cpu_to_le32(TARGET_VOW_CONFIG); 36195e3dd157SKalle Valo 36205e3dd157SKalle Valo config.gtk_offload_max_vdev = 36215e3dd157SKalle Valo __cpu_to_le32(TARGET_GTK_OFFLOAD_MAX_VDEV); 36225e3dd157SKalle Valo 36235e3dd157SKalle Valo config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC); 36245e3dd157SKalle Valo config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES); 36255e3dd157SKalle Valo 3626b3effe61SBartosz Markowski len = sizeof(*cmd) + 3627b3effe61SBartosz Markowski (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); 3628b3effe61SBartosz Markowski 36297aa7a72aSMichal Kazior buf = ath10k_wmi_alloc_skb(ar, len); 36305e3dd157SKalle Valo if (!buf) 3631d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 36325e3dd157SKalle Valo 36335e3dd157SKalle Valo cmd = (struct wmi_init_cmd *)buf->data; 3634b3effe61SBartosz Markowski 36355e3dd157SKalle Valo memcpy(&cmd->resource_config, &config, sizeof(config)); 3636cf9fca8fSMichal Kazior ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 36375e3dd157SKalle Valo 36387aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n"); 3639d7579d12SMichal Kazior return buf; 36405e3dd157SKalle Valo } 36415e3dd157SKalle Valo 3642d7579d12SMichal Kazior static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar) 364312b2b9e3SBartosz Markowski { 364412b2b9e3SBartosz Markowski struct wmi_init_cmd_10x *cmd; 364512b2b9e3SBartosz Markowski struct sk_buff *buf; 364612b2b9e3SBartosz Markowski struct wmi_resource_config_10x config = {}; 364712b2b9e3SBartosz Markowski u32 len, val; 364812b2b9e3SBartosz Markowski 3649ec6a73f0SBartosz Markowski config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); 3650ec6a73f0SBartosz Markowski config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); 3651ec6a73f0SBartosz Markowski config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); 3652ec6a73f0SBartosz Markowski config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); 3653ec6a73f0SBartosz Markowski config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); 3654ec6a73f0SBartosz Markowski config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); 3655ec6a73f0SBartosz Markowski config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); 3656ec6a73f0SBartosz Markowski config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); 3657ec6a73f0SBartosz Markowski config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); 3658ec6a73f0SBartosz Markowski config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); 3659ec6a73f0SBartosz Markowski config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); 3660ec6a73f0SBartosz Markowski config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); 366112b2b9e3SBartosz Markowski 366212b2b9e3SBartosz Markowski config.scan_max_pending_reqs = 3663ec6a73f0SBartosz Markowski __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); 366412b2b9e3SBartosz Markowski 366512b2b9e3SBartosz Markowski config.bmiss_offload_max_vdev = 3666ec6a73f0SBartosz Markowski __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); 366712b2b9e3SBartosz Markowski 366812b2b9e3SBartosz Markowski config.roam_offload_max_vdev = 3669ec6a73f0SBartosz Markowski __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); 367012b2b9e3SBartosz Markowski 367112b2b9e3SBartosz Markowski config.roam_offload_max_ap_profiles = 3672ec6a73f0SBartosz Markowski __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); 367312b2b9e3SBartosz Markowski 3674ec6a73f0SBartosz Markowski config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); 367512b2b9e3SBartosz Markowski config.num_mcast_table_elems = 3676ec6a73f0SBartosz Markowski __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); 367712b2b9e3SBartosz Markowski 3678ec6a73f0SBartosz Markowski config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); 3679ec6a73f0SBartosz Markowski config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); 3680ec6a73f0SBartosz Markowski config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); 3681ec6a73f0SBartosz Markowski config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE); 3682ec6a73f0SBartosz Markowski config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); 368312b2b9e3SBartosz Markowski 3684ec6a73f0SBartosz Markowski val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; 368512b2b9e3SBartosz Markowski config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); 368612b2b9e3SBartosz Markowski 3687ec6a73f0SBartosz Markowski config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); 368812b2b9e3SBartosz Markowski 3689ec6a73f0SBartosz Markowski config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); 3690ec6a73f0SBartosz Markowski config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); 369112b2b9e3SBartosz Markowski 369212b2b9e3SBartosz Markowski len = sizeof(*cmd) + 369312b2b9e3SBartosz Markowski (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); 369412b2b9e3SBartosz Markowski 36957aa7a72aSMichal Kazior buf = ath10k_wmi_alloc_skb(ar, len); 369612b2b9e3SBartosz Markowski if (!buf) 3697d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 369812b2b9e3SBartosz Markowski 369912b2b9e3SBartosz Markowski cmd = (struct wmi_init_cmd_10x *)buf->data; 370012b2b9e3SBartosz Markowski 370112b2b9e3SBartosz Markowski memcpy(&cmd->resource_config, &config, sizeof(config)); 3702cf9fca8fSMichal Kazior ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 370312b2b9e3SBartosz Markowski 37047aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n"); 3705d7579d12SMichal Kazior return buf; 370612b2b9e3SBartosz Markowski } 370712b2b9e3SBartosz Markowski 3708d7579d12SMichal Kazior static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar) 370924c88f78SMichal Kazior { 371024c88f78SMichal Kazior struct wmi_init_cmd_10_2 *cmd; 371124c88f78SMichal Kazior struct sk_buff *buf; 371224c88f78SMichal Kazior struct wmi_resource_config_10x config = {}; 3713b6c8e287SSujith Manoharan u32 len, val, features; 371424c88f78SMichal Kazior 371524c88f78SMichal Kazior config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); 371624c88f78SMichal Kazior config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); 371724c88f78SMichal Kazior config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); 371824c88f78SMichal Kazior config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); 371924c88f78SMichal Kazior config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); 372024c88f78SMichal Kazior config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); 372124c88f78SMichal Kazior config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); 372224c88f78SMichal Kazior config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); 372324c88f78SMichal Kazior config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); 372424c88f78SMichal Kazior config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); 372524c88f78SMichal Kazior config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); 372624c88f78SMichal Kazior config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); 372724c88f78SMichal Kazior 372824c88f78SMichal Kazior config.scan_max_pending_reqs = 372924c88f78SMichal Kazior __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); 373024c88f78SMichal Kazior 373124c88f78SMichal Kazior config.bmiss_offload_max_vdev = 373224c88f78SMichal Kazior __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); 373324c88f78SMichal Kazior 373424c88f78SMichal Kazior config.roam_offload_max_vdev = 373524c88f78SMichal Kazior __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); 373624c88f78SMichal Kazior 373724c88f78SMichal Kazior config.roam_offload_max_ap_profiles = 373824c88f78SMichal Kazior __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); 373924c88f78SMichal Kazior 374024c88f78SMichal Kazior config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); 374124c88f78SMichal Kazior config.num_mcast_table_elems = 374224c88f78SMichal Kazior __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); 374324c88f78SMichal Kazior 374424c88f78SMichal Kazior config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); 374524c88f78SMichal Kazior config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); 374624c88f78SMichal Kazior config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); 3747f6603ff2SSujith Manoharan config.dma_burst_size = __cpu_to_le32(TARGET_10_2_DMA_BURST_SIZE); 374824c88f78SMichal Kazior config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); 374924c88f78SMichal Kazior 375024c88f78SMichal Kazior val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; 375124c88f78SMichal Kazior config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); 375224c88f78SMichal Kazior 375324c88f78SMichal Kazior config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); 375424c88f78SMichal Kazior 375524c88f78SMichal Kazior config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); 375624c88f78SMichal Kazior config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); 375724c88f78SMichal Kazior 375824c88f78SMichal Kazior len = sizeof(*cmd) + 375924c88f78SMichal Kazior (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); 376024c88f78SMichal Kazior 37617aa7a72aSMichal Kazior buf = ath10k_wmi_alloc_skb(ar, len); 376224c88f78SMichal Kazior if (!buf) 3763d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 376424c88f78SMichal Kazior 376524c88f78SMichal Kazior cmd = (struct wmi_init_cmd_10_2 *)buf->data; 376624c88f78SMichal Kazior 3767b6c8e287SSujith Manoharan features = WMI_10_2_RX_BATCH_MODE; 3768b6c8e287SSujith Manoharan cmd->resource_config.feature_mask = __cpu_to_le32(features); 3769b6c8e287SSujith Manoharan 377024c88f78SMichal Kazior memcpy(&cmd->resource_config.common, &config, sizeof(config)); 3771cf9fca8fSMichal Kazior ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 377224c88f78SMichal Kazior 37737aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n"); 3774d7579d12SMichal Kazior return buf; 377512b2b9e3SBartosz Markowski } 377612b2b9e3SBartosz Markowski 37770226d602SMichal Kazior int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg) 37785e3dd157SKalle Valo { 3779a6aa5da3SMichal Kazior if (arg->ie_len && !arg->ie) 37805e3dd157SKalle Valo return -EINVAL; 3781a6aa5da3SMichal Kazior if (arg->n_channels && !arg->channels) 3782a6aa5da3SMichal Kazior return -EINVAL; 3783a6aa5da3SMichal Kazior if (arg->n_ssids && !arg->ssids) 3784a6aa5da3SMichal Kazior return -EINVAL; 3785a6aa5da3SMichal Kazior if (arg->n_bssids && !arg->bssids) 3786a6aa5da3SMichal Kazior return -EINVAL; 3787a6aa5da3SMichal Kazior 37885e3dd157SKalle Valo if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN) 37895e3dd157SKalle Valo return -EINVAL; 3790a6aa5da3SMichal Kazior if (arg->n_channels > ARRAY_SIZE(arg->channels)) 3791a6aa5da3SMichal Kazior return -EINVAL; 3792a6aa5da3SMichal Kazior if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID) 3793a6aa5da3SMichal Kazior return -EINVAL; 3794a6aa5da3SMichal Kazior if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID) 3795a6aa5da3SMichal Kazior return -EINVAL; 37965e3dd157SKalle Valo 3797a6aa5da3SMichal Kazior return 0; 3798a6aa5da3SMichal Kazior } 3799a6aa5da3SMichal Kazior 3800a6aa5da3SMichal Kazior static size_t 3801a6aa5da3SMichal Kazior ath10k_wmi_start_scan_tlvs_len(const struct wmi_start_scan_arg *arg) 3802a6aa5da3SMichal Kazior { 3803a6aa5da3SMichal Kazior int len = 0; 3804a6aa5da3SMichal Kazior 3805a6aa5da3SMichal Kazior if (arg->ie_len) { 38065e3dd157SKalle Valo len += sizeof(struct wmi_ie_data); 38075e3dd157SKalle Valo len += roundup(arg->ie_len, 4); 38085e3dd157SKalle Valo } 38095e3dd157SKalle Valo 38105e3dd157SKalle Valo if (arg->n_channels) { 38115e3dd157SKalle Valo len += sizeof(struct wmi_chan_list); 38125e3dd157SKalle Valo len += sizeof(__le32) * arg->n_channels; 38135e3dd157SKalle Valo } 38145e3dd157SKalle Valo 38155e3dd157SKalle Valo if (arg->n_ssids) { 38165e3dd157SKalle Valo len += sizeof(struct wmi_ssid_list); 38175e3dd157SKalle Valo len += sizeof(struct wmi_ssid) * arg->n_ssids; 38185e3dd157SKalle Valo } 38195e3dd157SKalle Valo 38205e3dd157SKalle Valo if (arg->n_bssids) { 38215e3dd157SKalle Valo len += sizeof(struct wmi_bssid_list); 38225e3dd157SKalle Valo len += sizeof(struct wmi_mac_addr) * arg->n_bssids; 38235e3dd157SKalle Valo } 38245e3dd157SKalle Valo 38255e3dd157SKalle Valo return len; 38265e3dd157SKalle Valo } 38275e3dd157SKalle Valo 38280226d602SMichal Kazior void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn, 38295e3dd157SKalle Valo const struct wmi_start_scan_arg *arg) 38305e3dd157SKalle Valo { 38315e3dd157SKalle Valo u32 scan_id; 38325e3dd157SKalle Valo u32 scan_req_id; 38335e3dd157SKalle Valo 38345e3dd157SKalle Valo scan_id = WMI_HOST_SCAN_REQ_ID_PREFIX; 38355e3dd157SKalle Valo scan_id |= arg->scan_id; 38365e3dd157SKalle Valo 38375e3dd157SKalle Valo scan_req_id = WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; 38385e3dd157SKalle Valo scan_req_id |= arg->scan_req_id; 38395e3dd157SKalle Valo 3840a6aa5da3SMichal Kazior cmn->scan_id = __cpu_to_le32(scan_id); 3841a6aa5da3SMichal Kazior cmn->scan_req_id = __cpu_to_le32(scan_req_id); 3842a6aa5da3SMichal Kazior cmn->vdev_id = __cpu_to_le32(arg->vdev_id); 3843a6aa5da3SMichal Kazior cmn->scan_priority = __cpu_to_le32(arg->scan_priority); 3844a6aa5da3SMichal Kazior cmn->notify_scan_events = __cpu_to_le32(arg->notify_scan_events); 3845a6aa5da3SMichal Kazior cmn->dwell_time_active = __cpu_to_le32(arg->dwell_time_active); 3846a6aa5da3SMichal Kazior cmn->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive); 3847a6aa5da3SMichal Kazior cmn->min_rest_time = __cpu_to_le32(arg->min_rest_time); 3848a6aa5da3SMichal Kazior cmn->max_rest_time = __cpu_to_le32(arg->max_rest_time); 3849a6aa5da3SMichal Kazior cmn->repeat_probe_time = __cpu_to_le32(arg->repeat_probe_time); 3850a6aa5da3SMichal Kazior cmn->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time); 3851a6aa5da3SMichal Kazior cmn->idle_time = __cpu_to_le32(arg->idle_time); 3852a6aa5da3SMichal Kazior cmn->max_scan_time = __cpu_to_le32(arg->max_scan_time); 3853a6aa5da3SMichal Kazior cmn->probe_delay = __cpu_to_le32(arg->probe_delay); 3854a6aa5da3SMichal Kazior cmn->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); 3855a6aa5da3SMichal Kazior } 38565e3dd157SKalle Valo 3857a6aa5da3SMichal Kazior static void 3858a6aa5da3SMichal Kazior ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs, 3859a6aa5da3SMichal Kazior const struct wmi_start_scan_arg *arg) 3860a6aa5da3SMichal Kazior { 3861a6aa5da3SMichal Kazior struct wmi_ie_data *ie; 3862a6aa5da3SMichal Kazior struct wmi_chan_list *channels; 3863a6aa5da3SMichal Kazior struct wmi_ssid_list *ssids; 3864a6aa5da3SMichal Kazior struct wmi_bssid_list *bssids; 3865a6aa5da3SMichal Kazior void *ptr = tlvs->tlvs; 3866a6aa5da3SMichal Kazior int i; 38675e3dd157SKalle Valo 38685e3dd157SKalle Valo if (arg->n_channels) { 3869a6aa5da3SMichal Kazior channels = ptr; 38705e3dd157SKalle Valo channels->tag = __cpu_to_le32(WMI_CHAN_LIST_TAG); 38715e3dd157SKalle Valo channels->num_chan = __cpu_to_le32(arg->n_channels); 38725e3dd157SKalle Valo 38735e3dd157SKalle Valo for (i = 0; i < arg->n_channels; i++) 387424c88f78SMichal Kazior channels->channel_list[i].freq = 387524c88f78SMichal Kazior __cpu_to_le16(arg->channels[i]); 38765e3dd157SKalle Valo 3877a6aa5da3SMichal Kazior ptr += sizeof(*channels); 3878a6aa5da3SMichal Kazior ptr += sizeof(__le32) * arg->n_channels; 38795e3dd157SKalle Valo } 38805e3dd157SKalle Valo 38815e3dd157SKalle Valo if (arg->n_ssids) { 3882a6aa5da3SMichal Kazior ssids = ptr; 38835e3dd157SKalle Valo ssids->tag = __cpu_to_le32(WMI_SSID_LIST_TAG); 38845e3dd157SKalle Valo ssids->num_ssids = __cpu_to_le32(arg->n_ssids); 38855e3dd157SKalle Valo 38865e3dd157SKalle Valo for (i = 0; i < arg->n_ssids; i++) { 38875e3dd157SKalle Valo ssids->ssids[i].ssid_len = 38885e3dd157SKalle Valo __cpu_to_le32(arg->ssids[i].len); 38895e3dd157SKalle Valo memcpy(&ssids->ssids[i].ssid, 38905e3dd157SKalle Valo arg->ssids[i].ssid, 38915e3dd157SKalle Valo arg->ssids[i].len); 38925e3dd157SKalle Valo } 38935e3dd157SKalle Valo 3894a6aa5da3SMichal Kazior ptr += sizeof(*ssids); 3895a6aa5da3SMichal Kazior ptr += sizeof(struct wmi_ssid) * arg->n_ssids; 38965e3dd157SKalle Valo } 38975e3dd157SKalle Valo 38985e3dd157SKalle Valo if (arg->n_bssids) { 3899a6aa5da3SMichal Kazior bssids = ptr; 39005e3dd157SKalle Valo bssids->tag = __cpu_to_le32(WMI_BSSID_LIST_TAG); 39015e3dd157SKalle Valo bssids->num_bssid = __cpu_to_le32(arg->n_bssids); 39025e3dd157SKalle Valo 39035e3dd157SKalle Valo for (i = 0; i < arg->n_bssids; i++) 39045e3dd157SKalle Valo memcpy(&bssids->bssid_list[i], 39055e3dd157SKalle Valo arg->bssids[i].bssid, 39065e3dd157SKalle Valo ETH_ALEN); 39075e3dd157SKalle Valo 3908a6aa5da3SMichal Kazior ptr += sizeof(*bssids); 3909a6aa5da3SMichal Kazior ptr += sizeof(struct wmi_mac_addr) * arg->n_bssids; 39105e3dd157SKalle Valo } 39115e3dd157SKalle Valo 39125e3dd157SKalle Valo if (arg->ie_len) { 3913a6aa5da3SMichal Kazior ie = ptr; 39145e3dd157SKalle Valo ie->tag = __cpu_to_le32(WMI_IE_TAG); 39155e3dd157SKalle Valo ie->ie_len = __cpu_to_le32(arg->ie_len); 39165e3dd157SKalle Valo memcpy(ie->ie_data, arg->ie, arg->ie_len); 39175e3dd157SKalle Valo 3918a6aa5da3SMichal Kazior ptr += sizeof(*ie); 3919a6aa5da3SMichal Kazior ptr += roundup(arg->ie_len, 4); 3920a6aa5da3SMichal Kazior } 39215e3dd157SKalle Valo } 39225e3dd157SKalle Valo 3923d7579d12SMichal Kazior static struct sk_buff * 3924d7579d12SMichal Kazior ath10k_wmi_op_gen_start_scan(struct ath10k *ar, 3925a6aa5da3SMichal Kazior const struct wmi_start_scan_arg *arg) 3926a6aa5da3SMichal Kazior { 3927d7579d12SMichal Kazior struct wmi_start_scan_cmd *cmd; 3928a6aa5da3SMichal Kazior struct sk_buff *skb; 3929a6aa5da3SMichal Kazior size_t len; 3930a6aa5da3SMichal Kazior int ret; 3931a6aa5da3SMichal Kazior 3932a6aa5da3SMichal Kazior ret = ath10k_wmi_start_scan_verify(arg); 3933a6aa5da3SMichal Kazior if (ret) 3934d7579d12SMichal Kazior return ERR_PTR(ret); 3935a6aa5da3SMichal Kazior 3936d7579d12SMichal Kazior len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg); 3937a6aa5da3SMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 3938a6aa5da3SMichal Kazior if (!skb) 3939d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 3940a6aa5da3SMichal Kazior 3941a6aa5da3SMichal Kazior cmd = (struct wmi_start_scan_cmd *)skb->data; 3942a6aa5da3SMichal Kazior 3943a6aa5da3SMichal Kazior ath10k_wmi_put_start_scan_common(&cmd->common, arg); 3944a6aa5da3SMichal Kazior ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg); 3945d7579d12SMichal Kazior 3946d7579d12SMichal Kazior cmd->burst_duration_ms = __cpu_to_le32(0); 39475e3dd157SKalle Valo 39487aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n"); 3949d7579d12SMichal Kazior return skb; 3950d7579d12SMichal Kazior } 3951d7579d12SMichal Kazior 3952d7579d12SMichal Kazior static struct sk_buff * 3953d7579d12SMichal Kazior ath10k_wmi_10x_op_gen_start_scan(struct ath10k *ar, 3954d7579d12SMichal Kazior const struct wmi_start_scan_arg *arg) 3955d7579d12SMichal Kazior { 3956d7579d12SMichal Kazior struct wmi_10x_start_scan_cmd *cmd; 3957d7579d12SMichal Kazior struct sk_buff *skb; 3958d7579d12SMichal Kazior size_t len; 3959d7579d12SMichal Kazior int ret; 3960d7579d12SMichal Kazior 3961d7579d12SMichal Kazior ret = ath10k_wmi_start_scan_verify(arg); 3962d7579d12SMichal Kazior if (ret) 3963d7579d12SMichal Kazior return ERR_PTR(ret); 3964d7579d12SMichal Kazior 3965d7579d12SMichal Kazior len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg); 3966d7579d12SMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 3967d7579d12SMichal Kazior if (!skb) 3968d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 3969d7579d12SMichal Kazior 3970d7579d12SMichal Kazior cmd = (struct wmi_10x_start_scan_cmd *)skb->data; 3971d7579d12SMichal Kazior 3972d7579d12SMichal Kazior ath10k_wmi_put_start_scan_common(&cmd->common, arg); 3973d7579d12SMichal Kazior ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg); 3974d7579d12SMichal Kazior 3975d7579d12SMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi 10x start scan\n"); 3976d7579d12SMichal Kazior return skb; 39775e3dd157SKalle Valo } 39785e3dd157SKalle Valo 39795e3dd157SKalle Valo void ath10k_wmi_start_scan_init(struct ath10k *ar, 39805e3dd157SKalle Valo struct wmi_start_scan_arg *arg) 39815e3dd157SKalle Valo { 39825e3dd157SKalle Valo /* setup commonly used values */ 39835e3dd157SKalle Valo arg->scan_req_id = 1; 39845e3dd157SKalle Valo arg->scan_priority = WMI_SCAN_PRIORITY_LOW; 39855e3dd157SKalle Valo arg->dwell_time_active = 50; 39865e3dd157SKalle Valo arg->dwell_time_passive = 150; 39875e3dd157SKalle Valo arg->min_rest_time = 50; 39885e3dd157SKalle Valo arg->max_rest_time = 500; 39895e3dd157SKalle Valo arg->repeat_probe_time = 0; 39905e3dd157SKalle Valo arg->probe_spacing_time = 0; 39915e3dd157SKalle Valo arg->idle_time = 0; 3992c322892fSBartosz Markowski arg->max_scan_time = 20000; 39935e3dd157SKalle Valo arg->probe_delay = 5; 39945e3dd157SKalle Valo arg->notify_scan_events = WMI_SCAN_EVENT_STARTED 39955e3dd157SKalle Valo | WMI_SCAN_EVENT_COMPLETED 39965e3dd157SKalle Valo | WMI_SCAN_EVENT_BSS_CHANNEL 39975e3dd157SKalle Valo | WMI_SCAN_EVENT_FOREIGN_CHANNEL 39985e3dd157SKalle Valo | WMI_SCAN_EVENT_DEQUEUED; 39995e3dd157SKalle Valo arg->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 40005e3dd157SKalle Valo arg->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 40015e3dd157SKalle Valo arg->n_bssids = 1; 40025e3dd157SKalle Valo arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF"; 40035e3dd157SKalle Valo } 40045e3dd157SKalle Valo 4005d7579d12SMichal Kazior static struct sk_buff * 4006d7579d12SMichal Kazior ath10k_wmi_op_gen_stop_scan(struct ath10k *ar, 4007d7579d12SMichal Kazior const struct wmi_stop_scan_arg *arg) 40085e3dd157SKalle Valo { 40095e3dd157SKalle Valo struct wmi_stop_scan_cmd *cmd; 40105e3dd157SKalle Valo struct sk_buff *skb; 40115e3dd157SKalle Valo u32 scan_id; 40125e3dd157SKalle Valo u32 req_id; 40135e3dd157SKalle Valo 40145e3dd157SKalle Valo if (arg->req_id > 0xFFF) 4015d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 40165e3dd157SKalle Valo if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) 4017d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 40185e3dd157SKalle Valo 40197aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 40205e3dd157SKalle Valo if (!skb) 4021d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 40225e3dd157SKalle Valo 40235e3dd157SKalle Valo scan_id = arg->u.scan_id; 40245e3dd157SKalle Valo scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; 40255e3dd157SKalle Valo 40265e3dd157SKalle Valo req_id = arg->req_id; 40275e3dd157SKalle Valo req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; 40285e3dd157SKalle Valo 40295e3dd157SKalle Valo cmd = (struct wmi_stop_scan_cmd *)skb->data; 40305e3dd157SKalle Valo cmd->req_type = __cpu_to_le32(arg->req_type); 40315e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id); 40325e3dd157SKalle Valo cmd->scan_id = __cpu_to_le32(scan_id); 40335e3dd157SKalle Valo cmd->scan_req_id = __cpu_to_le32(req_id); 40345e3dd157SKalle Valo 40357aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 40365e3dd157SKalle Valo "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", 40375e3dd157SKalle Valo arg->req_id, arg->req_type, arg->u.scan_id); 4038d7579d12SMichal Kazior return skb; 40395e3dd157SKalle Valo } 40405e3dd157SKalle Valo 4041d7579d12SMichal Kazior static struct sk_buff * 4042d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id, 40435e3dd157SKalle Valo enum wmi_vdev_type type, 40445e3dd157SKalle Valo enum wmi_vdev_subtype subtype, 40455e3dd157SKalle Valo const u8 macaddr[ETH_ALEN]) 40465e3dd157SKalle Valo { 40475e3dd157SKalle Valo struct wmi_vdev_create_cmd *cmd; 40485e3dd157SKalle Valo struct sk_buff *skb; 40495e3dd157SKalle Valo 40507aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 40515e3dd157SKalle Valo if (!skb) 4052d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 40535e3dd157SKalle Valo 40545e3dd157SKalle Valo cmd = (struct wmi_vdev_create_cmd *)skb->data; 40555e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 40565e3dd157SKalle Valo cmd->vdev_type = __cpu_to_le32(type); 40575e3dd157SKalle Valo cmd->vdev_subtype = __cpu_to_le32(subtype); 4058b25f32cbSKalle Valo ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); 40595e3dd157SKalle Valo 40607aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 40615e3dd157SKalle Valo "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", 40625e3dd157SKalle Valo vdev_id, type, subtype, macaddr); 4063d7579d12SMichal Kazior return skb; 40645e3dd157SKalle Valo } 40655e3dd157SKalle Valo 4066d7579d12SMichal Kazior static struct sk_buff * 4067d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id) 40685e3dd157SKalle Valo { 40695e3dd157SKalle Valo struct wmi_vdev_delete_cmd *cmd; 40705e3dd157SKalle Valo struct sk_buff *skb; 40715e3dd157SKalle Valo 40727aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 40735e3dd157SKalle Valo if (!skb) 4074d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 40755e3dd157SKalle Valo 40765e3dd157SKalle Valo cmd = (struct wmi_vdev_delete_cmd *)skb->data; 40775e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 40785e3dd157SKalle Valo 40797aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 40805e3dd157SKalle Valo "WMI vdev delete id %d\n", vdev_id); 4081d7579d12SMichal Kazior return skb; 40825e3dd157SKalle Valo } 40835e3dd157SKalle Valo 4084d7579d12SMichal Kazior static struct sk_buff * 4085d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_start(struct ath10k *ar, 40865e3dd157SKalle Valo const struct wmi_vdev_start_request_arg *arg, 4087d7579d12SMichal Kazior bool restart) 40885e3dd157SKalle Valo { 40895e3dd157SKalle Valo struct wmi_vdev_start_request_cmd *cmd; 40905e3dd157SKalle Valo struct sk_buff *skb; 40915e3dd157SKalle Valo const char *cmdname; 40925e3dd157SKalle Valo u32 flags = 0; 40935e3dd157SKalle Valo 40945e3dd157SKalle Valo if (WARN_ON(arg->ssid && arg->ssid_len == 0)) 4095d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 40965e3dd157SKalle Valo if (WARN_ON(arg->hidden_ssid && !arg->ssid)) 4097d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 40985e3dd157SKalle Valo if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 4099d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 41005e3dd157SKalle Valo 4101d7579d12SMichal Kazior if (restart) 41025e3dd157SKalle Valo cmdname = "restart"; 41035e3dd157SKalle Valo else 4104d7579d12SMichal Kazior cmdname = "start"; 41055e3dd157SKalle Valo 41067aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 41075e3dd157SKalle Valo if (!skb) 4108d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 41095e3dd157SKalle Valo 41105e3dd157SKalle Valo if (arg->hidden_ssid) 41115e3dd157SKalle Valo flags |= WMI_VDEV_START_HIDDEN_SSID; 41125e3dd157SKalle Valo if (arg->pmf_enabled) 41135e3dd157SKalle Valo flags |= WMI_VDEV_START_PMF_ENABLED; 41145e3dd157SKalle Valo 41155e3dd157SKalle Valo cmd = (struct wmi_vdev_start_request_cmd *)skb->data; 41165e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 41175e3dd157SKalle Valo cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack); 41185e3dd157SKalle Valo cmd->beacon_interval = __cpu_to_le32(arg->bcn_intval); 41195e3dd157SKalle Valo cmd->dtim_period = __cpu_to_le32(arg->dtim_period); 41205e3dd157SKalle Valo cmd->flags = __cpu_to_le32(flags); 41215e3dd157SKalle Valo cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate); 41225e3dd157SKalle Valo cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power); 41235e3dd157SKalle Valo 41245e3dd157SKalle Valo if (arg->ssid) { 41255e3dd157SKalle Valo cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len); 41265e3dd157SKalle Valo memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); 41275e3dd157SKalle Valo } 41285e3dd157SKalle Valo 41292d66721cSMichal Kazior ath10k_wmi_put_wmi_channel(&cmd->chan, &arg->channel); 41305e3dd157SKalle Valo 41317aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 41328cc7f26cSKalle Valo "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n", 41338cc7f26cSKalle Valo cmdname, arg->vdev_id, 4134e8a50f8bSMarek Puzyniak flags, arg->channel.freq, arg->channel.mode, 4135e8a50f8bSMarek Puzyniak cmd->chan.flags, arg->channel.max_power); 41365e3dd157SKalle Valo 4137d7579d12SMichal Kazior return skb; 41385e3dd157SKalle Valo } 41395e3dd157SKalle Valo 4140d7579d12SMichal Kazior static struct sk_buff * 4141d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id) 41425e3dd157SKalle Valo { 41435e3dd157SKalle Valo struct wmi_vdev_stop_cmd *cmd; 41445e3dd157SKalle Valo struct sk_buff *skb; 41455e3dd157SKalle Valo 41467aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 41475e3dd157SKalle Valo if (!skb) 4148d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 41495e3dd157SKalle Valo 41505e3dd157SKalle Valo cmd = (struct wmi_vdev_stop_cmd *)skb->data; 41515e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 41525e3dd157SKalle Valo 41537aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); 4154d7579d12SMichal Kazior return skb; 41555e3dd157SKalle Valo } 41565e3dd157SKalle Valo 4157d7579d12SMichal Kazior static struct sk_buff * 4158d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, 4159d7579d12SMichal Kazior const u8 *bssid) 41605e3dd157SKalle Valo { 41615e3dd157SKalle Valo struct wmi_vdev_up_cmd *cmd; 41625e3dd157SKalle Valo struct sk_buff *skb; 41635e3dd157SKalle Valo 41647aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 41655e3dd157SKalle Valo if (!skb) 4166d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 41675e3dd157SKalle Valo 41685e3dd157SKalle Valo cmd = (struct wmi_vdev_up_cmd *)skb->data; 41695e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 41705e3dd157SKalle Valo cmd->vdev_assoc_id = __cpu_to_le32(aid); 4171b25f32cbSKalle Valo ether_addr_copy(cmd->vdev_bssid.addr, bssid); 41725e3dd157SKalle Valo 41737aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 41745e3dd157SKalle Valo "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", 41755e3dd157SKalle Valo vdev_id, aid, bssid); 4176d7579d12SMichal Kazior return skb; 41775e3dd157SKalle Valo } 41785e3dd157SKalle Valo 4179d7579d12SMichal Kazior static struct sk_buff * 4180d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id) 41815e3dd157SKalle Valo { 41825e3dd157SKalle Valo struct wmi_vdev_down_cmd *cmd; 41835e3dd157SKalle Valo struct sk_buff *skb; 41845e3dd157SKalle Valo 41857aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 41865e3dd157SKalle Valo if (!skb) 4187d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 41885e3dd157SKalle Valo 41895e3dd157SKalle Valo cmd = (struct wmi_vdev_down_cmd *)skb->data; 41905e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 41915e3dd157SKalle Valo 41927aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 41935e3dd157SKalle Valo "wmi mgmt vdev down id 0x%x\n", vdev_id); 4194d7579d12SMichal Kazior return skb; 41955e3dd157SKalle Valo } 41965e3dd157SKalle Valo 4197d7579d12SMichal Kazior static struct sk_buff * 4198d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id, 41996d1506e7SBartosz Markowski u32 param_id, u32 param_value) 42005e3dd157SKalle Valo { 42015e3dd157SKalle Valo struct wmi_vdev_set_param_cmd *cmd; 42025e3dd157SKalle Valo struct sk_buff *skb; 42035e3dd157SKalle Valo 42046d1506e7SBartosz Markowski if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) { 42057aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 42066d1506e7SBartosz Markowski "vdev param %d not supported by firmware\n", 42076d1506e7SBartosz Markowski param_id); 4208d7579d12SMichal Kazior return ERR_PTR(-EOPNOTSUPP); 42096d1506e7SBartosz Markowski } 42106d1506e7SBartosz Markowski 42117aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 42125e3dd157SKalle Valo if (!skb) 4213d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 42145e3dd157SKalle Valo 42155e3dd157SKalle Valo cmd = (struct wmi_vdev_set_param_cmd *)skb->data; 42165e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 42175e3dd157SKalle Valo cmd->param_id = __cpu_to_le32(param_id); 42185e3dd157SKalle Valo cmd->param_value = __cpu_to_le32(param_value); 42195e3dd157SKalle Valo 42207aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 42215e3dd157SKalle Valo "wmi vdev id 0x%x set param %d value %d\n", 42225e3dd157SKalle Valo vdev_id, param_id, param_value); 4223d7579d12SMichal Kazior return skb; 42245e3dd157SKalle Valo } 42255e3dd157SKalle Valo 4226d7579d12SMichal Kazior static struct sk_buff * 4227d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_install_key(struct ath10k *ar, 42285e3dd157SKalle Valo const struct wmi_vdev_install_key_arg *arg) 42295e3dd157SKalle Valo { 42305e3dd157SKalle Valo struct wmi_vdev_install_key_cmd *cmd; 42315e3dd157SKalle Valo struct sk_buff *skb; 42325e3dd157SKalle Valo 42335e3dd157SKalle Valo if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) 4234d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 42355e3dd157SKalle Valo if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) 4236d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 42375e3dd157SKalle Valo 42387aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len); 42395e3dd157SKalle Valo if (!skb) 4240d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 42415e3dd157SKalle Valo 42425e3dd157SKalle Valo cmd = (struct wmi_vdev_install_key_cmd *)skb->data; 42435e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 42445e3dd157SKalle Valo cmd->key_idx = __cpu_to_le32(arg->key_idx); 42455e3dd157SKalle Valo cmd->key_flags = __cpu_to_le32(arg->key_flags); 42465e3dd157SKalle Valo cmd->key_cipher = __cpu_to_le32(arg->key_cipher); 42475e3dd157SKalle Valo cmd->key_len = __cpu_to_le32(arg->key_len); 42485e3dd157SKalle Valo cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len); 42495e3dd157SKalle Valo cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); 42505e3dd157SKalle Valo 42515e3dd157SKalle Valo if (arg->macaddr) 4252b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); 42535e3dd157SKalle Valo if (arg->key_data) 42545e3dd157SKalle Valo memcpy(cmd->key_data, arg->key_data, arg->key_len); 42555e3dd157SKalle Valo 42567aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 4257e0c508abSMichal Kazior "wmi vdev install key idx %d cipher %d len %d\n", 4258e0c508abSMichal Kazior arg->key_idx, arg->key_cipher, arg->key_len); 4259d7579d12SMichal Kazior return skb; 42605e3dd157SKalle Valo } 42615e3dd157SKalle Valo 4262d7579d12SMichal Kazior static struct sk_buff * 4263d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_spectral_conf(struct ath10k *ar, 4264855aed12SSimon Wunderlich const struct wmi_vdev_spectral_conf_arg *arg) 4265855aed12SSimon Wunderlich { 4266855aed12SSimon Wunderlich struct wmi_vdev_spectral_conf_cmd *cmd; 4267855aed12SSimon Wunderlich struct sk_buff *skb; 4268855aed12SSimon Wunderlich 42697aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4270855aed12SSimon Wunderlich if (!skb) 4271d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 4272855aed12SSimon Wunderlich 4273855aed12SSimon Wunderlich cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data; 4274855aed12SSimon Wunderlich cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 4275855aed12SSimon Wunderlich cmd->scan_count = __cpu_to_le32(arg->scan_count); 4276855aed12SSimon Wunderlich cmd->scan_period = __cpu_to_le32(arg->scan_period); 4277855aed12SSimon Wunderlich cmd->scan_priority = __cpu_to_le32(arg->scan_priority); 4278855aed12SSimon Wunderlich cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size); 4279855aed12SSimon Wunderlich cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena); 4280855aed12SSimon Wunderlich cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena); 4281855aed12SSimon Wunderlich cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref); 4282855aed12SSimon Wunderlich cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay); 4283855aed12SSimon Wunderlich cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr); 4284855aed12SSimon Wunderlich cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr); 4285855aed12SSimon Wunderlich cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode); 4286855aed12SSimon Wunderlich cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode); 4287855aed12SSimon Wunderlich cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr); 4288855aed12SSimon Wunderlich cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format); 4289855aed12SSimon Wunderlich cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode); 4290855aed12SSimon Wunderlich cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale); 4291855aed12SSimon Wunderlich cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); 4292855aed12SSimon Wunderlich cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); 4293855aed12SSimon Wunderlich 4294d7579d12SMichal Kazior return skb; 4295855aed12SSimon Wunderlich } 4296855aed12SSimon Wunderlich 4297d7579d12SMichal Kazior static struct sk_buff * 4298d7579d12SMichal Kazior ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, 4299d7579d12SMichal Kazior u32 trigger, u32 enable) 4300855aed12SSimon Wunderlich { 4301855aed12SSimon Wunderlich struct wmi_vdev_spectral_enable_cmd *cmd; 4302855aed12SSimon Wunderlich struct sk_buff *skb; 4303855aed12SSimon Wunderlich 43047aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4305855aed12SSimon Wunderlich if (!skb) 4306d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 4307855aed12SSimon Wunderlich 4308855aed12SSimon Wunderlich cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data; 4309855aed12SSimon Wunderlich cmd->vdev_id = __cpu_to_le32(vdev_id); 4310855aed12SSimon Wunderlich cmd->trigger_cmd = __cpu_to_le32(trigger); 4311855aed12SSimon Wunderlich cmd->enable_cmd = __cpu_to_le32(enable); 4312855aed12SSimon Wunderlich 4313d7579d12SMichal Kazior return skb; 4314855aed12SSimon Wunderlich } 4315855aed12SSimon Wunderlich 4316d7579d12SMichal Kazior static struct sk_buff * 4317d7579d12SMichal Kazior ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, 43185e3dd157SKalle Valo const u8 peer_addr[ETH_ALEN]) 43195e3dd157SKalle Valo { 43205e3dd157SKalle Valo struct wmi_peer_create_cmd *cmd; 43215e3dd157SKalle Valo struct sk_buff *skb; 43225e3dd157SKalle Valo 43237aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 43245e3dd157SKalle Valo if (!skb) 4325d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 43265e3dd157SKalle Valo 43275e3dd157SKalle Valo cmd = (struct wmi_peer_create_cmd *)skb->data; 43285e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 4329b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 43305e3dd157SKalle Valo 43317aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 43325e3dd157SKalle Valo "wmi peer create vdev_id %d peer_addr %pM\n", 43335e3dd157SKalle Valo vdev_id, peer_addr); 4334d7579d12SMichal Kazior return skb; 43355e3dd157SKalle Valo } 43365e3dd157SKalle Valo 4337d7579d12SMichal Kazior static struct sk_buff * 4338d7579d12SMichal Kazior ath10k_wmi_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id, 43395e3dd157SKalle Valo const u8 peer_addr[ETH_ALEN]) 43405e3dd157SKalle Valo { 43415e3dd157SKalle Valo struct wmi_peer_delete_cmd *cmd; 43425e3dd157SKalle Valo struct sk_buff *skb; 43435e3dd157SKalle Valo 43447aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 43455e3dd157SKalle Valo if (!skb) 4346d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 43475e3dd157SKalle Valo 43485e3dd157SKalle Valo cmd = (struct wmi_peer_delete_cmd *)skb->data; 43495e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 4350b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 43515e3dd157SKalle Valo 43527aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 43535e3dd157SKalle Valo "wmi peer delete vdev_id %d peer_addr %pM\n", 43545e3dd157SKalle Valo vdev_id, peer_addr); 4355d7579d12SMichal Kazior return skb; 43565e3dd157SKalle Valo } 43575e3dd157SKalle Valo 4358d7579d12SMichal Kazior static struct sk_buff * 4359d7579d12SMichal Kazior ath10k_wmi_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id, 43605e3dd157SKalle Valo const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) 43615e3dd157SKalle Valo { 43625e3dd157SKalle Valo struct wmi_peer_flush_tids_cmd *cmd; 43635e3dd157SKalle Valo struct sk_buff *skb; 43645e3dd157SKalle Valo 43657aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 43665e3dd157SKalle Valo if (!skb) 4367d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 43685e3dd157SKalle Valo 43695e3dd157SKalle Valo cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; 43705e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 43715e3dd157SKalle Valo cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); 4372b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 43735e3dd157SKalle Valo 43747aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 43755e3dd157SKalle Valo "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", 43765e3dd157SKalle Valo vdev_id, peer_addr, tid_bitmap); 4377d7579d12SMichal Kazior return skb; 43785e3dd157SKalle Valo } 43795e3dd157SKalle Valo 4380d7579d12SMichal Kazior static struct sk_buff * 4381d7579d12SMichal Kazior ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id, 4382d7579d12SMichal Kazior const u8 *peer_addr, 4383d7579d12SMichal Kazior enum wmi_peer_param param_id, 43845e3dd157SKalle Valo u32 param_value) 43855e3dd157SKalle Valo { 43865e3dd157SKalle Valo struct wmi_peer_set_param_cmd *cmd; 43875e3dd157SKalle Valo struct sk_buff *skb; 43885e3dd157SKalle Valo 43897aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 43905e3dd157SKalle Valo if (!skb) 4391d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 43925e3dd157SKalle Valo 43935e3dd157SKalle Valo cmd = (struct wmi_peer_set_param_cmd *)skb->data; 43945e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 43955e3dd157SKalle Valo cmd->param_id = __cpu_to_le32(param_id); 43965e3dd157SKalle Valo cmd->param_value = __cpu_to_le32(param_value); 4397b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); 43985e3dd157SKalle Valo 43997aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 44005e3dd157SKalle Valo "wmi vdev %d peer 0x%pM set param %d value %d\n", 44015e3dd157SKalle Valo vdev_id, peer_addr, param_id, param_value); 4402d7579d12SMichal Kazior return skb; 44035e3dd157SKalle Valo } 44045e3dd157SKalle Valo 4405d7579d12SMichal Kazior static struct sk_buff * 4406d7579d12SMichal Kazior ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, 44075e3dd157SKalle Valo enum wmi_sta_ps_mode psmode) 44085e3dd157SKalle Valo { 44095e3dd157SKalle Valo struct wmi_sta_powersave_mode_cmd *cmd; 44105e3dd157SKalle Valo struct sk_buff *skb; 44115e3dd157SKalle Valo 44127aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 44135e3dd157SKalle Valo if (!skb) 4414d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 44155e3dd157SKalle Valo 44165e3dd157SKalle Valo cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data; 44175e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 44185e3dd157SKalle Valo cmd->sta_ps_mode = __cpu_to_le32(psmode); 44195e3dd157SKalle Valo 44207aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 44215e3dd157SKalle Valo "wmi set powersave id 0x%x mode %d\n", 44225e3dd157SKalle Valo vdev_id, psmode); 4423d7579d12SMichal Kazior return skb; 44245e3dd157SKalle Valo } 44255e3dd157SKalle Valo 4426d7579d12SMichal Kazior static struct sk_buff * 4427d7579d12SMichal Kazior ath10k_wmi_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id, 44285e3dd157SKalle Valo enum wmi_sta_powersave_param param_id, 44295e3dd157SKalle Valo u32 value) 44305e3dd157SKalle Valo { 44315e3dd157SKalle Valo struct wmi_sta_powersave_param_cmd *cmd; 44325e3dd157SKalle Valo struct sk_buff *skb; 44335e3dd157SKalle Valo 44347aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 44355e3dd157SKalle Valo if (!skb) 4436d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 44375e3dd157SKalle Valo 44385e3dd157SKalle Valo cmd = (struct wmi_sta_powersave_param_cmd *)skb->data; 44395e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 44405e3dd157SKalle Valo cmd->param_id = __cpu_to_le32(param_id); 44415e3dd157SKalle Valo cmd->param_value = __cpu_to_le32(value); 44425e3dd157SKalle Valo 44437aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 44445e3dd157SKalle Valo "wmi sta ps param vdev_id 0x%x param %d value %d\n", 44455e3dd157SKalle Valo vdev_id, param_id, value); 4446d7579d12SMichal Kazior return skb; 44475e3dd157SKalle Valo } 44485e3dd157SKalle Valo 4449d7579d12SMichal Kazior static struct sk_buff * 4450d7579d12SMichal Kazior ath10k_wmi_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac, 44515e3dd157SKalle Valo enum wmi_ap_ps_peer_param param_id, u32 value) 44525e3dd157SKalle Valo { 44535e3dd157SKalle Valo struct wmi_ap_ps_peer_cmd *cmd; 44545e3dd157SKalle Valo struct sk_buff *skb; 44555e3dd157SKalle Valo 44565e3dd157SKalle Valo if (!mac) 4457d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 44585e3dd157SKalle Valo 44597aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 44605e3dd157SKalle Valo if (!skb) 4461d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 44625e3dd157SKalle Valo 44635e3dd157SKalle Valo cmd = (struct wmi_ap_ps_peer_cmd *)skb->data; 44645e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(vdev_id); 44655e3dd157SKalle Valo cmd->param_id = __cpu_to_le32(param_id); 44665e3dd157SKalle Valo cmd->param_value = __cpu_to_le32(value); 4467b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, mac); 44685e3dd157SKalle Valo 44697aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 44705e3dd157SKalle Valo "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", 44715e3dd157SKalle Valo vdev_id, param_id, value, mac); 4472d7579d12SMichal Kazior return skb; 44735e3dd157SKalle Valo } 44745e3dd157SKalle Valo 4475d7579d12SMichal Kazior static struct sk_buff * 4476d7579d12SMichal Kazior ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar, 44775e3dd157SKalle Valo const struct wmi_scan_chan_list_arg *arg) 44785e3dd157SKalle Valo { 44795e3dd157SKalle Valo struct wmi_scan_chan_list_cmd *cmd; 44805e3dd157SKalle Valo struct sk_buff *skb; 44815e3dd157SKalle Valo struct wmi_channel_arg *ch; 44825e3dd157SKalle Valo struct wmi_channel *ci; 44835e3dd157SKalle Valo int len; 44845e3dd157SKalle Valo int i; 44855e3dd157SKalle Valo 44865e3dd157SKalle Valo len = sizeof(*cmd) + arg->n_channels * sizeof(struct wmi_channel); 44875e3dd157SKalle Valo 44887aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 44895e3dd157SKalle Valo if (!skb) 4490d7579d12SMichal Kazior return ERR_PTR(-EINVAL); 44915e3dd157SKalle Valo 44925e3dd157SKalle Valo cmd = (struct wmi_scan_chan_list_cmd *)skb->data; 44935e3dd157SKalle Valo cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); 44945e3dd157SKalle Valo 44955e3dd157SKalle Valo for (i = 0; i < arg->n_channels; i++) { 44965e3dd157SKalle Valo ch = &arg->channels[i]; 44975e3dd157SKalle Valo ci = &cmd->chan_info[i]; 44985e3dd157SKalle Valo 44992d66721cSMichal Kazior ath10k_wmi_put_wmi_channel(ci, ch); 45005e3dd157SKalle Valo } 45015e3dd157SKalle Valo 4502d7579d12SMichal Kazior return skb; 45035e3dd157SKalle Valo } 45045e3dd157SKalle Valo 450524c88f78SMichal Kazior static void 450624c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf, 45075e3dd157SKalle Valo const struct wmi_peer_assoc_complete_arg *arg) 45085e3dd157SKalle Valo { 450924c88f78SMichal Kazior struct wmi_common_peer_assoc_complete_cmd *cmd = buf; 45105e3dd157SKalle Valo 45115e3dd157SKalle Valo cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 45125e3dd157SKalle Valo cmd->peer_new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); 45135e3dd157SKalle Valo cmd->peer_associd = __cpu_to_le32(arg->peer_aid); 45145e3dd157SKalle Valo cmd->peer_flags = __cpu_to_le32(arg->peer_flags); 45155e3dd157SKalle Valo cmd->peer_caps = __cpu_to_le32(arg->peer_caps); 45165e3dd157SKalle Valo cmd->peer_listen_intval = __cpu_to_le32(arg->peer_listen_intval); 45175e3dd157SKalle Valo cmd->peer_ht_caps = __cpu_to_le32(arg->peer_ht_caps); 45185e3dd157SKalle Valo cmd->peer_max_mpdu = __cpu_to_le32(arg->peer_max_mpdu); 45195e3dd157SKalle Valo cmd->peer_mpdu_density = __cpu_to_le32(arg->peer_mpdu_density); 45205e3dd157SKalle Valo cmd->peer_rate_caps = __cpu_to_le32(arg->peer_rate_caps); 45215e3dd157SKalle Valo cmd->peer_nss = __cpu_to_le32(arg->peer_num_spatial_streams); 45225e3dd157SKalle Valo cmd->peer_vht_caps = __cpu_to_le32(arg->peer_vht_caps); 45235e3dd157SKalle Valo cmd->peer_phymode = __cpu_to_le32(arg->peer_phymode); 45245e3dd157SKalle Valo 4525b25f32cbSKalle Valo ether_addr_copy(cmd->peer_macaddr.addr, arg->addr); 45265e3dd157SKalle Valo 45275e3dd157SKalle Valo cmd->peer_legacy_rates.num_rates = 45285e3dd157SKalle Valo __cpu_to_le32(arg->peer_legacy_rates.num_rates); 45295e3dd157SKalle Valo memcpy(cmd->peer_legacy_rates.rates, arg->peer_legacy_rates.rates, 45305e3dd157SKalle Valo arg->peer_legacy_rates.num_rates); 45315e3dd157SKalle Valo 45325e3dd157SKalle Valo cmd->peer_ht_rates.num_rates = 45335e3dd157SKalle Valo __cpu_to_le32(arg->peer_ht_rates.num_rates); 45345e3dd157SKalle Valo memcpy(cmd->peer_ht_rates.rates, arg->peer_ht_rates.rates, 45355e3dd157SKalle Valo arg->peer_ht_rates.num_rates); 45365e3dd157SKalle Valo 45375e3dd157SKalle Valo cmd->peer_vht_rates.rx_max_rate = 45385e3dd157SKalle Valo __cpu_to_le32(arg->peer_vht_rates.rx_max_rate); 45395e3dd157SKalle Valo cmd->peer_vht_rates.rx_mcs_set = 45405e3dd157SKalle Valo __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set); 45415e3dd157SKalle Valo cmd->peer_vht_rates.tx_max_rate = 45425e3dd157SKalle Valo __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); 45435e3dd157SKalle Valo cmd->peer_vht_rates.tx_mcs_set = 45445e3dd157SKalle Valo __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); 454524c88f78SMichal Kazior } 454624c88f78SMichal Kazior 454724c88f78SMichal Kazior static void 454824c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill_main(struct ath10k *ar, void *buf, 454924c88f78SMichal Kazior const struct wmi_peer_assoc_complete_arg *arg) 455024c88f78SMichal Kazior { 455124c88f78SMichal Kazior struct wmi_main_peer_assoc_complete_cmd *cmd = buf; 455224c88f78SMichal Kazior 455324c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill(ar, buf, arg); 455424c88f78SMichal Kazior memset(cmd->peer_ht_info, 0, sizeof(cmd->peer_ht_info)); 455524c88f78SMichal Kazior } 455624c88f78SMichal Kazior 455724c88f78SMichal Kazior static void 455824c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill_10_1(struct ath10k *ar, void *buf, 455924c88f78SMichal Kazior const struct wmi_peer_assoc_complete_arg *arg) 456024c88f78SMichal Kazior { 456124c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill(ar, buf, arg); 456224c88f78SMichal Kazior } 456324c88f78SMichal Kazior 456424c88f78SMichal Kazior static void 456524c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf, 456624c88f78SMichal Kazior const struct wmi_peer_assoc_complete_arg *arg) 456724c88f78SMichal Kazior { 456824c88f78SMichal Kazior struct wmi_10_2_peer_assoc_complete_cmd *cmd = buf; 456924c88f78SMichal Kazior int max_mcs, max_nss; 457024c88f78SMichal Kazior u32 info0; 457124c88f78SMichal Kazior 457224c88f78SMichal Kazior /* TODO: Is using max values okay with firmware? */ 457324c88f78SMichal Kazior max_mcs = 0xf; 457424c88f78SMichal Kazior max_nss = 0xf; 457524c88f78SMichal Kazior 457624c88f78SMichal Kazior info0 = SM(max_mcs, WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX) | 457724c88f78SMichal Kazior SM(max_nss, WMI_PEER_ASSOC_INFO0_MAX_NSS); 457824c88f78SMichal Kazior 457924c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill(ar, buf, arg); 458024c88f78SMichal Kazior cmd->info0 = __cpu_to_le32(info0); 458124c88f78SMichal Kazior } 458224c88f78SMichal Kazior 4583d7579d12SMichal Kazior static int 4584d7579d12SMichal Kazior ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg) 458524c88f78SMichal Kazior { 458624c88f78SMichal Kazior if (arg->peer_mpdu_density > 16) 458724c88f78SMichal Kazior return -EINVAL; 458824c88f78SMichal Kazior if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) 458924c88f78SMichal Kazior return -EINVAL; 459024c88f78SMichal Kazior if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) 459124c88f78SMichal Kazior return -EINVAL; 459224c88f78SMichal Kazior 4593d7579d12SMichal Kazior return 0; 459424c88f78SMichal Kazior } 459524c88f78SMichal Kazior 4596d7579d12SMichal Kazior static struct sk_buff * 4597d7579d12SMichal Kazior ath10k_wmi_op_gen_peer_assoc(struct ath10k *ar, 4598d7579d12SMichal Kazior const struct wmi_peer_assoc_complete_arg *arg) 4599d7579d12SMichal Kazior { 4600d7579d12SMichal Kazior size_t len = sizeof(struct wmi_main_peer_assoc_complete_cmd); 4601d7579d12SMichal Kazior struct sk_buff *skb; 4602d7579d12SMichal Kazior int ret; 4603d7579d12SMichal Kazior 4604d7579d12SMichal Kazior ret = ath10k_wmi_peer_assoc_check_arg(arg); 4605d7579d12SMichal Kazior if (ret) 4606d7579d12SMichal Kazior return ERR_PTR(ret); 4607d7579d12SMichal Kazior 46087aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 460924c88f78SMichal Kazior if (!skb) 4610d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 461124c88f78SMichal Kazior 461224c88f78SMichal Kazior ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg); 46135e3dd157SKalle Valo 46147aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 461544d6fa90SChun-Yeow Yeoh "wmi peer assoc vdev %d addr %pM (%s)\n", 461644d6fa90SChun-Yeow Yeoh arg->vdev_id, arg->addr, 461744d6fa90SChun-Yeow Yeoh arg->peer_reassoc ? "reassociate" : "new"); 4618d7579d12SMichal Kazior return skb; 4619d7579d12SMichal Kazior } 4620d7579d12SMichal Kazior 4621d7579d12SMichal Kazior static struct sk_buff * 4622d7579d12SMichal Kazior ath10k_wmi_10_1_op_gen_peer_assoc(struct ath10k *ar, 4623d7579d12SMichal Kazior const struct wmi_peer_assoc_complete_arg *arg) 4624d7579d12SMichal Kazior { 4625d7579d12SMichal Kazior size_t len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd); 4626d7579d12SMichal Kazior struct sk_buff *skb; 4627d7579d12SMichal Kazior int ret; 4628d7579d12SMichal Kazior 4629d7579d12SMichal Kazior ret = ath10k_wmi_peer_assoc_check_arg(arg); 4630d7579d12SMichal Kazior if (ret) 4631d7579d12SMichal Kazior return ERR_PTR(ret); 4632d7579d12SMichal Kazior 4633d7579d12SMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 4634d7579d12SMichal Kazior if (!skb) 4635d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 4636d7579d12SMichal Kazior 4637d7579d12SMichal Kazior ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); 4638d7579d12SMichal Kazior 4639d7579d12SMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 4640d7579d12SMichal Kazior "wmi peer assoc vdev %d addr %pM (%s)\n", 4641d7579d12SMichal Kazior arg->vdev_id, arg->addr, 4642d7579d12SMichal Kazior arg->peer_reassoc ? "reassociate" : "new"); 4643d7579d12SMichal Kazior return skb; 4644d7579d12SMichal Kazior } 4645d7579d12SMichal Kazior 4646d7579d12SMichal Kazior static struct sk_buff * 4647d7579d12SMichal Kazior ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar, 4648d7579d12SMichal Kazior const struct wmi_peer_assoc_complete_arg *arg) 4649d7579d12SMichal Kazior { 4650d7579d12SMichal Kazior size_t len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd); 4651d7579d12SMichal Kazior struct sk_buff *skb; 4652d7579d12SMichal Kazior int ret; 4653d7579d12SMichal Kazior 4654d7579d12SMichal Kazior ret = ath10k_wmi_peer_assoc_check_arg(arg); 4655d7579d12SMichal Kazior if (ret) 4656d7579d12SMichal Kazior return ERR_PTR(ret); 4657d7579d12SMichal Kazior 4658d7579d12SMichal Kazior skb = ath10k_wmi_alloc_skb(ar, len); 4659d7579d12SMichal Kazior if (!skb) 4660d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 4661d7579d12SMichal Kazior 4662d7579d12SMichal Kazior ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg); 4663d7579d12SMichal Kazior 4664d7579d12SMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 4665d7579d12SMichal Kazior "wmi peer assoc vdev %d addr %pM (%s)\n", 4666d7579d12SMichal Kazior arg->vdev_id, arg->addr, 4667d7579d12SMichal Kazior arg->peer_reassoc ? "reassociate" : "new"); 4668d7579d12SMichal Kazior return skb; 46695e3dd157SKalle Valo } 46705e3dd157SKalle Valo 4671a57a6a27SRajkumar Manoharan static struct sk_buff * 4672a57a6a27SRajkumar Manoharan ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar) 4673a57a6a27SRajkumar Manoharan { 4674a57a6a27SRajkumar Manoharan struct sk_buff *skb; 4675a57a6a27SRajkumar Manoharan 4676a57a6a27SRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, 0); 4677a57a6a27SRajkumar Manoharan if (!skb) 4678a57a6a27SRajkumar Manoharan return ERR_PTR(-ENOMEM); 4679a57a6a27SRajkumar Manoharan 4680a57a6a27SRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature\n"); 4681a57a6a27SRajkumar Manoharan return skb; 4682a57a6a27SRajkumar Manoharan } 4683a57a6a27SRajkumar Manoharan 4684748afc47SMichal Kazior /* This function assumes the beacon is already DMA mapped */ 4685d7579d12SMichal Kazior static struct sk_buff * 4686d7579d12SMichal Kazior ath10k_wmi_op_gen_beacon_dma(struct ath10k_vif *arvif) 46875e3dd157SKalle Valo { 4688d7579d12SMichal Kazior struct ath10k *ar = arvif->ar; 4689748afc47SMichal Kazior struct wmi_bcn_tx_ref_cmd *cmd; 46905e3dd157SKalle Valo struct sk_buff *skb; 4691748afc47SMichal Kazior struct sk_buff *beacon = arvif->beacon; 4692748afc47SMichal Kazior struct ieee80211_hdr *hdr; 4693748afc47SMichal Kazior u16 fc; 46945e3dd157SKalle Valo 46957aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 46965e3dd157SKalle Valo if (!skb) 4697d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 46985e3dd157SKalle Valo 4699748afc47SMichal Kazior hdr = (struct ieee80211_hdr *)beacon->data; 4700748afc47SMichal Kazior fc = le16_to_cpu(hdr->frame_control); 47015e3dd157SKalle Valo 4702748afc47SMichal Kazior cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data; 4703748afc47SMichal Kazior cmd->vdev_id = __cpu_to_le32(arvif->vdev_id); 4704748afc47SMichal Kazior cmd->data_len = __cpu_to_le32(beacon->len); 4705748afc47SMichal Kazior cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr); 4706748afc47SMichal Kazior cmd->msdu_id = 0; 4707748afc47SMichal Kazior cmd->frame_control = __cpu_to_le32(fc); 4708748afc47SMichal Kazior cmd->flags = 0; 470924c88f78SMichal Kazior cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA); 4710748afc47SMichal Kazior 4711748afc47SMichal Kazior if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero) 4712748afc47SMichal Kazior cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); 4713748afc47SMichal Kazior 4714748afc47SMichal Kazior if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab) 4715748afc47SMichal Kazior cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); 4716748afc47SMichal Kazior 4717d7579d12SMichal Kazior return skb; 47185e3dd157SKalle Valo } 47195e3dd157SKalle Valo 47200226d602SMichal Kazior void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, 47215e3dd157SKalle Valo const struct wmi_wmm_params_arg *arg) 47225e3dd157SKalle Valo { 47235e3dd157SKalle Valo params->cwmin = __cpu_to_le32(arg->cwmin); 47245e3dd157SKalle Valo params->cwmax = __cpu_to_le32(arg->cwmax); 47255e3dd157SKalle Valo params->aifs = __cpu_to_le32(arg->aifs); 47265e3dd157SKalle Valo params->txop = __cpu_to_le32(arg->txop); 47275e3dd157SKalle Valo params->acm = __cpu_to_le32(arg->acm); 47285e3dd157SKalle Valo params->no_ack = __cpu_to_le32(arg->no_ack); 47295e3dd157SKalle Valo } 47305e3dd157SKalle Valo 4731d7579d12SMichal Kazior static struct sk_buff * 4732d7579d12SMichal Kazior ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar, 47335e3dd157SKalle Valo const struct wmi_pdev_set_wmm_params_arg *arg) 47345e3dd157SKalle Valo { 47355e3dd157SKalle Valo struct wmi_pdev_set_wmm_params *cmd; 47365e3dd157SKalle Valo struct sk_buff *skb; 47375e3dd157SKalle Valo 47387aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 47395e3dd157SKalle Valo if (!skb) 4740d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 47415e3dd157SKalle Valo 47425e3dd157SKalle Valo cmd = (struct wmi_pdev_set_wmm_params *)skb->data; 47435e3dd157SKalle Valo ath10k_wmi_pdev_set_wmm_param(&cmd->ac_be, &arg->ac_be); 47445e3dd157SKalle Valo ath10k_wmi_pdev_set_wmm_param(&cmd->ac_bk, &arg->ac_bk); 47455e3dd157SKalle Valo ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vi, &arg->ac_vi); 47465e3dd157SKalle Valo ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); 47475e3dd157SKalle Valo 47487aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); 4749d7579d12SMichal Kazior return skb; 47505e3dd157SKalle Valo } 47515e3dd157SKalle Valo 4752d7579d12SMichal Kazior static struct sk_buff * 4753d7579d12SMichal Kazior ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 47545e3dd157SKalle Valo { 47555e3dd157SKalle Valo struct wmi_request_stats_cmd *cmd; 47565e3dd157SKalle Valo struct sk_buff *skb; 47575e3dd157SKalle Valo 47587aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 47595e3dd157SKalle Valo if (!skb) 4760d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 47615e3dd157SKalle Valo 47625e3dd157SKalle Valo cmd = (struct wmi_request_stats_cmd *)skb->data; 47635e3dd157SKalle Valo cmd->stats_id = __cpu_to_le32(stats_id); 47645e3dd157SKalle Valo 47657aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 4766d7579d12SMichal Kazior return skb; 47675e3dd157SKalle Valo } 47689cfbce75SMichal Kazior 4769d7579d12SMichal Kazior static struct sk_buff * 4770d7579d12SMichal Kazior ath10k_wmi_op_gen_force_fw_hang(struct ath10k *ar, 47719cfbce75SMichal Kazior enum wmi_force_fw_hang_type type, u32 delay_ms) 47729cfbce75SMichal Kazior { 47739cfbce75SMichal Kazior struct wmi_force_fw_hang_cmd *cmd; 47749cfbce75SMichal Kazior struct sk_buff *skb; 47759cfbce75SMichal Kazior 47767aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 47779cfbce75SMichal Kazior if (!skb) 4778d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 47799cfbce75SMichal Kazior 47809cfbce75SMichal Kazior cmd = (struct wmi_force_fw_hang_cmd *)skb->data; 47819cfbce75SMichal Kazior cmd->type = __cpu_to_le32(type); 47829cfbce75SMichal Kazior cmd->delay_ms = __cpu_to_le32(delay_ms); 47839cfbce75SMichal Kazior 47847aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", 47859cfbce75SMichal Kazior type, delay_ms); 4786d7579d12SMichal Kazior return skb; 47879cfbce75SMichal Kazior } 4788f118a3e5SKalle Valo 4789d7579d12SMichal Kazior static struct sk_buff * 4790d7579d12SMichal Kazior ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable) 4791f118a3e5SKalle Valo { 4792f118a3e5SKalle Valo struct wmi_dbglog_cfg_cmd *cmd; 4793f118a3e5SKalle Valo struct sk_buff *skb; 4794f118a3e5SKalle Valo u32 cfg; 4795f118a3e5SKalle Valo 47967aa7a72aSMichal Kazior skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4797f118a3e5SKalle Valo if (!skb) 4798d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 4799f118a3e5SKalle Valo 4800f118a3e5SKalle Valo cmd = (struct wmi_dbglog_cfg_cmd *)skb->data; 4801f118a3e5SKalle Valo 4802f118a3e5SKalle Valo if (module_enable) { 4803f118a3e5SKalle Valo cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE, 4804f118a3e5SKalle Valo ATH10K_DBGLOG_CFG_LOG_LVL); 4805f118a3e5SKalle Valo } else { 4806f118a3e5SKalle Valo /* set back defaults, all modules with WARN level */ 4807f118a3e5SKalle Valo cfg = SM(ATH10K_DBGLOG_LEVEL_WARN, 4808f118a3e5SKalle Valo ATH10K_DBGLOG_CFG_LOG_LVL); 4809f118a3e5SKalle Valo module_enable = ~0; 4810f118a3e5SKalle Valo } 4811f118a3e5SKalle Valo 4812f118a3e5SKalle Valo cmd->module_enable = __cpu_to_le32(module_enable); 4813f118a3e5SKalle Valo cmd->module_valid = __cpu_to_le32(~0); 4814f118a3e5SKalle Valo cmd->config_enable = __cpu_to_le32(cfg); 4815f118a3e5SKalle Valo cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK); 4816f118a3e5SKalle Valo 48177aa7a72aSMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, 4818f118a3e5SKalle Valo "wmi dbglog cfg modules %08x %08x config %08x %08x\n", 4819f118a3e5SKalle Valo __le32_to_cpu(cmd->module_enable), 4820f118a3e5SKalle Valo __le32_to_cpu(cmd->module_valid), 4821f118a3e5SKalle Valo __le32_to_cpu(cmd->config_enable), 4822f118a3e5SKalle Valo __le32_to_cpu(cmd->config_valid)); 4823d7579d12SMichal Kazior return skb; 4824f118a3e5SKalle Valo } 4825b79b9baaSMichal Kazior 4826d7579d12SMichal Kazior static struct sk_buff * 4827d7579d12SMichal Kazior ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) 482890174455SRajkumar Manoharan { 482990174455SRajkumar Manoharan struct wmi_pdev_pktlog_enable_cmd *cmd; 483090174455SRajkumar Manoharan struct sk_buff *skb; 483190174455SRajkumar Manoharan 483290174455SRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 483390174455SRajkumar Manoharan if (!skb) 4834d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 483590174455SRajkumar Manoharan 483690174455SRajkumar Manoharan ev_bitmap &= ATH10K_PKTLOG_ANY; 483790174455SRajkumar Manoharan 483890174455SRajkumar Manoharan cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data; 483990174455SRajkumar Manoharan cmd->ev_bitmap = __cpu_to_le32(ev_bitmap); 4840d7579d12SMichal Kazior 4841d7579d12SMichal Kazior ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi enable pktlog filter 0x%08x\n", 4842d7579d12SMichal Kazior ev_bitmap); 4843d7579d12SMichal Kazior return skb; 484490174455SRajkumar Manoharan } 484590174455SRajkumar Manoharan 4846d7579d12SMichal Kazior static struct sk_buff * 4847d7579d12SMichal Kazior ath10k_wmi_op_gen_pktlog_disable(struct ath10k *ar) 484890174455SRajkumar Manoharan { 484990174455SRajkumar Manoharan struct sk_buff *skb; 485090174455SRajkumar Manoharan 485190174455SRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, 0); 485290174455SRajkumar Manoharan if (!skb) 4853d7579d12SMichal Kazior return ERR_PTR(-ENOMEM); 485490174455SRajkumar Manoharan 485590174455SRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n"); 4856d7579d12SMichal Kazior return skb; 485790174455SRajkumar Manoharan } 485890174455SRajkumar Manoharan 4859ffdd738dSRajkumar Manoharan static struct sk_buff * 4860ffdd738dSRajkumar Manoharan ath10k_wmi_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period, 4861ffdd738dSRajkumar Manoharan u32 duration, u32 next_offset, 4862ffdd738dSRajkumar Manoharan u32 enabled) 4863ffdd738dSRajkumar Manoharan { 4864ffdd738dSRajkumar Manoharan struct wmi_pdev_set_quiet_cmd *cmd; 4865ffdd738dSRajkumar Manoharan struct sk_buff *skb; 4866ffdd738dSRajkumar Manoharan 4867ffdd738dSRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4868ffdd738dSRajkumar Manoharan if (!skb) 4869ffdd738dSRajkumar Manoharan return ERR_PTR(-ENOMEM); 4870ffdd738dSRajkumar Manoharan 4871ffdd738dSRajkumar Manoharan cmd = (struct wmi_pdev_set_quiet_cmd *)skb->data; 4872ffdd738dSRajkumar Manoharan cmd->period = __cpu_to_le32(period); 4873ffdd738dSRajkumar Manoharan cmd->duration = __cpu_to_le32(duration); 4874ffdd738dSRajkumar Manoharan cmd->next_start = __cpu_to_le32(next_offset); 4875ffdd738dSRajkumar Manoharan cmd->enabled = __cpu_to_le32(enabled); 4876ffdd738dSRajkumar Manoharan 4877ffdd738dSRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, 4878ffdd738dSRajkumar Manoharan "wmi quiet param: period %u duration %u enabled %d\n", 4879ffdd738dSRajkumar Manoharan period, duration, enabled); 4880ffdd738dSRajkumar Manoharan return skb; 4881ffdd738dSRajkumar Manoharan } 4882ffdd738dSRajkumar Manoharan 4883dc8ab278SRajkumar Manoharan static struct sk_buff * 4884dc8ab278SRajkumar Manoharan ath10k_wmi_op_gen_addba_clear_resp(struct ath10k *ar, u32 vdev_id, 4885dc8ab278SRajkumar Manoharan const u8 *mac) 4886dc8ab278SRajkumar Manoharan { 4887dc8ab278SRajkumar Manoharan struct wmi_addba_clear_resp_cmd *cmd; 4888dc8ab278SRajkumar Manoharan struct sk_buff *skb; 4889dc8ab278SRajkumar Manoharan 4890dc8ab278SRajkumar Manoharan if (!mac) 4891dc8ab278SRajkumar Manoharan return ERR_PTR(-EINVAL); 4892dc8ab278SRajkumar Manoharan 4893dc8ab278SRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4894dc8ab278SRajkumar Manoharan if (!skb) 4895dc8ab278SRajkumar Manoharan return ERR_PTR(-ENOMEM); 4896dc8ab278SRajkumar Manoharan 4897dc8ab278SRajkumar Manoharan cmd = (struct wmi_addba_clear_resp_cmd *)skb->data; 4898dc8ab278SRajkumar Manoharan cmd->vdev_id = __cpu_to_le32(vdev_id); 4899dc8ab278SRajkumar Manoharan ether_addr_copy(cmd->peer_macaddr.addr, mac); 4900dc8ab278SRajkumar Manoharan 4901dc8ab278SRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, 4902dc8ab278SRajkumar Manoharan "wmi addba clear resp vdev_id 0x%X mac_addr %pM\n", 4903dc8ab278SRajkumar Manoharan vdev_id, mac); 4904dc8ab278SRajkumar Manoharan return skb; 4905dc8ab278SRajkumar Manoharan } 4906dc8ab278SRajkumar Manoharan 490765c0893dSRajkumar Manoharan static struct sk_buff * 490865c0893dSRajkumar Manoharan ath10k_wmi_op_gen_addba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac, 490965c0893dSRajkumar Manoharan u32 tid, u32 buf_size) 491065c0893dSRajkumar Manoharan { 491165c0893dSRajkumar Manoharan struct wmi_addba_send_cmd *cmd; 491265c0893dSRajkumar Manoharan struct sk_buff *skb; 491365c0893dSRajkumar Manoharan 491465c0893dSRajkumar Manoharan if (!mac) 491565c0893dSRajkumar Manoharan return ERR_PTR(-EINVAL); 491665c0893dSRajkumar Manoharan 491765c0893dSRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 491865c0893dSRajkumar Manoharan if (!skb) 491965c0893dSRajkumar Manoharan return ERR_PTR(-ENOMEM); 492065c0893dSRajkumar Manoharan 492165c0893dSRajkumar Manoharan cmd = (struct wmi_addba_send_cmd *)skb->data; 492265c0893dSRajkumar Manoharan cmd->vdev_id = __cpu_to_le32(vdev_id); 492365c0893dSRajkumar Manoharan ether_addr_copy(cmd->peer_macaddr.addr, mac); 492465c0893dSRajkumar Manoharan cmd->tid = __cpu_to_le32(tid); 492565c0893dSRajkumar Manoharan cmd->buffersize = __cpu_to_le32(buf_size); 492665c0893dSRajkumar Manoharan 492765c0893dSRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, 492865c0893dSRajkumar Manoharan "wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n", 492965c0893dSRajkumar Manoharan vdev_id, mac, tid, buf_size); 493065c0893dSRajkumar Manoharan return skb; 493165c0893dSRajkumar Manoharan } 493265c0893dSRajkumar Manoharan 493311597413SRajkumar Manoharan static struct sk_buff * 493411597413SRajkumar Manoharan ath10k_wmi_op_gen_addba_set_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac, 493511597413SRajkumar Manoharan u32 tid, u32 status) 493611597413SRajkumar Manoharan { 493711597413SRajkumar Manoharan struct wmi_addba_setresponse_cmd *cmd; 493811597413SRajkumar Manoharan struct sk_buff *skb; 493911597413SRajkumar Manoharan 494011597413SRajkumar Manoharan if (!mac) 494111597413SRajkumar Manoharan return ERR_PTR(-EINVAL); 494211597413SRajkumar Manoharan 494311597413SRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 494411597413SRajkumar Manoharan if (!skb) 494511597413SRajkumar Manoharan return ERR_PTR(-ENOMEM); 494611597413SRajkumar Manoharan 494711597413SRajkumar Manoharan cmd = (struct wmi_addba_setresponse_cmd *)skb->data; 494811597413SRajkumar Manoharan cmd->vdev_id = __cpu_to_le32(vdev_id); 494911597413SRajkumar Manoharan ether_addr_copy(cmd->peer_macaddr.addr, mac); 495011597413SRajkumar Manoharan cmd->tid = __cpu_to_le32(tid); 495111597413SRajkumar Manoharan cmd->statuscode = __cpu_to_le32(status); 495211597413SRajkumar Manoharan 495311597413SRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, 495411597413SRajkumar Manoharan "wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n", 495511597413SRajkumar Manoharan vdev_id, mac, tid, status); 495611597413SRajkumar Manoharan return skb; 495711597413SRajkumar Manoharan } 495811597413SRajkumar Manoharan 495950abef85SRajkumar Manoharan static struct sk_buff * 496050abef85SRajkumar Manoharan ath10k_wmi_op_gen_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac, 496150abef85SRajkumar Manoharan u32 tid, u32 initiator, u32 reason) 496250abef85SRajkumar Manoharan { 496350abef85SRajkumar Manoharan struct wmi_delba_send_cmd *cmd; 496450abef85SRajkumar Manoharan struct sk_buff *skb; 496550abef85SRajkumar Manoharan 496650abef85SRajkumar Manoharan if (!mac) 496750abef85SRajkumar Manoharan return ERR_PTR(-EINVAL); 496850abef85SRajkumar Manoharan 496950abef85SRajkumar Manoharan skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 497050abef85SRajkumar Manoharan if (!skb) 497150abef85SRajkumar Manoharan return ERR_PTR(-ENOMEM); 497250abef85SRajkumar Manoharan 497350abef85SRajkumar Manoharan cmd = (struct wmi_delba_send_cmd *)skb->data; 497450abef85SRajkumar Manoharan cmd->vdev_id = __cpu_to_le32(vdev_id); 497550abef85SRajkumar Manoharan ether_addr_copy(cmd->peer_macaddr.addr, mac); 497650abef85SRajkumar Manoharan cmd->tid = __cpu_to_le32(tid); 497750abef85SRajkumar Manoharan cmd->initiator = __cpu_to_le32(initiator); 497850abef85SRajkumar Manoharan cmd->reasoncode = __cpu_to_le32(reason); 497950abef85SRajkumar Manoharan 498050abef85SRajkumar Manoharan ath10k_dbg(ar, ATH10K_DBG_WMI, 498150abef85SRajkumar Manoharan "wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n", 498250abef85SRajkumar Manoharan vdev_id, mac, tid, initiator, reason); 498350abef85SRajkumar Manoharan return skb; 498450abef85SRajkumar Manoharan } 498550abef85SRajkumar Manoharan 4986d7579d12SMichal Kazior static const struct wmi_ops wmi_ops = { 4987d7579d12SMichal Kazior .rx = ath10k_wmi_op_rx, 4988d7579d12SMichal Kazior .map_svc = wmi_main_svc_map, 4989d7579d12SMichal Kazior 4990d7579d12SMichal Kazior .pull_scan = ath10k_wmi_op_pull_scan_ev, 4991d7579d12SMichal Kazior .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, 4992d7579d12SMichal Kazior .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, 4993d7579d12SMichal Kazior .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, 4994d7579d12SMichal Kazior .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, 4995d7579d12SMichal Kazior .pull_swba = ath10k_wmi_op_pull_swba_ev, 4996d7579d12SMichal Kazior .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 4997d7579d12SMichal Kazior .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, 4998d7579d12SMichal Kazior .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 4999d7579d12SMichal Kazior .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats, 5000d7579d12SMichal Kazior 5001d7579d12SMichal Kazior .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5002d7579d12SMichal Kazior .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5003d7579d12SMichal Kazior .gen_pdev_set_rd = ath10k_wmi_op_gen_pdev_set_rd, 5004d7579d12SMichal Kazior .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, 5005d7579d12SMichal Kazior .gen_init = ath10k_wmi_op_gen_init, 5006d7579d12SMichal Kazior .gen_start_scan = ath10k_wmi_op_gen_start_scan, 5007d7579d12SMichal Kazior .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, 5008d7579d12SMichal Kazior .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, 5009d7579d12SMichal Kazior .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, 5010d7579d12SMichal Kazior .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, 5011d7579d12SMichal Kazior .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, 5012d7579d12SMichal Kazior .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, 5013d7579d12SMichal Kazior .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, 5014d7579d12SMichal Kazior .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, 5015d7579d12SMichal Kazior .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, 5016d7579d12SMichal Kazior .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, 5017d7579d12SMichal Kazior .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, 5018d7579d12SMichal Kazior .gen_peer_create = ath10k_wmi_op_gen_peer_create, 5019d7579d12SMichal Kazior .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, 5020d7579d12SMichal Kazior .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, 5021d7579d12SMichal Kazior .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, 5022d7579d12SMichal Kazior .gen_peer_assoc = ath10k_wmi_op_gen_peer_assoc, 5023d7579d12SMichal Kazior .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, 5024d7579d12SMichal Kazior .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, 5025d7579d12SMichal Kazior .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, 5026d7579d12SMichal Kazior .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, 5027d7579d12SMichal Kazior .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, 5028d7579d12SMichal Kazior .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, 5029d7579d12SMichal Kazior .gen_request_stats = ath10k_wmi_op_gen_request_stats, 5030d7579d12SMichal Kazior .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, 5031d7579d12SMichal Kazior .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, 5032d7579d12SMichal Kazior .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, 5033d7579d12SMichal Kazior .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, 5034d7579d12SMichal Kazior .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, 5035ffdd738dSRajkumar Manoharan .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, 5036a57a6a27SRajkumar Manoharan /* .gen_pdev_get_temperature not implemented */ 5037dc8ab278SRajkumar Manoharan .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, 503865c0893dSRajkumar Manoharan .gen_addba_send = ath10k_wmi_op_gen_addba_send, 503911597413SRajkumar Manoharan .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 504050abef85SRajkumar Manoharan .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5041be9ce9d8SMichal Kazior /* .gen_bcn_tmpl not implemented */ 5042d7579d12SMichal Kazior }; 5043d7579d12SMichal Kazior 5044d7579d12SMichal Kazior static const struct wmi_ops wmi_10_1_ops = { 5045d7579d12SMichal Kazior .rx = ath10k_wmi_10_1_op_rx, 5046d7579d12SMichal Kazior .map_svc = wmi_10x_svc_map, 5047d7579d12SMichal Kazior .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, 5048d7579d12SMichal Kazior .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats, 5049d7579d12SMichal Kazior .gen_init = ath10k_wmi_10_1_op_gen_init, 5050d7579d12SMichal Kazior .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, 5051d7579d12SMichal Kazior .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, 5052d7579d12SMichal Kazior .gen_peer_assoc = ath10k_wmi_10_1_op_gen_peer_assoc, 5053a57a6a27SRajkumar Manoharan /* .gen_pdev_get_temperature not implemented */ 5054d7579d12SMichal Kazior 5055d7579d12SMichal Kazior /* shared with main branch */ 5056d7579d12SMichal Kazior .pull_scan = ath10k_wmi_op_pull_scan_ev, 5057d7579d12SMichal Kazior .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, 5058d7579d12SMichal Kazior .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, 5059d7579d12SMichal Kazior .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, 5060d7579d12SMichal Kazior .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, 5061d7579d12SMichal Kazior .pull_swba = ath10k_wmi_op_pull_swba_ev, 5062d7579d12SMichal Kazior .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 5063d7579d12SMichal Kazior .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 5064d7579d12SMichal Kazior 5065d7579d12SMichal Kazior .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5066d7579d12SMichal Kazior .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5067d7579d12SMichal Kazior .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, 5068d7579d12SMichal Kazior .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, 5069d7579d12SMichal Kazior .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, 5070d7579d12SMichal Kazior .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, 5071d7579d12SMichal Kazior .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, 5072d7579d12SMichal Kazior .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, 5073d7579d12SMichal Kazior .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, 5074d7579d12SMichal Kazior .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, 5075d7579d12SMichal Kazior .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, 5076d7579d12SMichal Kazior .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, 5077d7579d12SMichal Kazior .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, 5078d7579d12SMichal Kazior .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, 5079d7579d12SMichal Kazior .gen_peer_create = ath10k_wmi_op_gen_peer_create, 5080d7579d12SMichal Kazior .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, 5081d7579d12SMichal Kazior .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, 5082d7579d12SMichal Kazior .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, 5083d7579d12SMichal Kazior .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, 5084d7579d12SMichal Kazior .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, 5085d7579d12SMichal Kazior .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, 5086d7579d12SMichal Kazior .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, 5087d7579d12SMichal Kazior .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, 5088d7579d12SMichal Kazior .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, 5089d7579d12SMichal Kazior .gen_request_stats = ath10k_wmi_op_gen_request_stats, 5090d7579d12SMichal Kazior .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, 5091d7579d12SMichal Kazior .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, 5092d7579d12SMichal Kazior .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, 5093d7579d12SMichal Kazior .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, 5094d7579d12SMichal Kazior .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, 5095ffdd738dSRajkumar Manoharan .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, 5096dc8ab278SRajkumar Manoharan .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, 509765c0893dSRajkumar Manoharan .gen_addba_send = ath10k_wmi_op_gen_addba_send, 509811597413SRajkumar Manoharan .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 509950abef85SRajkumar Manoharan .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5100be9ce9d8SMichal Kazior /* .gen_bcn_tmpl not implemented */ 5101d7579d12SMichal Kazior }; 5102d7579d12SMichal Kazior 5103d7579d12SMichal Kazior static const struct wmi_ops wmi_10_2_ops = { 5104d7579d12SMichal Kazior .rx = ath10k_wmi_10_2_op_rx, 5105d7579d12SMichal Kazior .gen_init = ath10k_wmi_10_2_op_gen_init, 5106d7579d12SMichal Kazior .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, 5107a57a6a27SRajkumar Manoharan /* .gen_pdev_get_temperature not implemented */ 5108d7579d12SMichal Kazior 5109d7579d12SMichal Kazior /* shared with 10.1 */ 5110d7579d12SMichal Kazior .map_svc = wmi_10x_svc_map, 5111d7579d12SMichal Kazior .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, 5112d7579d12SMichal Kazior .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats, 5113d7579d12SMichal Kazior .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, 5114d7579d12SMichal Kazior .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, 5115d7579d12SMichal Kazior 5116d7579d12SMichal Kazior .pull_scan = ath10k_wmi_op_pull_scan_ev, 5117d7579d12SMichal Kazior .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, 5118d7579d12SMichal Kazior .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, 5119d7579d12SMichal Kazior .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, 5120d7579d12SMichal Kazior .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, 5121d7579d12SMichal Kazior .pull_swba = ath10k_wmi_op_pull_swba_ev, 5122d7579d12SMichal Kazior .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 5123d7579d12SMichal Kazior .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 5124d7579d12SMichal Kazior 5125d7579d12SMichal Kazior .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5126d7579d12SMichal Kazior .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5127d7579d12SMichal Kazior .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, 5128d7579d12SMichal Kazior .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, 5129d7579d12SMichal Kazior .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, 5130d7579d12SMichal Kazior .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, 5131d7579d12SMichal Kazior .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, 5132d7579d12SMichal Kazior .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, 5133d7579d12SMichal Kazior .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, 5134d7579d12SMichal Kazior .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, 5135d7579d12SMichal Kazior .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, 5136d7579d12SMichal Kazior .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, 5137d7579d12SMichal Kazior .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, 5138d7579d12SMichal Kazior .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, 5139d7579d12SMichal Kazior .gen_peer_create = ath10k_wmi_op_gen_peer_create, 5140d7579d12SMichal Kazior .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, 5141d7579d12SMichal Kazior .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, 5142d7579d12SMichal Kazior .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, 5143d7579d12SMichal Kazior .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, 5144d7579d12SMichal Kazior .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, 5145d7579d12SMichal Kazior .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, 5146d7579d12SMichal Kazior .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, 5147d7579d12SMichal Kazior .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, 5148d7579d12SMichal Kazior .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, 5149d7579d12SMichal Kazior .gen_request_stats = ath10k_wmi_op_gen_request_stats, 5150d7579d12SMichal Kazior .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, 5151d7579d12SMichal Kazior .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, 5152d7579d12SMichal Kazior .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, 5153d7579d12SMichal Kazior .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, 5154d7579d12SMichal Kazior .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, 5155ffdd738dSRajkumar Manoharan .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, 5156dc8ab278SRajkumar Manoharan .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, 515765c0893dSRajkumar Manoharan .gen_addba_send = ath10k_wmi_op_gen_addba_send, 515811597413SRajkumar Manoharan .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 515950abef85SRajkumar Manoharan .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5160d7579d12SMichal Kazior }; 5161d7579d12SMichal Kazior 51624a16fbecSRajkumar Manoharan static const struct wmi_ops wmi_10_2_4_ops = { 51634a16fbecSRajkumar Manoharan .rx = ath10k_wmi_10_2_op_rx, 51644a16fbecSRajkumar Manoharan .gen_init = ath10k_wmi_10_2_op_gen_init, 51654a16fbecSRajkumar Manoharan .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, 5166a57a6a27SRajkumar Manoharan .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature, 51674a16fbecSRajkumar Manoharan 51684a16fbecSRajkumar Manoharan /* shared with 10.1 */ 51694a16fbecSRajkumar Manoharan .map_svc = wmi_10x_svc_map, 51704a16fbecSRajkumar Manoharan .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, 51714a16fbecSRajkumar Manoharan .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats, 51724a16fbecSRajkumar Manoharan .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, 51734a16fbecSRajkumar Manoharan .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, 51744a16fbecSRajkumar Manoharan 51754a16fbecSRajkumar Manoharan .pull_scan = ath10k_wmi_op_pull_scan_ev, 51764a16fbecSRajkumar Manoharan .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, 51774a16fbecSRajkumar Manoharan .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, 51784a16fbecSRajkumar Manoharan .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, 51794a16fbecSRajkumar Manoharan .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, 51804a16fbecSRajkumar Manoharan .pull_swba = ath10k_wmi_op_pull_swba_ev, 51814a16fbecSRajkumar Manoharan .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 51824a16fbecSRajkumar Manoharan .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 51834a16fbecSRajkumar Manoharan 51844a16fbecSRajkumar Manoharan .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 51854a16fbecSRajkumar Manoharan .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 51864a16fbecSRajkumar Manoharan .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, 51874a16fbecSRajkumar Manoharan .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, 51884a16fbecSRajkumar Manoharan .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, 51894a16fbecSRajkumar Manoharan .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, 51904a16fbecSRajkumar Manoharan .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, 51914a16fbecSRajkumar Manoharan .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, 51924a16fbecSRajkumar Manoharan .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, 51934a16fbecSRajkumar Manoharan .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, 51944a16fbecSRajkumar Manoharan .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, 51954a16fbecSRajkumar Manoharan .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, 51964a16fbecSRajkumar Manoharan .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, 51974a16fbecSRajkumar Manoharan .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, 51984a16fbecSRajkumar Manoharan .gen_peer_create = ath10k_wmi_op_gen_peer_create, 51994a16fbecSRajkumar Manoharan .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, 52004a16fbecSRajkumar Manoharan .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, 52014a16fbecSRajkumar Manoharan .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, 52024a16fbecSRajkumar Manoharan .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, 52034a16fbecSRajkumar Manoharan .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, 52044a16fbecSRajkumar Manoharan .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, 52054a16fbecSRajkumar Manoharan .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, 52064a16fbecSRajkumar Manoharan .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, 52074a16fbecSRajkumar Manoharan .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, 52084a16fbecSRajkumar Manoharan .gen_request_stats = ath10k_wmi_op_gen_request_stats, 52094a16fbecSRajkumar Manoharan .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, 52104a16fbecSRajkumar Manoharan .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, 52114a16fbecSRajkumar Manoharan .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, 52124a16fbecSRajkumar Manoharan .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, 52134a16fbecSRajkumar Manoharan .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, 5214ffdd738dSRajkumar Manoharan .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, 5215dc8ab278SRajkumar Manoharan .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, 521665c0893dSRajkumar Manoharan .gen_addba_send = ath10k_wmi_op_gen_addba_send, 521711597413SRajkumar Manoharan .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 521850abef85SRajkumar Manoharan .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5219be9ce9d8SMichal Kazior /* .gen_bcn_tmpl not implemented */ 52204a16fbecSRajkumar Manoharan }; 52214a16fbecSRajkumar Manoharan 5222b79b9baaSMichal Kazior int ath10k_wmi_attach(struct ath10k *ar) 5223b79b9baaSMichal Kazior { 5224d7579d12SMichal Kazior switch (ar->wmi.op_version) { 52254a16fbecSRajkumar Manoharan case ATH10K_FW_WMI_OP_VERSION_10_2_4: 52264a16fbecSRajkumar Manoharan ar->wmi.cmd = &wmi_10_2_4_cmd_map; 52274a16fbecSRajkumar Manoharan ar->wmi.ops = &wmi_10_2_4_ops; 52284a16fbecSRajkumar Manoharan ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map; 52294a16fbecSRajkumar Manoharan ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map; 52304a16fbecSRajkumar Manoharan break; 5231d7579d12SMichal Kazior case ATH10K_FW_WMI_OP_VERSION_10_2: 5232b79b9baaSMichal Kazior ar->wmi.cmd = &wmi_10_2_cmd_map; 5233d7579d12SMichal Kazior ar->wmi.ops = &wmi_10_2_ops; 5234b79b9baaSMichal Kazior ar->wmi.vdev_param = &wmi_10x_vdev_param_map; 5235b79b9baaSMichal Kazior ar->wmi.pdev_param = &wmi_10x_pdev_param_map; 5236d7579d12SMichal Kazior break; 5237d7579d12SMichal Kazior case ATH10K_FW_WMI_OP_VERSION_10_1: 5238d7579d12SMichal Kazior ar->wmi.cmd = &wmi_10x_cmd_map; 5239d7579d12SMichal Kazior ar->wmi.ops = &wmi_10_1_ops; 5240d7579d12SMichal Kazior ar->wmi.vdev_param = &wmi_10x_vdev_param_map; 5241d7579d12SMichal Kazior ar->wmi.pdev_param = &wmi_10x_pdev_param_map; 5242d7579d12SMichal Kazior break; 5243d7579d12SMichal Kazior case ATH10K_FW_WMI_OP_VERSION_MAIN: 5244b79b9baaSMichal Kazior ar->wmi.cmd = &wmi_cmd_map; 5245d7579d12SMichal Kazior ar->wmi.ops = &wmi_ops; 5246b79b9baaSMichal Kazior ar->wmi.vdev_param = &wmi_vdev_param_map; 5247b79b9baaSMichal Kazior ar->wmi.pdev_param = &wmi_pdev_param_map; 5248d7579d12SMichal Kazior break; 5249ca996ec5SMichal Kazior case ATH10K_FW_WMI_OP_VERSION_TLV: 5250ca996ec5SMichal Kazior ath10k_wmi_tlv_attach(ar); 5251ca996ec5SMichal Kazior break; 5252d7579d12SMichal Kazior case ATH10K_FW_WMI_OP_VERSION_UNSET: 5253d7579d12SMichal Kazior case ATH10K_FW_WMI_OP_VERSION_MAX: 5254d7579d12SMichal Kazior ath10k_err(ar, "unsupported WMI op version: %d\n", 5255d7579d12SMichal Kazior ar->wmi.op_version); 5256d7579d12SMichal Kazior return -EINVAL; 5257b79b9baaSMichal Kazior } 5258b79b9baaSMichal Kazior 5259b79b9baaSMichal Kazior init_completion(&ar->wmi.service_ready); 5260b79b9baaSMichal Kazior init_completion(&ar->wmi.unified_ready); 5261b79b9baaSMichal Kazior 5262b79b9baaSMichal Kazior return 0; 5263b79b9baaSMichal Kazior } 5264b79b9baaSMichal Kazior 5265b79b9baaSMichal Kazior void ath10k_wmi_detach(struct ath10k *ar) 5266b79b9baaSMichal Kazior { 5267b79b9baaSMichal Kazior int i; 5268b79b9baaSMichal Kazior 5269b79b9baaSMichal Kazior /* free the host memory chunks requested by firmware */ 5270b79b9baaSMichal Kazior for (i = 0; i < ar->wmi.num_mem_chunks; i++) { 5271b79b9baaSMichal Kazior dma_free_coherent(ar->dev, 5272b79b9baaSMichal Kazior ar->wmi.mem_chunks[i].len, 5273b79b9baaSMichal Kazior ar->wmi.mem_chunks[i].vaddr, 5274b79b9baaSMichal Kazior ar->wmi.mem_chunks[i].paddr); 5275b79b9baaSMichal Kazior } 5276b79b9baaSMichal Kazior 5277b79b9baaSMichal Kazior ar->wmi.num_mem_chunks = 0; 5278b79b9baaSMichal Kazior } 5279