driver_nl80211_capa.c 49 KB

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