/*-
 *  And then Indranet Technologies Ltd sponsored Derek Smithies to work
 * on this code. Derek Smithies (derek@indranet.co.nz) took parts of the 
 * adm module and pasted it into this code base. 
 *
 * This version of John Bicket's code takes the experimental approach one
 * step further.
 * When in auto rate mode, packets are sent at the selected rate.
 * The Hal asks for what alternative rate to use if the selected rate fails.
 * We provide the alternative rate from a random selection of 1.. max rate.
 * Given the probability of success, multiplied with the transmission time,
 * we can determine the rate which maximises packet throughput.
 *
 * Different rates are used for every remote node - some nodes will work 
 * better on different rates.
 * Every second, a timer fires, to assess the throughput at each rate with 
 *  each remote node.
 * This timer will then determine the optimum rate for each remote node, based
 * on the performance figures.
 *
 * This code is called minstrel, because we have taken a wandering minstrel
 * apporoch. Wander aimlessly around the different rates, singing wherever 
 * you can. And then, look at the performacnce, and make a choice.
 *
 *  Enjoy.  Derek Smithies.
 *
 ***********************************************************************
 * Copyright (c) 2005 John Bicket
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
 *    redistribution must be conditioned upon including a substantially
 *    similar Disclaimer requirement for further binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGES.
 *
 * $Id: minstrel.h 1441 2006-02-06 16:03:21Z mrenzmann $
 */

/*
 * Definitions for the Atheros Wireless LAN controller driver.
 */
#ifndef _DEV_ATH_RATE_MINSTREL_H
#define _DEV_ATH_RATE_MINSTREL_H
#define MINSTREL_COLUMNS 10

/* per-device state */
struct minstrel_softc {
	struct ath_ratectrl arc; 	/* base state */

#ifdef CONFIG_SYSCTL
	struct ctl_table_header *sysctl_header;
	struct ctl_table *sysctls;
#endif
	struct ath_softc  *sc;
	struct net_device *sc_dev;


	struct timer_list timer;	/* periodic timer */
	int close_timer_now;
};


#define ATH_SOFTC_MINSTREL(sc)    ((struct minstrel_softc *)sc->sc_rc)

struct rate_info {
	int rate;
	int rix;
	int rateCode;
	int shortPreambleRateCode;
};



/* per-node state */
struct minstrel_node {
	int static_rate_ndx; /*User has bypassed dynamic selection. Fix on one rate */
	int num_rates;
	struct rate_info rates[IEEE80211_RATE_MAXSIZE];

	unsigned perfect_tx_time[IEEE80211_RATE_MAXSIZE];  /* transmit time for 0 retries */
	unsigned retry_count[IEEE80211_RATE_MAXSIZE];      /*The number of retrys permitted for this particular rate */
	unsigned retry_adjusted_count[IEEE80211_RATE_MAXSIZE]; /*retry_count, but altered, depending on if this is a very poor (or very good) link */
	int current_rate;

	u_int32_t		rs_rateattempts[IEEE80211_RATE_MAXSIZE];
	u_int32_t               rs_thisprob    [IEEE80211_RATE_MAXSIZE];
	u_int32_t		rs_ratesuccess [IEEE80211_RATE_MAXSIZE];
	u_int32_t		rs_lastrateattempts[IEEE80211_RATE_MAXSIZE];
	u_int32_t		rs_lastratesuccess [IEEE80211_RATE_MAXSIZE];
	u_int32_t               rs_probability [IEEE80211_RATE_MAXSIZE]; /* units of parts per thousand */
	u_int64_t               rs_succ_hist   [IEEE80211_RATE_MAXSIZE];
	u_int64_t               rs_att_hist    [IEEE80211_RATE_MAXSIZE];

	u_int32_t               rs_this_tp     [IEEE80211_RATE_MAXSIZE]; /*Throughput, each rate */

       /**This flag on indicates to try other than the optimal rate,
          to see what we find */
	int                     is_sampling;

