aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.c2
-rw-r--r--include/net/cfg80211.h53
-rw-r--r--include/uapi/linux/nl80211.h14
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/wireless/ap.c1
-rw-r--r--net/wireless/ibss.c2
-rw-r--r--net/wireless/mesh.c1
-rw-r--r--net/wireless/nl80211.c62
-rw-r--r--net/wireless/rdev-ops.h15
-rw-r--r--net/wireless/sme.c2
-rw-r--r--net/wireless/trace.h40
-rw-r--r--net/wireless/util.c19
13 files changed, 210 insertions, 5 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index e9bdfdb95d8f..4f80e12a1d4a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1873,7 +1873,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1873 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); 1873 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
1874 /* determine the priority */ 1874 /* determine the priority */
1875 if (!skb->priority) 1875 if (!skb->priority)
1876 skb->priority = cfg80211_classify8021d(skb); 1876 skb->priority = cfg80211_classify8021d(skb, NULL);
1877 1877
1878 drvr->tx_multicast += !!multicast; 1878 drvr->tx_multicast += !!multicast;
1879 if (pae) 1879 if (pae)
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 6bf58aba51d2..2d6f5e1721cf 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -749,7 +749,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
749static u16 749static u16
750mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) 750mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb)
751{ 751{
752 skb->priority = cfg80211_classify8021d(skb); 752 skb->priority = cfg80211_classify8021d(skb, NULL);
753 return mwifiex_1d_to_wmm_queue[skb->priority]; 753 return mwifiex_1d_to_wmm_queue[skb->priority];
754} 754}
755 755
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6d238a4331bd..56c597793d6d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1972,6 +1972,50 @@ struct cfg80211_mgmt_tx_params {
1972}; 1972};
1973 1973
1974/** 1974/**
1975 * struct cfg80211_dscp_exception - DSCP exception
1976 *
1977 * @dscp: DSCP value that does not adhere to the user priority range definition
1978 * @up: user priority value to which the corresponding DSCP value belongs
1979 */
1980struct cfg80211_dscp_exception {
1981 u8 dscp;
1982 u8 up;
1983};
1984
1985/**
1986 * struct cfg80211_dscp_range - DSCP range definition for user priority
1987 *
1988 * @low: lowest DSCP value of this user priority range, inclusive
1989 * @high: highest DSCP value of this user priority range, inclusive
1990 */
1991struct cfg80211_dscp_range {
1992 u8 low;
1993 u8 high;
1994};
1995
1996/* QoS Map Set element length defined in IEEE Std 802.11-2012, 8.4.2.97 */
1997#define IEEE80211_QOS_MAP_MAX_EX 21
1998#define IEEE80211_QOS_MAP_LEN_MIN 16
1999#define IEEE80211_QOS_MAP_LEN_MAX \
2000 (IEEE80211_QOS_MAP_LEN_MIN + 2 * IEEE80211_QOS_MAP_MAX_EX)
2001
2002/**
2003 * struct cfg80211_qos_map - QoS Map Information
2004 *
2005 * This struct defines the Interworking QoS map setting for DSCP values
2006 *
2007 * @num_des: number of DSCP exceptions (0..21)
2008 * @dscp_exception: optionally up to maximum of 21 DSCP exceptions from
2009 * the user priority DSCP range definition
2010 * @up: DSCP range definition for a particular user priority
2011 */
2012struct cfg80211_qos_map {
2013 u8 num_des;
2014 struct cfg80211_dscp_exception dscp_exception[IEEE80211_QOS_MAP_MAX_EX];
2015 struct cfg80211_dscp_range up[8];
2016};
2017
2018/**
1975 * struct cfg80211_ops - backend description for wireless configuration 2019 * struct cfg80211_ops - backend description for wireless configuration
1976 * 2020 *
1977 * This struct is registered by fullmac card drivers and/or wireless stacks 2021 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2213,6 +2257,8 @@ struct cfg80211_mgmt_tx_params {
2213 * @set_coalesce: Set coalesce parameters. 2257 * @set_coalesce: Set coalesce parameters.
2214 * 2258 *
2215 * @channel_switch: initiate channel-switch procedure (with CSA) 2259 * @channel_switch: initiate channel-switch procedure (with CSA)
2260 *
2261 * @set_qos_map: Set QoS mapping information to the driver
2216 */ 2262 */
2217struct cfg80211_ops { 2263struct cfg80211_ops {
2218 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); 2264 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2454,6 +2500,9 @@ struct cfg80211_ops {
2454 int (*channel_switch)(struct wiphy *wiphy, 2500 int (*channel_switch)(struct wiphy *wiphy,
2455 struct net_device *dev, 2501 struct net_device *dev,
2456 struct cfg80211_csa_settings *params); 2502 struct cfg80211_csa_settings *params);
2503 int (*set_qos_map)(struct wiphy *wiphy,
2504 struct net_device *dev,
2505 struct cfg80211_qos_map *qos_map);
2457}; 2506};
2458 2507
2459/* 2508/*
@@ -3432,9 +3481,11 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
3432/** 3481/**
3433 * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame 3482 * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
3434 * @skb: the data frame 3483 * @skb: the data frame
3484 * @qos_map: Interworking QoS mapping or %NULL if not in use
3435 * Return: The 802.1p/1d tag. 3485 * Return: The 802.1p/1d tag.
3436 */ 3486 */
3437unsigned int cfg80211_classify8021d(struct sk_buff *skb); 3487unsigned int cfg80211_classify8021d(struct sk_buff *skb,
3488 struct cfg80211_qos_map *qos_map);
3438 3489
3439/** 3490/**
3440 * cfg80211_find_ie - find information element in data 3491 * cfg80211_find_ie - find information element in data
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 381184eb6c96..91054fd660e0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -702,6 +702,12 @@
702 * (&struct nl80211_vendor_cmd_info) of the supported vendor commands. 702 * (&struct nl80211_vendor_cmd_info) of the supported vendor commands.
703 * This may also be sent as an event with the same attributes. 703 * This may also be sent as an event with the same attributes.
704 * 704 *
705 * @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values.
706 * The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If
707 * that attribute is not included, QoS mapping is disabled. Since this
708 * QoS mapping is relevant for IP packets, it is only valid during an
709 * association. This is cleared on disassociation and AP restart.
710 *
705 * @NL80211_CMD_MAX: highest used command number 711 * @NL80211_CMD_MAX: highest used command number
706 * @__NL80211_CMD_AFTER_LAST: internal use 712 * @__NL80211_CMD_AFTER_LAST: internal use
707 */ 713 */
@@ -871,6 +877,8 @@ enum nl80211_commands {
871 877
872 NL80211_CMD_VENDOR, 878 NL80211_CMD_VENDOR,
873 879
880 NL80211_CMD_SET_QOS_MAP,
881
874 /* add new commands above here */ 882 /* add new commands above here */
875 883
876 /* used to define NL80211_CMD_MAX below */ 884 /* used to define NL80211_CMD_MAX below */
@@ -1543,6 +1551,10 @@ enum nl80211_commands {
1543 * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy 1551 * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy
1544 * info, containing a nested array of possible events 1552 * info, containing a nested array of possible events
1545 * 1553 *
1554 * @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This
1555 * data is in the format defined for the payload of the QoS Map Set element
1556 * in IEEE Std 802.11-2012, 8.4.2.97.
1557 *
1546 * @NL80211_ATTR_MAX: highest attribute number currently defined 1558 * @NL80211_ATTR_MAX: highest attribute number currently defined
1547 * @__NL80211_ATTR_AFTER_LAST: internal use 1559 * @__NL80211_ATTR_AFTER_LAST: internal use
1548 */ 1560 */
@@ -1869,6 +1881,8 @@ enum nl80211_attrs {
1869 NL80211_ATTR_VENDOR_DATA, 1881 NL80211_ATTR_VENDOR_DATA,
1870 NL80211_ATTR_VENDOR_EVENTS, 1882 NL80211_ATTR_VENDOR_EVENTS,
1871 1883
1884 NL80211_ATTR_QOS_MAP,
1885
1872 /* add attributes here, update the policy in nl80211.c */ 1886 /* add attributes here, update the policy in nl80211.c */
1873 1887
1874 __NL80211_ATTR_AFTER_LAST, 1888 __NL80211_ATTR_AFTER_LAST,
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index afba19cb6f87..faa9d8e451f0 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -155,7 +155,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
155 155
156 /* use the data classifier to determine what 802.1d tag the 156 /* use the data classifier to determine what 802.1d tag the
157 * data frame has */ 157 * data frame has */
158 skb->priority = cfg80211_classify8021d(skb); 158 skb->priority = cfg80211_classify8021d(skb, NULL);
159 159
160 return ieee80211_downgrade_queue(sdata, skb); 160 return ieee80211_downgrade_queue(sdata, skb);
161} 161}
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index 324e8d851dc4..11ee4ed04f73 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -29,6 +29,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
29 wdev->beacon_interval = 0; 29 wdev->beacon_interval = 0;
30 wdev->channel = NULL; 30 wdev->channel = NULL;
31 wdev->ssid_len = 0; 31 wdev->ssid_len = 0;
32 rdev_set_qos_map(rdev, dev, NULL);
32 } 33 }
33 34
34 return err; 35 return err;
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 730147ed8e65..f911c5f9f903 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -183,6 +183,8 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
183 kfree(wdev->connect_keys); 183 kfree(wdev->connect_keys);
184 wdev->connect_keys = NULL; 184 wdev->connect_keys = NULL;
185 185
186 rdev_set_qos_map(rdev, dev, NULL);
187
186 /* 188 /*
187 * Delete all the keys ... pairwise keys can't really 189 * Delete all the keys ... pairwise keys can't really
188 * exist any more anyway, but default keys might. 190 * exist any more anyway, but default keys might.
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 9c7a11ae7936..885862447b63 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -277,6 +277,7 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
277 if (!err) { 277 if (!err) {
278 wdev->mesh_id_len = 0; 278 wdev->mesh_id_len = 0;
279 wdev->channel = NULL; 279 wdev->channel = NULL;
280 rdev_set_qos_map(rdev, dev, NULL);
280 } 281 }
281 282
282 return err; 283 return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8a7ff041349b..b4f40fe84a01 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -382,6 +382,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
382 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 }, 382 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
383 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, 383 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
384 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, 384 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
385 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
386 .len = IEEE80211_QOS_MAP_LEN_MAX },
385}; 387};
386 388
387/* policy for the key attributes */ 389/* policy for the key attributes */
@@ -1456,6 +1458,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1456 if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) 1458 if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
1457 CMD(channel_switch, CHANNEL_SWITCH); 1459 CMD(channel_switch, CHANNEL_SWITCH);
1458 } 1460 }
1461 CMD(set_qos_map, SET_QOS_MAP);
1459 1462
1460#ifdef CONFIG_NL80211_TESTMODE 1463#ifdef CONFIG_NL80211_TESTMODE
1461 CMD(testmode_cmd, TESTMODE); 1464 CMD(testmode_cmd, TESTMODE);
@@ -9121,6 +9124,57 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
9121EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply); 9124EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
9122 9125
9123 9126
9127static int nl80211_set_qos_map(struct sk_buff *skb,
9128 struct genl_info *info)
9129{
9130 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9131 struct cfg80211_qos_map *qos_map = NULL;
9132 struct net_device *dev = info->user_ptr[1];
9133 u8 *pos, len, num_des, des_len, des;
9134 int ret;
9135
9136 if (!rdev->ops->set_qos_map)
9137 return -EOPNOTSUPP;
9138
9139 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
9140 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
9141 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
9142
9143 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
9144 len > IEEE80211_QOS_MAP_LEN_MAX)
9145 return -EINVAL;
9146
9147 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
9148 if (!qos_map)
9149 return -ENOMEM;
9150
9151 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
9152 if (num_des) {
9153 des_len = num_des *
9154 sizeof(struct cfg80211_dscp_exception);
9155 memcpy(qos_map->dscp_exception, pos, des_len);
9156 qos_map->num_des = num_des;
9157 for (des = 0; des < num_des; des++) {
9158 if (qos_map->dscp_exception[des].up > 7) {
9159 kfree(qos_map);
9160 return -EINVAL;
9161 }
9162 }
9163 pos += des_len;
9164 }
9165 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
9166 }
9167
9168 wdev_lock(dev->ieee80211_ptr);
9169 ret = nl80211_key_allowed(dev->ieee80211_ptr);
9170 if (!ret)
9171 ret = rdev_set_qos_map(rdev, dev, qos_map);
9172 wdev_unlock(dev->ieee80211_ptr);
9173
9174 kfree(qos_map);
9175 return ret;
9176}
9177
9124#define NL80211_FLAG_NEED_WIPHY 0x01 9178#define NL80211_FLAG_NEED_WIPHY 0x01
9125#define NL80211_FLAG_NEED_NETDEV 0x02 9179#define NL80211_FLAG_NEED_NETDEV 0x02
9126#define NL80211_FLAG_NEED_RTNL 0x04 9180#define NL80211_FLAG_NEED_RTNL 0x04
@@ -9853,6 +9907,14 @@ static const struct genl_ops nl80211_ops[] = {
9853 .internal_flags = NL80211_FLAG_NEED_WIPHY | 9907 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9854 NL80211_FLAG_NEED_RTNL, 9908 NL80211_FLAG_NEED_RTNL,
9855 }, 9909 },
9910 {
9911 .cmd = NL80211_CMD_SET_QOS_MAP,
9912 .doit = nl80211_set_qos_map,
9913 .policy = nl80211_policy,
9914 .flags = GENL_ADMIN_PERM,
9915 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9916 NL80211_FLAG_NEED_RTNL,
9917 },
9856}; 9918};
9857 9919
9858/* notification functions */ 9920/* notification functions */
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index a6c03ab14a0d..c8e225947adb 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -932,4 +932,19 @@ static inline int rdev_channel_switch(struct cfg80211_registered_device *rdev,
932 return ret; 932 return ret;
933} 933}
934 934
935static inline int rdev_set_qos_map(struct cfg80211_registered_device *rdev,
936 struct net_device *dev,
937 struct cfg80211_qos_map *qos_map)
938{
939 int ret = -EOPNOTSUPP;
940
941 if (rdev->ops->set_qos_map) {
942 trace_rdev_set_qos_map(&rdev->wiphy, dev, qos_map);
943 ret = rdev->ops->set_qos_map(&rdev->wiphy, dev, qos_map);
944 trace_rdev_return_int(&rdev->wiphy, ret);
945 }
946
947 return ret;
948}
949
935#endif /* __CFG80211_RDEV_OPS */ 950#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 65f800890d70..3f64202358f4 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -870,6 +870,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
870 for (i = 0; i < 6; i++) 870 for (i = 0; i < 6; i++)
871 rdev_del_key(rdev, dev, i, false, NULL); 871 rdev_del_key(rdev, dev, i, false, NULL);
872 872
873 rdev_set_qos_map(rdev, dev, NULL);
874
873#ifdef CONFIG_CFG80211_WEXT 875#ifdef CONFIG_CFG80211_WEXT
874 memset(&wrqu, 0, sizeof(wrqu)); 876 memset(&wrqu, 0, sizeof(wrqu));
875 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 877 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index f7aa7a72d9bc..fbcc23edee54 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -186,6 +186,28 @@
186 186
187#define BOOL_TO_STR(bo) (bo) ? "true" : "false" 187#define BOOL_TO_STR(bo) (bo) ? "true" : "false"
188 188
189#define QOS_MAP_ENTRY __field(u8, num_des) \
190 __array(u8, dscp_exception, \
191 2 * IEEE80211_QOS_MAP_MAX_EX) \
192 __array(u8, up, IEEE80211_QOS_MAP_LEN_MIN)
193#define QOS_MAP_ASSIGN(qos_map) \
194 do { \
195 if ((qos_map)) { \
196 __entry->num_des = (qos_map)->num_des; \
197 memcpy(__entry->dscp_exception, \
198 &(qos_map)->dscp_exception, \
199 2 * IEEE80211_QOS_MAP_MAX_EX); \
200 memcpy(__entry->up, &(qos_map)->up, \
201 IEEE80211_QOS_MAP_LEN_MIN); \
202 } else { \
203 __entry->num_des = 0; \
204 memset(__entry->dscp_exception, 0, \
205 2 * IEEE80211_QOS_MAP_MAX_EX); \
206 memset(__entry->up, 0, \
207 IEEE80211_QOS_MAP_LEN_MIN); \
208 } \
209 } while (0)
210
189/************************************************************* 211/*************************************************************
190 * rdev->ops traces * 212 * rdev->ops traces *
191 *************************************************************/ 213 *************************************************************/
@@ -1875,6 +1897,24 @@ TRACE_EVENT(rdev_channel_switch,
1875 __entry->counter_offset_presp) 1897 __entry->counter_offset_presp)
1876); 1898);
1877 1899
1900TRACE_EVENT(rdev_set_qos_map,
1901 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
1902 struct cfg80211_qos_map *qos_map),
1903 TP_ARGS(wiphy, netdev, qos_map),
1904 TP_STRUCT__entry(
1905 WIPHY_ENTRY
1906 NETDEV_ENTRY
1907 QOS_MAP_ENTRY
1908 ),
1909 TP_fast_assign(
1910 WIPHY_ASSIGN;
1911 NETDEV_ASSIGN;
1912 QOS_MAP_ASSIGN(qos_map);
1913 ),
1914 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", num_des: %u",
1915 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->num_des)
1916);
1917
1878/************************************************************* 1918/*************************************************************
1879 * cfg80211 exported functions traces * 1919 * cfg80211 exported functions traces *
1880 *************************************************************/ 1920 *************************************************************/
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 935dea9485da..5618888853b2 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -689,7 +689,8 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
689EXPORT_SYMBOL(ieee80211_amsdu_to_8023s); 689EXPORT_SYMBOL(ieee80211_amsdu_to_8023s);
690 690
691/* Given a data frame determine the 802.1p/1d tag to use. */ 691/* Given a data frame determine the 802.1p/1d tag to use. */
692unsigned int cfg80211_classify8021d(struct sk_buff *skb) 692unsigned int cfg80211_classify8021d(struct sk_buff *skb,
693 struct cfg80211_qos_map *qos_map)
693{ 694{
694 unsigned int dscp; 695 unsigned int dscp;
695 unsigned char vlan_priority; 696 unsigned char vlan_priority;
@@ -720,6 +721,21 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb)
720 return 0; 721 return 0;
721 } 722 }
722 723
724 if (qos_map) {
725 unsigned int i, tmp_dscp = dscp >> 2;
726
727 for (i = 0; i < qos_map->num_des; i++) {
728 if (tmp_dscp == qos_map->dscp_exception[i].dscp)
729 return qos_map->dscp_exception[i].up;
730 }
731
732 for (i = 0; i < 8; i++) {
733 if (tmp_dscp >= qos_map->up[i].low &&
734 tmp_dscp <= qos_map->up[i].high)
735 return i;
736 }
737 }
738
723 return dscp >> 5; 739 return dscp >> 5;
724} 740}
725EXPORT_SYMBOL(cfg80211_classify8021d); 741EXPORT_SYMBOL(cfg80211_classify8021d);
@@ -863,6 +879,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
863 879
864 dev->ieee80211_ptr->use_4addr = false; 880 dev->ieee80211_ptr->use_4addr = false;
865 dev->ieee80211_ptr->mesh_id_up_len = 0; 881 dev->ieee80211_ptr->mesh_id_up_len = 0;
882 rdev_set_qos_map(rdev, dev, NULL);
866 883
867 switch (otype) { 884 switch (otype) {
868 case NL80211_IFTYPE_AP: 885 case NL80211_IFTYPE_AP: