Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aeb64225 authored by Hante Meuleman's avatar Hante Meuleman Committed by Kalle Valo
Browse files

brcmfmac: Add wowl wake indication report.



On wakeup of the system (resume) a wowl wakeup indication report
can be sent to cfg80211. This patch adds support for this. The
report specifies if the device was responsible for the wakeup
and if so, will specify the exact reason.

Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent c2a43a6b
Loading
Loading
Loading
Loading
+65 −2
Original line number Diff line number Diff line
@@ -3062,6 +3062,67 @@ static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
	return ret;
}

#ifdef CONFIG_PM

static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
{
	struct brcmf_wowl_wakeind_le wake_ind_le;
	struct cfg80211_wowlan_wakeup wakeup_data;
	struct cfg80211_wowlan_wakeup *wakeup;
	u32 wakeind;
	s32 err;

	err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
				       sizeof(wake_ind_le));
	if (!err) {
		brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
		return;
	}

	wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
	if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
		       BRCMF_WOWL_RETR | BRCMF_WOWL_NET)) {
		wakeup = &wakeup_data;
		memset(&wakeup_data, 0, sizeof(wakeup_data));
		wakeup_data.pattern_idx = -1;

		if (wakeind & BRCMF_WOWL_MAGIC) {
			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
			wakeup_data.magic_pkt = true;
		}
		if (wakeind & BRCMF_WOWL_DIS) {
			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
			wakeup_data.disconnect = true;
		}
		if (wakeind & BRCMF_WOWL_BCN) {
			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
			wakeup_data.disconnect = true;
		}
		if (wakeind & BRCMF_WOWL_RETR) {
			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
			wakeup_data.disconnect = true;
		}
		if (wakeind & BRCMF_WOWL_NET) {
			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
			/* For now always map to pattern 0, no API to get
			 * correct information available at the moment.
			 */
			wakeup_data.pattern_idx = 0;
		}
	} else {
		wakeup = NULL;
	}
	cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
}

#else

static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
{
}

#endif /* CONFIG_PM */

static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
{
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
@@ -3071,11 +3132,12 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
	brcmf_dbg(TRACE, "Enter\n");

	if (cfg->wowl_enabled) {
		brcmf_report_wowl_wakeind(wiphy, ifp);
		brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
		brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
		brcmf_configure_arp_offload(ifp, true);
		brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
				      cfg->pre_wowl_pmmode);
		brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
		brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
		cfg->wowl_enabled = false;
	}
	return 0;
@@ -3109,6 +3171,7 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
				wowl->patterns[i].pkt_offset);
		}
	}
	brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear"));
	brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
	brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
	brcmf_bus_wowl_config(cfg->pub->bus_if, true);
+12 −0
Original line number Diff line number Diff line
@@ -634,4 +634,16 @@ struct brcmf_assoclist_le {
	u8 mac[BRCMF_MAX_ASSOCLIST][ETH_ALEN];
};

/**
 * struct brcmf_wowl_wakeind_le - Wakeup indicators
 *	Note: note both fields contain same information.
 *
 * @pci_wakeind: Whether PCI PMECSR PMEStatus bit was set.
 * @ucode_wakeind: What wakeup-event indication was set by ucode
 */
struct brcmf_wowl_wakeind_le {
	__le32 pci_wakeind;
	__le32 ucode_wakeind;
};

#endif /* FWIL_TYPES_H_ */