net/mac80211/chan.c

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

File Facts

System
Linux kernel
Corpus path
net/mac80211/chan.c
Extension
.c
Size
68118 bytes
Lines
2554
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 ieee80211_chanctx_user_iter {
	struct ieee80211_chan_req *chanreq;
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_link_data *link;
	struct ieee80211_nan_channel *nan_channel;
	int nan_channel_next_idx;
	enum nl80211_iftype iftype;
	bool reserved, radar_required, done;
	enum {
		CHANCTX_ITER_POS_ASSIGNED,
		CHANCTX_ITER_POS_RESERVED,
		CHANCTX_ITER_POS_DONE,
	} per_link;
};

enum ieee80211_chanctx_iter_type {
	CHANCTX_ITER_ALL,
	CHANCTX_ITER_RESERVED,
	CHANCTX_ITER_ASSIGNED,
};

static bool
ieee80211_chanctx_user_iter_next_nan_channel(struct ieee80211_chanctx *ctx,
					     struct ieee80211_chanctx_user_iter *iter)
{
	/* Start from the next index after current position */
	for (int i = iter->nan_channel_next_idx;
	     i < ARRAY_SIZE(iter->sdata->vif.cfg.nan_sched.channels); i++) {
		struct ieee80211_nan_channel *nan_channel =
			&iter->sdata->vif.cfg.nan_sched.channels[i];

		if (!nan_channel->chanreq.oper.chan)
			continue;

		if (nan_channel->chanctx_conf != &ctx->conf)
			continue;

		iter->nan_channel = nan_channel;
		iter->nan_channel_next_idx = i + 1;
		iter->chanreq = &nan_channel->chanreq;
		iter->link = NULL;
		iter->reserved = false;
		iter->radar_required = false;
		return true;
	}
	return false;
}

static bool
ieee80211_chanctx_user_iter_next_link(struct ieee80211_chanctx *ctx,
				      struct ieee80211_chanctx_user_iter *iter,
				      enum ieee80211_chanctx_iter_type type)
{
	for (int link_id = iter->link ? iter->link->link_id : 0;
	     link_id < ARRAY_SIZE(iter->sdata->link);
	     link_id++) {
		struct ieee80211_link_data *link;

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

		switch (iter->per_link) {
		case CHANCTX_ITER_POS_ASSIGNED:
			iter->per_link = CHANCTX_ITER_POS_RESERVED;
			if (type != CHANCTX_ITER_RESERVED &&
			    rcu_access_pointer(link->conf->chanctx_conf) == &ctx->conf) {
				iter->link = link;
				iter->reserved = false;
				iter->radar_required = link->radar_required;
				iter->chanreq = &link->conf->chanreq;
				return true;
			}
			fallthrough;
		case CHANCTX_ITER_POS_RESERVED:
			iter->per_link = CHANCTX_ITER_POS_DONE;
			if (type != CHANCTX_ITER_ASSIGNED &&
			    link->reserved_chanctx == ctx) {
				iter->link = link;
				iter->reserved = true;
				iter->radar_required =
					link->reserved_radar_required;

				iter->chanreq = &link->reserved;
				return true;
			}
			fallthrough;
		case CHANCTX_ITER_POS_DONE:
			iter->per_link = CHANCTX_ITER_POS_ASSIGNED;

Annotation

Implementation Notes