mac80211: refuse TX queue configuration on non-QoS HW
authorJohannes Berg <johannes.berg@intel.com>
Wed, 28 Mar 2012 09:04:25 +0000 (11:04 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 10 Apr 2012 18:54:10 +0000 (14:54 -0400)
Drivers that don't support QoS also don't support
setting up their ACs, catch that early. While at
it, remove the input check since cfg80211 does it
now.

Also fix up the restart code to not try to set up
the queues in this case.

Finally also change the tx_conf array to have
IEEE80211_NUM_ACS entries instead of # of queues
since that's what it really needs.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/util.c

index ef40db5ab3c77610f338aa9614d262d968e0710c..12226b7743c6ed7eadd49b28aefccfb0b5ab5c22 100644 (file)
@@ -1437,6 +1437,9 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
        if (!local->ops->conf_tx)
                return -EOPNOTSUPP;
 
+       if (local->hw.queues < IEEE80211_NUM_ACS)
+               return -EOPNOTSUPP;
+
        memset(&p, 0, sizeof(p));
        p.aifs = params->aifs;
        p.cw_max = params->cwmax;
@@ -1449,9 +1452,6 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
         */
        p.uapsd = false;
 
-       if (params->ac >= local->hw.queues)
-               return -EINVAL;
-
        sdata->tx_conf[params->ac] = p;
        if (drv_conf_tx(local, sdata, params->ac, &p)) {
                wiphy_debug(local->hw.wiphy,
index 93b075e14d09f76d22f418875228ebdf37b49bc5..8e7af7cee013fa27555b5b8b74cc3167d7e663e2 100644 (file)
@@ -687,7 +687,7 @@ struct ieee80211_sub_if_data {
        __be16 control_port_protocol;
        bool control_port_no_encrypt;
 
-       struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES];
+       struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
 
        struct work_struct work;
        struct sk_buff_head skb_queue;
index 1d4b8b7a5a333f4d8a14431ddf09007b704528dc..2b62307825d4333c909d726afac8e2985d0ee051 100644 (file)
@@ -769,19 +769,22 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_queue_params qparam;
-       int queue;
+       int ac;
        bool use_11b;
        int aCWmin, aCWmax;
 
        if (!local->ops->conf_tx)
                return;
 
+       if (local->hw.queues < IEEE80211_NUM_ACS)
+               return;
+
        memset(&qparam, 0, sizeof(qparam));
 
        use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
                 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
 
-       for (queue = 0; queue < local->hw.queues; queue++) {
+       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
                /* Set defaults according to 802.11-2007 Table 7-37 */
                aCWmax = 1023;
                if (use_11b)
@@ -789,7 +792,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
                else
                        aCWmin = 15;
 
-               switch (queue) {
+               switch (ac) {
                case IEEE80211_AC_BK:
                        qparam.cw_max = aCWmax;
                        qparam.cw_min = aCWmin;
@@ -825,8 +828,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
 
                qparam.uapsd = false;
 
-               sdata->tx_conf[queue] = qparam;
-               drv_conf_tx(local, sdata, queue, &qparam);
+               sdata->tx_conf[ac] = qparam;
+               drv_conf_tx(local, sdata, ac, &qparam);
        }
 
        /* after reinitialize QoS TX queues setting to default,
@@ -1226,14 +1229,17 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        mutex_unlock(&local->sta_mtx);
 
        /* reconfigure tx conf */
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
-                   sdata->vif.type == NL80211_IFTYPE_MONITOR ||
-                   !ieee80211_sdata_running(sdata))
-                       continue;
+       if (hw->queues >= IEEE80211_NUM_ACS) {
+               list_for_each_entry(sdata, &local->interfaces, list) {
+                       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+                           sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+                           !ieee80211_sdata_running(sdata))
+                               continue;
 
-               for (i = 0; i < hw->queues; i++)
-                       drv_conf_tx(local, sdata, i, &sdata->tx_conf[i]);
+                       for (i = 0; i < IEEE80211_NUM_ACS; i++)
+                               drv_conf_tx(local, sdata, i,
+                                           &sdata->tx_conf[i]);
+               }
        }
 
        /* reconfigure hardware */