Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11f70f97 authored by Juuso Oikarinen's avatar Juuso Oikarinen Committed by John W. Linville
Browse files

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: default avatarJuuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent eb5b28d0
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -1062,3 +1062,33 @@ int wl1271_acx_smart_reflex(struct wl1271 *wl)
	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;
}
+11 −1
Original line number Diff line number Diff line
@@ -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,
@@ -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__ */
+23 −0
Original line number Diff line number Diff line
@@ -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
+3 −1
Original line number Diff line number Diff line
@@ -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 = {
+10 −0
Original line number Diff line number Diff line
@@ -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)