ath10k-firmware: remove dependency on kmod-ath10k so that it can be selected instead
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 374-0009-brcmfmac-Add-wowl-wake-indication-report.patch
1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Thu, 29 Oct 2015 20:33:19 +0100
3 Subject: [PATCH] brcmfmac: Add wowl wake indication report.
4
5 On wakeup of the system (resume) a wowl wakeup indication report
6 can be sent to cfg80211. This patch adds support for this. The
7 report specifies if the device was responsible for the wakeup
8 and if so, will specify the exact reason.
9
10 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
11 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
13 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
16 ---
17
18 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
19 +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
20 @@ -3061,6 +3061,67 @@ static s32 brcmf_config_wowl_pattern(str
21         return ret;
22  }
23  
24 +#ifdef CPTCFG_PM
25 +
26 +static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
27 +{
28 +       struct brcmf_wowl_wakeind_le wake_ind_le;
29 +       struct cfg80211_wowlan_wakeup wakeup_data;
30 +       struct cfg80211_wowlan_wakeup *wakeup;
31 +       u32 wakeind;
32 +       s32 err;
33 +
34 +       err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
35 +                                      sizeof(wake_ind_le));
36 +       if (!err) {
37 +               brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
38 +               return;
39 +       }
40 +
41 +       wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
42 +       if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
43 +                      BRCMF_WOWL_RETR | BRCMF_WOWL_NET)) {
44 +               wakeup = &wakeup_data;
45 +               memset(&wakeup_data, 0, sizeof(wakeup_data));
46 +               wakeup_data.pattern_idx = -1;
47 +
48 +               if (wakeind & BRCMF_WOWL_MAGIC) {
49 +                       brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
50 +                       wakeup_data.magic_pkt = true;
51 +               }
52 +               if (wakeind & BRCMF_WOWL_DIS) {
53 +                       brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
54 +                       wakeup_data.disconnect = true;
55 +               }
56 +               if (wakeind & BRCMF_WOWL_BCN) {
57 +                       brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
58 +                       wakeup_data.disconnect = true;
59 +               }
60 +               if (wakeind & BRCMF_WOWL_RETR) {
61 +                       brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
62 +                       wakeup_data.disconnect = true;
63 +               }
64 +               if (wakeind & BRCMF_WOWL_NET) {
65 +                       brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
66 +                       /* For now always map to pattern 0, no API to get
67 +                        * correct information available at the moment.
68 +                        */
69 +                       wakeup_data.pattern_idx = 0;
70 +               }
71 +       } else {
72 +               wakeup = NULL;
73 +       }
74 +       cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
75 +}
76 +
77 +#else
78 +
79 +static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
80 +{
81 +}
82 +
83 +#endif /* CPTCFG_PM */
84 +
85  static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
86  {
87         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
88 @@ -3070,11 +3131,12 @@ static s32 brcmf_cfg80211_resume(struct
89         brcmf_dbg(TRACE, "Enter\n");
90  
91         if (cfg->wowl_enabled) {
92 +               brcmf_report_wowl_wakeind(wiphy, ifp);
93 +               brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
94 +               brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
95                 brcmf_configure_arp_offload(ifp, true);
96                 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
97                                       cfg->pre_wowl_pmmode);
98 -               brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
99 -               brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
100                 cfg->wowl_enabled = false;
101         }
102         return 0;
103 @@ -3108,6 +3170,7 @@ static void brcmf_configure_wowl(struct
104                                 wowl->patterns[i].pkt_offset);
105                 }
106         }
107 +       brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear"));
108         brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
109         brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
110         brcmf_bus_wowl_config(cfg->pub->bus_if, true);
111 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
112 +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
113 @@ -634,4 +634,16 @@ struct brcmf_assoclist_le {
114         u8 mac[BRCMF_MAX_ASSOCLIST][ETH_ALEN];
115  };
116  
117 +/**
118 + * struct brcmf_wowl_wakeind_le - Wakeup indicators
119 + *     Note: note both fields contain same information.
120 + *
121 + * @pci_wakeind: Whether PCI PMECSR PMEStatus bit was set.
122 + * @ucode_wakeind: What wakeup-event indication was set by ucode
123 + */
124 +struct brcmf_wowl_wakeind_le {
125 +       __le32 pci_wakeind;
126 +       __le32 ucode_wakeind;
127 +};
128 +
129  #endif /* FWIL_TYPES_H_ */