diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/mvm.h')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 150 |
1 files changed, 141 insertions, 9 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 503e51d32e7f..12e9ecc3ee27 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -83,7 +83,6 @@ #include "sta.h" #include "fw-api.h" #include "constants.h" -#include "tof.h" #include "fw/runtime.h" #include "fw/dbg.h" #include "fw/acpi.h" @@ -95,6 +94,8 @@ /* RSSI offset for WkP */ #define IWL_RSSI_OFFSET 50 #define IWL_MVM_MISSED_BEACONS_THRESHOLD 8 +#define IWL_MVM_MISSED_BEACONS_THRESHOLD_LONG 16 + /* A TimeUnit is 1024 microsecond */ #define MSEC_TO_TU(_msec) (_msec*1000/1024) @@ -299,17 +300,38 @@ enum iwl_bt_force_ant_mode { }; /** + * struct iwl_mvm_low_latency_force - low latency force mode set by debugfs + * @LOW_LATENCY_FORCE_UNSET: unset force mode + * @LOW_LATENCY_FORCE_ON: for low latency on + * @LOW_LATENCY_FORCE_OFF: for low latency off + * @NUM_LOW_LATENCY_FORCE: max num of modes + */ +enum iwl_mvm_low_latency_force { + LOW_LATENCY_FORCE_UNSET, + LOW_LATENCY_FORCE_ON, + LOW_LATENCY_FORCE_OFF, + NUM_LOW_LATENCY_FORCE +}; + +/** * struct iwl_mvm_low_latency_cause - low latency set causes * @LOW_LATENCY_TRAFFIC: indicates low latency traffic was detected * @LOW_LATENCY_DEBUGFS: low latency mode set from debugfs * @LOW_LATENCY_VCMD: low latency mode set from vendor command * @LOW_LATENCY_VIF_TYPE: low latency mode set because of vif type (ap) +* @LOW_LATENCY_DEBUGFS_FORCE_ENABLE: indicate that force mode is enabled +* the actual set/unset is done with LOW_LATENCY_DEBUGFS_FORCE +* @LOW_LATENCY_DEBUGFS_FORCE: low latency force mode from debugfs +* set this with LOW_LATENCY_DEBUGFS_FORCE_ENABLE flag +* in low_latency. */ enum iwl_mvm_low_latency_cause { LOW_LATENCY_TRAFFIC = BIT(0), LOW_LATENCY_DEBUGFS = BIT(1), LOW_LATENCY_VCMD = BIT(2), LOW_LATENCY_VIF_TYPE = BIT(3), + LOW_LATENCY_DEBUGFS_FORCE_ENABLE = BIT(4), + LOW_LATENCY_DEBUGFS_FORCE = BIT(5), }; /** @@ -360,8 +382,10 @@ struct iwl_probe_resp_data { * @pm_enabled - Indicate if MAC power management is allowed * @monitor_active: indicates that monitor context is configured, and that the * interface should get quota etc. - * @low_latency: indicates low latency is set, see - * enum &iwl_mvm_low_latency_cause for causes. + * @low_latency: bit flags for low latency + * see enum &iwl_mvm_low_latency_cause for causes. + * @low_latency_actual: boolean, indicates low latency is set, + * as a result from low_latency bit flags and takes force into account. * @ps_disabled: indicates that this interface requires PS to be disabled * @queue_params: QoS params for this MAC * @bcast_sta: station used for broadcast packets. Used by the following @@ -393,7 +417,8 @@ struct iwl_mvm_vif { bool ap_ibss_active; bool pm_enabled; bool monitor_active; - u8 low_latency; + u8 low_latency: 6; + u8 low_latency_actual: 1; bool ps_disabled; struct iwl_mvm_vif_bf_data bf_data; @@ -781,8 +806,7 @@ struct iwl_mvm_geo_profile { struct iwl_mvm_txq { struct list_head list; u16 txq_id; - /* Protects TX path invocation from two places */ - spinlock_t tx_path_lock; + atomic_t tx_request; bool stopped; }; @@ -965,6 +989,7 @@ struct iwl_mvm { struct debugfs_blob_wrapper nvm_calib_blob; struct debugfs_blob_wrapper nvm_prod_blob; struct debugfs_blob_wrapper nvm_phy_sku_blob; + struct debugfs_blob_wrapper nvm_reg_blob; struct iwl_mvm_frame_stats drv_rx_stats; spinlock_t drv_stats_lock; @@ -988,6 +1013,7 @@ struct iwl_mvm { u8 refs[IWL_MVM_REF_COUNT]; u8 vif_count; + struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER]; /* -1 for always, 0 for never, >0 for that many times */ s8 fw_restart; @@ -1123,7 +1149,6 @@ struct iwl_mvm { u32 ciphers[IWL_MVM_NUM_CIPHERS]; struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; - struct iwl_mvm_tof_data tof_data; struct ieee80211_vif *nan_vif; #define IWL_MAX_BAID 32 @@ -1139,6 +1164,10 @@ struct iwl_mvm { /* does a monitor vif exist (only one can exist hence bool) */ bool monitor_on; + + /* sniffer data to include in radiotap */ + __le16 cur_aid; + #ifdef CONFIG_ACPI struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM]; struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES]; @@ -1183,7 +1212,6 @@ enum iwl_mvm_init_status { IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE = BIT(0), IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE = BIT(1), IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE = BIT(2), - IWL_MVM_INIT_STATUS_TOF_INIT_COMPLETE = BIT(3), }; static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) @@ -1240,6 +1268,19 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id) return iwl_mvm_sta_from_mac80211(sta); } +static inline struct ieee80211_vif * +iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu) +{ + if (WARN_ON(vif_id >= ARRAY_SIZE(mvm->vif_id_to_mac))) + return NULL; + + if (rcu) + return rcu_dereference(mvm->vif_id_to_mac[vif_id]); + + return rcu_dereference_protected(mvm->vif_id_to_mac[vif_id], + lockdep_is_held(&mvm->mutex)); +} + static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm) { return !iwlwifi_mod_params.d0i3_disable && @@ -1905,17 +1946,43 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif) * binding, so this has no real impact. For now, just return * the current desired low-latency state. */ - return mvmvif->low_latency; + return mvmvif->low_latency_actual; } static inline void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set, enum iwl_mvm_low_latency_cause cause) { + u8 new_state; + if (set) mvmvif->low_latency |= cause; else mvmvif->low_latency &= ~cause; + + /* + * if LOW_LATENCY_DEBUGFS_FORCE_ENABLE is enabled no changes are + * allowed to actual mode. + */ + if (mvmvif->low_latency & LOW_LATENCY_DEBUGFS_FORCE_ENABLE && + cause != LOW_LATENCY_DEBUGFS_FORCE_ENABLE) + return; + + if (cause == LOW_LATENCY_DEBUGFS_FORCE_ENABLE && set) + /* + * We enter force state + */ + new_state = !!(mvmvif->low_latency & + LOW_LATENCY_DEBUGFS_FORCE); + else + /* + * Check if any other one set low latency + */ + new_state = !!(mvmvif->low_latency & + ~(LOW_LATENCY_DEBUGFS_FORCE_ENABLE | + LOW_LATENCY_DEBUGFS_FORCE)); + + mvmvif->low_latency_actual = new_state; } /* Return a bitmask with all the hw supported queues, except for the @@ -1930,6 +1997,16 @@ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) { lockdep_assert_held(&mvm->mutex); + /* If IWL_MVM_STATUS_HW_RESTART_REQUESTED bit is set then we received + * an assert. Since we failed to bring the interface up, mac80211 + * will not attempt to reconfig the device, + * which handles the dump collection in assert flow, + * so trigger dump collection here. + */ + if (test_and_clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, + &mvm->status)) + iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, + false, 0); /* calling this function without using dump_start/end since at this * point we already hold the op mode mutex */ @@ -2046,4 +2123,59 @@ void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, struct dentry *dir); #endif +/* Channel info utils */ +static inline bool iwl_mvm_has_ultra_hb_channel(struct iwl_mvm *mvm) +{ + return fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS); +} + +static inline void *iwl_mvm_chan_info_cmd_tail(struct iwl_mvm *mvm, + struct iwl_fw_channel_info *ci) +{ + return (u8 *)ci + (iwl_mvm_has_ultra_hb_channel(mvm) ? + sizeof(struct iwl_fw_channel_info) : + sizeof(struct iwl_fw_channel_info_v1)); +} + +static inline size_t iwl_mvm_chan_info_padding(struct iwl_mvm *mvm) +{ + return iwl_mvm_has_ultra_hb_channel(mvm) ? 0 : + sizeof(struct iwl_fw_channel_info) - + sizeof(struct iwl_fw_channel_info_v1); +} + +static inline void iwl_mvm_set_chan_info(struct iwl_mvm *mvm, + struct iwl_fw_channel_info *ci, + u32 chan, u8 band, u8 width, + u8 ctrl_pos) +{ + if (iwl_mvm_has_ultra_hb_channel(mvm)) { + ci->channel = cpu_to_le32(chan); + ci->band = band; + ci->width = width; + ci->ctrl_pos = ctrl_pos; + } else { + struct iwl_fw_channel_info_v1 *ci_v1 = + (struct iwl_fw_channel_info_v1 *)ci; + + ci_v1->channel = chan; + ci_v1->band = band; + ci_v1->width = width; + ci_v1->ctrl_pos = ctrl_pos; + } +} + +static inline void +iwl_mvm_set_chan_info_chandef(struct iwl_mvm *mvm, + struct iwl_fw_channel_info *ci, + struct cfg80211_chan_def *chandef) +{ + iwl_mvm_set_chan_info(mvm, ci, chandef->chan->hw_value, + (chandef->chan->band == NL80211_BAND_2GHZ ? + PHY_BAND_24 : PHY_BAND_5), + iwl_mvm_get_channel_width(chandef), + iwl_mvm_get_ctrl_pos(chandef)); +} + #endif /* __IWL_MVM_H__ */ |