Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wifi: mac80211: always use full chanctx compatible check

For NPCA, we need to treat the channel request differently
for AP and other interfaces (APs can share NPCA, under the
assumption that userspace will set them up with the same
BSS color.) This is difficult if we have to check against
a chanreq made up from the chanctx, but this isn't a code
path that needs to be highly optimised, so just always use
the (originally) recheck functionality to check against
all users of the chanctx.

Link: https://patch.msgid.link/20260303152641.1a3ff6ead82b.I486f1a94b9a32e0b045815cbbb22679c8cef56e4@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+39 -51
+39 -51
net/mac80211/chan.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * mac80211 - channel management 4 - * Copyright 2020 - 2025 Intel Corporation 4 + * Copyright 2020-2026 Intel Corporation 5 5 */ 6 6 7 7 #include <linux/nl80211.h> ··· 239 239 return tmp; 240 240 } 241 241 242 + /* 243 + * When checking for compatible, check against all the links using 244 + * the chanctx (except the one passed that might be changing) to 245 + * allow changes to the AP's bandwidth for wider bandwidth OFDMA 246 + * purposes, which wouldn't be treated as compatible by checking 247 + * against the chanctx's oper/ap chandefs. 248 + */ 242 249 static const struct ieee80211_chan_req * 243 - ieee80211_chanctx_compatible(struct ieee80211_chanctx *ctx, 250 + _ieee80211_chanctx_compatible(struct ieee80211_local *local, 251 + struct ieee80211_link_data *skip_link, 252 + struct ieee80211_chanctx *ctx, 253 + const struct ieee80211_chan_req *req, 254 + struct ieee80211_chan_req *tmp) 255 + { 256 + const struct ieee80211_chan_req *ret = req; 257 + struct ieee80211_chanctx_user_iter iter; 258 + 259 + lockdep_assert_wiphy(local->hw.wiphy); 260 + 261 + for_each_chanctx_user_all(local, ctx, &iter) { 262 + if (iter.link && iter.link == skip_link) 263 + continue; 264 + 265 + ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp); 266 + if (!ret) 267 + return NULL; 268 + } 269 + 270 + *tmp = *ret; 271 + return tmp; 272 + } 273 + 274 + static const struct ieee80211_chan_req * 275 + ieee80211_chanctx_compatible(struct ieee80211_local *local, 276 + struct ieee80211_chanctx *ctx, 244 277 const struct ieee80211_chan_req *req, 245 278 struct ieee80211_chan_req *tmp) 246 279 { 247 - const struct ieee80211_chan_req *ret; 248 - struct ieee80211_chan_req tmp2; 249 - 250 - *tmp = (struct ieee80211_chan_req){ 251 - .oper = ctx->conf.def, 252 - .ap = ctx->conf.ap, 253 - }; 254 - 255 - ret = ieee80211_chanreq_compatible(tmp, req, &tmp2); 256 - if (!ret) 257 - return NULL; 258 - *tmp = *ret; 259 - return tmp; 280 + return _ieee80211_chanctx_compatible(local, NULL, ctx, req, tmp); 260 281 } 261 282 262 283 static const struct ieee80211_chan_req * ··· 777 756 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 778 757 continue; 779 758 780 - compat = ieee80211_chanctx_compatible(ctx, chanreq, &tmp); 759 + compat = ieee80211_chanctx_compatible(local, ctx, chanreq, 760 + &tmp); 781 761 if (!compat) 782 762 continue; 783 763 ··· 2150 2128 return 0; 2151 2129 } 2152 2130 2153 - /* 2154 - * This is similar to ieee80211_chanctx_compatible(), but rechecks 2155 - * against all the links actually using it (except the one that's 2156 - * passed, since that one is changing). 2157 - * This is done in order to allow changes to the AP's bandwidth for 2158 - * wider bandwidth OFDMA purposes, which wouldn't be treated as 2159 - * compatible by ieee80211_chanctx_recheck() but is OK if the link 2160 - * requesting the update is the only one using it. 2161 - */ 2162 - static const struct ieee80211_chan_req * 2163 - ieee80211_chanctx_recheck(struct ieee80211_local *local, 2164 - struct ieee80211_link_data *skip_link, 2165 - struct ieee80211_chanctx *ctx, 2166 - const struct ieee80211_chan_req *req, 2167 - struct ieee80211_chan_req *tmp) 2168 - { 2169 - const struct ieee80211_chan_req *ret = req; 2170 - struct ieee80211_chanctx_user_iter iter; 2171 - 2172 - lockdep_assert_wiphy(local->hw.wiphy); 2173 - 2174 - for_each_chanctx_user_all(local, ctx, &iter) { 2175 - if (iter.link == skip_link) 2176 - continue; 2177 - 2178 - ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp); 2179 - if (!ret) 2180 - return NULL; 2181 - } 2182 - 2183 - *tmp = *ret; 2184 - return tmp; 2185 - } 2186 - 2187 2131 int ieee80211_link_change_chanreq(struct ieee80211_link_data *link, 2188 2132 const struct ieee80211_chan_req *chanreq, 2189 2133 u64 *changed) ··· 2186 2198 2187 2199 ctx = container_of(conf, struct ieee80211_chanctx, conf); 2188 2200 2189 - compat = ieee80211_chanctx_recheck(local, link, ctx, chanreq, &tmp); 2201 + compat = _ieee80211_chanctx_compatible(local, link, ctx, chanreq, &tmp); 2190 2202 if (!compat) 2191 2203 return -EINVAL; 2192 2204