diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2009-10-13 05:47:46 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-27 16:48:09 -0400 |
commit | 11f70f9715f0d8f99eac42d69689e8df15283fea (patch) | |
tree | 92f5e45ca20e554948800aa3beacab00604e8b74 /drivers/net | |
parent | eb5b28d021a1b96050f7af46e9140eb0051cc6d8 (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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_conf.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_ps.c | 10 |
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 880c82894f63..44a1237fa794 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 | |||
1066 | int 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 | |||
1091 | out: | ||
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 73ef2bdf3b74..29fd3635e383 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 | |||
950 | struct 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 | |||
949 | enum { | 958 | enum { |
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); | |||
1043 | int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask); | 1052 | int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask); |
1044 | int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); | 1053 | int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); |
1045 | int wl1271_acx_cts_protect(struct wl1271 *wl, | 1054 | int wl1271_acx_cts_protect(struct wl1271 *wl, |
1046 | enum acx_ctsprotect_type ctsprotect); | 1055 | enum acx_ctsprotect_type ctsprotect); |
1047 | int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); | 1056 | int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); |
1048 | int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates); | 1057 | int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates); |
1049 | int wl1271_acx_ac_cfg(struct wl1271 *wl); | 1058 | int wl1271_acx_ac_cfg(struct wl1271 *wl); |
@@ -1054,5 +1063,6 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl); | |||
1054 | int wl1271_acx_init_mem_config(struct wl1271 *wl); | 1063 | int wl1271_acx_init_mem_config(struct wl1271 *wl); |
1055 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); | 1064 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); |
1056 | int wl1271_acx_smart_reflex(struct wl1271 *wl); | 1065 | int wl1271_acx_smart_reflex(struct wl1271 *wl); |
1066 | int 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 5333a2731254..00ffa6679324 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 | ||
606 | enum conf_bet_mode { | ||
607 | CONF_BET_MODE_DISABLE = 0, | ||
608 | CONF_BET_MODE_ENABLE = 1, | ||
609 | }; | ||
610 | |||
606 | struct conf_conn_settings { | 611 | struct 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 7f1093cd816c..3d2e999ef15a 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 bb8745d9bd64..507cd91d7eed 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) |