2007-05-05 22:45:53 +04:00
/*
* Copyright 2002 - 2005 , Instant802 Networks , Inc .
* Copyright 2005 , Devicescape Software , Inc .
* Copyright ( c ) 2006 Jiri Benc < jbenc @ suse . cz >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# ifndef IEEE80211_RATE_H
# define IEEE80211_RATE_H
# include <linux/netdevice.h>
# include <linux/skbuff.h>
# include <linux/types.h>
# include <net/mac80211.h>
# include "ieee80211_i.h"
# include "sta_info.h"
2012-03-30 10:43:32 +04:00
# include "driver-ops.h"
2007-05-05 22:45:53 +04:00
struct rate_control_ref {
2008-09-18 20:14:18 +04:00
struct ieee80211_local * local ;
2014-01-21 02:29:34 +04:00
const struct rate_control_ops * ops ;
2007-05-05 22:45:53 +04:00
void * priv ;
} ;
2008-09-18 20:14:18 +04:00
void rate_control_get_rate ( struct ieee80211_sub_if_data * sdata ,
2008-10-21 14:40:02 +04:00
struct sta_info * sta ,
struct ieee80211_tx_rate_control * txrc ) ;
2007-05-05 22:45:53 +04:00
2008-09-18 20:14:18 +04:00
static inline void rate_control_tx_status ( struct ieee80211_local * local ,
struct ieee80211_supported_band * sband ,
struct sta_info * sta ,
2008-05-15 14:55:29 +04:00
struct sk_buff * skb )
2007-05-05 22:45:53 +04:00
{
struct rate_control_ref * ref = local - > rate_ctrl ;
2008-09-18 20:14:18 +04:00
struct ieee80211_sta * ista = & sta - > sta ;
void * priv_sta = sta - > rate_ctrl_priv ;
2014-11-19 22:08:08 +03:00
struct ieee80211_tx_info * info = IEEE80211_SKB_CB ( skb ) ;
2010-02-01 16:19:07 +03:00
2012-02-08 22:17:11 +04:00
if ( ! ref | | ! test_sta_flag ( sta , WLAN_STA_RATE_CONTROL ) )
2010-02-01 16:19:07 +03:00
return ;
2015-03-05 18:10:08 +03:00
spin_lock_bh ( & sta - > rate_ctrl_lock ) ;
2014-11-19 22:08:08 +03:00
if ( ref - > ops - > tx_status )
ref - > ops - > tx_status ( ref - > priv , sband , ista , priv_sta , skb ) ;
else
ref - > ops - > tx_status_noskb ( ref - > priv , sband , ista , priv_sta , info ) ;
2015-03-05 18:10:08 +03:00
spin_unlock_bh ( & sta - > rate_ctrl_lock ) ;
2007-05-05 22:45:53 +04:00
}
2014-11-19 22:08:13 +03:00
static inline void
rate_control_tx_status_noskb ( struct ieee80211_local * local ,
struct ieee80211_supported_band * sband ,
struct sta_info * sta ,
struct ieee80211_tx_info * info )
{
struct rate_control_ref * ref = local - > rate_ctrl ;
struct ieee80211_sta * ista = & sta - > sta ;
void * priv_sta = sta - > rate_ctrl_priv ;
if ( ! ref | | ! test_sta_flag ( sta , WLAN_STA_RATE_CONTROL ) )
return ;
if ( WARN_ON_ONCE ( ! ref - > ops - > tx_status_noskb ) )
return ;
2015-03-05 18:10:08 +03:00
spin_lock_bh ( & sta - > rate_ctrl_lock ) ;
2014-11-19 22:08:13 +03:00
ref - > ops - > tx_status_noskb ( ref - > priv , sband , ista , priv_sta , info ) ;
2015-03-05 18:10:08 +03:00
spin_unlock_bh ( & sta - > rate_ctrl_lock ) ;
2014-11-19 22:08:13 +03:00
}
2007-05-05 22:45:53 +04:00
2008-09-18 20:14:18 +04:00
static inline void rate_control_rate_init ( struct sta_info * sta )
2007-05-05 22:45:53 +04:00
{
2008-09-18 20:14:18 +04:00
struct ieee80211_local * local = sta - > sdata - > local ;
2007-05-05 22:45:53 +04:00
struct rate_control_ref * ref = sta - > rate_ctrl ;
2008-09-18 20:14:18 +04:00
struct ieee80211_sta * ista = & sta - > sta ;
void * priv_sta = sta - > rate_ctrl_priv ;
struct ieee80211_supported_band * sband ;
2012-07-26 19:24:39 +04:00
struct ieee80211_chanctx_conf * chanctx_conf ;
2008-09-18 20:14:18 +04:00
2013-12-02 14:54:07 +04:00
ieee80211_sta_set_rx_nss ( sta ) ;
2009-11-17 20:18:36 +03:00
if ( ! ref )
return ;
2012-07-26 19:24:39 +04:00
rcu_read_lock ( ) ;
chanctx_conf = rcu_dereference ( sta - > sdata - > vif . chanctx_conf ) ;
if ( WARN_ON ( ! chanctx_conf ) ) {
rcu_read_unlock ( ) ;
return ;
}
2012-11-09 14:39:59 +04:00
sband = local - > hw . wiphy - > bands [ chanctx_conf - > def . chan - > band ] ;
2008-09-18 20:14:18 +04:00
2015-03-05 18:10:08 +03:00
spin_lock_bh ( & sta - > rate_ctrl_lock ) ;
2013-07-08 18:55:50 +04:00
ref - > ops - > rate_init ( ref - > priv , sband , & chanctx_conf - > def , ista ,
priv_sta ) ;
2015-03-05 18:10:08 +03:00
spin_unlock_bh ( & sta - > rate_ctrl_lock ) ;
2013-07-08 18:55:50 +04:00
rcu_read_unlock ( ) ;
2012-01-20 16:55:23 +04:00
set_sta_flag ( sta , WLAN_STA_RATE_CONTROL ) ;
2007-05-05 22:45:53 +04:00
}
2009-02-12 09:08:37 +03:00
static inline void rate_control_rate_update ( struct ieee80211_local * local ,
struct ieee80211_supported_band * sband ,
2012-03-28 12:58:37 +04:00
struct sta_info * sta , u32 changed )
2009-02-12 09:08:37 +03:00
{
struct rate_control_ref * ref = local - > rate_ctrl ;
struct ieee80211_sta * ista = & sta - > sta ;
void * priv_sta = sta - > rate_ctrl_priv ;
2013-07-08 18:55:50 +04:00
struct ieee80211_chanctx_conf * chanctx_conf ;
if ( ref & & ref - > ops - > rate_update ) {
rcu_read_lock ( ) ;
2009-02-12 09:08:37 +03:00
2013-07-08 18:55:50 +04:00
chanctx_conf = rcu_dereference ( sta - > sdata - > vif . chanctx_conf ) ;
if ( WARN_ON ( ! chanctx_conf ) ) {
rcu_read_unlock ( ) ;
return ;
}
2015-03-05 18:10:08 +03:00
spin_lock_bh ( & sta - > rate_ctrl_lock ) ;
2013-07-08 18:55:50 +04:00
ref - > ops - > rate_update ( ref - > priv , sband , & chanctx_conf - > def ,
ista , priv_sta , changed ) ;
2015-03-05 18:10:08 +03:00
spin_unlock_bh ( & sta - > rate_ctrl_lock ) ;
2013-07-08 18:55:50 +04:00
rcu_read_unlock ( ) ;
}
2012-03-30 10:43:32 +04:00
drv_sta_rc_update ( local , sta - > sdata , & sta - > sta , changed ) ;
2009-02-12 09:08:37 +03:00
}
2007-05-05 22:45:53 +04:00
static inline void * rate_control_alloc_sta ( struct rate_control_ref * ref ,
2015-03-05 18:10:08 +03:00
struct sta_info * sta , gfp_t gfp )
2007-05-05 22:45:53 +04:00
{
2015-03-05 18:10:08 +03:00
spin_lock_init ( & sta - > rate_ctrl_lock ) ;
return ref - > ops - > alloc_sta ( ref - > priv , & sta - > sta , gfp ) ;
2007-05-05 22:45:53 +04:00
}
2008-09-18 20:14:18 +04:00
static inline void rate_control_free_sta ( struct sta_info * sta )
2007-05-05 22:45:53 +04:00
{
2008-09-18 20:14:18 +04:00
struct rate_control_ref * ref = sta - > rate_ctrl ;
struct ieee80211_sta * ista = & sta - > sta ;
void * priv_sta = sta - > rate_ctrl_priv ;
ref - > ops - > free_sta ( ref - > priv , ista , priv_sta ) ;
2007-05-05 22:45:53 +04:00
}
2007-05-05 22:46:38 +04:00
static inline void rate_control_add_sta_debugfs ( struct sta_info * sta )
{
# ifdef CONFIG_MAC80211_DEBUGFS
struct rate_control_ref * ref = sta - > rate_ctrl ;
2009-11-17 20:18:36 +03:00
if ( ref & & sta - > debugfs . dir & & ref - > ops - > add_sta_debugfs )
2007-05-05 22:46:38 +04:00
ref - > ops - > add_sta_debugfs ( ref - > priv , sta - > rate_ctrl_priv ,
sta - > debugfs . dir ) ;
# endif
}
static inline void rate_control_remove_sta_debugfs ( struct sta_info * sta )
{
# ifdef CONFIG_MAC80211_DEBUGFS
struct rate_control_ref * ref = sta - > rate_ctrl ;
2009-11-17 20:18:36 +03:00
if ( ref & & ref - > ops - > remove_sta_debugfs )
2007-05-05 22:46:38 +04:00
ref - > ops - > remove_sta_debugfs ( ref - > priv , sta - > rate_ctrl_priv ) ;
# endif
}
2010-02-08 05:47:50 +03:00
/* Get a reference to the rate control algorithm. If `name' is NULL, get the
* first available algorithm . */
2007-07-27 17:43:23 +04:00
int ieee80211_init_rate_ctrl_alg ( struct ieee80211_local * local ,
const char * name ) ;
void rate_control_deinitialize ( struct ieee80211_local * local ) ;
2008-01-02 17:17:03 +03:00
/* Rate control algorithms */
2008-10-05 20:07:45 +04:00
# ifdef CONFIG_MAC80211_RC_MINSTREL
2013-10-19 00:48:25 +04:00
int rc80211_minstrel_init ( void ) ;
void rc80211_minstrel_exit ( void ) ;
2008-10-05 20:07:45 +04:00
# else
static inline int rc80211_minstrel_init ( void )
{
return 0 ;
}
static inline void rc80211_minstrel_exit ( void )
{
}
# endif
2010-05-13 18:48:03 +04:00
# ifdef CONFIG_MAC80211_RC_MINSTREL_HT
2013-10-19 00:48:25 +04:00
int rc80211_minstrel_ht_init ( void ) ;
void rc80211_minstrel_ht_exit ( void ) ;
2010-05-13 18:48:03 +04:00
# else
static inline int rc80211_minstrel_ht_init ( void )
{
return 0 ;
}
static inline void rc80211_minstrel_ht_exit ( void )
{
}
# endif
2008-10-05 20:07:45 +04:00
2007-05-05 22:45:53 +04:00
# endif /* IEEE80211_RATE_H */