summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_acx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_acx.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c146
1 files changed, 141 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index adaa3f2485c..2ad086efe06 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -505,12 +505,17 @@ out:
return ret;
}
-int wl1271_acx_conn_monit_params(struct wl1271 *wl)
+#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff
+
+int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
{
struct acx_conn_monit_params *acx;
+ u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
+ u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
int ret;
- wl1271_debug(DEBUG_ACX, "acx connection monitor parameters");
+ wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
+ enable ? "enabled" : "disabled");
acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx) {
@@ -518,8 +523,13 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl)
goto out;
}
- acx->synch_fail_thold = cpu_to_le32(wl->conf.conn.synch_fail_thold);
- acx->bss_lose_timeout = cpu_to_le32(wl->conf.conn.bss_lose_timeout);
+ if (enable) {
+ threshold = wl->conf.conn.synch_fail_thold;
+ timeout = wl->conf.conn.bss_lose_timeout;
+ }
+
+ acx->synch_fail_thold = cpu_to_le32(threshold);
+ acx->bss_lose_timeout = cpu_to_le32(timeout);
ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
acx, sizeof(*acx));
@@ -793,7 +803,7 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
/* configure one basic rate class */
idx = ACX_TX_BASIC_RATE;
- acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set);
+ acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
acx->rate_class[idx].aflags = c->aflags;
@@ -1130,3 +1140,129 @@ out:
kfree(acx);
return ret;
}
+
+int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
+{
+ struct wl1271_acx_keep_alive_mode *acx = NULL;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->enabled = enable;
+
+ ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx keep alive mode failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
+int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
+{
+ struct wl1271_acx_keep_alive_config *acx = NULL;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx keep alive config");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
+ acx->index = index;
+ acx->tpl_validation = tpl_valid;
+ acx->trigger = ACX_KEEP_ALIVE_NO_TX;
+
+ ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
+ acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx keep alive config failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
+int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
+ s16 thold, u8 hyst)
+{
+ struct wl1271_acx_rssi_snr_trigger *acx = NULL;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ wl->last_rssi_event = -1;
+
+ acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
+ acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
+ acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
+ if (enable)
+ acx->enable = WL1271_ACX_TRIG_ENABLE;
+ else
+ acx->enable = WL1271_ACX_TRIG_DISABLE;
+
+ acx->index = WL1271_ACX_TRIG_IDX_RSSI;
+ acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
+ acx->threshold = cpu_to_le16(thold);
+ acx->hysteresis = hyst;
+
+ ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
+int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
+{
+ struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
+ struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->rssi_beacon = c->avg_weight_rssi_beacon;
+ acx->rssi_data = c->avg_weight_rssi_data;
+ acx->snr_beacon = c->avg_weight_snr_beacon;
+ acx->snr_data = c->avg_weight_snr_data;
+
+ ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}