diff options
author | David S. Miller <davem@davemloft.net> | 2009-06-11 02:41:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-11 02:41:43 -0400 |
commit | 84503ddd65e804ccdeedee3f307b40d80ff793e6 (patch) | |
tree | c7b805f441b1d8cb2e86b8411cf2302ff46186b4 /net | |
parent | 51611a120e8120290152edd7d0020d22a7f4b4a3 (diff) | |
parent | 2f0accc13520b2644b85f80aedce10d10d88b0ca (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.c | 1 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 6 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 5 | ||||
-rw-r--r-- | net/mac80211/main.c | 61 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 57 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 27 | ||||
-rw-r--r-- | net/mac80211/tx.c | 19 | ||||
-rw-r--r-- | net/mac80211/util.c | 46 | ||||
-rw-r--r-- | net/mac80211/wme.c | 2 | ||||
-rw-r--r-- | net/rfkill/Kconfig | 2 | ||||
-rw-r--r-- | net/rfkill/core.c | 93 | ||||
-rw-r--r-- | net/wireless/core.c | 19 | ||||
-rw-r--r-- | net/wireless/reg.c | 7 |
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 | ||
594 | struct ieee80211_master_priv { | 595 | struct 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); |
1122 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1123 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1123 | enum queue_stop_reason reason); | 1124 | enum queue_stop_reason reason); |
1125 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | ||
1126 | struct sk_buff *skb); | ||
1127 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
1128 | struct sk_buff_head *skbs); | ||
1124 | 1129 | ||
1125 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1130 | void 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 | */ | ||
376 | static 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 | |||
413 | no_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 | |||
422 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 372 | static 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, ¶ms) && local->ops->conf_tx) | 798 | if (drv_conf_tx(local, queue, ¶ms) && 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 | */ |
910 | static ieee80211_tx_result | 911 | static 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 | } |
342 | EXPORT_SYMBOL(ieee80211_stop_queue); | 342 | EXPORT_SYMBOL(ieee80211_stop_queue); |
343 | 343 | ||
344 | void 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 | |||
359 | int 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 | |||
344 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 390 | void 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 | ||
20 | config RFKILL_INPUT | 20 | config 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 | ||
118 | static struct { | 119 | static 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 | ||
122 | static unsigned long rfkill_states_default_locked; | ||
123 | |||
124 | static bool rfkill_epo_lock_active; | 123 | static 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 | ||
467 | void 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 | } | ||
488 | EXPORT_SYMBOL(rfkill_set_global_sw_state); | ||
489 | |||
490 | 466 | ||
491 | bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) | 467 | bool 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 | } |
574 | EXPORT_SYMBOL(rfkill_set_states); | 552 | EXPORT_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 | } |
442 | EXPORT_SYMBOL(wiphy_register); | 441 | EXPORT_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) |