Source-Changes-HG archive

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

[src-draft/trunk]: src/sys/dev/pci Initial attempt at iwn scanning with new f...



details:   https://anonhg.NetBSD.org/src-all/rev/4b3d92c0167a
branches:  trunk
changeset: 1025999:4b3d92c0167a
user:      Nathanial Sloss <nat%netbsd.org@localhost>
date:      Mon May 18 20:27:02 2020 +1000

description:
Initial attempt at iwn scanning with new functions from freebsd.

diffstat:

 sys/dev/pci/if_iwn.c |  256 ++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 181 insertions(+), 75 deletions(-)

diffs (truncated from 417 to 300 lines):

diff -r e1421011e67c -r 4b3d92c0167a sys/dev/pci/if_iwn.c
--- a/sys/dev/pci/if_iwn.c      Mon May 18 20:26:21 2020 +1000
+++ b/sys/dev/pci/if_iwn.c      Mon May 18 20:27:02 2020 +1000
@@ -247,7 +247,11 @@
                    const uint8_t [IEEE80211_ADDR_LEN]);
 static void    iwn_vap_delete(struct ieee80211vap *);
 static void    iwn_parent(struct ieee80211com *);
+static void    iwn_scan_start(struct ieee80211com *);
 static void    iwn_scan_end(struct ieee80211com *);
+static void    iwn_set_channel(struct ieee80211com *);
+static void    iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
+static void    iwn_scan_mindwell(struct ieee80211_scan_state *);
 static void    iwn_next_scan(void *);
 static int     iwn_reset(struct ieee80211vap *, u_long);
 
@@ -340,7 +344,7 @@
                    uint8_t);
 static uint16_t        iwn_limit_dwell(struct ieee80211_node *, uint16_t);
 static uint16_t        iwn_get_passive_dwell_time(struct ieee80211_node *, uint16_t);
-static void    iwn_scan(struct ieee80211com *);
+static int     iwn_scan(struct ieee80211com *, struct ieee80211_scan_state *);
 static int     iwn_auth(struct ieee80211vap *);
 static int     iwn_run(struct ieee80211vap *);
 #ifdef IWN_HWCRYPTO
@@ -467,7 +471,6 @@
        callout_init(&sc->calib_to, 0);
        callout_setfunc(&sc->calib_to, iwn_calib_timeout, sc);
        callout_init(&sc->scan_to, 0);
-       callout_setfunc(&sc->scan_to, iwn_next_scan, sc);
 
        pci_aprint_devinfo(pa, NULL);
 
@@ -674,7 +677,8 @@
         * IEEE80211_C_PMGT too.
         */
        ic->ic_caps =
-           IEEE80211_C_IBSS |          /* IBSS mode support */
+           IEEE80211_C_STA |           /* station mode supported */
+          // IEEE80211_C_IBSS |                /* IBSS mode support */
            IEEE80211_C_WPA |           /* 802.11i */
            IEEE80211_C_MONITOR |       /* monitor mode supported */
            IEEE80211_C_TXPMGT |        /* tx power management */
@@ -735,8 +739,11 @@
        ic->ic_vap_create = iwn_vap_create;
        ic->ic_vap_delete = iwn_vap_delete;
        ic->ic_parent = iwn_parent;
-       ic->ic_scan_start = iwn_scan;
+       ic->ic_scan_start = iwn_scan_start;
        ic->ic_scan_end = iwn_scan_end;
+       ic->ic_set_channel = iwn_set_channel;
+       ic->ic_scan_curchan = iwn_scan_curchan;
+       ic->ic_scan_mindwell = iwn_scan_mindwell;
        ic->ic_newassoc = iwn_newassoc;
 #ifdef IWN_HWCRYPTO
        ic->ic_crypto.cs_key_set = iwn_set_key;
@@ -777,6 +784,7 @@
                return 0;
        }
 
