diff options
author | Felix Fietkau <nbd@openwrt.org> | 2009-07-12 00:01:17 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2009-07-12 00:01:17 +0000 |
commit | 3270a9653d0ab38920818381a00a015053310b74 (patch) | |
tree | 6ff051d275bff5c26f8ec5d449e77cbe4ce6294e | |
parent | b59c32cf37b527a12d05daf1e0c4d26e2aa2b291 (diff) | |
download | upstream-3270a9653d0ab38920818381a00a015053310b74.tar.gz upstream-3270a9653d0ab38920818381a00a015053310b74.tar.bz2 upstream-3270a9653d0ab38920818381a00a015053310b74.zip |
madwifi: clean up wme handling, use same packet classification as mac80211
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@16790 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r-- | package/madwifi/patches/440-wme_cleanup.patch | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/package/madwifi/patches/440-wme_cleanup.patch b/package/madwifi/patches/440-wme_cleanup.patch new file mode 100644 index 0000000000..d6c1b26838 --- /dev/null +++ b/package/madwifi/patches/440-wme_cleanup.patch @@ -0,0 +1,136 @@ +--- a/net80211/ieee80211_output.c ++++ b/net80211/ieee80211_output.c +@@ -73,6 +73,29 @@ doprint(struct ieee80211vap *vap, int su + } + #endif + ++static const int ieee802_1d_to_ac[8] = { ++ WME_AC_BE, WME_AC_BK, WME_AC_BK, WME_AC_BE, ++ WME_AC_VI, WME_AC_VI, WME_AC_VO, WME_AC_VO ++}; ++ ++/* Given a data frame determine the 802.1p/1d tag to use. */ ++static unsigned int ieee80211_classify_ip(struct sk_buff *skb) ++{ ++ const struct ether_header *eh = (struct ether_header *) skb->data; ++ const struct iphdr *ip = (struct iphdr *) ++ (skb->data + sizeof (struct ether_header)); ++ unsigned int dscp; ++ ++ switch (skb->protocol) { ++ case __constant_htons(ETH_P_IP): ++ dscp = ip->tos & 0xfc; ++ break; ++ default: ++ return 0; ++ } ++ ++ return dscp >> 5; ++} + + /* + * Determine the priority based on VLAN and/or IP TOS. Priority is +@@ -83,90 +106,24 @@ static int + ieee80211_classify(struct ieee80211_node *ni, struct sk_buff *skb) + { + struct ieee80211vap *vap = ni->ni_vap; +- struct ether_header *eh = (struct ether_header *) skb->data; +- int v_wme_ac = 0, d_wme_ac = 0; +- +- /* default priority */ +- skb->priority = WME_AC_BE; +- +- if (!(ni->ni_flags & IEEE80211_NODE_QOS)) +- return 0; + +- /* +- * If node has a vlan tag then all traffic +- * to it must have a matching vlan id. ++ /* skb->priority values from 256->263 are magic values to ++ * directly indicate a specific 802.1d priority. This is used ++ * to allow 802.1d priority to be passed directly in from VLAN ++ * tags, etc. + */ +- if (ni->ni_vlan != 0 && vlan_tx_tag_present(skb)) { +- u_int32_t tag=0; +- int v_pri; +- +- if (vap->iv_vlgrp == NULL) { +- IEEE80211_NODE_STAT(ni, tx_novlantag); +- ni->ni_stats.ns_tx_novlantag++; +- return 1; +- } +- if (((tag = vlan_tx_tag_get(skb)) & VLAN_VID_MASK) != +- (ni->ni_vlan & VLAN_VID_MASK)) { +- IEEE80211_NODE_STAT(ni, tx_vlanmismatch); +- ni->ni_stats.ns_tx_vlanmismatch++; +- return 1; +- } +- if (ni->ni_flags & IEEE80211_NODE_QOS) { +- v_pri = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; +- switch (v_pri) { +- case 1: +- case 2: /* Background (BK) */ +- v_wme_ac = WME_AC_BK; +- break; +- case 0: +- case 3: /* Best Effort (BE) */ +- v_wme_ac = WME_AC_BE; +- break; +- case 4: +- case 5: /* Video (VI) */ +- v_wme_ac = WME_AC_VI; +- break; +- case 6: +- case 7: /* Voice (VO) */ +- v_wme_ac = WME_AC_VO; +- break; +- } +- } ++ if (skb->priority >= 256 && skb->priority <= 263) { ++ skb->priority = ieee802_1d_to_ac[skb->priority - 256]; ++ return 0; + } + +- if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) { +- const struct iphdr *ip = (struct iphdr *) +- (skb->data + sizeof (struct ether_header)); +- /* +- * IP frame, map the TOS field. +- * +- * XXX: fill out these mappings??? +- */ +- switch (ip->tos) { +- case 0x08: /* Background */ +- case 0x20: +- d_wme_ac = WME_AC_BK; +- break; +- case 0x28: /* Video */ +- case 0xa0: +- d_wme_ac = WME_AC_VI; +- break; +- case 0x30: /* Voice */ +- case 0xe0: +- case 0x88: /* XXX UPSD */ +- case 0xb8: +- d_wme_ac = WME_AC_VO; +- break; +- default: /* All others */ +- d_wme_ac = WME_AC_BE; +- break; +- } +- } else { +- d_wme_ac = WME_AC_BE; ++ if (!(ni->ni_flags & IEEE80211_NODE_QOS)) { ++ /* default priority */ ++ skb->priority = WME_AC_BE; ++ return 0; + } +- skb->priority = d_wme_ac; +- if (v_wme_ac > d_wme_ac) +- skb->priority = v_wme_ac; ++ ++ skb->priority = ieee802_1d_to_ac[ieee80211_classify_ip(skb)]; + + /* Applying ACM policy */ + if (vap->iv_opmode == IEEE80211_M_STA) { |