Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Pull in some hardware support from FreeBSD. Also...



details:   https://anonhg.NetBSD.org/src/rev/3b464da01d03
branches:  trunk
changeset: 825522:3b464da01d03
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Wed Jul 19 16:55:12 2017 +0000

description:
Pull in some hardware support from FreeBSD. Also fix 5GHz mode by
adapting the method described in: https://forums.freebsd.org/threads/53574/.

diffstat:

 sys/dev/pci/if_iwn.c    |  80 ++++++++++++++++++++++++++++++++++++++++++++----
 sys/dev/pci/if_iwnreg.h |  60 +++++++++++++++++++++++++++++++----
 sys/dev/pci/if_iwnvar.h |   6 +++-
 3 files changed, 130 insertions(+), 16 deletions(-)

diffs (truncated from 364 to 300 lines):

diff -r b9671ee58957 -r 3b464da01d03 sys/dev/pci/if_iwn.c
--- a/sys/dev/pci/if_iwn.c      Wed Jul 19 16:37:17 2017 +0000
+++ b/sys/dev/pci/if_iwn.c      Wed Jul 19 16:55:12 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_iwn.c,v 1.84 2017/02/02 10:05:35 nonaka Exp $       */
+/*     $NetBSD: if_iwn.c,v 1.85 2017/07/19 16:55:12 mlelstv Exp $      */
 /*     $OpenBSD: if_iwn.c,v 1.135 2014/09/10 07:22:09 dcoppa Exp $     */
 
 /*-
@@ -22,7 +22,7 @@
  * adapters.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.84 2017/02/02 10:05:35 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.85 2017/07/19 16:55:12 mlelstv Exp $");
 
 #define IWN_USE_RBUF   /* Use local storage for RX */
 #undef IWN_HWCRYPTO    /* XXX does not even compile yet */
@@ -790,7 +790,7 @@
                        sc->fwname = "iwlwifi-6000g2a-5.ucode";
                break;
        case IWN_HW_REV_TYPE_2030:
-               sc->limits = &iwn2000_sensitivity_limits;
+               sc->limits = &iwn2030_sensitivity_limits;
                sc->fwname = "iwlwifi-2030-6.ucode";
                ops->config_bt_coex = iwn_config_bt_coex_adv2;
                break;
@@ -1781,6 +1781,7 @@
        struct iwn_eeprom_enhinfo enhinfo[35];
        uint16_t val, base;
        int8_t maxpwr;
+       uint8_t flags;
        int i;
 
        iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
@@ -1790,7 +1791,8 @@
 
        memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr);
        for (i = 0; i < __arraycount(enhinfo); i++) {
-               if (enhinfo[i].chan == 0 || enhinfo[i].reserved != 0)
+               flags = enhinfo[i].flags;
+               if (!(flags & IWN_ENHINFO_VALID))
                        continue;       /* Skip invalid entries. */
 
                maxpwr = 0;
@@ -1915,6 +1917,10 @@
                sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
                sc->calib.state = IWN_CALIB_STATE_INIT;
 
+               /* Wait until we hear a beacon before we transmit */
+               if (IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan))
+                       sc->sc_beacon_wait = 1;
+
                if ((error = iwn_auth(sc)) != 0) {
                        aprint_error_dev(sc->sc_dev,
                            "could not move to auth state\n");
@@ -1923,6 +1929,18 @@
                break;
 
        case IEEE80211_S_RUN:
+               /*
+                * RUN -> RUN transition; Just restart timers.
+                */
+               if (ic->ic_state == IEEE80211_S_RUN) {
+                       sc->calib_cnt = 0;
+                       break;
+               }
+
+               /* Wait until we hear a beacon before we transmit */
+               if (IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan))
+                       sc->sc_beacon_wait = 1;
+
                if ((error = iwn_run(sc)) != 0) {
                        aprint_error_dev(sc->sc_dev,
                            "could not move to run state\n");
@@ -1933,6 +1951,13 @@
        case IEEE80211_S_INIT:
                sc->sc_flags &= ~IWN_FLAG_SCANNING;
                sc->calib.state = IWN_CALIB_STATE_INIT;
+               /*
+                * Purge the xmit queue so we don't have old frames
+                * during a new association attempt.
+                */
+               sc->sc_beacon_wait = 0;
+               ifp->if_flags &= ~IFF_OACTIVE;
+               iwn_start(ifp);
                break;
        }
 
