People with AR9285/AR9287/AR9227 devices, please test the
following diff to see if there is no regression.
It adds support for newer AR9285 devices (XE) but it also
changes behavior for legacy AR9285 devices.

Damien

Index: athn.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/athn.c,v
retrieving revision 1.31
diff -u -p -r1.31 athn.c
--- athn.c      5 Apr 2010 19:09:00 -0000       1.31
+++ athn.c      6 Apr 2010 16:52:45 -0000
@@ -242,9 +242,6 @@ athn_attach(struct athn_softc *sc)
        }
        base = sc->eep;
 
-       /* We can put the chip in sleep state now. */
-       athn_set_power_sleep(sc);
-
        eep_ver = (base->version >> 12) & 0xf;
        sc->eep_rev = (base->version & 0xfff);
        if (eep_ver != AR_EEP_VER || sc->eep_rev == 0) {
@@ -252,8 +249,10 @@ athn_attach(struct athn_softc *sc)
                    sc->eep_rev);
                return (EINVAL);
        }
-
        sc->ops.setup(sc);
+
+       /* We can put the chip in sleep state now. */
+       athn_set_power_sleep(sc);
 
        IEEE80211_ADDR_COPY(ic->ic_myaddr, base->macAddr);
        printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
Index: athnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/athnreg.h,v
retrieving revision 1.6
diff -u -p -r1.6 athnreg.h
--- athnreg.h   24 Feb 2010 19:39:43 -0000      1.6
+++ athnreg.h   6 Apr 2010 16:52:48 -0000
@@ -365,6 +365,7 @@
 #define AR_PHY_PDADC_TBL_BASE          0xa280
 #define AR_PHY_TX_GAIN_TBL(i)          (0xa300 + (i) * 4)
 #define AR_PHY_CL_CAL_CTL              0xa358
+#define AR_PHY_CLC_TBL(i)              (0xa35c + (i) * 4)
 #define AR_PHY_POWER_TX_RATE5          0xa38c
 #define AR_PHY_POWER_TX_RATE6          0xa390
 #define AR_PHY_CH0_TX_PWRCTRL11                0xa398
@@ -842,7 +843,7 @@
 /* Bits for AR_WA. */
 #define AR5416_WA_DEFAULT      0x0000073f
 #define AR9280_WA_DEFAULT      0x0040073b
-#define AR9285_WA_DEFAULT      0x004a05cb
+#define AR9285_WA_DEFAULT      0x004a050b
 #define AR_WA_UNTIE_RESET_EN   0x00008000
 #define AR_WA_RESET_EN         0x00040000
 #define AR_WA_ANALOG_SHIFT     0x00100000
@@ -1785,6 +1786,8 @@
 #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S       24
 
 /* Bits for AR_PHY_TX_PWRCTRL7. */
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_M    0x0007e000
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S    13
 #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_M       0x01f80000
 #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S       19
 
@@ -1794,6 +1797,8 @@
 #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL      0x80000000
 
 /* Bits for AR_PHY_TX_GAIN_TBL. */
+#define AR_PHY_TX_GAIN_CLC_M   0x0000001e
+#define AR_PHY_TX_GAIN_CLC_S   1
 #define AR_PHY_TX_GAIN_M       0x0007f000
 #define AR_PHY_TX_GAIN_S       12
 
@@ -1824,6 +1829,12 @@
 /* Bits for AR_PHY_CL_CAL_CTL. */
 #define AR_PHY_PARALLEL_CAL_ENABLE     0x00000001
 #define AR_PHY_CL_CAL_ENABLE           0x00000002
+
+/* Bits for AR_PHY_CLC_TBL. */
+#define AR_PHY_CLC_Q0_M                0x0000ffd0
+#define AR_PHY_CLC_Q0_S                5
+#define AR_PHY_CLC_I0_M                0x07ff0000
+#define AR_PHY_CLC_I0_S                16
 
 /* Bits for AR_PHY_XPA_CFG. */
 #define AR_PHY_FORCE_XPA_CFG   0x000000001
