hw_features.c 24 KB

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