diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 329 |
1 files changed, 169 insertions, 160 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 98c0b5e56ecc..b182f018a187 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -35,8 +35,6 @@ | |||
35 | #include "debugfs.h" | 35 | #include "debugfs.h" |
36 | #include "debugfs_netdev.h" | 36 | #include "debugfs_netdev.h" |
37 | 37 | ||
38 | #define SUPP_MCS_SET_LEN 16 | ||
39 | |||
40 | /* | 38 | /* |
41 | * For seeing transmitted packets on monitor interfaces | 39 | * For seeing transmitted packets on monitor interfaces |
42 | * we have a radiotap header too. | 40 | * we have a radiotap header too. |
@@ -112,7 +110,13 @@ static int ieee80211_master_open(struct net_device *dev) | |||
112 | break; | 110 | break; |
113 | } | 111 | } |
114 | } | 112 | } |
115 | return res; | 113 | |
114 | if (res) | ||
115 | return res; | ||
116 | |||
117 | netif_start_queue(local->mdev); | ||
118 | |||
119 | return 0; | ||
116 | } | 120 | } |
117 | 121 | ||
118 | static int ieee80211_master_stop(struct net_device *dev) | 122 | static int ieee80211_master_stop(struct net_device *dev) |
@@ -346,6 +350,7 @@ static int ieee80211_open(struct net_device *dev) | |||
346 | goto err_del_interface; | 350 | goto err_del_interface; |
347 | } | 351 | } |
348 | 352 | ||
353 | /* no locking required since STA is not live yet */ | ||
349 | sta->flags |= WLAN_STA_AUTHORIZED; | 354 | sta->flags |= WLAN_STA_AUTHORIZED; |
350 | 355 | ||
351 | res = sta_info_insert(sta); | 356 | res = sta_info_insert(sta); |
@@ -385,8 +390,8 @@ static int ieee80211_open(struct net_device *dev) | |||
385 | * yet be effective. Trigger execution of ieee80211_sta_work | 390 | * yet be effective. Trigger execution of ieee80211_sta_work |
386 | * to fix this. | 391 | * to fix this. |
387 | */ | 392 | */ |
388 | if(sdata->vif.type == IEEE80211_IF_TYPE_STA || | 393 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
389 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 394 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
390 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 395 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
391 | queue_work(local->hw.workqueue, &ifsta->work); | 396 | queue_work(local->hw.workqueue, &ifsta->work); |
392 | } | 397 | } |
@@ -585,16 +590,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
585 | sta = sta_info_get(local, ra); | 590 | sta = sta_info_get(local, ra); |
586 | if (!sta) { | 591 | if (!sta) { |
587 | printk(KERN_DEBUG "Could not find the station\n"); | 592 | printk(KERN_DEBUG "Could not find the station\n"); |
588 | rcu_read_unlock(); | 593 | ret = -ENOENT; |
589 | return -ENOENT; | 594 | goto exit; |
590 | } | 595 | } |
591 | 596 | ||
592 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 597 | spin_lock_bh(&sta->lock); |
593 | 598 | ||
594 | /* we have tried too many times, receiver does not want A-MPDU */ | 599 | /* we have tried too many times, receiver does not want A-MPDU */ |
595 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 600 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
596 | ret = -EBUSY; | 601 | ret = -EBUSY; |
597 | goto start_ba_exit; | 602 | goto err_unlock_sta; |
598 | } | 603 | } |
599 | 604 | ||
600 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 605 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
@@ -605,7 +610,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
605 | "idle on tid %u\n", tid); | 610 | "idle on tid %u\n", tid); |
606 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 611 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
607 | ret = -EAGAIN; | 612 | ret = -EAGAIN; |
608 | goto start_ba_exit; | 613 | goto err_unlock_sta; |
609 | } | 614 | } |
610 | 615 | ||
611 | /* prepare A-MPDU MLME for Tx aggregation */ | 616 | /* prepare A-MPDU MLME for Tx aggregation */ |
@@ -616,7 +621,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
616 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | 621 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", |
617 | tid); | 622 | tid); |
618 | ret = -ENOMEM; | 623 | ret = -ENOMEM; |
619 | goto start_ba_exit; | 624 | goto err_unlock_sta; |
620 | } | 625 | } |
621 | /* Tx timer */ | 626 | /* Tx timer */ |
622 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = | 627 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = |
@@ -639,7 +644,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
639 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | 644 | printk(KERN_DEBUG "BA request denied - queue unavailable for" |
640 | " tid %d\n", tid); | 645 | " tid %d\n", tid); |
641 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 646 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
642 | goto start_ba_err; | 647 | goto err_unlock_queue; |
643 | } | 648 | } |
644 | sdata = sta->sdata; | 649 | sdata = sta->sdata; |
645 | 650 | ||
@@ -661,12 +666,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
661 | " tid %d\n", tid); | 666 | " tid %d\n", tid); |
662 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 667 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
663 | *state = HT_AGG_STATE_IDLE; | 668 | *state = HT_AGG_STATE_IDLE; |
664 | goto start_ba_err; | 669 | goto err_unlock_queue; |
665 | } | 670 | } |
666 | 671 | ||
667 | /* Will put all the packets in the new SW queue */ | 672 | /* Will put all the packets in the new SW queue */ |
668 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 673 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); |
669 | spin_unlock_bh(&local->mdev->queue_lock); | 674 | spin_unlock_bh(&local->mdev->queue_lock); |
675 | spin_unlock_bh(&sta->lock); | ||
670 | 676 | ||
671 | /* send an addBA request */ | 677 | /* send an addBA request */ |
672 | sta->ampdu_mlme.dialog_token_allocator++; | 678 | sta->ampdu_mlme.dialog_token_allocator++; |
@@ -674,25 +680,26 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
674 | sta->ampdu_mlme.dialog_token_allocator; | 680 | sta->ampdu_mlme.dialog_token_allocator; |
675 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 681 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
676 | 682 | ||
683 | |||
677 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, | 684 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, |
678 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 685 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
679 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 686 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
680 | 0x40, 5000); | 687 | 0x40, 5000); |
681 | |||
682 | /* activate the timer for the recipient's addBA response */ | 688 | /* activate the timer for the recipient's addBA response */ |
683 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 689 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
684 | jiffies + ADDBA_RESP_INTERVAL; | 690 | jiffies + ADDBA_RESP_INTERVAL; |
685 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 691 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
686 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 692 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
687 | goto start_ba_exit; | 693 | goto exit; |
688 | 694 | ||
689 | start_ba_err: | 695 | err_unlock_queue: |
690 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 696 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
691 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 697 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
692 | spin_unlock_bh(&local->mdev->queue_lock); | 698 | spin_unlock_bh(&local->mdev->queue_lock); |
693 | ret = -EBUSY; | 699 | ret = -EBUSY; |
694 | start_ba_exit: | 700 | err_unlock_sta: |
695 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 701 | spin_unlock_bh(&sta->lock); |
702 | exit: | ||
696 | rcu_read_unlock(); | 703 | rcu_read_unlock(); |
697 | return ret; | 704 | return ret; |
698 | } | 705 | } |
@@ -720,7 +727,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
720 | 727 | ||
721 | /* check if the TID is in aggregation */ | 728 | /* check if the TID is in aggregation */ |
722 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 729 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
723 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 730 | spin_lock_bh(&sta->lock); |
724 | 731 | ||
725 | if (*state != HT_AGG_STATE_OPERATIONAL) { | 732 | if (*state != HT_AGG_STATE_OPERATIONAL) { |
726 | ret = -ENOENT; | 733 | ret = -ENOENT; |
@@ -750,7 +757,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
750 | } | 757 | } |
751 | 758 | ||
752 | stop_BA_exit: | 759 | stop_BA_exit: |
753 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 760 | spin_unlock_bh(&sta->lock); |
754 | rcu_read_unlock(); | 761 | rcu_read_unlock(); |
755 | return ret; | 762 | return ret; |
756 | } | 763 | } |
@@ -779,12 +786,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
779 | } | 786 | } |
780 | 787 | ||
781 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 788 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
782 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 789 | spin_lock_bh(&sta->lock); |
783 | 790 | ||
784 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 791 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
785 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 792 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
786 | *state); | 793 | *state); |
787 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 794 | spin_unlock_bh(&sta->lock); |
788 | rcu_read_unlock(); | 795 | rcu_read_unlock(); |
789 | return; | 796 | return; |
790 | } | 797 | } |
@@ -797,7 +804,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
797 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 804 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
798 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 805 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
799 | } | 806 | } |
800 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 807 | spin_unlock_bh(&sta->lock); |
801 | rcu_read_unlock(); | 808 | rcu_read_unlock(); |
802 | } | 809 | } |
803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 810 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
@@ -831,10 +838,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
831 | } | 838 | } |
832 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 839 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
833 | 840 | ||
834 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 841 | /* NOTE: no need to use sta->lock in this state check, as |
842 | * ieee80211_stop_tx_ba_session will let only | ||
843 | * one stop call to pass through per sta/tid */ | ||
835 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 844 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
836 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 845 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
837 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
838 | rcu_read_unlock(); | 846 | rcu_read_unlock(); |
839 | return; | 847 | return; |
840 | } | 848 | } |
@@ -857,11 +865,12 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
857 | * ieee80211_wake_queue is not used here as this queue is not | 865 | * ieee80211_wake_queue is not used here as this queue is not |
858 | * necessarily stopped */ | 866 | * necessarily stopped */ |
859 | netif_schedule(local->mdev); | 867 | netif_schedule(local->mdev); |
868 | spin_lock_bh(&sta->lock); | ||
860 | *state = HT_AGG_STATE_IDLE; | 869 | *state = HT_AGG_STATE_IDLE; |
861 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 870 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
862 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 871 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
863 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 872 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
864 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 873 | spin_unlock_bh(&sta->lock); |
865 | 874 | ||
866 | rcu_read_unlock(); | 875 | rcu_read_unlock(); |
867 | } | 876 | } |
@@ -967,8 +976,7 @@ void ieee80211_if_setup(struct net_device *dev) | |||
967 | /* everything else */ | 976 | /* everything else */ |
968 | 977 | ||
969 | static int __ieee80211_if_config(struct net_device *dev, | 978 | static int __ieee80211_if_config(struct net_device *dev, |
970 | struct sk_buff *beacon, | 979 | struct sk_buff *beacon) |
971 | struct ieee80211_tx_control *control) | ||
972 | { | 980 | { |
973 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 981 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
974 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 982 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -986,13 +994,11 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
986 | conf.ssid_len = sdata->u.sta.ssid_len; | 994 | conf.ssid_len = sdata->u.sta.ssid_len; |
987 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 995 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
988 | conf.beacon = beacon; | 996 | conf.beacon = beacon; |
989 | conf.beacon_control = control; | ||
990 | ieee80211_start_mesh(dev); | 997 | ieee80211_start_mesh(dev); |
991 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 998 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
992 | conf.ssid = sdata->u.ap.ssid; | 999 | conf.ssid = sdata->u.ap.ssid; |
993 | conf.ssid_len = sdata->u.ap.ssid_len; | 1000 | conf.ssid_len = sdata->u.ap.ssid_len; |
994 | conf.beacon = beacon; | 1001 | conf.beacon = beacon; |
995 | conf.beacon_control = control; | ||
996 | } | 1002 | } |
997 | return local->ops->config_interface(local_to_hw(local), | 1003 | return local->ops->config_interface(local_to_hw(local), |
998 | &sdata->vif, &conf); | 1004 | &sdata->vif, &conf); |
@@ -1005,23 +1011,21 @@ int ieee80211_if_config(struct net_device *dev) | |||
1005 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | 1011 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && |
1006 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1012 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
1007 | return ieee80211_if_config_beacon(dev); | 1013 | return ieee80211_if_config_beacon(dev); |
1008 | return __ieee80211_if_config(dev, NULL, NULL); | 1014 | return __ieee80211_if_config(dev, NULL); |
1009 | } | 1015 | } |
1010 | 1016 | ||
1011 | int ieee80211_if_config_beacon(struct net_device *dev) | 1017 | int ieee80211_if_config_beacon(struct net_device *dev) |
1012 | { | 1018 | { |
1013 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1019 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1014 | struct ieee80211_tx_control control; | ||
1015 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1020 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1016 | struct sk_buff *skb; | 1021 | struct sk_buff *skb; |
1017 | 1022 | ||
1018 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1023 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
1019 | return 0; | 1024 | return 0; |
1020 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, | 1025 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif); |
1021 | &control); | ||
1022 | if (!skb) | 1026 | if (!skb) |
1023 | return -ENOMEM; | 1027 | return -ENOMEM; |
1024 | return __ieee80211_if_config(dev, skb, &control); | 1028 | return __ieee80211_if_config(dev, skb); |
1025 | } | 1029 | } |
1026 | 1030 | ||
1027 | int ieee80211_hw_config(struct ieee80211_local *local) | 1031 | int ieee80211_hw_config(struct ieee80211_local *local) |
@@ -1068,56 +1072,84 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | |||
1068 | struct ieee80211_supported_band *sband; | 1072 | struct ieee80211_supported_band *sband; |
1069 | struct ieee80211_ht_info ht_conf; | 1073 | struct ieee80211_ht_info ht_conf; |
1070 | struct ieee80211_ht_bss_info ht_bss_conf; | 1074 | struct ieee80211_ht_bss_info ht_bss_conf; |
1071 | int i; | ||
1072 | u32 changed = 0; | 1075 | u32 changed = 0; |
1076 | int i; | ||
1077 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
1078 | u8 tx_mcs_set_cap; | ||
1073 | 1079 | ||
1074 | sband = local->hw.wiphy->bands[conf->channel->band]; | 1080 | sband = local->hw.wiphy->bands[conf->channel->band]; |
1075 | 1081 | ||
1082 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
1083 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
1084 | |||
1076 | /* HT is not supported */ | 1085 | /* HT is not supported */ |
1077 | if (!sband->ht_info.ht_supported) { | 1086 | if (!sband->ht_info.ht_supported) { |
1078 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1087 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
1079 | return 0; | 1088 | goto out; |
1080 | } | 1089 | } |
1081 | 1090 | ||
1082 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | 1091 | /* disable HT */ |
1083 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | 1092 | if (!enable_ht) { |
1084 | 1093 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | |
1085 | if (enable_ht) { | ||
1086 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
1087 | changed |= BSS_CHANGED_HT; | 1094 | changed |= BSS_CHANGED_HT; |
1095 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1096 | conf->ht_conf.ht_supported = 0; | ||
1097 | goto out; | ||
1098 | } | ||
1088 | 1099 | ||
1089 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1090 | ht_conf.ht_supported = 1; | ||
1091 | 1100 | ||
1092 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | 1101 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) |
1093 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1102 | changed |= BSS_CHANGED_HT; |
1094 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | ||
1095 | 1103 | ||
1096 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1104 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
1097 | ht_conf.supp_mcs_set[i] = | 1105 | ht_conf.ht_supported = 1; |
1098 | sband->ht_info.supp_mcs_set[i] & | ||
1099 | req_ht_cap->supp_mcs_set[i]; | ||
1100 | 1106 | ||
1101 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | 1107 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
1102 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 1108 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
1103 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 1109 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
1110 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
1111 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
1112 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
1104 | 1113 | ||
1105 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | 1114 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; |
1106 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | 1115 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; |
1107 | 1116 | ||
1108 | /* if bss configuration changed store the new one */ | 1117 | /* Bits 96-100 */ |
1109 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | 1118 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; |
1110 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | 1119 | |
1111 | changed |= BSS_CHANGED_HT; | 1120 | /* configure suppoerted Tx MCS according to requested MCS |
1112 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | 1121 | * (based in most cases on Rx capabilities of peer) and self |
1113 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | 1122 | * Tx MCS capabilities (as defined by low level driver HW |
1114 | } | 1123 | * Tx capabilities) */ |
1115 | } else { | 1124 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) |
1116 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 1125 | goto check_changed; |
1117 | changed |= BSS_CHANGED_HT; | ||
1118 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1119 | } | ||
1120 | 1126 | ||
1127 | /* Counting from 0 therfore + 1 */ | ||
1128 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) | ||
1129 | max_tx_streams = ((tx_mcs_set_cap & | ||
1130 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
1131 | |||
1132 | for (i = 0; i < max_tx_streams; i++) | ||
1133 | ht_conf.supp_mcs_set[i] = | ||
1134 | sband->ht_info.supp_mcs_set[i] & | ||
1135 | req_ht_cap->supp_mcs_set[i]; | ||
1136 | |||
1137 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
1138 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
1139 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
1140 | ht_conf.supp_mcs_set[i] = | ||
1141 | sband->ht_info.supp_mcs_set[i] & | ||
1142 | req_ht_cap->supp_mcs_set[i]; | ||
1143 | |||
1144 | check_changed: | ||
1145 | /* if bss configuration changed store the new one */ | ||
1146 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
1147 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
1148 | changed |= BSS_CHANGED_HT; | ||
1149 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
1150 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
1151 | } | ||
1152 | out: | ||
1121 | return changed; | 1153 | return changed; |
1122 | } | 1154 | } |
1123 | 1155 | ||
@@ -1148,38 +1180,20 @@ void ieee80211_reset_erp_info(struct net_device *dev) | |||
1148 | } | 1180 | } |
1149 | 1181 | ||
1150 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 1182 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
1151 | struct sk_buff *skb, | 1183 | struct sk_buff *skb) |
1152 | struct ieee80211_tx_status *status) | ||
1153 | { | 1184 | { |
1154 | struct ieee80211_local *local = hw_to_local(hw); | 1185 | struct ieee80211_local *local = hw_to_local(hw); |
1155 | struct ieee80211_tx_status *saved; | 1186 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1156 | int tmp; | 1187 | int tmp; |
1157 | 1188 | ||
1158 | skb->dev = local->mdev; | 1189 | skb->dev = local->mdev; |
1159 | saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC); | ||
1160 | if (unlikely(!saved)) { | ||
1161 | if (net_ratelimit()) | ||
1162 | printk(KERN_WARNING "%s: Not enough memory, " | ||
1163 | "dropping tx status", skb->dev->name); | ||
1164 | /* should be dev_kfree_skb_irq, but due to this function being | ||
1165 | * named _irqsafe instead of just _irq we can't be sure that | ||
1166 | * people won't call it from non-irq contexts */ | ||
1167 | dev_kfree_skb_any(skb); | ||
1168 | return; | ||
1169 | } | ||
1170 | memcpy(saved, status, sizeof(struct ieee80211_tx_status)); | ||
1171 | /* copy pointer to saved status into skb->cb for use by tasklet */ | ||
1172 | memcpy(skb->cb, &saved, sizeof(saved)); | ||
1173 | |||
1174 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | 1190 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; |
1175 | skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ? | 1191 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? |
1176 | &local->skb_queue : &local->skb_queue_unreliable, skb); | 1192 | &local->skb_queue : &local->skb_queue_unreliable, skb); |
1177 | tmp = skb_queue_len(&local->skb_queue) + | 1193 | tmp = skb_queue_len(&local->skb_queue) + |
1178 | skb_queue_len(&local->skb_queue_unreliable); | 1194 | skb_queue_len(&local->skb_queue_unreliable); |
1179 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | 1195 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
1180 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1196 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
1181 | memcpy(&saved, skb->cb, sizeof(saved)); | ||
1182 | kfree(saved); | ||
1183 | dev_kfree_skb_irq(skb); | 1197 | dev_kfree_skb_irq(skb); |
1184 | tmp--; | 1198 | tmp--; |
1185 | I802_DEBUG_INC(local->tx_status_drop); | 1199 | I802_DEBUG_INC(local->tx_status_drop); |
@@ -1193,7 +1207,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1193 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 1207 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
1194 | struct sk_buff *skb; | 1208 | struct sk_buff *skb; |
1195 | struct ieee80211_rx_status rx_status; | 1209 | struct ieee80211_rx_status rx_status; |
1196 | struct ieee80211_tx_status *tx_status; | ||
1197 | struct ieee80211_ra_tid *ra_tid; | 1210 | struct ieee80211_ra_tid *ra_tid; |
1198 | 1211 | ||
1199 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1212 | while ((skb = skb_dequeue(&local->skb_queue)) || |
@@ -1208,12 +1221,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1208 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); | 1221 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); |
1209 | break; | 1222 | break; |
1210 | case IEEE80211_TX_STATUS_MSG: | 1223 | case IEEE80211_TX_STATUS_MSG: |
1211 | /* get pointer to saved status out of skb->cb */ | ||
1212 | memcpy(&tx_status, skb->cb, sizeof(tx_status)); | ||
1213 | skb->pkt_type = 0; | 1224 | skb->pkt_type = 0; |
1214 | ieee80211_tx_status(local_to_hw(local), | 1225 | ieee80211_tx_status(local_to_hw(local), skb); |
1215 | skb, tx_status); | ||
1216 | kfree(tx_status); | ||
1217 | break; | 1226 | break; |
1218 | case IEEE80211_DELBA_MSG: | 1227 | case IEEE80211_DELBA_MSG: |
1219 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 1228 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -1242,24 +1251,15 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1242 | * Also, tx_packet_data in cb is restored from tx_control. */ | 1251 | * Also, tx_packet_data in cb is restored from tx_control. */ |
1243 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1252 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1244 | struct ieee80211_key *key, | 1253 | struct ieee80211_key *key, |
1245 | struct sk_buff *skb, | 1254 | struct sk_buff *skb) |
1246 | struct ieee80211_tx_control *control) | ||
1247 | { | 1255 | { |
1248 | int hdrlen, iv_len, mic_len; | 1256 | int hdrlen, iv_len, mic_len; |
1249 | struct ieee80211_tx_packet_data *pkt_data; | 1257 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1250 | 1258 | ||
1251 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1259 | info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | |
1252 | pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; | 1260 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT | |
1253 | pkt_data->flags = 0; | 1261 | IEEE80211_TX_CTL_REQUEUE | |
1254 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 1262 | IEEE80211_TX_CTL_EAPOL_FRAME; |
1255 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1256 | if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT) | ||
1257 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | ||
1258 | if (control->flags & IEEE80211_TXCTL_REQUEUE) | ||
1259 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | ||
1260 | if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) | ||
1261 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | ||
1262 | pkt_data->queue = control->queue; | ||
1263 | 1263 | ||
1264 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1264 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1265 | 1265 | ||
@@ -1306,9 +1306,10 @@ no_key: | |||
1306 | 1306 | ||
1307 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 1307 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
1308 | struct sta_info *sta, | 1308 | struct sta_info *sta, |
1309 | struct sk_buff *skb, | 1309 | struct sk_buff *skb) |
1310 | struct ieee80211_tx_status *status) | ||
1311 | { | 1310 | { |
1311 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1312 | |||
1312 | sta->tx_filtered_count++; | 1313 | sta->tx_filtered_count++; |
1313 | 1314 | ||
1314 | /* | 1315 | /* |
@@ -1316,7 +1317,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1316 | * packet. If the STA went to power save mode, this will happen | 1317 | * packet. If the STA went to power save mode, this will happen |
1317 | * when it wakes up for the next time. | 1318 | * when it wakes up for the next time. |
1318 | */ | 1319 | */ |
1319 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | 1320 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); |
1320 | 1321 | ||
1321 | /* | 1322 | /* |
1322 | * This code races in the following way: | 1323 | * This code races in the following way: |
@@ -1348,20 +1349,18 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1348 | * can be unknown, for example with different interrupt status | 1349 | * can be unknown, for example with different interrupt status |
1349 | * bits. | 1350 | * bits. |
1350 | */ | 1351 | */ |
1351 | if (sta->flags & WLAN_STA_PS && | 1352 | if (test_sta_flags(sta, WLAN_STA_PS) && |
1352 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1353 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
1353 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1354 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1354 | &status->control); | ||
1355 | skb_queue_tail(&sta->tx_filtered, skb); | 1355 | skb_queue_tail(&sta->tx_filtered, skb); |
1356 | return; | 1356 | return; |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | if (!(sta->flags & WLAN_STA_PS) && | 1359 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
1360 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1360 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { |
1361 | /* Software retry the packet once */ | 1361 | /* Software retry the packet once */ |
1362 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1362 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
1363 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1363 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1364 | &status->control); | ||
1365 | dev_queue_xmit(skb); | 1364 | dev_queue_xmit(skb); |
1366 | return; | 1365 | return; |
1367 | } | 1366 | } |
@@ -1371,61 +1370,49 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1371 | "queue_len=%d PS=%d @%lu\n", | 1370 | "queue_len=%d PS=%d @%lu\n", |
1372 | wiphy_name(local->hw.wiphy), | 1371 | wiphy_name(local->hw.wiphy), |
1373 | skb_queue_len(&sta->tx_filtered), | 1372 | skb_queue_len(&sta->tx_filtered), |
1374 | !!(sta->flags & WLAN_STA_PS), jiffies); | 1373 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
1375 | dev_kfree_skb(skb); | 1374 | dev_kfree_skb(skb); |
1376 | } | 1375 | } |
1377 | 1376 | ||
1378 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1377 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
1379 | struct ieee80211_tx_status *status) | ||
1380 | { | 1378 | { |
1381 | struct sk_buff *skb2; | 1379 | struct sk_buff *skb2; |
1382 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1380 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1383 | struct ieee80211_local *local = hw_to_local(hw); | 1381 | struct ieee80211_local *local = hw_to_local(hw); |
1382 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1384 | u16 frag, type; | 1383 | u16 frag, type; |
1385 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1384 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
1386 | struct ieee80211_sub_if_data *sdata; | 1385 | struct ieee80211_sub_if_data *sdata; |
1387 | struct net_device *prev_dev = NULL; | 1386 | struct net_device *prev_dev = NULL; |
1388 | 1387 | ||
1389 | if (!status) { | ||
1390 | printk(KERN_ERR | ||
1391 | "%s: ieee80211_tx_status called with NULL status\n", | ||
1392 | wiphy_name(local->hw.wiphy)); | ||
1393 | dev_kfree_skb(skb); | ||
1394 | return; | ||
1395 | } | ||
1396 | |||
1397 | rcu_read_lock(); | 1388 | rcu_read_lock(); |
1398 | 1389 | ||
1399 | if (status->excessive_retries) { | 1390 | if (info->status.excessive_retries) { |
1400 | struct sta_info *sta; | 1391 | struct sta_info *sta; |
1401 | sta = sta_info_get(local, hdr->addr1); | 1392 | sta = sta_info_get(local, hdr->addr1); |
1402 | if (sta) { | 1393 | if (sta) { |
1403 | if (sta->flags & WLAN_STA_PS) { | 1394 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
1404 | /* | 1395 | /* |
1405 | * The STA is in power save mode, so assume | 1396 | * The STA is in power save mode, so assume |
1406 | * that this TX packet failed because of that. | 1397 | * that this TX packet failed because of that. |
1407 | */ | 1398 | */ |
1408 | status->excessive_retries = 0; | 1399 | ieee80211_handle_filtered_frame(local, sta, skb); |
1409 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | ||
1410 | ieee80211_handle_filtered_frame(local, sta, | ||
1411 | skb, status); | ||
1412 | rcu_read_unlock(); | 1400 | rcu_read_unlock(); |
1413 | return; | 1401 | return; |
1414 | } | 1402 | } |
1415 | } | 1403 | } |
1416 | } | 1404 | } |
1417 | 1405 | ||
1418 | if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) { | 1406 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
1419 | struct sta_info *sta; | 1407 | struct sta_info *sta; |
1420 | sta = sta_info_get(local, hdr->addr1); | 1408 | sta = sta_info_get(local, hdr->addr1); |
1421 | if (sta) { | 1409 | if (sta) { |
1422 | ieee80211_handle_filtered_frame(local, sta, skb, | 1410 | ieee80211_handle_filtered_frame(local, sta, skb); |
1423 | status); | ||
1424 | rcu_read_unlock(); | 1411 | rcu_read_unlock(); |
1425 | return; | 1412 | return; |
1426 | } | 1413 | } |
1427 | } else | 1414 | } else |
1428 | rate_control_tx_status(local->mdev, skb, status); | 1415 | rate_control_tx_status(local->mdev, skb); |
1429 | 1416 | ||
1430 | rcu_read_unlock(); | 1417 | rcu_read_unlock(); |
1431 | 1418 | ||
@@ -1439,14 +1426,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1439 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 1426 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
1440 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | 1427 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; |
1441 | 1428 | ||
1442 | if (status->flags & IEEE80211_TX_STATUS_ACK) { | 1429 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
1443 | if (frag == 0) { | 1430 | if (frag == 0) { |
1444 | local->dot11TransmittedFrameCount++; | 1431 | local->dot11TransmittedFrameCount++; |
1445 | if (is_multicast_ether_addr(hdr->addr1)) | 1432 | if (is_multicast_ether_addr(hdr->addr1)) |
1446 | local->dot11MulticastTransmittedFrameCount++; | 1433 | local->dot11MulticastTransmittedFrameCount++; |
1447 | if (status->retry_count > 0) | 1434 | if (info->status.retry_count > 0) |
1448 | local->dot11RetryCount++; | 1435 | local->dot11RetryCount++; |
1449 | if (status->retry_count > 1) | 1436 | if (info->status.retry_count > 1) |
1450 | local->dot11MultipleRetryCount++; | 1437 | local->dot11MultipleRetryCount++; |
1451 | } | 1438 | } |
1452 | 1439 | ||
@@ -1483,7 +1470,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1483 | return; | 1470 | return; |
1484 | } | 1471 | } |
1485 | 1472 | ||
1486 | rthdr = (struct ieee80211_tx_status_rtap_hdr*) | 1473 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) |
1487 | skb_push(skb, sizeof(*rthdr)); | 1474 | skb_push(skb, sizeof(*rthdr)); |
1488 | 1475 | ||
1489 | memset(rthdr, 0, sizeof(*rthdr)); | 1476 | memset(rthdr, 0, sizeof(*rthdr)); |
@@ -1492,17 +1479,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1492 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 1479 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
1493 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 1480 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); |
1494 | 1481 | ||
1495 | if (!(status->flags & IEEE80211_TX_STATUS_ACK) && | 1482 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
1496 | !is_multicast_ether_addr(hdr->addr1)) | 1483 | !is_multicast_ether_addr(hdr->addr1)) |
1497 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 1484 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
1498 | 1485 | ||
1499 | if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && | 1486 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && |
1500 | (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) | 1487 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) |
1501 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 1488 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
1502 | else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1489 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1503 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 1490 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
1504 | 1491 | ||
1505 | rthdr->data_retries = status->retry_count; | 1492 | rthdr->data_retries = info->status.retry_count; |
1506 | 1493 | ||
1507 | /* XXX: is this sufficient for BPF? */ | 1494 | /* XXX: is this sufficient for BPF? */ |
1508 | skb_set_mac_header(skb, 0); | 1495 | skb_set_mac_header(skb, 0); |
@@ -1652,12 +1639,32 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1652 | if (result < 0) | 1639 | if (result < 0) |
1653 | return result; | 1640 | return result; |
1654 | 1641 | ||
1642 | /* | ||
1643 | * We use the number of queues for feature tests (QoS, HT) internally | ||
1644 | * so restrict them appropriately. | ||
1645 | */ | ||
1646 | #ifdef CONFIG_MAC80211_QOS | ||
1647 | if (hw->queues > IEEE80211_MAX_QUEUES) | ||
1648 | hw->queues = IEEE80211_MAX_QUEUES; | ||
1649 | if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) | ||
1650 | hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; | ||
1651 | if (hw->queues < 4) | ||
1652 | hw->ampdu_queues = 0; | ||
1653 | #else | ||
1654 | hw->queues = 1; | ||
1655 | hw->ampdu_queues = 0; | ||
1656 | #endif | ||
1657 | |||
1655 | /* for now, mdev needs sub_if_data :/ */ | 1658 | /* for now, mdev needs sub_if_data :/ */ |
1656 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | 1659 | mdev = alloc_netdev_mq(sizeof(struct ieee80211_sub_if_data), |
1657 | "wmaster%d", ether_setup); | 1660 | "wmaster%d", ether_setup, |
1661 | ieee80211_num_queues(hw)); | ||
1658 | if (!mdev) | 1662 | if (!mdev) |
1659 | goto fail_mdev_alloc; | 1663 | goto fail_mdev_alloc; |
1660 | 1664 | ||
1665 | if (ieee80211_num_queues(hw) > 1) | ||
1666 | mdev->features |= NETIF_F_MULTI_QUEUE; | ||
1667 | |||
1661 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | 1668 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); |
1662 | mdev->ieee80211_ptr = &sdata->wdev; | 1669 | mdev->ieee80211_ptr = &sdata->wdev; |
1663 | sdata->wdev.wiphy = local->hw.wiphy; | 1670 | sdata->wdev.wiphy = local->hw.wiphy; |
@@ -1702,13 +1709,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1702 | 1709 | ||
1703 | local->hw.conf.beacon_int = 1000; | 1710 | local->hw.conf.beacon_int = 1000; |
1704 | 1711 | ||
1705 | local->wstats_flags |= local->hw.max_rssi ? | 1712 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
1706 | IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; | 1713 | IEEE80211_HW_SIGNAL_DB | |
1707 | local->wstats_flags |= local->hw.max_signal ? | 1714 | IEEE80211_HW_SIGNAL_DBM) ? |
1708 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | 1715 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; |
1709 | local->wstats_flags |= local->hw.max_noise ? | 1716 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? |
1710 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | 1717 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; |
1711 | if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) | 1718 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
1712 | local->wstats_flags |= IW_QUAL_DBM; | 1719 | local->wstats_flags |= IW_QUAL_DBM; |
1713 | 1720 | ||
1714 | result = sta_info_start(local); | 1721 | result = sta_info_start(local); |
@@ -1858,7 +1865,9 @@ static int __init ieee80211_init(void) | |||
1858 | struct sk_buff *skb; | 1865 | struct sk_buff *skb; |
1859 | int ret; | 1866 | int ret; |
1860 | 1867 | ||
1861 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1868 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1869 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | ||
1870 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | ||
1862 | 1871 | ||
1863 | ret = rc80211_pid_init(); | 1872 | ret = rc80211_pid_init(); |
1864 | if (ret) | 1873 | if (ret) |