aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2009-10-13 05:47:46 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:48:09 -0400
commit11f70f9715f0d8f99eac42d69689e8df15283fea (patch)
tree92f5e45ca20e554948800aa3beacab00604e8b74
parenteb5b28d021a1b96050f7af46e9140eb0051cc6d8 (diff)
wl1271: Implement beacon early termination support
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>
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c30
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h23
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c10
5 files changed, 77 insertions, 2 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 880c82894f6..44a1237fa79 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -1062,3 +1062,33 @@ out:
1062 return ret; 1062 return ret;
1063 1063
1064} 1064}
1065
1066int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
1067{
1068 struct wl1271_acx_bet_enable *acx = NULL;
1069 int ret = 0;
1070
1071 wl1271_debug(DEBUG_ACX, "acx bet enable");
1072
1073 if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
1074 goto out;
1075
1076 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1077 if (!acx) {
1078 ret = -ENOMEM;
1079 goto out;
1080 }
1081
1082 acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
1083 acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
1084
1085 ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1086 if (ret < 0) {
1087 wl1271_warning("acx bet enable failed: %d", ret);
1088 goto out;
1089 }
1090
1091out:
1092 kfree(acx);
1093 return ret;
1094}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 73ef2bdf3b7..29fd3635e38 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -946,6 +946,15 @@ struct wl1271_acx_rx_config_opt {
946 u8 reserved; 946 u8 reserved;
947} __attribute__ ((packed)); 947} __attribute__ ((packed));
948 948
949
950struct wl1271_acx_bet_enable {
951 struct acx_header header;
952
953 u8 enable;
954 u8 max_consecutive;
955 u8 padding[2];
956} __attribute__ ((packed));
957
949enum { 958enum {
950 ACX_WAKE_UP_CONDITIONS = 0x0002, 959 ACX_WAKE_UP_CONDITIONS = 0x0002,
951 ACX_MEM_CFG = 0x0003, 960 ACX_MEM_CFG = 0x0003,
@@ -1043,7 +1052,7 @@ int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
1043int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask); 1052int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask);
1044int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); 1053int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
1045int wl1271_acx_cts_protect(struct wl1271 *wl, 1054int wl1271_acx_cts_protect(struct wl1271 *wl,
1046 enum acx_ctsprotect_type ctsprotect); 1055 enum acx_ctsprotect_type ctsprotect);
1047int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); 1056int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
1048int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates); 1057int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates);
1049int wl1271_acx_ac_cfg(struct wl1271 *wl); 1058int wl1271_acx_ac_cfg(struct wl1271 *wl);
@@ -1054,5 +1063,6 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl);
1054int wl1271_acx_init_mem_config(struct wl1271 *wl); 1063int wl1271_acx_init_mem_config(struct wl1271 *wl);
1055int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); 1064int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
1056int wl1271_acx_smart_reflex(struct wl1271 *wl); 1065int wl1271_acx_smart_reflex(struct wl1271 *wl);
1066int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1057 1067
1058#endif /* __WL1271_ACX_H__ */ 1068#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 5333a273125..00ffa667932 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -603,6 +603,11 @@ enum conf_bcn_filt_mode {
603 CONF_BCN_FILT_MODE_ENABLED = 1 603 CONF_BCN_FILT_MODE_ENABLED = 1
604}; 604};
605 605
606enum conf_bet_mode {
607 CONF_BET_MODE_DISABLE = 0,
608 CONF_BET_MODE_ENABLE = 1,
609};
610
606struct conf_conn_settings { 611struct conf_conn_settings {
607 /* 612 /*
608 * Firmware wakeup conditions configuration. The host may set only 613 * Firmware wakeup conditions configuration. The host may set only
@@ -689,6 +694,24 @@ struct conf_conn_settings {
689 * Configuration of signal average weights. 694 * Configuration of signal average weights.
690 */ 695 */
691 struct conf_sig_weights sig_weights; 696 struct conf_sig_weights sig_weights;
697
698 /*
699 * Specifies if beacon early termination procedure is enabled or
700 * disabled.
701 *
702 * Range: CONF_BET_MODE_*
703 */
704 u8 bet_enable;
705
706 /*
707 * Specifies the maximum number of consecutive beacons that may be
708 * early terminated. After this number is reached at least one full
709 * beacon must be correctly received in FW before beacon ET
710 * resumes.
711 *
712 * Range 0 - 255
713 */
714 u8 bet_max_consecutive;
692}; 715};
693 716
694#define CONF_SR_ERR_TBL_MAX_VALUES 14 717#define CONF_SR_ERR_TBL_MAX_VALUES 14
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 7f1093cd816..3d2e999ef15 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -219,7 +219,9 @@ static struct conf_drv_settings default_conf = {
219 .rssi_pkt_avg_weight = 10, 219 .rssi_pkt_avg_weight = 10,
220 .snr_bcn_avg_weight = 10, 220 .snr_bcn_avg_weight = 10,
221 .snr_pkt_avg_weight = 10 221 .snr_pkt_avg_weight = 10
222 } 222 },
223 .bet_enable = CONF_BET_MODE_ENABLE,
224 .bet_max_consecutive = 100
223 }, 225 },
224 .init = { 226 .init = {
225 .sr_err_tbl = { 227 .sr_err_tbl = {
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index bb8745d9bd6..507cd91d7ee 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -130,6 +130,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
130 if (ret < 0) 130 if (ret < 0)
131 return ret; 131 return ret;
132 132
133 /* enable beacon early termination */
134 ret = wl1271_acx_bet_enable(wl, true);
135 if (ret < 0)
136 return ret;
137
133 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); 138 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
134 if (ret < 0) 139 if (ret < 0)
135 return ret; 140 return ret;
@@ -147,6 +152,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
147 if (ret < 0) 152 if (ret < 0)
148 return ret; 153 return ret;
149 154
155 /* disable beacon early termination */
156 ret = wl1271_acx_bet_enable(wl, false);
157 if (ret < 0)
158 return ret;
159
150 /* disable beacon filtering */ 160 /* disable beacon filtering */
151 ret = wl1271_acx_beacon_filter_opt(wl, false); 161 ret = wl1271_acx_beacon_filter_opt(wl, false);
152 if (ret < 0) 162 if (ret < 0)