+       callout_setfunc(&sc->scan_to, iwn_next_scan, vap);
        if (pmf_device_register(self, NULL, iwn_resume))
                pmf_class_network_register(self, vap->iv_ifp);
        else {
@@ -820,18 +828,90 @@
 static void
 iwn_next_scan(void *arg)
 {
+#if 0
+       struct ieee80211vap *vap = arg;
        printf ("NNN iwn_next_scan called....\n");
-}
-
+#endif
+}
+
+/*
+ * Callback from net80211 to start a scan.
+ */
+static void
+iwn_scan_start(struct ieee80211com *ic)
+{
+       struct iwn_softc *sc = ic->ic_softc;
+
+printf("SCAN_START\n");
+       /* make the link LED blink while we're scanning */
+       iwn_set_led(sc, IWN_LED_LINK, 20, 2);
+}
+
+/*
+ * Callback from net80211 to terminate a scan.
+ */
 static void
 iwn_scan_end(struct ieee80211com *ic)
 {
-       struct iwn_softc *sc __unused = ic->ic_softc;
-
-       DPRINTFN(DBG_FN, ("%s: %s\n",device_xname(sc->sc_dev), __func__));
-
-       /* Not sure what to do here yet. */
-} 
+       struct iwn_softc *sc = ic->ic_softc;
+       struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+printf("SCAN_END\n");
+       if (vap->iv_state == IEEE80211_S_RUN) {
+               /* Set link LED to ON status if we are associated */
+               iwn_set_led(sc, IWN_LED_LINK, 0, 1);
+       }
+}
+
+/*
+ * Callback from net80211 to force a channel change.
+ */
+static void
+iwn_set_channel(struct ieee80211com *ic)
+{
+       struct iwn_softc *sc = ic->ic_softc;
+       struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+       int error;
+
+printf("SET_CHANNEL\n");
+       /*
+        * Only need to set the channel in Monitor mode. AP scanning and auth
+        * are already taken care of by their respective firmware commands.
+        */
+       if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+               error = iwn_config(vap);
+               if (error != 0)
+               device_printf(sc->sc_dev,
+                   "%s: error %d settting channel\n", __func__, error);
+       }
+}
+
+/*
+ * Callback from net80211 to start scanning of the current channel.
+ */
+static void
+iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
+{
+       struct ieee80211vap *vap = ss->ss_vap;
+       struct ieee80211com *ic = vap->iv_ic;
+       int error;
+
+printf("SCAN CURCHAN\n");
+       error = iwn_scan(ic, ss);
+       if (error != 0)
+               ieee80211_cancel_scan(vap);
+}
+
+/*
+ * Callback from net80211 to handle the minimum dwell time being met.
+ * The intent is to terminate the scan but we just let the firmware
+ * notify us when it's finished as we have no safe way to abort it.
+ */
+static void
+iwn_scan_mindwell(struct ieee80211_scan_state *ss)
+{
+       /* NB: don't try to abort scan; wait for firmware to finish */
+}
 
 static void
 iwn_parent(struct ieee80211com *ic)
