aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2011-09-07 20:49:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-14 13:56:48 -0400
commit4777be41638cfab56c78b2a764a5f83beb6cfdd2 (patch)
tree9b041c2ffdaccf13a24b8bdb62c817cc87942a01
parent3de3d966007592693e68a973f62a1e3828565af0 (diff)
mac80211: Start implementing QoS support for mesh interfaces
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>
-rw-r--r--net/mac80211/mesh_pathtbl.c4
-rw-r--r--net/mac80211/rx.c10
-rw-r--r--net/mac80211/tx.c4
-rw-r--r--net/mac80211/wme.c6
4 files changed, 14 insertions, 10 deletions
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 55a206cfb8cc..4fc8c7a5d4dd 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -14,6 +14,7 @@
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <net/mac80211.h> 16#include <net/mac80211.h>
17#include "wme.h"
17#include "ieee80211_i.h" 18#include "ieee80211_i.h"
18#include "mesh.h" 19#include "mesh.h"
19 20
@@ -212,6 +213,7 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
212 struct ieee80211_hdr *hdr; 213 struct ieee80211_hdr *hdr;
213 struct sk_buff_head tmpq; 214 struct sk_buff_head tmpq;
214 unsigned long flags; 215 unsigned long flags;
216 struct ieee80211_sub_if_data *sdata = mpath->sdata;
215 217
216 rcu_assign_pointer(mpath->next_hop, sta); 218 rcu_assign_pointer(mpath->next_hop, sta);
217 219
@@ -222,6 +224,8 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
222 while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { 224 while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
223 hdr = (struct ieee80211_hdr *) skb->data; 225 hdr = (struct ieee80211_hdr *) skb->data;
224 memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); 226 memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
227 skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
228 ieee80211_set_qos_hdr(sdata->local, skb);
225 __skb_queue_tail(&tmpq, skb); 229 __skb_queue_tail(&tmpq, skb);
226 } 230 }
227 231
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 811e3ade8c74..b1ea4444065e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1905,13 +1905,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1905 memset(info, 0, sizeof(*info)); 1905 memset(info, 0, sizeof(*info));
1906 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1906 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1907 info->control.vif = &rx->sdata->vif; 1907 info->control.vif = &rx->sdata->vif;
1908 skb_set_queue_mapping(skb, 1908 if (is_multicast_ether_addr(fwd_hdr->addr1)) {
1909 ieee80211_select_queue(rx->sdata, fwd_skb));
1910 ieee80211_set_qos_hdr(local, skb);
1911 if (is_multicast_ether_addr(fwd_hdr->addr1))
1912 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, 1909 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
1913 fwded_mcast); 1910 fwded_mcast);
1914 else { 1911 skb_set_queue_mapping(fwd_skb,
1912 ieee80211_select_queue(sdata, fwd_skb));
1913 ieee80211_set_qos_hdr(local, fwd_skb);
1914 } else {
1915 int err; 1915 int err;
1916 /* 1916 /*
1917 * Save TA to addr1 to send TA a path error if a 1917 * Save TA to addr1 to send TA a path error if a
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2521716aa97b..2a8e437165fb 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1879,6 +1879,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1879 rcu_read_unlock(); 1879 rcu_read_unlock();
1880 } 1880 }
1881 1881
1882 /* For mesh, the use of the QoS header is mandatory */
1883 if (ieee80211_vif_is_mesh(&sdata->vif))
1884 sta_flags |= WLAN_STA_WME;
1885
1882 /* receiver and we are QoS enabled, use a QoS type frame */ 1886 /* receiver and we are QoS enabled, use a QoS type frame */
1883 if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) { 1887 if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) {
1884 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); 1888 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 7a49532f14cb..a9fee2bc6300 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -83,11 +83,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
83 break; 83 break;
84#ifdef CONFIG_MAC80211_MESH 84#ifdef CONFIG_MAC80211_MESH
85 case NL80211_IFTYPE_MESH_POINT: 85 case NL80211_IFTYPE_MESH_POINT:
86 /* 86 ra = skb->data;
87 * XXX: This is clearly broken ... but already was before,
88 * because ieee80211_fill_mesh_addresses() would clear A1
89 * except for multicast addresses.
90 */
91 break; 87 break;
92#endif 88#endif
93 case NL80211_IFTYPE_STATION: 89 case NL80211_IFTYPE_STATION: