wow.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. // SPDX-License-Identifier: BSD-3-Clause-Clear
  2. /*
  3. * Copyright (c) 2020 The Linux Foundation. All rights reserved.
  4. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  5. */
  6. #include <linux/delay.h>
  7. #include <linux/inetdevice.h>
  8. #include <net/addrconf.h>
  9. #include <net/if_inet6.h>
  10. #include <net/ipv6.h>
  11. #include "mac.h"
  12. #include <net/mac80211.h>
  13. #include "core.h"
  14. #include "hif.h"
  15. #include "debug.h"
  16. #include "wmi.h"
  17. #include "wow.h"
  18. static const struct wiphy_wowlan_support ath12k_wowlan_support = {
  19. .flags = WIPHY_WOWLAN_DISCONNECT |
  20. WIPHY_WOWLAN_MAGIC_PKT |
  21. WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
  22. WIPHY_WOWLAN_GTK_REKEY_FAILURE,
  23. .pattern_min_len = WOW_MIN_PATTERN_SIZE,
  24. .pattern_max_len = WOW_MAX_PATTERN_SIZE,
  25. .max_pkt_offset = WOW_MAX_PKT_OFFSET,
  26. };
  27. static inline bool ath12k_wow_is_p2p_vdev(struct ath12k_vif *ahvif)
  28. {
  29. return (ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_DEVICE ||
  30. ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_CLIENT ||
  31. ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_GO);
  32. }
  33. int ath12k_wow_enable(struct ath12k *ar)
  34. {
  35. struct ath12k_base *ab = ar->ab;
  36. int i, ret;
  37. clear_bit(ATH12K_FLAG_HTC_SUSPEND_COMPLETE, &ab->dev_flags);
  38. /* The firmware might be busy and it can not enter WoW immediately.
  39. * In that case firmware notifies host with
  40. * ATH12K_HTC_MSG_NACK_SUSPEND message, asking host to try again
  41. * later. Per the firmware team there could be up to 10 loops.
  42. */
  43. for (i = 0; i < ATH12K_WOW_RETRY_NUM; i++) {
  44. reinit_completion(&ab->htc_suspend);
  45. ret = ath12k_wmi_wow_enable(ar);
  46. if (ret) {
  47. ath12k_warn(ab, "failed to issue wow enable: %d\n", ret);
  48. return ret;
  49. }
  50. ret = wait_for_completion_timeout(&ab->htc_suspend, 3 * HZ);
  51. if (ret == 0) {
  52. ath12k_warn(ab,
  53. "timed out while waiting for htc suspend completion\n");
  54. return -ETIMEDOUT;
  55. }
  56. if (test_bit(ATH12K_FLAG_HTC_SUSPEND_COMPLETE, &ab->dev_flags))
  57. /* success, suspend complete received */
  58. return 0;
  59. ath12k_warn(ab, "htc suspend not complete, retrying (try %d)\n",
  60. i);
  61. msleep(ATH12K_WOW_RETRY_WAIT_MS);
  62. }
  63. ath12k_warn(ab, "htc suspend not complete, failing after %d tries\n", i);
  64. return -ETIMEDOUT;
  65. }
  66. int ath12k_wow_wakeup(struct ath12k *ar)
  67. {
  68. struct ath12k_base *ab = ar->ab;
  69. int ret;
  70. reinit_completion(&ab->wow.wakeup_completed);
  71. ret = ath12k_wmi_wow_host_wakeup_ind(ar);
  72. if (ret) {
  73. ath12k_warn(ab, "failed to send wow wakeup indication: %d\n",
  74. ret);
  75. return ret;
  76. }
  77. ret = wait_for_completion_timeout(&ab->wow.wakeup_completed, 3 * HZ);
  78. if (ret == 0) {
  79. ath12k_warn(ab, "timed out while waiting for wow wakeup completion\n");
  80. return -ETIMEDOUT;
  81. }
  82. return 0;
  83. }
  84. static int ath12k_wow_vif_cleanup(struct ath12k_link_vif *arvif)
  85. {
  86. struct ath12k *ar = arvif->ar;
  87. int i, ret;
  88. for (i = 0; i < WOW_EVENT_MAX; i++) {
  89. ret = ath12k_wmi_wow_add_wakeup_event(ar, arvif->vdev_id, i, 0);
  90. if (ret) {
  91. ath12k_warn(ar->ab, "failed to issue wow wakeup for event %s on vdev %i: %d\n",
  92. wow_wakeup_event(i), arvif->vdev_id, ret);
  93. return ret;
  94. }
  95. }
  96. for (i = 0; i < ar->wow.max_num_patterns; i++) {
  97. ret = ath12k_wmi_wow_del_pattern(ar, arvif->vdev_id, i);
  98. if (ret) {
  99. ath12k_warn(ar->ab, "failed to delete wow pattern %d for vdev %i: %d\n",
  100. i, arvif->vdev_id, ret);
  101. return ret;
  102. }
  103. }
  104. return 0;
  105. }
  106. static int ath12k_wow_cleanup(struct ath12k *ar)
  107. {
  108. struct ath12k_link_vif *arvif;
  109. int ret;
  110. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  111. list_for_each_entry(arvif, &ar->arvifs, list) {
  112. if (arvif != &arvif->ahvif->deflink)
  113. continue;
  114. ret = ath12k_wow_vif_cleanup(arvif);
  115. if (ret) {
  116. ath12k_warn(ar->ab, "failed to clean wow wakeups on vdev %i: %d\n",
  117. arvif->vdev_id, ret);
  118. return ret;
  119. }
  120. }
  121. return 0;
  122. }
  123. /* Convert a 802.3 format to a 802.11 format.
  124. * +------------+-----------+--------+----------------+
  125. * 802.3: |dest mac(6B)|src mac(6B)|type(2B)| body... |
  126. * +------------+-----------+--------+----------------+
  127. * |__ |_______ |____________ |________
  128. * | | | |
  129. * +--+------------+----+-----------+---------------+-----------+
  130. * 802.11: |4B|dest mac(6B)| 6B |src mac(6B)| 8B |type(2B)| body... |
  131. * +--+------------+----+-----------+---------------+-----------+
  132. */
  133. static void
  134. ath12k_wow_convert_8023_to_80211(struct ath12k *ar,
  135. const struct cfg80211_pkt_pattern *eth_pattern,
  136. struct ath12k_pkt_pattern *i80211_pattern)
  137. {
  138. size_t r1042_eth_ofs = offsetof(struct rfc1042_hdr, eth_type);
  139. size_t a1_ofs = offsetof(struct ieee80211_hdr_3addr, addr1);
  140. size_t a3_ofs = offsetof(struct ieee80211_hdr_3addr, addr3);
  141. size_t i80211_hdr_len = sizeof(struct ieee80211_hdr_3addr);
  142. size_t prot_ofs = offsetof(struct ethhdr, h_proto);
  143. size_t src_ofs = offsetof(struct ethhdr, h_source);
  144. u8 eth_bytemask[WOW_MAX_PATTERN_SIZE] = {};
  145. const u8 *eth_pat = eth_pattern->pattern;
  146. size_t eth_pat_len = eth_pattern->pattern_len;
  147. size_t eth_pkt_ofs = eth_pattern->pkt_offset;
  148. u8 *bytemask = i80211_pattern->bytemask;
  149. u8 *pat = i80211_pattern->pattern;
  150. size_t pat_len = 0;
  151. size_t pkt_ofs = 0;
  152. size_t delta;
  153. int i;
  154. /* convert bitmask to bytemask */
  155. for (i = 0; i < eth_pat_len; i++)
  156. if (eth_pattern->mask[i / 8] & BIT(i % 8))
  157. eth_bytemask[i] = 0xff;
  158. if (eth_pkt_ofs < ETH_ALEN) {
  159. pkt_ofs = eth_pkt_ofs + a1_ofs;
  160. if (size_add(eth_pkt_ofs, eth_pat_len) < ETH_ALEN) {
  161. memcpy(pat, eth_pat, eth_pat_len);
  162. memcpy(bytemask, eth_bytemask, eth_pat_len);
  163. pat_len = eth_pat_len;
  164. } else if (size_add(eth_pkt_ofs, eth_pat_len) < prot_ofs) {
  165. memcpy(pat, eth_pat, ETH_ALEN - eth_pkt_ofs);
  166. memcpy(bytemask, eth_bytemask, ETH_ALEN - eth_pkt_ofs);
  167. delta = eth_pkt_ofs + eth_pat_len - src_ofs;
  168. memcpy(pat + a3_ofs - pkt_ofs,
  169. eth_pat + ETH_ALEN - eth_pkt_ofs,
  170. delta);
  171. memcpy(bytemask + a3_ofs - pkt_ofs,
  172. eth_bytemask + ETH_ALEN - eth_pkt_ofs,
  173. delta);
  174. pat_len = a3_ofs - pkt_ofs + delta;
  175. } else {
  176. memcpy(pat, eth_pat, ETH_ALEN - eth_pkt_ofs);
  177. memcpy(bytemask, eth_bytemask, ETH_ALEN - eth_pkt_ofs);
  178. memcpy(pat + a3_ofs - pkt_ofs,
  179. eth_pat + ETH_ALEN - eth_pkt_ofs,
  180. ETH_ALEN);
  181. memcpy(bytemask + a3_ofs - pkt_ofs,
  182. eth_bytemask + ETH_ALEN - eth_pkt_ofs,
  183. ETH_ALEN);
  184. delta = eth_pkt_ofs + eth_pat_len - prot_ofs;
  185. memcpy(pat + i80211_hdr_len + r1042_eth_ofs - pkt_ofs,
  186. eth_pat + prot_ofs - eth_pkt_ofs,
  187. delta);
  188. memcpy(bytemask + i80211_hdr_len + r1042_eth_ofs - pkt_ofs,
  189. eth_bytemask + prot_ofs - eth_pkt_ofs,
  190. delta);
  191. pat_len = i80211_hdr_len + r1042_eth_ofs - pkt_ofs + delta;
  192. }
  193. } else if (eth_pkt_ofs < prot_ofs) {
  194. pkt_ofs = eth_pkt_ofs - ETH_ALEN + a3_ofs;
  195. if (size_add(eth_pkt_ofs, eth_pat_len) < prot_ofs) {
  196. memcpy(pat, eth_pat, eth_pat_len);
  197. memcpy(bytemask, eth_bytemask, eth_pat_len);
  198. pat_len = eth_pat_len;
  199. } else {
  200. memcpy(pat, eth_pat, prot_ofs - eth_pkt_ofs);
  201. memcpy(bytemask, eth_bytemask, prot_ofs - eth_pkt_ofs);
  202. delta = eth_pkt_ofs + eth_pat_len - prot_ofs;
  203. memcpy(pat + i80211_hdr_len + r1042_eth_ofs - pkt_ofs,
  204. eth_pat + prot_ofs - eth_pkt_ofs,
  205. delta);
  206. memcpy(bytemask + i80211_hdr_len + r1042_eth_ofs - pkt_ofs,
  207. eth_bytemask + prot_ofs - eth_pkt_ofs,
  208. delta);
  209. pat_len = i80211_hdr_len + r1042_eth_ofs - pkt_ofs + delta;
  210. }
  211. } else {
  212. pkt_ofs = eth_pkt_ofs - prot_ofs + i80211_hdr_len + r1042_eth_ofs;
  213. memcpy(pat, eth_pat, eth_pat_len);
  214. memcpy(bytemask, eth_bytemask, eth_pat_len);
  215. pat_len = eth_pat_len;
  216. }
  217. i80211_pattern->pattern_len = pat_len;
  218. i80211_pattern->pkt_offset = pkt_ofs;
  219. }
  220. static int
  221. ath12k_wow_pno_check_and_convert(struct ath12k *ar, u32 vdev_id,
  222. const struct cfg80211_sched_scan_request *nd_config,
  223. struct wmi_pno_scan_req_arg *pno)
  224. {
  225. int i, j;
  226. u8 ssid_len;
  227. pno->enable = 1;
  228. pno->vdev_id = vdev_id;
  229. pno->uc_networks_count = nd_config->n_match_sets;
  230. if (!pno->uc_networks_count ||
  231. pno->uc_networks_count > WMI_PNO_MAX_SUPP_NETWORKS)
  232. return -EINVAL;
  233. if (nd_config->n_channels > WMI_PNO_MAX_NETW_CHANNELS_EX)
  234. return -EINVAL;
  235. /* Filling per profile params */
  236. for (i = 0; i < pno->uc_networks_count; i++) {
  237. ssid_len = nd_config->match_sets[i].ssid.ssid_len;
  238. if (ssid_len == 0 || ssid_len > 32)
  239. return -EINVAL;
  240. pno->a_networks[i].ssid.ssid_len = ssid_len;
  241. memcpy(pno->a_networks[i].ssid.ssid,
  242. nd_config->match_sets[i].ssid.ssid,
  243. ssid_len);
  244. pno->a_networks[i].authentication = 0;
  245. pno->a_networks[i].encryption = 0;
  246. pno->a_networks[i].bcast_nw_type = 0;
  247. /* Copying list of valid channel into request */
  248. pno->a_networks[i].channel_count = nd_config->n_channels;
  249. pno->a_networks[i].rssi_threshold = nd_config->match_sets[i].rssi_thold;
  250. for (j = 0; j < nd_config->n_channels; j++) {
  251. pno->a_networks[i].channels[j] =
  252. nd_config->channels[j]->center_freq;
  253. }
  254. }
  255. /* set scan to passive if no SSIDs are specified in the request */
  256. if (nd_config->n_ssids == 0)
  257. pno->do_passive_scan = true;
  258. else
  259. pno->do_passive_scan = false;
  260. for (i = 0; i < nd_config->n_ssids; i++) {
  261. for (j = 0; j < pno->uc_networks_count; j++) {
  262. if (pno->a_networks[j].ssid.ssid_len ==
  263. nd_config->ssids[i].ssid_len &&
  264. !memcmp(pno->a_networks[j].ssid.ssid,
  265. nd_config->ssids[i].ssid,
  266. pno->a_networks[j].ssid.ssid_len)) {
  267. pno->a_networks[j].bcast_nw_type = BCAST_HIDDEN;
  268. break;
  269. }
  270. }
  271. }
  272. if (nd_config->n_scan_plans == 2) {
  273. pno->fast_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC;
  274. pno->fast_scan_max_cycles = nd_config->scan_plans[0].iterations;
  275. pno->slow_scan_period =
  276. nd_config->scan_plans[1].interval * MSEC_PER_SEC;
  277. } else if (nd_config->n_scan_plans == 1) {
  278. pno->fast_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC;
  279. pno->fast_scan_max_cycles = 1;
  280. pno->slow_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC;
  281. } else {
  282. ath12k_warn(ar->ab, "Invalid number of PNO scan plans: %d",
  283. nd_config->n_scan_plans);
  284. }
  285. if (nd_config->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
  286. /* enable mac randomization */
  287. pno->enable_pno_scan_randomization = 1;
  288. memcpy(pno->mac_addr, nd_config->mac_addr, ETH_ALEN);
  289. memcpy(pno->mac_addr_mask, nd_config->mac_addr_mask, ETH_ALEN);
  290. }
  291. pno->delay_start_time = nd_config->delay;
  292. /* Current FW does not support min-max range for dwell time */
  293. pno->active_max_time = WMI_ACTIVE_MAX_CHANNEL_TIME;
  294. pno->passive_max_time = WMI_PASSIVE_MAX_CHANNEL_TIME;
  295. return 0;
  296. }
  297. static int ath12k_wow_vif_set_wakeups(struct ath12k_link_vif *arvif,
  298. struct cfg80211_wowlan *wowlan)
  299. {
  300. const struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
  301. struct ath12k *ar = arvif->ar;
  302. unsigned long wow_mask = 0;
  303. int pattern_id = 0;
  304. int ret, i, j;
  305. /* Setup requested WOW features */
  306. switch (arvif->ahvif->vdev_type) {
  307. case WMI_VDEV_TYPE_IBSS:
  308. __set_bit(WOW_BEACON_EVENT, &wow_mask);
  309. fallthrough;
  310. case WMI_VDEV_TYPE_AP:
  311. __set_bit(WOW_DEAUTH_RECVD_EVENT, &wow_mask);
  312. __set_bit(WOW_DISASSOC_RECVD_EVENT, &wow_mask);
  313. __set_bit(WOW_PROBE_REQ_WPS_IE_EVENT, &wow_mask);
  314. __set_bit(WOW_AUTH_REQ_EVENT, &wow_mask);
  315. __set_bit(WOW_ASSOC_REQ_EVENT, &wow_mask);
  316. __set_bit(WOW_HTT_EVENT, &wow_mask);
  317. __set_bit(WOW_RA_MATCH_EVENT, &wow_mask);
  318. break;
  319. case WMI_VDEV_TYPE_STA:
  320. if (wowlan->disconnect) {
  321. __set_bit(WOW_DEAUTH_RECVD_EVENT, &wow_mask);
  322. __set_bit(WOW_DISASSOC_RECVD_EVENT, &wow_mask);
  323. __set_bit(WOW_BMISS_EVENT, &wow_mask);
  324. __set_bit(WOW_CSA_IE_EVENT, &wow_mask);
  325. }
  326. if (wowlan->magic_pkt)
  327. __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask);
  328. if (wowlan->nd_config) {
  329. struct wmi_pno_scan_req_arg *pno;
  330. int ret;
  331. pno = kzalloc_obj(*pno);
  332. if (!pno)
  333. return -ENOMEM;
  334. ar->nlo_enabled = true;
  335. ret = ath12k_wow_pno_check_and_convert(ar, arvif->vdev_id,
  336. wowlan->nd_config, pno);
  337. if (!ret) {
  338. ath12k_wmi_wow_config_pno(ar, arvif->vdev_id, pno);
  339. __set_bit(WOW_NLO_DETECTED_EVENT, &wow_mask);
  340. }
  341. kfree(pno);
  342. }
  343. break;
  344. default:
  345. break;
  346. }
  347. for (i = 0; i < wowlan->n_patterns; i++) {
  348. const struct cfg80211_pkt_pattern *eth_pattern = &patterns[i];
  349. struct ath12k_pkt_pattern new_pattern = {};
  350. if (WARN_ON(eth_pattern->pattern_len > WOW_MAX_PATTERN_SIZE))
  351. return -EINVAL;
  352. if (ar->ab->wow.wmi_conf_rx_decap_mode ==
  353. ATH12K_HW_TXRX_NATIVE_WIFI) {
  354. ath12k_wow_convert_8023_to_80211(ar, eth_pattern,
  355. &new_pattern);
  356. if (WARN_ON(new_pattern.pattern_len > WOW_MAX_PATTERN_SIZE))
  357. return -EINVAL;
  358. } else {
  359. memcpy(new_pattern.pattern, eth_pattern->pattern,
  360. eth_pattern->pattern_len);
  361. /* convert bitmask to bytemask */
  362. for (j = 0; j < eth_pattern->pattern_len; j++)
  363. if (eth_pattern->mask[j / 8] & BIT(j % 8))
  364. new_pattern.bytemask[j] = 0xff;
  365. new_pattern.pattern_len = eth_pattern->pattern_len;
  366. new_pattern.pkt_offset = eth_pattern->pkt_offset;
  367. }
  368. ret = ath12k_wmi_wow_add_pattern(ar, arvif->vdev_id,
  369. pattern_id,
  370. new_pattern.pattern,
  371. new_pattern.bytemask,
  372. new_pattern.pattern_len,
  373. new_pattern.pkt_offset);
  374. if (ret) {
  375. ath12k_warn(ar->ab, "failed to add pattern %i to vdev %i: %d\n",
  376. pattern_id,
  377. arvif->vdev_id, ret);
  378. return ret;
  379. }
  380. pattern_id++;
  381. __set_bit(WOW_PATTERN_MATCH_EVENT, &wow_mask);
  382. }
  383. for (i = 0; i < WOW_EVENT_MAX; i++) {
  384. if (!test_bit(i, &wow_mask))
  385. continue;
  386. ret = ath12k_wmi_wow_add_wakeup_event(ar, arvif->vdev_id, i, 1);
  387. if (ret) {
  388. ath12k_warn(ar->ab, "failed to enable wakeup event %s on vdev %i: %d\n",
  389. wow_wakeup_event(i), arvif->vdev_id, ret);
  390. return ret;
  391. }
  392. }
  393. return 0;
  394. }
  395. static int ath12k_wow_set_wakeups(struct ath12k *ar,
  396. struct cfg80211_wowlan *wowlan)
  397. {
  398. struct ath12k_link_vif *arvif;
  399. int ret;
  400. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  401. list_for_each_entry(arvif, &ar->arvifs, list) {
  402. if (arvif != &arvif->ahvif->deflink)
  403. continue;
  404. if (ath12k_wow_is_p2p_vdev(arvif->ahvif))
  405. continue;
  406. ret = ath12k_wow_vif_set_wakeups(arvif, wowlan);
  407. if (ret) {
  408. ath12k_warn(ar->ab, "failed to set wow wakeups on vdev %i: %d\n",
  409. arvif->vdev_id, ret);
  410. return ret;
  411. }
  412. }
  413. return 0;
  414. }
  415. static int ath12k_wow_vdev_clean_nlo(struct ath12k *ar, u32 vdev_id)
  416. {
  417. struct wmi_pno_scan_req_arg *pno;
  418. int ret;
  419. if (!ar->nlo_enabled)
  420. return 0;
  421. pno = kzalloc_obj(*pno);
  422. if (!pno)
  423. return -ENOMEM;
  424. pno->enable = 0;
  425. ret = ath12k_wmi_wow_config_pno(ar, vdev_id, pno);
  426. if (ret) {
  427. ath12k_warn(ar->ab, "failed to disable PNO: %d", ret);
  428. goto out;
  429. }
  430. ar->nlo_enabled = false;
  431. out:
  432. kfree(pno);
  433. return ret;
  434. }
  435. static int ath12k_wow_vif_clean_nlo(struct ath12k_link_vif *arvif)
  436. {
  437. struct ath12k *ar = arvif->ar;
  438. switch (arvif->ahvif->vdev_type) {
  439. case WMI_VDEV_TYPE_STA:
  440. return ath12k_wow_vdev_clean_nlo(ar, arvif->vdev_id);
  441. default:
  442. return 0;
  443. }
  444. }
  445. static int ath12k_wow_nlo_cleanup(struct ath12k *ar)
  446. {
  447. struct ath12k_link_vif *arvif;
  448. int ret;
  449. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  450. list_for_each_entry(arvif, &ar->arvifs, list) {
  451. if (arvif != &arvif->ahvif->deflink)
  452. continue;
  453. if (ath12k_wow_is_p2p_vdev(arvif->ahvif))
  454. continue;
  455. ret = ath12k_wow_vif_clean_nlo(arvif);
  456. if (ret) {
  457. ath12k_warn(ar->ab, "failed to clean nlo settings on vdev %i: %d\n",
  458. arvif->vdev_id, ret);
  459. return ret;
  460. }
  461. }
  462. return 0;
  463. }
  464. static int ath12k_wow_set_hw_filter(struct ath12k *ar)
  465. {
  466. struct wmi_hw_data_filter_arg arg;
  467. struct ath12k_link_vif *arvif;
  468. int ret;
  469. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  470. list_for_each_entry(arvif, &ar->arvifs, list) {
  471. if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA)
  472. continue;
  473. arg.vdev_id = arvif->vdev_id;
  474. arg.enable = true;
  475. arg.hw_filter_bitmap = WMI_HW_DATA_FILTER_DROP_NON_ICMPV6_MC;
  476. ret = ath12k_wmi_hw_data_filter_cmd(ar, &arg);
  477. if (ret) {
  478. ath12k_warn(ar->ab, "failed to set hw data filter on vdev %i: %d\n",
  479. arvif->vdev_id, ret);
  480. return ret;
  481. }
  482. }
  483. return 0;
  484. }
  485. static int ath12k_wow_clear_hw_filter(struct ath12k *ar)
  486. {
  487. struct wmi_hw_data_filter_arg arg;
  488. struct ath12k_link_vif *arvif;
  489. int ret;
  490. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  491. list_for_each_entry(arvif, &ar->arvifs, list) {
  492. if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA)
  493. continue;
  494. arg.vdev_id = arvif->vdev_id;
  495. arg.enable = false;
  496. arg.hw_filter_bitmap = 0;
  497. ret = ath12k_wmi_hw_data_filter_cmd(ar, &arg);
  498. if (ret) {
  499. ath12k_warn(ar->ab, "failed to clear hw data filter on vdev %i: %d\n",
  500. arvif->vdev_id, ret);
  501. return ret;
  502. }
  503. }
  504. return 0;
  505. }
  506. static void ath12k_wow_generate_ns_mc_addr(struct ath12k_base *ab,
  507. struct wmi_arp_ns_offload_arg *offload)
  508. {
  509. int i;
  510. for (i = 0; i < offload->ipv6_count; i++) {
  511. offload->self_ipv6_addr[i][0] = 0xff;
  512. offload->self_ipv6_addr[i][1] = 0x02;
  513. offload->self_ipv6_addr[i][11] = 0x01;
  514. offload->self_ipv6_addr[i][12] = 0xff;
  515. offload->self_ipv6_addr[i][13] =
  516. offload->ipv6_addr[i][13];
  517. offload->self_ipv6_addr[i][14] =
  518. offload->ipv6_addr[i][14];
  519. offload->self_ipv6_addr[i][15] =
  520. offload->ipv6_addr[i][15];
  521. ath12k_dbg(ab, ATH12K_DBG_WOW, "NS solicited addr %pI6\n",
  522. offload->self_ipv6_addr[i]);
  523. }
  524. }
  525. static void ath12k_wow_prepare_ns_offload(struct ath12k_link_vif *arvif,
  526. struct wmi_arp_ns_offload_arg *offload)
  527. {
  528. struct net_device *ndev = ieee80211_vif_to_wdev(arvif->ahvif->vif)->netdev;
  529. struct ath12k_base *ab = arvif->ar->ab;
  530. struct inet6_ifaddr *ifa6;
  531. struct ifacaddr6 *ifaca6;
  532. struct inet6_dev *idev;
  533. u32 count = 0, scope;
  534. if (!ndev)
  535. return;
  536. idev = in6_dev_get(ndev);
  537. if (!idev)
  538. return;
  539. ath12k_dbg(ab, ATH12K_DBG_WOW, "wow prepare ns offload\n");
  540. read_lock_bh(&idev->lock);
  541. /* get unicast address */
  542. list_for_each_entry(ifa6, &idev->addr_list, if_list) {
  543. if (count >= WMI_IPV6_MAX_COUNT)
  544. goto unlock;
  545. if (ifa6->flags & IFA_F_DADFAILED)
  546. continue;
  547. scope = ipv6_addr_src_scope(&ifa6->addr);
  548. if (scope != IPV6_ADDR_SCOPE_LINKLOCAL &&
  549. scope != IPV6_ADDR_SCOPE_GLOBAL) {
  550. ath12k_dbg(ab, ATH12K_DBG_WOW,
  551. "Unsupported ipv6 scope: %d\n", scope);
  552. continue;
  553. }
  554. memcpy(offload->ipv6_addr[count], &ifa6->addr.s6_addr,
  555. sizeof(ifa6->addr.s6_addr));
  556. offload->ipv6_type[count] = WMI_IPV6_UC_TYPE;
  557. ath12k_dbg(ab, ATH12K_DBG_WOW, "mac count %d ipv6 uc %pI6 scope %d\n",
  558. count, offload->ipv6_addr[count],
  559. scope);
  560. count++;
  561. }
  562. /* get anycast address */
  563. rcu_read_lock();
  564. for (ifaca6 = rcu_dereference(idev->ac_list); ifaca6;
  565. ifaca6 = rcu_dereference(ifaca6->aca_next)) {
  566. if (count >= WMI_IPV6_MAX_COUNT) {
  567. rcu_read_unlock();
  568. goto unlock;
  569. }
  570. scope = ipv6_addr_src_scope(&ifaca6->aca_addr);
  571. if (scope != IPV6_ADDR_SCOPE_LINKLOCAL &&
  572. scope != IPV6_ADDR_SCOPE_GLOBAL) {
  573. ath12k_dbg(ab, ATH12K_DBG_WOW,
  574. "Unsupported ipv scope: %d\n", scope);
  575. continue;
  576. }
  577. memcpy(offload->ipv6_addr[count], &ifaca6->aca_addr,
  578. sizeof(ifaca6->aca_addr));
  579. offload->ipv6_type[count] = WMI_IPV6_AC_TYPE;
  580. ath12k_dbg(ab, ATH12K_DBG_WOW, "mac count %d ipv6 ac %pI6 scope %d\n",
  581. count, offload->ipv6_addr[count],
  582. scope);
  583. count++;
  584. }
  585. rcu_read_unlock();
  586. unlock:
  587. read_unlock_bh(&idev->lock);
  588. in6_dev_put(idev);
  589. offload->ipv6_count = count;
  590. ath12k_wow_generate_ns_mc_addr(ab, offload);
  591. }
  592. static void ath12k_wow_prepare_arp_offload(struct ath12k_link_vif *arvif,
  593. struct wmi_arp_ns_offload_arg *offload)
  594. {
  595. struct ieee80211_vif *vif = arvif->ahvif->vif;
  596. struct ieee80211_vif_cfg vif_cfg = vif->cfg;
  597. struct ath12k_base *ab = arvif->ar->ab;
  598. u32 ipv4_cnt;
  599. ath12k_dbg(ab, ATH12K_DBG_WOW, "wow prepare arp offload\n");
  600. ipv4_cnt = min(vif_cfg.arp_addr_cnt, WMI_IPV4_MAX_COUNT);
  601. memcpy(offload->ipv4_addr, vif_cfg.arp_addr_list, ipv4_cnt * sizeof(u32));
  602. offload->ipv4_count = ipv4_cnt;
  603. ath12k_dbg(ab, ATH12K_DBG_WOW,
  604. "wow arp_addr_cnt %d vif->addr %pM, offload_addr %pI4\n",
  605. vif_cfg.arp_addr_cnt, vif->addr, offload->ipv4_addr);
  606. }
  607. static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable)
  608. {
  609. struct wmi_arp_ns_offload_arg *offload;
  610. struct ath12k_link_vif *arvif;
  611. struct ath12k_vif *ahvif;
  612. int ret;
  613. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  614. offload = kmalloc_obj(*offload);
  615. if (!offload)
  616. return -ENOMEM;
  617. list_for_each_entry(arvif, &ar->arvifs, list) {
  618. ahvif = arvif->ahvif;
  619. if (arvif != &ahvif->deflink)
  620. continue;
  621. if (ahvif->vdev_type != WMI_VDEV_TYPE_STA)
  622. continue;
  623. memset(offload, 0, sizeof(*offload));
  624. memcpy(offload->mac_addr, ahvif->vif->addr, ETH_ALEN);
  625. ath12k_wow_prepare_ns_offload(arvif, offload);
  626. ath12k_wow_prepare_arp_offload(arvif, offload);
  627. ret = ath12k_wmi_arp_ns_offload(ar, arvif, offload, enable);
  628. if (ret) {
  629. ath12k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n",
  630. arvif->vdev_id, enable, ret);
  631. kfree(offload);
  632. return ret;
  633. }
  634. }
  635. kfree(offload);
  636. return 0;
  637. }
  638. static int ath12k_gtk_rekey_offload(struct ath12k *ar, bool enable)
  639. {
  640. struct ath12k_link_vif *arvif;
  641. int ret;
  642. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  643. list_for_each_entry(arvif, &ar->arvifs, list) {
  644. if (arvif != &arvif->ahvif->deflink)
  645. continue;
  646. if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA ||
  647. !arvif->is_up ||
  648. !arvif->rekey_data.enable_offload)
  649. continue;
  650. /* get rekey info before disable rekey offload */
  651. if (!enable) {
  652. ret = ath12k_wmi_gtk_rekey_getinfo(ar, arvif);
  653. if (ret) {
  654. ath12k_warn(ar->ab, "failed to request rekey info vdev %i, ret %d\n",
  655. arvif->vdev_id, ret);
  656. return ret;
  657. }
  658. }
  659. ret = ath12k_wmi_gtk_rekey_offload(ar, arvif, enable);
  660. if (ret) {
  661. ath12k_warn(ar->ab, "failed to offload gtk reky vdev %i: enable %d, ret %d\n",
  662. arvif->vdev_id, enable, ret);
  663. return ret;
  664. }
  665. }
  666. return 0;
  667. }
  668. static int ath12k_wow_protocol_offload(struct ath12k *ar, bool enable)
  669. {
  670. int ret;
  671. ret = ath12k_wow_arp_ns_offload(ar, enable);
  672. if (ret) {
  673. ath12k_warn(ar->ab, "failed to offload ARP and NS %d %d\n",
  674. enable, ret);
  675. return ret;
  676. }
  677. ret = ath12k_gtk_rekey_offload(ar, enable);
  678. if (ret) {
  679. ath12k_warn(ar->ab, "failed to offload gtk rekey %d %d\n",
  680. enable, ret);
  681. return ret;
  682. }
  683. return 0;
  684. }
  685. static int ath12k_wow_set_keepalive(struct ath12k *ar,
  686. enum wmi_sta_keepalive_method method,
  687. u32 interval)
  688. {
  689. struct ath12k_link_vif *arvif;
  690. int ret;
  691. lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
  692. list_for_each_entry(arvif, &ar->arvifs, list) {
  693. ret = ath12k_mac_vif_set_keepalive(arvif, method, interval);
  694. if (ret)
  695. return ret;
  696. }
  697. return 0;
  698. }
  699. int ath12k_wow_op_suspend(struct ieee80211_hw *hw,
  700. struct cfg80211_wowlan *wowlan)
  701. {
  702. struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
  703. struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
  704. int ret;
  705. lockdep_assert_wiphy(hw->wiphy);
  706. ret = ath12k_wow_cleanup(ar);
  707. if (ret) {
  708. ath12k_warn(ar->ab, "failed to clear wow wakeup events: %d\n",
  709. ret);
  710. goto exit;
  711. }
  712. ret = ath12k_wow_set_wakeups(ar, wowlan);
  713. if (ret) {
  714. ath12k_warn(ar->ab, "failed to set wow wakeup events: %d\n",
  715. ret);
  716. goto cleanup;
  717. }
  718. ret = ath12k_wow_protocol_offload(ar, true);
  719. if (ret) {
  720. ath12k_warn(ar->ab, "failed to set wow protocol offload events: %d\n",
  721. ret);
  722. goto cleanup;
  723. }
  724. ret = ath12k_mac_wait_tx_complete(ar);
  725. if (ret) {
  726. ath12k_warn(ar->ab, "failed to wait tx complete: %d\n", ret);
  727. goto cleanup;
  728. }
  729. ret = ath12k_wow_set_hw_filter(ar);
  730. if (ret) {
  731. ath12k_warn(ar->ab, "failed to set hw filter: %d\n",
  732. ret);
  733. goto cleanup;
  734. }
  735. ret = ath12k_wow_set_keepalive(ar,
  736. WMI_STA_KEEPALIVE_METHOD_NULL_FRAME,
  737. WMI_STA_KEEPALIVE_INTERVAL_DEFAULT);
  738. if (ret) {
  739. ath12k_warn(ar->ab, "failed to enable wow keepalive: %d\n", ret);
  740. goto cleanup;
  741. }
  742. ret = ath12k_wow_enable(ar);
  743. if (ret) {
  744. ath12k_warn(ar->ab, "failed to start wow: %d\n", ret);
  745. goto cleanup;
  746. }
  747. ath12k_hif_irq_disable(ar->ab);
  748. ath12k_hif_ce_irq_disable(ar->ab);
  749. ret = ath12k_hif_suspend(ar->ab);
  750. if (ret) {
  751. ath12k_warn(ar->ab, "failed to suspend hif: %d\n", ret);
  752. goto wakeup;
  753. }
  754. goto exit;
  755. wakeup:
  756. ath12k_wow_wakeup(ar);
  757. cleanup:
  758. ath12k_wow_cleanup(ar);
  759. exit:
  760. return ret ? 1 : 0;
  761. }
  762. EXPORT_SYMBOL(ath12k_wow_op_suspend);
  763. void ath12k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled)
  764. {
  765. struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
  766. struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
  767. lockdep_assert_wiphy(hw->wiphy);
  768. device_set_wakeup_enable(ar->ab->dev, enabled);
  769. }
  770. EXPORT_SYMBOL(ath12k_wow_op_set_wakeup);
  771. int ath12k_wow_op_resume(struct ieee80211_hw *hw)
  772. {
  773. struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
  774. struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
  775. int ret;
  776. lockdep_assert_wiphy(hw->wiphy);
  777. ret = ath12k_hif_resume(ar->ab);
  778. if (ret) {
  779. ath12k_warn(ar->ab, "failed to resume hif: %d\n", ret);
  780. goto exit;
  781. }
  782. ath12k_hif_ce_irq_enable(ar->ab);
  783. ath12k_hif_irq_enable(ar->ab);
  784. ret = ath12k_wow_wakeup(ar);
  785. if (ret) {
  786. ath12k_warn(ar->ab, "failed to wakeup from wow: %d\n", ret);
  787. goto exit;
  788. }
  789. ret = ath12k_wow_nlo_cleanup(ar);
  790. if (ret) {
  791. ath12k_warn(ar->ab, "failed to cleanup nlo: %d\n", ret);
  792. goto exit;
  793. }
  794. ret = ath12k_wow_clear_hw_filter(ar);
  795. if (ret) {
  796. ath12k_warn(ar->ab, "failed to clear hw filter: %d\n", ret);
  797. goto exit;
  798. }
  799. ret = ath12k_wow_protocol_offload(ar, false);
  800. if (ret) {
  801. ath12k_warn(ar->ab, "failed to clear wow protocol offload events: %d\n",
  802. ret);
  803. goto exit;
  804. }
  805. ret = ath12k_wow_set_keepalive(ar,
  806. WMI_STA_KEEPALIVE_METHOD_NULL_FRAME,
  807. WMI_STA_KEEPALIVE_INTERVAL_DISABLE);
  808. if (ret) {
  809. ath12k_warn(ar->ab, "failed to disable wow keepalive: %d\n", ret);
  810. goto exit;
  811. }
  812. exit:
  813. if (ret) {
  814. switch (ah->state) {
  815. case ATH12K_HW_STATE_ON:
  816. ah->state = ATH12K_HW_STATE_RESTARTING;
  817. ret = 1;
  818. break;
  819. case ATH12K_HW_STATE_OFF:
  820. case ATH12K_HW_STATE_RESTARTING:
  821. case ATH12K_HW_STATE_RESTARTED:
  822. case ATH12K_HW_STATE_WEDGED:
  823. case ATH12K_HW_STATE_TM:
  824. ath12k_warn(ar->ab, "encountered unexpected device state %d on resume, cannot recover\n",
  825. ah->state);
  826. ret = -EIO;
  827. break;
  828. }
  829. }
  830. return ret;
  831. }
  832. EXPORT_SYMBOL(ath12k_wow_op_resume);
  833. int ath12k_wow_init(struct ath12k *ar)
  834. {
  835. if (!test_bit(WMI_TLV_SERVICE_WOW, ar->wmi->wmi_ab->svc_map))
  836. return 0;
  837. ar->wow.wowlan_support = ath12k_wowlan_support;
  838. if (ar->ab->wow.wmi_conf_rx_decap_mode == ATH12K_HW_TXRX_NATIVE_WIFI) {
  839. ar->wow.wowlan_support.pattern_max_len -= WOW_MAX_REDUCE;
  840. ar->wow.wowlan_support.max_pkt_offset -= WOW_MAX_REDUCE;
  841. }
  842. if (test_bit(WMI_TLV_SERVICE_NLO, ar->wmi->wmi_ab->svc_map)) {
  843. ar->wow.wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
  844. ar->wow.wowlan_support.max_nd_match_sets = WMI_PNO_MAX_SUPP_NETWORKS;
  845. }
  846. ar->wow.max_num_patterns = ATH12K_WOW_PATTERNS;
  847. ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns;
  848. ar->ah->hw->wiphy->wowlan = &ar->wow.wowlan_support;
  849. device_set_wakeup_capable(ar->ab->dev, true);
  850. return 0;
  851. }