Skip to contentSkip to conversation

mac80211: add IEEE802.11e/WMM structures

PATCH In review Zhu Yi 6 participants 12 messages Jun 6, 2007 – Jun 8, 2007 802.11 (including cfg80211/NL80211)

lore
Share & tools
lore

Zhu Yi

author
#0 lore raw

PATCH 1/3 mac80211: add IEEE802.11e/WMM structures

Add data types and structures for IEEE802.11e/WMM TS management and DLS.

---
 include/linux/ieee80211.h |  166 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 166 insertions(+), 0 deletions(-)
include/linux/ieee80211.h +166 -0
index ecd61e8..cd91ade 100644
@@ -106,6 +106,52 @@ struct ieee80211_hdr {
 } __attribute__ ((packed));
 
 
+
+#define IEEE80211_TSINFO_TYPE(a)	((a.short1 & 0x0001) >> 0)
+#define IEEE80211_TSINFO_TSID(a)	((a.short1 & 0x001E) >> 1)
+#define IEEE80211_TSINFO_DIR(a)		((a.short1 & 0x0060) >> 5)
+#define IEEE80211_TSINFO_POLICY(a)	((a.short1 & 0x0180) >> 7)
+#define IEEE80211_TSINFO_AGG(a)		((a.short1 & 0x0200) >> 9)
+#define IEEE80211_TSINFO_APSD(a)	((a.short1 & 0x0400) >> 10)
+#define IEEE80211_TSINFO_UP(a)		((a.short1 & 0x3800) >> 11)
+#define IEEE80211_TSINFO_ACK(a)		((a.short1 & 0xC000) >> 14)
+#define IEEE80211_TSINFO_SCHEDULE(a)	((a.byte3 & 0x01) >> 0)
+
+#define SET_TSINFO_TYPE(i, d)		(i.short1 |= (d << 0) & 0x0001)
+#define SET_TSINFO_TSID(i, d)		(i.short1 |= (d << 1) & 0x001E)
+#define SET_TSINFO_DIR(i, d)		(i.short1 |= (d << 5) & 0x0060)
+#define SET_TSINFO_POLICY(i, d)		(i.short1 |= (d << 7) & 0x0180)
+#define SET_TSINFO_AGG(i, d)		(i.short1 |= (d << 9) & 0x0200)
+#define SET_TSINFO_APSD(i, d)		(i.short1 |= (d << 10) & 0x0400)
+#define SET_TSINFO_UP(i, d)		(i.short1 |= (d << 11) & 0x3800)
+#define SET_TSINFO_ACK(i, d)		(i.short1 |= (d << 14) & 0xC000)
+#define SET_TSINFO_SCHEDULE(i, d)	(i.byte3 |= (d << 0) & 0x01)
+
+struct ieee80211_ts_info {
+	__le16 short1;
+	u8 byte3;
+} __attribute__ ((packed));
+
+struct ieee80211_elem_tspec {
+	struct ieee80211_ts_info ts_info;
+	__le16 nominal_msdu_size;
+	__le16 max_msdu_size;
+	__le32 min_service_interval;
+	__le32 max_service_interval;
+	__le32 inactivity_interval;
+	__le32 suspension_interval;
+	__le32 service_start_time;
+	__le32 min_data_rate;
+	__le32 mean_data_rate;
+	__le32 peak_data_rate;
+	__le32 burst_size;
+	__le32 delay_bound;
+	__le32 min_phy_rate;
+	__le16 surplus_band_allow;
+	__le16 medium_time;
+} __attribute__ ((packed));
+
+
 struct ieee80211_mgmt {
 	__le16 frame_control;
 	__le16 duration;
@@ -173,9 +219,51 @@ struct ieee80211_mgmt {
 				struct {
 					u8 action_code;
 					u8 dialog_token;
+					u8 variable[0];
+				} __attribute__ ((packed)) addts_req;
+				struct {
+					u8 action_code;
+					u8 dialog_token;
+					__le16 status_code;
+					u8 variable[0];
+				} __attribute__ ((packed)) addts_resp;
+				struct {
+					u8 action_code;
+					struct ieee80211_ts_info ts_info;
+					__le16 reason_code;
+				} __attribute__ ((packed)) delts;
+				struct {
+					u8 action_code;
+					u8 dialog_token;
 					u8 status_code;
 					u8 variable[0];
 				} __attribute__ ((packed)) wme_action;
+				struct {
+					u8 action_code;
+					u8 dest[6];
+					u8 src[6];
+					__le16 capab_info;
+					__le16 timeout;
+					/* Followed by Supported Rates and
+					 * Extended Supported Rates */
+					u8 variable[0];
+				} __attribute__ ((packed)) dls_req;
+				struct {
+					u8 action_code;
+					__le16 status_code;
+					u8 dest[6];
+					u8 src[6];
+					/* Followed by Capability Information,
+					 * Supported Rates and Extended
+					 * Supported Rates */
+					u8 variable[0];
+				} __attribute__ ((packed)) dls_resp;
+				struct {
+					u8 action_code;
+					u8 dest[6];
+					u8 src[6];
+					__le16 reason_code;
+				} __attribute__ ((packed)) dls_teardown;
 				struct{
 					u8 action_code;
 					u8 element_id;
@@ -259,6 +347,18 @@ enum ieee80211_statuscode {
 	WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
 	WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
 	WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+	/* 802.11e */
+	WLAN_STATUS_UNSPECIFIED_QOS = 32,
+	WLAN_STATUS_ASSOC_DENIED_NOBANDWIDTH = 33,
+	WLAN_STATUS_ASSOC_DENIED_LOWACK = 34,
+	WLAN_STATUS_ASSOC_DENIED_UNSUPP_QOS = 35,
+	WLAN_STATUS_REQUEST_DECLINED = 37,
+	WLAN_STATUS_INVALID_QOS_PARAM = 38,
+	WLAN_STATUS_CHANGE_TSPEC = 39,
+	WLAN_STATUS_WAIT_TS_DELAY = 47,
+	WLAN_STATUS_NO_DIRECT_LINK = 48,
+	WLAN_STATUS_STA_NOT_PRESENT = 49,
+	WLAN_STATUS_STA_NOT_QSTA = 50,
 };
 
 
@@ -289,8 +389,32 @@ enum ieee80211_reasoncode {
 	WLAN_REASON_INVALID_RSN_IE_CAP = 22,
 	WLAN_REASON_IEEE8021X_FAILED = 23,
 	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+	/* 802.11e */
+	WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32,
+	WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33,
+	WLAN_REASON_DISASSOC_LOW_ACK = 34,
+	WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35,
+	WLAN_REASON_QSTA_LEAVE_QBSS = 36,
+	WLAN_REASON_QSTA_NOT_USE = 37,
+	WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
+	WLAN_REASON_QSTA_TIMEOUT = 39,
+	WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
 };
 
+/* QoS Action Code */
+enum ieee80211_qos_actioncode {
+	WLAN_ACTION_QOS_ADDTS_REQ = 0,
+	WLAN_ACTION_QOS_ADDTS_RESP = 1,
+	WLAN_ACTION_QOS_DELTS = 2,
+	WLAN_ACTION_QOS_SCHEDULE = 3,
+};
+
+/* DLS Action Code */
+enum ieee80211_dls_actioncode {
+	WLAN_ACTION_DLS_REQ = 0,
+	WLAN_ACTION_DLS_RESP = 1,
+	WLAN_ACTION_DLS_TEARDOWN = 2,
+};
 
 /* Information Element IDs */
 enum ieee80211_eid {
@@ -307,6 +431,15 @@ enum ieee80211_eid {
 	WLAN_EID_HP_PARAMS = 8,
 	WLAN_EID_HP_TABLE = 9,
 	WLAN_EID_REQUEST = 10,
+	/* 802.11e */
+	WLAN_EID_QBSS_LOAD = 11,
+	WLAN_EID_EDCA_PARAM_SET = 12,
+	WLAN_EID_TSPEC = 13,
+	WLAN_EID_TCLAS = 14,
+	WLAN_EID_SCHEDULE = 15,
+	WLAN_EID_TS_DELAY = 43,
+	WLAN_EID_TCLAS_PROCESSING = 44,
+	WLAN_EID_QOS_CAPA = 46,
 	/* 802.11h */
 	WLAN_EID_PWR_CONSTRAINT = 32,
 	WLAN_EID_PWR_CAPABILITY = 33,
@@ -339,4 +472,37 @@ enum ieee80211_eid {
 
 #define WLAN_MAX_KEY_LEN		32
 
+enum ieee80211_tsinfo_direction {
+	WLAN_TSINFO_UPLINK = 0,
+	WLAN_TSINFO_DOWNLINK = 1,
+	WLAN_TSINFO_DIRECTLINK = 2,
+	WLAN_TSINFO_BIDIRECTIONAL = 3,
+};
+
+enum ieee80211_tsinfo_access {
+	WLAN_TSINFO_EDCA = 1,
+	WLAN_TSINFO_HCCA = 2,
+	WLAN_TSINFO_HEMM = 3,
+};
+
+enum ieee80211_tsinfo_psb {
+	WLAN_TSINFO_PSB_LEGACY = 0,
+	WLAN_TSINFO_PSB_APSD = 1,
+};
+
+
+/* WI-FI Alliance OUI Type and Subtype */
+enum wifi_oui_type {
+	WIFI_OUI_TYPE_WPA = 1,
+	WIFI_OUI_TYPE_WMM = 2,
+	WIFI_OUI_TYPE_WSC = 4,
+	WIFI_OUI_TYPE_PSD = 6,
+};
+
+enum wifi_oui_stype_wmm {
+	WIFI_OUI_STYPE_WMM_INFO = 0,
+	WIFI_OUI_STYPE_WMM_PARAM = 1,
+	WIFI_OUI_STYPE_WMM_TSPEC = 2,
+};
+
 #endif /* IEEE80211_H */
Signature · 1 line
1.5.0.rc2.g73a2
#1 lore raw
Quoted 16 lines · Zhu Yi
include/linux/ieee80211.h +10 -0
@@ -106,6 +106,52 @@ struct ieee80211_hdr {
 } __attribute__ ((packed));
 
 
+
+#define IEEE80211_TSINFO_TYPE(a)	((a.short1 & 0x0001) >> 0)
+#define IEEE80211_TSINFO_TSID(a)	((a.short1 & 0x001E) >> 1)
+#define IEEE80211_TSINFO_DIR(a)		((a.short1 & 0x0060) >> 5)
+#define IEEE80211_TSINFO_POLICY(a)	((a.short1 & 0x0180) >> 7)
+#define IEEE80211_TSINFO_AGG(a)		((a.short1 & 0x0200) >> 9)
+#define IEEE80211_TSINFO_APSD(a)	((a.short1 & 0x0400) >> 10)
+#define IEEE80211_TSINFO_UP(a)		((a.short1 & 0x3800) >> 11)
+#define IEEE80211_TSINFO_ACK(a)		((a.short1 & 0xC000) >> 14)
+#define IEEE80211_TSINFO_SCHEDULE(a)	((a.byte3 & 0x01) >> 0)

include/linux/ieee80211.h struct ieee80211_hdr { · line 128

Quoted 10 lines
include/linux/ieee80211.h +10 -0
+
+#define SET_TSINFO_TYPE(i, d)		(i.short1 |= (d << 0) & 0x0001)
+#define SET_TSINFO_TSID(i, d)		(i.short1 |= (d << 1) & 0x001E)
+#define SET_TSINFO_DIR(i, d)		(i.short1 |= (d << 5) & 0x0060)
+#define SET_TSINFO_POLICY(i, d)		(i.short1 |= (d << 7) & 0x0180)
+#define SET_TSINFO_AGG(i, d)		(i.short1 |= (d << 9) & 0x0200)
+#define SET_TSINFO_APSD(i, d)		(i.short1 |= (d << 10) & 0x0400)
+#define SET_TSINFO_UP(i, d)		(i.short1 |= (d << 11) & 0x3800)
+#define SET_TSINFO_ACK(i, d)		(i.short1 |= (d << 14) & 0xC000)
+#define SET_TSINFO_SCHEDULE(i, d)	(i.byte3 |= (d << 0) & 0x01)

Please add IEEE80211_ prefix here as well. For consistency and not polluting a name space.

Quoted 10 lines

[...]

include/linux/ieee80211.h +9 -0
+enum ieee80211_tsinfo_psb {
+	WLAN_TSINFO_PSB_LEGACY = 0,
+	WLAN_TSINFO_PSB_APSD = 1,
+};
+
+
+/* WI-FI Alliance OUI Type and Subtype */
+enum wifi_oui_type {
+	WIFI_OUI_TYPE_WPA = 1,

include/linux/ieee80211.h enum ieee80211_eid { · line 506

Quoted 10 lines
include/linux/ieee80211.h +10 -0
+	WIFI_OUI_TYPE_WMM = 2,
+	WIFI_OUI_TYPE_WSC = 4,
+	WIFI_OUI_TYPE_PSD = 6,
+};
+
+enum wifi_oui_stype_wmm {
+	WIFI_OUI_STYPE_WMM_INFO = 0,
+	WIFI_OUI_STYPE_WMM_PARAM = 1,
+	WIFI_OUI_STYPE_WMM_TSPEC = 2,
+};

Please don't invent new useless prefixes. Also, a registered trademark doesn't seem to be a good prefix.

Thanks,

Jiri

Signature · 2 lines
Jiri Benc
SUSE Labs
#2 lore raw
Quoted 4 lines · Jiri Benc
Quoted 3 lines · Zhu Yi
include/linux/ieee80211.h +0 -0
@@ -106,6 +106,52 @@ struct ieee80211_hdr {

...

Quoted 7 lines

include/linux/ieee80211.h enum ieee80211_eid { · line 506

Quoted 5 lines
include/linux/ieee80211.h +5 -0
+enum wifi_oui_stype_wmm {
+	WIFI_OUI_STYPE_WMM_INFO = 0,
+	WIFI_OUI_STYPE_WMM_PARAM = 1,
+	WIFI_OUI_STYPE_WMM_TSPEC = 2,
+};

Please don't invent new useless prefixes.

It doesn't really look like he invented a 'new useless' prefix. It looks to me like he picked a prefix that correlates attribution of the data declaration to the entity that created it. You may not like that he provided attribution, but that doesn't mean its useless.

If you'd rather use a different prefix, send a patch to fix it.

Quoted 1 line

Also, a registered trademark doesn't seem to be a good prefix.

Who holds 'WIFI' as a registered trademark?

James

#3 lore raw
Quoted 4 lines · jketreno

It doesn't really look like he invented a 'new useless' prefix. It looks to me like he picked a prefix that correlates attribution of the data declaration to the entity that created it. You may not like that he provided attribution, but that doesn't mean its useless.

By "useless", I meant "if you use a WLAN_ prefix like in all other #defines in that file, it will do the same job". Ok, I understand the argument about attribution, but it shouldn't be in exchange of consistency and clarity.

Quoted 1 line

If you'd rather use a different prefix, send a patch to fix it.

I'd appreciate if you use a WLAN_ prefix in the next respin of the patch.

Quoted 1 line

Who holds 'WIFI' as a registered trademark?

Wi-Fi Alliance? Ok, it's "Wi-Fi", but you can use only capitals in macros and you cannot use dash, so it looks really similar.

Thanks,

Jiri

Signature · 2 lines
Jiri Benc
SUSE Labs
#4 lore raw
Quoted 9 lines · Jiri Benc
Quoted 4 lines · jketreno

It doesn't really look like he invented a 'new useless' prefix. It looks to me like he picked a prefix that correlates attribution of the data declaration to the entity that created it. You may not like that he provided attribution, but that doesn't mean its useless.

By "useless", I meant "if you use a WLAN_ prefix like in all other #defines in that file, it will do the same job". Ok, I understand the argument about attribution, but it shouldn't be in exchange of consistency and clarity.

WLAN_ prefix is currently mostly (only?) used for values defined in IEEE 802.11 while the WMM parameters are defined in WFA specification, not IEEE 802.11.

Signature · 1 line
Jouni Malinen                                            PGP id EFC895FA
author
#5 lore raw
In reply to Jiri Benc
Quoted 4 lines · Jiri Benc
Quoted 1 line

+#define SET_TSINFO_SCHEDULE(i, d) (i.byte3 |= (d << 0) & 0x01)

Please add IEEE80211_ prefix here as well. For consistency and not polluting a name space.

Point accepted.

Quoted 8 lines

include/linux/ieee80211.h enum ieee80211_eid { · line 506

Quoted 5 lines
include/linux/ieee80211.h +5 -0
+enum wifi_oui_stype_wmm {
+	WIFI_OUI_STYPE_WMM_INFO = 0,
+	WIFI_OUI_STYPE_WMM_PARAM = 1,
+	WIFI_OUI_STYPE_WMM_TSPEC = 2,
+};

Please don't invent new useless prefixes. Also, a registered trademark doesn't seem to be a good prefix.

I think we have talked this early and now you know correctly WIFI is not a trademark. You define IEEE80211_STYPE_ASSOC_REQ, etc, but defines those for Wi-Fi with WLAN prefix? WLAN prefix should be used by symbols defined by mac80211, for example: WLAN_CAPABILITY_ESS.

Thanks,
-yi

maintainer
#6 lore raw
Quoted 4 lines · Zhu Yi

I think we have talked this early and now you know correctly WIFI is not a trademark. You define IEEE80211_STYPE_ASSOC_REQ, etc, but defines those for Wi-Fi with WLAN prefix? WLAN prefix should be used by symbols defined by mac80211, for example: WLAN_CAPABILITY_ESS.

FWIW, I agree, and not using WIFI_ because it might be a trademark... Jiri, feel free to put a note in the header that "all mentioned names may be trademarks of their respective owners" or something, but something that is defined by the wifi alliance should reasonably be called WIFI_... too.

johannes

#7 lore raw
In reply to Zhu Yi
Quoted 7 lines · Zhu Yi
Quoted 4 lines · Jiri Benc
Quoted 1 line

+#define SET_TSINFO_SCHEDULE(i, d) (i.byte3 |= (d << 0) & 0x01)

Please add IEEE80211_ prefix here as well. For consistency and not polluting a name space.

Point accepted.

Thanks :-)

Quoted 4 lines

I think we have talked this early and now you know correctly WIFI is not a trademark. You define IEEE80211_STYPE_ASSOC_REQ, etc, but defines those for Wi-Fi with WLAN prefix? WLAN prefix should be used by symbols defined by mac80211, for example: WLAN_CAPABILITY_ESS.

You and Jouni are right, WLAN_ is used for IEEE 802.11 stuff. So another prefix makes sense here. And I realized my other comment wasn't meaningful too, as also IEEE 802.11 is a trademark. ACK for those names, thanks for the clarification.

Jiri

Signature · 2 lines
Jiri Benc
SUSE Labs
#8 lore raw
In reply to Zhu Yi
Quoted 10 lines · Zhu Yi
include/linux/ieee80211.h +10 -0
+#define IEEE80211_TSINFO_TYPE(a)	((a.short1 & 0x0001) >> 0)
+#define IEEE80211_TSINFO_TSID(a)	((a.short1 & 0x001E) >> 1)
+#define IEEE80211_TSINFO_DIR(a)		((a.short1 & 0x0060) >> 5)
+#define IEEE80211_TSINFO_POLICY(a)	((a.short1 & 0x0180) >> 7)
+#define IEEE80211_TSINFO_AGG(a)		((a.short1 & 0x0200) >> 9)
+#define IEEE80211_TSINFO_APSD(a)	((a.short1 & 0x0400) >> 10)
+#define IEEE80211_TSINFO_UP(a)		((a.short1 & 0x3800) >> 11)
+#define IEEE80211_TSINFO_ACK(a)		((a.short1 & 0xC000) >> 14)
+#define IEEE80211_TSINFO_SCHEDULE(a)	((a.byte3 & 0x01) >> 0)
+

include/linux/ieee80211.h struct ieee80211_hdr { · line 129

Quoted 10 lines
include/linux/ieee80211.h +10 -0
+#define SET_TSINFO_TYPE(i, d)		(i.short1 |= (d << 0) & 0x0001)
+#define SET_TSINFO_TSID(i, d)		(i.short1 |= (d << 1) & 0x001E)
+#define SET_TSINFO_DIR(i, d)		(i.short1 |= (d << 5) & 0x0060)
+#define SET_TSINFO_POLICY(i, d)		(i.short1 |= (d << 7) & 0x0180)
+#define SET_TSINFO_AGG(i, d)		(i.short1 |= (d << 9) & 0x0200)
+#define SET_TSINFO_APSD(i, d)		(i.short1 |= (d << 10) & 0x0400)
+#define SET_TSINFO_UP(i, d)		(i.short1 |= (d << 11) & 0x3800)
+#define SET_TSINFO_ACK(i, d)		(i.short1 |= (d << 14) & 0xC000)
+#define SET_TSINFO_SCHEDULE(i, d)	(i.byte3 |= (d << 0) & 0x01)
+

Everything that touches short1 looks broken on big endian.

-Michael Wu

author
#9 lore raw
Quoted 4 lines · Michael Wu
Quoted 1 line

+#define SET_TSINFO_ACK(i, d) (i.short1 |= (d << 14) &

0xC000)

Quoted 1 line

+

Everything that touches short1 looks broken on big endian.

No. These are safe on all endians as long as you touch short1 with these macros. Because from the macro mask, you can see no value d is more than a byte.

Thanks,
-yi

#10 lore raw
Quoted 9 lines · Zhu Yi
Quoted 4 lines · Michael Wu
Quoted 1 line

+#define SET_TSINFO_ACK(i, d) (i.short1 |= (d << 14) &

0xC000)

Quoted 1 line

+

Everything that touches short1 looks broken on big endian.

No. These are safe on all endians as long as you touch short1 with these macros. Because from the macro mask, you can see no value d is more than a byte.

No. Michael is right and I'm really blind I haven't seen that myself. That's totally broken. You cannot do _any_ bit operation on __le16.

Let's assume that a value of short1 is 0x34 0x12 (two bytes as stored in a memory). Now let's look at the result of (short1 & 0xff).

On a LE platform that's (0x1234 & 0xff), i.e. 0x34.

On a BE platform that's (0x3412 & 0xff), i.e. 0x12.

How that could be correct?

Jiri

Signature · 2 lines
Jiri Benc
SUSE Labs
author
#11 lore raw
Quoted 11 lines · Jiri Benc

No. Michael is right and I'm really blind I haven't seen that myself. That's totally broken. You cannot do _any_ bit operation on __le16.

Let's assume that a value of short1 is 0x34 0x12 (two bytes as stored in a memory). Now let's look at the result of (short1 & 0xff).

On a LE platform that's (0x1234 & 0xff), i.e. 0x34.

On a BE platform that's (0x3412 & 0xff), i.e. 0x12.

How that could be correct?

You and Michael are right. The mask (i.e 0x00ff) need a cpu_to_le16() in this case. I will replace the short with 2 bytes to fix this issue.

Thanks,
-yi