summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-05-15 11:10:28 +0300
committerLuciano Coelho <coelho@ti.com>2011-06-27 10:15:48 +0300
commitf84673d59773ded6efab640c5ee5f44b34116b75 (patch)
tree03008adebfab66632726f430d1ac148c309650e6
parentba2274c68e103271ba0c70fb8ad9afb4ede42d20 (diff)
wl12xx: add support for rx streaming
wl12xx supports the "rx streaming" feature: When in ps mode, and @timeout msecs have been passed since the last rx/tx, it issues trigger packets (QoS-null/PS-Poll packets, according to the ac type) in const intervals (in order to reduce the rx time). Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/wl12xx/acx.c47
-rw-r--r--drivers/net/wireless/wl12xx/acx.h14
-rw-r--r--drivers/net/wireless/wl12xx/conf.h25
-rw-r--r--drivers/net/wireless/wl12xx/main.c5
4 files changed, 91 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index c6ee530e5bf..edb389d6a29 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1577,6 +1577,53 @@ out:
return ret;
}
+int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable)
+{
+ struct wl1271_acx_ps_rx_streaming *rx_streaming;
+ u32 conf_queues, enable_queues;
+ int i, ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx ps rx streaming");
+
+ rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL);
+ if (!rx_streaming) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ conf_queues = wl->conf.rx_streaming.queues;
+ if (enable)
+ enable_queues = conf_queues;
+ else
+ enable_queues = 0;
+
+ for (i = 0; i < 8; i++) {
+ /*
+ * Skip non-changed queues, to avoid redundant acxs.
+ * this check assumes conf.rx_streaming.queues can't
+ * be changed while rx_streaming is enabled.
+ */
+ if (!(conf_queues & BIT(i)))
+ continue;
+
+ rx_streaming->tid = i;
+ rx_streaming->enable = enable_queues & BIT(i);
+ rx_streaming->period = wl->conf.rx_streaming.interval;
+ rx_streaming->timeout = wl->conf.rx_streaming.interval;
+
+ ret = wl1271_cmd_configure(wl, ACX_PS_RX_STREAMING,
+ rx_streaming,
+ sizeof(*rx_streaming));
+ if (ret < 0) {
+ wl1271_warning("acx ps rx streaming failed: %d", ret);
+ goto out;
+ }
+ }
+out:
+ kfree(rx_streaming);
+ return ret;
+}
+
int wl1271_acx_max_tx_retry(struct wl1271 *wl)
{
struct wl1271_acx_max_tx_retry *acx = NULL;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 9a895e3cc61..f1d55313617 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1153,6 +1153,19 @@ struct wl1271_acx_fw_tsf_information {
u8 padding[3];
} __packed;
+struct wl1271_acx_ps_rx_streaming {
+ struct acx_header header;
+
+ u8 tid;
+ u8 enable;
+
+ /* interval between triggers (10-100 msec) */
+ u8 period;
+
+ /* timeout before first trigger (0-200 msec) */
+ u8 timeout;
+} __packed;
+
struct wl1271_acx_max_tx_retry {
struct acx_header header;
@@ -1384,6 +1397,7 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
bool enable);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
+int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable);
int wl1271_acx_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_config_ps(struct wl1271 *wl);
int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index c83fefb6662..94a5c5646bb 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -1248,6 +1248,30 @@ struct conf_fm_coex {
u8 swallow_clk_diff;
};
+struct conf_rx_streaming_settings {
+ /*
+ * RX Streaming duration (in msec) from last tx/rx
+ *
+ * Range: u32
+ */
+ u32 duration;
+
+ /*
+ * Bitmap of tids to be polled during RX streaming.
+ * (Note: it doesn't look like it really matters)
+ *
+ * Range: 0x1-0xff
+ */
+ u8 queues;
+
+ /*
+ * RX Streaming interval.
+ * (Note:this value is also used as the rx streaming timeout)
+ * Range: 0 (disabled), 10 - 100
+ */
+ u8 interval;
+};
+
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
@@ -1263,6 +1287,7 @@ struct conf_drv_settings {
struct conf_memory_settings mem_wl127x;
struct conf_memory_settings mem_wl128x;
struct conf_fm_coex fm_coex;
+ struct conf_rx_streaming_settings rx_streaming;
u8 hci_io_ds;
};
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index f37f0b873c7..a2171a4e941 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -362,6 +362,11 @@ static struct conf_drv_settings default_conf = {
.fm_disturbed_band_margin = 0xff, /* default */
.swallow_clk_diff = 0xff, /* default */
},
+ .rx_streaming = {
+ .duration = 150,
+ .queues = 0x1,
+ .interval = 20,
+ },
.hci_io_ds = HCI_IO_DS_6MA,
};