Index: ar9285.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ar9285.c,v
retrieving revision 1.5
diff -u -p -r1.5 ar9285.c
--- ar9285.c    7 Feb 2010 12:02:52 -0000       1.5
+++ ar9285.c    6 Apr 2010 16:52:49 -0000
@@ -1,8 +1,8 @@
 /*     $OpenBSD: ar9285.c,v 1.5 2010/02/07 12:02:52 damien Exp $       */
 
 /*-
- * Copyright (c) 2009 Damien Bergamini <damien.bergam...@free.fr>
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009-2010 Damien Bergamini <damien.bergam...@free.fr>
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -73,7 +73,7 @@ const struct ar_spur_chan *ar9285_get_sp
 void   ar9285_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
            struct ieee80211_channel *);
 void   ar9285_pa_calib(struct athn_softc *);
-int    ar9285_1_2_init_calib(struct athn_softc *, struct ieee80211_channel *,
+int    ar9285_1_2_cl_cal(struct athn_softc *, struct ieee80211_channel *,
            struct ieee80211_channel *);
 void   ar9285_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
            int, uint8_t, uint8_t *, uint8_t *);
@@ -113,14 +113,21 @@ ar9285_setup(struct athn_softc *sc)
        const struct ar9285_eeprom *eep = sc->eep;
        uint8_t type;
 
-       if (AR_SREV_9285_12(sc)) {
+       if (AR_SREV_9285_12_OR_LATER(sc)) {
                /* Select initialization values based on ROM. */
                type = eep->baseEepHeader.txGainType;
                DPRINTF(("Tx gain type=0x%x\n", type));
-               if (type == AR_EEP_TXGAIN_HIGH_POWER)
-                       sc->tx_gain = &ar9285_1_2_tx_gain_high_power;
-               else
-                       sc->tx_gain = &ar9285_1_2_tx_gain;
+               if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) { /* XE rev. */
+                       if (type == AR_EEP_TXGAIN_HIGH_POWER)
+                               sc->tx_gain = &ar9285_2_0_tx_gain_high_power;
+                       else
+                               sc->tx_gain = &ar9285_2_0_tx_gain;
+               } else {
+                       if (type == AR_EEP_TXGAIN_HIGH_POWER)
+                               sc->tx_gain = &ar9285_1_2_tx_gain_high_power;
+                       else
+                               sc->tx_gain = &ar9285_1_2_tx_gain;
+               }
        }
 }
 
@@ -456,10 +463,10 @@ ar9285_pa_calib(struct athn_softc *sc)
 }
 
 /*
- * Carrier Leak Calibration (>= AR9285 1.2 only.)
+ * Carrier Leakage Calibration (>= AR9285 1.2 only.)
  */
 int
-ar9285_1_2_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
+ar9285_1_2_cl_cal(struct athn_softc *sc, struct ieee80211_channel *c,
     struct ieee80211_channel *extc)
 {
        int ntries;
@@ -502,6 +509,54 @@ ar9285_1_2_init_calib(struct athn_softc 
        AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
        AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
        return (0);
+}
+
+int
+ar9285_1_2_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
+    struct ieee80211_channel *extc)
+{
+       uint32_t reg, mask, clcgain, rf2g5_svg;
+       int i, maxgain, nclcs, thresh, error;
+
+       /* Do carrier leakage calibration. */
+       if ((error = ar9285_1_2_cl_cal(sc, c, extc)) != 0)
+               return (error);
+
+       mask = 0;
+       nclcs = 0;
+       reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7);
+       maxgain = MS(reg, AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
+       for (i = 0; i <= maxgain; i++) {
+               reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i));
+               clcgain = MS(reg, AR_PHY_TX_GAIN_CLC);
+               /* NB: clcgain <= 0xf. */
+               if (!(mask & (1 << clcgain))) {
+                       mask |= 1 << clcgain;
+                       nclcs++;
+               }
+       }
+       thresh = 0;
+       for (i = 0; i < nclcs; i++) {
+               reg = AR_READ(sc, AR_PHY_CLC_TBL(i));
+               if (MS(reg, AR_PHY_CLC_I0) == 0)
+                       thresh++;
+               if (MS(reg, AR_PHY_CLC_Q0) == 0)
+                       thresh++;
+       }
+       if (thresh <= AR9285_CL_CAL_REDO_THRESH)
+               return (0);     /* No need to redo. */
+
+       /* Threshold reached, redo carrier leakage calibration. */
+       DPRINTFN(2, ("CLC threshold=%d\n", thresh));
+       rf2g5_svg = reg = AR_READ(sc, AR9285_AN_RF2G5);
+       if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1)   /* XE rev. */
+               reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x5);
+       else
+               reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x4);
+       AR_WRITE(sc, AR9285_AN_RF2G5, reg);
+       error = ar9285_1_2_cl_cal(sc, c, extc);
+       AR_WRITE(sc, AR9285_AN_RF2G5, rf2g5_svg);
+       return (error);
 }
 
 void
Index: ar9285reg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/ar9285reg.h,v
retrieving revision 1.1
diff -u -p -r1.1 ar9285reg.h
--- ar9285reg.h 14 Nov 2009 16:55:11 -0000      1.1
+++ ar9285reg.h 6 Apr 2010 16:52:50 -0000
@@ -21,6 +21,8 @@
 
 #define AR9285_PHY_CCA_MAX_GOOD_VALUE  (-118)
 
+#define AR9285_CL_CAL_REDO_THRESH      1
+
 /*
  * Analog registers.
  */
@@ -28,6 +30,7 @@
 #define AR9285_AN_RF2G2                        0x7824
 #define AR9285_AN_RF2G3                        0x7828
 #define AR9285_AN_RF2G4                        0x782c
+#define AR9285_AN_RF2G5                        0x7830
 #define AR9285_AN_RF2G6                        0x7834
 #define AR9285_AN_RF2G7                        0x7838
 #define AR9285_AN_RF2G8                        0x783c
@@ -81,6 +84,10 @@
 #define AR9285_AN_RF2G4_DB2_4_M                0x00003800
 #define AR9285_AN_RF2G4_DB2_4_S                11
 
+/* Bits for AR9285_AN_RF2G5. */
+#define AR9285_AN_RF2G5_IC50TX_M       0x00000700
+#define AR9285_AN_RF2G5_IC50TX_S       8
+
 /* Bits for AR9285_AN_RF2G6. */
 #define AR9285_AN_RF2G6_CCOMP_M                0x00007800
 #define AR9285_AN_RF2G6_CCOMP_S                11
@@ -676,10 +683,10 @@ static const uint32_t ar9285_1_2_vals_2g
        0x00058088, 0x0005808c, 0x00058100, 0x00058104, 0x00058108,
        0x0005810c, 0x00058110, 0x00058114, 0x00058180, 0x00058184,
        0x00058188, 0x0005818c, 0x00058190, 0x00058194, 0x000581a0,
-       0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058220,
+       0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058224,
        0x00058290, 0x00058300, 0x00058304, 0x00058308, 0x0005830c,
        0x00058380, 0x00058384, 0x00068700, 0x00068704, 0x00068708,
-       0x0006870c, 0x00068780, 0x00068784, 0x00078b04, 0x00078b08,
+       0x0006870c, 0x00068780, 0x00068784, 0x00078b00, 0x00078b04,
        0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88,
        0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88,
        0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, 0x000db384,
@@ -702,10 +709,10 @@ static const uint32_t ar9285_1_2_vals_2g
        0x00058100, 0x00058104, 0x00058108, 0x0005810c, 0x00058110,
        0x00058114, 0x00058180, 0x00058184, 0x00058188, 0x0005818c,
        0x00058190, 0x00058194, 0x000581a0, 0x0005820c, 0x000581a8,
-       0x00058284, 0x00058288, 0x00058220, 0x00058290, 0x00058300,
+       0x00058284, 0x00058288, 0x00058224, 0x00058290, 0x00058300,
        0x00058304, 0x00058308, 0x0005830c, 0x00058380, 0x00058384,
        0x00068700, 0x00068704, 0x00068708, 0x0006870c, 0x00068780,
-       0x00068784, 0x00078b04, 0x00078b08, 0x00078b08, 0x00078b0c,
+       0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, 0x00078b0c,
        0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, 0x00078b90,
        0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, 0x000caf90,
        0x000db30c, 0x000db310, 0x000db384, 0x000db388, 0x000db324,
