Merge git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6
[linux-2.6.git] / drivers / net / wireless / wl12xx / acx.c
index b1b5139..34f6ab5 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/crc7.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 
@@ -78,8 +77,6 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
        auth->sleep_auth = sleep_auth;
 
        ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
-       if (ret < 0)
-               return ret;
 
 out:
        kfree(auth);
@@ -91,7 +88,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
        struct acx_current_tx_power *acx;
        int ret;
 
-       wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+       wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power);
 
        if (power < 0 || power > 25)
                return -EINVAL;
@@ -325,12 +322,19 @@ out:
        return ret;
 }
 
-int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold)
 {
        struct acx_rts_threshold *rts;
        int ret;
 
-       wl1271_debug(DEBUG_ACX, "acx rts threshold");
+       /*
+        * If the RTS threshold is not configured or out of range, use the
+        * default value.
+        */
+       if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
+               rts_threshold = wl->conf.rx.rts_threshold;
+
+       wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
 
        rts = kzalloc(sizeof(*rts), GFP_KERNEL);
        if (!rts) {
@@ -338,7 +342,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
                goto out;
        }
 
-       rts->threshold = cpu_to_le16(rts_threshold);
+       rts->threshold = cpu_to_le16((u16)rts_threshold);
 
        ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
        if (ret < 0) {
@@ -540,13 +544,43 @@ out:
        return ret;
 }
 
-int wl1271_acx_sg_cfg(struct wl1271 *wl)
+int wl1271_acx_sta_sg_cfg(struct wl1271 *wl)
+{
+       struct acx_sta_bt_wlan_coex_param *param;
+       struct conf_sg_settings *c = &wl->conf.sg;
+       int i, ret;
+
+       wl1271_debug(DEBUG_ACX, "acx sg sta cfg");
+
+       param = kzalloc(sizeof(*param), GFP_KERNEL);
+       if (!param) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* BT-WLAN coext parameters */
+       for (i = 0; i < CONF_SG_STA_PARAMS_MAX; i++)
+               param->params[i] = cpu_to_le32(c->sta_params[i]);
+       param->param_idx = CONF_SG_PARAMS_ALL;
+
+       ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
+       if (ret < 0) {
+               wl1271_warning("failed to set sg config: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(param);
+       return ret;
+}
+
+int wl1271_acx_ap_sg_cfg(struct wl1271 *wl)
 {
-       struct acx_bt_wlan_coex_param *param;
+       struct acx_ap_bt_wlan_coex_param *param;
        struct conf_sg_settings *c = &wl->conf.sg;
        int i, ret;
 
-       wl1271_debug(DEBUG_ACX, "acx sg cfg");
+       wl1271_debug(DEBUG_ACX, "acx sg ap cfg");
 
        param = kzalloc(sizeof(*param), GFP_KERNEL);
        if (!param) {
@@ -555,8 +589,8 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
        }
 
        /* BT-WLAN coext parameters */
-       for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
-               param->params[i] = cpu_to_le32(c->params[i]);
+       for (i = 0; i < CONF_SG_AP_PARAMS_MAX; i++)
+               param->params[i] = cpu_to_le32(c->ap_params[i]);
        param->param_idx = CONF_SG_PARAMS_ALL;
 
        ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
@@ -588,10 +622,8 @@ int wl1271_acx_cca_threshold(struct wl1271 *wl)
 
        ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
                                   detection, sizeof(*detection));
-       if (ret < 0) {
+       if (ret < 0)
                wl1271_warning("failed to set cca threshold: %d", ret);
-               return ret;
-       }
 
 out:
        kfree(detection);
@@ -804,7 +836,8 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
        struct acx_ap_rate_policy *acx;
        int ret = 0;
 
-       wl1271_debug(DEBUG_ACX, "acx ap rate policy");
+       wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
+                    idx, c->enabled_rates);
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
        if (!acx) {
@@ -898,12 +931,19 @@ out:
        return ret;
 }
 
-int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
 {
        struct acx_frag_threshold *acx;
        int ret = 0;
 
-       wl1271_debug(DEBUG_ACX, "acx frag threshold");
+       /*
+        * If the fragmentation is not configured or out of range, use the
+        * default value.
+        */
+       if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
+               frag_threshold = wl->conf.tx.frag_threshold;
+
+       wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 
@@ -912,7 +952,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
                goto out;
        }
 
-       acx->frag_threshold = cpu_to_le16(frag_threshold);
+       acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
        ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
        if (ret < 0) {
                wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -1023,6 +1063,7 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
        mem_conf->tx_free_req = mem->min_req_tx_blocks;
        mem_conf->rx_free_req = mem->min_req_rx_blocks;
        mem_conf->tx_min = mem->tx_min;
+       mem_conf->fwlog_blocks = wl->conf.fwlog.mem_blocks;
 
        ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
                                   sizeof(*mem_conf));
@@ -1532,46 +1573,69 @@ out:
        return ret;
 }
 
-int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl)
+int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable)
 {
-       struct wl1271_acx_ap_max_tx_retry *acx = NULL;
-       int ret;
-
-       wl1271_debug(DEBUG_ACX, "acx ap max tx retry");
+       struct wl1271_acx_ps_rx_streaming *rx_streaming;
+       u32 conf_queues, enable_queues;
+       int i, ret = 0;
 
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx)
-               return -ENOMEM;
+       wl1271_debug(DEBUG_ACX, "acx ps rx streaming");
 
-       acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries);
-
-       ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1271_warning("acx ap max tx retry failed: %d", ret);
+       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(acx);
+       kfree(rx_streaming);
        return ret;
 }
 
-int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl)
+int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl)
 {
-       struct wl1271_acx_sta_max_tx_retry *acx = NULL;
+       struct wl1271_acx_ap_max_tx_retry *acx = NULL;
        int ret;
 
-       wl1271_debug(DEBUG_ACX, "acx sta max tx retry");
+       wl1271_debug(DEBUG_ACX, "acx ap max tx retry");
 
        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
        if (!acx)
                return -ENOMEM;
 
-       acx->max_tx_retry = wl->conf.tx.max_tx_retries;
+       acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries);
 
-       ret = wl1271_cmd_configure(wl, ACX_CONS_TX_FAILURE, acx, sizeof(*acx));
+       ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
        if (ret < 0) {
-               wl1271_warning("acx sta max tx retry failed: %d", ret);
+               wl1271_warning("acx ap max tx retry failed: %d", ret);
                goto out;
        }
 
@@ -1635,6 +1699,31 @@ out:
        return ret;
 }
 
+int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable)
+{
+       struct acx_ap_beacon_filter *acx = NULL;
+       int ret;
+
+       wl1271_debug(DEBUG_ACX, "acx set ap beacon filter: %d", enable);
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx)
+               return -ENOMEM;
+
+       acx->enable = enable ? 1 : 0;
+
+       ret = wl1271_cmd_configure(wl, ACX_AP_BEACON_FILTER_OPT,
+                                  acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1271_warning("acx set ap beacon filter failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
 int wl1271_acx_fm_coex(struct wl1271 *wl)
 {
        struct wl1271_acx_fm_coex *acx;