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

Commit 0f9c8250 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho
Browse files

wl12xx: re-enable block ack session support



Incorporate interface changes for HT support.

Add ba_bitmap field to the wl1271_link struct, to indicate
activate RX BA sessions (for AP mode).

Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent e51ae9be
Loading
Loading
Loading
Loading
+22 −44
Original line number Diff line number Diff line
@@ -1323,19 +1323,15 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
		goto out;
	}

	/* Allow HT Operation ? */
	if (allow_ht_operation) {
		ht_capabilites =
			WL1271_ACX_FW_CAP_HT_OPERATION;
		if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD)
			ht_capabilites |=
				WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT;
		if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
			ht_capabilites |=
				WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS;
		if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT)
			ht_capabilites |=
				WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION;
		/* no need to translate capabilities - use the spec values */
		ht_capabilites = ht_cap->cap;

		/*
		 * this bit is not employed by the spec but only by FW to
		 * indicate peer HT support
		 */
		ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;

		/* get data from A-MPDU parameters field */
		acx->ampdu_max_length = ht_cap->ampdu_factor;
@@ -1392,14 +1388,12 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
}

/* 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)
int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl)
{
	struct wl1271_acx_ba_session_policy *acx;
	struct wl1271_acx_ba_initiator_policy *acx;
	int ret;

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

	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx) {
@@ -1407,33 +1401,18 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
		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:
	/* set for the current role */
	acx->role_id = wl->role_id;
	acx->tid_bitmap = wl->conf.ht.tx_ba_tid_bitmap;
	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_BA_SESSION_INIT_POLICY,
				   acx,
				   sizeof(*acx));
	if (ret < 0) {
		wl1271_warning("acx ba session setting failed: %d", ret);
		wl1271_warning("acx ba initiator policy failed: %d", ret);
		goto out;
	}

@@ -1443,8 +1422,8 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
}

/* setup BA session receiver setting in the FW. */
int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
					bool enable)
int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
				       u16 ssn, bool enable, u8 peer_hlid)
{
	struct wl1271_acx_ba_receiver_setup *acx;
	int ret;
@@ -1457,11 +1436,10 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
		goto out;
	}

	/* Single link for now */
	acx->link_id = 1;
	acx->hlid = peer_hlid;
	acx->tid = tid_index;
	acx->enable = enable;
	acx->win_size = 0;
	acx->win_size = wl->conf.ht.rx_ba_win_size;
	acx->ssn = ssn;

	ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx,
+27 −55
Original line number Diff line number Diff line
@@ -899,6 +899,10 @@ struct wl1271_acx_rssi_snr_avg_weights {
	u8 snr_data;
};


/* special capability bit (not employed by the 802.11n spec) */
#define WL12XX_HT_CAP_HT_OPERATION BIT(16)

/*
 * ACX_PEER_HT_CAP
 * Configure HT capabilities - declare the capabilities of the peer
@@ -907,19 +911,7 @@ struct wl1271_acx_rssi_snr_avg_weights {
struct wl1271_acx_ht_capabilities {
	struct acx_header header;

	/*
	 * bit 0 - Allow HT Operation
	 * bit 1 - Allow Greenfield format in TX
	 * bit 2 - Allow Short GI in TX
	 * bit 3 - Allow L-SIG TXOP Protection in TX
	 * bit 4 - Allow HT Control fields in TX.
	 *         Note, driver will still leave space for HT control in packets
	 *         regardless of the value of this field. FW will be responsible
	 *         to drop the HT field from any frame when this Bit set to 0.
	 * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD.
	 *         Exact policy setting for this feature is TBD.
	 *         Note, this bit can only be set to 1 if bit 3 is set to 1.
	 */
	/* bitmask of capability bits supported by the peer */
	__le32 ht_capabilites;

	/* Indicates to which link these capabilities apply. */
@@ -937,15 +929,6 @@ struct wl1271_acx_ht_capabilities {
	u8 padding;
} __packed;

/* HT Capabilites Fw Bit Mask Mapping */
#define WL1271_ACX_FW_CAP_HT_OPERATION                 BIT(0)
#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT      BIT(1)
#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS   BIT(2)
#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION         BIT(3)
#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS            BIT(4)
#define WL1271_ACX_FW_CAP_RD_INITIATION                BIT(5)


