madwifi: clean up wme handling, use same packet classification as mac80211
[openwrt/svn-archive/archive.git] / package / madwifi / patches / 440-wme_cleanup.patch
1 --- a/net80211/ieee80211_output.c
2 +++ b/net80211/ieee80211_output.c
3 @@ -73,6 +73,29 @@ doprint(struct ieee80211vap *vap, int su
4 }
5 #endif
6
7 +static const int ieee802_1d_to_ac[8] = {
8 + WME_AC_BE, WME_AC_BK, WME_AC_BK, WME_AC_BE,
9 + WME_AC_VI, WME_AC_VI, WME_AC_VO, WME_AC_VO
10 +};
11 +
12 +/* Given a data frame determine the 802.1p/1d tag to use. */
13 +static unsigned int ieee80211_classify_ip(struct sk_buff *skb)
14 +{
15 + const struct ether_header *eh = (struct ether_header *) skb->data;
16 + const struct iphdr *ip = (struct iphdr *)
17 + (skb->data + sizeof (struct ether_header));
18 + unsigned int dscp;
19 +
20 + switch (skb->protocol) {
21 + case __constant_htons(ETH_P_IP):
22 + dscp = ip->tos & 0xfc;
23 + break;
24 + default:
25 + return 0;
26 + }
27 +
28 + return dscp >> 5;
29 +}
30
31 /*
32 * Determine the priority based on VLAN and/or IP TOS. Priority is
33 @@ -83,90 +106,24 @@ static int
34 ieee80211_classify(struct ieee80211_node *ni, struct sk_buff *skb)
35 {
36 struct ieee80211vap *vap = ni->ni_vap;
37 - struct ether_header *eh = (struct ether_header *) skb->data;
38 - int v_wme_ac = 0, d_wme_ac = 0;
39 -
40 - /* default priority */
41 - skb->priority = WME_AC_BE;
42 -
43 - if (!(ni->ni_flags & IEEE80211_NODE_QOS))
44 - return 0;
45
46 - /*
47 - * If node has a vlan tag then all traffic
48 - * to it must have a matching vlan id.
49 + /* skb->priority values from 256->263 are magic values to
50 + * directly indicate a specific 802.1d priority. This is used
51 + * to allow 802.1d priority to be passed directly in from VLAN
52 + * tags, etc.
53 */
54 - if (ni->ni_vlan != 0 && vlan_tx_tag_present(skb)) {
55 - u_int32_t tag=0;
56 - int v_pri;
57 -
58 - if (vap->iv_vlgrp == NULL) {
59 - IEEE80211_NODE_STAT(ni, tx_novlantag);
60 - ni->ni_stats.ns_tx_novlantag++;
61 - return 1;
62 - }
63 - if (((tag = vlan_tx_tag_get(skb)) & VLAN_VID_MASK) !=
64 - (ni->ni_vlan & VLAN_VID_MASK)) {
65 - IEEE80211_NODE_STAT(ni, tx_vlanmismatch);
66 - ni->ni_stats.ns_tx_vlanmismatch++;
67 - return 1;
68 - }
69 - if (ni->ni_flags & IEEE80211_NODE_QOS) {
70 - v_pri = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
71 - switch (v_pri) {
72 - case 1:
73 - case 2: /* Background (BK) */
74 - v_wme_ac = WME_AC_BK;
75 - break;
76 - case 0:
77 - case 3: /* Best Effort (BE) */
78 - v_wme_ac = WME_AC_BE;
79 - break;
80 - case 4:
81 - case 5: /* Video (VI) */
82 - v_wme_ac = WME_AC_VI;
83 - break;
84 - case 6:
85 - case 7: /* Voice (VO) */
86 - v_wme_ac = WME_AC_VO;
87 - break;
88 - }
89 - }
90 + if (skb->priority >= 256 && skb->priority <= 263) {
91 + skb->priority = ieee802_1d_to_ac[skb->priority - 256];
92 + return 0;
93 }
94
95 - if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
96 - const struct iphdr *ip = (struct iphdr *)
97 - (skb->data + sizeof (struct ether_header));
98 - /*
99 - * IP frame, map the TOS field.
100 - *
101 - * XXX: fill out these mappings???
102 - */
103 - switch (ip->tos) {
104 - case 0x08: /* Background */
105 - case 0x20:
106 - d_wme_ac = WME_AC_BK;
107 - break;
108 - case 0x28: /* Video */
109 - case 0xa0:
110 - d_wme_ac = WME_AC_VI;
111 - break;
112 - case 0x30: /* Voice */
113 - case 0xe0:
114 - case 0x88: /* XXX UPSD */
115 - case 0xb8:
116 - d_wme_ac = WME_AC_VO;
117 - break;
118 - default: /* All others */
119 - d_wme_ac = WME_AC_BE;
120 - break;
121 - }
122 - } else {
123 - d_wme_ac = WME_AC_BE;
124 + if (!(ni->ni_flags & IEEE80211_NODE_QOS)) {
125 + /* default priority */
126 + skb->priority = WME_AC_BE;
127 + return 0;
128 }
129 - skb->priority = d_wme_ac;
130 - if (v_wme_ac > d_wme_ac)
131 - skb->priority = v_wme_ac;
132 +
133 + skb->priority = ieee802_1d_to_ac[ieee80211_classify_ip(skb)];
134
135 /* Applying ACM policy */
136 if (vap->iv_opmode == IEEE80211_M_STA) {