forked from mirrors/linux
		
	wifi: mac80211: update the right link for tx power
Stop looking at deflink and start using the actual link. Initialize the power settings upon link init. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20241007144851.2685dab8e1ab.I1d82cbdb2dda020aee4a225bd9a134f7d82dd810@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									0b7392ee3b
								
							
						
					
					
						commit
						c4382d5ca1
					
				
					 4 changed files with 74 additions and 51 deletions
				
			
		|  | @ -3061,9 +3061,25 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, | ||||||
| 	enum nl80211_tx_power_setting txp_type = type; | 	enum nl80211_tx_power_setting txp_type = type; | ||||||
| 	bool update_txp_type = false; | 	bool update_txp_type = false; | ||||||
| 	bool has_monitor = false; | 	bool has_monitor = false; | ||||||
|  | 	int user_power_level; | ||||||
| 
 | 
 | ||||||
| 	lockdep_assert_wiphy(local->hw.wiphy); | 	lockdep_assert_wiphy(local->hw.wiphy); | ||||||
| 
 | 
 | ||||||
|  | 	switch (type) { | ||||||
|  | 	case NL80211_TX_POWER_AUTOMATIC: | ||||||
|  | 		user_power_level = IEEE80211_UNSET_POWER_LEVEL; | ||||||
|  | 		txp_type = NL80211_TX_POWER_LIMITED; | ||||||
|  | 		break; | ||||||
|  | 	case NL80211_TX_POWER_LIMITED: | ||||||
|  | 	case NL80211_TX_POWER_FIXED: | ||||||
|  | 		if (mbm < 0 || (mbm % 100)) | ||||||
|  | 			return -EOPNOTSUPP; | ||||||
|  | 		user_power_level = MBM_TO_DBM(mbm); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (wdev) { | 	if (wdev) { | ||||||
| 		sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | 		sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||||||
| 
 | 
 | ||||||
|  | @ -3077,57 +3093,65 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, | ||||||
| 				return -EOPNOTSUPP; | 				return -EOPNOTSUPP; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		switch (type) { | 		for (int link_id = 0; | ||||||
| 		case NL80211_TX_POWER_AUTOMATIC: | 		     link_id < ARRAY_SIZE(sdata->link); | ||||||
| 			sdata->deflink.user_power_level = | 		     link_id++) { | ||||||
| 				IEEE80211_UNSET_POWER_LEVEL; | 			struct ieee80211_link_data *link = | ||||||
| 			txp_type = NL80211_TX_POWER_LIMITED; | 				wiphy_dereference(wiphy, sdata->link[link_id]); | ||||||
| 			break; | 
 | ||||||
| 		case NL80211_TX_POWER_LIMITED: | 			if (!link) | ||||||
| 		case NL80211_TX_POWER_FIXED: | 				continue; | ||||||
| 			if (mbm < 0 || (mbm % 100)) | 
 | ||||||
| 				return -EOPNOTSUPP; | 			link->user_power_level = user_power_level; | ||||||
| 			sdata->deflink.user_power_level = MBM_TO_DBM(mbm); | 
 | ||||||
| 			break; | 			if (txp_type != link->conf->txpower_type) { | ||||||
|  | 				update_txp_type = true; | ||||||
|  | 				link->conf->txpower_type = txp_type; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			ieee80211_recalc_txpower(link, update_txp_type); | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		if (txp_type != sdata->vif.bss_conf.txpower_type) { |  | ||||||
| 			update_txp_type = true; |  | ||||||
| 			sdata->vif.bss_conf.txpower_type = txp_type; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		ieee80211_recalc_txpower(&sdata->deflink, update_txp_type); |  | ||||||
| 
 |  | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	switch (type) { | 	local->user_power_level = user_power_level; | ||||||
| 	case NL80211_TX_POWER_AUTOMATIC: |  | ||||||
| 		local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; |  | ||||||
| 		txp_type = NL80211_TX_POWER_LIMITED; |  | ||||||
| 		break; |  | ||||||
| 	case NL80211_TX_POWER_LIMITED: |  | ||||||
| 	case NL80211_TX_POWER_FIXED: |  | ||||||
| 		if (mbm < 0 || (mbm % 100)) |  | ||||||
| 			return -EOPNOTSUPP; |  | ||||||
| 		local->user_power_level = MBM_TO_DBM(mbm); |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	list_for_each_entry(sdata, &local->interfaces, list) { | 	list_for_each_entry(sdata, &local->interfaces, list) { | ||||||
| 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { | 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { | ||||||
| 			has_monitor = true; | 			has_monitor = true; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		sdata->deflink.user_power_level = local->user_power_level; | 
 | ||||||
| 		if (txp_type != sdata->vif.bss_conf.txpower_type) | 		for (int link_id = 0; | ||||||
| 			update_txp_type = true; | 		     link_id < ARRAY_SIZE(sdata->link); | ||||||
| 		sdata->vif.bss_conf.txpower_type = txp_type; | 		     link_id++) { | ||||||
|  | 			struct ieee80211_link_data *link = | ||||||
|  | 				wiphy_dereference(wiphy, sdata->link[link_id]); | ||||||
|  | 
 | ||||||
|  | 			if (!link) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			link->user_power_level = local->user_power_level; | ||||||
|  | 			if (txp_type != link->conf->txpower_type) | ||||||
|  | 				update_txp_type = true; | ||||||
|  | 			link->conf->txpower_type = txp_type; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	list_for_each_entry(sdata, &local->interfaces, list) { | 	list_for_each_entry(sdata, &local->interfaces, list) { | ||||||
| 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | 		if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | ||||||
| 			continue; | 			continue; | ||||||
| 		ieee80211_recalc_txpower(&sdata->deflink, update_txp_type); | 
 | ||||||
|  | 		for (int link_id = 0; | ||||||
|  | 		     link_id < ARRAY_SIZE(sdata->link); | ||||||
|  | 		     link_id++) { | ||||||
|  | 			struct ieee80211_link_data *link = | ||||||
|  | 				wiphy_dereference(wiphy, sdata->link[link_id]); | ||||||
|  | 
 | ||||||
|  | 			if (!link) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			ieee80211_recalc_txpower(link, update_txp_type); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (has_monitor) { | 	if (has_monitor) { | ||||||
|  |  | ||||||
|  | @ -905,7 +905,7 @@ static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { | 	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { | ||||||
| 		ieee80211_recalc_txpower(&sdata->deflink, false); | 		ieee80211_recalc_txpower(link, false); | ||||||
| 		ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false); | 		ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL, false); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1712,7 +1712,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) | ||||||
| 								  link, | 								  link, | ||||||
| 								  changed); | 								  changed); | ||||||
| 
 | 
 | ||||||
| 			ieee80211_recalc_txpower(&sdata->deflink, false); | 			ieee80211_recalc_txpower(link, false); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		ieee80211_recalc_chanctx_chantype(local, ctx); | 		ieee80211_recalc_chanctx_chantype(local, ctx); | ||||||
|  |  | ||||||
|  | @ -46,12 +46,11 @@ static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work); | ||||||
| 
 | 
 | ||||||
| bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) | bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) | ||||||
| { | { | ||||||
| 	struct ieee80211_sub_if_data *sdata = link->sdata; |  | ||||||
| 	struct ieee80211_chanctx_conf *chanctx_conf; | 	struct ieee80211_chanctx_conf *chanctx_conf; | ||||||
| 	int power; | 	int power; | ||||||
| 
 | 
 | ||||||
| 	rcu_read_lock(); | 	rcu_read_lock(); | ||||||
| 	chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); | 	chanctx_conf = rcu_dereference(link->conf->chanctx_conf); | ||||||
| 	if (!chanctx_conf) { | 	if (!chanctx_conf) { | ||||||
| 		rcu_read_unlock(); | 		rcu_read_unlock(); | ||||||
| 		return false; | 		return false; | ||||||
|  | @ -60,15 +59,15 @@ bool __ieee80211_recalc_txpower(struct ieee80211_link_data *link) | ||||||
| 	power = ieee80211_chandef_max_power(&chanctx_conf->def); | 	power = ieee80211_chandef_max_power(&chanctx_conf->def); | ||||||
| 	rcu_read_unlock(); | 	rcu_read_unlock(); | ||||||
| 
 | 
 | ||||||
| 	if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL) | 	if (link->user_power_level != IEEE80211_UNSET_POWER_LEVEL) | ||||||
| 		power = min(power, sdata->deflink.user_power_level); | 		power = min(power, link->user_power_level); | ||||||
| 
 | 
 | ||||||
| 	if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL) | 	if (link->ap_power_level != IEEE80211_UNSET_POWER_LEVEL) | ||||||
| 		power = min(power, sdata->deflink.ap_power_level); | 		power = min(power, link->ap_power_level); | ||||||
| 
 | 
 | ||||||
| 	if (power != sdata->vif.bss_conf.txpower) { | 	if (power != link->conf->txpower) { | ||||||
| 		sdata->vif.bss_conf.txpower = power; | 		link->conf->txpower = power; | ||||||
| 		ieee80211_hw_config(sdata->local, 0); | 		ieee80211_hw_config(link->sdata->local, 0); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -2177,9 +2176,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | ||||||
| 
 | 
 | ||||||
| 	ieee80211_set_default_queues(sdata); | 	ieee80211_set_default_queues(sdata); | ||||||
| 
 | 
 | ||||||
| 	sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL; |  | ||||||
| 	sdata->deflink.user_power_level = local->user_power_level; |  | ||||||
| 
 |  | ||||||
| 	/* setup type-dependent data */ | 	/* setup type-dependent data */ | ||||||
| 	ieee80211_setup_sdata(sdata, type); | 	ieee80211_setup_sdata(sdata, type); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -36,6 +36,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, | ||||||
| 	link->conf = link_conf; | 	link->conf = link_conf; | ||||||
| 	link_conf->link_id = link_id; | 	link_conf->link_id = link_id; | ||||||
| 	link_conf->vif = &sdata->vif; | 	link_conf->vif = &sdata->vif; | ||||||
|  | 	link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; | ||||||
|  | 	link->user_power_level = sdata->local->user_power_level; | ||||||
|  | 	link_conf->txpower = INT_MIN; | ||||||
| 
 | 
 | ||||||
| 	wiphy_work_init(&link->csa.finalize_work, | 	wiphy_work_init(&link->csa.finalize_work, | ||||||
| 			ieee80211_csa_finalize_work); | 			ieee80211_csa_finalize_work); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Emmanuel Grumbach
						Emmanuel Grumbach