Skip to content

Commit

Permalink
mac80211: allow drivers to support NL80211_SCAN_FLAG_RANDOM_ADDR
Browse files Browse the repository at this point in the history
Allow drivers to support NL80211_SCAN_FLAG_RANDOM_ADDR with software
based scanning and generate a random MAC address for them for every
scan request with the flag.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Johannes Berg committed Nov 19, 2014
1 parent 6ea0a69 commit a344d67
Show file tree
Hide file tree
Showing 24 changed files with 166 additions and 72 deletions.
6 changes: 4 additions & 2 deletions drivers/net/wireless/ath/ath5k/mac80211-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,


static void
ath5k_sw_scan_start(struct ieee80211_hw *hw)
ath5k_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct ath5k_hw *ah = hw->priv;
if (!ah->assoc)
Expand All @@ -556,7 +558,7 @@ ath5k_sw_scan_start(struct ieee80211_hw *hw)


static void
ath5k_sw_scan_complete(struct ieee80211_hw *hw)
ath5k_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct ath5k_hw *ah = hw->priv;
ath5k_hw_set_ledstate(ah, ah->assoc ?
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
struct ieee80211_tx_info *info;
int band = sc->offchannel.chan.chandef.chan->band;

skb = ieee80211_probereq_get(sc->hw, vif,
skb = ieee80211_probereq_get(sc->hw, vif->addr,
ssid->ssid, ssid->ssid_len, req->ie_len);
if (!skb)
return;
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
return ret;
}

static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct ath9k_htc_priv *priv = hw->priv;
struct ath_common *common = ath9k_hw_common(priv->ah);
Expand All @@ -1705,7 +1707,8 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
}

static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath9k_htc_priv *priv = hw->priv;
struct ath_common *common = ath9k_hw_common(priv->ah);
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2180,14 +2180,17 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
return 0;
}

static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
static void ath9k_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
set_bit(ATH_OP_SCANNING, &common->op_flags);
}

static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
static void ath9k_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/ath/wcn36xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,15 +494,18 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}

static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw)
static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct wcn36xx *wcn = hw->priv;

wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
wcn36xx_smd_start_scan(wcn);
}

static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw)
static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct wcn36xx *wcn = hw->priv;

Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/b43/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5110,7 +5110,9 @@ static void b43_op_sta_notify(struct ieee80211_hw *hw,
B43_WARN_ON(!vif || wl->vif != vif);
}

static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
Expand All @@ -5124,7 +5126,8 @@ static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
mutex_unlock(&wl->mutex);
}

static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,9 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw,
return;
}

static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct brcms_info *wl = hw->priv;
spin_lock_bh(&wl->lock);
Expand All @@ -773,7 +775,8 @@ static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
return;
}

static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct brcms_info *wl = hw->priv;
spin_lock_bh(&wl->lock);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/cw1200/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
return -EINVAL;

frame.skb = ieee80211_probereq_get(hw, priv->vif, NULL, 0,
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
req->ie_len);
if (!frame.skb)
return -ENOMEM;
Expand Down
9 changes: 6 additions & 3 deletions drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -1802,7 +1802,7 @@ static void hw_scan_work(struct work_struct *work)
struct sk_buff *probe;

probe = ieee80211_probereq_get(hwsim->hw,
hwsim->hw_scan_vif,
hwsim->hw_scan_vif->addr,
req->ssids[i].ssid,
req->ssids[i].ssid_len,
req->ie_len);
Expand Down Expand Up @@ -1866,7 +1866,9 @@ static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw,
mutex_unlock(&hwsim->mutex);
}

static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw)
static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct mac80211_hwsim_data *hwsim = hw->priv;

Expand All @@ -1884,7 +1886,8 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw)
mutex_unlock(&hwsim->mutex);
}

static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw)
static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mac80211_hwsim_data *hwsim = hw->priv;

Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/mwl8k.c
Original file line number Diff line number Diff line change
Expand Up @@ -5548,7 +5548,9 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return rc;
}

static void mwl8k_sw_scan_start(struct ieee80211_hw *hw)
static void mwl8k_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct mwl8k_priv *priv = hw->priv;
u8 tmp;
Expand All @@ -5565,7 +5567,8 @@ static void mwl8k_sw_scan_start(struct ieee80211_hw *hw)
priv->sw_scan_start = true;
}

static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw)
static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mwl8k_priv *priv = hw->priv;
u8 tmp;
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/rt2x00/rt2x00.h
Original file line number Diff line number Diff line change
Expand Up @@ -1437,8 +1437,11 @@ int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw);
void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw);
void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr);
void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int rt2x00mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/rt2x00/rt2x00mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,15 +568,18 @@ int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove);

void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw)
void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
rt2x00link_stop_tuner(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start);

void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw)
void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/rtlwifi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,9 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
return 0;
}

