aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-10-08 15:39:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-08 15:39:28 -0400
commite9a68707d736f4f73d7e209885d7b4c5c452b1dc (patch)
treed9f76964c77c1059483b08436ed060b702b8e25d /net
parentdd53df265b1ee7a1fbbc76bb62c3bec2383bbd44 (diff)
parent15a6321d1c0f8db561932cd99e1b9897981da71f (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ipw2x00/ipw2200.c
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-rx.c8
-rw-r--r--net/mac80211/agg-tx.c16
-rw-r--r--net/mac80211/cfg.c79
-rw-r--r--net/mac80211/debugfs_sta.c3
-rw-r--r--net/mac80211/ht.c17
-rw-r--r--net/mac80211/ibss.c65
-rw-r--r--net/mac80211/ieee80211_i.h20
-rw-r--r--net/mac80211/iface.c50
-rw-r--r--net/mac80211/key.c95
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/main.c27
-rw-r--r--net/mac80211/mlme.c33
-rw-r--r--net/mac80211/pm.c5
-rw-r--r--net/mac80211/rx.c42
-rw-r--r--net/mac80211/scan.c154
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/mac80211/sta_info.h8
-rw-r--r--net/mac80211/status.c6
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c22
-rw-r--r--net/netlink/genetlink.c14
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/ibss.c2
-rw-r--r--net/wireless/mlme.c54
-rw-r--r--net/wireless/nl80211.c2000
-rw-r--r--net/wireless/scan.c12
-rw-r--r--net/wireless/sme.c2
-rw-r--r--net/wireless/util.c12
-rw-r--r--net/wireless/wext-compat.c38
30 files changed, 1228 insertions, 1632 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 58eab9e8e4ee..720b7a84af59 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -56,7 +56,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
56} 56}
57 57
58void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 58void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
59 u16 initiator, u16 reason) 59 u16 initiator, u16 reason, bool tx)
60{ 60{
61 struct ieee80211_local *local = sta->local; 61 struct ieee80211_local *local = sta->local;
62 struct tid_ampdu_rx *tid_rx; 62 struct tid_ampdu_rx *tid_rx;
@@ -81,7 +81,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
81 "aggregation for tid %d\n", tid); 81 "aggregation for tid %d\n", tid);
82 82
83 /* check if this is a self generated aggregation halt */ 83 /* check if this is a self generated aggregation halt */
84 if (initiator == WLAN_BACK_RECIPIENT) 84 if (initiator == WLAN_BACK_RECIPIENT && tx)
85 ieee80211_send_delba(sta->sdata, sta->sta.addr, 85 ieee80211_send_delba(sta->sdata, sta->sta.addr,
86 tid, 0, reason); 86 tid, 0, reason);
87 87
@@ -92,10 +92,10 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
92} 92}
93 93
94void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 94void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
95 u16 initiator, u16 reason) 95 u16 initiator, u16 reason, bool tx)
96{ 96{
97 mutex_lock(&sta->ampdu_mlme.mtx); 97 mutex_lock(&sta->ampdu_mlme.mtx);
98 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); 98 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx);
99 mutex_unlock(&sta->ampdu_mlme.mtx); 99 mutex_unlock(&sta->ampdu_mlme.mtx);
100} 100}
101 101
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c893f236acea..d4679b265ba8 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -145,7 +145,8 @@ static void kfree_tid_tx(struct rcu_head *rcu_head)
145} 145}
146 146
147int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 147int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
148 enum ieee80211_back_parties initiator) 148 enum ieee80211_back_parties initiator,
149 bool tx)
149{ 150{
150 struct ieee80211_local *local = sta->local; 151 struct ieee80211_local *local = sta->local;
151 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; 152 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
@@ -175,6 +176,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
175 176
176 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); 177 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
177 178
179 del_timer_sync(&tid_tx->addba_resp_timer);
180
178 /* 181 /*
179 * After this packets are no longer handed right through 182 * After this packets are no longer handed right through
180 * to the driver but are put onto tid_tx->pending instead, 183 * to the driver but are put onto tid_tx->pending instead,
@@ -183,6 +186,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
183 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); 186 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
184 187
185 tid_tx->stop_initiator = initiator; 188 tid_tx->stop_initiator = initiator;
189 tid_tx->tx_stop = tx;
186 190
187 ret = drv_ampdu_action(local, sta->sdata, 191 ret = drv_ampdu_action(local, sta->sdata,
188 IEEE80211_AMPDU_TX_STOP, 192 IEEE80211_AMPDU_TX_STOP,
@@ -575,13 +579,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
575EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); 579EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
576 580
577int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 581int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
578 enum ieee80211_back_parties initiator) 582 enum ieee80211_back_parties initiator,
583 bool tx)
579{ 584{
580 int ret; 585 int ret;
581 586
582 mutex_lock(&sta->ampdu_mlme.mtx); 587 mutex_lock(&sta->ampdu_mlme.mtx);
583 588
584 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); 589 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx);
585 590
586 mutex_unlock(&sta->ampdu_mlme.mtx); 591 mutex_unlock(&sta->ampdu_mlme.mtx);
587 592
@@ -670,7 +675,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
670 goto unlock_sta; 675 goto unlock_sta;
671 } 676 }
672 677
673 if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR) 678 if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
674 ieee80211_send_delba(sta->sdata, ra, tid, 679 ieee80211_send_delba(sta->sdata, ra, tid,
675 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 680 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
676 681
@@ -770,7 +775,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
770 775
771 sta->ampdu_mlme.addba_req_num[tid] = 0; 776 sta->ampdu_mlme.addba_req_num[tid] = 0;
772 } else { 777 } else {
773 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 778 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
779 true);
774 } 780 }
775 781
776 out: 782 out:
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c981604b71e6..ecf9b7166ed1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -68,14 +68,42 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
68 params && params->use_4addr >= 0) 68 params && params->use_4addr >= 0)
69 sdata->u.mgd.use_4addr = params->use_4addr; 69 sdata->u.mgd.use_4addr = params->use_4addr;
70 70
71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) 71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
72 sdata->u.mntr_flags = *flags; 72 struct ieee80211_local *local = sdata->local;
73
74 if (ieee80211_sdata_running(sdata)) {
75 /*
76 * Prohibit MONITOR_FLAG_COOK_FRAMES to be
77 * changed while the interface is up.
78 * Else we would need to add a lot of cruft
79 * to update everything:
80 * cooked_mntrs, monitor and all fif_* counters
81 * reconfigure hardware
82 */
83 if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
84 (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
85 return -EBUSY;
86
87 ieee80211_adjust_monitor_flags(sdata, -1);
88 sdata->u.mntr_flags = *flags;
89 ieee80211_adjust_monitor_flags(sdata, 1);
90
91 ieee80211_configure_filter(local);
92 } else {
93 /*
94 * Because the interface is down, ieee80211_do_stop
95 * and ieee80211_do_open take care of "everything"
96 * mentioned in the comment above.
97 */
98 sdata->u.mntr_flags = *flags;
99 }
100 }
73 101
74 return 0; 102 return 0;
75} 103}
76 104
77static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
78 u8 key_idx, const u8 *mac_addr, 106 u8 key_idx, bool pairwise, const u8 *mac_addr,
79 struct key_params *params) 107 struct key_params *params)
80{ 108{
81 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -103,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
103 if (IS_ERR(key)) 131 if (IS_ERR(key))
104 return PTR_ERR(key); 132 return PTR_ERR(key);
105 133
134 if (pairwise)
135 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
136
106 mutex_lock(&sdata->local->sta_mtx); 137 mutex_lock(&sdata->local->sta_mtx);
107 138
108 if (mac_addr) { 139 if (mac_addr) {
@@ -125,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
125} 156}
126 157
127static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 158static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
128 u8 key_idx, const u8 *mac_addr) 159 u8 key_idx, bool pairwise, const u8 *mac_addr)
129{ 160{
130 struct ieee80211_sub_if_data *sdata; 161 struct ieee80211_sub_if_data *sdata;
131 struct sta_info *sta; 162 struct sta_info *sta;
@@ -142,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
142 if (!sta) 173 if (!sta)
143 goto out_unlock; 174 goto out_unlock;
144 175
145 if (sta->key) { 176 if (pairwise) {
146 ieee80211_key_free(sdata->local, sta->key); 177 if (sta->ptk) {
147 WARN_ON(sta->key); 178 ieee80211_key_free(sdata->local, sta->ptk);
148 ret = 0; 179 ret = 0;
180 }
181 } else {
182 if (sta->gtk[key_idx]) {
183 ieee80211_key_free(sdata->local,
184 sta->gtk[key_idx]);
185 ret = 0;
186 }
149 } 187 }
150 188
151 goto out_unlock; 189 goto out_unlock;
@@ -167,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
167} 205}
168 206
169static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 207static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
170 u8 key_idx, const u8 *mac_addr, void *cookie, 208 u8 key_idx, bool pairwise, const u8 *mac_addr,
209 void *cookie,
171 void (*callback)(void *cookie, 210 void (*callback)(void *cookie,
172 struct key_params *params)) 211 struct key_params *params))
173{ 212{
@@ -175,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
175 struct sta_info *sta = NULL; 214 struct sta_info *sta = NULL;
176 u8 seq[6] = {0}; 215 u8 seq[6] = {0};
177 struct key_params params; 216 struct key_params params;
178 struct ieee80211_key *key; 217 struct ieee80211_key *key = NULL;
179 u32 iv32; 218 u32 iv32;
180 u16 iv16; 219 u16 iv16;
181 int err = -ENOENT; 220 int err = -ENOENT;
@@ -189,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
189 if (!sta) 228 if (!sta)
190 goto out; 229 goto out;
191 230
192 key = sta->key; 231 if (pairwise)
232 key = sta->ptk;
233 else if (key_idx < NUM_DEFAULT_KEYS)
234 key = sta->gtk[key_idx];
193 } else 235 } else
194 key = sdata->keys[key_idx]; 236 key = sdata->keys[key_idx];
195 237
@@ -285,6 +327,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
285 STATION_INFO_TX_BYTES | 327 STATION_INFO_TX_BYTES |
286 STATION_INFO_RX_PACKETS | 328 STATION_INFO_RX_PACKETS |
287 STATION_INFO_TX_PACKETS | 329 STATION_INFO_TX_PACKETS |
330 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED |
288 STATION_INFO_TX_BITRATE; 332 STATION_INFO_TX_BITRATE;
289 333
290 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 334 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
@@ -292,6 +336,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
292 sinfo->tx_bytes = sta->tx_bytes; 336 sinfo->tx_bytes = sta->tx_bytes;
293 sinfo->rx_packets = sta->rx_packets; 337 sinfo->rx_packets = sta->rx_packets;
294 sinfo->tx_packets = sta->tx_packets; 338 sinfo->tx_packets = sta->tx_packets;
339 sinfo->tx_retries = sta->tx_retry_count;
340 sinfo->tx_failed = sta->tx_retry_failed;
295 341
296 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 342 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
297 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 343 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1317,7 +1363,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1317} 1363}
1318 1364
1319static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, 1365static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
1320 u8 *addr) 1366 const u8 *addr)
1321{ 1367{
1322 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1368 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1323 1369
@@ -1366,7 +1412,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1366 if (!sdata->u.mgd.associated || 1412 if (!sdata->u.mgd.associated ||
1367 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { 1413 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1368 mutex_lock(&sdata->local->iflist_mtx); 1414 mutex_lock(&sdata->local->iflist_mtx);
1369 ieee80211_recalc_smps(sdata->local, sdata); 1415 ieee80211_recalc_smps(sdata->local);
1370 mutex_unlock(&sdata->local->iflist_mtx); 1416 mutex_unlock(&sdata->local->iflist_mtx);
1371 return 0; 1417 return 0;
1372 } 1418 }
@@ -1521,7 +1567,11 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1521 1567
1522 switch (sdata->vif.type) { 1568 switch (sdata->vif.type) {
1523 case NL80211_IFTYPE_ADHOC: 1569 case NL80211_IFTYPE_ADHOC:
1524 if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1570 case NL80211_IFTYPE_AP:
1571 case NL80211_IFTYPE_AP_VLAN:
1572 case NL80211_IFTYPE_P2P_GO:
1573 if (!ieee80211_is_action(mgmt->frame_control) ||
1574 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1525 break; 1575 break;
1526 rcu_read_lock(); 1576 rcu_read_lock();
1527 sta = sta_info_get(sdata, mgmt->da); 1577 sta = sta_info_get(sdata, mgmt->da);
@@ -1530,6 +1580,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1530 return -ENOLINK; 1580 return -ENOLINK;
1531 break; 1581 break;
1532 case NL80211_IFTYPE_STATION: 1582 case NL80211_IFTYPE_STATION:
1583 case NL80211_IFTYPE_P2P_CLIENT:
1533 break; 1584 break;
1534 default: 1585 default:
1535 return -EOPNOTSUPP; 1586 return -EOPNOTSUPP;
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 6b7ff9fb4604..50c40ea3cb4d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -196,7 +196,8 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
196 else 196 else
197 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); 197 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
198 } else { 198 } else {
199 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); 199 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
200 3, true);
200 ret = 0; 201 ret = 0;
201 } 202 }
202 203
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 11f74f5f7b2f..4214bb6e12fc 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -101,16 +101,16 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
101 ht_cap->mcs.rx_mask[32/8] |= 1; 101 ht_cap->mcs.rx_mask[32/8] |= 1;
102} 102}
103 103
104void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) 104void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
105{ 105{
106 int i; 106 int i;
107 107
108 cancel_work_sync(&sta->ampdu_mlme.work); 108 cancel_work_sync(&sta->ampdu_mlme.work);
109 109
110 for (i = 0; i < STA_TID_NUM; i++) { 110 for (i = 0; i < STA_TID_NUM; i++) {
111 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR); 111 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
112 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, 112 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
113 WLAN_REASON_QSTA_LEAVE_QBSS); 113 WLAN_REASON_QSTA_LEAVE_QBSS, tx);
114 } 114 }
115} 115}
116 116
@@ -135,7 +135,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
135 if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) 135 if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
136 ___ieee80211_stop_rx_ba_session( 136 ___ieee80211_stop_rx_ba_session(
137 sta, tid, WLAN_BACK_RECIPIENT, 137 sta, tid, WLAN_BACK_RECIPIENT,
138 WLAN_REASON_QSTA_TIMEOUT); 138 WLAN_REASON_QSTA_TIMEOUT, true);
139 139
140 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 140 tid_tx = sta->ampdu_mlme.tid_tx[tid];
141 if (!tid_tx) 141 if (!tid_tx)
@@ -146,7 +146,8 @@ void ieee80211_ba_session_work(struct work_struct *work)
146 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 146 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
147 &tid_tx->state)) 147 &tid_tx->state))
148 ___ieee80211_stop_tx_ba_session(sta, tid, 148 ___ieee80211_stop_tx_ba_session(sta, tid,
149 WLAN_BACK_INITIATOR); 149 WLAN_BACK_INITIATOR,
150 true);
150 } 151 }
151 mutex_unlock(&sta->ampdu_mlme.mtx); 152 mutex_unlock(&sta->ampdu_mlme.mtx);
152} 153}
@@ -214,9 +215,11 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
214#endif /* CONFIG_MAC80211_HT_DEBUG */ 215#endif /* CONFIG_MAC80211_HT_DEBUG */
215 216
216 if (initiator == WLAN_BACK_INITIATOR) 217 if (initiator == WLAN_BACK_INITIATOR)
217 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0); 218 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
219 true);
218 else 220 else
219 __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT); 221 __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
222 true);
220} 223}
221 224
222int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, 225int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 1a3aae54f0cf..ff60c022f51d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
173 memcpy(skb_put(skb, ifibss->ie_len), 173 memcpy(skb_put(skb, ifibss->ie_len),
174 ifibss->ie, ifibss->ie_len); 174 ifibss->ie, ifibss->ie_len);
175 175
176 if (local->hw.queues >= 4) {
177 pos = skb_put(skb, 9);
178 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
179 *pos++ = 7; /* len */
180 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
181 *pos++ = 0x50;
182 *pos++ = 0xf2;
183 *pos++ = 2; /* WME */
184 *pos++ = 0; /* WME info */
185 *pos++ = 1; /* WME ver */
186 *pos++ = 0; /* U-APSD no in use */
187 }
188
176 rcu_assign_pointer(ifibss->presp, skb); 189 rcu_assign_pointer(ifibss->presp, skb);
177 190
178 sdata->vif.bss_conf.beacon_int = beacon_int; 191 sdata->vif.bss_conf.beacon_int = beacon_int;
@@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
266 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 279 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
267 return; 280 return;
268 281
269 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates && 282 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
270 memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { 283 memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
271 supp_rates = ieee80211_sta_get_rates(local, elems, band);
272 284
273 rcu_read_lock(); 285 rcu_read_lock();
274
275 sta = sta_info_get(sdata, mgmt->sa); 286 sta = sta_info_get(sdata, mgmt->sa);
276 if (sta) {
277 u32 prev_rates;
278 287
279 prev_rates = sta->sta.supp_rates[band]; 288 if (elems->supp_rates) {
280 /* make sure mandatory rates are always added */ 289 supp_rates = ieee80211_sta_get_rates(local, elems,
281 sta->sta.supp_rates[band] = supp_rates | 290 band);
282 ieee80211_mandatory_rates(local, band); 291 if (sta) {
292 u32 prev_rates;
283 293
284 if (sta->sta.supp_rates[band] != prev_rates) { 294 prev_rates = sta->sta.supp_rates[band];
295 /* make sure mandatory rates are always added */
296 sta->sta.supp_rates[band] = supp_rates |
297 ieee80211_mandatory_rates(local, band);
298
299 if (sta->sta.supp_rates[band] != prev_rates) {
285#ifdef CONFIG_MAC80211_IBSS_DEBUG 300#ifdef CONFIG_MAC80211_IBSS_DEBUG
286 printk(KERN_DEBUG "%s: updated supp_rates set " 301 printk(KERN_DEBUG
287 "for %pM based on beacon/probe_response " 302 "%s: updated supp_rates set "
288 "(0x%x -> 0x%x)\n", 303 "for %pM based on beacon"
289 sdata->name, sta->sta.addr, 304 "/probe_resp (0x%x -> 0x%x)\n",
290 prev_rates, sta->sta.supp_rates[band]); 305 sdata->name, sta->sta.addr,
306 prev_rates,
307 sta->sta.supp_rates[band]);
291#endif 308#endif
292 rate_control_rate_init(sta); 309 rate_control_rate_init(sta);
293 } 310 }
294 rcu_read_unlock(); 311 } else
295 } else { 312 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
296 rcu_read_unlock(); 313 mgmt->sa, supp_rates,
297 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 314 GFP_ATOMIC);
298 supp_rates, GFP_KERNEL);
299 } 315 }
316
317 if (sta && elems->wmm_info)
318 set_sta_flags(sta, WLAN_STA_WME);
319
320 rcu_read_unlock();
300 } 321 }
301 322
302 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 323 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 945fbf29719d..f0610fa4fbe0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -369,6 +369,7 @@ struct ieee80211_if_managed {
369 369
370 unsigned int flags; 370 unsigned int flags;
371 371
372 bool beacon_crc_valid;
372 u32 beacon_crc; 373 u32 beacon_crc;
373 374
374 enum { 375 enum {
@@ -548,8 +549,6 @@ struct ieee80211_sub_if_data {
548 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 549 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
549 unsigned int fragment_next; 550 unsigned int fragment_next;
550 551
551#define NUM_DEFAULT_KEYS 4
552#define NUM_DEFAULT_MGMT_KEYS 2
553 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 552 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
554 struct ieee80211_key *default_key; 553 struct ieee80211_key *default_key;
555 struct ieee80211_key *default_mgmt_key; 554 struct ieee80211_key *default_mgmt_key;
@@ -1132,6 +1131,8 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
1132void ieee80211_remove_interfaces(struct ieee80211_local *local); 1131void ieee80211_remove_interfaces(struct ieee80211_local *local);
1133u32 __ieee80211_recalc_idle(struct ieee80211_local *local); 1132u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
1134void ieee80211_recalc_idle(struct ieee80211_local *local); 1133void ieee80211_recalc_idle(struct ieee80211_local *local);
1134void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
1135 const int offset);
1135 1136
1136static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) 1137static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
1137{ 1138{
@@ -1172,10 +1173,10 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
1172void ieee80211_request_smps_work(struct work_struct *work); 1173void ieee80211_request_smps_work(struct work_struct *work);
1173 1174
1174void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1175void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1175 u16 initiator, u16 reason); 1176 u16 initiator, u16 reason, bool stop);
1176void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1177void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1177 u16 initiator, u16 reason); 1178 u16 initiator, u16 reason, bool stop);
1178void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); 1179void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx);
1179void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, 1180void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
1180 struct sta_info *sta, 1181 struct sta_info *sta,
1181 struct ieee80211_mgmt *mgmt, size_t len); 1182 struct ieee80211_mgmt *mgmt, size_t len);
@@ -1189,9 +1190,11 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
1189 size_t len); 1190 size_t len);
1190 1191
1191int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 1192int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
1192 enum ieee80211_back_parties initiator); 1193 enum ieee80211_back_parties initiator,
1194 bool tx);
1193int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 1195int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
1194 enum ieee80211_back_parties initiator); 1196 enum ieee80211_back_parties initiator,
1197 bool tx);
1195void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); 1198void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
1196void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); 1199void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
1197void ieee80211_ba_session_work(struct work_struct *work); 1200void ieee80211_ba_session_work(struct work_struct *work);
@@ -1294,8 +1297,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1294 enum ieee80211_band band); 1297 enum ieee80211_band band);
1295int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, 1298int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1296 enum ieee80211_smps_mode smps_mode); 1299 enum ieee80211_smps_mode smps_mode);
1297void ieee80211_recalc_smps(struct ieee80211_local *local, 1300void ieee80211_recalc_smps(struct ieee80211_local *local);
1298 struct ieee80211_sub_if_data *forsdata);
1299 1301
1300size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1302size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
1301 const u8 *ids, int n_ids, size_t offset); 1303 const u8 *ids, int n_ids, size_t offset);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 66785739dad3..e99d1b60557c 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -24,6 +24,7 @@
24#include "led.h" 24#include "led.h"
25#include "driver-ops.h" 25#include "driver-ops.h"
26#include "wme.h" 26#include "wme.h"
27#include "rate.h"
27 28
28/** 29/**
29 * DOC: Interface list locking 30 * DOC: Interface list locking
@@ -148,6 +149,26 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
148 return 0; 149 return 0;
149} 150}
150 151
152void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
153 const int offset)
154{
155 struct ieee80211_local *local = sdata->local;
156 u32 flags = sdata->u.mntr_flags;
157
158#define ADJUST(_f, _s) do { \
159 if (flags & MONITOR_FLAG_##_f) \
160 local->fif_##_s += offset; \
161 } while (0)
162
163 ADJUST(FCSFAIL, fcsfail);
164 ADJUST(PLCPFAIL, plcpfail);
165 ADJUST(CONTROL, control);
166 ADJUST(CONTROL, pspoll);
167 ADJUST(OTHER_BSS, other_bss);
168
169#undef ADJUST
170}
171
151/* 172/*
152 * NOTE: Be very careful when changing this function, it must NOT return 173 * NOTE: Be very careful when changing this function, it must NOT return
153 * an error on interface type changes that have been pre-checked, so most 174 * an error on interface type changes that have been pre-checked, so most
@@ -240,17 +261,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
240 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 261 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
241 } 262 }
242 263
243 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) 264 ieee80211_adjust_monitor_flags(sdata, 1);
244 local->fif_fcsfail++;
245 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
246 local->fif_plcpfail++;
247 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
248 local->fif_control++;
249 local->fif_pspoll++;
250 }
251 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
252 local->fif_other_bss++;
253
254 ieee80211_configure_filter(local); 265 ieee80211_configure_filter(local);
255 266
256 netif_carrier_on(dev); 267 netif_carrier_on(dev);
@@ -301,6 +312,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
301 /* STA has been freed */ 312 /* STA has been freed */
302 goto err_del_interface; 313 goto err_del_interface;
303 } 314 }
315
316 rate_control_rate_init(sta);
304 } 317 }
305 318
306 /* 319 /*
@@ -477,17 +490,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
477 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 490 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
478 } 491 }
479 492
480 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) 493 ieee80211_adjust_monitor_flags(sdata, -1);
481 local->fif_fcsfail--;
482 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
483 local->fif_plcpfail--;
484 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
485 local->fif_pspoll--;
486 local->fif_control--;
487 }
488 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
489 local->fif_other_bss--;
490
491 ieee80211_configure_filter(local); 494 ieee80211_configure_filter(local);
492 break; 495 break;
493 case NL80211_IFTYPE_MESH_POINT: 496 case NL80211_IFTYPE_MESH_POINT:
@@ -793,7 +796,8 @@ static void ieee80211_iface_work(struct work_struct *work)
793 796
794 __ieee80211_stop_rx_ba_session( 797 __ieee80211_stop_rx_ba_session(
795 sta, tid, WLAN_BACK_RECIPIENT, 798 sta, tid, WLAN_BACK_RECIPIENT,
796 WLAN_REASON_QSTA_REQUIRE_SETUP); 799 WLAN_REASON_QSTA_REQUIRE_SETUP,
800 true);
797 } 801 }
798 mutex_unlock(&local->sta_mtx); 802 mutex_unlock(&local->sta_mtx);
799 } else switch (sdata->vif.type) { 803 } else switch (sdata->vif.type) {
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 6a63d1abd14d..ccd676b2f599 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -68,15 +68,21 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
68 68
69 might_sleep(); 69 might_sleep();
70 70
71 if (!key->local->ops->set_key) { 71 if (!key->local->ops->set_key)
72 ret = -EOPNOTSUPP;
73 goto out_unsupported; 72 goto out_unsupported;
74 }
75 73
76 assert_key_lock(key->local); 74 assert_key_lock(key->local);
77 75
78 sta = get_sta_for_key(key); 76 sta = get_sta_for_key(key);
79 77
78 /*
79 * If this is a per-STA GTK, check if it
80 * is supported; if not, return.
81 */
82 if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
83 !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
84 goto out_unsupported;
85
80 sdata = key->sdata; 86 sdata = key->sdata;
81 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 87 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
82 sdata = container_of(sdata->bss, 88 sdata = container_of(sdata->bss,
@@ -85,31 +91,28 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
85 91
86 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 92 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
87 93
88 if (!ret) 94 if (!ret) {
89 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 95 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
96 return 0;
97 }
90 98
91 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) 99 if (ret != -ENOSPC && ret != -EOPNOTSUPP)
92 wiphy_err(key->local->hw.wiphy, 100 wiphy_err(key->local->hw.wiphy,
93 "failed to set key (%d, %pM) to hardware (%d)\n", 101 "failed to set key (%d, %pM) to hardware (%d)\n",
94 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); 102 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
95 103
96out_unsupported: 104 out_unsupported:
97 if (ret) { 105 switch (key->conf.cipher) {
98 switch (key->conf.cipher) { 106 case WLAN_CIPHER_SUITE_WEP40:
99 case WLAN_CIPHER_SUITE_WEP40: 107 case WLAN_CIPHER_SUITE_WEP104:
100 case WLAN_CIPHER_SUITE_WEP104: 108 case WLAN_CIPHER_SUITE_TKIP:
101 case WLAN_CIPHER_SUITE_TKIP: 109 case WLAN_CIPHER_SUITE_CCMP:
102 case WLAN_CIPHER_SUITE_CCMP: 110 case WLAN_CIPHER_SUITE_AES_CMAC:
103 case WLAN_CIPHER_SUITE_AES_CMAC: 111 /* all of these we can do in software */
104 /* all of these we can do in software */ 112 return 0;
105 ret = 0; 113 default:
106 break; 114 return -EINVAL;
107 default:
108 ret = -EINVAL;
109 }
110 } 115 }
111
112 return ret;
113} 116}
114 117
115static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) 118static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
@@ -147,6 +150,26 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
147 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 150 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
148} 151}
149 152
153void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
154{
155 struct ieee80211_key *key;
156
157 key = container_of(key_conf, struct ieee80211_key, conf);
158
159 might_sleep();
160 assert_key_lock(key->local);
161
162 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
163
164 /*
165 * Flush TX path to avoid attempts to use this key
166 * after this function returns. Until then, drivers
167 * must be prepared to handle the key.
168 */
169 synchronize_rcu();
170}
171EXPORT_SYMBOL_GPL(ieee80211_key_removed);
172
150static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 173static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
151 int idx) 174 int idx)
152{ 175{
@@ -202,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
202 225
203static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, 226static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
204 struct sta_info *sta, 227 struct sta_info *sta,
228 bool pairwise,
205 struct ieee80211_key *old, 229 struct ieee80211_key *old,
206 struct ieee80211_key *new) 230 struct ieee80211_key *new)
207{ 231{
@@ -210,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
210 if (new) 234 if (new)
211 list_add(&new->list, &sdata->key_list); 235 list_add(&new->list, &sdata->key_list);
212 236
213 if (sta) { 237 if (sta && pairwise) {
214 rcu_assign_pointer(sta->key, new); 238 rcu_assign_pointer(sta->ptk, new);
239 } else if (sta) {
240 if (old)
241 idx = old->conf.keyidx;
242 else
243 idx = new->conf.keyidx;
244 rcu_assign_pointer(sta->gtk[idx], new);
215 } else { 245 } else {
216 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); 246 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
217 247
@@ -355,6 +385,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
355{ 385{
356 struct ieee80211_key *old_key; 386 struct ieee80211_key *old_key;
357 int idx, ret; 387 int idx, ret;
388 bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
358 389
359 BUG_ON(!sdata); 390 BUG_ON(!sdata);
360 BUG_ON(!key); 391 BUG_ON(!key);
@@ -371,13 +402,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
371 */ 402 */
372 if (test_sta_flags(sta, WLAN_STA_WME)) 403 if (test_sta_flags(sta, WLAN_STA_WME))
373 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 404 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
374
375 /*
376 * This key is for a specific sta interface,
377 * inform the driver that it should try to store
378 * this key as pairwise key.
379 */
380 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
381 } else { 405 } else {
382 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 406 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
383 struct sta_info *ap; 407 struct sta_info *ap;
@@ -399,12 +423,14 @@ int ieee80211_key_link(struct ieee80211_key *key,
399 423
400 mutex_lock(&sdata->local->key_mtx); 424 mutex_lock(&sdata->local->key_mtx);
401 425
402 if (sta) 426 if (sta && pairwise)
403 old_key = sta->key; 427 old_key = sta->ptk;
428 else if (sta)
429 old_key = sta->gtk[idx];
404 else 430 else
405 old_key = sdata->keys[idx]; 431 old_key = sdata->keys[idx];
406 432
407 __ieee80211_key_replace(sdata, sta, old_key, key); 433 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
408 __ieee80211_key_destroy(old_key); 434 __ieee80211_key_destroy(old_key);
409 435
410 ieee80211_debugfs_key_add(key); 436 ieee80211_debugfs_key_add(key);
@@ -423,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
423 */ 449 */
424 if (key->sdata) 450 if (key->sdata)
425 __ieee80211_key_replace(key->sdata, key->sta, 451 __ieee80211_key_replace(key->sdata, key->sta,
426 key, NULL); 452 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
453 key, NULL);
427 __ieee80211_key_destroy(key); 454 __ieee80211_key_destroy(key);
428} 455}
429 456
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index cb9a4a65cc68..0db1c0f5f697 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -16,6 +16,9 @@
16#include <linux/rcupdate.h> 16#include <linux/rcupdate.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18 18
19#define NUM_DEFAULT_KEYS 4
20#define NUM_DEFAULT_MGMT_KEYS 2
21
19#define WEP_IV_LEN 4 22#define WEP_IV_LEN 4
20#define WEP_ICV_LEN 4 23#define WEP_ICV_LEN 4
21#define ALG_TKIP_KEY_LEN 32 24#define ALG_TKIP_KEY_LEN 32
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index db341a99c7c7..eb0f59977676 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -201,6 +201,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
201 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 201 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
202 else if (sdata->vif.type == NL80211_IFTYPE_AP) 202 else if (sdata->vif.type == NL80211_IFTYPE_AP)
203 sdata->vif.bss_conf.bssid = sdata->vif.addr; 203 sdata->vif.bss_conf.bssid = sdata->vif.addr;
204 else if (sdata->vif.type == NL80211_IFTYPE_WDS)
205 sdata->vif.bss_conf.bssid = NULL;
204 else if (ieee80211_vif_is_mesh(&sdata->vif)) { 206 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
205 sdata->vif.bss_conf.bssid = zero; 207 sdata->vif.bss_conf.bssid = zero;
206 } else { 208 } else {
@@ -211,6 +213,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
211 switch (sdata->vif.type) { 213 switch (sdata->vif.type) {
212 case NL80211_IFTYPE_AP: 214 case NL80211_IFTYPE_AP:
213 case NL80211_IFTYPE_ADHOC: 215 case NL80211_IFTYPE_ADHOC:
216 case NL80211_IFTYPE_WDS:
214 case NL80211_IFTYPE_MESH_POINT: 217 case NL80211_IFTYPE_MESH_POINT:
215 break; 218 break;
216 default: 219 default:
@@ -295,7 +298,16 @@ static void ieee80211_restart_work(struct work_struct *work)
295 struct ieee80211_local *local = 298 struct ieee80211_local *local =
296 container_of(work, struct ieee80211_local, restart_work); 299 container_of(work, struct ieee80211_local, restart_work);
297 300
301 /* wait for scan work complete */
302 flush_workqueue(local->workqueue);
303
304 mutex_lock(&local->mtx);
305 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
306 "%s called with hardware scan in progress\n", __func__);
307 mutex_unlock(&local->mtx);
308
298 rtnl_lock(); 309 rtnl_lock();
310 ieee80211_scan_cancel(local);
299 ieee80211_reconfig(local); 311 ieee80211_reconfig(local);
300 rtnl_unlock(); 312 rtnl_unlock();
301} 313}
@@ -306,15 +318,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
306 318
307 trace_api_restart_hw(local); 319 trace_api_restart_hw(local);
308 320
309 /* wait for scan work complete */
310 flush_workqueue(local->workqueue);
311
312 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
313 "%s called with hardware scan in progress\n", __func__);
314
315 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
316 ieee80211_scan_cancel(local);
317
318 /* use this reason, ieee80211_reconfig will unblock it */ 321 /* use this reason, ieee80211_reconfig will unblock it */
319 ieee80211_stop_queues_by_reason(hw, 322 ieee80211_stop_queues_by_reason(hw,
320 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 323 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -329,7 +332,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
329 container_of(work, struct ieee80211_local, recalc_smps); 332 container_of(work, struct ieee80211_local, recalc_smps);
330 333
331 mutex_lock(&local->iflist_mtx); 334 mutex_lock(&local->iflist_mtx);
332 ieee80211_recalc_smps(local, NULL); 335 ieee80211_recalc_smps(local);
333 mutex_unlock(&local->iflist_mtx); 336 mutex_unlock(&local->iflist_mtx);
334} 337}
335 338
@@ -533,6 +536,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
533 /* set up some defaults */ 536 /* set up some defaults */
534 local->hw.queues = 1; 537 local->hw.queues = 1;
535 local->hw.max_rates = 1; 538 local->hw.max_rates = 1;
539 local->hw.max_report_rates = 0;
536 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 540 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
537 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 541 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
538 local->user_power_level = -1; 542 local->user_power_level = -1;
@@ -608,6 +612,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
608 WLAN_CIPHER_SUITE_AES_CMAC 612 WLAN_CIPHER_SUITE_AES_CMAC
609 }; 613 };
610 614
615 if (hw->max_report_rates == 0)
616 hw->max_report_rates = hw->max_rates;
617
611 /* 618 /*
612 * generic code guarantees at least one band, 619 * generic code guarantees at least one band,
613 * set this very early because much code assumes 620 * set this very early because much code assumes
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 77913a15f537..5695c94c49aa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -913,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
913 913
914 mutex_lock(&local->iflist_mtx); 914 mutex_lock(&local->iflist_mtx);
915 ieee80211_recalc_ps(local, -1); 915 ieee80211_recalc_ps(local, -1);
916 ieee80211_recalc_smps(local, sdata); 916 ieee80211_recalc_smps(local);
917 mutex_unlock(&local->iflist_mtx); 917 mutex_unlock(&local->iflist_mtx);
918 918
919 netif_tx_start_all_queues(sdata->dev); 919 netif_tx_start_all_queues(sdata->dev);
@@ -921,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
921} 921}
922 922
923static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 923static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
924 bool remove_sta) 924 bool remove_sta, bool tx)
925{ 925{
926 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 926 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
927 struct ieee80211_local *local = sdata->local; 927 struct ieee80211_local *local = sdata->local;
@@ -960,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
960 sta = sta_info_get(sdata, bssid); 960 sta = sta_info_get(sdata, bssid);
961 if (sta) { 961 if (sta) {
962 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 962 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
963 ieee80211_sta_tear_down_BA_sessions(sta); 963 ieee80211_sta_tear_down_BA_sessions(sta, tx);
964 } 964 }
965 mutex_unlock(&local->sta_mtx); 965 mutex_unlock(&local->sta_mtx);
966 966
@@ -1124,7 +1124,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
1124 1124
1125 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 1125 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
1126 1126
1127 ieee80211_set_disassoc(sdata, true); 1127 ieee80211_set_disassoc(sdata, true, true);
1128 mutex_unlock(&ifmgd->mtx); 1128 mutex_unlock(&ifmgd->mtx);
1129 1129
1130 mutex_lock(&local->mtx); 1130 mutex_lock(&local->mtx);
@@ -1197,7 +1197,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1197 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1197 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1198 sdata->name, bssid, reason_code); 1198 sdata->name, bssid, reason_code);
1199 1199
1200 ieee80211_set_disassoc(sdata, true); 1200 ieee80211_set_disassoc(sdata, true, false);
1201 mutex_lock(&sdata->local->mtx); 1201 mutex_lock(&sdata->local->mtx);
1202 ieee80211_recalc_idle(sdata->local); 1202 ieee80211_recalc_idle(sdata->local);
1203 mutex_unlock(&sdata->local->mtx); 1203 mutex_unlock(&sdata->local->mtx);
@@ -1229,7 +1229,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1229 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1229 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1230 sdata->name, mgmt->sa, reason_code); 1230 sdata->name, mgmt->sa, reason_code);
1231 1231
1232 ieee80211_set_disassoc(sdata, true); 1232 ieee80211_set_disassoc(sdata, true, false);
1233 mutex_lock(&sdata->local->mtx); 1233 mutex_lock(&sdata->local->mtx);
1234 ieee80211_recalc_idle(sdata->local); 1234 ieee80211_recalc_idle(sdata->local);
1235 mutex_unlock(&sdata->local->mtx); 1235 mutex_unlock(&sdata->local->mtx);
@@ -1291,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1291 1291
1292 rates = 0; 1292 rates = 0;
1293 basic_rates = 0; 1293 basic_rates = 0;
1294 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1294 sband = local->hw.wiphy->bands[wk->chan->band];
1295 1295
1296 for (i = 0; i < elems.supp_rates_len; i++) { 1296 for (i = 0; i < elems.supp_rates_len; i++) {
1297 int rate = (elems.supp_rates[i] & 0x7f) * 5; 1297 int rate = (elems.supp_rates[i] & 0x7f) * 5;
@@ -1327,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1327 } 1327 }
1328 } 1328 }
1329 1329
1330 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 1330 sta->sta.supp_rates[wk->chan->band] = rates;
1331 sdata->vif.bss_conf.basic_rates = basic_rates; 1331 sdata->vif.bss_conf.basic_rates = basic_rates;
1332 1332
1333 /* cf. IEEE 802.11 9.2.12 */ 1333 /* cf. IEEE 802.11 9.2.12 */
1334 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 1334 if (wk->chan->band == IEEE80211_BAND_2GHZ &&
1335 have_higher_than_11mbit) 1335 have_higher_than_11mbit)
1336 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 1336 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1337 else 1337 else
@@ -1639,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1639 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, 1639 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
1640 ifmgd->aid); 1640 ifmgd->aid);
1641 1641
1642 if (ncrc != ifmgd->beacon_crc) { 1642 if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
1643 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, 1643 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
1644 true); 1644 true);
1645 1645
@@ -1670,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1670 } 1670 }
1671 } 1671 }
1672 1672
1673 if (ncrc == ifmgd->beacon_crc) 1673 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
1674 return; 1674 return;
1675 ifmgd->beacon_crc = ncrc; 1675 ifmgd->beacon_crc = ncrc;
1676 ifmgd->beacon_crc_valid = true;
1676 1677
1677 if (elems.erp_info && elems.erp_info_len >= 1) { 1678 if (elems.erp_info && elems.erp_info_len >= 1) {
1678 erp_valid = true; 1679 erp_valid = true;
@@ -1879,7 +1880,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1879 printk(KERN_DEBUG "No probe response from AP %pM" 1880 printk(KERN_DEBUG "No probe response from AP %pM"
1880 " after %dms, disconnecting.\n", 1881 " after %dms, disconnecting.\n",
1881 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1882 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1882 ieee80211_set_disassoc(sdata, true); 1883 ieee80211_set_disassoc(sdata, true, true);
1883 mutex_unlock(&ifmgd->mtx); 1884 mutex_unlock(&ifmgd->mtx);
1884 mutex_lock(&local->mtx); 1885 mutex_lock(&local->mtx);
1885 ieee80211_recalc_idle(local); 1886 ieee80211_recalc_idle(local);
@@ -2203,7 +2204,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2203 } 2204 }
2204 2205
2205 /* Trying to reassociate - clear previous association state */ 2206 /* Trying to reassociate - clear previous association state */
2206 ieee80211_set_disassoc(sdata, true); 2207 ieee80211_set_disassoc(sdata, true, false);
2207 } 2208 }
2208 mutex_unlock(&ifmgd->mtx); 2209 mutex_unlock(&ifmgd->mtx);
2209 2210
@@ -2214,6 +2215,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2214 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 2215 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2215 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 2216 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2216 2217
2218 ifmgd->beacon_crc_valid = false;
2219
2217 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 2220 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
2218 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 2221 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
2219 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 2222 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
@@ -2315,7 +2318,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2315 2318
2316 memcpy(bssid, req->bss->bssid, ETH_ALEN); 2319 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2317 if (ifmgd->associated == req->bss) { 2320 if (ifmgd->associated == req->bss) {
2318 ieee80211_set_disassoc(sdata, false); 2321 ieee80211_set_disassoc(sdata, false, true);
2319 mutex_unlock(&ifmgd->mtx); 2322 mutex_unlock(&ifmgd->mtx);
2320 assoc_bss = true; 2323 assoc_bss = true;
2321 } else { 2324 } else {
@@ -2398,7 +2401,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2398 sdata->name, req->bss->bssid, req->reason_code); 2401 sdata->name, req->bss->bssid, req->reason_code);
2399 2402
2400 memcpy(bssid, req->bss->bssid, ETH_ALEN); 2403 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2401 ieee80211_set_disassoc(sdata, false); 2404 ieee80211_set_disassoc(sdata, false, true);
2402 2405
2403 mutex_unlock(&ifmgd->mtx); 2406 mutex_unlock(&ifmgd->mtx);
2404 2407
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index ce671dfd238c..e37355193ed1 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -12,8 +12,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
13 struct sta_info *sta; 13 struct sta_info *sta;
14 14
15 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) 15 ieee80211_scan_cancel(local);
16 ieee80211_scan_cancel(local);
17 16
18 ieee80211_stop_queues_by_reason(hw, 17 ieee80211_stop_queues_by_reason(hw,
19 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 18 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -46,7 +45,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
46 list_for_each_entry(sta, &local->sta_list, list) { 45 list_for_each_entry(sta, &local->sta_list, list) {
47 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 46 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
48 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 47 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
49 ieee80211_sta_tear_down_BA_sessions(sta); 48 ieee80211_sta_tear_down_BA_sessions(sta, true);
50 } 49 }
51 50
52 if (sta->uploaded) { 51 if (sta->uploaded) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 0b0e83ebe3d5..b67221def584 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -819,6 +819,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
819 if (unlikely((ieee80211_is_data(hdr->frame_control) || 819 if (unlikely((ieee80211_is_data(hdr->frame_control) ||
820 ieee80211_is_pspoll(hdr->frame_control)) && 820 ieee80211_is_pspoll(hdr->frame_control)) &&
821 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 821 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
822 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
822 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { 823 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
823 if ((!ieee80211_has_fromds(hdr->frame_control) && 824 if ((!ieee80211_has_fromds(hdr->frame_control) &&
824 !ieee80211_has_tods(hdr->frame_control) && 825 !ieee80211_has_tods(hdr->frame_control) &&
@@ -845,7 +846,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
845 int keyidx; 846 int keyidx;
846 int hdrlen; 847 int hdrlen;
847 ieee80211_rx_result result = RX_DROP_UNUSABLE; 848 ieee80211_rx_result result = RX_DROP_UNUSABLE;
848 struct ieee80211_key *stakey = NULL; 849 struct ieee80211_key *sta_ptk = NULL;
849 int mmie_keyidx = -1; 850 int mmie_keyidx = -1;
850 __le16 fc; 851 __le16 fc;
851 852
@@ -887,15 +888,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
887 rx->key = NULL; 888 rx->key = NULL;
888 889
889 if (rx->sta) 890 if (rx->sta)
890 stakey = rcu_dereference(rx->sta->key); 891 sta_ptk = rcu_dereference(rx->sta->ptk);
891 892
892 fc = hdr->frame_control; 893 fc = hdr->frame_control;
893 894
894 if (!ieee80211_has_protected(fc)) 895 if (!ieee80211_has_protected(fc))
895 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 896 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
896 897
897 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 898 if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
898 rx->key = stakey; 899 rx->key = sta_ptk;
899 if ((status->flag & RX_FLAG_DECRYPTED) && 900 if ((status->flag & RX_FLAG_DECRYPTED) &&
900 (status->flag & RX_FLAG_IV_STRIPPED)) 901 (status->flag & RX_FLAG_IV_STRIPPED))
901 return RX_CONTINUE; 902 return RX_CONTINUE;
@@ -911,7 +912,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
911 if (mmie_keyidx < NUM_DEFAULT_KEYS || 912 if (mmie_keyidx < NUM_DEFAULT_KEYS ||
912 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 913 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
913 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 914 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
914 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 915 if (rx->sta)
916 rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
917 if (!rx->key)
918 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
915 } else if (!ieee80211_has_protected(fc)) { 919 } else if (!ieee80211_has_protected(fc)) {
916 /* 920 /*
917 * The frame was not protected, so skip decryption. However, we 921 * The frame was not protected, so skip decryption. However, we
@@ -954,17 +958,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
954 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 958 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
955 keyidx = keyid >> 6; 959 keyidx = keyid >> 6;
956 960
957 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 961 /* check per-station GTK first, if multicast packet */
962 if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
963 rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
958 964
959 /* 965 /* if not found, try default key */
960 * RSNA-protected unicast frames should always be sent with 966 if (!rx->key) {
961 * pairwise or station-to-station keys, but for WEP we allow 967 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
962 * using a key index as well. 968
963 */ 969 /*
964 if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && 970 * RSNA-protected unicast frames should always be
965 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && 971 * sent with pairwise or station-to-station keys,
966 !is_multicast_ether_addr(hdr->addr1)) 972 * but for WEP we allow using a key index as well.
967 rx->key = NULL; 973 */
974 if (rx->key &&
975 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
976 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
977 !is_multicast_ether_addr(hdr->addr1))
978 rx->key = NULL;
979 }
968 } 980 }
969 981
970 if (rx->key) { 982 if (rx->key) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 5171a9581631..fb274db77e3c 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -249,12 +249,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
249 return true; 249 return true;
250} 250}
251 251
252static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 252static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
253 bool was_hw_scan)
253{ 254{
254 struct ieee80211_local *local = hw_to_local(hw); 255 struct ieee80211_local *local = hw_to_local(hw);
255 bool was_hw_scan;
256 256
257 mutex_lock(&local->mtx); 257 lockdep_assert_held(&local->mtx);
258 258
259 /* 259 /*
260 * It's ok to abort a not-yet-running scan (that 260 * It's ok to abort a not-yet-running scan (that
@@ -265,17 +265,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
265 if (WARN_ON(!local->scanning && !aborted)) 265 if (WARN_ON(!local->scanning && !aborted))
266 aborted = true; 266 aborted = true;
267 267
268 if (WARN_ON(!local->scan_req)) { 268 if (WARN_ON(!local->scan_req))
269 mutex_unlock(&local->mtx); 269 return false;
270 return;
271 }
272 270
273 was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
274 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { 271 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
275 ieee80211_queue_delayed_work(&local->hw, 272 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
276 &local->scan_work, 0); 273 if (rc == 0)
277 mutex_unlock(&local->mtx); 274 return false;
278 return;
279 } 275 }
280 276
281 kfree(local->hw_scan_req); 277 kfree(local->hw_scan_req);
@@ -289,23 +285,25 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
289 local->scanning = 0; 285 local->scanning = 0;
290 local->scan_channel = NULL; 286 local->scan_channel = NULL;
291 287
292 /* we only have to protect scan_req and hw/sw scan */ 288 return true;
293 mutex_unlock(&local->mtx); 289}
294
295 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
296 if (was_hw_scan)
297 goto done;
298
299 ieee80211_configure_filter(local);
300 290
301 drv_sw_scan_complete(local); 291static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
292 bool was_hw_scan)
293{
294 struct ieee80211_local *local = hw_to_local(hw);
302 295
303 ieee80211_offchannel_return(local, true); 296 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
297 if (!was_hw_scan) {
298 ieee80211_configure_filter(local);
299 drv_sw_scan_complete(local);
300 ieee80211_offchannel_return(local, true);
301 }
304 302
305 done:
306 mutex_lock(&local->mtx); 303 mutex_lock(&local->mtx);
307 ieee80211_recalc_idle(local); 304 ieee80211_recalc_idle(local);
308 mutex_unlock(&local->mtx); 305 mutex_unlock(&local->mtx);
306
309 ieee80211_mlme_notify_scan_completed(local); 307 ieee80211_mlme_notify_scan_completed(local);
310 ieee80211_ibss_notify_scan_completed(local); 308 ieee80211_ibss_notify_scan_completed(local);
311 ieee80211_mesh_notify_scan_completed(local); 309 ieee80211_mesh_notify_scan_completed(local);
@@ -366,6 +364,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
366 struct ieee80211_local *local = sdata->local; 364 struct ieee80211_local *local = sdata->local;
367 int rc; 365 int rc;
368 366
367 lockdep_assert_held(&local->mtx);
368
369 if (local->scan_req) 369 if (local->scan_req)
370 return -EBUSY; 370 return -EBUSY;
371 371
@@ -447,8 +447,8 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
447 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; 447 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
448} 448}
449 449
450static int ieee80211_scan_state_decision(struct ieee80211_local *local, 450static void ieee80211_scan_state_decision(struct ieee80211_local *local,
451 unsigned long *next_delay) 451 unsigned long *next_delay)
452{ 452{
453 bool associated = false; 453 bool associated = false;
454 bool tx_empty = true; 454 bool tx_empty = true;
@@ -458,12 +458,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
458 struct ieee80211_sub_if_data *sdata; 458 struct ieee80211_sub_if_data *sdata;
459 struct ieee80211_channel *next_chan; 459 struct ieee80211_channel *next_chan;
460 460
461 /* if no more bands/channels left, complete scan and advance to the idle state */
462 if (local->scan_channel_idx >= local->scan_req->n_channels) {
463 __ieee80211_scan_completed(&local->hw, false);
464 return 1;
465 }
466
467 /* 461 /*
468 * check if at least one STA interface is associated, 462 * check if at least one STA interface is associated,
469 * check if at least one STA interface has pending tx frames 463 * check if at least one STA interface has pending tx frames
@@ -535,7 +529,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
535 } 529 }
536 530
537 *next_delay = 0; 531 *next_delay = 0;
538 return 0;
539} 532}
540 533
541static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 534static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
@@ -651,28 +644,17 @@ void ieee80211_scan_work(struct work_struct *work)
651 container_of(work, struct ieee80211_local, scan_work.work); 644 container_of(work, struct ieee80211_local, scan_work.work);
652 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 645 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
653 unsigned long next_delay = 0; 646 unsigned long next_delay = 0;
647 bool aborted, hw_scan, finish;
654 648
655 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { 649 mutex_lock(&local->mtx);
656 bool aborted;
657 650
651 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
658 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); 652 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
659 __ieee80211_scan_completed(&local->hw, aborted); 653 goto out_complete;
660 return;
661 }
662
663 mutex_lock(&local->mtx);
664 if (!sdata || !local->scan_req) {
665 mutex_unlock(&local->mtx);
666 return;
667 } 654 }
668 655
669 if (local->hw_scan_req) { 656 if (!sdata || !local->scan_req)
670 int rc = drv_hw_scan(local, sdata, local->hw_scan_req); 657 goto out;
671 mutex_unlock(&local->mtx);
672 if (rc)
673 __ieee80211_scan_completed(&local->hw, true);
674 return;
675 }
676 658
677 if (local->scan_req && !local->scanning) { 659 if (local->scan_req && !local->scanning) {
678 struct cfg80211_scan_request *req = local->scan_req; 660 struct cfg80211_scan_request *req = local->scan_req;
@@ -682,21 +664,21 @@ void ieee80211_scan_work(struct work_struct *work)
682 local->scan_sdata = NULL; 664 local->scan_sdata = NULL;
683 665
684 rc = __ieee80211_start_scan(sdata, req); 666 rc = __ieee80211_start_scan(sdata, req);
685 mutex_unlock(&local->mtx); 667 if (rc) {
686 668 /* need to complete scan in cfg80211 */
687 if (rc) 669 local->scan_req = req;
688 __ieee80211_scan_completed(&local->hw, true); 670 aborted = true;
689 return; 671 goto out_complete;
672 } else
673 goto out;
690 } 674 }
691 675
692 mutex_unlock(&local->mtx);
693
694 /* 676 /*
695 * Avoid re-scheduling when the sdata is going away. 677 * Avoid re-scheduling when the sdata is going away.
696 */ 678 */
697 if (!ieee80211_sdata_running(sdata)) { 679 if (!ieee80211_sdata_running(sdata)) {
698 __ieee80211_scan_completed(&local->hw, true); 680 aborted = true;
699 return; 681 goto out_complete;
700 } 682 }
701 683
702 /* 684 /*
@@ -706,8 +688,12 @@ void ieee80211_scan_work(struct work_struct *work)
706 do { 688 do {
707 switch (local->next_scan_state) { 689 switch (local->next_scan_state) {
708 case SCAN_DECISION: 690 case SCAN_DECISION:
709 if (ieee80211_scan_state_decision(local, &next_delay)) 691 /* if no more bands/channels left, complete scan */
710 return; 692 if (local->scan_channel_idx >= local->scan_req->n_channels) {
693 aborted = false;
694 goto out_complete;
695 }
696 ieee80211_scan_state_decision(local, &next_delay);
711 break; 697 break;
712 case SCAN_SET_CHANNEL: 698 case SCAN_SET_CHANNEL:
713 ieee80211_scan_state_set_channel(local, &next_delay); 699 ieee80211_scan_state_set_channel(local, &next_delay);
@@ -725,6 +711,19 @@ void ieee80211_scan_work(struct work_struct *work)
725 } while (next_delay == 0); 711 } while (next_delay == 0);
726 712
727 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); 713 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
714 mutex_unlock(&local->mtx);
715 return;
716
717out_complete:
718 hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
719 finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
720 mutex_unlock(&local->mtx);
721 if (finish)
722 __ieee80211_scan_completed_finish(&local->hw, hw_scan);
723 return;
724
725out:
726 mutex_unlock(&local->mtx);
728} 727}
729 728
730int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 729int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
@@ -786,21 +785,40 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
786 return ret; 785 return ret;
787} 786}
788 787
788/*
789 * Only call this function when a scan can't be queued -- under RTNL.
790 */
789void ieee80211_scan_cancel(struct ieee80211_local *local) 791void ieee80211_scan_cancel(struct ieee80211_local *local)
790{ 792{
791 bool abortscan; 793 bool abortscan;
792 794 bool finish = false;
793 cancel_delayed_work_sync(&local->scan_work);
794 795
795 /* 796 /*
796 * Only call this function when a scan can't be 797 * We are only canceling software scan, or deferred scan that was not
797 * queued -- mostly at suspend under RTNL. 798 * yet really started (see __ieee80211_start_scan ).
799 *
800 * Regarding hardware scan:
801 * - we can not call __ieee80211_scan_completed() as when
802 * SCAN_HW_SCANNING bit is set this function change
803 * local->hw_scan_req to operate on 5G band, what race with
804 * driver which can use local->hw_scan_req
805 *
806 * - we can not cancel scan_work since driver can schedule it
807 * by ieee80211_scan_completed(..., true) to finish scan
808 *
809 * Hence low lever driver is responsible for canceling HW scan.
798 */ 810 */
811
799 mutex_lock(&local->mtx); 812 mutex_lock(&local->mtx);
800 abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || 813 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
801 (!local->scanning && local->scan_req); 814 if (abortscan)
815 finish = __ieee80211_scan_completed(&local->hw, true, false);
802 mutex_unlock(&local->mtx); 816 mutex_unlock(&local->mtx);
803 817
804 if (abortscan) 818 if (abortscan) {
805 __ieee80211_scan_completed(&local->hw, true); 819 /* The scan is canceled, but stop work from being pending */
820 cancel_delayed_work_sync(&local->scan_work);
821 }
822 if (finish)
823 __ieee80211_scan_completed_finish(&local->hw, false);
806} 824}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ca2cba9cea87..6d8f897d8763 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -616,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
616 struct ieee80211_sub_if_data *sdata; 616 struct ieee80211_sub_if_data *sdata;
617 struct sk_buff *skb; 617 struct sk_buff *skb;
618 unsigned long flags; 618 unsigned long flags;
619 int ret; 619 int ret, i;
620 620
621 might_sleep(); 621 might_sleep();
622 622
@@ -633,7 +633,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
633 * will be sufficient. 633 * will be sufficient.
634 */ 634 */
635 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 635 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
636 ieee80211_sta_tear_down_BA_sessions(sta); 636 ieee80211_sta_tear_down_BA_sessions(sta, true);
637 637
638 spin_lock_irqsave(&local->sta_lock, flags); 638 spin_lock_irqsave(&local->sta_lock, flags);
639 ret = sta_info_hash_del(local, sta); 639 ret = sta_info_hash_del(local, sta);
@@ -644,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
644 if (ret) 644 if (ret)
645 return ret; 645 return ret;
646 646
647 if (sta->key) { 647 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
648 ieee80211_key_free(local, sta->key); 648 ieee80211_key_free(local, sta->gtk[i]);
649 WARN_ON(sta->key); 649 if (sta->ptk)
650 } 650 ieee80211_key_free(local, sta->ptk);
651 651
652 sta->dead = true; 652 sta->dead = true;
653 653
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 810c5ce98316..9265acadef32 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -79,6 +79,7 @@ enum ieee80211_sta_info_flags {
79 * @dialog_token: dialog token for aggregation session 79 * @dialog_token: dialog token for aggregation session
80 * @state: session state (see above) 80 * @state: session state (see above)
81 * @stop_initiator: initiator of a session stop 81 * @stop_initiator: initiator of a session stop
82 * @tx_stop: TX DelBA frame when stopping
82 * 83 *
83 * This structure is protected by RCU and the per-station 84 * This structure is protected by RCU and the per-station
84 * spinlock. Assignments to the array holding it must hold 85 * spinlock. Assignments to the array holding it must hold
@@ -95,6 +96,7 @@ struct tid_ampdu_tx {
95 unsigned long state; 96 unsigned long state;
96 u8 dialog_token; 97 u8 dialog_token;
97 u8 stop_initiator; 98 u8 stop_initiator;
99 bool tx_stop;
98}; 100};
99 101
100/** 102/**
@@ -197,7 +199,8 @@ enum plink_state {
197 * @hnext: hash table linked list pointer 199 * @hnext: hash table linked list pointer
198 * @local: pointer to the global information 200 * @local: pointer to the global information
199 * @sdata: virtual interface this station belongs to 201 * @sdata: virtual interface this station belongs to
200 * @key: peer key negotiated with this station, if any 202 * @ptk: peer key negotiated with this station, if any
203 * @gtk: group keys negotiated with this station, if any
201 * @rate_ctrl: rate control algorithm reference 204 * @rate_ctrl: rate control algorithm reference
202 * @rate_ctrl_priv: rate control private per-STA pointer 205 * @rate_ctrl_priv: rate control private per-STA pointer
203 * @last_tx_rate: rate used for last transmit, to report to userspace as 206 * @last_tx_rate: rate used for last transmit, to report to userspace as
@@ -252,7 +255,8 @@ struct sta_info {
252 struct sta_info *hnext; 255 struct sta_info *hnext;
253 struct ieee80211_local *local; 256 struct ieee80211_local *local;
254 struct ieee80211_sub_if_data *sdata; 257 struct ieee80211_sub_if_data *sdata;
255 struct ieee80211_key *key; 258 struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
259 struct ieee80211_key *ptk;
256 struct rate_control_ref *rate_ctrl; 260 struct rate_control_ref *rate_ctrl;
257 void *rate_ctrl_priv; 261 void *rate_ctrl_priv;
258 spinlock_t lock; 262 spinlock_t lock;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index dd85006c4fe8..3153c19893b8 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -176,7 +176,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
176 176
177 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 177 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
178 /* the HW cannot have attempted that rate */ 178 /* the HW cannot have attempted that rate */
179 if (i >= hw->max_rates) { 179 if (i >= hw->max_report_rates) {
180 info->status.rates[i].idx = -1; 180 info->status.rates[i].idx = -1;
181 info->status.rates[i].count = 0; 181 info->status.rates[i].count = 0;
182 } else if (info->status.rates[i].idx >= 0) { 182 } else if (info->status.rates[i].idx >= 0) {
@@ -377,7 +377,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
377 skb2 = skb_clone(skb, GFP_ATOMIC); 377 skb2 = skb_clone(skb, GFP_ATOMIC);
378 if (skb2) { 378 if (skb2) {
379 skb2->dev = prev_dev; 379 skb2->dev = prev_dev;
380 netif_receive_skb(skb2); 380 netif_rx(skb2);
381 } 381 }
382 } 382 }
383 383
@@ -386,7 +386,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
386 } 386 }
387 if (prev_dev) { 387 if (prev_dev) {
388 skb->dev = prev_dev; 388 skb->dev = prev_dev;
389 netif_receive_skb(skb); 389 netif_rx(skb);
390 skb = NULL; 390 skb = NULL;
391 } 391 }
392 rcu_read_unlock(); 392 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e1733dcb58a7..96c594309506 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -273,6 +273,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
273 */ 273 */
274 return TX_DROP; 274 return TX_DROP;
275 275
276 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
277 return TX_CONTINUE;
278
276 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 279 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
277 return TX_CONTINUE; 280 return TX_CONTINUE;
278 281
@@ -529,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
529 532
530 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) 533 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
531 tx->key = NULL; 534 tx->key = NULL;
532 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 535 else if (tx->sta && (key = rcu_dereference(tx->sta->ptk)))
533 tx->key = key; 536 tx->key = key;
534 else if (ieee80211_is_mgmt(hdr->frame_control) && 537 else if (ieee80211_is_mgmt(hdr->frame_control) &&
535 is_multicast_ether_addr(hdr->addr1) && 538 is_multicast_ether_addr(hdr->addr1) &&
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index aba025d748e9..0b6fc92bc0d7 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1221,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1221 mutex_lock(&local->sta_mtx); 1221 mutex_lock(&local->sta_mtx);
1222 1222
1223 list_for_each_entry(sta, &local->sta_list, list) { 1223 list_for_each_entry(sta, &local->sta_list, list) {
1224 ieee80211_sta_tear_down_BA_sessions(sta); 1224 ieee80211_sta_tear_down_BA_sessions(sta, true);
1225 clear_sta_flags(sta, WLAN_STA_BLOCK_BA); 1225 clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
1226 } 1226 }
1227 1227
@@ -1297,16 +1297,12 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1297} 1297}
1298 1298
1299/* must hold iflist_mtx */ 1299/* must hold iflist_mtx */
1300void ieee80211_recalc_smps(struct ieee80211_local *local, 1300void ieee80211_recalc_smps(struct ieee80211_local *local)
1301 struct ieee80211_sub_if_data *forsdata)
1302{ 1301{
1303 struct ieee80211_sub_if_data *sdata; 1302 struct ieee80211_sub_if_data *sdata;
1304 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; 1303 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
1305 int count = 0; 1304 int count = 0;
1306 1305
1307 if (forsdata)
1308 lockdep_assert_held(&forsdata->u.mgd.mtx);
1309
1310 lockdep_assert_held(&local->iflist_mtx); 1306 lockdep_assert_held(&local->iflist_mtx);
1311 1307
1312 /* 1308 /*
@@ -1324,18 +1320,8 @@ void ieee80211_recalc_smps(struct ieee80211_local *local,
1324 continue; 1320 continue;
1325 if (sdata->vif.type != NL80211_IFTYPE_STATION) 1321 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1326 goto set; 1322 goto set;
1327 if (sdata != forsdata) { 1323
1328 /* 1324 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1329 * This nested is ok -- we are holding the iflist_mtx
1330 * so can't get here twice or so. But it's required
1331 * since normally we acquire it first and then the
1332 * iflist_mtx.
1333 */
1334 mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING);
1335 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1336 mutex_unlock(&sdata->u.mgd.mtx);
1337 } else
1338 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1339 1325
1340 if (count > 1) { 1326 if (count > 1) {
1341 smps_mode = IEEE80211_SMPS_OFF; 1327 smps_mode = IEEE80211_SMPS_OFF;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 26ed3e8587c2..1781d99145e2 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
547 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 547 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
548 info.attrs = family->attrbuf; 548 info.attrs = family->attrbuf;
549 genl_info_net_set(&info, net); 549 genl_info_net_set(&info, net);
550 memset(&info.user_ptr, 0, sizeof(info.user_ptr));
550 551
551 return ops->doit(skb, &info); 552 if (family->pre_doit) {
553 err = family->pre_doit(ops, skb, &info);
554 if (err)
555 return err;
556 }
557
558 err = ops->doit(skb, &info);
559
560 if (family->post_doit)
561 family->post_doit(ops, skb, &info);
562
563 return err;
552} 564}
553 565
554static void genl_rcv(struct sk_buff *skb) 566static void genl_rcv(struct sk_buff *skb)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 9c21ebf9780e..1684ad91763c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,26 +178,10 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
178 char *newname) 178 char *newname)
179{ 179{
180 struct cfg80211_registered_device *rdev2; 180 struct cfg80211_registered_device *rdev2;
181 int wiphy_idx, taken = -1, result, digits; 181 int result;
182 182
183 assert_cfg80211_lock(); 183 assert_cfg80211_lock();
184 184
185 /* prohibit calling the thing phy%d when %d is not its number */
186 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
187 if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
188 /* count number of places needed to print wiphy_idx */
189 digits = 1;
190 while (wiphy_idx /= 10)
191 digits++;
192 /*
193 * deny the name if it is phy<idx> where <idx> is printed
194 * without leading zeroes. taken == strlen(newname) here
195 */
196 if (taken == strlen(PHY_NAME) + digits)
197 return -EINVAL;
198 }
199
200
201 /* Ignore nop renames */ 185 /* Ignore nop renames */
202 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 186 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
203 return 0; 187 return 0;
@@ -205,7 +189,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
205 /* Ensure another device does not already have this name. */ 189 /* Ensure another device does not already have this name. */
206 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 190 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
207 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 191 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
208 return -EINVAL; 192 return -EEXIST;
209 193
210 result = device_rename(&rdev->wiphy.dev, newname); 194 result = device_rename(&rdev->wiphy.dev, newname);
211 if (result) 195 if (result)
@@ -320,9 +304,11 @@ static void cfg80211_event_work(struct work_struct *work)
320struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 304struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
321{ 305{
322 static int wiphy_counter; 306 static int wiphy_counter;
323 307 int i;
324 struct cfg80211_registered_device *rdev; 308 struct cfg80211_registered_device *rdev, *rdev2;
325 int alloc_size; 309 int alloc_size;
310 char nname[IFNAMSIZ + 1];
311 bool found = false;
326 312
327 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); 313 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
328 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); 314 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -346,16 +332,36 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
346 332
347 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { 333 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
348 wiphy_counter--; 334 wiphy_counter--;
335 goto too_many_devs;
336 }
337
338 /* 64k wiphy devices is enough for anyone! */
339 for (i = 0; i < 0xFFFF; i++) {
340 found = false;
341 snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
342 nname[sizeof(nname)-1] = 0;
343 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
344 if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
345 found = true;
346 break;
347 }
348
349 if (!found)
350 break;
351 }
352
353 if (unlikely(found)) {
354too_many_devs:
349 mutex_unlock(&cfg80211_mutex); 355 mutex_unlock(&cfg80211_mutex);
350 /* ugh, wrapped! */ 356 /* ugh, too many devices already! */
351 kfree(rdev); 357 kfree(rdev);
352 return NULL; 358 return NULL;
353 } 359 }
354 360
355 mutex_unlock(&cfg80211_mutex);
356
357 /* give it a proper name */ 361 /* give it a proper name */
358 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 362 dev_set_name(&rdev->wiphy.dev, "%s", nname);
363
364 mutex_unlock(&cfg80211_mutex);
359 365
360 mutex_init(&rdev->mtx); 366 mutex_init(&rdev->mtx);
361 mutex_init(&rdev->devlist_mtx); 367 mutex_init(&rdev->devlist_mtx);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 5d89310b3587..6583cca0e2ee 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -375,7 +375,7 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
375/* internal helpers */ 375/* internal helpers */
376int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 376int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
377 struct key_params *params, int key_idx, 377 struct key_params *params, int key_idx,
378 const u8 *mac_addr); 378 bool pairwise, const u8 *mac_addr);
379void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 379void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
380 size_t ie_len, u16 reason, bool from_ap); 380 size_t ie_len, u16 reason, bool from_ap);
381void cfg80211_sme_scan_done(struct net_device *dev); 381void cfg80211_sme_scan_done(struct net_device *dev);
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 8cb6e08373b9..f33fbb79437c 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -160,7 +160,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
160 */ 160 */
161 if (rdev->ops->del_key) 161 if (rdev->ops->del_key)
162 for (i = 0; i < 6; i++) 162 for (i = 0; i < 6; i++)
163 rdev->ops->del_key(wdev->wiphy, dev, i, NULL); 163 rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL);
164 164
165 if (wdev->current_bss) { 165 if (wdev->current_bss) {
166 cfg80211_unhold_bss(wdev->current_bss); 166 cfg80211_unhold_bss(wdev->current_bss);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 46f371160896..caf11a427507 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -876,21 +876,53 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
876 876
877 if (ieee80211_is_action(mgmt->frame_control) && 877 if (ieee80211_is_action(mgmt->frame_control) &&
878 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { 878 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
879 /* Verify that we are associated with the destination AP */ 879 int err = 0;
880
880 wdev_lock(wdev); 881 wdev_lock(wdev);
881 882
882 if (!wdev->current_bss || 883 switch (wdev->iftype) {
883 memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, 884 case NL80211_IFTYPE_ADHOC:
884 ETH_ALEN) != 0 || 885 case NL80211_IFTYPE_STATION:
885 ((wdev->iftype == NL80211_IFTYPE_STATION || 886 case NL80211_IFTYPE_P2P_CLIENT:
886 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && 887 if (!wdev->current_bss) {
887 memcmp(wdev->current_bss->pub.bssid, mgmt->da, 888 err = -ENOTCONN;
888 ETH_ALEN) != 0)) { 889 break;
889 wdev_unlock(wdev); 890 }
890 return -ENOTCONN; 891
891 } 892 if (memcmp(wdev->current_bss->pub.bssid,
893 mgmt->bssid, ETH_ALEN)) {
894 err = -ENOTCONN;
895 break;
896 }
897
898 /*
899 * check for IBSS DA must be done by driver as
900 * cfg80211 doesn't track the stations
901 */
902 if (wdev->iftype == NL80211_IFTYPE_ADHOC)
903 break;
892 904
905 /* for station, check that DA is the AP */
906 if (memcmp(wdev->current_bss->pub.bssid,
907 mgmt->da, ETH_ALEN)) {
908 err = -ENOTCONN;
909 break;
910 }
911 break;
912 case NL80211_IFTYPE_AP:
913 case NL80211_IFTYPE_P2P_GO:
914 case NL80211_IFTYPE_AP_VLAN:
915 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
916 err = -EINVAL;
917 break;
918 default:
919 err = -EOPNOTSUPP;
920 break;
921 }
893 wdev_unlock(wdev); 922 wdev_unlock(wdev);
923
924 if (err)
925 return err;
894 } 926 }
895 927
896 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) 928 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9c84825803ce..882dc921103b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -23,6 +23,11 @@
23#include "nl80211.h" 23#include "nl80211.h"
24#include "reg.h" 24#include "reg.h"
25 25
26static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
27 struct genl_info *info);
28static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
29 struct genl_info *info);
30
26/* the netlink family */ 31/* the netlink family */
27static struct genl_family nl80211_fam = { 32static struct genl_family nl80211_fam = {
28 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ 33 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
@@ -31,6 +36,8 @@ static struct genl_family nl80211_fam = {
31 .version = 1, /* no particular meaning now */ 36 .version = 1, /* no particular meaning now */
32 .maxattr = NL80211_ATTR_MAX, 37 .maxattr = NL80211_ATTR_MAX,
33 .netnsok = true, 38 .netnsok = true,
39 .pre_doit = nl80211_pre_doit,
40 .post_doit = nl80211_post_doit,
34}; 41};
35 42
36/* internal helper: get rdev and dev */ 43/* internal helper: get rdev and dev */
@@ -86,6 +93,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
86 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, 93 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
87 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, 94 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
88 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, 95 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
96 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
89 97
90 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, 98 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
91 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, 99 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
@@ -161,7 +169,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
161 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, 169 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
162}; 170};
163 171
164/* policy for the attributes */ 172/* policy for the key attributes */
165static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { 173static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
166 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, 174 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
167 [NL80211_KEY_IDX] = { .type = NLA_U8 }, 175 [NL80211_KEY_IDX] = { .type = NLA_U8 },
@@ -169,6 +177,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
169 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, 177 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
170 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 178 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
171 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 179 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
180 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
172}; 181};
173 182
174/* ifidx get helper */ 183/* ifidx get helper */
@@ -191,6 +200,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb)
191 return res; 200 return res;
192} 201}
193 202
203static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
204 struct netlink_callback *cb,
205 struct cfg80211_registered_device **rdev,
206 struct net_device **dev)
207{
208 int ifidx = cb->args[0];
209 int err;
210
211 if (!ifidx)
212 ifidx = nl80211_get_ifidx(cb);
213 if (ifidx < 0)
214 return ifidx;
215
216 cb->args[0] = ifidx;
217
218 rtnl_lock();
219
220 *dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
221 if (!*dev) {
222 err = -ENODEV;
223 goto out_rtnl;
224 }
225
226 *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
227 if (IS_ERR(dev)) {
228 err = PTR_ERR(dev);
229 goto out_rtnl;
230 }
231
232 return 0;
233 out_rtnl:
234 rtnl_unlock();
235 return err;
236}
237
238static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
239{
240 cfg80211_unlock_rdev(rdev);
241 rtnl_unlock();
242}
243
194/* IE validation */ 244/* IE validation */
195static bool is_valid_ie_attr(const struct nlattr *attr) 245static bool is_valid_ie_attr(const struct nlattr *attr)
196{ 246{
@@ -258,6 +308,7 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
258struct key_parse { 308struct key_parse {
259 struct key_params p; 309 struct key_params p;
260 int idx; 310 int idx;
311 int type;
261 bool def, defmgmt; 312 bool def, defmgmt;
262}; 313};
263 314
@@ -288,6 +339,12 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
288 if (tb[NL80211_KEY_CIPHER]) 339 if (tb[NL80211_KEY_CIPHER])
289 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); 340 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
290 341
342 if (tb[NL80211_KEY_TYPE]) {
343 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
344 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
345 return -EINVAL;
346 }
347
291 return 0; 348 return 0;
292} 349}
293 350
@@ -312,6 +369,12 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
312 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; 369 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
313 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; 370 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
314 371
372 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
373 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
374 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
375 return -EINVAL;
376 }
377
315 return 0; 378 return 0;
316} 379}
317 380
@@ -321,6 +384,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
321 384
322 memset(k, 0, sizeof(*k)); 385 memset(k, 0, sizeof(*k));
323 k->idx = -1; 386 k->idx = -1;
387 k->type = -1;
324 388
325 if (info->attrs[NL80211_ATTR_KEY]) 389 if (info->attrs[NL80211_ATTR_KEY])
326 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k); 390 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
@@ -385,7 +449,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
385 } else if (parse.defmgmt) 449 } else if (parse.defmgmt)
386 goto error; 450 goto error;
387 err = cfg80211_validate_key_settings(rdev, &parse.p, 451 err = cfg80211_validate_key_settings(rdev, &parse.p,
388 parse.idx, NULL); 452 parse.idx, false, NULL);
389 if (err) 453 if (err)
390 goto error; 454 goto error;
391 result->params[parse.idx].cipher = parse.p.cipher; 455 result->params[parse.idx].cipher = parse.p.cipher;
@@ -404,9 +468,6 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
404{ 468{
405 ASSERT_WDEV_LOCK(wdev); 469 ASSERT_WDEV_LOCK(wdev);
406 470
407 if (!netif_running(wdev->netdev))
408 return -ENETDOWN;
409
410 switch (wdev->iftype) { 471 switch (wdev->iftype) {
411 case NL80211_IFTYPE_AP: 472 case NL80211_IFTYPE_AP:
412 case NL80211_IFTYPE_AP_VLAN: 473 case NL80211_IFTYPE_AP_VLAN:
@@ -471,6 +532,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
471 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 532 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
472 dev->wiphy.max_scan_ie_len); 533 dev->wiphy.max_scan_ie_len);
473 534
535 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
536 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
537
474 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 538 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
475 sizeof(u32) * dev->wiphy.n_cipher_suites, 539 sizeof(u32) * dev->wiphy.n_cipher_suites,
476 dev->wiphy.cipher_suites); 540 dev->wiphy.cipher_suites);
@@ -603,6 +667,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
603 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); 667 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
604 } 668 }
605 CMD(set_channel, SET_CHANNEL); 669 CMD(set_channel, SET_CHANNEL);
670 CMD(set_wds_peer, SET_WDS_PEER);
606 671
607#undef CMD 672#undef CMD
608 673
@@ -703,28 +768,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
703static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) 768static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
704{ 769{
705 struct sk_buff *msg; 770 struct sk_buff *msg;
706 struct cfg80211_registered_device *dev; 771 struct cfg80211_registered_device *dev = info->user_ptr[0];
707
708 dev = cfg80211_get_dev_from_info(info);
709 if (IS_ERR(dev))
710 return PTR_ERR(dev);
711 772
712 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 773 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
713 if (!msg) 774 if (!msg)
714 goto out_err; 775 return -ENOMEM;
715
716 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
717 goto out_free;
718 776
719 cfg80211_unlock_rdev(dev); 777 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) {
778 nlmsg_free(msg);
779 return -ENOBUFS;
780 }
720 781
721 return genlmsg_reply(msg, info); 782 return genlmsg_reply(msg, info);
722
723 out_free:
724 nlmsg_free(msg);
725 out_err:
726 cfg80211_unlock_rdev(dev);
727 return -ENOBUFS;
728} 783}
729 784
730static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { 785static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
@@ -813,24 +868,36 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
813 868
814static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) 869static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
815{ 870{
816 struct cfg80211_registered_device *rdev; 871 struct cfg80211_registered_device *rdev = info->user_ptr[0];
817 struct net_device *netdev; 872 struct net_device *netdev = info->user_ptr[1];
818 int result;
819 873
820 rtnl_lock(); 874 return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
875}
821 876
822 result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); 877static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
823 if (result) 878{
824 goto unlock; 879 struct cfg80211_registered_device *rdev = info->user_ptr[0];
880 struct net_device *dev = info->user_ptr[1];
881 struct wireless_dev *wdev = dev->ieee80211_ptr;
882 const u8 *bssid;
825 883
826 result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); 884 if (!info->attrs[NL80211_ATTR_MAC])
885 return -EINVAL;
827 886
828 unlock: 887 if (netif_running(dev))
829 rtnl_unlock(); 888 return -EBUSY;
830 889
831 return result; 890 if (!rdev->ops->set_wds_peer)
891 return -EOPNOTSUPP;
892
893 if (wdev->iftype != NL80211_IFTYPE_WDS)
894 return -EOPNOTSUPP;
895
896 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
897 return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid);
832} 898}
833 899
900
834static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 901static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
835{ 902{
836 struct cfg80211_registered_device *rdev; 903 struct cfg80211_registered_device *rdev;
@@ -843,8 +910,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
843 u32 frag_threshold = 0, rts_threshold = 0; 910 u32 frag_threshold = 0, rts_threshold = 0;
844 u8 coverage_class = 0; 911 u8 coverage_class = 0;
845 912
846 rtnl_lock();
847
848 /* 913 /*
849 * Try to find the wiphy and netdev. Normally this 914 * Try to find the wiphy and netdev. Normally this
850 * function shouldn't need the netdev, but this is 915 * function shouldn't need the netdev, but this is
@@ -871,8 +936,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
871 rdev = __cfg80211_rdev_from_info(info); 936 rdev = __cfg80211_rdev_from_info(info);
872 if (IS_ERR(rdev)) { 937 if (IS_ERR(rdev)) {
873 mutex_unlock(&cfg80211_mutex); 938 mutex_unlock(&cfg80211_mutex);
874 result = PTR_ERR(rdev); 939 return PTR_ERR(rdev);
875 goto unlock;
876 } 940 }
877 wdev = NULL; 941 wdev = NULL;
878 netdev = NULL; 942 netdev = NULL;
@@ -1054,8 +1118,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 mutex_unlock(&rdev->mtx); 1118 mutex_unlock(&rdev->mtx);
1055 if (netdev) 1119 if (netdev)
1056 dev_put(netdev); 1120 dev_put(netdev);
1057 unlock:
1058 rtnl_unlock();
1059 return result; 1121 return result;
1060} 1122}
1061 1123
@@ -1135,33 +1197,20 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
1135static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) 1197static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
1136{ 1198{
1137 struct sk_buff *msg; 1199 struct sk_buff *msg;
1138 struct cfg80211_registered_device *dev; 1200 struct cfg80211_registered_device *dev = info->user_ptr[0];
1139 struct net_device *netdev; 1201 struct net_device *netdev = info->user_ptr[1];
1140 int err;
1141
1142 err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
1143 if (err)
1144 return err;
1145 1202
1146 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1203 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1147 if (!msg) 1204 if (!msg)
1148 goto out_err; 1205 return -ENOMEM;
1149 1206
1150 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, 1207 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
1151 dev, netdev) < 0) 1208 dev, netdev) < 0) {
1152 goto out_free; 1209 nlmsg_free(msg);
1153 1210 return -ENOBUFS;
1154 dev_put(netdev); 1211 }
1155 cfg80211_unlock_rdev(dev);
1156 1212
1157 return genlmsg_reply(msg, info); 1213 return genlmsg_reply(msg, info);
1158
1159 out_free:
1160 nlmsg_free(msg);
1161 out_err:
1162 dev_put(netdev);
1163 cfg80211_unlock_rdev(dev);
1164 return -ENOBUFS;
1165} 1214}
1166 1215
1167static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { 1216static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
@@ -1221,39 +1270,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
1221 1270
1222static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) 1271static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1223{ 1272{
1224 struct cfg80211_registered_device *rdev; 1273 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1225 struct vif_params params; 1274 struct vif_params params;
1226 int err; 1275 int err;
1227 enum nl80211_iftype otype, ntype; 1276 enum nl80211_iftype otype, ntype;
1228 struct net_device *dev; 1277 struct net_device *dev = info->user_ptr[1];
1229 u32 _flags, *flags = NULL; 1278 u32 _flags, *flags = NULL;
1230 bool change = false; 1279 bool change = false;
1231 1280
1232 memset(&params, 0, sizeof(params)); 1281 memset(&params, 0, sizeof(params));
1233 1282
1234 rtnl_lock();
1235
1236 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1237 if (err)
1238 goto unlock_rtnl;
1239
1240 otype = ntype = dev->ieee80211_ptr->iftype; 1283 otype = ntype = dev->ieee80211_ptr->iftype;
1241 1284
1242 if (info->attrs[NL80211_ATTR_IFTYPE]) { 1285 if (info->attrs[NL80211_ATTR_IFTYPE]) {
1243 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 1286 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
1244 if (otype != ntype) 1287 if (otype != ntype)
1245 change = true; 1288 change = true;
1246 if (ntype > NL80211_IFTYPE_MAX) { 1289 if (ntype > NL80211_IFTYPE_MAX)
1247 err = -EINVAL; 1290 return -EINVAL;
1248 goto unlock;
1249 }
1250 } 1291 }
1251 1292
1252 if (info->attrs[NL80211_ATTR_MESH_ID]) { 1293 if (info->attrs[NL80211_ATTR_MESH_ID]) {
1253 if (ntype != NL80211_IFTYPE_MESH_POINT) { 1294 if (ntype != NL80211_IFTYPE_MESH_POINT)
1254 err = -EINVAL; 1295 return -EINVAL;
1255 goto unlock;
1256 }
1257 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); 1296 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
1258 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 1297 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
1259 change = true; 1298 change = true;
@@ -1264,20 +1303,18 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1264 change = true; 1303 change = true;
1265 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); 1304 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
1266 if (err) 1305 if (err)
1267 goto unlock; 1306 return err;
1268 } else { 1307 } else {
1269 params.use_4addr = -1; 1308 params.use_4addr = -1;
1270 } 1309 }
1271 1310
1272 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 1311 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
1273 if (ntype != NL80211_IFTYPE_MONITOR) { 1312 if (ntype != NL80211_IFTYPE_MONITOR)
1274 err = -EINVAL; 1313 return -EINVAL;
1275 goto unlock;
1276 }
1277 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], 1314 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
1278 &_flags); 1315 &_flags);
1279 if (err) 1316 if (err)
1280 goto unlock; 1317 return err;
1281 1318
1282 flags = &_flags; 1319 flags = &_flags;
1283 change = true; 1320 change = true;
@@ -1291,17 +1328,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1291 if (!err && params.use_4addr != -1) 1328 if (!err && params.use_4addr != -1)
1292 dev->ieee80211_ptr->use_4addr = params.use_4addr; 1329 dev->ieee80211_ptr->use_4addr = params.use_4addr;
1293 1330
1294 unlock:
1295 dev_put(dev);
1296 cfg80211_unlock_rdev(rdev);
1297 unlock_rtnl:
1298 rtnl_unlock();
1299 return err; 1331 return err;
1300} 1332}
1301 1333
1302static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) 1334static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1303{ 1335{
1304 struct cfg80211_registered_device *rdev; 1336 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1305 struct vif_params params; 1337 struct vif_params params;
1306 int err; 1338 int err;
1307 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; 1339 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -1318,19 +1350,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1318 return -EINVAL; 1350 return -EINVAL;
1319 } 1351 }
1320 1352
1321 rtnl_lock();
1322
1323 rdev = cfg80211_get_dev_from_info(info);
1324 if (IS_ERR(rdev)) {
1325 err = PTR_ERR(rdev);
1326 goto unlock_rtnl;
1327 }
1328
1329 if (!rdev->ops->add_virtual_intf || 1353 if (!rdev->ops->add_virtual_intf ||
1330 !(rdev->wiphy.interface_modes & (1 << type))) { 1354 !(rdev->wiphy.interface_modes & (1 << type)))
1331 err = -EOPNOTSUPP; 1355 return -EOPNOTSUPP;
1332 goto unlock;
1333 }
1334 1356
1335 if (type == NL80211_IFTYPE_MESH_POINT && 1357 if (type == NL80211_IFTYPE_MESH_POINT &&
1336 info->attrs[NL80211_ATTR_MESH_ID]) { 1358 info->attrs[NL80211_ATTR_MESH_ID]) {
@@ -1342,7 +1364,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1342 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); 1364 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
1343 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); 1365 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
1344 if (err) 1366 if (err)
1345 goto unlock; 1367 return err;
1346 } 1368 }
1347 1369
1348 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 1370 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
@@ -1352,38 +1374,18 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1352 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 1374 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
1353 type, err ? NULL : &flags, &params); 1375 type, err ? NULL : &flags, &params);
1354 1376
1355 unlock:
1356 cfg80211_unlock_rdev(rdev);
1357 unlock_rtnl:
1358 rtnl_unlock();
1359 return err; 1377 return err;
1360} 1378}
1361 1379
1362static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 1380static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1363{ 1381{
1364 struct cfg80211_registered_device *rdev; 1382 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1365 int err; 1383 struct net_device *dev = info->user_ptr[1];
1366 struct net_device *dev;
1367
1368 rtnl_lock();
1369
1370 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1371 if (err)
1372 goto unlock_rtnl;
1373 1384
1374 if (!rdev->ops->del_virtual_intf) { 1385 if (!rdev->ops->del_virtual_intf)
1375 err = -EOPNOTSUPP; 1386 return -EOPNOTSUPP;
1376 goto out;
1377 }
1378
1379 err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1380 1387
1381 out: 1388 return rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1382 cfg80211_unlock_rdev(rdev);
1383 dev_put(dev);
1384 unlock_rtnl:
1385 rtnl_unlock();
1386 return err;
1387} 1389}
1388 1390
1389struct get_key_cookie { 1391struct get_key_cookie {
@@ -1436,11 +1438,12 @@ static void get_key_callback(void *c, struct key_params *params)
1436 1438
1437static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) 1439static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1438{ 1440{
1439 struct cfg80211_registered_device *rdev; 1441 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1440 int err; 1442 int err;
1441 struct net_device *dev; 1443 struct net_device *dev = info->user_ptr[1];
1442 u8 key_idx = 0; 1444 u8 key_idx = 0;
1443 u8 *mac_addr = NULL; 1445 const u8 *mac_addr = NULL;
1446 bool pairwise;
1444 struct get_key_cookie cookie = { 1447 struct get_key_cookie cookie = {
1445 .error = 0, 1448 .error = 0,
1446 }; 1449 };
@@ -1456,30 +1459,28 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1456 if (info->attrs[NL80211_ATTR_MAC]) 1459 if (info->attrs[NL80211_ATTR_MAC])
1457 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1460 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1458 1461
1459 rtnl_lock(); 1462 pairwise = !!mac_addr;
1460 1463 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
1461 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 1464 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
1462 if (err) 1465 if (kt >= NUM_NL80211_KEYTYPES)
1463 goto unlock_rtnl; 1466 return -EINVAL;
1464 1467 if (kt != NL80211_KEYTYPE_GROUP &&
1465 if (!rdev->ops->get_key) { 1468 kt != NL80211_KEYTYPE_PAIRWISE)
1466 err = -EOPNOTSUPP; 1469 return -EINVAL;
1467 goto out; 1470 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
1468 } 1471 }
1469 1472
1473 if (!rdev->ops->get_key)
1474 return -EOPNOTSUPP;
1475
1470 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1476 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1471 if (!msg) { 1477 if (!msg)
1472 err = -ENOMEM; 1478 return -ENOMEM;
1473 goto out;
1474 }
1475 1479
1476 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 1480 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
1477 NL80211_CMD_NEW_KEY); 1481 NL80211_CMD_NEW_KEY);
1478 1482 if (IS_ERR(hdr))
1479 if (IS_ERR(hdr)) { 1483 return PTR_ERR(hdr);
1480 err = PTR_ERR(hdr);
1481 goto free_msg;
1482 }
1483 1484
1484 cookie.msg = msg; 1485 cookie.msg = msg;
1485 cookie.idx = key_idx; 1486 cookie.idx = key_idx;
@@ -1489,8 +1490,12 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1489 if (mac_addr) 1490 if (mac_addr)
1490 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); 1491 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
1491 1492
1492 err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr, 1493 if (pairwise && mac_addr &&
1493 &cookie, get_key_callback); 1494 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
1495 return -ENOENT;
1496
1497 err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise,
1498 mac_addr, &cookie, get_key_callback);
1494 1499
1495 if (err) 1500 if (err)
1496 goto free_msg; 1501 goto free_msg;
@@ -1499,28 +1504,21 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1499 goto nla_put_failure; 1504 goto nla_put_failure;
1500 1505
1501 genlmsg_end(msg, hdr); 1506 genlmsg_end(msg, hdr);
1502 err = genlmsg_reply(msg, info); 1507 return genlmsg_reply(msg, info);
1503 goto out;
1504 1508
1505 nla_put_failure: 1509 nla_put_failure:
1506 err = -ENOBUFS; 1510 err = -ENOBUFS;
1507 free_msg: 1511 free_msg:
1508 nlmsg_free(msg); 1512 nlmsg_free(msg);
1509 out:
1510 cfg80211_unlock_rdev(rdev);
1511 dev_put(dev);
1512 unlock_rtnl:
1513 rtnl_unlock();
1514
1515 return err; 1513 return err;
1516} 1514}
1517 1515
1518static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) 1516static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1519{ 1517{
1520 struct cfg80211_registered_device *rdev; 1518 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1521 struct key_parse key; 1519 struct key_parse key;
1522 int err; 1520 int err;
1523 struct net_device *dev; 1521 struct net_device *dev = info->user_ptr[1];
1524 int (*func)(struct wiphy *wiphy, struct net_device *netdev, 1522 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1525 u8 key_index); 1523 u8 key_index);
1526 1524
@@ -1535,21 +1533,13 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1535 if (!key.def && !key.defmgmt) 1533 if (!key.def && !key.defmgmt)
1536 return -EINVAL; 1534 return -EINVAL;
1537 1535
1538 rtnl_lock();
1539
1540 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1541 if (err)
1542 goto unlock_rtnl;
1543
1544 if (key.def) 1536 if (key.def)
1545 func = rdev->ops->set_default_key; 1537 func = rdev->ops->set_default_key;
1546 else 1538 else
1547 func = rdev->ops->set_default_mgmt_key; 1539 func = rdev->ops->set_default_mgmt_key;
1548 1540
1549 if (!func) { 1541 if (!func)
1550 err = -EOPNOTSUPP; 1542 return -EOPNOTSUPP;
1551 goto out;
1552 }
1553 1543
1554 wdev_lock(dev->ieee80211_ptr); 1544 wdev_lock(dev->ieee80211_ptr);
1555 err = nl80211_key_allowed(dev->ieee80211_ptr); 1545 err = nl80211_key_allowed(dev->ieee80211_ptr);
@@ -1566,23 +1556,16 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1566#endif 1556#endif
1567 wdev_unlock(dev->ieee80211_ptr); 1557 wdev_unlock(dev->ieee80211_ptr);
1568 1558
1569 out:
1570 cfg80211_unlock_rdev(rdev);
1571 dev_put(dev);
1572
1573 unlock_rtnl:
1574 rtnl_unlock();
1575
1576 return err; 1559 return err;
1577} 1560}
1578 1561
1579static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 1562static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1580{ 1563{
1581 struct cfg80211_registered_device *rdev; 1564 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1582 int err; 1565 int err;
1583 struct net_device *dev; 1566 struct net_device *dev = info->user_ptr[1];
1584 struct key_parse key; 1567 struct key_parse key;
1585 u8 *mac_addr = NULL; 1568 const u8 *mac_addr = NULL;
1586 1569
1587 err = nl80211_parse_key(info, &key); 1570 err = nl80211_parse_key(info, &key);
1588 if (err) 1571 if (err)
@@ -1594,43 +1577,42 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1594 if (info->attrs[NL80211_ATTR_MAC]) 1577 if (info->attrs[NL80211_ATTR_MAC])
1595 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1578 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1596 1579
1597 rtnl_lock(); 1580 if (key.type == -1) {
1581 if (mac_addr)
1582 key.type = NL80211_KEYTYPE_PAIRWISE;
1583 else
1584 key.type = NL80211_KEYTYPE_GROUP;
1585 }
1598 1586
1599 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 1587 /* for now */
1600 if (err) 1588 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
1601 goto unlock_rtnl; 1589 key.type != NL80211_KEYTYPE_GROUP)
1590 return -EINVAL;
1602 1591
1603 if (!rdev->ops->add_key) { 1592 if (!rdev->ops->add_key)
1604 err = -EOPNOTSUPP; 1593 return -EOPNOTSUPP;
1605 goto out;
1606 }
1607 1594
1608 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) { 1595 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
1609 err = -EINVAL; 1596 key.type == NL80211_KEYTYPE_PAIRWISE,
1610 goto out; 1597 mac_addr))
1611 } 1598 return -EINVAL;
1612 1599
1613 wdev_lock(dev->ieee80211_ptr); 1600 wdev_lock(dev->ieee80211_ptr);
1614 err = nl80211_key_allowed(dev->ieee80211_ptr); 1601 err = nl80211_key_allowed(dev->ieee80211_ptr);
1615 if (!err) 1602 if (!err)
1616 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx, 1603 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
1604 key.type == NL80211_KEYTYPE_PAIRWISE,
1617 mac_addr, &key.p); 1605 mac_addr, &key.p);
1618 wdev_unlock(dev->ieee80211_ptr); 1606 wdev_unlock(dev->ieee80211_ptr);
1619 1607
1620 out:
1621 cfg80211_unlock_rdev(rdev);
1622 dev_put(dev);
1623 unlock_rtnl:
1624 rtnl_unlock();
1625
1626 return err; 1608 return err;
1627} 1609}
1628 1610
1629static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) 1611static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1630{ 1612{
1631 struct cfg80211_registered_device *rdev; 1613 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1632 int err; 1614 int err;
1633 struct net_device *dev; 1615 struct net_device *dev = info->user_ptr[1];
1634 u8 *mac_addr = NULL; 1616 u8 *mac_addr = NULL;
1635 struct key_parse key; 1617 struct key_parse key;
1636 1618
@@ -1641,21 +1623,32 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1641 if (info->attrs[NL80211_ATTR_MAC]) 1623 if (info->attrs[NL80211_ATTR_MAC])
1642 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1624 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1643 1625
1644 rtnl_lock(); 1626 if (key.type == -1) {
1627 if (mac_addr)
1628 key.type = NL80211_KEYTYPE_PAIRWISE;
1629 else
1630 key.type = NL80211_KEYTYPE_GROUP;
1631 }
1645 1632
1646 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 1633 /* for now */
1647 if (err) 1634 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
1648 goto unlock_rtnl; 1635 key.type != NL80211_KEYTYPE_GROUP)
1636 return -EINVAL;
1649 1637
1650 if (!rdev->ops->del_key) { 1638 if (!rdev->ops->del_key)
1651 err = -EOPNOTSUPP; 1639 return -EOPNOTSUPP;
1652 goto out;
1653 }
1654 1640
1655 wdev_lock(dev->ieee80211_ptr); 1641 wdev_lock(dev->ieee80211_ptr);
1656 err = nl80211_key_allowed(dev->ieee80211_ptr); 1642 err = nl80211_key_allowed(dev->ieee80211_ptr);
1643
1644 if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
1645 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
1646 err = -ENOENT;
1647
1657 if (!err) 1648 if (!err)
1658 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr); 1649 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx,
1650 key.type == NL80211_KEYTYPE_PAIRWISE,
1651 mac_addr);
1659 1652
1660#ifdef CONFIG_CFG80211_WEXT 1653#ifdef CONFIG_CFG80211_WEXT
1661 if (!err) { 1654 if (!err) {
@@ -1667,13 +1660,6 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1667#endif 1660#endif
1668 wdev_unlock(dev->ieee80211_ptr); 1661 wdev_unlock(dev->ieee80211_ptr);
1669 1662
1670 out:
1671 cfg80211_unlock_rdev(rdev);
1672 dev_put(dev);
1673
1674 unlock_rtnl:
1675 rtnl_unlock();
1676
1677 return err; 1663 return err;
1678} 1664}
1679 1665
@@ -1681,36 +1667,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1681{ 1667{
1682 int (*call)(struct wiphy *wiphy, struct net_device *dev, 1668 int (*call)(struct wiphy *wiphy, struct net_device *dev,
1683 struct beacon_parameters *info); 1669 struct beacon_parameters *info);
1684 struct cfg80211_registered_device *rdev; 1670 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1685 int err; 1671 struct net_device *dev = info->user_ptr[1];
1686 struct net_device *dev;
1687 struct beacon_parameters params; 1672 struct beacon_parameters params;
1688 int haveinfo = 0; 1673 int haveinfo = 0;
1689 1674
1690 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1675 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1691 return -EINVAL; 1676 return -EINVAL;
1692 1677
1693 rtnl_lock();
1694
1695 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1696 if (err)
1697 goto unlock_rtnl;
1698
1699 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 1678 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1700 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 1679 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1701 err = -EOPNOTSUPP; 1680 return -EOPNOTSUPP;
1702 goto out;
1703 }
1704 1681
1705 switch (info->genlhdr->cmd) { 1682 switch (info->genlhdr->cmd) {
1706 case NL80211_CMD_NEW_BEACON: 1683 case NL80211_CMD_NEW_BEACON:
1707 /* these are required for NEW_BEACON */ 1684 /* these are required for NEW_BEACON */
1708 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || 1685 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
1709 !info->attrs[NL80211_ATTR_DTIM_PERIOD] || 1686 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
1710 !info->attrs[NL80211_ATTR_BEACON_HEAD]) { 1687 !info->attrs[NL80211_ATTR_BEACON_HEAD])
1711 err = -EINVAL; 1688 return -EINVAL;
1712 goto out;
1713 }
1714 1689
1715 call = rdev->ops->add_beacon; 1690 call = rdev->ops->add_beacon;
1716 break; 1691 break;
@@ -1719,14 +1694,11 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1719 break; 1694 break;
1720 default: 1695 default:
1721 WARN_ON(1); 1696 WARN_ON(1);
1722 err = -EOPNOTSUPP; 1697 return -EOPNOTSUPP;
1723 goto out;
1724 } 1698 }
1725 1699
1726 if (!call) { 1700 if (!call)
1727 err = -EOPNOTSUPP; 1701 return -EOPNOTSUPP;
1728 goto out;
1729 }
1730 1702
1731 memset(&params, 0, sizeof(params)); 1703 memset(&params, 0, sizeof(params));
1732 1704
@@ -1756,53 +1728,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1756 haveinfo = 1; 1728 haveinfo = 1;
1757 } 1729 }
1758 1730
1759 if (!haveinfo) { 1731 if (!haveinfo)
1760 err = -EINVAL; 1732 return -EINVAL;
1761 goto out;
1762 }
1763
1764 err = call(&rdev->wiphy, dev, &params);
1765
1766 out:
1767 cfg80211_unlock_rdev(rdev);
1768 dev_put(dev);
1769 unlock_rtnl:
1770 rtnl_unlock();
1771 1733
1772 return err; 1734 return call(&rdev->wiphy, dev, &params);
1773} 1735}
1774 1736
1775static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 1737static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1776{ 1738{
1777 struct cfg80211_registered_device *rdev; 1739 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1778 int err; 1740 struct net_device *dev = info->user_ptr[1];
1779 struct net_device *dev;
1780 1741
1781 rtnl_lock(); 1742 if (!rdev->ops->del_beacon)
1782 1743 return -EOPNOTSUPP;
1783 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1784 if (err)
1785 goto unlock_rtnl;
1786
1787 if (!rdev->ops->del_beacon) {
1788 err = -EOPNOTSUPP;
1789 goto out;
1790 }
1791 1744
1792 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 1745 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1793 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 1746 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1794 err = -EOPNOTSUPP; 1747 return -EOPNOTSUPP;
1795 goto out;
1796 }
1797 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
1798
1799 out:
1800 cfg80211_unlock_rdev(rdev);
1801 dev_put(dev);
1802 unlock_rtnl:
1803 rtnl_unlock();
1804 1748
1805 return err; 1749 return rdev->ops->del_beacon(&rdev->wiphy, dev);
1806} 1750}
1807 1751
1808static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 1752static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -1923,6 +1867,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1923 if (sinfo->filled & STATION_INFO_TX_PACKETS) 1867 if (sinfo->filled & STATION_INFO_TX_PACKETS)
1924 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS, 1868 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
1925 sinfo->tx_packets); 1869 sinfo->tx_packets);
1870 if (sinfo->filled & STATION_INFO_TX_RETRIES)
1871 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES,
1872 sinfo->tx_retries);
1873 if (sinfo->filled & STATION_INFO_TX_FAILED)
1874 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
1875 sinfo->tx_failed);
1926 nla_nest_end(msg, sinfoattr); 1876 nla_nest_end(msg, sinfoattr);
1927 1877
1928 return genlmsg_end(msg, hdr); 1878 return genlmsg_end(msg, hdr);
@@ -1939,28 +1889,12 @@ static int nl80211_dump_station(struct sk_buff *skb,
1939 struct cfg80211_registered_device *dev; 1889 struct cfg80211_registered_device *dev;
1940 struct net_device *netdev; 1890 struct net_device *netdev;
1941 u8 mac_addr[ETH_ALEN]; 1891 u8 mac_addr[ETH_ALEN];
1942 int ifidx = cb->args[0];
1943 int sta_idx = cb->args[1]; 1892 int sta_idx = cb->args[1];
1944 int err; 1893 int err;
1945 1894
1946 if (!ifidx) 1895 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
1947 ifidx = nl80211_get_ifidx(cb); 1896 if (err)
1948 if (ifidx < 0) 1897 return err;
1949 return ifidx;
1950
1951 rtnl_lock();
1952
1953 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
1954 if (!netdev) {
1955 err = -ENODEV;
1956 goto out_rtnl;
1957 }
1958
1959 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
1960 if (IS_ERR(dev)) {
1961 err = PTR_ERR(dev);
1962 goto out_rtnl;
1963 }
1964 1898
1965 if (!dev->ops->dump_station) { 1899 if (!dev->ops->dump_station) {
1966 err = -EOPNOTSUPP; 1900 err = -EOPNOTSUPP;
@@ -1990,21 +1924,19 @@ static int nl80211_dump_station(struct sk_buff *skb,
1990 cb->args[1] = sta_idx; 1924 cb->args[1] = sta_idx;
1991 err = skb->len; 1925 err = skb->len;
1992 out_err: 1926 out_err:
1993 cfg80211_unlock_rdev(dev); 1927 nl80211_finish_netdev_dump(dev);
1994 out_rtnl:
1995 rtnl_unlock();
1996 1928
1997 return err; 1929 return err;
1998} 1930}
1999 1931
2000static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) 1932static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
2001{ 1933{
2002 struct cfg80211_registered_device *rdev; 1934 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2003 int err; 1935 struct net_device *dev = info->user_ptr[1];
2004 struct net_device *dev;
2005 struct station_info sinfo; 1936 struct station_info sinfo;
2006 struct sk_buff *msg; 1937 struct sk_buff *msg;
2007 u8 *mac_addr = NULL; 1938 u8 *mac_addr = NULL;
1939 int err;
2008 1940
2009 memset(&sinfo, 0, sizeof(sinfo)); 1941 memset(&sinfo, 0, sizeof(sinfo));
2010 1942
@@ -2013,41 +1945,24 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
2013 1945
2014 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1946 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2015 1947
2016 rtnl_lock(); 1948 if (!rdev->ops->get_station)
2017 1949 return -EOPNOTSUPP;
2018 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2019 if (err)
2020 goto out_rtnl;
2021
2022 if (!rdev->ops->get_station) {
2023 err = -EOPNOTSUPP;
2024 goto out;
2025 }
2026 1950
2027 err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); 1951 err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
2028 if (err) 1952 if (err)
2029 goto out; 1953 return err;
2030 1954
2031 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1955 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2032 if (!msg) 1956 if (!msg)
2033 goto out; 1957 return -ENOMEM;
2034 1958
2035 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, 1959 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
2036 dev, mac_addr, &sinfo) < 0) 1960 dev, mac_addr, &sinfo) < 0) {
2037 goto out_free; 1961 nlmsg_free(msg);
2038 1962 return -ENOBUFS;
2039 err = genlmsg_reply(msg, info); 1963 }
2040 goto out;
2041
2042 out_free:
2043 nlmsg_free(msg);
2044 out:
2045 cfg80211_unlock_rdev(rdev);
2046 dev_put(dev);
2047 out_rtnl:
2048 rtnl_unlock();
2049 1964
2050 return err; 1965 return genlmsg_reply(msg, info);
2051} 1966}
2052 1967
2053/* 1968/*
@@ -2077,9 +1992,9 @@ static int get_vlan(struct genl_info *info,
2077 1992
2078static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) 1993static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2079{ 1994{
2080 struct cfg80211_registered_device *rdev; 1995 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2081 int err; 1996 int err;
2082 struct net_device *dev; 1997 struct net_device *dev = info->user_ptr[1];
2083 struct station_parameters params; 1998 struct station_parameters params;
2084 u8 *mac_addr = NULL; 1999 u8 *mac_addr = NULL;
2085 2000
@@ -2117,12 +2032,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2117 params.plink_action = 2032 params.plink_action =
2118 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 2033 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2119 2034
2120 rtnl_lock();
2121
2122 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2123 if (err)
2124 goto out_rtnl;
2125
2126 err = get_vlan(info, rdev, &params.vlan); 2035 err = get_vlan(info, rdev, &params.vlan);
2127 if (err) 2036 if (err)
2128 goto out; 2037 goto out;
@@ -2184,19 +2093,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2184 out: 2093 out:
2185 if (params.vlan) 2094 if (params.vlan)
2186 dev_put(params.vlan); 2095 dev_put(params.vlan);
2187 cfg80211_unlock_rdev(rdev);
2188 dev_put(dev);
2189 out_rtnl:
2190 rtnl_unlock();
2191 2096
2192 return err; 2097 return err;
2193} 2098}
2194 2099
2195static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 2100static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2196{ 2101{
2197 struct cfg80211_registered_device *rdev; 2102 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2198 int err; 2103 int err;
2199 struct net_device *dev; 2104 struct net_device *dev = info->user_ptr[1];
2200 struct station_parameters params; 2105 struct station_parameters params;
2201 u8 *mac_addr = NULL; 2106 u8 *mac_addr = NULL;
2202 2107
@@ -2233,18 +2138,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2233 if (parse_station_flags(info, &params)) 2138 if (parse_station_flags(info, &params))
2234 return -EINVAL; 2139 return -EINVAL;
2235 2140
2236 rtnl_lock();
2237
2238 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2239 if (err)
2240 goto out_rtnl;
2241
2242 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2141 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2243 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2142 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2244 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 2143 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2245 err = -EINVAL; 2144 return -EINVAL;
2246 goto out;
2247 }
2248 2145
2249 err = get_vlan(info, rdev, &params.vlan); 2146 err = get_vlan(info, rdev, &params.vlan);
2250 if (err) 2147 if (err)
@@ -2258,62 +2155,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2258 goto out; 2155 goto out;
2259 } 2156 }
2260 2157
2261 if (!netif_running(dev)) {
2262 err = -ENETDOWN;
2263 goto out;
2264 }
2265
2266 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params); 2158 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
2267 2159
2268 out: 2160 out:
2269 if (params.vlan) 2161 if (params.vlan)
2270 dev_put(params.vlan); 2162 dev_put(params.vlan);
2271 cfg80211_unlock_rdev(rdev);
2272 dev_put(dev);
2273 out_rtnl:
2274 rtnl_unlock();
2275
2276 return err; 2163 return err;
2277} 2164}
2278 2165
2279static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) 2166static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2280{ 2167{
2281 struct cfg80211_registered_device *rdev; 2168 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2282 int err; 2169 struct net_device *dev = info->user_ptr[1];
2283 struct net_device *dev;
2284 u8 *mac_addr = NULL; 2170 u8 *mac_addr = NULL;
2285 2171
2286 if (info->attrs[NL80211_ATTR_MAC]) 2172 if (info->attrs[NL80211_ATTR_MAC])
2287 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 2173 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2288 2174
2289 rtnl_lock();
2290
2291 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2292 if (err)
2293 goto out_rtnl;
2294
2295 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2175 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2176 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && 2177 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
2298 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 2178 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2299 err = -EINVAL; 2179 return -EINVAL;
2300 goto out;
2301 }
2302
2303 if (!rdev->ops->del_station) {
2304 err = -EOPNOTSUPP;
2305 goto out;
2306 }
2307
2308 err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
2309 2180
2310 out: 2181 if (!rdev->ops->del_station)
2311 cfg80211_unlock_rdev(rdev); 2182 return -EOPNOTSUPP;
2312 dev_put(dev);
2313 out_rtnl:
2314 rtnl_unlock();
2315 2183
2316 return err; 2184 return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
2317} 2185}
2318 2186
2319static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, 2187static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
@@ -2376,28 +2244,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2376 struct net_device *netdev; 2244 struct net_device *netdev;
2377 u8 dst[ETH_ALEN]; 2245 u8 dst[ETH_ALEN];
2378 u8 next_hop[ETH_ALEN]; 2246 u8 next_hop[ETH_ALEN];
2379 int ifidx = cb->args[0];
2380 int path_idx = cb->args[1]; 2247 int path_idx = cb->args[1];
2381 int err; 2248 int err;
2382 2249
2383 if (!ifidx) 2250 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
2384 ifidx = nl80211_get_ifidx(cb); 2251 if (err)
2385 if (ifidx < 0) 2252 return err;
2386 return ifidx;
2387
2388 rtnl_lock();
2389
2390 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
2391 if (!netdev) {
2392 err = -ENODEV;
2393 goto out_rtnl;
2394 }
2395
2396 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
2397 if (IS_ERR(dev)) {
2398 err = PTR_ERR(dev);
2399 goto out_rtnl;
2400 }
2401 2253
2402 if (!dev->ops->dump_mpath) { 2254 if (!dev->ops->dump_mpath) {
2403 err = -EOPNOTSUPP; 2255 err = -EOPNOTSUPP;
@@ -2431,18 +2283,15 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2431 cb->args[1] = path_idx; 2283 cb->args[1] = path_idx;
2432 err = skb->len; 2284 err = skb->len;
2433 out_err: 2285 out_err:
2434 cfg80211_unlock_rdev(dev); 2286 nl80211_finish_netdev_dump(dev);
2435 out_rtnl:
2436 rtnl_unlock();
2437
2438 return err; 2287 return err;
2439} 2288}
2440 2289
2441static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) 2290static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2442{ 2291{
2443 struct cfg80211_registered_device *rdev; 2292 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2444 int err; 2293 int err;
2445 struct net_device *dev; 2294 struct net_device *dev = info->user_ptr[1];
2446 struct mpath_info pinfo; 2295 struct mpath_info pinfo;
2447 struct sk_buff *msg; 2296 struct sk_buff *msg;
2448 u8 *dst = NULL; 2297 u8 *dst = NULL;
@@ -2455,53 +2304,33 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2455 2304
2456 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2305 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2457 2306
2458 rtnl_lock(); 2307 if (!rdev->ops->get_mpath)
2459 2308 return -EOPNOTSUPP;
2460 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2461 if (err)
2462 goto out_rtnl;
2463
2464 if (!rdev->ops->get_mpath) {
2465 err = -EOPNOTSUPP;
2466 goto out;
2467 }
2468 2309
2469 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { 2310 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
2470 err = -EOPNOTSUPP; 2311 return -EOPNOTSUPP;
2471 goto out;
2472 }
2473 2312
2474 err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo); 2313 err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
2475 if (err) 2314 if (err)
2476 goto out; 2315 return err;
2477 2316
2478 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2317 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2479 if (!msg) 2318 if (!msg)
2480 goto out; 2319 return -ENOMEM;
2481 2320
2482 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, 2321 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
2483 dev, dst, next_hop, &pinfo) < 0) 2322 dev, dst, next_hop, &pinfo) < 0) {
2484 goto out_free; 2323 nlmsg_free(msg);
2485 2324 return -ENOBUFS;
2486 err = genlmsg_reply(msg, info); 2325 }
2487 goto out;
2488
2489 out_free:
2490 nlmsg_free(msg);
2491 out:
2492 cfg80211_unlock_rdev(rdev);
2493 dev_put(dev);
2494 out_rtnl:
2495 rtnl_unlock();
2496 2326
2497 return err; 2327 return genlmsg_reply(msg, info);
2498} 2328}
2499 2329
2500static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) 2330static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2501{ 2331{
2502 struct cfg80211_registered_device *rdev; 2332 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2503 int err; 2333 struct net_device *dev = info->user_ptr[1];
2504 struct net_device *dev;
2505 u8 *dst = NULL; 2334 u8 *dst = NULL;
2506 u8 *next_hop = NULL; 2335 u8 *next_hop = NULL;
2507 2336
@@ -2514,42 +2343,19 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2514 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2343 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2515 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 2344 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
2516 2345
2517 rtnl_lock(); 2346 if (!rdev->ops->change_mpath)
2518 2347 return -EOPNOTSUPP;
2519 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2520 if (err)
2521 goto out_rtnl;
2522
2523 if (!rdev->ops->change_mpath) {
2524 err = -EOPNOTSUPP;
2525 goto out;
2526 }
2527
2528 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2529 err = -EOPNOTSUPP;
2530 goto out;
2531 }
2532
2533 if (!netif_running(dev)) {
2534 err = -ENETDOWN;
2535 goto out;
2536 }
2537
2538 err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
2539 2348
2540 out: 2349 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
2541 cfg80211_unlock_rdev(rdev); 2350 return -EOPNOTSUPP;
2542 dev_put(dev);
2543 out_rtnl:
2544 rtnl_unlock();
2545 2351
2546 return err; 2352 return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
2547} 2353}
2354
2548static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) 2355static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2549{ 2356{
2550 struct cfg80211_registered_device *rdev; 2357 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2551 int err; 2358 struct net_device *dev = info->user_ptr[1];
2552 struct net_device *dev;
2553 u8 *dst = NULL; 2359 u8 *dst = NULL;
2554 u8 *next_hop = NULL; 2360 u8 *next_hop = NULL;
2555 2361
@@ -2562,75 +2368,34 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2562 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2368 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2563 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 2369 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
2564 2370
2565 rtnl_lock(); 2371 if (!rdev->ops->add_mpath)
2566 2372 return -EOPNOTSUPP;
2567 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2568 if (err)
2569 goto out_rtnl;
2570
2571 if (!rdev->ops->add_mpath) {
2572 err = -EOPNOTSUPP;
2573 goto out;
2574 }
2575
2576 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2577 err = -EOPNOTSUPP;
2578 goto out;
2579 }
2580
2581 if (!netif_running(dev)) {
2582 err = -ENETDOWN;
2583 goto out;
2584 }
2585
2586 err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
2587 2373
2588 out: 2374 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
2589 cfg80211_unlock_rdev(rdev); 2375 return -EOPNOTSUPP;
2590 dev_put(dev);
2591 out_rtnl:
2592 rtnl_unlock();
2593 2376
2594 return err; 2377 return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
2595} 2378}
2596 2379
2597static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) 2380static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
2598{ 2381{
2599 struct cfg80211_registered_device *rdev; 2382 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2600 int err; 2383 struct net_device *dev = info->user_ptr[1];
2601 struct net_device *dev;
2602 u8 *dst = NULL; 2384 u8 *dst = NULL;
2603 2385
2604 if (info->attrs[NL80211_ATTR_MAC]) 2386 if (info->attrs[NL80211_ATTR_MAC])
2605 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2387 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2606 2388
2607 rtnl_lock(); 2389 if (!rdev->ops->del_mpath)
2608 2390 return -EOPNOTSUPP;
2609 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2610 if (err)
2611 goto out_rtnl;
2612
2613 if (!rdev->ops->del_mpath) {
2614 err = -EOPNOTSUPP;
2615 goto out;
2616 }
2617
2618 err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
2619
2620 out:
2621 cfg80211_unlock_rdev(rdev);
2622 dev_put(dev);
2623 out_rtnl:
2624 rtnl_unlock();
2625 2391
2626 return err; 2392 return rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
2627} 2393}
2628 2394
2629static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) 2395static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2630{ 2396{
2631 struct cfg80211_registered_device *rdev; 2397 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2632 int err; 2398 struct net_device *dev = info->user_ptr[1];
2633 struct net_device *dev;
2634 struct bss_parameters params; 2399 struct bss_parameters params;
2635 2400
2636 memset(&params, 0, sizeof(params)); 2401 memset(&params, 0, sizeof(params));
@@ -2658,32 +2423,14 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2658 if (info->attrs[NL80211_ATTR_AP_ISOLATE]) 2423 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
2659 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); 2424 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
2660 2425
2661 rtnl_lock(); 2426 if (!rdev->ops->change_bss)
2662 2427 return -EOPNOTSUPP;
2663 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2664 if (err)
2665 goto out_rtnl;
2666
2667 if (!rdev->ops->change_bss) {
2668 err = -EOPNOTSUPP;
2669 goto out;
2670 }
2671 2428
2672 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2429 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2673 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 2430 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2674 err = -EOPNOTSUPP; 2431 return -EOPNOTSUPP;
2675 goto out;
2676 }
2677
2678 err = rdev->ops->change_bss(&rdev->wiphy, dev, &params);
2679
2680 out:
2681 cfg80211_unlock_rdev(rdev);
2682 dev_put(dev);
2683 out_rtnl:
2684 rtnl_unlock();
2685 2432
2686 return err; 2433 return rdev->ops->change_bss(&rdev->wiphy, dev, &params);
2687} 2434}
2688 2435
2689static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { 2436static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
@@ -2762,37 +2509,26 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2762static int nl80211_get_mesh_params(struct sk_buff *skb, 2509static int nl80211_get_mesh_params(struct sk_buff *skb,
2763 struct genl_info *info) 2510 struct genl_info *info)
2764{ 2511{
2765 struct cfg80211_registered_device *rdev; 2512 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2766 struct mesh_config cur_params; 2513 struct mesh_config cur_params;
2767 int err; 2514 int err;
2768 struct net_device *dev; 2515 struct net_device *dev = info->user_ptr[1];
2769 void *hdr; 2516 void *hdr;
2770 struct nlattr *pinfoattr; 2517 struct nlattr *pinfoattr;
2771 struct sk_buff *msg; 2518 struct sk_buff *msg;
2772 2519
2773 rtnl_lock(); 2520 if (!rdev->ops->get_mesh_params)
2774 2521 return -EOPNOTSUPP;
2775 /* Look up our device */
2776 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2777 if (err)
2778 goto out_rtnl;
2779
2780 if (!rdev->ops->get_mesh_params) {
2781 err = -EOPNOTSUPP;
2782 goto out;
2783 }
2784 2522
2785 /* Get the mesh params */ 2523 /* Get the mesh params */
2786 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params); 2524 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
2787 if (err) 2525 if (err)
2788 goto out; 2526 return err;
2789 2527
2790 /* Draw up a netlink message to send back */ 2528 /* Draw up a netlink message to send back */
2791 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2529 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2792 if (!msg) { 2530 if (!msg)
2793 err = -ENOBUFS; 2531 return -ENOMEM;
2794 goto out;
2795 }
2796 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2532 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2797 NL80211_CMD_GET_MESH_PARAMS); 2533 NL80211_CMD_GET_MESH_PARAMS);
2798 if (!hdr) 2534 if (!hdr)
@@ -2831,21 +2567,12 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2831 cur_params.dot11MeshHWMPRootMode); 2567 cur_params.dot11MeshHWMPRootMode);
2832 nla_nest_end(msg, pinfoattr); 2568 nla_nest_end(msg, pinfoattr);
2833 genlmsg_end(msg, hdr); 2569 genlmsg_end(msg, hdr);
2834 err = genlmsg_reply(msg, info); 2570 return genlmsg_reply(msg, info);
2835 goto out;
2836 2571
2837 nla_put_failure: 2572 nla_put_failure:
2838 genlmsg_cancel(msg, hdr); 2573 genlmsg_cancel(msg, hdr);
2839 nlmsg_free(msg); 2574 nlmsg_free(msg);
2840 err = -EMSGSIZE; 2575 return -ENOBUFS;
2841 out:
2842 /* Cleanup */
2843 cfg80211_unlock_rdev(rdev);
2844 dev_put(dev);
2845 out_rtnl:
2846 rtnl_unlock();
2847
2848 return err;
2849} 2576}
2850 2577
2851#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ 2578#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
@@ -2875,10 +2602,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2875 2602
2876static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) 2603static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2877{ 2604{
2878 int err;
2879 u32 mask; 2605 u32 mask;
2880 struct cfg80211_registered_device *rdev; 2606 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2881 struct net_device *dev; 2607 struct net_device *dev = info->user_ptr[1];
2882 struct mesh_config cfg; 2608 struct mesh_config cfg;
2883 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; 2609 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
2884 struct nlattr *parent_attr; 2610 struct nlattr *parent_attr;
@@ -2890,16 +2616,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2890 parent_attr, nl80211_meshconf_params_policy)) 2616 parent_attr, nl80211_meshconf_params_policy))
2891 return -EINVAL; 2617 return -EINVAL;
2892 2618
2893 rtnl_lock(); 2619 if (!rdev->ops->set_mesh_params)
2894 2620 return -EOPNOTSUPP;
2895 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2896 if (err)
2897 goto out_rtnl;
2898
2899 if (!rdev->ops->set_mesh_params) {
2900 err = -EOPNOTSUPP;
2901 goto out;
2902 }
2903 2621
2904 /* This makes sure that there aren't more than 32 mesh config 2622 /* This makes sure that there aren't more than 32 mesh config
2905 * parameters (otherwise our bitfield scheme would not work.) */ 2623 * parameters (otherwise our bitfield scheme would not work.) */
@@ -2945,16 +2663,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2945 nla_get_u8); 2663 nla_get_u8);
2946 2664
2947 /* Apply changes */ 2665 /* Apply changes */
2948 err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); 2666 return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
2949
2950 out:
2951 /* cleanup */
2952 cfg80211_unlock_rdev(rdev);
2953 dev_put(dev);
2954 out_rtnl:
2955 rtnl_unlock();
2956
2957 return err;
2958} 2667}
2959 2668
2960#undef FILL_IN_MESH_PARAM_IF_SET 2669#undef FILL_IN_MESH_PARAM_IF_SET
@@ -3137,8 +2846,8 @@ static int validate_scan_freqs(struct nlattr *freqs)
3137 2846
3138static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 2847static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3139{ 2848{
3140 struct cfg80211_registered_device *rdev; 2849 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3141 struct net_device *dev; 2850 struct net_device *dev = info->user_ptr[1];
3142 struct cfg80211_scan_request *request; 2851 struct cfg80211_scan_request *request;
3143 struct cfg80211_ssid *ssid; 2852 struct cfg80211_ssid *ssid;
3144 struct ieee80211_channel *channel; 2853 struct ieee80211_channel *channel;
@@ -3151,36 +2860,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3151 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 2860 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3152 return -EINVAL; 2861 return -EINVAL;
3153 2862
3154 rtnl_lock();
3155
3156 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3157 if (err)
3158 goto out_rtnl;
3159
3160 wiphy = &rdev->wiphy; 2863 wiphy = &rdev->wiphy;
3161 2864
3162 if (!rdev->ops->scan) { 2865 if (!rdev->ops->scan)
3163 err = -EOPNOTSUPP; 2866 return -EOPNOTSUPP;
3164 goto out;
3165 }
3166
3167 if (!netif_running(dev)) {
3168 err = -ENETDOWN;
3169 goto out;
3170 }
3171 2867
3172 if (rdev->scan_req) { 2868 if (rdev->scan_req)
3173 err = -EBUSY; 2869 return -EBUSY;
3174 goto out;
3175 }
3176 2870
3177 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 2871 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3178 n_channels = validate_scan_freqs( 2872 n_channels = validate_scan_freqs(
3179 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); 2873 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
3180 if (!n_channels) { 2874 if (!n_channels)
3181 err = -EINVAL; 2875 return -EINVAL;
3182 goto out;
3183 }
3184 } else { 2876 } else {
3185 n_channels = 0; 2877 n_channels = 0;
3186 2878
@@ -3193,29 +2885,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3193 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) 2885 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
3194 n_ssids++; 2886 n_ssids++;
3195 2887
3196 if (n_ssids > wiphy->max_scan_ssids) { 2888 if (n_ssids > wiphy->max_scan_ssids)
3197 err = -EINVAL; 2889 return -EINVAL;
3198 goto out;
3199 }
3200 2890
3201 if (info->attrs[NL80211_ATTR_IE]) 2891 if (info->attrs[NL80211_ATTR_IE])
3202 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2892 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3203 else 2893 else
3204 ie_len = 0; 2894 ie_len = 0;
3205 2895
3206 if (ie_len > wiphy->max_scan_ie_len) { 2896 if (ie_len > wiphy->max_scan_ie_len)
3207 err = -EINVAL; 2897 return -EINVAL;
3208 goto out;
3209 }
3210 2898
3211 request = kzalloc(sizeof(*request) 2899 request = kzalloc(sizeof(*request)
3212 + sizeof(*ssid) * n_ssids 2900 + sizeof(*ssid) * n_ssids
3213 + sizeof(channel) * n_channels 2901 + sizeof(channel) * n_channels
3214 + ie_len, GFP_KERNEL); 2902 + ie_len, GFP_KERNEL);
3215 if (!request) { 2903 if (!request)
3216 err = -ENOMEM; 2904 return -ENOMEM;
3217 goto out;
3218 }
3219 2905
3220 if (n_ssids) 2906 if (n_ssids)
3221 request->ssids = (void *)&request->channels[n_channels]; 2907 request->ssids = (void *)&request->channels[n_channels];
@@ -3303,18 +2989,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3303 if (!err) { 2989 if (!err) {
3304 nl80211_send_scan_start(rdev, dev); 2990 nl80211_send_scan_start(rdev, dev);
3305 dev_hold(dev); 2991 dev_hold(dev);
3306 } 2992 } else {
3307
3308 out_free: 2993 out_free:
3309 if (err) {
3310 rdev->scan_req = NULL; 2994 rdev->scan_req = NULL;
3311 kfree(request); 2995 kfree(request);
3312 } 2996 }
3313 out:
3314 cfg80211_unlock_rdev(rdev);
3315 dev_put(dev);
3316 out_rtnl:
3317 rtnl_unlock();
3318 2997
3319 return err; 2998 return err;
3320} 2999}
@@ -3411,25 +3090,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3411 struct net_device *dev; 3090 struct net_device *dev;
3412 struct cfg80211_internal_bss *scan; 3091 struct cfg80211_internal_bss *scan;
3413 struct wireless_dev *wdev; 3092 struct wireless_dev *wdev;
3414 int ifidx = cb->args[0];
3415 int start = cb->args[1], idx = 0; 3093 int start = cb->args[1], idx = 0;
3416 int err; 3094 int err;
3417 3095
3418 if (!ifidx) 3096 err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
3419 ifidx = nl80211_get_ifidx(cb); 3097 if (err)
3420 if (ifidx < 0) 3098 return err;
3421 return ifidx;
3422 cb->args[0] = ifidx;
3423
3424 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3425 if (!dev)
3426 return -ENODEV;
3427
3428 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3429 if (IS_ERR(rdev)) {
3430 err = PTR_ERR(rdev);
3431 goto out_put_netdev;
3432 }
3433 3099
3434 wdev = dev->ieee80211_ptr; 3100 wdev = dev->ieee80211_ptr;
3435 3101
@@ -3445,21 +3111,17 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3445 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3111 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3446 rdev, wdev, scan) < 0) { 3112 rdev, wdev, scan) < 0) {
3447 idx--; 3113 idx--;
3448 goto out; 3114 break;
3449 } 3115 }
3450 } 3116 }
3451 3117
3452 out:
3453 spin_unlock_bh(&rdev->bss_lock); 3118 spin_unlock_bh(&rdev->bss_lock);
3454 wdev_unlock(wdev); 3119 wdev_unlock(wdev);
3455 3120
3456 cb->args[1] = idx; 3121 cb->args[1] = idx;
3457 err = skb->len; 3122 nl80211_finish_netdev_dump(rdev);
3458 cfg80211_unlock_rdev(rdev);
3459 out_put_netdev:
3460 dev_put(dev);
3461 3123
3462 return err; 3124 return skb->len;
3463} 3125}
3464 3126
3465static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, 3127static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
@@ -3489,6 +3151,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3489 if (survey->filled & SURVEY_INFO_NOISE_DBM) 3151 if (survey->filled & SURVEY_INFO_NOISE_DBM)
3490 NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE, 3152 NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE,
3491 survey->noise); 3153 survey->noise);
3154 if (survey->filled & SURVEY_INFO_IN_USE)
3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
3492 3156
3493 nla_nest_end(msg, infoattr); 3157 nla_nest_end(msg, infoattr);
3494 3158
@@ -3505,29 +3169,12 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3505 struct survey_info survey; 3169 struct survey_info survey;
3506 struct cfg80211_registered_device *dev; 3170 struct cfg80211_registered_device *dev;
3507 struct net_device *netdev; 3171 struct net_device *netdev;
3508 int ifidx = cb->args[0];
3509 int survey_idx = cb->args[1]; 3172 int survey_idx = cb->args[1];
3510 int res; 3173 int res;
3511 3174
3512 if (!ifidx) 3175 res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
3513 ifidx = nl80211_get_ifidx(cb); 3176 if (res)
3514 if (ifidx < 0) 3177 return res;
3515 return ifidx;
3516 cb->args[0] = ifidx;
3517
3518 rtnl_lock();
3519
3520 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3521 if (!netdev) {
3522 res = -ENODEV;
3523 goto out_rtnl;
3524 }
3525
3526 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3527 if (IS_ERR(dev)) {
3528 res = PTR_ERR(dev);
3529 goto out_rtnl;
3530 }
3531 3178
3532 if (!dev->ops->dump_survey) { 3179 if (!dev->ops->dump_survey) {
3533 res = -EOPNOTSUPP; 3180 res = -EOPNOTSUPP;
@@ -3555,10 +3202,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3555 cb->args[1] = survey_idx; 3202 cb->args[1] = survey_idx;
3556 res = skb->len; 3203 res = skb->len;
3557 out_err: 3204 out_err:
3558 cfg80211_unlock_rdev(dev); 3205 nl80211_finish_netdev_dump(dev);
3559 out_rtnl:
3560 rtnl_unlock();
3561
3562 return res; 3206 return res;
3563} 3207}
3564 3208
@@ -3591,8 +3235,8 @@ static bool nl80211_valid_cipher_suite(u32 cipher)
3591 3235
3592static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) 3236static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3593{ 3237{
3594 struct cfg80211_registered_device *rdev; 3238 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3595 struct net_device *dev; 3239 struct net_device *dev = info->user_ptr[1];
3596 struct ieee80211_channel *chan; 3240 struct ieee80211_channel *chan;
3597 const u8 *bssid, *ssid, *ie = NULL; 3241 const u8 *bssid, *ssid, *ie = NULL;
3598 int err, ssid_len, ie_len = 0; 3242 int err, ssid_len, ie_len = 0;
@@ -3620,6 +3264,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3620 return err; 3264 return err;
3621 3265
3622 if (key.idx >= 0) { 3266 if (key.idx >= 0) {
3267 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
3268 return -EINVAL;
3623 if (!key.p.key || !key.p.key_len) 3269 if (!key.p.key || !key.p.key_len)
3624 return -EINVAL; 3270 return -EINVAL;
3625 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 || 3271 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
@@ -3634,12 +3280,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3634 key.p.key = NULL; 3280 key.p.key = NULL;
3635 } 3281 }
3636 3282
3637 rtnl_lock();
3638
3639 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3640 if (err)
3641 goto unlock_rtnl;
3642
3643 if (key.idx >= 0) { 3283 if (key.idx >= 0) {
3644 int i; 3284 int i;
3645 bool ok = false; 3285 bool ok = false;
@@ -3649,35 +3289,22 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3649 break; 3289 break;
3650 } 3290 }
3651 } 3291 }
3652 if (!ok) { 3292 if (!ok)
3653 err = -EINVAL; 3293 return -EINVAL;
3654 goto out;
3655 }
3656 } 3294 }
3657 3295
3658 if (!rdev->ops->auth) { 3296 if (!rdev->ops->auth)
3659 err = -EOPNOTSUPP; 3297 return -EOPNOTSUPP;
3660 goto out;
3661 }
3662 3298
3663 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3299 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3664 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3300 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3665 err = -EOPNOTSUPP; 3301 return -EOPNOTSUPP;
3666 goto out;
3667 }
3668
3669 if (!netif_running(dev)) {
3670 err = -ENETDOWN;
3671 goto out;
3672 }
3673 3302
3674 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3303 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3675 chan = ieee80211_get_channel(&rdev->wiphy, 3304 chan = ieee80211_get_channel(&rdev->wiphy,
3676 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3305 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3677 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { 3306 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
3678 err = -EINVAL; 3307 return -EINVAL;
3679 goto out;
3680 }
3681 3308
3682 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 3309 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3683 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 3310 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -3688,24 +3315,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3688 } 3315 }
3689 3316
3690 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 3317 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
3691 if (!nl80211_valid_auth_type(auth_type)) { 3318 if (!nl80211_valid_auth_type(auth_type))
3692 err = -EINVAL; 3319 return -EINVAL;
3693 goto out;
3694 }
3695 3320
3696 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 3321 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3697 3322
3698 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 3323 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
3699 ssid, ssid_len, ie, ie_len, 3324 ssid, ssid_len, ie, ie_len,
3700 key.p.key, key.p.key_len, key.idx, 3325 key.p.key, key.p.key_len, key.idx,
3701 local_state_change); 3326 local_state_change);
3702
3703out:
3704 cfg80211_unlock_rdev(rdev);
3705 dev_put(dev);
3706unlock_rtnl:
3707 rtnl_unlock();
3708 return err;
3709} 3327}
3710 3328
3711static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, 3329static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -3789,8 +3407,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
3789 3407
3790static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) 3408static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3791{ 3409{
3792 struct cfg80211_registered_device *rdev; 3410 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3793 struct net_device *dev; 3411 struct net_device *dev = info->user_ptr[1];
3794 struct cfg80211_crypto_settings crypto; 3412 struct cfg80211_crypto_settings crypto;
3795 struct ieee80211_channel *chan; 3413 struct ieee80211_channel *chan;
3796 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; 3414 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
@@ -3805,36 +3423,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3805 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 3423 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
3806 return -EINVAL; 3424 return -EINVAL;
3807 3425
3808 rtnl_lock(); 3426 if (!rdev->ops->assoc)
3809 3427 return -EOPNOTSUPP;
3810 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3811 if (err)
3812 goto unlock_rtnl;
3813
3814 if (!rdev->ops->assoc) {
3815 err = -EOPNOTSUPP;
3816 goto out;
3817 }
3818 3428
3819 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3429 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3820 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3430 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3821 err = -EOPNOTSUPP; 3431 return -EOPNOTSUPP;
3822 goto out;
3823 }
3824
3825 if (!netif_running(dev)) {
3826 err = -ENETDOWN;
3827 goto out;
3828 }
3829 3432
3830 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3433 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3831 3434
3832 chan = ieee80211_get_channel(&rdev->wiphy, 3435 chan = ieee80211_get_channel(&rdev->wiphy,
3833 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3436 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3834 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { 3437 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
3835 err = -EINVAL; 3438 return -EINVAL;
3836 goto out;
3837 }
3838 3439
3839 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 3440 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3840 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 3441 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -3849,10 +3450,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3849 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); 3450 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
3850 if (mfp == NL80211_MFP_REQUIRED) 3451 if (mfp == NL80211_MFP_REQUIRED)
3851 use_mfp = true; 3452 use_mfp = true;
3852 else if (mfp != NL80211_MFP_NO) { 3453 else if (mfp != NL80211_MFP_NO)
3853 err = -EINVAL; 3454 return -EINVAL;
3854 goto out;
3855 }
3856 } 3455 }
3857 3456
3858 if (info->attrs[NL80211_ATTR_PREV_BSSID]) 3457 if (info->attrs[NL80211_ATTR_PREV_BSSID])
@@ -3864,20 +3463,15 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3864 ssid, ssid_len, ie, ie_len, use_mfp, 3463 ssid, ssid_len, ie, ie_len, use_mfp,
3865 &crypto); 3464 &crypto);
3866 3465
3867out:
3868 cfg80211_unlock_rdev(rdev);
3869 dev_put(dev);
3870unlock_rtnl:
3871 rtnl_unlock();
3872 return err; 3466 return err;
3873} 3467}
3874 3468
3875static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) 3469static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3876{ 3470{
3877 struct cfg80211_registered_device *rdev; 3471 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3878 struct net_device *dev; 3472 struct net_device *dev = info->user_ptr[1];
3879 const u8 *ie = NULL, *bssid; 3473 const u8 *ie = NULL, *bssid;
3880 int err, ie_len = 0; 3474 int ie_len = 0;
3881 u16 reason_code; 3475 u16 reason_code;
3882 bool local_state_change; 3476 bool local_state_change;
3883 3477
@@ -3890,35 +3484,19 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3890 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 3484 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3891 return -EINVAL; 3485 return -EINVAL;
3892 3486
3893 rtnl_lock(); 3487 if (!rdev->ops->deauth)
3894 3488 return -EOPNOTSUPP;
3895 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3896 if (err)
3897 goto unlock_rtnl;
3898
3899 if (!rdev->ops->deauth) {
3900 err = -EOPNOTSUPP;
3901 goto out;
3902 }
3903 3489
3904 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3490 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3905 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3491 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3906 err = -EOPNOTSUPP; 3492 return -EOPNOTSUPP;
3907 goto out;
3908 }
3909
3910 if (!netif_running(dev)) {
3911 err = -ENETDOWN;
3912 goto out;
3913 }
3914 3493
3915 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3494 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3916 3495
3917 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3496 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3918 if (reason_code == 0) { 3497 if (reason_code == 0) {
3919 /* Reason Code 0 is reserved */ 3498 /* Reason Code 0 is reserved */
3920 err = -EINVAL; 3499 return -EINVAL;
3921 goto out;
3922 } 3500 }
3923 3501
3924 if (info->attrs[NL80211_ATTR_IE]) { 3502 if (info->attrs[NL80211_ATTR_IE]) {
@@ -3928,23 +3506,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3928 3506
3929 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 3507 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3930 3508
3931 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, 3509 return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
3932 local_state_change); 3510 local_state_change);
3933
3934out:
3935 cfg80211_unlock_rdev(rdev);
3936 dev_put(dev);
3937unlock_rtnl:
3938 rtnl_unlock();
3939 return err;
3940} 3511}
3941 3512
3942static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) 3513static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3943{ 3514{
3944 struct cfg80211_registered_device *rdev; 3515 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3945 struct net_device *dev; 3516 struct net_device *dev = info->user_ptr[1];
3946 const u8 *ie = NULL, *bssid; 3517 const u8 *ie = NULL, *bssid;
3947 int err, ie_len = 0; 3518 int ie_len = 0;
3948 u16 reason_code; 3519 u16 reason_code;
3949 bool local_state_change; 3520 bool local_state_change;
3950 3521
@@ -3957,35 +3528,19 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3957 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 3528 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3958 return -EINVAL; 3529 return -EINVAL;
3959 3530
3960 rtnl_lock(); 3531 if (!rdev->ops->disassoc)
3961 3532 return -EOPNOTSUPP;
3962 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3963 if (err)
3964 goto unlock_rtnl;
3965
3966 if (!rdev->ops->disassoc) {
3967 err = -EOPNOTSUPP;
3968 goto out;
3969 }
3970 3533
3971 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3534 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3972 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3535 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3973 err = -EOPNOTSUPP; 3536 return -EOPNOTSUPP;
3974 goto out;
3975 }
3976
3977 if (!netif_running(dev)) {
3978 err = -ENETDOWN;
3979 goto out;
3980 }
3981 3537
3982 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3538 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3983 3539
3984 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3540 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3985 if (reason_code == 0) { 3541 if (reason_code == 0) {
3986 /* Reason Code 0 is reserved */ 3542 /* Reason Code 0 is reserved */
3987 err = -EINVAL; 3543 return -EINVAL;
3988 goto out;
3989 } 3544 }
3990 3545
3991 if (info->attrs[NL80211_ATTR_IE]) { 3546 if (info->attrs[NL80211_ATTR_IE]) {
@@ -3995,21 +3550,14 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3995 3550
3996 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 3551 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3997 3552
3998 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, 3553 return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
3999 local_state_change); 3554 local_state_change);
4000
4001out:
4002 cfg80211_unlock_rdev(rdev);
4003 dev_put(dev);
4004unlock_rtnl:
4005 rtnl_unlock();
4006 return err;
4007} 3555}
4008 3556
4009static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) 3557static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4010{ 3558{
4011 struct cfg80211_registered_device *rdev; 3559 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4012 struct net_device *dev; 3560 struct net_device *dev = info->user_ptr[1];
4013 struct cfg80211_ibss_params ibss; 3561 struct cfg80211_ibss_params ibss;
4014 struct wiphy *wiphy; 3562 struct wiphy *wiphy;
4015 struct cfg80211_cached_keys *connkeys = NULL; 3563 struct cfg80211_cached_keys *connkeys = NULL;
@@ -4034,26 +3582,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4034 return -EINVAL; 3582 return -EINVAL;
4035 } 3583 }
4036 3584
4037 rtnl_lock(); 3585 if (!rdev->ops->join_ibss)
4038 3586 return -EOPNOTSUPP;
4039 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4040 if (err)
4041 goto unlock_rtnl;
4042
4043 if (!rdev->ops->join_ibss) {
4044 err = -EOPNOTSUPP;
4045 goto out;
4046 }
4047
4048 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
4049 err = -EOPNOTSUPP;
4050 goto out;
4051 }
4052 3587
4053 if (!netif_running(dev)) { 3588 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
4054 err = -ENETDOWN; 3589 return -EOPNOTSUPP;
4055 goto out;
4056 }
4057 3590
4058 wiphy = &rdev->wiphy; 3591 wiphy = &rdev->wiphy;
4059 3592
@@ -4071,24 +3604,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4071 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3604 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4072 if (!ibss.channel || 3605 if (!ibss.channel ||
4073 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || 3606 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
4074 ibss.channel->flags & IEEE80211_CHAN_DISABLED) { 3607 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
4075 err = -EINVAL; 3608 return -EINVAL;
4076 goto out;
4077 }
4078 3609
4079 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 3610 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
4080 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 3611 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4081 3612
4082 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
4083 connkeys = nl80211_parse_connkeys(rdev,
4084 info->attrs[NL80211_ATTR_KEYS]);
4085 if (IS_ERR(connkeys)) {
4086 err = PTR_ERR(connkeys);
4087 connkeys = NULL;
4088 goto out;
4089 }
4090 }
4091
4092 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { 3613 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
4093 u8 *rates = 3614 u8 *rates =
4094 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 3615 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
@@ -4098,10 +3619,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4098 wiphy->bands[ibss.channel->band]; 3619 wiphy->bands[ibss.channel->band];
4099 int i, j; 3620 int i, j;
4100 3621
4101 if (n_rates == 0) { 3622 if (n_rates == 0)
4102 err = -EINVAL; 3623 return -EINVAL;
4103 goto out;
4104 }
4105 3624
4106 for (i = 0; i < n_rates; i++) { 3625 for (i = 0; i < n_rates; i++) {
4107 int rate = (rates[i] & 0x7f) * 5; 3626 int rate = (rates[i] & 0x7f) * 5;
@@ -4114,60 +3633,36 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4114 break; 3633 break;
4115 } 3634 }
4116 } 3635 }
4117 if (!found) { 3636 if (!found)
4118 err = -EINVAL; 3637 return -EINVAL;
4119 goto out;
4120 }
4121 } 3638 }
4122 } 3639 }
4123 3640
4124 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); 3641 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
3642 connkeys = nl80211_parse_connkeys(rdev,
3643 info->attrs[NL80211_ATTR_KEYS]);
3644 if (IS_ERR(connkeys))
3645 return PTR_ERR(connkeys);
3646 }
4125 3647
4126out: 3648 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
4127 cfg80211_unlock_rdev(rdev);
4128 dev_put(dev);
4129unlock_rtnl:
4130 if (err) 3649 if (err)
4131 kfree(connkeys); 3650 kfree(connkeys);
4132 rtnl_unlock();
4133 return err; 3651 return err;
4134} 3652}
4135 3653
4136static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) 3654static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
4137{ 3655{
4138 struct cfg80211_registered_device *rdev; 3656 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4139 struct net_device *dev; 3657 struct net_device *dev = info->user_ptr[1];
4140 int err;
4141 3658
4142 rtnl_lock(); 3659 if (!rdev->ops->leave_ibss)
4143 3660 return -EOPNOTSUPP;
4144 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4145 if (err)
4146 goto unlock_rtnl;
4147
4148 if (!rdev->ops->leave_ibss) {
4149 err = -EOPNOTSUPP;
4150 goto out;
4151 }
4152
4153 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
4154 err = -EOPNOTSUPP;
4155 goto out;
4156 }
4157
4158 if (!netif_running(dev)) {
4159 err = -ENETDOWN;
4160 goto out;
4161 }
4162 3661
4163 err = cfg80211_leave_ibss(rdev, dev, false); 3662 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
3663 return -EOPNOTSUPP;
4164 3664
4165out: 3665 return cfg80211_leave_ibss(rdev, dev, false);
4166 cfg80211_unlock_rdev(rdev);
4167 dev_put(dev);
4168unlock_rtnl:
4169 rtnl_unlock();
4170 return err;
4171} 3666}
4172 3667
4173#ifdef CONFIG_NL80211_TESTMODE 3668#ifdef CONFIG_NL80211_TESTMODE
@@ -4177,20 +3672,12 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = {
4177 3672
4178static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) 3673static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4179{ 3674{
4180 struct cfg80211_registered_device *rdev; 3675 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4181 int err; 3676 int err;
4182 3677
4183 if (!info->attrs[NL80211_ATTR_TESTDATA]) 3678 if (!info->attrs[NL80211_ATTR_TESTDATA])
4184 return -EINVAL; 3679 return -EINVAL;
4185 3680
4186 rtnl_lock();
4187
4188 rdev = cfg80211_get_dev_from_info(info);
4189 if (IS_ERR(rdev)) {
4190 err = PTR_ERR(rdev);
4191 goto unlock_rtnl;
4192 }
4193
4194 err = -EOPNOTSUPP; 3681 err = -EOPNOTSUPP;
4195 if (rdev->ops->testmode_cmd) { 3682 if (rdev->ops->testmode_cmd) {
4196 rdev->testmode_info = info; 3683 rdev->testmode_info = info;
@@ -4200,10 +3687,6 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4200 rdev->testmode_info = NULL; 3687 rdev->testmode_info = NULL;
4201 } 3688 }
4202 3689
4203 cfg80211_unlock_rdev(rdev);
4204
4205 unlock_rtnl:
4206 rtnl_unlock();
4207 return err; 3690 return err;
4208} 3691}
4209 3692
@@ -4294,8 +3777,8 @@ EXPORT_SYMBOL(cfg80211_testmode_event);
4294 3777
4295static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) 3778static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4296{ 3779{
4297 struct cfg80211_registered_device *rdev; 3780 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4298 struct net_device *dev; 3781 struct net_device *dev = info->user_ptr[1];
4299 struct cfg80211_connect_params connect; 3782 struct cfg80211_connect_params connect;
4300 struct wiphy *wiphy; 3783 struct wiphy *wiphy;
4301 struct cfg80211_cached_keys *connkeys = NULL; 3784 struct cfg80211_cached_keys *connkeys = NULL;
@@ -4324,22 +3807,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4324 NL80211_MAX_NR_CIPHER_SUITES); 3807 NL80211_MAX_NR_CIPHER_SUITES);
4325 if (err) 3808 if (err)
4326 return err; 3809 return err;
4327 rtnl_lock();
4328
4329 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4330 if (err)
4331 goto unlock_rtnl;
4332 3810
4333 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3811 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4334 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3812 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4335 err = -EOPNOTSUPP; 3813 return -EOPNOTSUPP;
4336 goto out;
4337 }
4338
4339 if (!netif_running(dev)) {
4340 err = -ENETDOWN;
4341 goto out;
4342 }
4343 3814
4344 wiphy = &rdev->wiphy; 3815 wiphy = &rdev->wiphy;
4345 3816
@@ -4358,39 +3829,27 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4358 ieee80211_get_channel(wiphy, 3829 ieee80211_get_channel(wiphy,
4359 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3830 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4360 if (!connect.channel || 3831 if (!connect.channel ||
4361 connect.channel->flags & IEEE80211_CHAN_DISABLED) { 3832 connect.channel->flags & IEEE80211_CHAN_DISABLED)
4362 err = -EINVAL; 3833 return -EINVAL;
4363 goto out;
4364 }
4365 } 3834 }
4366 3835
4367 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { 3836 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
4368 connkeys = nl80211_parse_connkeys(rdev, 3837 connkeys = nl80211_parse_connkeys(rdev,
4369 info->attrs[NL80211_ATTR_KEYS]); 3838 info->attrs[NL80211_ATTR_KEYS]);
4370 if (IS_ERR(connkeys)) { 3839 if (IS_ERR(connkeys))
4371 err = PTR_ERR(connkeys); 3840 return PTR_ERR(connkeys);
4372 connkeys = NULL;
4373 goto out;
4374 }
4375 } 3841 }
4376 3842
4377 err = cfg80211_connect(rdev, dev, &connect, connkeys); 3843 err = cfg80211_connect(rdev, dev, &connect, connkeys);
4378
4379out:
4380 cfg80211_unlock_rdev(rdev);
4381 dev_put(dev);
4382unlock_rtnl:
4383 if (err) 3844 if (err)
4384 kfree(connkeys); 3845 kfree(connkeys);
4385 rtnl_unlock();
4386 return err; 3846 return err;
4387} 3847}
4388 3848
4389static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) 3849static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4390{ 3850{
4391 struct cfg80211_registered_device *rdev; 3851 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4392 struct net_device *dev; 3852 struct net_device *dev = info->user_ptr[1];
4393 int err;
4394 u16 reason; 3853 u16 reason;
4395 3854
4396 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 3855 if (!info->attrs[NL80211_ATTR_REASON_CODE])
@@ -4401,36 +3860,16 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4401 if (reason == 0) 3860 if (reason == 0)
4402 return -EINVAL; 3861 return -EINVAL;
4403 3862
4404 rtnl_lock();
4405
4406 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4407 if (err)
4408 goto unlock_rtnl;
4409
4410 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3863 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4411 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3864 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4412 err = -EOPNOTSUPP; 3865 return -EOPNOTSUPP;
4413 goto out;
4414 }
4415
4416 if (!netif_running(dev)) {
4417 err = -ENETDOWN;
4418 goto out;
4419 }
4420
4421 err = cfg80211_disconnect(rdev, dev, reason, true);
4422 3866
4423out: 3867 return cfg80211_disconnect(rdev, dev, reason, true);
4424 cfg80211_unlock_rdev(rdev);
4425 dev_put(dev);
4426unlock_rtnl:
4427 rtnl_unlock();
4428 return err;
4429} 3868}
4430 3869
4431static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) 3870static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4432{ 3871{
4433 struct cfg80211_registered_device *rdev; 3872 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4434 struct net *net; 3873 struct net *net;
4435 int err; 3874 int err;
4436 u32 pid; 3875 u32 pid;
@@ -4440,43 +3879,26 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4440 3879
4441 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]); 3880 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
4442 3881
4443 rtnl_lock();
4444
4445 rdev = cfg80211_get_dev_from_info(info);
4446 if (IS_ERR(rdev)) {
4447 err = PTR_ERR(rdev);
4448 goto out_rtnl;
4449 }
4450
4451 net = get_net_ns_by_pid(pid); 3882 net = get_net_ns_by_pid(pid);
4452 if (IS_ERR(net)) { 3883 if (IS_ERR(net))
4453 err = PTR_ERR(net); 3884 return PTR_ERR(net);
4454 goto out;
4455 }
4456 3885
4457 err = 0; 3886 err = 0;
4458 3887
4459 /* check if anything to do */ 3888 /* check if anything to do */
4460 if (net_eq(wiphy_net(&rdev->wiphy), net)) 3889 if (!net_eq(wiphy_net(&rdev->wiphy), net))
4461 goto out_put_net; 3890 err = cfg80211_switch_netns(rdev, net);
4462 3891
4463 err = cfg80211_switch_netns(rdev, net);
4464 out_put_net:
4465 put_net(net); 3892 put_net(net);
4466 out:
4467 cfg80211_unlock_rdev(rdev);
4468 out_rtnl:
4469 rtnl_unlock();
4470 return err; 3893 return err;
4471} 3894}
4472 3895
4473static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) 3896static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4474{ 3897{
4475 struct cfg80211_registered_device *rdev; 3898 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4476 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev, 3899 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
4477 struct cfg80211_pmksa *pmksa) = NULL; 3900 struct cfg80211_pmksa *pmksa) = NULL;
4478 int err; 3901 struct net_device *dev = info->user_ptr[1];
4479 struct net_device *dev;
4480 struct cfg80211_pmksa pmksa; 3902 struct cfg80211_pmksa pmksa;
4481 3903
4482 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); 3904 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
@@ -4487,20 +3909,12 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4487 if (!info->attrs[NL80211_ATTR_PMKID]) 3909 if (!info->attrs[NL80211_ATTR_PMKID])
4488 return -EINVAL; 3910 return -EINVAL;
4489 3911
4490 rtnl_lock();
4491
4492 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4493 if (err)
4494 goto out_rtnl;
4495
4496 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); 3912 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
4497 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3913 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4498 3914
4499 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3915 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4500 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3916 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4501 err = -EOPNOTSUPP; 3917 return -EOPNOTSUPP;
4502 goto out;
4503 }
4504 3918
4505 switch (info->genlhdr->cmd) { 3919 switch (info->genlhdr->cmd) {
4506 case NL80211_CMD_SET_PMKSA: 3920 case NL80211_CMD_SET_PMKSA:
@@ -4514,62 +3928,32 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4514 break; 3928 break;
4515 } 3929 }
4516 3930
4517 if (!rdev_ops) { 3931 if (!rdev_ops)
4518 err = -EOPNOTSUPP; 3932 return -EOPNOTSUPP;
4519 goto out;
4520 }
4521
4522 err = rdev_ops(&rdev->wiphy, dev, &pmksa);
4523
4524 out:
4525 cfg80211_unlock_rdev(rdev);
4526 dev_put(dev);
4527 out_rtnl:
4528 rtnl_unlock();
4529 3933
4530 return err; 3934 return rdev_ops(&rdev->wiphy, dev, &pmksa);
4531} 3935}
4532 3936
4533static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) 3937static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4534{ 3938{
4535 struct cfg80211_registered_device *rdev; 3939 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4536 int err; 3940 struct net_device *dev = info->user_ptr[1];
4537 struct net_device *dev;
4538
4539 rtnl_lock();
4540
4541 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4542 if (err)
4543 goto out_rtnl;
4544 3941
4545 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3942 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4546 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3943 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4547 err = -EOPNOTSUPP; 3944 return -EOPNOTSUPP;
4548 goto out;
4549 }
4550
4551 if (!rdev->ops->flush_pmksa) {
4552 err = -EOPNOTSUPP;
4553 goto out;
4554 }
4555
4556 err = rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4557
4558 out:
4559 cfg80211_unlock_rdev(rdev);
4560 dev_put(dev);
4561 out_rtnl:
4562 rtnl_unlock();
4563 3945
4564 return err; 3946 if (!rdev->ops->flush_pmksa)
3947 return -EOPNOTSUPP;
4565 3948
3949 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4566} 3950}
4567 3951
4568static int nl80211_remain_on_channel(struct sk_buff *skb, 3952static int nl80211_remain_on_channel(struct sk_buff *skb,
4569 struct genl_info *info) 3953 struct genl_info *info)
4570{ 3954{
4571 struct cfg80211_registered_device *rdev; 3955 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4572 struct net_device *dev; 3956 struct net_device *dev = info->user_ptr[1];
4573 struct ieee80211_channel *chan; 3957 struct ieee80211_channel *chan;
4574 struct sk_buff *msg; 3958 struct sk_buff *msg;
4575 void *hdr; 3959 void *hdr;
@@ -4591,21 +3975,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4591 if (!duration || !msecs_to_jiffies(duration) || duration > 5000) 3975 if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
4592 return -EINVAL; 3976 return -EINVAL;
4593 3977
4594 rtnl_lock(); 3978 if (!rdev->ops->remain_on_channel)
4595 3979 return -EOPNOTSUPP;
4596 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4597 if (err)
4598 goto unlock_rtnl;
4599
4600 if (!rdev->ops->remain_on_channel) {
4601 err = -EOPNOTSUPP;
4602 goto out;
4603 }
4604
4605 if (!netif_running(dev)) {
4606 err = -ENETDOWN;
4607 goto out;
4608 }
4609 3980
4610 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 3981 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4611 channel_type = nla_get_u32( 3982 channel_type = nla_get_u32(
@@ -4613,24 +3984,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4613 if (channel_type != NL80211_CHAN_NO_HT && 3984 if (channel_type != NL80211_CHAN_NO_HT &&
4614 channel_type != NL80211_CHAN_HT20 && 3985 channel_type != NL80211_CHAN_HT20 &&
4615 channel_type != NL80211_CHAN_HT40PLUS && 3986 channel_type != NL80211_CHAN_HT40PLUS &&
4616 channel_type != NL80211_CHAN_HT40MINUS) { 3987 channel_type != NL80211_CHAN_HT40MINUS)
4617 err = -EINVAL; 3988 return -EINVAL;
4618 goto out;
4619 }
4620 } 3989 }
4621 3990
4622 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 3991 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
4623 chan = rdev_freq_to_chan(rdev, freq, channel_type); 3992 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4624 if (chan == NULL) { 3993 if (chan == NULL)
4625 err = -EINVAL; 3994 return -EINVAL;
4626 goto out;
4627 }
4628 3995
4629 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3996 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4630 if (!msg) { 3997 if (!msg)
4631 err = -ENOMEM; 3998 return -ENOMEM;
4632 goto out;
4633 }
4634 3999
4635 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 4000 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
4636 NL80211_CMD_REMAIN_ON_CHANNEL); 4001 NL80211_CMD_REMAIN_ON_CHANNEL);
@@ -4649,58 +4014,32 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4649 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); 4014 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
4650 4015
4651 genlmsg_end(msg, hdr); 4016 genlmsg_end(msg, hdr);
4652 err = genlmsg_reply(msg, info); 4017
4653 goto out; 4018 return genlmsg_reply(msg, info);
4654 4019
4655 nla_put_failure: 4020 nla_put_failure:
4656 err = -ENOBUFS; 4021 err = -ENOBUFS;
4657 free_msg: 4022 free_msg:
4658 nlmsg_free(msg); 4023 nlmsg_free(msg);
4659 out:
4660 cfg80211_unlock_rdev(rdev);
4661 dev_put(dev);
4662 unlock_rtnl:
4663 rtnl_unlock();
4664 return err; 4024 return err;
4665} 4025}
4666 4026
4667static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, 4027static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
4668 struct genl_info *info) 4028 struct genl_info *info)
4669{ 4029{
4670 struct cfg80211_registered_device *rdev; 4030 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4671 struct net_device *dev; 4031 struct net_device *dev = info->user_ptr[1];
4672 u64 cookie; 4032 u64 cookie;
4673 int err;
4674 4033
4675 if (!info->attrs[NL80211_ATTR_COOKIE]) 4034 if (!info->attrs[NL80211_ATTR_COOKIE])
4676 return -EINVAL; 4035 return -EINVAL;
4677 4036
4678 rtnl_lock(); 4037 if (!rdev->ops->cancel_remain_on_channel)
4679 4038 return -EOPNOTSUPP;
4680 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4681 if (err)
4682 goto unlock_rtnl;
4683
4684 if (!rdev->ops->cancel_remain_on_channel) {
4685 err = -EOPNOTSUPP;
4686 goto out;
4687 }
4688
4689 if (!netif_running(dev)) {
4690 err = -ENETDOWN;
4691 goto out;
4692 }
4693 4039
4694 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); 4040 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
4695 4041
4696 err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); 4042 return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
4697
4698 out:
4699 cfg80211_unlock_rdev(rdev);
4700 dev_put(dev);
4701 unlock_rtnl:
4702 rtnl_unlock();
4703 return err;
4704} 4043}
4705 4044
4706static u32 rateset_to_mask(struct ieee80211_supported_band *sband, 4045static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
@@ -4736,26 +4075,18 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4736 struct genl_info *info) 4075 struct genl_info *info)
4737{ 4076{
4738 struct nlattr *tb[NL80211_TXRATE_MAX + 1]; 4077 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4739 struct cfg80211_registered_device *rdev; 4078 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4740 struct cfg80211_bitrate_mask mask; 4079 struct cfg80211_bitrate_mask mask;
4741 int err, rem, i; 4080 int rem, i;
4742 struct net_device *dev; 4081 struct net_device *dev = info->user_ptr[1];
4743 struct nlattr *tx_rates; 4082 struct nlattr *tx_rates;
4744 struct ieee80211_supported_band *sband; 4083 struct ieee80211_supported_band *sband;
4745 4084
4746 if (info->attrs[NL80211_ATTR_TX_RATES] == NULL) 4085 if (info->attrs[NL80211_ATTR_TX_RATES] == NULL)
4747 return -EINVAL; 4086 return -EINVAL;
4748 4087
4749 rtnl_lock(); 4088 if (!rdev->ops->set_bitrate_mask)
4750 4089 return -EOPNOTSUPP;
4751 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4752 if (err)
4753 goto unlock_rtnl;
4754
4755 if (!rdev->ops->set_bitrate_mask) {
4756 err = -EOPNOTSUPP;
4757 goto unlock;
4758 }
4759 4090
4760 memset(&mask, 0, sizeof(mask)); 4091 memset(&mask, 0, sizeof(mask));
4761 /* Default to all rates enabled */ 4092 /* Default to all rates enabled */
@@ -4772,15 +4103,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4772 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) 4103 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
4773 { 4104 {
4774 enum ieee80211_band band = nla_type(tx_rates); 4105 enum ieee80211_band band = nla_type(tx_rates);
4775 if (band < 0 || band >= IEEE80211_NUM_BANDS) { 4106 if (band < 0 || band >= IEEE80211_NUM_BANDS)
4776 err = -EINVAL; 4107 return -EINVAL;
4777 goto unlock;
4778 }
4779 sband = rdev->wiphy.bands[band]; 4108 sband = rdev->wiphy.bands[band];
4780 if (sband == NULL) { 4109 if (sband == NULL)
4781 err = -EINVAL; 4110 return -EINVAL;
4782 goto unlock;
4783 }
4784 nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), 4111 nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
4785 nla_len(tx_rates), nl80211_txattr_policy); 4112 nla_len(tx_rates), nl80211_txattr_policy);
4786 if (tb[NL80211_TXRATE_LEGACY]) { 4113 if (tb[NL80211_TXRATE_LEGACY]) {
@@ -4788,29 +4115,19 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4788 sband, 4115 sband,
4789 nla_data(tb[NL80211_TXRATE_LEGACY]), 4116 nla_data(tb[NL80211_TXRATE_LEGACY]),
4790 nla_len(tb[NL80211_TXRATE_LEGACY])); 4117 nla_len(tb[NL80211_TXRATE_LEGACY]));
4791 if (mask.control[band].legacy == 0) { 4118 if (mask.control[band].legacy == 0)
4792 err = -EINVAL; 4119 return -EINVAL;
4793 goto unlock;
4794 }
4795 } 4120 }
4796 } 4121 }
4797 4122
4798 err = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); 4123 return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask);
4799
4800 unlock:
4801 dev_put(dev);
4802 cfg80211_unlock_rdev(rdev);
4803 unlock_rtnl:
4804 rtnl_unlock();
4805 return err;
4806} 4124}
4807 4125
4808static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) 4126static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4809{ 4127{
4810 struct cfg80211_registered_device *rdev; 4128 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4811 struct net_device *dev; 4129 struct net_device *dev = info->user_ptr[1];
4812 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; 4130 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
4813 int err;
4814 4131
4815 if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) 4132 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
4816 return -EINVAL; 4133 return -EINVAL;
@@ -4818,41 +4135,28 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4818 if (info->attrs[NL80211_ATTR_FRAME_TYPE]) 4135 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
4819 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); 4136 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
4820 4137
4821 rtnl_lock();
4822
4823 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4824 if (err)
4825 goto unlock_rtnl;
4826
4827 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 4138 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4828 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && 4139 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
4829 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4140 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4830 err = -EOPNOTSUPP; 4141 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4831 goto out; 4142 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4832 } 4143 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4144 return -EOPNOTSUPP;
4833 4145
4834 /* not much point in registering if we can't reply */ 4146 /* not much point in registering if we can't reply */
4835 if (!rdev->ops->mgmt_tx) { 4147 if (!rdev->ops->mgmt_tx)
4836 err = -EOPNOTSUPP; 4148 return -EOPNOTSUPP;
4837 goto out;
4838 }
4839 4149
4840 err = cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, 4150 return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid,
4841 frame_type, 4151 frame_type,
4842 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), 4152 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
4843 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); 4153 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
4844 out:
4845 cfg80211_unlock_rdev(rdev);
4846 dev_put(dev);
4847 unlock_rtnl:
4848 rtnl_unlock();
4849 return err;
4850} 4154}
4851 4155
4852static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) 4156static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4853{ 4157{
4854 struct cfg80211_registered_device *rdev; 4158 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4855 struct net_device *dev; 4159 struct net_device *dev = info->user_ptr[1];
4856 struct ieee80211_channel *chan; 4160 struct ieee80211_channel *chan;
4857 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 4161 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
4858 bool channel_type_valid = false; 4162 bool channel_type_valid = false;
@@ -4866,28 +4170,16 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4866 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 4170 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
4867 return -EINVAL; 4171 return -EINVAL;
4868 4172
4869 rtnl_lock(); 4173 if (!rdev->ops->mgmt_tx)
4870 4174 return -EOPNOTSUPP;
4871 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4872 if (err)
4873 goto unlock_rtnl;
4874
4875 if (!rdev->ops->mgmt_tx) {
4876 err = -EOPNOTSUPP;
4877 goto out;
4878 }
4879 4175
4880 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 4176 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4881 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && 4177 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
4882 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4178 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4883 err = -EOPNOTSUPP; 4179 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4884 goto out; 4180 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4885 } 4181 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4886 4182 return -EOPNOTSUPP;
4887 if (!netif_running(dev)) {
4888 err = -ENETDOWN;
4889 goto out;
4890 }
4891 4183
4892 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 4184 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4893 channel_type = nla_get_u32( 4185 channel_type = nla_get_u32(
@@ -4895,25 +4187,19 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4895 if (channel_type != NL80211_CHAN_NO_HT && 4187 if (channel_type != NL80211_CHAN_NO_HT &&
4896 channel_type != NL80211_CHAN_HT20 && 4188 channel_type != NL80211_CHAN_HT20 &&
4897 channel_type != NL80211_CHAN_HT40PLUS && 4189 channel_type != NL80211_CHAN_HT40PLUS &&
4898 channel_type != NL80211_CHAN_HT40MINUS) { 4190 channel_type != NL80211_CHAN_HT40MINUS)
4899 err = -EINVAL; 4191 return -EINVAL;
4900 goto out;
4901 }
4902 channel_type_valid = true; 4192 channel_type_valid = true;
4903 } 4193 }
4904 4194
4905 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 4195 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
4906 chan = rdev_freq_to_chan(rdev, freq, channel_type); 4196 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4907 if (chan == NULL) { 4197 if (chan == NULL)
4908 err = -EINVAL; 4198 return -EINVAL;
4909 goto out;
4910 }
4911 4199
4912 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4200 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4913 if (!msg) { 4201 if (!msg)
4914 err = -ENOMEM; 4202 return -ENOMEM;
4915 goto out;
4916 }
4917 4203
4918 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 4204 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
4919 NL80211_CMD_FRAME); 4205 NL80211_CMD_FRAME);
@@ -4933,110 +4219,72 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4933 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); 4219 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
4934 4220
4935 genlmsg_end(msg, hdr); 4221 genlmsg_end(msg, hdr);
4936 err = genlmsg_reply(msg, info); 4222 return genlmsg_reply(msg, info);
4937 goto out;
4938 4223
4939 nla_put_failure: 4224 nla_put_failure:
4940 err = -ENOBUFS; 4225 err = -ENOBUFS;
4941 free_msg: 4226 free_msg:
4942 nlmsg_free(msg); 4227 nlmsg_free(msg);
4943 out:
4944 cfg80211_unlock_rdev(rdev);
4945 dev_put(dev);
4946unlock_rtnl:
4947 rtnl_unlock();
4948 return err; 4228 return err;
4949} 4229}
4950 4230
4951static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) 4231static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
4952{ 4232{
4953 struct cfg80211_registered_device *rdev; 4233 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4954 struct wireless_dev *wdev; 4234 struct wireless_dev *wdev;
4955 struct net_device *dev; 4235 struct net_device *dev = info->user_ptr[1];
4956 u8 ps_state; 4236 u8 ps_state;
4957 bool state; 4237 bool state;
4958 int err; 4238 int err;
4959 4239
4960 if (!info->attrs[NL80211_ATTR_PS_STATE]) { 4240 if (!info->attrs[NL80211_ATTR_PS_STATE])
4961 err = -EINVAL; 4241 return -EINVAL;
4962 goto out;
4963 }
4964 4242
4965 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); 4243 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
4966 4244
4967 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) { 4245 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
4968 err = -EINVAL; 4246 return -EINVAL;
4969 goto out;
4970 }
4971
4972 rtnl_lock();
4973
4974 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4975 if (err)
4976 goto unlock_rtnl;
4977 4247
4978 wdev = dev->ieee80211_ptr; 4248 wdev = dev->ieee80211_ptr;
4979 4249
4980 if (!rdev->ops->set_power_mgmt) { 4250 if (!rdev->ops->set_power_mgmt)
4981 err = -EOPNOTSUPP; 4251 return -EOPNOTSUPP;
4982 goto unlock_rdev;
4983 }
4984 4252
4985 state = (ps_state == NL80211_PS_ENABLED) ? true : false; 4253 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
4986 4254
4987 if (state == wdev->ps) 4255 if (state == wdev->ps)
4988 goto unlock_rdev; 4256 return 0;
4989
4990 wdev->ps = state;
4991
4992 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps,
4993 wdev->ps_timeout))
4994 /* assume this means it's off */
4995 wdev->ps = false;
4996
4997unlock_rdev:
4998 cfg80211_unlock_rdev(rdev);
4999 dev_put(dev);
5000unlock_rtnl:
5001 rtnl_unlock();
5002 4257
5003out: 4258 err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state,
4259 wdev->ps_timeout);
4260 if (!err)
4261 wdev->ps = state;
5004 return err; 4262 return err;
5005} 4263}
5006 4264
5007static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) 4265static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
5008{ 4266{
5009 struct cfg80211_registered_device *rdev; 4267 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5010 enum nl80211_ps_state ps_state; 4268 enum nl80211_ps_state ps_state;
5011 struct wireless_dev *wdev; 4269 struct wireless_dev *wdev;
5012 struct net_device *dev; 4270 struct net_device *dev = info->user_ptr[1];
5013 struct sk_buff *msg; 4271 struct sk_buff *msg;
5014 void *hdr; 4272 void *hdr;
5015 int err; 4273 int err;
5016 4274
5017 rtnl_lock();
5018
5019 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5020 if (err)
5021 goto unlock_rtnl;
5022
5023 wdev = dev->ieee80211_ptr; 4275 wdev = dev->ieee80211_ptr;
5024 4276
5025 if (!rdev->ops->set_power_mgmt) { 4277 if (!rdev->ops->set_power_mgmt)
5026 err = -EOPNOTSUPP; 4278 return -EOPNOTSUPP;
5027 goto out;
5028 }
5029 4279
5030 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4280 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5031 if (!msg) { 4281 if (!msg)
5032 err = -ENOMEM; 4282 return -ENOMEM;
5033 goto out;
5034 }
5035 4283
5036 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 4284 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5037 NL80211_CMD_GET_POWER_SAVE); 4285 NL80211_CMD_GET_POWER_SAVE);
5038 if (!hdr) { 4286 if (!hdr) {
5039 err = -ENOMEM; 4287 err = -ENOBUFS;
5040 goto free_msg; 4288 goto free_msg;
5041 } 4289 }
5042 4290
@@ -5048,22 +4296,12 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
5048 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); 4296 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
5049 4297
5050 genlmsg_end(msg, hdr); 4298 genlmsg_end(msg, hdr);
5051 err = genlmsg_reply(msg, info); 4299 return genlmsg_reply(msg, info);
5052 goto out;
5053 4300
5054nla_put_failure: 4301 nla_put_failure:
5055 err = -ENOBUFS; 4302 err = -ENOBUFS;
5056 4303 free_msg:
5057free_msg:
5058 nlmsg_free(msg); 4304 nlmsg_free(msg);
5059
5060out:
5061 cfg80211_unlock_rdev(rdev);
5062 dev_put(dev);
5063
5064unlock_rtnl:
5065 rtnl_unlock();
5066
5067 return err; 4305 return err;
5068} 4306}
5069 4307
@@ -5077,42 +4315,24 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
5077static int nl80211_set_cqm_rssi(struct genl_info *info, 4315static int nl80211_set_cqm_rssi(struct genl_info *info,
5078 s32 threshold, u32 hysteresis) 4316 s32 threshold, u32 hysteresis)
5079{ 4317{
5080 struct cfg80211_registered_device *rdev; 4318 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5081 struct wireless_dev *wdev; 4319 struct wireless_dev *wdev;
5082 struct net_device *dev; 4320 struct net_device *dev = info->user_ptr[1];
5083 int err;
5084 4321
5085 if (threshold > 0) 4322 if (threshold > 0)
5086 return -EINVAL; 4323 return -EINVAL;
5087 4324
5088 rtnl_lock();
5089
5090 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5091 if (err)
5092 goto unlock_rdev;
5093
5094 wdev = dev->ieee80211_ptr; 4325 wdev = dev->ieee80211_ptr;
5095 4326
5096 if (!rdev->ops->set_cqm_rssi_config) { 4327 if (!rdev->ops->set_cqm_rssi_config)
5097 err = -EOPNOTSUPP; 4328 return -EOPNOTSUPP;
5098 goto unlock_rdev;
5099 }
5100 4329
5101 if (wdev->iftype != NL80211_IFTYPE_STATION && 4330 if (wdev->iftype != NL80211_IFTYPE_STATION &&
5102 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4331 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
5103 err = -EOPNOTSUPP; 4332 return -EOPNOTSUPP;
5104 goto unlock_rdev;
5105 }
5106
5107 err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
5108 threshold, hysteresis);
5109
5110unlock_rdev:
5111 cfg80211_unlock_rdev(rdev);
5112 dev_put(dev);
5113 rtnl_unlock();
5114 4333
5115 return err; 4334 return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
4335 threshold, hysteresis);
5116} 4336}
5117 4337
5118static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) 4338static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
@@ -5146,6 +4366,65 @@ out:
5146 return err; 4366 return err;
5147} 4367}
5148 4368
4369#define NL80211_FLAG_NEED_WIPHY 0x01
4370#define NL80211_FLAG_NEED_NETDEV 0x02
4371#define NL80211_FLAG_NEED_RTNL 0x04
4372#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
4373#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
4374 NL80211_FLAG_CHECK_NETDEV_UP)
4375
4376static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
4377 struct genl_info *info)
4378{
4379 struct cfg80211_registered_device *rdev;
4380 struct net_device *dev;
4381 int err;
4382 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
4383
4384 if (rtnl)
4385 rtnl_lock();
4386
4387 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4388 rdev = cfg80211_get_dev_from_info(info);
4389 if (IS_ERR(rdev)) {
4390 if (rtnl)
4391 rtnl_unlock();
4392 return PTR_ERR(rdev);
4393 }
4394 info->user_ptr[0] = rdev;
4395 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
4396 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4397 if (err) {
4398 if (rtnl)
4399 rtnl_unlock();
4400 return err;
4401 }
4402 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
4403 !netif_running(dev)) {
4404 cfg80211_unlock_rdev(rdev);
4405 dev_put(dev);
4406 if (rtnl)
4407 rtnl_unlock();
4408 return -ENETDOWN;
4409 }
4410 info->user_ptr[0] = rdev;
4411 info->user_ptr[1] = dev;
4412 }
4413
4414 return 0;
4415}
4416
4417static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
4418 struct genl_info *info)
4419{
4420 if (info->user_ptr[0])
4421 cfg80211_unlock_rdev(info->user_ptr[0]);
4422 if (info->user_ptr[1])
4423 dev_put(info->user_ptr[1]);
4424 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
4425 rtnl_unlock();
4426}
4427
5149static struct genl_ops nl80211_ops[] = { 4428static struct genl_ops nl80211_ops[] = {
5150 { 4429 {
5151 .cmd = NL80211_CMD_GET_WIPHY, 4430 .cmd = NL80211_CMD_GET_WIPHY,
@@ -5153,12 +4432,14 @@ static struct genl_ops nl80211_ops[] = {
5153 .dumpit = nl80211_dump_wiphy, 4432 .dumpit = nl80211_dump_wiphy,
5154 .policy = nl80211_policy, 4433 .policy = nl80211_policy,
5155 /* can be retrieved by unprivileged users */ 4434 /* can be retrieved by unprivileged users */
4435 .internal_flags = NL80211_FLAG_NEED_WIPHY,
5156 }, 4436 },
5157 { 4437 {
5158 .cmd = NL80211_CMD_SET_WIPHY, 4438 .cmd = NL80211_CMD_SET_WIPHY,
5159 .doit = nl80211_set_wiphy, 4439 .doit = nl80211_set_wiphy,
5160 .policy = nl80211_policy, 4440 .policy = nl80211_policy,
5161 .flags = GENL_ADMIN_PERM, 4441 .flags = GENL_ADMIN_PERM,
4442 .internal_flags = NL80211_FLAG_NEED_RTNL,
5162 }, 4443 },
5163 { 4444 {
5164 .cmd = NL80211_CMD_GET_INTERFACE, 4445 .cmd = NL80211_CMD_GET_INTERFACE,
@@ -5166,90 +4447,119 @@ static struct genl_ops nl80211_ops[] = {
5166 .dumpit = nl80211_dump_interface, 4447 .dumpit = nl80211_dump_interface,
5167 .policy = nl80211_policy, 4448 .policy = nl80211_policy,
5168 /* can be retrieved by unprivileged users */ 4449 /* can be retrieved by unprivileged users */
4450 .internal_flags = NL80211_FLAG_NEED_NETDEV,
5169 }, 4451 },
5170 { 4452 {
5171 .cmd = NL80211_CMD_SET_INTERFACE, 4453 .cmd = NL80211_CMD_SET_INTERFACE,
5172 .doit = nl80211_set_interface, 4454 .doit = nl80211_set_interface,
5173 .policy = nl80211_policy, 4455 .policy = nl80211_policy,
5174 .flags = GENL_ADMIN_PERM, 4456 .flags = GENL_ADMIN_PERM,
4457 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4458 NL80211_FLAG_NEED_RTNL,
5175 }, 4459 },
5176 { 4460 {
5177 .cmd = NL80211_CMD_NEW_INTERFACE, 4461 .cmd = NL80211_CMD_NEW_INTERFACE,
5178 .doit = nl80211_new_interface, 4462 .doit = nl80211_new_interface,
5179 .policy = nl80211_policy, 4463 .policy = nl80211_policy,
5180 .flags = GENL_ADMIN_PERM, 4464 .flags = GENL_ADMIN_PERM,
4465 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4466 NL80211_FLAG_NEED_RTNL,
5181 }, 4467 },
5182 { 4468 {
5183 .cmd = NL80211_CMD_DEL_INTERFACE, 4469 .cmd = NL80211_CMD_DEL_INTERFACE,
5184 .doit = nl80211_del_interface, 4470 .doit = nl80211_del_interface,
5185 .policy = nl80211_policy, 4471 .policy = nl80211_policy,
5186 .flags = GENL_ADMIN_PERM, 4472 .flags = GENL_ADMIN_PERM,
4473 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4474 NL80211_FLAG_NEED_RTNL,
5187 }, 4475 },
5188 { 4476 {
5189 .cmd = NL80211_CMD_GET_KEY, 4477 .cmd = NL80211_CMD_GET_KEY,
5190 .doit = nl80211_get_key, 4478 .doit = nl80211_get_key,
5191 .policy = nl80211_policy, 4479 .policy = nl80211_policy,
5192 .flags = GENL_ADMIN_PERM, 4480 .flags = GENL_ADMIN_PERM,
4481 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4482 NL80211_FLAG_NEED_RTNL,
5193 }, 4483 },
5194 { 4484 {
5195 .cmd = NL80211_CMD_SET_KEY, 4485 .cmd = NL80211_CMD_SET_KEY,
5196 .doit = nl80211_set_key, 4486 .doit = nl80211_set_key,
5197 .policy = nl80211_policy, 4487 .policy = nl80211_policy,
5198 .flags = GENL_ADMIN_PERM, 4488 .flags = GENL_ADMIN_PERM,
4489 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4490 NL80211_FLAG_NEED_RTNL,
5199 }, 4491 },
5200 { 4492 {
5201 .cmd = NL80211_CMD_NEW_KEY, 4493 .cmd = NL80211_CMD_NEW_KEY,
5202 .doit = nl80211_new_key, 4494 .doit = nl80211_new_key,
5203 .policy = nl80211_policy, 4495 .policy = nl80211_policy,
5204 .flags = GENL_ADMIN_PERM, 4496 .flags = GENL_ADMIN_PERM,
4497 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4498 NL80211_FLAG_NEED_RTNL,
5205 }, 4499 },
5206 { 4500 {
5207 .cmd = NL80211_CMD_DEL_KEY, 4501 .cmd = NL80211_CMD_DEL_KEY,
5208 .doit = nl80211_del_key, 4502 .doit = nl80211_del_key,
5209 .policy = nl80211_policy, 4503 .policy = nl80211_policy,
5210 .flags = GENL_ADMIN_PERM, 4504 .flags = GENL_ADMIN_PERM,
4505 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4506 NL80211_FLAG_NEED_RTNL,
5211 }, 4507 },
5212 { 4508 {
5213 .cmd = NL80211_CMD_SET_BEACON, 4509 .cmd = NL80211_CMD_SET_BEACON,
5214 .policy = nl80211_policy, 4510 .policy = nl80211_policy,
5215 .flags = GENL_ADMIN_PERM, 4511 .flags = GENL_ADMIN_PERM,
5216 .doit = nl80211_addset_beacon, 4512 .doit = nl80211_addset_beacon,
4513 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4514 NL80211_FLAG_NEED_RTNL,
5217 }, 4515 },
5218 { 4516 {
5219 .cmd = NL80211_CMD_NEW_BEACON, 4517 .cmd = NL80211_CMD_NEW_BEACON,
5220 .policy = nl80211_policy, 4518 .policy = nl80211_policy,
5221 .flags = GENL_ADMIN_PERM, 4519 .flags = GENL_ADMIN_PERM,
5222 .doit = nl80211_addset_beacon, 4520 .doit = nl80211_addset_beacon,
4521 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4522 NL80211_FLAG_NEED_RTNL,
5223 }, 4523 },
5224 { 4524 {
5225 .cmd = NL80211_CMD_DEL_BEACON, 4525 .cmd = NL80211_CMD_DEL_BEACON,
5226 .policy = nl80211_policy, 4526 .policy = nl80211_policy,
5227 .flags = GENL_ADMIN_PERM, 4527 .flags = GENL_ADMIN_PERM,
5228 .doit = nl80211_del_beacon, 4528 .doit = nl80211_del_beacon,
4529 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4530 NL80211_FLAG_NEED_RTNL,
5229 }, 4531 },
5230 { 4532 {
5231 .cmd = NL80211_CMD_GET_STATION, 4533 .cmd = NL80211_CMD_GET_STATION,
5232 .doit = nl80211_get_station, 4534 .doit = nl80211_get_station,
5233 .dumpit = nl80211_dump_station, 4535 .dumpit = nl80211_dump_station,
5234 .policy = nl80211_policy, 4536 .policy = nl80211_policy,
4537 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4538 NL80211_FLAG_NEED_RTNL,
5235 }, 4539 },
5236 { 4540 {
5237 .cmd = NL80211_CMD_SET_STATION, 4541 .cmd = NL80211_CMD_SET_STATION,
5238 .doit = nl80211_set_station, 4542 .doit = nl80211_set_station,
5239 .policy = nl80211_policy, 4543 .policy = nl80211_policy,
5240 .flags = GENL_ADMIN_PERM, 4544 .flags = GENL_ADMIN_PERM,
4545 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4546 NL80211_FLAG_NEED_RTNL,
5241 }, 4547 },
5242 { 4548 {
5243 .cmd = NL80211_CMD_NEW_STATION, 4549 .cmd = NL80211_CMD_NEW_STATION,
5244 .doit = nl80211_new_station, 4550 .doit = nl80211_new_station,
5245 .policy = nl80211_policy, 4551 .policy = nl80211_policy,
5246 .flags = GENL_ADMIN_PERM, 4552 .flags = GENL_ADMIN_PERM,
4553 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4554 NL80211_FLAG_NEED_RTNL,
5247 }, 4555 },
5248 { 4556 {
5249 .cmd = NL80211_CMD_DEL_STATION, 4557 .cmd = NL80211_CMD_DEL_STATION,
5250 .doit = nl80211_del_station, 4558 .doit = nl80211_del_station,
5251 .policy = nl80211_policy, 4559 .policy = nl80211_policy,
5252 .flags = GENL_ADMIN_PERM, 4560 .flags = GENL_ADMIN_PERM,
4561 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4562 NL80211_FLAG_NEED_RTNL,
5253 }, 4563 },
5254 { 4564 {
5255 .cmd = NL80211_CMD_GET_MPATH, 4565 .cmd = NL80211_CMD_GET_MPATH,
@@ -5257,30 +4567,40 @@ static struct genl_ops nl80211_ops[] = {
5257 .dumpit = nl80211_dump_mpath, 4567 .dumpit = nl80211_dump_mpath,
5258 .policy = nl80211_policy, 4568 .policy = nl80211_policy,
5259 .flags = GENL_ADMIN_PERM, 4569 .flags = GENL_ADMIN_PERM,
4570 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4571 NL80211_FLAG_NEED_RTNL,
5260 }, 4572 },
5261 { 4573 {
5262 .cmd = NL80211_CMD_SET_MPATH, 4574 .cmd = NL80211_CMD_SET_MPATH,
5263 .doit = nl80211_set_mpath, 4575 .doit = nl80211_set_mpath,
5264 .policy = nl80211_policy, 4576 .policy = nl80211_policy,
5265 .flags = GENL_ADMIN_PERM, 4577 .flags = GENL_ADMIN_PERM,
4578 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4579 NL80211_FLAG_NEED_RTNL,
5266 }, 4580 },
5267 { 4581 {
5268 .cmd = NL80211_CMD_NEW_MPATH, 4582 .cmd = NL80211_CMD_NEW_MPATH,
5269 .doit = nl80211_new_mpath, 4583 .doit = nl80211_new_mpath,
5270 .policy = nl80211_policy, 4584 .policy = nl80211_policy,
5271 .flags = GENL_ADMIN_PERM, 4585 .flags = GENL_ADMIN_PERM,
4586 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4587 NL80211_FLAG_NEED_RTNL,
5272 }, 4588 },
5273 { 4589 {
5274 .cmd = NL80211_CMD_DEL_MPATH, 4590 .cmd = NL80211_CMD_DEL_MPATH,
5275 .doit = nl80211_del_mpath, 4591 .doit = nl80211_del_mpath,
5276 .policy = nl80211_policy, 4592 .policy = nl80211_policy,
5277 .flags = GENL_ADMIN_PERM, 4593 .flags = GENL_ADMIN_PERM,
4594 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4595 NL80211_FLAG_NEED_RTNL,
5278 }, 4596 },
5279 { 4597 {
5280 .cmd = NL80211_CMD_SET_BSS, 4598 .cmd = NL80211_CMD_SET_BSS,
5281 .doit = nl80211_set_bss, 4599 .doit = nl80211_set_bss,
5282 .policy = nl80211_policy, 4600 .policy = nl80211_policy,
5283 .flags = GENL_ADMIN_PERM, 4601 .flags = GENL_ADMIN_PERM,
4602 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4603 NL80211_FLAG_NEED_RTNL,
5284 }, 4604 },
5285 { 4605 {
5286 .cmd = NL80211_CMD_GET_REG, 4606 .cmd = NL80211_CMD_GET_REG,
@@ -5305,18 +4625,24 @@ static struct genl_ops nl80211_ops[] = {
5305 .doit = nl80211_get_mesh_params, 4625 .doit = nl80211_get_mesh_params,
5306 .policy = nl80211_policy, 4626 .policy = nl80211_policy,
5307 /* can be retrieved by unprivileged users */ 4627 /* can be retrieved by unprivileged users */
4628 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4629 NL80211_FLAG_NEED_RTNL,
5308 }, 4630 },
5309 { 4631 {
5310 .cmd = NL80211_CMD_SET_MESH_PARAMS, 4632 .cmd = NL80211_CMD_SET_MESH_PARAMS,
5311 .doit = nl80211_set_mesh_params, 4633 .doit = nl80211_set_mesh_params,
5312 .policy = nl80211_policy, 4634 .policy = nl80211_policy,
5313 .flags = GENL_ADMIN_PERM, 4635 .flags = GENL_ADMIN_PERM,
4636 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4637 NL80211_FLAG_NEED_RTNL,
5314 }, 4638 },
5315 { 4639 {
5316 .cmd = NL80211_CMD_TRIGGER_SCAN, 4640 .cmd = NL80211_CMD_TRIGGER_SCAN,
5317 .doit = nl80211_trigger_scan, 4641 .doit = nl80211_trigger_scan,
5318 .policy = nl80211_policy, 4642 .policy = nl80211_policy,
5319 .flags = GENL_ADMIN_PERM, 4643 .flags = GENL_ADMIN_PERM,
4644 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4645 NL80211_FLAG_NEED_RTNL,
5320 }, 4646 },
5321 { 4647 {
5322 .cmd = NL80211_CMD_GET_SCAN, 4648 .cmd = NL80211_CMD_GET_SCAN,
@@ -5328,36 +4654,48 @@ static struct genl_ops nl80211_ops[] = {
5328 .doit = nl80211_authenticate, 4654 .doit = nl80211_authenticate,
5329 .policy = nl80211_policy, 4655 .policy = nl80211_policy,
5330 .flags = GENL_ADMIN_PERM, 4656 .flags = GENL_ADMIN_PERM,
4657 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4658 NL80211_FLAG_NEED_RTNL,
5331 }, 4659 },
5332 { 4660 {
5333 .cmd = NL80211_CMD_ASSOCIATE, 4661 .cmd = NL80211_CMD_ASSOCIATE,
5334 .doit = nl80211_associate, 4662 .doit = nl80211_associate,
5335 .policy = nl80211_policy, 4663 .policy = nl80211_policy,
5336 .flags = GENL_ADMIN_PERM, 4664 .flags = GENL_ADMIN_PERM,
4665 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4666 NL80211_FLAG_NEED_RTNL,
5337 }, 4667 },
5338 { 4668 {
5339 .cmd = NL80211_CMD_DEAUTHENTICATE, 4669 .cmd = NL80211_CMD_DEAUTHENTICATE,
5340 .doit = nl80211_deauthenticate, 4670 .doit = nl80211_deauthenticate,
5341 .policy = nl80211_policy, 4671 .policy = nl80211_policy,
5342 .flags = GENL_ADMIN_PERM, 4672 .flags = GENL_ADMIN_PERM,
4673 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4674 NL80211_FLAG_NEED_RTNL,
5343 }, 4675 },
5344 { 4676 {
5345 .cmd = NL80211_CMD_DISASSOCIATE, 4677 .cmd = NL80211_CMD_DISASSOCIATE,
5346 .doit = nl80211_disassociate, 4678 .doit = nl80211_disassociate,
5347 .policy = nl80211_policy, 4679 .policy = nl80211_policy,
5348 .flags = GENL_ADMIN_PERM, 4680 .flags = GENL_ADMIN_PERM,
4681 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4682 NL80211_FLAG_NEED_RTNL,
5349 }, 4683 },
5350 { 4684 {
5351 .cmd = NL80211_CMD_JOIN_IBSS, 4685 .cmd = NL80211_CMD_JOIN_IBSS,
5352 .doit = nl80211_join_ibss, 4686 .doit = nl80211_join_ibss,
5353 .policy = nl80211_policy, 4687 .policy = nl80211_policy,
5354 .flags = GENL_ADMIN_PERM, 4688 .flags = GENL_ADMIN_PERM,
4689 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4690 NL80211_FLAG_NEED_RTNL,
5355 }, 4691 },
5356 { 4692 {
5357 .cmd = NL80211_CMD_LEAVE_IBSS, 4693 .cmd = NL80211_CMD_LEAVE_IBSS,
5358 .doit = nl80211_leave_ibss, 4694 .doit = nl80211_leave_ibss,
5359 .policy = nl80211_policy, 4695 .policy = nl80211_policy,
5360 .flags = GENL_ADMIN_PERM, 4696 .flags = GENL_ADMIN_PERM,
4697 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4698 NL80211_FLAG_NEED_RTNL,
5361 }, 4699 },
5362#ifdef CONFIG_NL80211_TESTMODE 4700#ifdef CONFIG_NL80211_TESTMODE
5363 { 4701 {
@@ -5365,6 +4703,8 @@ static struct genl_ops nl80211_ops[] = {
5365 .doit = nl80211_testmode_do, 4703 .doit = nl80211_testmode_do,
5366 .policy = nl80211_policy, 4704 .policy = nl80211_policy,
5367 .flags = GENL_ADMIN_PERM, 4705 .flags = GENL_ADMIN_PERM,
4706 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4707 NL80211_FLAG_NEED_RTNL,
5368 }, 4708 },
5369#endif 4709#endif
5370 { 4710 {
@@ -5372,18 +4712,24 @@ static struct genl_ops nl80211_ops[] = {
5372 .doit = nl80211_connect, 4712 .doit = nl80211_connect,
5373 .policy = nl80211_policy, 4713 .policy = nl80211_policy,
5374 .flags = GENL_ADMIN_PERM, 4714 .flags = GENL_ADMIN_PERM,
4715 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4716 NL80211_FLAG_NEED_RTNL,
5375 }, 4717 },
5376 { 4718 {
5377 .cmd = NL80211_CMD_DISCONNECT, 4719 .cmd = NL80211_CMD_DISCONNECT,
5378 .doit = nl80211_disconnect, 4720 .doit = nl80211_disconnect,
5379 .policy = nl80211_policy, 4721 .policy = nl80211_policy,
5380 .flags = GENL_ADMIN_PERM, 4722 .flags = GENL_ADMIN_PERM,
4723 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4724 NL80211_FLAG_NEED_RTNL,
5381 }, 4725 },
5382 { 4726 {
5383 .cmd = NL80211_CMD_SET_WIPHY_NETNS, 4727 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
5384 .doit = nl80211_wiphy_netns, 4728 .doit = nl80211_wiphy_netns,
5385 .policy = nl80211_policy, 4729 .policy = nl80211_policy,
5386 .flags = GENL_ADMIN_PERM, 4730 .flags = GENL_ADMIN_PERM,
4731 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4732 NL80211_FLAG_NEED_RTNL,
5387 }, 4733 },
5388 { 4734 {
5389 .cmd = NL80211_CMD_GET_SURVEY, 4735 .cmd = NL80211_CMD_GET_SURVEY,
@@ -5395,72 +4741,104 @@ static struct genl_ops nl80211_ops[] = {
5395 .doit = nl80211_setdel_pmksa, 4741 .doit = nl80211_setdel_pmksa,
5396 .policy = nl80211_policy, 4742 .policy = nl80211_policy,
5397 .flags = GENL_ADMIN_PERM, 4743 .flags = GENL_ADMIN_PERM,
4744 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4745 NL80211_FLAG_NEED_RTNL,
5398 }, 4746 },
5399 { 4747 {
5400 .cmd = NL80211_CMD_DEL_PMKSA, 4748 .cmd = NL80211_CMD_DEL_PMKSA,
5401 .doit = nl80211_setdel_pmksa, 4749 .doit = nl80211_setdel_pmksa,
5402 .policy = nl80211_policy, 4750 .policy = nl80211_policy,
5403 .flags = GENL_ADMIN_PERM, 4751 .flags = GENL_ADMIN_PERM,
4752 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4753 NL80211_FLAG_NEED_RTNL,
5404 }, 4754 },
5405 { 4755 {
5406 .cmd = NL80211_CMD_FLUSH_PMKSA, 4756 .cmd = NL80211_CMD_FLUSH_PMKSA,
5407 .doit = nl80211_flush_pmksa, 4757 .doit = nl80211_flush_pmksa,
5408 .policy = nl80211_policy, 4758 .policy = nl80211_policy,
5409 .flags = GENL_ADMIN_PERM, 4759 .flags = GENL_ADMIN_PERM,
4760 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4761 NL80211_FLAG_NEED_RTNL,
5410 }, 4762 },
5411 { 4763 {
5412 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL, 4764 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
5413 .doit = nl80211_remain_on_channel, 4765 .doit = nl80211_remain_on_channel,
5414 .policy = nl80211_policy, 4766 .policy = nl80211_policy,
5415 .flags = GENL_ADMIN_PERM, 4767 .flags = GENL_ADMIN_PERM,
4768 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4769 NL80211_FLAG_NEED_RTNL,
5416 }, 4770 },
5417 { 4771 {
5418 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 4772 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
5419 .doit = nl80211_cancel_remain_on_channel, 4773 .doit = nl80211_cancel_remain_on_channel,
5420 .policy = nl80211_policy, 4774 .policy = nl80211_policy,
5421 .flags = GENL_ADMIN_PERM, 4775 .flags = GENL_ADMIN_PERM,
4776 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4777 NL80211_FLAG_NEED_RTNL,
5422 }, 4778 },
5423 { 4779 {
5424 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK, 4780 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
5425 .doit = nl80211_set_tx_bitrate_mask, 4781 .doit = nl80211_set_tx_bitrate_mask,
5426 .policy = nl80211_policy, 4782 .policy = nl80211_policy,
5427 .flags = GENL_ADMIN_PERM, 4783 .flags = GENL_ADMIN_PERM,
4784 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4785 NL80211_FLAG_NEED_RTNL,
5428 }, 4786 },
5429 { 4787 {
5430 .cmd = NL80211_CMD_REGISTER_FRAME, 4788 .cmd = NL80211_CMD_REGISTER_FRAME,
5431 .doit = nl80211_register_mgmt, 4789 .doit = nl80211_register_mgmt,
5432 .policy = nl80211_policy, 4790 .policy = nl80211_policy,
5433 .flags = GENL_ADMIN_PERM, 4791 .flags = GENL_ADMIN_PERM,
4792 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4793 NL80211_FLAG_NEED_RTNL,
5434 }, 4794 },
5435 { 4795 {
5436 .cmd = NL80211_CMD_FRAME, 4796 .cmd = NL80211_CMD_FRAME,
5437 .doit = nl80211_tx_mgmt, 4797 .doit = nl80211_tx_mgmt,
5438 .policy = nl80211_policy, 4798 .policy = nl80211_policy,
5439 .flags = GENL_ADMIN_PERM, 4799 .flags = GENL_ADMIN_PERM,
4800 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4801 NL80211_FLAG_NEED_RTNL,
5440 }, 4802 },
5441 { 4803 {
5442 .cmd = NL80211_CMD_SET_POWER_SAVE, 4804 .cmd = NL80211_CMD_SET_POWER_SAVE,
5443 .doit = nl80211_set_power_save, 4805 .doit = nl80211_set_power_save,
5444 .policy = nl80211_policy, 4806 .policy = nl80211_policy,
5445 .flags = GENL_ADMIN_PERM, 4807 .flags = GENL_ADMIN_PERM,
4808 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4809 NL80211_FLAG_NEED_RTNL,
5446 }, 4810 },
5447 { 4811 {
5448 .cmd = NL80211_CMD_GET_POWER_SAVE, 4812 .cmd = NL80211_CMD_GET_POWER_SAVE,
5449 .doit = nl80211_get_power_save, 4813 .doit = nl80211_get_power_save,
5450 .policy = nl80211_policy, 4814 .policy = nl80211_policy,
5451 /* can be retrieved by unprivileged users */ 4815 /* can be retrieved by unprivileged users */
4816 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4817 NL80211_FLAG_NEED_RTNL,
5452 }, 4818 },
5453 { 4819 {
5454 .cmd = NL80211_CMD_SET_CQM, 4820 .cmd = NL80211_CMD_SET_CQM,
5455 .doit = nl80211_set_cqm, 4821 .doit = nl80211_set_cqm,
5456 .policy = nl80211_policy, 4822 .policy = nl80211_policy,
5457 .flags = GENL_ADMIN_PERM, 4823 .flags = GENL_ADMIN_PERM,
4824 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4825 NL80211_FLAG_NEED_RTNL,
5458 }, 4826 },
5459 { 4827 {
5460 .cmd = NL80211_CMD_SET_CHANNEL, 4828 .cmd = NL80211_CMD_SET_CHANNEL,
5461 .doit = nl80211_set_channel, 4829 .doit = nl80211_set_channel,
5462 .policy = nl80211_policy, 4830 .policy = nl80211_policy,
5463 .flags = GENL_ADMIN_PERM, 4831 .flags = GENL_ADMIN_PERM,
4832 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4833 NL80211_FLAG_NEED_RTNL,
4834 },
4835 {
4836 .cmd = NL80211_CMD_SET_WDS_PEER,
4837 .doit = nl80211_set_wds_peer,
4838 .policy = nl80211_policy,
4839 .flags = GENL_ADMIN_PERM,
4840 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4841 NL80211_FLAG_NEED_RTNL,
5464 }, 4842 },
5465}; 4843};
5466 4844
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 5ca8c7180141..503ebb86ba18 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -650,14 +650,14 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
650 bss = container_of(pub, struct cfg80211_internal_bss, pub); 650 bss = container_of(pub, struct cfg80211_internal_bss, pub);
651 651
652 spin_lock_bh(&dev->bss_lock); 652 spin_lock_bh(&dev->bss_lock);
653 if (!list_empty(&bss->list)) {
654 list_del_init(&bss->list);
655 dev->bss_generation++;
656 rb_erase(&bss->rbn, &dev->bss_tree);
653 657
654 list_del(&bss->list); 658 kref_put(&bss->ref, bss_release);
655 dev->bss_generation++; 659 }
656 rb_erase(&bss->rbn, &dev->bss_tree);
657
658 spin_unlock_bh(&dev->bss_lock); 660 spin_unlock_bh(&dev->bss_lock);
659
660 kref_put(&bss->ref, bss_release);
661} 661}
662EXPORT_SYMBOL(cfg80211_unlink_bss); 662EXPORT_SYMBOL(cfg80211_unlink_bss);
663 663
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index f161b9844542..e17b0bee6bdc 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -698,7 +698,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
698 */ 698 */
699 if (rdev->ops->del_key) 699 if (rdev->ops->del_key)
700 for (i = 0; i < 6; i++) 700 for (i = 0; i < 6; i++)
701 rdev->ops->del_key(wdev->wiphy, dev, i, NULL); 701 rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL);
702 702
703#ifdef CONFIG_CFG80211_WEXT 703#ifdef CONFIG_CFG80211_WEXT
704 memset(&wrqu, 0, sizeof(wrqu)); 704 memset(&wrqu, 0, sizeof(wrqu));
diff --git a/net/wireless/util.c b/net/wireless/util.c
index fb5448f7d55a..76120aeda57d 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
144 144
145int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 145int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
146 struct key_params *params, int key_idx, 146 struct key_params *params, int key_idx,
147 const u8 *mac_addr) 147 bool pairwise, const u8 *mac_addr)
148{ 148{
149 int i; 149 int i;
150 150
151 if (key_idx > 5) 151 if (key_idx > 5)
152 return -EINVAL; 152 return -EINVAL;
153 153
154 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
155 return -EINVAL;
156
157 if (pairwise && !mac_addr)
158 return -EINVAL;
159
154 /* 160 /*
155 * Disallow pairwise keys with non-zero index unless it's WEP 161 * Disallow pairwise keys with non-zero index unless it's WEP
156 * (because current deployments use pairwise WEP keys with 162 * (because current deployments use pairwise WEP keys with
157 * non-zero indizes but 802.11i clearly specifies to use zero) 163 * non-zero indizes but 802.11i clearly specifies to use zero)
158 */ 164 */
159 if (mac_addr && key_idx && 165 if (pairwise && key_idx &&
160 params->cipher != WLAN_CIPHER_SUITE_WEP40 && 166 params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
161 params->cipher != WLAN_CIPHER_SUITE_WEP104) 167 params->cipher != WLAN_CIPHER_SUITE_WEP104)
162 return -EINVAL; 168 return -EINVAL;
@@ -677,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
677 for (i = 0; i < 6; i++) { 683 for (i = 0; i < 6; i++) {
678 if (!wdev->connect_keys->params[i].cipher) 684 if (!wdev->connect_keys->params[i].cipher)
679 continue; 685 continue;
680 if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL, 686 if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL,
681 &wdev->connect_keys->params[i])) { 687 &wdev->connect_keys->params[i])) {
682 printk(KERN_ERR "%s: failed to set key %d\n", 688 printk(KERN_ERR "%s: failed to set key %d\n",
683 dev->name, i); 689 dev->name, i);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 7e5c3a45f811..6002265289c6 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -432,14 +432,17 @@ int cfg80211_wext_giwretry(struct net_device *dev,
432EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); 432EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
433 433
434static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 434static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
435 struct net_device *dev, const u8 *addr, 435 struct net_device *dev, bool pairwise,
436 bool remove, bool tx_key, int idx, 436 const u8 *addr, bool remove, bool tx_key,
437 struct key_params *params) 437 int idx, struct key_params *params)
438{ 438{
439 struct wireless_dev *wdev = dev->ieee80211_ptr; 439 struct wireless_dev *wdev = dev->ieee80211_ptr;
440 int err, i; 440 int err, i;
441 bool rejoin = false; 441 bool rejoin = false;
442 442
443 if (pairwise && !addr)
444 return -EINVAL;
445
443 if (!wdev->wext.keys) { 446 if (!wdev->wext.keys) {
444 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), 447 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
445 GFP_KERNEL); 448 GFP_KERNEL);
@@ -478,7 +481,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
478 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 481 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
479 rejoin = true; 482 rejoin = true;
480 } 483 }
481 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); 484
485 if (!pairwise && addr &&
486 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
487 err = -ENOENT;
488 else
489 err = rdev->ops->del_key(&rdev->wiphy, dev, idx,
490 pairwise, addr);
482 } 491 }
483 wdev->wext.connect.privacy = false; 492 wdev->wext.connect.privacy = false;
484 /* 493 /*
@@ -507,12 +516,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
507 if (addr) 516 if (addr)
508 tx_key = false; 517 tx_key = false;
509 518
510 if (cfg80211_validate_key_settings(rdev, params, idx, addr)) 519 if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
511 return -EINVAL; 520 return -EINVAL;
512 521
513 err = 0; 522 err = 0;
514 if (wdev->current_bss) 523 if (wdev->current_bss)
515 err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params); 524 err = rdev->ops->add_key(&rdev->wiphy, dev, idx,
525 pairwise, addr, params);
516 if (err) 526 if (err)
517 return err; 527 return err;
518 528
@@ -563,17 +573,17 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
563} 573}
564 574
565static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 575static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
566 struct net_device *dev, const u8 *addr, 576 struct net_device *dev, bool pairwise,
567 bool remove, bool tx_key, int idx, 577 const u8 *addr, bool remove, bool tx_key,
568 struct key_params *params) 578 int idx, struct key_params *params)
569{ 579{
570 int err; 580 int err;
571 581
572 /* devlist mutex needed for possible IBSS re-join */ 582 /* devlist mutex needed for possible IBSS re-join */
573 mutex_lock(&rdev->devlist_mtx); 583 mutex_lock(&rdev->devlist_mtx);
574 wdev_lock(dev->ieee80211_ptr); 584 wdev_lock(dev->ieee80211_ptr);
575 err = __cfg80211_set_encryption(rdev, dev, addr, remove, 585 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
576 tx_key, idx, params); 586 remove, tx_key, idx, params);
577 wdev_unlock(dev->ieee80211_ptr); 587 wdev_unlock(dev->ieee80211_ptr);
578 mutex_unlock(&rdev->devlist_mtx); 588 mutex_unlock(&rdev->devlist_mtx);
579 589
@@ -635,7 +645,7 @@ int cfg80211_wext_siwencode(struct net_device *dev,
635 else if (!remove) 645 else if (!remove)
636 return -EINVAL; 646 return -EINVAL;
637 647
638 return cfg80211_set_encryption(rdev, dev, NULL, remove, 648 return cfg80211_set_encryption(rdev, dev, false, NULL, remove,
639 wdev->wext.default_key == -1, 649 wdev->wext.default_key == -1,
640 idx, &params); 650 idx, &params);
641} 651}
@@ -725,7 +735,9 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
725 } 735 }
726 736
727 return cfg80211_set_encryption( 737 return cfg80211_set_encryption(
728 rdev, dev, addr, remove, 738 rdev, dev,
739 !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
740 addr, remove,
729 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 741 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
730 idx, &params); 742 idx, &params);
731} 743}