1c42a7b7eSSam Leffler /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 4b032f27cSSam Leffler * Copyright (c) 2004-2008 Sam Leffler, Errno Consulting 5c42a7b7eSSam Leffler * Copyright (c) 2004 Video54 Technologies, Inc. 6c42a7b7eSSam Leffler * All rights reserved. 7c42a7b7eSSam Leffler * 8c42a7b7eSSam Leffler * Redistribution and use in source and binary forms, with or without 9c42a7b7eSSam Leffler * modification, are permitted provided that the following conditions 10c42a7b7eSSam Leffler * are met: 11c42a7b7eSSam Leffler * 1. Redistributions of source code must retain the above copyright 12c42a7b7eSSam Leffler * notice, this list of conditions and the following disclaimer, 13515d617eSSam Leffler * without modification. 14c42a7b7eSSam Leffler * 2. Redistributions in binary form must reproduce at minimum a disclaimer 15c42a7b7eSSam Leffler * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 16c42a7b7eSSam Leffler * redistribution must be conditioned upon including a substantially 17c42a7b7eSSam Leffler * similar Disclaimer requirement for further binary redistribution. 18c42a7b7eSSam Leffler * 19c42a7b7eSSam Leffler * NO WARRANTY 20c42a7b7eSSam Leffler * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21c42a7b7eSSam Leffler * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22c42a7b7eSSam Leffler * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 23c42a7b7eSSam Leffler * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 24c42a7b7eSSam Leffler * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 25c42a7b7eSSam Leffler * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26c42a7b7eSSam Leffler * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27c42a7b7eSSam Leffler * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 28c42a7b7eSSam Leffler * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29c42a7b7eSSam Leffler * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30c42a7b7eSSam Leffler * THE POSSIBILITY OF SUCH DAMAGES. 31c42a7b7eSSam Leffler */ 32c42a7b7eSSam Leffler #ifndef _ATH_RATECTRL_H_ 33c42a7b7eSSam Leffler #define _ATH_RATECTRL_H_ 34c42a7b7eSSam Leffler 35c42a7b7eSSam Leffler /* 36c42a7b7eSSam Leffler * Interface definitions for transmit rate control modules for the 37c42a7b7eSSam Leffler * Atheros driver. 38c42a7b7eSSam Leffler * 39c42a7b7eSSam Leffler * A rate control module is responsible for choosing the transmit rate 40c42a7b7eSSam Leffler * for each data frame. Management+control frames are always sent at 41c42a7b7eSSam Leffler * a fixed rate. 42c42a7b7eSSam Leffler * 43c42a7b7eSSam Leffler * Only one module may be present at a time; the driver references 44c42a7b7eSSam Leffler * rate control interfaces by symbol name. If multiple modules are 45c42a7b7eSSam Leffler * to be supported we'll need to switch to a registration-based scheme 46c42a7b7eSSam Leffler * as is currently done, for example, for authentication modules. 47c42a7b7eSSam Leffler * 48c42a7b7eSSam Leffler * An instance of the rate control module is attached to each device 49c42a7b7eSSam Leffler * at attach time and detached when the device is destroyed. The module 50c42a7b7eSSam Leffler * may associate data with each device and each node (station). Both 51c42a7b7eSSam Leffler * sets of storage are opaque except for the size of the per-node storage 52c42a7b7eSSam Leffler * which must be provided when the module is attached. 53c42a7b7eSSam Leffler * 54c42a7b7eSSam Leffler * The rate control module is notified for each state transition and 55c42a7b7eSSam Leffler * station association/reassociation. Otherwise it is queried for a 56c42a7b7eSSam Leffler * rate for each outgoing frame and provided status from each transmitted 57c42a7b7eSSam Leffler * frame. Any ancillary processing is the responsibility of the module 58c42a7b7eSSam Leffler * (e.g. if periodic processing is required then the module should setup 59c42a7b7eSSam Leffler * it's own timer). 60c42a7b7eSSam Leffler * 61c42a7b7eSSam Leffler * In addition to the transmit rate for each frame the module must also 62c42a7b7eSSam Leffler * indicate the number of attempts to make at the specified rate. If this 63c42a7b7eSSam Leffler * number is != ATH_TXMAXTRY then an additional callback is made to setup 64c42a7b7eSSam Leffler * additional transmit state. The rate control code is assumed to write 65c42a7b7eSSam Leffler * this additional data directly to the transmit descriptor. 66c42a7b7eSSam Leffler */ 67c42a7b7eSSam Leffler struct ath_softc; 68c42a7b7eSSam Leffler struct ath_node; 69c42a7b7eSSam Leffler struct ath_desc; 70c42a7b7eSSam Leffler 71c42a7b7eSSam Leffler struct ath_ratectrl { 72c42a7b7eSSam Leffler size_t arc_space; /* space required for per-node state */ 73c42a7b7eSSam Leffler }; 74c42a7b7eSSam Leffler /* 75c42a7b7eSSam Leffler * Attach/detach a rate control module. 76c42a7b7eSSam Leffler */ 77c42a7b7eSSam Leffler struct ath_ratectrl *ath_rate_attach(struct ath_softc *); 78c42a7b7eSSam Leffler void ath_rate_detach(struct ath_ratectrl *); 79c42a7b7eSSam Leffler 8010830c38SAdrian Chadd #define ATH_RC_NUM 4 8110830c38SAdrian Chadd 8210830c38SAdrian Chadd #define ATH_RC_DS_FLAG 0x01 /* dual-stream rate */ 8310830c38SAdrian Chadd #define ATH_RC_CW40_FLAG 0x02 /* use HT40 */ 8410830c38SAdrian Chadd #define ATH_RC_SGI_FLAG 0x04 /* use short-GI */ 8510830c38SAdrian Chadd #define ATH_RC_HT_FLAG 0x08 /* use HT */ 8610830c38SAdrian Chadd #define ATH_RC_RTSCTS_FLAG 0x10 /* enable RTS/CTS protection */ 8787c176d2SAdrian Chadd #define ATH_RC_STBC_FLAG 0x20 /* enable STBC */ 88de00e5cbSAdrian Chadd #define ATH_RC_TS_FLAG 0x40 /* triple-stream rate */ 8910830c38SAdrian Chadd 9010830c38SAdrian Chadd struct ath_rc_series { 9110830c38SAdrian Chadd uint8_t rix; /* ratetable index, not rate code */ 9210830c38SAdrian Chadd uint8_t ratecode; /* hardware rate code */ 9310830c38SAdrian Chadd uint8_t tries; 94de00e5cbSAdrian Chadd uint8_t tx_power_cap; 95de00e5cbSAdrian Chadd uint16_t flags; 96de00e5cbSAdrian Chadd uint16_t max4msframelen; 9710830c38SAdrian Chadd }; 98c42a7b7eSSam Leffler 99c42a7b7eSSam Leffler /* 100c42a7b7eSSam Leffler * State storage handling. 101c42a7b7eSSam Leffler */ 102c42a7b7eSSam Leffler /* 103c42a7b7eSSam Leffler * Initialize per-node state already allocated for the specified 104c42a7b7eSSam Leffler * node; this space can be assumed initialized to zero. 105c42a7b7eSSam Leffler */ 106c42a7b7eSSam Leffler void ath_rate_node_init(struct ath_softc *, struct ath_node *); 107c42a7b7eSSam Leffler /* 108c42a7b7eSSam Leffler * Cleanup any per-node state prior to the node being reclaimed. 109c42a7b7eSSam Leffler */ 110c42a7b7eSSam Leffler void ath_rate_node_cleanup(struct ath_softc *, struct ath_node *); 111c42a7b7eSSam Leffler /* 112c42a7b7eSSam Leffler * Update rate control state on station associate/reassociate 113c42a7b7eSSam Leffler * (when operating as an ap or for nodes discovered when operating 114c42a7b7eSSam Leffler * in ibss mode). 115c42a7b7eSSam Leffler */ 116c42a7b7eSSam Leffler void ath_rate_newassoc(struct ath_softc *, struct ath_node *, 117c42a7b7eSSam Leffler int isNewAssociation); 118c42a7b7eSSam Leffler 119c42a7b7eSSam Leffler /* 120c42a7b7eSSam Leffler * Transmit handling. 121c42a7b7eSSam Leffler */ 122c42a7b7eSSam Leffler /* 123710c3778SAdrian Chadd * Return the four TX rate index and try counts for the current data packet. 124710c3778SAdrian Chadd */ 125710c3778SAdrian Chadd void ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an, 126051ea90cSAdrian Chadd uint8_t rix0, int is_aggr, struct ath_rc_series *rc); 127710c3778SAdrian Chadd 128710c3778SAdrian Chadd /* 129c42a7b7eSSam Leffler * Return the transmit info for a data packet. If multi-rate state 130c42a7b7eSSam Leffler * is to be setup then try0 should contain a value other than ATH_TXMATRY 131c42a7b7eSSam Leffler * and ath_rate_setupxtxdesc will be called after deciding if the frame 132c42a7b7eSSam Leffler * can be transmitted with multi-rate retry. 13384f950a5SAdrian Chadd * 13484f950a5SAdrian Chadd * maxdur is an optional return value (or -1 if not set) that defines 13584f950a5SAdrian Chadd * the maximum frame duration in microseconds. This allows the rate 13684f950a5SAdrian Chadd * control selection to override the maximum duration (normally 4ms) 13784f950a5SAdrian Chadd * that the packet aggregation logic makes. 138c42a7b7eSSam Leffler */ 139c42a7b7eSSam Leffler void ath_rate_findrate(struct ath_softc *, struct ath_node *, 140cce63444SAdrian Chadd int shortPreamble, size_t frameLen, int tid, int is_aggr, 141cce63444SAdrian Chadd u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur, 142cce63444SAdrian Chadd int *maxpktlen); 143c42a7b7eSSam Leffler /* 144c42a7b7eSSam Leffler * Setup any extended (multi-rate) descriptor state for a data packet. 145c42a7b7eSSam Leffler * The rate index returned by ath_rate_findrate is passed back in. 146c42a7b7eSSam Leffler */ 147c42a7b7eSSam Leffler void ath_rate_setupxtxdesc(struct ath_softc *, struct ath_node *, 148a4d8dd10SSam Leffler struct ath_desc *, int shortPreamble, u_int8_t rix); 149c42a7b7eSSam Leffler /* 150c42a7b7eSSam Leffler * Update rate control state for a packet associated with the 151c42a7b7eSSam Leffler * supplied transmit descriptor. The routine is invoked both 152c42a7b7eSSam Leffler * for packets that were successfully sent and for those that 153c42a7b7eSSam Leffler * failed (consult the descriptor for details). 154eb6f0de0SAdrian Chadd * 155eb6f0de0SAdrian Chadd * For A-MPDU frames, nframes and nbad indicate how many frames 156eb6f0de0SAdrian Chadd * were in the aggregate, and how many failed. 157c42a7b7eSSam Leffler */ 15865f9edeeSSam Leffler struct ath_buf; 159c42a7b7eSSam Leffler void ath_rate_tx_complete(struct ath_softc *, struct ath_node *, 160eb6f0de0SAdrian Chadd const struct ath_rc_series *, const struct ath_tx_status *, 161cce63444SAdrian Chadd int pktlen, int rc_framelen, int nframes, int nbad); 1629e38f708SAdrian Chadd 1639e38f708SAdrian Chadd /* 1647d450faaSAdrian Chadd * Update rate control with a per-packet receive RSSI value. 1657d450faaSAdrian Chadd */ 1667d450faaSAdrian Chadd void ath_rate_update_rx_rssi(struct ath_softc *, struct ath_node *, 1677d450faaSAdrian Chadd int rssi); 1687d450faaSAdrian Chadd 1697d450faaSAdrian Chadd /* 1709e38f708SAdrian Chadd * Fetch the global rate control statistics. 1719e38f708SAdrian Chadd */ 1729e38f708SAdrian Chadd int ath_rate_fetch_stats(struct ath_softc *sc, struct ath_rateioctl *rs); 1739e38f708SAdrian Chadd 1749e38f708SAdrian Chadd /* 1759e38f708SAdrian Chadd * Fetch the per-node statistics. 1769e38f708SAdrian Chadd */ 1779e38f708SAdrian Chadd int ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an, 1789e38f708SAdrian Chadd struct ath_rateioctl *rs); 1799e38f708SAdrian Chadd 180c42a7b7eSSam Leffler #endif /* _ATH_RATECTRL_H_ */ 181