static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
static void rtl_op_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
Expand Down Expand Up @@ -1396,7 +1398,8 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0);
}

static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ti/wl1251/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
goto out_sleep;
}

skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
skb = ieee80211_probereq_get(wl->hw, wl->vif->addr, ssid, ssid_len,
req->ie_len);
if (!skb) {
ret = -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ti/wlcore/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,

wl1271_debug(DEBUG_SCAN, "build probe request band %d", band);

skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
skb = ieee80211_probereq_get(wl->hw, vif->addr, ssid, ssid_len,
ie0_len + ie1_len);
if (!skb) {
ret = -ENOMEM;
Expand Down
7 changes: 5 additions & 2 deletions drivers/staging/vt6656/main_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,9 @@ static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return 0;
}

static void vnt_sw_scan_start(struct ieee80211_hw *hw)
static void vnt_sw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *addr)
{
struct vnt_private *priv = hw->priv;

Expand All @@ -865,7 +867,8 @@ static void vnt_sw_scan_start(struct ieee80211_hw *hw)
vnt_update_pre_ed_threshold(priv, true);
}

static void vnt_sw_scan_complete(struct ieee80211_hw *hw)
static void vnt_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct vnt_private *priv = hw->priv;

Expand Down
15 changes: 10 additions & 5 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2622,7 +2622,9 @@ enum ieee80211_reconfig_type {
*
* @sw_scan_start: Notifier function that is called just before a software scan
* is started. Can be NULL, if the driver doesn't need this notification.
* The callback can sleep.
* The mac_addr parameter allows supporting NL80211_SCAN_FLAG_RANDOM_ADDR,
* the driver may set the NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR flag if it
* can use this parameter. The callback can sleep.
*
* @sw_scan_complete: Notifier function that is called just after a
* software scan finished. Can be NULL, if the driver doesn't need
Expand Down Expand Up @@ -3016,8 +3018,11 @@ struct ieee80211_ops {
struct ieee80211_scan_ies *ies);
int (*sched_scan_stop)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void (*sw_scan_start)(struct ieee80211_hw *hw);
void (*sw_scan_complete)(struct ieee80211_hw *hw);
void (*sw_scan_start)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *mac_addr);
void (*sw_scan_complete)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int (*get_stats)(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
Expand Down Expand Up @@ -3820,7 +3825,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
/**
* ieee80211_probereq_get - retrieve a Probe Request template
* @hw: pointer obtained from ieee80211_alloc_hw().
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @src_addr: source MAC address
* @ssid: SSID buffer
* @ssid_len: length of SSID
* @tailroom: tailroom to reserve at end of SKB for IEs
Expand All @@ -3831,7 +3836,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
* Return: The Probe Request template. %NULL on error.
*/
struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const u8 *src_addr,
const u8 *ssid, size_t ssid_len,
size_t tailroom);

Expand Down
15 changes: 9 additions & 6 deletions net/mac80211/driver-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,23 +380,26 @@ static inline int drv_sched_scan_stop(struct ieee80211_local *local,
return ret;
}

static inline void drv_sw_scan_start(struct ieee80211_local *local)
static inline void drv_sw_scan_start(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
const u8 *mac_addr)
{
might_sleep();

trace_drv_sw_scan_start(local);
trace_drv_sw_scan_start(local, sdata, mac_addr);
if (local->ops->sw_scan_start)
local->ops->sw_scan_start(&local->hw);
local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr);
trace_drv_return_void(local);
}

static inline void drv_sw_scan_complete(struct ieee80211_local *local)
static inline void drv_sw_scan_complete(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
{
might_sleep();

trace_drv_sw_scan_complete(local);
trace_drv_sw_scan_complete(local, sdata);
if (local->ops->sw_scan_complete)
local->ops->sw_scan_complete(&local->hw);
local->ops->sw_scan_complete(&local->hw, &sdata->vif);
trace_drv_return_void(local);
}

Expand Down
7 changes: 5 additions & 2 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,7 @@ struct ieee80211_local {
struct work_struct sched_scan_stopped_work;
struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
struct cfg80211_sched_scan_request __rcu *sched_scan_req;
u8 scan_addr[ETH_ALEN];

unsigned long leave_oper_channel_time;
enum mac80211_scan_state next_scan_state;
Expand Down Expand Up @@ -1901,12 +1902,14 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
u8 bands_used, u32 *rate_masks,
struct cfg80211_chan_def *chandef);
struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
u8 *dst, u32 ratemask,
const u8 *src, const u8 *dst,
u32 ratemask,
struct ieee80211_channel *chan,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len,
bool directed);
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata,
const u8 *src, const u8 *dst,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len,
u32 ratemask, bool directed, u32 tx_flags,
Expand Down
Loading

0 comments on commit a344d67

Please sign in to comment.