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>
This commit is contained in:
parent
ba2274c68e
commit
f84673d597
|
@ -1577,6 +1577,53 @@ out:
|
||||||
return ret;
|
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)
|
int wl1271_acx_max_tx_retry(struct wl1271 *wl)
|
||||||
{
|
{
|
||||||
struct wl1271_acx_max_tx_retry *acx = NULL;
|
struct wl1271_acx_max_tx_retry *acx = NULL;
|
||||||
|
|
|
@ -1153,6 +1153,19 @@ struct wl1271_acx_fw_tsf_information {
|
||||||
u8 padding[3];
|
u8 padding[3];
|
||||||
} __packed;
|
} __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 wl1271_acx_max_tx_retry {
|
||||||
struct acx_header header;
|
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,
|
int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
|
||||||
bool enable);
|
bool enable);
|
||||||
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
|
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_max_tx_retry(struct wl1271 *wl);
|
||||||
int wl1271_acx_config_ps(struct wl1271 *wl);
|
int wl1271_acx_config_ps(struct wl1271 *wl);
|
||||||
int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
|
int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
|
||||||
|
|
|
@ -1248,6 +1248,30 @@ struct conf_fm_coex {
|
||||||
u8 swallow_clk_diff;
|
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_drv_settings {
|
||||||
struct conf_sg_settings sg;
|
struct conf_sg_settings sg;
|
||||||
struct conf_rx_settings rx;
|
struct conf_rx_settings rx;
|
||||||
|
@ -1263,6 +1287,7 @@ struct conf_drv_settings {
|
||||||
struct conf_memory_settings mem_wl127x;
|
struct conf_memory_settings mem_wl127x;
|
||||||
struct conf_memory_settings mem_wl128x;
|
struct conf_memory_settings mem_wl128x;
|
||||||
struct conf_fm_coex fm_coex;
|
struct conf_fm_coex fm_coex;
|
||||||
|
struct conf_rx_streaming_settings rx_streaming;
|
||||||
u8 hci_io_ds;
|
u8 hci_io_ds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -362,6 +362,11 @@ static struct conf_drv_settings default_conf = {
|
||||||
.fm_disturbed_band_margin = 0xff, /* default */
|
.fm_disturbed_band_margin = 0xff, /* default */
|
||||||
.swallow_clk_diff = 0xff, /* default */
|
.swallow_clk_diff = 0xff, /* default */
|
||||||
},
|
},
|
||||||
|
.rx_streaming = {
|
||||||
|
.duration = 150,
|
||||||
|
.queues = 0x1,
|
||||||
|
.interval = 20,
|
||||||
|
},
|
||||||
.hci_io_ds = HCI_IO_DS_6MA,
|
.hci_io_ds = HCI_IO_DS_6MA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue