wl1251: enable beacon early termination while in power-saving mode
authorDavid Gnedt <david.gnedt@davizone.at>
Sun, 30 Jan 2011 19:10:57 +0000 (20:10 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 3 Feb 2011 21:42:44 +0000 (16:42 -0500)
Port the beacon early termination feature from wl1251 driver version
included in the Maemo Fremantle kernel.
It is enabled when going to power-saving mode and disabled when leaving
power-saving mode.

Signed-off-by: David Gnedt <david.gnedt@davizone.at>
Acked-by: Kalle Valo <kvalo@adurom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/wl1251/acx.c
drivers/net/wireless/wl1251/acx.h
drivers/net/wireless/wl1251/ps.c
drivers/net/wireless/wl1251/wl1251.h

index 64a0214cfb29b2b23df56b988e882841e2743edb..8c943661f2df9090c3fab5d9ed1b5c0f4ff78d18 100644 (file)
@@ -978,6 +978,34 @@ out:
        return ret;
 }
 
+int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
+                         u8 max_consecutive)
+{
+       struct wl1251_acx_bet_enable *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx bet enable");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->enable = mode;
+       acx->max_consecutive = max_consecutive;
+
+       ret = wl1251_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("wl1251 acx bet enable failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
 int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
                      u8 aifs, u16 txop)
 {
index efcc3aaca14f53d84675e5a4044d48691ac7c853..6a19f38958f7b9acfcbeb9285d59ba1013b0f6f1 100644 (file)
@@ -1164,6 +1164,31 @@ struct wl1251_acx_wr_tbtt_and_dtim {
        u8  padding;
 } __packed;
 
+enum wl1251_acx_bet_mode {
+       WL1251_ACX_BET_DISABLE = 0,
+       WL1251_ACX_BET_ENABLE = 1,
+};
+
+struct wl1251_acx_bet_enable {
+       struct acx_header header;
+
+       /*
+        * Specifies if beacon early termination procedure is enabled or
+        * disabled, see enum wl1251_acx_bet_mode.
+        */
+       u8 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 max_consecutive;
+
+       u8 padding[2];
+} __packed;
+
 struct wl1251_acx_ac_cfg {
        struct acx_header header;
 
@@ -1401,6 +1426,8 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
 int wl1251_acx_rate_policies(struct wl1251 *wl);
 int wl1251_acx_mem_cfg(struct wl1251 *wl);
 int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
+int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
+                         u8 max_consecutive);
 int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
                      u8 aifs, u16 txop);
 int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
index 5ed47c8373d2ae846db307b9d7306781f69564a6..9ba23ede51bd964c26412ad3a79b48b12654c4bb 100644 (file)
@@ -153,6 +153,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
                if (ret < 0)
                        return ret;
 
+               ret = wl1251_acx_bet_enable(wl, WL1251_ACX_BET_ENABLE,
+                                           WL1251_DEFAULT_BET_CONSECUTIVE);
+               if (ret < 0)
+                       return ret;
+
                ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
                if (ret < 0)
                        return ret;
@@ -170,6 +175,12 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
                if (ret < 0)
                        return ret;
 
+               /* disable BET */
+               ret = wl1251_acx_bet_enable(wl, WL1251_ACX_BET_DISABLE,
+                                           WL1251_DEFAULT_BET_CONSECUTIVE);
+               if (ret < 0)
+                       return ret;
+
                /* disable beacon filtering */
                ret = wl1251_acx_beacon_filter_opt(wl, false);
                if (ret < 0)
index c0ce2c8b43b8715fbb2c502f4c5bce710e901da7..462ac5b20585b6e0e030494050c3cf2127b58150 100644 (file)
@@ -410,6 +410,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl);
 
 #define WL1251_DEFAULT_CHANNEL 0
 
+#define WL1251_DEFAULT_BET_CONSECUTIVE 10
+
 #define CHIP_ID_1251_PG10                 (0x7010101)
 #define CHIP_ID_1251_PG11                 (0x7020101)
 #define CHIP_ID_1251_PG12                 (0x7030101)