        /**The current minstrel sample rate - which could be anything
         from 1..11 - assuming there are 12 possible rates. Note that
         we never ever sample at the base rate of 0.*/
       int                     rs_sample_rate;

       /**Flag to indicate that the sample rate is slower than the
          current maximum throughput rate. This determines the order
          of the retry chain. */
       int                     rs_sample_rate_slower;

	/** These four parameters are indexes into the current rate
	    table, and are calculated in ath_rate_statistics(), which
	    happens every time the timer for rate adjustment fires */
	int max_tp_rate;       /*  Has the current highest recorded throughput */
	int max_tp_rate2;      /*  Has the second highest recorded throughput */
	int max_prob_rate;     /*  This rate has the highest chance of success. */

	/**These two variables are used to keep track of what
	   percentage of packets have been used to do sample on. 
	   Thus,if ath_lookaround_rate is set to 10%, we can expect that
	   sample_count
	       ------------                    = 0.1
	   sample_count + packet_count                           */
	int packet_count;     /*  The number of times we have  
				  sent a packet to this node. */
	int sample_count;     /* The number of times we have 
				 sent a sample packet to this node */

	/**The table that holds the sequence of rates that we use. In
	   each column in the table, the rates we sample are provided
	   in some "random" order. Each rate we sample occurs once in
	   each column. There are several columns, so we sample the
	   different rates in a different order each time. */
	u_int8_t              rs_sampleTable[IEEE80211_RATE_MAXSIZE][MINSTREL_COLUMNS];
	int                   rs_sampleColumn;
	int                   rs_sampleIndex;

	   /**Random number generator is
	       Rn+1 = (A*Rn) + B. 

	       This Random number generator determines when we send a minstrel
	       packet, or a packet at an optimal rate.*/
	int random_n;
	int a, b;          /**Coefficients of the random thing */
};


#define	ATH_NODE_MINSTREL(an)	((struct minstrel_node *)&an[1])


#ifndef MIN
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b)        ((a) > (b) ? (a) : (b))
#endif

/*
 * Definitions for pulling the rate and trie counts from
 * a 5212 h/w descriptor. These Don't belong here; the
 * driver should record this information so the rate control
 * code doesn't go groveling around in the descriptor bits.
 */
#define	ds_ctl2	ds_hw[0]
#define	ds_ctl3	ds_hw[1]

/* TX ds_ctl3 */
#define	AR_XmitDataTries0	0x000f0000	/* series 0 max attempts */
#define	AR_XmitDataTries0_S	16
#define	AR_XmitDataTries1	0x00f00000	/* series 1 max attempts */
#define	AR_XmitDataTries1_S	20
#define	AR_XmitDataTries2	0x0f000000	/* series 2 max attempts */
#define	AR_XmitDataTries2_S	24
#define	AR_XmitDataTries3	0xf0000000	/* series 3 max attempts */
#define	AR_XmitDataTries3_S	28

/* TX ds_ctl3 */
#define	AR_XmitRate0		0x0000001f	/* series 0 tx rate */
#define	AR_XmitRate0_S		0
#define	AR_XmitRate1		0x000003e0	/* series 1 tx rate */
#define	AR_XmitRate1_S		5
#define	AR_XmitRate2		0x00007c00	/* series 2 tx rate */
#define	AR_XmitRate2_S		10
#define	AR_XmitRate3		0x000f8000	/* series 3 tx rate */
#define	AR_XmitRate3_S		15

#define MS(_v, _f)	(((_v) & (_f)) >> _f##_S)
#endif /* _DEV_ATH_RATE_MINSTEL_H */

/* The comment below is magic for those who use emacs to edit this file. */
/* With the comment below, the tab key does auto indent to 8 spaces.     */

/*
 * Local Variables:
 * mode:c
 * c-file-style:"linux"
 * c-basic-offset:8
 * End:
 */
