if_ath_tx_ht.c revision 218566
1148456Spjd/*- 2220922Spjd * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. 3148456Spjd * All rights reserved. 4148456Spjd * 5148456Spjd * Redistribution and use in source and binary forms, with or without 6148456Spjd * modification, are permitted provided that the following conditions 7148456Spjd * are met: 8148456Spjd * 1. Redistributions of source code must retain the above copyright 9148456Spjd * notice, this list of conditions and the following disclaimer, 10148456Spjd * without modification. 11148456Spjd * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12148456Spjd * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13155174Spjd * redistribution must be conditioned upon including a substantially 14148456Spjd * similar Disclaimer requirement for further binary redistribution. 15148456Spjd * 16148456Spjd * NO WARRANTY 17148456Spjd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18148456Spjd * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19148456Spjd * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20148456Spjd * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21148456Spjd * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22148456Spjd * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23148456Spjd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24148456Spjd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25148456Spjd * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26148456Spjd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27148456Spjd * THE POSSIBILITY OF SUCH DAMAGES. 28148456Spjd */ 29148456Spjd 30148456Spjd#include <sys/cdefs.h> 31148456Spjd__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx_ht.c 218566 2011-02-11 14:07:27Z adrian $"); 32148456Spjd 33148456Spjd#include "opt_inet.h" 34148456Spjd#include "opt_ath.h" 35148456Spjd#include "opt_wlan.h" 36148456Spjd 37148456Spjd#include <sys/param.h> 38148456Spjd#include <sys/systm.h> 39148456Spjd#include <sys/sysctl.h> 40148456Spjd#include <sys/mbuf.h> 41148456Spjd#include <sys/malloc.h> 42148456Spjd#include <sys/lock.h> 43148456Spjd#include <sys/mutex.h> 44148456Spjd#include <sys/kernel.h> 45148456Spjd#include <sys/socket.h> 46213067Spjd#include <sys/sockio.h> 47213067Spjd#include <sys/errno.h> 48213067Spjd#include <sys/callout.h> 49148456Spjd#include <sys/bus.h> 50148456Spjd#include <sys/endian.h> 51148456Spjd#include <sys/kthread.h> 52148456Spjd#include <sys/taskqueue.h> 53148456Spjd#include <sys/priv.h> 54148456Spjd 55148456Spjd#include <machine/bus.h> 56148456Spjd 57148456Spjd#include <net/if.h> 58148456Spjd#include <net/if_dl.h> 59148456Spjd#include <net/if_media.h> 60148456Spjd#include <net/if_types.h> 61148456Spjd#include <net/if_arp.h> 62148456Spjd#include <net/ethernet.h> 63148456Spjd#include <net/if_llc.h> 64148456Spjd 65148456Spjd#include <net80211/ieee80211_var.h> 66148456Spjd#include <net80211/ieee80211_regdomain.h> 67148456Spjd#ifdef IEEE80211_SUPPORT_SUPERG 68148456Spjd#include <net80211/ieee80211_superg.h> 69148456Spjd#endif 70148456Spjd#ifdef IEEE80211_SUPPORT_TDMA 71148456Spjd#include <net80211/ieee80211_tdma.h> 72148456Spjd#endif 73148456Spjd 74148456Spjd#include <net/bpf.h> 75148456Spjd 76148456Spjd#ifdef INET 77148456Spjd#include <netinet/in.h> 78148456Spjd#include <netinet/if_ether.h> 79148456Spjd#endif 80148456Spjd 81148456Spjd#include <dev/ath/if_athvar.h> 82148456Spjd#include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */ 83148456Spjd#include <dev/ath/ath_hal/ah_diagcodes.h> 84148456Spjd 85148456Spjd#ifdef ATH_TX99_DIAG 86148456Spjd#include <dev/ath/ath_tx99/ath_tx99.h> 87148456Spjd#endif 88148456Spjd 89148456Spjd#include <dev/ath/if_ath_tx_ht.h> 90148456Spjd 91148456Spjd/* 92148456Spjd * Setup a 11n rate series structure 93148456Spjd * 94148456Spjd * This should be called for both legacy and MCS rates. 95148456Spjd */ 96148456Spjdstatic void 97148456Spjdath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni, 98148456Spjd HAL_11N_RATE_SERIES *series, unsigned int pktlen, uint8_t *rix, 99148456Spjd uint8_t *try) 100148456Spjd{ 101148456Spjd struct ieee80211com *ic = ni->ni_ic; 102148456Spjd struct ath_hal *ah = sc->sc_ah; 103148456Spjd HAL_BOOL shortPreamble = AH_FALSE; 104148456Spjd const HAL_RATE_TABLE *rt = sc->sc_currates; 105148456Spjd int i; 106148456Spjd uint8_t txrate; 107148456Spjd 108148456Spjd if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && 109148456Spjd (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) 110148456Spjd shortPreamble = AH_TRUE; 111148456Spjd 112148456Spjd memset(series, 0, sizeof(HAL_11N_RATE_SERIES) * 4); 113148456Spjd for (i = 0; i < 4; i++) { 114148456Spjd txrate = rt->info[rix[i]].rateCode; 115148456Spjd series[i].Tries = try[i]; 116148456Spjd series[i].ChSel = sc->sc_txchainmask; 117148456Spjd if (ic->ic_protmode == IEEE80211_PROT_RTSCTS || 118148456Spjd ic->ic_protmode == IEEE80211_PROT_CTSONLY) 119148456Spjd series[i].RateFlags |= HAL_RATESERIES_RTS_CTS; 120148456Spjd if (ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) 121148456Spjd series[i].RateFlags |= HAL_RATESERIES_2040; 122148456Spjd if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20 || 123148456Spjd ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) 124148456Spjd series[i].RateFlags |= HAL_RATESERIES_HALFGI; 125148456Spjd 126148456Spjd /* XXX should this check the short preamble value should be set for legacy rates? -adrian */ 127148456Spjd series[i].Rate = txrate; 128159307Spjd 129148456Spjd /* PktDuration doesn't include slot, ACK, RTS, etc timing - it's just the packet duration */ 130148456Spjd if (txrate & IEEE80211_RATE_MCS) { 131159307Spjd series[i].PktDuration = 132148456Spjd ath_computedur_ht(pktlen 133148456Spjd , txrate 134148456Spjd , ic->ic_rxstream 135148456Spjd , (ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) 136148456Spjd , series[i].RateFlags & HAL_RATESERIES_HALFGI); 137148456Spjd } else { 138148456Spjd series[i].PktDuration = ath_hal_computetxtime(ah, 139148456Spjd rt, pktlen, rix[i], shortPreamble); 140148456Spjd } 141148456Spjd } 142148456Spjd} 143148456Spjd 144148456Spjd#if 0 145148456Spjdstatic void 146148456Spjdath_rateseries_print(HAL_11N_RATE_SERIES *series) 147148456Spjd{ 148148456Spjd int i; 149148456Spjd for (i = 0; i < 4; i++) { 150148456Spjd printf("series %d: rate %x; tries %d; pktDuration %d; chSel %d; rateFlags %x\n", 151148456Spjd i, 152148456Spjd series[i].Rate, 153148456Spjd series[i].Tries, 154148456Spjd series[i].PktDuration, 155148456Spjd series[i].ChSel, 156148456Spjd series[i].RateFlags); 157148456Spjd } 158148456Spjd} 159148456Spjd#endif 160148456Spjd 161148456Spjd/* 162148456Spjd * Setup the 11n rate scenario and burst duration for the given TX descriptor 163148456Spjd * list. 164148456Spjd * 165148456Spjd * This isn't useful for sending beacon frames, which has different needs 166148456Spjd * wrt what's passed into the rate scenario function. 167148456Spjd */ 168148456Spjd 169148456Spjdvoid 170148456Spjdath_buf_set_rate(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, 171148456Spjd int pktlen, int flags, uint8_t ctsrate, uint8_t *rix, uint8_t *try) 172148456Spjd{ 173148456Spjd HAL_11N_RATE_SERIES series[4]; 174148456Spjd struct ath_desc *ds = bf->bf_desc; 175148456Spjd struct ath_desc *lastds = NULL; 176148456Spjd struct ath_hal *ah = sc->sc_ah; 177148456Spjd 178148456Spjd /* Setup rate scenario */ 179148456Spjd memset(&series, 0, sizeof(series)); 180148456Spjd 181148456Spjd ath_rateseries_setup(sc, ni, series, pktlen, rix, try); 182159307Spjd 183159307Spjd /* Enforce AR5416 aggregate limit - can't do RTS w/ an agg frame > 8k */ 184159307Spjd 185159307Spjd /* Enforce RTS and CTS are mutually exclusive */ 186159307Spjd 187159307Spjd /* Get a pointer to the last tx descriptor in the list */ 188159307Spjd lastds = &bf->bf_desc[bf->bf_nseg - 1]; 189159307Spjd 190159307Spjd /* Set rate scenario */ 191159307Spjd ath_hal_set11nratescenario(ah, ds, 192159307Spjd ctsrate, /* rts/cts rate */ 193159307Spjd 0, /* rts/cts duration */ 194159307Spjd series, /* 11n rate series */ 195159307Spjd 4, /* number of series */ 196159307Spjd flags); 197159307Spjd 198159307Spjd /* Setup the last descriptor in the chain */ 199213067Spjd ath_hal_setuplasttxdesc(ah, lastds, ds); 200213067Spjd 201213067Spjd /* Set burst duration */ 202213067Spjd /* This should only be done if aggregate protection is enabled */ 203213067Spjd //ath_hal_set11nburstduration(ah, ds, 8192); 204213067Spjd} 205159307Spjd