Re: athn(4) noisefloor calibration

2019-01-31 Thread Klemens Nanni
On Thu, Jan 31, 2019 at 11:02:05PM +0100, Juan Francisco Cantero Hurtado wrote:
> Works for me with an AR9271. I don't see differences.
Same here on AR9287 in a busy network with lots of clients, fwiw.
Resume/suspend, up/down, etc. all works as expected as without the diff.



Re: athn(4) noisefloor calibration

2019-01-31 Thread Juan Francisco Cantero Hurtado
On Thu, Jan 31, 2019 at 04:30:30PM +0100, Stefan Sperling wrote:
> 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.

Works for me with an AR9271. I don't see differences.


-- 
Juan Francisco Cantero Hurtado http://juanfra.info



Re: athn(4) noisefloor calibration

2019-01-31 Thread Stefan Sperling
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