diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.c | 232 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/pcic.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/qmi.c | 87 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/wmi.c | 2 |
8 files changed, 237 insertions, 118 deletions
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index b99180bc8172..edf78df9b12f 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -195,6 +195,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, + .support_fw_mac_sequence = false, }, { .name = "qca6390 hw2.0", @@ -277,6 +278,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, }, { .name = "qcn9074 hw1.0", @@ -356,6 +358,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, + .support_fw_mac_sequence = false, }, { .name = "wcn6855 hw2.0", @@ -438,6 +441,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, }, { .name = "wcn6855 hw2.1", @@ -519,6 +523,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, }, { .name = "wcn6750 hw1.0", @@ -597,6 +602,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .tcl_ring_retry = false, .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, .smp2p_wow_exit = true, + .support_fw_mac_sequence = true, }, }; @@ -1641,7 +1647,7 @@ static void ath11k_update_11d(struct work_struct *work) } } -static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) +void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) { struct ath11k *ar; struct ath11k_pdev *pdev; @@ -1677,6 +1683,10 @@ static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) ath11k_mac_tx_mgmt_pending_free, ar); idr_destroy(&ar->txmgmt_idr); wake_up(&ar->txmgmt_empty_waitq); + + ar->monitor_vdev_id = -1; + clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags); + clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); } wake_up(&ab->wmi_ab.tx_credits_wq); @@ -1730,9 +1740,6 @@ static void ath11k_core_restart(struct work_struct *work) struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); int ret; - if (!ab->is_reset) - ath11k_core_pre_reconfigure_recovery(ab); - ret = ath11k_core_reconfigure_on_crash(ab); if (ret) { ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index cf2f52cc4e30..22460b0abf03 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -505,6 +505,8 @@ struct ath11k_sta { u64 ps_start_jiffies; u64 ps_total_duration; bool peer_current_ps_valid; + + u32 bw_prev; }; #define ATH11K_MIN_5G_FREQ 4150 @@ -1157,6 +1159,7 @@ int ath11k_core_check_smbios(struct ath11k_base *ab); void ath11k_core_halt(struct ath11k *ar); int ath11k_core_resume(struct ath11k_base *ab); int ath11k_core_suspend(struct ath11k_base *ab); +void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab); const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, const char *filename); diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 8a3f24862edc..0c5ef8a526d8 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -219,6 +219,7 @@ struct ath11k_hw_params { bool tcl_ring_retry; u32 tx_ring_size; bool smp2p_wow_exit; + bool support_fw_mac_sequence; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2d1e3fd9b526..9e923ecb0891 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -241,7 +241,10 @@ const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default = { #define ath11k_a_rates (ath11k_legacy_rates + 4) #define ath11k_a_rates_size (ARRAY_SIZE(ath11k_legacy_rates) - 4) -#define ATH11K_MAC_SCAN_TIMEOUT_MSECS 200 /* in msecs */ +#define ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD 200 /* in msecs */ + +/* Overhead due to the processing of channel switch events from FW */ +#define ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD 10 /* in msecs */ static const u32 ath11k_smps_map[] = { [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC, @@ -3612,6 +3615,7 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, struct scan_req_params arg; int ret = 0; int i; + u32 scan_timeout; mutex_lock(&ar->conf_mutex); @@ -3681,6 +3685,26 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask); } + /* if duration is set, default dwell times will be overwritten */ + if (req->duration) { + arg.dwell_time_active = req->duration; + arg.dwell_time_active_2g = req->duration; + arg.dwell_time_active_6g = req->duration; + arg.dwell_time_passive = req->duration; + arg.dwell_time_passive_6g = req->duration; + arg.burst_duration = req->duration; + + scan_timeout = min_t(u32, arg.max_rest_time * + (arg.num_chan - 1) + (req->duration + + ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) * + arg.num_chan, arg.max_scan_time); + } else { + scan_timeout = arg.max_scan_time; + } + + /* Add a margin to account for event/command processing */ + scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD; + ret = ath11k_start_scan(ar, &arg); if (ret) { ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret); @@ -3689,10 +3713,8 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, spin_unlock_bh(&ar->data_lock); } - /* Add a 200ms margin to account for event/command processing */ ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, - msecs_to_jiffies(arg.max_scan_time + - ATH11K_MAC_SCAN_TIMEOUT_MSECS)); + msecs_to_jiffies(scan_timeout)); exit: kfree(arg.chan_list); @@ -4215,10 +4237,11 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; const u16 *he_mcs_mask; - u32 changed, bw, nss, smps; + u32 changed, bw, nss, smps, bw_prev; int err, num_vht_rates, num_he_rates; const struct cfg80211_bitrate_mask *mask; struct peer_assoc_params peer_arg; + enum wmi_phy_mode peer_phymode; arsta = container_of(wk, struct ath11k_sta, update_wk); sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); @@ -4239,6 +4262,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) arsta->changed = 0; bw = arsta->bw; + bw_prev = arsta->bw_prev; nss = arsta->nss; smps = arsta->smps; @@ -4252,26 +4276,57 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) ath11k_mac_max_he_nss(he_mcs_mask))); if (changed & IEEE80211_RC_BW_CHANGED) { - /* Send peer assoc command before set peer bandwidth param to - * avoid the mismatch between the peer phymode and the peer - * bandwidth. - */ - ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true); - - peer_arg.is_assoc = false; - err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg); - if (err) { - ath11k_warn(ar->ab, "failed to send peer assoc for STA %pM vdev %i: %d\n", - sta->addr, arvif->vdev_id, err); - } else if (wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) { + /* Get the peer phymode */ + ath11k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg); + peer_phymode = peer_arg.peer_phymode; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n", + sta->addr, bw, peer_phymode); + + if (bw > bw_prev) { + /* BW is upgraded. In this case we send WMI_PEER_PHYMODE + * followed by WMI_PEER_CHWIDTH + */ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW upgrade for sta %pM new BW %d, old BW %d\n", + sta->addr, bw, bw_prev); + + err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, + WMI_PEER_PHYMODE, peer_phymode); + + if (err) { + ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n", + sta->addr, peer_phymode, err); + goto err_rc_bw_changed; + } + err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, WMI_PEER_CHWIDTH, bw); + if (err) ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n", sta->addr, bw, err); } else { - ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n", - sta->addr, arvif->vdev_id); + /* BW is downgraded. In this case we send WMI_PEER_CHWIDTH + * followed by WMI_PEER_PHYMODE + */ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW downgrade for sta %pM new BW %d,old BW %d\n", + sta->addr, bw, bw_prev); + + err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, + WMI_PEER_CHWIDTH, bw); + + if (err) { + ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n", + sta->addr, bw, err); + goto err_rc_bw_changed; + } + + err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, + WMI_PEER_PHYMODE, peer_phymode); + + if (err) + ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n", + sta->addr, peer_phymode, err); } } @@ -4352,6 +4407,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) } } +err_rc_bw_changed: mutex_unlock(&ar->conf_mutex); } @@ -4505,6 +4561,34 @@ exit: return ret; } +static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, + struct ieee80211_sta *sta) +{ + u32 bw = WMI_PEER_CHWIDTH_20MHZ; + + switch (sta->deflink.bandwidth) { + case IEEE80211_STA_RX_BW_20: + bw = WMI_PEER_CHWIDTH_20MHZ; + break; + case IEEE80211_STA_RX_BW_40: + bw = WMI_PEER_CHWIDTH_40MHZ; + break; + case IEEE80211_STA_RX_BW_80: + bw = WMI_PEER_CHWIDTH_80MHZ; + break; + case IEEE80211_STA_RX_BW_160: + bw = WMI_PEER_CHWIDTH_160MHZ; + break; + default: + ath11k_warn(ar->ab, "Invalid bandwidth %d for %pM\n", + sta->deflink.bandwidth, sta->addr); + bw = WMI_PEER_CHWIDTH_20MHZ; + break; + } + + return bw; +} + static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -4590,6 +4674,12 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, if (ret) ath11k_warn(ar->ab, "Failed to associate station: %pM\n", sta->addr); + + spin_lock_bh(&ar->data_lock); + /* Set arsta bw and prev bw */ + arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); + arsta->bw_prev = arsta->bw; + spin_unlock_bh(&ar->data_lock); } else if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTHORIZED) { spin_lock_bh(&ar->ab->base_lock); @@ -4713,28 +4803,8 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, spin_lock_bh(&ar->data_lock); if (changed & IEEE80211_RC_BW_CHANGED) { - bw = WMI_PEER_CHWIDTH_20MHZ; - - switch (sta->deflink.bandwidth) { - case IEEE80211_STA_RX_BW_20: - bw = WMI_PEER_CHWIDTH_20MHZ; - break; - case IEEE80211_STA_RX_BW_40: - bw = WMI_PEER_CHWIDTH_40MHZ; - break; - case IEEE80211_STA_RX_BW_80: - bw = WMI_PEER_CHWIDTH_80MHZ; - break; - case IEEE80211_STA_RX_BW_160: - bw = WMI_PEER_CHWIDTH_160MHZ; - break; - default: - ath11k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n", - sta->deflink.bandwidth, sta->addr); - bw = WMI_PEER_CHWIDTH_20MHZ; - break; - } - + bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); + arsta->bw_prev = arsta->bw; arsta->bw = bw; } @@ -6163,6 +6233,40 @@ void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab) } } +static int ath11k_mac_vdev_delete(struct ath11k *ar, struct ath11k_vif *arvif) +{ + unsigned long time_left; + struct ieee80211_vif *vif = arvif->vif; + int ret = 0; + + lockdep_assert_held(&ar->conf_mutex); + + reinit_completion(&ar->vdev_delete_done); + + ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to delete WMI vdev %d: %d\n", + arvif->vdev_id, ret); + return ret; + } + + time_left = wait_for_completion_timeout(&ar->vdev_delete_done, + ATH11K_VDEV_DELETE_TIMEOUT_HZ); + if (time_left == 0) { + ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n"); + return -ETIMEDOUT; + } + + ar->ab->free_vdev_map |= 1LL << (arvif->vdev_id); + ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); + ar->num_created_vdevs--; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", + vif->addr, arvif->vdev_id); + + return ret; +} + static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -6373,18 +6477,16 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, ath11k_dp_vdev_tx_attach(ar, arvif); + ath11k_debugfs_add_interface(arvif); + if (vif->type != NL80211_IFTYPE_MONITOR && test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) { ret = ath11k_mac_monitor_vdev_create(ar); - if (ret) { + if (ret) ath11k_warn(ar->ab, "failed to create monitor vdev during add interface: %d", ret); - goto err_peer_del; - } } - ath11k_debugfs_add_interface(arvif); - mutex_unlock(&ar->conf_mutex); return 0; @@ -6400,16 +6502,12 @@ err_peer_del: } err_vdev_del: - ath11k_wmi_vdev_delete(ar, arvif->vdev_id); - ar->num_created_vdevs--; - ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); - ab->free_vdev_map |= 1LL << arvif->vdev_id; + ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); spin_unlock_bh(&ar->data_lock); err: - ath11k_debugfs_remove_interface(arvif); mutex_unlock(&ar->conf_mutex); return ret; @@ -6432,7 +6530,6 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw, struct ath11k *ar = hw->priv; struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ath11k_base *ab = ar->ab; - unsigned long time_left; int ret; int i; @@ -6453,29 +6550,13 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw, arvif->vdev_id, ret); } - reinit_completion(&ar->vdev_delete_done); - - ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); + ret = ath11k_mac_vdev_delete(ar, arvif); if (ret) { - ath11k_warn(ab, "failed to delete WMI vdev %d: %d\n", + ath11k_warn(ab, "failed to delete vdev %d: %d\n", arvif->vdev_id, ret); goto err_vdev_del; } - time_left = wait_for_completion_timeout(&ar->vdev_delete_done, - ATH11K_VDEV_DELETE_TIMEOUT_HZ); - if (time_left == 0) { - ath11k_warn(ab, "Timeout in receiving vdev delete response\n"); - goto err_vdev_del; - } - - ab->free_vdev_map |= 1LL << (arvif->vdev_id); - ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); - ar->num_created_vdevs--; - - ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", - vif->addr, arvif->vdev_id); - if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); ar->monitor_vdev_id = -1; @@ -7929,6 +8010,7 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw, struct ath11k *ar = hw->priv; struct ath11k_base *ab = ar->ab; int recovery_count; + struct ath11k_vif *arvif; if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) return; @@ -7964,6 +8046,12 @@ ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw, ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n"); } } + if (ar->ab->hw_params.support_fw_mac_sequence) { + list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA) + ieee80211_hw_restart_disconnect(arvif->vif); + } + } } mutex_unlock(&ar->conf_mutex); @@ -8539,6 +8627,7 @@ err_fallback: static const struct ieee80211_ops ath11k_ops = { .tx = ath11k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, .start = ath11k_mac_op_start, .stop = ath11k_mac_op_stop, .reconfig_complete = ath11k_mac_op_reconfig_complete, @@ -9014,6 +9103,9 @@ static int __ath11k_mac_register(struct ath11k *ar) NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP); } + wiphy_ext_feature_set(ar->hw->wiphy, + NL80211_EXT_FEATURE_SET_SCAN_DWELL); + ath11k_reg_init(ar); if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 2a0d3afb0c99..0231783ad754 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -163,7 +163,7 @@ void ath11k_mac_drain_tx(struct ath11k *ar); void ath11k_mac_peer_cleanup_all(struct ath11k *ar); int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); u8 ath11k_mac_bw_to_mac80211_bw(u8 bw); -u32 ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi); +enum nl80211_he_gi ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi); enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy); enum nl80211_he_ru_alloc ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones); enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw); diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index 380f9d37b644..30d66147223f 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -218,9 +218,16 @@ int ath11k_pcic_read(struct ath11k_base *ab, void *buf, u32 start, u32 end) if (wakeup_required && ab->pci.ops->wakeup) { ret = ab->pci.ops->wakeup(ab); if (ret) { - ath11k_warn(ab, "failed to wakeup for read from 0x%x: %d\n", - start, ret); - return ret; + ath11k_warn(ab, + "wakeup failed, data may be invalid: %d", + ret); + /* Even though wakeup() failed, continue processing rather + * than returning because some parts of the data may still + * be valid and useful in some cases, e.g. could give us + * some clues on firmware crash. + * Mislead due to invalid data could be avoided because we + * are aware of the wakeup failure. + */ } } diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 51de2208b789..ab923e24b0a9 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -19,6 +19,7 @@ #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 #define HOST_CSTATE_BIT 0x04 #define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08 +#define PLATFORM_CAP_PCIE_PME_D3COLD 0x10 #define FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING=" @@ -28,7 +29,7 @@ module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644); MODULE_PARM_DESC(cold_boot_cal, "Decrease the channel switch time but increase the driver load time (Default: true)"); -static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, @@ -279,7 +280,7 @@ static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -296,7 +297,7 @@ static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, @@ -521,7 +522,7 @@ static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -557,7 +558,7 @@ static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, @@ -589,7 +590,7 @@ static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -631,7 +632,7 @@ static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, @@ -658,7 +659,7 @@ static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, @@ -698,7 +699,7 @@ static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, @@ -725,7 +726,7 @@ static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -743,7 +744,7 @@ static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -751,7 +752,7 @@ static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -759,7 +760,7 @@ static struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -813,7 +814,7 @@ static struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -839,7 +840,7 @@ static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -856,7 +857,7 @@ static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -872,7 +873,7 @@ static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -898,7 +899,7 @@ static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -1099,7 +1100,7 @@ static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, @@ -1234,7 +1235,7 @@ static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -1252,7 +1253,7 @@ static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, @@ -1276,7 +1277,7 @@ static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -1293,7 +1294,7 @@ static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -1346,7 +1347,7 @@ static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -1381,7 +1382,7 @@ static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, @@ -1405,7 +1406,7 @@ static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -1422,7 +1423,7 @@ static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, @@ -1457,7 +1458,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -1475,7 +1476,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, @@ -1614,7 +1615,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -1631,28 +1632,28 @@ static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .array_type = NO_ARRAY, }, }; -static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .array_type = NO_ARRAY, }, }; -static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .array_type = NO_ARRAY, }, }; -static struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, @@ -1678,7 +1679,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, .elem_len = 1, @@ -1696,7 +1697,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { }, }; -static struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { +static const struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -1752,6 +1753,8 @@ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) if (ab->hw_params.global_reset) req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET; + req.nm_modem |= PLATFORM_CAP_PCIE_PME_D3COLD; + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi host cap request\n"); ret = qmi_txn_init(&ab->qmi.handle, &txn, @@ -1961,7 +1964,7 @@ static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab) continue; dma_free_coherent(ab->dev, - ab->qmi.target_mem[i].size, + ab->qmi.target_mem[i].prev_size, ab->qmi.target_mem[i].vaddr, ab->qmi.target_mem[i].paddr); ab->qmi.target_mem[i].vaddr = NULL; @@ -1982,12 +1985,12 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) * in such case, no need to allocate memory for FW again. */ if (chunk->vaddr) { - if (chunk->prev_type == chunk->type || + if (chunk->prev_type == chunk->type && chunk->prev_size == chunk->size) continue; /* cannot reuse the existing chunk */ - dma_free_coherent(ab->dev, chunk->size, + dma_free_coherent(ab->dev, chunk->prev_size, chunk->vaddr, chunk->paddr); chunk->vaddr = NULL; } @@ -3087,6 +3090,9 @@ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = { sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01), .fn = ath11k_qmi_msg_fw_init_done_cb, }, + + /* end of list */ + {}, }; static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl, @@ -3158,6 +3164,9 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) case ATH11K_QMI_EVENT_SERVER_EXIT: set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); + + if (!ab->is_reset) + ath11k_core_pre_reconfigure_recovery(ab); break; case ATH11K_QMI_EVENT_REQUEST_MEM: ret = ath11k_qmi_event_mem_request(qmi); diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index fad9f8d308a2..2a8a3e3dcff6 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -6829,7 +6829,7 @@ static void ath11k_wmi_event_peer_sta_ps_state_chg(struct ath11k_base *ab, } ath11k_dbg(ab, ATH11K_DBG_WMI, - "peer sta ps chnange ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n", + "peer sta ps change ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n", ev->peer_macaddr.addr, ev->peer_ps_state, ev->ps_supported_bitmap, ev->peer_ps_valid, ev->peer_ps_timestamp); |