diff options
author | Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> | 2012-02-29 15:14:38 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:06:40 +0200 |
commit | 9da830b2f4b7cb886d6b0d816bd7b857271e4c8e (patch) | |
tree | 182566b78402319845108e4042e46ef32f8f6251 | |
parent | fc8126b0320d96e97f64122a1114d4da10507f2e (diff) |
cw1200: TX burst forming.
The patch implements simple TX burst forming.
ST-Ericsson ID: 355241, 355096, 355166, 355221
Change-Id: Ied9fb8c619783881b3fc22e16829ee13bb651cdc
Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/36790
Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Tested-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
-rw-r--r-- | drivers/staging/cw1200/bh.c | 25 | ||||
-rw-r--r-- | drivers/staging/cw1200/debug.c | 4 | ||||
-rw-r--r-- | drivers/staging/cw1200/debug.h | 20 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.c | 14 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.h | 5 |
5 files changed, 60 insertions, 8 deletions
diff --git a/drivers/staging/cw1200/bh.c b/drivers/staging/cw1200/bh.c index acc16459807..1f7409fbff4 100644 --- a/drivers/staging/cw1200/bh.c +++ b/drivers/staging/cw1200/bh.c @@ -22,6 +22,7 @@ #include "hwio.h" #include "wsm.h" #include "sbus.h" +#include "debug.h" #if defined(CONFIG_CW1200_BH_DEBUG) #define bh_printk(...) printk(__VA_ARGS__) @@ -261,6 +262,8 @@ static int cw1200_bh(void *arg) u16 ctrl_reg = 0; int tx_allowed; int pending_tx = 0; + int tx_burst; + int rx_burst = 0; long status; u8 dummy; @@ -339,8 +342,10 @@ static int cw1200_bh(void *arg) break; rx: read_len = (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2; - if (!read_len) + if (!read_len) { + rx_burst = 0; goto tx; + } if (WARN_ON((read_len < sizeof(struct wsm_hdr)) || (read_len > EFFECTIVE_BUF_SIZE))) { @@ -425,13 +430,19 @@ rx: } read_len = 0; + + if (rx_burst) { + cw1200_debug_rx_burst(priv); + --rx_burst; + goto rx; + } } tx: /* HACK! One buffer is reserved for control path */ BUG_ON(priv->hw_bufs_used > priv->wsm_caps.numInpChBufs); - tx_allowed = - priv->hw_bufs_used < priv->wsm_caps.numInpChBufs; + tx_burst = priv->wsm_caps.numInpChBufs - priv->hw_bufs_used; + tx_allowed = tx_burst > 0; if (tx && tx_allowed) { size_t tx_len; @@ -452,7 +463,7 @@ tx: } wsm_alloc_tx_buffer(priv); - ret = wsm_get_tx(priv, &data, &tx_len); + ret = wsm_get_tx(priv, &data, &tx_len, &tx_burst); if (ret <= 0) { wsm_release_tx_buffer(priv, 1); if (WARN_ON(ret < 0)) @@ -503,6 +514,12 @@ tx: wsm_txed(priv, data); priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX; + + if (tx_burst > 1) { + cw1200_debug_tx_burst(priv); + ++rx_burst; + goto tx; + } } } diff --git a/drivers/staging/cw1200/debug.c b/drivers/staging/cw1200/debug.c index 50941846e28..597f94de87f 100644 --- a/drivers/staging/cw1200/debug.c +++ b/drivers/staging/cw1200/debug.c @@ -291,6 +291,10 @@ static int cw1200_status_show(struct seq_file *seq, void *v) d->tx_cache_miss); seq_printf(seq, "TX align: %d\n", d->tx_align); + seq_printf(seq, "TX burst: %d\n", + d->tx_burst); + seq_printf(seq, "RX burst: %d\n", + d->rx_burst); seq_printf(seq, "TX TTL: %d\n", d->tx_ttl); seq_printf(seq, "Scan: %s\n", diff --git a/drivers/staging/cw1200/debug.h b/drivers/staging/cw1200/debug.h index 96b11feab1c..02943e699b8 100644 --- a/drivers/staging/cw1200/debug.h +++ b/drivers/staging/cw1200/debug.h @@ -27,6 +27,8 @@ struct cw1200_debug_priv { int tx_cache_miss; int tx_align; int tx_ttl; + int tx_burst; + int rx_burst; }; int cw1200_debug_init(struct cw1200_common *priv); @@ -74,6 +76,16 @@ static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv) ++priv->debug->tx_ttl; } +static inline void cw1200_debug_tx_burst(struct cw1200_common *priv) +{ + ++priv->debug->tx_burst; +} + +static inline void cw1200_debug_rx_burst(struct cw1200_common *priv) +{ + ++priv->debug->rx_burst; +} + #else /* CONFIG_CW1200_DEBUGFS */ static inline int cw1200_debug_init(struct cw1200_common *priv) @@ -118,6 +130,14 @@ static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv) { } +static inline void cw1200_debug_tx_burst(struct cw1200_common *priv) +{ +} + +static inline void cw1200_debug_rx_burst(struct cw1200_common *priv) +{ +} + #endif /* CONFIG_CW1200_DEBUGFS */ #endif /* CW1200_DEBUG_H_INCLUDED */ diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c index add382d78ee..a93ecc534ca 100644 --- a/drivers/staging/cw1200/wsm.c +++ b/drivers/staging/cw1200/wsm.c @@ -1548,13 +1548,15 @@ found: } int wsm_get_tx(struct cw1200_common *priv, u8 **data, - size_t *tx_len) + size_t *tx_len, int *burst) { struct wsm_tx *wsm = NULL; struct ieee80211_tx_info *tx_info; struct cw1200_queue *queue = NULL; + int queue_num; u32 tx_allowed_mask = 0; const struct cw1200_txpriv *txpriv = NULL; + static const int trottle[] = { 0, 2, 4, 6 }; /* * Count was intended as an input for wsm->more flag. * During implementation it was found that wsm->more @@ -1572,6 +1574,7 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, BUG_ON(!priv->wsm_cmd.ptr); *data = priv->wsm_cmd.ptr; *tx_len = priv->wsm_cmd.len; + *burst = 1; spin_unlock(&priv->wsm_cmd.lock); } else { for (;;) { @@ -1584,6 +1587,7 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, ret = wsm_get_tx_queue_and_mask(priv, &queue, &tx_allowed_mask, &more); + queue_num = queue - priv->tx_queue; if (priv->buffered_multicasts && (ret || !more) && @@ -1617,7 +1621,13 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, *data = (u8 *)wsm; *tx_len = __le16_to_cpu(wsm->hdr.len); - + if (priv->sta_asleep_mask) + *burst = 1; + else + *burst = min(max( + *burst - trottle[queue_num], 1), + (int)cw1200_queue_get_num_queued( + queue, -1)); if (more) { struct ieee80211_hdr *hdr = diff --git a/drivers/staging/cw1200/wsm.h b/drivers/staging/cw1200/wsm.h index 635c9c7fca1..61c1d5b8a02 100644 --- a/drivers/staging/cw1200/wsm.h +++ b/drivers/staging/cw1200/wsm.h @@ -1716,8 +1716,9 @@ struct wsm_cmd { /* ******************************************************************** */ /* WSM TX buffer access */ -int wsm_get_tx(struct cw1200_common *priv, u8 ** data, size_t * tx_len); -void wsm_txed(struct cw1200_common *priv, u8 * data); +int wsm_get_tx(struct cw1200_common *priv, u8 **data, + size_t *tx_len, int *burst); +void wsm_txed(struct cw1200_common *priv, u8 *data); /* ******************************************************************** */ /* Queue mapping: WSM <---> linux */ |