diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-15 06:34:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-17 22:21:12 -0400 |
commit | 51cb6db0f5654f08a4a6bfa3888dc36a51c2df3e (patch) | |
tree | b9103a34674efeca9ffa2f9ef9cec1ee9735ab9d /net/mac80211/main.c | |
parent | eae792b722fef08dcf3aee88266ee7def9710757 (diff) |
mac80211: Reimplement WME using ->select_queue().
The only behavior change is that we do not drop packets under any
circumstances. If that is absolutely needed, we could easily add it
back.
With cleanups and help from Johannes Berg.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 61 |
1 files changed, 15 insertions, 46 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c74607eda1ee..f1a83d450ea0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -114,7 +114,7 @@ static int ieee80211_master_open(struct net_device *dev) | |||
114 | if (res) | 114 | if (res) |
115 | return res; | 115 | return res; |
116 | 116 | ||
117 | netif_start_queue(local->mdev); | 117 | netif_tx_start_all_queues(local->mdev); |
118 | 118 | ||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
@@ -375,7 +375,7 @@ static int ieee80211_open(struct net_device *dev) | |||
375 | queue_work(local->hw.workqueue, &ifsta->work); | 375 | queue_work(local->hw.workqueue, &ifsta->work); |
376 | } | 376 | } |
377 | 377 | ||
378 | netif_start_queue(dev); | 378 | netif_tx_start_all_queues(dev); |
379 | 379 | ||
380 | return 0; | 380 | return 0; |
381 | err_del_interface: | 381 | err_del_interface: |
@@ -400,7 +400,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
400 | /* | 400 | /* |
401 | * Stop TX on this interface first. | 401 | * Stop TX on this interface first. |
402 | */ | 402 | */ |
403 | netif_stop_queue(dev); | 403 | netif_tx_stop_all_queues(dev); |
404 | 404 | ||
405 | /* | 405 | /* |
406 | * Now delete all active aggregation sessions. | 406 | * Now delete all active aggregation sessions. |
@@ -554,7 +554,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
554 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 554 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) |
555 | { | 555 | { |
556 | struct ieee80211_local *local = hw_to_local(hw); | 556 | struct ieee80211_local *local = hw_to_local(hw); |
557 | struct netdev_queue *txq; | ||
558 | struct sta_info *sta; | 557 | struct sta_info *sta; |
559 | struct ieee80211_sub_if_data *sdata; | 558 | struct ieee80211_sub_if_data *sdata; |
560 | u16 start_seq_num = 0; | 559 | u16 start_seq_num = 0; |
@@ -619,11 +618,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
619 | (unsigned long)&sta->timer_to_tid[tid]; | 618 | (unsigned long)&sta->timer_to_tid[tid]; |
620 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 619 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
621 | 620 | ||
622 | /* ensure that TX flow won't interrupt us | ||
623 | * until the end of the call to requeue function */ | ||
624 | txq = netdev_get_tx_queue(local->mdev, 0); | ||
625 | spin_lock_bh(&txq->lock); | ||
626 | |||
627 | /* create a new queue for this aggregation */ | 621 | /* create a new queue for this aggregation */ |
628 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | 622 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); |
629 | 623 | ||
@@ -650,7 +644,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
650 | /* No need to requeue the packets in the agg queue, since we | 644 | /* No need to requeue the packets in the agg queue, since we |
651 | * held the tx lock: no packet could be enqueued to the newly | 645 | * held the tx lock: no packet could be enqueued to the newly |
652 | * allocated queue */ | 646 | * allocated queue */ |
653 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | 647 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); |
654 | #ifdef CONFIG_MAC80211_HT_DEBUG | 648 | #ifdef CONFIG_MAC80211_HT_DEBUG |
655 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | 649 | printk(KERN_DEBUG "BA request denied - HW unavailable for" |
656 | " tid %d\n", tid); | 650 | " tid %d\n", tid); |
@@ -661,7 +655,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
661 | 655 | ||
662 | /* Will put all the packets in the new SW queue */ | 656 | /* Will put all the packets in the new SW queue */ |
663 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 657 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); |
664 | spin_unlock_bh(&txq->lock); | ||
665 | spin_unlock_bh(&sta->lock); | 658 | spin_unlock_bh(&sta->lock); |
666 | 659 | ||
667 | /* send an addBA request */ | 660 | /* send an addBA request */ |
@@ -687,7 +680,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
687 | err_unlock_queue: | 680 | err_unlock_queue: |
688 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 681 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
689 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 682 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
690 | spin_unlock_bh(&txq->lock); | ||
691 | ret = -EBUSY; | 683 | ret = -EBUSY; |
692 | err_unlock_sta: | 684 | err_unlock_sta: |
693 | spin_unlock_bh(&sta->lock); | 685 | spin_unlock_bh(&sta->lock); |
@@ -812,7 +804,6 @@ EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | |||
812 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 804 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) |
813 | { | 805 | { |
814 | struct ieee80211_local *local = hw_to_local(hw); | 806 | struct ieee80211_local *local = hw_to_local(hw); |
815 | struct netdev_queue *txq; | ||
816 | struct sta_info *sta; | 807 | struct sta_info *sta; |
817 | u8 *state; | 808 | u8 *state; |
818 | int agg_queue; | 809 | int agg_queue; |
@@ -844,8 +835,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
844 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 835 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
845 | 836 | ||
846 | /* NOTE: no need to use sta->lock in this state check, as | 837 | /* NOTE: no need to use sta->lock in this state check, as |
847 | * ieee80211_stop_tx_ba_session will let only | 838 | * ieee80211_stop_tx_ba_session will let only one stop call to |
848 | * one stop call to pass through per sta/tid */ | 839 | * pass through per sta/tid |
840 | */ | ||
849 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 841 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
850 | #ifdef CONFIG_MAC80211_HT_DEBUG | 842 | #ifdef CONFIG_MAC80211_HT_DEBUG |
851 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 843 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
@@ -860,19 +852,14 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
860 | 852 | ||
861 | agg_queue = sta->tid_to_tx_q[tid]; | 853 | agg_queue = sta->tid_to_tx_q[tid]; |
862 | 854 | ||
863 | /* avoid ordering issues: we are the only one that can modify | ||
864 | * the content of the qdiscs */ | ||
865 | txq = netdev_get_tx_queue(local->mdev, 0); | ||
866 | spin_lock_bh(&txq->lock); | ||
867 | /* remove the queue for this aggregation */ | ||
868 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | 855 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); |
869 | spin_unlock_bh(&txq->lock); | ||
870 | 856 | ||
871 | /* we just requeued the all the frames that were in the removed | 857 | /* We just requeued the all the frames that were in the |
872 | * queue, and since we might miss a softirq we do netif_schedule_queue. | 858 | * removed queue, and since we might miss a softirq we do |
873 | * ieee80211_wake_queue is not used here as this queue is not | 859 | * netif_schedule_queue. ieee80211_wake_queue is not used |
874 | * necessarily stopped */ | 860 | * here as this queue is not necessarily stopped |
875 | netif_schedule_queue(txq); | 861 | */ |
862 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); | ||
876 | spin_lock_bh(&sta->lock); | 863 | spin_lock_bh(&sta->lock); |
877 | *state = HT_AGG_STATE_IDLE; | 864 | *state = HT_AGG_STATE_IDLE; |
878 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 865 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
@@ -1660,17 +1647,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1660 | * We use the number of queues for feature tests (QoS, HT) internally | 1647 | * We use the number of queues for feature tests (QoS, HT) internally |
1661 | * so restrict them appropriately. | 1648 | * so restrict them appropriately. |
1662 | */ | 1649 | */ |
1663 | #ifdef CONFIG_MAC80211_QOS | ||
1664 | if (hw->queues > IEEE80211_MAX_QUEUES) | 1650 | if (hw->queues > IEEE80211_MAX_QUEUES) |
1665 | hw->queues = IEEE80211_MAX_QUEUES; | 1651 | hw->queues = IEEE80211_MAX_QUEUES; |
1666 | if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) | 1652 | if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) |
1667 | hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; | 1653 | hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; |
1668 | if (hw->queues < 4) | 1654 | if (hw->queues < 4) |
1669 | hw->ampdu_queues = 0; | 1655 | hw->ampdu_queues = 0; |
1670 | #else | ||
1671 | hw->queues = 1; | ||
1672 | hw->ampdu_queues = 0; | ||
1673 | #endif | ||
1674 | 1656 | ||
1675 | mdev = alloc_netdev_mq(sizeof(struct wireless_dev), | 1657 | mdev = alloc_netdev_mq(sizeof(struct wireless_dev), |
1676 | "wmaster%d", ether_setup, | 1658 | "wmaster%d", ether_setup, |
@@ -1754,7 +1736,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1754 | goto fail_wep; | 1736 | goto fail_wep; |
1755 | } | 1737 | } |
1756 | 1738 | ||
1757 | ieee80211_install_qdisc(local->mdev); | 1739 | local->mdev->select_queue = ieee80211_select_queue; |
1758 | 1740 | ||
1759 | /* add one default STA interface */ | 1741 | /* add one default STA interface */ |
1760 | result = ieee80211_if_add(local, "wlan%d", NULL, | 1742 | result = ieee80211_if_add(local, "wlan%d", NULL, |
@@ -1852,23 +1834,11 @@ static int __init ieee80211_init(void) | |||
1852 | 1834 | ||
1853 | ret = rc80211_pid_init(); | 1835 | ret = rc80211_pid_init(); |
1854 | if (ret) | 1836 | if (ret) |
1855 | goto out; | 1837 | return ret; |
1856 | |||
1857 | ret = ieee80211_wme_register(); | ||
1858 | if (ret) { | ||
1859 | printk(KERN_DEBUG "ieee80211_init: failed to " | ||
1860 | "initialize WME (err=%d)\n", ret); | ||
1861 | goto out_cleanup_pid; | ||
1862 | } | ||
1863 | 1838 | ||
1864 | ieee80211_debugfs_netdev_init(); | 1839 | ieee80211_debugfs_netdev_init(); |
1865 | 1840 | ||
1866 | return 0; | 1841 | return 0; |
1867 | |||
1868 | out_cleanup_pid: | ||
1869 | rc80211_pid_exit(); | ||
1870 | out: | ||
1871 | return ret; | ||
1872 | } | 1842 | } |
1873 | 1843 | ||
1874 | static void __exit ieee80211_exit(void) | 1844 | static void __exit ieee80211_exit(void) |
@@ -1884,7 +1854,6 @@ static void __exit ieee80211_exit(void) | |||
1884 | if (mesh_allocated) | 1854 | if (mesh_allocated) |
1885 | ieee80211s_stop(); | 1855 | ieee80211s_stop(); |
1886 | 1856 | ||
1887 | ieee80211_wme_unregister(); | ||
1888 | ieee80211_debugfs_netdev_exit(); | 1857 | ieee80211_debugfs_netdev_exit(); |
1889 | } | 1858 | } |
1890 | 1859 | ||