chan.c 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * mac80211 - channel management
  4. * Copyright 2020 - 2025 Intel Corporation
  5. */
  6. #include <linux/nl80211.h>
  7. #include <linux/export.h>
  8. #include <linux/rtnetlink.h>
  9. #include <net/cfg80211.h>
  10. #include "ieee80211_i.h"
  11. #include "driver-ops.h"
  12. #include "rate.h"
  13. struct ieee80211_chanctx_user_iter {
  14. struct ieee80211_chan_req *chanreq;
  15. struct ieee80211_sub_if_data *sdata;
  16. struct ieee80211_link_data *link;
  17. enum nl80211_iftype iftype;
  18. bool reserved, radar_required, done;
  19. enum {
  20. CHANCTX_ITER_POS_ASSIGNED,
  21. CHANCTX_ITER_POS_RESERVED,
  22. CHANCTX_ITER_POS_DONE,
  23. } per_link;
  24. };
  25. enum ieee80211_chanctx_iter_type {
  26. CHANCTX_ITER_ALL,
  27. CHANCTX_ITER_RESERVED,
  28. CHANCTX_ITER_ASSIGNED,
  29. };
  30. static void ieee80211_chanctx_user_iter_next(struct ieee80211_local *local,
  31. struct ieee80211_chanctx *ctx,
  32. struct ieee80211_chanctx_user_iter *iter,
  33. enum ieee80211_chanctx_iter_type type,
  34. bool start)
  35. {
  36. lockdep_assert_wiphy(local->hw.wiphy);
  37. if (start) {
  38. memset(iter, 0, sizeof(*iter));
  39. goto next_interface;
  40. }
  41. next_link:
  42. for (int link_id = iter->link ? iter->link->link_id : 0;
  43. link_id < ARRAY_SIZE(iter->sdata->link);
  44. link_id++) {
  45. struct ieee80211_link_data *link;
  46. link = sdata_dereference(iter->sdata->link[link_id],
  47. iter->sdata);
  48. if (!link)
  49. continue;
  50. switch (iter->per_link) {
  51. case CHANCTX_ITER_POS_ASSIGNED:
  52. iter->per_link = CHANCTX_ITER_POS_RESERVED;
  53. if (type != CHANCTX_ITER_RESERVED &&
  54. rcu_access_pointer(link->conf->chanctx_conf) == &ctx->conf) {
  55. iter->link = link;
  56. iter->reserved = false;
  57. iter->radar_required = link->radar_required;
  58. iter->chanreq = &link->conf->chanreq;
  59. return;
  60. }
  61. fallthrough;
  62. case CHANCTX_ITER_POS_RESERVED:
  63. iter->per_link = CHANCTX_ITER_POS_DONE;
  64. if (type != CHANCTX_ITER_ASSIGNED &&
  65. link->reserved_chanctx == ctx) {
  66. iter->link = link;
  67. iter->reserved = true;
  68. iter->radar_required =
  69. link->reserved_radar_required;
  70. iter->chanreq = &link->reserved;
  71. return;
  72. }
  73. fallthrough;
  74. case CHANCTX_ITER_POS_DONE:
  75. iter->per_link = CHANCTX_ITER_POS_ASSIGNED;
  76. continue;
  77. }
  78. }
  79. next_interface:
  80. /* next (or first) interface */
  81. iter->sdata = list_prepare_entry(iter->sdata, &local->interfaces, list);
  82. list_for_each_entry_continue(iter->sdata, &local->interfaces, list) {
  83. if (!ieee80211_sdata_running(iter->sdata))
  84. continue;
  85. /* AP_VLAN has a chanctx pointer but follows AP */
  86. if (iter->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  87. continue;
  88. iter->link = NULL;
  89. iter->per_link = CHANCTX_ITER_POS_ASSIGNED;
  90. iter->iftype = iter->sdata->vif.type;
  91. goto next_link;
  92. }
  93. iter->done = true;
  94. }
  95. #define for_each_chanctx_user_assigned(local, ctx, iter) \
  96. for (ieee80211_chanctx_user_iter_next(local, ctx, iter, \
  97. CHANCTX_ITER_ASSIGNED, \
  98. true); \
  99. !((iter)->done); \
  100. ieee80211_chanctx_user_iter_next(local, ctx, iter, \
  101. CHANCTX_ITER_ASSIGNED, \
  102. false))
  103. #define for_each_chanctx_user_reserved(local, ctx, iter) \
  104. for (ieee80211_chanctx_user_iter_next(local, ctx, iter, \
  105. CHANCTX_ITER_RESERVED, \
  106. true); \
  107. !((iter)->done); \
  108. ieee80211_chanctx_user_iter_next(local, ctx, iter, \
  109. CHANCTX_ITER_RESERVED, \
  110. false))
  111. #define for_each_chanctx_user_all(local, ctx, iter) \
  112. for (ieee80211_chanctx_user_iter_next(local, ctx, iter, \
  113. CHANCTX_ITER_ALL, \
  114. true); \
  115. !((iter)->done); \
  116. ieee80211_chanctx_user_iter_next(local, ctx, iter, \
  117. CHANCTX_ITER_ALL, \
  118. false))
  119. static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
  120. struct ieee80211_chanctx *ctx)
  121. {
  122. struct ieee80211_chanctx_user_iter iter;
  123. int num = 0;
  124. for_each_chanctx_user_assigned(local, ctx, &iter)
  125. num++;
  126. return num;
  127. }
  128. static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local,
  129. struct ieee80211_chanctx *ctx)
  130. {
  131. struct ieee80211_chanctx_user_iter iter;
  132. int num = 0;
  133. for_each_chanctx_user_reserved(local, ctx, &iter)
  134. num++;
  135. return num;
  136. }
  137. int ieee80211_chanctx_refcount(struct ieee80211_local *local,
  138. struct ieee80211_chanctx *ctx)
  139. {
  140. struct ieee80211_chanctx_user_iter iter;
  141. int num = 0;
  142. for_each_chanctx_user_all(local, ctx, &iter)
  143. num++;
  144. return num;
  145. }
  146. static int ieee80211_num_chanctx(struct ieee80211_local *local, int radio_idx)
  147. {
  148. struct ieee80211_chanctx *ctx;
  149. int num = 0;
  150. lockdep_assert_wiphy(local->hw.wiphy);
  151. list_for_each_entry(ctx, &local->chanctx_list, list) {
  152. if (radio_idx >= 0 && ctx->conf.radio_idx != radio_idx)
  153. continue;
  154. num++;
  155. }
  156. return num;
  157. }
  158. static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local,
  159. int radio_idx)
  160. {
  161. lockdep_assert_wiphy(local->hw.wiphy);
  162. return ieee80211_num_chanctx(local, radio_idx) <
  163. ieee80211_max_num_channels(local, radio_idx);
  164. }
  165. static struct ieee80211_chanctx *
  166. ieee80211_link_get_chanctx(struct ieee80211_link_data *link)
  167. {
  168. struct ieee80211_local *local __maybe_unused = link->sdata->local;
  169. struct ieee80211_chanctx_conf *conf;
  170. conf = rcu_dereference_protected(link->conf->chanctx_conf,
  171. lockdep_is_held(&local->hw.wiphy->mtx));
  172. if (!conf)
  173. return NULL;
  174. return container_of(conf, struct ieee80211_chanctx, conf);
  175. }
  176. bool ieee80211_chanreq_identical(const struct ieee80211_chan_req *a,
  177. const struct ieee80211_chan_req *b)
  178. {
  179. if (!cfg80211_chandef_identical(&a->oper, &b->oper))
  180. return false;
  181. if (!a->ap.chan && !b->ap.chan)
  182. return true;
  183. return cfg80211_chandef_identical(&a->ap, &b->ap);
  184. }
  185. static const struct ieee80211_chan_req *
  186. ieee80211_chanreq_compatible(const struct ieee80211_chan_req *a,
  187. const struct ieee80211_chan_req *b,
  188. struct ieee80211_chan_req *tmp)
  189. {
  190. const struct cfg80211_chan_def *compat;
  191. if (a->ap.chan && b->ap.chan &&
  192. !cfg80211_chandef_identical(&a->ap, &b->ap))
  193. return NULL;
  194. compat = cfg80211_chandef_compatible(&a->oper, &b->oper);
  195. if (!compat)
  196. return NULL;
  197. /* Note: later code assumes this always fills & returns tmp if compat */
  198. tmp->oper = *compat;
  199. tmp->ap = a->ap.chan ? a->ap : b->ap;
  200. return tmp;
  201. }
  202. static const struct ieee80211_chan_req *
  203. ieee80211_chanctx_compatible(struct ieee80211_chanctx *ctx,
  204. const struct ieee80211_chan_req *req,
  205. struct ieee80211_chan_req *tmp)
  206. {
  207. const struct ieee80211_chan_req *ret;
  208. struct ieee80211_chan_req tmp2;
  209. *tmp = (struct ieee80211_chan_req){
  210. .oper = ctx->conf.def,
  211. .ap = ctx->conf.ap,
  212. };
  213. ret = ieee80211_chanreq_compatible(tmp, req, &tmp2);
  214. if (!ret)
  215. return NULL;
  216. *tmp = *ret;
  217. return tmp;
  218. }
  219. static const struct ieee80211_chan_req *
  220. ieee80211_chanctx_reserved_chanreq(struct ieee80211_local *local,
  221. struct ieee80211_chanctx *ctx,
  222. const struct ieee80211_chan_req *req,
  223. struct ieee80211_chan_req *tmp)
  224. {
  225. struct ieee80211_chanctx_user_iter iter;
  226. lockdep_assert_wiphy(local->hw.wiphy);
  227. if (WARN_ON(!req))
  228. return NULL;
  229. for_each_chanctx_user_reserved(local, ctx, &iter) {
  230. req = ieee80211_chanreq_compatible(iter.chanreq, req, tmp);
  231. if (!req)
  232. break;
  233. }
  234. return req;
  235. }
  236. static const struct ieee80211_chan_req *
  237. ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,
  238. struct ieee80211_chanctx *ctx,
  239. const struct ieee80211_chan_req *compat,
  240. struct ieee80211_chan_req *tmp)
  241. {
  242. const struct ieee80211_chan_req *comp_def = compat;
  243. struct ieee80211_chanctx_user_iter iter;
  244. lockdep_assert_wiphy(local->hw.wiphy);
  245. for_each_chanctx_user_assigned(local, ctx, &iter) {
  246. if (iter.link->reserved_chanctx)
  247. continue;
  248. comp_def = ieee80211_chanreq_compatible(iter.chanreq,
  249. comp_def, tmp);
  250. if (!comp_def)
  251. break;
  252. }
  253. return comp_def;
  254. }
  255. static bool
  256. ieee80211_chanctx_can_reserve(struct ieee80211_local *local,
  257. struct ieee80211_chanctx *ctx,
  258. const struct ieee80211_chan_req *req)
  259. {
  260. struct ieee80211_chan_req tmp;
  261. lockdep_assert_wiphy(local->hw.wiphy);
  262. if (!ieee80211_chanctx_reserved_chanreq(local, ctx, req, &tmp))
  263. return false;
  264. if (!ieee80211_chanctx_non_reserved_chandef(local, ctx, req, &tmp))
  265. return false;
  266. if (ieee80211_chanctx_num_reserved(local, ctx) != 0 &&
  267. ieee80211_chanctx_reserved_chanreq(local, ctx, req, &tmp))
  268. return true;
  269. return false;
  270. }
  271. static struct ieee80211_chanctx *
  272. ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
  273. const struct ieee80211_chan_req *chanreq,
  274. enum ieee80211_chanctx_mode mode)
  275. {
  276. struct ieee80211_chanctx *ctx;
  277. lockdep_assert_wiphy(local->hw.wiphy);
  278. if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
  279. return NULL;
  280. list_for_each_entry(ctx, &local->chanctx_list, list) {
  281. if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
  282. continue;
  283. if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
  284. continue;
  285. if (!ieee80211_chanctx_can_reserve(local, ctx, chanreq))
  286. continue;
  287. return ctx;
  288. }
  289. return NULL;
  290. }
  291. static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta,
  292. unsigned int link_id)
  293. {
  294. enum ieee80211_sta_rx_bandwidth width;
  295. struct link_sta_info *link_sta;
  296. link_sta = wiphy_dereference(sta->local->hw.wiphy, sta->link[link_id]);
  297. /* no effect if this STA has no presence on this link */
  298. if (!link_sta)
  299. return NL80211_CHAN_WIDTH_20_NOHT;
  300. /*
  301. * We assume that TX/RX might be asymmetric (so e.g. VHT operating
  302. * mode notification changes what a STA wants to receive, but not
  303. * necessarily what it will transmit to us), and therefore use the
  304. * capabilities here. Calling it RX bandwidth capability is a bit
  305. * wrong though, since capabilities are in fact symmetric.
  306. */
  307. width = ieee80211_sta_cap_rx_bw(link_sta);
  308. switch (width) {
  309. case IEEE80211_STA_RX_BW_20:
  310. if (link_sta->pub->ht_cap.ht_supported)
  311. return NL80211_CHAN_WIDTH_20;
  312. else
  313. return NL80211_CHAN_WIDTH_20_NOHT;
  314. case IEEE80211_STA_RX_BW_40:
  315. return NL80211_CHAN_WIDTH_40;
  316. case IEEE80211_STA_RX_BW_80:
  317. return NL80211_CHAN_WIDTH_80;
  318. case IEEE80211_STA_RX_BW_160:
  319. /*
  320. * This applied for both 160 and 80+80. since we use
  321. * the returned value to consider degradation of
  322. * ctx->conf.min_def, we have to make sure to take
  323. * the bigger one (NL80211_CHAN_WIDTH_160).
  324. * Otherwise we might try degrading even when not
  325. * needed, as the max required sta_bw returned (80+80)
  326. * might be smaller than the configured bw (160).
  327. */
  328. return NL80211_CHAN_WIDTH_160;
  329. case IEEE80211_STA_RX_BW_320:
  330. return NL80211_CHAN_WIDTH_320;
  331. default:
  332. WARN_ON(1);
  333. return NL80211_CHAN_WIDTH_20;
  334. }
  335. }
  336. static enum nl80211_chan_width
  337. ieee80211_get_max_required_bw(struct ieee80211_link_data *link)
  338. {
  339. struct ieee80211_sub_if_data *sdata = link->sdata;
  340. unsigned int link_id = link->link_id;
  341. enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
  342. struct sta_info *sta;
  343. lockdep_assert_wiphy(sdata->local->hw.wiphy);
  344. list_for_each_entry(sta, &sdata->local->sta_list, list) {
  345. if (sdata != sta->sdata &&
  346. !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
  347. continue;
  348. max_bw = max(max_bw, ieee80211_get_sta_bw(sta, link_id));
  349. }
  350. return max_bw;
  351. }
  352. static enum nl80211_chan_width
  353. ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
  354. struct ieee80211_chanctx *ctx,
  355. struct ieee80211_link_data *rsvd_for,
  356. bool check_reserved)
  357. {
  358. struct ieee80211_sub_if_data *sdata;
  359. struct ieee80211_link_data *link;
  360. enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
  361. if (WARN_ON(check_reserved && rsvd_for))
  362. return ctx->conf.def.width;
  363. for_each_sdata_link(local, link) {
  364. enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
  365. if (check_reserved) {
  366. if (link->reserved_chanctx != ctx)
  367. continue;
  368. } else if (link != rsvd_for &&
  369. rcu_access_pointer(link->conf->chanctx_conf) != &ctx->conf)
  370. continue;
  371. switch (link->sdata->vif.type) {
  372. case NL80211_IFTYPE_STATION:
  373. if (!link->sdata->vif.cfg.assoc) {
  374. /*
  375. * The AP's sta->bandwidth may not yet be set
  376. * at this point (pre-association), so simply
  377. * take the width from the chandef. We cannot
  378. * have TDLS peers yet (only after association).
  379. */
  380. width = link->conf->chanreq.oper.width;
  381. break;
  382. }
  383. /*
  384. * otherwise just use min_def like in AP, depending on what
  385. * we currently think the AP STA (and possibly TDLS peers)
  386. * require(s)
  387. */
  388. fallthrough;
  389. case NL80211_IFTYPE_AP:
  390. case NL80211_IFTYPE_AP_VLAN:
  391. width = ieee80211_get_max_required_bw(link);
  392. break;
  393. case NL80211_IFTYPE_P2P_DEVICE:
  394. case NL80211_IFTYPE_NAN:
  395. continue;
  396. case NL80211_IFTYPE_MONITOR:
  397. WARN_ON_ONCE(!ieee80211_hw_check(&local->hw,
  398. NO_VIRTUAL_MONITOR));
  399. fallthrough;
  400. case NL80211_IFTYPE_ADHOC:
  401. case NL80211_IFTYPE_MESH_POINT:
  402. case NL80211_IFTYPE_OCB:
  403. width = link->conf->chanreq.oper.width;
  404. break;
  405. case NL80211_IFTYPE_WDS:
  406. case NL80211_IFTYPE_UNSPECIFIED:
  407. case NUM_NL80211_IFTYPES:
  408. case NL80211_IFTYPE_P2P_CLIENT:
  409. case NL80211_IFTYPE_P2P_GO:
  410. WARN_ON_ONCE(1);
  411. }
  412. max_bw = max(max_bw, width);
  413. }
  414. /* use the configured bandwidth in case of monitor interface */
  415. sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
  416. if (sdata &&
  417. rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &ctx->conf)
  418. max_bw = max(max_bw, ctx->conf.def.width);
  419. return max_bw;
  420. }
  421. /*
  422. * recalc the min required chan width of the channel context, which is
  423. * the max of min required widths of all the interfaces bound to this
  424. * channel context.
  425. */
  426. static u32
  427. __ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
  428. struct ieee80211_chanctx *ctx,
  429. struct ieee80211_link_data *rsvd_for,
  430. bool check_reserved)
  431. {
  432. enum nl80211_chan_width max_bw;
  433. struct cfg80211_chan_def min_def;
  434. lockdep_assert_wiphy(local->hw.wiphy);
  435. /* don't optimize non-20MHz based and radar_enabled confs */
  436. if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
  437. ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
  438. ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
  439. ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
  440. ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
  441. ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
  442. ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
  443. ctx->conf.radar_enabled) {
  444. ctx->conf.min_def = ctx->conf.def;
  445. return 0;
  446. }
  447. max_bw = ieee80211_get_chanctx_max_required_bw(local, ctx, rsvd_for,
  448. check_reserved);
  449. /* downgrade chandef up to max_bw */
  450. min_def = ctx->conf.def;
  451. while (min_def.width > max_bw)
  452. ieee80211_chandef_downgrade(&min_def, NULL);
  453. if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
  454. return 0;
  455. ctx->conf.min_def = min_def;
  456. if (!ctx->driver_present)
  457. return 0;
  458. return IEEE80211_CHANCTX_CHANGE_MIN_DEF;
  459. }
  460. static void ieee80211_chan_bw_change(struct ieee80211_local *local,
  461. struct ieee80211_chanctx *ctx,
  462. bool reserved, bool narrowed)
  463. {
  464. struct sta_info *sta;
  465. struct ieee80211_supported_band *sband =
  466. local->hw.wiphy->bands[ctx->conf.def.chan->band];
  467. rcu_read_lock();
  468. list_for_each_entry_rcu(sta, &local->sta_list,
  469. list) {
  470. struct ieee80211_sub_if_data *sdata;
  471. enum ieee80211_sta_rx_bandwidth new_sta_bw;
  472. unsigned int link_id;
  473. if (!ieee80211_sdata_running(sta->sdata))
  474. continue;
  475. sdata = get_bss_sdata(sta->sdata);
  476. for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
  477. struct ieee80211_link_data *link =
  478. rcu_dereference(sdata->link[link_id]);
  479. struct ieee80211_bss_conf *link_conf;
  480. struct cfg80211_chan_def *new_chandef;
  481. struct link_sta_info *link_sta;
  482. if (!link)
  483. continue;
  484. link_conf = link->conf;
  485. if (rcu_access_pointer(link_conf->chanctx_conf) != &ctx->conf)
  486. continue;
  487. link_sta = rcu_dereference(sta->link[link_id]);
  488. if (!link_sta)
  489. continue;
  490. if (reserved)
  491. new_chandef = &link->reserved.oper;
  492. else
  493. new_chandef = &link_conf->chanreq.oper;
  494. new_sta_bw = _ieee80211_sta_cur_vht_bw(link_sta,
  495. new_chandef);
  496. /* nothing change */
  497. if (new_sta_bw == link_sta->pub->bandwidth)
  498. continue;
  499. /* vif changed to narrow BW and narrow BW for station wasn't
  500. * requested or vice versa */
  501. if ((new_sta_bw < link_sta->pub->bandwidth) == !narrowed)
  502. continue;
  503. link_sta->pub->bandwidth = new_sta_bw;
  504. rate_control_rate_update(local, sband, link_sta,
  505. IEEE80211_RC_BW_CHANGED);
  506. }
  507. }
  508. rcu_read_unlock();
  509. }
  510. /*
  511. * recalc the min required chan width of the channel context, which is
  512. * the max of min required widths of all the interfaces bound to this
  513. * channel context.
  514. */
  515. static void
  516. _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
  517. struct ieee80211_chanctx *ctx,
  518. struct ieee80211_link_data *rsvd_for,
  519. bool check_reserved)
  520. {
  521. u32 changed = __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for,
  522. check_reserved);
  523. if (!changed)
  524. return;
  525. /* check is BW narrowed */
  526. ieee80211_chan_bw_change(local, ctx, false, true);
  527. drv_change_chanctx(local, ctx, changed);
  528. /* check is BW wider */
  529. ieee80211_chan_bw_change(local, ctx, false, false);
  530. }
  531. void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
  532. struct ieee80211_chanctx *ctx)
  533. {
  534. _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
  535. }
  536. static void _ieee80211_change_chanctx(struct ieee80211_local *local,
  537. struct ieee80211_chanctx *ctx,
  538. struct ieee80211_chanctx *old_ctx,
  539. const struct ieee80211_chan_req *chanreq,
  540. struct ieee80211_link_data *rsvd_for)
  541. {
  542. const struct cfg80211_chan_def *chandef = &chanreq->oper;
  543. struct ieee80211_chan_req ctx_req = {
  544. .oper = ctx->conf.def,
  545. .ap = ctx->conf.ap,
  546. };
  547. u32 changed = 0;
  548. /* 5/10 MHz not handled here */
  549. switch (chandef->width) {
  550. case NL80211_CHAN_WIDTH_1:
  551. case NL80211_CHAN_WIDTH_2:
  552. case NL80211_CHAN_WIDTH_4:
  553. case NL80211_CHAN_WIDTH_8:
  554. case NL80211_CHAN_WIDTH_16:
  555. /*
  556. * mac80211 currently only supports sharing identical
  557. * chanctx's for S1G interfaces.
  558. */
  559. WARN_ON(!ieee80211_chanreq_identical(&ctx_req, chanreq));
  560. return;
  561. case NL80211_CHAN_WIDTH_20_NOHT:
  562. case NL80211_CHAN_WIDTH_20:
  563. case NL80211_CHAN_WIDTH_40:
  564. case NL80211_CHAN_WIDTH_80:
  565. case NL80211_CHAN_WIDTH_80P80:
  566. case NL80211_CHAN_WIDTH_160:
  567. case NL80211_CHAN_WIDTH_320:
  568. break;
  569. default:
  570. WARN_ON(1);
  571. }
  572. /* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def
  573. * due to maybe not returning from it, e.g in case new context was added
  574. * first time with all parameters up to date.
  575. */
  576. ieee80211_chan_bw_change(local, old_ctx, false, true);
  577. if (ieee80211_chanreq_identical(&ctx_req, chanreq)) {
  578. _ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, false);
  579. return;
  580. }
  581. WARN_ON(ieee80211_chanctx_refcount(local, ctx) > 1 &&
  582. !cfg80211_chandef_compatible(&ctx->conf.def, &chanreq->oper));
  583. ieee80211_remove_wbrf(local, &ctx->conf.def);
  584. if (!cfg80211_chandef_identical(&ctx->conf.def, &chanreq->oper)) {
  585. if (ctx->conf.def.width != chanreq->oper.width)
  586. changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
  587. if (ctx->conf.def.punctured != chanreq->oper.punctured)
  588. changed |= IEEE80211_CHANCTX_CHANGE_PUNCTURING;
  589. }
  590. if (!cfg80211_chandef_identical(&ctx->conf.ap, &chanreq->ap))
  591. changed |= IEEE80211_CHANCTX_CHANGE_AP;
  592. ctx->conf.def = *chandef;
  593. ctx->conf.ap = chanreq->ap;
  594. /* check if min chanctx also changed */
  595. changed |= __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for,
  596. false);
  597. ieee80211_add_wbrf(local, &ctx->conf.def);
  598. drv_change_chanctx(local, ctx, changed);
  599. /* check if BW is wider */
  600. ieee80211_chan_bw_change(local, old_ctx, false, false);
  601. }
  602. static void ieee80211_change_chanctx(struct ieee80211_local *local,
  603. struct ieee80211_chanctx *ctx,
  604. struct ieee80211_chanctx *old_ctx,
  605. const struct ieee80211_chan_req *chanreq)
  606. {
  607. _ieee80211_change_chanctx(local, ctx, old_ctx, chanreq, NULL);
  608. }
  609. /* Note: if successful, the returned chanctx is reserved for the link */
  610. static struct ieee80211_chanctx *
  611. ieee80211_find_chanctx(struct ieee80211_local *local,
  612. struct ieee80211_link_data *link,
  613. const struct ieee80211_chan_req *chanreq,
  614. enum ieee80211_chanctx_mode mode)
  615. {
  616. struct ieee80211_chan_req tmp;
  617. struct ieee80211_chanctx *ctx;
  618. lockdep_assert_wiphy(local->hw.wiphy);
  619. if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
  620. return NULL;
  621. if (WARN_ON(link->reserved_chanctx))
  622. return NULL;
  623. list_for_each_entry(ctx, &local->chanctx_list, list) {
  624. const struct ieee80211_chan_req *compat;
  625. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
  626. continue;
  627. if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
  628. continue;
  629. compat = ieee80211_chanctx_compatible(ctx, chanreq, &tmp);
  630. if (!compat)
  631. continue;
  632. compat = ieee80211_chanctx_reserved_chanreq(local, ctx,
  633. compat, &tmp);
  634. if (!compat)
  635. continue;
  636. /*
  637. * Reserve the chanctx temporarily, as the driver might change
  638. * active links during callbacks we make into it below and/or
  639. * later during assignment, which could (otherwise) cause the
  640. * context to actually be removed.
  641. */
  642. link->reserved_chanctx = ctx;
  643. ieee80211_change_chanctx(local, ctx, ctx, compat);
  644. return ctx;
  645. }
  646. return NULL;
  647. }
  648. bool ieee80211_is_radar_required(struct ieee80211_local *local,
  649. struct cfg80211_scan_request *req)
  650. {
  651. struct wiphy *wiphy = local->hw.wiphy;
  652. struct ieee80211_link_data *link;
  653. struct ieee80211_channel *chan;
  654. int radio_idx;
  655. lockdep_assert_wiphy(local->hw.wiphy);
  656. if (!req)
  657. return false;
  658. for_each_sdata_link(local, link) {
  659. if (link->radar_required) {
  660. chan = link->conf->chanreq.oper.chan;
  661. radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chan);
  662. if (ieee80211_is_radio_idx_in_scan_req(wiphy, req,
  663. radio_idx))
  664. return true;
  665. }
  666. }
  667. return false;
  668. }
  669. static bool
  670. ieee80211_chanctx_radar_required(struct ieee80211_local *local,
  671. struct ieee80211_chanctx *ctx)
  672. {
  673. struct ieee80211_chanctx_user_iter iter;
  674. lockdep_assert_wiphy(local->hw.wiphy);
  675. for_each_chanctx_user_assigned(local, ctx, &iter) {
  676. if (iter.radar_required)
  677. return true;
  678. }
  679. return false;
  680. }
  681. static struct ieee80211_chanctx *
  682. ieee80211_alloc_chanctx(struct ieee80211_local *local,
  683. const struct ieee80211_chan_req *chanreq,
  684. enum ieee80211_chanctx_mode mode,
  685. int radio_idx)
  686. {
  687. struct ieee80211_chanctx *ctx;
  688. lockdep_assert_wiphy(local->hw.wiphy);
  689. ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
  690. if (!ctx)
  691. return NULL;
  692. ctx->conf.def = chanreq->oper;
  693. ctx->conf.ap = chanreq->ap;
  694. ctx->conf.rx_chains_static = 1;
  695. ctx->conf.rx_chains_dynamic = 1;
  696. ctx->mode = mode;
  697. ctx->conf.radar_enabled = false;
  698. ctx->conf.radio_idx = radio_idx;
  699. ctx->radar_detected = false;
  700. __ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
  701. return ctx;
  702. }
  703. static int ieee80211_add_chanctx(struct ieee80211_local *local,
  704. struct ieee80211_chanctx *ctx)
  705. {
  706. u32 changed;
  707. int err;
  708. lockdep_assert_wiphy(local->hw.wiphy);
  709. ieee80211_add_wbrf(local, &ctx->conf.def);
  710. /* turn idle off *before* setting channel -- some drivers need that */
  711. changed = ieee80211_idle_off(local);
  712. if (changed)
  713. ieee80211_hw_config(local, -1, changed);
  714. err = drv_add_chanctx(local, ctx);
  715. if (err) {
  716. ieee80211_recalc_idle(local);
  717. return err;
  718. }
  719. return 0;
  720. }
  721. static struct ieee80211_chanctx *
  722. ieee80211_new_chanctx(struct ieee80211_local *local,
  723. const struct ieee80211_chan_req *chanreq,
  724. enum ieee80211_chanctx_mode mode,
  725. bool assign_on_failure,
  726. int radio_idx)
  727. {
  728. struct ieee80211_chanctx *ctx;
  729. int err;
  730. lockdep_assert_wiphy(local->hw.wiphy);
  731. ctx = ieee80211_alloc_chanctx(local, chanreq, mode, radio_idx);
  732. if (!ctx)
  733. return ERR_PTR(-ENOMEM);
  734. err = ieee80211_add_chanctx(local, ctx);
  735. if (!assign_on_failure && err) {
  736. kfree(ctx);
  737. return ERR_PTR(err);
  738. }
  739. /* We ignored a driver error, see _ieee80211_set_active_links */
  740. WARN_ON_ONCE(err && !local->in_reconfig);
  741. list_add_rcu(&ctx->list, &local->chanctx_list);
  742. return ctx;
  743. }
  744. static void ieee80211_del_chanctx(struct ieee80211_local *local,
  745. struct ieee80211_chanctx *ctx,
  746. bool skip_idle_recalc)
  747. {
  748. lockdep_assert_wiphy(local->hw.wiphy);
  749. drv_remove_chanctx(local, ctx);
  750. if (!skip_idle_recalc)
  751. ieee80211_recalc_idle(local);
  752. ieee80211_remove_wbrf(local, &ctx->conf.def);
  753. }
  754. static void ieee80211_free_chanctx(struct ieee80211_local *local,
  755. struct ieee80211_chanctx *ctx,
  756. bool skip_idle_recalc)
  757. {
  758. lockdep_assert_wiphy(local->hw.wiphy);
  759. WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0);
  760. list_del_rcu(&ctx->list);
  761. ieee80211_del_chanctx(local, ctx, skip_idle_recalc);
  762. kfree_rcu(ctx, rcu_head);
  763. }
  764. void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
  765. struct ieee80211_chanctx *ctx)
  766. {
  767. struct ieee80211_chanctx_conf *conf = &ctx->conf;
  768. const struct ieee80211_chan_req *compat = NULL;
  769. struct ieee80211_chanctx_user_iter iter;
  770. struct ieee80211_chan_req tmp;
  771. struct sta_info *sta;
  772. lockdep_assert_wiphy(local->hw.wiphy);
  773. for_each_chanctx_user_assigned(local, ctx, &iter) {
  774. if (!compat)
  775. compat = iter.chanreq;
  776. compat = ieee80211_chanreq_compatible(iter.chanreq,
  777. compat, &tmp);
  778. if (WARN_ON_ONCE(!compat))
  779. return;
  780. }
  781. if (WARN_ON_ONCE(!compat))
  782. return;
  783. /* TDLS peers can sometimes affect the chandef width */
  784. list_for_each_entry(sta, &local->sta_list, list) {
  785. struct ieee80211_sub_if_data *sdata = sta->sdata;
  786. struct ieee80211_chan_req tdls_chanreq = {};
  787. struct ieee80211_link_data *link;
  788. int tdls_link_id;
  789. if (!sta->uploaded ||
  790. !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) ||
  791. !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
  792. !sta->tdls_chandef.chan)
  793. continue;
  794. tdls_link_id = ieee80211_tdls_sta_link_id(sta);
  795. link = sdata_dereference(sdata->link[tdls_link_id], sdata);
  796. if (!link)
  797. continue;
  798. if (rcu_access_pointer(link->conf->chanctx_conf) != conf)
  799. continue;
  800. tdls_chanreq.oper = sta->tdls_chandef;
  801. /* note this always fills and returns &tmp if compat */
  802. compat = ieee80211_chanreq_compatible(&tdls_chanreq,
  803. compat, &tmp);
  804. if (WARN_ON_ONCE(!compat))
  805. return;
  806. }
  807. ieee80211_change_chanctx(local, ctx, ctx, compat);
  808. }
  809. static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
  810. struct ieee80211_chanctx *chanctx)
  811. {
  812. bool radar_enabled;
  813. lockdep_assert_wiphy(local->hw.wiphy);
  814. radar_enabled = ieee80211_chanctx_radar_required(local, chanctx);
  815. if (radar_enabled == chanctx->conf.radar_enabled)
  816. return;
  817. chanctx->conf.radar_enabled = radar_enabled;
  818. drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
  819. }
  820. static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
  821. struct ieee80211_chanctx *new_ctx,
  822. bool assign_on_failure)
  823. {
  824. struct ieee80211_sub_if_data *sdata = link->sdata;
  825. struct ieee80211_local *local = sdata->local;
  826. struct ieee80211_chanctx_conf *conf;
  827. struct ieee80211_chanctx *curr_ctx = NULL;
  828. bool new_idle;
  829. int ret;
  830. if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
  831. return -EOPNOTSUPP;
  832. conf = rcu_dereference_protected(link->conf->chanctx_conf,
  833. lockdep_is_held(&local->hw.wiphy->mtx));
  834. if (conf && !local->in_reconfig) {
  835. curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
  836. drv_unassign_vif_chanctx(local, sdata, link->conf, curr_ctx);
  837. conf = NULL;
  838. }
  839. if (new_ctx) {
  840. /* recalc considering the link we'll use it for now */
  841. _ieee80211_recalc_chanctx_min_def(local, new_ctx, link, false);
  842. ret = drv_assign_vif_chanctx(local, sdata, link->conf, new_ctx);
  843. if (assign_on_failure || !ret) {
  844. /* Need to continue, see _ieee80211_set_active_links */
  845. WARN_ON_ONCE(ret && !local->in_reconfig);
  846. ret = 0;
  847. /* succeeded, so commit it to the data structures */
  848. conf = &new_ctx->conf;
  849. }
  850. } else {
  851. ret = 0;
  852. }
  853. rcu_assign_pointer(link->conf->chanctx_conf, conf);
  854. if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
  855. ieee80211_recalc_chanctx_chantype(local, curr_ctx);
  856. ieee80211_recalc_smps_chanctx(local, curr_ctx);
  857. ieee80211_recalc_radar_chanctx(local, curr_ctx);
  858. ieee80211_recalc_chanctx_min_def(local, curr_ctx);
  859. }
  860. if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
  861. ieee80211_recalc_txpower(link, false);
  862. ieee80211_recalc_chanctx_min_def(local, new_ctx);
  863. }
  864. if (conf) {
  865. new_idle = false;
  866. } else {
  867. struct ieee80211_link_data *tmp;
  868. new_idle = true;
  869. for_each_sdata_link(local, tmp) {
  870. if (rcu_access_pointer(tmp->conf->chanctx_conf)) {
  871. new_idle = false;
  872. break;
  873. }
  874. }
  875. }
  876. if (new_idle != sdata->vif.cfg.idle) {
  877. sdata->vif.cfg.idle = new_idle;
  878. if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
  879. sdata->vif.type != NL80211_IFTYPE_MONITOR)
  880. ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_IDLE);
  881. }
  882. ieee80211_check_fast_xmit_iface(sdata);
  883. return ret;
  884. }
  885. void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
  886. struct ieee80211_chanctx *chanctx)
  887. {
  888. struct ieee80211_chanctx_user_iter iter;
  889. struct ieee80211_sub_if_data *sdata;
  890. u8 rx_chains_static, rx_chains_dynamic;
  891. lockdep_assert_wiphy(local->hw.wiphy);
  892. rx_chains_static = 1;
  893. rx_chains_dynamic = 1;
  894. for_each_chanctx_user_assigned(local, chanctx, &iter) {
  895. u8 needed_static, needed_dynamic;
  896. switch (iter.iftype) {
  897. case NL80211_IFTYPE_STATION:
  898. if (!iter.sdata->u.mgd.associated)
  899. continue;
  900. break;
  901. case NL80211_IFTYPE_MONITOR:
  902. if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
  903. continue;
  904. break;
  905. case NL80211_IFTYPE_AP:
  906. case NL80211_IFTYPE_ADHOC:
  907. case NL80211_IFTYPE_MESH_POINT:
  908. case NL80211_IFTYPE_OCB:
  909. break;
  910. default:
  911. continue;
  912. }
  913. if (iter.iftype == NL80211_IFTYPE_MONITOR) {
  914. rx_chains_dynamic = rx_chains_static = local->rx_chains;
  915. break;
  916. }
  917. switch (iter.link->smps_mode) {
  918. default:
  919. WARN_ONCE(1, "Invalid SMPS mode %d\n",
  920. iter.link->smps_mode);
  921. fallthrough;
  922. case IEEE80211_SMPS_OFF:
  923. needed_static = iter.link->needed_rx_chains;
  924. needed_dynamic = iter.link->needed_rx_chains;
  925. break;
  926. case IEEE80211_SMPS_DYNAMIC:
  927. needed_static = 1;
  928. needed_dynamic = iter.link->needed_rx_chains;
  929. break;
  930. case IEEE80211_SMPS_STATIC:
  931. needed_static = 1;
  932. needed_dynamic = 1;
  933. break;
  934. }
  935. rx_chains_static = max(rx_chains_static, needed_static);
  936. rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
  937. }
  938. /* Disable SMPS for the monitor interface */
  939. sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
  940. if (sdata &&
  941. rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &chanctx->conf)
  942. rx_chains_dynamic = rx_chains_static = local->rx_chains;
  943. if (rx_chains_static == chanctx->conf.rx_chains_static &&
  944. rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
  945. return;
  946. chanctx->conf.rx_chains_static = rx_chains_static;
  947. chanctx->conf.rx_chains_dynamic = rx_chains_dynamic;
  948. drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
  949. }
  950. static void
  951. __ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
  952. bool clear)
  953. {
  954. struct ieee80211_sub_if_data *sdata = link->sdata;
  955. unsigned int link_id = link->link_id;
  956. struct ieee80211_bss_conf *link_conf = link->conf;
  957. struct ieee80211_local *local __maybe_unused = sdata->local;
  958. struct ieee80211_sub_if_data *vlan;
  959. struct ieee80211_chanctx_conf *conf;
  960. if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
  961. return;
  962. lockdep_assert_wiphy(local->hw.wiphy);
  963. /* Check that conf exists, even when clearing this function
  964. * must be called with the AP's channel context still there
  965. * as it would otherwise cause VLANs to have an invalid
  966. * channel context pointer for a while, possibly pointing
  967. * to a channel context that has already been freed.
  968. */
  969. conf = rcu_dereference_protected(link_conf->chanctx_conf,
  970. lockdep_is_held(&local->hw.wiphy->mtx));
  971. WARN_ON(!conf);
  972. if (clear)
  973. conf = NULL;
  974. list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
  975. struct ieee80211_bss_conf *vlan_conf;
  976. vlan_conf = wiphy_dereference(local->hw.wiphy,
  977. vlan->vif.link_conf[link_id]);
  978. if (WARN_ON(!vlan_conf))
  979. continue;
  980. rcu_assign_pointer(vlan_conf->chanctx_conf, conf);
  981. }
  982. }
  983. void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
  984. bool clear)
  985. {
  986. struct ieee80211_local *local = link->sdata->local;
  987. lockdep_assert_wiphy(local->hw.wiphy);
  988. __ieee80211_link_copy_chanctx_to_vlans(link, clear);
  989. }
  990. void ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link)
  991. {
  992. struct ieee80211_sub_if_data *sdata = link->sdata;
  993. struct ieee80211_chanctx *ctx = link->reserved_chanctx;
  994. lockdep_assert_wiphy(sdata->local->hw.wiphy);
  995. if (WARN_ON(!ctx))
  996. return;
  997. link->reserved_chanctx = NULL;
  998. if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
  999. if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
  1000. if (WARN_ON(!ctx->replace_ctx))
  1001. return;
  1002. WARN_ON(ctx->replace_ctx->replace_state !=
  1003. IEEE80211_CHANCTX_WILL_BE_REPLACED);
  1004. WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
  1005. ctx->replace_ctx->replace_ctx = NULL;
  1006. ctx->replace_ctx->replace_state =
  1007. IEEE80211_CHANCTX_REPLACE_NONE;
  1008. list_del_rcu(&ctx->list);
  1009. kfree_rcu(ctx, rcu_head);
  1010. } else {
  1011. ieee80211_free_chanctx(sdata->local, ctx, false);
  1012. }
  1013. }
  1014. }
  1015. static struct ieee80211_chanctx *
  1016. ieee80211_replace_chanctx(struct ieee80211_local *local,
  1017. const struct ieee80211_chan_req *chanreq,
  1018. enum ieee80211_chanctx_mode mode,
  1019. struct ieee80211_chanctx *curr_ctx)
  1020. {
  1021. struct ieee80211_chanctx *new_ctx, *ctx;
  1022. struct wiphy *wiphy = local->hw.wiphy;
  1023. const struct wiphy_radio *radio;
  1024. if (!curr_ctx ||
  1025. curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED ||
  1026. ieee80211_chanctx_num_reserved(local, curr_ctx) != 0) {
  1027. /*
  1028. * Another link already requested this context for a
  1029. * reservation. Find another one hoping all links assigned
  1030. * to it will also switch soon enough.
  1031. *
  1032. * TODO: This needs a little more work as some cases
  1033. * (more than 2 chanctx capable devices) may fail which could
  1034. * otherwise succeed provided some channel context juggling was
  1035. * performed.
  1036. *
  1037. * Consider ctx1..3, link1..6, each ctx has 2 links. link1 and
  1038. * link2 from ctx1 request new different chandefs starting 2
  1039. * in-place reservations with ctx4 and ctx5 replacing ctx1 and
  1040. * ctx2 respectively. Next link5 and link6 from ctx3 reserve
  1041. * ctx4. If link3 and link4 remain on ctx2 as they are then this
  1042. * fails unless `replace_ctx` from ctx5 is replaced with ctx3.
  1043. */
  1044. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1045. if (ctx->replace_state !=
  1046. IEEE80211_CHANCTX_REPLACE_NONE)
  1047. continue;
  1048. if (ieee80211_chanctx_num_reserved(local, ctx) != 0)
  1049. continue;
  1050. if (ctx->conf.radio_idx >= 0) {
  1051. radio = &wiphy->radio[ctx->conf.radio_idx];
  1052. if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
  1053. continue;
  1054. }
  1055. curr_ctx = ctx;
  1056. break;
  1057. }
  1058. }
  1059. /*
  1060. * If that's true then all available contexts already have reservations
  1061. * and cannot be used.
  1062. */
  1063. if (!curr_ctx ||
  1064. curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED ||
  1065. ieee80211_chanctx_num_reserved(local, curr_ctx) != 0)
  1066. return ERR_PTR(-EBUSY);
  1067. new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1);
  1068. if (!new_ctx)
  1069. return ERR_PTR(-ENOMEM);
  1070. new_ctx->replace_ctx = curr_ctx;
  1071. new_ctx->replace_state = IEEE80211_CHANCTX_REPLACES_OTHER;
  1072. curr_ctx->replace_ctx = new_ctx;
  1073. curr_ctx->replace_state = IEEE80211_CHANCTX_WILL_BE_REPLACED;
  1074. list_add_rcu(&new_ctx->list, &local->chanctx_list);
  1075. return new_ctx;
  1076. }
  1077. static bool
  1078. ieee80211_find_available_radio(struct ieee80211_local *local,
  1079. const struct ieee80211_chan_req *chanreq,
  1080. u32 radio_mask, int *radio_idx)
  1081. {
  1082. struct wiphy *wiphy = local->hw.wiphy;
  1083. const struct wiphy_radio *radio;
  1084. int i;
  1085. *radio_idx = -1;
  1086. if (!wiphy->n_radio)
  1087. return true;
  1088. for (i = 0; i < wiphy->n_radio; i++) {
  1089. if (!(radio_mask & BIT(i)))
  1090. continue;
  1091. radio = &wiphy->radio[i];
  1092. if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
  1093. continue;
  1094. if (!ieee80211_can_create_new_chanctx(local, i))
  1095. continue;
  1096. *radio_idx = i;
  1097. return true;
  1098. }
  1099. return false;
  1100. }
  1101. int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
  1102. const struct ieee80211_chan_req *chanreq,
  1103. enum ieee80211_chanctx_mode mode,
  1104. bool radar_required)
  1105. {
  1106. struct ieee80211_sub_if_data *sdata = link->sdata;
  1107. struct ieee80211_local *local = sdata->local;
  1108. struct ieee80211_chanctx *new_ctx, *curr_ctx;
  1109. int radio_idx;
  1110. lockdep_assert_wiphy(local->hw.wiphy);
  1111. curr_ctx = ieee80211_link_get_chanctx(link);
  1112. if (curr_ctx && !local->ops->switch_vif_chanctx)
  1113. return -EOPNOTSUPP;
  1114. new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
  1115. if (!new_ctx) {
  1116. if (ieee80211_can_create_new_chanctx(local, -1) &&
  1117. ieee80211_find_available_radio(local, chanreq,
  1118. sdata->wdev.radio_mask,
  1119. &radio_idx))
  1120. new_ctx = ieee80211_new_chanctx(local, chanreq, mode,
  1121. false, radio_idx);
  1122. else
  1123. new_ctx = ieee80211_replace_chanctx(local, chanreq,
  1124. mode, curr_ctx);
  1125. if (IS_ERR(new_ctx))
  1126. return PTR_ERR(new_ctx);
  1127. }
  1128. link->reserved_chanctx = new_ctx;
  1129. link->reserved = *chanreq;
  1130. link->reserved_radar_required = radar_required;
  1131. link->reserved_ready = false;
  1132. return 0;
  1133. }
  1134. static void
  1135. ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link)
  1136. {
  1137. struct ieee80211_sub_if_data *sdata = link->sdata;
  1138. switch (sdata->vif.type) {
  1139. case NL80211_IFTYPE_ADHOC:
  1140. case NL80211_IFTYPE_AP:
  1141. case NL80211_IFTYPE_MESH_POINT:
  1142. case NL80211_IFTYPE_OCB:
  1143. wiphy_work_queue(sdata->local->hw.wiphy,
  1144. &link->csa.finalize_work);
  1145. break;
  1146. case NL80211_IFTYPE_STATION:
  1147. wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
  1148. &link->u.mgd.csa.switch_work, 0);
  1149. break;
  1150. case NL80211_IFTYPE_UNSPECIFIED:
  1151. case NL80211_IFTYPE_AP_VLAN:
  1152. case NL80211_IFTYPE_WDS:
  1153. case NL80211_IFTYPE_MONITOR:
  1154. case NL80211_IFTYPE_P2P_CLIENT:
  1155. case NL80211_IFTYPE_P2P_GO:
  1156. case NL80211_IFTYPE_P2P_DEVICE:
  1157. case NL80211_IFTYPE_NAN:
  1158. case NUM_NL80211_IFTYPES:
  1159. WARN_ON(1);
  1160. break;
  1161. }
  1162. }
  1163. static void
  1164. ieee80211_link_update_chanreq(struct ieee80211_link_data *link,
  1165. const struct ieee80211_chan_req *chanreq)
  1166. {
  1167. struct ieee80211_sub_if_data *sdata = link->sdata;
  1168. unsigned int link_id = link->link_id;
  1169. struct ieee80211_sub_if_data *vlan;
  1170. link->conf->chanreq = *chanreq;
  1171. if (sdata->vif.type != NL80211_IFTYPE_AP)
  1172. return;
  1173. list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
  1174. struct ieee80211_bss_conf *vlan_conf;
  1175. vlan_conf = wiphy_dereference(sdata->local->hw.wiphy,
  1176. vlan->vif.link_conf[link_id]);
  1177. if (WARN_ON(!vlan_conf))
  1178. continue;
  1179. vlan_conf->chanreq = *chanreq;
  1180. }
  1181. }
  1182. static int
  1183. ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
  1184. {
  1185. struct ieee80211_sub_if_data *sdata = link->sdata;
  1186. struct ieee80211_bss_conf *link_conf = link->conf;
  1187. struct ieee80211_local *local = sdata->local;
  1188. struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
  1189. struct ieee80211_chanctx *old_ctx, *new_ctx;
  1190. const struct ieee80211_chan_req *chanreq;
  1191. struct ieee80211_chan_req tmp;
  1192. u64 changed = 0;
  1193. int err;
  1194. lockdep_assert_wiphy(local->hw.wiphy);
  1195. new_ctx = link->reserved_chanctx;
  1196. old_ctx = ieee80211_link_get_chanctx(link);
  1197. if (WARN_ON(!link->reserved_ready))
  1198. return -EBUSY;
  1199. if (WARN_ON(!new_ctx))
  1200. return -EINVAL;
  1201. if (WARN_ON(!old_ctx))
  1202. return -EINVAL;
  1203. if (WARN_ON(new_ctx->replace_state ==
  1204. IEEE80211_CHANCTX_REPLACES_OTHER))
  1205. return -EINVAL;
  1206. chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
  1207. &link->reserved,
  1208. &tmp);
  1209. if (WARN_ON(!chanreq))
  1210. return -EINVAL;
  1211. if (link_conf->chanreq.oper.width != link->reserved.oper.width)
  1212. changed = BSS_CHANGED_BANDWIDTH;
  1213. ieee80211_link_update_chanreq(link, &link->reserved);
  1214. _ieee80211_change_chanctx(local, new_ctx, old_ctx, chanreq, link);
  1215. vif_chsw[0].vif = &sdata->vif;
  1216. vif_chsw[0].old_ctx = &old_ctx->conf;
  1217. vif_chsw[0].new_ctx = &new_ctx->conf;
  1218. vif_chsw[0].link_conf = link->conf;
  1219. link->reserved_chanctx = NULL;
  1220. err = drv_switch_vif_chanctx(local, vif_chsw, 1,
  1221. CHANCTX_SWMODE_REASSIGN_VIF);
  1222. if (err) {
  1223. if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
  1224. ieee80211_free_chanctx(local, new_ctx, false);
  1225. goto out;
  1226. }
  1227. link->radar_required = link->reserved_radar_required;
  1228. rcu_assign_pointer(link_conf->chanctx_conf, &new_ctx->conf);
  1229. if (sdata->vif.type == NL80211_IFTYPE_AP)
  1230. __ieee80211_link_copy_chanctx_to_vlans(link, false);
  1231. ieee80211_check_fast_xmit_iface(sdata);
  1232. if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
  1233. ieee80211_free_chanctx(local, old_ctx, false);
  1234. ieee80211_recalc_chanctx_min_def(local, new_ctx);
  1235. ieee80211_recalc_smps_chanctx(local, new_ctx);
  1236. ieee80211_recalc_radar_chanctx(local, new_ctx);
  1237. if (changed)
  1238. ieee80211_link_info_change_notify(sdata, link, changed);
  1239. out:
  1240. ieee80211_link_chanctx_reservation_complete(link);
  1241. return err;
  1242. }
  1243. static int
  1244. ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link)
  1245. {
  1246. struct ieee80211_sub_if_data *sdata = link->sdata;
  1247. struct ieee80211_local *local = sdata->local;
  1248. struct ieee80211_chanctx *old_ctx, *new_ctx;
  1249. const struct ieee80211_chan_req *chanreq;
  1250. struct ieee80211_chan_req tmp;
  1251. int err;
  1252. old_ctx = ieee80211_link_get_chanctx(link);
  1253. new_ctx = link->reserved_chanctx;
  1254. if (WARN_ON(!link->reserved_ready))
  1255. return -EINVAL;
  1256. if (WARN_ON(old_ctx))
  1257. return -EINVAL;
  1258. if (WARN_ON(!new_ctx))
  1259. return -EINVAL;
  1260. if (WARN_ON(new_ctx->replace_state ==
  1261. IEEE80211_CHANCTX_REPLACES_OTHER))
  1262. return -EINVAL;
  1263. chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
  1264. &link->reserved,
  1265. &tmp);
  1266. if (WARN_ON(!chanreq))
  1267. return -EINVAL;
  1268. ieee80211_change_chanctx(local, new_ctx, new_ctx, chanreq);
  1269. link->reserved_chanctx = NULL;
  1270. err = ieee80211_assign_link_chanctx(link, new_ctx, false);
  1271. if (err) {
  1272. if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
  1273. ieee80211_free_chanctx(local, new_ctx, false);
  1274. goto out;
  1275. }
  1276. out:
  1277. ieee80211_link_chanctx_reservation_complete(link);
  1278. return err;
  1279. }
  1280. static bool
  1281. ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)
  1282. {
  1283. struct ieee80211_sub_if_data *sdata = link->sdata;
  1284. struct ieee80211_chanctx *old_ctx, *new_ctx;
  1285. lockdep_assert_wiphy(sdata->local->hw.wiphy);
  1286. new_ctx = link->reserved_chanctx;
  1287. old_ctx = ieee80211_link_get_chanctx(link);
  1288. if (!old_ctx)
  1289. return false;
  1290. if (WARN_ON(!new_ctx))
  1291. return false;
  1292. if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
  1293. return false;
  1294. if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1295. return false;
  1296. return true;
  1297. }
  1298. static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
  1299. int n_vifs)
  1300. {
  1301. struct ieee80211_vif_chanctx_switch *vif_chsw;
  1302. struct ieee80211_chanctx *ctx, *old_ctx;
  1303. int i, err;
  1304. lockdep_assert_wiphy(local->hw.wiphy);
  1305. vif_chsw = kzalloc_objs(vif_chsw[0], n_vifs);
  1306. if (!vif_chsw)
  1307. return -ENOMEM;
  1308. i = 0;
  1309. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1310. struct ieee80211_chanctx_user_iter iter;
  1311. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1312. continue;
  1313. if (WARN_ON(!ctx->replace_ctx)) {
  1314. err = -EINVAL;
  1315. goto out;
  1316. }
  1317. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1318. if (!ieee80211_link_has_in_place_reservation(iter.link))
  1319. continue;
  1320. old_ctx = ieee80211_link_get_chanctx(iter.link);
  1321. vif_chsw[i].vif = &iter.sdata->vif;
  1322. vif_chsw[i].old_ctx = &old_ctx->conf;
  1323. vif_chsw[i].new_ctx = &ctx->conf;
  1324. vif_chsw[i].link_conf = iter.link->conf;
  1325. i++;
  1326. }
  1327. }
  1328. err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
  1329. CHANCTX_SWMODE_SWAP_CONTEXTS);
  1330. out:
  1331. kfree(vif_chsw);
  1332. return err;
  1333. }
  1334. static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
  1335. {
  1336. struct ieee80211_chanctx *ctx;
  1337. int err;
  1338. lockdep_assert_wiphy(local->hw.wiphy);
  1339. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1340. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1341. continue;
  1342. if (ieee80211_chanctx_num_assigned(local, ctx) != 0)
  1343. continue;
  1344. ieee80211_del_chanctx(local, ctx->replace_ctx, false);
  1345. err = ieee80211_add_chanctx(local, ctx);
  1346. if (err)
  1347. goto err;
  1348. }
  1349. return 0;
  1350. err:
  1351. WARN_ON(ieee80211_add_chanctx(local, ctx));
  1352. list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
  1353. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1354. continue;
  1355. if (ieee80211_chanctx_num_assigned(local, ctx) != 0)
  1356. continue;
  1357. ieee80211_del_chanctx(local, ctx, false);
  1358. WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
  1359. }
  1360. return err;
  1361. }
  1362. static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
  1363. {
  1364. struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
  1365. int err, n_assigned, n_reserved, n_ready;
  1366. int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
  1367. lockdep_assert_wiphy(local->hw.wiphy);
  1368. /*
  1369. * If there are 2 independent pairs of channel contexts performing
  1370. * cross-switch of their vifs this code will still wait until both are
  1371. * ready even though it could be possible to switch one before the
  1372. * other is ready.
  1373. *
  1374. * For practical reasons and code simplicity just do a single huge
  1375. * switch.
  1376. */
  1377. /*
  1378. * Verify if the reservation is still feasible.
  1379. * - if it's not then disconnect
  1380. * - if it is but not all vifs necessary are ready then defer
  1381. */
  1382. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1383. struct ieee80211_chanctx_user_iter iter;
  1384. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1385. continue;
  1386. if (WARN_ON(!ctx->replace_ctx)) {
  1387. err = -EINVAL;
  1388. goto err;
  1389. }
  1390. n_ctx++;
  1391. n_assigned = 0;
  1392. n_reserved = 0;
  1393. n_ready = 0;
  1394. for_each_chanctx_user_assigned(local, ctx->replace_ctx, &iter) {
  1395. n_assigned++;
  1396. if (iter.link->reserved_chanctx) {
  1397. n_reserved++;
  1398. if (iter.link->reserved_ready)
  1399. n_ready++;
  1400. }
  1401. }
  1402. if (n_assigned != n_reserved) {
  1403. if (n_ready == n_reserved) {
  1404. wiphy_info(local->hw.wiphy,
  1405. "channel context reservation cannot be finalized because some interfaces aren't switching\n");
  1406. err = -EBUSY;
  1407. goto err;
  1408. }
  1409. return -EAGAIN;
  1410. }
  1411. ctx->conf.radar_enabled = false;
  1412. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1413. if (ieee80211_link_has_in_place_reservation(iter.link) &&
  1414. !iter.link->reserved_ready)
  1415. return -EAGAIN;
  1416. old_ctx = ieee80211_link_get_chanctx(iter.link);
  1417. if (old_ctx) {
  1418. if (old_ctx->replace_state ==
  1419. IEEE80211_CHANCTX_WILL_BE_REPLACED)
  1420. n_vifs_switch++;
  1421. else
  1422. n_vifs_assign++;
  1423. } else {
  1424. n_vifs_ctxless++;
  1425. }
  1426. if (iter.radar_required)
  1427. ctx->conf.radar_enabled = true;
  1428. }
  1429. }
  1430. if (WARN_ON(n_ctx == 0) ||
  1431. WARN_ON(n_vifs_switch == 0 &&
  1432. n_vifs_assign == 0 &&
  1433. n_vifs_ctxless == 0)) {
  1434. err = -EINVAL;
  1435. goto err;
  1436. }
  1437. /* update station rate control and min width before switch */
  1438. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1439. struct ieee80211_chanctx_user_iter iter;
  1440. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1441. continue;
  1442. if (WARN_ON(!ctx->replace_ctx)) {
  1443. err = -EINVAL;
  1444. goto err;
  1445. }
  1446. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1447. if (!ieee80211_link_has_in_place_reservation(iter.link))
  1448. continue;
  1449. ieee80211_chan_bw_change(local,
  1450. ieee80211_link_get_chanctx(iter.link),
  1451. true, true);
  1452. }
  1453. _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, true);
  1454. }
  1455. /*
  1456. * All necessary vifs are ready. Perform the switch now depending on
  1457. * reservations and driver capabilities.
  1458. */
  1459. if (n_vifs_switch > 0) {
  1460. err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
  1461. if (err)
  1462. goto err;
  1463. }
  1464. if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
  1465. err = ieee80211_chsw_switch_ctxs(local);
  1466. if (err)
  1467. goto err;
  1468. }
  1469. /*
  1470. * Update all structures, values and pointers to point to new channel
  1471. * context(s).
  1472. */
  1473. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1474. struct ieee80211_chanctx_user_iter iter;
  1475. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1476. continue;
  1477. if (WARN_ON(!ctx->replace_ctx)) {
  1478. err = -EINVAL;
  1479. goto err;
  1480. }
  1481. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1482. struct ieee80211_link_data *link = iter.link;
  1483. struct ieee80211_sub_if_data *sdata = iter.sdata;
  1484. struct ieee80211_bss_conf *link_conf = link->conf;
  1485. u64 changed = 0;
  1486. if (!ieee80211_link_has_in_place_reservation(link))
  1487. continue;
  1488. rcu_assign_pointer(link_conf->chanctx_conf,
  1489. &ctx->conf);
  1490. if (sdata->vif.type == NL80211_IFTYPE_AP)
  1491. __ieee80211_link_copy_chanctx_to_vlans(link,
  1492. false);
  1493. ieee80211_check_fast_xmit_iface(sdata);
  1494. link->radar_required = iter.radar_required;
  1495. if (link_conf->chanreq.oper.width != iter.chanreq->oper.width)
  1496. changed = BSS_CHANGED_BANDWIDTH;
  1497. ieee80211_link_update_chanreq(link, &link->reserved);
  1498. if (changed)
  1499. ieee80211_link_info_change_notify(sdata,
  1500. link,
  1501. changed);
  1502. ieee80211_recalc_txpower(link, false);
  1503. }
  1504. ieee80211_recalc_chanctx_chantype(local, ctx);
  1505. ieee80211_recalc_smps_chanctx(local, ctx);
  1506. ieee80211_recalc_radar_chanctx(local, ctx);
  1507. ieee80211_recalc_chanctx_min_def(local, ctx);
  1508. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1509. if (ieee80211_link_get_chanctx(iter.link) != ctx)
  1510. continue;
  1511. iter.link->reserved_chanctx = NULL;
  1512. ieee80211_link_chanctx_reservation_complete(iter.link);
  1513. ieee80211_chan_bw_change(local, ctx, false, false);
  1514. }
  1515. /*
  1516. * This context might have been a dependency for an already
  1517. * ready re-assign reservation interface that was deferred. Do
  1518. * not propagate error to the caller though. The in-place
  1519. * reservation for originally requested interface has already
  1520. * succeeded at this point.
  1521. */
  1522. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1523. struct ieee80211_link_data *link = iter.link;
  1524. if (WARN_ON(ieee80211_link_has_in_place_reservation(link)))
  1525. continue;
  1526. if (!link->reserved_ready)
  1527. continue;
  1528. if (ieee80211_link_get_chanctx(link))
  1529. err = ieee80211_link_use_reserved_reassign(link);
  1530. else
  1531. err = ieee80211_link_use_reserved_assign(link);
  1532. if (err) {
  1533. link_info(link,
  1534. "failed to finalize (re-)assign reservation (err=%d)\n",
  1535. err);
  1536. ieee80211_link_unreserve_chanctx(link);
  1537. cfg80211_stop_iface(local->hw.wiphy,
  1538. &link->sdata->wdev,
  1539. GFP_KERNEL);
  1540. }
  1541. }
  1542. }
  1543. /*
  1544. * Finally free old contexts
  1545. */
  1546. list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
  1547. if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
  1548. continue;
  1549. ctx->replace_ctx->replace_ctx = NULL;
  1550. ctx->replace_ctx->replace_state =
  1551. IEEE80211_CHANCTX_REPLACE_NONE;
  1552. list_del_rcu(&ctx->list);
  1553. kfree_rcu(ctx, rcu_head);
  1554. }
  1555. return 0;
  1556. err:
  1557. list_for_each_entry(ctx, &local->chanctx_list, list) {
  1558. struct ieee80211_chanctx_user_iter iter;
  1559. if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
  1560. continue;
  1561. for_each_chanctx_user_reserved(local, ctx, &iter) {
  1562. ieee80211_link_unreserve_chanctx(iter.link);
  1563. ieee80211_link_chanctx_reservation_complete(iter.link);
  1564. }
  1565. }
  1566. return err;
  1567. }
  1568. void __ieee80211_link_release_channel(struct ieee80211_link_data *link,
  1569. bool skip_idle_recalc)
  1570. {
  1571. struct ieee80211_sub_if_data *sdata = link->sdata;
  1572. struct ieee80211_bss_conf *link_conf = link->conf;
  1573. struct ieee80211_local *local = sdata->local;
  1574. struct ieee80211_chanctx_conf *conf;
  1575. struct ieee80211_chanctx *ctx;
  1576. bool use_reserved_switch = false;
  1577. lockdep_assert_wiphy(local->hw.wiphy);
  1578. conf = rcu_dereference_protected(link_conf->chanctx_conf,
  1579. lockdep_is_held(&local->hw.wiphy->mtx));
  1580. if (!conf)
  1581. return;
  1582. ctx = container_of(conf, struct ieee80211_chanctx, conf);
  1583. if (link->reserved_chanctx) {
  1584. if (link->reserved_chanctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
  1585. ieee80211_chanctx_num_reserved(local, link->reserved_chanctx) > 1)
  1586. use_reserved_switch = true;
  1587. ieee80211_link_unreserve_chanctx(link);
  1588. }
  1589. ieee80211_assign_link_chanctx(link, NULL, false);
  1590. if (ieee80211_chanctx_refcount(local, ctx) == 0)
  1591. ieee80211_free_chanctx(local, ctx, skip_idle_recalc);
  1592. link->radar_required = false;
  1593. /* Unreserving may ready an in-place reservation. */
  1594. if (use_reserved_switch)
  1595. ieee80211_vif_use_reserved_switch(local);
  1596. }
  1597. int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
  1598. const struct ieee80211_chan_req *chanreq,
  1599. enum ieee80211_chanctx_mode mode,
  1600. bool assign_on_failure)
  1601. {
  1602. struct ieee80211_sub_if_data *sdata = link->sdata;
  1603. struct ieee80211_local *local = sdata->local;
  1604. struct ieee80211_chanctx *ctx;
  1605. u8 radar_detect_width = 0;
  1606. bool reserved = false;
  1607. int radio_idx;
  1608. int ret;
  1609. lockdep_assert_wiphy(local->hw.wiphy);
  1610. if (!ieee80211_vif_link_active(&sdata->vif, link->link_id)) {
  1611. ieee80211_link_update_chanreq(link, chanreq);
  1612. return 0;
  1613. }
  1614. ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
  1615. &chanreq->oper,
  1616. sdata->wdev.iftype);
  1617. if (ret < 0)
  1618. goto out;
  1619. if (ret > 0)
  1620. radar_detect_width = BIT(chanreq->oper.width);
  1621. link->radar_required = ret;
  1622. ret = ieee80211_check_combinations(sdata, &chanreq->oper, mode,
  1623. radar_detect_width, -1);
  1624. if (ret < 0)
  1625. goto out;
  1626. if (!local->in_reconfig)
  1627. __ieee80211_link_release_channel(link, false);
  1628. ctx = ieee80211_find_chanctx(local, link, chanreq, mode);
  1629. /* Note: context is now reserved */
  1630. if (ctx)
  1631. reserved = true;
  1632. else if (!ieee80211_find_available_radio(local, chanreq,
  1633. sdata->wdev.radio_mask,
  1634. &radio_idx))
  1635. ctx = ERR_PTR(-EBUSY);
  1636. else
  1637. ctx = ieee80211_new_chanctx(local, chanreq, mode,
  1638. assign_on_failure, radio_idx);
  1639. if (IS_ERR(ctx)) {
  1640. ret = PTR_ERR(ctx);
  1641. goto out;
  1642. }
  1643. ieee80211_link_update_chanreq(link, chanreq);
  1644. ret = ieee80211_assign_link_chanctx(link, ctx, assign_on_failure);
  1645. if (reserved) {
  1646. /* remove reservation */
  1647. WARN_ON(link->reserved_chanctx != ctx);
  1648. link->reserved_chanctx = NULL;
  1649. }
  1650. if (ret) {
  1651. /* if assign fails refcount stays the same */
  1652. if (ieee80211_chanctx_refcount(local, ctx) == 0)
  1653. ieee80211_free_chanctx(local, ctx, false);
  1654. goto out;
  1655. }
  1656. ieee80211_recalc_smps_chanctx(local, ctx);
  1657. ieee80211_recalc_radar_chanctx(local, ctx);
  1658. out:
  1659. if (ret)
  1660. link->radar_required = false;
  1661. return ret;
  1662. }
  1663. int ieee80211_link_use_reserved_context(struct ieee80211_link_data *link)
  1664. {
  1665. struct ieee80211_sub_if_data *sdata = link->sdata;
  1666. struct ieee80211_local *local = sdata->local;
  1667. struct ieee80211_chanctx *new_ctx;
  1668. struct ieee80211_chanctx *old_ctx;
  1669. int err;
  1670. lockdep_assert_wiphy(local->hw.wiphy);
  1671. new_ctx = link->reserved_chanctx;
  1672. old_ctx = ieee80211_link_get_chanctx(link);
  1673. if (WARN_ON(!new_ctx))
  1674. return -EINVAL;
  1675. if (WARN_ON(new_ctx->replace_state ==
  1676. IEEE80211_CHANCTX_WILL_BE_REPLACED))
  1677. return -EINVAL;
  1678. if (WARN_ON(link->reserved_ready))
  1679. return -EINVAL;
  1680. link->reserved_ready = true;
  1681. if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
  1682. if (old_ctx)
  1683. return ieee80211_link_use_reserved_reassign(link);
  1684. return ieee80211_link_use_reserved_assign(link);
  1685. }
  1686. /*
  1687. * In-place reservation may need to be finalized now either if:
  1688. * a) sdata is taking part in the swapping itself and is the last one
  1689. * b) sdata has switched with a re-assign reservation to an existing
  1690. * context readying in-place switching of old_ctx
  1691. *
  1692. * In case of (b) do not propagate the error up because the requested
  1693. * sdata already switched successfully. Just spill an extra warning.
  1694. * The ieee80211_vif_use_reserved_switch() already stops all necessary
  1695. * interfaces upon failure.
  1696. */
  1697. if ((old_ctx &&
  1698. old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
  1699. new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
  1700. err = ieee80211_vif_use_reserved_switch(local);
  1701. if (err && err != -EAGAIN) {
  1702. if (new_ctx->replace_state ==
  1703. IEEE80211_CHANCTX_REPLACES_OTHER)
  1704. return err;
  1705. wiphy_info(local->hw.wiphy,
  1706. "depending in-place reservation failed (err=%d)\n",
  1707. err);
  1708. }
  1709. }
  1710. return 0;
  1711. }
  1712. /*
  1713. * This is similar to ieee80211_chanctx_compatible(), but rechecks
  1714. * against all the links actually using it (except the one that's
  1715. * passed, since that one is changing).
  1716. * This is done in order to allow changes to the AP's bandwidth for
  1717. * wider bandwidth OFDMA purposes, which wouldn't be treated as
  1718. * compatible by ieee80211_chanctx_recheck() but is OK if the link
  1719. * requesting the update is the only one using it.
  1720. */
  1721. static const struct ieee80211_chan_req *
  1722. ieee80211_chanctx_recheck(struct ieee80211_local *local,
  1723. struct ieee80211_link_data *skip_link,
  1724. struct ieee80211_chanctx *ctx,
  1725. const struct ieee80211_chan_req *req,
  1726. struct ieee80211_chan_req *tmp)
  1727. {
  1728. const struct ieee80211_chan_req *ret = req;
  1729. struct ieee80211_chanctx_user_iter iter;
  1730. lockdep_assert_wiphy(local->hw.wiphy);
  1731. for_each_chanctx_user_all(local, ctx, &iter) {
  1732. if (iter.link == skip_link)
  1733. continue;
  1734. ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp);
  1735. if (!ret)
  1736. return NULL;
  1737. }
  1738. *tmp = *ret;
  1739. return tmp;
  1740. }
  1741. int ieee80211_link_change_chanreq(struct ieee80211_link_data *link,
  1742. const struct ieee80211_chan_req *chanreq,
  1743. u64 *changed)
  1744. {
  1745. struct ieee80211_sub_if_data *sdata = link->sdata;
  1746. struct ieee80211_bss_conf *link_conf = link->conf;
  1747. struct ieee80211_local *local = sdata->local;
  1748. struct ieee80211_chanctx_conf *conf;
  1749. struct ieee80211_chanctx *ctx;
  1750. const struct ieee80211_chan_req *compat;
  1751. struct ieee80211_chan_req tmp;
  1752. lockdep_assert_wiphy(local->hw.wiphy);
  1753. if (!cfg80211_chandef_usable(sdata->local->hw.wiphy,
  1754. &chanreq->oper,
  1755. IEEE80211_CHAN_DISABLED))
  1756. return -EINVAL;
  1757. /* for non-HT 20 MHz the rest doesn't matter */
  1758. if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT &&
  1759. cfg80211_chandef_identical(&chanreq->oper, &link_conf->chanreq.oper))
  1760. return 0;
  1761. /* but you cannot switch to/from it */
  1762. if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT ||
  1763. link_conf->chanreq.oper.width == NL80211_CHAN_WIDTH_20_NOHT)
  1764. return -EINVAL;
  1765. conf = rcu_dereference_protected(link_conf->chanctx_conf,
  1766. lockdep_is_held(&local->hw.wiphy->mtx));
  1767. if (!conf)
  1768. return -EINVAL;
  1769. ctx = container_of(conf, struct ieee80211_chanctx, conf);
  1770. compat = ieee80211_chanctx_recheck(local, link, ctx, chanreq, &tmp);
  1771. if (!compat)
  1772. return -EINVAL;
  1773. switch (ctx->replace_state) {
  1774. case IEEE80211_CHANCTX_REPLACE_NONE:
  1775. if (!ieee80211_chanctx_reserved_chanreq(local, ctx, compat,
  1776. &tmp))
  1777. return -EBUSY;
  1778. break;
  1779. case IEEE80211_CHANCTX_WILL_BE_REPLACED:
  1780. /* TODO: Perhaps the bandwidth change could be treated as a
  1781. * reservation itself? */
  1782. return -EBUSY;
  1783. case IEEE80211_CHANCTX_REPLACES_OTHER:
  1784. /* channel context that is going to replace another channel
  1785. * context doesn't really exist and shouldn't be assigned
  1786. * anywhere yet */
  1787. WARN_ON(1);
  1788. break;
  1789. }
  1790. ieee80211_link_update_chanreq(link, chanreq);
  1791. ieee80211_recalc_chanctx_chantype(local, ctx);
  1792. *changed |= BSS_CHANGED_BANDWIDTH;
  1793. return 0;
  1794. }
  1795. void ieee80211_link_release_channel(struct ieee80211_link_data *link)
  1796. {
  1797. struct ieee80211_sub_if_data *sdata = link->sdata;
  1798. if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  1799. return;
  1800. lockdep_assert_wiphy(sdata->local->hw.wiphy);
  1801. if (rcu_access_pointer(link->conf->chanctx_conf))
  1802. __ieee80211_link_release_channel(link, false);
  1803. }
  1804. void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link)
  1805. {
  1806. struct ieee80211_sub_if_data *sdata = link->sdata;
  1807. unsigned int link_id = link->link_id;
  1808. struct ieee80211_bss_conf *link_conf = link->conf;
  1809. struct ieee80211_bss_conf *ap_conf;
  1810. struct ieee80211_local *local = sdata->local;
  1811. struct ieee80211_sub_if_data *ap;
  1812. struct ieee80211_chanctx_conf *conf;
  1813. lockdep_assert_wiphy(local->hw.wiphy);
  1814. if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
  1815. return;
  1816. ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
  1817. ap_conf = wiphy_dereference(local->hw.wiphy,
  1818. ap->vif.link_conf[link_id]);
  1819. conf = wiphy_dereference(local->hw.wiphy,
  1820. ap_conf->chanctx_conf);
  1821. rcu_assign_pointer(link_conf->chanctx_conf, conf);
  1822. }
  1823. void ieee80211_iter_chan_contexts_atomic(
  1824. struct ieee80211_hw *hw,
  1825. void (*iter)(struct ieee80211_hw *hw,
  1826. struct ieee80211_chanctx_conf *chanctx_conf,
  1827. void *data),
  1828. void *iter_data)
  1829. {
  1830. struct ieee80211_local *local = hw_to_local(hw);
  1831. struct ieee80211_chanctx *ctx;
  1832. rcu_read_lock();
  1833. list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
  1834. if (ctx->driver_present)
  1835. iter(hw, &ctx->conf, iter_data);
  1836. rcu_read_unlock();
  1837. }
  1838. EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);
  1839. void ieee80211_iter_chan_contexts_mtx(
  1840. struct ieee80211_hw *hw,
  1841. void (*iter)(struct ieee80211_hw *hw,
  1842. struct ieee80211_chanctx_conf *chanctx_conf,
  1843. void *data),
  1844. void *iter_data)
  1845. {
  1846. struct ieee80211_local *local = hw_to_local(hw);
  1847. struct ieee80211_chanctx *ctx;
  1848. lockdep_assert_wiphy(hw->wiphy);
  1849. list_for_each_entry(ctx, &local->chanctx_list, list)
  1850. if (ctx->driver_present)
  1851. iter(hw, &ctx->conf, iter_data);
  1852. }
  1853. EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_mtx);