diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 1277 |
1 files changed, 147 insertions, 1130 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ccf3597..55f90c7 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -23,470 +23,29 @@ #include "wmi.h" #include "mac.h" -/* MAIN WMI cmd track */ -static struct wmi_cmd_map wmi_cmd_map = { - .init_cmdid = WMI_INIT_CMDID, - .start_scan_cmdid = WMI_START_SCAN_CMDID, - .stop_scan_cmdid = WMI_STOP_SCAN_CMDID, - .scan_chan_list_cmdid = WMI_SCAN_CHAN_LIST_CMDID, - .scan_sch_prio_tbl_cmdid = WMI_SCAN_SCH_PRIO_TBL_CMDID, - .pdev_set_regdomain_cmdid = WMI_PDEV_SET_REGDOMAIN_CMDID, - .pdev_set_channel_cmdid = WMI_PDEV_SET_CHANNEL_CMDID, - .pdev_set_param_cmdid = WMI_PDEV_SET_PARAM_CMDID, - .pdev_pktlog_enable_cmdid = WMI_PDEV_PKTLOG_ENABLE_CMDID, - .pdev_pktlog_disable_cmdid = WMI_PDEV_PKTLOG_DISABLE_CMDID, - .pdev_set_wmm_params_cmdid = WMI_PDEV_SET_WMM_PARAMS_CMDID, - .pdev_set_ht_cap_ie_cmdid = WMI_PDEV_SET_HT_CAP_IE_CMDID, - .pdev_set_vht_cap_ie_cmdid = WMI_PDEV_SET_VHT_CAP_IE_CMDID, - .pdev_set_dscp_tid_map_cmdid = WMI_PDEV_SET_DSCP_TID_MAP_CMDID, - .pdev_set_quiet_mode_cmdid = WMI_PDEV_SET_QUIET_MODE_CMDID, - .pdev_green_ap_ps_enable_cmdid = WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, - .pdev_get_tpc_config_cmdid = WMI_PDEV_GET_TPC_CONFIG_CMDID, - .pdev_set_base_macaddr_cmdid = WMI_PDEV_SET_BASE_MACADDR_CMDID, - .vdev_create_cmdid = WMI_VDEV_CREATE_CMDID, - .vdev_delete_cmdid = WMI_VDEV_DELETE_CMDID, - .vdev_start_request_cmdid = WMI_VDEV_START_REQUEST_CMDID, - .vdev_restart_request_cmdid = WMI_VDEV_RESTART_REQUEST_CMDID, - .vdev_up_cmdid = WMI_VDEV_UP_CMDID, - .vdev_stop_cmdid = WMI_VDEV_STOP_CMDID, - .vdev_down_cmdid = WMI_VDEV_DOWN_CMDID, - .vdev_set_param_cmdid = WMI_VDEV_SET_PARAM_CMDID, - .vdev_install_key_cmdid = WMI_VDEV_INSTALL_KEY_CMDID, - .peer_create_cmdid = WMI_PEER_CREATE_CMDID, - .peer_delete_cmdid = WMI_PEER_DELETE_CMDID, - .peer_flush_tids_cmdid = WMI_PEER_FLUSH_TIDS_CMDID, - .peer_set_param_cmdid = WMI_PEER_SET_PARAM_CMDID, - .peer_assoc_cmdid = WMI_PEER_ASSOC_CMDID, - .peer_add_wds_entry_cmdid = WMI_PEER_ADD_WDS_ENTRY_CMDID, - .peer_remove_wds_entry_cmdid = WMI_PEER_REMOVE_WDS_ENTRY_CMDID, - .peer_mcast_group_cmdid = WMI_PEER_MCAST_GROUP_CMDID, - .bcn_tx_cmdid = WMI_BCN_TX_CMDID, - .pdev_send_bcn_cmdid = WMI_PDEV_SEND_BCN_CMDID, - .bcn_tmpl_cmdid = WMI_BCN_TMPL_CMDID, - .bcn_filter_rx_cmdid = WMI_BCN_FILTER_RX_CMDID, - .prb_req_filter_rx_cmdid = WMI_PRB_REQ_FILTER_RX_CMDID, - .mgmt_tx_cmdid = WMI_MGMT_TX_CMDID, - .prb_tmpl_cmdid = WMI_PRB_TMPL_CMDID, - .addba_clear_resp_cmdid = WMI_ADDBA_CLEAR_RESP_CMDID, - .addba_send_cmdid = WMI_ADDBA_SEND_CMDID, - .addba_status_cmdid = WMI_ADDBA_STATUS_CMDID, - .delba_send_cmdid = WMI_DELBA_SEND_CMDID, - .addba_set_resp_cmdid = WMI_ADDBA_SET_RESP_CMDID, - .send_singleamsdu_cmdid = WMI_SEND_SINGLEAMSDU_CMDID, - .sta_powersave_mode_cmdid = WMI_STA_POWERSAVE_MODE_CMDID, - .sta_powersave_param_cmdid = WMI_STA_POWERSAVE_PARAM_CMDID, - .sta_mimo_ps_mode_cmdid = WMI_STA_MIMO_PS_MODE_CMDID, - .pdev_dfs_enable_cmdid = WMI_PDEV_DFS_ENABLE_CMDID, - .pdev_dfs_disable_cmdid = WMI_PDEV_DFS_DISABLE_CMDID, - .roam_scan_mode = WMI_ROAM_SCAN_MODE, - .roam_scan_rssi_threshold = WMI_ROAM_SCAN_RSSI_THRESHOLD, - .roam_scan_period = WMI_ROAM_SCAN_PERIOD, - .roam_scan_rssi_change_threshold = WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, - .roam_ap_profile = WMI_ROAM_AP_PROFILE, - .ofl_scan_add_ap_profile = WMI_ROAM_AP_PROFILE, - .ofl_scan_remove_ap_profile = WMI_OFL_SCAN_REMOVE_AP_PROFILE, - .ofl_scan_period = WMI_OFL_SCAN_PERIOD, - .p2p_dev_set_device_info = WMI_P2P_DEV_SET_DEVICE_INFO, - .p2p_dev_set_discoverability = WMI_P2P_DEV_SET_DISCOVERABILITY, - .p2p_go_set_beacon_ie = WMI_P2P_GO_SET_BEACON_IE, - .p2p_go_set_probe_resp_ie = WMI_P2P_GO_SET_PROBE_RESP_IE, - .p2p_set_vendor_ie_data_cmdid = WMI_P2P_SET_VENDOR_IE_DATA_CMDID, - .ap_ps_peer_param_cmdid = WMI_AP_PS_PEER_PARAM_CMDID, - .ap_ps_peer_uapsd_coex_cmdid = WMI_AP_PS_PEER_UAPSD_COEX_CMDID, - .peer_rate_retry_sched_cmdid = WMI_PEER_RATE_RETRY_SCHED_CMDID, - .wlan_profile_trigger_cmdid = WMI_WLAN_PROFILE_TRIGGER_CMDID, - .wlan_profile_set_hist_intvl_cmdid = - WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, - .wlan_profile_get_profile_data_cmdid = - WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, - .wlan_profile_enable_profile_id_cmdid = - WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, - .wlan_profile_list_profile_id_cmdid = - WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, - .pdev_suspend_cmdid = WMI_PDEV_SUSPEND_CMDID, - .pdev_resume_cmdid = WMI_PDEV_RESUME_CMDID, - .add_bcn_filter_cmdid = WMI_ADD_BCN_FILTER_CMDID, - .rmv_bcn_filter_cmdid = WMI_RMV_BCN_FILTER_CMDID, - .wow_add_wake_pattern_cmdid = WMI_WOW_ADD_WAKE_PATTERN_CMDID, - .wow_del_wake_pattern_cmdid = WMI_WOW_DEL_WAKE_PATTERN_CMDID, - .wow_enable_disable_wake_event_cmdid = - WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, - .wow_enable_cmdid = WMI_WOW_ENABLE_CMDID, - .wow_hostwakeup_from_sleep_cmdid = WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, - .rtt_measreq_cmdid = WMI_RTT_MEASREQ_CMDID, - .rtt_tsf_cmdid = WMI_RTT_TSF_CMDID, - .vdev_spectral_scan_configure_cmdid = - WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, - .vdev_spectral_scan_enable_cmdid = WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, - .request_stats_cmdid = WMI_REQUEST_STATS_CMDID, - .set_arp_ns_offload_cmdid = WMI_SET_ARP_NS_OFFLOAD_CMDID, - .network_list_offload_config_cmdid = - WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, - .gtk_offload_cmdid = WMI_GTK_OFFLOAD_CMDID, - .csa_offload_enable_cmdid = WMI_CSA_OFFLOAD_ENABLE_CMDID, - .csa_offload_chanswitch_cmdid = WMI_CSA_OFFLOAD_CHANSWITCH_CMDID, - .chatter_set_mode_cmdid = WMI_CHATTER_SET_MODE_CMDID, - .peer_tid_addba_cmdid = WMI_PEER_TID_ADDBA_CMDID, - .peer_tid_delba_cmdid = WMI_PEER_TID_DELBA_CMDID, - .sta_dtim_ps_method_cmdid = WMI_STA_DTIM_PS_METHOD_CMDID, - .sta_uapsd_auto_trig_cmdid = WMI_STA_UAPSD_AUTO_TRIG_CMDID, - .sta_keepalive_cmd = WMI_STA_KEEPALIVE_CMD, - .echo_cmdid = WMI_ECHO_CMDID, - .pdev_utf_cmdid = WMI_PDEV_UTF_CMDID, - .dbglog_cfg_cmdid = WMI_DBGLOG_CFG_CMDID, - .pdev_qvit_cmdid = WMI_PDEV_QVIT_CMDID, - .pdev_ftm_intg_cmdid = WMI_PDEV_FTM_INTG_CMDID, - .vdev_set_keepalive_cmdid = WMI_VDEV_SET_KEEPALIVE_CMDID, - .vdev_get_keepalive_cmdid = WMI_VDEV_GET_KEEPALIVE_CMDID, - .force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID, - .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID, - .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID, -}; - -/* 10.X WMI cmd track */ -static struct wmi_cmd_map wmi_10x_cmd_map = { - .init_cmdid = WMI_10X_INIT_CMDID, - .start_scan_cmdid = WMI_10X_START_SCAN_CMDID, - .stop_scan_cmdid = WMI_10X_STOP_SCAN_CMDID, - .scan_chan_list_cmdid = WMI_10X_SCAN_CHAN_LIST_CMDID, - .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, - .pdev_set_regdomain_cmdid = WMI_10X_PDEV_SET_REGDOMAIN_CMDID, - .pdev_set_channel_cmdid = WMI_10X_PDEV_SET_CHANNEL_CMDID, - .pdev_set_param_cmdid = WMI_10X_PDEV_SET_PARAM_CMDID, - .pdev_pktlog_enable_cmdid = WMI_10X_PDEV_PKTLOG_ENABLE_CMDID, - .pdev_pktlog_disable_cmdid = WMI_10X_PDEV_PKTLOG_DISABLE_CMDID, - .pdev_set_wmm_params_cmdid = WMI_10X_PDEV_SET_WMM_PARAMS_CMDID, - .pdev_set_ht_cap_ie_cmdid = WMI_10X_PDEV_SET_HT_CAP_IE_CMDID, - .pdev_set_vht_cap_ie_cmdid = WMI_10X_PDEV_SET_VHT_CAP_IE_CMDID, - .pdev_set_dscp_tid_map_cmdid = WMI_10X_PDEV_SET_DSCP_TID_MAP_CMDID, - .pdev_set_quiet_mode_cmdid = WMI_10X_PDEV_SET_QUIET_MODE_CMDID, - .pdev_green_ap_ps_enable_cmdid = WMI_10X_PDEV_GREEN_AP_PS_ENABLE_CMDID, - .pdev_get_tpc_config_cmdid = WMI_10X_PDEV_GET_TPC_CONFIG_CMDID, - .pdev_set_base_macaddr_cmdid = WMI_10X_PDEV_SET_BASE_MACADDR_CMDID, - .vdev_create_cmdid = WMI_10X_VDEV_CREATE_CMDID, - .vdev_delete_cmdid = WMI_10X_VDEV_DELETE_CMDID, - .vdev_start_request_cmdid = WMI_10X_VDEV_START_REQUEST_CMDID, - .vdev_restart_request_cmdid = WMI_10X_VDEV_RESTART_REQUEST_CMDID, - .vdev_up_cmdid = WMI_10X_VDEV_UP_CMDID, - .vdev_stop_cmdid = WMI_10X_VDEV_STOP_CMDID, - .vdev_down_cmdid = WMI_10X_VDEV_DOWN_CMDID, - .vdev_set_param_cmdid = WMI_10X_VDEV_SET_PARAM_CMDID, - .vdev_install_key_cmdid = WMI_10X_VDEV_INSTALL_KEY_CMDID, - .peer_create_cmdid = WMI_10X_PEER_CREATE_CMDID, - .peer_delete_cmdid = WMI_10X_PEER_DELETE_CMDID, - .peer_flush_tids_cmdid = WMI_10X_PEER_FLUSH_TIDS_CMDID, - .peer_set_param_cmdid = WMI_10X_PEER_SET_PARAM_CMDID, - .peer_assoc_cmdid = WMI_10X_PEER_ASSOC_CMDID, - .peer_add_wds_entry_cmdid = WMI_10X_PEER_ADD_WDS_ENTRY_CMDID, - .peer_remove_wds_entry_cmdid = WMI_10X_PEER_REMOVE_WDS_ENTRY_CMDID, - .peer_mcast_group_cmdid = WMI_10X_PEER_MCAST_GROUP_CMDID, - .bcn_tx_cmdid = WMI_10X_BCN_TX_CMDID, - .pdev_send_bcn_cmdid = WMI_10X_PDEV_SEND_BCN_CMDID, - .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, - .bcn_filter_rx_cmdid = WMI_10X_BCN_FILTER_RX_CMDID, - .prb_req_filter_rx_cmdid = WMI_10X_PRB_REQ_FILTER_RX_CMDID, - .mgmt_tx_cmdid = WMI_10X_MGMT_TX_CMDID, - .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, - .addba_clear_resp_cmdid = WMI_10X_ADDBA_CLEAR_RESP_CMDID, - .addba_send_cmdid = WMI_10X_ADDBA_SEND_CMDID, - .addba_status_cmdid = WMI_10X_ADDBA_STATUS_CMDID, - .delba_send_cmdid = WMI_10X_DELBA_SEND_CMDID, - .addba_set_resp_cmdid = WMI_10X_ADDBA_SET_RESP_CMDID, - .send_singleamsdu_cmdid = WMI_10X_SEND_SINGLEAMSDU_CMDID, - .sta_powersave_mode_cmdid = WMI_10X_STA_POWERSAVE_MODE_CMDID, - .sta_powersave_param_cmdid = WMI_10X_STA_POWERSAVE_PARAM_CMDID, - .sta_mimo_ps_mode_cmdid = WMI_10X_STA_MIMO_PS_MODE_CMDID, - .pdev_dfs_enable_cmdid = WMI_10X_PDEV_DFS_ENABLE_CMDID, - .pdev_dfs_disable_cmdid = WMI_10X_PDEV_DFS_DISABLE_CMDID, - .roam_scan_mode = WMI_10X_ROAM_SCAN_MODE, - .roam_scan_rssi_threshold = WMI_10X_ROAM_SCAN_RSSI_THRESHOLD, - .roam_scan_period = WMI_10X_ROAM_SCAN_PERIOD, - .roam_scan_rssi_change_threshold = - WMI_10X_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, - .roam_ap_profile = WMI_10X_ROAM_AP_PROFILE, - .ofl_scan_add_ap_profile = WMI_10X_OFL_SCAN_ADD_AP_PROFILE, - .ofl_scan_remove_ap_profile = WMI_10X_OFL_SCAN_REMOVE_AP_PROFILE, - .ofl_scan_period = WMI_10X_OFL_SCAN_PERIOD, - .p2p_dev_set_device_info = WMI_10X_P2P_DEV_SET_DEVICE_INFO, - .p2p_dev_set_discoverability = WMI_10X_P2P_DEV_SET_DISCOVERABILITY, - .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE, - .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE, - .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, - .ap_ps_peer_param_cmdid = WMI_CMD_UNSUPPORTED, - .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, - .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID, - .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID, - .wlan_profile_set_hist_intvl_cmdid = - WMI_10X_WLAN_PROFILE_SET_HIST_INTVL_CMDID, - .wlan_profile_get_profile_data_cmdid = - WMI_10X_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, - .wlan_profile_enable_profile_id_cmdid = - WMI_10X_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, - .wlan_profile_list_profile_id_cmdid = - WMI_10X_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, - .pdev_suspend_cmdid = WMI_10X_PDEV_SUSPEND_CMDID, - .pdev_resume_cmdid = WMI_10X_PDEV_RESUME_CMDID, - .add_bcn_filter_cmdid = WMI_10X_ADD_BCN_FILTER_CMDID, - .rmv_bcn_filter_cmdid = WMI_10X_RMV_BCN_FILTER_CMDID, - .wow_add_wake_pattern_cmdid = WMI_10X_WOW_ADD_WAKE_PATTERN_CMDID, - .wow_del_wake_pattern_cmdid = WMI_10X_WOW_DEL_WAKE_PATTERN_CMDID, - .wow_enable_disable_wake_event_cmdid = - WMI_10X_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, - .wow_enable_cmdid = WMI_10X_WOW_ENABLE_CMDID, - .wow_hostwakeup_from_sleep_cmdid = - WMI_10X_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, - .rtt_measreq_cmdid = WMI_10X_RTT_MEASREQ_CMDID, - .rtt_tsf_cmdid = WMI_10X_RTT_TSF_CMDID, - .vdev_spectral_scan_configure_cmdid = - WMI_10X_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, - .vdev_spectral_scan_enable_cmdid = - WMI_10X_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, - .request_stats_cmdid = WMI_10X_REQUEST_STATS_CMDID, - .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, - .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, - .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, - .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, - .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, - .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, - .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, - .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, - .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, - .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, - .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, - .echo_cmdid = WMI_10X_ECHO_CMDID, - .pdev_utf_cmdid = WMI_10X_PDEV_UTF_CMDID, - .dbglog_cfg_cmdid = WMI_10X_DBGLOG_CFG_CMDID, - .pdev_qvit_cmdid = WMI_10X_PDEV_QVIT_CMDID, - .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, - .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, - .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, - .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, - .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID, - .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID, -}; - -/* MAIN WMI VDEV param map */ -static struct wmi_vdev_param_map wmi_vdev_param_map = { - .rts_threshold = WMI_VDEV_PARAM_RTS_THRESHOLD, - .fragmentation_threshold = WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - .beacon_interval = WMI_VDEV_PARAM_BEACON_INTERVAL, - .listen_interval = WMI_VDEV_PARAM_LISTEN_INTERVAL, - .multicast_rate = WMI_VDEV_PARAM_MULTICAST_RATE, - .mgmt_tx_rate = WMI_VDEV_PARAM_MGMT_TX_RATE, - .slot_time = WMI_VDEV_PARAM_SLOT_TIME, - .preamble = WMI_VDEV_PARAM_PREAMBLE, - .swba_time = WMI_VDEV_PARAM_SWBA_TIME, - .wmi_vdev_stats_update_period = WMI_VDEV_STATS_UPDATE_PERIOD, - .wmi_vdev_pwrsave_ageout_time = WMI_VDEV_PWRSAVE_AGEOUT_TIME, - .wmi_vdev_host_swba_interval = WMI_VDEV_HOST_SWBA_INTERVAL, - .dtim_period = WMI_VDEV_PARAM_DTIM_PERIOD, - .wmi_vdev_oc_scheduler_air_time_limit = - WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, - .wds = WMI_VDEV_PARAM_WDS, - .atim_window = WMI_VDEV_PARAM_ATIM_WINDOW, - .bmiss_count_max = WMI_VDEV_PARAM_BMISS_COUNT_MAX, - .bmiss_first_bcnt = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, - .bmiss_final_bcnt = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, - .feature_wmm = WMI_VDEV_PARAM_FEATURE_WMM, - .chwidth = WMI_VDEV_PARAM_CHWIDTH, - .chextoffset = WMI_VDEV_PARAM_CHEXTOFFSET, - .disable_htprotection = WMI_VDEV_PARAM_DISABLE_HTPROTECTION, - .sta_quickkickout = WMI_VDEV_PARAM_STA_QUICKKICKOUT, - .mgmt_rate = WMI_VDEV_PARAM_MGMT_RATE, - .protection_mode = WMI_VDEV_PARAM_PROTECTION_MODE, - .fixed_rate = WMI_VDEV_PARAM_FIXED_RATE, - .sgi = WMI_VDEV_PARAM_SGI, - .ldpc = WMI_VDEV_PARAM_LDPC, - .tx_stbc = WMI_VDEV_PARAM_TX_STBC, - .rx_stbc = WMI_VDEV_PARAM_RX_STBC, - .intra_bss_fwd = WMI_VDEV_PARAM_INTRA_BSS_FWD, - .def_keyid = WMI_VDEV_PARAM_DEF_KEYID, - .nss = WMI_VDEV_PARAM_NSS, - .bcast_data_rate = WMI_VDEV_PARAM_BCAST_DATA_RATE, - .mcast_data_rate = WMI_VDEV_PARAM_MCAST_DATA_RATE, - .mcast_indicate = WMI_VDEV_PARAM_MCAST_INDICATE, - .dhcp_indicate = WMI_VDEV_PARAM_DHCP_INDICATE, - .unknown_dest_indicate = WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, - .ap_keepalive_min_idle_inactive_time_secs = - WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_idle_inactive_time_secs = - WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_unresponsive_time_secs = - WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, - .ap_enable_nawds = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, - .mcast2ucast_set = WMI_VDEV_PARAM_UNSUPPORTED, - .enable_rtscts = WMI_VDEV_PARAM_ENABLE_RTSCTS, - .txbf = WMI_VDEV_PARAM_TXBF, - .packet_powersave = WMI_VDEV_PARAM_PACKET_POWERSAVE, - .drop_unencry = WMI_VDEV_PARAM_DROP_UNENCRY, - .tx_encap_type = WMI_VDEV_PARAM_TX_ENCAP_TYPE, - .ap_detect_out_of_sync_sleeping_sta_time_secs = - WMI_VDEV_PARAM_UNSUPPORTED, -}; - -/* 10.X WMI VDEV param map */ -static struct wmi_vdev_param_map wmi_10x_vdev_param_map = { - .rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD, - .fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - .beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL, - .listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL, - .multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE, - .mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE, - .slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME, - .preamble = WMI_10X_VDEV_PARAM_PREAMBLE, - .swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME, - .wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD, - .wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME, - .wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL, - .dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD, - .wmi_vdev_oc_scheduler_air_time_limit = - WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, - .wds = WMI_10X_VDEV_PARAM_WDS, - .atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW, - .bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX, - .bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, - .bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, - .feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM, - .chwidth = WMI_10X_VDEV_PARAM_CHWIDTH, - .chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET, - .disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION, - .sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT, - .mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE, - .protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE, - .fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE, - .sgi = WMI_10X_VDEV_PARAM_SGI, - .ldpc = WMI_10X_VDEV_PARAM_LDPC, - .tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC, - .rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC, - .intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD, - .def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID, - .nss = WMI_10X_VDEV_PARAM_NSS, - .bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE, - .mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE, - .mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE, - .dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE, - .unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE, - .ap_keepalive_min_idle_inactive_time_secs = - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_idle_inactive_time_secs = - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_unresponsive_time_secs = - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, - .ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS, - .mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET, - .enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, - .txbf = WMI_VDEV_PARAM_UNSUPPORTED, - .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED, - .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED, - .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, - .ap_detect_out_of_sync_sleeping_sta_time_secs = - WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -}; - -static struct wmi_pdev_param_map wmi_pdev_param_map = { - .tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK, - .rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK, - .txpower_limit2g = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, - .txpower_limit5g = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, - .txpower_scale = WMI_PDEV_PARAM_TXPOWER_SCALE, - .beacon_gen_mode = WMI_PDEV_PARAM_BEACON_GEN_MODE, - .beacon_tx_mode = WMI_PDEV_PARAM_BEACON_TX_MODE, - .resmgr_offchan_mode = WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, - .protection_mode = WMI_PDEV_PARAM_PROTECTION_MODE, - .dynamic_bw = WMI_PDEV_PARAM_DYNAMIC_BW, - .non_agg_sw_retry_th = WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, - .agg_sw_retry_th = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, - .sta_kickout_th = WMI_PDEV_PARAM_STA_KICKOUT_TH, - .ac_aggrsize_scaling = WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, - .ltr_enable = WMI_PDEV_PARAM_LTR_ENABLE, - .ltr_ac_latency_be = WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, - .ltr_ac_latency_bk = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, - .ltr_ac_latency_vi = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, - .ltr_ac_latency_vo = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, - .ltr_ac_latency_timeout = WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, - .ltr_sleep_override = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, - .ltr_rx_override = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, - .ltr_tx_activity_timeout = WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, - .l1ss_enable = WMI_PDEV_PARAM_L1SS_ENABLE, - .dsleep_enable = WMI_PDEV_PARAM_DSLEEP_ENABLE, - .pcielp_txbuf_flush = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, - .pcielp_txbuf_watermark = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, - .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, - .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, - .pdev_stats_update_period = WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, - .vdev_stats_update_period = WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, - .peer_stats_update_period = WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, - .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, - .pmf_qos = WMI_PDEV_PARAM_PMF_QOS, - .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, - .arpdhcp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, - .dcs = WMI_PDEV_PARAM_DCS, - .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE, - .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD, - .ani_listen_period = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, - .ani_ofdm_level = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, - .ani_cck_level = WMI_PDEV_PARAM_ANI_CCK_LEVEL, - .dyntxchain = WMI_PDEV_PARAM_DYNTXCHAIN, - .proxy_sta = WMI_PDEV_PARAM_PROXY_STA, - .idle_ps_config = WMI_PDEV_PARAM_IDLE_PS_CONFIG, - .power_gating_sleep = WMI_PDEV_PARAM_POWER_GATING_SLEEP, - .fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED, - .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED, - .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED, -}; - -static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { - .tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK, - .rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK, - .txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G, - .txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G, - .txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE, - .beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE, - .beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE, - .resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE, - .protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE, - .dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW, - .non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH, - .agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH, - .sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH, - .ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING, - .ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE, - .ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE, - .ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK, - .ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI, - .ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO, - .ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, - .ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE, - .ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE, - .ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, - .l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE, - .dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE, - .pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED, - .pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED, - .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED, - .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED, - .pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, - .vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, - .peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, - .bcnflt_stats_update_period = - WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, - .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, - .arp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, - .arpdhcp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE, - .dcs = WMI_10X_PDEV_PARAM_DCS, - .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, - .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, - .ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD, - .ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL, - .ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL, - .dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN, - .proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED, - .idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED, - .power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED, - .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, - .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, - .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, -}; +void ath10k_wmi_flush_tx(struct ath10k *ar) +{ + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + if (ar->state == ATH10K_STATE_WEDGED) { + ath10k_warn("wmi flush skipped - device is wedged anyway\n"); + return; + } + + ret = wait_event_timeout(ar->wmi.wq, + atomic_read(&ar->wmi.pending_tx_count) == 0, + 5*HZ); + if (atomic_read(&ar->wmi.pending_tx_count) == 0) + return; + + if (ret == 0) + ret = -ETIMEDOUT; + + if (ret < 0) + ath10k_warn("wmi flush failed (%d)\n", ret); +} int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { @@ -526,14 +85,18 @@ static struct sk_buff *ath10k_wmi_alloc_skb(u32 len) static void ath10k_wmi_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) { dev_kfree_skb(skb); + + if (atomic_sub_return(1, &ar->wmi.pending_tx_count) == 0) + wake_up(&ar->wmi.wq); } -static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, - u32 cmd_id) +/* WMI command API */ +static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, + enum wmi_cmd_id cmd_id) { struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); struct wmi_cmd_hdr *cmd_hdr; - int ret; + int status; u32 cmd = 0; if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL) @@ -544,146 +107,25 @@ static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, cmd_hdr = (struct wmi_cmd_hdr *)skb->data; cmd_hdr->cmd_id = __cpu_to_le32(cmd); - memset(skb_cb, 0, sizeof(*skb_cb)); - ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); - trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len, ret); - - if (ret) - goto err_pull; - - return 0; - -err_pull: - skb_pull(skb, sizeof(struct wmi_cmd_hdr)); - return ret; -} - -static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) -{ - struct wmi_bcn_tx_arg arg = {0}; - int ret; - - lockdep_assert_held(&arvif->ar->data_lock); - - if (arvif->beacon == NULL) - return; - - arg.vdev_id = arvif->vdev_id; - arg.tx_rate = 0; - arg.tx_power = 0; - arg.bcn = arvif->beacon->data; - arg.bcn_len = arvif->beacon->len; - - ret = ath10k_wmi_beacon_send_nowait(arvif->ar, &arg); - if (ret) - return; - - dev_kfree_skb_any(arvif->beacon); - arvif->beacon = NULL; -} - -static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); - - ath10k_wmi_tx_beacon_nowait(arvif); -} - -static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar) -{ - spin_lock_bh(&ar->data_lock); - ieee80211_iterate_active_interfaces_atomic(ar->hw, - IEEE80211_IFACE_ITER_NORMAL, - ath10k_wmi_tx_beacons_iter, - NULL); - spin_unlock_bh(&ar->data_lock); -} - -static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) -{ - /* try to send pending beacons first. they take priority */ - ath10k_wmi_tx_beacons_nowait(ar); - - wake_up(&ar->wmi.tx_credits_wq); -} - -static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, - u32 cmd_id) -{ - int ret = -EOPNOTSUPP; - - might_sleep(); - - if (cmd_id == WMI_CMD_UNSUPPORTED) { - ath10k_warn("wmi command %d is not supported by firmware\n", - cmd_id); - return ret; + if (atomic_add_return(1, &ar->wmi.pending_tx_count) > + WMI_MAX_PENDING_TX_COUNT) { + /* avoid using up memory when FW hangs */ + atomic_dec(&ar->wmi.pending_tx_count); + return -EBUSY; } - wait_event_timeout(ar->wmi.tx_credits_wq, ({ - /* try to send pending beacons first. they take priority */ - ath10k_wmi_tx_beacons_nowait(ar); - - ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id); - (ret != -EAGAIN); - }), 3*HZ); - - if (ret) - dev_kfree_skb_any(skb); - - return ret; -} - -int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) -{ - int ret = 0; - struct wmi_mgmt_tx_cmd *cmd; - struct ieee80211_hdr *hdr; - struct sk_buff *wmi_skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int len; - u16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = le16_to_cpu(hdr->frame_control); - - if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) - return -EINVAL; - - len = sizeof(cmd->hdr) + skb->len; - len = round_up(len, 4); - - wmi_skb = ath10k_wmi_alloc_skb(len); - if (!wmi_skb) - return -ENOMEM; - - cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data; - - cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); - cmd->hdr.tx_rate = 0; - cmd->hdr.tx_power = 0; - cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len)); - - memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); - memcpy(cmd->buf, skb->data, skb->len); + memset(skb_cb, 0, sizeof(*skb_cb)); - ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", - wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, - fc & IEEE80211_FCTL_STYPE); + trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len); - /* Send the management frame buffer to the target */ - ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); - if (ret) { + status = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); + if (status) { dev_kfree_skb_any(skb); - return ret; + atomic_dec(&ar->wmi.pending_tx_count); + return status; } - /* TODO: report tx status to mac80211 - temporary just ACK */ - info->flags |= IEEE80211_TX_STAT_ACK; - ieee80211_tx_status_irqsafe(ar->hw, skb); - - return ret; + return 0; } static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) @@ -873,9 +315,7 @@ static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band) static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) { - struct wmi_mgmt_rx_event_v1 *ev_v1; - struct wmi_mgmt_rx_event_v2 *ev_v2; - struct wmi_mgmt_rx_hdr_v1 *ev_hdr; + struct wmi_mgmt_rx_event *event = (struct wmi_mgmt_rx_event *)skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr; u32 rx_status; @@ -885,24 +325,13 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) u32 rate; u32 buf_len; u16 fc; - int pull_len; - - if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { - ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; - ev_hdr = &ev_v2->hdr.v1; - pull_len = sizeof(*ev_v2); - } else { - ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data; - ev_hdr = &ev_v1->hdr; - pull_len = sizeof(*ev_v1); - } - channel = __le32_to_cpu(ev_hdr->channel); - buf_len = __le32_to_cpu(ev_hdr->buf_len); - rx_status = __le32_to_cpu(ev_hdr->status); - snr = __le32_to_cpu(ev_hdr->snr); - phy_mode = __le32_to_cpu(ev_hdr->phy_mode); - rate = __le32_to_cpu(ev_hdr->rate); + channel = __le32_to_cpu(event->hdr.channel); + buf_len = __le32_to_cpu(event->hdr.buf_len); + rx_status = __le32_to_cpu(event->hdr.status); + snr = __le32_to_cpu(event->hdr.snr); + phy_mode = __le32_to_cpu(event->hdr.phy_mode); + rate = __le32_to_cpu(event->hdr.rate); memset(status, 0, sizeof(*status)); @@ -929,7 +358,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; status->rate_idx = get_rate_idx(rate, status->band); - skb_pull(skb, pull_len); + skb_pull(skb, sizeof(event->hdr)); hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); @@ -1305,8 +734,10 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) int i = -1; struct wmi_bcn_info *bcn_info; struct ath10k_vif *arvif; + struct wmi_bcn_tx_arg arg; struct sk_buff *bcn; int vdev_id = 0; + int ret; ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n"); @@ -1363,17 +794,17 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info); ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); - spin_lock_bh(&ar->data_lock); - if (arvif->beacon) { - ath10k_warn("SWBA overrun on vdev %d\n", - arvif->vdev_id); - dev_kfree_skb_any(arvif->beacon); - } + arg.vdev_id = arvif->vdev_id; + arg.tx_rate = 0; + arg.tx_power = 0; + arg.bcn = bcn->data; + arg.bcn_len = bcn->len; - arvif->beacon = bcn; + ret = ath10k_wmi_beacon_send(ar, &arg); + if (ret) + ath10k_warn("could not send beacon (%d)\n", ret); - ath10k_wmi_tx_beacon_nowait(arvif); - spin_unlock_bh(&ar->data_lock); + dev_kfree_skb_any(bcn); } } @@ -1488,55 +919,6 @@ static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); } -static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, - struct sk_buff *skb) -{ - ath10k_dbg(ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); -} - -static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, - struct sk_buff *skb) -{ - ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); -} - -static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, - struct sk_buff *skb) -{ - ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); -} - -static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, - u32 num_units, u32 unit_len) -{ - dma_addr_t paddr; - u32 pool_size; - int idx = ar->wmi.num_mem_chunks; - - pool_size = num_units * round_up(unit_len, 4); - - if (!pool_size) - return -EINVAL; - - ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev, - pool_size, - &paddr, - GFP_ATOMIC); - if (!ar->wmi.mem_chunks[idx].vaddr) { - ath10k_warn("failed to allocate memory chunk\n"); - return -ENOMEM; - } - - memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size); - - ar->wmi.mem_chunks[idx].paddr = paddr; - ar->wmi.mem_chunks[idx].len = pool_size; - ar->wmi.mem_chunks[idx].req_id = req_id; - ar->wmi.num_mem_chunks++; - - return 0; -} - static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) { @@ -1561,10 +943,6 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, ar->phy_capability = __le32_to_cpu(ev->phy_capability); ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); - /* only manually set fw features when not using FW IE format */ - if (ar->fw_api == 1 && ar->fw_version_build > 636) - set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); - if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); @@ -1609,108 +987,6 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, complete(&ar->wmi.service_ready); } -static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, - struct sk_buff *skb) -{ - u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; - int ret; - struct wmi_service_ready_event_10x *ev = (void *)skb->data; - - if (skb->len < sizeof(*ev)) { - ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", - skb->len, sizeof(*ev)); - return; - } - - ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); - ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); - ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); - ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); - ar->fw_version_major = - (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; - ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); - ar->phy_capability = __le32_to_cpu(ev->phy_capability); - ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); - - if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { - ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", - ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); - ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; - } - - ar->ath_common.regulatory.current_rd = - __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); - - ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, - sizeof(ev->wmi_service_bitmap)); - - if (strlen(ar->hw->wiphy->fw_version) == 0) { - snprintf(ar->hw->wiphy->fw_version, - sizeof(ar->hw->wiphy->fw_version), - "%u.%u", - ar->fw_version_major, - ar->fw_version_minor); - } - - num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs); - - if (num_mem_reqs > ATH10K_MAX_MEM_REQS) { - ath10k_warn("requested memory chunks number (%d) exceeds the limit\n", - num_mem_reqs); - return; - } - - if (!num_mem_reqs) - goto exit; - - ath10k_dbg(ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n", - num_mem_reqs); - - for (i = 0; i < num_mem_reqs; ++i) { - req_id = __le32_to_cpu(ev->mem_reqs[i].req_id); - num_units = __le32_to_cpu(ev->mem_reqs[i].num_units); - unit_size = __le32_to_cpu(ev->mem_reqs[i].unit_size); - num_unit_info = __le32_to_cpu(ev->mem_reqs[i].num_unit_info); - - if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) - /* number of units to allocate is number of - * peers, 1 extra for self peer on target */ - /* this needs to be tied, host and target - * can get out of sync */ - num_units = TARGET_10X_NUM_PEERS + 1; - else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) - num_units = TARGET_10X_NUM_VDEVS + 1; - - ath10k_dbg(ATH10K_DBG_WMI, - "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", - req_id, - __le32_to_cpu(ev->mem_reqs[i].num_units), - num_unit_info, - unit_size, - num_units); - - ret = ath10k_wmi_alloc_host_mem(ar, req_id, num_units, - unit_size); - if (ret) - return; - } - -exit: - ath10k_dbg(ATH10K_DBG_WMI, - "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", - __le32_to_cpu(ev->sw_version), - __le32_to_cpu(ev->abi_version), - __le32_to_cpu(ev->phy_capability), - __le32_to_cpu(ev->ht_cap_info), - __le32_to_cpu(ev->vht_cap_info), - __le32_to_cpu(ev->vht_supp_mcs), - __le32_to_cpu(ev->sys_cap_info), - __le32_to_cpu(ev->num_mem_reqs), - __le32_to_cpu(ev->num_rf_chains)); - - complete(&ar->wmi.service_ready); -} - static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data; @@ -1731,7 +1007,7 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) return 0; } -static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) +static void ath10k_wmi_event_process(struct ath10k *ar, struct sk_buff *skb) { struct wmi_cmd_hdr *cmd_hdr; enum wmi_event_id id; @@ -1850,158 +1126,64 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) dev_kfree_skb(skb); } -static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) +static void ath10k_wmi_event_work(struct work_struct *work) { - struct wmi_cmd_hdr *cmd_hdr; - enum wmi_10x_event_id id; - u16 len; + struct ath10k *ar = container_of(work, struct ath10k, + wmi.wmi_event_work); + struct sk_buff *skb; - cmd_hdr = (struct wmi_cmd_hdr *)skb->data; - id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); + for (;;) { + skb = skb_dequeue(&ar->wmi.wmi_event_list); + if (!skb) + break; - if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) - return; + ath10k_wmi_event_process(ar, skb); + } +} - len = skb->len; +static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) +{ + struct wmi_cmd_hdr *cmd_hdr = (struct wmi_cmd_hdr *)skb->data; + enum wmi_event_id event_id; - trace_ath10k_wmi_event(id, skb->data, skb->len); + event_id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); - switch (id) { - case WMI_10X_MGMT_RX_EVENTID: - ath10k_wmi_event_mgmt_rx(ar, skb); - /* mgmt_rx() owns the skb now! */ + /* some events require to be handled ASAP + * thus can't be defered to a worker thread */ + switch (event_id) { + case WMI_HOST_SWBA_EVENTID: + case WMI_MGMT_RX_EVENTID: + ath10k_wmi_event_process(ar, skb); return; - case WMI_10X_SCAN_EVENTID: - ath10k_wmi_event_scan(ar, skb); - break; - case WMI_10X_CHAN_INFO_EVENTID: - ath10k_wmi_event_chan_info(ar, skb); - break; - case WMI_10X_ECHO_EVENTID: - ath10k_wmi_event_echo(ar, skb); - break; - case WMI_10X_DEBUG_MESG_EVENTID: - ath10k_wmi_event_debug_mesg(ar, skb); - break; - case WMI_10X_UPDATE_STATS_EVENTID: - ath10k_wmi_event_update_stats(ar, skb); - break; - case WMI_10X_VDEV_START_RESP_EVENTID: - ath10k_wmi_event_vdev_start_resp(ar, skb); - break; - case WMI_10X_VDEV_STOPPED_EVENTID: - ath10k_wmi_event_vdev_stopped(ar, skb); - break; - case WMI_10X_PEER_STA_KICKOUT_EVENTID: - ath10k_wmi_event_peer_sta_kickout(ar, skb); - break; - case WMI_10X_HOST_SWBA_EVENTID: - ath10k_wmi_event_host_swba(ar, skb); - break; - case WMI_10X_TBTTOFFSET_UPDATE_EVENTID: - ath10k_wmi_event_tbttoffset_update(ar, skb); - break; - case WMI_10X_PHYERR_EVENTID: - ath10k_wmi_event_phyerr(ar, skb); - break; - case WMI_10X_ROAM_EVENTID: - ath10k_wmi_event_roam(ar, skb); - break; - case WMI_10X_PROFILE_MATCH: - ath10k_wmi_event_profile_match(ar, skb); - break; - case WMI_10X_DEBUG_PRINT_EVENTID: - ath10k_wmi_event_debug_print(ar, skb); - break; - case WMI_10X_PDEV_QVIT_EVENTID: - ath10k_wmi_event_pdev_qvit(ar, skb); - break; - case WMI_10X_WLAN_PROFILE_DATA_EVENTID: - ath10k_wmi_event_wlan_profile_data(ar, skb); - break; - case WMI_10X_RTT_MEASUREMENT_REPORT_EVENTID: - ath10k_wmi_event_rtt_measurement_report(ar, skb); - break; - case WMI_10X_TSF_MEASUREMENT_REPORT_EVENTID: - ath10k_wmi_event_tsf_measurement_report(ar, skb); - break; - case WMI_10X_RTT_ERROR_REPORT_EVENTID: - ath10k_wmi_event_rtt_error_report(ar, skb); - break; - case WMI_10X_WOW_WAKEUP_HOST_EVENTID: - ath10k_wmi_event_wow_wakeup_host(ar, skb); - break; - case WMI_10X_DCS_INTERFERENCE_EVENTID: - ath10k_wmi_event_dcs_interference(ar, skb); - break; - case WMI_10X_PDEV_TPC_CONFIG_EVENTID: - ath10k_wmi_event_pdev_tpc_config(ar, skb); - break; - case WMI_10X_INST_RSSI_STATS_EVENTID: - ath10k_wmi_event_inst_rssi_stats(ar, skb); - break; - case WMI_10X_VDEV_STANDBY_REQ_EVENTID: - ath10k_wmi_event_vdev_standby_req(ar, skb); - break; - case WMI_10X_VDEV_RESUME_REQ_EVENTID: - ath10k_wmi_event_vdev_resume_req(ar, skb); - break; - case WMI_10X_SERVICE_READY_EVENTID: - ath10k_wmi_10x_service_ready_event_rx(ar, skb); - break; - case WMI_10X_READY_EVENTID: - ath10k_wmi_ready_event_rx(ar, skb); - break; default: - ath10k_warn("Unknown eventid: %d\n", id); break; } - dev_kfree_skb(skb); -} - - -static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) -{ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ath10k_wmi_10x_process_rx(ar, skb); - else - ath10k_wmi_main_process_rx(ar, skb); + skb_queue_tail(&ar->wmi.wmi_event_list, skb); + queue_work(ar->workqueue, &ar->wmi.wmi_event_work); } /* WMI Initialization functions */ int ath10k_wmi_attach(struct ath10k *ar) { - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { - ar->wmi.cmd = &wmi_10x_cmd_map; - ar->wmi.vdev_param = &wmi_10x_vdev_param_map; - ar->wmi.pdev_param = &wmi_10x_pdev_param_map; - } else { - ar->wmi.cmd = &wmi_cmd_map; - ar->wmi.vdev_param = &wmi_vdev_param_map; - ar->wmi.pdev_param = &wmi_pdev_param_map; - } - init_completion(&ar->wmi.service_ready); init_completion(&ar->wmi.unified_ready); - init_waitqueue_head(&ar->wmi.tx_credits_wq); + init_waitqueue_head(&ar->wmi.wq); + + skb_queue_head_init(&ar->wmi.wmi_event_list); + INIT_WORK(&ar->wmi.wmi_event_work, ath10k_wmi_event_work); return 0; } void ath10k_wmi_detach(struct ath10k *ar) { - int i; - - /* free the host memory chunks requested by firmware */ - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - dma_free_coherent(ar->dev, - ar->wmi.mem_chunks[i].len, - ar->wmi.mem_chunks[i].vaddr, - ar->wmi.mem_chunks[i].paddr); - } + /* HTC should've drained the packets already */ + if (WARN_ON(atomic_read(&ar->wmi.pending_tx_count) > 0)) + ath10k_warn("there are still pending packets\n"); - ar->wmi.num_mem_chunks = 0; + cancel_work_sync(&ar->wmi.wmi_event_work); + skb_queue_purge(&ar->wmi.wmi_event_list); } int ath10k_wmi_connect_htc_service(struct ath10k *ar) @@ -2016,7 +1198,6 @@ int ath10k_wmi_connect_htc_service(struct ath10k *ar) /* these fields are the same for all service endpoints */ conn_req.ep_ops.ep_tx_complete = ath10k_wmi_htc_tx_complete; conn_req.ep_ops.ep_rx_complete = ath10k_wmi_process_rx; - conn_req.ep_ops.ep_tx_credits = ath10k_wmi_op_ep_tx_credits; /* connect to control service */ conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL; @@ -2053,8 +1234,7 @@ int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", rd, rd2g, rd5g, ctl2g, ctl5g); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_regdomain_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_REGDOMAIN_CMDID); } int ath10k_wmi_pdev_set_channel(struct ath10k *ar, @@ -2084,8 +1264,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar, "wmi set channel mode %d freq %d\n", arg->mode, arg->freq); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_channel_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_CHANNEL_CMDID); } int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) @@ -2100,7 +1279,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) cmd = (struct wmi_pdev_suspend_cmd *)skb->data; cmd->suspend_opt = WMI_PDEV_SUSPEND; - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SUSPEND_CMDID); } int ath10k_wmi_pdev_resume_target(struct ath10k *ar) @@ -2111,19 +1290,15 @@ int ath10k_wmi_pdev_resume_target(struct ath10k *ar) if (skb == NULL) return -ENOMEM; - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_RESUME_CMDID); } -int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) +int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id, + u32 value) { struct wmi_pdev_set_param_cmd *cmd; struct sk_buff *skb; - if (id == WMI_PDEV_PARAM_UNSUPPORTED) { - ath10k_warn("pdev param %d not supported by firmware\n", id); - return -EOPNOTSUPP; - } - skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); if (!skb) return -ENOMEM; @@ -2134,16 +1309,15 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", id, value); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_PARAM_CMDID); } -static int ath10k_wmi_main_cmd_init(struct ath10k *ar) +int ath10k_wmi_cmd_init(struct ath10k *ar) { struct wmi_init_cmd *cmd; struct sk_buff *buf; struct wmi_resource_config config = {}; - u32 len, val; - int i; + u32 val; config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS); @@ -2196,158 +1370,23 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC); config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES); - len = sizeof(*cmd) + - (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); - - buf = ath10k_wmi_alloc_skb(len); + buf = ath10k_wmi_alloc_skb(sizeof(*cmd)); if (!buf) return -ENOMEM; cmd = (struct wmi_init_cmd *)buf->data; - - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - __cpu_to_le32(ar->wmi.num_mem_chunks)); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%x\n", - i, - cmd->host_mem_chunks[i].size, - cmd->host_mem_chunks[i].ptr); - } -out: + cmd->num_host_mem_chunks = 0; memcpy(&cmd->resource_config, &config, sizeof(config)); ath10k_dbg(ATH10K_DBG_WMI, "wmi init\n"); - return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); + return ath10k_wmi_cmd_send(ar, buf, WMI_INIT_CMDID); } -static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) -{ - struct wmi_init_cmd_10x *cmd; - struct sk_buff *buf; - struct wmi_resource_config_10x config = {}; - u32 len, val; - int i; - - config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); - config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); - config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); - config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); - config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); - config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); - config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); - config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); - config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); - config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); - config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); - config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); - - config.scan_max_pending_reqs = - __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); - - config.bmiss_offload_max_vdev = - __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); - - config.roam_offload_max_vdev = - __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); - - config.roam_offload_max_ap_profiles = - __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); - - config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); - config.num_mcast_table_elems = - __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); - - config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); - config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); - config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); - config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE); - config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); - - val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; - config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); - - config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); - - config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); - config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); - - len = sizeof(*cmd) + - (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); - - buf = ath10k_wmi_alloc_skb(len); - if (!buf) - return -ENOMEM; - - cmd = (struct wmi_init_cmd_10x *)buf->data; - - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - __cpu_to_le32(ar->wmi.num_mem_chunks)); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%x\n", - i, - cmd->host_mem_chunks[i].size, - cmd->host_mem_chunks[i].ptr); - } -out: - memcpy(&cmd->resource_config, &config, sizeof(config)); - - ath10k_dbg(ATH10K_DBG_WMI, "wmi init 10x\n"); - return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); -} - -int ath10k_wmi_cmd_init(struct ath10k *ar) -{ - int ret; - - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ret = ath10k_wmi_10x_cmd_init(ar); - else - ret = ath10k_wmi_main_cmd_init(ar); - - return ret; -} - -static int ath10k_wmi_start_scan_calc_len(struct ath10k *ar, - const struct wmi_start_scan_arg *arg) +static int ath10k_wmi_start_scan_calc_len(const struct wmi_start_scan_arg *arg) { int len; - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - len = sizeof(struct wmi_start_scan_cmd_10x); - else - len = sizeof(struct wmi_start_scan_cmd); + len = sizeof(struct wmi_start_scan_cmd); if (arg->ie_len) { if (!arg->ie) @@ -2407,7 +1446,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, int len = 0; int i; - len = ath10k_wmi_start_scan_calc_len(ar, arg); + len = ath10k_wmi_start_scan_calc_len(arg); if (len < 0) return len; /* len contains error code here */ @@ -2439,14 +1478,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, cmd->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); /* TLV list starts after fields included in the struct */ - /* There's just one filed that differes the two start_scan - * structures - burst_duration, which we are not using btw, - no point to make the split here, just shift the buffer to fit with - given FW */ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - off = sizeof(struct wmi_start_scan_cmd_10x); - else - off = sizeof(struct wmi_start_scan_cmd); + off = sizeof(*cmd); if (arg->n_channels) { channels = (void *)skb->data + off; @@ -2508,7 +1540,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, } ath10k_dbg(ATH10K_DBG_WMI, "wmi start scan\n"); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_START_SCAN_CMDID); } void ath10k_wmi_start_scan_init(struct ath10k *ar, @@ -2524,7 +1556,7 @@ void ath10k_wmi_start_scan_init(struct ath10k *ar, arg->repeat_probe_time = 0; arg->probe_spacing_time = 0; arg->idle_time = 0; - arg->max_scan_time = 20000; + arg->max_scan_time = 5000; arg->probe_delay = 5; arg->notify_scan_events = WMI_SCAN_EVENT_STARTED | WMI_SCAN_EVENT_COMPLETED @@ -2568,7 +1600,7 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) ath10k_dbg(ATH10K_DBG_WMI, "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", arg->req_id, arg->req_type, arg->u.scan_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_STOP_SCAN_CMDID); } int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, @@ -2593,7 +1625,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", vdev_id, type, subtype, macaddr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_CREATE_CMDID); } int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) @@ -2611,20 +1643,20 @@ int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) ath10k_dbg(ATH10K_DBG_WMI, "WMI vdev delete id %d\n", vdev_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_DELETE_CMDID); } static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, const struct wmi_vdev_start_request_arg *arg, - u32 cmd_id) + enum wmi_cmd_id cmd_id) { struct wmi_vdev_start_request_cmd *cmd; struct sk_buff *skb; const char *cmdname; u32 flags = 0; - if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && - cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) + if (cmd_id != WMI_VDEV_START_REQUEST_CMDID && + cmd_id != WMI_VDEV_RESTART_REQUEST_CMDID) return -EINVAL; if (WARN_ON(arg->ssid && arg->ssid_len == 0)) return -EINVAL; @@ -2633,9 +1665,9 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) return -EINVAL; - if (cmd_id == ar->wmi.cmd->vdev_start_request_cmdid) + if (cmd_id == WMI_VDEV_START_REQUEST_CMDID) cmdname = "start"; - else if (cmd_id == ar->wmi.cmd->vdev_restart_request_cmdid) + else if (cmd_id == WMI_VDEV_RESTART_REQUEST_CMDID) cmdname = "restart"; else return -EINVAL; /* should not happen, we already check cmd_id */ @@ -2686,17 +1718,15 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, int ath10k_wmi_vdev_start(struct ath10k *ar, const struct wmi_vdev_start_request_arg *arg) { - u32 cmd_id = ar->wmi.cmd->vdev_start_request_cmdid; - - return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id); + return ath10k_wmi_vdev_start_restart(ar, arg, + WMI_VDEV_START_REQUEST_CMDID); } int ath10k_wmi_vdev_restart(struct ath10k *ar, const struct wmi_vdev_start_request_arg *arg) { - u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid; - - return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id); + return ath10k_wmi_vdev_start_restart(ar, arg, + WMI_VDEV_RESTART_REQUEST_CMDID); } int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) @@ -2713,7 +1743,7 @@ int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_STOP_CMDID); } int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) @@ -2728,13 +1758,13 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) cmd = (struct wmi_vdev_up_cmd *)skb->data; cmd->vdev_id = __cpu_to_le32(vdev_id); cmd->vdev_assoc_id = __cpu_to_le32(aid); - memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); + memcpy(&cmd->vdev_bssid.addr, bssid, 6); ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", vdev_id, aid, bssid); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_UP_CMDID); } int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) @@ -2752,22 +1782,15 @@ int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt vdev down id 0x%x\n", vdev_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_DOWN_CMDID); } int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, - u32 param_id, u32 param_value) + enum wmi_vdev_param param_id, u32 param_value) { struct wmi_vdev_set_param_cmd *cmd; struct sk_buff *skb; - if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) { - ath10k_dbg(ATH10K_DBG_WMI, - "vdev param %d not supported by firmware\n", - param_id); - return -EOPNOTSUPP; - } - skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); if (!skb) return -ENOMEM; @@ -2781,7 +1804,7 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, "wmi vdev id 0x%x set param %d value %d\n", vdev_id, param_id, param_value); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_SET_PARAM_CMDID); } int ath10k_wmi_vdev_install_key(struct ath10k *ar, @@ -2816,8 +1839,7 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev install key idx %d cipher %d len %d\n", arg->key_idx, arg->key_cipher, arg->key_len); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->vdev_install_key_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_INSTALL_KEY_CMDID); } int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, @@ -2837,7 +1859,7 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer create vdev_id %d peer_addr %pM\n", vdev_id, peer_addr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_CREATE_CMDID); } int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, @@ -2857,7 +1879,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer delete vdev_id %d peer_addr %pM\n", vdev_id, peer_addr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_DELETE_CMDID); } int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, @@ -2878,7 +1900,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", vdev_id, peer_addr, tid_bitmap); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_FLUSH_TIDS_CMDID); } int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, @@ -2896,13 +1918,13 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, cmd->vdev_id = __cpu_to_le32(vdev_id); cmd->param_id = __cpu_to_le32(param_id); cmd->param_value = __cpu_to_le32(param_value); - memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); + memcpy(&cmd->peer_macaddr.addr, peer_addr, 6); ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev %d peer 0x%pM set param %d value %d\n", vdev_id, peer_addr, param_id, param_value); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_SET_PARAM_CMDID); } int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, @@ -2923,8 +1945,7 @@ int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, "wmi set powersave id 0x%x mode %d\n", vdev_id, psmode); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->sta_powersave_mode_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_STA_POWERSAVE_MODE_CMDID); } int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, @@ -2946,8 +1967,7 @@ int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi sta ps param vdev_id 0x%x param %d value %d\n", vdev_id, param_id, value); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->sta_powersave_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_STA_POWERSAVE_PARAM_CMDID); } int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, @@ -2973,8 +1993,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", vdev_id, param_id, value, mac); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->ap_ps_peer_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_AP_PS_PEER_PARAM_CMDID); } int ath10k_wmi_scan_chan_list(struct ath10k *ar, @@ -3027,7 +2046,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, ci->flags |= __cpu_to_le32(flags); } - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_SCAN_CHAN_LIST_CMDID); } int ath10k_wmi_peer_assoc(struct ath10k *ar, @@ -3086,11 +2105,10 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer assoc vdev %d addr %pM\n", arg->vdev_id, arg->addr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_ASSOC_CMDID); } -int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, - const struct wmi_bcn_tx_arg *arg) +int ath10k_wmi_beacon_send(struct ath10k *ar, const struct wmi_bcn_tx_arg *arg) { struct wmi_bcn_tx_cmd *cmd; struct sk_buff *skb; @@ -3106,7 +2124,7 @@ int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); memcpy(cmd->bcn, arg->bcn, arg->bcn_len); - return ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_BCN_TX_CMDID); } static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, @@ -3137,8 +2155,7 @@ int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_wmm_params_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_WMM_PARAMS_CMDID); } int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) @@ -3154,7 +2171,7 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) cmd->stats_id = __cpu_to_le32(stats_id); ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_REQUEST_STATS_CMDID); } int ath10k_wmi_force_fw_hang(struct ath10k *ar, @@ -3173,5 +2190,5 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", type, delay_ms); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_FORCE_FW_HANG_CMDID); } |