mirror of
https://github.com/torvalds/linux.git
synced 2024-11-05 03:21:32 +00:00
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: Roland Vossen <rvossen@broadcom.com> Reviewed-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
47a6d2cdc7
commit
e52f408bf6
@ -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 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 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,
|
static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu,
|
||||||
u8 dur);
|
u8 dur);
|
||||||
static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
|
static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
|
||||||
@ -411,22 +408,26 @@ static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
brcms_c_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
|
brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
|
||||||
uint prec)
|
u8 ba_wsize) /* negotiated ba window size (in pdu) */
|
||||||
{
|
{
|
||||||
scb_ampdu_t *scb_ampdu;
|
scb_ampdu_t *scb_ampdu;
|
||||||
scb_ampdu_tid_ini_t *ini;
|
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);
|
scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
|
||||||
|
|
||||||
/* initialize initiator on first packet; sends addba req */
|
if (!ampdu->ini_enable[tid]) {
|
||||||
ini = SCB_AMPDU_INI(scb_ampdu, tid);
|
wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
|
||||||
if (ini->magic != INI_MAGIC) {
|
__func__, tid);
|
||||||
ini = brcms_c_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false);
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
ini = SCB_AMPDU_INI(scb_ampdu, tid);
|
||||||
|
ini->tid = tid;
|
||||||
|
ini->scb = scb_ampdu->scb;
|
||||||
|
ini->ba_wsize = ba_wsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -479,12 +480,13 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_c_txq_info *qi,
|
|||||||
|
|
||||||
/* Let pressure continue to build ... */
|
/* Let pressure continue to build ... */
|
||||||
qlen = pktq_plen(&qi->q, prec);
|
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;
|
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];
|
rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
|
||||||
ampdu_len = 0;
|
ampdu_len = 0;
|
||||||
dma_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);
|
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)
|
static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
|
||||||
{
|
{
|
||||||
struct brcms_c_info *wlc = ampdu->wlc;
|
struct brcms_c_info *wlc = ampdu->wlc;
|
||||||
|
@ -656,7 +656,14 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
|
|||||||
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_OPERATIONAL:
|
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 */
|
/* Power save wakeup */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -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,
|
extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
|
||||||
struct ieee80211_sta *sta, u16 tid);
|
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,
|
extern int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
|
||||||
int val);
|
int val);
|
||||||
extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
|
extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
|
||||||
|
@ -25,11 +25,11 @@
|
|||||||
#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
|
#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
|
||||||
/* structure to store per-tid state for the ampdu initiator */
|
/* structure to store per-tid state for the ampdu initiator */
|
||||||
struct scb_ampdu_tid_ini {
|
struct scb_ampdu_tid_ini {
|
||||||
u32 magic;
|
|
||||||
u8 tx_in_transit; /* number of pending mpdus in transit in driver */
|
u8 tx_in_transit; /* number of pending mpdus in transit in driver */
|
||||||
u8 tid; /* initiator tid for easy lookup */
|
u8 tid; /* initiator tid for easy lookup */
|
||||||
u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */
|
u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */
|
||||||
struct scb *scb; /* backptr for easy lookup */
|
struct scb *scb; /* backptr for easy lookup */
|
||||||
|
u8 ba_wsize; /* negotiated ba window size (in pdu) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AMPDU_MAX_SCB_TID NUMPRIO
|
#define AMPDU_MAX_SCB_TID NUMPRIO
|
||||||
@ -51,7 +51,6 @@ struct scb_ampdu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define SCB_MAGIC 0xbeefcafe
|
#define SCB_MAGIC 0xbeefcafe
|
||||||
#define INI_MAGIC 0xabcd1234
|
|
||||||
|
|
||||||
/* station control block - one per remote MAC address */
|
/* station control block - one per remote MAC address */
|
||||||
struct scb {
|
struct scb {
|
||||||
|
Loading…
Reference in New Issue
Block a user