Commit e52f408b authored by Roland Vossen's avatar Roland Vossen Committed by Greg Kroah-Hartman
Browse files

staging: brcm80211: parsed ADDBA response ack window parameter



IEEE80211_AMPDU_TX_OPERATIONAL provides a BA window size parameter. Code
is now using this parameter to restrict the amount of outstanding tx
AMPDUs.

Signed-off-by: default avatarRoland Vossen <rvossen@broadcom.com>
Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 47a6d2cd
Loading
Loading
Loading
Loading
+18 −37
Original line number Diff line number Diff line
@@ -114,9 +114,6 @@ static void brcms_c_ffpld_init(struct ampdu_info *ampdu);
static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int f);
static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);

static scb_ampdu_tid_ini_t *brcms_c_ampdu_init_tid_ini(struct ampdu_info *ampdu,
						   scb_ampdu_t *scb_ampdu,
						   u8 tid, bool override);
static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu,
					       u8 dur);
static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
@@ -411,24 +408,28 @@ static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
	}
}

static void
brcms_c_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
	      uint prec)
void
brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
		  u8 ba_wsize)		/* negotiated ba window size (in pdu) */
{
	scb_ampdu_t *scb_ampdu;
	scb_ampdu_tid_ini_t *ini;
	u8 tid = (u8) (p->priority);

	struct ampdu_info *ampdu = wlc->ampdu;
	struct scb *scb = wlc->pub->global_scb;
	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);

	/* initialize initiator on first packet; sends addba req */
	ini = SCB_AMPDU_INI(scb_ampdu, tid);
	if (ini->magic != INI_MAGIC) {
		ini = brcms_c_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false);
	}
	if (!ampdu->ini_enable[tid]) {
		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
			  __func__, tid);
		return;
	}

	ini = SCB_AMPDU_INI(scb_ampdu, tid);
	ini->tid = tid;
	ini->scb = scb_ampdu->scb;
	ini->ba_wsize = ba_wsize;
}

int
brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_c_txq_info *qi,
	      struct sk_buff **pdu, int prec)
@@ -479,12 +480,13 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_c_txq_info *qi,

	/* Let pressure continue to build ... */
	qlen = pktq_plen(&qi->q, prec);
	if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
	if (ini->tx_in_transit > 0 &&
	    qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) {
		/* Collect multiple MPDU's to be sent in the next AMPDU */
		return -EBUSY;
	}

	brcms_c_ampdu_agg(ampdu, scb, p, tid);

	/* at this point we intend to transmit an AMPDU */
	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
	ampdu_len = 0;
	dma_len = 0;
@@ -1083,27 +1085,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
	brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
}

/* initialize the initiator code for tid */
static scb_ampdu_tid_ini_t *brcms_c_ampdu_init_tid_ini(struct ampdu_info *ampdu,
						   scb_ampdu_t *scb_ampdu,
						   u8 tid, bool override)
{
	scb_ampdu_tid_ini_t *ini;

	/* check for per-tid control of ampdu */
	if (!ampdu->ini_enable[tid]) {
		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
			  __func__, tid);
		return NULL;
	}

	ini = SCB_AMPDU_INI(scb_ampdu, tid);
	ini->tid = tid;
	ini->scb = scb_ampdu->scb;
	ini->magic = INI_MAGIC;
	return ini;
}

static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
{
	struct brcms_c_info *wlc = ampdu->wlc;
+8 −1
Original line number Diff line number Diff line
@@ -656,7 +656,14 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
		break;
	case IEEE80211_AMPDU_TX_OPERATIONAL:
		/* Not sure what to do here */
		/*
		 * BA window size from ADDBA response ('buf_size') defines how
		 * many outstanding MPDUs are allowed for the BA stream by
		 * recipient and traffic class.
		 */
		LOCK(wl);
		brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size);
		UNLOCK(wl);
		/* Power save wakeup */
		break;
	default:
+2 −0
Original line number Diff line number Diff line
@@ -626,6 +626,8 @@ extern void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs);

extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
			    struct ieee80211_sta *sta, u16 tid);
extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
					 u8 ba_wsize);
extern int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
			   int val);
extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
+1 −2
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@
#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
/* structure to store per-tid state for the ampdu initiator */
struct scb_ampdu_tid_ini {
	u32 magic;
	u8 tx_in_transit;	/* number of pending mpdus in transit in driver */
	u8 tid;		/* initiator tid for easy lookup */
	u8 txretry[AMPDU_TX_BA_MAX_WSIZE];	/* tx retry count; indexed by seq modulo */
	struct scb *scb;	/* backptr for easy lookup */
	u8 ba_wsize;		/* negotiated ba window size (in pdu) */
};

#define AMPDU_MAX_SCB_TID	NUMPRIO
@@ -51,7 +51,6 @@ struct scb_ampdu {
};

#define SCB_MAGIC 	0xbeefcafe
#define INI_MAGIC 	0xabcd1234

/* station control block - one per remote MAC address */
struct scb {