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

Commit 4b7fac77 authored by Levi, Shahar's avatar Levi, Shahar Committed by Luciano Coelho
Browse files

wl12xx: BA initiator support



Add 80211n BA initiator session support wl1271 driver.
Include BA supported FW version auto detection mechanism.
BA initiator session management included in FW independently.

Signed-off-by: default avatarShahar Levi <shahar_levi@ti.com>
Reviewed-by: default avatarLuciano Coelho <coelho@ti.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 6c89b7b2
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -1342,6 +1342,57 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
	return ret;
	return ret;
}
}


/* Configure BA session initiator/receiver parameters setting in the FW. */
int wl1271_acx_set_ba_session(struct wl1271 *wl,
			       enum ieee80211_back_parties direction,
			       u8 tid_index, u8 policy)
{
	struct wl1271_acx_ba_session_policy *acx;
	int ret;

	wl1271_debug(DEBUG_ACX, "acx ba session setting");

	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}

	/* ANY role */
	acx->role_id = 0xff;
	acx->tid = tid_index;
	acx->enable = policy;
	acx->ba_direction = direction;

	switch (direction) {
	case WLAN_BACK_INITIATOR:
		acx->win_size = wl->conf.ht.tx_ba_win_size;
		acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
		break;
	case WLAN_BACK_RECIPIENT:
		acx->win_size = RX_BA_WIN_SIZE;
		acx->inactivity_timeout = 0;
		break;
	default:
		wl1271_error("Incorrect acx command id=%x\n", direction);
		ret = -EINVAL;
		goto out;
	}

	ret = wl1271_cmd_configure(wl,
				   ACX_BA_SESSION_POLICY_CFG,
				   acx,
				   sizeof(*acx));
	if (ret < 0) {
		wl1271_warning("acx ba session setting failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}

int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
{
{
	struct wl1271_acx_fw_tsf_information *tsf_info;
	struct wl1271_acx_fw_tsf_information *tsf_info;
+39 −2
Original line number Original line Diff line number Diff line
@@ -1061,6 +1061,40 @@ struct wl1271_acx_ht_information {
	u8 padding[3];
	u8 padding[3];
} __packed;
} __packed;


#define RX_BA_WIN_SIZE 8

struct wl1271_acx_ba_session_policy {
	struct acx_header header;
	/*
	 * Specifies role Id, Range 0-7, 0xFF means ANY role.
	 * Future use. For now this field is irrelevant
	 */
	u8 role_id;
	/*
	 * Specifies Link Id, Range 0-31, 0xFF means ANY  Link Id.
	 * Not applicable if Role Id is set to ANY.
	 */
	u8 link_id;

	u8 tid;

	u8 enable;

	/* Windows size in number of packets */
	u16 win_size;

	/*
	 * As initiator inactivity timeout in time units(TU) of 1024us.
	 * As receiver reserved
	 */
	u16 inactivity_timeout;

	/* Initiator = 1/Receiver = 0 */
	u8 ba_direction;

	u8 padding[3];
} __packed;

struct wl1271_acx_fw_tsf_information {
struct wl1271_acx_fw_tsf_information {
	struct acx_header header;
	struct acx_header header;


@@ -1134,8 +1168,8 @@ enum {
	ACX_RSSI_SNR_WEIGHTS        = 0x0052,
	ACX_RSSI_SNR_WEIGHTS        = 0x0052,
	ACX_KEEP_ALIVE_MODE         = 0x0053,
	ACX_KEEP_ALIVE_MODE         = 0x0053,
	ACX_SET_KEEP_ALIVE_CONFIG   = 0x0054,
	ACX_SET_KEEP_ALIVE_CONFIG   = 0x0054,
	ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
	ACX_BA_SESSION_POLICY_CFG   = 0x0055,
	ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
	ACX_BA_SESSION_RX_SETUP     = 0x0056,
	ACX_PEER_HT_CAP             = 0x0057,
	ACX_PEER_HT_CAP             = 0x0057,
	ACX_HT_BSS_OPERATION        = 0x0058,
	ACX_HT_BSS_OPERATION        = 0x0058,
	ACX_COEX_ACTIVITY           = 0x0059,
	ACX_COEX_ACTIVITY           = 0x0059,
@@ -1209,6 +1243,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
				    bool allow_ht_operation);
				    bool allow_ht_operation);
int wl1271_acx_set_ht_information(struct wl1271 *wl,
int wl1271_acx_set_ht_information(struct wl1271 *wl,
				   u16 ht_operation_mode);
				   u16 ht_operation_mode);
int wl1271_acx_set_ba_session(struct wl1271 *wl,
			       enum ieee80211_back_parties direction,
			       u8 tid_index, u8 policy);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
int wl1271_acx_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_max_tx_retry(struct wl1271 *wl);


+21 −3
Original line number Original line Diff line number Diff line
@@ -101,6 +101,22 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
	wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
	wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
}
}


static void wl1271_parse_fw_ver(struct wl1271 *wl)
{
	int ret;

	ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
		     &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
		     &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
		     &wl->chip.fw_ver[4]);

	if (ret != 5) {
		wl1271_warning("fw version incorrect value");
		memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
		return;
	}
}

static void wl1271_boot_fw_version(struct wl1271 *wl)
static void wl1271_boot_fw_version(struct wl1271 *wl)
{
{
	struct wl1271_static_data static_data;
	struct wl1271_static_data static_data;
@@ -108,11 +124,13 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
	wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
	wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
		    false);
		    false);


	strncpy(wl->chip.fw_ver, static_data.fw_version,
	strncpy(wl->chip.fw_ver_str, static_data.fw_version,
		sizeof(wl->chip.fw_ver));
		sizeof(wl->chip.fw_ver_str));


	/* make sure the string is NULL-terminated */
	/* make sure the string is NULL-terminated */
	wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0';
	wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';

	wl1271_parse_fw_ver(wl);
}
}