@@ -2154,6 +2179,25 @@
                bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
        }
 
+       /*
+        * If it's a beacon and we're waiting, then do the wakeup.
+        */
+       if (sc->sc_beacon_wait) {
+               uint8_t type, subtype;
+               type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+               subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+               /*
+                * This assumes at this point we've received our own
+                * beacon.
+                */
+               if (type == IEEE80211_FC0_TYPE_MGT &&
+                   subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
+                       sc->sc_beacon_wait = 0;
+                       ifp->if_flags &= ~IFF_OACTIVE;
+                       iwn_start(ifp);
+               }
+       }
+
        /* Send the frame to the 802.11 layer. */
        ieee80211_input(ic, m, ni, rssi, 0);
 
@@ -3142,6 +3186,11 @@
                return;
 
        for (;;) {
+               if (sc->sc_beacon_wait == 1) {
+                       ifp->if_flags |= IFF_OACTIVE;
+                       break;
+               }
+
                if (sc->qfullmsk != 0) {
                        ifp->if_flags |= IFF_OACTIVE;
                        break;
@@ -3184,7 +3233,8 @@
                ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
                    M_WME_GETAC(m) : WME_AC_BE;
 
-               bpf_mtap(ifp, m);
+               if (sc->sc_beacon_wait == 0)
+                       bpf_mtap(ifp, m);
 
                if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
                        ieee80211_free_node(ni);
@@ -3192,6 +3242,9 @@
                        continue;
                }
 sendit:
+               if (sc->sc_beacon_wait)
+                       continue;
+
                bpf_mtap3(ic->ic_rawbpf, m);
 
                if (iwn_tx(sc, m, ni, ac) != 0) {
@@ -3203,6 +3256,9 @@
                sc->sc_tx_timer = 5;
                ifp->if_timer = 1;
        }
+
+       if (sc->sc_beacon_wait > 1)
+               sc->sc_beacon_wait = 0;
 }
 
 static void
