diff options
| author | Adrian Chadd <adrian@FreeBSD.org> | 2019-05-05 04:56:37 +0000 |
|---|---|---|
| committer | Adrian Chadd <adrian@FreeBSD.org> | 2019-05-05 04:56:37 +0000 |
| commit | 7d450faa6f27823b2bff126363e7606f82b25f3b (patch) | |
| tree | ea8adaebe014a6be8cb941ead993d82c411629cc /sys/dev/ath | |
| parent | 02273ca83275dac07cbf662ef1d4554affd71cce (diff) | |
Notes
Diffstat (limited to 'sys/dev/ath')
| -rw-r--r-- | sys/dev/ath/ath_rate/amrr/amrr.c | 5 | ||||
| -rw-r--r-- | sys/dev/ath/ath_rate/onoe/onoe.c | 6 | ||||
| -rw-r--r-- | sys/dev/ath/ath_rate/sample/sample.c | 6 | ||||
| -rw-r--r-- | sys/dev/ath/if_ath.c | 57 | ||||
| -rw-r--r-- | sys/dev/ath/if_ath_rx.c | 22 | ||||
| -rw-r--r-- | sys/dev/ath/if_ath_tx_edma.c | 2 | ||||
| -rw-r--r-- | sys/dev/ath/if_athrate.h | 6 | ||||
| -rw-r--r-- | sys/dev/ath/if_athvar.h | 1 |
8 files changed, 104 insertions, 1 deletions
diff --git a/sys/dev/ath/ath_rate/amrr/amrr.c b/sys/dev/ath/ath_rate/amrr/amrr.c index 9a7518373c19..a946daef34ed 100644 --- a/sys/dev/ath/ath_rate/amrr/amrr.c +++ b/sys/dev/ath/ath_rate/amrr/amrr.c @@ -196,6 +196,11 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) ath_rate_ctl_start(sc, &an->an_node); } +void +ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi) +{ +} + static void node_reset(struct amrr_node *amn) { diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c index 05604c08823c..7e11d9d350cf 100644 --- a/sys/dev/ath/ath_rate/onoe/onoe.c +++ b/sys/dev/ath/ath_rate/onoe/onoe.c @@ -189,6 +189,12 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) ath_rate_ctl_start(sc, &an->an_node); } +void +ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi) +{ +} + + static void ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) { diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c index 45fad2786849..e0ab13eab719 100644 --- a/sys/dev/ath/ath_rate/sample/sample.c +++ b/sys/dev/ath/ath_rate/sample/sample.c @@ -1019,6 +1019,12 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) ath_rate_ctl_reset(sc, &an->an_node); } +void +ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi) +{ +} + + static const struct txschedule *mrr_schedules[IEEE80211_MODE_MAX+2] = { NULL, /* IEEE80211_MODE_AUTO */ series_11a, /* IEEE80211_MODE_11A */ diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 7e6ab3c614b7..2121d316ce05 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -3882,6 +3882,10 @@ ath_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) /* XXX setup ath_tid */ ath_tx_tid_init(sc, an); + an->an_node_stats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; + an->an_node_stats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; + an->an_node_stats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; + DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__, mac, ":", an); return &an->an_node; } @@ -4493,6 +4497,8 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) sc->sc_stats.ast_tx_rssi = ts->ts_rssi; ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, ts->ts_rssi); + ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgtxrssi, + ts->ts_rssi); } ATH_TXQ_UNLOCK(txq); @@ -5435,6 +5441,16 @@ ath_calibrate(void *arg) __func__, sc->sc_curchan->ic_freq); sc->sc_stats.ast_per_calfail++; } + /* + * XXX TODO: get the NF calibration results from the HAL. + * If we failed NF cal then schedule a hard reset to potentially + * un-freeze the PHY. + * + * Note we have to be careful here to not get stuck in an + * infinite NIC restart. Ideally we'd not restart if we + * failed the first NF cal - that /can/ fail sometimes in + * a noisy environment. + */ if (shortCal) sc->sc_lastshortcal = ticks; } @@ -6090,6 +6106,17 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) taskqueue_block(sc->sc_tq); sc->sc_beacons = 0; } + + /* + * For at least STA mode we likely should clear the ANI + * and NF calibration state and allow the NIC/HAL to figure + * out optimal parameters at runtime. Otherwise if we + * disassociate due to interference / deafness it may persist + * when we reconnect. + * + * Note: may need to do this for other states too, not just + * _S_INIT. + */ #ifdef IEEE80211_SUPPORT_TDMA ath_hal_setcca(ah, AH_TRUE); #endif @@ -6119,9 +6146,39 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) } ATH_UNLOCK(sc); } + + /* + * Note - the ANI/calibration timer isn't re-enabled during + * network sleep for now. One unfortunate side-effect is that + * the PHY/airtime statistics aren't gathered on the channel + * but I haven't yet tested to see if reading those registers + * CAN occur during network sleep. + * + * This should be revisited in a future commit, even if it's + * just to split out the airtime polling from ANI/calibration. + */ } else if (nstate == IEEE80211_S_SCAN) { /* Quiet time handling - ensure we resync */ memset(&avp->quiet_ie, 0, sizeof(avp->quiet_ie)); + + /* + * If we're in scan mode then startpcureceive() is + * hopefully being called with "reset ANI" for this channel; + * but once we attempt to reassociate we program in the previous + * ANI values and.. not do any calibration until we're running. + * This may mean we stay deaf unless we can associate successfully. + * + * So do kick off the cal timer to get NF/ANI going. + */ + ATH_LOCK(sc); + if (ath_longcalinterval != 0) { + /* start periodic recalibration timer */ + callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc); + } else { + DPRINTF(sc, ATH_DEBUG_CALIBRATE, + "%s: calibration disabled\n", __func__); + } + ATH_UNLOCK(sc); } bad: ieee80211_free_node(ni); diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c index 70a2a63b298b..93a1d7455191 100644 --- a/sys/dev/ath/if_ath_rx.c +++ b/sys/dev/ath/if_ath_rx.c @@ -363,6 +363,11 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rxs, rssi, nf); switch (subtype) { case IEEE80211_FC0_SUBTYPE_BEACON: + /* + * Always update the per-node beacon RSSI if we're hearing + * beacons from that node. + */ + ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgbrssi, rssi); /* * Only do the following processing if it's for @@ -946,6 +951,21 @@ rx_accept: m->m_flags |= M_AMPDU; /* + * Inform rate control about the received RSSI. + * It can then use this information to potentially drastically + * alter the available rate based on the RSSI estimate. + * + * This is super important when associating to a far away station; + * you don't want to waste time trying higher rates at some low + * packet exchange rate (like during DHCP) just to establish + * that higher MCS rates aren't available. + */ + ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgrssi, + rs->rs_rssi); + ath_rate_update_rx_rssi(sc, ATH_NODE(ni), + ATH_RSSI(ATH_NODE(ni)->an_node_stats.ns_avgrssi)); + + /* * Sending station is known, dispatch directly. */ (void) ieee80211_add_rx_params(m, &rxs); @@ -973,7 +993,7 @@ rx_accept: */ /* - * Track rx rssi and do any rx antenna management. + * Track legacy station RX rssi and do any rx antenna management. */ ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi); if (sc->sc_diversity) { diff --git a/sys/dev/ath/if_ath_tx_edma.c b/sys/dev/ath/if_ath_tx_edma.c index 375c7ff4bbc8..b7e97428ba69 100644 --- a/sys/dev/ath/if_ath_tx_edma.c +++ b/sys/dev/ath/if_ath_tx_edma.c @@ -1012,6 +1012,8 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched) sc->sc_stats.ast_tx_rssi = ts.ts_rssi; ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, ts.ts_rssi); + ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgtxrssi, + ts.ts_rssi); } /* Handle frame completion and rate control update */ diff --git a/sys/dev/ath/if_athrate.h b/sys/dev/ath/if_athrate.h index 5aec9e6b3870..8cf395c5d828 100644 --- a/sys/dev/ath/if_athrate.h +++ b/sys/dev/ath/if_athrate.h @@ -157,6 +157,12 @@ void ath_rate_tx_complete(struct ath_softc *, struct ath_node *, int pktlen, int nframes, int nbad); /* + * Update rate control with a per-packet receive RSSI value. + */ +void ath_rate_update_rx_rssi(struct ath_softc *, struct ath_node *, + int rssi); + +/* * Fetch the global rate control statistics. */ int ath_rate_fetch_stats(struct ath_softc *sc, struct ath_rateioctl *rs); diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 8f3b7df11ecc..d3200ce6d714 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -204,6 +204,7 @@ struct ath_node { node */ int clrdmask; /* has clrdmask been set */ uint32_t an_leak_count; /* How many frames to leak during pause */ + HAL_NODE_STATS an_node_stats; /* HAL node stats for this node */ /* variable-length rate control state follows */ }; #define ATH_NODE(ni) ((struct ath_node *)(ni)) |
