mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next
This commit is contained in:
commit
79afb22d09
|
@ -337,11 +337,11 @@ struct mac80211_hwsim_data {
|
||||||
int scan_chan_idx;
|
int scan_chan_idx;
|
||||||
|
|
||||||
struct ieee80211_channel *channel;
|
struct ieee80211_channel *channel;
|
||||||
unsigned long beacon_int; /* in jiffies unit */
|
u64 beacon_int /* beacon interval in us */;
|
||||||
unsigned int rx_filter;
|
unsigned int rx_filter;
|
||||||
bool started, idle, scanning;
|
bool started, idle, scanning;
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
struct timer_list beacon_timer;
|
struct tasklet_hrtimer beacon_timer;
|
||||||
enum ps_mode {
|
enum ps_mode {
|
||||||
PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
|
PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
|
||||||
} ps;
|
} ps;
|
||||||
|
@ -361,7 +361,8 @@ struct mac80211_hwsim_data {
|
||||||
int power_level;
|
int power_level;
|
||||||
|
|
||||||
/* difference between this hw's clock and the real clock, in usecs */
|
/* difference between this hw's clock and the real clock, in usecs */
|
||||||
u64 tsf_offset;
|
s64 tsf_offset;
|
||||||
|
s64 bcn_delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -427,9 +428,13 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif, u64 tsf)
|
struct ieee80211_vif *vif, u64 tsf)
|
||||||
{
|
{
|
||||||
struct mac80211_hwsim_data *data = hw->priv;
|
struct mac80211_hwsim_data *data = hw->priv;
|
||||||
struct timeval tv = ktime_to_timeval(ktime_get_real());
|
u64 now = mac80211_hwsim_get_tsf(hw, vif);
|
||||||
u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
|
u32 bcn_int = data->beacon_int;
|
||||||
data->tsf_offset = tsf - now;
|
s64 delta = tsf - now;
|
||||||
|
|
||||||
|
data->tsf_offset += delta;
|
||||||
|
/* adjust after beaconing with new timestamp at old TBTT */
|
||||||
|
data->bcn_delta = do_div(delta, bcn_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
|
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
|
||||||
|
@ -916,7 +921,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
struct mac80211_hwsim_data *data = hw->priv;
|
struct mac80211_hwsim_data *data = hw->priv;
|
||||||
data->started = false;
|
data->started = false;
|
||||||
del_timer(&data->beacon_timer);
|
tasklet_hrtimer_cancel(&data->beacon_timer);
|
||||||
wiphy_debug(hw->wiphy, "%s\n", __func__);
|
wiphy_debug(hw->wiphy, "%s\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,21 +1005,34 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||||
rcu_dereference(vif->chanctx_conf)->def.chan);
|
rcu_dereference(vif->chanctx_conf)->def.chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum hrtimer_restart
|
||||||
static void mac80211_hwsim_beacon(unsigned long arg)
|
mac80211_hwsim_beacon(struct hrtimer *timer)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
|
struct mac80211_hwsim_data *data =
|
||||||
struct mac80211_hwsim_data *data = hw->priv;
|
container_of(timer, struct mac80211_hwsim_data,
|
||||||
|
beacon_timer.timer);
|
||||||
|
struct ieee80211_hw *hw = data->hw;
|
||||||
|
u64 bcn_int = data->beacon_int;
|
||||||
|
ktime_t next_bcn;
|
||||||
|
|
||||||
if (!data->started)
|
if (!data->started)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
ieee80211_iterate_active_interfaces_atomic(
|
ieee80211_iterate_active_interfaces_atomic(
|
||||||
hw, IEEE80211_IFACE_ITER_NORMAL,
|
hw, IEEE80211_IFACE_ITER_NORMAL,
|
||||||
mac80211_hwsim_beacon_tx, hw);
|
mac80211_hwsim_beacon_tx, hw);
|
||||||
|
|
||||||
data->beacon_timer.expires = jiffies + data->beacon_int;
|
/* beacon at new TBTT + beacon interval */
|
||||||
add_timer(&data->beacon_timer);
|
if (data->bcn_delta) {
|
||||||
|
bcn_int -= data->bcn_delta;
|
||||||
|
data->bcn_delta = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_bcn = ktime_add(hrtimer_get_expires(timer),
|
||||||
|
ns_to_ktime(bcn_int * 1000));
|
||||||
|
tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS);
|
||||||
|
out:
|
||||||
|
return HRTIMER_NORESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *hwsim_chantypes[] = {
|
static const char *hwsim_chantypes[] = {
|
||||||
|
@ -1052,9 +1070,16 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
|
|
||||||
data->power_level = conf->power_level;
|
data->power_level = conf->power_level;
|
||||||
if (!data->started || !data->beacon_int)
|
if (!data->started || !data->beacon_int)
|
||||||
del_timer(&data->beacon_timer);
|
tasklet_hrtimer_cancel(&data->beacon_timer);
|
||||||
else
|
else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {
|
||||||
mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
|
u64 tsf = mac80211_hwsim_get_tsf(hw, NULL);
|
||||||
|
u32 bcn_int = data->beacon_int;
|
||||||
|
u64 until_tbtt = bcn_int - do_div(tsf, bcn_int);
|
||||||
|
|
||||||
|
tasklet_hrtimer_start(&data->beacon_timer,
|
||||||
|
ns_to_ktime(until_tbtt * 1000),
|
||||||
|
HRTIMER_MODE_REL);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1104,12 +1129,26 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
if (changed & BSS_CHANGED_BEACON_INT) {
|
if (changed & BSS_CHANGED_BEACON_INT) {
|
||||||
wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int);
|
wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int);
|
||||||
data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
|
data->beacon_int = info->beacon_int * 1024;
|
||||||
if (WARN_ON(!data->beacon_int))
|
}
|
||||||
data->beacon_int = 1;
|
|
||||||
if (data->started)
|
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||||
mod_timer(&data->beacon_timer,
|
wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon);
|
||||||
jiffies + data->beacon_int);
|
if (data->started &&
|
||||||
|
!hrtimer_is_queued(&data->beacon_timer.timer) &&
|
||||||
|
info->enable_beacon) {
|
||||||
|
u64 tsf, until_tbtt;
|
||||||
|
u32 bcn_int;
|
||||||
|
if (WARN_ON(!data->beacon_int))
|
||||||
|
data->beacon_int = 1000 * 1024;
|
||||||
|
tsf = mac80211_hwsim_get_tsf(hw, vif);
|
||||||
|
bcn_int = data->beacon_int;
|
||||||
|
until_tbtt = bcn_int - do_div(tsf, bcn_int);
|
||||||
|
tasklet_hrtimer_start(&data->beacon_timer,
|
||||||
|
ns_to_ktime(until_tbtt * 1000),
|
||||||
|
HRTIMER_MODE_REL);
|
||||||
|
} else if (!info->enable_beacon)
|
||||||
|
tasklet_hrtimer_cancel(&data->beacon_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
|
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
|
||||||
|
@ -2392,8 +2431,9 @@ static int __init init_mac80211_hwsim(void)
|
||||||
data->debugfs, data,
|
data->debugfs, data,
|
||||||
&hwsim_fops_group);
|
&hwsim_fops_group);
|
||||||
|
|
||||||
setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
|
tasklet_hrtimer_init(&data->beacon_timer,
|
||||||
(unsigned long) hw);
|
mac80211_hwsim_beacon,
|
||||||
|
CLOCK_REALTIME, HRTIMER_MODE_ABS);
|
||||||
|
|
||||||
list_add_tail(&data->list, &hwsim_radios);
|
list_add_tail(&data->list, &hwsim_radios);
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,12 +219,14 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mesh_send_path error - Sends a PERR mesh management frame
|
* mesh_path_error_tx - Sends a PERR mesh management frame
|
||||||
*
|
*
|
||||||
|
* @ttl: allowed remaining hops
|
||||||
* @target: broken destination
|
* @target: broken destination
|
||||||
* @target_sn: SN of the broken destination
|
* @target_sn: SN of the broken destination
|
||||||
* @target_rcode: reason code for this PERR
|
* @target_rcode: reason code for this PERR
|
||||||
* @ra: node this frame is addressed to
|
* @ra: node this frame is addressed to
|
||||||
|
* @sdata: local mesh subif
|
||||||
*
|
*
|
||||||
* Note: This function may be called with driver locks taken that the driver
|
* Note: This function may be called with driver locks taken that the driver
|
||||||
* also acquires in the TX path. To avoid a deadlock we don't transmit the
|
* also acquires in the TX path. To avoid a deadlock we don't transmit the
|
||||||
|
@ -350,6 +352,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||||
* @sdata: local mesh subif
|
* @sdata: local mesh subif
|
||||||
* @mgmt: mesh management frame
|
* @mgmt: mesh management frame
|
||||||
* @hwmp_ie: hwmp information element (PREP or PREQ)
|
* @hwmp_ie: hwmp information element (PREP or PREQ)
|
||||||
|
* @action: type of hwmp ie
|
||||||
*
|
*
|
||||||
* This function updates the path routing information to the originator and the
|
* This function updates the path routing information to the originator and the
|
||||||
* transmitter of a HWMP PREQ or PREP frame.
|
* transmitter of a HWMP PREQ or PREP frame.
|
||||||
|
|
|
@ -140,8 +140,8 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r)
|
||||||
|
|
||||||
static struct regulatory_request *get_last_request(void)
|
static struct regulatory_request *get_last_request(void)
|
||||||
{
|
{
|
||||||
return rcu_dereference_protected(last_request,
|
return rcu_dereference_check(last_request,
|
||||||
lockdep_is_held(®_mutex));
|
lockdep_is_held(®_mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used to queue up regulatory hints */
|
/* Used to queue up regulatory hints */
|
||||||
|
@ -1848,7 +1848,7 @@ static void restore_regulatory_settings(bool reset_user)
|
||||||
mutex_lock(&cfg80211_mutex);
|
mutex_lock(&cfg80211_mutex);
|
||||||
mutex_lock(®_mutex);
|
mutex_lock(®_mutex);
|
||||||
|
|
||||||
reset_regdomains(true, cfg80211_world_regdom);
|
reset_regdomains(true, &world_regdom);
|
||||||
restore_alpha2(alpha2, reset_user);
|
restore_alpha2(alpha2, reset_user);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2250,14 +2250,21 @@ int set_regdom(const struct ieee80211_regdomain *rd)
|
||||||
#ifdef CONFIG_HOTPLUG
|
#ifdef CONFIG_HOTPLUG
|
||||||
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct regulatory_request *lr = get_last_request();
|
struct regulatory_request *lr;
|
||||||
|
u8 alpha2[2];
|
||||||
|
bool add = false;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
lr = get_last_request();
|
||||||
if (lr && !lr->processed) {
|
if (lr && !lr->processed) {
|
||||||
if (add_uevent_var(env, "COUNTRY=%c%c",
|
memcpy(alpha2, lr->alpha2, 2);
|
||||||
lr->alpha2[0], lr->alpha2[1]))
|
add = true;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
return add_uevent_var(env, "COUNTRY=%c%c",
|
||||||
|
alpha2[0], alpha2[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue