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

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

wl12xx: BA receiver support



Add new ampdu_action ops to support receiver BA.
The BA initiator session management 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 4b7fac77
Loading
Loading
Loading
Loading
+34 −0
Original line number Original line Diff line number Diff line
@@ -1393,6 +1393,40 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
	return ret;
	return ret;
}
}


/* 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)
{
	struct wl1271_acx_ba_receiver_setup *acx;
	int ret;

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

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

	/* Single link for now */
	acx->link_id = 1;
	acx->tid = tid_index;
	acx->enable = enable;
	acx->win_size = 0;
	acx->ssn = ssn;

	ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx,
				   sizeof(*acx));
	if (ret < 0) {
		wl1271_warning("acx ba receiver session 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;
+23 −2
Original line number Original line Diff line number Diff line
@@ -1095,6 +1095,25 @@ struct wl1271_acx_ba_session_policy {
	u8 padding[3];
	u8 padding[3];
} __packed;
} __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;

	u8 tid;

	u8 enable;

	u8 padding[1];

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

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

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


@@ -1246,6 +1265,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
int wl1271_acx_set_ba_session(struct wl1271 *wl,
int wl1271_acx_set_ba_session(struct wl1271 *wl,
			      enum ieee80211_back_parties direction,
			      enum ieee80211_back_parties direction,
			      u8 tid_index, u8 policy);
			      u8 tid_index, u8 policy);
int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
				       bool enable);
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);


+0 −1
Original line number Original line Diff line number Diff line
@@ -473,7 +473,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
	u8 ret = 0;
	u8 ret = 0;


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


	/* validate that FW support BA */
	/* validate that FW support BA */
+60 −0
Original line number Original line Diff line number Diff line
@@ -2724,6 +2724,65 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
	return ret;
	return ret;
}
}


int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
			    enum ieee80211_ampdu_mlme_action action,
			    struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
	struct wl1271 *wl = hw->priv;
	int ret;

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF)) {
		ret = -EAGAIN;
		goto out;
	}

	ret = wl1271_ps_elp_wakeup(wl, false);
	if (ret < 0)
		goto out;

	switch (action) {
	case IEEE80211_AMPDU_RX_START:
		if (wl->ba_support) {
			ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn,
								 true);
			if (!ret)
				wl->ba_rx_bitmap |= BIT(tid);
		} else {
			ret = -ENOTSUPP;
		}
		break;

	case IEEE80211_AMPDU_RX_STOP:
		ret = wl1271_acx_set_ba_receiver_session(wl, tid, 0, false);
		if (!ret)
			wl->ba_rx_bitmap &= ~BIT(tid);
		break;

	/*
	 * The BA initiator session management in FW independently.
	 * Falling break here on purpose for all TX APDU commands.
	 */
	case IEEE80211_AMPDU_TX_START:
	case IEEE80211_AMPDU_TX_STOP:
	case IEEE80211_AMPDU_TX_OPERATIONAL:
		ret = -EINVAL;
		break;

	default:
		wl1271_error("Incorrect ampdu action id=%x\n", action);
		ret = -EINVAL;
	}

	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

/* can't be const, mac80211 writes to this */
/* can't be const, mac80211 writes to this */
static struct ieee80211_rate wl1271_rates[] = {
static struct ieee80211_rate wl1271_rates[] = {
	{ .bitrate = 10,
	{ .bitrate = 10,
@@ -2973,6 +3032,7 @@ static const struct ieee80211_ops wl1271_ops = {
	.get_survey = wl1271_op_get_survey,
	.get_survey = wl1271_op_get_survey,
	.sta_add = wl1271_op_sta_add,
	.sta_add = wl1271_op_sta_add,
	.sta_remove = wl1271_op_sta_remove,
	.sta_remove = wl1271_op_sta_remove,
	.ampdu_action = wl1271_op_ampdu_action,
	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
};
};


+0 −1
Original line number Original line Diff line number Diff line
@@ -473,7 +473,6 @@ struct wl1271 {


	/* RX BA constraint value */
	/* RX BA constraint value */
	bool ba_support;
	bool ba_support;
	u8 ba_allowed;
	u8 ba_rx_bitmap;
	u8 ba_rx_bitmap;
};
};