diff options
Diffstat (limited to 'sys/contrib/dev/iwlwifi/mvm/link.c')
| -rw-r--r-- | sys/contrib/dev/iwlwifi/mvm/link.c | 106 | 
1 files changed, 42 insertions, 64 deletions
| diff --git a/sys/contrib/dev/iwlwifi/mvm/link.c b/sys/contrib/dev/iwlwifi/mvm/link.c index a9929aa49913..2269acc55c0e 100644 --- a/sys/contrib/dev/iwlwifi/mvm/link.c +++ b/sys/contrib/dev/iwlwifi/mvm/link.c @@ -12,6 +12,7 @@  	HOW(BLOCKED_FW)			\  	HOW(BLOCKED_NON_BSS)		\  	HOW(BLOCKED_ROC)		\ +	HOW(BLOCKED_TMP_NON_BSS)	\  	HOW(EXIT_MISSED_BEACON)		\  	HOW(EXIT_LOW_RSSI)		\  	HOW(EXIT_COEX)			\ @@ -48,20 +49,6 @@ static void iwl_mvm_print_esr_state(struct iwl_mvm *mvm, u32 mask)  #undef NAME_PR  } -static u32 iwl_mvm_get_free_fw_link_id(struct iwl_mvm *mvm, -				       struct iwl_mvm_vif *mvm_vif) -{ -	u32 i; - -	lockdep_assert_held(&mvm->mutex); - -	for (i = 0; i < ARRAY_SIZE(mvm->link_id_to_link_conf); i++) -		if (!rcu_access_pointer(mvm->link_id_to_link_conf[i])) -			return i; - -	return IWL_MVM_FW_LINK_ID_INVALID; -} -  static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm,  				 struct iwl_link_config_cmd *cmd,  				 enum iwl_ctxt_action action) @@ -78,25 +65,15 @@ static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm,  	return ret;  } -int iwl_mvm_set_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif, -			     struct ieee80211_bss_conf *link_conf) +void iwl_mvm_set_link_fw_id(struct iwl_mvm *mvm, struct ieee80211_vif *vif, +			    struct ieee80211_bss_conf *link_conf)  {  	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);  	struct iwl_mvm_vif_link_info *link_info =  		mvmvif->link[link_conf->link_id]; -	if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) { -		link_info->fw_link_id = iwl_mvm_get_free_fw_link_id(mvm, -								    mvmvif); -		if (link_info->fw_link_id >= -		    ARRAY_SIZE(mvm->link_id_to_link_conf)) -			return -EINVAL; - -		rcu_assign_pointer(mvm->link_id_to_link_conf[link_info->fw_link_id], -				   link_conf); -	} - -	return 0; +	if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) +		link_info->fw_link_id = mvmvif->id;  }  int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -108,14 +85,11 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	struct iwl_link_config_cmd cmd = {};  	unsigned int cmd_id = WIDE_ID(MAC_CONF_GROUP, LINK_CONFIG_CMD);  	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 1); -	int ret;  	if (WARN_ON_ONCE(!link_info))  		return -EINVAL; -	ret = iwl_mvm_set_link_mapping(mvm, vif, link_conf); -	if (ret) -		return ret; +	iwl_mvm_set_link_fw_id(mvm, vif, link_conf);  	/* Update SF - Disable if needed. if this fails, SF might still be on  	 * while many macs are bound, which is forbidden - so fail the binding. @@ -233,10 +207,15 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  		WARN_ON_ONCE(active == link_info->active);  		/* When deactivating a link session protection should -		 * be stopped +		 * be stopped. Also let the firmware know if we can't Tx.  		 */ -		if (!active && vif->type == NL80211_IFTYPE_STATION) +		if (!active && vif->type == NL80211_IFTYPE_STATION) {  			iwl_mvm_stop_session_protection(mvm, vif); +			if (link_info->csa_block_tx) { +				cmd.block_tx = 1; +				link_info->csa_block_tx = false; +			} +		}  	}  	cmd.link_id = cpu_to_le32(link_info->fw_link_id); @@ -258,7 +237,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid)  		memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN); -	iwl_mvm_set_fw_basic_rates(mvm, vif, link_conf, +	iwl_mvm_set_fw_basic_rates(mvm, vif, link_info,  				   &cmd.cck_rates, &cmd.ofdm_rates);  	cmd.cck_short_preamble = cpu_to_le32(link_conf->use_short_preamble); @@ -293,6 +272,17 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  			(link_conf->uora_ocw_range >> 3) & 0x7;  	} +	/* ap_sta may be NULL if we're disconnecting */ +	if (changes & LINK_CONTEXT_MODIFY_HE_PARAMS && mvmvif->ap_sta) { +		struct ieee80211_link_sta *link_sta = +			link_sta_dereference_check(mvmvif->ap_sta, link_id); + +		if (!WARN_ON(!link_sta) && link_sta->he_cap.has_he && +		    link_sta->he_cap.he_cap_elem.mac_cap_info[5] & +		    IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX) +			cmd.ul_mu_data_disable = 1; +	} +  	/* TODO  how to set ndp_fdbk_buff_th_exp? */  	if (iwl_mvm_set_fw_mu_edca_params(mvm, mvmvif->link[link_id], @@ -343,7 +333,8 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  send_cmd:  	cmd.modify_mask = cpu_to_le32(changes);  	cmd.flags = cpu_to_le32(flags); -	cmd.flags_mask = cpu_to_le32(flags_mask); +	if (cmd_ver < 6) +		cmd.flags_mask = cpu_to_le32(flags_mask);  	cmd.spec_link_id = link_conf->link_id;  	if (cmd_ver < 2)  		cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac); @@ -355,24 +346,6 @@ send_cmd:  	return ret;  } -int iwl_mvm_unset_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif, -			       struct ieee80211_bss_conf *link_conf) -{ -	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); -	struct iwl_mvm_vif_link_info *link_info = -		mvmvif->link[link_conf->link_id]; - -	/* mac80211 thought we have the link, but it was never configured */ -	if (WARN_ON(!link_info || -		    link_info->fw_link_id >= -		    ARRAY_SIZE(mvm->link_id_to_link_conf))) -		return -EINVAL; - -	RCU_INIT_POINTER(mvm->link_id_to_link_conf[link_info->fw_link_id], -			 NULL); -	return 0; -} -  int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  			struct ieee80211_bss_conf *link_conf)  { @@ -382,10 +355,6 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	struct iwl_link_config_cmd cmd = {};  	int ret; -	ret = iwl_mvm_unset_link_mapping(mvm, vif, link_conf); -	if (ret) -		return 0; -  	cmd.link_id = cpu_to_le32(link_info->fw_link_id);  	link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;  	cmd.spec_link_id = link_conf->link_id; @@ -393,9 +362,8 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); -	if (!ret) -		if (iwl_mvm_sf_update(mvm, vif, true)) -			IWL_ERR(mvm, "Failed to update SF state\n"); +	if (!ret && iwl_mvm_sf_update(mvm, vif, true)) +		IWL_ERR(mvm, "Failed to update SF state\n");  	return ret;  } @@ -743,9 +711,8 @@ bool iwl_mvm_mld_valid_link_pair(struct ieee80211_vif *vif,  	    iwl_mvm_esr_disallowed_with_link(mvm, vif, b, false))  		return false; -	if (a->chandef->width != b->chandef->width || -	    !(a->chandef->chan->band == NL80211_BAND_6GHZ && -	      b->chandef->chan->band == NL80211_BAND_5GHZ)) +	if (a->chandef->chan->band == b->chandef->chan->band || +	    a->chandef->width != b->chandef->width)  		ret |= IWL_MVM_ESR_EXIT_BANDWIDTH;  	if (ret) { @@ -1148,3 +1115,14 @@ void iwl_mvm_unblock_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	if (!mvmvif->esr_disable_reason)  		iwl_mvm_esr_unblocked(mvm, vif);  } + +void iwl_mvm_init_link(struct iwl_mvm_vif_link_info *link) +{ +	link->bcast_sta.sta_id = IWL_INVALID_STA; +	link->mcast_sta.sta_id = IWL_INVALID_STA; +	link->ap_sta_id = IWL_INVALID_STA; + +	for (int r = 0; r < NUM_IWL_MVM_SMPS_REQ; r++) +		link->smps_requests[r] = +			IEEE80211_SMPS_AUTOMATIC; +} | 
