#852: madwifi HAL does not do binary exponential backoff
-----------------------------------+----------------------------------------
Reporter: [EMAIL PROTECTED] | Owner:
Type: defect | Status: new
Priority: major | Milestone:
Component: madwifi: HAL | Version: trunk
Resolution: | Keywords: beb
Patch_attached: 1 |
-----------------------------------+----------------------------------------
Changes (by mrenzmann):
* version: => trunk
Old description:
> A simple experiment shows beb (binary exponential backoff) is not done in
> the madwifi HAL. I use a netgear wag311 card and a single computer
> sending out 1500 b frames. I add a simple DPRINTF to see at what time the
> function ath_tx_processq is called. I make sure that in one experiment
> txs_longretry of ath_tx_status struct is 11. In another experiement I
> make sure it is 1. I use a valid but unreachable ethernet address. I
> observe that ath_tx_processq is called at intervals ~10 times larger when
> txs_longretry=11 than when txs_longretry=1. My cwmin is 31, and cwmax is
> 1023. I then perform a different experiment where I send out 1500 b
> frames with longretry=1 and perform beb in the driver by doubling
> relevant cwmin up to 9 retries when ath_tx_processq is called. The time
> intervals at which ath_tx_processq is called are what you would expect
> (i.e. exponentially increasing along with the cwmin) s.t. the overall
> time for 10 retries is much larger than the 10x I would see in the
> previous experiment.
>
> If interested in a patch that enables the functionality I mention above:
> {{{
> Index: ath/if_ath.c
> ===================================================================
> --- ath/if_ath.c (revision 1705)
> +++ ath/if_ath.c (working copy)
> @@ -255,6 +255,7 @@
> static int countrycode = -1;
> static int outdoor = -1;
> static int xchanmode = -1;
> +static int ieeemode = -1; /* select channels by
> IEEE mode */
>
> static const char *hal_status_desc[] = {
> "No error",
> @@ -285,6 +286,7 @@
> MODULE_PARM(xchanmode, "i");
> MODULE_PARM(rfkill, "i");
> MODULE_PARM(autocreate, "s");
> +MODULE_PARM(ieeemode, "i");
> #else
> #include <linux/moduleparam.h>
> module_param(countrycode, int, 0);
> @@ -292,13 +294,17 @@
> module_param(xchanmode, int, 0);
> module_param(rfkill, int, 0);
> module_param(autocreate, charp, 0);
> +module_param(ieeemode, int, 0);
> #endif
> MODULE_PARM_DESC(countrycode, "Override default country code");
> MODULE_PARM_DESC(outdoor, "Enable/disable outdoor use");
> MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
> MODULE_PARM_DESC(rfkill, "Enable/disable RFKILL capability");
> MODULE_PARM_DESC(autocreate, "Create ath device in
> [sta|ap|wds|adhoc|ahdemo|monitor] mode. defaults to sta, use 'none' to
> disable");
> +MODULE_PARM_DESC(ieeemode, "Restrict 80211 mode ");
>
> +static int firstdevice = 1; // set to 0 as soon as one device
> initialized
> +
> static int ath_debug = 0;
> #ifdef AR_DEBUG
> #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
> @@ -335,12 +341,19 @@
> ATH_DEBUG_TURBO = 0x00400000, /* turbo/dynamice turbo
> */
> ATH_DEBUG_UAPSD = 0x00800000, /* uapsd */
> ATH_DEBUG_DOTH = 0x01000000, /* 11.h */
> + ATH_DEBUG_TIME = 0x20000000, /* use CURRENT_TIME on
> all debug printouts! */
> + ATH_DEBUG_SZYM = 0x40000000, /* szym routines */
> ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
> ATH_DEBUG_ANY = 0xffffffff
> };
> #define DPRINTF(sc, _m, _fmt, ...) do { \
> - if (sc->sc_debug & (_m)) \
> + if (sc->sc_debug & (_m)) { \
> + if (sc->sc_debug & ATH_DEBUG_TIME) { \
> + struct timespec ct = CURRENT_TIME; \
> + printk("%ld.%09ld ", ct.tv_sec, ct.tv_nsec); \
> + } \
> printk(_fmt, __VA_ARGS__); \
> + } \
> } while (0)
> #define KEYPRINTF(sc, ix, hk, mac) do { \
> if (sc->sc_debug & ATH_DEBUG_KEYCACHE) \
> @@ -390,6 +403,18 @@
> int autocreatemode = IEEE80211_M_STA;
> u_int8_t csz;
>
> + if(firstdevice == 0) {
> + printk("%s 0x%x: not first device...\n", dev->name,
> devid);
> + if(countrycode == 0x1ff) {
> + printk("%s 0x%x: Countrycode 0x1ff forbidden for
> non first devices!\n", dev->name, devid);
> + countrycode = 0x0;
> + }
> + }
> + if(countrycode != 0x1ff && ieeemode != -1) {
> + printk("%s 0x%x: ieeemode makes no sense for non-debug
> countrycode\n", dev->name, devid);
> + ieeemode = -1;
> + }
> +
> sc->devid = devid;
> sc->sc_debug = ath_debug;
> DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
> @@ -902,6 +927,8 @@
> dev->name, error);
> }
>
> + firstdevice = 0;
> +
> return 0;
> bad3:
> ieee80211_ifdetach(ic);
> @@ -5469,7 +5496,7 @@
> * allow through packets that have crypto
> problems).
> */
> if ((ds->ds_rxstat.rs_status &~
> - (HAL_RXERR_DECRYPT|HAL_RXERR_MIC)) ||
> +
> (HAL_RXERR_DECRYPT|HAL_RXERR_MIC|HAL_RXERR_CRC)) ||
> sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
> goto rx_next;
> }
> @@ -7008,6 +7035,94 @@
> #undef MIN
> }
>
> +static uint16_t
> +szym_get_cw(struct ath_softc *sc, int get_min) {
> + struct ath_hal *ah = sc->sc_ah;
> + HAL_TXQ_INFO qi;
> + u_int qnum = sc->sc_ac2q[WME_AC_BE]->axq_qnum;
> +
> + ath_hal_gettxqueueprops(ah, qnum, &qi);
> + if (get_min) {
> + return qi.tqi_cwmin;
> + } else {
> + return qi.tqi_cwmax;
> + }
> +}
> +
> +static void
> +szym_set_cw(struct ath_softc *sc, int set_min, uint16_t cw) {
> + struct ath_hal *ah = sc->sc_ah;
> + HAL_TXQ_INFO qi;
> + u_int qnum = sc->sc_ac2q[WME_AC_BE]->axq_qnum;
> +
> + ath_hal_gettxqueueprops(ah, qnum, &qi);
> + if (set_min && cw <= qi.tqi_cwmax) {
> + DPRINTF(sc, ATH_DEBUG_SZYM, "szym cwmin %d\n", cw);
> + qi.tqi_cwmin = cw;
> + } else if(cw >= qi.tqi_cwmin) {
> + DPRINTF(sc, ATH_DEBUG_SZYM, "szym cwmax %d\n", cw);
> + qi.tqi_cwmax = cw;
> + }
> + if (!ath_hal_settxqueueprops(ah, qnum, &qi)) {
> + printk("SZYM: unable to update hardware queue "
> + "paramers!\n");
> + } else {
> + ath_hal_resettxqueue(ah, qnum); /* push to h/w */
> + }
> +}
> +
> +
> +static void
> +szym_tx_updatecw(struct ath_softc *sc, struct ath_txq *txq, struct
> ath_tx_status *txs) {
> + struct ath_hal *ah = sc->sc_ah;
> + HAL_TXQ_INFO qi;
> +
> + struct timespec ct = CURRENT_TIME;
> +
> + u_int32_t tsf = 0;
> +
> + // XXX
> + if (sc->sc_szym_cw == -1)
> + return;
> +
> + tsf = ath_hal_gettsf32(sc->sc_ah);
> + if ((tsf & 0x7fff) < txs->ts_tstamp)
> + tsf -= 0x8000;
> + tsf = txs->ts_tstamp | (tsf &~ 0x7fff);
> +
> + ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
> +
> + DPRINTF(sc, ATH_DEBUG_SZYM, "szym %ld.%09ld ts %u txs %d srty %d
> lrty %d cwmin %d cwmax %d myrty %d\n",
> + ct.tv_sec, ct.tv_nsec,
> + tsf,
> + txs->ts_status, txs->ts_shortretry,
> txs->ts_longretry,
> + qi.tqi_cwmin, qi.tqi_cwmax,
> sc->sc_szym_retries);
> +
> + if (sc->sc_szym_cw == 0 || txq != sc->sc_ac2q[WME_AC_BE])
> + return;
> +
> + if (txs->ts_status == 0 || sc->sc_szym_retries >=
> sc->sc_szym_max_retries) {
> + /* the frame was successful (or no ACK needed or max
> retries hit), reset cwmin here */
> + qi.tqi_cwmin = (1<<(sc->sc_ic.ic_wme.wme_chanParams.
> + cap_wmeParams[WME_AC_BE].wmep_logcwmin))
> - 1;
> + sc->sc_szym_retries = 0;
> + } else {
> + /* the frame failed, double cwmin */
> + if ((qi.tqi_cwmin<<1) < qi.tqi_cwmax) {
> + qi.tqi_cwmin = (qi.tqi_cwmin<<1) + 1;
> + }
> + if(sc->sc_szym_cw > 1)
> + ++sc->sc_szym_retries;
> + }
> + if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
> + printk("SZYM: unable to update hardware queue "
> + "parameters\n");
> + } else {
> + if(1) ath_hal_resettxqueue(ah, txq->axq_qnum); /* push
> to h/w */
> + }
> +// ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
> +}
> +
> /*
> * Process completed xmit descriptors from the specified queue.
> * Should only be called from tasklet context
> @@ -7138,6 +7253,7 @@
> */
> ieee80211_free_node(ni);
> }
> + szym_tx_updatecw(sc, txq, &(ds->ds_txstat));
>
> bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
> bf->bf_skb->len, BUS_DMA_TODEVICE);
> @@ -8388,15 +8504,21 @@
> struct ath_hal *ah = sc->sc_ah;
> HAL_CHANNEL *chans;
> int i, nchan;
> + u_int mode = HAL_MODE_ALL;
>
> chans = kmalloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
> GFP_KERNEL);
> if (chans == NULL) {
> printk("%s: unable to allocate channel table\n",
> dev->name);
> return -ENOMEM;
> }
> +
> + if(ieeemode != -1) {
> + mode = ieeemode;
> + }
> +
> if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
> ic->ic_regclassids, IEEE80211_REGCLASSIDS_MAX,
> &ic->ic_nregclass,
> - cc, HAL_MODE_ALL, outdoor, xchanmode)) {
> + cc, mode, outdoor, xchanmode)) {
> u_int32_t rd;
>
> ath_hal_getregdomain(ah, &rd);
> @@ -9072,6 +9194,11 @@
> ATH_XR_POLL_PERIOD = 20,
> ATH_XR_POLL_COUNT = 21,
> ATH_ACKRATE = 22,
> + ATH_SZYM_CW = 23,
> + ATH_SZYM_CWMIN = 24,
> + ATH_SZYM_CWMAX = 25,
> + ATH_SZYM_CWMIND = 26,
> + ATH_SZYM_MAX_RETRIES = 27,
> };
>
> static int
> @@ -9201,6 +9328,22 @@
> sc->sc_ackrate = val;
> ath_set_ack_bitrate(sc, sc->sc_ackrate);
> break;
> + case ATH_SZYM_CW:
> + sc->sc_szym_cw = val;
> + DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s:
> szym_cw = %d", __func__, val);
> + break;
> + case ATH_SZYM_CWMIN: case ATH_SZYM_CWMAX:
> + szym_set_cw(sc, ctl->ctl_name ==
> ATH_SZYM_CWMIN, val);
> + break;
> + case ATH_SZYM_CWMIND:
> + sc->sc_ic.ic_wme.wme_chanParams.
> +
> cap_wmeParams[WME_AC_BE].wmep_logcwmin = val;
> + DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s:
> szym_cwmind = %d", __func__, val);
> + break;
> + case ATH_SZYM_MAX_RETRIES:
> + sc->sc_szym_max_retries = val;
> + DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s:
> szym_max_retries = %d", __func__, val);
> + break;
> default:
> return -EINVAL;
> }
> @@ -9260,6 +9403,19 @@
> case ATH_ACKRATE:
> val = sc->sc_ackrate;
> break;
> + case ATH_SZYM_CW:
> + val = sc->sc_szym_cw;
> + break;
> + case ATH_SZYM_CWMIN: case ATH_SZYM_CWMAX:
> + val = szym_get_cw(sc, ctl->ctl_name ==
> ATH_SZYM_CWMIN);
> + break;
> + case ATH_SZYM_CWMIND:
> + val = sc->sc_ic.ic_wme.wme_chanParams.
> + cap_wmeParams[WME_AC_BE].wmep_logcwmin;
> + break;
> + case ATH_SZYM_MAX_RETRIES:
> + val = sc->sc_szym_max_retries;
> + break;
> default:
> return -EINVAL;
> }
> @@ -9363,6 +9519,31 @@
> .mode = 0644,
> .proc_handler = ath_sysctl_halparam
> },
> + { .ctl_name = ATH_SZYM_CW,
> + .procname = "szym_cw",
> + .mode = 0644,
> + .proc_handler = ath_sysctl_halparam
> + },
> + { .ctl_name = ATH_SZYM_CWMIN,
> + .procname = "szym_cwmin", /* FIXME: currently only for
> the BE queue */
> + .mode = 0644,
> + .proc_handler = ath_sysctl_halparam
> + },
> + { .ctl_name = ATH_SZYM_CWMAX,
> + .procname = "szym_cwmax",
> + .mode = 0644,
> + .proc_handler = ath_sysctl_halparam
> + },
> + { .ctl_name = ATH_SZYM_CWMIND,
> + .procname = "szym_cwmind",
> + .mode = 0644,
> + .proc_handler = ath_sysctl_halparam
> + },
> + { .ctl_name = ATH_SZYM_MAX_RETRIES,
> + .procname = "szym_retries",
> + .mode = 0644,
> + .proc_handler = ath_sysctl_halparam
> + },
> { 0 }
> };
>
> Index: ath/if_athvar.h
> ===================================================================
> --- ath/if_athvar.h (revision 1705)
> +++ ath/if_athvar.h (working copy)
> @@ -673,6 +673,11 @@
> u_int32_t sc_dturbo_bw_turbo; /* bandwidth threshold */
> #endif
> u_int sc_slottimeconf; /* manual override for
> slottime */
> +
> +
> + u_int sc_szym_cw; /* enable
> szym_tx_updatecw */
> + u_int sc_szym_retries; /* current retry count */
> + u_int sc_szym_max_retries; /* max retry count */
> };
>
> typedef void (*ath_callback) (struct ath_softc *);
>
> }}}
New description:
A simple experiment shows beb (binary exponential backoff) is not done in
the madwifi HAL. I use a netgear wag311 card and a single computer sending
out 1500 b frames. I add a simple DPRINTF to see at what time the function
ath_tx_processq is called. I make sure that in one experiment
txs_longretry of ath_tx_status struct is 11. In another experiement I make
sure it is 1. I use a valid but unreachable ethernet address. I observe
that ath_tx_processq is called at intervals ~10 times larger when
txs_longretry=11 than when txs_longretry=1. My cwmin is 31, and cwmax is
1023. I then perform a different experiment where I send out 1500 b frames
with longretry=1 and perform beb in the driver by doubling relevant cwmin
up to 9 retries when ath_tx_processq is called. The time intervals at
which ath_tx_processq is called are what you would expect (i.e.
exponentially increasing along with the cwmin) s.t. the overall time for
10 retries is much larger than the 10x I would see in the previous
experiment.
If interested in a patch that enables the functionality I mention above:
{{{
Index: ath/if_ath.c
===================================================================
--- ath/if_ath.c (revision 1705)
+++ ath/if_ath.c (working copy)
@@ -255,6 +255,7 @@
static int countrycode = -1;
static int outdoor = -1;
static int xchanmode = -1;
+static int ieeemode = -1; /* select channels by IEEE
mode */
static const char *hal_status_desc[] = {
"No error",
@@ -285,6 +286,7 @@
MODULE_PARM(xchanmode, "i");
MODULE_PARM(rfkill, "i");
MODULE_PARM(autocreate, "s");
+MODULE_PARM(ieeemode, "i");
#else
#include <linux/moduleparam.h>
module_param(countrycode, int, 0);
@@ -292,13 +294,17 @@
module_param(xchanmode, int, 0);
module_param(rfkill, int, 0);
module_param(autocreate, charp, 0);
+module_param(ieeemode, int, 0);
#endif
MODULE_PARM_DESC(countrycode, "Override default country code");
MODULE_PARM_DESC(outdoor, "Enable/disable outdoor use");
MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
MODULE_PARM_DESC(rfkill, "Enable/disable RFKILL capability");
MODULE_PARM_DESC(autocreate, "Create ath device in
[sta|ap|wds|adhoc|ahdemo|monitor] mode. defaults to sta, use 'none' to
disable");
+MODULE_PARM_DESC(ieeemode, "Restrict 80211 mode ");
+static int firstdevice = 1; // set to 0 as soon as one device
initialized
+
static int ath_debug = 0;
#ifdef AR_DEBUG
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
@@ -335,12 +341,19 @@
ATH_DEBUG_TURBO = 0x00400000, /* turbo/dynamice turbo */
ATH_DEBUG_UAPSD = 0x00800000, /* uapsd */
ATH_DEBUG_DOTH = 0x01000000, /* 11.h */
+ ATH_DEBUG_TIME = 0x20000000, /* use CURRENT_TIME on all
debug printouts! */
+ ATH_DEBUG_SZYM = 0x40000000, /* szym routines */
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
ATH_DEBUG_ANY = 0xffffffff
};
#define DPRINTF(sc, _m, _fmt, ...) do { \
- if (sc->sc_debug & (_m)) \
+ if (sc->sc_debug & (_m)) { \
+ if (sc->sc_debug & ATH_DEBUG_TIME) { \
+ struct timespec ct = CURRENT_TIME; \
+ printk("%ld.%09ld ", ct.tv_sec, ct.tv_nsec); \
+ } \
printk(_fmt, __VA_ARGS__); \
+ } \
} while (0)
#define KEYPRINTF(sc, ix, hk, mac) do { \
if (sc->sc_debug & ATH_DEBUG_KEYCACHE) \
@@ -390,6 +403,18 @@
int autocreatemode = IEEE80211_M_STA;
u_int8_t csz;
+ if(firstdevice == 0) {
+ printk("%s 0x%x: not first device...\n", dev->name,
devid);
+ if(countrycode == 0x1ff) {
+ printk("%s 0x%x: Countrycode 0x1ff forbidden for
non first devices!\n", dev->name, devid);
+ countrycode = 0x0;
+ }
+ }
+ if(countrycode != 0x1ff && ieeemode != -1) {
+ printk("%s 0x%x: ieeemode makes no sense for non-debug
countrycode\n", dev->name, devid);
+ ieeemode = -1;
+ }
+
sc->devid = devid;
sc->sc_debug = ath_debug;
DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
@@ -902,6 +927,8 @@
dev->name, error);
}
+ firstdevice = 0;
+
return 0;
bad3:
ieee80211_ifdetach(ic);
@@ -5469,7 +5496,7 @@
* allow through packets that have crypto
problems).
*/
if ((ds->ds_rxstat.rs_status &~
- (HAL_RXERR_DECRYPT|HAL_RXERR_MIC)) ||
+
(HAL_RXERR_DECRYPT|HAL_RXERR_MIC|HAL_RXERR_CRC)) ||
sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
goto rx_next;
}
@@ -7008,6 +7035,94 @@
#undef MIN
}
+static uint16_t
+szym_get_cw(struct ath_softc *sc, int get_min) {
+ struct ath_hal *ah = sc->sc_ah;
+ HAL_TXQ_INFO qi;
+ u_int qnum = sc->sc_ac2q[WME_AC_BE]->axq_qnum;
+
+ ath_hal_gettxqueueprops(ah, qnum, &qi);
+ if (get_min) {
+ return qi.tqi_cwmin;
+ } else {
+ return qi.tqi_cwmax;
+ }
+}
+
+static void
+szym_set_cw(struct ath_softc *sc, int set_min, uint16_t cw) {
+ struct ath_hal *ah = sc->sc_ah;
+ HAL_TXQ_INFO qi;
+ u_int qnum = sc->sc_ac2q[WME_AC_BE]->axq_qnum;
+
+ ath_hal_gettxqueueprops(ah, qnum, &qi);
+ if (set_min && cw <= qi.tqi_cwmax) {
+ DPRINTF(sc, ATH_DEBUG_SZYM, "szym cwmin %d\n", cw);
+ qi.tqi_cwmin = cw;
+ } else if(cw >= qi.tqi_cwmin) {
+ DPRINTF(sc, ATH_DEBUG_SZYM, "szym cwmax %d\n", cw);
+ qi.tqi_cwmax = cw;
+ }
+ if (!ath_hal_settxqueueprops(ah, qnum, &qi)) {
+ printk("SZYM: unable to update hardware queue "
+ "paramers!\n");
+ } else {
+ ath_hal_resettxqueue(ah, qnum); /* push to h/w */
+ }
+}
+
+
+static void
+szym_tx_updatecw(struct ath_softc *sc, struct ath_txq *txq, struct
ath_tx_status *txs) {
+ struct ath_hal *ah = sc->sc_ah;
+ HAL_TXQ_INFO qi;
+
+ struct timespec ct = CURRENT_TIME;
+
+ u_int32_t tsf = 0;
+
+ // XXX
+ if (sc->sc_szym_cw == -1)
+ return;
+
+ tsf = ath_hal_gettsf32(sc->sc_ah);
+ if ((tsf & 0x7fff) < txs->ts_tstamp)
+ tsf -= 0x8000;
+ tsf = txs->ts_tstamp | (tsf &~ 0x7fff);
+
+ ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
+
+ DPRINTF(sc, ATH_DEBUG_SZYM, "szym %ld.%09ld ts %u txs %d srty %d
lrty %d cwmin %d cwmax %d myrty %d\n",
+ ct.tv_sec, ct.tv_nsec,
+ tsf,
+ txs->ts_status, txs->ts_shortretry,
txs->ts_longretry,
+ qi.tqi_cwmin, qi.tqi_cwmax, sc->sc_szym_retries);
+
+ if (sc->sc_szym_cw == 0 || txq != sc->sc_ac2q[WME_AC_BE])
+ return;
+
+ if (txs->ts_status == 0 || sc->sc_szym_retries >=
sc->sc_szym_max_retries) {
+ /* the frame was successful (or no ACK needed or max
retries hit), reset cwmin here */
+ qi.tqi_cwmin = (1<<(sc->sc_ic.ic_wme.wme_chanParams.
+ cap_wmeParams[WME_AC_BE].wmep_logcwmin))
- 1;
+ sc->sc_szym_retries = 0;
+ } else {
+ /* the frame failed, double cwmin */
+ if ((qi.tqi_cwmin<<1) < qi.tqi_cwmax) {
+ qi.tqi_cwmin = (qi.tqi_cwmin<<1) + 1;
+ }
+ if(sc->sc_szym_cw > 1)
+ ++sc->sc_szym_retries;
+ }
+ if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
+ printk("SZYM: unable to update hardware queue "
+ "parameters\n");
+ } else {
+ if(1) ath_hal_resettxqueue(ah, txq->axq_qnum); /* push to
h/w */
+ }
+// ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
+}
+
/*
* Process completed xmit descriptors from the specified queue.
* Should only be called from tasklet context
@@ -7138,6 +7253,7 @@
*/
ieee80211_free_node(ni);
}
+ szym_tx_updatecw(sc, txq, &(ds->ds_txstat));
bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
bf->bf_skb->len, BUS_DMA_TODEVICE);
@@ -8388,15 +8504,21 @@
struct ath_hal *ah = sc->sc_ah;
HAL_CHANNEL *chans;
int i, nchan;
+ u_int mode = HAL_MODE_ALL;
chans = kmalloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
GFP_KERNEL);
if (chans == NULL) {
printk("%s: unable to allocate channel table\n",
dev->name);
return -ENOMEM;
}
+
+ if(ieeemode != -1) {
+ mode = ieeemode;
+ }
+
if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
ic->ic_regclassids, IEEE80211_REGCLASSIDS_MAX,
&ic->ic_nregclass,
- cc, HAL_MODE_ALL, outdoor, xchanmode)) {
+ cc, mode, outdoor, xchanmode)) {
u_int32_t rd;
ath_hal_getregdomain(ah, &rd);
@@ -9072,6 +9194,11 @@
ATH_XR_POLL_PERIOD = 20,
ATH_XR_POLL_COUNT = 21,
ATH_ACKRATE = 22,
+ ATH_SZYM_CW = 23,
+ ATH_SZYM_CWMIN = 24,
+ ATH_SZYM_CWMAX = 25,
+ ATH_SZYM_CWMIND = 26,
+ ATH_SZYM_MAX_RETRIES = 27,
};
static int
@@ -9201,6 +9328,22 @@
sc->sc_ackrate = val;
ath_set_ack_bitrate(sc, sc->sc_ackrate);
break;
+ case ATH_SZYM_CW:
+ sc->sc_szym_cw = val;
+ DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s:
szym_cw = %d", __func__, val);
+ break;
+ case ATH_SZYM_CWMIN: case ATH_SZYM_CWMAX:
+ szym_set_cw(sc, ctl->ctl_name ==
ATH_SZYM_CWMIN, val);
+ break;
+ case ATH_SZYM_CWMIND:
+ sc->sc_ic.ic_wme.wme_chanParams.
+
cap_wmeParams[WME_AC_BE].wmep_logcwmin = val;
+ DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s:
szym_cwmind = %d", __func__, val);
+ break;
+ case ATH_SZYM_MAX_RETRIES:
+ sc->sc_szym_max_retries = val;
+ DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s:
szym_max_retries = %d", __func__, val);
+ break;
default:
return -EINVAL;
}
@@ -9260,6 +9403,19 @@
case ATH_ACKRATE:
val = sc->sc_ackrate;
break;
+ case ATH_SZYM_CW:
+ val = sc->sc_szym_cw;
+ break;
+ case ATH_SZYM_CWMIN: case ATH_SZYM_CWMAX:
+ val = szym_get_cw(sc, ctl->ctl_name ==
ATH_SZYM_CWMIN);
+ break;
+ case ATH_SZYM_CWMIND:
+ val = sc->sc_ic.ic_wme.wme_chanParams.
+ cap_wmeParams[WME_AC_BE].wmep_logcwmin;
+ break;
+ case ATH_SZYM_MAX_RETRIES:
+ val = sc->sc_szym_max_retries;
+ break;
default:
return -EINVAL;
}
@@ -9363,6 +9519,31 @@
.mode = 0644,
.proc_handler = ath_sysctl_halparam
},
+ { .ctl_name = ATH_SZYM_CW,
+ .procname = "szym_cw",
+ .mode = 0644,
+ .proc_handler = ath_sysctl_halparam
+ },
+ { .ctl_name = ATH_SZYM_CWMIN,
+ .procname = "szym_cwmin", /* FIXME: currently only for the
BE queue */
+ .mode = 0644,
+ .proc_handler = ath_sysctl_halparam
+ },
+ { .ctl_name = ATH_SZYM_CWMAX,
+ .procname = "szym_cwmax",
+ .mode = 0644,
+ .proc_handler = ath_sysctl_halparam
+ },
+ { .ctl_name = ATH_SZYM_CWMIND,
+ .procname = "szym_cwmind",
+ .mode = 0644,
+ .proc_handler = ath_sysctl_halparam
+ },
+ { .ctl_name = ATH_SZYM_MAX_RETRIES,
+ .procname = "szym_retries",
+ .mode = 0644,
+ .proc_handler = ath_sysctl_halparam
+ },
{ 0 }
};
Index: ath/if_athvar.h
===================================================================
--- ath/if_athvar.h (revision 1705)
+++ ath/if_athvar.h (working copy)
@@ -673,6 +673,11 @@
u_int32_t sc_dturbo_bw_turbo; /* bandwidth threshold */
#endif
u_int sc_slottimeconf; /* manual override for
slottime */
+
+
+ u_int sc_szym_cw; /* enable szym_tx_updatecw
*/
+ u_int sc_szym_retries; /* current retry count */
+ u_int sc_szym_max_retries; /* max retry count */
};
typedef void (*ath_callback) (struct ath_softc *);
}}}
--
Ticket URL: <http://madwifi.org/ticket/852>
MadWifi <http://madwifi.org/>
Multiband Atheros Driver for Wireless Fidelity-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Madwifi-tickets mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/madwifi-tickets