12c8dccc7SJohannes Berg /* 22c8dccc7SJohannes Berg * Copyright 2002-2005, Instant802 Networks, Inc. 32c8dccc7SJohannes Berg * Copyright 2005, Devicescape Software, Inc. 42c8dccc7SJohannes Berg * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> 52c8dccc7SJohannes Berg * 62c8dccc7SJohannes Berg * This program is free software; you can redistribute it and/or modify 72c8dccc7SJohannes Berg * it under the terms of the GNU General Public License version 2 as 82c8dccc7SJohannes Berg * published by the Free Software Foundation. 92c8dccc7SJohannes Berg */ 102c8dccc7SJohannes Berg 112c8dccc7SJohannes Berg #ifndef IEEE80211_RATE_H 122c8dccc7SJohannes Berg #define IEEE80211_RATE_H 132c8dccc7SJohannes Berg 142c8dccc7SJohannes Berg #include <linux/netdevice.h> 152c8dccc7SJohannes Berg #include <linux/skbuff.h> 162c8dccc7SJohannes Berg #include <linux/types.h> 172c8dccc7SJohannes Berg #include <net/mac80211.h> 182c8dccc7SJohannes Berg #include "ieee80211_i.h" 192c8dccc7SJohannes Berg #include "sta_info.h" 208f727ef3SJohannes Berg #include "driver-ops.h" 212c8dccc7SJohannes Berg 222c8dccc7SJohannes Berg struct rate_control_ref { 23631ad703SJohannes Berg const struct rate_control_ops *ops; 242c8dccc7SJohannes Berg void *priv; 252c8dccc7SJohannes Berg }; 262c8dccc7SJohannes Berg 274b7679a5SJohannes Berg void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, 28e6a9854bSJohannes Berg struct sta_info *sta, 29e6a9854bSJohannes Berg struct ieee80211_tx_rate_control *txrc); 302c8dccc7SJohannes Berg 314b7679a5SJohannes Berg static inline void rate_control_tx_status(struct ieee80211_local *local, 324b7679a5SJohannes Berg struct ieee80211_supported_band *sband, 334b7679a5SJohannes Berg struct sta_info *sta, 34e039fa4aSJohannes Berg struct sk_buff *skb) 352c8dccc7SJohannes Berg { 362c8dccc7SJohannes Berg struct rate_control_ref *ref = local->rate_ctrl; 374b7679a5SJohannes Berg struct ieee80211_sta *ista = &sta->sta; 384b7679a5SJohannes Berg void *priv_sta = sta->rate_ctrl_priv; 39f684565eSFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 403c384053SVasanthakumar 412cfc6fc5SFelix Fietkau if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) 423c384053SVasanthakumar return; 433c384053SVasanthakumar 4435c347acSJohannes Berg spin_lock_bh(&sta->rate_ctrl_lock); 45f684565eSFelix Fietkau if (ref->ops->tx_status) 464b7679a5SJohannes Berg ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); 47f684565eSFelix Fietkau else 48f684565eSFelix Fietkau ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info); 4935c347acSJohannes Berg spin_unlock_bh(&sta->rate_ctrl_lock); 502c8dccc7SJohannes Berg } 512c8dccc7SJohannes Berg 52f027c2acSFelix Fietkau static inline void 53f027c2acSFelix Fietkau rate_control_tx_status_noskb(struct ieee80211_local *local, 54f027c2acSFelix Fietkau struct ieee80211_supported_band *sband, 55f027c2acSFelix Fietkau struct sta_info *sta, 56f027c2acSFelix Fietkau struct ieee80211_tx_info *info) 57f027c2acSFelix Fietkau { 58f027c2acSFelix Fietkau struct rate_control_ref *ref = local->rate_ctrl; 59f027c2acSFelix Fietkau struct ieee80211_sta *ista = &sta->sta; 60f027c2acSFelix Fietkau void *priv_sta = sta->rate_ctrl_priv; 61f027c2acSFelix Fietkau 62f027c2acSFelix Fietkau if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) 63f027c2acSFelix Fietkau return; 64f027c2acSFelix Fietkau 65f027c2acSFelix Fietkau if (WARN_ON_ONCE(!ref->ops->tx_status_noskb)) 66f027c2acSFelix Fietkau return; 67f027c2acSFelix Fietkau 6835c347acSJohannes Berg spin_lock_bh(&sta->rate_ctrl_lock); 69f027c2acSFelix Fietkau ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info); 7035c347acSJohannes Berg spin_unlock_bh(&sta->rate_ctrl_lock); 71f027c2acSFelix Fietkau } 722c8dccc7SJohannes Berg 73eb6d9293SDenys Vlasenko void rate_control_rate_init(struct sta_info *sta); 74eb6d9293SDenys Vlasenko void rate_control_rate_update(struct ieee80211_local *local, 7581cb7623SSujith struct ieee80211_supported_band *sband, 76eb6d9293SDenys Vlasenko struct sta_info *sta, u32 changed); 772c8dccc7SJohannes Berg 782c8dccc7SJohannes Berg static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, 7935c347acSJohannes Berg struct sta_info *sta, gfp_t gfp) 802c8dccc7SJohannes Berg { 8135c347acSJohannes Berg spin_lock_init(&sta->rate_ctrl_lock); 8235c347acSJohannes Berg return ref->ops->alloc_sta(ref->priv, &sta->sta, gfp); 832c8dccc7SJohannes Berg } 842c8dccc7SJohannes Berg 854b7679a5SJohannes Berg static inline void rate_control_free_sta(struct sta_info *sta) 862c8dccc7SJohannes Berg { 874b7679a5SJohannes Berg struct rate_control_ref *ref = sta->rate_ctrl; 884b7679a5SJohannes Berg struct ieee80211_sta *ista = &sta->sta; 894b7679a5SJohannes Berg void *priv_sta = sta->rate_ctrl_priv; 904b7679a5SJohannes Berg 914b7679a5SJohannes Berg ref->ops->free_sta(ref->priv, ista, priv_sta); 922c8dccc7SJohannes Berg } 932c8dccc7SJohannes Berg 942c8dccc7SJohannes Berg static inline void rate_control_add_sta_debugfs(struct sta_info *sta) 952c8dccc7SJohannes Berg { 962c8dccc7SJohannes Berg #ifdef CONFIG_MAC80211_DEBUGFS 972c8dccc7SJohannes Berg struct rate_control_ref *ref = sta->rate_ctrl; 98fc4a25c5SJohannes Berg if (ref && sta->debugfs_dir && ref->ops->add_sta_debugfs) 992c8dccc7SJohannes Berg ref->ops->add_sta_debugfs(ref->priv, sta->rate_ctrl_priv, 100fc4a25c5SJohannes Berg sta->debugfs_dir); 1012c8dccc7SJohannes Berg #endif 1022c8dccc7SJohannes Berg } 1032c8dccc7SJohannes Berg 1042c8dccc7SJohannes Berg static inline void rate_control_remove_sta_debugfs(struct sta_info *sta) 1052c8dccc7SJohannes Berg { 1062c8dccc7SJohannes Berg #ifdef CONFIG_MAC80211_DEBUGFS 1072c8dccc7SJohannes Berg struct rate_control_ref *ref = sta->rate_ctrl; 108af65cd96SJohannes Berg if (ref && ref->ops->remove_sta_debugfs) 1092c8dccc7SJohannes Berg ref->ops->remove_sta_debugfs(ref->priv, sta->rate_ctrl_priv); 1102c8dccc7SJohannes Berg #endif 1112c8dccc7SJohannes Berg } 1122c8dccc7SJohannes Berg 113*e8e4f528SJohannes Berg void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata); 114*e8e4f528SJohannes Berg 115209c671dSAndres Salomon /* Get a reference to the rate control algorithm. If `name' is NULL, get the 116209c671dSAndres Salomon * first available algorithm. */ 1172c8dccc7SJohannes Berg int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 1182c8dccc7SJohannes Berg const char *name); 1192c8dccc7SJohannes Berg void rate_control_deinitialize(struct ieee80211_local *local); 1202c8dccc7SJohannes Berg 1212c8dccc7SJohannes Berg 1222c8dccc7SJohannes Berg /* Rate control algorithms */ 123cccf129fSFelix Fietkau #ifdef CONFIG_MAC80211_RC_MINSTREL 124c1b1203dSJoe Perches int rc80211_minstrel_init(void); 125c1b1203dSJoe Perches void rc80211_minstrel_exit(void); 126cccf129fSFelix Fietkau #else 127cccf129fSFelix Fietkau static inline int rc80211_minstrel_init(void) 128cccf129fSFelix Fietkau { 129cccf129fSFelix Fietkau return 0; 130cccf129fSFelix Fietkau } 131cccf129fSFelix Fietkau static inline void rc80211_minstrel_exit(void) 132cccf129fSFelix Fietkau { 133cccf129fSFelix Fietkau } 134cccf129fSFelix Fietkau #endif 135cccf129fSFelix Fietkau 136ec8aa669SFelix Fietkau #ifdef CONFIG_MAC80211_RC_MINSTREL_HT 137c1b1203dSJoe Perches int rc80211_minstrel_ht_init(void); 138c1b1203dSJoe Perches void rc80211_minstrel_ht_exit(void); 139ec8aa669SFelix Fietkau #else 140ec8aa669SFelix Fietkau static inline int rc80211_minstrel_ht_init(void) 141ec8aa669SFelix Fietkau { 142ec8aa669SFelix Fietkau return 0; 143ec8aa669SFelix Fietkau } 144ec8aa669SFelix Fietkau static inline void rc80211_minstrel_ht_exit(void) 145ec8aa669SFelix Fietkau { 146ec8aa669SFelix Fietkau } 147ec8aa669SFelix Fietkau #endif 148ec8aa669SFelix Fietkau 149cccf129fSFelix Fietkau 1502c8dccc7SJohannes Berg #endif /* IEEE80211_RATE_H */ 151