wl12xx: add support for rx streaming
authorEliad Peller <eliad@wizery.com>
Sun, 15 May 2011 08:10:28 +0000 (11:10 +0300)
committerLuciano Coelho <coelho@ti.com>
Mon, 27 Jun 2011 07:15:48 +0000 (10:15 +0300)
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>
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/main.c

index c6ee530..edb389d 100644 (file)
@@ -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;
index 9a895e3..f1d5531 100644 (file)
@@ -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);
index c83fefb..94a5c56 100644 (file)
@@ -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;
 };
 
index f37f0b8..a2171a4 100644 (file)
@@ -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,
 };