hw_features.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  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. wpa_printf(MSG_INFO, "Fallback to 20 MHz");
  275. }
  276. hostapd_setup_interface_complete(iface, !res);
  277. }
  278. static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
  279. struct wpa_driver_scan_params *params)
  280. {
  281. /* Scan only the affected frequency range */
  282. int pri_freq, sec_freq;
  283. int affected_start, affected_end;
  284. int i, pos;
  285. struct hostapd_hw_modes *mode;
  286. if (iface->current_mode == NULL)
  287. return;
  288. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  289. if (iface->conf->secondary_channel > 0)
  290. sec_freq = pri_freq + 20;
  291. else
  292. sec_freq = pri_freq - 20;
  293. /*
  294. * Note: Need to find the PRI channel also in cases where the affected
  295. * channel is the SEC channel of a 40 MHz BSS, so need to include the
  296. * scanning coverage here to be 40 MHz from the center frequency.
  297. */
  298. affected_start = (pri_freq + sec_freq) / 2 - 40;
  299. affected_end = (pri_freq + sec_freq) / 2 + 40;
  300. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  301. affected_start, affected_end);
  302. mode = iface->current_mode;
  303. params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
  304. if (params->freqs == NULL)
  305. return;
  306. pos = 0;
  307. for (i = 0; i < mode->num_channels; i++) {
  308. struct hostapd_channel_data *chan = &mode->channels[i];
  309. if (chan->flag & HOSTAPD_CHAN_DISABLED)
  310. continue;
  311. if (chan->freq < affected_start ||
  312. chan->freq > affected_end)
  313. continue;
  314. params->freqs[pos++] = chan->freq;
  315. }
  316. }
  317. static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
  318. struct wpa_driver_scan_params *params)
  319. {
  320. /* Scan only the affected frequency range */
  321. int pri_freq;
  322. int affected_start, affected_end;
  323. int i, pos;
  324. struct hostapd_hw_modes *mode;
  325. if (iface->current_mode == NULL)
  326. return;
  327. pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
  328. if (iface->conf->secondary_channel > 0) {
  329. affected_start = pri_freq - 10;
  330. affected_end = pri_freq + 30;
  331. } else {
  332. affected_start = pri_freq - 30;
  333. affected_end = pri_freq + 10;
  334. }
  335. wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
  336. affected_start, affected_end);
  337. mode = iface->current_mode;
  338. params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
  339. if (params->freqs == NULL)
  340. return;
  341. pos = 0;
  342. for (i = 0; i < mode->num_channels; i++) {
  343. struct hostapd_channel_data *chan = &mode->channels[i];
  344. if (chan->flag & HOSTAPD_CHAN_DISABLED)
  345. continue;
  346. if (chan->freq < affected_start ||
  347. chan->freq > affected_end)
  348. continue;
  349. params->freqs[pos++] = chan->freq;
  350. }
  351. }
  352. static void ap_ht40_scan_retry(void *eloop_data, void *user_data)
  353. {
  354. #define HT2040_COEX_SCAN_RETRY 15
  355. struct hostapd_iface *iface = eloop_data;
  356. struct wpa_driver_scan_params params;
  357. int ret;
  358. os_memset(&params, 0, sizeof(params));
  359. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
  360. ieee80211n_scan_channels_2g4(iface, &params);
  361. else
  362. ieee80211n_scan_channels_5g(iface, &params);
  363. ret = hostapd_driver_scan(iface->bss[0], &params);
  364. iface->num_ht40_scan_tries++;
  365. os_free(params.freqs);
  366. if (ret == -EBUSY &&
  367. iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) {
  368. wpa_printf(MSG_ERROR,
  369. "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
  370. ret, strerror(-ret), iface->num_ht40_scan_tries);
  371. eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
  372. return;
  373. }
  374. if (ret == 0) {
  375. iface->scan_cb = ieee80211n_check_scan;
  376. return;
  377. }
  378. wpa_printf(MSG_DEBUG,
  379. "Failed to request a scan in device, bringing up in HT20 mode");
  380. iface->conf->secondary_channel = 0;
  381. iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
  382. hostapd_setup_interface_complete(iface, 0);
  383. }
  384. void hostapd_stop_setup_timers(struct hostapd_iface *iface)
  385. {
  386. eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
  387. }
  388. static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
  389. {
  390. struct wpa_driver_scan_params params;
  391. int ret;
  392. /* Check that HT40 is used and PRI / SEC switch is allowed */
  393. if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch)
  394. return 0;
  395. hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
  396. wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
  397. "40 MHz channel");
  398. os_memset(&params, 0, sizeof(params));
  399. if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
  400. ieee80211n_scan_channels_2g4(iface, &params);
  401. else
  402. ieee80211n_scan_channels_5g(iface, &params);
  403. ret = hostapd_driver_scan(iface->bss[0], &params);
  404. os_free(params.freqs);
  405. if (ret == -EBUSY) {
  406. wpa_printf(MSG_ERROR,
  407. "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again",
  408. ret, strerror(-ret));
  409. iface->num_ht40_scan_tries = 1;
  410. eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
  411. eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
  412. return 1;
  413. }
  414. if (ret < 0) {
  415. wpa_printf(MSG_ERROR,
  416. "Failed to request a scan of neighboring BSSes ret=%d (%s)",
  417. ret, strerror(-ret));
  418. return -1;
  419. }
  420. iface->scan_cb = ieee80211n_check_scan;
  421. return 1;
  422. }
  423. static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
  424. {
  425. u16 hw = iface->current_mode->ht_capab;
  426. u16 conf = iface->conf->ht_capab;
  427. if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
  428. !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
  429. wpa_printf(MSG_ERROR, "Driver does not support configured "
  430. "HT capability [LDPC]");
  431. return 0;
  432. }
  433. /*
  434. * Driver ACS chosen channel may not be HT40 due to internal driver
  435. * restrictions.
  436. */
  437. if (!iface->conf->acs && (conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
  438. !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
  439. wpa_printf(MSG_ERROR, "Driver does not support configured "
  440. "HT capability [HT40*]");
  441. return 0;
  442. }
  443. switch (conf & HT_CAP_INFO_SMPS_MASK) {
  444. case HT_CAP_INFO_SMPS_STATIC:
  445. if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_STATIC)) {
  446. wpa_printf(MSG_ERROR,
  447. "Driver does not support configured HT capability [SMPS-STATIC]");
  448. return 0;
  449. }
  450. break;
  451. case HT_CAP_INFO_SMPS_DYNAMIC:
  452. if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_DYNAMIC)) {
  453. wpa_printf(MSG_ERROR,
  454. "Driver does not support configured HT capability [SMPS-DYNAMIC]");
  455. return 0;
  456. }
  457. break;
  458. case HT_CAP_INFO_SMPS_DISABLED:
  459. default:
  460. break;
  461. }
  462. if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
  463. !(hw & HT_CAP_INFO_GREEN_FIELD)) {
  464. wpa_printf(MSG_ERROR, "Driver does not support configured "
  465. "HT capability [GF]");
  466. return 0;
  467. }
  468. if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
  469. !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
  470. wpa_printf(MSG_ERROR, "Driver does not support configured "
  471. "HT capability [SHORT-GI-20]");
  472. return 0;
  473. }
  474. if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
  475. !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
  476. wpa_printf(MSG_ERROR, "Driver does not support configured "
  477. "HT capability [SHORT-GI-40]");
  478. return 0;
  479. }
  480. if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
  481. wpa_printf(MSG_ERROR, "Driver does not support configured "
  482. "HT capability [TX-STBC]");
  483. return 0;
  484. }
  485. if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
  486. (hw & HT_CAP_INFO_RX_STBC_MASK)) {
  487. wpa_printf(MSG_ERROR, "Driver does not support configured "
  488. "HT capability [RX-STBC*]");
  489. return 0;
  490. }
  491. if ((conf & HT_CAP_INFO_DELAYED_BA) &&
  492. !(hw & HT_CAP_INFO_DELAYED_BA)) {
  493. wpa_printf(MSG_ERROR, "Driver does not support configured "
  494. "HT capability [DELAYED-BA]");
  495. return 0;
  496. }
  497. if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
  498. !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
  499. wpa_printf(MSG_ERROR, "Driver does not support configured "
  500. "HT capability [MAX-AMSDU-7935]");
  501. return 0;
  502. }
  503. if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
  504. !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
  505. wpa_printf(MSG_ERROR, "Driver does not support configured "
  506. "HT capability [DSSS_CCK-40]");
  507. return 0;
  508. }
  509. if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
  510. !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
  511. wpa_printf(MSG_ERROR, "Driver does not support configured "
  512. "HT capability [LSIG-TXOP-PROT]");
  513. return 0;
  514. }
  515. return 1;
  516. }
  517. #ifdef CONFIG_IEEE80211AC
  518. static int ieee80211ac_cap_check(u32 hw, u32 conf, u32 cap, const char *name)
  519. {
  520. u32 req_cap = conf & cap;
  521. /*
  522. * Make sure we support all requested capabilities.
  523. * NOTE: We assume that 'cap' represents a capability mask,
  524. * not a discrete value.
  525. */
  526. if ((hw & req_cap) != req_cap) {
  527. wpa_printf(MSG_ERROR, "Driver does not support configured VHT capability [%s]",
  528. name);
  529. return 0;
  530. }
  531. return 1;
  532. }
  533. static int ieee80211ac_cap_check_max(u32 hw, u32 conf, u32 mask,
  534. unsigned int shift,
  535. const char *name)
  536. {
  537. u32 hw_max = hw & mask;
  538. u32 conf_val = conf & mask;
  539. if (conf_val > hw_max) {
  540. wpa_printf(MSG_ERROR, "Configured VHT capability [%s] exceeds max value supported by the driver (%d > %d)",
  541. name, conf_val >> shift, hw_max >> shift);
  542. return 0;
  543. }
  544. return 1;
  545. }
  546. static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
  547. {
  548. struct hostapd_hw_modes *mode = iface->current_mode;
  549. u32 hw = mode->vht_capab;
  550. u32 conf = iface->conf->vht_capab;
  551. wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x",
  552. hw, conf);
  553. if (mode->mode == HOSTAPD_MODE_IEEE80211G &&
  554. iface->conf->bss[0]->vendor_vht &&
  555. mode->vht_capab == 0 && iface->hw_features) {
  556. int i;
  557. for (i = 0; i < iface->num_hw_features; i++) {
  558. if (iface->hw_features[i].mode ==
  559. HOSTAPD_MODE_IEEE80211A) {
  560. mode = &iface->hw_features[i];
  561. hw = mode->vht_capab;
  562. wpa_printf(MSG_DEBUG,
  563. "update hw vht capab based on 5 GHz band: 0x%x",
  564. hw);
  565. break;
  566. }
  567. }
  568. }
  569. #define VHT_CAP_CHECK(cap) \
  570. do { \
  571. if (!ieee80211ac_cap_check(hw, conf, cap, #cap)) \
  572. return 0; \
  573. } while (0)
  574. #define VHT_CAP_CHECK_MAX(cap) \
  575. do { \
  576. if (!ieee80211ac_cap_check_max(hw, conf, cap, cap ## _SHIFT, \
  577. #cap)) \
  578. return 0; \
  579. } while (0)
  580. VHT_CAP_CHECK_MAX(VHT_CAP_MAX_MPDU_LENGTH_MASK);
  581. VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ);
  582. VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ);
  583. VHT_CAP_CHECK(VHT_CAP_RXLDPC);
  584. VHT_CAP_CHECK(VHT_CAP_SHORT_GI_80);
  585. VHT_CAP_CHECK(VHT_CAP_SHORT_GI_160);
  586. VHT_CAP_CHECK(VHT_CAP_TXSTBC);
  587. VHT_CAP_CHECK_MAX(VHT_CAP_RXSTBC_MASK);
  588. VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMER_CAPABLE);
  589. VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMEE_CAPABLE);
  590. VHT_CAP_CHECK_MAX(VHT_CAP_BEAMFORMEE_STS_MAX);
  591. VHT_CAP_CHECK_MAX(VHT_CAP_SOUNDING_DIMENSION_MAX);
  592. VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMER_CAPABLE);
  593. VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMEE_CAPABLE);
  594. VHT_CAP_CHECK(VHT_CAP_VHT_TXOP_PS);
  595. VHT_CAP_CHECK(VHT_CAP_HTC_VHT);
  596. VHT_CAP_CHECK_MAX(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX);
  597. VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB);
  598. VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB);
  599. VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN);
  600. VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN);
  601. #undef VHT_CAP_CHECK
  602. #undef VHT_CAP_CHECK_MAX
  603. return 1;
  604. }
  605. #endif /* CONFIG_IEEE80211AC */
  606. #endif /* CONFIG_IEEE80211N */
  607. int hostapd_check_ht_capab(struct hostapd_iface *iface)
  608. {
  609. #ifdef CONFIG_IEEE80211N
  610. int ret;
  611. if (!iface->conf->ieee80211n)
  612. return 0;
  613. if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211B &&
  614. iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G &&
  615. (iface->conf->ht_capab & HT_CAP_INFO_DSSS_CCK40MHZ)) {
  616. wpa_printf(MSG_DEBUG,
  617. "Disable HT capability [DSSS_CCK-40] on 5 GHz band");
  618. iface->conf->ht_capab &= ~HT_CAP_INFO_DSSS_CCK40MHZ;
  619. }
  620. if (!ieee80211n_supported_ht_capab(iface))
  621. return -1;
  622. #ifdef CONFIG_IEEE80211AC
  623. if (!ieee80211ac_supported_vht_capab(iface))
  624. return -1;
  625. #endif /* CONFIG_IEEE80211AC */
  626. ret = ieee80211n_check_40mhz(iface);
  627. if (ret)
  628. return ret;
  629. if (!ieee80211n_allowed_ht40_channel_pair(iface))
  630. return -1;
  631. #endif /* CONFIG_IEEE80211N */
  632. return 0;
  633. }
  634. static int hostapd_is_usable_chan(struct hostapd_iface *iface,
  635. int channel, int primary)
  636. {
  637. int i;
  638. struct hostapd_channel_data *chan;
  639. if (!iface->current_mode)
  640. return 0;
  641. for (i = 0; i < iface->current_mode->num_channels; i++) {
  642. chan = &iface->current_mode->channels[i];
  643. if (chan->chan != channel)
  644. continue;
  645. if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
  646. return 1;
  647. wpa_printf(MSG_DEBUG,
  648. "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s",
  649. primary ? "" : "Configured HT40 secondary ",
  650. i, chan->chan, chan->flag,
  651. chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "",
  652. chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
  653. }
  654. return 0;
  655. }
  656. static int hostapd_is_usable_chans(struct hostapd_iface *iface)
  657. {
  658. if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
  659. return 0;
  660. if (!iface->conf->secondary_channel)
  661. return 1;
  662. return hostapd_is_usable_chan(iface, iface->conf->channel +
  663. iface->conf->secondary_channel * 4, 0);
  664. }
  665. static enum hostapd_chan_status
  666. hostapd_check_chans(struct hostapd_iface *iface)
  667. {
  668. if (iface->conf->channel) {
  669. if (hostapd_is_usable_chans(iface))
  670. return HOSTAPD_CHAN_VALID;
  671. else
  672. return HOSTAPD_CHAN_INVALID;
  673. }
  674. /*
  675. * The user set channel=0 or channel=acs_survey
  676. * which is used to trigger ACS.
  677. */
  678. switch (acs_init(iface)) {
  679. case HOSTAPD_CHAN_ACS:
  680. return HOSTAPD_CHAN_ACS;
  681. case HOSTAPD_CHAN_VALID:
  682. case HOSTAPD_CHAN_INVALID:
  683. default:
  684. return HOSTAPD_CHAN_INVALID;
  685. }
  686. }
  687. static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
  688. {
  689. if (!iface->current_mode) {
  690. hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
  691. HOSTAPD_LEVEL_WARNING,
  692. "Hardware does not support configured mode");
  693. return;
  694. }
  695. hostapd_logger(iface->bss[0], NULL,
  696. HOSTAPD_MODULE_IEEE80211,
  697. HOSTAPD_LEVEL_WARNING,
  698. "Configured channel (%d) not found from the "
  699. "channel list of current mode (%d) %s",
  700. iface->conf->channel,
  701. iface->current_mode->mode,
  702. hostapd_hw_mode_txt(iface->current_mode->mode));
  703. hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
  704. HOSTAPD_LEVEL_WARNING,
  705. "Hardware does not support configured channel");
  706. }
  707. int hostapd_acs_completed(struct hostapd_iface *iface, int err)
  708. {
  709. int ret = -1;
  710. if (err)
  711. goto out;
  712. switch (hostapd_check_chans(iface)) {
  713. case HOSTAPD_CHAN_VALID:
  714. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
  715. ACS_EVENT_COMPLETED "freq=%d channel=%d",
  716. hostapd_hw_get_freq(iface->bss[0],
  717. iface->conf->channel),
  718. iface->conf->channel);
  719. break;
  720. case HOSTAPD_CHAN_ACS:
  721. wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
  722. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
  723. hostapd_notify_bad_chans(iface);
  724. goto out;
  725. case HOSTAPD_CHAN_INVALID:
  726. default:
  727. wpa_printf(MSG_ERROR, "ACS picked unusable channels");
  728. wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
  729. hostapd_notify_bad_chans(iface);
  730. goto out;
  731. }
  732. ret = hostapd_check_ht_capab(iface);
  733. if (ret < 0)
  734. goto out;
  735. if (ret == 1) {
  736. wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback");
  737. return 0;
  738. }
  739. ret = 0;
  740. out:
  741. return hostapd_setup_interface_complete(iface, ret);
  742. }
  743. /**
  744. * hostapd_select_hw_mode - Select the hardware mode
  745. * @iface: Pointer to interface data.
  746. * Returns: 0 on success, < 0 on failure
  747. *
  748. * Sets up the hardware mode, channel, rates, and passive scanning
  749. * based on the configuration.
  750. */
  751. int hostapd_select_hw_mode(struct hostapd_iface *iface)
  752. {
  753. int i;
  754. if (iface->num_hw_features < 1)
  755. return -1;
  756. if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G ||
  757. iface->conf->ieee80211n || iface->conf->ieee80211ac) &&
  758. iface->conf->channel == 14) {
  759. wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT on channel 14");
  760. iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
  761. iface->conf->ieee80211n = 0;
  762. iface->conf->ieee80211ac = 0;
  763. }
  764. iface->current_mode = NULL;
  765. for (i = 0; i < iface->num_hw_features; i++) {
  766. struct hostapd_hw_modes *mode = &iface->hw_features[i];
  767. if (mode->mode == iface->conf->hw_mode) {
  768. iface->current_mode = mode;
  769. break;
  770. }
  771. }
  772. if (iface->current_mode == NULL) {
  773. if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) ||
  774. !(iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY))
  775. {
  776. wpa_printf(MSG_ERROR,
  777. "Hardware does not support configured mode");
  778. hostapd_logger(iface->bss[0], NULL,
  779. HOSTAPD_MODULE_IEEE80211,
  780. HOSTAPD_LEVEL_WARNING,
  781. "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)",
  782. (int) iface->conf->hw_mode);
  783. return -2;
  784. }
  785. }
  786. switch (hostapd_check_chans(iface)) {
  787. case HOSTAPD_CHAN_VALID:
  788. return 0;
  789. case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */
  790. return 1;
  791. case HOSTAPD_CHAN_INVALID:
  792. default:
  793. hostapd_notify_bad_chans(iface);
  794. return -3;
  795. }
  796. }
  797. const char * hostapd_hw_mode_txt(int mode)
  798. {
  799. switch (mode) {
  800. case HOSTAPD_MODE_IEEE80211A:
  801. return "IEEE 802.11a";
  802. case HOSTAPD_MODE_IEEE80211B:
  803. return "IEEE 802.11b";
  804. case HOSTAPD_MODE_IEEE80211G:
  805. return "IEEE 802.11g";
  806. case HOSTAPD_MODE_IEEE80211AD:
  807. return "IEEE 802.11ad";
  808. default:
  809. return "UNKNOWN";
  810. }
  811. }
  812. int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
  813. {
  814. return hw_get_freq(hapd->iface->current_mode, chan);
  815. }
  816. int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
  817. {
  818. return hw_get_chan(hapd->iface->current_mode, freq);
  819. }