/*
 * ACX_HT_BSS_OPERATION
 * Configure HT capabilities - AP rules for behavior in the BSS.
@@ -979,57 +962,48 @@ struct wl1271_acx_ht_information {
	u8 padding[2];
} __packed;

#define RX_BA_WIN_SIZE 8
#define RX_BA_MAX_SESSIONS 2

struct wl1271_acx_ba_session_policy {
struct wl1271_acx_ba_initiator_policy {
	struct acx_header header;
	/*
	 * Specifies role Id, Range 0-7, 0xFF means ANY role.
	 * Future use. For now this field is irrelevant
	 */

	/* Specifies role Id, Range 0-7, 0xFF means ANY role. */
	u8 role_id;

	/*
	 * Specifies Link Id, Range 0-31, 0xFF means ANY  Link Id.
	 * Not applicable if Role Id is set to ANY.
	 * Per TID setting for allowing TX BA. Set a bit to 1 to allow
	 * TX BA sessions for the corresponding TID.
	 */
	u8 link_id;

	u8 tid;

	u8 enable;
	u8 tid_bitmap;

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

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

	/* Initiator = 1/Receiver = 0 */
	u8 ba_direction;
	/* As initiator inactivity timeout in time units(TU) of 1024us */
	u16 inactivity_timeout;

	u8 padding[3];
	u8 padding[2];
} __packed;

struct wl1271_acx_ba_receiver_setup {
	struct acx_header header;

	/* Specifies Link Id, Range 0-31, 0xFF means ANY  Link Id */
	u8 link_id;
	/* Specifies link id, range 0-31 */
	u8 hlid;

	u8 tid;

	u8 enable;

	u8 padding[1];

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

	/* BA session starting sequence number.  RANGE 0-FFF */
	u16 ssn;

	u8 padding[2];
} __packed;

struct wl1271_acx_fw_tsf_information {
@@ -1218,7 +1192,7 @@ enum {
	ACX_RSSI_SNR_WEIGHTS        = 0x0052,
	ACX_KEEP_ALIVE_MODE         = 0x0053,
	ACX_SET_KEEP_ALIVE_CONFIG   = 0x0054,
	ACX_BA_SESSION_POLICY_CFG   = 0x0055,
	ACX_BA_SESSION_INIT_POLICY  = 0x0055,
	ACX_BA_SESSION_RX_SETUP     = 0x0056,
	ACX_PEER_HT_CAP             = 0x0057,
	ACX_HT_BSS_OPERATION        = 0x0058,
@@ -1297,11 +1271,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
				    bool allow_ht_operation);
int wl1271_acx_set_ht_information(struct wl1271 *wl,
				   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_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
				       bool enable);
int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl);
int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
				       u16 ssn, bool enable, u8 peer_hlid);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable);
int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl);
+1 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ enum {
	CMD_STATUS_TIMEOUT		= 21, /* Driver internal use.*/
	CMD_STATUS_FW_RESET		= 22, /* Driver internal use.*/
	CMD_STATUS_TEMPLATE_OOM		= 23,
	CMD_STATUS_NO_RX_BA_SESSION	= 24,
	MAX_COMMAND_STATUS		= 0xff
};

+8 −1
Original line number Diff line number Diff line
@@ -557,6 +557,9 @@ struct conf_tx_ac_category {

#define CONF_TX_MAX_TID_COUNT 8

/* Allow TX BA on all TIDs but 6,7. These are currently reserved in the FW */
#define CONF_TX_BA_ENABLED_TID_BITMAP 0x3F

enum {
	CONF_CHANNEL_TYPE_DCF = 0,   /* DC/LEGACY*/
	CONF_CHANNEL_TYPE_EDCF = 1,  /* EDCA*/
@@ -1095,8 +1098,12 @@ struct conf_rf_settings {
};

struct conf_ht_setting {
	u16 tx_ba_win_size;
	u8 rx_ba_win_size;
	u8 tx_ba_win_size;
	u16 inactivity_timeout;

	/* bitmap of enabled TIDs for TX BA sessions */
	u8 tx_ba_tid_bitmap;
};

struct conf_memory_settings {
+10 −27
Original line number Diff line number Diff line
@@ -529,41 +529,24 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
	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;
	int ret = 0;

	/* Reset the BA RX indicators */
	wl->ba_rx_bitmap = 0;
	wl->ba_allowed = true;
	wl->ba_rx_session_count = 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;
	/* BA is supported in STA/AP modes */
	if (wl->bss_type != BSS_TYPE_AP_BSS &&
	    wl->bss_type != BSS_TYPE_STA_BSS) {
		wl->ba_support = false;
		return 0;
	}

	return ret;
	wl->ba_support = true;

	/* 802.11n initiator BA session setting */
	return wl12xx_acx_set_ba_initiator_policy(wl);
}

int wl1271_chip_specific_init(struct wl1271 *wl)
Loading