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

Commit 79afb22d authored by John W. Linville's avatar John W. Linville
Browse files

Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next

parents e7f767a7 2d319867
Loading
Loading
Loading
Loading
+65 −25
Original line number Diff line number Diff line
@@ -337,11 +337,11 @@ struct mac80211_hwsim_data {
	int scan_chan_idx;

	struct ieee80211_channel *channel;
	unsigned long beacon_int; /* in jiffies unit */
	u64 beacon_int	/* beacon interval in us */;
	unsigned int rx_filter;
	bool started, idle, scanning;
	struct mutex mutex;
	struct timer_list beacon_timer;
	struct tasklet_hrtimer beacon_timer;
	enum ps_mode {
		PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
	} ps;
@@ -361,7 +361,8 @@ struct mac80211_hwsim_data {
	int power_level;

	/* 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 mac80211_hwsim_data *data = hw->priv;
	struct timeval tv = ktime_to_timeval(ktime_get_real());
	u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
	data->tsf_offset = tsf - now;
	u64 now = mac80211_hwsim_get_tsf(hw, vif);
	u32 bcn_int = data->beacon_int;
	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,
@@ -916,7 +921,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
{
	struct mac80211_hwsim_data *data = hw->priv;
	data->started = false;
	del_timer(&data->beacon_timer);
	tasklet_hrtimer_cancel(&data->beacon_timer);
	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);
}


static void mac80211_hwsim_beacon(unsigned long arg)
static enum hrtimer_restart
mac80211_hwsim_beacon(struct hrtimer *timer)
{
	struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
	struct mac80211_hwsim_data *data = hw->priv;
	struct mac80211_hwsim_data *data =
		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)
		return;
		goto out;

	ieee80211_iterate_active_interfaces_atomic(
		hw, IEEE80211_IFACE_ITER_NORMAL,
		mac80211_hwsim_beacon_tx, hw);

	data->beacon_timer.expires = jiffies + data->beacon_int;
	add_timer(&data->beacon_timer);
	/* beacon at new TBTT + beacon interval */
	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[] = {
@@ -1052,9 +1070,16 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)

	data->power_level = conf->power_level;
	if (!data->started || !data->beacon_int)
		del_timer(&data->beacon_timer);
	else
		mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
		tasklet_hrtimer_cancel(&data->beacon_timer);
	else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {
		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;
}
@@ -1104,12 +1129,26 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,

	if (changed & BSS_CHANGED_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 (changed & BSS_CHANGED_BEACON_ENABLED) {
		wiphy_debug(hw->wiphy, "  BCN EN: %d\n", info->enable_beacon);
		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 = 1;
		if (data->started)
			mod_timer(&data->beacon_timer,
				  jiffies + 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) {
@@ -2392,8 +2431,9 @@ static int __init init_mac80211_hwsim(void)
							data->debugfs, data,
							&hwsim_fops_group);

		setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
			    (unsigned long) hw);
		tasklet_hrtimer_init(&data->beacon_timer,
				     mac80211_hwsim_beacon,
				     CLOCK_REALTIME, HRTIMER_MODE_ABS);

		list_add_tail(&data->list, &hwsim_radios);
	}
+4 −1
Original line number Diff line number Diff line
@@ -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_sn: SN of the broken destination
 * @target_rcode: reason code for this PERR
 * @ra: node this frame is addressed to
 * @sdata: local mesh subif
 *
 * 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
@@ -350,6 +352,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
 * @sdata: local mesh subif
 * @mgmt: mesh management frame
 * @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
 * transmitter of a HWMP PREQ or PREP frame.
+14 −7
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r)

static struct regulatory_request *get_last_request(void)
{
	return rcu_dereference_protected(last_request,
	return rcu_dereference_check(last_request,
				     lockdep_is_held(&reg_mutex));
}

@@ -1848,7 +1848,7 @@ static void restore_regulatory_settings(bool reset_user)
	mutex_lock(&cfg80211_mutex);
	mutex_lock(&reg_mutex);

	reset_regdomains(true, cfg80211_world_regdom);
	reset_regdomains(true, &world_regdom);
	restore_alpha2(alpha2, reset_user);

	/*
@@ -2250,14 +2250,21 @@ int set_regdom(const struct ieee80211_regdomain *rd)
#ifdef CONFIG_HOTPLUG
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 (add_uevent_var(env, "COUNTRY=%c%c",
				   lr->alpha2[0], lr->alpha2[1]))
			return -ENOMEM;
		memcpy(alpha2, lr->alpha2, 2);
		add = true;
	}
	rcu_read_unlock();

	if (add)
		return add_uevent_var(env, "COUNTRY=%c%c",
				      alpha2[0], alpha2[1]);
	return 0;
}
#else