@@ -3695,6 +3751,7 @@
 iwn5000_set_txpower(struct iwn_softc *sc, int async)
 {
        struct iwn5000_cmd_txpower cmd;
+       int cmdid;
 
        /*
         * TX power calibration is handled automatically by the firmware
@@ -3705,7 +3762,11 @@
        cmd.flags = IWN5000_TXPOWER_NO_CLOSED;
        cmd.srv_limit = IWN5000_TXPOWER_AUTO;
        DPRINTF(("setting TX power\n"));
-       return iwn_cmd(sc, IWN_CMD_TXPOWER_DBM, &cmd, sizeof cmd, async);
+       if (IWN_UCODE_API(sc->ucode_rev) == 1)
+               cmdid = IWN_CMD_TXPOWER_DBM_V1;
+       else
+               cmdid = IWN_CMD_TXPOWER_DBM;
+       return iwn_cmd(sc, cmdid, &cmd, sizeof cmd, async);
 }
 
 /*
@@ -4166,7 +4227,7 @@
        cmd.energy_cck       = htole16(calib->energy_cck);
        /* Barker modulation: use default values. */
        cmd.corr_barker      = htole16(190);
-       cmd.corr_barker_mrc  = htole16(390);
+       cmd.corr_barker_mrc  = htole16(sc->limits->barker_mrc);
        if (!(sc->sc_flags & IWN_FLAG_ENH_SENS))
                goto send;
        /* Enhanced sensitivity settings. */
@@ -5677,6 +5738,8 @@
        ptr = (const uint32_t *)fw->data;
        rev = le32toh(*ptr++);
 
+       sc->ucode_rev = rev;
+
        /* Check firmware API version. */
        if (IWN_FW_API(rev) <= 1) {
                aprint_error_dev(sc->sc_dev,
@@ -5742,6 +5805,7 @@
        }
        DPRINTF(("FW: \"%.64s\", build 0x%x\n", hdr->descr,
            le32toh(hdr->build)));
+       sc->ucode_rev = le32toh(hdr->rev);
 
        /*
         * Select the closest supported alternative that is less than
@@ -6330,6 +6394,8 @@
                goto fail;
        }
 
+       sc->sc_beacon_wait = 0;
+
        ifp->if_flags &= ~IFF_OACTIVE;
        ifp->if_flags |= IFF_RUNNING;
 
diff -r b9671ee58957 -r 3b464da01d03 sys/dev/pci/if_iwnreg.h
--- a/sys/dev/pci/if_iwnreg.h   Wed Jul 19 16:37:17 2017 +0000
+++ b/sys/dev/pci/if_iwnreg.h   Wed Jul 19 16:55:12 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_iwnreg.h,v 1.16 2017/03/11 21:23:36 maya Exp $      */
+/*     $NetBSD: if_iwnreg.h,v 1.17 2017/07/19 16:55:12 mlelstv Exp $   */
 /*     $OpenBSD: if_iwnreg.h,v 1.49 2014/09/09 18:56:24 sthen Exp $    */
 
 /*-
@@ -440,6 +440,7 @@
 #define IWN_CMD_TXPOWER_DBM            149
 #define IWN_CMD_TXPOWER                        151
 #define IWN5000_CMD_TX_ANT_CONFIG      152
+#define IWN_CMD_TXPOWER_DBM_V1         152
 #define IWN_CMD_BT_COEX                        155
 #define IWN_CMD_GET_STATISTICS         156
 #define IWN_CMD_SET_CRITICAL_TEMP      164
@@ -1594,7 +1595,17 @@
 } __packed;
 
 struct iwn_eeprom_enhinfo {
-       uint16_t        chan;
+       uint8_t         flags;
+#define IWN_ENHINFO_VALID       (1 << 0)
+#define IWN_ENHINFO_5GHZ        (1 << 1)
+#define IWN_ENHINFO_OFDM        (1 << 2)
+#define IWN_ENHINFO_HT40        (1 << 3)
+#define IWN_ENHINFO_HTAP        (1 << 4)
+#define IWN_ENHINFO_RES1        (1 << 5)
+#define IWN_ENHINFO_RES2        (1 << 6)
+#define IWN_ENHINFO_COMMON      (1 << 7)
+
+       uint8_t         chan;
        int8_t          chain[3];       /* max power in half-dBm */
        uint8_t         reserved;
        int8_t          mimo2;          /* max power in half-dBm */
@@ -1813,6 +1824,7 @@
        uint32_t        min_energy_cck;
        uint32_t        energy_cck;
        uint32_t        energy_ofdm;
+       uint32_t        barker_mrc;
 };
 
 /*
@@ -1827,7 +1839,8 @@
        200, 400,
         97,
        100,
-       100
+       100,
+       390
 };
 
 static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
@@ -1839,7 +1852,8 @@
        170, 400,
         95,
         95,
-        95
+        95,
+       390
 };
 
 static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
@@ -1851,7 +1865,8 @@
        170, 400,
         95,
         95,
-        95
+        95,
+       390
 };
 
 static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {
@@ -1863,7 +1878,8 @@
        170, 400,
         95,
         95,
-        95
+        95,
+       390
 };
 
 static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
@@ -1875,7 +1891,21 @@
        160, 310,
         97,



Home | Main Index | Thread Index | Old Index