summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>2012-02-29 15:14:38 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:06:40 +0200
commit9da830b2f4b7cb886d6b0d816bd7b857271e4c8e (patch)
tree182566b78402319845108e4042e46ef32f8f6251
parentfc8126b0320d96e97f64122a1114d4da10507f2e (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.c25
-rw-r--r--drivers/staging/cw1200/debug.c4
-rw-r--r--drivers/staging/cw1200/debug.h20
-rw-r--r--drivers/staging/cw1200/wsm.c14
-rw-r--r--drivers/staging/cw1200/wsm.h5
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 */