aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-11 02:41:43 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-11 02:41:43 -0400
commit84503ddd65e804ccdeedee3f307b40d80ff793e6 (patch)
treec7b805f441b1d8cb2e86b8411cf2302ff46186b4 /net
parent51611a120e8120290152edd7d0020d22a7f4b4a3 (diff)
parent2f0accc13520b2644b85f80aedce10d10d88b0ca (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/core/skbuff.c1
-rw-r--r--net/mac80211/agg-tx.c6
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/main.c61
-rw-r--r--net/mac80211/mlme.c57
-rw-r--r--net/mac80211/rc80211_minstrel.c2
-rw-r--r--net/mac80211/rx.c27
-rw-r--r--net/mac80211/tx.c19
-rw-r--r--net/mac80211/util.c46
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/rfkill/Kconfig2
-rw-r--r--net/rfkill/core.c93
-rw-r--r--net/wireless/core.c19
-rw-r--r--net/wireless/reg.c7
15 files changed, 174 insertions, 177 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 49961ba3c0f6..b94d777e3eb4 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -552,7 +552,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
552 new->vlan_tci = old->vlan_tci; 552 new->vlan_tci = old->vlan_tci;
553#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) 553#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
554 new->do_not_encrypt = old->do_not_encrypt; 554 new->do_not_encrypt = old->do_not_encrypt;
555 new->requeue = old->requeue;
556#endif 555#endif
557 556
558 skb_copy_secmark(new, old); 557 skb_copy_secmark(new, old);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 43d00ffd3988..9e5762ad307d 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -132,6 +132,9 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
132 132
133 state = &sta->ampdu_mlme.tid_state_tx[tid]; 133 state = &sta->ampdu_mlme.tid_state_tx[tid];
134 134
135 if (*state == HT_AGG_STATE_OPERATIONAL)
136 sta->ampdu_mlme.addba_req_num[tid] = 0;
137
135 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 138 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
136 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 139 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
137 140
@@ -337,6 +340,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
337 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 340 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
338 sta->ampdu_mlme.tid_tx[tid]->ssn, 341 sta->ampdu_mlme.tid_tx[tid]->ssn,
339 0x40, 5000); 342 0x40, 5000);
343 sta->ampdu_mlme.addba_req_num[tid]++;
340 /* activate the timer for the recipient's addBA response */ 344 /* activate the timer for the recipient's addBA response */
341 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = 345 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
342 jiffies + ADDBA_RESP_INTERVAL; 346 jiffies + ADDBA_RESP_INTERVAL;
@@ -606,7 +610,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
606 610
607 *state = HT_AGG_STATE_IDLE; 611 *state = HT_AGG_STATE_IDLE;
608 /* from now on packets are no longer put onto sta->pending */ 612 /* from now on packets are no longer put onto sta->pending */
609 sta->ampdu_mlme.addba_req_num[tid] = 0;
610 kfree(sta->ampdu_mlme.tid_tx[tid]); 613 kfree(sta->ampdu_mlme.tid_tx[tid]);
611 sta->ampdu_mlme.tid_tx[tid] = NULL; 614 sta->ampdu_mlme.tid_tx[tid] = NULL;
612 615
@@ -689,7 +692,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
689 692
690 sta->ampdu_mlme.addba_req_num[tid] = 0; 693 sta->ampdu_mlme.addba_req_num[tid] = 0;
691 } else { 694 } else {
692 sta->ampdu_mlme.addba_req_num[tid]++;
693 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 695 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
694 } 696 }
695 spin_unlock_bh(&sta->lock); 697 spin_unlock_bh(&sta->lock);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a9211cc183cb..3f47276caeb8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1122,8 +1122,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1122 p.txop = params->txop; 1122 p.txop = params->txop;
1123 if (drv_conf_tx(local, params->queue, &p)) { 1123 if (drv_conf_tx(local, params->queue, &p)) {
1124 printk(KERN_DEBUG "%s: failed to set TX queue " 1124 printk(KERN_DEBUG "%s: failed to set TX queue "
1125 "parameters for queue %d\n", local->mdev->name, 1125 "parameters for queue %d\n",
1126 params->queue); 1126 wiphy_name(local->hw.wiphy), params->queue);
1127 return -EINVAL; 1127 return -EINVAL;
1128 } 1128 }
1129 1129
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c088c46704a3..4dbc28964196 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -589,6 +589,7 @@ enum queue_stop_reason {
589 IEEE80211_QUEUE_STOP_REASON_AGGREGATION, 589 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
590 IEEE80211_QUEUE_STOP_REASON_SUSPEND, 590 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
591 IEEE80211_QUEUE_STOP_REASON_PENDING, 591 IEEE80211_QUEUE_STOP_REASON_PENDING,
592 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
592}; 593};
593 594
594struct ieee80211_master_priv { 595struct ieee80211_master_priv {
@@ -1121,6 +1122,10 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
1121 enum queue_stop_reason reason); 1122 enum queue_stop_reason reason);
1122void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 1123void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
1123 enum queue_stop_reason reason); 1124 enum queue_stop_reason reason);
1125void ieee80211_add_pending_skb(struct ieee80211_local *local,
1126 struct sk_buff *skb);
1127int ieee80211_add_pending_skbs(struct ieee80211_local *local,
1128 struct sk_buff_head *skbs);
1124 1129
1125void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1130void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1126 u16 transaction, u16 auth_alg, 1131 u16 transaction, u16 auth_alg,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 2683df918073..092a017b237e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -369,60 +369,12 @@ static void ieee80211_tasklet_handler(unsigned long data)
369 } 369 }
370} 370}
371 371
372/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to
373 * make a prepared TX frame (one that has been given to hw) to look like brand
374 * new IEEE 802.11 frame that is ready to go through TX processing again.
375 */
376static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
377 struct ieee80211_key *key,
378 struct sk_buff *skb)
379{
380 unsigned int hdrlen, iv_len, mic_len;
381 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
382
383 hdrlen = ieee80211_hdrlen(hdr->frame_control);
384
385 if (!key)
386 goto no_key;
387
388 switch (key->conf.alg) {
389 case ALG_WEP:
390 iv_len = WEP_IV_LEN;
391 mic_len = WEP_ICV_LEN;
392 break;
393 case ALG_TKIP:
394 iv_len = TKIP_IV_LEN;
395 mic_len = TKIP_ICV_LEN;
396 break;
397 case ALG_CCMP:
398 iv_len = CCMP_HDR_LEN;
399 mic_len = CCMP_MIC_LEN;
400 break;
401 default:
402 goto no_key;
403 }
404
405 if (skb->len >= hdrlen + mic_len &&
406 !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
407 skb_trim(skb, skb->len - mic_len);
408 if (skb->len >= hdrlen + iv_len) {
409 memmove(skb->data + iv_len, skb->data, hdrlen);
410 hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len);
411 }
412
413no_key:
414 if (ieee80211_is_data_qos(hdr->frame_control)) {
415 hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
416 memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data,
417 hdrlen - IEEE80211_QOS_CTL_LEN);
418 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
419 }
420}
421
422static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, 372static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
423 struct sta_info *sta, 373 struct sta_info *sta,
424 struct sk_buff *skb) 374 struct sk_buff *skb)
425{ 375{
376 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
377
426 sta->tx_filtered_count++; 378 sta->tx_filtered_count++;
427 379
428 /* 380 /*
@@ -464,16 +416,15 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
464 */ 416 */
465 if (test_sta_flags(sta, WLAN_STA_PS) && 417 if (test_sta_flags(sta, WLAN_STA_PS) &&
466 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { 418 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
467 ieee80211_remove_tx_extra(local, sta->key, skb);
468 skb_queue_tail(&sta->tx_filtered, skb); 419 skb_queue_tail(&sta->tx_filtered, skb);
469 return; 420 return;
470 } 421 }
471 422
472 if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { 423 if (!test_sta_flags(sta, WLAN_STA_PS) &&
424 !(info->flags & IEEE80211_TX_INTFL_RETRIED)) {
473 /* Software retry the packet once */ 425 /* Software retry the packet once */
474 skb->requeue = 1; 426 info->flags |= IEEE80211_TX_INTFL_RETRIED;
475 ieee80211_remove_tx_extra(local, sta->key, skb); 427 ieee80211_add_pending_skb(local, skb);
476 dev_queue_xmit(skb);
477 return; 428 return;
478 } 429 }
479 430
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 509469cb9265..d779c57a8220 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -621,9 +621,6 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
621 struct ieee80211_conf *conf = &local->hw.conf; 621 struct ieee80211_conf *conf = &local->hw.conf;
622 622
623 if (local->ps_sdata) { 623 if (local->ps_sdata) {
624 if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
625 return;
626
627 ieee80211_enable_ps(local, local->ps_sdata); 624 ieee80211_enable_ps(local, local->ps_sdata);
628 } else if (conf->flags & IEEE80211_CONF_PS) { 625 } else if (conf->flags & IEEE80211_CONF_PS) {
629 conf->flags &= ~IEEE80211_CONF_PS; 626 conf->flags &= ~IEEE80211_CONF_PS;
@@ -653,7 +650,9 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
653 count++; 650 count++;
654 } 651 }
655 652
656 if (count == 1 && found->u.mgd.powersave) { 653 if (count == 1 && found->u.mgd.powersave &&
654 (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) &&
655 !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) {
657 s32 beaconint_us; 656 s32 beaconint_us;
658 657
659 if (latency < 0) 658 if (latency < 0)
@@ -793,13 +792,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
793#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 792#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
794 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " 793 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
795 "cWmin=%d cWmax=%d txop=%d\n", 794 "cWmin=%d cWmax=%d txop=%d\n",
796 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, 795 wiphy_name(local->hw.wiphy), queue, aci, acm,
797 params.cw_max, params.txop); 796 params.aifs, params.cw_min, params.cw_max, params.txop);
798#endif 797#endif
799 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx) 798 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
800 printk(KERN_DEBUG "%s: failed to set TX queue " 799 printk(KERN_DEBUG "%s: failed to set TX queue "
801 "parameters for queue %d\n", local->mdev->name, 800 "parameters for queue %d\n",
802 queue); 801 wiphy_name(local->hw.wiphy), queue);
803 } 802 }
804} 803}
805 804
@@ -1322,6 +1321,11 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1322#endif 1321#endif
1323 1322
1324 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; 1323 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1324
1325 mutex_lock(&sdata->local->iflist_mtx);
1326 ieee80211_recalc_ps(sdata->local, -1);
1327 mutex_unlock(&sdata->local->iflist_mtx);
1328
1325 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1329 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1326 ifmgd->ssid_len, NULL, 0); 1330 ifmgd->ssid_len, NULL, 0);
1327 1331
@@ -1342,6 +1346,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1342 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1346 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1343 struct ieee80211_local *local = sdata->local; 1347 struct ieee80211_local *local = sdata->local;
1344 struct sta_info *sta; 1348 struct sta_info *sta;
1349 unsigned long last_rx;
1345 bool disassoc = false; 1350 bool disassoc = false;
1346 1351
1347 /* TODO: start monitoring current AP signal quality and number of 1352 /* TODO: start monitoring current AP signal quality and number of
@@ -1358,17 +1363,21 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1358 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", 1363 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
1359 sdata->dev->name, ifmgd->bssid); 1364 sdata->dev->name, ifmgd->bssid);
1360 disassoc = true; 1365 disassoc = true;
1361 goto unlock; 1366 rcu_read_unlock();
1367 goto out;
1362 } 1368 }
1363 1369
1370 last_rx = sta->last_rx;
1371 rcu_read_unlock();
1372
1364 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && 1373 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
1365 time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { 1374 time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) {
1366 printk(KERN_DEBUG "%s: no probe response from AP %pM " 1375 printk(KERN_DEBUG "%s: no probe response from AP %pM "
1367 "- disassociating\n", 1376 "- disassociating\n",
1368 sdata->dev->name, ifmgd->bssid); 1377 sdata->dev->name, ifmgd->bssid);
1369 disassoc = true; 1378 disassoc = true;
1370 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1379 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1371 goto unlock; 1380 goto out;
1372 } 1381 }
1373 1382
1374 /* 1383 /*
@@ -1387,26 +1396,29 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1387 } 1396 }
1388#endif 1397#endif
1389 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; 1398 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1399 mutex_lock(&local->iflist_mtx);
1400 ieee80211_recalc_ps(local, -1);
1401 mutex_unlock(&local->iflist_mtx);
1390 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1402 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1391 ifmgd->ssid_len, NULL, 0); 1403 ifmgd->ssid_len, NULL, 0);
1392 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); 1404 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
1393 goto unlock; 1405 goto out;
1394 } 1406 }
1395 1407
1396 if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { 1408 if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) {
1397 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; 1409 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1410 mutex_lock(&local->iflist_mtx);
1411 ieee80211_recalc_ps(local, -1);
1412 mutex_unlock(&local->iflist_mtx);
1398 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1413 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1399 ifmgd->ssid_len, NULL, 0); 1414 ifmgd->ssid_len, NULL, 0);
1400 } 1415 }
1401 1416
1417 out:
1402 if (!disassoc) 1418 if (!disassoc)
1403 mod_timer(&ifmgd->timer, 1419 mod_timer(&ifmgd->timer,
1404 jiffies + IEEE80211_MONITORING_INTERVAL); 1420 jiffies + IEEE80211_MONITORING_INTERVAL);
1405 1421 else
1406 unlock:
1407 rcu_read_unlock();
1408
1409 if (disassoc)
1410 ieee80211_set_disassoc(sdata, true, true, 1422 ieee80211_set_disassoc(sdata, true, true,
1411 WLAN_REASON_PREV_AUTH_NOT_VALID); 1423 WLAN_REASON_PREV_AUTH_NOT_VALID);
1412} 1424}
@@ -1889,8 +1901,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1889 ieee80211_authenticate(sdata); 1901 ieee80211_authenticate(sdata);
1890 } 1902 }
1891 1903
1892 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) 1904 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
1893 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1905 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1906 mutex_lock(&sdata->local->iflist_mtx);
1907 ieee80211_recalc_ps(sdata->local, -1);
1908 mutex_unlock(&sdata->local->iflist_mtx);
1909 }
1894} 1910}
1895 1911
1896/* 1912/*
@@ -1948,6 +1964,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1948 } 1964 }
1949#endif 1965#endif
1950 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1966 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1967 mutex_lock(&local->iflist_mtx);
1968 ieee80211_recalc_ps(local, -1);
1969 mutex_unlock(&local->iflist_mtx);
1951 } 1970 }
1952 1971
1953 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 1972 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 0a11515341ba..b218b98fba7f 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -215,7 +215,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi)
215 unsigned int sample_ndx; 215 unsigned int sample_ndx;
216 sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); 216 sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
217 mi->sample_idx++; 217 mi->sample_idx++;
218 if (mi->sample_idx > (mi->n_rates - 2)) { 218 if ((int) mi->sample_idx > (mi->n_rates - 2)) {
219 mi->sample_idx = 0; 219 mi->sample_idx = 0;
220 mi->sample_column++; 220 mi->sample_column++;
221 if (mi->sample_column >= SAMPLE_COLUMNS) 221 if (mi->sample_column >= SAMPLE_COLUMNS)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6a9b8e63a6bf..de5bba7f910a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -797,8 +797,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
797{ 797{
798 struct ieee80211_sub_if_data *sdata = sta->sdata; 798 struct ieee80211_sub_if_data *sdata = sta->sdata;
799 struct ieee80211_local *local = sdata->local; 799 struct ieee80211_local *local = sdata->local;
800 struct sk_buff *skb; 800 int sent, buffered;
801 int sent = 0;
802 801
803 atomic_dec(&sdata->bss->num_sta_ps); 802 atomic_dec(&sdata->bss->num_sta_ps);
804 803
@@ -814,22 +813,16 @@ static int ap_sta_ps_end(struct sta_info *sta)
814#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 813#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
815 814
816 /* Send all buffered frames to the station */ 815 /* Send all buffered frames to the station */
817 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { 816 sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
818 sent++; 817 buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
819 skb->requeue = 1; 818 sent += buffered;
820 dev_queue_xmit(skb); 819 local->total_ps_buffered -= buffered;
821 } 820
822 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
823 local->total_ps_buffered--;
824 sent++;
825#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 821#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
826 printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " 822 printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames "
827 "since STA not sleeping anymore\n", sdata->dev->name, 823 "since STA not sleeping anymore\n", sdata->dev->name,
828 sta->sta.addr, sta->sta.aid); 824 sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
829#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 825#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
830 skb->requeue = 1;
831 dev_queue_xmit(skb);
832 }
833 826
834 return sent; 827 return sent;
835} 828}
@@ -1335,7 +1328,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1335 * mac80211. That also explains the __skb_push() 1328 * mac80211. That also explains the __skb_push()
1336 * below. 1329 * below.
1337 */ 1330 */
1338 align = (unsigned long)skb->data & 3; 1331 align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3;
1339 if (align) { 1332 if (align) {
1340 if (WARN_ON(skb_headroom(skb) < 3)) { 1333 if (WARN_ON(skb_headroom(skb) < 3)) {
1341 dev_kfree_skb(skb); 1334 dev_kfree_skb(skb);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1436f747531a..364222bfb10d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
400 sta_info_set_tim_bit(sta); 400 sta_info_set_tim_bit(sta);
401 401
402 info->control.jiffies = jiffies; 402 info->control.jiffies = jiffies;
403 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
403 skb_queue_tail(&sta->ps_tx_buf, tx->skb); 404 skb_queue_tail(&sta->ps_tx_buf, tx->skb);
404 return TX_QUEUED; 405 return TX_QUEUED;
405 } 406 }
@@ -420,7 +421,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
420 * frame filtering and keeps a station blacklist on its own 421 * frame filtering and keeps a station blacklist on its own
421 * (e.g: p54), so that frames can be delivered unimpeded. 422 * (e.g: p54), so that frames can be delivered unimpeded.
422 * 423 *
423 * Note: It should be save to disable the filter now. 424 * Note: It should be safe to disable the filter now.
424 * As, it is really unlikely that we still have any pending 425 * As, it is really unlikely that we still have any pending
425 * frame for this station in the hw's buffers/fifos left, 426 * frame for this station in the hw's buffers/fifos left,
426 * that is not rejected with a unsuccessful tx_status yet. 427 * that is not rejected with a unsuccessful tx_status yet.
@@ -907,9 +908,8 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
907 * deal with packet injection down monitor interface 908 * deal with packet injection down monitor interface
908 * with Radiotap Header -- only called for monitor mode interface 909 * with Radiotap Header -- only called for monitor mode interface
909 */ 910 */
910static ieee80211_tx_result 911static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
911__ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, 912 struct sk_buff *skb)
912 struct sk_buff *skb)
913{ 913{
914 /* 914 /*
915 * this is the moment to interpret and discard the radiotap header that 915 * this is the moment to interpret and discard the radiotap header that
@@ -960,7 +960,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
960 * on transmission 960 * on transmission
961 */ 961 */
962 if (skb->len < (iterator.max_length + FCS_LEN)) 962 if (skb->len < (iterator.max_length + FCS_LEN))
963 return TX_DROP; 963 return false;
964 964
965 skb_trim(skb, skb->len - FCS_LEN); 965 skb_trim(skb, skb->len - FCS_LEN);
966 } 966 }
@@ -982,7 +982,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
982 } 982 }
983 983
984 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ 984 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
985 return TX_DROP; 985 return false;
986 986
987 /* 987 /*
988 * remove the radiotap header 988 * remove the radiotap header
@@ -991,7 +991,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
991 */ 991 */
992 skb_pull(skb, iterator.max_length); 992 skb_pull(skb, iterator.max_length);
993 993
994 return TX_CONTINUE; 994 return true;
995} 995}
996 996
997/* 997/*
@@ -1025,7 +1025,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1025 /* process and remove the injection radiotap header */ 1025 /* process and remove the injection radiotap header */
1026 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1026 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1027 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { 1027 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
1028 if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) 1028 if (!__ieee80211_parse_tx_radiotap(tx, skb))
1029 return TX_DROP; 1029 return TX_DROP;
1030 1030
1031 /* 1031 /*
@@ -1415,7 +1415,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1415 } 1415 }
1416 1416
1417 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 1417 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
1418 local->hw.conf.dynamic_ps_timeout > 0) { 1418 local->hw.conf.dynamic_ps_timeout > 0 &&
1419 !local->sw_scanning && !local->hw_scanning && local->ps_sdata) {
1419 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 1420 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1420 ieee80211_stop_queues_by_reason(&local->hw, 1421 ieee80211_stop_queues_by_reason(&local->hw,
1421 IEEE80211_QUEUE_STOP_REASON_PS); 1422 IEEE80211_QUEUE_STOP_REASON_PS);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 22f63815fb36..66ce96a69f31 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -341,6 +341,52 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
341} 341}
342EXPORT_SYMBOL(ieee80211_stop_queue); 342EXPORT_SYMBOL(ieee80211_stop_queue);
343 343
344void ieee80211_add_pending_skb(struct ieee80211_local *local,
345 struct sk_buff *skb)
346{
347 struct ieee80211_hw *hw = &local->hw;
348 unsigned long flags;
349 int queue = skb_get_queue_mapping(skb);
350
351 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
352 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
353 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING);
354 skb_queue_tail(&local->pending[queue], skb);
355 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
356 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
357}
358
359int ieee80211_add_pending_skbs(struct ieee80211_local *local,
360 struct sk_buff_head *skbs)
361{
362 struct ieee80211_hw *hw = &local->hw;
363 struct sk_buff *skb;
364 unsigned long flags;
365 int queue, ret = 0, i;
366
367 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
368 for (i = 0; i < hw->queues; i++)
369 __ieee80211_stop_queue(hw, i,
370 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
371
372 while ((skb = skb_dequeue(skbs))) {
373 ret++;
374 queue = skb_get_queue_mapping(skb);
375 skb_queue_tail(&local->pending[queue], skb);
376 }
377
378 for (i = 0; i < hw->queues; i++) {
379 if (ret)
380 __ieee80211_stop_queue(hw, i,
381 IEEE80211_QUEUE_STOP_REASON_PENDING);
382 __ieee80211_wake_queue(hw, i,
383 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
384 }
385 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
386
387 return ret;
388}
389
344void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 390void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
345 enum queue_stop_reason reason) 391 enum queue_stop_reason reason)
346{ 392{
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 694343b9102b..116a923b14d6 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -101,7 +101,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
101 * Now we know the 1d priority, fill in the QoS header if 101 * Now we know the 1d priority, fill in the QoS header if
102 * there is one (and we haven't done this before). 102 * there is one (and we haven't done this before).
103 */ 103 */
104 if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) { 104 if (ieee80211_is_data_qos(hdr->frame_control)) {
105 u8 *p = ieee80211_get_qos_ctl(hdr); 105 u8 *p = ieee80211_get_qos_ctl(hdr);
106 u8 ack_policy = 0; 106 u8 ack_policy = 0;
107 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; 107 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig
index fd7600d8ab14..eaf765876458 100644
--- a/net/rfkill/Kconfig
+++ b/net/rfkill/Kconfig
@@ -18,7 +18,7 @@ config RFKILL_LEDS
18 default y 18 default y
19 19
20config RFKILL_INPUT 20config RFKILL_INPUT
21 bool "RF switch input support" 21 bool "RF switch input support" if EMBEDDED
22 depends on RFKILL 22 depends on RFKILL
23 depends on INPUT = y || RFKILL = INPUT 23 depends on INPUT = y || RFKILL = INPUT
24 default y if !EMBEDDED 24 default y if !EMBEDDED
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 11b7314723df..4e68ab439d5d 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -57,6 +57,7 @@ struct rfkill {
57 57
58 bool registered; 58 bool registered;
59 bool suspended; 59 bool suspended;
60 bool persistent;
60 61
61 const struct rfkill_ops *ops; 62 const struct rfkill_ops *ops;
62 void *data; 63 void *data;
@@ -116,11 +117,9 @@ MODULE_PARM_DESC(default_state,
116 "Default initial state for all radio types, 0 = radio off"); 117 "Default initial state for all radio types, 0 = radio off");
117 118
118static struct { 119static struct {
119 bool cur, def; 120 bool cur, sav;
120} rfkill_global_states[NUM_RFKILL_TYPES]; 121} rfkill_global_states[NUM_RFKILL_TYPES];
121 122
122static unsigned long rfkill_states_default_locked;
123
124static bool rfkill_epo_lock_active; 123static bool rfkill_epo_lock_active;
125 124
126 125
@@ -392,7 +391,7 @@ void rfkill_epo(void)
392 rfkill_set_block(rfkill, true); 391 rfkill_set_block(rfkill, true);
393 392
394 for (i = 0; i < NUM_RFKILL_TYPES; i++) { 393 for (i = 0; i < NUM_RFKILL_TYPES; i++) {
395 rfkill_global_states[i].def = rfkill_global_states[i].cur; 394 rfkill_global_states[i].sav = rfkill_global_states[i].cur;
396 rfkill_global_states[i].cur = true; 395 rfkill_global_states[i].cur = true;
397 } 396 }
398 397
@@ -417,7 +416,7 @@ void rfkill_restore_states(void)
417 416
418 rfkill_epo_lock_active = false; 417 rfkill_epo_lock_active = false;
419 for (i = 0; i < NUM_RFKILL_TYPES; i++) 418 for (i = 0; i < NUM_RFKILL_TYPES; i++)
420 __rfkill_switch_all(i, rfkill_global_states[i].def); 419 __rfkill_switch_all(i, rfkill_global_states[i].sav);
421 mutex_unlock(&rfkill_global_mutex); 420 mutex_unlock(&rfkill_global_mutex);
422} 421}
423 422
@@ -464,29 +463,6 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type)
464} 463}
465#endif 464#endif
466 465
467void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked)
468{
469 BUG_ON(type == RFKILL_TYPE_ALL);
470
471 mutex_lock(&rfkill_global_mutex);
472
473 /* don't allow unblock when epo */
474 if (rfkill_epo_lock_active && !blocked)
475 goto out;
476
477 /* too late */
478 if (rfkill_states_default_locked & BIT(type))
479 goto out;
480
481 rfkill_states_default_locked |= BIT(type);
482
483 rfkill_global_states[type].cur = blocked;
484 rfkill_global_states[type].def = blocked;
485 out:
486 mutex_unlock(&rfkill_global_mutex);
487}
488EXPORT_SYMBOL(rfkill_set_global_sw_state);
489
490 466
491bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) 467bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
492{ 468{
@@ -532,13 +508,14 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
532 blocked = blocked || hwblock; 508 blocked = blocked || hwblock;
533 spin_unlock_irqrestore(&rfkill->lock, flags); 509 spin_unlock_irqrestore(&rfkill->lock, flags);
534 510
535 if (!rfkill->registered) 511 if (!rfkill->registered) {
536 return blocked; 512 rfkill->persistent = true;
537 513 } else {
538 if (prev != blocked && !hwblock) 514 if (prev != blocked && !hwblock)
539 schedule_work(&rfkill->uevent_work); 515 schedule_work(&rfkill->uevent_work);
540 516
541 rfkill_led_trigger_event(rfkill); 517 rfkill_led_trigger_event(rfkill);
518 }
542 519
543 return blocked; 520 return blocked;
544} 521}
@@ -563,13 +540,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
563 540
564 spin_unlock_irqrestore(&rfkill->lock, flags); 541 spin_unlock_irqrestore(&rfkill->lock, flags);
565 542
566 if (!rfkill->registered) 543 if (!rfkill->registered) {
567 return; 544 rfkill->persistent = true;
568 545 } else {
569 if (swprev != sw || hwprev != hw) 546 if (swprev != sw || hwprev != hw)
570 schedule_work(&rfkill->uevent_work); 547 schedule_work(&rfkill->uevent_work);
571 548
572 rfkill_led_trigger_event(rfkill); 549 rfkill_led_trigger_event(rfkill);
550 }
573} 551}
574EXPORT_SYMBOL(rfkill_set_states); 552EXPORT_SYMBOL(rfkill_set_states);
575 553
@@ -750,15 +728,11 @@ static int rfkill_resume(struct device *dev)
750 struct rfkill *rfkill = to_rfkill(dev); 728 struct rfkill *rfkill = to_rfkill(dev);
751 bool cur; 729 bool cur;
752 730
753 mutex_lock(&rfkill_global_mutex); 731 cur = !!(rfkill->state & RFKILL_BLOCK_SW);
754 cur = rfkill_global_states[rfkill->type].cur;
755 rfkill_set_block(rfkill, cur); 732 rfkill_set_block(rfkill, cur);
756 mutex_unlock(&rfkill_global_mutex);
757 733
758 rfkill->suspended = false; 734 rfkill->suspended = false;
759 735
760 schedule_work(&rfkill->uevent_work);
761
762 rfkill_resume_polling(rfkill); 736 rfkill_resume_polling(rfkill);
763 737
764 return 0; 738 return 0;
@@ -888,15 +862,6 @@ int __must_check rfkill_register(struct rfkill *rfkill)
888 dev_set_name(dev, "rfkill%lu", rfkill_no); 862 dev_set_name(dev, "rfkill%lu", rfkill_no);
889 rfkill_no++; 863 rfkill_no++;
890 864
891 if (!(rfkill_states_default_locked & BIT(rfkill->type))) {
892 /* first of its kind */
893 BUILD_BUG_ON(NUM_RFKILL_TYPES >
894 sizeof(rfkill_states_default_locked) * 8);
895 rfkill_states_default_locked |= BIT(rfkill->type);
896 rfkill_global_states[rfkill->type].cur =
897 rfkill_global_states[rfkill->type].def;
898 }
899
900 list_add_tail(&rfkill->node, &rfkill_list); 865 list_add_tail(&rfkill->node, &rfkill_list);
901 866
902 error = device_add(dev); 867 error = device_add(dev);
@@ -916,7 +881,17 @@ int __must_check rfkill_register(struct rfkill *rfkill)
916 if (rfkill->ops->poll) 881 if (rfkill->ops->poll)
917 schedule_delayed_work(&rfkill->poll_work, 882 schedule_delayed_work(&rfkill->poll_work,
918 round_jiffies_relative(POLL_INTERVAL)); 883 round_jiffies_relative(POLL_INTERVAL));
919 schedule_work(&rfkill->sync_work); 884
885 if (!rfkill->persistent || rfkill_epo_lock_active) {
886 schedule_work(&rfkill->sync_work);
887 } else {
888#ifdef CONFIG_RFKILL_INPUT
889 bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);
890
891 if (!atomic_read(&rfkill_input_disabled))
892 __rfkill_switch_all(rfkill->type, soft_blocked);
893#endif
894 }
920 895
921 rfkill_send_events(rfkill, RFKILL_OP_ADD); 896 rfkill_send_events(rfkill, RFKILL_OP_ADD);
922 897
@@ -1134,7 +1109,8 @@ static int rfkill_fop_release(struct inode *inode, struct file *file)
1134 1109
1135#ifdef CONFIG_RFKILL_INPUT 1110#ifdef CONFIG_RFKILL_INPUT
1136 if (data->input_handler) 1111 if (data->input_handler)
1137 atomic_dec(&rfkill_input_disabled); 1112 if (atomic_dec_return(&rfkill_input_disabled) == 0)
1113 printk(KERN_DEBUG "rfkill: input handler enabled\n");
1138#endif 1114#endif
1139 1115
1140 kfree(data); 1116 kfree(data);
@@ -1157,7 +1133,8 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
1157 mutex_lock(&data->mtx); 1133 mutex_lock(&data->mtx);
1158 1134
1159 if (!data->input_handler) { 1135 if (!data->input_handler) {
1160 atomic_inc(&rfkill_input_disabled); 1136 if (atomic_inc_return(&rfkill_input_disabled) == 1)
1137 printk(KERN_DEBUG "rfkill: input handler disabled\n");
1161 data->input_handler = true; 1138 data->input_handler = true;
1162 } 1139 }
1163 1140
@@ -1191,7 +1168,7 @@ static int __init rfkill_init(void)
1191 int i; 1168 int i;
1192 1169
1193 for (i = 0; i < NUM_RFKILL_TYPES; i++) 1170 for (i = 0; i < NUM_RFKILL_TYPES; i++)
1194 rfkill_global_states[i].def = !rfkill_default_state; 1171 rfkill_global_states[i].cur = !rfkill_default_state;
1195 1172
1196 error = class_register(&rfkill_class); 1173 error = class_register(&rfkill_class);
1197 if (error) 1174 if (error)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 3b74b88e10a3..d5850292b3df 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -395,21 +395,23 @@ int wiphy_register(struct wiphy *wiphy)
395 /* check and set up bitrates */ 395 /* check and set up bitrates */
396 ieee80211_set_bitrate_flags(wiphy); 396 ieee80211_set_bitrate_flags(wiphy);
397 397
398 mutex_lock(&cfg80211_mutex);
399
400 /* set up regulatory info */
401 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
402
403 res = device_add(&drv->wiphy.dev); 398 res = device_add(&drv->wiphy.dev);
404 if (res) 399 if (res)
405 goto out_unlock; 400 return res;
406 401
407 res = rfkill_register(drv->rfkill); 402 res = rfkill_register(drv->rfkill);
408 if (res) 403 if (res)
409 goto out_rm_dev; 404 goto out_rm_dev;
410 405
406 mutex_lock(&cfg80211_mutex);
407
408 /* set up regulatory info */
409 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
410
411 list_add(&drv->list, &cfg80211_drv_list); 411 list_add(&drv->list, &cfg80211_drv_list);
412 412
413 mutex_unlock(&cfg80211_mutex);
414
413 /* add to debugfs */ 415 /* add to debugfs */
414 drv->wiphy.debugfsdir = 416 drv->wiphy.debugfsdir =
415 debugfs_create_dir(wiphy_name(&drv->wiphy), 417 debugfs_create_dir(wiphy_name(&drv->wiphy),
@@ -430,13 +432,10 @@ int wiphy_register(struct wiphy *wiphy)
430 432
431 cfg80211_debugfs_drv_add(drv); 433 cfg80211_debugfs_drv_add(drv);
432 434
433 res = 0; 435 return 0;
434 goto out_unlock;
435 436
436 out_rm_dev: 437 out_rm_dev:
437 device_del(&drv->wiphy.dev); 438 device_del(&drv->wiphy.dev);
438 out_unlock:
439 mutex_unlock(&cfg80211_mutex);
440 return res; 439 return res;
441} 440}
442EXPORT_SYMBOL(wiphy_register); 441EXPORT_SYMBOL(wiphy_register);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ea4c299fbe3b..5e14371cda70 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2129,7 +2129,12 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2129 * driver wanted to the wiphy to deal with conflicts 2129 * driver wanted to the wiphy to deal with conflicts
2130 */ 2130 */
2131 2131
2132 BUG_ON(request_wiphy->regd); 2132 /*
2133 * Userspace could have sent two replies with only
2134 * one kernel request.
2135 */
2136 if (request_wiphy->regd)
2137 return -EALREADY;
2133 2138
2134 r = reg_copy_regd(&request_wiphy->regd, rd); 2139 r = reg_copy_regd(&request_wiphy->regd, rd);
2135 if (r) 2140 if (r)