hw_features.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  1. /*
  2. * hostapd / Hardware feature query and different modes
  3. * Copyright 2002-2003, Instant802 Networks, Inc.
  4. * Copyright 2005-2006, Devicescape Software, Inc.
  5. * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
  6. *
  7. * This software may be distributed under the terms of the BSD license.
  8. * See README for more details.
  9. */
  10. #include "utils/includes.h"
  11. #include "utils/common.h"
  12. #include "utils/eloop.h"
  13. #include "common/ieee802_11_defs.h"
  14. #include "common/ieee802_11_common.h"
  15. #include "common/wpa_ctrl.h"
  16. #include "common/hw_features_common.h"
  17. #include "hostapd.h"
  18. #include "ap_config.h"
  19. #include "ap_drv_ops.h"
  20. #include "acs.h"
  21. #include "ieee802_11.h"
  22. #include "beacon.h"
  23. #include "hw_features.h"
  24. void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
  25. size_t num_hw_features)
  26. {
  27. size_t i;
  28. if (hw_features == NULL)
  29. return;
  30. for (i = 0; i < num_hw_features; i++) {
  31. os_free(hw_features[i].channels);
  32. os_free(hw_features[i].rates);
  33. }
  34. os_free(hw_features);
  35. }
  36. #ifndef CONFIG_NO_STDOUT_DEBUG
  37. static char * dfs_info(struct hostapd_channel_data *chan)
  38. {
  39. static char info[256];
  40. char *state;
  41. switch (chan->flag & HOSTAPD_CHAN_DFS_MASK) {
  42. case HOSTAPD_CHAN_DFS_UNKNOWN:
  43. state = "unknown";
  44. break;
  45. case HOSTAPD_CHAN_DFS_USABLE:
  46. state = "usable";
  47. break;
  48. case HOSTAPD_CHAN_DFS_UNAVAILABLE:
  49. state = "unavailable";
  50. break;
  51. case HOSTAPD_CHAN_DFS_AVAILABLE:
  52. state = "available";
  53. break;
  54. default:
  55. return "";
  56. }
  57. os_snprintf(info, sizeof(info), " (DFS state = %s)", state);
  58. info[sizeof(info) - 1] = '\0';
  59. return info;
  60. }
  61. #endif /* CONFIG_NO_STDOUT_DEBUG */
  62. int hostapd_get_hw_features(struct hostapd_iface *iface)
  63. {
  64. struct hostapd_data *hapd = iface->bss[0];
  65. int ret = 0, i, j;
  66. u16 num_modes, flags;
  67. struct hostapd_hw_modes *modes;
  68. if (hostapd_drv_none(hapd))
  69. return -1;
  70. modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);
  71. if (modes == NULL) {
  72. hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
  73. HOSTAPD_LEVEL_DEBUG,
  74. "Fetching hardware channel/rate support not "
  75. "supported.");
  76. return -1;
  77. }
  78. iface->hw_flags = flags;
  79. hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
  80. iface->hw_features = modes;
  81. iface->num_hw_features = num_modes;
  82. for (i = 0; i < num_modes; i++) {
  83. struct hostapd_hw_modes *feature = &modes[i];
  84. int dfs_enabled = hapd->iconf->ieee80211h &&
  85. (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR);
  86. /* set flag for channels we can use in current regulatory
  87. * domain */
  88. for (j = 0; j < feature->num_channels; j++) {
  89. int dfs = 0;
  90. /*
  91. * Disable all channels that are marked not to allow
  92. * to initiate radiation (a.k.a. passive scan and no
  93. * IBSS).
  94. * Use radar channels only if the driver supports DFS.
  95. */
  96. if ((feature->channels[j].flag &
  97. HOSTAPD_CHAN_RADAR) && dfs_enabled) {
  98. dfs = 1;
  99. } else if (((feature->channels[j].flag &
  100. HOSTAPD_CHAN_RADAR) &&
  101. !(iface->drv_flags &
  102. WPA_DRIVER_FLAGS_DFS_OFFLOAD)) ||
  103. (feature->channels[j].flag &
  104. HOSTAPD_CHAN_NO_IR)) {
  105. feature->channels[j].flag |=
  106. HOSTAPD_CHAN_DISABLED;
  107. }
  108. if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED)
  109. continue;
  110. wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d "
  111. "chan=%d freq=%d MHz max_tx_power=%d dBm%s",
  112. feature->mode,
  113. feature->channels[j].chan,
  114. feature->channels[j].freq,
  115. feature->channels[j].max_tx_power,
  116. dfs ? dfs_info(&feature->channels[j]) : "");
  117. }
  118. }
  119. return ret;
  120. }
  121. int hostapd_prepare_rates(struct hostapd_iface *iface,
  122. struct hostapd_hw_modes *mode)
  123. {
  124. int i, num_basic_rates = 0;
  125. int basic_rates_a[] = { 60, 120, 240, -1 };
  126. int basic_rates_b[] = { 10, 20, -1 };
  127. int basic_rates_g[] = { 10, 20, 55, 110, -1 };
  128. int *basic_rates;
  129. if (iface->conf->basic_rates)
  130. basic_rates = iface->conf->basic_rates;
  131. else switch (mode->mode) {
  132. case HOSTAPD_MODE_IEEE80211A:
  133. basic_rates = basic_rates_a;
  134. break;
  135. case HOSTAPD_MODE_IEEE80211B:
  136. basic_rates = basic_rates_b;
  137. break;
  138. case HOSTAPD_MODE_IEEE80211G:
  139. basic_rates = basic_rates_g;
  140. break;
  141. case HOSTAPD_MODE_IEEE80211AD:
  142. return 0; /* No basic rates for 11ad */
  143. default:
  144. return -1;
  145. }
  146. i = 0;
  147. while (basic_rates[i] >= 0)
  148. i++;
  149. if (i)
  150. i++; /* -1 termination */
  151. os_free(iface->basic_rates);
  152. iface->basic_rates = os_malloc(i * sizeof(int));
  153. if (iface->basic_rates)
  154. os_memcpy(iface->basic_rates, basic_rates, i * sizeof(int));
  155. os_free(iface->current_rates);
  156. iface->num_rates = 0;
  157. iface->current_rates =
  158. os_calloc(mode->num_rates, sizeof(struct hostapd_rate_data));
  159. if (!iface->current_rates) {
  160. wpa_printf(MSG_ERROR, "Failed to allocate memory for rate "
  161. "table.");
  162. return -1;
  163. }
  164. for (i = 0; i < mode->num_rates; i++) {
  165. struct hostapd_rate_data *rate;
  166. if (iface->conf->supported_rates &&
  167. !hostapd_rate_found(iface->conf->supported_rates,
  168. mode->rates[i]))
  169. continue;
  170. rate = &iface->current_rates[iface->num_rates];
  171. rate->rate = mode->rates[i];
  172. if (hostapd_rate_found(basic_rates, rate->rate)) {
  173. rate->flags |= HOSTAPD_RATE_BASIC;
  174. num_basic_rates++;
  175. }
  176. wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x",
  177. iface->num_rates, rate->rate, rate->flags);
  178. iface->num_rates++;
  179. }
  180. if ((iface->num_rates == 0 || num_basic_rates == 0) &&
  181. (!iface->conf->ieee80211n || !iface->conf->require_ht)) {
  182. wpa_printf(MSG_ERROR, "No rates remaining in supported/basic "
  183. "rate sets (%d,%d).",
  184. iface->num_rates, num_basic_rates);
  185. return -1;
  186. }
  187. return 0;
  188. }
  189. #ifdef CONFIG_IEEE80211N
  190. static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
  191. {
  192. int pri_chan, sec_chan;
  193. if (!iface->conf->secondary_channel)
  194. return 1; /* HT40 not used */
  195. pri_chan = iface->conf->channel;
  196. sec_chan = pri_chan + iface->conf->secondary_channel * 4;
  197. return allowed_ht40_channel_pair(iface->current_mode, pri_chan,
  198. sec_chan);
  199. }
  200. static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
  201. {
  202. if (iface->conf->secondary_channel > 0) {
  203. iface->conf->channel += 4;
  204. iface->conf->secondary_channel = -1;
  205. } else {
  206. iface->conf->channel -= 4;
  207. iface->conf->secondary_channel = 1;
  208. }
  209. }
  210. static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res *bss,
  211. int *pri_chan, int *sec_chan)
  212. {
  213. struct ieee80211_ht_operation *oper;
  214. struct ieee802_11_elems elems;
  215. *pri_chan = *sec_chan = 0;
  216. ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
  217. if (elems.ht_operation &&
  218. elems.ht_operation_len >= sizeof(*oper)) {
  219. oper = (struct ieee80211_ht_operation *) elems.ht_operation;
  220. *pri_chan = oper->primary_chan;
  221. if (oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) {
  222. int sec = oper->ht_param &
  223. HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
  224. if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
  225. *sec_chan = *pri_chan + 4;
  226. else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
  227. *sec_chan = *pri_chan - 4;
  228. }
  229. }
  230. }
  231. static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface,
  232. struct wpa_scan_results *scan_res)
  233. {
  234. int pri_chan, sec_chan, pri_freq, sec_freq, pri_bss, sec_bss;
  235. int bss_pri_chan, bss_sec_chan;
  236. size_t i;
  237. int match;
  238. pri_chan = iface->conf->channel;
  239. sec_chan = pri_chan + iface->conf->secondary_channel * 4;
  240. pri_freq = hostapd_hw_get_freq(iface->bss[0], pri_chan);
  241. if (iface->conf->secondary_channel > 0)
  242. sec_freq = pri_freq + 20;
  243. else
  244. sec_freq = pri_freq - 20;
  245. /*
  246. * Switch PRI/SEC channels if Beacons were detected on selected SEC
  247. * channel, but not on selected PRI channel.
  248. */
  249. pri_bss = sec_bss = 0;
  250. for (i = 0; i < scan_res->num; i++) {
  251. struct wpa_scan_res *bss = scan_res->res[i];
  252. if (bss->freq == pri_freq)
  253. pri_bss++;
  254. else if (bss->freq == sec_freq)
  255. sec_bss++;
  256. }
  257. if (sec_bss && !pri_bss) {
  258. wpa_printf(MSG_INFO, "Switch own primary and secondary "
  259. "channel to get secondary channel with no Beacons "
  260. "from other BSSes");
  261. ieee80211n_switch_pri_sec(iface);
  262. return 1;
  263. }
  264. /*
  265. * Match PRI/SEC channel with any existing HT40 BSS on the same
  266. * channels that we are about to use (if already mixed order in
  267. * existing BSSes, use own preference).
  268. */
  269. match = 0;
  270. for (i = 0; i < scan_res->num; i++) {
  271. struct wpa_scan_res *bss = scan_res->res[i];
  272. ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
  273. if (pri_chan == bss_pri_chan &&
  274. sec_chan == bss_sec_chan) {
  275. match = 1;
  276. break;
  277. }
  278. }
  279. if (!match) {
  280. for (i = 0; i < scan_res->num; i++) {
  281. struct wpa_scan_res *bss = scan_res->res[i];
  282. ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan,
  283. &bss_sec_chan);
  284. if (pri_chan == bss_sec_chan &&
  285. sec_chan == bss_pri_chan) {
  286. wpa_printf(MSG_INFO, "Switch own primary and "
  287. "secondary channel due to BSS "
  288. "overlap with " MACSTR,
  289. MAC2STR(bss->bssid));
  290. ieee80211n_switch_pri_sec(iface);
  291. break;
  292. }
  293. }
  294. }
  295. return 1;
  296. }
  297. static int ieee80211n_check_20mhz_bss(struct wpa_scan_res *bss, int pri_freq,
  298. int start, int end)
  299. {
  300. struct ieee802_11_elems elems;
  301. struct ieee80211_ht_operation *oper;
  302. if (bss->freq < start || bss->freq > end || bss->freq == pri_freq)
  303. return 0;
  304. ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
  305. if (!elems.ht_capabilities) {
  306. wpa_printf(MSG_DEBUG, "Found overlapping legacy BSS: "
  307. MACSTR " freq=%d", MAC2STR(bss->bssid), bss->freq);
  308. return 1;
  309. }
  310. if (elems.ht_operation &&
  311. elems.ht_operation_len >= sizeof(*oper)) {
  312. oper = (struct ieee80211_ht_operation *) elems.ht_operation;
  313. if (oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)
  314. return 0;
  315. wpa_printf(MSG_DEBUG, "Found overlapping 20 MHz HT BSS: "
  316. MACSTR " freq=%d", MAC2STR(bss->bssid), bss->freq);
  317. return 1;
  318. }
  319. return 0;
  320. }
  321. static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface,
  322. struct wpa_scan_results *scan_res)
  323. {
  324. int pri_freq, sec_freq;
  325. int affected_start, affected_end;
  326. size_t i;
  327. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  328. if (iface->conf->secondary_channel > 0)
  329. sec_freq = pri_freq + 20;
  330. else
  331. sec_freq = pri_freq - 20;
  332. affected_start = (pri_freq + sec_freq) / 2 - 25;
  333. affected_end = (pri_freq + sec_freq) / 2 + 25;
  334. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  335. affected_start, affected_end);
  336. for (i = 0; i < scan_res->num; i++) {
  337. struct wpa_scan_res *bss = scan_res->res[i];
  338. int pri = bss->freq;
  339. int sec = pri;
  340. int sec_chan, pri_chan;
  341. struct ieee802_11_elems elems;
  342. /* Check for overlapping 20 MHz BSS */
  343. if (ieee80211n_check_20mhz_bss(bss, pri_freq, affected_start,
  344. affected_end)) {
  345. wpa_printf(MSG_DEBUG,
  346. "Overlapping 20 MHz BSS is found");
  347. return 0;
  348. }
  349. ieee80211n_get_pri_sec_chan(bss, &pri_chan, &sec_chan);
  350. if (sec_chan) {
  351. if (sec_chan < pri_chan)
  352. sec = pri - 20;
  353. else
  354. sec = pri + 20;
  355. }
  356. if ((pri < affected_start || pri > affected_end) &&
  357. (sec < affected_start || sec > affected_end))
  358. continue; /* not within affected channel range */
  359. wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
  360. " freq=%d pri=%d sec=%d",
  361. MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
  362. if (sec_chan) {
  363. if (pri_freq != pri || sec_freq != sec) {
  364. wpa_printf(MSG_DEBUG, "40 MHz pri/sec "
  365. "mismatch with BSS " MACSTR
  366. " <%d,%d> (chan=%d%c) vs. <%d,%d>",
  367. MAC2STR(bss->bssid),
  368. pri, sec, pri_chan,
  369. sec > pri ? '+' : '-',
  370. pri_freq, sec_freq);
  371. return 0;
  372. }
  373. }
  374. ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems,
  375. 0);
  376. if (elems.ht_capabilities &&
  377. elems.ht_capabilities_len >=
  378. sizeof(struct ieee80211_ht_capabilities)) {
  379. struct ieee80211_ht_capabilities *ht_cap =
  380. (struct ieee80211_ht_capabilities *)
  381. elems.ht_capabilities;
  382. if (le_to_host16(ht_cap->ht_capabilities_info) &
  383. HT_CAP_INFO_40MHZ_INTOLERANT) {
  384. wpa_printf(MSG_DEBUG,
  385. "40 MHz Intolerant is set on channel %d in BSS "
  386. MACSTR, pri, MAC2STR(bss->bssid));
  387. return 0;
  388. }
  389. }
  390. }
  391. return 1;
  392. }
  393. static void ieee80211n_check_scan(struct hostapd_iface *iface)
  394. {
  395. struct wpa_scan_results *scan_res;
  396. int oper40;
  397. int res;
  398. /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
  399. * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
  400. iface->scan_cb = NULL;
  401. scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
  402. if (scan_res == NULL) {
  403. hostapd_setup_interface_complete(iface, 1);
  404. return;
  405. }
  406. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A)
  407. oper40 = ieee80211n_check_40mhz_5g(iface, scan_res);
  408. else
  409. oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res);
  410. wpa_scan_results_free(scan_res);
  411. iface->secondary_ch = iface->conf->secondary_channel;
  412. if (!oper40) {
  413. wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on "
  414. "channel pri=%d sec=%d based on overlapping BSSes",
  415. iface->conf->channel,
  416. iface->conf->channel +
  417. iface->conf->secondary_channel * 4);
  418. iface->conf->secondary_channel = 0;
  419. if (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX) {
  420. /*
  421. * TODO: Could consider scheduling another scan to check
  422. * if channel width can be changed if no coex reports
  423. * are received from associating stations.
  424. */
  425. }
  426. }
  427. res = ieee80211n_allowed_ht40_channel_pair(iface);
  428. if (!res) {
  429. iface->conf->secondary_channel = 0;
  430. wpa_printf(MSG_INFO, "Fallback to 20 MHz");
  431. }
  432. hostapd_setup_interface_complete(iface, !res);
  433. }
  434. static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
  435. struct wpa_driver_scan_params *params)
  436. {
  437. /* Scan only the affected frequency range */
  438. int pri_freq, sec_freq;
  439. int affected_start, affected_end;
  440. int i, pos;
  441. struct hostapd_hw_modes *mode;
  442. if (iface->current_mode == NULL)
  443. return;
  444. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  445. if (iface->conf->secondary_channel > 0)
  446. sec_freq = pri_freq + 20;
  447. else
  448. sec_freq = pri_freq - 20;
  449. affected_start = (pri_freq + sec_freq) / 2 - 25;
  450. affected_end = (pri_freq + sec_freq) / 2 + 25;
  451. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  452. affected_start, affected_end);
  453. mode = iface->current_mode;
  454. params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
  455. if (params->freqs == NULL)
  456. return;
  457. pos = 0;
  458. for (i = 0; i < mode->num_channels; i++) {
  459. struct hostapd_channel_data *chan = &mode->channels[i];
  460. if (chan->flag & HOSTAPD_CHAN_DISABLED)
  461. continue;
  462. if (chan->freq < affected_start ||
  463. chan->freq > affected_end)
  464. continue;
  465. params->freqs[pos++] = chan->freq;
  466. }
  467. }
  468. static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
  469. struct wpa_driver_scan_params *params)
  470. {
  471. /* Scan only the affected frequency range */
  472. int pri_freq;
  473. int affected_start, affected_end;
  474. int i, pos;
  475. struct hostapd_hw_modes *mode;
  476. if (iface->current_mode == NULL)
  477. return;
  478. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  479. if (iface->conf->secondary_channel > 0) {
  480. affected_start = pri_freq - 10;
  481. affected_end = pri_freq + 30;
  482. } else {
  483. affected_start = pri_freq - 30;
  484. affected_end = pri_freq + 10;
  485. }
  486. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  487. affected_start, affected_end);
  488. mode = iface->current_mode;
  489. params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
  490. if (params->freqs == NULL)
  491. return;
  492. pos = 0;
  493. for (i = 0; i < mode->num_channels; i++) {
  494. struct hostapd_channel_data *chan = &mode->channels[i];
  495. if (chan->flag & HOSTAPD_CHAN_DISABLED)
  496. continue;
  497. if (chan->freq < affected_start ||
  498. chan->freq > affected_end)
  499. continue;
  500. params->freqs[pos++] = chan->freq;
  501. }
  502. }
  503. static void ap_ht40_scan_retry(void *eloop_data, void *user_data)
  504. {
  505. #define HT2040_COEX_SCAN_RETRY 15
  506. struct hostapd_iface *iface = eloop_data;
  507. struct wpa_driver_scan_params params;
  508. int ret;
  509. os_memset(&params, 0, sizeof(params));
  510. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
  511. ieee80211n_scan_channels_2g4(iface, &params);
  512. else
  513. ieee80211n_scan_channels_5g(iface, &params);
  514. ret = hostapd_driver_scan(iface->bss[0], &params);
  515. iface->num_ht40_scan_tries++;
  516. os_free(params.freqs);
  517. if (ret == -EBUSY &&
  518. iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) {
  519. wpa_printf(MSG_ERROR,
  520. "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
  521. ret, strerror(-ret), iface->num_ht40_scan_tries);
  522. eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
  523. return;
  524. }
  525. if (ret == 0) {
  526. iface->scan_cb = ieee80211n_check_scan;
  527. return;
  528. }
  529. wpa_printf(MSG_DEBUG,
  530. "Failed to request a scan in device, bringing up in HT20 mode");
  531. iface->conf->secondary_channel = 0;
  532. iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
  533. hostapd_setup_interface_complete(iface, 0);
  534. }
  535. void hostapd_stop_setup_timers(struct hostapd_iface *iface)
  536. {
  537. eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
  538. }
  539. static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
  540. {
  541. struct wpa_driver_scan_params params;
  542. int ret;
  543. if (!iface->conf->secondary_channel)
  544. return 0; /* HT40 not used */
  545. hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
  546. wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
  547. "40 MHz channel");
  548. os_memset(&params, 0, sizeof(params));
  549. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
  550. ieee80211n_scan_channels_2g4(iface, &params);
  551. else
  552. ieee80211n_scan_channels_5g(iface, &params);
  553. ret = hostapd_driver_scan(iface->bss[0], &params);
  554. os_free(params.freqs);
  555. if (ret == -EBUSY) {
  556. wpa_printf(MSG_ERROR,
  557. "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again",
  558. ret, strerror(-ret));
  559. iface->num_ht40_scan_tries = 1;
  560. eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
  561. eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
  562. return 1;
  563. }
  564. if (ret < 0) {
  565. wpa_printf(MSG_ERROR,
  566. "Failed to request a scan of neighboring BSSes ret=%d (%s)",
  567. ret, strerror(-ret));
  568. return -1;
  569. }
  570. iface->scan_cb = ieee80211n_check_scan;
  571. return 1;
  572. }
  573. static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
  574. {
  575. u16 hw = iface->current_mode->ht_capab;
  576. u16 conf = iface->conf->ht_capab;
  577. if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
  578. !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
  579. wpa_printf(MSG_ERROR, "Driver does not support configured "
  580. "HT capability [LDPC]");
  581. return 0;
  582. }
  583. if ((conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
  584. !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
  585. wpa_printf(MSG_ERROR, "Driver does not support configured "
  586. "HT capability [HT40*]");
  587. return 0;
  588. }
  589. switch (conf & HT_CAP_INFO_SMPS_MASK) {
  590. case HT_CAP_INFO_SMPS_STATIC:
  591. if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_STATIC)) {
  592. wpa_printf(MSG_ERROR,
  593. "Driver does not support configured HT capability [SMPS-STATIC]");
  594. return 0;
  595. }
  596. break;
  597. case HT_CAP_INFO_SMPS_DYNAMIC:
  598. if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_DYNAMIC)) {
  599. wpa_printf(MSG_ERROR,
  600. "Driver does not support configured HT capability [SMPS-DYNAMIC]");
  601. return 0;
  602. }
  603. break;
  604. case HT_CAP_INFO_SMPS_DISABLED:
  605. default:
  606. break;
  607. }
  608. if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
  609. !(hw & HT_CAP_INFO_GREEN_FIELD)) {
  610. wpa_printf(MSG_ERROR, "Driver does not support configured "
  611. "HT capability [GF]");
  612. return 0;
  613. }
  614. if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
  615. !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
  616. wpa_printf(MSG_ERROR, "Driver does not support configured "
  617. "HT capability [SHORT-GI-20]");
  618. return 0;
  619. }
  620. if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
  621. !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
  622. wpa_printf(MSG_ERROR, "Driver does not support configured "
  623. "HT capability [SHORT-GI-40]");
  624. return 0;
  625. }
  626. if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
  627. wpa_printf(MSG_ERROR, "Driver does not support configured "
  628. "HT capability [TX-STBC]");
  629. return 0;
  630. }
  631. if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
  632. (hw & HT_CAP_INFO_RX_STBC_MASK)) {
  633. wpa_printf(MSG_ERROR, "Driver does not support configured "
  634. "HT capability [RX-STBC*]");
  635. return 0;
  636. }
  637. if ((conf & HT_CAP_INFO_DELAYED_BA) &&
  638. !(hw & HT_CAP_INFO_DELAYED_BA)) {
  639. wpa_printf(MSG_ERROR, "Driver does not support configured "
  640. "HT capability [DELAYED-BA]");
  641. return 0;
  642. }
  643. if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
  644. !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
  645. wpa_printf(MSG_ERROR, "Driver does not support configured "
  646. "HT capability [MAX-AMSDU-7935]");
  647. return 0;
  648. }
  649. if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
  650. !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
  651. wpa_printf(MSG_ERROR, "Driver does not support configured "
  652. "HT capability [DSSS_CCK-40]");
  653. return 0;
  654. }
  655. if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
  656. !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
  657. wpa_printf(MSG_ERROR, "Driver does not support configured "
  658. "HT capability [LSIG-TXOP-PROT]");
  659. return 0;
  660. }
  661. return 1;
  662. }
  663. #ifdef CONFIG_IEEE80211AC
  664. static int ieee80211ac_cap_check(u32 hw, u32 conf, u32 cap, const char *name)
  665. {
  666. u32 req_cap = conf & cap;
  667. /*
  668. * Make sure we support all requested capabilities.
  669. * NOTE: We assume that 'cap' represents a capability mask,
  670. * not a discrete value.
  671. */
  672. if ((hw & req_cap) != req_cap) {
  673. wpa_printf(MSG_ERROR, "Driver does not support configured VHT capability [%s]",
  674. name);
  675. return 0;
  676. }
  677. return 1;
  678. }
  679. static int ieee80211ac_cap_check_max(u32 hw, u32 conf, u32 mask,
  680. unsigned int shift,
  681. const char *name)
  682. {
  683. u32 hw_max = hw & mask;
  684. u32 conf_val = conf & mask;
  685. if (conf_val > hw_max) {
  686. wpa_printf(MSG_ERROR, "Configured VHT capability [%s] exceeds max value supported by the driver (%d > %d)",
  687. name, conf_val >> shift, hw_max >> shift);
  688. return 0;
  689. }
  690. return 1;
  691. }
  692. static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
  693. {
  694. u32 hw = iface->current_mode->vht_capab;
  695. u32 conf = iface->conf->vht_capab;
  696. wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x",
  697. hw, conf);
  698. #define VHT_CAP_CHECK(cap) \
  699. do { \
  700. if (!ieee80211ac_cap_check(hw, conf, cap, #cap)) \
  701. return 0; \
  702. } while (0)
  703. #define VHT_CAP_CHECK_MAX(cap) \
  704. do { \
  705. if (!ieee80211ac_cap_check_max(hw, conf, cap, cap ## _SHIFT, \
  706. #cap)) \
  707. return 0; \
  708. } while (0)
  709. VHT_CAP_CHECK_MAX(VHT_CAP_MAX_MPDU_LENGTH_MASK);
  710. VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ);
  711. VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ);
  712. VHT_CAP_CHECK(VHT_CAP_RXLDPC);
  713. VHT_CAP_CHECK(VHT_CAP_SHORT_GI_80);
  714. VHT_CAP_CHECK(VHT_CAP_SHORT_GI_160);
  715. VHT_CAP_CHECK(VHT_CAP_TXSTBC);
  716. VHT_CAP_CHECK_MAX(VHT_CAP_RXSTBC_MASK);
  717. VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMER_CAPABLE);
  718. VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMEE_CAPABLE);
  719. VHT_CAP_CHECK_MAX(VHT_CAP_BEAMFORMEE_STS_MAX);
  720. VHT_CAP_CHECK_MAX(VHT_CAP_SOUNDING_DIMENSION_MAX);
  721. VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMER_CAPABLE);
  722. VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMEE_CAPABLE);
  723. VHT_CAP_CHECK(VHT_CAP_VHT_TXOP_PS);
  724. VHT_CAP_CHECK(VHT_CAP_HTC_VHT);
  725. VHT_CAP_CHECK_MAX(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX);
  726. VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB);
  727. VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB);
  728. VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN);
  729. VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN);
  730. #undef VHT_CAP_CHECK
  731. #undef VHT_CAP_CHECK_MAX
  732. return 1;
  733. }
  734. #endif /* CONFIG_IEEE80211AC */
  735. #endif /* CONFIG_IEEE80211N */
  736. int hostapd_check_ht_capab(struct hostapd_iface *iface)
  737. {
  738. #ifdef CONFIG_IEEE80211N
  739. int ret;
  740. if (!iface->conf->ieee80211n)
  741. return 0;
  742. if (!ieee80211n_supported_ht_capab(iface))
  743. return -1;
  744. #ifdef CONFIG_IEEE80211AC
  745. if (!ieee80211ac_supported_vht_capab(iface))
  746. return -1;
  747. #endif /* CONFIG_IEEE80211AC */
  748. ret = ieee80211n_check_40mhz(iface);
  749. if (ret)
  750. return ret;
  751. if (!ieee80211n_allowed_ht40_channel_pair(iface))
  752. return -1;
  753. #endif /* CONFIG_IEEE80211N */
  754. return 0;
  755. }
  756. static int hostapd_is_usable_chan(struct hostapd_iface *iface,
  757. int channel, int primary)
  758. {
  759. int i;
  760. struct hostapd_channel_data *chan;
  761. for (i = 0; i < iface->current_mode->num_channels; i++) {
  762. chan = &iface->current_mode->channels[i];
  763. if (chan->chan != channel)
  764. continue;
  765. if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
  766. return 1;
  767. wpa_printf(MSG_DEBUG,
  768. "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s",
  769. primary ? "" : "Configured HT40 secondary ",
  770. i, chan->chan, chan->flag,
  771. chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "",
  772. chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
  773. }
  774. return 0;
  775. }
  776. static int hostapd_is_usable_chans(struct hostapd_iface *iface)
  777. {
  778. if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
  779. return 0;
  780. if (!iface->conf->secondary_channel)
  781. return 1;
  782. return hostapd_is_usable_chan(iface, iface->conf->channel +
  783. iface->conf->secondary_channel * 4, 0);
  784. }
  785. static enum hostapd_chan_status
  786. hostapd_check_chans(struct hostapd_iface *iface)
  787. {
  788. if (iface->conf->channel) {
  789. if (hostapd_is_usable_chans(iface))
  790. return HOSTAPD_CHAN_VALID;
  791. else
  792. return HOSTAPD_CHAN_INVALID;
  793. }
  794. /*
  795. * The user set channel=0 or channel=acs_survey
  796. * which is used to trigger ACS.
  797. */
  798. switch (acs_init(iface)) {
  799. case HOSTAPD_CHAN_ACS:
  800. return HOSTAPD_CHAN_ACS;
  801. case HOSTAPD_CHAN_VALID:
  802. case HOSTAPD_CHAN_INVALID:
  803. default:
  804. return HOSTAPD_CHAN_INVALID;
  805. }
  806. }
  807. static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
  808. {
  809. hostapd_logger(iface->bss[0], NULL,
  810. HOSTAPD_MODULE_IEEE80211,
  811. HOSTAPD_LEVEL_WARNING,
  812. "Configured channel (%d) not found from the "
  813. "channel list of current mode (%d) %s",
  814. iface->conf->channel,
  815. iface->current_mode->mode,
  816. hostapd_hw_mode_txt(iface->current_mode->mode));
  817. hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
  818. HOSTAPD_LEVEL_WARNING,
  819. "Hardware does not support configured channel");
  820. }
  821. int hostapd_acs_completed(struct hostapd_iface *iface, int err)
  822. {
  823. int ret = -1;
  824. if (err)
  825. goto out;
  826. switch (hostapd_check_chans(iface)) {
  827. case HOSTAPD_CHAN_VALID:
  828. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
  829. ACS_EVENT_COMPLETED "freq=%d channel=%d",
  830. hostapd_hw_get_freq(iface->bss[0],
  831. iface->conf->channel),
  832. iface->conf->channel);
  833. break;
  834. case HOSTAPD_CHAN_ACS:
  835. wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
  836. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
  837. hostapd_notify_bad_chans(iface);
  838. goto out;
  839. case HOSTAPD_CHAN_INVALID:
  840. default:
  841. wpa_printf(MSG_ERROR, "ACS picked unusable channels");
  842. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
  843. hostapd_notify_bad_chans(iface);
  844. goto out;
  845. }
  846. ret = hostapd_check_ht_capab(iface);
  847. if (ret < 0)
  848. goto out;
  849. if (ret == 1) {
  850. wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback");
  851. return 0;
  852. }
  853. ret = 0;
  854. out:
  855. return hostapd_setup_interface_complete(iface, ret);
  856. }
  857. /**
  858. * hostapd_select_hw_mode - Select the hardware mode
  859. * @iface: Pointer to interface data.
  860. * Returns: 0 on success, < 0 on failure
  861. *
  862. * Sets up the hardware mode, channel, rates, and passive scanning
  863. * based on the configuration.
  864. */
  865. int hostapd_select_hw_mode(struct hostapd_iface *iface)
  866. {
  867. int i;
  868. if (iface->num_hw_features < 1)
  869. return -1;
  870. if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G ||
  871. iface->conf->ieee80211n || iface->conf->ieee80211ac) &&
  872. iface->conf->channel == 14) {
  873. wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT on channel 14");
  874. iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
  875. iface->conf->ieee80211n = 0;
  876. iface->conf->ieee80211ac = 0;
  877. }
  878. iface->current_mode = NULL;
  879. for (i = 0; i < iface->num_hw_features; i++) {
  880. struct hostapd_hw_modes *mode = &iface->hw_features[i];
  881. if (mode->mode == iface->conf->hw_mode) {
  882. iface->current_mode = mode;
  883. break;
  884. }
  885. }
  886. if (iface->current_mode == NULL) {
  887. wpa_printf(MSG_ERROR, "Hardware does not support configured "
  888. "mode");
  889. hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
  890. HOSTAPD_LEVEL_WARNING,
  891. "Hardware does not support configured mode "
  892. "(%d) (hw_mode in hostapd.conf)",
  893. (int) iface->conf->hw_mode);
  894. return -2;
  895. }
  896. switch (hostapd_check_chans(iface)) {
  897. case HOSTAPD_CHAN_VALID:
  898. return 0;
  899. case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */
  900. return 1;
  901. case HOSTAPD_CHAN_INVALID:
  902. default:
  903. hostapd_notify_bad_chans(iface);
  904. return -3;
  905. }
  906. }
  907. const char * hostapd_hw_mode_txt(int mode)
  908. {
  909. switch (mode) {
  910. case HOSTAPD_MODE_IEEE80211A:
  911. return "IEEE 802.11a";
  912. case HOSTAPD_MODE_IEEE80211B:
  913. return "IEEE 802.11b";
  914. case HOSTAPD_MODE_IEEE80211G:
  915. return "IEEE 802.11g";
  916. case HOSTAPD_MODE_IEEE80211AD:
  917. return "IEEE 802.11ad";
  918. default:
  919. return "UNKNOWN";
  920. }
  921. }
  922. int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
  923. {
  924. return hw_get_freq(hapd->iface->current_mode, chan);
  925. }
  926. int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
  927. {
  928. return hw_get_chan(hapd->iface->current_mode, freq);
  929. }