On Thu, Jan 31, 2019 at 03:32:05PM +0100, Stefan Sperling wrote:
> This diff completes noisefloor calibration code in our athn(4) driver.
> Update default/min/max noisefloor values to those used by Linux.
>
> Tested on AR9280 on 2GHz and 5Ghz. Further tests are appreciated.
jmc@ found out the hard way that my previous diff broke association
to other APs. Fixed in this version.
Index: ar5008.c
===
RCS file: /cvs/src/sys/dev/ic/ar5008.c,v
retrieving revision 1.46
diff -u -p -r1.46 ar5008.c
--- ar5008.c28 Nov 2017 04:35:39 - 1.46
+++ ar5008.c31 Jan 2019 15:17:00 -
@@ -98,10 +98,11 @@ voidar5008_init_chains(struct athn_soft
void ar5008_set_rxchains(struct athn_softc *);
void ar5008_read_noisefloor(struct athn_softc *, int16_t *, int16_t *);
void ar5008_write_noisefloor(struct athn_softc *, int16_t *, int16_t *);
-void ar5008_get_noisefloor(struct athn_softc *, struct ieee80211_channel *);
+intar5008_get_noisefloor(struct athn_softc *);
+void ar5008_apply_noisefloor(struct athn_softc *);
void ar5008_bb_load_noisefloor(struct athn_softc *);
-void ar5008_noisefloor_calib(struct athn_softc *);
void ar5008_do_noisefloor_calib(struct athn_softc *);
+void ar5008_init_noisefloor_calib(struct athn_softc *);
void ar5008_do_calib(struct athn_softc *);
void ar5008_next_calib(struct athn_softc *);
void ar5008_calib_iq(struct athn_softc *);
@@ -176,6 +177,9 @@ ar5008_attach(struct athn_softc *sc)
ops->disable_phy = ar5008_disable_phy;
ops->set_rxchains = ar5008_set_rxchains;
ops->noisefloor_calib = ar5008_do_noisefloor_calib;
+ ops->init_noisefloor_calib = ar5008_init_noisefloor_calib;
+ ops->get_noisefloor = ar5008_get_noisefloor;
+ ops->apply_noisefloor = ar5008_apply_noisefloor;
ops->do_calib = ar5008_do_calib;
ops->next_calib = ar5008_next_calib;
ops->hw_init = ar5008_hw_init;
@@ -1876,15 +1880,15 @@ ar5008_write_noisefloor(struct athn_soft
AR_WRITE_BARRIER(sc);
}
-void
-ar5008_get_noisefloor(struct athn_softc *sc, struct ieee80211_channel *c)
+int
+ar5008_get_noisefloor(struct athn_softc *sc)
{
int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS];
int i;
if (AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
/* Noisefloor calibration not finished. */
- return;
+ return 0;
}
/* Noisefloor calibration is finished. */
ar5008_read_noisefloor(sc, nf, nf_ext);
@@ -1896,6 +1900,7 @@ ar5008_get_noisefloor(struct athn_softc
}
if (++sc->nf_hist_cur >= ATHN_NF_CAL_HIST_MAX)
sc->nf_hist_cur = 0;
+ return 1;
}
void
@@ -1926,14 +1931,41 @@ ar5008_bb_load_noisefloor(struct athn_so
return;
}
- /* Restore noisefloor values to initial (max) values. */
+ /*
+* Restore noisefloor values to initial (max) values. These will
+* be used as initial values during the next NF calibration.
+*/
for (i = 0; i < AR_MAX_CHAINS; i++)
nf[i] = nf_ext[i] = AR_DEFAULT_NOISE_FLOOR;
ar5008_write_noisefloor(sc, nf, nf_ext);
}
void
-ar5008_noisefloor_calib(struct athn_softc *sc)
+ar5008_apply_noisefloor(struct athn_softc *sc)
+{
+ uint32_t agc_nfcal;
+
+ agc_nfcal = AR_READ(sc, AR_PHY_AGC_CONTROL) &
+ (AR_PHY_AGC_CONTROL_NF | AR_PHY_AGC_CONTROL_ENABLE_NF |
+ AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+
+ if (agc_nfcal & AR_PHY_AGC_CONTROL_NF) {
+ /* Pause running NF calibration while values are updated. */
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+ AR_WRITE_BARRIER(sc);
+ }
+
+ ar5008_bb_load_noisefloor(sc);
+
+ if (agc_nfcal & AR_PHY_AGC_CONTROL_NF) {
+ /* Restart interrupted NF calibration. */
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, agc_nfcal);
+ AR_WRITE_BARRIER(sc);
+ }
+}
+
+void
+ar5008_do_noisefloor_calib(struct athn_softc *sc)
{
AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
@@ -1942,7 +1974,7 @@ ar5008_noisefloor_calib(struct athn_soft
}
void
-ar5008_do_noisefloor_calib(struct athn_softc *sc)
+ar5008_init_noisefloor_calib(struct athn_softc *sc)
{
AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
AR_WRITE_BARRIER(sc);
Index: ar5416.c
===
RCS file: /cvs/src/sys/dev/ic/ar5416.c,v
retrieving revision 1.20
diff -u -p -r1.20 ar5416.c
--- ar5416.c12 Jan 2017 16:32:28 - 1.20
+++ ar5416.c31 Jan 2019 12:13:37 -
@@ -112,7 +112,6 @@ ar5416_attach(struct athn_softc *sc)
{
sc->eep_base = AR5416_EEP_START_LOC;
sc->eep_size = sizeof(struct