hw_features.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  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 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 0;
  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 int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface,
  211. struct wpa_scan_results *scan_res)
  212. {
  213. int pri_chan, sec_chan;
  214. int res;
  215. pri_chan = iface->conf->channel;
  216. sec_chan = pri_chan + iface->conf->secondary_channel * 4;
  217. res = check_40mhz_5g(iface->current_mode, scan_res, pri_chan, sec_chan);
  218. if (res == 2) {
  219. if (iface->conf->no_pri_sec_switch) {
  220. wpa_printf(MSG_DEBUG,
  221. "Cannot switch PRI/SEC channels due to local constraint");
  222. } else {
  223. ieee80211n_switch_pri_sec(iface);
  224. }
  225. }
  226. return !!res;
  227. }
  228. static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface,
  229. struct wpa_scan_results *scan_res)
  230. {
  231. int pri_chan, sec_chan;
  232. pri_chan = iface->conf->channel;
  233. sec_chan = pri_chan + iface->conf->secondary_channel * 4;
  234. return check_40mhz_2g4(iface->current_mode, scan_res, pri_chan,
  235. sec_chan);
  236. }
  237. static void ieee80211n_check_scan(struct hostapd_iface *iface)
  238. {
  239. struct wpa_scan_results *scan_res;
  240. int oper40;
  241. int res;
  242. /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
  243. * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
  244. iface->scan_cb = NULL;
  245. scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
  246. if (scan_res == NULL) {
  247. hostapd_setup_interface_complete(iface, 1);
  248. return;
  249. }
  250. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A)
  251. oper40 = ieee80211n_check_40mhz_5g(iface, scan_res);
  252. else
  253. oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res);
  254. wpa_scan_results_free(scan_res);
  255. iface->secondary_ch = iface->conf->secondary_channel;
  256. if (!oper40) {
  257. wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on "
  258. "channel pri=%d sec=%d based on overlapping BSSes",
  259. iface->conf->channel,
  260. iface->conf->channel +
  261. iface->conf->secondary_channel * 4);
  262. iface->conf->secondary_channel = 0;
  263. if (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX) {
  264. /*
  265. * TODO: Could consider scheduling another scan to check
  266. * if channel width can be changed if no coex reports
  267. * are received from associating stations.
  268. */
  269. }
  270. }
  271. res = ieee80211n_allowed_ht40_channel_pair(iface);
  272. if (!res) {
  273. iface->conf->secondary_channel = 0;
  274. iface->conf->vht_oper_centr_freq_seg0_idx = 0;
  275. iface->conf->vht_oper_centr_freq_seg1_idx = 0;
  276. res = 1;
  277. wpa_printf(MSG_INFO, "Fallback to 20 MHz");
  278. }
  279. hostapd_setup_interface_complete(iface, !res);
  280. }
  281. static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
  282. struct wpa_driver_scan_params *params)
  283. {
  284. /* Scan only the affected frequency range */
  285. int pri_freq, sec_freq;
  286. int affected_start, affected_end;
  287. int i, pos;
  288. struct hostapd_hw_modes *mode;
  289. if (iface->current_mode == NULL)
  290. return;
  291. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  292. if (iface->conf->secondary_channel > 0)
  293. sec_freq = pri_freq + 20;
  294. else
  295. sec_freq = pri_freq - 20;
  296. /*
  297. * Note: Need to find the PRI channel also in cases where the affected
  298. * channel is the SEC channel of a 40 MHz BSS, so need to include the
  299. * scanning coverage here to be 40 MHz from the center frequency.
  300. */
  301. affected_start = (pri_freq + sec_freq) / 2 - 40;
  302. affected_end = (pri_freq + sec_freq) / 2 + 40;
  303. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  304. affected_start, affected_end);
  305. mode = iface->current_mode;
  306. params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
  307. if (params->freqs == NULL)
  308. return;
  309. pos = 0;
  310. for (i = 0; i < mode->num_channels; i++) {
  311. struct hostapd_channel_data *chan = &mode->channels[i];
  312. if (chan->flag & HOSTAPD_CHAN_DISABLED)
  313. continue;
  314. if (chan->freq < affected_start ||
  315. chan->freq > affected_end)
  316. continue;
  317. params->freqs[pos++] = chan->freq;
  318. }
  319. }
  320. static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
  321. struct wpa_driver_scan_params *params)
  322. {
  323. /* Scan only the affected frequency range */
  324. int pri_freq;
  325. int affected_start, affected_end;
  326. int i, pos;
  327. struct hostapd_hw_modes *mode;
  328. if (iface->current_mode == NULL)
  329. return;
  330. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  331. if (iface->conf->secondary_channel > 0) {
  332. affected_start = pri_freq - 10;
  333. affected_end = pri_freq + 30;
  334. } else {
  335. affected_start = pri_freq - 30;
  336. affected_end = pri_freq + 10;
  337. }
  338. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  339. affected_start, affected_end);
  340. mode = iface->current_mode;
  341. params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
  342. if (params->freqs == NULL)
  343. return;
  344. pos = 0;
  345. for (i = 0; i < mode->num_channels; i++) {
  346. struct hostapd_channel_data *chan = &mode->channels[i];
  347. if (chan->flag & HOSTAPD_CHAN_DISABLED)
  348. continue;
  349. if (chan->freq < affected_start ||
  350. chan->freq > affected_end)
  351. continue;
  352. params->freqs[pos++] = chan->freq;
  353. }
  354. }
  355. static void ap_ht40_scan_retry(void *eloop_data, void *user_data)
  356. {
  357. #define HT2040_COEX_SCAN_RETRY 15
  358. struct hostapd_iface *iface = eloop_data;
  359. struct wpa_driver_scan_params params;
  360. int ret;
  361. os_memset(&params, 0, sizeof(params));
  362. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
  363. ieee80211n_scan_channels_2g4(iface, &params);
  364. else
  365. ieee80211n_scan_channels_5g(iface, &params);
  366. ret = hostapd_driver_scan(iface->bss[0], &params);
  367. iface->num_ht40_scan_tries++;
  368. os_free(params.freqs);
  369. if (ret == -EBUSY &&
  370. iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) {
  371. wpa_printf(MSG_ERROR,
  372. "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
  373. ret, strerror(-ret), iface->num_ht40_scan_tries);
  374. eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
  375. return;
  376. }
  377. if (ret == 0) {
  378. iface->scan_cb = ieee80211n_check_scan;
  379. return;
  380. }
  381. wpa_printf(MSG_DEBUG,
  382. "Failed to request a scan in device, bringing up in HT20 mode");
  383. iface->conf->secondary_channel = 0;
  384. iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
  385. hostapd_setup_interface_complete(iface, 0);
  386. }
  387. void hostapd_stop_setup_timers(struct hostapd_iface *iface)
  388. {
  389. eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
  390. }
  391. static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
  392. {
  393. struct wpa_driver_scan_params params;
  394. int ret;
  395. /* Check that HT40 is used and PRI / SEC switch is allowed */
  396. if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch)
  397. return 0;
  398. hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
  399. wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
  400. "40 MHz channel");
  401. os_memset(&params, 0, sizeof(params));
  402. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
  403. ieee80211n_scan_channels_2g4(iface, &params);
  404. else
  405. ieee80211n_scan_channels_5g(iface, &params);
  406. ret = hostapd_driver_scan(iface->bss[0], &params);
  407. os_free(params.freqs);
  408. if (ret == -EBUSY) {
  409. wpa_printf(MSG_ERROR,
  410. "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again",
  411. ret, strerror(-ret));
  412. iface->num_ht40_scan_tries = 1;
  413. eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
  414. eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
  415. return 1;
  416. }
  417. if (ret < 0) {
  418. wpa_printf(MSG_ERROR,
  419. "Failed to request a scan of neighboring BSSes ret=%d (%s)",
  420. ret, strerror(-ret));
  421. return -1;
  422. }
  423. iface->scan_cb = ieee80211n_check_scan;
  424. return 1;
  425. }
  426. static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
  427. {
  428. u16 hw = iface->current_mode->ht_capab;
  429. u16 conf = iface->conf->ht_capab;
  430. if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
  431. !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
  432. wpa_printf(MSG_ERROR, "Driver does not support configured "
  433. "HT capability [LDPC]");
  434. return 0;
  435. }
  436. /*
  437. * Driver ACS chosen channel may not be HT40 due to internal driver
  438. * restrictions.
  439. */
  440. if (!iface->conf->acs && (conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
  441. !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
  442. wpa_printf(MSG_ERROR, "Driver does not support configured "
  443. "HT capability [HT40*]");
  444. return 0;
  445. }
  446. switch (conf & HT_CAP_INFO_SMPS_MASK) {
  447. case HT_CAP_INFO_SMPS_STATIC:
  448. if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_STATIC)) {
  449. wpa_printf(MSG_ERROR,
  450. "Driver does not support configured HT capability [SMPS-STATIC]");
  451. return 0;
  452. }
  453. break;
  454. case HT_CAP_INFO_SMPS_DYNAMIC:
  455. if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_DYNAMIC)) {
  456. wpa_printf(MSG_ERROR,
  457. "Driver does not support configured HT capability [SMPS-DYNAMIC]");
  458. return 0;
  459. }
  460. break;
  461. case HT_CAP_INFO_SMPS_DISABLED:
  462. default:
  463. break;
  464. }
  465. if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
  466. !(hw & HT_CAP_INFO_GREEN_FIELD)) {
  467. wpa_printf(MSG_ERROR, "Driver does not support configured "
  468. "HT capability [GF]");
  469. return 0;
  470. }
  471. if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
  472. !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
  473. wpa_printf(MSG_ERROR, "Driver does not support configured "
  474. "HT capability [SHORT-GI-20]");
  475. return 0;
  476. }
  477. if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
  478. !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
  479. wpa_printf(MSG_ERROR, "Driver does not support configured "
  480. "HT capability [SHORT-GI-40]");
  481. return 0;
  482. }
  483. if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
  484. wpa_printf(MSG_ERROR, "Driver does not support configured "
  485. "HT capability [TX-STBC]");
  486. return 0;
  487. }
  488. if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
  489. (hw & HT_CAP_INFO_RX_STBC_MASK)) {
  490. wpa_printf(MSG_ERROR, "Driver does not support configured "
  491. "HT capability [RX-STBC*]");
  492. return 0;
  493. }
  494. if ((conf & HT_CAP_INFO_DELAYED_BA) &&
  495. !(hw & HT_CAP_INFO_DELAYED_BA)) {
  496. wpa_printf(MSG_ERROR, "Driver does not support configured "
  497. "HT capability [DELAYED-BA]");
  498. return 0;
  499. }
  500. if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
  501. !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
  502. wpa_printf(MSG_ERROR, "Driver does not support configured "
  503. "HT capability [MAX-AMSDU-7935]");
  504. return 0;
  505. }
  506. if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
  507. !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
  508. wpa_printf(MSG_ERROR, "Driver does not support configured "
  509. "HT capability [DSSS_CCK-40]");
  510. return 0;
  511. }
  512. if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
  513. !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
  514. wpa_printf(MSG_ERROR, "Driver does not support configured "
  515. "HT capability [LSIG-TXOP-PROT]");
  516. return 0;
  517. }
  518. return 1;
  519. }
  520. #ifdef CONFIG_IEEE80211AC
  521. static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
  522. {
  523. struct hostapd_hw_modes *mode = iface->current_mode;
  524. u32 hw = mode->vht_capab;
  525. u32 conf = iface->conf->vht_capab;
  526. wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x",
  527. hw, conf);
  528. if (mode->mode == HOSTAPD_MODE_IEEE80211G &&
  529. iface->conf->bss[0]->vendor_vht &&
  530. mode->vht_capab == 0 && iface->hw_features) {
  531. int i;
  532. for (i = 0; i < iface->num_hw_features; i++) {
  533. if (iface->hw_features[i].mode ==
  534. HOSTAPD_MODE_IEEE80211A) {
  535. mode = &iface->hw_features[i];
  536. hw = mode->vht_capab;
  537. wpa_printf(MSG_DEBUG,
  538. "update hw vht capab based on 5 GHz band: 0x%x",
  539. hw);
  540. break;
  541. }
  542. }
  543. }
  544. return ieee80211ac_cap_check(hw, conf);
  545. }
  546. #endif /* CONFIG_IEEE80211AC */
  547. #endif /* CONFIG_IEEE80211N */
  548. int hostapd_check_ht_capab(struct hostapd_iface *iface)
  549. {
  550. #ifdef CONFIG_IEEE80211N
  551. int ret;
  552. if (!iface->conf->ieee80211n)
  553. return 0;
  554. if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211B &&
  555. iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G &&
  556. (iface->conf->ht_capab & HT_CAP_INFO_DSSS_CCK40MHZ)) {
  557. wpa_printf(MSG_DEBUG,
  558. "Disable HT capability [DSSS_CCK-40] on 5 GHz band");
  559. iface->conf->ht_capab &= ~HT_CAP_INFO_DSSS_CCK40MHZ;
  560. }
  561. if (!ieee80211n_supported_ht_capab(iface))
  562. return -1;
  563. #ifdef CONFIG_IEEE80211AC
  564. if (!ieee80211ac_supported_vht_capab(iface))
  565. return -1;
  566. #endif /* CONFIG_IEEE80211AC */
  567. ret = ieee80211n_check_40mhz(iface);
  568. if (ret)
  569. return ret;
  570. if (!ieee80211n_allowed_ht40_channel_pair(iface))
  571. return -1;
  572. #endif /* CONFIG_IEEE80211N */
  573. return 0;
  574. }
  575. static int hostapd_is_usable_chan(struct hostapd_iface *iface,
  576. int channel, int primary)
  577. {
  578. int i;
  579. struct hostapd_channel_data *chan;
  580. if (!iface->current_mode)
  581. return 0;
  582. for (i = 0; i < iface->current_mode->num_channels; i++) {
  583. chan = &iface->current_mode->channels[i];
  584. if (chan->chan != channel)
  585. continue;
  586. if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
  587. return 1;
  588. wpa_printf(MSG_DEBUG,
  589. "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s",
  590. primary ? "" : "Configured HT40 secondary ",
  591. i, chan->chan, chan->flag,
  592. chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "",
  593. chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
  594. }
  595. wpa_printf(MSG_INFO, "Channel %d (%s) not allowed for AP mode",
  596. channel, primary ? "primary" : "secondary");
  597. return 0;
  598. }
  599. static int hostapd_is_usable_chans(struct hostapd_iface *iface)
  600. {
  601. if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
  602. return 0;
  603. if (!iface->conf->secondary_channel)
  604. return 1;
  605. return hostapd_is_usable_chan(iface, iface->conf->channel +
  606. iface->conf->secondary_channel * 4, 0);
  607. }
  608. static enum hostapd_chan_status
  609. hostapd_check_chans(struct hostapd_iface *iface)
  610. {
  611. if (iface->conf->channel) {
  612. if (hostapd_is_usable_chans(iface))
  613. return HOSTAPD_CHAN_VALID;
  614. else
  615. return HOSTAPD_CHAN_INVALID;
  616. }
  617. /*
  618. * The user set channel=0 or channel=acs_survey
  619. * which is used to trigger ACS.
  620. */
  621. switch (acs_init(iface)) {
  622. case HOSTAPD_CHAN_ACS:
  623. return HOSTAPD_CHAN_ACS;
  624. case HOSTAPD_CHAN_VALID:
  625. case HOSTAPD_CHAN_INVALID:
  626. default:
  627. return HOSTAPD_CHAN_INVALID;
  628. }
  629. }
  630. static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
  631. {
  632. if (!iface->current_mode) {
  633. hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
  634. HOSTAPD_LEVEL_WARNING,
  635. "Hardware does not support configured mode");
  636. return;
  637. }
  638. hostapd_logger(iface->bss[0], NULL,
  639. HOSTAPD_MODULE_IEEE80211,
  640. HOSTAPD_LEVEL_WARNING,
  641. "Configured channel (%d) not found from the "
  642. "channel list of current mode (%d) %s",
  643. iface->conf->channel,
  644. iface->current_mode->mode,
  645. hostapd_hw_mode_txt(iface->current_mode->mode));
  646. hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
  647. HOSTAPD_LEVEL_WARNING,
  648. "Hardware does not support configured channel");
  649. }
  650. int hostapd_acs_completed(struct hostapd_iface *iface, int err)
  651. {
  652. int ret = -1;
  653. if (err)
  654. goto out;
  655. switch (hostapd_check_chans(iface)) {
  656. case HOSTAPD_CHAN_VALID:
  657. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
  658. ACS_EVENT_COMPLETED "freq=%d channel=%d",
  659. hostapd_hw_get_freq(iface->bss[0],
  660. iface->conf->channel),
  661. iface->conf->channel);
  662. break;
  663. case HOSTAPD_CHAN_ACS:
  664. wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
  665. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
  666. hostapd_notify_bad_chans(iface);
  667. goto out;
  668. case HOSTAPD_CHAN_INVALID:
  669. default:
  670. wpa_printf(MSG_ERROR, "ACS picked unusable channels");
  671. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
  672. hostapd_notify_bad_chans(iface);
  673. goto out;
  674. }
  675. ret = hostapd_check_ht_capab(iface);
  676. if (ret < 0)
  677. goto out;
  678. if (ret == 1) {
  679. wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback");
  680. return 0;
  681. }
  682. ret = 0;
  683. out:
  684. return hostapd_setup_interface_complete(iface, ret);
  685. }
  686. /**
  687. * hostapd_select_hw_mode - Select the hardware mode
  688. * @iface: Pointer to interface data.
  689. * Returns: 0 on success, < 0 on failure
  690. *
  691. * Sets up the hardware mode, channel, rates, and passive scanning
  692. * based on the configuration.
  693. */
  694. int hostapd_select_hw_mode(struct hostapd_iface *iface)
  695. {
  696. int i;
  697. if (iface->num_hw_features < 1)
  698. return -1;
  699. if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G ||
  700. iface->conf->ieee80211n || iface->conf->ieee80211ac) &&
  701. iface->conf->channel == 14) {
  702. wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT on channel 14");
  703. iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
  704. iface->conf->ieee80211n = 0;
  705. iface->conf->ieee80211ac = 0;
  706. }
  707. iface->current_mode = NULL;
  708. for (i = 0; i < iface->num_hw_features; i++) {
  709. struct hostapd_hw_modes *mode = &iface->hw_features[i];
  710. if (mode->mode == iface->conf->hw_mode) {
  711. iface->current_mode = mode;
  712. break;
  713. }
  714. }
  715. if (iface->current_mode == NULL) {
  716. if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) ||
  717. !(iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY))
  718. {
  719. wpa_printf(MSG_ERROR,
  720. "Hardware does not support configured mode");
  721. hostapd_logger(iface->bss[0], NULL,
  722. HOSTAPD_MODULE_IEEE80211,
  723. HOSTAPD_LEVEL_WARNING,
  724. "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)",
  725. (int) iface->conf->hw_mode);
  726. return -2;
  727. }
  728. }
  729. switch (hostapd_check_chans(iface)) {
  730. case HOSTAPD_CHAN_VALID:
  731. return 0;
  732. case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */
  733. return 1;
  734. case HOSTAPD_CHAN_INVALID:
  735. default:
  736. hostapd_notify_bad_chans(iface);
  737. return -3;
  738. }
  739. }
  740. const char * hostapd_hw_mode_txt(int mode)
  741. {
  742. switch (mode) {
  743. case HOSTAPD_MODE_IEEE80211A:
  744. return "IEEE 802.11a";
  745. case HOSTAPD_MODE_IEEE80211B:
  746. return "IEEE 802.11b";
  747. case HOSTAPD_MODE_IEEE80211G:
  748. return "IEEE 802.11g";
  749. case HOSTAPD_MODE_IEEE80211AD:
  750. return "IEEE 802.11ad";
  751. default:
  752. return "UNKNOWN";
  753. }
  754. }
  755. int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
  756. {
  757. return hw_get_freq(hapd->iface->current_mode, chan);
  758. }
  759. int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
  760. {
  761. int i, channel;
  762. struct hostapd_hw_modes *mode;
  763. channel = hw_get_chan(hapd->iface->current_mode, freq);
  764. if (channel)
  765. return channel;
  766. /* Check other available modes since the channel list for the current
  767. * mode did not include the specified frequency. */
  768. for (i = 0; i < hapd->iface->num_hw_features; i++) {
  769. mode = &hapd->iface->hw_features[i];
  770. channel = hw_get_chan(mode, freq);
  771. if (channel)
  772. return channel;
  773. }
  774. return 0;
  775. }