string: factorize skip_spaces and export it to be generally available
[safe/jmp/linux-2.6] / include / linux / ieee80211.h
index b0726e2..d9724a2 100644 (file)
 #include <linux/types.h>
 #include <asm/byteorder.h>
 
+/*
+ * DS bit usage
+ *
+ * TA = transmitter address
+ * RA = receiver address
+ * DA = destination address
+ * SA = source address
+ *
+ * ToDS    FromDS  A1(RA)  A2(TA)  A3      A4      Use
+ * -----------------------------------------------------------------
+ *  0       0       DA      SA      BSSID   -       IBSS/DLS
+ *  0       1       DA      BSSID   SA      -       AP -> STA
+ *  1       0       BSSID   SA      DA      -       AP <- STA
+ *  1       1       RA      TA      DA      SA      unspecified (WDS)
+ */
+
 #define FCS_LEN 4
 
 #define IEEE80211_FCTL_VERS            0x0003
 #define IEEE80211_MAX_FRAME_LEN                2352
 
 #define IEEE80211_MAX_SSID_LEN         32
+
 #define IEEE80211_MAX_MESH_ID_LEN      32
+
 #define IEEE80211_QOS_CTL_LEN          2
 #define IEEE80211_QOS_CTL_TID_MASK     0x000F
 #define IEEE80211_QOS_CTL_TAG1D_MASK   0x0007
@@ -453,7 +471,7 @@ static inline int ieee80211_is_cfendack(__le16 fc)
 }
 
 /**
- * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC
+ * ieee80211_is_nullfunc - check if frame is a regular (non-QoS) nullfunc frame
  * @fc: frame control bytes in little-endian byteorder
  */
 static inline int ieee80211_is_nullfunc(__le16 fc)
@@ -462,6 +480,16 @@ static inline int ieee80211_is_nullfunc(__le16 fc)
               cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC);
 }
 
+/**
+ * ieee80211_is_qos_nullfunc - check if frame is a QoS nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee80211_is_qos_nullfunc(__le16 fc)
+{
+       return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+              cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);
+}
+
 struct ieee80211s_hdr {
        u8 flags;
        u8 ttl;
@@ -474,6 +502,7 @@ struct ieee80211s_hdr {
 /* Mesh flags */
 #define MESH_FLAGS_AE_A4       0x1
 #define MESH_FLAGS_AE_A5_A6    0x2
+#define MESH_FLAGS_AE          0x3
 #define MESH_FLAGS_PS_DEEP     0x4
 
 /**
@@ -521,9 +550,40 @@ struct ieee80211_tim_ie {
        u8 dtim_period;
        u8 bitmap_ctrl;
        /* variable size: 1 - 251 bytes */
-       u8 virtual_map[0];
+       u8 virtual_map[1];
 } __attribute__ ((packed));
 
+/**
+ * struct ieee80211_meshconf_ie
+ *
+ * This structure refers to "Mesh Configuration information element"
+ */
+struct ieee80211_meshconf_ie {
+       u8 meshconf_psel;
+       u8 meshconf_pmetric;
+       u8 meshconf_congest;
+       u8 meshconf_synch;
+       u8 meshconf_auth;
+       u8 meshconf_form;
+       u8 meshconf_cap;
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_rann_ie
+ *
+ * This structure refers to "Root Announcement information element"
+ */
+struct ieee80211_rann_ie {
+       u8 rann_flags;
+       u8 rann_hopcount;
+       u8 rann_ttl;
+       u8 rann_addr[6];
+       u32 rann_seq;
+       u32 rann_metric;
+} __attribute__ ((packed));
+
+#define WLAN_SA_QUERY_TR_ID_LEN 2
+
 struct ieee80211_mgmt {
        __le16 frame_control;
        __le16 duration;
@@ -643,6 +703,10 @@ struct ieee80211_mgmt {
                                        u8 action_code;
                                        u8 variable[0];
                                } __attribute__((packed)) mesh_action;
+                               struct {
+                                       u8 action;
+                                       u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+                               } __attribute__ ((packed)) sa_query;
                        } u;
                } __attribute__ ((packed)) action;
        } u;
