driver_nl80211_capa.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590
  1. /*
  2. * Driver interaction with Linux nl80211/cfg80211 - Capabilities
  3. * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
  4. * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
  5. * Copyright (c) 2009-2010, Atheros Communications
  6. *
  7. * This software may be distributed under the terms of the BSD license.
  8. * See README for more details.
  9. */
  10. #include "includes.h"
  11. #include <netlink/genl/genl.h>
  12. #include "utils/common.h"
  13. #include "common/ieee802_11_defs.h"
  14. #include "common/ieee802_11_common.h"
  15. #include "common/qca-vendor.h"
  16. #include "common/qca-vendor-attr.h"
  17. #include "driver_nl80211.h"
  18. static int protocol_feature_handler(struct nl_msg *msg, void *arg)
  19. {
  20. u32 *feat = arg;
  21. struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
  22. struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  23. nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  24. genlmsg_attrlen(gnlh, 0), NULL);
  25. if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
  26. *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
  27. return NL_SKIP;
  28. }
  29. static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
  30. {
  31. u32 feat = 0;
  32. struct nl_msg *msg;
  33. msg = nlmsg_alloc();
  34. if (!msg)
  35. return 0;
  36. if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES)) {
  37. nlmsg_free(msg);
  38. return 0;
  39. }
  40. if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
  41. return feat;
  42. return 0;
  43. }
  44. struct wiphy_info_data {
  45. struct wpa_driver_nl80211_data *drv;
  46. struct wpa_driver_capa *capa;
  47. unsigned int num_multichan_concurrent;
  48. unsigned int error:1;
  49. unsigned int device_ap_sme:1;
  50. unsigned int poll_command_supported:1;
  51. unsigned int data_tx_status:1;
  52. unsigned int monitor_supported:1;
  53. unsigned int auth_supported:1;
  54. unsigned int connect_supported:1;
  55. unsigned int p2p_go_supported:1;
  56. unsigned int p2p_client_supported:1;
  57. unsigned int p2p_go_ctwindow_supported:1;
  58. unsigned int p2p_concurrent:1;
  59. unsigned int channel_switch_supported:1;
  60. unsigned int set_qos_map_supported:1;
  61. unsigned int have_low_prio_scan:1;
  62. unsigned int wmm_ac_supported:1;
  63. unsigned int mac_addr_rand_scan_supported:1;
  64. unsigned int mac_addr_rand_sched_scan_supported:1;
  65. };
  66. static unsigned int probe_resp_offload_support(int supp_protocols)
  67. {
  68. unsigned int prot = 0;
  69. if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
  70. prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
  71. if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
  72. prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
  73. if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
  74. prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
  75. if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
  76. prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
  77. return prot;
  78. }
  79. static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
  80. struct nlattr *tb)
  81. {
  82. struct nlattr *nl_mode;
  83. int i;
  84. if (tb == NULL)
  85. return;
  86. nla_for_each_nested(nl_mode, tb, i) {
  87. switch (nla_type(nl_mode)) {
  88. case NL80211_IFTYPE_AP:
  89. info->capa->flags |= WPA_DRIVER_FLAGS_AP;
  90. break;
  91. case NL80211_IFTYPE_MESH_POINT:
  92. info->capa->flags |= WPA_DRIVER_FLAGS_MESH;
  93. break;
  94. case NL80211_IFTYPE_ADHOC:
  95. info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
  96. break;
  97. case NL80211_IFTYPE_P2P_DEVICE:
  98. info->capa->flags |=
  99. WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
  100. break;
  101. case NL80211_IFTYPE_P2P_GO:
  102. info->p2p_go_supported = 1;
  103. break;
  104. case NL80211_IFTYPE_P2P_CLIENT:
  105. info->p2p_client_supported = 1;
  106. break;
  107. case NL80211_IFTYPE_MONITOR:
  108. info->monitor_supported = 1;
  109. break;
  110. }
  111. }
  112. }
  113. static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
  114. struct nlattr *nl_combi)
  115. {
  116. struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
  117. struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
  118. struct nlattr *nl_limit, *nl_mode;
  119. int err, rem_limit, rem_mode;
  120. int combination_has_p2p = 0, combination_has_mgd = 0;
  121. static struct nla_policy
  122. iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
  123. [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
  124. [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
  125. [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
  126. [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
  127. [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
  128. },
  129. iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
  130. [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
  131. [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
  132. };
  133. err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
  134. nl_combi, iface_combination_policy);
  135. if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
  136. !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
  137. !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
  138. return 0; /* broken combination */
  139. if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
  140. info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
  141. nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
  142. rem_limit) {
  143. err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
  144. nl_limit, iface_limit_policy);
  145. if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
  146. return 0; /* broken combination */
  147. nla_for_each_nested(nl_mode,
  148. tb_limit[NL80211_IFACE_LIMIT_TYPES],
  149. rem_mode) {
  150. int ift = nla_type(nl_mode);
  151. if (ift == NL80211_IFTYPE_P2P_GO ||
  152. ift == NL80211_IFTYPE_P2P_CLIENT)
  153. combination_has_p2p = 1;
  154. if (ift == NL80211_IFTYPE_STATION)
  155. combination_has_mgd = 1;
  156. }
  157. if (combination_has_p2p && combination_has_mgd)
  158. break;
  159. }
  160. if (combination_has_p2p && combination_has_mgd) {
  161. unsigned int num_channels =
  162. nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
  163. info->p2p_concurrent = 1;
  164. if (info->num_multichan_concurrent < num_channels)
  165. info->num_multichan_concurrent = num_channels;
  166. }
  167. return 0;
  168. }
  169. static void wiphy_info_iface_comb(struct wiphy_info_data *info,
  170. struct nlattr *tb)
  171. {
  172. struct nlattr *nl_combi;
  173. int rem_combi;
  174. if (tb == NULL)
  175. return;
  176. nla_for_each_nested(nl_combi, tb, rem_combi) {
  177. if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
  178. break;
  179. }
  180. }
  181. static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
  182. struct nlattr *tb)
  183. {
  184. struct nlattr *nl_cmd;
  185. int i;
  186. if (tb == NULL)
  187. return;
  188. nla_for_each_nested(nl_cmd, tb, i) {
  189. switch (nla_get_u32(nl_cmd)) {
  190. case NL80211_CMD_AUTHENTICATE:
  191. info->auth_supported = 1;
  192. break;
  193. case NL80211_CMD_CONNECT:
  194. info->connect_supported = 1;
  195. break;
  196. case NL80211_CMD_START_SCHED_SCAN:
  197. info->capa->sched_scan_supported = 1;
  198. break;
  199. case NL80211_CMD_PROBE_CLIENT:
  200. info->poll_command_supported = 1;
  201. break;
  202. case NL80211_CMD_CHANNEL_SWITCH:
  203. info->channel_switch_supported = 1;
  204. break;
  205. case NL80211_CMD_SET_QOS_MAP:
  206. info->set_qos_map_supported = 1;
  207. break;
  208. }
  209. }
  210. }
  211. static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
  212. struct nlattr *tb)
  213. {
  214. int i, num;
  215. u32 *ciphers;
  216. if (tb == NULL)
  217. return;
  218. num = nla_len(tb) / sizeof(u32);
  219. ciphers = nla_data(tb);
  220. for (i = 0; i < num; i++) {
  221. u32 c = ciphers[i];
  222. wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
  223. c >> 24, (c >> 16) & 0xff,
  224. (c >> 8) & 0xff, c & 0xff);
  225. switch (c) {
  226. case WLAN_CIPHER_SUITE_CCMP_256:
  227. info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
  228. break;
  229. case WLAN_CIPHER_SUITE_GCMP_256:
  230. info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
  231. break;
  232. case WLAN_CIPHER_SUITE_CCMP:
  233. info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
  234. break;
  235. case WLAN_CIPHER_SUITE_GCMP:
  236. info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
  237. break;
  238. case WLAN_CIPHER_SUITE_TKIP:
  239. info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
  240. break;
  241. case WLAN_CIPHER_SUITE_WEP104:
  242. info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
  243. break;
  244. case WLAN_CIPHER_SUITE_WEP40:
  245. info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
  246. break;
  247. case WLAN_CIPHER_SUITE_AES_CMAC:
  248. info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
  249. break;
  250. case WLAN_CIPHER_SUITE_BIP_GMAC_128:
  251. info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
  252. break;
  253. case WLAN_CIPHER_SUITE_BIP_GMAC_256:
  254. info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
  255. break;
  256. case WLAN_CIPHER_SUITE_BIP_CMAC_256:
  257. info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
  258. break;
  259. case WLAN_CIPHER_SUITE_NO_GROUP_ADDR:
  260. info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
  261. break;
  262. }
  263. }
  264. }
  265. static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
  266. struct nlattr *tb)
  267. {
  268. if (tb)
  269. capa->max_remain_on_chan = nla_get_u32(tb);
  270. }
  271. static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
  272. struct nlattr *ext_setup)
  273. {
  274. if (tdls == NULL)
  275. return;
  276. wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
  277. capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
  278. if (ext_setup) {
  279. wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
  280. capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
  281. }
  282. }
  283. static int ext_feature_isset(const u8 *ext_features, int ext_features_len,
  284. enum nl80211_ext_feature_index ftidx)
  285. {
  286. u8 ft_byte;
  287. if ((int) ftidx / 8 >= ext_features_len)
  288. return 0;
  289. ft_byte = ext_features[ftidx / 8];
  290. return (ft_byte & BIT(ftidx % 8)) != 0;
  291. }
  292. static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
  293. struct nlattr *tb)
  294. {
  295. struct wpa_driver_capa *capa = info->capa;
  296. if (tb == NULL)
  297. return;
  298. if (ext_feature_isset(nla_data(tb), nla_len(tb),
  299. NL80211_EXT_FEATURE_VHT_IBSS))
  300. capa->flags |= WPA_DRIVER_FLAGS_VHT_IBSS;
  301. }
  302. static void wiphy_info_feature_flags(struct wiphy_info_data *info,
  303. struct nlattr *tb)
  304. {
  305. u32 flags;
  306. struct wpa_driver_capa *capa = info->capa;
  307. if (tb == NULL)
  308. return;
  309. flags = nla_get_u32(tb);
  310. if (flags & NL80211_FEATURE_SK_TX_STATUS)
  311. info->data_tx_status = 1;
  312. if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
  313. capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
  314. if (flags & NL80211_FEATURE_SAE)
  315. capa->flags |= WPA_DRIVER_FLAGS_SAE;
  316. if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
  317. capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
  318. if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)
  319. capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
  320. if (flags & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) {
  321. wpa_printf(MSG_DEBUG, "nl80211: TDLS channel switch");
  322. capa->flags |= WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH;
  323. }
  324. if (flags & NL80211_FEATURE_P2P_GO_CTWIN)
  325. info->p2p_go_ctwindow_supported = 1;
  326. if (flags & NL80211_FEATURE_LOW_PRIORITY_SCAN)
  327. info->have_low_prio_scan = 1;
  328. if (flags & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
  329. info->mac_addr_rand_scan_supported = 1;
  330. if (flags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR)
  331. info->mac_addr_rand_sched_scan_supported = 1;
  332. if (flags & NL80211_FEATURE_STATIC_SMPS)
  333. capa->smps_modes |= WPA_DRIVER_SMPS_MODE_STATIC;
  334. if (flags & NL80211_FEATURE_DYNAMIC_SMPS)
  335. capa->smps_modes |= WPA_DRIVER_SMPS_MODE_DYNAMIC;
  336. if (flags & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
  337. info->wmm_ac_supported = 1;
  338. if (flags & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES)
  339. capa->rrm_flags |= WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES;
  340. if (flags & NL80211_FEATURE_WFA_TPC_IE_IN_PROBES)
  341. capa->rrm_flags |= WPA_DRIVER_FLAGS_WFA_TPC_IE_IN_PROBES;
  342. if (flags & NL80211_FEATURE_QUIET)
  343. capa->rrm_flags |= WPA_DRIVER_FLAGS_QUIET;
  344. if (flags & NL80211_FEATURE_TX_POWER_INSERTION)
  345. capa->rrm_flags |= WPA_DRIVER_FLAGS_TX_POWER_INSERTION;
  346. if (flags & NL80211_FEATURE_HT_IBSS)
  347. capa->flags |= WPA_DRIVER_FLAGS_HT_IBSS;
  348. }
  349. static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
  350. struct nlattr *tb)
  351. {
  352. u32 protocols;
  353. if (tb == NULL)
  354. return;
  355. protocols = nla_get_u32(tb);
  356. wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
  357. "mode");
  358. capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
  359. capa->probe_resp_offloads = probe_resp_offload_support(protocols);
  360. }
  361. static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
  362. struct nlattr *tb)
  363. {
  364. struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
  365. if (tb == NULL)
  366. return;
  367. if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
  368. tb, NULL))
  369. return;
  370. if (triggers[NL80211_WOWLAN_TRIG_ANY])
  371. capa->wowlan_triggers.any = 1;
  372. if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
  373. capa->wowlan_triggers.disconnect = 1;
  374. if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
  375. capa->wowlan_triggers.magic_pkt = 1;
  376. if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
  377. capa->wowlan_triggers.gtk_rekey_failure = 1;
  378. if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
  379. capa->wowlan_triggers.eap_identity_req = 1;
  380. if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
  381. capa->wowlan_triggers.four_way_handshake = 1;
  382. if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
  383. capa->wowlan_triggers.rfkill_release = 1;
  384. }
  385. static int wiphy_info_handler(struct nl_msg *msg, void *arg)
  386. {
  387. struct nlattr *tb[NL80211_ATTR_MAX + 1];
  388. struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  389. struct wiphy_info_data *info = arg;
  390. struct wpa_driver_capa *capa = info->capa;
  391. struct wpa_driver_nl80211_data *drv = info->drv;
  392. nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  393. genlmsg_attrlen(gnlh, 0), NULL);
  394. if (tb[NL80211_ATTR_WIPHY_NAME])
  395. os_strlcpy(drv->phyname,
  396. nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
  397. sizeof(drv->phyname));
  398. if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
  399. capa->max_scan_ssids =
  400. nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
  401. if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
  402. capa->max_sched_scan_ssids =
  403. nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
  404. if (tb[NL80211_ATTR_MAX_MATCH_SETS])
  405. capa->max_match_sets =
  406. nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
  407. if (tb[NL80211_ATTR_MAC_ACL_MAX])
  408. capa->max_acl_mac_addrs =
  409. nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
  410. wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
  411. wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
  412. wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
  413. wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
  414. if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
  415. wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
  416. "off-channel TX");
  417. capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
  418. }
  419. if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
  420. wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
  421. capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
  422. }
  423. wiphy_info_max_roc(capa,
  424. tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
  425. if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
  426. capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
  427. wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
  428. tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
  429. if (tb[NL80211_ATTR_DEVICE_AP_SME])
  430. info->device_ap_sme = 1;
  431. wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
  432. wiphy_info_ext_feature_flags(info, tb[NL80211_ATTR_EXT_FEATURES]);
  433. wiphy_info_probe_resp_offload(capa,
  434. tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
  435. if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
  436. drv->extended_capa == NULL) {
  437. drv->extended_capa =
  438. os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
  439. if (drv->extended_capa) {
  440. os_memcpy(drv->extended_capa,
  441. nla_data(tb[NL80211_ATTR_EXT_CAPA]),
  442. nla_len(tb[NL80211_ATTR_EXT_CAPA]));
  443. drv->extended_capa_len =
  444. nla_len(tb[NL80211_ATTR_EXT_CAPA]);
  445. }
  446. drv->extended_capa_mask =
  447. os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
  448. if (drv->extended_capa_mask) {
  449. os_memcpy(drv->extended_capa_mask,
  450. nla_data(tb[NL80211_ATTR_EXT_CAPA_MASK]),
  451. nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
  452. } else {
  453. os_free(drv->extended_capa);
  454. drv->extended_capa = NULL;
  455. drv->extended_capa_len = 0;
  456. }
  457. }
  458. if (tb[NL80211_ATTR_VENDOR_DATA]) {
  459. struct nlattr *nl;
  460. int rem;
  461. nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
  462. struct nl80211_vendor_cmd_info *vinfo;
  463. if (nla_len(nl) != sizeof(*vinfo)) {
  464. wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
  465. continue;
  466. }
  467. vinfo = nla_data(nl);
  468. if (vinfo->vendor_id == OUI_QCA) {
  469. switch (vinfo->subcmd) {
  470. case QCA_NL80211_VENDOR_SUBCMD_TEST:
  471. drv->vendor_cmd_test_avail = 1;
  472. break;
  473. case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
  474. drv->roaming_vendor_cmd_avail = 1;
  475. break;
  476. case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
  477. drv->dfs_vendor_cmd_avail = 1;
  478. break;
  479. case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
  480. drv->get_features_vendor_cmd_avail = 1;
  481. break;
  482. case QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST:
  483. drv->get_pref_freq_list = 1;
  484. break;
  485. case QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL:
  486. drv->set_prob_oper_freq = 1;
  487. break;
  488. case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
  489. drv->capa.flags |=
  490. WPA_DRIVER_FLAGS_ACS_OFFLOAD;
  491. break;
  492. case QCA_NL80211_VENDOR_SUBCMD_SETBAND:
  493. drv->setband_vendor_cmd_avail = 1;
  494. break;
  495. }
  496. }
  497. wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
  498. vinfo->vendor_id, vinfo->subcmd);
  499. }
  500. }
  501. if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
  502. struct nlattr *nl;
  503. int rem;
  504. nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
  505. struct nl80211_vendor_cmd_info *vinfo;
  506. if (nla_len(nl) != sizeof(*vinfo)) {
  507. wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
  508. continue;
  509. }
  510. vinfo = nla_data(nl);
  511. wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
  512. vinfo->vendor_id, vinfo->subcmd);
  513. }
  514. }
  515. wiphy_info_wowlan_triggers(capa,
  516. tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
  517. if (tb[NL80211_ATTR_MAX_AP_ASSOC_STA])
  518. capa->max_stations =
  519. nla_get_u32(tb[NL80211_ATTR_MAX_AP_ASSOC_STA]);
  520. return NL_SKIP;
  521. }
  522. static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
  523. struct wiphy_info_data *info)
  524. {
  525. u32 feat;
  526. struct nl_msg *msg;
  527. int flags = 0;
  528. os_memset(info, 0, sizeof(*info));
  529. info->capa = &drv->capa;
  530. info->drv = drv;
  531. feat = get_nl80211_protocol_features(drv);
  532. if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
  533. flags = NLM_F_DUMP;
  534. msg = nl80211_cmd_msg(drv->first_bss, flags, NL80211_CMD_GET_WIPHY);
  535. if (!msg || nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
  536. nlmsg_free(msg);
  537. return -1;
  538. }
  539. if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info))
  540. return -1;
  541. if (info->auth_supported)
  542. drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
  543. else if (!info->connect_supported) {
  544. wpa_printf(MSG_INFO, "nl80211: Driver does not support "
  545. "authentication/association or connect commands");
  546. info->error = 1;
  547. }
  548. if (info->p2p_go_supported && info->p2p_client_supported)
  549. drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
  550. if (info->p2p_concurrent) {
  551. wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
  552. "interface (driver advertised support)");
  553. drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
  554. drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
  555. }
  556. if (info->num_multichan_concurrent > 1) {
  557. wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
  558. "concurrent (driver advertised support)");
  559. drv->capa.num_multichan_concurrent =
  560. info->num_multichan_concurrent;
  561. }
  562. if (drv->capa.flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
  563. wpa_printf(MSG_DEBUG, "nl80211: use P2P_DEVICE support");
  564. /* default to 5000 since early versions of mac80211 don't set it */
  565. if (!drv->capa.max_remain_on_chan)
  566. drv->capa.max_remain_on_chan = 5000;
  567. if (info->channel_switch_supported)
  568. drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
  569. drv->capa.wmm_ac_supported = info->wmm_ac_supported;
  570. drv->capa.mac_addr_rand_sched_scan_supported =
  571. info->mac_addr_rand_sched_scan_supported;
  572. drv->capa.mac_addr_rand_scan_supported =
  573. info->mac_addr_rand_scan_supported;
  574. return 0;
  575. }
  576. static int dfs_info_handler(struct nl_msg *msg, void *arg)
  577. {
  578. struct nlattr *tb[NL80211_ATTR_MAX + 1];
  579. struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  580. int *dfs_capability_ptr = arg;
  581. nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  582. genlmsg_attrlen(gnlh, 0), NULL);
  583. if (tb[NL80211_ATTR_VENDOR_DATA]) {
  584. struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
  585. struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
  586. nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
  587. nla_data(nl_vend), nla_len(nl_vend), NULL);
  588. if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
  589. u32 val;
  590. val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
  591. wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
  592. val);
  593. *dfs_capability_ptr = val;
  594. }
  595. }
  596. return NL_SKIP;
  597. }
  598. static void qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data *drv)
  599. {
  600. struct nl_msg *msg;
  601. int dfs_capability = 0;
  602. int ret;
  603. if (!drv->dfs_vendor_cmd_avail)
  604. return;
  605. if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
  606. nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
  607. nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
  608. QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY)) {
  609. nlmsg_free(msg);
  610. return;
  611. }
  612. ret = send_and_recv_msgs(drv, msg, dfs_info_handler, &dfs_capability);
  613. if (!ret && dfs_capability)
  614. drv->capa.flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
  615. }
  616. struct features_info {
  617. u8 *flags;
  618. size_t flags_len;
  619. struct wpa_driver_capa *capa;
  620. };
  621. static int features_info_handler(struct nl_msg *msg, void *arg)
  622. {
  623. struct nlattr *tb[NL80211_ATTR_MAX + 1];
  624. struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  625. struct features_info *info = arg;
  626. struct nlattr *nl_vend, *attr;
  627. nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  628. genlmsg_attrlen(gnlh, 0), NULL);
  629. nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
  630. if (nl_vend) {
  631. struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
  632. nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
  633. nla_data(nl_vend), nla_len(nl_vend), NULL);
  634. attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
  635. if (attr) {
  636. info->flags = nla_data(attr);
  637. info->flags_len = nla_len(attr);
  638. }
  639. attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA];
  640. if (attr)
  641. info->capa->conc_capab = nla_get_u32(attr);
  642. attr = tb_vendor[
  643. QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND];
  644. if (attr)
  645. info->capa->max_conc_chan_2_4 = nla_get_u32(attr);
  646. attr = tb_vendor[
  647. QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND];
  648. if (attr)
  649. info->capa->max_conc_chan_5_0 = nla_get_u32(attr);
  650. }
  651. return NL_SKIP;
  652. }
  653. static int check_feature(enum qca_wlan_vendor_features feature,
  654. struct features_info *info)
  655. {
  656. size_t idx = feature / 8;
  657. return (idx < info->flags_len) &&
  658. (info->flags[idx] & BIT(feature % 8));
  659. }
  660. static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
  661. {
  662. struct nl_msg *msg;
  663. struct features_info info;
  664. int ret;
  665. if (!drv->get_features_vendor_cmd_avail)
  666. return;
  667. if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
  668. nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
  669. nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
  670. QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
  671. nlmsg_free(msg);
  672. return;
  673. }
  674. os_memset(&info, 0, sizeof(info));
  675. info.capa = &drv->capa;
  676. ret = send_and_recv_msgs(drv, msg, features_info_handler, &info);
  677. if (ret || !info.flags)
  678. return;
  679. if (check_feature(QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD, &info))
  680. drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD;
  681. if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
  682. drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
  683. }
  684. int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
  685. {
  686. struct wiphy_info_data info;
  687. if (wpa_driver_nl80211_get_info(drv, &info))
  688. return -1;
  689. if (info.error)
  690. return -1;
  691. drv->has_capability = 1;
  692. drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
  693. WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
  694. WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
  695. WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
  696. WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
  697. WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
  698. drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
  699. WPA_DRIVER_AUTH_SHARED |
  700. WPA_DRIVER_AUTH_LEAP;
  701. drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
  702. drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
  703. drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
  704. /*
  705. * As all cfg80211 drivers must support cases where the AP interface is
  706. * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
  707. * case that the user space daemon has crashed, they must be able to
  708. * cleanup all stations and key entries in the AP tear down flow. Thus,
  709. * this flag can/should always be set for cfg80211 drivers.
  710. */
  711. drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
  712. if (!info.device_ap_sme) {
  713. drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
  714. /*
  715. * No AP SME is currently assumed to also indicate no AP MLME
  716. * in the driver/firmware.
  717. */
  718. drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
  719. }
  720. drv->device_ap_sme = info.device_ap_sme;
  721. drv->poll_command_supported = info.poll_command_supported;
  722. drv->data_tx_status = info.data_tx_status;
  723. drv->p2p_go_ctwindow_supported = info.p2p_go_ctwindow_supported;
  724. if (info.set_qos_map_supported)
  725. drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
  726. drv->have_low_prio_scan = info.have_low_prio_scan;
  727. /*
  728. * If poll command and tx status are supported, mac80211 is new enough
  729. * to have everything we need to not need monitor interfaces.
  730. */
  731. drv->use_monitor = !info.poll_command_supported || !info.data_tx_status;
  732. if (drv->device_ap_sme && drv->use_monitor) {
  733. /*
  734. * Non-mac80211 drivers may not support monitor interface.
  735. * Make sure we do not get stuck with incorrect capability here
  736. * by explicitly testing this.
  737. */
  738. if (!info.monitor_supported) {
  739. wpa_printf(MSG_DEBUG, "nl80211: Disable use_monitor "
  740. "with device_ap_sme since no monitor mode "
  741. "support detected");
  742. drv->use_monitor = 0;
  743. }
  744. }
  745. /*
  746. * If we aren't going to use monitor interfaces, but the
  747. * driver doesn't support data TX status, we won't get TX
  748. * status for EAPOL frames.
  749. */
  750. if (!drv->use_monitor && !info.data_tx_status)
  751. drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
  752. qca_nl80211_check_dfs_capa(drv);
  753. qca_nl80211_get_features(drv);
  754. return 0;
  755. }
  756. struct phy_info_arg {
  757. u16 *num_modes;
  758. struct hostapd_hw_modes *modes;
  759. int last_mode, last_chan_idx;
  760. };
  761. static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
  762. struct nlattr *ampdu_factor,
  763. struct nlattr *ampdu_density,
  764. struct nlattr *mcs_set)
  765. {
  766. if (capa)
  767. mode->ht_capab = nla_get_u16(capa);
  768. if (ampdu_factor)
  769. mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
  770. if (ampdu_density)
  771. mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
  772. if (mcs_set && nla_len(mcs_set) >= 16) {
  773. u8 *mcs;
  774. mcs = nla_data(mcs_set);
  775. os_memcpy(mode->mcs_set, mcs, 16);
  776. }
  777. }
  778. static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
  779. struct nlattr *capa,
  780. struct nlattr *mcs_set)
  781. {
  782. if (capa)
  783. mode->vht_capab = nla_get_u32(capa);
  784. if (mcs_set && nla_len(mcs_set) >= 8) {
  785. u8 *mcs;
  786. mcs = nla_data(mcs_set);
  787. os_memcpy(mode->vht_mcs_set, mcs, 8);
  788. }
  789. }
  790. static void phy_info_freq(struct hostapd_hw_modes *mode,
  791. struct hostapd_channel_data *chan,
  792. struct nlattr *tb_freq[])
  793. {
  794. u8 channel;
  795. chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
  796. chan->flag = 0;
  797. chan->dfs_cac_ms = 0;
  798. if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
  799. chan->chan = channel;
  800. if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
  801. chan->flag |= HOSTAPD_CHAN_DISABLED;
  802. if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
  803. chan->flag |= HOSTAPD_CHAN_NO_IR;
  804. if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
  805. chan->flag |= HOSTAPD_CHAN_RADAR;
  806. if (tb_freq[NL80211_FREQUENCY_ATTR_INDOOR_ONLY])
  807. chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
  808. if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT])
  809. chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
  810. if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
  811. enum nl80211_dfs_state state =
  812. nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
  813. switch (state) {
  814. case NL80211_DFS_USABLE:
  815. chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
  816. break;
  817. case NL80211_DFS_AVAILABLE:
  818. chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
  819. break;
  820. case NL80211_DFS_UNAVAILABLE:
  821. chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
  822. break;
  823. }
  824. }
  825. if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
  826. chan->dfs_cac_ms = nla_get_u32(
  827. tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
  828. }
  829. }
  830. static int phy_info_freqs(struct phy_info_arg *phy_info,
  831. struct hostapd_hw_modes *mode, struct nlattr *tb)
  832. {
  833. static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
  834. [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
  835. [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
  836. [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
  837. [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
  838. [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
  839. [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
  840. };
  841. int new_channels = 0;
  842. struct hostapd_channel_data *channel;
  843. struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
  844. struct nlattr *nl_freq;
  845. int rem_freq, idx;
  846. if (tb == NULL)
  847. return NL_OK;
  848. nla_for_each_nested(nl_freq, tb, rem_freq) {
  849. nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
  850. nla_data(nl_freq), nla_len(nl_freq), freq_policy);
  851. if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
  852. continue;
  853. new_channels++;
  854. }
  855. channel = os_realloc_array(mode->channels,
  856. mode->num_channels + new_channels,
  857. sizeof(struct hostapd_channel_data));
  858. if (!channel)
  859. return NL_SKIP;
  860. mode->channels = channel;
  861. mode->num_channels += new_channels;
  862. idx = phy_info->last_chan_idx;
  863. nla_for_each_nested(nl_freq, tb, rem_freq) {
  864. nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
  865. nla_data(nl_freq), nla_len(nl_freq), freq_policy);
  866. if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
  867. continue;
  868. phy_info_freq(mode, &mode->channels[idx], tb_freq);
  869. idx++;
  870. }
  871. phy_info->last_chan_idx = idx;
  872. return NL_OK;
  873. }
  874. static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
  875. {
  876. static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
  877. [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
  878. [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
  879. { .type = NLA_FLAG },
  880. };
  881. struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
  882. struct nlattr *nl_rate;
  883. int rem_rate, idx;
  884. if (tb == NULL)
  885. return NL_OK;
  886. nla_for_each_nested(nl_rate, tb, rem_rate) {
  887. nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
  888. nla_data(nl_rate), nla_len(nl_rate),
  889. rate_policy);
  890. if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
  891. continue;
  892. mode->num_rates++;
  893. }
  894. mode->rates = os_calloc(mode->num_rates, sizeof(int));
  895. if (!mode->rates)
  896. return NL_SKIP;
  897. idx = 0;
  898. nla_for_each_nested(nl_rate, tb, rem_rate) {
  899. nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
  900. nla_data(nl_rate), nla_len(nl_rate),
  901. rate_policy);
  902. if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
  903. continue;
  904. mode->rates[idx] = nla_get_u32(
  905. tb_rate[NL80211_BITRATE_ATTR_RATE]);
  906. idx++;
  907. }
  908. return NL_OK;
  909. }
  910. static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
  911. {
  912. struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
  913. struct hostapd_hw_modes *mode;
  914. int ret;
  915. if (phy_info->last_mode != nl_band->nla_type) {
  916. mode = os_realloc_array(phy_info->modes,
  917. *phy_info->num_modes + 1,
  918. sizeof(*mode));
  919. if (!mode)
  920. return NL_SKIP;
  921. phy_info->modes = mode;
  922. mode = &phy_info->modes[*(phy_info->num_modes)];
  923. os_memset(mode, 0, sizeof(*mode));
  924. mode->mode = NUM_HOSTAPD_MODES;
  925. mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
  926. HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
  927. /*
  928. * Unsupported VHT MCS stream is defined as value 3, so the VHT
  929. * MCS RX/TX map must be initialized with 0xffff to mark all 8
  930. * possible streams as unsupported. This will be overridden if
  931. * driver advertises VHT support.
  932. */
  933. mode->vht_mcs_set[0] = 0xff;
  934. mode->vht_mcs_set[1] = 0xff;
  935. mode->vht_mcs_set[4] = 0xff;
  936. mode->vht_mcs_set[5] = 0xff;
  937. *(phy_info->num_modes) += 1;
  938. phy_info->last_mode = nl_band->nla_type;
  939. phy_info->last_chan_idx = 0;
  940. } else
  941. mode = &phy_info->modes[*(phy_info->num_modes) - 1];
  942. nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
  943. nla_len(nl_band), NULL);
  944. phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
  945. tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
  946. tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
  947. tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
  948. phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
  949. tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
  950. ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
  951. if (ret != NL_OK)
  952. return ret;
  953. ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
  954. if (ret != NL_OK)
  955. return ret;
  956. return NL_OK;
  957. }
  958. static int phy_info_handler(struct nl_msg *msg, void *arg)
  959. {
  960. struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
  961. struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  962. struct phy_info_arg *phy_info = arg;
  963. struct nlattr *nl_band;
  964. int rem_band;
  965. nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  966. genlmsg_attrlen(gnlh, 0), NULL);
  967. if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
  968. return NL_SKIP;
  969. nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
  970. {
  971. int res = phy_info_band(phy_info, nl_band);
  972. if (res != NL_OK)
  973. return res;
  974. }
  975. return NL_SKIP;
  976. }
  977. static struct hostapd_hw_modes *
  978. wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
  979. u16 *num_modes)
  980. {
  981. u16 m;
  982. struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
  983. int i, mode11g_idx = -1;
  984. /* heuristic to set up modes */
  985. for (m = 0; m < *num_modes; m++) {
  986. if (!modes[m].num_channels)
  987. continue;
  988. if (modes[m].channels[0].freq < 4000) {
  989. modes[m].mode = HOSTAPD_MODE_IEEE80211B;
  990. for (i = 0; i < modes[m].num_rates; i++) {
  991. if (modes[m].rates[i] > 200) {
  992. modes[m].mode = HOSTAPD_MODE_IEEE80211G;
  993. break;
  994. }
  995. }
  996. } else if (modes[m].channels[0].freq > 50000)
  997. modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
  998. else
  999. modes[m].mode = HOSTAPD_MODE_IEEE80211A;
  1000. }
  1001. /* If only 802.11g mode is included, use it to construct matching
  1002. * 802.11b mode data. */
  1003. for (m = 0; m < *num_modes; m++) {
  1004. if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
  1005. return modes; /* 802.11b already included */
  1006. if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
  1007. mode11g_idx = m;
  1008. }
  1009. if (mode11g_idx < 0)
  1010. return modes; /* 2.4 GHz band not supported at all */
  1011. nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
  1012. if (nmodes == NULL)
  1013. return modes; /* Could not add 802.11b mode */
  1014. mode = &nmodes[*num_modes];
  1015. os_memset(mode, 0, sizeof(*mode));
  1016. (*num_modes)++;
  1017. modes = nmodes;
  1018. mode->mode = HOSTAPD_MODE_IEEE80211B;
  1019. mode11g = &modes[mode11g_idx];
  1020. mode->num_channels = mode11g->num_channels;
  1021. mode->channels = os_malloc(mode11g->num_channels *
  1022. sizeof(struct hostapd_channel_data));
  1023. if (mode->channels == NULL) {
  1024. (*num_modes)--;
  1025. return modes; /* Could not add 802.11b mode */
  1026. }
  1027. os_memcpy(mode->channels, mode11g->channels,
  1028. mode11g->num_channels * sizeof(struct hostapd_channel_data));
  1029. mode->num_rates = 0;
  1030. mode->rates = os_malloc(4 * sizeof(int));
  1031. if (mode->rates == NULL) {
  1032. os_free(mode->channels);
  1033. (*num_modes)--;
  1034. return modes; /* Could not add 802.11b mode */
  1035. }
  1036. for (i = 0; i < mode11g->num_rates; i++) {
  1037. if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
  1038. mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
  1039. continue;
  1040. mode->rates[mode->num_rates] = mode11g->rates[i];
  1041. mode->num_rates++;
  1042. if (mode->num_rates == 4)
  1043. break;
  1044. }
  1045. if (mode->num_rates == 0) {
  1046. os_free(mode->channels);
  1047. os_free(mode->rates);
  1048. (*num_modes)--;
  1049. return modes; /* No 802.11b rates */
  1050. }
  1051. wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
  1052. "information");
  1053. return modes;
  1054. }
  1055. static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
  1056. int end)
  1057. {
  1058. int c;
  1059. for (c = 0; c < mode->num_channels; c++) {
  1060. struct hostapd_channel_data *chan = &mode->channels[c];
  1061. if (chan->freq - 10 >= start && chan->freq + 10 <= end)
  1062. chan->flag |= HOSTAPD_CHAN_HT40;
  1063. }
  1064. }
  1065. static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
  1066. int end)
  1067. {
  1068. int c;
  1069. for (c = 0; c < mode->num_channels; c++) {
  1070. struct hostapd_channel_data *chan = &mode->channels[c];
  1071. if (!(chan->flag & HOSTAPD_CHAN_HT40))
  1072. continue;
  1073. if (chan->freq - 30 >= start && chan->freq - 10 <= end)
  1074. chan->flag |= HOSTAPD_CHAN_HT40MINUS;
  1075. if (chan->freq + 10 >= start && chan->freq + 30 <= end)
  1076. chan->flag |= HOSTAPD_CHAN_HT40PLUS;
  1077. }
  1078. }
  1079. static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
  1080. struct phy_info_arg *results)
  1081. {
  1082. u16 m;
  1083. for (m = 0; m < *results->num_modes; m++) {
  1084. int c;
  1085. struct hostapd_hw_modes *mode = &results->modes[m];
  1086. for (c = 0; c < mode->num_channels; c++) {
  1087. struct hostapd_channel_data *chan = &mode->channels[c];
  1088. if ((u32) chan->freq - 10 >= start &&
  1089. (u32) chan->freq + 10 <= end)
  1090. chan->max_tx_power = max_eirp;
  1091. }
  1092. }
  1093. }
  1094. static void nl80211_reg_rule_ht40(u32 start, u32 end,
  1095. struct phy_info_arg *results)
  1096. {
  1097. u16 m;
  1098. for (m = 0; m < *results->num_modes; m++) {
  1099. if (!(results->modes[m].ht_capab &
  1100. HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
  1101. continue;
  1102. nl80211_set_ht40_mode(&results->modes[m], start, end);
  1103. }
  1104. }
  1105. static void nl80211_reg_rule_sec(struct nlattr *tb[],
  1106. struct phy_info_arg *results)
  1107. {
  1108. u32 start, end, max_bw;
  1109. u16 m;
  1110. if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
  1111. tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
  1112. tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
  1113. return;
  1114. start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
  1115. end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
  1116. max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
  1117. if (max_bw < 20)
  1118. return;
  1119. for (m = 0; m < *results->num_modes; m++) {
  1120. if (!(results->modes[m].ht_capab &
  1121. HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
  1122. continue;
  1123. nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
  1124. }
  1125. }
  1126. static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
  1127. int end)
  1128. {
  1129. int c;
  1130. for (c = 0; c < mode->num_channels; c++) {
  1131. struct hostapd_channel_data *chan = &mode->channels[c];
  1132. if (chan->freq - 10 >= start && chan->freq + 70 <= end)
  1133. chan->flag |= HOSTAPD_CHAN_VHT_10_70;
  1134. if (chan->freq - 30 >= start && chan->freq + 50 <= end)
  1135. chan->flag |= HOSTAPD_CHAN_VHT_30_50;
  1136. if (chan->freq - 50 >= start && chan->freq + 30 <= end)
  1137. chan->flag |= HOSTAPD_CHAN_VHT_50_30;
  1138. if (chan->freq - 70 >= start && chan->freq + 10 <= end)
  1139. chan->flag |= HOSTAPD_CHAN_VHT_70_10;
  1140. }
  1141. }
  1142. static void nl80211_reg_rule_vht(struct nlattr *tb[],
  1143. struct phy_info_arg *results)
  1144. {
  1145. u32 start, end, max_bw;
  1146. u16 m;
  1147. if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
  1148. tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
  1149. tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
  1150. return;
  1151. start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
  1152. end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
  1153. max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
  1154. if (max_bw < 80)
  1155. return;
  1156. for (m = 0; m < *results->num_modes; m++) {
  1157. if (!(results->modes[m].ht_capab &
  1158. HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
  1159. continue;
  1160. /* TODO: use a real VHT support indication */
  1161. if (!results->modes[m].vht_capab)
  1162. continue;
  1163. nl80211_set_vht_mode(&results->modes[m], start, end);
  1164. }
  1165. }
  1166. static const char * dfs_domain_name(enum nl80211_dfs_regions region)
  1167. {
  1168. switch (region) {
  1169. case NL80211_DFS_UNSET:
  1170. return "DFS-UNSET";
  1171. case NL80211_DFS_FCC:
  1172. return "DFS-FCC";
  1173. case NL80211_DFS_ETSI:
  1174. return "DFS-ETSI";
  1175. case NL80211_DFS_JP:
  1176. return "DFS-JP";
  1177. default:
  1178. return "DFS-invalid";
  1179. }
  1180. }
  1181. static int nl80211_get_reg(struct nl_msg *msg, void *arg)
  1182. {
  1183. struct phy_info_arg *results = arg;
  1184. struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
  1185. struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  1186. struct nlattr *nl_rule;
  1187. struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
  1188. int rem_rule;
  1189. static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
  1190. [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
  1191. [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
  1192. [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
  1193. [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
  1194. [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
  1195. [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
  1196. };
  1197. nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  1198. genlmsg_attrlen(gnlh, 0), NULL);
  1199. if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
  1200. !tb_msg[NL80211_ATTR_REG_RULES]) {
  1201. wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
  1202. "available");
  1203. return NL_SKIP;
  1204. }
  1205. if (tb_msg[NL80211_ATTR_DFS_REGION]) {
  1206. enum nl80211_dfs_regions dfs_domain;
  1207. dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
  1208. wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
  1209. (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
  1210. dfs_domain_name(dfs_domain));
  1211. } else {
  1212. wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
  1213. (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
  1214. }
  1215. nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
  1216. {
  1217. u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
  1218. nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
  1219. nla_data(nl_rule), nla_len(nl_rule), reg_policy);
  1220. if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
  1221. tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
  1222. continue;
  1223. start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
  1224. end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
  1225. if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
  1226. max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
  1227. if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
  1228. max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
  1229. if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
  1230. flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
  1231. wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
  1232. start, end, max_bw, max_eirp,
  1233. flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
  1234. flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
  1235. flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
  1236. flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
  1237. "",
  1238. flags & NL80211_RRF_DFS ? " (DFS)" : "",
  1239. flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
  1240. flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
  1241. flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
  1242. if (max_bw >= 40)
  1243. nl80211_reg_rule_ht40(start, end, results);
  1244. if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
  1245. nl80211_reg_rule_max_eirp(start, end, max_eirp,
  1246. results);
  1247. }
  1248. nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
  1249. {
  1250. nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
  1251. nla_data(nl_rule), nla_len(nl_rule), reg_policy);
  1252. nl80211_reg_rule_sec(tb_rule, results);
  1253. }
  1254. nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
  1255. {
  1256. nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
  1257. nla_data(nl_rule), nla_len(nl_rule), reg_policy);
  1258. nl80211_reg_rule_vht(tb_rule, results);
  1259. }
  1260. return NL_SKIP;
  1261. }
  1262. static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
  1263. struct phy_info_arg *results)
  1264. {
  1265. struct nl_msg *msg;
  1266. msg = nlmsg_alloc();
  1267. if (!msg)
  1268. return -ENOMEM;
  1269. nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
  1270. return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
  1271. }
  1272. struct hostapd_hw_modes *
  1273. nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
  1274. {
  1275. u32 feat;
  1276. struct i802_bss *bss = priv;
  1277. struct wpa_driver_nl80211_data *drv = bss->drv;
  1278. int nl_flags = 0;
  1279. struct nl_msg *msg;
  1280. struct phy_info_arg result = {
  1281. .num_modes = num_modes,
  1282. .modes = NULL,
  1283. .last_mode = -1,
  1284. };
  1285. *num_modes = 0;
  1286. *flags = 0;
  1287. feat = get_nl80211_protocol_features(drv);
  1288. if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
  1289. nl_flags = NLM_F_DUMP;
  1290. if (!(msg = nl80211_cmd_msg(bss, nl_flags, NL80211_CMD_GET_WIPHY)) ||
  1291. nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
  1292. nlmsg_free(msg);
  1293. return NULL;
  1294. }
  1295. if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
  1296. nl80211_set_regulatory_flags(drv, &result);
  1297. return wpa_driver_nl80211_postprocess_modes(result.modes,
  1298. num_modes);
  1299. }
  1300. return NULL;
  1301. }