[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree
zrouter-src-freebsd at zrouter.org
zrouter-src-freebsd at zrouter.org
Wed Aug 15 08:14:47 UTC 2012
details: http://zrouter.org/hg/FreeBSD/head//rev/7fffa673adcd
changeset: 523:7fffa673adcd
user: Aleksandr Rybalko <ray at ddteam.net>
date: Wed Aug 15 11:15:12 2012 +0300
description:
Update dev/ath to r239289.
diffstat:
head/sys/dev/ath/ath_hal/ah.c | 34 +++--
head/sys/dev/ath/ath_hal/ah.h | 8 +-
head/sys/dev/ath/ath_rate/sample/sample.c | 42 +++---
head/sys/dev/ath/ath_rate/sample/sample.h | 4 +-
head/sys/dev/ath/ath_rate/sample/tx_schedules.h | 52 +++++++-
head/sys/dev/ath/if_ath.c | 149 ++++++++++++++++-------
head/sys/dev/ath/if_ath_beacon.c | 58 ++++++++-
head/sys/dev/ath/if_ath_beacon.h | 4 +-
head/sys/dev/ath/if_ath_debug.c | 5 +-
head/sys/dev/ath/if_ath_misc.h | 15 +-
head/sys/dev/ath/if_ath_sysctl.c | 7 +-
head/sys/dev/ath/if_ath_tx.c | 9 +-
head/sys/dev/ath/if_ath_tx.h | 8 +-
head/sys/dev/ath/if_ath_tx_edma.c | 147 +++++++++++++++++++++--
head/sys/dev/ath/if_athvar.h | 18 +-
15 files changed, 425 insertions(+), 135 deletions(-)
diffs (1229 lines):
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/ath_hal/ah.c
--- a/head/sys/dev/ath/ath_hal/ah.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/ath_hal/ah.c Wed Aug 15 11:15:12 2012 +0300
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/ath/ath_hal/ah.c 238858 2012-07-28 07:28:08Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ah.c 239288 2012-08-15 07:56:48Z adrian $
*/
#include "opt_ah.h"
@@ -275,31 +275,37 @@
/* 11n frame - extract out the number of spatial streams */
numStreams = HT_RC_2_STREAMS(rc);
- KASSERT(numStreams == 1 || numStreams == 2, ("number of spatial streams needs to be 1 or 2: MCS rate 0x%x!", rateix));
+ KASSERT(numStreams > 0 && numStreams <= 4,
+ ("number of spatial streams needs to be 1..3: MCS rate 0x%x!",
+ rateix));
return ath_computedur_ht(frameLen, rc, numStreams, isht40, shortPreamble);
}
+static const uint16_t ht20_bps[32] = {
+ 26, 52, 78, 104, 156, 208, 234, 260,
+ 52, 104, 156, 208, 312, 416, 468, 520,
+ 78, 156, 234, 312, 468, 624, 702, 780,
+ 104, 208, 312, 416, 624, 832, 936, 1040
+};
+static const uint16_t ht40_bps[32] = {
+ 54, 108, 162, 216, 324, 432, 486, 540,
+ 108, 216, 324, 432, 648, 864, 972, 1080,
+ 162, 324, 486, 648, 972, 1296, 1458, 1620,
+ 216, 432, 648, 864, 1296, 1728, 1944, 2160
+};
+
/*
* Calculate the transmit duration of an 11n frame.
- * This only works for MCS0->MCS15.
*/
uint32_t
-ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams, HAL_BOOL isht40,
- HAL_BOOL isShortGI)
+ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams,
+ HAL_BOOL isht40, HAL_BOOL isShortGI)
{
- static const uint16_t ht20_bps[16] = {
- 26, 52, 78, 104, 156, 208, 234, 260,
- 52, 104, 156, 208, 312, 416, 468, 520
- };
- static const uint16_t ht40_bps[16] = {
- 54, 108, 162, 216, 324, 432, 486, 540,
- 108, 216, 324, 432, 648, 864, 972, 1080,
- };
uint32_t bitsPerSymbol, numBits, numSymbols, txTime;
KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate));
- KASSERT((rate &~ IEEE80211_RATE_MCS) < 16, ("bad mcs 0x%x", rate));
+ KASSERT((rate &~ IEEE80211_RATE_MCS) < 31, ("bad mcs 0x%x", rate));
if (isht40)
bitsPerSymbol = ht40_bps[rate & 0xf];
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/ath_hal/ah.h
--- a/head/sys/dev/ath/ath_hal/ah.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/ath_hal/ah.h Wed Aug 15 11:15:12 2012 +0300
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/ath/ath_hal/ah.h 239053 2012-08-05 11:24:21Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ah.h 239289 2012-08-15 08:06:06Z adrian $
*/
#ifndef _ATH_AH_H_
@@ -550,7 +550,7 @@
typedef struct {
int rateCount; /* NB: for proper padding */
- uint8_t rateCodeToIndex[144]; /* back mapping */
+ uint8_t rateCodeToIndex[256]; /* back mapping */
struct {
uint8_t valid; /* valid for rate control use */
uint8_t phy; /* CCK/OFDM/XR */
@@ -564,12 +564,12 @@
* rate; used for dur. calcs */
uint16_t lpAckDuration; /* long preamble ACK duration */
uint16_t spAckDuration; /* short preamble ACK duration*/
- } info[32];
+ } info[64];
} HAL_RATE_TABLE;
typedef struct {
u_int rs_count; /* number of valid entries */
- uint8_t rs_rates[32]; /* rates */
+ uint8_t rs_rates[64]; /* rates */
} HAL_RATE_SET;
/*
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/ath_rate/sample/sample.c
--- a/head/sys/dev/ath/ath_rate/sample/sample.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/ath_rate/sample/sample.c Wed Aug 15 11:15:12 2012 +0300
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.c 238962 2012-08-01 00:18:02Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.c 239284 2012-08-15 07:10:10Z adrian $");
/*
* John Bicket's SampleRate control algorithm.
@@ -164,7 +164,7 @@
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
int best_rate_rix, best_rate_tt, best_rate_pct;
- uint32_t mask;
+ uint64_t mask;
int rix, tt, pct;
best_rate_rix = 0;
@@ -251,7 +251,7 @@
struct sample_node *sn = ATH_NODE_SAMPLE(an);
int current_rix, rix;
unsigned current_tt;
- uint32_t mask;
+ uint64_t mask;
current_rix = sn->current_rix[size_bin];
if (current_rix < 0) {
@@ -263,9 +263,9 @@
current_tt = sn->stats[size_bin][current_rix].average_tx_time;
rix = sn->last_sample_rix[size_bin]+1; /* next sample rate */
- mask = sn->ratemask &~ (1<<current_rix);/* don't sample current rate */
+ mask = sn->ratemask &~ ((uint64_t) 1<<current_rix);/* don't sample current rate */
while (mask != 0) {
- if ((mask & (1<<rix)) == 0) { /* not a supported rate */
+ if ((mask & ((uint64_t) 1<<rix)) == 0) { /* not a supported rate */
nextrate:
if (++rix >= rt->rateCount)
rix = 0;
@@ -275,20 +275,20 @@
/* if the node is HT and the rate isn't HT, don't bother sample */
if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
(rt->info[rix].phy != IEEE80211_T_HT)) {
- mask &= ~(1<<rix);
+ mask &= ~((uint64_t) 1<<rix);
goto nextrate;
}
/* this bit-rate is always worse than the current one */
if (sn->stats[size_bin][rix].perfect_tx_time > current_tt) {
- mask &= ~(1<<rix);
+ mask &= ~((uint64_t) 1<<rix);
goto nextrate;
}
/* rarely sample bit-rates that fail a lot */
if (sn->stats[size_bin][rix].successive_failures > ssc->max_successive_failures &&
ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout) {
- mask &= ~(1<<rix);
+ mask &= ~((uint64_t) 1<<rix);
goto nextrate;
}
@@ -304,7 +304,7 @@
if ((sn->stats[size_bin][rix].average_tx_time * 10 >
sn->stats[size_bin][current_rix].average_tx_time * 9) &&
(ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout)) {
- mask &= ~(1<<rix);
+ mask &= ~((uint64_t) 1<<rix);
goto nextrate;
}
}
@@ -317,7 +317,7 @@
/* Don't sample more than 2 rates higher for rates > 11M for non-HT rates */
if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
if (DOT11RATE(rix) > 2*11 && rix > current_rix + 2) {
- mask &= ~(1<<rix);
+ mask &= ~((uint64_t) 1<<rix);
goto nextrate;
}
}
@@ -394,7 +394,7 @@
/* no packet has been sent successfully yet */
for (rix = rt->rateCount-1; rix > 0; rix--) {
- if ((sn->ratemask & (1<<rix)) == 0)
+ if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
continue;
/* Skip HT rates */
@@ -436,7 +436,7 @@
/* no packet has been sent successfully yet */
for (rix = rt->rateCount-1; rix > 0; rix--) {
/* Skip rates we can't use */
- if ((sn->ratemask & (1<<rix)) == 0)
+ if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
continue;
/* Keep a copy of the last seen HT rate index */
@@ -660,7 +660,8 @@
struct sample_node *sn = ATH_NODE_SAMPLE(an);
const struct txschedule *sched = &sn->sched[rix0];
- KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n", rix0, sched->r0));
+ KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
+ rix0, sched->r0));
rc[0].flags = rc[1].flags = rc[2].flags = rc[3].flags = 0;
@@ -919,6 +920,8 @@
if (!mrr || ts->ts_finaltsi == 0) {
if (!IS_RATE_DEFINED(sn, final_rix)) {
+ device_printf(sc->sc_dev, "%s: ts_rate=%d ts_finaltsi=%d\n",
+ __func__, ts->ts_rate, ts->ts_finaltsi);
badrate(ifp, 0, ts->ts_rate, long_tries, status);
return;
}
@@ -1087,6 +1090,7 @@
KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2,
("curmode %u", sc->sc_curmode));
+
sn->sched = mrr_schedules[sc->sc_curmode];
KASSERT(sn->sched != NULL,
("no mrr schedule for mode %u", sc->sc_curmode));
@@ -1113,7 +1117,7 @@
continue;
KASSERT(rix < SAMPLE_MAXRATES,
("mcs %u has rix %d", MCS(x), rix));
- sn->ratemask |= 1<<rix;
+ sn->ratemask |= (uint64_t) 1<<rix;
}
}
@@ -1127,11 +1131,11 @@
continue;
KASSERT(rix < SAMPLE_MAXRATES,
("rate %u has rix %d", RATE(x), rix));
- sn->ratemask |= 1<<rix;
+ sn->ratemask |= (uint64_t) 1<<rix;
}
#ifdef IEEE80211_DEBUG
if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) {
- uint32_t mask;
+ uint64_t mask;
ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt",
ni->ni_macaddr, ":", __func__);
@@ -1147,7 +1151,7 @@
#endif
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
int size = bin_to_size(y);
- uint32_t mask;
+ uint64_t mask;
sn->packets_sent[y] = 0;
sn->current_sample_rix[y] = -1;
@@ -1289,10 +1293,10 @@
struct ath_softc *sc = arg;
const HAL_RATE_TABLE *rt = sc->sc_currates;
struct sample_node *sn = ATH_NODE_SAMPLE(ATH_NODE(ni));
- uint32_t mask;
+ uint64_t mask;
int rix, y;
- printf("\n[%s] refcnt %d static_rix (%d %s) ratemask 0x%x\n",
+ printf("\n[%s] refcnt %d static_rix (%d %s) ratemask 0x%qx\n",
ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni),
dot11rate(rt, sn->static_rix),
dot11rate_label(rt, sn->static_rix),
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/ath_rate/sample/sample.h
--- a/head/sys/dev/ath/ath_rate/sample/sample.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/ath_rate/sample/sample.h Wed Aug 15 11:15:12 2012 +0300
@@ -33,7 +33,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.h 238636 2012-07-20 01:41:18Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.h 239284 2012-08-15 07:10:10Z adrian $
*/
/*
@@ -91,7 +91,7 @@
struct sample_node {
int static_rix; /* rate index of fixed tx rate */
#define SAMPLE_MAXRATES 64 /* NB: corresponds to hal info[32] */
- uint32_t ratemask; /* bit mask of valid rate indices */
+ uint64_t ratemask; /* bit mask of valid rate indices */
const struct txschedule *sched; /* tx schedule table */
const HAL_RATE_TABLE *currates;
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/ath_rate/sample/tx_schedules.h
--- a/head/sys/dev/ath/ath_rate/sample/tx_schedules.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/ath_rate/sample/tx_schedules.h Wed Aug 15 11:15:12 2012 +0300
@@ -38,7 +38,7 @@
#define __ATH_RATE_SAMPLE_TXSCHEDULES_H__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/sample/tx_schedules.h 221869 2011-05-14 01:53:38Z attilio $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/sample/tx_schedules.h 239286 2012-08-15 07:50:42Z adrian $");
#define A(_r) \
(((_r) == 6) ? 0 : (((_r) == 9) ? 1 : (((_r) == 12) ? 2 : \
@@ -63,6 +63,10 @@
(((_r) == 13) ? 16 : (((_r) == 26) ? 17 : (((_r) == 39) ? 18 : \
(((_r) == 52) ? 19 : (((_r) == 78) ? 20 : (((_r) == 104)? 21 : \
(((_r) == 117)? 22 : (((_r) == 130)? 23 : 0))))))))
+#define NA3(_r) \
+ (((_r) == 19.5) ? 24 : (((_r) == 39) ? 25 : (((_r) == 58.5) ? 26 : \
+ (((_r) == 78) ? 27 : (((_r) == 117) ? 28 : (((_r) == 156) ? 29 : \
+ (((_r) == 175.5) ? 30 : (((_r) == 195)? 31 : 0))))))))
static const struct txschedule series_11na[] = {
{ 3,A( 6), 3,A( 6), 0,A( 6), 0,A( 6) }, /* 6Mb/s */
{ 4,A( 9), 3,A( 6), 4,A( 6), 0,A( 6) }, /* 9Mb/s */
@@ -72,6 +76,9 @@
{ 4,A(36), 3,A( 24), 4,A( 18), 2,A( 6) }, /* 36Mb/s */
{ 4,A(48), 3,A( 36), 4,A( 24), 2,A(12) }, /* 48Mb/s */
{ 4,A(54), 3,A( 48), 4,A( 36), 2,A(24) }, /* 54Mb/s */
+
+ /* 1 stream rates */
+
{ 3,NA1( 6.5), 3,NA1( 6.5), 0,NA1( 6.5), 0,NA1(6.5) }, /* 6.5Mb/s */
{ 4,NA1( 13), 3,NA1( 6.5), 4,NA1( 6.5), 0,NA1(6.5) }, /* 13Mb/s */
{ 4,NA1(19.5), 3,NA1( 6.5), 4,NA1( 6.5), 0,NA1(6.5) }, /*19.5Mb/s */
@@ -80,6 +87,9 @@
{ 4,NA1( 52), 3,NA1( 39), 4,NA1( 26), 2,NA1(6.5) }, /* 52Mb/s */
{ 4,NA1(58.5), 3,NA1( 52), 4,NA1( 39), 2,NA1( 13) }, /*58.5Mb/s */
{ 4,NA1( 65), 3,NA1(58.5), 4,NA1( 52), 2,NA1( 13) }, /* 65Mb/s */
+
+ /* 2 stream rates */
+
{ 3,NA2( 13), 3,NA2( 13), 0,NA2( 13), 0,NA2( 13) }, /* 13Mb/s */
{ 4,NA2( 26), 3,NA2( 13), 4,NA2( 13), 0,NA2( 13) }, /* 26Mb/s */
{ 4,NA2( 39), 3,NA2( 26), 4,NA2( 13), 2,NA2( 13) }, /* 39Mb/s */
@@ -87,9 +97,21 @@
{ 4,NA2( 78), 3,NA2( 52), 4,NA2( 39), 2,NA2( 13) }, /* 78Mb/s */
{ 4,NA2( 104), 3,NA2( 78), 4,NA2( 52), 2,NA2( 13) }, /* 104Mb/s */
{ 4,NA2( 117), 3,NA2( 104), 4,NA2( 78), 2,NA2( 26) }, /* 117Mb/s */
- { 4,NA2( 130), 3,NA2( 117), 4,NA2( 104), 2,NA2( 26) } /* 130Mb/s */
+ { 4,NA2( 130), 3,NA2( 117), 4,NA2( 104), 2,NA2( 26) }, /* 130Mb/s */
+
+ /* 3 stream rates */
+
+ { 3,NA3(19.5), 3,NA3(19.5), 0,NA3(19.5), 0,NA3(19.5) }, /* 19Mb/s */
+ { 3,NA3( 39), 3,NA3(19.5), 0,NA3(19.5), 0,NA3(19.5) }, /* 39Mb/s */
+ { 3,NA3(58.5), 3,NA3( 39), 0,NA3(19.5), 0,NA3(19.5) }, /* 58Mb/s */
+ { 3,NA3( 78), 3,NA3(58.5), 0,NA3( 39), 0,NA3(19.5) }, /* 78Mb/s */
+ { 3,NA3( 117), 3,NA3( 78), 0,NA3(58.5), 0,NA3(19.5) }, /* 117Mb/s */
+ { 3,NA3( 156), 3,NA3( 117), 0,NA3( 78), 0,NA3(19.5) }, /* 156Mb/s */
+ { 3,NA3(175.5), 3,NA3( 156), 0,NA3( 117), 0,NA3( 39) }, /* 175Mb/s */
+ { 3,NA3( 195), 3,NA3( 195), 0,NA3( 156), 0,NA3(58.5) }, /* 195Mb/s */
};
#undef A
+#undef NA3
#undef NA2
#undef NA1
@@ -121,6 +143,11 @@
(((_r) == 13) ? 20 : (((_r) == 26) ? 21 : (((_r) == 39) ? 22 : \
(((_r) == 52) ? 23 : (((_r) == 78) ? 24 : (((_r) == 104) ? 25 : \
(((_r) == 117) ? 26 : (((_r) == 130)? 27 : 0))))))))
+#define NG3(_r) \
+ (((_r) == 19.5) ? 28 : (((_r) == 39) ? 29 : (((_r) == 58.5) ? 30 : \
+ (((_r) == 78) ? 31 : (((_r) == 117) ? 32 : (((_r) == 156) ? 33 : \
+ (((_r) == 175.5) ? 34 : (((_r) == 195)? 35 : 0))))))))
+
static const struct txschedule series_11ng[] = {
{ 3,G( 1), 3,G( 1), 0,G( 1), 0,G( 1) }, /* 1Mb/s */
{ 4,G( 2), 3,G( 1), 4,G( 1), 0,G( 1) }, /* 2Mb/s */
@@ -134,6 +161,9 @@
{ 4,G(36), 3,G( 24), 4,G( 18), 2,G( 1) }, /* 36Mb/s */
{ 4,G(48), 3,G( 36), 4,G( 24), 2,G( 1) }, /* 48Mb/s */
{ 4,G(54), 3,G( 48), 4,G( 36), 2,G( 1) }, /* 54Mb/s */
+
+ /* 1 stream rates */
+
{ 3,NG1( 6.5), 3,NG1( 6.5), 0,NG1( 6.5), 0,NG1(6.5) }, /* 6.5Mb/s */
{ 4,NG1( 13), 3,NG1( 6.5), 4,NG1( 6.5), 0,NG1(6.5) }, /* 13Mb/s */
{ 4,NG1(19.5), 3,NG1( 6.5), 4,NG1( 6.5), 0,NG1(6.5) }, /*19.5Mb/s */
@@ -142,6 +172,9 @@
{ 4,NG1( 52), 3,NG1( 39), 4,NG1( 26), 2,NG1(6.5) }, /* 52Mb/s */
{ 4,NG1(58.5), 3,NG1( 52), 4,NG1( 39), 2,NG1( 13) }, /*58.5Mb/s */
{ 4,NG1( 65), 3,NG1(58.5), 4,NG1( 52), 2,NG1( 13) }, /* 65Mb/s */
+
+ /* 2 stream rates */
+
{ 3,NG2( 13), 3,NG2( 13), 0,NG2( 13), 0,NG2( 13) }, /* 13Mb/s */
{ 4,NG2( 26), 3,NG2( 13), 4,NG2( 13), 0,NG2( 13) }, /* 26Mb/s */
{ 4,NG2( 39), 3,NG2( 26), 4,NG2( 13), 2,NG2( 13) }, /* 39Mb/s */
@@ -149,9 +182,22 @@
{ 4,NG2( 78), 3,NG2( 52), 4,NG2( 39), 2,NG2( 13) }, /* 78Mb/s */
{ 4,NG2( 104), 3,NG2( 78), 4,NG2( 52), 2,NG2( 13) }, /* 104Mb/s */
{ 4,NG2( 117), 3,NG2( 104), 4,NG2( 78), 2,NG2( 26) }, /* 117Mb/s */
- { 4,NG2( 130), 3,NG2( 117), 4,NG2( 104), 2,NG2( 26) } /* 130Mb/s */
+ { 4,NG2( 130), 3,NG2( 117), 4,NG2( 104), 2,NG2( 26) }, /* 130Mb/s */
+
+ /* 3 stream rates */
+
+ { 3,NG3(19.5), 3,NG3(19.5), 0,NG3(19.5), 0,NG3(19.5) }, /* 19Mb/s */
+ { 3,NG3( 39), 3,NG3(19.5), 0,NG3(19.5), 0,NG3(19.5) }, /* 39Mb/s */
+ { 3,NG3(58.5), 3,NG3( 39), 0,NG3(19.5), 0,NG3(19.5) }, /* 58Mb/s */
+ { 3,NG3( 78), 3,NG3(58.5), 0,NG3( 39), 0,NG3(19.5) }, /* 78Mb/s */
+ { 3,NG3( 117), 3,NG3( 78), 0,NG3(58.5), 0,NG3(19.5) }, /* 117Mb/s */
+ { 3,NG3( 156), 3,NG3( 117), 0,NG3( 78), 0,NG3(19.5) }, /* 156Mb/s */
+ { 3,NG3(175.5), 3,NG3( 156), 0,NG3( 117), 0,NG3( 39) }, /* 175Mb/s */
+ { 3,NG3( 195), 3,NG3( 195), 0,NG3( 156), 0,NG3(58.5) }, /* 195Mb/s */
+
};
#undef G
+#undef NG3
#undef NG2
#undef NG1
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath.c
--- a/head/sys/dev/ath/if_ath.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath.c Wed Aug 15 11:15:12 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 238961 2012-07-31 23:54:15Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 239282 2012-08-15 06:48:34Z adrian $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -168,12 +168,13 @@
static int ath_tx_setup(struct ath_softc *, int, int);
static void ath_tx_cleanupq(struct ath_softc *, struct ath_txq *);
static void ath_tx_cleanup(struct ath_softc *);
+static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq,
+ int dosched);
static void ath_tx_proc_q0(void *, int);
static void ath_tx_proc_q0123(void *, int);
static void ath_tx_proc(void *, int);
static void ath_txq_sched_tasklet(void *, int);
static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
-static void ath_draintxq(struct ath_softc *, ATH_RESET_TYPE reset_type);
static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *);
static void ath_scan_start(struct ieee80211com *);
static void ath_scan_end(struct ieee80211com *);
@@ -443,7 +444,7 @@
*
* XXX PS-Poll
*/
- sc->sc_bhalq = ath_beaconq_setup(ah);
+ sc->sc_bhalq = ath_beaconq_setup(sc);
if (sc->sc_bhalq == (u_int) -1) {
if_printf(ifp, "unable to setup a beacon xmit queue!\n");
error = EIO;
@@ -1674,12 +1675,14 @@
* and blank them. This is the only place we should be
* doing this.
*/
- ATH_PCU_LOCK(sc);
- txqs = 0xffffffff;
- ath_hal_gettxintrtxqs(sc->sc_ah, &txqs);
- sc->sc_txq_active |= txqs;
+ if (! sc->sc_isedma) {
+ ATH_PCU_LOCK(sc);
+ txqs = 0xffffffff;
+ ath_hal_gettxintrtxqs(sc->sc_ah, &txqs);
+ sc->sc_txq_active |= txqs;
+ ATH_PCU_UNLOCK(sc);
+ }
taskqueue_enqueue(sc->sc_tq, &sc->sc_txtask);
- ATH_PCU_UNLOCK(sc);
}
if (status & HAL_INT_BMISS) {
sc->sc_stats.ast_bmiss++;
@@ -2341,6 +2344,14 @@
bf->bf_comp = NULL; /* XXX again, just to be sure */
bzero(&bf->bf_state, sizeof(bf->bf_state));
+ /*
+ * Track the descriptor ID only if doing EDMA
+ */
+ if (sc->sc_isedma) {
+ bf->bf_descid = sc->sc_txbuf_descid;
+ sc->sc_txbuf_descid++;
+ }
+
return bf;
}
@@ -3581,19 +3592,68 @@
}
/*
+ * Process the completion of the given buffer.
+ *
+ * This calls the rate control update and then the buffer completion.
+ * This will either free the buffer or requeue it. In any case, the
+ * bf pointer should be treated as invalid after this function is called.
+ */
+void
+ath_tx_process_buf_completion(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_tx_status *ts, struct ath_buf *bf)
+{
+ struct ieee80211_node *ni = bf->bf_node;
+ struct ath_node *an = NULL;
+
+ ATH_TXQ_UNLOCK_ASSERT(txq);
+
+ /* If unicast frame, update general statistics */
+ if (ni != NULL) {
+ an = ATH_NODE(ni);
+ /* update statistics */
+ ath_tx_update_stats(sc, ts, bf);
+ }
+
+ /*
+ * Call the completion handler.
+ * The completion handler is responsible for
+ * calling the rate control code.
+ *
+ * Frames with no completion handler get the
+ * rate control code called here.
+ */
+ if (bf->bf_comp == NULL) {
+ if ((ts->ts_status & HAL_TXERR_FILT) == 0 &&
+ (bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0) {
+ /*
+ * XXX assume this isn't an aggregate
+ * frame.
+ */
+ ath_tx_update_ratectrl(sc, ni,
+ bf->bf_state.bfs_rc, ts,
+ bf->bf_state.bfs_pktlen, 1,
+ (ts->ts_status == 0 ? 0 : 1));
+ }
+ ath_tx_default_comp(sc, bf, 0);
+ } else
+ bf->bf_comp(sc, bf, 0);
+}
+
+
+
+/*
* Process completed xmit descriptors from the specified queue.
* Kick the packet scheduler if needed. This can occur from this
* particular task.
*/
-int
-ath_legacy_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched)
+static int
+ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched)
{
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf;
struct ath_desc *ds;
struct ath_tx_status *ts;
struct ieee80211_node *ni;
- struct ath_node *an;
#ifdef IEEE80211_SUPPORT_SUPERG
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
#endif /* IEEE80211_SUPPORT_SUPERG */
@@ -3665,36 +3725,12 @@
}
ATH_TXQ_UNLOCK(txq);
- /* If unicast frame, update general statistics */
- if (ni != NULL) {
- an = ATH_NODE(ni);
- /* update statistics */
- ath_tx_update_stats(sc, ts, bf);
- }
-
/*
- * Call the completion handler.
- * The completion handler is responsible for
- * calling the rate control code.
- *
- * Frames with no completion handler get the
- * rate control code called here.
+ * Update statistics and call completion
*/
- if (bf->bf_comp == NULL) {
- if ((ts->ts_status & HAL_TXERR_FILT) == 0 &&
- (bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0) {
- /*
- * XXX assume this isn't an aggregate
- * frame.
- */
- ath_tx_update_ratectrl(sc, ni,
- bf->bf_state.bfs_rc, ts,
- bf->bf_state.bfs_pktlen, 1,
- (ts->ts_status == 0 ? 0 : 1));
- }
- ath_tx_default_comp(sc, bf, 0);
- } else
- bf->bf_comp(sc, bf, 0);
+ ath_tx_process_buf_completion(sc, txq, ts, bf);
+
+
}
#ifdef IEEE80211_SUPPORT_SUPERG
/*
@@ -3986,7 +4022,7 @@
}
void
-ath_legacy_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
+ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
{
#ifdef ATH_DEBUG
struct ath_hal *ah = sc->sc_ah;
@@ -4012,6 +4048,17 @@
bf = TAILQ_FIRST(&txq->axq_q);
if (bf == NULL) {
txq->axq_link = NULL;
+ /*
+ * There's currently no flag that indicates
+ * a buffer is on the FIFO. So until that
+ * occurs, just clear the FIFO counter here.
+ *
+ * Yes, this means that if something in parallel
+ * is pushing things onto this TXQ and pushing
+ * _that_ into the hardware, things will get
+ * very fruity very quickly.
+ */
+ txq->axq_fifo_depth = 0;
ATH_TXQ_UNLOCK(txq);
break;
}
@@ -4021,10 +4068,20 @@
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_RESET) {
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
-
- ath_printtxbuf(sc, bf, txq->axq_qnum, ix,
- ath_hal_txprocdesc(ah, bf->bf_lastds,
+ int status = 0;
+
+ /*
+ * EDMA operation has a TX completion FIFO
+ * separate from the TX descriptor, so this
+ * method of checking the "completion" status
+ * is wrong.
+ */
+ if (! sc->sc_isedma) {
+ status = (ath_hal_txprocdesc(ah,
+ bf->bf_lastds,
&bf->bf_status.ds_txstat) == HAL_OK);
+ }
+ ath_printtxbuf(sc, bf, txq->axq_qnum, ix, status);
ieee80211_dump_pkt(ic, mtod(bf->bf_m, const uint8_t *),
bf->bf_m->m_len, 0, -1);
}
@@ -4065,7 +4122,7 @@
(void) ath_hal_stoptxdma(ah, txq->axq_qnum);
}
-static int
+int
ath_stoptxdma(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
@@ -4093,8 +4150,8 @@
/*
* Drain the transmit queues and reclaim resources.
*/
-static void
-ath_draintxq(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
+void
+ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
{
#ifdef ATH_DEBUG
struct ath_hal *ah = sc->sc_ah;
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_beacon.c
--- a/head/sys/dev/ath/if_ath_beacon.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_beacon.c Wed Aug 15 11:15:12 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_beacon.c 239051 2012-08-05 10:12:27Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_beacon.c 239201 2012-08-11 23:26:19Z adrian $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -108,8 +108,9 @@
* Setup a h/w transmit queue for beacons.
*/
int
-ath_beaconq_setup(struct ath_hal *ah)
+ath_beaconq_setup(struct ath_softc *sc)
{
+ struct ath_hal *ah = sc->sc_ah;
HAL_TXQ_INFO qi;
memset(&qi, 0, sizeof(qi));
@@ -118,6 +119,10 @@
qi.tqi_cwmax = HAL_TXQ_USEDEFAULT;
/* NB: for dynamic turbo, don't enable any other interrupts */
qi.tqi_qflags = HAL_TXQ_TXDESCINT_ENABLE;
+ if (sc->sc_isedma)
+ qi.tqi_qflags |= HAL_TXQ_TXOKINT_ENABLE |
+ HAL_TXQ_TXERRINT_ENABLE;
+
return ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_BEACON, &qi);
}
@@ -268,6 +273,7 @@
u_int8_t rix, rate;
HAL_DMA_ADDR bufAddrList[4];
uint32_t segLenList[4];
+ HAL_11N_RATE_SERIES rc[4];
DPRINTF(sc, ATH_DEBUG_BEACON_PROC, "%s: m %p len %u\n",
__func__, m, m->m_len);
@@ -324,6 +330,26 @@
, 0 /* rts/cts rate */
, 0 /* rts/cts duration */
);
+
+ /*
+ * The EDMA HAL currently assumes that _all_ rate control
+ * settings are done in ath_hal_set11nratescenario(), rather
+ * than in ath_hal_setuptxdesc().
+ */
+ if (sc->sc_isedma) {
+ memset(&rc, 0, sizeof(rc));
+
+ rc[0].ChSel = sc->sc_txchainmask;
+ rc[0].Tries = 1;
+ rc[0].Rate = rt->info[rix].rateCode;
+ rc[0].RateIndex = rix;
+ rc[0].tx_power_cap = 0x3f;
+ rc[0].PktDuration =
+ ath_hal_computetxtime(ah, rt, roundup(m->m_len, 4),
+ rix, 0);
+ ath_hal_set11nratescenario(ah, ds, 0, 0, rc, 4, flags);
+ }
+
/* NB: beacon's BufLen must be a multiple of 4 bytes */
segLenList[0] = roundup(m->m_len, 4);
segLenList[1] = segLenList[2] = segLenList[3] = 0;
@@ -458,12 +484,15 @@
* This should never fail since we check above that no frames
* are still pending on the queue.
*/
- if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) {
- DPRINTF(sc, ATH_DEBUG_ANY,
- "%s: beacon queue %u did not stop?\n",
- __func__, sc->sc_bhalq);
+ if (! sc->sc_isedma) {
+ if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) {
+ DPRINTF(sc, ATH_DEBUG_ANY,
+ "%s: beacon queue %u did not stop?\n",
+ __func__, sc->sc_bhalq);
+ }
}
/* NB: cabq traffic should already be queued and primed */
+
ath_hal_puttxbuf(ah, sc->sc_bhalq, bfaddr);
ath_hal_txstart(ah, sc->sc_bhalq);
@@ -673,6 +702,7 @@
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211_node *ni;
u_int32_t nexttbtt, intval, tsftu;
+ u_int32_t nexttbtt_u8, intval_u8;
u_int64_t tsf;
if (vap == NULL)
@@ -836,7 +866,21 @@
sc->sc_imask |= HAL_INT_SWBA; /* beacon prepare */
ath_beaconq_config(sc);
}
- ath_hal_beaconinit(ah, nexttbtt, intval);
+
+ /*
+ * Now dirty things because for now, the EDMA HAL has
+ * nexttbtt and intval is TU/8.
+ */
+ if (sc->sc_isedma) {
+ nexttbtt_u8 = (nexttbtt << 3);
+ intval_u8 = (intval << 3);
+ if (intval & HAL_BEACON_ENA)
+ intval_u8 |= HAL_BEACON_ENA;
+ if (intval & HAL_BEACON_RESET_TSF)
+ intval_u8 |= HAL_BEACON_RESET_TSF;
+ ath_hal_beaconinit(ah, nexttbtt_u8, intval_u8);
+ } else
+ ath_hal_beaconinit(ah, nexttbtt, intval);
sc->sc_bmisscount = 0;
ath_hal_intrset(ah, sc->sc_imask);
/*
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_beacon.h
--- a/head/sys/dev/ath/if_ath_beacon.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_beacon.h Wed Aug 15 11:15:12 2012 +0300
@@ -26,14 +26,14 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/if_ath_beacon.h 235680 2012-05-20 04:14:29Z adrian $
+ * $FreeBSD: head/sys/dev/ath/if_ath_beacon.h 239201 2012-08-11 23:26:19Z adrian $
*/
#ifndef __IF_ATH_BEACON_H__
#define __IF_ATH_BEACON_H__
extern int ath_bstuck_threshold;
-extern int ath_beaconq_setup(struct ath_hal *ah);
+extern int ath_beaconq_setup(struct ath_softc *sc);
extern int ath_beaconq_config(struct ath_softc *sc);
extern void ath_beacon_config(struct ath_softc *sc,
struct ieee80211vap *vap);
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_debug.c
--- a/head/sys/dev/ath/if_ath_debug.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_debug.c Wed Aug 15 11:15:12 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_debug.c 238275 2012-07-09 06:39:46Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_debug.c 239199 2012-08-11 22:39:27Z adrian $");
#include "opt_inet.h"
#include "opt_ath.h"
@@ -158,7 +158,8 @@
ds->ds_ctl0, ds->ds_ctl1,
ds->ds_hw[0], ds->ds_hw[1],
ds->ds_hw[2], ds->ds_hw[3]);
- if (ah->ah_magic == 0x20065416) {
+ if (ah->ah_magic == 0x20065416 ||
+ ah->ah_magic == 0x19741014) {
printf(" %08x %08x %08x %08x %08x %08x %08x %08x\n",
ds->ds_hw[4], ds->ds_hw[5], ds->ds_hw[6],
ds->ds_hw[7], ds->ds_hw[8], ds->ds_hw[9],
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_misc.h
--- a/head/sys/dev/ath/if_ath_misc.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_misc.h Wed Aug 15 11:15:12 2012 +0300
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/if_ath_misc.h 238931 2012-07-31 03:09:48Z adrian $
+ * $FreeBSD: head/sys/dev/ath/if_ath_misc.h 239262 2012-08-14 22:32:20Z adrian $
*/
#ifndef __IF_ATH_MISC_H__
#define __IF_ATH_MISC_H__
@@ -96,9 +96,16 @@
struct ath_descdma *dd, ath_bufhead *head);
extern void ath_legacy_attach_comp_func(struct ath_softc *sc);
-extern void ath_legacy_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq);
-extern int ath_legacy_tx_processq(struct ath_softc *sc, struct ath_txq *txq,
- int dosched);
+
+extern void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq);
+
+extern void ath_legacy_tx_drain(struct ath_softc *sc,
+ ATH_RESET_TYPE reset_type);
+
+extern void ath_tx_process_buf_completion(struct ath_softc *sc,
+ struct ath_txq *txq, struct ath_tx_status *ts, struct ath_buf *bf);
+
+extern int ath_stoptxdma(struct ath_softc *sc);
/*
* This is only here so that the RX proc function can call it.
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_sysctl.c
--- a/head/sys/dev/ath/if_ath_sysctl.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_sysctl.c Wed Aug 15 11:15:12 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_sysctl.c 238507 2012-07-15 20:51:41Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_sysctl.c 239263 2012-08-14 22:34:22Z adrian $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -357,10 +357,11 @@
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
- printf("HW TXQ %d: axq_depth=%d, axq_aggr_depth=%d\n",
+ printf("HW TXQ %d: axq_depth=%d, axq_aggr_depth=%d, axq_fifo_depth=%d\n",
i,
sc->sc_txq[i].axq_depth,
- sc->sc_txq[i].axq_aggr_depth);
+ sc->sc_txq[i].axq_aggr_depth,
+ sc->sc_txq[i].axq_fifo_depth);
}
}
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_tx.c
--- a/head/sys/dev/ath/if_ath_tx.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_tx.c Wed Aug 15 11:15:12 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx.c 239120 2012-08-07 00:42:46Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx.c 239205 2012-08-12 00:46:15Z adrian $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -120,7 +120,8 @@
static inline int
ath_tx_is_11n(struct ath_softc *sc)
{
- return (sc->sc_ah->ah_magic == 0x20065416);
+ return ((sc->sc_ah->ah_magic == 0x20065416) ||
+ (sc->sc_ah->ah_magic == 0x19741014));
}
/*
@@ -4570,6 +4571,6 @@
sc->sc_tx.xmit_dma_restart = ath_legacy_tx_dma_restart;
sc->sc_tx.xmit_handoff = ath_legacy_xmit_handoff;
- sc->sc_tx.xmit_processq = ath_legacy_tx_processq;
- sc->sc_tx.xmit_drainq = ath_legacy_tx_draintxq;
+
+ sc->sc_tx.xmit_drain = ath_legacy_tx_drain;
}
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_tx.h
--- a/head/sys/dev/ath/if_ath_tx.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_tx.h Wed Aug 15 11:15:12 2012 +0300
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/if_ath_tx.h 238931 2012-07-31 03:09:48Z adrian $
+ * $FreeBSD: head/sys/dev/ath/if_ath_tx.h 239205 2012-08-12 00:46:15Z adrian $
*/
#ifndef __IF_ATH_TX_H__
#define __IF_ATH_TX_H__
@@ -134,10 +134,8 @@
(_sc)->sc_tx.xmit_dma_restart((_sc), (_txq))
#define ath_tx_handoff(_sc, _txq, _bf) \
(_sc)->sc_tx.xmit_handoff((_sc), (_txq), (_bf))
-#define ath_tx_draintxq(_sc, _txq) \
- (_sc)->sc_tx.xmit_drainq((_sc), (_txq))
-#define ath_tx_processq(_sc, _txq, _dosched) \
- (_sc)->sc_tx.xmit_processq((_sc), (_txq), (_dosched))
+#define ath_draintxq(_sc, _rtype) \
+ (_sc)->sc_tx.xmit_drain((_sc), (_rtype))
extern void ath_xmit_setup_legacy(struct ath_softc *sc);
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_ath_tx_edma.c
--- a/head/sys/dev/ath/if_ath_tx_edma.c Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_ath_tx_edma.c Wed Aug 15 11:15:12 2012 +0300
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx_edma.c 238931 2012-07-31 03:09:48Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx_edma.c 239205 2012-08-12 00:46:15Z adrian $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -132,7 +132,7 @@
/*
* Re-initialise the DMA FIFO with the current contents of
- * said FIFO.
+ * said TXQ.
*
* This should only be called as part of the chip reset path, as it
* assumes the FIFO is currently empty.
@@ -152,6 +152,90 @@
}
/*
+ * Hand off this frame to a hardware queue.
+ *
+ * Things are a bit hairy in the EDMA world. The TX FIFO is only
+ * 8 entries deep, so we need to keep track of exactly what we've
+ * pushed into the FIFO and what's just sitting in the TX queue,
+ * waiting to go out.
+ *
+ * So this is split into two halves - frames get appended to the
+ * TXQ; then a scheduler is called to push some frames into the
+ * actual TX FIFO.
+ */
+static void
+ath_edma_xmit_handoff_hw(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_buf *bf)
+{
+ struct ath_hal *ah = sc->sc_ah;
+
+ ATH_TXQ_LOCK_ASSERT(txq);
+
+ KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0,
+ ("%s: busy status 0x%x", __func__, bf->bf_flags));
+
+ /*
+ * XXX TODO: write a hard-coded check to ensure that
+ * the queue id in the TX descriptor matches txq->axq_qnum.
+ */
+
+ /* Update aggr stats */
+ if (bf->bf_state.bfs_aggr)
+ txq->axq_aggr_depth++;
+
+ /* Push and update frame stats */
+ ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
+
+ /* Only schedule to the FIFO if there's space */
+ if (txq->axq_fifo_depth < HAL_TXFIFO_DEPTH) {
+ ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+ ath_hal_txstart(ah, txq->axq_qnum);
+ }
+}
+
+/*
+ * Hand off this frame to a multicast software queue.
+ *
+ * Unlike legacy DMA, this doesn't chain together frames via the
+ * link pointer. Instead, they're just added to the queue.
+ * When it comes time to populate the CABQ, these frames should
+ * be individually pushed into the FIFO as appropriate.
+ *
+ * Yes, this does mean that I'll eventually have to flesh out some
+ * replacement code to handle populating the CABQ, rather than
+ * what's done in ath_beacon_generate(). It'll have to push each
+ * frame from the HW CABQ to the FIFO rather than just appending
+ * it to the existing TXQ and kicking off DMA.
+ */
+static void
+ath_edma_xmit_handoff_mcast(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_buf *bf)
+{
+
+ ATH_TXQ_LOCK_ASSERT(txq);
+ KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0,
+ ("%s: busy status 0x%x", __func__, bf->bf_flags));
+
+ /*
+ * XXX this is mostly duplicated in ath_tx_handoff_mcast().
+ */
+ if (ATH_TXQ_FIRST(txq) != NULL) {
+ struct ath_buf *bf_last = ATH_TXQ_LAST(txq, axq_q_s);
+ struct ieee80211_frame *wh;
+
+ /* mark previous frame */
+ wh = mtod(bf_last->bf_m, struct ieee80211_frame *);
+ wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
+
+ /* sync descriptor to memory */
+ bus_dmamap_sync(sc->sc_dmat, bf_last->bf_dmamap,
+ BUS_DMASYNC_PREWRITE);
+ }
+
+ ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
+}
+
+/*
* Handoff this frame to the hardware.
*
* For the multicast queue, this will treat it as a software queue
@@ -173,17 +257,26 @@
struct ath_buf *bf)
{
+ ATH_TXQ_LOCK_ASSERT(txq);
+
device_printf(sc->sc_dev, "%s: called; bf=%p, txq=%p, qnum=%d\n",
__func__,
bf,
txq,
txq->axq_qnum);
+ if (txq->axq_qnum == ATH_TXQ_SWQ)
+ ath_edma_xmit_handoff_mcast(sc, txq, bf);
+ else
+ ath_edma_xmit_handoff_hw(sc, txq, bf);
+
+#if 0
/*
* XXX For now this is a placeholder; free the buffer
* and inform the stack that the TX failed.
*/
ath_tx_default_comp(sc, bf, 1);
+#endif
}
static int
@@ -255,26 +348,55 @@
return (0);
}
-static int
-ath_edma_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched)
+/*
+ * Drain all TXQs, potentially after completing the existing completed
+ * frames.
+ */
+static void
+ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
{
- return (0);
+ device_printf(sc->sc_dev, "%s: called\n", __func__);
}
-static void
-ath_edma_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
-{
-
-}
-
+/*
+ * Process the TX status queue.
+ */
static void
ath_edma_tx_proc(void *arg, int npending)
{
struct ath_softc *sc = (struct ath_softc *) arg;
+ struct ath_hal *ah = sc->sc_ah;
+ HAL_STATUS status;
+ struct ath_tx_status ts;
+ struct ath_txq *txq;
device_printf(sc->sc_dev, "%s: called, npending=%d\n",
__func__, npending);
+
+ for (;;) {
+ ATH_TXSTATUS_LOCK(sc);
+ status = ath_hal_txprocdesc(ah, NULL, (void *) &ts);
+ ATH_TXSTATUS_UNLOCK(sc);
+
+ if (status != HAL_OK)
+ break;
+
+ /*
+ * At this point we have a valid status descriptor.
+ * The QID and descriptor ID (which currently isn't set)
+ * is part of the status.
+ *
+ * We then assume that the descriptor in question is the
+ * -head- of the given QID. Eventually we should verify
+ * this by using the descriptor ID.
+ */
+ device_printf(sc->sc_dev, "%s: qcuid=%d\n",
+ __func__,
+ ts.ts_queue_id);
+
+ txq = &sc->sc_txq[ts.ts_queue_id];
+ }
}
static void
@@ -306,6 +428,5 @@
sc->sc_tx.xmit_dma_restart = ath_edma_dma_restart;
sc->sc_tx.xmit_handoff = ath_edma_xmit_handoff;
- sc->sc_tx.xmit_processq = ath_edma_tx_processq;
- sc->sc_tx.xmit_drainq = ath_edma_tx_draintxq;
+ sc->sc_tx.xmit_drain = ath_edma_tx_drain;
}
diff -r f9d564d21599 -r 7fffa673adcd head/sys/dev/ath/if_athvar.h
--- a/head/sys/dev/ath/if_athvar.h Fri Aug 10 16:14:45 2012 +0300
+++ b/head/sys/dev/ath/if_athvar.h Wed Aug 15 11:15:12 2012 +0300
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/if_athvar.h 239053 2012-08-05 11:24:21Z adrian $
+ * $FreeBSD: head/sys/dev/ath/if_athvar.h 239282 2012-08-15 06:48:34Z adrian $
*/
/*
@@ -191,6 +191,7 @@
int bf_nseg;
HAL_STATUS bf_rxstatus;
uint16_t bf_flags; /* status flags (below) */
+ uint16_t bf_descid; /* 16 bit descriptor ID */
struct ath_desc *bf_desc; /* virtual addr of desc */
struct ath_desc_status bf_status; /* tx/rx status */
bus_addr_t bf_daddr; /* physical addr of desc */
@@ -304,6 +305,7 @@
#define ATH_TXQ_PUTPENDING 0x0001 /* ath_hal_puttxbuf pending */
u_int axq_depth; /* queue depth (stat only) */
u_int axq_aggr_depth; /* how many aggregates are queued */
+ u_int axq_fifo_depth; /* depth of FIFO frames */
u_int axq_intrcnt; /* interrupt count */
u_int32_t *axq_link; /* link ptr in last TX desc */
TAILQ_HEAD(axq_q_s, ath_buf) axq_q; /* transmit queue */
@@ -326,7 +328,10 @@
#define ATH_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->axq_lock)
#define ATH_TXQ_LOCK(_tq) mtx_lock(&(_tq)->axq_lock)
#define ATH_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->axq_lock)
-#define ATH_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, MA_OWNED)
+#define ATH_TXQ_LOCK_ASSERT(_tq) \
+ mtx_assert(&(_tq)->axq_lock, MA_OWNED)
+#define ATH_TXQ_UNLOCK_ASSERT(_tq) \
+ mtx_assert(&(_tq)->axq_lock, MA_NOTOWNED)
#define ATH_TXQ_IS_LOCKED(_tq) mtx_owned(&(_tq)->axq_lock)
#define ATH_TID_LOCK_ASSERT(_sc, _tid) \
@@ -344,6 +349,7 @@
TAILQ_REMOVE(&(_tq)->axq_q, _elm, _field); \
(_tq)->axq_depth--; \
} while (0)
+#define ATH_TXQ_FIRST(_tq) TAILQ_FIRST(&(_tq)->axq_q)
#define ATH_TXQ_LAST(_tq, _field) TAILQ_LAST(&(_tq)->axq_q, _field)
struct ath_vap {
@@ -414,11 +420,8 @@
struct ath_txq *txq);
void (*xmit_handoff)(struct ath_softc *sc,
struct ath_txq *txq, struct ath_buf *bf);
-
- void (*xmit_drainq)(struct ath_softc *sc,
- struct ath_txq *txq);
- int (*xmit_processq)(struct ath_softc *sc,
- struct ath_txq *txq, int dosched);
+ void (*xmit_drain)(struct ath_softc *sc,
+ ATH_RESET_TYPE reset_type);
};
struct ath_softc {
@@ -574,6 +577,7 @@
u_int sc_monpass; /* frames to pass in mon.mode */
struct ath_descdma sc_txdma; /* TX descriptors */
+ uint16_t sc_txbuf_descid;
ath_bufhead sc_txbuf; /* transmit buffer */
int sc_txbuf_cnt; /* how many buffers avail */
struct ath_descdma sc_txdma_mgmt; /* mgmt TX descriptors */
More information about the Zrouter-src-freebsd
mailing list