@@ -2134,6 +2214,7 @@
        vap->iv_debug = ieee80211_debug;
        switch (nstate) {
        case IEEE80211_S_SCAN:
+#if 0
                /* XXX Do not abort a running scan. */
                if (sc->sc_flags & IWN_FLAG_SCANNING) {
                        if (ostate == nstate)
@@ -2145,8 +2226,7 @@
 
                /* XXX Not sure if call and flags are needed. */
                //ieee80211_node_table_reset(&ic->ic_scan);
-               ic->ic_flags |= IEEE80211_F_SCAN; // | IEEE80211_F_ASCAN;
-               sc->sc_flags |= IWN_FLAG_SCANNING_2GHZ;
+               ic->ic_flags |= IEEE80211_F_SCAN;// | IEEE80211_F_ASCAN;
 
                /* Make the link LED blink while we're scanning. */
                iwn_set_led(sc, IWN_LED_LINK, 10, 10);
@@ -2155,6 +2235,8 @@
                //ic->ic_state = nstate;
 
                /* Start periodic scan. */
+#endif
+               //ic->ic_flags |= IEEE80211_F_SCAN;// | IEEE80211_F_ASCAN;
                callout_schedule(&sc->scan_to, hz / 5);
                break;
 
@@ -2863,12 +2945,18 @@
                        DPRINTFN(2, ("scanning channel %d status %x\n",
                            scan->chan, le32toh(scan->status)));
 
+#if 0
+                       IEEE80211_LOCK(ic);
+                       ic->ic_flags |= IEEE80211_F_SCAN;
+                       IEEE80211_UNLOCK(ic);
+#endif
                        /* Fix current channel. */
                        vap->iv_bss->ni_chan = &ic->ic_channels[scan->chan];
                        break;
                }
                case IWN_STOP_SCAN:
                {
+printf("STOP SCAN\n");
                        struct iwn_stop_scan *scan =
                            (struct iwn_stop_scan *)(desc + 1);
 
@@ -2877,18 +2965,13 @@
                        DPRINTF(("scan finished nchan=%d status=%d chan=%d\n",
                            scan->nchan, scan->status, scan->chan));
 
-                       if (scan->status == 1 && scan->chan <= 14 &&
-                           (sc->sc_flags & IWN_FLAG_HAS_5GHZ)) {
-                               /*
-                                * We just finished scanning 2GHz channels,
-                                * start scanning 5GHz ones.
-                                */
-                               sc->sc_flags &= ~IWN_FLAG_SCANNING_2GHZ;
-                               sc->sc_flags |= IWN_FLAG_SCANNING_5GHZ;
-                               //iwn_scan(ic);
-                       }
                        sc->sc_flags &= ~IWN_FLAG_SCANNING;
-                       //ieee80211_end_scan(ic);
+#if 0
+                       IEEE80211_LOCK(ic);
+                       ic->ic_flags &= ~IEEE80211_F_SCAN;
+                       IEEE80211_UNLOCK(ic);
+#endif
+                       ieee80211_scan_next(vap);
                        break;
                }
                case IWN5000_CALIBRATION_RESULT:
@@ -4928,8 +5011,8 @@
        return iwn_limit_dwell(ni, passive);
 }
 
-static void
-iwn_scan(struct ieee80211com *ic)
+static int
+iwn_scan(struct ieee80211com *ic, struct ieee80211_scan_state *ss)
 {
        struct ieee80211_node *ni;
        struct iwn_softc *sc = ic->ic_softc;
@@ -4945,11 +5028,23 @@
        uint8_t txant;
        int buflen, is_active;
 
+       /*
+        * We are absolutely not allowed to send a scan command when another
+        * scan command is pending.
+        */
+       if (sc->sc_flags & IWN_FLAG_SCANNING) {
+               device_printf(sc->sc_dev, "%s: called whilst scanning!\n",
+                   __func__);
+               return (EAGAIN);
+       }
+
+       c = ic->ic_curchan;
+
        buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
        if (buf == NULL) {
                aprint_error_dev(sc->sc_dev,
                    "could not allocate buffer for scan command\n");
-               return;
+               return 1;
        }
        hdr = (struct iwn_scan_hdr *)buf;
        /*
@@ -5006,15 +5101,17 @@
        is_active = 0;
 
        essid = (struct iwn_scan_essid *)(tx + 1);
-#if 0
-       if (ic->ic_des_esslen != 0) {
-               essid[0].id = IEEE80211_ELEMID_SSID;
-               essid[0].len = ic->ic_des_esslen;
-               memcpy(essid[0].data, ic->ic_des_essid, ic->ic_des_esslen);
-
-               is_active = 1;
-       }
-#endif
+       if (ss != NULL) {
+               if (ss->ss_ssid[0].len != 0) {
+                       essid[0].id = IEEE80211_ELEMID_SSID;
+                       essid[0].len = ss->ss_ssid[0].len;
+                       memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
+               }
+
+               if (ss->ss_nssid > 0)
+                       is_active = 1;
+       }
+
        /*
         * Build a probe request frame.  Most of the following code is a
         * copy & paste of what is done in net80211.
@@ -5081,52 +5178,59 @@
                    IWN_GOOD_CRC_TH_DEFAULT : IWN_GOOD_CRC_TH_NEVER;
 
        chan = (struct iwn_scan_chan *)frm;



Home | Main Index | Thread Index | Old Index