mwifiex: support random MAC address for scanning

This patch advertises RANDOM_MAC_ADDR feature to cfg80211. It allow the
application to issue scan with a MAC address and mask. Random MACs are
generated and used in probe requests sent for scanning until it is changed
by the application or device is restarted.

Signed-off-by: Ganapathi Bhat <gbhat@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Ganapathi Bhat 2016-07-25 21:21:07 +05:30 committed by Kalle Valo
parent c8ccf3ade7
commit c2a8f0ff9c
4 changed files with 38 additions and 1 deletions

View File

@ -2485,6 +2485,16 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
priv->scan_request = request; priv->scan_request = request;
if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
ether_addr_copy(priv->random_mac, request->mac_addr);
for (i = 0; i < ETH_ALEN; i++) {
priv->random_mac[i] &= request->mac_addr_mask[i];
priv->random_mac[i] |= get_random_int() &
~(request->mac_addr_mask[i]);
}
}
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
user_scan_cfg->num_ssids = request->n_ssids; user_scan_cfg->num_ssids = request->n_ssids;
user_scan_cfg->ssid_list = request->ssids; user_scan_cfg->ssid_list = request->ssids;
@ -4173,7 +4183,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->features |= NL80211_FEATURE_HT_IBSS | wiphy->features |= NL80211_FEATURE_HT_IBSS |
NL80211_FEATURE_INACTIVITY_TIMER | NL80211_FEATURE_INACTIVITY_TIMER |
NL80211_FEATURE_LOW_PRIORITY_SCAN | NL80211_FEATURE_LOW_PRIORITY_SCAN |
NL80211_FEATURE_NEED_OBSS_SCAN; NL80211_FEATURE_NEED_OBSS_SCAN |
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH; wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;

View File

@ -188,6 +188,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202) #define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202)
#define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203) #define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203)
#define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206) #define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206)
#define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236)
#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
@ -780,6 +781,11 @@ struct mwifiex_ie_types_scan_chan_gap {
__le16 chan_gap; __le16 chan_gap;
} __packed; } __packed;
struct mwifiex_ie_types_random_mac {
struct mwifiex_ie_types_header header;
u8 mac[ETH_ALEN];
} __packed;
struct mwifiex_ietypes_chanstats { struct mwifiex_ietypes_chanstats {
struct mwifiex_ie_types_header header; struct mwifiex_ie_types_header header;
struct mwifiex_fw_chan_stats chanstats[0]; struct mwifiex_fw_chan_stats chanstats[0];
@ -1464,6 +1470,7 @@ struct mwifiex_user_scan_cfg {
/* Variable number (fixed maximum) of channels to scan up */ /* Variable number (fixed maximum) of channels to scan up */
struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
u16 scan_chan_gap; u16 scan_chan_gap;
u8 random_mac[ETH_ALEN];
} __packed; } __packed;
#define MWIFIEX_BG_SCAN_CHAN_MAX 38 #define MWIFIEX_BG_SCAN_CHAN_MAX 38

View File

@ -675,6 +675,7 @@ struct mwifiex_private {
struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX]; struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX];
u8 assoc_resp_ht_param; u8 assoc_resp_ht_param;
bool ht_param_present; bool ht_param_present;
u8 random_mac[ETH_ALEN];
}; };

View File

@ -820,6 +820,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_ie_types_num_probes *num_probes_tlv; struct mwifiex_ie_types_num_probes *num_probes_tlv;
struct mwifiex_ie_types_scan_chan_gap *chan_gap_tlv; struct mwifiex_ie_types_scan_chan_gap *chan_gap_tlv;
struct mwifiex_ie_types_random_mac *random_mac_tlv;
struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
struct mwifiex_ie_types_bssid_list *bssid_tlv; struct mwifiex_ie_types_bssid_list *bssid_tlv;
u8 *tlv_pos; u8 *tlv_pos;
@ -835,6 +836,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
u8 ssid_filter; u8 ssid_filter;
struct mwifiex_ie_types_htcap *ht_cap; struct mwifiex_ie_types_htcap *ht_cap;
struct mwifiex_ie_types_bss_mode *bss_mode; struct mwifiex_ie_types_bss_mode *bss_mode;
const u8 zero_mac[6] = {0, 0, 0, 0, 0, 0};
/* The tlv_buf_len is calculated for each scan command. The TLVs added /* The tlv_buf_len is calculated for each scan command. The TLVs added
in this routine will be preserved since the routine that sends the in this routine will be preserved since the routine that sends the
@ -967,6 +969,18 @@ mwifiex_config_scan(struct mwifiex_private *priv,
tlv_pos += tlv_pos +=
sizeof(struct mwifiex_ie_types_scan_chan_gap); sizeof(struct mwifiex_ie_types_scan_chan_gap);
} }
if (!ether_addr_equal(user_scan_in->random_mac, zero_mac)) {
random_mac_tlv = (void *)tlv_pos;
random_mac_tlv->header.type =
cpu_to_le16(TLV_TYPE_RANDOM_MAC);
random_mac_tlv->header.len =
cpu_to_le16(sizeof(random_mac_tlv->mac));
ether_addr_copy(random_mac_tlv->mac,
user_scan_in->random_mac);
tlv_pos +=
sizeof(struct mwifiex_ie_types_random_mac);
}
} else { } else {
scan_cfg_out->bss_mode = (u8) adapter->scan_mode; scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
num_probes = adapter->scan_probes; num_probes = adapter->scan_probes;
@ -1922,6 +1936,7 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
} }
adapter->active_scan_triggered = true; adapter->active_scan_triggered = true;
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
user_scan_cfg->num_ssids = priv->scan_request->n_ssids; user_scan_cfg->num_ssids = priv->scan_request->n_ssids;
user_scan_cfg->ssid_list = priv->scan_request->ssids; user_scan_cfg->ssid_list = priv->scan_request->ssids;
@ -2761,6 +2776,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
if (!scan_cfg) if (!scan_cfg)
return -ENOMEM; return -ENOMEM;
ether_addr_copy(scan_cfg->random_mac, priv->random_mac);
scan_cfg->ssid_list = req_ssid; scan_cfg->ssid_list = req_ssid;
scan_cfg->num_ssids = 1; scan_cfg->num_ssids = 1;