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