summaryrefslogtreecommitdiff
path: root/include/net/mac80211.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/mac80211.h')
-rw-r--r--include/net/mac80211.h239
1 files changed, 185 insertions, 54 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ff137fd7714..5617a1613c9 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -158,13 +158,17 @@ struct ieee80211_low_level_stats {
* also implies a change in the AID.
* @BSS_CHANGED_ERP_CTS_PROT: CTS protection changed
* @BSS_CHANGED_ERP_PREAMBLE: preamble changed
+ * @BSS_CHANGED_ERP_SLOT: slot timing changed
* @BSS_CHANGED_HT: 802.11n parameters changed
+ * @BSS_CHANGED_BASIC_RATES: Basic rateset changed
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
BSS_CHANGED_ERP_CTS_PROT = 1<<1,
BSS_CHANGED_ERP_PREAMBLE = 1<<2,
+ BSS_CHANGED_ERP_SLOT = 1<<3,
BSS_CHANGED_HT = 1<<4,
+ BSS_CHANGED_BASIC_RATES = 1<<5,
};
/**
@@ -177,6 +181,7 @@ enum ieee80211_bss_change {
* @aid: association ID number, valid only when @assoc is true
* @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble
+ * @use_short_slot: use short slot time (only relevant for ERP)
* @dtim_period: num of beacons before the next DTIM, for PSM
* @timestamp: beacon timestamp
* @beacon_int: beacon interval
@@ -184,6 +189,9 @@ enum ieee80211_bss_change {
* @assoc_ht: association in HT mode
* @ht_conf: ht capabilities
* @ht_bss_conf: ht extended capabilities
+ * @basic_rates: bitmap of basic rates, each bit stands for an
+ * index into the rate table configured by the driver in
+ * the current band.
*/
struct ieee80211_bss_conf {
/* association related data */
@@ -192,10 +200,12 @@ struct ieee80211_bss_conf {
/* erp related data */
bool use_cts_prot;
bool use_short_preamble;
+ bool use_short_slot;
u8 dtim_period;
u16 beacon_int;
u16 assoc_capability;
u64 timestamp;
+ u64 basic_rates;
/* ht related data */
bool assoc_ht;
struct ieee80211_ht_info *ht_conf;
@@ -282,6 +292,20 @@ enum mac80211_tx_control_flags {
#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \
(IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *))
+/* maximum number of alternate rate retry stages */
+#define IEEE80211_TX_MAX_ALTRATE 3
+
+/**
+ * struct ieee80211_tx_altrate - alternate rate selection/status
+ *
+ * @rate_idx: rate index to attempt to send with
+ * @limit: number of retries before fallback
+ */
+struct ieee80211_tx_altrate {
+ s8 rate_idx;
+ u8 limit;
+};
+
/**
* struct ieee80211_tx_info - skb transmit information
*
@@ -290,6 +314,9 @@ enum mac80211_tx_control_flags {
* (2) driver internal use (if applicable)
* (3) TX status information - driver tells mac80211 what happened
*
+ * The TX control's sta pointer is only valid during the ->tx call,
+ * it may be NULL.
+ *
* @flags: transmit info flags, defined above
* @band: TBD
* @tx_rate_idx: TBD
@@ -317,18 +344,19 @@ struct ieee80211_tx_info {
union {
struct {
+ /* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
+ struct ieee80211_sta *sta;
unsigned long jiffies;
- u16 aid;
- s8 rts_cts_rate_idx, alt_retry_rate_idx;
+ s8 rts_cts_rate_idx;
u8 retry_limit;
- u8 icv_len;
- u8 iv_len;
+ struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE];
} control;
struct {
u64 ampdu_ack_map;
int ack_signal;
+ struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE + 1];
u8 retry_count;
bool excessive_retries;
u8 ampdu_ack_len;
@@ -363,6 +391,7 @@ static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
* @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime field)
* is valid. This is useful in monitor mode and necessary for beacon frames
* to enable IBSS merging.
+ * @RX_FLAG_SHORTPRE: Short preamble was used for this frame
*/
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = 1<<0,
@@ -373,6 +402,7 @@ enum mac80211_rx_flags {
RX_FLAG_FAILED_FCS_CRC = 1<<5,
RX_FLAG_FAILED_PLCP_CRC = 1<<6,
RX_FLAG_TSFT = 1<<7,
+ RX_FLAG_SHORTPRE = 1<<8
};
/**
@@ -418,6 +448,11 @@ struct ieee80211_rx_status {
* @IEEE80211_CONF_PS: Enable 802.11 power save mode
*/
enum ieee80211_conf_flags {
+ /*
+ * TODO: IEEE80211_CONF_SHORT_SLOT_TIME will be removed once drivers
+ * have been converted to use bss_info_changed() for slot time
+ * configuration
+ */
IEEE80211_CONF_SHORT_SLOT_TIME = (1<<0),
IEEE80211_CONF_RADIOTAP = (1<<1),
IEEE80211_CONF_SUPPORT_HT_MODE = (1<<2),
@@ -461,33 +496,6 @@ struct ieee80211_conf {
};
/**
- * enum ieee80211_if_types - types of 802.11 network interfaces
- *
- * @IEEE80211_IF_TYPE_INVALID: invalid interface type, not used
- * by mac80211 itself
- * @IEEE80211_IF_TYPE_AP: interface in AP mode.
- * @IEEE80211_IF_TYPE_MGMT: special interface for communication with hostap
- * daemon. Drivers should never see this type.
- * @IEEE80211_IF_TYPE_STA: interface in STA (client) mode.
- * @IEEE80211_IF_TYPE_IBSS: interface in IBSS (ad-hoc) mode.
- * @IEEE80211_IF_TYPE_MNTR: interface in monitor (rfmon) mode.
- * @IEEE80211_IF_TYPE_WDS: interface in WDS mode.
- * @IEEE80211_IF_TYPE_VLAN: VLAN interface bound to an AP, drivers
- * will never see this type.
- * @IEEE80211_IF_TYPE_MESH_POINT: 802.11s mesh point
- */
-enum ieee80211_if_types {
- IEEE80211_IF_TYPE_INVALID,
- IEEE80211_IF_TYPE_AP,
- IEEE80211_IF_TYPE_STA,
- IEEE80211_IF_TYPE_IBSS,
- IEEE80211_IF_TYPE_MESH_POINT,
- IEEE80211_IF_TYPE_MNTR,
- IEEE80211_IF_TYPE_WDS,
- IEEE80211_IF_TYPE_VLAN,
-};
-
-/**
* struct ieee80211_vif - per-interface data
*
* Data in this structure is continually present for driver
@@ -498,7 +506,7 @@ enum ieee80211_if_types {
* sizeof(void *).
*/
struct ieee80211_vif {
- enum ieee80211_if_types type;
+ enum nl80211_iftype type;
/* must be last */
u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
};
@@ -506,7 +514,7 @@ struct ieee80211_vif {
static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
{
#ifdef CONFIG_MAC80211_MESH
- return vif->type == IEEE80211_IF_TYPE_MESH_POINT;
+ return vif->type == NL80211_IFTYPE_MESH_POINT;
#endif
return false;
}
@@ -517,7 +525,7 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
* @vif: pointer to a driver-use per-interface structure. The pointer
* itself is also used for various functions including
* ieee80211_beacon_get() and ieee80211_get_buffered_bc().
- * @type: one of &enum ieee80211_if_types constants. Determines the type of
+ * @type: one of &enum nl80211_iftype constants. Determines the type of
* added/removed interface.
* @mac_addr: pointer to MAC address of the interface. This pointer is valid
* until the interface is removed (i.e. it cannot be used after
@@ -533,7 +541,7 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
* in pure monitor mode.
*/
struct ieee80211_if_init_conf {
- enum ieee80211_if_types type;
+ enum nl80211_iftype type;
struct ieee80211_vif *vif;
void *mac_addr;
};
@@ -641,6 +649,8 @@ enum ieee80211_key_flags {
*/
struct ieee80211_key_conf {
enum ieee80211_key_alg alg;
+ u8 icv_len;
+ u8 iv_len;
u8 hw_key_idx;
u8 flags;
s8 keyidx;
@@ -662,6 +672,33 @@ enum set_key_cmd {
};
/**
+ * struct ieee80211_sta - station table entry
+ *
+ * A station table entry represents a station we are possibly
+ * communicating with. Since stations are RCU-managed in
+ * mac80211, any ieee80211_sta pointer you get access to must
+ * either be protected by rcu_read_lock() explicitly or implicitly,
+ * or you must take good care to not use such a pointer after a
+ * call to your sta_notify callback that removed it.
+ *
+ * @addr: MAC address
+ * @aid: AID we assigned to the station if we're an AP
+ * @supp_rates: Bitmap of supported rates (per band)
+ * @ht_info: HT capabilities of this STA
+ * @drv_priv: data area for driver use, will always be aligned to
+ * sizeof(void *), size is determined in hw information.
+ */
+struct ieee80211_sta {
+ u64 supp_rates[IEEE80211_NUM_BANDS];
+ u8 addr[ETH_ALEN];
+ u16 aid;
+ struct ieee80211_ht_info ht_info;
+
+ /* must be last */
+ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
+};
+
+/**
* enum sta_notify_cmd - sta notify command
*
* Used with the sta_notify() callback in &struct ieee80211_ops, this
@@ -805,6 +842,11 @@ enum ieee80211_hw_flags {
*
* @vif_data_size: size (in bytes) of the drv_priv data area
* within &struct ieee80211_vif.
+ * @sta_data_size: size (in bytes) of the drv_priv data area
+ * within &struct ieee80211_sta.
+ *
+ * @max_altrates: maximum number of alternate rate retry stages
+ * @max_altrate_tries: maximum number of tries for each stage
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -816,12 +858,17 @@ struct ieee80211_hw {
unsigned int extra_tx_headroom;
int channel_change_time;
int vif_data_size;
+ int sta_data_size;
u16 queues;
u16 ampdu_queues;
u16 max_listen_interval;
s8 max_signal;
+ u8 max_altrates;
+ u8 max_altrate_tries;
};
+struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy);
+
/**
* SET_IEEE80211_DEV - set device for 802.11 hardware
*
@@ -874,11 +921,11 @@ ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw,
static inline struct ieee80211_rate *
ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
- const struct ieee80211_tx_info *c)
+ const struct ieee80211_tx_info *c, int idx)
{
- if (c->control.alt_retry_rate_idx < 0)
+ if (c->control.retries[idx].rate_idx < 0)
return NULL;
- return &hw->wiphy->bands[c->band]->bitrates[c->control.alt_retry_rate_idx];
+ return &hw->wiphy->bands[c->band]->bitrates[c->control.retries[idx].rate_idx];
}
/**
@@ -1097,7 +1144,7 @@ enum ieee80211_ampdu_mlme_action {
* This callback must be implemented and atomic.
*
* @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
- * must be set or cleared for a given AID. Must be atomic.
+ * must be set or cleared for a given STA. Must be atomic.
*
* @set_key: See the section "Hardware crypto acceleration"
* This callback can sleep, and is only called between add_interface
@@ -1111,7 +1158,9 @@ enum ieee80211_ampdu_mlme_action {
* @hw_scan: Ask the hardware to service the scan request, no need to start
* the scan state machine in stack. The scan must honour the channel
* configuration done by the regulatory agent in the wiphy's registered
- * bands.
+ * bands. When the scan finishes, ieee80211_scan_completed() must be
+ * called; note that it also must be called when the scan cannot finish
+ * because the hardware is turned off! Anything else is a bug!
*
* @get_stats: return low-level statistics
*
@@ -1131,7 +1180,7 @@ enum ieee80211_ampdu_mlme_action {
* of assocaited station or AP.
*
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
- * bursting) for a hardware TX queue. Must be atomic.
+ * bursting) for a hardware TX queue.
*
* @get_tx_stats: Get statistics of the current TX queue status. This is used
* to get number of currently queued packets (queue length), maximum queue
@@ -1181,7 +1230,8 @@ struct ieee80211_ops {
unsigned int changed_flags,
unsigned int *total_flags,
int mc_count, struct dev_addr_list *mc_list);
- int (*set_tim)(struct ieee80211_hw *hw, int aid, int set);
+ int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ bool set);
int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
const u8 *local_address, const u8 *address,
struct ieee80211_key_conf *key);
@@ -1198,7 +1248,7 @@ struct ieee80211_ops {
int (*set_retry_limit)(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retr);
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- enum sta_notify_cmd, const u8 *addr);
+ enum sta_notify_cmd, struct ieee80211_sta *sta);
int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int (*get_tx_stats)(struct ieee80211_hw *hw,
@@ -1208,7 +1258,7 @@ struct ieee80211_ops {
int (*tx_last_beacon)(struct ieee80211_hw *hw);
int (*ampdu_action)(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
- const u8 *addr, u16 tid, u16 *ssn);
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
};
/**
@@ -1557,16 +1607,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
/**
- * ieee80211_get_hdrlen - get header length from frame control
- *
- * This function returns the 802.11 header length in bytes (not including
- * encryption headers.)
- *
- * @fc: the frame control field (in CPU endianness)
- */
-int ieee80211_get_hdrlen(u16 fc);
-
-/**
* ieee80211_hdrlen - get header length in bytes from frame control
* @fc: frame control field in little-endian format
*/
@@ -1608,6 +1648,16 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue);
void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue);
/**
+ * ieee80211_queue_stopped - test status of the queue
+ * @hw: pointer as obtained from ieee80211_alloc_hw().
+ * @queue: queue number (counted from zero).
+ *
+ * Drivers should use this function instead of netif_stop_queue.
+ */
+
+int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue);
+
+/**
* ieee80211_stop_queues - stop all queues
* @hw: pointer as obtained from ieee80211_alloc_hw().
*
@@ -1758,4 +1808,85 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra,
*/
void ieee80211_notify_mac(struct ieee80211_hw *hw,
enum ieee80211_notification_types notif_type);
+
+/**
+ * ieee80211_find_sta - find a station
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @addr: station's address
+ *
+ * This function must be called under RCU lock and the
+ * resulting pointer is only valid under RCU lock as well.
+ */
+struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
+ const u8 *addr);
+
+
+/* Rate control API */
+/**
+ * struct rate_selection - rate information for/from rate control algorithms
+ *
+ * @rate_idx: selected transmission rate index
+ * @nonerp_idx: Non-ERP rate to use instead if ERP cannot be used
+ * @probe_idx: rate for probing (or -1)
+ * @max_rate_idx: maximum rate index that can be used, this is
+ * input to the algorithm and will be enforced
+ */
+struct rate_selection {
+ s8 rate_idx, nonerp_idx, probe_idx, max_rate_idx;
+};
+
+struct rate_control_ops {
+ struct module *module;
+ const char *name;
+ void *(*alloc)(struct ieee80211_hw *hw, struct dentry *debugfsdir);
+ void (*clear)(void *priv);
+ void (*free)(void *priv);
+
+ void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp);
+ void (*rate_init)(void *priv, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta);
+ void (*free_sta)(void *priv, struct ieee80211_sta *sta,
+ void *priv_sta);
+
+ void (*tx_status)(void *priv, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb);
+ void (*get_rate)(void *priv, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb,
+ struct rate_selection *sel);
+
+ void (*add_sta_debugfs)(void *priv, void *priv_sta,
+ struct dentry *dir);
+ void (*remove_sta_debugfs)(void *priv, void *priv_sta);
+};
+
+static inline int rate_supported(struct ieee80211_sta *sta,
+ enum ieee80211_band band,
+ int index)
+{
+ return (sta == NULL || sta->supp_rates[band] & BIT(index));
+}
+
+static inline s8
+rate_lowest_index(struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta)
+{
+ int i;
+
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (rate_supported(sta, sband->band, i))
+ return i;
+
+ /* warn when we cannot find a rate. */
+ WARN_ON(1);
+
+ return 0;
+}
+
+
+int ieee80211_rate_control_register(struct rate_control_ops *ops);
+void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
+
#endif /* MAC80211_H */