if_ath_tx_ht.c revision 233966
1218159Sadrian/*- 2218159Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. 3218159Sadrian * All rights reserved. 4218159Sadrian * 5218159Sadrian * Redistribution and use in source and binary forms, with or without 6218159Sadrian * modification, are permitted provided that the following conditions 7218159Sadrian * are met: 8218159Sadrian * 1. Redistributions of source code must retain the above copyright 9218159Sadrian * notice, this list of conditions and the following disclaimer, 10218159Sadrian * without modification. 11218159Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12218159Sadrian * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13218159Sadrian * redistribution must be conditioned upon including a substantially 14218159Sadrian * similar Disclaimer requirement for further binary redistribution. 15218159Sadrian * 16218159Sadrian * NO WARRANTY 17218159Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18218159Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19218159Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20218159Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21218159Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22218159Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23218159Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24218159Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25218159Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26218159Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27218159Sadrian * THE POSSIBILITY OF SUCH DAMAGES. 28218159Sadrian */ 29218159Sadrian 30218159Sadrian#include <sys/cdefs.h> 31218159Sadrian__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx_ht.c 233966 2012-04-07 02:01:26Z adrian $"); 32218159Sadrian 33218159Sadrian#include "opt_inet.h" 34218159Sadrian#include "opt_ath.h" 35218159Sadrian#include "opt_wlan.h" 36218159Sadrian 37218159Sadrian#include <sys/param.h> 38218159Sadrian#include <sys/systm.h> 39218159Sadrian#include <sys/sysctl.h> 40218159Sadrian#include <sys/mbuf.h> 41218159Sadrian#include <sys/malloc.h> 42218159Sadrian#include <sys/lock.h> 43218159Sadrian#include <sys/mutex.h> 44218159Sadrian#include <sys/kernel.h> 45218159Sadrian#include <sys/socket.h> 46218159Sadrian#include <sys/sockio.h> 47218159Sadrian#include <sys/errno.h> 48218159Sadrian#include <sys/callout.h> 49218159Sadrian#include <sys/bus.h> 50218159Sadrian#include <sys/endian.h> 51218159Sadrian#include <sys/kthread.h> 52218159Sadrian#include <sys/taskqueue.h> 53218159Sadrian#include <sys/priv.h> 54218159Sadrian 55218159Sadrian#include <machine/bus.h> 56218159Sadrian 57218159Sadrian#include <net/if.h> 58218159Sadrian#include <net/if_dl.h> 59218159Sadrian#include <net/if_media.h> 60218159Sadrian#include <net/if_types.h> 61218159Sadrian#include <net/if_arp.h> 62218159Sadrian#include <net/ethernet.h> 63218159Sadrian#include <net/if_llc.h> 64218159Sadrian 65218159Sadrian#include <net80211/ieee80211_var.h> 66218159Sadrian#include <net80211/ieee80211_regdomain.h> 67218159Sadrian#ifdef IEEE80211_SUPPORT_SUPERG 68218159Sadrian#include <net80211/ieee80211_superg.h> 69218159Sadrian#endif 70218159Sadrian#ifdef IEEE80211_SUPPORT_TDMA 71218159Sadrian#include <net80211/ieee80211_tdma.h> 72218159Sadrian#endif 73218159Sadrian 74218159Sadrian#include <net/bpf.h> 75218159Sadrian 76218159Sadrian#ifdef INET 77218159Sadrian#include <netinet/in.h> 78218159Sadrian#include <netinet/if_ether.h> 79218159Sadrian#endif 80218159Sadrian 81218159Sadrian#include <dev/ath/if_athvar.h> 82218159Sadrian#include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */ 83218159Sadrian#include <dev/ath/ath_hal/ah_diagcodes.h> 84218159Sadrian 85218159Sadrian#ifdef ATH_TX99_DIAG 86218159Sadrian#include <dev/ath/ath_tx99/ath_tx99.h> 87218159Sadrian#endif 88218159Sadrian 89227364Sadrian#include <dev/ath/if_ath_tx.h> /* XXX for some support functions */ 90218159Sadrian#include <dev/ath/if_ath_tx_ht.h> 91227364Sadrian#include <dev/ath/if_athrate.h> 92227364Sadrian#include <dev/ath/if_ath_debug.h> 93218159Sadrian 94218159Sadrian/* 95227364Sadrian * XXX net80211? 96227364Sadrian */ 97227364Sadrian#define IEEE80211_AMPDU_SUBFRAME_DEFAULT 32 98227364Sadrian 99227364Sadrian#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ 100227364Sadrian#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ 101227364Sadrian#define ATH_AGGR_ENCRYPTDELIM 10 /* number of delimiters for encryption padding */ 102227364Sadrian 103227364Sadrian/* 104227364Sadrian * returns delimiter padding required given the packet length 105227364Sadrian */ 106227364Sadrian#define ATH_AGGR_GET_NDELIM(_len) \ 107227364Sadrian (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \ 108227364Sadrian (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2) 109227364Sadrian 110227364Sadrian#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) 111227364Sadrian 112227364Sadrianint ath_max_4ms_framelen[4][32] = { 113227364Sadrian [MCS_HT20] = { 114227364Sadrian 3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172, 115227364Sadrian 6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280, 116227364Sadrian 9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532, 117227364Sadrian 12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532, 118227364Sadrian }, 119227364Sadrian [MCS_HT20_SGI] = { 120227364Sadrian 3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744, 121227364Sadrian 7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532, 122227364Sadrian 10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532, 123227364Sadrian 14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532, 124227364Sadrian }, 125227364Sadrian [MCS_HT40] = { 126227364Sadrian 6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532, 127227364Sadrian 13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532, 128227364Sadrian 20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532, 129227364Sadrian 26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532, 130227364Sadrian }, 131227364Sadrian [MCS_HT40_SGI] = { 132227364Sadrian 7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532, 133227364Sadrian 14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532, 134227364Sadrian 22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532, 135227364Sadrian 29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532, 136227364Sadrian } 137227364Sadrian}; 138227364Sadrian 139227364Sadrian/* 140227364Sadrian * XXX should be in net80211 141227364Sadrian */ 142227364Sadrianstatic int ieee80211_mpdudensity_map[] = { 143227364Sadrian 0, /* IEEE80211_HTCAP_MPDUDENSITY_NA */ 144227364Sadrian 25, /* IEEE80211_HTCAP_MPDUDENSITY_025 */ 145227364Sadrian 50, /* IEEE80211_HTCAP_MPDUDENSITY_05 */ 146227364Sadrian 100, /* IEEE80211_HTCAP_MPDUDENSITY_1 */ 147227364Sadrian 200, /* IEEE80211_HTCAP_MPDUDENSITY_2 */ 148227364Sadrian 400, /* IEEE80211_HTCAP_MPDUDENSITY_4 */ 149227364Sadrian 800, /* IEEE80211_HTCAP_MPDUDENSITY_8 */ 150227364Sadrian 1600, /* IEEE80211_HTCAP_MPDUDENSITY_16 */ 151227364Sadrian}; 152227364Sadrian 153227364Sadrian/* 154227364Sadrian * XXX should be in the HAL/net80211 ? 155227364Sadrian */ 156227364Sadrian#define BITS_PER_BYTE 8 157227364Sadrian#define OFDM_PLCP_BITS 22 158227364Sadrian#define HT_RC_2_MCS(_rc) ((_rc) & 0x7f) 159227364Sadrian#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 160227364Sadrian#define L_STF 8 161227364Sadrian#define L_LTF 8 162227364Sadrian#define L_SIG 4 163227364Sadrian#define HT_SIG 8 164227364Sadrian#define HT_STF 4 165227364Sadrian#define HT_LTF(_ns) (4 * (_ns)) 166227364Sadrian#define SYMBOL_TIME(_ns) ((_ns) << 2) // ns * 4 us 167227364Sadrian#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5) // ns * 3.6 us 168227364Sadrian#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2) 169227364Sadrian#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18) 170227364Sadrian#define IS_HT_RATE(_rate) ((_rate) & 0x80) 171227364Sadrian 172227364Sadrianconst uint32_t bits_per_symbol[][2] = { 173227364Sadrian /* 20MHz 40MHz */ 174227364Sadrian { 26, 54 }, // 0: BPSK 175227364Sadrian { 52, 108 }, // 1: QPSK 1/2 176227364Sadrian { 78, 162 }, // 2: QPSK 3/4 177227364Sadrian { 104, 216 }, // 3: 16-QAM 1/2 178227364Sadrian { 156, 324 }, // 4: 16-QAM 3/4 179227364Sadrian { 208, 432 }, // 5: 64-QAM 2/3 180227364Sadrian { 234, 486 }, // 6: 64-QAM 3/4 181227364Sadrian { 260, 540 }, // 7: 64-QAM 5/6 182227364Sadrian { 52, 108 }, // 8: BPSK 183227364Sadrian { 104, 216 }, // 9: QPSK 1/2 184227364Sadrian { 156, 324 }, // 10: QPSK 3/4 185227364Sadrian { 208, 432 }, // 11: 16-QAM 1/2 186227364Sadrian { 312, 648 }, // 12: 16-QAM 3/4 187227364Sadrian { 416, 864 }, // 13: 64-QAM 2/3 188227364Sadrian { 468, 972 }, // 14: 64-QAM 3/4 189227364Sadrian { 520, 1080 }, // 15: 64-QAM 5/6 190227364Sadrian { 78, 162 }, // 16: BPSK 191227364Sadrian { 156, 324 }, // 17: QPSK 1/2 192227364Sadrian { 234, 486 }, // 18: QPSK 3/4 193227364Sadrian { 312, 648 }, // 19: 16-QAM 1/2 194227364Sadrian { 468, 972 }, // 20: 16-QAM 3/4 195227364Sadrian { 624, 1296 }, // 21: 64-QAM 2/3 196227364Sadrian { 702, 1458 }, // 22: 64-QAM 3/4 197227364Sadrian { 780, 1620 }, // 23: 64-QAM 5/6 198227364Sadrian { 104, 216 }, // 24: BPSK 199227364Sadrian { 208, 432 }, // 25: QPSK 1/2 200227364Sadrian { 312, 648 }, // 26: QPSK 3/4 201227364Sadrian { 416, 864 }, // 27: 16-QAM 1/2 202227364Sadrian { 624, 1296 }, // 28: 16-QAM 3/4 203227364Sadrian { 832, 1728 }, // 29: 64-QAM 2/3 204227364Sadrian { 936, 1944 }, // 30: 64-QAM 3/4 205227364Sadrian { 1040, 2160 }, // 31: 64-QAM 5/6 206227364Sadrian}; 207227364Sadrian 208227364Sadrian/* 209227364Sadrian * Fill in the rate array information based on the current 210227364Sadrian * node configuration and the choices made by the rate 211227364Sadrian * selection code and ath_buf setup code. 212227364Sadrian * 213227364Sadrian * Later on, this may end up also being made by the 214227364Sadrian * rate control code, but for now it can live here. 215227364Sadrian * 216227364Sadrian * This needs to be called just before the packet is 217227364Sadrian * queued to the software queue or hardware queue, 218227364Sadrian * so all of the needed fields in bf_state are setup. 219227364Sadrian */ 220227364Sadrianvoid 221227364Sadrianath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf) 222227364Sadrian{ 223227364Sadrian struct ieee80211_node *ni = bf->bf_node; 224227364Sadrian struct ieee80211com *ic = ni->ni_ic; 225227364Sadrian const HAL_RATE_TABLE *rt = sc->sc_currates; 226227364Sadrian struct ath_rc_series *rc = bf->bf_state.bfs_rc; 227227364Sadrian uint8_t rate; 228227364Sadrian int i; 229227364Sadrian 230227364Sadrian for (i = 0; i < ATH_RC_NUM; i++) { 231227364Sadrian rc[i].flags = 0; 232227364Sadrian if (rc[i].tries == 0) 233227364Sadrian continue; 234227364Sadrian 235227364Sadrian rate = rt->info[rc[i].rix].rateCode; 236227364Sadrian 237227364Sadrian /* 238227364Sadrian * XXX only do this for legacy rates? 239227364Sadrian */ 240227364Sadrian if (bf->bf_state.bfs_shpream) 241227364Sadrian rate |= rt->info[rc[i].rix].shortPreamble; 242227364Sadrian 243227364Sadrian /* 244227364Sadrian * Save this, used by the TX and completion code 245227364Sadrian */ 246227364Sadrian rc[i].ratecode = rate; 247227364Sadrian 248233966Sadrian if (bf->bf_state.bfs_txflags & 249227364Sadrian (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) 250227364Sadrian rc[i].flags |= ATH_RC_RTSCTS_FLAG; 251227364Sadrian 252227364Sadrian /* Only enable shortgi, 2040, dual-stream if HT is set */ 253227364Sadrian if (IS_HT_RATE(rate)) { 254227364Sadrian rc[i].flags |= ATH_RC_HT_FLAG; 255227364Sadrian 256227364Sadrian if (ni->ni_chw == 40) 257227364Sadrian rc[i].flags |= ATH_RC_CW40_FLAG; 258227364Sadrian 259227364Sadrian if (ni->ni_chw == 40 && 260227364Sadrian ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40 && 261227364Sadrian ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) 262227364Sadrian rc[i].flags |= ATH_RC_SGI_FLAG; 263227364Sadrian 264227364Sadrian if (ni->ni_chw == 20 && 265227364Sadrian ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20 && 266227364Sadrian ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) 267227364Sadrian rc[i].flags |= ATH_RC_SGI_FLAG; 268227364Sadrian 269227364Sadrian /* XXX dual stream? and 3-stream? */ 270227364Sadrian } 271227364Sadrian 272227364Sadrian /* 273227364Sadrian * Calculate the maximum 4ms frame length based 274227364Sadrian * on the MCS rate, SGI and channel width flags. 275227364Sadrian */ 276227364Sadrian if ((rc[i].flags & ATH_RC_HT_FLAG) && 277227364Sadrian (HT_RC_2_MCS(rate) < 32)) { 278227364Sadrian int j; 279227364Sadrian if (rc[i].flags & ATH_RC_CW40_FLAG) { 280227364Sadrian if (rc[i].flags & ATH_RC_SGI_FLAG) 281227364Sadrian j = MCS_HT40_SGI; 282227364Sadrian else 283227364Sadrian j = MCS_HT40; 284227364Sadrian } else { 285227364Sadrian if (rc[i].flags & ATH_RC_SGI_FLAG) 286227364Sadrian j = MCS_HT20_SGI; 287227364Sadrian else 288227364Sadrian j = MCS_HT20; 289227364Sadrian } 290227364Sadrian rc[i].max4msframelen = 291227364Sadrian ath_max_4ms_framelen[j][HT_RC_2_MCS(rate)]; 292227364Sadrian } else 293227364Sadrian rc[i].max4msframelen = 0; 294227364Sadrian DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, 295227364Sadrian "%s: i=%d, rate=0x%x, flags=0x%x, max4ms=%d\n", 296227364Sadrian __func__, i, rate, rc[i].flags, rc[i].max4msframelen); 297227364Sadrian } 298227364Sadrian} 299227364Sadrian 300227364Sadrian/* 301227364Sadrian * Return the number of delimiters to be added to 302227364Sadrian * meet the minimum required mpdudensity. 303227364Sadrian * 304227364Sadrian * Caller should make sure that the rate is HT. 305227364Sadrian * 306227364Sadrian * TODO: is this delimiter calculation supposed to be the 307227364Sadrian * total frame length, the hdr length, the data length (including 308227364Sadrian * delimiters, padding, CRC, etc) or ? 309227364Sadrian * 310227364Sadrian * TODO: this should ensure that the rate control information 311227364Sadrian * HAS been setup for the first rate. 312227364Sadrian * 313227364Sadrian * TODO: ensure this is only called for MCS rates. 314227364Sadrian * 315227364Sadrian * TODO: enforce MCS < 31 316227364Sadrian */ 317227364Sadrianstatic int 318227364Sadrianath_compute_num_delims(struct ath_softc *sc, struct ath_buf *first_bf, 319227364Sadrian uint16_t pktlen) 320227364Sadrian{ 321227364Sadrian const HAL_RATE_TABLE *rt = sc->sc_currates; 322227364Sadrian struct ieee80211_node *ni = first_bf->bf_node; 323227364Sadrian struct ieee80211vap *vap = ni->ni_vap; 324227364Sadrian int ndelim, mindelim = 0; 325227364Sadrian int mpdudensity; /* in 1/100'th of a microsecond */ 326227364Sadrian uint8_t rc, rix, flags; 327227364Sadrian int width, half_gi; 328227364Sadrian uint32_t nsymbits, nsymbols; 329227364Sadrian uint16_t minlen; 330227364Sadrian 331227364Sadrian /* 332227364Sadrian * vap->iv_ampdu_density is a value, rather than the actual 333227364Sadrian * density. 334227364Sadrian */ 335227364Sadrian if (vap->iv_ampdu_density > IEEE80211_HTCAP_MPDUDENSITY_16) 336227364Sadrian mpdudensity = 1600; /* maximum density */ 337227364Sadrian else 338227364Sadrian mpdudensity = ieee80211_mpdudensity_map[vap->iv_ampdu_density]; 339227364Sadrian 340227364Sadrian /* Select standard number of delimiters based on frame length */ 341227364Sadrian ndelim = ATH_AGGR_GET_NDELIM(pktlen); 342227364Sadrian 343227364Sadrian /* 344227364Sadrian * If encryption is enabled, add extra delimiters to let the 345227364Sadrian * crypto hardware catch up. This could be tuned per-MAC and 346227364Sadrian * per-rate, but for now we'll simply assume encryption is 347227364Sadrian * always enabled. 348227364Sadrian */ 349227364Sadrian ndelim += ATH_AGGR_ENCRYPTDELIM; 350227364Sadrian 351227364Sadrian DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, 352227364Sadrian "%s: pktlen=%d, ndelim=%d, mpdudensity=%d\n", 353227364Sadrian __func__, pktlen, ndelim, mpdudensity); 354227364Sadrian 355227364Sadrian /* 356227364Sadrian * If the MPDU density is 0, we can return here. 357227364Sadrian * Otherwise, we need to convert the desired mpdudensity 358227364Sadrian * into a byte length, based on the rate in the subframe. 359227364Sadrian */ 360227364Sadrian if (mpdudensity == 0) 361227364Sadrian return ndelim; 362227364Sadrian 363227364Sadrian /* 364227364Sadrian * Convert desired mpdu density from microeconds to bytes based 365227364Sadrian * on highest rate in rate series (i.e. first rate) to determine 366227364Sadrian * required minimum length for subframe. Take into account 367227364Sadrian * whether high rate is 20 or 40Mhz and half or full GI. 368227364Sadrian */ 369227364Sadrian rix = first_bf->bf_state.bfs_rc[0].rix; 370227364Sadrian rc = rt->info[rix].rateCode; 371227364Sadrian flags = first_bf->bf_state.bfs_rc[0].flags; 372227364Sadrian width = !! (flags & ATH_RC_CW40_FLAG); 373227364Sadrian half_gi = !! (flags & ATH_RC_SGI_FLAG); 374227364Sadrian 375227364Sadrian /* 376227364Sadrian * mpdudensity is in 1/100th of a usec, so divide by 100 377227364Sadrian */ 378227364Sadrian if (half_gi) 379227364Sadrian nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity); 380227364Sadrian else 381227364Sadrian nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity); 382227364Sadrian nsymbols /= 100; 383227364Sadrian 384227364Sadrian if (nsymbols == 0) 385227364Sadrian nsymbols = 1; 386227364Sadrian 387227364Sadrian nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; 388227364Sadrian minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; 389227364Sadrian 390227364Sadrian /* 391227364Sadrian * Min length is the minimum frame length for the 392227364Sadrian * required MPDU density. 393227364Sadrian */ 394227364Sadrian if (pktlen < minlen) { 395227364Sadrian mindelim = (minlen - pktlen) / ATH_AGGR_DELIM_SZ; 396227364Sadrian ndelim = MAX(mindelim, ndelim); 397227364Sadrian } 398227364Sadrian 399227364Sadrian DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, 400227364Sadrian "%s: pktlen=%d, minlen=%d, rix=%x, rc=%x, width=%d, hgi=%d, ndelim=%d\n", 401227364Sadrian __func__, pktlen, minlen, rix, rc, width, half_gi, ndelim); 402227364Sadrian 403227364Sadrian return ndelim; 404227364Sadrian} 405227364Sadrian 406227364Sadrian/* 407227364Sadrian * Fetch the aggregation limit. 408227364Sadrian * 409227364Sadrian * It's the lowest of the four rate series 4ms frame length. 410227364Sadrian */ 411227364Sadrianstatic int 412227364Sadrianath_get_aggr_limit(struct ath_softc *sc, struct ath_buf *bf) 413227364Sadrian{ 414227364Sadrian int amin = 65530; 415227364Sadrian int i; 416227364Sadrian 417227364Sadrian for (i = 0; i < 4; i++) { 418227364Sadrian if (bf->bf_state.bfs_rc[i].tries == 0) 419227364Sadrian continue; 420227364Sadrian amin = MIN(amin, bf->bf_state.bfs_rc[i].max4msframelen); 421227364Sadrian } 422227364Sadrian 423227364Sadrian DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: max frame len= %d\n", 424227364Sadrian __func__, amin); 425227364Sadrian 426227364Sadrian return amin; 427227364Sadrian} 428227364Sadrian 429227364Sadrian/* 430218159Sadrian * Setup a 11n rate series structure 431218159Sadrian * 432218159Sadrian * This should be called for both legacy and MCS rates. 433227364Sadrian * 434227364Sadrian * It, along with ath_buf_set_rate, must be called -after- a burst 435227364Sadrian * or aggregate is setup. 436218159Sadrian */ 437218159Sadrianstatic void 438218159Sadrianath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni, 439227364Sadrian struct ath_buf *bf, HAL_11N_RATE_SERIES *series) 440218159Sadrian{ 441219588Sadrian#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 442218159Sadrian struct ieee80211com *ic = ni->ni_ic; 443218159Sadrian struct ath_hal *ah = sc->sc_ah; 444218159Sadrian HAL_BOOL shortPreamble = AH_FALSE; 445218159Sadrian const HAL_RATE_TABLE *rt = sc->sc_currates; 446218159Sadrian int i; 447227364Sadrian int pktlen; 448233966Sadrian int flags = bf->bf_state.bfs_txflags; 449227364Sadrian struct ath_rc_series *rc = bf->bf_state.bfs_rc; 450218159Sadrian 451218159Sadrian if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && 452218159Sadrian (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) 453218159Sadrian shortPreamble = AH_TRUE; 454218159Sadrian 455227364Sadrian /* 456227364Sadrian * If this is the first frame in an aggregate series, 457227364Sadrian * use the aggregate length. 458227364Sadrian */ 459227364Sadrian if (bf->bf_state.bfs_aggr) 460227364Sadrian pktlen = bf->bf_state.bfs_al; 461227364Sadrian else 462227364Sadrian pktlen = bf->bf_state.bfs_pktlen; 463227364Sadrian 464227364Sadrian /* 465227364Sadrian * XXX TODO: modify this routine to use the bfs_rc[x].flags 466227364Sadrian * XXX fields. 467227364Sadrian */ 468218159Sadrian memset(series, 0, sizeof(HAL_11N_RATE_SERIES) * 4); 469218159Sadrian for (i = 0; i < 4; i++) { 470218931Sadrian /* Only set flags for actual TX attempts */ 471227364Sadrian if (rc[i].tries == 0) 472218931Sadrian continue; 473218931Sadrian 474227364Sadrian series[i].Tries = rc[i].tries; 475218931Sadrian 476218931Sadrian /* 477218931Sadrian * XXX this isn't strictly correct - sc_txchainmask 478218931Sadrian * XXX isn't the currently active chainmask; 479218931Sadrian * XXX it's the interface chainmask at startup. 480218931Sadrian * XXX It's overridden in the HAL rate scenario function 481218931Sadrian * XXX for now. 482218931Sadrian */ 483218159Sadrian series[i].ChSel = sc->sc_txchainmask; 484218931Sadrian 485218935Sadrian if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) 486218159Sadrian series[i].RateFlags |= HAL_RATESERIES_RTS_CTS; 487218931Sadrian 488219985Sadrian /* 489219985Sadrian * Transmit 40MHz frames only if the node has negotiated 490219985Sadrian * it rather than whether the node is capable of it or not. 491219985Sadrian * It's subtly different in the hostap case. 492219985Sadrian */ 493219985Sadrian if (ni->ni_chw == 40) 494219985Sadrian series[i].RateFlags |= HAL_RATESERIES_2040; 495222498Sadrian 496218779Sadrian /* 497222498Sadrian * Set short-GI only if the node has advertised it 498222498Sadrian * the channel width is suitable, and we support it. 499222498Sadrian * We don't currently have a "negotiated" set of bits - 500222498Sadrian * ni_htcap is what the remote end sends, not what this 501222498Sadrian * node is capable of. 502218779Sadrian */ 503222498Sadrian if (ni->ni_chw == 40 && 504222498Sadrian ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40 && 505222498Sadrian ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) 506218159Sadrian series[i].RateFlags |= HAL_RATESERIES_HALFGI; 507218159Sadrian 508222498Sadrian if (ni->ni_chw == 20 && 509222498Sadrian ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20 && 510222498Sadrian ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) 511222498Sadrian series[i].RateFlags |= HAL_RATESERIES_HALFGI; 512222498Sadrian 513227364Sadrian series[i].Rate = rt->info[rc[i].rix].rateCode; 514218159Sadrian 515218159Sadrian /* PktDuration doesn't include slot, ACK, RTS, etc timing - it's just the packet duration */ 516218907Sadrian if (series[i].Rate & IEEE80211_RATE_MCS) { 517218159Sadrian series[i].PktDuration = 518218159Sadrian ath_computedur_ht(pktlen 519218907Sadrian , series[i].Rate 520219588Sadrian , HT_RC_2_STREAMS(series[i].Rate) 521219588Sadrian , series[i].RateFlags & HAL_RATESERIES_2040 522218566Sadrian , series[i].RateFlags & HAL_RATESERIES_HALFGI); 523218159Sadrian } else { 524219870Sadrian if (shortPreamble) 525227364Sadrian series[i].Rate |= 526227364Sadrian rt->info[rc[i].rix].shortPreamble; 527218159Sadrian series[i].PktDuration = ath_hal_computetxtime(ah, 528227364Sadrian rt, pktlen, rc[i].rix, shortPreamble); 529218159Sadrian } 530218159Sadrian } 531219588Sadrian#undef HT_RC_2_STREAMS 532218159Sadrian} 533218159Sadrian 534218159Sadrian#if 0 535218159Sadrianstatic void 536218159Sadrianath_rateseries_print(HAL_11N_RATE_SERIES *series) 537218159Sadrian{ 538218159Sadrian int i; 539218159Sadrian for (i = 0; i < 4; i++) { 540218159Sadrian printf("series %d: rate %x; tries %d; pktDuration %d; chSel %d; rateFlags %x\n", 541218159Sadrian i, 542218159Sadrian series[i].Rate, 543218159Sadrian series[i].Tries, 544218159Sadrian series[i].PktDuration, 545218159Sadrian series[i].ChSel, 546218159Sadrian series[i].RateFlags); 547218159Sadrian } 548218159Sadrian} 549218159Sadrian#endif 550218159Sadrian 551218159Sadrian/* 552218159Sadrian * Setup the 11n rate scenario and burst duration for the given TX descriptor 553218159Sadrian * list. 554218159Sadrian * 555218159Sadrian * This isn't useful for sending beacon frames, which has different needs 556218159Sadrian * wrt what's passed into the rate scenario function. 557218159Sadrian */ 558218159Sadrian 559218159Sadrianvoid 560227364Sadrianath_buf_set_rate(struct ath_softc *sc, struct ieee80211_node *ni, 561227364Sadrian struct ath_buf *bf) 562218159Sadrian{ 563218159Sadrian HAL_11N_RATE_SERIES series[4]; 564218159Sadrian struct ath_desc *ds = bf->bf_desc; 565218159Sadrian struct ath_desc *lastds = NULL; 566218159Sadrian struct ath_hal *ah = sc->sc_ah; 567227364Sadrian int is_pspoll = (bf->bf_state.bfs_atype == HAL_PKT_TYPE_PSPOLL); 568227364Sadrian int ctsrate = bf->bf_state.bfs_ctsrate; 569233966Sadrian int flags = bf->bf_state.bfs_txflags; 570218159Sadrian 571218159Sadrian /* Setup rate scenario */ 572218159Sadrian memset(&series, 0, sizeof(series)); 573218159Sadrian 574227364Sadrian ath_rateseries_setup(sc, ni, bf, series); 575218159Sadrian 576218159Sadrian /* Enforce AR5416 aggregate limit - can't do RTS w/ an agg frame > 8k */ 577218159Sadrian 578218159Sadrian /* Enforce RTS and CTS are mutually exclusive */ 579218159Sadrian 580218159Sadrian /* Get a pointer to the last tx descriptor in the list */ 581227364Sadrian lastds = bf->bf_lastds; 582218159Sadrian 583218935Sadrian#if 0 584218935Sadrian printf("pktlen: %d; flags 0x%x\n", pktlen, flags); 585218935Sadrian ath_rateseries_print(series); 586218935Sadrian#endif 587218935Sadrian 588218159Sadrian /* Set rate scenario */ 589218159Sadrian ath_hal_set11nratescenario(ah, ds, 590218593Sadrian !is_pspoll, /* whether to override the duration or not */ 591218593Sadrian /* don't allow hardware to override the duration on ps-poll packets */ 592218159Sadrian ctsrate, /* rts/cts rate */ 593218159Sadrian series, /* 11n rate series */ 594218159Sadrian 4, /* number of series */ 595218159Sadrian flags); 596218159Sadrian 597218159Sadrian /* Setup the last descriptor in the chain */ 598218159Sadrian ath_hal_setuplasttxdesc(ah, lastds, ds); 599218159Sadrian 600218159Sadrian /* Set burst duration */ 601227364Sadrian /* 602227364Sadrian * This is only required when doing 11n burst, not aggregation 603227364Sadrian * ie, if there's a second frame in a RIFS or A-MPDU burst 604227364Sadrian * w/ >1 A-MPDU frame bursting back to back. 605227364Sadrian * Normal A-MPDU doesn't do bursting -between- aggregates. 606227364Sadrian * 607227364Sadrian * .. and it's highly likely this won't ever be implemented 608227364Sadrian */ 609218159Sadrian //ath_hal_set11nburstduration(ah, ds, 8192); 610218159Sadrian} 611227364Sadrian 612227364Sadrian/* 613227364Sadrian * Form an aggregate packet list. 614227364Sadrian * 615227364Sadrian * This function enforces the aggregate restrictions/requirements. 616227364Sadrian * 617227364Sadrian * These are: 618227364Sadrian * 619227364Sadrian * + The aggregate size maximum (64k for AR9160 and later, 8K for 620227364Sadrian * AR5416 when doing RTS frame protection.) 621227364Sadrian * + Maximum number of sub-frames for an aggregate 622227364Sadrian * + The aggregate delimiter size, giving MACs time to do whatever is 623227364Sadrian * needed before each frame 624227364Sadrian * + Enforce the BAW limit 625227364Sadrian * 626227364Sadrian * Each descriptor queued should have the DMA setup. 627227364Sadrian * The rate series, descriptor setup, linking, etc is all done 628227364Sadrian * externally. This routine simply chains them together. 629227364Sadrian * ath_tx_setds_11n() will take care of configuring the per- 630227364Sadrian * descriptor setup, and ath_buf_set_rate() will configure the 631227364Sadrian * rate control. 632227364Sadrian * 633227364Sadrian * Note that the TID lock is only grabbed when dequeuing packets from 634227364Sadrian * the TID queue. If some code in another thread adds to the head of this 635227364Sadrian * list, very strange behaviour will occur. Since retransmission is the 636227364Sadrian * only reason this will occur, and this routine is designed to be called 637227364Sadrian * from within the scheduler task, it won't ever clash with the completion 638227364Sadrian * task. 639227364Sadrian * 640227364Sadrian * So if you want to call this from an upper layer context (eg, to direct- 641227364Sadrian * dispatch aggregate frames to the hardware), please keep this in mind. 642227364Sadrian */ 643227364SadrianATH_AGGR_STATUS 644227364Sadrianath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, 645227364Sadrian ath_bufhead *bf_q) 646227364Sadrian{ 647233227Sadrian struct ieee80211_node *ni = &an->an_node; 648227364Sadrian struct ath_buf *bf, *bf_first = NULL, *bf_prev = NULL; 649227364Sadrian int nframes = 0; 650227364Sadrian uint16_t aggr_limit = 0, al = 0, bpad = 0, al_delta, h_baw; 651227364Sadrian struct ieee80211_tx_ampdu *tap; 652227364Sadrian int status = ATH_AGGR_DONE; 653227364Sadrian int prev_frames = 0; /* XXX for AR5416 burst, not done here */ 654227364Sadrian int prev_al = 0; /* XXX also for AR5416 burst */ 655227364Sadrian 656227364Sadrian ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); 657227364Sadrian 658227364Sadrian tap = ath_tx_get_tx_tid(an, tid->tid); 659227364Sadrian if (tap == NULL) { 660227364Sadrian status = ATH_AGGR_ERROR; 661227364Sadrian goto finish; 662227364Sadrian } 663227364Sadrian 664227364Sadrian h_baw = tap->txa_wnd / 2; 665227364Sadrian 666227364Sadrian for (;;) { 667227364Sadrian bf = TAILQ_FIRST(&tid->axq_q); 668227364Sadrian if (bf_first == NULL) 669227364Sadrian bf_first = bf; 670227364Sadrian if (bf == NULL) { 671227364Sadrian status = ATH_AGGR_DONE; 672227364Sadrian break; 673227364Sadrian } else { 674227364Sadrian /* 675227364Sadrian * It's the first frame; 676227364Sadrian * set the aggregation limit based on the 677227364Sadrian * rate control decision that has been made. 678227364Sadrian */ 679227364Sadrian aggr_limit = ath_get_aggr_limit(sc, bf_first); 680227364Sadrian } 681227364Sadrian 682227364Sadrian /* Set this early just so things don't get confused */ 683227364Sadrian bf->bf_next = NULL; 684227364Sadrian 685227364Sadrian /* 686227364Sadrian * Don't unlock the tid lock until we're sure we are going 687227364Sadrian * to queue this frame. 688227364Sadrian */ 689227364Sadrian 690227364Sadrian /* 691227364Sadrian * If the frame doesn't have a sequence number that we're 692227364Sadrian * tracking in the BAW (eg NULL QOS data frame), we can't 693227364Sadrian * aggregate it. Stop the aggregation process; the sender 694227364Sadrian * can then TX what's in the list thus far and then 695227364Sadrian * TX the frame individually. 696227364Sadrian */ 697227364Sadrian if (! bf->bf_state.bfs_dobaw) { 698227364Sadrian status = ATH_AGGR_NONAGGR; 699227364Sadrian break; 700227364Sadrian } 701227364Sadrian 702227364Sadrian /* 703227364Sadrian * If any of the rates are non-HT, this packet 704227364Sadrian * can't be aggregated. 705227364Sadrian * XXX TODO: add a bf_state flag which gets marked 706227364Sadrian * if any active rate is non-HT. 707227364Sadrian */ 708227364Sadrian 709227364Sadrian /* 710227364Sadrian * XXX TODO: AR5416 has an 8K aggregation size limit 711227364Sadrian * when RTS is enabled, and RTS is required for dual-stream 712227364Sadrian * rates. 713227364Sadrian * 714227364Sadrian * For now, limit all aggregates for the AR5416 to be 8K. 715227364Sadrian */ 716227364Sadrian 717227364Sadrian /* 718227364Sadrian * do not exceed aggregation limit 719227364Sadrian */ 720227364Sadrian al_delta = ATH_AGGR_DELIM_SZ + bf->bf_state.bfs_pktlen; 721227364Sadrian if (nframes && 722227364Sadrian (aggr_limit < (al + bpad + al_delta + prev_al))) { 723227364Sadrian status = ATH_AGGR_LIMITED; 724227364Sadrian break; 725227364Sadrian } 726227364Sadrian 727227364Sadrian /* 728227364Sadrian * Do not exceed subframe limit. 729227364Sadrian */ 730227364Sadrian if ((nframes + prev_frames) >= MIN((h_baw), 731227364Sadrian IEEE80211_AMPDU_SUBFRAME_DEFAULT)) { 732227364Sadrian status = ATH_AGGR_LIMITED; 733227364Sadrian break; 734227364Sadrian } 735227364Sadrian 736227364Sadrian /* 737233227Sadrian * TODO: If it's _before_ the BAW left edge, complain very loudly. 738233227Sadrian * This means something (else) has slid the left edge along 739233227Sadrian * before we got a chance to be TXed. 740233227Sadrian */ 741233227Sadrian 742233227Sadrian /* 743233227Sadrian * Check if we have space in the BAW for this frame before 744233227Sadrian * we add it. 745233227Sadrian * 746233227Sadrian * see ath_tx_xmit_aggr() for more info. 747233227Sadrian */ 748233227Sadrian if (bf->bf_state.bfs_dobaw) { 749233514Sadrian ieee80211_seq seqno; 750233514Sadrian 751233514Sadrian /* 752233514Sadrian * If the sequence number is allocated, use it. 753233514Sadrian * Otherwise, use the sequence number we WOULD 754233514Sadrian * allocate. 755233514Sadrian */ 756233514Sadrian if (bf->bf_state.bfs_seqno_assigned) 757233514Sadrian seqno = SEQNO(bf->bf_state.bfs_seqno); 758233514Sadrian else 759233514Sadrian seqno = ni->ni_txseqs[bf->bf_state.bfs_tid]; 760233514Sadrian 761233514Sadrian /* 762233514Sadrian * Check whether either the currently allocated 763233514Sadrian * sequence number _OR_ the to-be allocated 764233514Sadrian * sequence number is inside the BAW. 765233514Sadrian */ 766233227Sadrian if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd, 767233514Sadrian seqno)) { 768233227Sadrian status = ATH_AGGR_BAW_CLOSED; 769233227Sadrian break; 770233227Sadrian } 771233514Sadrian 772233227Sadrian /* XXX check for bfs_need_seqno? */ 773233227Sadrian if (! bf->bf_state.bfs_seqno_assigned) { 774233514Sadrian int seqno; 775233227Sadrian seqno = ath_tx_tid_seqno_assign(sc, ni, bf, bf->bf_m); 776233227Sadrian if (seqno < 0) { 777233227Sadrian device_printf(sc->sc_dev, 778233227Sadrian "%s: bf=%p, huh, seqno=-1?\n", 779233227Sadrian __func__, 780233227Sadrian bf); 781233227Sadrian /* XXX what can we even do here? */ 782233227Sadrian } 783233227Sadrian /* Flush seqno update to RAM */ 784233227Sadrian /* 785233227Sadrian * XXX This is required because the dmasetup 786233227Sadrian * XXX is done early rather than at dispatch 787233227Sadrian * XXX time. Ew, we should fix this! 788233227Sadrian */ 789233227Sadrian bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 790233227Sadrian BUS_DMASYNC_PREWRITE); 791233227Sadrian } 792233227Sadrian } 793233227Sadrian 794233227Sadrian /* 795233227Sadrian * If the packet has a sequence number, do not 796233227Sadrian * step outside of the block-ack window. 797233227Sadrian */ 798233227Sadrian if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd, 799233227Sadrian SEQNO(bf->bf_state.bfs_seqno))) { 800233227Sadrian device_printf(sc->sc_dev, 801233227Sadrian "%s: bf=%p, seqno=%d, outside?!\n", 802233227Sadrian __func__, bf, SEQNO(bf->bf_state.bfs_seqno)); 803233227Sadrian status = ATH_AGGR_BAW_CLOSED; 804233227Sadrian break; 805233227Sadrian } 806233227Sadrian 807233227Sadrian /* 808227364Sadrian * this packet is part of an aggregate. 809227364Sadrian */ 810227364Sadrian ATH_TXQ_REMOVE(tid, bf, bf_list); 811227364Sadrian 812227364Sadrian /* The TID lock is required for the BAW update */ 813227364Sadrian ath_tx_addto_baw(sc, an, tid, bf); 814227364Sadrian bf->bf_state.bfs_addedbaw = 1; 815227364Sadrian 816227364Sadrian /* 817227364Sadrian * XXX TODO: If any frame in the aggregate requires RTS/CTS, 818227364Sadrian * set the first frame. 819227364Sadrian */ 820227364Sadrian 821227364Sadrian /* 822227364Sadrian * XXX enforce ACK for aggregate frames (this needs to be 823227364Sadrian * XXX handled more gracefully? 824227364Sadrian */ 825233966Sadrian if (bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) { 826227364Sadrian device_printf(sc->sc_dev, 827227364Sadrian "%s: HAL_TXDESC_NOACK set for an aggregate frame?\n", 828227364Sadrian __func__); 829233966Sadrian bf->bf_state.bfs_txflags &= (~HAL_TXDESC_NOACK); 830227364Sadrian } 831227364Sadrian 832227364Sadrian /* 833227364Sadrian * Add the now owned buffer (which isn't 834227364Sadrian * on the software TXQ any longer) to our 835227364Sadrian * aggregate frame list. 836227364Sadrian */ 837227364Sadrian TAILQ_INSERT_TAIL(bf_q, bf, bf_list); 838227364Sadrian nframes ++; 839227364Sadrian 840227364Sadrian /* Completion handler */ 841227364Sadrian bf->bf_comp = ath_tx_aggr_comp; 842227364Sadrian 843227364Sadrian /* 844227364Sadrian * add padding for previous frame to aggregation length 845227364Sadrian */ 846227364Sadrian al += bpad + al_delta; 847227364Sadrian 848227364Sadrian /* 849227364Sadrian * Calculate delimiters needed for the current frame 850227364Sadrian */ 851227364Sadrian bf->bf_state.bfs_ndelim = 852227364Sadrian ath_compute_num_delims(sc, bf_first, 853227364Sadrian bf->bf_state.bfs_pktlen); 854227364Sadrian 855227364Sadrian /* 856227364Sadrian * Calculate the padding needed from this set of delimiters, 857227364Sadrian * used when calculating if the next frame will fit in 858227364Sadrian * the aggregate. 859227364Sadrian */ 860227364Sadrian bpad = PADBYTES(al_delta) + (bf->bf_state.bfs_ndelim << 2); 861227364Sadrian 862227364Sadrian /* 863227364Sadrian * Chain the buffers together 864227364Sadrian */ 865227364Sadrian if (bf_prev) 866227364Sadrian bf_prev->bf_next = bf; 867227364Sadrian bf_prev = bf; 868227364Sadrian 869227364Sadrian /* 870227364Sadrian * XXX TODO: if any sub-frames have RTS/CTS enabled; 871227364Sadrian * enable it for the entire aggregate. 872227364Sadrian */ 873227364Sadrian 874227364Sadrian#if 0 875227364Sadrian /* 876227364Sadrian * terminate aggregation on a small packet boundary 877227364Sadrian */ 878227364Sadrian if (bf->bf_state.bfs_pktlen < ATH_AGGR_MINPLEN) { 879227364Sadrian status = ATH_AGGR_SHORTPKT; 880227364Sadrian break; 881227364Sadrian } 882227364Sadrian#endif 883227364Sadrian 884227364Sadrian } 885227364Sadrian 886227364Sadrianfinish: 887227364Sadrian /* 888227364Sadrian * Just in case the list was empty when we tried to 889227364Sadrian * dequeue a packet .. 890227364Sadrian */ 891227364Sadrian if (bf_first) { 892227364Sadrian bf_first->bf_state.bfs_al = al; 893227364Sadrian bf_first->bf_state.bfs_nframes = nframes; 894227364Sadrian } 895227364Sadrian return status; 896227364Sadrian} 897