@@ -741,10 +748,10 @@ static const uint32_t ar9285_1_2_vals_2g
        0x00058088, 0x0005808c, 0x00058100, 0x00058104, 0x00058108,
        0x0005810c, 0x00058110, 0x00058114, 0x00058180, 0x00058184,
        0x00058188, 0x0005818c, 0x00058190, 0x00058194, 0x000581a0,
-       0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058220,
+       0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058224,
        0x00058290, 0x00058300, 0x00058304, 0x00058308, 0x0005830c,
        0x00058380, 0x00058384, 0x00068700, 0x00068704, 0x00068708,
-       0x0006870c, 0x00068780, 0x00068784, 0x00078b04, 0x00078b08,
+       0x0006870c, 0x00068780, 0x00068784, 0x00078b00, 0x00078b04,
        0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88,
        0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88,
        0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, 0x000db384,
@@ -767,10 +774,10 @@ static const uint32_t ar9285_1_2_vals_2g
        0x00058100, 0x00058104, 0x00058108, 0x0005810c, 0x00058110,
        0x00058114, 0x00058180, 0x00058184, 0x00058188, 0x0005818c,
        0x00058190, 0x00058194, 0x000581a0, 0x0005820c, 0x000581a8,
-       0x00058284, 0x00058288, 0x00058220, 0x00058290, 0x00058300,
+       0x00058284, 0x00058288, 0x00058224, 0x00058290, 0x00058300,
        0x00058304, 0x00058308, 0x0005830c, 0x00058380, 0x00058384,
        0x00068700, 0x00068704, 0x00068708, 0x0006870c, 0x00068780,
-       0x00068784, 0x00078b04, 0x00078b08, 0x00078b08, 0x00078b0c,
+       0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, 0x00078b0c,
        0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, 0x00078b90,
        0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, 0x000caf90,
        0x000db30c, 0x000db310, 0x000db384, 0x000db388, 0x000db324,
@@ -854,8 +861,7 @@ static const uint16_t ar9285_1_2_cm_regs
        P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0), P(0x0a3c4),
        P(0x0a3cc), P(0x0a3d0), P(0x0a3d4), P(0x0a3e4), P(0x0a3e8),
        P(0x0a3ec), P(0x07800), P(0x07804), P(0x07808), P(0x0780c),
-       P(0x07810), P(0x07814), P(0x0781c), P(0x07824), P(0x07828),
-       P(0x0782c), P(0x07830), P(0x07834), P(0x0783c), P(0x07840),
+       P(0x07810), P(0x0781c), P(0x07824), P(0x0782c), P(0x07834),
        P(0x07844), P(0x07848), P(0x0784c), P(0x07850), P(0x07854),
        P(0x07858), P(0x0785c), P(0x07860), P(0x07864), P(0x07868),
        P(0x07870)
@@ -922,9 +928,8 @@ static const uint32_t ar9285_1_2_cm_vals
        0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
        0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x18c43433,
        0x00f70081, 0x00140000, 0x0e4548d8, 0x54214514, 0x02025830,
-       0x71c0d388, 0x924934a8, 0x00000000, 0x00d86fff, 0x26d2491b,
-       0x6e36d97b, 0xedb6d96e, 0x71400087, 0x0001fffe, 0xffeb1a20,
-       0x000c0db6, 0x6db61b6f, 0x6d9b66db, 0x6d8c6dba, 0x00040000,
+       0x71c0d388, 0x00000000, 0x00d86fff, 0x6e36d97b, 0x71400087,
+       0x000c0db6, 0x6db6246f, 0x6d9b66db, 0x6d8c6dba, 0x00040000,
        0xdb003012, 0x04924914, 0x21084210, 0xf7d7ffde, 0xc2034080,
        0x10142c00
 };
@@ -951,7 +956,8 @@ static const uint16_t ar9285_1_2_tx_gain
        P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324),
        P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334), P(0x0a338),
        P(0x0a33c), P(0x0a340), P(0x0a344), P(0x0a348), P(0x0a34c),
-       P(0x0a350), P(0x0a354), P(0x07838), P(0x0786c), P(0x07820),
+       P(0x0a350), P(0x0a354), P(0x07814), P(0x07828), P(0x07830),
+       P(0x07838), P(0x0783c), P(0x07840), P(0x0786c), P(0x07820),
        P(0x0a274), P(0x0a278), P(0x0a27c), P(0x0a394), P(0x0a398),
        P(0x0a3dc), P(0x0a3e0)
 };
