Skip to content

Commit

Permalink
Merge tag 'mac80211-for-davem-2016-01-26' of git://git.kernel.org/pub…
Browse files Browse the repository at this point in the history
…/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
Here's a first set of fixes for the 4.5-rc cycle:
 * make regulatory messages much less verbose by default
 * various remain-on-channel fixes
 * scheduled scanning fixes with hardware restart
 * a PS-Poll handling fix; was broken just recently
 * bugfix to avoid buffering non-bufferable MMPDUs
 * world regulatory domain data fix
 * a fix for scanning causing other work to get stuck
 * hwsim: revert an older problematic patch that caused some
   userspace tools to have issues - not that big a deal as
   it's a debug only driver though
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Jan 29, 2016
2 parents c731f0e + 6736fde commit bd7c5e3
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 64 deletions.
5 changes: 3 additions & 2 deletions drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,8 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
goto nla_put_failure;
}

if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, hdr->addr2))
if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
ETH_ALEN, data->addresses[1].addr))
goto nla_put_failure;

/* We get the skb->data */
Expand Down Expand Up @@ -2736,7 +2737,7 @@ static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)

spin_lock_bh(&hwsim_radio_lock);
list_for_each_entry(data, &hwsim_radios, list) {
if (mac80211_hwsim_addr_match(data, addr)) {
if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) {
_found = true;
break;
}
Expand Down
1 change: 0 additions & 1 deletion net/mac80211/ibss.c
Original file line number Diff line number Diff line change
Expand Up @@ -1733,7 +1733,6 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
continue;
sdata->u.ibss.last_scan_completed = jiffies;
ieee80211_queue_work(&local->hw, &sdata->work);
}
mutex_unlock(&local->iflist_mtx);
}
Expand Down
6 changes: 6 additions & 0 deletions net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ static void ieee80211_restart_work(struct work_struct *work)

/* wait for scan work complete */
flush_workqueue(local->workqueue);
flush_work(&local->sched_scan_stopped_work);

WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
"%s called with hardware scan in progress\n", __func__);
Expand All @@ -256,6 +257,11 @@ static void ieee80211_restart_work(struct work_struct *work)
list_for_each_entry(sdata, &local->interfaces, list)
flush_delayed_work(&sdata->dec_tailroom_needed_wk);
ieee80211_scan_cancel(local);

/* make sure any new ROC will consider local->in_reconfig */
flush_delayed_work(&local->roc_work);
flush_work(&local->hw_roc_done);

ieee80211_reconfig(local);
rtnl_unlock();
}
Expand Down
11 changes: 0 additions & 11 deletions net/mac80211/mesh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1370,17 +1370,6 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
sdata_unlock(sdata);
}

void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;

rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list)
if (ieee80211_vif_is_mesh(&sdata->vif) &&
ieee80211_sdata_running(sdata))
ieee80211_queue_work(&local->hw, &sdata->work);
rcu_read_unlock();
}

void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
{
Expand Down
4 changes: 0 additions & 4 deletions net/mac80211/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
}

void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);

void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
void ieee80211s_stop(void);
#else
static inline void
ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
{ return false; }
static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
Expand Down
2 changes: 0 additions & 2 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -4005,8 +4005,6 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
ieee80211_queue_work(&sdata->local->hw,
&sdata->u.mgd.monitor_work);
/* and do all the other regular work too */
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
}
}

Expand Down
16 changes: 9 additions & 7 deletions net/mac80211/offchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,11 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local,
static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
unsigned long start_time)
{
struct ieee80211_local *local = roc->sdata->local;

if (WARN_ON(roc->notified))
return;

roc->start_time = start_time;
roc->started = true;
roc->hw_begun = true;

if (roc->mgmt_tx_cookie) {
if (!WARN_ON(!roc->frame)) {
Expand All @@ -274,9 +271,6 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
}

roc->notified = true;

if (!local->ops->remain_on_channel)
ieee80211_recalc_sw_work(local, start_time);
}

static void ieee80211_hw_roc_start(struct work_struct *work)
Expand All @@ -291,6 +285,7 @@ static void ieee80211_hw_roc_start(struct work_struct *work)
if (!roc->started)
break;

roc->hw_begun = true;
ieee80211_handle_roc_started(roc, local->hw_roc_start_time);
}

Expand Down Expand Up @@ -413,6 +408,10 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
return;
}

/* defer roc if driver is not started (i.e. during reconfig) */
if (local->in_reconfig)
return;

roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
list);

Expand Down Expand Up @@ -534,8 +533,10 @@ ieee80211_coalesce_hw_started_roc(struct ieee80211_local *local,
* begin, otherwise they'll both be marked properly by the work
* struct that runs once the driver notifies us of the beginning
*/
if (cur_roc->hw_begun)
if (cur_roc->hw_begun) {
new_roc->hw_begun = true;
ieee80211_handle_roc_started(new_roc, now);
}

return true;
}
Expand Down Expand Up @@ -658,6 +659,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
queued = true;
roc->on_channel = tmp->on_channel;
ieee80211_handle_roc_started(roc, now);
ieee80211_recalc_sw_work(local, now);
break;
}

Expand Down
20 changes: 19 additions & 1 deletion net/mac80211/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
bool was_scanning = local->scanning;
struct cfg80211_scan_request *scan_req;
struct ieee80211_sub_if_data *scan_sdata;
struct ieee80211_sub_if_data *sdata;

lockdep_assert_held(&local->mtx);

Expand Down Expand Up @@ -373,7 +374,16 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)

ieee80211_mlme_notify_scan_completed(local);
ieee80211_ibss_notify_scan_completed(local);
ieee80211_mesh_notify_scan_completed(local);

/* Requeue all the work that might have been ignored while
* the scan was in progress; if there was none this will
* just be a no-op for the particular interface.
*/
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
if (ieee80211_sdata_running(sdata))
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
}

if (was_scanning)
ieee80211_start_next_roc(local);
}
Expand Down Expand Up @@ -1213,6 +1223,14 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)

trace_api_sched_scan_stopped(local);

/*
* this shouldn't really happen, so for simplicity
* simply ignore it, and let mac80211 reconfigure
* the sched scan later on.
*/
if (local->in_reconfig)
return;

schedule_work(&local->sched_scan_stopped_work);
}
EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
2 changes: 1 addition & 1 deletion net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -1453,7 +1453,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,

more_data = ieee80211_sta_ps_more_data(sta, ignored_acs, reason, driver_release_tids);

if (reason == IEEE80211_FRAME_RELEASE_PSPOLL)
if (driver_release_tids && reason == IEEE80211_FRAME_RELEASE_PSPOLL)
driver_release_tids =
BIT(find_highest_prio_tid(driver_release_tids));

Expand Down
5 changes: 5 additions & 0 deletions net/mac80211/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
struct ieee80211_hdr *hdr = (void *)skb->data;
int ac;

if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
ieee80211_free_txskb(&local->hw, skb);
return;
}

/*
* This skb 'survived' a round-trip through the driver, and
* hopefully the driver didn't mangle it too badly. However,
Expand Down
16 changes: 13 additions & 3 deletions net/mac80211/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -2043,16 +2043,26 @@ int ieee80211_reconfig(struct ieee80211_local *local)
*/
if (sched_scan_req->n_scan_plans > 1 ||
__ieee80211_request_sched_scan_start(sched_scan_sdata,
sched_scan_req))
sched_scan_req)) {
RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
RCU_INIT_POINTER(local->sched_scan_req, NULL);
sched_scan_stopped = true;
}
mutex_unlock(&local->mtx);

if (sched_scan_stopped)
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy);

wake_up:
local->in_reconfig = false;
barrier();
if (local->in_reconfig) {
local->in_reconfig = false;
barrier();

/* Restart deferred ROCs */
mutex_lock(&local->mtx);
ieee80211_start_next_roc(local);
mutex_unlock(&local->mtx);
}

if (local->monitors == local->open_count && local->monitors > 0)
ieee80211_add_virtual_monitor(local);
Expand Down
16 changes: 4 additions & 12 deletions net/rfkill/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1095,17 +1095,6 @@ static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
return res;
}

static bool rfkill_readable(struct rfkill_data *data)
{
bool r;

mutex_lock(&data->mtx);
r = !list_empty(&data->events);
mutex_unlock(&data->mtx);

return r;
}

static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
{
Expand All @@ -1122,8 +1111,11 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
goto out;
}
mutex_unlock(&data->mtx);
/* since we re-check and it just compares pointers,
* using !list_empty() without locking isn't a problem
*/
ret = wait_event_interruptible(data->read_wait,
rfkill_readable(data));
!list_empty(&data->events));
mutex_lock(&data->mtx);

if (ret)
Expand Down
Loading

0 comments on commit bd7c5e3

Please sign in to comment.