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 <linux/kref.h> 182c8dccc7SJohannes Berg #include <net/mac80211.h> 192c8dccc7SJohannes Berg #include "ieee80211_i.h" 202c8dccc7SJohannes Berg #include "sta_info.h" 212c8dccc7SJohannes Berg 222e92e6f2SJohannes Berg /** 232e92e6f2SJohannes Berg * struct rate_selection - rate selection for rate control algos 242e92e6f2SJohannes Berg * @rate: selected transmission rate index 252e92e6f2SJohannes Berg * @nonerp: Non-ERP rate to use instead if ERP cannot be used 262e92e6f2SJohannes Berg * @probe: rate for probing (or -1) 272e92e6f2SJohannes Berg * 282e92e6f2SJohannes Berg */ 292c8dccc7SJohannes Berg struct rate_selection { 302e92e6f2SJohannes Berg s8 rate_idx, nonerp_idx, probe_idx; 312c8dccc7SJohannes Berg }; 322c8dccc7SJohannes Berg 332c8dccc7SJohannes Berg struct rate_control_ops { 342c8dccc7SJohannes Berg struct module *module; 352c8dccc7SJohannes Berg const char *name; 362c8dccc7SJohannes Berg void (*tx_status)(void *priv, struct net_device *dev, 37*e039fa4aSJohannes Berg struct sk_buff *skb); 382c8dccc7SJohannes Berg void (*get_rate)(void *priv, struct net_device *dev, 392c8dccc7SJohannes Berg struct ieee80211_supported_band *band, 402c8dccc7SJohannes Berg struct sk_buff *skb, 412c8dccc7SJohannes Berg struct rate_selection *sel); 422c8dccc7SJohannes Berg void (*rate_init)(void *priv, void *priv_sta, 432c8dccc7SJohannes Berg struct ieee80211_local *local, struct sta_info *sta); 442c8dccc7SJohannes Berg void (*clear)(void *priv); 452c8dccc7SJohannes Berg 462c8dccc7SJohannes Berg void *(*alloc)(struct ieee80211_local *local); 472c8dccc7SJohannes Berg void (*free)(void *priv); 482c8dccc7SJohannes Berg void *(*alloc_sta)(void *priv, gfp_t gfp); 492c8dccc7SJohannes Berg void (*free_sta)(void *priv, void *priv_sta); 502c8dccc7SJohannes Berg 512c8dccc7SJohannes Berg int (*add_attrs)(void *priv, struct kobject *kobj); 522c8dccc7SJohannes Berg void (*remove_attrs)(void *priv, struct kobject *kobj); 532c8dccc7SJohannes Berg void (*add_sta_debugfs)(void *priv, void *priv_sta, 542c8dccc7SJohannes Berg struct dentry *dir); 552c8dccc7SJohannes Berg void (*remove_sta_debugfs)(void *priv, void *priv_sta); 562c8dccc7SJohannes Berg }; 572c8dccc7SJohannes Berg 582c8dccc7SJohannes Berg struct rate_control_ref { 592c8dccc7SJohannes Berg struct rate_control_ops *ops; 602c8dccc7SJohannes Berg void *priv; 612c8dccc7SJohannes Berg struct kref kref; 622c8dccc7SJohannes Berg }; 632c8dccc7SJohannes Berg 642c8dccc7SJohannes Berg int ieee80211_rate_control_register(struct rate_control_ops *ops); 652c8dccc7SJohannes Berg void ieee80211_rate_control_unregister(struct rate_control_ops *ops); 662c8dccc7SJohannes Berg 672c8dccc7SJohannes Berg /* Get a reference to the rate control algorithm. If `name' is NULL, get the 682c8dccc7SJohannes Berg * first available algorithm. */ 692c8dccc7SJohannes Berg struct rate_control_ref *rate_control_alloc(const char *name, 702c8dccc7SJohannes Berg struct ieee80211_local *local); 712c8dccc7SJohannes Berg void rate_control_get_rate(struct net_device *dev, 722c8dccc7SJohannes Berg struct ieee80211_supported_band *sband, 732c8dccc7SJohannes Berg struct sk_buff *skb, 742c8dccc7SJohannes Berg struct rate_selection *sel); 752c8dccc7SJohannes Berg struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); 762c8dccc7SJohannes Berg void rate_control_put(struct rate_control_ref *ref); 772c8dccc7SJohannes Berg 782c8dccc7SJohannes Berg static inline void rate_control_tx_status(struct net_device *dev, 79*e039fa4aSJohannes Berg struct sk_buff *skb) 802c8dccc7SJohannes Berg { 812c8dccc7SJohannes Berg struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 822c8dccc7SJohannes Berg struct rate_control_ref *ref = local->rate_ctrl; 832c8dccc7SJohannes Berg 84*e039fa4aSJohannes Berg ref->ops->tx_status(ref->priv, dev, skb); 852c8dccc7SJohannes Berg } 862c8dccc7SJohannes Berg 872c8dccc7SJohannes Berg 882c8dccc7SJohannes Berg static inline void rate_control_rate_init(struct sta_info *sta, 892c8dccc7SJohannes Berg struct ieee80211_local *local) 902c8dccc7SJohannes Berg { 912c8dccc7SJohannes Berg struct rate_control_ref *ref = sta->rate_ctrl; 922c8dccc7SJohannes Berg ref->ops->rate_init(ref->priv, sta->rate_ctrl_priv, local, sta); 932c8dccc7SJohannes Berg } 942c8dccc7SJohannes Berg 952c8dccc7SJohannes Berg 962c8dccc7SJohannes Berg static inline void rate_control_clear(struct ieee80211_local *local) 972c8dccc7SJohannes Berg { 982c8dccc7SJohannes Berg struct rate_control_ref *ref = local->rate_ctrl; 992c8dccc7SJohannes Berg ref->ops->clear(ref->priv); 1002c8dccc7SJohannes Berg } 1012c8dccc7SJohannes Berg 1022c8dccc7SJohannes Berg static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, 1032c8dccc7SJohannes Berg gfp_t gfp) 1042c8dccc7SJohannes Berg { 1052c8dccc7SJohannes Berg return ref->ops->alloc_sta(ref->priv, gfp); 1062c8dccc7SJohannes Berg } 1072c8dccc7SJohannes Berg 1082c8dccc7SJohannes Berg static inline void rate_control_free_sta(struct rate_control_ref *ref, 1092c8dccc7SJohannes Berg void *priv) 1102c8dccc7SJohannes Berg { 1112c8dccc7SJohannes Berg ref->ops->free_sta(ref->priv, priv); 1122c8dccc7SJohannes Berg } 1132c8dccc7SJohannes Berg 1142c8dccc7SJohannes Berg static inline void rate_control_add_sta_debugfs(struct sta_info *sta) 1152c8dccc7SJohannes Berg { 1162c8dccc7SJohannes Berg #ifdef CONFIG_MAC80211_DEBUGFS 1172c8dccc7SJohannes Berg struct rate_control_ref *ref = sta->rate_ctrl; 1182c8dccc7SJohannes Berg if (sta->debugfs.dir && ref->ops->add_sta_debugfs) 1192c8dccc7SJohannes Berg ref->ops->add_sta_debugfs(ref->priv, sta->rate_ctrl_priv, 1202c8dccc7SJohannes Berg sta->debugfs.dir); 1212c8dccc7SJohannes Berg #endif 1222c8dccc7SJohannes Berg } 1232c8dccc7SJohannes Berg 1242c8dccc7SJohannes Berg static inline void rate_control_remove_sta_debugfs(struct sta_info *sta) 1252c8dccc7SJohannes Berg { 1262c8dccc7SJohannes Berg #ifdef CONFIG_MAC80211_DEBUGFS 1272c8dccc7SJohannes Berg struct rate_control_ref *ref = sta->rate_ctrl; 1282c8dccc7SJohannes Berg if (ref->ops->remove_sta_debugfs) 1292c8dccc7SJohannes Berg ref->ops->remove_sta_debugfs(ref->priv, sta->rate_ctrl_priv); 1302c8dccc7SJohannes Berg #endif 1312c8dccc7SJohannes Berg } 1322c8dccc7SJohannes Berg 1332c8dccc7SJohannes Berg static inline int rate_supported(struct sta_info *sta, 1342c8dccc7SJohannes Berg enum ieee80211_band band, 1352c8dccc7SJohannes Berg int index) 1362c8dccc7SJohannes Berg { 1372c8dccc7SJohannes Berg return (sta == NULL || sta->supp_rates[band] & BIT(index)); 1382c8dccc7SJohannes Berg } 1392c8dccc7SJohannes Berg 1402e92e6f2SJohannes Berg static inline s8 1412c8dccc7SJohannes Berg rate_lowest_index(struct ieee80211_local *local, 1422c8dccc7SJohannes Berg struct ieee80211_supported_band *sband, 1432c8dccc7SJohannes Berg struct sta_info *sta) 1442c8dccc7SJohannes Berg { 1452c8dccc7SJohannes Berg int i; 1462c8dccc7SJohannes Berg 1472c8dccc7SJohannes Berg for (i = 0; i < sband->n_bitrates; i++) 1482c8dccc7SJohannes Berg if (rate_supported(sta, sband->band, i)) 1492c8dccc7SJohannes Berg return i; 1502c8dccc7SJohannes Berg 1512c8dccc7SJohannes Berg /* warn when we cannot find a rate. */ 1522c8dccc7SJohannes Berg WARN_ON(1); 1532c8dccc7SJohannes Berg 1542c8dccc7SJohannes Berg return 0; 1552c8dccc7SJohannes Berg } 1562c8dccc7SJohannes Berg 1572c8dccc7SJohannes Berg 1582c8dccc7SJohannes Berg /* functions for rate control related to a device */ 1592c8dccc7SJohannes Berg int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 1602c8dccc7SJohannes Berg const char *name); 1612c8dccc7SJohannes Berg void rate_control_deinitialize(struct ieee80211_local *local); 1622c8dccc7SJohannes Berg 1632c8dccc7SJohannes Berg 1642c8dccc7SJohannes Berg /* Rate control algorithms */ 1652c8dccc7SJohannes Berg #if defined(RC80211_PID_COMPILE) || \ 1662c8dccc7SJohannes Berg (defined(CONFIG_MAC80211_RC_PID) && \ 1672c8dccc7SJohannes Berg !defined(CONFIG_MAC80211_RC_PID_MODULE)) 1682c8dccc7SJohannes Berg extern int rc80211_pid_init(void); 1692c8dccc7SJohannes Berg extern void rc80211_pid_exit(void); 1702c8dccc7SJohannes Berg #else 1712c8dccc7SJohannes Berg static inline int rc80211_pid_init(void) 1722c8dccc7SJohannes Berg { 1732c8dccc7SJohannes Berg return 0; 1742c8dccc7SJohannes Berg } 1752c8dccc7SJohannes Berg static inline void rc80211_pid_exit(void) 1762c8dccc7SJohannes Berg { 1772c8dccc7SJohannes Berg } 1782c8dccc7SJohannes Berg #endif 1792c8dccc7SJohannes Berg 1802c8dccc7SJohannes Berg #endif /* IEEE80211_RATE_H */ 181