wl1271: Implement beacon early termination support
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>
Tue, 13 Oct 2009 09:47:46 +0000 (12:47 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 27 Oct 2009 20:48:09 +0000 (16:48 -0400)
Add support to enable beacon early termination in the firmware. Early
Beacon termination is a feature which allows the radio to be turned off
after TIM IE to save power.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/wl12xx/wl1271_acx.c
drivers/net/wireless/wl12xx/wl1271_acx.h
drivers/net/wireless/wl12xx/wl1271_conf.h
drivers/net/wireless/wl12xx/wl1271_main.c
drivers/net/wireless/wl12xx/wl1271_ps.c

index 880c82894f63202a0c524817e71b88351a9c5c36..44a1237fa794afe759cdbdb5d00db5a07bbd2e7d 100644 (file)
@@ -1062,3 +1062,33 @@ out:
        return ret;
 
 }
+
+int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
+{
+       struct wl1271_acx_bet_enable *acx = NULL;
+       int ret = 0;
+
+       wl1271_debug(DEBUG_ACX, "acx bet enable");
+
+       if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
+               goto out;
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
+       acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
+
+       ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1271_warning("acx bet enable failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
index 73ef2bdf3b7445fb25e98e99a001113715464c8e..29fd3635e3836c28c1c31a24674087cbadcc5a34 100644 (file)
@@ -946,6 +946,15 @@ struct wl1271_acx_rx_config_opt {
        u8 reserved;
 } __attribute__ ((packed));
 
+
+struct wl1271_acx_bet_enable {
+       struct acx_header header;
+
+       u8 enable;
+       u8 max_consecutive;
+       u8 padding[2];
+} __attribute__ ((packed));
+
 enum {
        ACX_WAKE_UP_CONDITIONS      = 0x0002,
        ACX_MEM_CFG                 = 0x0003,
@@ -1043,7 +1052,7 @@ int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
 int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask);
 int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
 int wl1271_acx_cts_protect(struct wl1271 *wl,
-                           enum acx_ctsprotect_type ctsprotect);
+                          enum acx_ctsprotect_type ctsprotect);
 int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
 int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates);
 int wl1271_acx_ac_cfg(struct wl1271 *wl);
@@ -1054,5 +1063,6 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl);
 int wl1271_acx_init_mem_config(struct wl1271 *wl);
 int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
 int wl1271_acx_smart_reflex(struct wl1271 *wl);
+int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
 
 #endif /* __WL1271_ACX_H__ */
index 5333a27312546056bed0ada0d1f04149b1214d44..00ffa66793248581efbc56c5da990cfa1acd598b 100644 (file)
@@ -603,6 +603,11 @@ enum conf_bcn_filt_mode {
        CONF_BCN_FILT_MODE_ENABLED = 1
 };
 
+enum conf_bet_mode {
+       CONF_BET_MODE_DISABLE = 0,
+       CONF_BET_MODE_ENABLE = 1,
+};
+
 struct conf_conn_settings {
        /*
         * Firmware wakeup conditions configuration. The host may set only
@@ -689,6 +694,24 @@ struct conf_conn_settings {
         * Configuration of signal average weights.
         */
        struct conf_sig_weights sig_weights;
+
+       /*
+        * Specifies if beacon early termination procedure is enabled or
+        * disabled.
+        *
+        * Range: CONF_BET_MODE_*
+        */
+       u8 bet_enable;
+
+       /*
+        * Specifies the maximum number of consecutive beacons that may be
+        * early terminated. After this number is reached at least one full
+        * beacon must be correctly received in FW before beacon ET
+        * resumes.
+        *
+        * Range 0 - 255
+        */
+       u8 bet_max_consecutive;
 };
 
 #define CONF_SR_ERR_TBL_MAX_VALUES   14
index 7f1093cd816c9b58c1d57646ba23ae086f8c91bb..3d2e999ef15af8c1a7f7aaa29cbd2567a1ba49ee 100644 (file)
@@ -219,7 +219,9 @@ static struct conf_drv_settings default_conf = {
                        .rssi_pkt_avg_weight = 10,
                        .snr_bcn_avg_weight  = 10,
                        .snr_pkt_avg_weight  = 10
-               }
+               },
+               .bet_enable                  = CONF_BET_MODE_ENABLE,
+               .bet_max_consecutive         = 100
        },
        .init = {
                .sr_err_tbl = {
index bb8745d9bd64764b066d65ca72eb0f740c12e3f4..507cd91d7eed3418a2c69e57fe98410b23031242 100644 (file)
@@ -130,6 +130,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
                if (ret < 0)
                        return ret;
 
+               /* enable beacon early termination */
+               ret = wl1271_acx_bet_enable(wl, true);
+               if (ret < 0)
+                       return ret;
+
                ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
                if (ret < 0)
                        return ret;
@@ -147,6 +152,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
                if (ret < 0)
                        return ret;
 
+               /* disable beacon early termination */
+               ret = wl1271_acx_bet_enable(wl, false);
+               if (ret < 0)
+                       return ret;
+
                /* disable beacon filtering */
                ret = wl1271_acx_beacon_filter_opt(wl, false);
                if (ret < 0)