driver_nl80211_capa.c 39 KB

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