aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ath
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2019-05-05 04:56:37 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2019-05-05 04:56:37 +0000
commit7d450faa6f27823b2bff126363e7606f82b25f3b (patch)
treeea8adaebe014a6be8cb941ead993d82c411629cc /sys/dev/ath
parent02273ca83275dac07cbf662ef1d4554affd71cce (diff)
Notes
Diffstat (limited to 'sys/dev/ath')
-rw-r--r--sys/dev/ath/ath_rate/amrr/amrr.c5
-rw-r--r--sys/dev/ath/ath_rate/onoe/onoe.c6
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c6
-rw-r--r--sys/dev/ath/if_ath.c57
-rw-r--r--sys/dev/ath/if_ath_rx.c22
-rw-r--r--sys/dev/ath/if_ath_tx_edma.c2
-rw-r--r--sys/dev/ath/if_athrate.h6
-rw-r--r--sys/dev/ath/if_athvar.h1
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))