Commit 32d0f12a authored by Seth Forshee's avatar Seth Forshee Committed by John W. Linville

brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels

The mac80211 tx queues and brcmsmac DMA fifos both map directly to AC
levels. Therefore it's much more straightforward to queue tx frames and
choose the tx fifo based on the mac80211 queue instead of mapping 802.1D
priority tags to precedence levels then back to AC levels. mac80211
already maps the 802.1D levels to the appropriate AC levels and queues
management frames at the maximum priority, so the results should be
identical.

One functional change resulting from this patch is that AMPDU retries no
longer get a priority boost to queue them ahead of packets with the same
priority already in the tx queue. This behavior will be restored (in
effect at least) in a later patch when the tx queue is removed.
Signed-off-by: default avatarSeth Forshee <seth.forshee@canonical.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Tested-by: default avatarDaniel Wagner <wagi@monom.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7f2de08f
...@@ -827,7 +827,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, ...@@ -827,7 +827,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
struct scb *scb; struct scb *scb;
struct scb_ampdu *scb_ampdu; struct scb_ampdu *scb_ampdu;
struct scb_ampdu_tid_ini *ini; struct scb_ampdu_tid_ini *ini;
struct brcms_fifo_info *f;
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
u16 qlen; u16 qlen;
struct wiphy *wiphy; struct wiphy *wiphy;
...@@ -838,8 +837,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, ...@@ -838,8 +837,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
tid = (u8) (p->priority); tid = (u8) (p->priority);
f = ampdu->fifo_tb + prio2fifo[tid];
scb = &wlc->pri_scb; scb = &wlc->pri_scb;
scb_ampdu = &scb->scb_ampdu; scb_ampdu = &scb->scb_ampdu;
ini = &scb_ampdu->ini[tid]; ini = &scb_ampdu->ini[tid];
...@@ -1048,8 +1045,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ...@@ -1048,8 +1045,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
* if there were underflows, but pre-loading * if there were underflows, but pre-loading
* is not active, notify rate adaptation. * is not active, notify rate adaptation.
*/ */
if (brcms_c_ffpld_check_txfunfl(wlc, if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0)
prio2fifo[tid]) > 0)
tx_error = true; tx_error = true;
} }
} else if (txs->phyerr) { } else if (txs->phyerr) {
...@@ -1119,12 +1115,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ...@@ -1119,12 +1115,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
if (retry && (ini->txretry[index] < (int)retry_limit)) { if (retry && (ini->txretry[index] < (int)retry_limit)) {
ini->txretry[index]++; ini->txretry[index]++;
ini->tx_in_transit--; ini->tx_in_transit--;
/* brcms_c_txq_enq(wlc, scb, p);
* Use high prededence for retransmit to
* give some punch
*/
brcms_c_txq_enq(wlc, scb, p,
BRCMS_PRIO_TO_HI_PREC(tid));
} else { } else {
/* Retry timeout */ /* Retry timeout */
ini->tx_in_transit--; ini->tx_in_transit--;
......
...@@ -277,17 +277,6 @@ struct edcf_acparam { ...@@ -277,17 +277,6 @@ struct edcf_acparam {
u16 TXOP; u16 TXOP;
} __packed; } __packed;
const u8 prio2fifo[NUMPRIO] = {
TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */
TX_AC_BK_FIFO, /* 1 BK AC_BK Background */
TX_AC_BK_FIFO, /* 2 -- AC_BK Background */
TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */
TX_AC_VI_FIFO, /* 4 CL AC_VI Video */
TX_AC_VI_FIFO, /* 5 VI AC_VI Video */
TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */
TX_AC_VO_FIFO /* 7 NC AC_VO Voice */
};
/* debug/trace */ /* debug/trace */
uint brcm_msg_level = uint brcm_msg_level =
#if defined(DEBUG) #if defined(DEBUG)
...@@ -314,18 +303,6 @@ static const u8 wme_ac2fifo[] = { ...@@ -314,18 +303,6 @@ static const u8 wme_ac2fifo[] = {
TX_AC_BK_FIFO TX_AC_BK_FIFO
}; };
/* 802.1D Priority to precedence queue mapping */
const u8 wlc_prio2prec_map[] = {
_BRCMS_PREC_BE, /* 0 BE - Best-effort */
_BRCMS_PREC_BK, /* 1 BK - Background */
_BRCMS_PREC_NONE, /* 2 None = - */
_BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
_BRCMS_PREC_CL, /* 4 CL - Controlled Load */
_BRCMS_PREC_VI, /* 5 Vi - Video */
_BRCMS_PREC_VO, /* 6 Vo - Voice */
_BRCMS_PREC_NC, /* 7 NC - Network Control */
};
static const u16 xmtfifo_sz[][NFIFO] = { static const u16 xmtfifo_sz[][NFIFO] = {
/* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
{20, 192, 192, 21, 17, 5}, {20, 192, 192, 21, 17, 5},
...@@ -365,6 +342,21 @@ static const char fifo_names[6][0]; ...@@ -365,6 +342,21 @@ static const char fifo_names[6][0];
static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
#endif #endif
/* Mapping of ieee80211 AC numbers to tx fifos */
static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
[IEEE80211_AC_VO] = TX_AC_VO_FIFO,
[IEEE80211_AC_VI] = TX_AC_VI_FIFO,
[IEEE80211_AC_BE] = TX_AC_BE_FIFO,
[IEEE80211_AC_BK] = TX_AC_BK_FIFO,
};
static u8 brcms_ac_to_fifo(u8 ac)
{
if (ac >= ARRAY_SIZE(ac_to_fifo_mapping))
return TX_AC_BE_FIFO;
return ac_to_fifo_mapping[ac];
}
/* Find basic rate for a given rate */ /* Find basic rate for a given rate */
static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
{ {
...@@ -3753,12 +3745,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, ...@@ -3753,12 +3745,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
{ {
wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
} }
/* push sw hps and wake state through hardware */ /* push sw hps and wake state through hardware */
...@@ -6068,14 +6054,13 @@ static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, ...@@ -6068,14 +6054,13 @@ static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
} }
void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
struct sk_buff *sdu, uint prec) struct sk_buff *sdu)
{ {
struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
struct pktq *q = &qi->q; struct pktq *q = &qi->q;
int prio; uint prec;
prio = sdu->priority;
prec = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
if (!brcms_c_prec_enq(wlc, q, sdu, prec)) { if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
/* /*
* we might hit this condtion in case * we might hit this condtion in case
...@@ -7248,21 +7233,13 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, ...@@ -7248,21 +7233,13 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
struct ieee80211_hw *hw) struct ieee80211_hw *hw)
{ {
u8 prio;
uint fifo; uint fifo;
struct scb *scb = &wlc->pri_scb; struct scb *scb = &wlc->pri_scb;
struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
/* fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
* 802.11 standard requires management traffic
* to go at highest priority
*/
prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
MAXPRIO;
fifo = prio2fifo[prio];
if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
return; return;
brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)); brcms_c_txq_enq(wlc, scb, sdu);
brcms_c_send_q(wlc); brcms_c_send_q(wlc);
} }
...@@ -7402,7 +7379,7 @@ brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo) ...@@ -7402,7 +7379,7 @@ brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo)
wlc->core->txpktpend[fifo]); wlc->core->txpktpend[fifo]);
/* There is more room; mark precedences related to this FIFO sendable */ /* There is more room; mark precedences related to this FIFO sendable */
wlc->tx_prec_map |= wlc->fifo2prec_map[fifo]; wlc->tx_prec_map |= 1 << fifo;
/* figure out which bsscfg is being worked on... */ /* figure out which bsscfg is being worked on... */
} }
...@@ -7877,7 +7854,7 @@ int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop) ...@@ -7877,7 +7854,7 @@ int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) { if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
/* Mark precedences related to this FIFO, unsendable */ /* Mark precedences related to this FIFO, unsendable */
/* A fifo is full. Clear precedences related to that FIFO */ /* A fifo is full. Clear precedences related to that FIFO */
wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]); wlc->tx_prec_map &= ~(1 << fifo);
return -EBUSY; return -EBUSY;
} }
return 0; return 0;
......
...@@ -101,9 +101,6 @@ ...@@ -101,9 +101,6 @@
#define DATA_BLOCK_TX_SUPR (1 << 4) #define DATA_BLOCK_TX_SUPR (1 << 4)
/* 802.1D Priority to TX FIFO number for wme */
extern const u8 prio2fifo[];
/* Ucode MCTL_WAKE override bits */ /* Ucode MCTL_WAKE override bits */
#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
...@@ -534,7 +531,6 @@ struct brcms_c_info { ...@@ -534,7 +531,6 @@ struct brcms_c_info {
u16 wme_retries[IEEE80211_NUM_ACS]; u16 wme_retries[IEEE80211_NUM_ACS];
u16 tx_prec_map; u16 tx_prec_map;
u16 fifo2prec_map[NFIFO];
struct brcms_bss_cfg *bsscfg; struct brcms_bss_cfg *bsscfg;
...@@ -641,7 +637,7 @@ extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, ...@@ -641,7 +637,7 @@ extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
struct sk_buff *p, bool commit); struct sk_buff *p, bool commit);
extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo); extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo);
extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
struct sk_buff *sdu, uint prec); struct sk_buff *sdu);
extern void brcms_c_print_txstatus(struct tx_status *txs); extern void brcms_c_print_txstatus(struct tx_status *txs);
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks); uint *blocks);
......
...@@ -200,13 +200,7 @@ enum wlc_par_id { ...@@ -200,13 +200,7 @@ enum wlc_par_id {
/* WL11N Support */ /* WL11N Support */
#define AMPDU_AGG_HOST 1 #define AMPDU_AGG_HOST 1
/* pri is priority encoded in the packet. This maps the Packet priority to #define BRCMS_PREC_COUNT 4 /* Max precedence level implemented */
* enqueue precedence as defined in wlc_prec_map
*/
extern const u8 wlc_prio2prec_map[];
#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
/* Mask to describe all precedence levels */ /* Mask to describe all precedence levels */
#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT) #define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
...@@ -219,24 +213,6 @@ extern const u8 wlc_prio2prec_map[]; ...@@ -219,24 +213,6 @@ extern const u8 wlc_prio2prec_map[];
#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ #define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
BRCMS_PREC_COUNT - 1) BRCMS_PREC_COUNT - 1)
/* Define a bitmap of precedences comprised by each AC */
#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
/* network protection config */ /* network protection config */
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment