diff options
Diffstat (limited to 'include/net/mac80211.h')
-rw-r--r-- | include/net/mac80211.h | 242 |
1 files changed, 187 insertions, 55 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ff137fd7714..d861197f83c 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; }; @@ -637,10 +645,13 @@ enum ieee80211_key_flags { * - Temporal Encryption Key (128 bits) * - Temporal Authenticator Tx MIC Key (64 bits) * - Temporal Authenticator Rx MIC Key (64 bits) - * + * @icv_len: FIXME + * @iv_len: FIXME */ 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 +673,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 +843,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 +859,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 +922,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 +1145,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 +1159,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 +1181,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 +1231,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 +1249,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 +1259,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 +1608,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 +1649,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 +1809,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 */ |