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

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

brcmfmac: Add support for scheduled scan mac randomization



Scheduled scan be requested to use mac randomization. This patch
checks the flags and enables the randomization if desired.

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 3f5893d1
Loading
Loading
Loading
Loading
+47 −7
Original line number Diff line number Diff line
@@ -3544,9 +3544,14 @@ static int brcmf_dev_pno_clean(struct net_device *ndev)
	return ret;
}

static int brcmf_dev_pno_config(struct net_device *ndev)
static int brcmf_dev_pno_config(struct brcmf_if *ifp,
				struct cfg80211_sched_scan_request *request)
{
	struct brcmf_pno_param_le pfn_param;
	struct brcmf_pno_macaddr_le pfn_mac;
	s32 err;
	u8 *mac_mask;
	int i;

	memset(&pfn_param, 0, sizeof(pfn_param));
	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
@@ -3559,8 +3564,37 @@ static int brcmf_dev_pno_config(struct net_device *ndev)
	/* set up pno scan fr */
	pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);

	return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
					&pfn_param, sizeof(pfn_param));
	err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
				       sizeof(pfn_param));
	if (err) {
		brcmf_err("pfn_set failed, err=%d\n", err);
		return err;
	}

	/* Find out if mac randomization should be turned on */
	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
		return 0;

	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
	pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;

	memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
	mac_mask = request->mac_addr_mask;
	for (i = 0; i < ETH_ALEN; i++) {
		pfn_mac.mac[i] &= mac_mask[i];
		pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
	}
	/* Clear multi bit */
	pfn_mac.mac[0] &= 0xFE;
	/* Set locally administered */
	pfn_mac.mac[0] |= 0x02;

	err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
				       sizeof(pfn_mac));
	if (err)
		brcmf_err("pfn_macaddr failed, err=%d\n", err);

	return err;
}

static int
@@ -3614,11 +3648,8 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
		}

		/* configure pno */
		ret = brcmf_dev_pno_config(ndev);
		if (ret < 0) {
			brcmf_err("PNO setup failed!! ret=%d\n", ret);
		if (brcmf_dev_pno_config(ifp, request))
			return -EINVAL;
		}

		/* configure each match set */
		for (i = 0; i < request->n_match_sets; i++) {
@@ -6455,6 +6486,15 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
		goto wiphy_unreg_out;
	}

	/* Fill in some of the advertised nl80211 supported features */
	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
		wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
#ifdef CONFIG_PM
		if (wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
			wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
#endif
	}

	return cfg;

wiphy_unreg_out:
+10 −0
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@
#include <linux/module.h>

#include <brcm_hw_ids.h>
#include <brcmu_wifi.h>
#include "core.h"
#include "bus.h"
#include "debug.h"
#include "fwil.h"
#include "fwil_types.h"
#include "feature.h"


@@ -129,6 +131,8 @@ static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
void brcmf_feat_attach(struct brcmf_pub *drvr)
{
	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
	struct brcmf_pno_macaddr_le pfn_mac;
	s32 err;

	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
@@ -140,6 +144,12 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");

	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
	err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac,
				       sizeof(pfn_mac));
	if (!err)
		ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_SCAN_RANDOM_MAC);

	if (brcmf_feature_disable) {
		brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n",
			  ifp->drvr->feat_flags, brcmf_feature_disable);
+3 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
 * P2P: peer-to-peer
 * RSDB: Real Simultaneous Dual Band
 * TDLS: Tunneled Direct Link Setup
 * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan.
 */
#define BRCMF_FEAT_LIST \
	BRCMF_FEAT_DEF(MBSS) \
@@ -34,7 +35,8 @@
	BRCMF_FEAT_DEF(WOWL) \
	BRCMF_FEAT_DEF(P2P) \
	BRCMF_FEAT_DEF(RSDB) \
	BRCMF_FEAT_DEF(TDLS)
	BRCMF_FEAT_DEF(TDLS) \
	BRCMF_FEAT_DEF(SCAN_RANDOM_MAC)

/*
 * Quirks:
+17 −0
Original line number Diff line number Diff line
@@ -128,6 +128,10 @@

#define	BRCMF_MAXPMKID			16	/* max # PMKID cache entries */

#define BRCMF_PFN_MACADDR_CFG_VER	1
#define BRCMF_PFN_MAC_OUI_ONLY		BIT(0)
#define BRCMF_PFN_SET_MAC_UNASSOC	BIT(1)

/* join preference types for join_pref iovar */
enum brcmf_join_pref_types {
	BRCMF_JOIN_PREF_RSSI = 1,
@@ -751,6 +755,19 @@ struct brcmf_pno_scanresults_le {
	__le32 count;
};

/**
 * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization.
 *
 * @version: PNO version identifier.
 * @flags: Flags defining how mac addrss should be used.
 * @mac: MAC address.
 */
struct brcmf_pno_macaddr_le {
	u8 version;
	u8 flags;
	u8 mac[ETH_ALEN];
};

/**
 * struct brcmf_pktcnt_le - packet counters.
 *