Loading drivers/net/wireless/mac80211_hwsim.c +65 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; }; Loading Loading @@ -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, Loading Loading @@ -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__); } Loading Loading @@ -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[] = { Loading Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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); } Loading net/mac80211/mesh_hwmp.c +4 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. Loading net/wireless/reg.c +14 −7 Original line number Diff line number Diff line Loading @@ -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(®_mutex)); } Loading Loading @@ -1848,7 +1848,7 @@ static void restore_regulatory_settings(bool reset_user) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); reset_regdomains(true, cfg80211_world_regdom); reset_regdomains(true, &world_regdom); restore_alpha2(alpha2, reset_user); /* Loading Loading @@ -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 Loading Loading
drivers/net/wireless/mac80211_hwsim.c +65 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; }; Loading Loading @@ -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, Loading Loading @@ -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__); } Loading Loading @@ -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[] = { Loading Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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); } Loading
net/mac80211/mesh_hwmp.c +4 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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. Loading
net/wireless/reg.c +14 −7 Original line number Diff line number Diff line Loading @@ -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(®_mutex)); } Loading Loading @@ -1848,7 +1848,7 @@ static void restore_regulatory_settings(bool reset_user) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); reset_regdomains(true, cfg80211_world_regdom); reset_regdomains(true, &world_regdom); restore_alpha2(alpha2, reset_user); /* Loading Loading @@ -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 Loading