@@ -961,7 +967,8 @@ static const uint32_t ar9285_1_2_tx_gain
        0x0002a6c9, 0x00031710, 0x00035718, 0x00038758, 0x0003c75a,
        0x0004075c, 0x0004475e, 0x0004679f, 0x000487df, 0x0003891e,
        0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
-       0x0003e9df, 0x0003e9df, 0xfac68801, 0x48609eb4, 0x00000c04,
+       0x0003e9df, 0x0003e9df, 0x924934a8, 0x26d2491b, 0xedb6d96e,
+       0xfac68801, 0x0001fffe, 0xffeb1a20, 0x48609eb4, 0x00000c04,
        0x0a21a652, 0x39ce739c, 0x050e039c, 0x39ce739c, 0x0000039c,
        0x39ce739c, 0x0000039c
 };
@@ -978,7 +985,8 @@ static const uint32_t ar9285_1_2_tx_gain
        0x0000f600, 0x00012800, 0x00016802, 0x0001b805, 0x00021a80,
        0x00028b00, 0x0002ab40, 0x0002cd80, 0x00033d82, 0x0003891e,
        0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
-       0x0003e9df, 0x0003e9df, 0xfac68803, 0x08609ebe, 0x00000c00,
+       0x0003e9df, 0x0003e9df, 0x924934a8, 0x26d2491b, 0xedb6d96e,
+       0xfac68803, 0x0001fffe, 0xffeb1a20, 0x08609ebe, 0x00000c00,
        0x0a216652, 0x0e739ce7, 0x050380e7, 0x0e739ce7, 0x000000e7,
        0x0e739ce7, 0x000000e7
 };
@@ -988,4 +996,43 @@ static const struct athn_gain ar9285_1_2
        ar9285_1_2_tx_gain_regs,
        NULL,   /* 2GHz only. */
        ar9285_1_2_tx_gain_high_power_vals_2g
+};
+
+/*
+ * AR9285 XE 2.0 Tx gains.
+ */
+static const uint32_t ar9285_2_0_tx_gain_vals_2g[] = {
+       0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x00022618,
+       0x0002a6c9, 0x00031710, 0x00035718, 0x00038758, 0x0003c75a,
+       0x0004075c, 0x0004475e, 0x0004679f, 0x000487df, 0x0003891e,
+       0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+       0x0003e9df, 0x0003e9df, 0x92497ca8, 0x2ad2491b, 0xedb6da6e,
+       0xdac71441, 0x2481f6fe, 0xba5f638c, 0x48609eb4, 0x00000c04,
+       0x0a21a652, 0x39ce739c, 0x050e039c, 0x39ce739c, 0x0000039c,
+       0x39ce739c, 0x0000039c
+};
+
+static const struct athn_gain ar9285_2_0_tx_gain = {
+       nitems(ar9285_1_2_tx_gain_regs),
+       ar9285_1_2_tx_gain_regs,
+       NULL,   /* 2GHz only. */
+       ar9285_2_0_tx_gain_vals_2g
+};
+
+static const uint32_t ar9285_2_0_tx_gain_high_power_vals_2g[] = {
+       0x00000000, 0x00006200, 0x00008201, 0x0000b240, 0x0000d241,
+       0x0000f600, 0x00012800, 0x00016802, 0x0001b805, 0x00021a80,
+       0x00028b00, 0x0002ab40, 0x0002cd80, 0x00033d82, 0x0003891e,
+       0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+       0x0003e9df, 0x0003e9df, 0x92497ca8, 0x2ad2491b, 0xedb6da6e,
+       0xdac71443, 0x2481f6fe, 0xba5f638c, 0x08609ebe, 0x00000c00,
+       0x0a216652, 0x0e739ce7, 0x050380e7, 0x0e739ce7, 0x000000e7,
+       0x0e739ce7, 0x000000e7
+};
+
+static const struct athn_gain ar9285_2_0_tx_gain_high_power = {
+       nitems(ar9285_1_2_tx_gain_regs),
+       ar9285_1_2_tx_gain_regs,
+       NULL,   /* 2GHz only. */
+       ar9285_2_0_tx_gain_high_power_vals_2g
 };

Reply via email to