Commit 5a009adf authored by Avinash Patil's avatar Avinash Patil Committed by John W. Linville
Browse files

mwifiex: add 11n Block Ack support for uAP



This patch adds support for handling BA request and BA setup
events for AP interface.

RA list is marked as either 11n enabled or disabled from station's
capabilities in association request. BA setup is initiated only
after some specific number of packets for particular RA list are
transmitted.

Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarKiran Divekar <dkiran@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d1cf3b95
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -157,4 +157,18 @@ mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,

	return false;
}

/*
 * This function checks whether associated station is 11n enabled
 */
static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
					     struct mwifiex_sta_node *node)
{

	if (!node || (priv->bss_role != MWIFIEX_BSS_ROLE_UAP) ||
	    !priv->ap_11n_enabled)
		return 0;

	return node->is_11n_enabled;
}
#endif /* !_MWIFIEX_11N_H_ */
+11 −4
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
	struct mwifiex_rx_reorder_tbl *tbl, *new_node;
	u16 last_seq = 0;
	unsigned long flags;
	struct mwifiex_sta_node *node;

	/*
	 * If we get a TID, ta pair which is already present dispatch all the
@@ -257,13 +258,19 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
	new_node->tid = tid;
	memcpy(new_node->ta, ta, ETH_ALEN);
	new_node->start_win = seq_num;
	if (mwifiex_queuing_ra_based(priv))
		/* TODO for adhoc */

	if (mwifiex_queuing_ra_based(priv)) {
		dev_dbg(priv->adapter->dev,
			"info: ADHOC:last_seq=%d start_win=%d\n",
			"info: AP/ADHOC:last_seq=%d start_win=%d\n",
			last_seq, new_node->start_win);
	else
		if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
			node = mwifiex_get_sta_entry(priv, ta);
			if (node)
				last_seq = node->rx_seq[tid];
		}
	} else {
		last_seq = priv->rx_seq[tid];
	}

	if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
	    last_seq >= new_node->start_win)
+2 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#define ADDBA_RSP_STATUS_ACCEPT 0

#define MWIFIEX_DEF_11N_RX_SEQ_NUM	0xffff
#define BA_SETUP_MAX_PACKET_THRESHOLD	16
#define BA_SETUP_PACKET_OFFSET		16

static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
{
+3 −0
Original line number Diff line number Diff line
@@ -200,6 +200,9 @@ struct mwifiex_ra_list_tbl {
	u8 ra[ETH_ALEN];
	u32 total_pkts_size;
	u32 is_11n_enabled;
	u16 max_amsdu;
	u16 pkt_count;
	u8 ba_packet_thr;
};

struct mwifiex_tid_tbl {
+21 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "decl.h"
#include "main.h"
#include "11n.h"

/*
 * This function will return the pointer to station entry in station list
@@ -168,6 +169,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
	struct mwifiex_assoc_event *event;
	struct mwifiex_sta_node *node;
	u8 *deauth_mac;
	struct host_cmd_ds_11n_batimeout *ba_timeout;

	switch (eventcause) {
	case EVENT_UAP_STA_ASSOC:
@@ -255,6 +257,25 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
				adapter->tx_buf_size);
		}
		break;
	case EVENT_ADDBA:
		dev_dbg(adapter->dev, "event: ADDBA Request\n");
		if (priv->media_connected)
			mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP,
					       HostCmd_ACT_GEN_SET, 0,
					       adapter->event_body);
		break;
	case EVENT_DELBA:
		dev_dbg(adapter->dev, "event: DELBA Request\n");
		if (priv->media_connected)
			mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
		break;
	case EVENT_BA_STREAM_TIEMOUT:
		dev_dbg(adapter->dev, "event:  BA Stream timeout\n");
		if (priv->media_connected) {
			ba_timeout = (void *)adapter->event_body;
			mwifiex_11n_ba_stream_timeout(priv, ba_timeout);
		}
		break;
	default:
		dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
			eventcause);
Loading