cfg80211.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328
  1. /*
  2. * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <linux/etherdevice.h>
  17. #include <linux/moduleparam.h>
  18. #include <net/netlink.h>
  19. #include "wil6210.h"
  20. #include "wmi.h"
  21. #define WIL_MAX_ROC_DURATION_MS 5000
  22. bool disable_ap_sme;
  23. module_param(disable_ap_sme, bool, 0444);
  24. MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
  25. #ifdef CONFIG_PM
  26. static struct wiphy_wowlan_support wil_wowlan_support = {
  27. .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
  28. };
  29. #endif
  30. #define CHAN60G(_channel, _flags) { \
  31. .band = NL80211_BAND_60GHZ, \
  32. .center_freq = 56160 + (2160 * (_channel)), \
  33. .hw_value = (_channel), \
  34. .flags = (_flags), \
  35. .max_antenna_gain = 0, \
  36. .max_power = 40, \
  37. }
  38. static struct ieee80211_channel wil_60ghz_channels[] = {
  39. CHAN60G(1, 0),
  40. CHAN60G(2, 0),
  41. CHAN60G(3, 0),
  42. /* channel 4 not supported yet */
  43. };
  44. /* Vendor id to be used in vendor specific command and events
  45. * to user space.
  46. * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
  47. * vendor subcmd definitions prefixed with QCA_NL80211_VENDOR_SUBCMD, and
  48. * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in
  49. * git://w1.fi/srv/git/hostap.git; the values here are just a copy of that
  50. */
  51. #define QCA_NL80211_VENDOR_ID 0x001374
  52. #define WIL_MAX_RF_SECTORS (128)
  53. #define WIL_CID_ALL (0xff)
  54. enum qca_wlan_vendor_attr_rf_sector {
  55. QCA_ATTR_MAC_ADDR = 6,
  56. QCA_ATTR_PAD = 13,
  57. QCA_ATTR_TSF = 29,
  58. QCA_ATTR_DMG_RF_SECTOR_INDEX = 30,
  59. QCA_ATTR_DMG_RF_SECTOR_TYPE = 31,
  60. QCA_ATTR_DMG_RF_MODULE_MASK = 32,
  61. QCA_ATTR_DMG_RF_SECTOR_CFG = 33,
  62. QCA_ATTR_DMG_RF_SECTOR_MAX,
  63. };
  64. enum qca_wlan_vendor_attr_dmg_rf_sector_type {
  65. QCA_ATTR_DMG_RF_SECTOR_TYPE_RX,
  66. QCA_ATTR_DMG_RF_SECTOR_TYPE_TX,
  67. QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX
  68. };
  69. enum qca_wlan_vendor_attr_dmg_rf_sector_cfg {
  70. QCA_ATTR_DMG_RF_SECTOR_CFG_INVALID = 0,
  71. QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX,
  72. QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0,
  73. QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1,
  74. QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2,
  75. QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI,
  76. QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO,
  77. QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16,
  78. /* keep last */
  79. QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST,
  80. QCA_ATTR_DMG_RF_SECTOR_CFG_MAX =
  81. QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST - 1
  82. };
  83. static const struct
  84. nla_policy wil_rf_sector_policy[QCA_ATTR_DMG_RF_SECTOR_MAX + 1] = {
  85. [QCA_ATTR_MAC_ADDR] = { .len = ETH_ALEN },
  86. [QCA_ATTR_DMG_RF_SECTOR_INDEX] = { .type = NLA_U16 },
  87. [QCA_ATTR_DMG_RF_SECTOR_TYPE] = { .type = NLA_U8 },
  88. [QCA_ATTR_DMG_RF_MODULE_MASK] = { .type = NLA_U32 },
  89. [QCA_ATTR_DMG_RF_SECTOR_CFG] = { .type = NLA_NESTED },
  90. };
  91. static const struct
  92. nla_policy wil_rf_sector_cfg_policy[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1] = {
  93. [QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX] = { .type = NLA_U8 },
  94. [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0] = { .type = NLA_U32 },
  95. [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1] = { .type = NLA_U32 },
  96. [QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2] = { .type = NLA_U32 },
  97. [QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI] = { .type = NLA_U32 },
  98. [QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO] = { .type = NLA_U32 },
  99. [QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16] = { .type = NLA_U32 },
  100. };
  101. enum qca_nl80211_vendor_subcmds {
  102. QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG = 139,
  103. QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG = 140,
  104. QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR = 141,
  105. QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR = 142,
  106. };
  107. static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
  108. struct wireless_dev *wdev,
  109. const void *data, int data_len);
  110. static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
  111. struct wireless_dev *wdev,
  112. const void *data, int data_len);
  113. static int wil_rf_sector_get_selected(struct wiphy *wiphy,
  114. struct wireless_dev *wdev,
  115. const void *data, int data_len);
  116. static int wil_rf_sector_set_selected(struct wiphy *wiphy,
  117. struct wireless_dev *wdev,
  118. const void *data, int data_len);
  119. /* vendor specific commands */
  120. static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
  121. {
  122. .info.vendor_id = QCA_NL80211_VENDOR_ID,
  123. .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG,
  124. .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
  125. WIPHY_VENDOR_CMD_NEED_RUNNING,
  126. .doit = wil_rf_sector_get_cfg
  127. },
  128. {
  129. .info.vendor_id = QCA_NL80211_VENDOR_ID,
  130. .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG,
  131. .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
  132. WIPHY_VENDOR_CMD_NEED_RUNNING,
  133. .doit = wil_rf_sector_set_cfg
  134. },
  135. {
  136. .info.vendor_id = QCA_NL80211_VENDOR_ID,
  137. .info.subcmd =
  138. QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR,
  139. .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
  140. WIPHY_VENDOR_CMD_NEED_RUNNING,
  141. .doit = wil_rf_sector_get_selected
  142. },
  143. {
  144. .info.vendor_id = QCA_NL80211_VENDOR_ID,
  145. .info.subcmd =
  146. QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR,
  147. .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
  148. WIPHY_VENDOR_CMD_NEED_RUNNING,
  149. .doit = wil_rf_sector_set_selected
  150. },
  151. };
  152. static struct ieee80211_supported_band wil_band_60ghz = {
  153. .channels = wil_60ghz_channels,
  154. .n_channels = ARRAY_SIZE(wil_60ghz_channels),
  155. .ht_cap = {
  156. .ht_supported = true,
  157. .cap = 0, /* TODO */
  158. .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, /* TODO */
  159. .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, /* TODO */
  160. .mcs = {
  161. /* MCS 1..12 - SC PHY */
  162. .rx_mask = {0xfe, 0x1f}, /* 1..12 */
  163. .tx_params = IEEE80211_HT_MCS_TX_DEFINED, /* TODO */
  164. },
  165. },
  166. };
  167. static const struct ieee80211_txrx_stypes
  168. wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
  169. [NL80211_IFTYPE_STATION] = {
  170. .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  171. BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  172. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  173. BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  174. },
  175. [NL80211_IFTYPE_AP] = {
  176. .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  177. BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
  178. BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
  179. BIT(IEEE80211_STYPE_DISASSOC >> 4),
  180. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  181. BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  182. BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  183. BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  184. BIT(IEEE80211_STYPE_AUTH >> 4) |
  185. BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  186. BIT(IEEE80211_STYPE_REASSOC_REQ >> 4)
  187. },
  188. [NL80211_IFTYPE_P2P_CLIENT] = {
  189. .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  190. BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  191. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  192. BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  193. },
  194. [NL80211_IFTYPE_P2P_GO] = {
  195. .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  196. BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  197. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  198. BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  199. },
  200. [NL80211_IFTYPE_P2P_DEVICE] = {
  201. .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  202. BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  203. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  204. BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  205. },
  206. };
  207. static const u32 wil_cipher_suites[] = {
  208. WLAN_CIPHER_SUITE_GCMP,
  209. };
  210. static const char * const key_usage_str[] = {
  211. [WMI_KEY_USE_PAIRWISE] = "PTK",
  212. [WMI_KEY_USE_RX_GROUP] = "RX_GTK",
  213. [WMI_KEY_USE_TX_GROUP] = "TX_GTK",
  214. };
  215. int wil_iftype_nl2wmi(enum nl80211_iftype type)
  216. {
  217. static const struct {
  218. enum nl80211_iftype nl;
  219. enum wmi_network_type wmi;
  220. } __nl2wmi[] = {
  221. {NL80211_IFTYPE_ADHOC, WMI_NETTYPE_ADHOC},
  222. {NL80211_IFTYPE_STATION, WMI_NETTYPE_INFRA},
  223. {NL80211_IFTYPE_AP, WMI_NETTYPE_AP},
  224. {NL80211_IFTYPE_P2P_CLIENT, WMI_NETTYPE_P2P},
  225. {NL80211_IFTYPE_P2P_GO, WMI_NETTYPE_P2P},
  226. {NL80211_IFTYPE_MONITOR, WMI_NETTYPE_ADHOC}, /* FIXME */
  227. };
  228. uint i;
  229. for (i = 0; i < ARRAY_SIZE(__nl2wmi); i++) {
  230. if (__nl2wmi[i].nl == type)
  231. return __nl2wmi[i].wmi;
  232. }
  233. return -EOPNOTSUPP;
  234. }
  235. int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
  236. struct station_info *sinfo)
  237. {
  238. struct wmi_notify_req_cmd cmd = {
  239. .cid = cid,
  240. .interval_usec = 0,
  241. };
  242. struct {
  243. struct wmi_cmd_hdr wmi;
  244. struct wmi_notify_req_done_event evt;
  245. } __packed reply;
  246. struct wil_net_stats *stats = &wil->sta[cid].stats;
  247. int rc;
  248. rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
  249. WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
  250. if (rc)
  251. return rc;
  252. wil_dbg_wmi(wil, "Link status for CID %d: {\n"
  253. " MCS %d TSF 0x%016llx\n"
  254. " BF status 0x%08x RSSI %d SQI %d%%\n"
  255. " Tx Tpt %d goodput %d Rx goodput %d\n"
  256. " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
  257. cid, le16_to_cpu(reply.evt.bf_mcs),
  258. le64_to_cpu(reply.evt.tsf), reply.evt.status,
  259. reply.evt.rssi,
  260. reply.evt.sqi,
  261. le32_to_cpu(reply.evt.tx_tpt),
  262. le32_to_cpu(reply.evt.tx_goodput),
  263. le32_to_cpu(reply.evt.rx_goodput),
  264. le16_to_cpu(reply.evt.my_rx_sector),
  265. le16_to_cpu(reply.evt.my_tx_sector),
  266. le16_to_cpu(reply.evt.other_rx_sector),
  267. le16_to_cpu(reply.evt.other_tx_sector));
  268. sinfo->generation = wil->sinfo_gen;
  269. sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) |
  270. BIT(NL80211_STA_INFO_TX_BYTES) |
  271. BIT(NL80211_STA_INFO_RX_PACKETS) |
  272. BIT(NL80211_STA_INFO_TX_PACKETS) |
  273. BIT(NL80211_STA_INFO_RX_BITRATE) |
  274. BIT(NL80211_STA_INFO_TX_BITRATE) |
  275. BIT(NL80211_STA_INFO_RX_DROP_MISC) |
  276. BIT(NL80211_STA_INFO_TX_FAILED);
  277. sinfo->txrate.flags = RATE_INFO_FLAGS_60G;
  278. sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
  279. sinfo->rxrate.mcs = stats->last_mcs_rx;
  280. sinfo->rx_bytes = stats->rx_bytes;
  281. sinfo->rx_packets = stats->rx_packets;
  282. sinfo->rx_dropped_misc = stats->rx_dropped;
  283. sinfo->tx_bytes = stats->tx_bytes;
  284. sinfo->tx_packets = stats->tx_packets;
  285. sinfo->tx_failed = stats->tx_errors;
  286. if (test_bit(wil_status_fwconnected, wil->status)) {
  287. sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
  288. if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING,
  289. wil->fw_capabilities))
  290. sinfo->signal = reply.evt.rssi;
  291. else
  292. sinfo->signal = reply.evt.sqi;
  293. }
  294. return rc;
  295. }
  296. static int wil_cfg80211_get_station(struct wiphy *wiphy,
  297. struct net_device *ndev,
  298. const u8 *mac, struct station_info *sinfo)
  299. {
  300. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  301. int rc;
  302. int cid = wil_find_cid(wil, mac);
  303. wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid);
  304. if (cid < 0)
  305. return cid;
  306. rc = wil_cid_fill_sinfo(wil, cid, sinfo);
  307. return rc;
  308. }
  309. /*
  310. * Find @idx-th active STA for station dump.
  311. */
  312. static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx)
  313. {
  314. int i;
  315. for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
  316. if (wil->sta[i].status == wil_sta_unused)
  317. continue;
  318. if (idx == 0)
  319. return i;
  320. idx--;
  321. }
  322. return -ENOENT;
  323. }
  324. static int wil_cfg80211_dump_station(struct wiphy *wiphy,
  325. struct net_device *dev, int idx,
  326. u8 *mac, struct station_info *sinfo)
  327. {
  328. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  329. int rc;
  330. int cid = wil_find_cid_by_idx(wil, idx);
  331. if (cid < 0)
  332. return -ENOENT;
  333. ether_addr_copy(mac, wil->sta[cid].addr);
  334. wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid);
  335. rc = wil_cid_fill_sinfo(wil, cid, sinfo);
  336. return rc;
  337. }
  338. static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
  339. struct wireless_dev *wdev)
  340. {
  341. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  342. wil_dbg_misc(wil, "start_p2p_device: entered\n");
  343. wil->p2p.p2p_dev_started = 1;
  344. return 0;
  345. }
  346. static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
  347. struct wireless_dev *wdev)
  348. {
  349. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  350. struct wil_p2p_info *p2p = &wil->p2p;
  351. if (!p2p->p2p_dev_started)
  352. return;
  353. wil_dbg_misc(wil, "stop_p2p_device: entered\n");
  354. mutex_lock(&wil->mutex);
  355. mutex_lock(&wil->p2p_wdev_mutex);
  356. wil_p2p_stop_radio_operations(wil);
  357. p2p->p2p_dev_started = 0;
  358. mutex_unlock(&wil->p2p_wdev_mutex);
  359. mutex_unlock(&wil->mutex);
  360. }
  361. static struct wireless_dev *
  362. wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
  363. unsigned char name_assign_type,
  364. enum nl80211_iftype type,
  365. struct vif_params *params)
  366. {
  367. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  368. struct net_device *ndev = wil_to_ndev(wil);
  369. struct wireless_dev *p2p_wdev;
  370. wil_dbg_misc(wil, "add_iface\n");
  371. if (type != NL80211_IFTYPE_P2P_DEVICE) {
  372. wil_err(wil, "unsupported iftype %d\n", type);
  373. return ERR_PTR(-EINVAL);
  374. }
  375. if (wil->p2p_wdev) {
  376. wil_err(wil, "P2P_DEVICE interface already created\n");
  377. return ERR_PTR(-EINVAL);
  378. }
  379. p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL);
  380. if (!p2p_wdev)
  381. return ERR_PTR(-ENOMEM);
  382. p2p_wdev->iftype = type;
  383. p2p_wdev->wiphy = wiphy;
  384. /* use our primary ethernet address */
  385. ether_addr_copy(p2p_wdev->address, ndev->perm_addr);
  386. wil->p2p_wdev = p2p_wdev;
  387. return p2p_wdev;
  388. }
  389. static int wil_cfg80211_del_iface(struct wiphy *wiphy,
  390. struct wireless_dev *wdev)
  391. {
  392. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  393. wil_dbg_misc(wil, "del_iface\n");
  394. if (wdev != wil->p2p_wdev) {
  395. wil_err(wil, "delete of incorrect interface 0x%p\n", wdev);
  396. return -EINVAL;
  397. }
  398. wil_cfg80211_stop_p2p_device(wiphy, wdev);
  399. wil_p2p_wdev_free(wil);
  400. return 0;
  401. }
  402. static int wil_cfg80211_change_iface(struct wiphy *wiphy,
  403. struct net_device *ndev,
  404. enum nl80211_iftype type,
  405. struct vif_params *params)
  406. {
  407. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  408. struct wireless_dev *wdev = wil_to_wdev(wil);
  409. int rc;
  410. wil_dbg_misc(wil, "change_iface: type=%d\n", type);
  411. if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) {
  412. wil_dbg_misc(wil, "interface is up. resetting...\n");
  413. mutex_lock(&wil->mutex);
  414. __wil_down(wil);
  415. rc = __wil_up(wil);
  416. mutex_unlock(&wil->mutex);
  417. if (rc)
  418. return rc;
  419. }
  420. switch (type) {
  421. case NL80211_IFTYPE_STATION:
  422. case NL80211_IFTYPE_AP:
  423. case NL80211_IFTYPE_P2P_CLIENT:
  424. case NL80211_IFTYPE_P2P_GO:
  425. break;
  426. case NL80211_IFTYPE_MONITOR:
  427. if (params->flags)
  428. wil->monitor_flags = params->flags;
  429. break;
  430. default:
  431. return -EOPNOTSUPP;
  432. }
  433. wdev->iftype = type;
  434. return 0;
  435. }
  436. static int wil_cfg80211_scan(struct wiphy *wiphy,
  437. struct cfg80211_scan_request *request)
  438. {
  439. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  440. struct wireless_dev *wdev = request->wdev;
  441. struct {
  442. struct wmi_start_scan_cmd cmd;
  443. u16 chnl[4];
  444. } __packed cmd;
  445. uint i, n;
  446. int rc;
  447. wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
  448. /* check we are client side */
  449. switch (wdev->iftype) {
  450. case NL80211_IFTYPE_STATION:
  451. case NL80211_IFTYPE_P2P_CLIENT:
  452. case NL80211_IFTYPE_P2P_DEVICE:
  453. break;
  454. default:
  455. return -EOPNOTSUPP;
  456. }
  457. /* FW don't support scan after connection attempt */
  458. if (test_bit(wil_status_dontscan, wil->status)) {
  459. wil_err(wil, "Can't scan now\n");
  460. return -EBUSY;
  461. }
  462. mutex_lock(&wil->mutex);
  463. mutex_lock(&wil->p2p_wdev_mutex);
  464. if (wil->scan_request || wil->p2p.discovery_started) {
  465. wil_err(wil, "Already scanning\n");
  466. mutex_unlock(&wil->p2p_wdev_mutex);
  467. rc = -EAGAIN;
  468. goto out;
  469. }
  470. mutex_unlock(&wil->p2p_wdev_mutex);
  471. if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
  472. if (!wil->p2p.p2p_dev_started) {
  473. wil_err(wil, "P2P search requested on stopped P2P device\n");
  474. rc = -EIO;
  475. goto out;
  476. }
  477. /* social scan on P2P_DEVICE is handled as p2p search */
  478. if (wil_p2p_is_social_scan(request)) {
  479. wil->scan_request = request;
  480. wil->radio_wdev = wdev;
  481. rc = wil_p2p_search(wil, request);
  482. if (rc) {
  483. wil->radio_wdev = wil_to_wdev(wil);
  484. wil->scan_request = NULL;
  485. }
  486. goto out;
  487. }
  488. }
  489. (void)wil_p2p_stop_discovery(wil);
  490. wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
  491. wil_dbg_misc(wil, "SSID count: %d", request->n_ssids);
  492. for (i = 0; i < request->n_ssids; i++) {
  493. wil_dbg_misc(wil, "SSID[%d]", i);
  494. wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
  495. request->ssids[i].ssid,
  496. request->ssids[i].ssid_len, true);
  497. }
  498. if (request->n_ssids)
  499. rc = wmi_set_ssid(wil, request->ssids[0].ssid_len,
  500. request->ssids[0].ssid);
  501. else
  502. rc = wmi_set_ssid(wil, 0, NULL);
  503. if (rc) {
  504. wil_err(wil, "set SSID for scan request failed: %d\n", rc);
  505. goto out;
  506. }
  507. wil->scan_request = request;
  508. mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
  509. memset(&cmd, 0, sizeof(cmd));
  510. cmd.cmd.scan_type = WMI_ACTIVE_SCAN;
  511. cmd.cmd.num_channels = 0;
  512. n = min(request->n_channels, 4U);
  513. for (i = 0; i < n; i++) {
  514. int ch = request->channels[i]->hw_value;
  515. if (ch == 0) {
  516. wil_err(wil,
  517. "Scan requested for unknown frequency %dMhz\n",
  518. request->channels[i]->center_freq);
  519. continue;
  520. }
  521. /* 0-based channel indexes */
  522. cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
  523. wil_dbg_misc(wil, "Scan for ch %d : %d MHz\n", ch,
  524. request->channels[i]->center_freq);
  525. }
  526. if (request->ie_len)
  527. wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET, 16, 1,
  528. request->ie, request->ie_len, true);
  529. else
  530. wil_dbg_misc(wil, "Scan has no IE's\n");
  531. rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
  532. if (rc)
  533. goto out_restore;
  534. if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) {
  535. cmd.cmd.discovery_mode = 1;
  536. wil_dbg_misc(wil, "active scan with discovery_mode=1\n");
  537. }
  538. wil->radio_wdev = wdev;
  539. rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
  540. cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
  541. out_restore:
  542. if (rc) {
  543. del_timer_sync(&wil->scan_timer);
  544. wil->radio_wdev = wil_to_wdev(wil);
  545. wil->scan_request = NULL;
  546. }
  547. out:
  548. mutex_unlock(&wil->mutex);
  549. return rc;
  550. }
  551. static void wil_cfg80211_abort_scan(struct wiphy *wiphy,
  552. struct wireless_dev *wdev)
  553. {
  554. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  555. wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
  556. mutex_lock(&wil->mutex);
  557. mutex_lock(&wil->p2p_wdev_mutex);
  558. if (!wil->scan_request)
  559. goto out;
  560. if (wdev != wil->scan_request->wdev) {
  561. wil_dbg_misc(wil, "abort scan was called on the wrong iface\n");
  562. goto out;
  563. }
  564. if (wil->radio_wdev == wil->p2p_wdev)
  565. wil_p2p_stop_radio_operations(wil);
  566. else
  567. wil_abort_scan(wil, true);
  568. out:
  569. mutex_unlock(&wil->p2p_wdev_mutex);
  570. mutex_unlock(&wil->mutex);
  571. }
  572. static void wil_print_crypto(struct wil6210_priv *wil,
  573. struct cfg80211_crypto_settings *c)
  574. {
  575. int i, n;
  576. wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
  577. c->wpa_versions, c->cipher_group);
  578. wil_dbg_misc(wil, "Pairwise ciphers [%d] {\n", c->n_ciphers_pairwise);
  579. n = min_t(int, c->n_ciphers_pairwise, ARRAY_SIZE(c->ciphers_pairwise));
  580. for (i = 0; i < n; i++)
  581. wil_dbg_misc(wil, " [%d] = 0x%08x\n", i,
  582. c->ciphers_pairwise[i]);
  583. wil_dbg_misc(wil, "}\n");
  584. wil_dbg_misc(wil, "AKM suites [%d] {\n", c->n_akm_suites);
  585. n = min_t(int, c->n_akm_suites, ARRAY_SIZE(c->akm_suites));
  586. for (i = 0; i < n; i++)
  587. wil_dbg_misc(wil, " [%d] = 0x%08x\n", i,
  588. c->akm_suites[i]);
  589. wil_dbg_misc(wil, "}\n");
  590. wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
  591. c->control_port, be16_to_cpu(c->control_port_ethertype),
  592. c->control_port_no_encrypt);
  593. }
  594. static void wil_print_connect_params(struct wil6210_priv *wil,
  595. struct cfg80211_connect_params *sme)
  596. {
  597. wil_info(wil, "Connecting to:\n");
  598. if (sme->channel) {
  599. wil_info(wil, " Channel: %d freq %d\n",
  600. sme->channel->hw_value, sme->channel->center_freq);
  601. }
  602. if (sme->bssid)
  603. wil_info(wil, " BSSID: %pM\n", sme->bssid);
  604. if (sme->ssid)
  605. print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET,
  606. 16, 1, sme->ssid, sme->ssid_len, true);
  607. wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open");
  608. wil_info(wil, " PBSS: %d\n", sme->pbss);
  609. wil_print_crypto(wil, &sme->crypto);
  610. }
  611. static int wil_cfg80211_connect(struct wiphy *wiphy,
  612. struct net_device *ndev,
  613. struct cfg80211_connect_params *sme)
  614. {
  615. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  616. struct cfg80211_bss *bss;
  617. struct wmi_connect_cmd conn;
  618. const u8 *ssid_eid;
  619. const u8 *rsn_eid;
  620. int ch;
  621. int rc = 0;
  622. enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
  623. wil_dbg_misc(wil, "connect\n");
  624. wil_print_connect_params(wil, sme);
  625. if (test_bit(wil_status_fwconnecting, wil->status) ||
  626. test_bit(wil_status_fwconnected, wil->status))
  627. return -EALREADY;
  628. if (sme->ie_len > WMI_MAX_IE_LEN) {
  629. wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
  630. return -ERANGE;
  631. }
  632. rsn_eid = sme->ie ?
  633. cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
  634. NULL;
  635. if (sme->privacy && !rsn_eid)
  636. wil_info(wil, "WSC connection\n");
  637. if (sme->pbss)
  638. bss_type = IEEE80211_BSS_TYPE_PBSS;
  639. bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
  640. sme->ssid, sme->ssid_len,
  641. bss_type, IEEE80211_PRIVACY_ANY);
  642. if (!bss) {
  643. wil_err(wil, "Unable to find BSS\n");
  644. return -ENOENT;
  645. }
  646. ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
  647. if (!ssid_eid) {
  648. wil_err(wil, "No SSID\n");
  649. rc = -ENOENT;
  650. goto out;
  651. }
  652. wil->privacy = sme->privacy;
  653. wil->pbss = sme->pbss;
  654. if (wil->privacy) {
  655. /* For secure assoc, remove old keys */
  656. rc = wmi_del_cipher_key(wil, 0, bss->bssid,
  657. WMI_KEY_USE_PAIRWISE);
  658. if (rc) {
  659. wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n");
  660. goto out;
  661. }
  662. rc = wmi_del_cipher_key(wil, 0, bss->bssid,
  663. WMI_KEY_USE_RX_GROUP);
  664. if (rc) {
  665. wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n");
  666. goto out;
  667. }
  668. }
  669. /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info
  670. * elements. Send it also in case it's empty, to erase previously set
  671. * ies in FW.
  672. */
  673. rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
  674. if (rc)
  675. goto out;
  676. /* WMI_CONNECT_CMD */
  677. memset(&conn, 0, sizeof(conn));
  678. switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
  679. case WLAN_CAPABILITY_DMG_TYPE_AP:
  680. conn.network_type = WMI_NETTYPE_INFRA;
  681. break;
  682. case WLAN_CAPABILITY_DMG_TYPE_PBSS:
  683. conn.network_type = WMI_NETTYPE_P2P;
  684. break;
  685. default:
  686. wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
  687. bss->capability);
  688. goto out;
  689. }
  690. if (wil->privacy) {
  691. if (rsn_eid) { /* regular secure connection */
  692. conn.dot11_auth_mode = WMI_AUTH11_SHARED;
  693. conn.auth_mode = WMI_AUTH_WPA2_PSK;
  694. conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
  695. conn.pairwise_crypto_len = 16;
  696. conn.group_crypto_type = WMI_CRYPT_AES_GCMP;
  697. conn.group_crypto_len = 16;
  698. } else { /* WSC */
  699. conn.dot11_auth_mode = WMI_AUTH11_WSC;
  700. conn.auth_mode = WMI_AUTH_NONE;
  701. }
  702. } else { /* insecure connection */
  703. conn.dot11_auth_mode = WMI_AUTH11_OPEN;
  704. conn.auth_mode = WMI_AUTH_NONE;
  705. }
  706. conn.ssid_len = min_t(u8, ssid_eid[1], 32);
  707. memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
  708. ch = bss->channel->hw_value;
  709. if (ch == 0) {
  710. wil_err(wil, "BSS at unknown frequency %dMhz\n",
  711. bss->channel->center_freq);
  712. rc = -EOPNOTSUPP;
  713. goto out;
  714. }
  715. conn.channel = ch - 1;
  716. ether_addr_copy(conn.bssid, bss->bssid);
  717. ether_addr_copy(conn.dst_mac, bss->bssid);
  718. set_bit(wil_status_fwconnecting, wil->status);
  719. rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
  720. if (rc == 0) {
  721. netif_carrier_on(ndev);
  722. wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
  723. wil->bss = bss;
  724. /* Connect can take lots of time */
  725. mod_timer(&wil->connect_timer,
  726. jiffies + msecs_to_jiffies(5000));
  727. } else {
  728. clear_bit(wil_status_fwconnecting, wil->status);
  729. }
  730. out:
  731. cfg80211_put_bss(wiphy, bss);
  732. return rc;
  733. }
  734. static int wil_cfg80211_disconnect(struct wiphy *wiphy,
  735. struct net_device *ndev,
  736. u16 reason_code)
  737. {
  738. int rc;
  739. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  740. wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code);
  741. if (!(test_bit(wil_status_fwconnecting, wil->status) ||
  742. test_bit(wil_status_fwconnected, wil->status))) {
  743. wil_err(wil, "Disconnect was called while disconnected\n");
  744. return 0;
  745. }
  746. wil->locally_generated_disc = true;
  747. rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
  748. WMI_DISCONNECT_EVENTID, NULL, 0,
  749. WIL6210_DISCONNECT_TO_MS);
  750. if (rc)
  751. wil_err(wil, "disconnect error %d\n", rc);
  752. return rc;
  753. }
  754. static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
  755. {
  756. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  757. int rc;
  758. /* these parameters are explicitly not supported */
  759. if (changed & (WIPHY_PARAM_RETRY_LONG |
  760. WIPHY_PARAM_FRAG_THRESHOLD |
  761. WIPHY_PARAM_RTS_THRESHOLD))
  762. return -ENOTSUPP;
  763. if (changed & WIPHY_PARAM_RETRY_SHORT) {
  764. rc = wmi_set_mgmt_retry(wil, wiphy->retry_short);
  765. if (rc)
  766. return rc;
  767. }
  768. return 0;
  769. }
  770. int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
  771. struct cfg80211_mgmt_tx_params *params,
  772. u64 *cookie)
  773. {
  774. const u8 *buf = params->buf;
  775. size_t len = params->len;
  776. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  777. int rc;
  778. bool tx_status = false;
  779. struct ieee80211_mgmt *mgmt_frame = (void *)buf;
  780. struct wmi_sw_tx_req_cmd *cmd;
  781. struct {
  782. struct wmi_cmd_hdr wmi;
  783. struct wmi_sw_tx_complete_event evt;
  784. } __packed evt;
  785. /* Note, currently we do not support the "wait" parameter, user-space
  786. * must call remain_on_channel before mgmt_tx or listen on a channel
  787. * another way (AP/PCP or connected station)
  788. * in addition we need to check if specified "chan" argument is
  789. * different from currently "listened" channel and fail if it is.
  790. */
  791. wil_dbg_misc(wil, "mgmt_tx\n");
  792. wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
  793. len, true);
  794. if (len < sizeof(struct ieee80211_hdr_3addr))
  795. return -EINVAL;
  796. cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
  797. if (!cmd) {
  798. rc = -ENOMEM;
  799. goto out;
  800. }
  801. memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
  802. cmd->len = cpu_to_le16(len);
  803. memcpy(cmd->payload, buf, len);
  804. rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
  805. WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
  806. if (rc == 0)
  807. tx_status = !evt.evt.status;
  808. kfree(cmd);
  809. out:
  810. cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
  811. tx_status, GFP_KERNEL);
  812. return rc;
  813. }
  814. static int wil_cfg80211_set_channel(struct wiphy *wiphy,
  815. struct cfg80211_chan_def *chandef)
  816. {
  817. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  818. struct wireless_dev *wdev = wil_to_wdev(wil);
  819. wdev->preset_chandef = *chandef;
  820. return 0;
  821. }
  822. static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
  823. bool pairwise)
  824. {
  825. struct wireless_dev *wdev = wil_to_wdev(wil);
  826. enum wmi_key_usage rc;
  827. if (pairwise) {
  828. rc = WMI_KEY_USE_PAIRWISE;
  829. } else {
  830. switch (wdev->iftype) {
  831. case NL80211_IFTYPE_STATION:
  832. case NL80211_IFTYPE_P2P_CLIENT:
  833. rc = WMI_KEY_USE_RX_GROUP;
  834. break;
  835. case NL80211_IFTYPE_AP:
  836. case NL80211_IFTYPE_P2P_GO:
  837. rc = WMI_KEY_USE_TX_GROUP;
  838. break;
  839. default:
  840. /* TODO: Rx GTK or Tx GTK? */
  841. wil_err(wil, "Can't determine GTK type\n");
  842. rc = WMI_KEY_USE_RX_GROUP;
  843. break;
  844. }
  845. }
  846. wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]);
  847. return rc;
  848. }
  849. static struct wil_sta_info *
  850. wil_find_sta_by_key_usage(struct wil6210_priv *wil,
  851. enum wmi_key_usage key_usage, const u8 *mac_addr)
  852. {
  853. int cid = -EINVAL;
  854. if (key_usage == WMI_KEY_USE_TX_GROUP)
  855. return NULL; /* not needed */
  856. /* supplicant provides Rx group key in STA mode with NULL MAC address */
  857. if (mac_addr)
  858. cid = wil_find_cid(wil, mac_addr);
  859. else if (key_usage == WMI_KEY_USE_RX_GROUP)
  860. cid = wil_find_cid_by_idx(wil, 0);
  861. if (cid < 0) {
  862. wil_err(wil, "No CID for %pM %s\n", mac_addr,
  863. key_usage_str[key_usage]);
  864. return ERR_PTR(cid);
  865. }
  866. return &wil->sta[cid];
  867. }
  868. static void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
  869. struct wil_sta_info *cs,
  870. struct key_params *params)
  871. {
  872. struct wil_tid_crypto_rx_single *cc;
  873. int tid;
  874. if (!cs)
  875. return;
  876. switch (key_usage) {
  877. case WMI_KEY_USE_PAIRWISE:
  878. for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
  879. cc = &cs->tid_crypto_rx[tid].key_id[key_index];
  880. if (params->seq)
  881. memcpy(cc->pn, params->seq,
  882. IEEE80211_GCMP_PN_LEN);
  883. else
  884. memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
  885. cc->key_set = true;
  886. }
  887. break;
  888. case WMI_KEY_USE_RX_GROUP:
  889. cc = &cs->group_crypto_rx.key_id[key_index];
  890. if (params->seq)
  891. memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
  892. else
  893. memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
  894. cc->key_set = true;
  895. break;
  896. default:
  897. break;
  898. }
  899. }
  900. static void wil_del_rx_key(u8 key_index, enum wmi_key_usage key_usage,
  901. struct wil_sta_info *cs)
  902. {
  903. struct wil_tid_crypto_rx_single *cc;
  904. int tid;
  905. if (!cs)
  906. return;
  907. switch (key_usage) {
  908. case WMI_KEY_USE_PAIRWISE:
  909. for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
  910. cc = &cs->tid_crypto_rx[tid].key_id[key_index];
  911. cc->key_set = false;
  912. }
  913. break;
  914. case WMI_KEY_USE_RX_GROUP:
  915. cc = &cs->group_crypto_rx.key_id[key_index];
  916. cc->key_set = false;
  917. break;
  918. default:
  919. break;
  920. }
  921. }
  922. static int wil_cfg80211_add_key(struct wiphy *wiphy,
  923. struct net_device *ndev,
  924. u8 key_index, bool pairwise,
  925. const u8 *mac_addr,
  926. struct key_params *params)
  927. {
  928. int rc;
  929. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  930. enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
  931. struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
  932. mac_addr);
  933. if (!params) {
  934. wil_err(wil, "NULL params\n");
  935. return -EINVAL;
  936. }
  937. wil_dbg_misc(wil, "add_key: %pM %s[%d] PN %*phN\n",
  938. mac_addr, key_usage_str[key_usage], key_index,
  939. params->seq_len, params->seq);
  940. if (IS_ERR(cs)) {
  941. wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
  942. mac_addr, key_usage_str[key_usage], key_index,
  943. params->seq_len, params->seq);
  944. return -EINVAL;
  945. }
  946. wil_del_rx_key(key_index, key_usage, cs);
  947. if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
  948. wil_err(wil,
  949. "Wrong PN len %d, %pM %s[%d] PN %*phN\n",
  950. params->seq_len, mac_addr,
  951. key_usage_str[key_usage], key_index,
  952. params->seq_len, params->seq);
  953. return -EINVAL;
  954. }
  955. rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len,
  956. params->key, key_usage);
  957. if (!rc)
  958. wil_set_crypto_rx(key_index, key_usage, cs, params);
  959. return rc;
  960. }
  961. static int wil_cfg80211_del_key(struct wiphy *wiphy,
  962. struct net_device *ndev,
  963. u8 key_index, bool pairwise,
  964. const u8 *mac_addr)
  965. {
  966. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  967. enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
  968. struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
  969. mac_addr);
  970. wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
  971. key_usage_str[key_usage], key_index);
  972. if (IS_ERR(cs))
  973. wil_info(wil, "Not connected, %pM %s[%d]\n",
  974. mac_addr, key_usage_str[key_usage], key_index);
  975. if (!IS_ERR_OR_NULL(cs))
  976. wil_del_rx_key(key_index, key_usage, cs);
  977. return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage);
  978. }
  979. /* Need to be present or wiphy_new() will WARN */
  980. static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
  981. struct net_device *ndev,
  982. u8 key_index, bool unicast,
  983. bool multicast)
  984. {
  985. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  986. wil_dbg_misc(wil, "set_default_key: entered\n");
  987. return 0;
  988. }
  989. static int wil_remain_on_channel(struct wiphy *wiphy,
  990. struct wireless_dev *wdev,
  991. struct ieee80211_channel *chan,
  992. unsigned int duration,
  993. u64 *cookie)
  994. {
  995. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  996. int rc;
  997. wil_dbg_misc(wil,
  998. "remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
  999. chan->center_freq, duration, wdev->iftype);
  1000. rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
  1001. return rc;
  1002. }
  1003. static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
  1004. struct wireless_dev *wdev,
  1005. u64 cookie)
  1006. {
  1007. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1008. wil_dbg_misc(wil, "cancel_remain_on_channel\n");
  1009. return wil_p2p_cancel_listen(wil, cookie);
  1010. }
  1011. /**
  1012. * find a specific IE in a list of IEs
  1013. * return a pointer to the beginning of IE in the list
  1014. * or NULL if not found
  1015. */
  1016. static const u8 *_wil_cfg80211_find_ie(const u8 *ies, u16 ies_len, const u8 *ie,
  1017. u16 ie_len)
  1018. {
  1019. struct ieee80211_vendor_ie *vie;
  1020. u32 oui;
  1021. /* IE tag at offset 0, length at offset 1 */
  1022. if (ie_len < 2 || 2 + ie[1] > ie_len)
  1023. return NULL;
  1024. if (ie[0] != WLAN_EID_VENDOR_SPECIFIC)
  1025. return cfg80211_find_ie(ie[0], ies, ies_len);
  1026. /* make sure there is room for 3 bytes OUI + 1 byte OUI type */
  1027. if (ie[1] < 4)
  1028. return NULL;
  1029. vie = (struct ieee80211_vendor_ie *)ie;
  1030. oui = vie->oui[0] << 16 | vie->oui[1] << 8 | vie->oui[2];
  1031. return cfg80211_find_vendor_ie(oui, vie->oui_type, ies,
  1032. ies_len);
  1033. }
  1034. /**
  1035. * merge the IEs in two lists into a single list.
  1036. * do not include IEs from the second list which exist in the first list.
  1037. * add only vendor specific IEs from second list to keep
  1038. * the merged list sorted (since vendor-specific IE has the
  1039. * highest tag number)
  1040. * caller must free the allocated memory for merged IEs
  1041. */
  1042. static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len,
  1043. const u8 *ies2, u16 ies2_len,
  1044. u8 **merged_ies, u16 *merged_len)
  1045. {
  1046. u8 *buf, *dpos;
  1047. const u8 *spos;
  1048. if (ies1_len == 0 && ies2_len == 0) {
  1049. *merged_ies = NULL;
  1050. *merged_len = 0;
  1051. return 0;
  1052. }
  1053. buf = kmalloc(ies1_len + ies2_len, GFP_KERNEL);
  1054. if (!buf)
  1055. return -ENOMEM;
  1056. memcpy(buf, ies1, ies1_len);
  1057. dpos = buf + ies1_len;
  1058. spos = ies2;
  1059. while (spos + 1 < ies2 + ies2_len) {
  1060. /* IE tag at offset 0, length at offset 1 */
  1061. u16 ielen = 2 + spos[1];
  1062. if (spos + ielen > ies2 + ies2_len)
  1063. break;
  1064. if (spos[0] == WLAN_EID_VENDOR_SPECIFIC &&
  1065. !_wil_cfg80211_find_ie(ies1, ies1_len, spos, ielen)) {
  1066. memcpy(dpos, spos, ielen);
  1067. dpos += ielen;
  1068. }
  1069. spos += ielen;
  1070. }
  1071. *merged_ies = buf;
  1072. *merged_len = dpos - buf;
  1073. return 0;
  1074. }
  1075. static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
  1076. {
  1077. wil_hex_dump_misc("head ", DUMP_PREFIX_OFFSET, 16, 1,
  1078. b->head, b->head_len, true);
  1079. wil_hex_dump_misc("tail ", DUMP_PREFIX_OFFSET, 16, 1,
  1080. b->tail, b->tail_len, true);
  1081. wil_hex_dump_misc("BCON IE ", DUMP_PREFIX_OFFSET, 16, 1,
  1082. b->beacon_ies, b->beacon_ies_len, true);
  1083. wil_hex_dump_misc("PROBE ", DUMP_PREFIX_OFFSET, 16, 1,
  1084. b->probe_resp, b->probe_resp_len, true);
  1085. wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET, 16, 1,
  1086. b->proberesp_ies, b->proberesp_ies_len, true);
  1087. wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1,
  1088. b->assocresp_ies, b->assocresp_ies_len, true);
  1089. }
  1090. /* internal functions for device reset and starting AP */
  1091. static int _wil_cfg80211_set_ies(struct wiphy *wiphy,
  1092. struct cfg80211_beacon_data *bcon)
  1093. {
  1094. int rc;
  1095. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1096. u16 len = 0, proberesp_len = 0;
  1097. u8 *ies = NULL, *proberesp = NULL;
  1098. if (bcon->probe_resp) {
  1099. struct ieee80211_mgmt *f =
  1100. (struct ieee80211_mgmt *)bcon->probe_resp;
  1101. size_t hlen = offsetof(struct ieee80211_mgmt,
  1102. u.probe_resp.variable);
  1103. proberesp = f->u.probe_resp.variable;
  1104. proberesp_len = bcon->probe_resp_len - hlen;
  1105. }
  1106. rc = _wil_cfg80211_merge_extra_ies(proberesp,
  1107. proberesp_len,
  1108. bcon->proberesp_ies,
  1109. bcon->proberesp_ies_len,
  1110. &ies, &len);
  1111. if (rc)
  1112. goto out;
  1113. rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, len, ies);
  1114. if (rc)
  1115. goto out;
  1116. if (bcon->assocresp_ies)
  1117. rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP,
  1118. bcon->assocresp_ies_len, bcon->assocresp_ies);
  1119. else
  1120. rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, len, ies);
  1121. #if 0 /* to use beacon IE's, remove this #if 0 */
  1122. if (rc)
  1123. goto out;
  1124. rc = wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->tail_len, bcon->tail);
  1125. #endif
  1126. out:
  1127. kfree(ies);
  1128. return rc;
  1129. }
  1130. static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
  1131. struct net_device *ndev,
  1132. const u8 *ssid, size_t ssid_len, u32 privacy,
  1133. int bi, u8 chan,
  1134. struct cfg80211_beacon_data *bcon,
  1135. u8 hidden_ssid, u32 pbss)
  1136. {
  1137. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1138. int rc;
  1139. struct wireless_dev *wdev = ndev->ieee80211_ptr;
  1140. u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
  1141. u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO);
  1142. if (pbss)
  1143. wmi_nettype = WMI_NETTYPE_P2P;
  1144. wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go);
  1145. if (is_go && !pbss) {
  1146. wil_err(wil, "P2P GO must be in PBSS\n");
  1147. return -ENOTSUPP;
  1148. }
  1149. wil_set_recovery_state(wil, fw_recovery_idle);
  1150. mutex_lock(&wil->mutex);
  1151. __wil_down(wil);
  1152. rc = __wil_up(wil);
  1153. if (rc)
  1154. goto out;
  1155. rc = wmi_set_ssid(wil, ssid_len, ssid);
  1156. if (rc)
  1157. goto out;
  1158. rc = _wil_cfg80211_set_ies(wiphy, bcon);
  1159. if (rc)
  1160. goto out;
  1161. wil->privacy = privacy;
  1162. wil->channel = chan;
  1163. wil->hidden_ssid = hidden_ssid;
  1164. wil->pbss = pbss;
  1165. netif_carrier_on(ndev);
  1166. wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
  1167. rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go);
  1168. if (rc)
  1169. goto err_pcp_start;
  1170. rc = wil_bcast_init(wil);
  1171. if (rc)
  1172. goto err_bcast;
  1173. goto out; /* success */
  1174. err_bcast:
  1175. wmi_pcp_stop(wil);
  1176. err_pcp_start:
  1177. netif_carrier_off(ndev);
  1178. wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
  1179. out:
  1180. mutex_unlock(&wil->mutex);
  1181. return rc;
  1182. }
  1183. static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
  1184. struct net_device *ndev,
  1185. struct cfg80211_beacon_data *bcon)
  1186. {
  1187. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1188. int rc;
  1189. u32 privacy = 0;
  1190. wil_dbg_misc(wil, "change_beacon\n");
  1191. wil_print_bcon_data(bcon);
  1192. if (bcon->tail &&
  1193. cfg80211_find_ie(WLAN_EID_RSN, bcon->tail,
  1194. bcon->tail_len))
  1195. privacy = 1;
  1196. /* in case privacy has changed, need to restart the AP */
  1197. if (wil->privacy != privacy) {
  1198. struct wireless_dev *wdev = ndev->ieee80211_ptr;
  1199. wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n",
  1200. wil->privacy, privacy);
  1201. rc = _wil_cfg80211_start_ap(wiphy, ndev, wdev->ssid,
  1202. wdev->ssid_len, privacy,
  1203. wdev->beacon_interval,
  1204. wil->channel, bcon,
  1205. wil->hidden_ssid,
  1206. wil->pbss);
  1207. } else {
  1208. rc = _wil_cfg80211_set_ies(wiphy, bcon);
  1209. }
  1210. return rc;
  1211. }
  1212. static int wil_cfg80211_start_ap(struct wiphy *wiphy,
  1213. struct net_device *ndev,
  1214. struct cfg80211_ap_settings *info)
  1215. {
  1216. int rc;
  1217. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1218. struct ieee80211_channel *channel = info->chandef.chan;
  1219. struct cfg80211_beacon_data *bcon = &info->beacon;
  1220. struct cfg80211_crypto_settings *crypto = &info->crypto;
  1221. u8 hidden_ssid;
  1222. wil_dbg_misc(wil, "start_ap\n");
  1223. if (!channel) {
  1224. wil_err(wil, "AP: No channel???\n");
  1225. return -EINVAL;
  1226. }
  1227. switch (info->hidden_ssid) {
  1228. case NL80211_HIDDEN_SSID_NOT_IN_USE:
  1229. hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
  1230. break;
  1231. case NL80211_HIDDEN_SSID_ZERO_LEN:
  1232. hidden_ssid = WMI_HIDDEN_SSID_SEND_EMPTY;
  1233. break;
  1234. case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
  1235. hidden_ssid = WMI_HIDDEN_SSID_CLEAR;
  1236. break;
  1237. default:
  1238. wil_err(wil, "AP: Invalid hidden SSID %d\n", info->hidden_ssid);
  1239. return -EOPNOTSUPP;
  1240. }
  1241. wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
  1242. channel->center_freq, info->privacy ? "secure" : "open");
  1243. wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
  1244. info->privacy, info->auth_type);
  1245. wil_dbg_misc(wil, "Hidden SSID mode: %d\n",
  1246. info->hidden_ssid);
  1247. wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
  1248. info->dtim_period);
  1249. wil_dbg_misc(wil, "PBSS %d\n", info->pbss);
  1250. wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
  1251. info->ssid, info->ssid_len, true);
  1252. wil_print_bcon_data(bcon);
  1253. wil_print_crypto(wil, crypto);
  1254. rc = _wil_cfg80211_start_ap(wiphy, ndev,
  1255. info->ssid, info->ssid_len, info->privacy,
  1256. info->beacon_interval, channel->hw_value,
  1257. bcon, hidden_ssid, info->pbss);
  1258. return rc;
  1259. }
  1260. static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
  1261. struct net_device *ndev)
  1262. {
  1263. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1264. wil_dbg_misc(wil, "stop_ap\n");
  1265. netif_carrier_off(ndev);
  1266. wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
  1267. wil_set_recovery_state(wil, fw_recovery_idle);
  1268. set_bit(wil_status_resetting, wil->status);
  1269. mutex_lock(&wil->mutex);
  1270. wmi_pcp_stop(wil);
  1271. __wil_down(wil);
  1272. mutex_unlock(&wil->mutex);
  1273. return 0;
  1274. }
  1275. static int wil_cfg80211_add_station(struct wiphy *wiphy,
  1276. struct net_device *dev,
  1277. const u8 *mac,
  1278. struct station_parameters *params)
  1279. {
  1280. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1281. wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid);
  1282. if (!disable_ap_sme) {
  1283. wil_err(wil, "not supported with AP SME enabled\n");
  1284. return -EOPNOTSUPP;
  1285. }
  1286. if (params->aid > WIL_MAX_DMG_AID) {
  1287. wil_err(wil, "invalid aid\n");
  1288. return -EINVAL;
  1289. }
  1290. return wmi_new_sta(wil, mac, params->aid);
  1291. }
  1292. static int wil_cfg80211_del_station(struct wiphy *wiphy,
  1293. struct net_device *dev,
  1294. struct station_del_parameters *params)
  1295. {
  1296. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1297. wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac,
  1298. params->reason_code);
  1299. mutex_lock(&wil->mutex);
  1300. wil6210_disconnect(wil, params->mac, params->reason_code, false);
  1301. mutex_unlock(&wil->mutex);
  1302. return 0;
  1303. }
  1304. static int wil_cfg80211_change_station(struct wiphy *wiphy,
  1305. struct net_device *dev,
  1306. const u8 *mac,
  1307. struct station_parameters *params)
  1308. {
  1309. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1310. int authorize;
  1311. int cid, i;
  1312. struct vring_tx_data *txdata = NULL;
  1313. wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac,
  1314. params->sta_flags_mask, params->sta_flags_set);
  1315. if (!disable_ap_sme) {
  1316. wil_dbg_misc(wil, "not supported with AP SME enabled\n");
  1317. return -EOPNOTSUPP;
  1318. }
  1319. if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
  1320. return 0;
  1321. cid = wil_find_cid(wil, mac);
  1322. if (cid < 0) {
  1323. wil_err(wil, "station not found\n");
  1324. return -ENOLINK;
  1325. }
  1326. for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
  1327. if (wil->vring2cid_tid[i][0] == cid) {
  1328. txdata = &wil->vring_tx_data[i];
  1329. break;
  1330. }
  1331. if (!txdata) {
  1332. wil_err(wil, "vring data not found\n");
  1333. return -ENOLINK;
  1334. }
  1335. authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
  1336. txdata->dot1x_open = authorize ? 1 : 0;
  1337. wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
  1338. txdata->dot1x_open);
  1339. return 0;
  1340. }
  1341. /* probe_client handling */
  1342. static void wil_probe_client_handle(struct wil6210_priv *wil,
  1343. struct wil_probe_client_req *req)
  1344. {
  1345. struct net_device *ndev = wil_to_ndev(wil);
  1346. struct wil_sta_info *sta = &wil->sta[req->cid];
  1347. /* assume STA is alive if it is still connected,
  1348. * else FW will disconnect it
  1349. */
  1350. bool alive = (sta->status == wil_sta_connected);
  1351. cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, GFP_KERNEL);
  1352. }
  1353. static struct list_head *next_probe_client(struct wil6210_priv *wil)
  1354. {
  1355. struct list_head *ret = NULL;
  1356. mutex_lock(&wil->probe_client_mutex);
  1357. if (!list_empty(&wil->probe_client_pending)) {
  1358. ret = wil->probe_client_pending.next;
  1359. list_del(ret);
  1360. }
  1361. mutex_unlock(&wil->probe_client_mutex);
  1362. return ret;
  1363. }
  1364. void wil_probe_client_worker(struct work_struct *work)
  1365. {
  1366. struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
  1367. probe_client_worker);
  1368. struct wil_probe_client_req *req;
  1369. struct list_head *lh;
  1370. while ((lh = next_probe_client(wil)) != NULL) {
  1371. req = list_entry(lh, struct wil_probe_client_req, list);
  1372. wil_probe_client_handle(wil, req);
  1373. kfree(req);
  1374. }
  1375. }
  1376. void wil_probe_client_flush(struct wil6210_priv *wil)
  1377. {
  1378. struct wil_probe_client_req *req, *t;
  1379. wil_dbg_misc(wil, "probe_client_flush\n");
  1380. mutex_lock(&wil->probe_client_mutex);
  1381. list_for_each_entry_safe(req, t, &wil->probe_client_pending, list) {
  1382. list_del(&req->list);
  1383. kfree(req);
  1384. }
  1385. mutex_unlock(&wil->probe_client_mutex);
  1386. }
  1387. static int wil_cfg80211_probe_client(struct wiphy *wiphy,
  1388. struct net_device *dev,
  1389. const u8 *peer, u64 *cookie)
  1390. {
  1391. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1392. struct wil_probe_client_req *req;
  1393. int cid = wil_find_cid(wil, peer);
  1394. wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid);
  1395. if (cid < 0)
  1396. return -ENOLINK;
  1397. req = kzalloc(sizeof(*req), GFP_KERNEL);
  1398. if (!req)
  1399. return -ENOMEM;
  1400. req->cid = cid;
  1401. req->cookie = cid;
  1402. mutex_lock(&wil->probe_client_mutex);
  1403. list_add_tail(&req->list, &wil->probe_client_pending);
  1404. mutex_unlock(&wil->probe_client_mutex);
  1405. *cookie = req->cookie;
  1406. queue_work(wil->wq_service, &wil->probe_client_worker);
  1407. return 0;
  1408. }
  1409. static int wil_cfg80211_change_bss(struct wiphy *wiphy,
  1410. struct net_device *dev,
  1411. struct bss_parameters *params)
  1412. {
  1413. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1414. if (params->ap_isolate >= 0) {
  1415. wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n",
  1416. wil->ap_isolate, params->ap_isolate);
  1417. wil->ap_isolate = params->ap_isolate;
  1418. }
  1419. return 0;
  1420. }
  1421. static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
  1422. struct net_device *dev,
  1423. bool enabled, int timeout)
  1424. {
  1425. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1426. enum wmi_ps_profile_type ps_profile;
  1427. wil_dbg_misc(wil, "enabled=%d, timeout=%d\n",
  1428. enabled, timeout);
  1429. if (enabled)
  1430. ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT;
  1431. else
  1432. ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED;
  1433. return wil_ps_update(wil, ps_profile);
  1434. }
  1435. static int wil_cfg80211_suspend(struct wiphy *wiphy,
  1436. struct cfg80211_wowlan *wow)
  1437. {
  1438. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1439. int rc;
  1440. /* Setting the wakeup trigger based on wow is TBD */
  1441. if (test_bit(wil_status_suspended, wil->status)) {
  1442. wil_dbg_pm(wil, "trying to suspend while suspended\n");
  1443. return 0;
  1444. }
  1445. rc = wil_can_suspend(wil, false);
  1446. if (rc)
  1447. goto out;
  1448. wil_dbg_pm(wil, "suspending\n");
  1449. wil_p2p_stop_discovery(wil);
  1450. wil_abort_scan(wil, true);
  1451. out:
  1452. return rc;
  1453. }
  1454. static int wil_cfg80211_resume(struct wiphy *wiphy)
  1455. {
  1456. struct wil6210_priv *wil = wiphy_to_wil(wiphy);
  1457. wil_dbg_pm(wil, "resuming\n");
  1458. return 0;
  1459. }
  1460. static const struct cfg80211_ops wil_cfg80211_ops = {
  1461. .add_virtual_intf = wil_cfg80211_add_iface,
  1462. .del_virtual_intf = wil_cfg80211_del_iface,
  1463. .scan = wil_cfg80211_scan,
  1464. .abort_scan = wil_cfg80211_abort_scan,
  1465. .connect = wil_cfg80211_connect,
  1466. .disconnect = wil_cfg80211_disconnect,
  1467. .set_wiphy_params = wil_cfg80211_set_wiphy_params,
  1468. .change_virtual_intf = wil_cfg80211_change_iface,
  1469. .get_station = wil_cfg80211_get_station,
  1470. .dump_station = wil_cfg80211_dump_station,
  1471. .remain_on_channel = wil_remain_on_channel,
  1472. .cancel_remain_on_channel = wil_cancel_remain_on_channel,
  1473. .mgmt_tx = wil_cfg80211_mgmt_tx,
  1474. .set_monitor_channel = wil_cfg80211_set_channel,
  1475. .add_key = wil_cfg80211_add_key,
  1476. .del_key = wil_cfg80211_del_key,
  1477. .set_default_key = wil_cfg80211_set_default_key,
  1478. /* AP mode */
  1479. .change_beacon = wil_cfg80211_change_beacon,
  1480. .start_ap = wil_cfg80211_start_ap,
  1481. .stop_ap = wil_cfg80211_stop_ap,
  1482. .add_station = wil_cfg80211_add_station,
  1483. .del_station = wil_cfg80211_del_station,
  1484. .change_station = wil_cfg80211_change_station,
  1485. .probe_client = wil_cfg80211_probe_client,
  1486. .change_bss = wil_cfg80211_change_bss,
  1487. /* P2P device */
  1488. .start_p2p_device = wil_cfg80211_start_p2p_device,
  1489. .stop_p2p_device = wil_cfg80211_stop_p2p_device,
  1490. .set_power_mgmt = wil_cfg80211_set_power_mgmt,
  1491. .suspend = wil_cfg80211_suspend,
  1492. .resume = wil_cfg80211_resume,
  1493. };
  1494. static void wil_wiphy_init(struct wiphy *wiphy)
  1495. {
  1496. wiphy->max_scan_ssids = 1;
  1497. wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
  1498. wiphy->max_remain_on_channel_duration = WIL_MAX_ROC_DURATION_MS;
  1499. wiphy->max_num_pmkids = 0 /* TODO: */;
  1500. wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
  1501. BIT(NL80211_IFTYPE_AP) |
  1502. BIT(NL80211_IFTYPE_P2P_CLIENT) |
  1503. BIT(NL80211_IFTYPE_P2P_GO) |
  1504. BIT(NL80211_IFTYPE_P2P_DEVICE) |
  1505. BIT(NL80211_IFTYPE_MONITOR);
  1506. wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
  1507. WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
  1508. WIPHY_FLAG_PS_ON_BY_DEFAULT;
  1509. if (!disable_ap_sme)
  1510. wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
  1511. dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
  1512. __func__, wiphy->flags);
  1513. wiphy->probe_resp_offload =
  1514. NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
  1515. NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
  1516. NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
  1517. wiphy->bands[NL80211_BAND_60GHZ] = &wil_band_60ghz;
  1518. /* may change after reading FW capabilities */
  1519. wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
  1520. wiphy->cipher_suites = wil_cipher_suites;
  1521. wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
  1522. wiphy->mgmt_stypes = wil_mgmt_stypes;
  1523. wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
  1524. wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands);
  1525. wiphy->vendor_commands = wil_nl80211_vendor_commands;
  1526. #ifdef CONFIG_PM
  1527. wiphy->wowlan = &wil_wowlan_support;
  1528. #endif
  1529. }
  1530. struct wireless_dev *wil_cfg80211_init(struct device *dev)
  1531. {
  1532. int rc = 0;
  1533. struct wireless_dev *wdev;
  1534. dev_dbg(dev, "%s()\n", __func__);
  1535. wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
  1536. if (!wdev)
  1537. return ERR_PTR(-ENOMEM);
  1538. wdev->wiphy = wiphy_new(&wil_cfg80211_ops,
  1539. sizeof(struct wil6210_priv));
  1540. if (!wdev->wiphy) {
  1541. rc = -ENOMEM;
  1542. goto out;
  1543. }
  1544. set_wiphy_dev(wdev->wiphy, dev);
  1545. wil_wiphy_init(wdev->wiphy);
  1546. return wdev;
  1547. out:
  1548. kfree(wdev);
  1549. return ERR_PTR(rc);
  1550. }
  1551. void wil_wdev_free(struct wil6210_priv *wil)
  1552. {
  1553. struct wireless_dev *wdev = wil_to_wdev(wil);
  1554. dev_dbg(wil_to_dev(wil), "%s()\n", __func__);
  1555. if (!wdev)
  1556. return;
  1557. wiphy_free(wdev->wiphy);
  1558. kfree(wdev);
  1559. }
  1560. void wil_p2p_wdev_free(struct wil6210_priv *wil)
  1561. {
  1562. struct wireless_dev *p2p_wdev;
  1563. mutex_lock(&wil->p2p_wdev_mutex);
  1564. p2p_wdev = wil->p2p_wdev;
  1565. wil->p2p_wdev = NULL;
  1566. wil->radio_wdev = wil_to_wdev(wil);
  1567. mutex_unlock(&wil->p2p_wdev_mutex);
  1568. if (p2p_wdev) {
  1569. cfg80211_unregister_wdev(p2p_wdev);
  1570. kfree(p2p_wdev);
  1571. }
  1572. }
  1573. static int wil_rf_sector_status_to_rc(u8 status)
  1574. {
  1575. switch (status) {
  1576. case WMI_RF_SECTOR_STATUS_SUCCESS:
  1577. return 0;
  1578. case WMI_RF_SECTOR_STATUS_BAD_PARAMETERS_ERROR:
  1579. return -EINVAL;
  1580. case WMI_RF_SECTOR_STATUS_BUSY_ERROR:
  1581. return -EAGAIN;
  1582. case WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR:
  1583. return -EOPNOTSUPP;
  1584. default:
  1585. return -EINVAL;
  1586. }
  1587. }
  1588. static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
  1589. struct wireless_dev *wdev,
  1590. const void *data, int data_len)
  1591. {
  1592. struct wil6210_priv *wil = wdev_to_wil(wdev);
  1593. int rc;
  1594. struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
  1595. u16 sector_index;
  1596. u8 sector_type;
  1597. u32 rf_modules_vec;
  1598. struct wmi_get_rf_sector_params_cmd cmd;
  1599. struct {
  1600. struct wmi_cmd_hdr wmi;
  1601. struct wmi_get_rf_sector_params_done_event evt;
  1602. } __packed reply;
  1603. struct sk_buff *msg;
  1604. struct nlattr *nl_cfgs, *nl_cfg;
  1605. u32 i;
  1606. struct wmi_rf_sector_info *si;
  1607. if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
  1608. return -EOPNOTSUPP;
  1609. rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
  1610. wil_rf_sector_policy, NULL);
  1611. if (rc) {
  1612. wil_err(wil, "Invalid rf sector ATTR\n");
  1613. return rc;
  1614. }
  1615. if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
  1616. !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE] ||
  1617. !tb[QCA_ATTR_DMG_RF_MODULE_MASK]) {
  1618. wil_err(wil, "Invalid rf sector spec\n");
  1619. return -EINVAL;
  1620. }
  1621. sector_index = nla_get_u16(
  1622. tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
  1623. if (sector_index >= WIL_MAX_RF_SECTORS) {
  1624. wil_err(wil, "Invalid sector index %d\n", sector_index);
  1625. return -EINVAL;
  1626. }
  1627. sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
  1628. if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
  1629. wil_err(wil, "Invalid sector type %d\n", sector_type);
  1630. return -EINVAL;
  1631. }
  1632. rf_modules_vec = nla_get_u32(
  1633. tb[QCA_ATTR_DMG_RF_MODULE_MASK]);
  1634. if (rf_modules_vec >= BIT(WMI_MAX_RF_MODULES_NUM)) {
  1635. wil_err(wil, "Invalid rf module mask 0x%x\n", rf_modules_vec);
  1636. return -EINVAL;
  1637. }
  1638. cmd.sector_idx = cpu_to_le16(sector_index);
  1639. cmd.sector_type = sector_type;
  1640. cmd.rf_modules_vec = rf_modules_vec & 0xFF;
  1641. memset(&reply, 0, sizeof(reply));
  1642. rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd),
  1643. WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID,
  1644. &reply, sizeof(reply),
  1645. 500);
  1646. if (rc)
  1647. return rc;
  1648. if (reply.evt.status) {
  1649. wil_err(wil, "get rf sector cfg failed with status %d\n",
  1650. reply.evt.status);
  1651. return wil_rf_sector_status_to_rc(reply.evt.status);
  1652. }
  1653. msg = cfg80211_vendor_cmd_alloc_reply_skb(
  1654. wiphy, 64 * WMI_MAX_RF_MODULES_NUM);
  1655. if (!msg)
  1656. return -ENOMEM;
  1657. if (nla_put_u64_64bit(msg, QCA_ATTR_TSF,
  1658. le64_to_cpu(reply.evt.tsf),
  1659. QCA_ATTR_PAD))
  1660. goto nla_put_failure;
  1661. nl_cfgs = nla_nest_start(msg, QCA_ATTR_DMG_RF_SECTOR_CFG);
  1662. if (!nl_cfgs)
  1663. goto nla_put_failure;
  1664. for (i = 0; i < WMI_MAX_RF_MODULES_NUM; i++) {
  1665. if (!(rf_modules_vec & BIT(i)))
  1666. continue;
  1667. nl_cfg = nla_nest_start(msg, i);
  1668. if (!nl_cfg)
  1669. goto nla_put_failure;
  1670. si = &reply.evt.sectors_info[i];
  1671. if (nla_put_u8(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX,
  1672. i) ||
  1673. nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0,
  1674. le32_to_cpu(si->etype0)) ||
  1675. nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1,
  1676. le32_to_cpu(si->etype1)) ||
  1677. nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2,
  1678. le32_to_cpu(si->etype2)) ||
  1679. nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI,
  1680. le32_to_cpu(si->psh_hi)) ||
  1681. nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO,
  1682. le32_to_cpu(si->psh_lo)) ||
  1683. nla_put_u32(msg, QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16,
  1684. le32_to_cpu(si->dtype_swch_off)))
  1685. goto nla_put_failure;
  1686. nla_nest_end(msg, nl_cfg);
  1687. }
  1688. nla_nest_end(msg, nl_cfgs);
  1689. rc = cfg80211_vendor_cmd_reply(msg);
  1690. return rc;
  1691. nla_put_failure:
  1692. kfree_skb(msg);
  1693. return -ENOBUFS;
  1694. }
  1695. static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
  1696. struct wireless_dev *wdev,
  1697. const void *data, int data_len)
  1698. {
  1699. struct wil6210_priv *wil = wdev_to_wil(wdev);
  1700. int rc, tmp;
  1701. struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
  1702. struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1];
  1703. u16 sector_index, rf_module_index;
  1704. u8 sector_type;
  1705. u32 rf_modules_vec = 0;
  1706. struct wmi_set_rf_sector_params_cmd cmd;
  1707. struct {
  1708. struct wmi_cmd_hdr wmi;
  1709. struct wmi_set_rf_sector_params_done_event evt;
  1710. } __packed reply;
  1711. struct nlattr *nl_cfg;
  1712. struct wmi_rf_sector_info *si;
  1713. if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
  1714. return -EOPNOTSUPP;
  1715. rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
  1716. wil_rf_sector_policy, NULL);
  1717. if (rc) {
  1718. wil_err(wil, "Invalid rf sector ATTR\n");
  1719. return rc;
  1720. }
  1721. if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
  1722. !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE] ||
  1723. !tb[QCA_ATTR_DMG_RF_SECTOR_CFG]) {
  1724. wil_err(wil, "Invalid rf sector spec\n");
  1725. return -EINVAL;
  1726. }
  1727. sector_index = nla_get_u16(
  1728. tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
  1729. if (sector_index >= WIL_MAX_RF_SECTORS) {
  1730. wil_err(wil, "Invalid sector index %d\n", sector_index);
  1731. return -EINVAL;
  1732. }
  1733. sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
  1734. if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
  1735. wil_err(wil, "Invalid sector type %d\n", sector_type);
  1736. return -EINVAL;
  1737. }
  1738. memset(&cmd, 0, sizeof(cmd));
  1739. cmd.sector_idx = cpu_to_le16(sector_index);
  1740. cmd.sector_type = sector_type;
  1741. nla_for_each_nested(nl_cfg, tb[QCA_ATTR_DMG_RF_SECTOR_CFG],
  1742. tmp) {
  1743. rc = nla_parse_nested(tb2, QCA_ATTR_DMG_RF_SECTOR_CFG_MAX,
  1744. nl_cfg, wil_rf_sector_cfg_policy,
  1745. NULL);
  1746. if (rc) {
  1747. wil_err(wil, "invalid sector cfg\n");
  1748. return -EINVAL;
  1749. }
  1750. if (!tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX] ||
  1751. !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0] ||
  1752. !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1] ||
  1753. !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2] ||
  1754. !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI] ||
  1755. !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO] ||
  1756. !tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16]) {
  1757. wil_err(wil, "missing cfg params\n");
  1758. return -EINVAL;
  1759. }
  1760. rf_module_index = nla_get_u8(
  1761. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX]);
  1762. if (rf_module_index >= WMI_MAX_RF_MODULES_NUM) {
  1763. wil_err(wil, "invalid RF module index %d\n",
  1764. rf_module_index);
  1765. return -EINVAL;
  1766. }
  1767. rf_modules_vec |= BIT(rf_module_index);
  1768. si = &cmd.sectors_info[rf_module_index];
  1769. si->etype0 = cpu_to_le32(nla_get_u32(
  1770. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE0]));
  1771. si->etype1 = cpu_to_le32(nla_get_u32(
  1772. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE1]));
  1773. si->etype2 = cpu_to_le32(nla_get_u32(
  1774. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_ETYPE2]));
  1775. si->psh_hi = cpu_to_le32(nla_get_u32(
  1776. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_HI]));
  1777. si->psh_lo = cpu_to_le32(nla_get_u32(
  1778. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_PSH_LO]));
  1779. si->dtype_swch_off = cpu_to_le32(nla_get_u32(
  1780. tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16]));
  1781. }
  1782. cmd.rf_modules_vec = rf_modules_vec & 0xFF;
  1783. memset(&reply, 0, sizeof(reply));
  1784. rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd),
  1785. WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID,
  1786. &reply, sizeof(reply),
  1787. 500);
  1788. if (rc)
  1789. return rc;
  1790. return wil_rf_sector_status_to_rc(reply.evt.status);
  1791. }
  1792. static int wil_rf_sector_get_selected(struct wiphy *wiphy,
  1793. struct wireless_dev *wdev,
  1794. const void *data, int data_len)
  1795. {
  1796. struct wil6210_priv *wil = wdev_to_wil(wdev);
  1797. int rc;
  1798. struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
  1799. u8 sector_type, mac_addr[ETH_ALEN];
  1800. int cid = 0;
  1801. struct wmi_get_selected_rf_sector_index_cmd cmd;
  1802. struct {
  1803. struct wmi_cmd_hdr wmi;
  1804. struct wmi_get_selected_rf_sector_index_done_event evt;
  1805. } __packed reply;
  1806. struct sk_buff *msg;
  1807. if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
  1808. return -EOPNOTSUPP;
  1809. rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
  1810. wil_rf_sector_policy, NULL);
  1811. if (rc) {
  1812. wil_err(wil, "Invalid rf sector ATTR\n");
  1813. return rc;
  1814. }
  1815. if (!tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]) {
  1816. wil_err(wil, "Invalid rf sector spec\n");
  1817. return -EINVAL;
  1818. }
  1819. sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
  1820. if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
  1821. wil_err(wil, "Invalid sector type %d\n", sector_type);
  1822. return -EINVAL;
  1823. }
  1824. if (tb[QCA_ATTR_MAC_ADDR]) {
  1825. ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
  1826. cid = wil_find_cid(wil, mac_addr);
  1827. if (cid < 0) {
  1828. wil_err(wil, "invalid MAC address %pM\n", mac_addr);
  1829. return -ENOENT;
  1830. }
  1831. } else {
  1832. if (test_bit(wil_status_fwconnected, wil->status)) {
  1833. wil_err(wil, "must specify MAC address when connected\n");
  1834. return -EINVAL;
  1835. }
  1836. }
  1837. memset(&cmd, 0, sizeof(cmd));
  1838. cmd.cid = (u8)cid;
  1839. cmd.sector_type = sector_type;
  1840. memset(&reply, 0, sizeof(reply));
  1841. rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID,
  1842. &cmd, sizeof(cmd),
  1843. WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
  1844. &reply, sizeof(reply),
  1845. 500);
  1846. if (rc)
  1847. return rc;
  1848. if (reply.evt.status) {
  1849. wil_err(wil, "get rf selected sector cfg failed with status %d\n",
  1850. reply.evt.status);
  1851. return wil_rf_sector_status_to_rc(reply.evt.status);
  1852. }
  1853. msg = cfg80211_vendor_cmd_alloc_reply_skb(
  1854. wiphy, 64 * WMI_MAX_RF_MODULES_NUM);
  1855. if (!msg)
  1856. return -ENOMEM;
  1857. if (nla_put_u64_64bit(msg, QCA_ATTR_TSF,
  1858. le64_to_cpu(reply.evt.tsf),
  1859. QCA_ATTR_PAD) ||
  1860. nla_put_u16(msg, QCA_ATTR_DMG_RF_SECTOR_INDEX,
  1861. le16_to_cpu(reply.evt.sector_idx)))
  1862. goto nla_put_failure;
  1863. rc = cfg80211_vendor_cmd_reply(msg);
  1864. return rc;
  1865. nla_put_failure:
  1866. kfree_skb(msg);
  1867. return -ENOBUFS;
  1868. }
  1869. static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
  1870. u16 sector_index,
  1871. u8 sector_type, u8 cid)
  1872. {
  1873. struct wmi_set_selected_rf_sector_index_cmd cmd;
  1874. struct {
  1875. struct wmi_cmd_hdr wmi;
  1876. struct wmi_set_selected_rf_sector_index_done_event evt;
  1877. } __packed reply;
  1878. int rc;
  1879. memset(&cmd, 0, sizeof(cmd));
  1880. cmd.sector_idx = cpu_to_le16(sector_index);
  1881. cmd.sector_type = sector_type;
  1882. cmd.cid = (u8)cid;
  1883. memset(&reply, 0, sizeof(reply));
  1884. rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID,
  1885. &cmd, sizeof(cmd),
  1886. WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
  1887. &reply, sizeof(reply),
  1888. 500);
  1889. if (rc)
  1890. return rc;
  1891. return wil_rf_sector_status_to_rc(reply.evt.status);
  1892. }
  1893. static int wil_rf_sector_set_selected(struct wiphy *wiphy,
  1894. struct wireless_dev *wdev,
  1895. const void *data, int data_len)
  1896. {
  1897. struct wil6210_priv *wil = wdev_to_wil(wdev);
  1898. int rc;
  1899. struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
  1900. u16 sector_index;
  1901. u8 sector_type, mac_addr[ETH_ALEN], i;
  1902. int cid = 0;
  1903. if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
  1904. return -EOPNOTSUPP;
  1905. rc = nla_parse(tb, QCA_ATTR_DMG_RF_SECTOR_MAX, data, data_len,
  1906. wil_rf_sector_policy, NULL);
  1907. if (rc) {
  1908. wil_err(wil, "Invalid rf sector ATTR\n");
  1909. return rc;
  1910. }
  1911. if (!tb[QCA_ATTR_DMG_RF_SECTOR_INDEX] ||
  1912. !tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]) {
  1913. wil_err(wil, "Invalid rf sector spec\n");
  1914. return -EINVAL;
  1915. }
  1916. sector_index = nla_get_u16(
  1917. tb[QCA_ATTR_DMG_RF_SECTOR_INDEX]);
  1918. if (sector_index >= WIL_MAX_RF_SECTORS &&
  1919. sector_index != WMI_INVALID_RF_SECTOR_INDEX) {
  1920. wil_err(wil, "Invalid sector index %d\n", sector_index);
  1921. return -EINVAL;
  1922. }
  1923. sector_type = nla_get_u8(tb[QCA_ATTR_DMG_RF_SECTOR_TYPE]);
  1924. if (sector_type >= QCA_ATTR_DMG_RF_SECTOR_TYPE_MAX) {
  1925. wil_err(wil, "Invalid sector type %d\n", sector_type);
  1926. return -EINVAL;
  1927. }
  1928. if (tb[QCA_ATTR_MAC_ADDR]) {
  1929. ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
  1930. if (!is_broadcast_ether_addr(mac_addr)) {
  1931. cid = wil_find_cid(wil, mac_addr);
  1932. if (cid < 0) {
  1933. wil_err(wil, "invalid MAC address %pM\n",
  1934. mac_addr);
  1935. return -ENOENT;
  1936. }
  1937. } else {
  1938. if (sector_index != WMI_INVALID_RF_SECTOR_INDEX) {
  1939. wil_err(wil, "broadcast MAC valid only with unlocking\n");
  1940. return -EINVAL;
  1941. }
  1942. cid = -1;
  1943. }
  1944. } else {
  1945. if (test_bit(wil_status_fwconnected, wil->status)) {
  1946. wil_err(wil, "must specify MAC address when connected\n");
  1947. return -EINVAL;
  1948. }
  1949. /* otherwise, using cid=0 for unassociated station */
  1950. }
  1951. if (cid >= 0) {
  1952. rc = wil_rf_sector_wmi_set_selected(wil, sector_index,
  1953. sector_type, cid);
  1954. } else {
  1955. /* unlock all cids */
  1956. rc = wil_rf_sector_wmi_set_selected(
  1957. wil, WMI_INVALID_RF_SECTOR_INDEX, sector_type,
  1958. WIL_CID_ALL);
  1959. if (rc == -EINVAL) {
  1960. for (i = 0; i < WIL6210_MAX_CID; i++) {
  1961. rc = wil_rf_sector_wmi_set_selected(
  1962. wil, WMI_INVALID_RF_SECTOR_INDEX,
  1963. sector_type, i);
  1964. /* the FW will silently ignore and return
  1965. * success for unused cid, so abort the loop
  1966. * on any other error
  1967. */
  1968. if (rc) {
  1969. wil_err(wil, "unlock cid %d failed with status %d\n",
  1970. i, rc);
  1971. break;
  1972. }
  1973. }
  1974. }
  1975. }
  1976. return rc;
  1977. }