mac80211: Start implementing QoS support for mesh interfaces
authorJavier Cardona <javier@cozybit.com>
Thu, 8 Sep 2011 00:49:52 +0000 (17:49 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 14 Sep 2011 17:56:48 +0000 (13:56 -0400)
In order to support QoS in mesh, we need to assign queue mapping only
after the next hop has been resolved, both for forwarded and locally
originated frames.  Also, now that this is fixed, remove the XXX comment
in ieee80211_select_queue().

Also, V-Shy Ho reported that the queue mapping was not being applied to
the forwarded frame (fwd_skb instead of skb).  Fixed that as well.

Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/mesh_pathtbl.c
net/mac80211/rx.c
net/mac80211/tx.c
net/mac80211/wme.c

index 55a206cfb8cc0909021fea09b6f290cac6b068cd..4fc8c7a5d4dd010f934f5ddecf01f2d07224f9fe 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <net/mac80211.h>
+#include "wme.h"
 #include "ieee80211_i.h"
 #include "mesh.h"
 
@@ -212,6 +213,7 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
        struct ieee80211_hdr *hdr;
        struct sk_buff_head tmpq;
        unsigned long flags;
+       struct ieee80211_sub_if_data *sdata = mpath->sdata;
 
        rcu_assign_pointer(mpath->next_hop, sta);
 
@@ -222,6 +224,8 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
        while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
                hdr = (struct ieee80211_hdr *) skb->data;
                memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
+               skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
+               ieee80211_set_qos_hdr(sdata->local, skb);
                __skb_queue_tail(&tmpq, skb);
        }
 
index 811e3ade8c743afeb7712809f0463480d8e74e4c..b1ea4444065eb983f4042ae178d0844f155dd6b9 100644 (file)
@@ -1905,13 +1905,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                        memset(info, 0, sizeof(*info));
                        info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
                        info->control.vif = &rx->sdata->vif;
-                       skb_set_queue_mapping(skb,
-                               ieee80211_select_queue(rx->sdata, fwd_skb));
-                       ieee80211_set_qos_hdr(local, skb);
-                       if (is_multicast_ether_addr(fwd_hdr->addr1))
+                       if (is_multicast_ether_addr(fwd_hdr->addr1)) {
                                IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
                                                                fwded_mcast);
-                       else {
+                               skb_set_queue_mapping(fwd_skb,
+                                       ieee80211_select_queue(sdata, fwd_skb));
+                               ieee80211_set_qos_hdr(local, fwd_skb);
+                       } else {
                                int err;
                                /*
                                 * Save TA to addr1 to send TA a path error if a
index 2521716aa97b033bb6953152a87f0432b77ab587..2a8e437165fb92d1c24e7e17169a03d8ad0640c3 100644 (file)
@@ -1879,6 +1879,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                rcu_read_unlock();
        }
 
+       /* For mesh, the use of the QoS header is mandatory */
+       if (ieee80211_vif_is_mesh(&sdata->vif))
+               sta_flags |= WLAN_STA_WME;
+
        /* receiver and we are QoS enabled, use a QoS type frame */
        if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) {
                fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
index 7a49532f14cbff932fbfdbfaddc53abc0c974c17..a9fee2bc63001ffb2e863fc16581fedf3816d77c 100644 (file)
@@ -83,11 +83,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
                break;
 #ifdef CONFIG_MAC80211_MESH
        case NL80211_IFTYPE_MESH_POINT:
-               /*
-                * XXX: This is clearly broken ... but already was before,
-                * because ieee80211_fill_mesh_addresses() would clear A1
-                * except for multicast addresses.
-                */
+               ra = skb->data;
                break;
 #endif
        case NL80211_IFTYPE_STATION: