diff options
author | David S. Miller <davem@davemloft.net> | 2017-11-21 14:30:57 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-21 14:30:57 +0300 |
commit | a13e8d418f3cb9d0b4efa6e744b8b23c0e3cdfe8 (patch) | |
tree | a294d1434ebca50330b797803b22749f91866ab7 | |
parent | b48b1f7ac716e3f0474f8b94bc471c6e47b2f57a (diff) | |
parent | 33ddd81e2bd5d9970b9f01ab383ba45035fa41ee (diff) | |
download | linux-a13e8d418f3cb9d0b4efa6e744b8b23c0e3cdfe8.tar.xz |
Merge tag 'mac80211-for-davem-2017-11-20' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says:
====================
A few things:
* straggler timer conversions from Kees
* memory leak fix in hwsim
* fix some fallout from regdb changes if wireless is built-in
* also free aggregation sessions in startup state when station
goes away, to avoid crashing the timer
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 5 | ||||
-rw-r--r-- | net/mac80211/agg-rx.c | 41 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 49 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 7 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/led.c | 11 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 27 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 4 | ||||
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 32 | ||||
-rw-r--r-- | net/mac80211/ocb.c | 10 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 15 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 12 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 26 | ||||
-rw-r--r-- | net/wireless/reg.c | 42 |
17 files changed, 155 insertions, 137 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7c3600643c7f..10b075a46b26 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -3108,6 +3108,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) { struct hwsim_new_radio_params param = { 0 }; const char *hwname = NULL; + int ret; param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; @@ -3147,7 +3148,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) param.regd = hwsim_world_regdom_custom[idx]; } - return mac80211_hwsim_new_radio(info, ¶m); + ret = mac80211_hwsim_new_radio(info, ¶m); + kfree(hwname); + return ret; } static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 88cc1ae935ea..d444752dbf40 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -151,21 +151,17 @@ EXPORT_SYMBOL(ieee80211_stop_rx_ba_session); * After accepting the AddBA Request we activated a timer, * resetting it after each frame that arrives from the originator. */ -static void sta_rx_agg_session_timer_expired(unsigned long data) +static void sta_rx_agg_session_timer_expired(struct timer_list *t) { - /* not an elegant detour, but there is no choice as the timer passes - * only one argument, and various sta_info are needed here, so init - * flow in sta_info_create gives the TID as data, while the timer_to_id - * array gives the sta through container_of */ - u8 *ptid = (u8 *)data; - u8 *timer_to_id = ptid - *ptid; - struct sta_info *sta = container_of(timer_to_id, struct sta_info, - timer_to_tid[0]); + struct tid_ampdu_rx *tid_rx_timer = + from_timer(tid_rx_timer, t, session_timer); + struct sta_info *sta = tid_rx_timer->sta; + u8 tid = tid_rx_timer->tid; struct tid_ampdu_rx *tid_rx; unsigned long timeout; rcu_read_lock(); - tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); + tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); if (!tid_rx) { rcu_read_unlock(); return; @@ -180,21 +176,18 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) rcu_read_unlock(); ht_dbg(sta->sdata, "RX session timer expired on %pM tid %d\n", - sta->sta.addr, (u16)*ptid); + sta->sta.addr, tid); - set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); + set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired); ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); } -static void sta_rx_agg_reorder_timer_expired(unsigned long data) +static void sta_rx_agg_reorder_timer_expired(struct timer_list *t) { - u8 *ptid = (u8 *)data; - u8 *timer_to_id = ptid - *ptid; - struct sta_info *sta = container_of(timer_to_id, struct sta_info, - timer_to_tid[0]); + struct tid_ampdu_rx *tid_rx = from_timer(tid_rx, t, reorder_timer); rcu_read_lock(); - ieee80211_release_reorder_timeout(sta, *ptid); + ieee80211_release_reorder_timeout(tid_rx->sta, tid_rx->tid); rcu_read_unlock(); } @@ -356,14 +349,12 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, spin_lock_init(&tid_agg_rx->reorder_lock); /* rx timer */ - setup_deferrable_timer(&tid_agg_rx->session_timer, - sta_rx_agg_session_timer_expired, - (unsigned long)&sta->timer_to_tid[tid]); + timer_setup(&tid_agg_rx->session_timer, + sta_rx_agg_session_timer_expired, TIMER_DEFERRABLE); /* rx reorder timer */ - setup_timer(&tid_agg_rx->reorder_timer, - sta_rx_agg_reorder_timer_expired, - (unsigned long)&sta->timer_to_tid[tid]); + timer_setup(&tid_agg_rx->reorder_timer, + sta_rx_agg_reorder_timer_expired, 0); /* prepare reordering buffer */ tid_agg_rx->reorder_buf = @@ -399,6 +390,8 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, tid_agg_rx->auto_seq = auto_seq; tid_agg_rx->started = false; tid_agg_rx->reorder_buf_filtered = 0; + tid_agg_rx->tid = tid; + tid_agg_rx->sta = sta; status = WLAN_STATUS_SUCCESS; /* activate it for RX */ diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index bef516ec47f9..5f8ab5be369f 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, spin_lock_bh(&sta->lock); + /* free struct pending for start, if present */ + tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; + kfree(tid_tx); + sta->ampdu_mlme.tid_start_tx[tid] = NULL; + tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (!tid_tx) { spin_unlock_bh(&sta->lock); @@ -422,15 +427,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, * add Block Ack response will arrive from the recipient. * If this timer expires sta_addba_resp_timer_expired will be executed. */ -static void sta_addba_resp_timer_expired(unsigned long data) +static void sta_addba_resp_timer_expired(struct timer_list *t) { - /* not an elegant detour, but there is no choice as the timer passes - * only one argument, and both sta_info and TID are needed, so init - * flow in sta_info_create gives the TID as data, while the timer_to_id - * array gives the sta through container_of */ - u16 tid = *(u8 *)data; - struct sta_info *sta = container_of((void *)data, - struct sta_info, timer_to_tid[tid]); + struct tid_ampdu_tx *tid_tx_timer = + from_timer(tid_tx_timer, t, addba_resp_timer); + struct sta_info *sta = tid_tx_timer->sta; + u8 tid = tid_tx_timer->tid; struct tid_ampdu_tx *tid_tx; /* check if the TID waits for addBA response */ @@ -525,21 +527,17 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) * After accepting the AddBA Response we activated a timer, * resetting it after each frame that we send. */ -static void sta_tx_agg_session_timer_expired(unsigned long data) +static void sta_tx_agg_session_timer_expired(struct timer_list *t) { - /* not an elegant detour, but there is no choice as the timer passes - * only one argument, and various sta_info are needed here, so init - * flow in sta_info_create gives the TID as data, while the timer_to_id - * array gives the sta through container_of */ - u8 *ptid = (u8 *)data; - u8 *timer_to_id = ptid - *ptid; - struct sta_info *sta = container_of(timer_to_id, struct sta_info, - timer_to_tid[0]); + struct tid_ampdu_tx *tid_tx_timer = + from_timer(tid_tx_timer, t, session_timer); + struct sta_info *sta = tid_tx_timer->sta; + u8 tid = tid_tx_timer->tid; struct tid_ampdu_tx *tid_tx; unsigned long timeout; rcu_read_lock(); - tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[*ptid]); + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); if (!tid_tx || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { rcu_read_unlock(); return; @@ -555,9 +553,9 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) rcu_read_unlock(); ht_dbg(sta->sdata, "tx session timer expired on %pM tid %d\n", - sta->sta.addr, (u16)*ptid); + sta->sta.addr, tid); - ieee80211_stop_tx_ba_session(&sta->sta, *ptid); + ieee80211_stop_tx_ba_session(&sta->sta, tid); } int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, @@ -670,16 +668,15 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); tid_tx->timeout = timeout; + tid_tx->sta = sta; + tid_tx->tid = tid; /* response timer */ - setup_timer(&tid_tx->addba_resp_timer, - sta_addba_resp_timer_expired, - (unsigned long)&sta->timer_to_tid[tid]); + timer_setup(&tid_tx->addba_resp_timer, sta_addba_resp_timer_expired, 0); /* tx timer */ - setup_deferrable_timer(&tid_tx->session_timer, - sta_tx_agg_session_timer_expired, - (unsigned long)&sta->timer_to_tid[tid]); + timer_setup(&tid_tx->session_timer, + sta_tx_agg_session_timer_expired, TIMER_DEFERRABLE); /* assign a dialog token */ sta->ampdu_mlme.dialog_token_allocator++; diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e9c6aa3ed05b..db07e0de9a03 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1711,10 +1711,10 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) sdata_unlock(sdata); } -static void ieee80211_ibss_timer(unsigned long data) +static void ieee80211_ibss_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.ibss.timer); ieee80211_queue_work(&sdata->local->hw, &sdata->work); } @@ -1723,8 +1723,7 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - setup_timer(&ifibss->timer, ieee80211_ibss_timer, - (unsigned long) sdata); + timer_setup(&ifibss->timer, ieee80211_ibss_timer, 0); INIT_LIST_HEAD(&ifibss->incomplete_stations); spin_lock_init(&ifibss->incomplete_lock); INIT_WORK(&ifibss->csa_connection_drop_work, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 68f874e73561..885d00b41911 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1057,6 +1057,7 @@ struct tpt_led_trigger { const struct ieee80211_tpt_blink *blink_table; unsigned int blink_table_len; struct timer_list timer; + struct ieee80211_local *local; unsigned long prev_traffic; unsigned long tx_bytes, rx_bytes; unsigned int active, want; @@ -1932,7 +1933,7 @@ static inline int ieee80211_ac_from_tid(int tid) void ieee80211_dynamic_ps_enable_work(struct work_struct *work); void ieee80211_dynamic_ps_disable_work(struct work_struct *work); -void ieee80211_dynamic_ps_timer(unsigned long data); +void ieee80211_dynamic_ps_timer(struct timer_list *t); void ieee80211_send_nullfunc(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, bool powersave); diff --git a/net/mac80211/led.c b/net/mac80211/led.c index 0505845b7ab8..ba0b507ea691 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c @@ -248,10 +248,10 @@ static unsigned long tpt_trig_traffic(struct ieee80211_local *local, return DIV_ROUND_UP(delta, 1024 / 8); } -static void tpt_trig_timer(unsigned long data) +static void tpt_trig_timer(struct timer_list *t) { - struct ieee80211_local *local = (void *)data; - struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; + struct tpt_led_trigger *tpt_trig = from_timer(tpt_trig, t, timer); + struct ieee80211_local *local = tpt_trig->local; struct led_classdev *led_cdev; unsigned long on, off, tpt; int i; @@ -306,8 +306,9 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, tpt_trig->blink_table = blink_table; tpt_trig->blink_table_len = blink_table_len; tpt_trig->want = flags; + tpt_trig->local = local; - setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local); + timer_setup(&tpt_trig->timer, tpt_trig_timer, 0); local->tpt_led_trigger = tpt_trig; @@ -326,7 +327,7 @@ static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) tpt_trig_traffic(local, tpt_trig); tpt_trig->running = true; - tpt_trig_timer((unsigned long)local); + tpt_trig_timer(&tpt_trig->timer); mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8aa1f5b6a051..e054a2fd8d38 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -633,8 +633,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, ieee80211_dynamic_ps_enable_work); INIT_WORK(&local->dynamic_ps_disable_work, ieee80211_dynamic_ps_disable_work); - setup_timer(&local->dynamic_ps_timer, - ieee80211_dynamic_ps_timer, (unsigned long) local); + timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0); INIT_WORK(&local->sched_scan_stopped_work, ieee80211_sched_scan_stopped_work); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 7a76c4a6df30..5e27364e10ac 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -37,9 +37,10 @@ void ieee80211s_stop(void) kmem_cache_destroy(rm_cache); } -static void ieee80211_mesh_housekeeping_timer(unsigned long data) +static void ieee80211_mesh_housekeeping_timer(struct timer_list *t) { - struct ieee80211_sub_if_data *sdata = (void *) data; + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.mesh.housekeeping_timer); struct ieee80211_local *local = sdata->local; struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; @@ -528,18 +529,18 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata, return 0; } -static void ieee80211_mesh_path_timer(unsigned long data) +static void ieee80211_mesh_path_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.mesh.mesh_path_timer); ieee80211_queue_work(&sdata->local->hw, &sdata->work); } -static void ieee80211_mesh_path_root_timer(unsigned long data) +static void ieee80211_mesh_path_root_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.mesh.mesh_path_root_timer); struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); @@ -1442,9 +1443,8 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; static u8 zero_addr[ETH_ALEN] = {}; - setup_timer(&ifmsh->housekeeping_timer, - ieee80211_mesh_housekeeping_timer, - (unsigned long) sdata); + timer_setup(&ifmsh->housekeeping_timer, + ieee80211_mesh_housekeeping_timer, 0); ifmsh->accepting_plinks = true; atomic_set(&ifmsh->mpaths, 0); @@ -1458,12 +1458,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) mesh_pathtbl_init(sdata); - setup_timer(&ifmsh->mesh_path_timer, - ieee80211_mesh_path_timer, - (unsigned long) sdata); - setup_timer(&ifmsh->mesh_path_root_timer, - ieee80211_mesh_path_root_timer, - (unsigned long) sdata); + timer_setup(&ifmsh->mesh_path_timer, ieee80211_mesh_path_timer, 0); + timer_setup(&ifmsh->mesh_path_root_timer, + ieee80211_mesh_path_root_timer, 0); INIT_LIST_HEAD(&ifmsh->preq_queue.list); skb_queue_head_init(&ifmsh->ps.bc_buf); spin_lock_init(&ifmsh->mesh_preq_queue_lock); diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 465b7853edc0..ee56f18cad3f 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -296,7 +296,7 @@ void mesh_path_tx_pending(struct mesh_path *mpath); int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata); void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata); int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr); -void mesh_path_timer(unsigned long data); +void mesh_path_timer(struct timer_list *t); void mesh_path_flush_by_nexthop(struct sta_info *sta); void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 146ec6c0f12f..4f7826d7b47c 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1194,9 +1194,9 @@ endlookup: return err; } -void mesh_path_timer(unsigned long data) +void mesh_path_timer(struct timer_list *t) { - struct mesh_path *mpath = (void *) data; + struct mesh_path *mpath = from_timer(mpath, t, timer); struct ieee80211_sub_if_data *sdata = mpath->sdata; int ret; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 97269caafecd..86c8dfef56a4 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -399,8 +399,7 @@ struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata, skb_queue_head_init(&new_mpath->frame_queue); new_mpath->exp_time = jiffies; spin_lock_init(&new_mpath->state_lock); - setup_timer(&new_mpath->timer, mesh_path_timer, - (unsigned long) new_mpath); + timer_setup(&new_mpath->timer, mesh_path_timer, 0); return new_mpath; } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e4ededa1909d..04460440d731 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1066,10 +1066,10 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) } EXPORT_SYMBOL(ieee80211_chswitch_done); -static void ieee80211_chswitch_timer(unsigned long data) +static void ieee80211_chswitch_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.mgd.chswitch_timer); ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work); } @@ -1577,9 +1577,9 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) } } -void ieee80211_dynamic_ps_timer(unsigned long data) +void ieee80211_dynamic_ps_timer(struct timer_list *t) { - struct ieee80211_local *local = (void *) data; + struct ieee80211_local *local = from_timer(local, t, dynamic_ps_timer); ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); } @@ -3711,10 +3711,10 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, sdata_unlock(sdata); } -static void ieee80211_sta_timer(unsigned long data) +static void ieee80211_sta_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.mgd.timer); ieee80211_queue_work(&sdata->local->hw, &sdata->work); } @@ -3991,10 +3991,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) sdata_unlock(sdata); } -static void ieee80211_sta_bcn_mon_timer(unsigned long data) +static void ieee80211_sta_bcn_mon_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.mgd.bcn_mon_timer); struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) @@ -4005,10 +4005,10 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) &sdata->u.mgd.beacon_connection_loss_work); } -static void ieee80211_sta_conn_mon_timer(unsigned long data) +static void ieee80211_sta_conn_mon_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = - (struct ieee80211_sub_if_data *) data; + from_timer(sdata, t, u.mgd.conn_mon_timer); struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; @@ -4139,14 +4139,10 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work); INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work, ieee80211_tdls_peer_del_work); - setup_timer(&ifmgd->timer, ieee80211_sta_timer, - (unsigned long) sdata); - setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, - (unsigned long) sdata); - setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, - (unsigned long) sdata); - setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, - (unsigned long) sdata); + timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0); + timer_setup(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 0); + timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0); + timer_setup(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 0); INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk, ieee80211_sta_handle_tspec_ac_params_wk); diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c index 88e6ebbbe24f..d351dc1162be 100644 --- a/net/mac80211/ocb.c +++ b/net/mac80211/ocb.c @@ -150,9 +150,10 @@ void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata) sdata_unlock(sdata); } -static void ieee80211_ocb_housekeeping_timer(unsigned long data) +static void ieee80211_ocb_housekeeping_timer(struct timer_list *t) { - struct ieee80211_sub_if_data *sdata = (void *)data; + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.ocb.housekeeping_timer); struct ieee80211_local *local = sdata->local; struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; @@ -165,9 +166,8 @@ void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; - setup_timer(&ifocb->housekeeping_timer, - ieee80211_ocb_housekeeping_timer, - (unsigned long)sdata); + timer_setup(&ifocb->housekeeping_timer, + ieee80211_ocb_housekeeping_timer, 0); INIT_LIST_HEAD(&ifocb->incomplete_stations); spin_lock_init(&ifocb->incomplete_lock); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a3060e55122c..0c5627f8a104 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -379,14 +379,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, if (sta_prepare_rate_control(local, sta, gfp)) goto free_txq; - for (i = 0; i < IEEE80211_NUM_TIDS; i++) { - /* - * timer_to_tid must be initialized with identity mapping - * to enable session_timer's data differentiation. See - * sta_rx_agg_session_timer_expired for usage. - */ - sta->timer_to_tid[i] = i; - } for (i = 0; i < IEEE80211_NUM_ACS; i++) { skb_queue_head_init(&sta->ps_tx_buf[i]); skb_queue_head_init(&sta->tx_filtered[i]); @@ -1064,9 +1056,9 @@ int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata, return ret; } -static void sta_info_cleanup(unsigned long data) +static void sta_info_cleanup(struct timer_list *t) { - struct ieee80211_local *local = (struct ieee80211_local *) data; + struct ieee80211_local *local = from_timer(local, t, sta_cleanup); struct sta_info *sta; bool timer_needed = false; @@ -1098,8 +1090,7 @@ int sta_info_init(struct ieee80211_local *local) mutex_init(&local->sta_mtx); INIT_LIST_HEAD(&local->sta_list); - setup_timer(&local->sta_cleanup, sta_info_cleanup, - (unsigned long)local); + timer_setup(&local->sta_cleanup, sta_info_cleanup, 0); return 0; } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5c54acd10562..cd53619435b6 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -126,6 +126,8 @@ enum ieee80211_agg_stop_reason { AGG_STOP_DESTROY_STA, }; +struct sta_info; + /** * struct tid_ampdu_tx - TID aggregation information (Tx). * @@ -133,8 +135,10 @@ enum ieee80211_agg_stop_reason { * @session_timer: check if we keep Tx-ing on the TID (by timeout value) * @addba_resp_timer: timer for peer's response to addba request * @pending: pending frames queue -- use sta's spinlock to protect + * @sta: station we are attached to * @dialog_token: dialog token for aggregation session * @timeout: session timeout value to be filled in ADDBA requests + * @tid: TID number * @state: session state (see above) * @last_tx: jiffies of last tx activity * @stop_initiator: initiator of a session stop @@ -158,6 +162,7 @@ struct tid_ampdu_tx { struct timer_list session_timer; struct timer_list addba_resp_timer; struct sk_buff_head pending; + struct sta_info *sta; unsigned long state; unsigned long last_tx; u16 timeout; @@ -169,6 +174,7 @@ struct tid_ampdu_tx { u16 failed_bar_ssn; bool bar_pending; bool amsdu; + u8 tid; }; /** @@ -181,12 +187,14 @@ struct tid_ampdu_tx { * @reorder_time: jiffies when skb was added * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) * @reorder_timer: releases expired frames from the reorder buffer. + * @sta: station we are attached to * @last_rx: jiffies of last rx activity * @head_seq_num: head sequence number in reordering buffer. * @stored_mpdu_num: number of MPDUs in reordering buffer * @ssn: Starting Sequence Number expected to be aggregated. * @buf_size: buffer size for incoming A-MPDUs * @timeout: reset timer value (in TUs). + * @tid: TID number * @rcu_head: RCU head used for freeing this struct * @reorder_lock: serializes access to reorder buffer, see below. * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and @@ -208,6 +216,7 @@ struct tid_ampdu_rx { u64 reorder_buf_filtered; struct sk_buff_head *reorder_buf; unsigned long *reorder_time; + struct sta_info *sta; struct timer_list session_timer; struct timer_list reorder_timer; unsigned long last_rx; @@ -216,6 +225,7 @@ struct tid_ampdu_rx { u16 ssn; u16 buf_size; u16 timeout; + u8 tid; u8 auto_seq:1, removed:1, started:1; @@ -447,7 +457,6 @@ struct ieee80211_sta_rx_stats { * plus one for non-QoS frames) * @tid_seq: per-TID sequence numbers for sending to this STA * @ampdu_mlme: A-MPDU state machine state - * @timer_to_tid: identity mapping to ID timers * @mesh: mesh STA information * @debugfs_dir: debug filesystem directory dentry * @dead: set to true when sta is unlinked @@ -554,7 +563,6 @@ struct sta_info { * Aggregation information, locked with lock. */ struct sta_ampdu_mlme ampdu_mlme; - u8 timer_to_tid[IEEE80211_NUM_TIDS]; #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *debugfs_dir; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a0e1951227fa..b1ac23ca20c8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2605,10 +2605,32 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag goto nla_put_failure; } - if (wdev->ssid_len) { - if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) + wdev_lock(wdev); + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + if (wdev->ssid_len && + nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) goto nla_put_failure; + break; + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_ADHOC: { + const u8 *ssid_ie; + if (!wdev->current_bss) + break; + ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub, + WLAN_EID_SSID); + if (!ssid_ie) + break; + if (nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2)) + goto nla_put_failure; + break; + } + default: + /* nothing */ + break; } + wdev_unlock(wdev); genlmsg_end(msg, hdr); return 0; diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 3871998059de..78e71b0390be 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -3644,27 +3644,14 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy, } } -int __init regulatory_init(void) +static int __init regulatory_init_db(void) { - int err = 0; + int err; err = load_builtin_regdb_keys(); if (err) return err; - reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0); - if (IS_ERR(reg_pdev)) - return PTR_ERR(reg_pdev); - - spin_lock_init(®_requests_lock); - spin_lock_init(®_pending_beacons_lock); - spin_lock_init(®_indoor_lock); - - rcu_assign_pointer(cfg80211_regdomain, cfg80211_world_regdom); - - user_alpha2[0] = '9'; - user_alpha2[1] = '7'; - /* We always try to get an update for the static regdomain */ err = regulatory_hint_core(cfg80211_world_regdom->alpha2); if (err) { @@ -3692,6 +3679,31 @@ int __init regulatory_init(void) return 0; } +#ifndef MODULE +late_initcall(regulatory_init_db); +#endif + +int __init regulatory_init(void) +{ + reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0); + if (IS_ERR(reg_pdev)) + return PTR_ERR(reg_pdev); + + spin_lock_init(®_requests_lock); + spin_lock_init(®_pending_beacons_lock); + spin_lock_init(®_indoor_lock); + + rcu_assign_pointer(cfg80211_regdomain, cfg80211_world_regdom); + + user_alpha2[0] = '9'; + user_alpha2[1] = '7'; + +#ifdef MODULE + return regulatory_init_db(); +#else + return 0; +#endif +} void regulatory_exit(void) { |