mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
Temporarily disable multi-rate retry (link quality) and eliminate rate
index lookups. * My recent(ish) change to iwn(4) and the net80211 rate control API to support 11n rates broke the link quality table use. So, until I or someone else decides to fix it, let's just disable it for now. * Teach iwn_tx_data_raw() to use the iwn_rate_to_plcp() function. * Eliminate two uses of the net80211 rate index lookup functions - they are only for legacy rates and they're not needed here. This fixes some invalid looking rate control TX issues that showed up on my 4965 but it doesn't fix the two TX hangs I've noticed. Those look like DMA related issues. Tested: * 4965, STA mode * 5100, STA mode
This commit is contained in:
parent
d884c4ddaa
commit
2e6fe9b630
1 changed files with 70 additions and 25 deletions
|
|
@ -3476,6 +3476,53 @@ iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check whether OFDM 11g protection will be enabled for the given rate.
|
||||
*
|
||||
* The original driver code only enabled protection for OFDM rates.
|
||||
* It didn't check to see whether it was operating in 11a or 11bg mode.
|
||||
*/
|
||||
static int
|
||||
iwn_check_rate_needs_protection(struct iwn_softc *sc,
|
||||
struct ieee80211vap *vap, uint8_t rate)
|
||||
{
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
|
||||
/*
|
||||
* Not in 2GHz mode? Then there's no need to enable OFDM
|
||||
* 11bg protection.
|
||||
*/
|
||||
if (! IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 11bg protection not enabled? Then don't use it.
|
||||
*/
|
||||
if ((ic->ic_flags & IEEE80211_F_USEPROT) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* If it's an 11n rate, then for now we enable
|
||||
* protection.
|
||||
*/
|
||||
if (rate & IEEE80211_RATE_MCS) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a rate table lookup. If the PHY is CCK,
|
||||
* don't do protection.
|
||||
*/
|
||||
if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_CCK)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Yup, enable protection.
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
||||
{
|
||||
|
|
@ -3496,7 +3543,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
|||
uint16_t qos;
|
||||
u_int hdrlen;
|
||||
bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER];
|
||||
uint8_t tid, ridx, txant, type;
|
||||
uint8_t tid, type;
|
||||
int ac, i, totlen, error, pad, nsegs = 0, rate;
|
||||
|
||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
|
||||
|
|
@ -3546,8 +3593,6 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
|||
(void) ieee80211_ratectl_rate(ni, NULL, 0);
|
||||
rate = ni->ni_txrate;
|
||||
}
|
||||
ridx = ieee80211_legacy_rate_lookup(ic->ic_rt,
|
||||
rate & IEEE80211_RATE_VAL);
|
||||
|
||||
/* Encrypt the frame if need be. */
|
||||
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
|
||||
|
|
@ -3604,13 +3649,15 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
|||
/* NB: Group frames are sent using CCK in 802.11b/g. */
|
||||
if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
|
||||
flags |= IWN_TX_NEED_RTS;
|
||||
} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
|
||||
ridx >= IWN_RIDX_OFDM6) {
|
||||
} else if (iwn_check_rate_needs_protection(sc, vap, rate)) {
|
||||
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
|
||||
flags |= IWN_TX_NEED_CTS;
|
||||
else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
|
||||
flags |= IWN_TX_NEED_RTS;
|
||||
}
|
||||
|
||||
/* XXX HT protection? */
|
||||
|
||||
if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
|
||||
if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
|
||||
/* 5000 autoselects RTS/CTS or CTS-to-self. */
|
||||
|
|
@ -3654,6 +3701,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
|||
tx->data_ntries = 15;
|
||||
tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
|
||||
tx->rate = iwn_rate_to_plcp(sc, ni, rate);
|
||||
#if 0
|
||||
if (tx->id == sc->broadcast_id) {
|
||||
/* Group or management frame. */
|
||||
tx->linkq = 0;
|
||||
|
|
@ -3661,9 +3709,21 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
|||
txant = IWN_LSB(sc->txchainmask);
|
||||
tx->rate |= htole32(IWN_RFLAG_ANT(txant));
|
||||
} else {
|
||||
/*
|
||||
* XXX This is no longer true. ni_rates may actually
|
||||
* XXX need to be ni_htrates (for 11n rates) and thus
|
||||
* XXX ridx is totally bogus here.
|
||||
*
|
||||
* XXX So, break this out into a function and look up
|
||||
* XXX the correct place to start the MRR table rate
|
||||
* XXX attempt.
|
||||
*/
|
||||
tx->linkq = ni->ni_rates.rs_nrates - ridx - 1;
|
||||
flags |= IWN_TX_LINKQ; /* enable MRR */
|
||||
}
|
||||
#else
|
||||
tx->linkq = 0; /* Don't enable MRR for now */
|
||||
#endif
|
||||
/* Set physical address of "scratch area". */
|
||||
tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
|
||||
tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
|
||||
|
|
@ -3756,9 +3816,9 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
|
|||
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
|
||||
{
|
||||
struct iwn_ops *ops = &sc->ops;
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
// struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211vap *vap = ni->ni_vap;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
// struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct iwn_tx_cmd *cmd;
|
||||
struct iwn_cmd_data *tx;
|
||||
struct ieee80211_frame *wh;
|
||||
|
|
@ -3770,7 +3830,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
|
|||
uint32_t flags;
|
||||
u_int hdrlen;
|
||||
int ac, totlen, error, pad, nsegs = 0, i, rate;
|
||||
uint8_t ridx, type, txant;
|
||||
uint8_t type;
|
||||
|
||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
|
||||
|
||||
|
|
@ -3786,16 +3846,8 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
|
|||
desc = &ring->desc[ring->cur];
|
||||
data = &ring->data[ring->cur];
|
||||
|
||||
/* Choose a TX rate index. */
|
||||
/* Choose a TX rate. */
|
||||
rate = params->ibp_rate0;
|
||||
ridx = ieee80211_legacy_rate_lookup(ic->ic_rt,
|
||||
rate & IEEE80211_RATE_VAL);
|
||||
if (ridx == (uint8_t)-1) {
|
||||
/* XXX fall back to mcast/mgmt rate? */
|
||||
m_freem(m);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
totlen = m->m_pkthdr.len;
|
||||
|
||||
/* Prepare TX firmware command. */
|
||||
|
|
@ -3865,17 +3917,10 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
|
|||
tx->rts_ntries = params->ibp_try1;
|
||||
tx->data_ntries = params->ibp_try0;
|
||||
tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
|
||||
|
||||
/* XXX should just use iwn_rate_to_plcp() */
|
||||
tx->rate = htole32(rate2plcp(rate));
|
||||
if (ridx < IWN_RIDX_OFDM6 &&
|
||||
IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
|
||||
tx->rate |= htole32(IWN_RFLAG_CCK);
|
||||
tx->rate = iwn_rate_to_plcp(sc, ni, rate);
|
||||
|
||||
/* Group or management frame. */
|
||||
tx->linkq = 0;
|
||||
txant = IWN_LSB(sc->txchainmask);
|
||||
tx->rate |= htole32(IWN_RFLAG_ANT(txant));
|
||||
|
||||
/* Set physical address of "scratch area". */
|
||||
tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
|
||||
|
|
|
|||
Loading…
Reference in a new issue