tech-net archive

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

RE: detecting loss of access point (link status monitoring fix?)



> -----Original Message-----
> From: tech-net-owner%NetBSD.org@localhost 
> [mailto:tech-net-owner%NetBSD.org@localhost] On
> Behalf Of David Young
> Sent: April 9, 2010 5:04 PM
> To: tech-net%netbsd.org@localhost
> Subject: Re: detecting loss of access point (link status monitoring
fix?)
> 
> On Tue, Apr 06, 2010 at 01:58:38PM -0400, Eric Naud wrote:
> > The change below uses the ieee80211_beacon_miss() function in a
periodic
> > callout to determine if two or more consecutive beacons were missed,
if
> > beacons were missed the driver state changes in order to initiate a
> > scan.
> 
> It looks to me like the change may work a little differently than
> you say: you indicate a beacon miss to net80211 every three seconds,
> regardless of whether any beacon was missed.  If ic_bmiss_max is 2
(the
> default), then on the first miss, net80211 sends a probe request to
the
> access point (iirc, a probe response resets the beacon-miss count),
and
> on the second miss, net80211 starts a scan.
> 
> Can ral(4) and rum(4) indicate a beacon miss with an interrupt?  Other
> NICs can.
> 
> Dave
> 
Hello Dave, 

Thank you for your reply. As far as I can tell from reading the
Rum/RT2501 (RT2571/RT2561) specs the only interrupt we could use to
detect missed beacons is the TBTT interrupt which fires once every
beacon interval, in typical cases this would involve an interrupt every
100ms which seems excessive for the task at hand. I also get the feeling
this is mostly used for IBSS mode. I don't have the specs for the run
driver but there's no indication in if_runreg.h of a missed beacon
interrupt in this newer device.

Seeing that the hardware capability isn't present like it is in other
devices I would like to propose a new, slightly modified change taking
into account your comments. Indeed, ieee80211_beacon_miss should only be
called once beacons appear to be stalled or missing, not every single
time the monitor runs. 

The change still includes a periodic callback (every three seconds when
in the IEEE80211_S_RUN state). This callback looks at the
ic->ic_stats.is_rx_beacon data structure element to determine if the
received beacon count has stalled.  On first detecting the beacon count
isn't moving we call ieee80211_beacon_miss to send a probe request to
the AP. Next time the link monitor runs, three seconds later, if the
beacon count still hasn't moved, we assume the AP is gone and
ieee80211_beacon_miss will be called again to initiate a channel scan.

Because of the generic nature of the change, with only one function
dependency on the ieee80211 stack, this change can apply to the rum(4),
ral(4) and run(4) drivers which all currently appear to lack the
hardware and software ability to detect the loss of an access point.

Regards, 
Eric


Index: if_rum.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_rum.c,v
retrieving revision 1.23
diff -u -r1.23 if_rum.c
--- if_rum.c    21 Oct 2008 12:21:46 -0000      1.23
+++ if_rum.c    19 Apr 2010 15:28:05 -0000
@@ -203,6 +203,7 @@
 Static void            rum_amrr_timeout(void *);
 Static void            rum_amrr_update(usbd_xfer_handle,
usbd_private_handle,
                            usbd_status status);
+Static void            rum_linkmon(void *);
 
 /*
  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
@@ -360,6 +361,7 @@
        sc->amrr.amrr_min_success_threshold =  1;
        sc->amrr.amrr_max_success_threshold = 10;
        usb_callout_init(sc->sc_amrr_ch);
+       usb_callout_init(sc->sc_link_mon);
 
        /* retrieve RT2573 rev. no */
        for (ntries = 0; ntries < 1000; ntries++) {
@@ -491,6 +493,7 @@
        usb_rem_task(sc->sc_udev, &sc->sc_task);
        usb_uncallout(sc->sc_scan_ch, rum_next_scan, sc);
        usb_uncallout(sc->sc_amrr_ch, rum_amrr_timeout, sc);
+       usb_uncallout(sc->sc_link_mon, rum_linkmon, sc);
 
        if (sc->amrr_xfer != NULL) {
                usbd_free_xfer(sc->amrr_xfer);
@@ -745,6 +748,7 @@
                                rum_amrr_start(sc, ni);
                }
 
+               usb_callout(sc->sc_link_mon, hz*3, rum_linkmon, sc);
                break;
        }
 
@@ -759,6 +763,7 @@
        usb_rem_task(sc->sc_udev, &sc->sc_task);
        usb_uncallout(sc->sc_scan_ch, rum_next_scan, sc);
        usb_uncallout(sc->sc_amrr_ch, rum_amrr_timeout, sc);
+       usb_uncallout(sc->sc_link_mon, rum_linkmon, NULL);
 
        /* do it in a process context */
        sc->sc_state = nstate;
@@ -2286,3 +2291,24 @@
 
        return 0;
 }
+
+static int beacon_count = 0;
+static int bcnt_initialized = 0;
+void rum_linkmon(void *arg) 
+{
+       struct rum_softc *sc = arg;
+       struct ieee80211com *ic = &sc->sc_ic;
+       if (bcnt_initialized == 0) {
+               beacon_count = ic->ic_stats.is_rx_beacon;
+               bcnt_initialized = 1;
+       } else if (beacon_count == ic->ic_stats.is_rx_beacon) {
+               ieee80211_beacon_miss(ic);
+       } else {
+               beacon_count = ic->ic_stats.is_rx_beacon;
+       }       
+               
+       if (sc->sc_ic.ic_state == IEEE80211_S_RUN) {
+               usb_callout(sc->sc_link_mon, hz*3, rum_linkmon, sc);
+       }
+}
Index: if_rumvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_rumvar.h,v
retrieving revision 1.4
diff -u -r1.4 if_rumvar.h
--- if_rumvar.h 25 Nov 2007 09:30:10 -0000      1.4
+++ if_rumvar.h 19 Apr 2010 15:28:05 -0000
@@ -110,6 +110,7 @@
 
        usb_callout_t                   sc_scan_ch;
        usb_callout_t                   sc_amrr_ch;
+       usb_callout_t                   sc_link_mon;
 
        int                             sc_tx_timer





Home | Main Index | Thread Index | Old Index