static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
+6 −0
Original line number Original line Diff line number Diff line
@@ -1138,6 +1138,11 @@ struct conf_rf_settings {
	u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
	u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
};
};


struct conf_ht_setting {
	u16 tx_ba_win_size;
	u16 inactivity_timeout;
};

struct conf_drv_settings {
struct conf_drv_settings {
	struct conf_sg_settings sg;
	struct conf_sg_settings sg;
	struct conf_rx_settings rx;
	struct conf_rx_settings rx;
@@ -1148,6 +1153,7 @@ struct conf_drv_settings {
	struct conf_roam_trigger_settings roam_trigger;
	struct conf_roam_trigger_settings roam_trigger;
	struct conf_scan_settings scan;
	struct conf_scan_settings scan;
	struct conf_rf_settings rf;
	struct conf_rf_settings rf;
	struct conf_ht_setting ht;
};
};


#endif
#endif
+42 −0
Original line number Original line Diff line number Diff line
@@ -455,6 +455,43 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
	return 0;
	return 0;
}
}


static void wl1271_check_ba_support(struct wl1271 *wl)
{
	/* validate FW cose ver x.x.x.50-60.x */
	if ((wl->chip.fw_ver[3] >= WL12XX_BA_SUPPORT_FW_COST_VER2_START) &&
	    (wl->chip.fw_ver[3] < WL12XX_BA_SUPPORT_FW_COST_VER2_END)) {
		wl->ba_support = true;
		return;
	}

	wl->ba_support = false;
}

static int wl1271_set_ba_policies(struct wl1271 *wl)
{
	u8 tid_index;
	u8 ret = 0;

	/* Reset the BA RX indicators */
	wl->ba_allowed = true;
	wl->ba_rx_bitmap = 0;

	/* validate that FW support BA */
	wl1271_check_ba_support(wl);

	if (wl->ba_support)
		/* 802.11n initiator BA session setting */
		for (tid_index = 0; tid_index < CONF_TX_MAX_TID_COUNT;
		     ++tid_index) {
			ret = wl1271_acx_set_ba_session(wl, WLAN_BACK_INITIATOR,
							tid_index, true);
			if (ret < 0)
				break;
		}

	return ret;
}

int wl1271_hw_init(struct wl1271 *wl)
int wl1271_hw_init(struct wl1271 *wl)
{
{
	struct conf_tx_ac_category *conf_ac;
	struct conf_tx_ac_category *conf_ac;
@@ -568,6 +605,11 @@ int wl1271_hw_init(struct wl1271 *wl)
	if (ret < 0)
	if (ret < 0)
		goto out_free_memmap;
		goto out_free_memmap;


	/* Configure initiator BA sessions policies */
	ret = wl1271_set_ba_policies(wl);
	if (ret < 0)
		goto out_free_memmap;

	return 0;
	return 0;


 out_free_memmap:
 out_free_memmap:
Loading