Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright 2002-2005, Instant802 Networks, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright 2005-2006, Devicescape Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright 2017	Intel Deutschland GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include "rate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include "ieee80211_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include "debugfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) struct rate_control_alg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 	const struct rate_control_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) static LIST_HEAD(rate_ctrl_algs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) static DEFINE_MUTEX(rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) static char *ieee80211_default_rc_algo = CONFIG_MAC80211_RC_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) module_param(ieee80211_default_rc_algo, charp, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) MODULE_PARM_DESC(ieee80211_default_rc_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 		 "Default rate control algorithm for mac80211 to use");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) void rate_control_rate_init(struct sta_info *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	struct ieee80211_local *local = sta->sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	struct rate_control_ref *ref = sta->rate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	struct ieee80211_sta *ista = &sta->sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	void *priv_sta = sta->rate_ctrl_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	struct ieee80211_chanctx_conf *chanctx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	ieee80211_sta_set_rx_nss(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	if (!ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	if (WARN_ON(!chanctx_conf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	/* TODO: check for minstrel_s1g ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	if (sband->band == NL80211_BAND_S1GHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		ieee80211_s1g_sta_rate_init(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	spin_lock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 			    priv_sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	spin_unlock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) void rate_control_tx_status(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 			    struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 			    struct ieee80211_tx_status *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	struct rate_control_ref *ref = local->rate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	struct sta_info *sta = container_of(st->sta, struct sta_info, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	void *priv_sta = sta->rate_ctrl_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	spin_lock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	if (ref->ops->tx_status_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		ref->ops->tx_status_ext(ref->priv, sband, priv_sta, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	else if (st->skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		ref->ops->tx_status(ref->priv, sband, st->sta, priv_sta, st->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	spin_unlock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) void rate_control_rate_update(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 				    struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 				    struct sta_info *sta, u32 changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	struct rate_control_ref *ref = local->rate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	struct ieee80211_sta *ista = &sta->sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	void *priv_sta = sta->rate_ctrl_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	struct ieee80211_chanctx_conf *chanctx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	if (ref && ref->ops->rate_update) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		if (WARN_ON(!chanctx_conf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		spin_lock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 				      ista, priv_sta, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		spin_unlock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) int ieee80211_rate_control_register(const struct rate_control_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	struct rate_control_alg *alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	if (!ops->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	mutex_lock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	list_for_each_entry(alg, &rate_ctrl_algs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		if (!strcmp(alg->ops->name, ops->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 			/* don't register an algorithm twice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 			WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 			mutex_unlock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 			return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	alg = kzalloc(sizeof(*alg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	if (alg == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		mutex_unlock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	alg->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	list_add_tail(&alg->list, &rate_ctrl_algs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	mutex_unlock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) EXPORT_SYMBOL(ieee80211_rate_control_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) void ieee80211_rate_control_unregister(const struct rate_control_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	struct rate_control_alg *alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	mutex_lock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	list_for_each_entry(alg, &rate_ctrl_algs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		if (alg->ops == ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			list_del(&alg->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			kfree(alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	mutex_unlock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) EXPORT_SYMBOL(ieee80211_rate_control_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) static const struct rate_control_ops *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) ieee80211_try_rate_control_ops_get(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	struct rate_control_alg *alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	const struct rate_control_ops *ops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	mutex_lock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	list_for_each_entry(alg, &rate_ctrl_algs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		if (!strcmp(alg->ops->name, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			ops = alg->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	mutex_unlock(&rate_ctrl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	return ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) /* Get the rate control algorithm. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) static const struct rate_control_ops *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) ieee80211_rate_control_ops_get(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	const struct rate_control_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	const char *alg_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	kernel_param_lock(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		alg_name = ieee80211_default_rc_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		alg_name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	ops = ieee80211_try_rate_control_ops_get(alg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	if (!ops && name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		/* try default if specific alg requested but not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	/* Note: check for > 0 is intentional to avoid clang warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (!ops && (strlen(CONFIG_MAC80211_RC_DEFAULT) > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		/* try built-in one if specific alg requested but not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	kernel_param_unlock(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	return ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) #ifdef CONFIG_MAC80211_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) static ssize_t rcname_read(struct file *file, char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	struct rate_control_ref *ref = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	int len = strlen(ref->ops->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	return simple_read_from_buffer(userbuf, count, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 				       ref->ops->name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) const struct file_operations rcname_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	.read = rcname_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	.open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	.llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) static struct rate_control_ref *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) rate_control_alloc(const char *name, struct ieee80211_local *local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	struct rate_control_ref *ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	if (!ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	ref->ops = ieee80211_rate_control_ops_get(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	if (!ref->ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	ref->priv = ref->ops->alloc(&local->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	if (!ref->priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	return ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	kfree(ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) static void rate_control_free(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 			      struct rate_control_ref *ctrl_ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	ctrl_ref->ops->free(ctrl_ref->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) #ifdef CONFIG_MAC80211_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	debugfs_remove_recursive(local->debugfs.rcdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	local->debugfs.rcdir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	kfree(ctrl_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	u32 user_mask, basic_rates = sdata->vif.bss_conf.basic_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	if (WARN_ON(!sdata->vif.bss_conf.chandef.chan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	band = sdata->vif.bss_conf.chandef.chan->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (band == NL80211_BAND_S1GHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		/* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	if (WARN_ON_ONCE(!basic_rates))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	user_mask = sdata->rc_rateidx_mask[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	sband = local->hw.wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if (user_mask & basic_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	sdata_dbg(sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		  "no overlap between basic rates (0x%x) and user mask (0x%x on band %d) - clearing the latter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		  basic_rates, user_mask, band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	sdata->rc_rateidx_mask[band] = (1 << sband->n_bitrates) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	struct sk_buff *skb = txrc->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	__le16 fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	fc = hdr->frame_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	return (info->flags & (IEEE80211_TX_CTL_NO_ACK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 			       IEEE80211_TX_CTL_USE_MINRATE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		!ieee80211_is_data(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) static void rc_send_low_basicrate(struct ieee80211_tx_rate *rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 				  u32 basic_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 				  struct ieee80211_supported_band *sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if (sband->band == NL80211_BAND_S1GHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		/* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		rate->flags |= IEEE80211_TX_RC_S1G_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		rate->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	if (basic_rates == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		return; /* assume basic rates unknown and accept rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	if (rate->idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	if (basic_rates & (1 << rate->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		return; /* selected rate is a basic rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	for (i = rate->idx + 1; i <= sband->n_bitrates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (basic_rates & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			rate->idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	/* could not find a basic rate; use original selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) static void __rate_control_send_low(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 				    struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 				    struct ieee80211_sta *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 				    struct ieee80211_tx_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 				    u32 rate_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	u32 rate_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		ieee80211_chandef_rate_flags(&hw->conf.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	if (sband->band == NL80211_BAND_S1GHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		info->control.rates[0].flags |= IEEE80211_TX_RC_S1G_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		info->control.rates[0].idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	if ((sband->band == NL80211_BAND_2GHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	    (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		rate_flags |= IEEE80211_RATE_ERP_G;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	info->control.rates[0].idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	for (i = 0; i < sband->n_bitrates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		if (!(rate_mask & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		if (!rate_supported(sta, sband->band, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		info->control.rates[0].idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	WARN_ONCE(i == sband->n_bitrates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		  "no supported rates for sta %pM (0x%x, band %d) in rate_mask 0x%x with flags 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		  sta ? sta->addr : NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		  sta ? sta->supp_rates[sband->band] : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		  sband->band,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		  rate_mask, rate_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	info->control.rates[0].count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		(info->flags & IEEE80211_TX_CTL_NO_ACK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		1 : hw->max_rate_tries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	info->control.skip_table = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) static bool rate_control_send_low(struct ieee80211_sta *pubsta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 				  struct ieee80211_tx_rate_control *txrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	struct ieee80211_supported_band *sband = txrc->sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	int mcast_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	bool use_basicrate = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (!pubsta || rc_no_data_or_no_ack_use_min(txrc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		__rate_control_send_low(txrc->hw, sband, pubsta, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 					txrc->rate_idx_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		if (!pubsta && txrc->bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			mcast_rate = txrc->bss_conf->mcast_rate[sband->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			if (mcast_rate > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 				info->control.rates[0].idx = mcast_rate - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			use_basicrate = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		} else if (pubsta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 			sta = container_of(pubsta, struct sta_info, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 			if (ieee80211_vif_is_mesh(&sta->sdata->vif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 				use_basicrate = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		if (use_basicrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			rc_send_low_basicrate(&info->control.rates[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 					      txrc->bss_conf->basic_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 					      sband);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static bool rate_idx_match_legacy_mask(s8 *rate_idx, int n_bitrates, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	/* See whether the selected rate or anything below it is allowed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	for (j = *rate_idx; j >= 0; j--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		if (mask & (1 << j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 			/* Okay, found a suitable rate. Use it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			*rate_idx = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	/* Try to find a higher rate that would be allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	for (j = *rate_idx + 1; j < n_bitrates; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		if (mask & (1 << j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			/* Okay, found a suitable rate. Use it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 			*rate_idx = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static bool rate_idx_match_mcs_mask(s8 *rate_idx, u8 *mcs_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	int ridx, rbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	ridx = *rate_idx / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	rbit = *rate_idx % 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	/* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	if (ridx < 0 || ridx >= IEEE80211_HT_MCS_MASK_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	/* See whether the selected rate or anything below it is allowed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	for (i = ridx; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		for (j = rbit; j >= 0; j--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			if (mcs_mask[i] & BIT(j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				*rate_idx = i * 8 + j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		rbit = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	/* Try to find a higher rate that would be allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	ridx = (*rate_idx + 1) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	rbit = (*rate_idx + 1) % 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	for (i = ridx; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		for (j = rbit; j < 8; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			if (mcs_mask[i] & BIT(j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 				*rate_idx = i * 8 + j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		rbit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) static bool rate_idx_match_vht_mcs_mask(s8 *rate_idx, u16 *vht_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	int ridx, rbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	ridx = *rate_idx >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	rbit = *rate_idx & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	if (ridx < 0 || ridx >= NL80211_VHT_NSS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	/* See whether the selected rate or anything below it is allowed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	for (i = ridx; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		for (j = rbit; j >= 0; j--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			if (vht_mask[i] & BIT(j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 				*rate_idx = (i << 4) | j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		rbit = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	/* Try to find a higher rate that would be allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	ridx = (*rate_idx + 1) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	rbit = (*rate_idx + 1) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	for (i = ridx; i < NL80211_VHT_NSS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		for (j = rbit; j < 16; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			if (vht_mask[i] & BIT(j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 				*rate_idx = (i << 4) | j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		rbit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static void rate_idx_match_mask(s8 *rate_idx, u16 *rate_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 				struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 				enum nl80211_chan_width chan_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 				u32 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 				u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 				u16 vht_mask[NL80211_VHT_NSS_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	if (*rate_flags & IEEE80211_TX_RC_VHT_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		/* handle VHT rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		if (rate_idx_match_vht_mcs_mask(rate_idx, vht_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		*rate_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		/* keep protection flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		*rate_flags &= (IEEE80211_TX_RC_USE_RTS_CTS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 				IEEE80211_TX_RC_USE_CTS_PROTECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 				IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		*rate_flags |= IEEE80211_TX_RC_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		if (chan_width == NL80211_CHAN_WIDTH_40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			*rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		if (rate_idx_match_mcs_mask(rate_idx, mcs_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		/* also try the legacy rates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		*rate_flags &= ~(IEEE80211_TX_RC_MCS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 				 IEEE80211_TX_RC_40_MHZ_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		if (rate_idx_match_legacy_mask(rate_idx, sband->n_bitrates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 					       mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	} else if (*rate_flags & IEEE80211_TX_RC_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		/* handle HT rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		if (rate_idx_match_mcs_mask(rate_idx, mcs_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		/* also try the legacy rates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		*rate_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		/* keep protection flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		*rate_flags &= (IEEE80211_TX_RC_USE_RTS_CTS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 				IEEE80211_TX_RC_USE_CTS_PROTECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 				IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		if (rate_idx_match_legacy_mask(rate_idx, sband->n_bitrates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 					       mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		/* handle legacy rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		if (rate_idx_match_legacy_mask(rate_idx, sband->n_bitrates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 					       mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		/* if HT BSS, and we handle a data frame, also try HT rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		switch (chan_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		case NL80211_CHAN_WIDTH_20_NOHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		case NL80211_CHAN_WIDTH_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		case NL80211_CHAN_WIDTH_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		*rate_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		/* keep protection flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		*rate_flags &= (IEEE80211_TX_RC_USE_RTS_CTS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 				IEEE80211_TX_RC_USE_CTS_PROTECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 				IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		*rate_flags |= IEEE80211_TX_RC_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		if (chan_width == NL80211_CHAN_WIDTH_40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 			*rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		if (rate_idx_match_mcs_mask(rate_idx, mcs_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	 * Uh.. No suitable rate exists. This should not really happen with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	 * sane TX rate mask configurations. However, should someone manage to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	 * configure supported rates and TX rate mask in incompatible way,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	 * allow the frame to be transmitted with whatever the rate control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	 * selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) static void rate_fixup_ratelist(struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 				struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 				struct ieee80211_tx_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 				struct ieee80211_tx_rate *rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 				int max_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	struct ieee80211_rate *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	bool inval = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	 * Set up the RTS/CTS rate as the fastest basic rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	 * that is not faster than the data rate unless there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	 * is no basic rate slower than the data rate, in which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	 * case we pick the slowest basic rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	 * XXX: Should this check all retry rates?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	if (!(rates[0].flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	      (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		u32 basic_rates = vif->bss_conf.basic_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		rate = &sband->bitrates[rates[0].idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		for (i = 0; i < sband->n_bitrates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			/* must be a basic rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			if (!(basic_rates & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			/* must not be faster than the data rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			if (sband->bitrates[i].bitrate > rate->bitrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			/* maximum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 			if (sband->bitrates[baserate].bitrate <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			     sband->bitrates[i].bitrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 				baserate = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		info->control.rts_cts_rate_idx = baserate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	for (i = 0; i < max_rates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		 * make sure there's no valid rate following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		 * an invalid one, just in case drivers don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		 * take the API seriously to stop at -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		if (inval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			rates[i].idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		if (rates[i].idx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			inval = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		 * For now assume MCS is already set up correctly, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		 * needs to be fixed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		if (rates[i].flags & IEEE80211_TX_RC_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			WARN_ON(rates[i].idx > 76);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			if (!(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			    info->control.use_cts_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 				rates[i].flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 					IEEE80211_TX_RC_USE_CTS_PROTECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		if (rates[i].flags & IEEE80211_TX_RC_VHT_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			WARN_ON(ieee80211_rate_get_vht_mcs(&rates[i]) > 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		/* set up RTS protection if desired */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		if (info->control.use_rts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			rates[i].flags |= IEEE80211_TX_RC_USE_RTS_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			info->control.use_cts_prot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		/* RC is busted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		if (WARN_ON_ONCE(rates[i].idx >= sband->n_bitrates)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			rates[i].idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		rate = &sband->bitrates[rates[i].idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		/* set up short preamble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		if (info->control.short_preamble &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		    rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 			rates[i].flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		/* set up G protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		if (!(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		    info->control.use_cts_prot &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		    rate->flags & IEEE80211_RATE_ERP_G)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			rates[i].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) static void rate_control_fill_sta_table(struct ieee80211_sta *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 					struct ieee80211_tx_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 					struct ieee80211_tx_rate *rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 					int max_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	struct ieee80211_sta_rates *ratetbl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	if (sta && !info->control.skip_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		ratetbl = rcu_dereference(sta->rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	/* Fill remaining rate slots with data from the sta rate table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	max_rates = min_t(int, max_rates, IEEE80211_TX_RATE_TABLE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	for (i = 0; i < max_rates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		if (i < ARRAY_SIZE(info->control.rates) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		    info->control.rates[i].idx >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		    info->control.rates[i].count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			if (rates != info->control.rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				rates[i] = info->control.rates[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		} else if (ratetbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			rates[i].idx = ratetbl->rate[i].idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			rates[i].flags = ratetbl->rate[i].flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			if (info->control.use_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 				rates[i].count = ratetbl->rate[i].count_rts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			else if (info->control.use_cts_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 				rates[i].count = ratetbl->rate[i].count_cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 				rates[i].count = ratetbl->rate[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			rates[i].idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			rates[i].count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		if (rates[i].idx < 0 || !rates[i].count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) static bool rate_control_cap_mask(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 				  struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 				  struct ieee80211_sta *sta, u32 *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 				  u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 				  u16 vht_mask[NL80211_VHT_NSS_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	u32 i, flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	*mask = sdata->rc_rateidx_mask[sband->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	for (i = 0; i < sband->n_bitrates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		if ((flags & sband->bitrates[i].flags) != flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			*mask &= ~BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if (*mask == (1 << sband->n_bitrates) - 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	    !sdata->rc_has_mcs_mask[sband->band] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	    !sdata->rc_has_vht_mcs_mask[sband->band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	if (sdata->rc_has_mcs_mask[sband->band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[sband->band],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		       IEEE80211_HT_MCS_MASK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		memset(mcs_mask, 0xff, IEEE80211_HT_MCS_MASK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	if (sdata->rc_has_vht_mcs_mask[sband->band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		memcpy(vht_mask, sdata->rc_rateidx_vht_mcs_mask[sband->band],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		       sizeof(u16) * NL80211_VHT_NSS_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		memset(vht_mask, 0xff, sizeof(u16) * NL80211_VHT_NSS_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (sta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		__le16 sta_vht_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		u16 sta_vht_mask[NL80211_VHT_NSS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		/* Filter out rates that the STA does not support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		*mask &= sta->supp_rates[sband->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			mcs_mask[i] &= sta->ht_cap.mcs.rx_mask[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		sta_vht_cap = sta->vht_cap.vht_mcs.rx_mcs_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		ieee80211_get_vht_mask_from_cap(sta_vht_cap, sta_vht_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			vht_mask[i] &= sta_vht_mask[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) rate_control_apply_mask_ratetbl(struct sta_info *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 				struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 				struct ieee80211_sta_rates *rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	u16 vht_mask[NL80211_VHT_NSS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	enum nl80211_chan_width chan_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	if (!rate_control_cap_mask(sta->sdata, sband, &sta->sta, &mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 				   mcs_mask, vht_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	chan_width = sta->sdata->vif.bss_conf.chandef.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	for (i = 0; i < IEEE80211_TX_RATE_TABLE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		if (rates->rate[i].idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		rate_idx_match_mask(&rates->rate[i].idx, &rates->rate[i].flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 				    sband, chan_width, mask, mcs_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 				    vht_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 				    struct ieee80211_sta *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 				    struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 				    struct ieee80211_tx_rate *rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				    int max_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	enum nl80211_chan_width chan_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	u16 rate_flags, vht_mask[NL80211_VHT_NSS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	 * Try to enforce the rateidx mask the user wanted. skip this if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	 * default mask (allow all rates) is used to save some processing for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	 * the common case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	if (!rate_control_cap_mask(sdata, sband, sta, &mask, mcs_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 				   vht_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	 * Make sure the rate index selected for each TX rate is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	 * included in the configured mask and change the rate indexes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	 * if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	chan_width = sdata->vif.bss_conf.chandef.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	for (i = 0; i < max_rates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		/* Skip invalid rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		if (rates[i].idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		rate_flags = rates[i].flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		rate_idx_match_mask(&rates[i].idx, &rate_flags, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				    chan_width, mask, mcs_mask, vht_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		rates[i].flags = rate_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			    struct ieee80211_sta *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			    struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			    struct ieee80211_tx_rate *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			    int max_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	struct ieee80211_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	rate_control_fill_sta_table(sta, info, dest, max_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	if (!vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	sdata = vif_to_sdata(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	sband = sdata->local->hw.wiphy->bands[info->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	if (ieee80211_is_data(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		rate_control_apply_mask(sdata, sta, sband, dest, max_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (dest[0].idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		__rate_control_send_low(&sdata->local->hw, sband, sta, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 					sdata->rc_rateidx_mask[info->band]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		rate_fixup_ratelist(vif, sband, info, dest, max_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) EXPORT_SYMBOL(ieee80211_get_tx_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			   struct sta_info *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			   struct ieee80211_tx_rate_control *txrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	struct rate_control_ref *ref = sdata->local->rate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	void *priv_sta = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	struct ieee80211_sta *ista = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		info->control.rates[i].idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		info->control.rates[i].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		info->control.rates[i].count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (rate_control_send_low(sta ? &sta->sta : NULL, txrc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		ista = &sta->sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		priv_sta = sta->rate_ctrl_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	if (ista) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		spin_lock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		spin_unlock_bh(&sta->rate_ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		rate_control_send_low(NULL, txrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_RC_TABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	ieee80211_get_tx_rates(&sdata->vif, ista, txrc->skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			       info->control.rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			       ARRAY_SIZE(info->control.rates));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) int rate_control_set_rates(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			   struct ieee80211_sta *pubsta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			   struct ieee80211_sta_rates *rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	struct ieee80211_sta_rates *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	sband = ieee80211_get_sband(sta->sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	rate_control_apply_mask_ratetbl(sta, sband, rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	 * mac80211 guarantees that this function will not be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	 * concurrently, so the following RCU access is safe, even without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	 * extra locking. This can not be checked easily, so we just set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	 * the condition to true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	old = rcu_dereference_protected(pubsta->rates, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	rcu_assign_pointer(pubsta->rates, rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		kfree_rcu(old, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (sta->uploaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	ieee80211_sta_set_expected_throughput(pubsta, sta_get_expected_throughput(sta));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) EXPORT_SYMBOL(rate_control_set_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 				 const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	struct rate_control_ref *ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	if (local->open_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		if (WARN_ON(!local->ops->set_rts_threshold))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	ref = rate_control_alloc(name, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	if (!ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		wiphy_warn(local->hw.wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 			   "Failed to select rate control algorithm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	WARN_ON(local->rate_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	local->rate_ctrl = ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		    ref->ops->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) void rate_control_deinitialize(struct ieee80211_local *local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct rate_control_ref *ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	ref = local->rate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	if (!ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	local->rate_ctrl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	rate_control_free(local, ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }