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/40216ca80654
branches: trunk
changeset: 363595:40216ca80654
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 c49100f9c8a6 -r 40216ca80654 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