@@ -652,6 +716,15 @@ struct ieee80211_mgmt {
 #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
 
 
+/* Management MIC information element (IEEE 802.11w) */
+struct ieee80211_mmie {
+       u8 element_id;
+       u8 length;
+       __le16 key_id;
+       u8 sequence_number[6];
+       u8 mic[8];
+} __attribute__ ((packed));
+
 /* Control frames */
 struct ieee80211_rts {
        __le16 frame_control;
@@ -666,6 +739,13 @@ struct ieee80211_cts {
        u8 ra[6];
 } __attribute__ ((packed));
 
+struct ieee80211_pspoll {
+       __le16 frame_control;
+       __le16 aid;
+       u8 bssid[6];
+       u8 ta[6];
+} __attribute__ ((packed));
+
 /**
  * struct ieee80211_bar - HT Block Ack Request
  *
@@ -760,6 +840,31 @@ struct ieee80211_ht_cap {
 #define IEEE80211_HT_AMPDU_PARM_FACTOR         0x03
 #define IEEE80211_HT_AMPDU_PARM_DENSITY                0x1C
 
+/*
+ * Maximum length of AMPDU that the STA can receive.
+ * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+enum ieee80211_max_ampdu_length_exp {
+       IEEE80211_HT_MAX_AMPDU_8K = 0,
+       IEEE80211_HT_MAX_AMPDU_16K = 1,
+       IEEE80211_HT_MAX_AMPDU_32K = 2,
+       IEEE80211_HT_MAX_AMPDU_64K = 3
+};
+
+#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
+
+/* Minimum MPDU start spacing */
+enum ieee80211_min_mpdu_spacing {
+       IEEE80211_HT_MPDU_DENSITY_NONE = 0,     /* No restriction */
+       IEEE80211_HT_MPDU_DENSITY_0_25 = 1,     /* 1/4 usec */
+       IEEE80211_HT_MPDU_DENSITY_0_5 = 2,      /* 1/2 usec */
+       IEEE80211_HT_MPDU_DENSITY_1 = 3,        /* 1 usec */
+       IEEE80211_HT_MPDU_DENSITY_2 = 4,        /* 2 usec */
+       IEEE80211_HT_MPDU_DENSITY_4 = 5,        /* 4 usec */
+       IEEE80211_HT_MPDU_DENSITY_8 = 6,        /* 8 usec */
+       IEEE80211_HT_MPDU_DENSITY_16 = 7        /* 16 usec */
+};
+
 /**
  * struct ieee80211_ht_info - HT information
  *
@@ -826,7 +931,7 @@ struct ieee80211_ht_info {
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_FAST_BSS_TRANSITION 2
+#define WLAN_AUTH_FT 2
 #define WLAN_AUTH_LEAP 128
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
@@ -890,6 +995,9 @@ enum ieee80211_statuscode {
        /* 802.11g */
        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+       /* 802.11w */
+       WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30,
+       WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
        /* 802.11i */
        WLAN_STATUS_INVALID_IE = 40,
        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
@@ -990,6 +1098,7 @@ enum ieee80211_eid {
        WLAN_EID_PREQ = 68,
        WLAN_EID_PREP = 69,
        WLAN_EID_PERR = 70,
+       WLAN_EID_RANN = 49,     /* compatible with FreeBSD */
        /* 802.11h */
        WLAN_EID_PWR_CONSTRAINT = 32,
        WLAN_EID_PWR_CAPABILITY = 33,
@@ -1009,6 +1118,8 @@ enum ieee80211_eid {
        WLAN_EID_HT_INFORMATION = 61,
        /* 802.11i */
        WLAN_EID_RSN = 48,
+       WLAN_EID_TIMEOUT_INTERVAL = 56,
+       WLAN_EID_MMIE = 76 /* 802.11w */,
        WLAN_EID_WPA = 221,
        WLAN_EID_GENERIC = 221,
        WLAN_EID_VENDOR_SPECIFIC = 221,
@@ -1021,7 +1132,13 @@ enum ieee80211_category {
        WLAN_CATEGORY_QOS = 1,
        WLAN_CATEGORY_DLS = 2,
        WLAN_CATEGORY_BACK = 3,
+       WLAN_CATEGORY_PUBLIC = 4,
+       WLAN_CATEGORY_HT = 7,
+       WLAN_CATEGORY_SA_QUERY = 8,
+       WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
        WLAN_CATEGORY_WMM = 17,
+       WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
+       WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
 };
 
 /* SPECTRUM_MGMT action code */
@@ -1033,6 +1150,83 @@ enum ieee80211_spectrum_mgmt_actioncode {
        WLAN_ACTION_SPCT_CHL_SWITCH = 4,
 };
 
+/* Security key length */
+enum ieee80211_key_len {
+       WLAN_KEY_LEN_WEP40 = 5,
+       WLAN_KEY_LEN_WEP104 = 13,
+       WLAN_KEY_LEN_CCMP = 16,
+       WLAN_KEY_LEN_TKIP = 32,
+       WLAN_KEY_LEN_AES_CMAC = 16,
+};
+
+/*
+ * IEEE 802.11-2007 7.3.2.9 Country information element
+ *
+ * Minimum length is 8 octets, ie len must be evenly
+ * divisible by 2
+ */
+
+/* Although the spec says 8 I'm seeing 6 in practice */
+#define IEEE80211_COUNTRY_IE_MIN_LEN   6
+
+/*
+ * For regulatory extension stuff see IEEE 802.11-2007
+ * Annex I (page 1141) and Annex J (page 1147). Also
+ * review 7.3.2.9.
+ *
+ * When dot11RegulatoryClassesRequired is true and the
+ * first_channel/reg_extension_id is >= 201 then the IE
+ * compromises of the 'ext' struct represented below:
+ *
+ *  - Regulatory extension ID - when generating IE this just needs
+ *    to be monotonically increasing for each triplet passed in
+ *    the IE
+ *  - Regulatory class - index into set of rules
+ *  - Coverage class - index into air propagation time (Table 7-27),
+ *    in microseconds, you can compute the air propagation time from
+ *    the index by multiplying by 3, so index 10 yields a propagation
+ *    of 10 us. Valid values are 0-31, values 32-255 are not defined
+ *    yet. A value of 0 inicates air propagation of <= 1 us.
+ *
+ *  See also Table I.2 for Emission limit sets and table
+ *  I.3 for Behavior limit sets. Table J.1 indicates how to map
+ *  a reg_class to an emission limit set and behavior limit set.
+ */
+#define IEEE80211_COUNTRY_EXTENSION_ID 201
+
+/*
+ *  Channels numbers in the IE must be monotonically increasing
+ *  if dot11RegulatoryClassesRequired is not true.
+ *
+ *  If dot11RegulatoryClassesRequired is true consecutive
+ *  subband triplets following a regulatory triplet shall
+ *  have monotonically increasing first_channel number fields.
+ *
+ *  Channel numbers shall not overlap.
+ *
+ *  Note that max_power is signed.
+ */
+struct ieee80211_country_ie_triplet {
+       union {
+               struct {
+                       u8 first_channel;
+                       u8 num_channels;
+                       s8 max_power;
+               } __attribute__ ((packed)) chans;
+               struct {
+                       u8 reg_extension_id;
+                       u8 reg_class;
+                       u8 coverage_class;
+               } __attribute__ ((packed)) ext;
+       };
+} __attribute__ ((packed));
+
+enum ieee80211_timeout_interval_type {
+       WLAN_TIMEOUT_REASSOC_DEADLINE = 1 /* 802.11r */,
+       WLAN_TIMEOUT_KEY_LIFETIME = 2 /* 802.11r */,
+       WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */,
+};
+
 /* BACK action code */
 enum ieee80211_back_actioncode {
        WLAN_ACTION_ADDBA_REQ = 0,
@@ -1047,6 +1241,13 @@ enum ieee80211_back_parties {
        WLAN_BACK_TIMER = 2,
 };
 
+/* SA Query action */
+enum ieee80211_sa_query_action {
+       WLAN_ACTION_SA_QUERY_REQUEST = 0,
+       WLAN_ACTION_SA_QUERY_RESPONSE = 1,
+};
+
+
 /* A-MSDU 802.11n */
 #define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080
 
@@ -1057,9 +1258,16 @@ enum ieee80211_back_parties {
 /* reserved:                           0x000FAC03 */
 #define WLAN_CIPHER_SUITE_CCMP         0x000FAC04
 #define WLAN_CIPHER_SUITE_WEP104       0x000FAC05
+#define WLAN_CIPHER_SUITE_AES_CMAC     0x000FAC06
+
+/* AKM suite selectors */
+#define WLAN_AKM_SUITE_8021X           0x000FAC01
+#define WLAN_AKM_SUITE_PSK             0x000FAC02
 
 #define WLAN_MAX_KEY_LEN               32
 
+#define WLAN_PMKID_LEN                 16
+
 /**
  * ieee80211_get_qos_ctl - get pointer to qos control bytes
  * @hdr: the frame
@@ -1114,4 +1322,190 @@ static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)
                return hdr->addr1;
 }
 
+/**
+ * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
+ * @hdr: the frame (buffer must include at least the first octet of payload)
+ */
+static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
+{
+       if (ieee80211_is_disassoc(hdr->frame_control) ||
+           ieee80211_is_deauth(hdr->frame_control))
+               return true;
+
+       if (ieee80211_is_action(hdr->frame_control)) {
+               u8 *category;
+
+               /*
+                * Action frames, excluding Public Action frames, are Robust
+                * Management Frames. However, if we are looking at a Protected
+                * frame, skip the check since the data may be encrypted and
+                * the frame has already been found to be a Robust Management
+                * Frame (by the other end).
+                */
+               if (ieee80211_has_protected(hdr->frame_control))
+                       return true;
+               category = ((u8 *) hdr) + 24;
+               return *category != WLAN_CATEGORY_PUBLIC &&
+                       *category != WLAN_CATEGORY_HT &&
+                       *category != WLAN_CATEGORY_VENDOR_SPECIFIC;
+       }
+
+       return false;
+}
+
+/**
+ * ieee80211_fhss_chan_to_freq - get channel frequency
+ * @channel: the FHSS channel
+ *
+ * Convert IEEE802.11 FHSS channel to frequency (MHz)
+ * Ref IEEE 802.11-2007 section 14.6
+ */
+static inline int ieee80211_fhss_chan_to_freq(int channel)
+{
+       if ((channel > 1) && (channel < 96))
+               return channel + 2400;
+       else
+               return -1;
+}
+
+/**
+ * ieee80211_freq_to_fhss_chan - get channel
+ * @freq: the channels frequency
+ *
+ * Convert frequency (MHz) to IEEE802.11 FHSS channel
+ * Ref IEEE 802.11-2007 section 14.6
+ */
+static inline int ieee80211_freq_to_fhss_chan(int freq)
+{
+       if ((freq > 2401) && (freq < 2496))
+               return freq - 2400;
+       else
+               return -1;
+}
+
+/**
+ * ieee80211_dsss_chan_to_freq - get channel center frequency
+ * @channel: the DSSS channel
+ *
+ * Convert IEEE802.11 DSSS channel to the center frequency (MHz).
+ * Ref IEEE 802.11-2007 section 15.6
+ */
+static inline int ieee80211_dsss_chan_to_freq(int channel)
+{
+       if ((channel > 0) && (channel < 14))
+               return 2407 + (channel * 5);
+       else if (channel == 14)
+               return 2484;
+       else
+               return -1;
+}
+
+/**
+ * ieee80211_freq_to_dsss_chan - get channel
+ * @freq: the frequency
+ *
+ * Convert frequency (MHz) to IEEE802.11 DSSS channel
+ * Ref IEEE 802.11-2007 section 15.6
+ *
+ * This routine selects the channel with the closest center frequency.
+ */
+static inline int ieee80211_freq_to_dsss_chan(int freq)
+{
+       if ((freq >= 2410) && (freq < 2475))
+               return (freq - 2405) / 5;
+       else if ((freq >= 2482) && (freq < 2487))
+               return 14;
+       else
+               return -1;
+}
+
+/* Convert IEEE802.11 HR DSSS channel to frequency (MHz) and back
+ * Ref IEEE 802.11-2007 section 18.4.6.2
+ *
+ * The channels and frequencies are the same as those defined for DSSS
+ */
+#define ieee80211_hr_chan_to_freq(chan) ieee80211_dsss_chan_to_freq(chan)
+#define ieee80211_freq_to_hr_chan(freq) ieee80211_freq_to_dsss_chan(freq)
+
+/* Convert IEEE802.11 ERP channel to frequency (MHz) and back
+ * Ref IEEE 802.11-2007 section 19.4.2
+ */
+#define ieee80211_erp_chan_to_freq(chan) ieee80211_hr_chan_to_freq(chan)
+#define ieee80211_freq_to_erp_chan(freq) ieee80211_freq_to_hr_chan(freq)
+
+/**
+ * ieee80211_ofdm_chan_to_freq - get channel center frequency
+ * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz
+ * @channel: the OFDM channel
+ *
+ * Convert IEEE802.11 OFDM channel to center frequency (MHz)
+ * Ref IEEE 802.11-2007 section 17.3.8.3.2
+ */
+static inline int ieee80211_ofdm_chan_to_freq(int s_freq, int channel)
+{
+       if ((channel > 0) && (channel <= 200) &&
+           (s_freq >= 4000))
+               return s_freq + (channel * 5);
+       else
+               return -1;
+}
+
+/**
+ * ieee80211_freq_to_ofdm_channel - get channel
+ * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz
+ * @freq: the frequency
+ *
+ * Convert frequency (MHz) to IEEE802.11 OFDM channel
+ * Ref IEEE 802.11-2007 section 17.3.8.3.2
+ *
+ * This routine selects the channel with the closest center frequency.
+ */
+static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq)
+{
+       if ((freq > (s_freq + 2)) && (freq <= (s_freq + 1202)) &&
+           (s_freq >= 4000))
+               return (freq + 2 - s_freq) / 5;
+       else
+               return -1;
+}
+
+/**
+ * ieee80211_tu_to_usec - convert time units (TU) to microseconds
+ * @tu: the TUs
+ */
+static inline unsigned long ieee80211_tu_to_usec(unsigned long tu)
+{
+       return 1024 * tu;
+}
+
+/**
+ * ieee80211_check_tim - check if AID bit is set in TIM
+ * @tim: the TIM IE
+ * @tim_len: length of the TIM IE
+ * @aid: the AID to look for
+ */
+static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim,
+                                      u8 tim_len, u16 aid)
+{
+       u8 mask;
+       u8 index, indexn1, indexn2;
+
+       if (unlikely(!tim || tim_len < sizeof(*tim)))
+               return false;
+
+       aid &= 0x3fff;
+       index = aid / 8;
+       mask  = 1 << (aid & 7);
+
+       indexn1 = tim->bitmap_ctrl & 0xfe;
+       indexn2 = tim_len + indexn1 - 4;
+
+       if (index < indexn1 || index > indexn2)
+               return false;
+
+       index -= indexn1;
+
+       return !!(tim->virtual_map[index] & mask);
+}
+
 #endif /* LINUX_IEEE80211_H */