Skip to content

Commit

Permalink
mac80211: Start implementing QoS support for mesh interfaces
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Javier Cardona authored and John W. Linville committed Sep 14, 2011
1 parent 3de3d96 commit 4777be4
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 10 deletions.
4 changes: 4 additions & 0 deletions net/mac80211/mesh_pathtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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);

Expand All @@ -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);
}

Expand Down
10 changes: 5 additions & 5 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 1 addition & 5 deletions net/mac80211/wme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 4777be4

Please sign in to comment.