net/mac80211/rate.c

Source file repositories/reference/linux-study-clean/net/mac80211/rate.c

File Facts

System
Linux kernel
Corpus path
net/mac80211/rate.c
Extension
.c
Size
26452 bytes
Lines
1036
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rate_control_alg {
	struct list_head list;
	const struct rate_control_ops *ops;
};

static LIST_HEAD(rate_ctrl_algs);
static DEFINE_MUTEX(rate_ctrl_mutex);

static char *ieee80211_default_rc_algo = CONFIG_MAC80211_RC_DEFAULT;
module_param(ieee80211_default_rc_algo, charp, 0644);
MODULE_PARM_DESC(ieee80211_default_rc_algo,
		 "Default rate control algorithm for mac80211 to use");

void rate_control_rate_init(struct link_sta_info *link_sta)
{
	struct sta_info *sta = link_sta->sta;
	struct ieee80211_local *local = sta->sdata->local;
	struct rate_control_ref *ref = sta->rate_ctrl;
	struct ieee80211_sta *ista = &sta->sta;
	void *priv_sta = sta->rate_ctrl_priv;
	struct ieee80211_supported_band *sband;
	struct ieee80211_chanctx_conf *chanctx_conf;

	if (!ref)
		return;

	/* SW rate control isn't supported with MLO right now */
	if (WARN_ON(ieee80211_vif_is_mld(&sta->sdata->vif)))
		return;

	rcu_read_lock();

	chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf);
	if (WARN_ON(!chanctx_conf)) {
		rcu_read_unlock();
		return;
	}

	sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];

	/* TODO: check for minstrel_s1g ? */
	if (sband->band == NL80211_BAND_S1GHZ) {
		ieee80211_s1g_sta_rate_init(sta);
		rcu_read_unlock();
		return;
	}

	spin_lock_bh(&sta->rate_ctrl_lock);
	ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
			    priv_sta);
	spin_unlock_bh(&sta->rate_ctrl_lock);
	rcu_read_unlock();
	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
}

void rate_control_rate_init_all_links(struct sta_info *sta)
{
	int link_id;

	for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) {
		struct link_sta_info *link_sta;

		link_sta = sdata_dereference(sta->link[link_id], sta->sdata);
		if (!link_sta)
			continue;

		rate_control_rate_init(link_sta);
	}
}

void rate_control_tx_status(struct ieee80211_local *local,
			    struct ieee80211_tx_status *st)
{
	struct rate_control_ref *ref = local->rate_ctrl;
	struct sta_info *sta = container_of(st->sta, struct sta_info, sta);
	void *priv_sta = sta->rate_ctrl_priv;
	struct ieee80211_supported_band *sband;

	if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
		return;

	if (st->info->band >= NUM_NL80211_BANDS)
		return;

	sband = local->hw.wiphy->bands[st->info->band];

	spin_lock_bh(&sta->rate_ctrl_lock);
	if (ref->ops->tx_status_ext)
		ref->ops->tx_status_ext(ref->priv, sband, priv_sta, st);
	else if (st->skb)

Annotation

Implementation Notes