Re: background scan for iwn(4)

2017-12-14 Thread Renato Aguiar

No regressions noticed using a single AP setup.

iwn0 at pci2 dev 0 function 0 "Intel Centrino Advanced-N 6205" rev 0x34: msi, 
MIMO 2T2R, MoW

On Wed, Dec 13 2017, Stefan Sperling wrote:

> Since nobody is reporting problems with iwm(4), I took some time to write the
> corresponding diff for iwn(4) as well. I hope this increases test coverage :)
>
> Works for me on:
> iwn0 at pci3 dev 0 function 0 "Intel Centrino Advanced-N 6200" rev 0x35: msi, 
> MIMO 2T2R, MoW
>
> Index: if_iwn.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.194
> diff -u -p -r1.194 if_iwn.c
> --- if_iwn.c  26 Oct 2017 15:00:28 -  1.194
> +++ if_iwn.c  13 Dec 2017 16:07:07 -
> @@ -222,7 +222,9 @@ int   iwn_config(struct iwn_softc *);
>  uint16_t iwn_get_active_dwell_time(struct iwn_softc *, uint16_t, 
> uint8_t);
>  uint16_t iwn_limit_dwell(struct iwn_softc *, uint16_t);
>  uint16_t iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t);
> -int  iwn_scan(struct iwn_softc *, uint16_t);
> +int  iwn_scan(struct iwn_softc *, uint16_t, int);
> +void iwn_scan_abort(struct iwn_softc *);
> +int  iwn_bgscan(struct ieee80211com *);
>  int  iwn_auth(struct iwn_softc *, int);
>  int  iwn_run(struct iwn_softc *);
>  int  iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
> @@ -516,6 +518,7 @@ iwn_attach(struct device *parent, struct
>   if_attach(ifp);
>   ieee80211_ifattach(ifp);
>   ic->ic_node_alloc = iwn_node_alloc;
> + ic->ic_bgscan_start = iwn_bgscan;
>   ic->ic_newassoc = iwn_newassoc;
>   ic->ic_updateedca = iwn_updateedca;
>   ic->ic_set_key = iwn_set_key;
> @@ -1761,18 +1764,20 @@ iwn_newstate(struct ieee80211com *ic, en
>   struct iwn_node *wn = (void *)ni;
>   int error;
>
> - timeout_del(>calib_to);
> -
> - if (ic->ic_state == IEEE80211_S_RUN &&
> - (ni->ni_flags & IEEE80211_NODE_HT))
> + if (ic->ic_state == IEEE80211_S_RUN) {
>   ieee80211_mira_cancel_timeouts(>mn);
> + timeout_del(>calib_to);
> + sc->calib.state = IWN_CALIB_STATE_INIT;
> + if (sc->sc_flags & IWN_FLAG_BGSCAN)
> + iwn_scan_abort(sc);
> + }
>
>   switch (nstate) {
>   case IEEE80211_S_SCAN:
>   /* Make the link LED blink while we're scanning. */
>   iwn_set_led(sc, IWN_LED_LINK, 10, 10);
>
> - if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ)) != 0) {
> + if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ, 0)) != 0) {
>   printf("%s: could not initiate scan\n",
>   sc->sc_dev.dv_xname);
>   return error;
> @@ -1971,11 +1976,13 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   struct ieee80211_frame *wh;
>   struct ieee80211_rxinfo rxi;
>   struct ieee80211_node *ni;
> + struct ieee80211_channel *bss_chan = NULL;
>   struct mbuf *m, *m1;
>   struct iwn_rx_stat *stat;
>   caddr_t head;
>   uint32_t flags;
>   int error, len, rssi;
> + uint8_t chan;
>
>   if (desc->type == IWN_MPDU_RX_DONE) {
>   /* Check for prior RX_PHY notification. */
> @@ -2131,6 +2138,16 @@ iwn_rx_done(struct iwn_softc *sc, struct
>
>   rssi = ops->get_rssi(stat);
>
> + chan = stat->chan;
> + if (chan > IEEE80211_CHAN_MAX)
> + chan = IEEE80211_CHAN_MAX;
> +
> + if (ni == ic->ic_bss) {
> + bss_chan = ni->ni_chan;
> + /* Fix current channel. */
> + ni->ni_chan = >ic_channels[chan];
> + }
> +
>  #if NBPFILTER > 0
>   if (sc->sc_drvbpf != NULL) {
>   struct mbuf mb;
> @@ -2140,9 +2157,8 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   tap->wr_flags = 0;
>   if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
>   tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> - tap->wr_chan_freq =
> - htole16(ic->ic_channels[stat->chan].ic_freq);
> - chan_flags = ic->ic_channels[stat->chan].ic_flags;
> + tap->wr_chan_freq = htole16(ic->ic_channels[chan].ic_freq);
> + chan_flags = ic->ic_channels[chan].ic_flags;
>   if (ic->ic_curmode != IEEE80211_MODE_11N)
>   chan_flags &= ~IEEE80211_CHAN_HT;
>   tap->wr_chan_flags = htole16(chan_flags);
> @@ -2187,6 +2203,10 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   rxi.rxi_tstamp = 0; /* unused */
>   ieee80211_input(ifp, m, ni, );
>
> + /* Restore BSS channel. */
> + if (ni == ic->ic_bss)
> + ni->ni_chan = bss_chan;
> +
>   /* Node is no longer needed. */
>   ieee80211_release_node(ic, ni);
>  }
> @@ -2586,6 +2606,9 @@ iwn_notif_intr(struct iwn_softc *sc)
>   DPRINTFN(2, ("scanning channel %d status 

Re: background scan for iwn(4)

2017-12-13 Thread Mike Larkin
On Wed, Dec 13, 2017 at 05:17:41PM +0100, Stefan Sperling wrote:
> Since nobody is reporting problems with iwm(4), I took some time to write the
> corresponding diff for iwn(4) as well. I hope this increases test coverage :)
> 
> Works for me on:
> iwn0 at pci3 dev 0 function 0 "Intel Centrino Advanced-N 6200" rev 0x35: msi, 
> MIMO 2T2R, MoW
> 

Ok on iwn0 at pci2 dev 0 function 0 "Intel Centrino Wireless-N 2200" rev 0xc4: 
msi, MIMO 2T2R, BGN, 
no regressions noted.

-ml

> Index: if_iwn.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.194
> diff -u -p -r1.194 if_iwn.c
> --- if_iwn.c  26 Oct 2017 15:00:28 -  1.194
> +++ if_iwn.c  13 Dec 2017 16:07:07 -
> @@ -222,7 +222,9 @@ int   iwn_config(struct iwn_softc *);
>  uint16_t iwn_get_active_dwell_time(struct iwn_softc *, uint16_t, 
> uint8_t);
>  uint16_t iwn_limit_dwell(struct iwn_softc *, uint16_t);
>  uint16_t iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t);
> -int  iwn_scan(struct iwn_softc *, uint16_t);
> +int  iwn_scan(struct iwn_softc *, uint16_t, int);
> +void iwn_scan_abort(struct iwn_softc *);
> +int  iwn_bgscan(struct ieee80211com *);
>  int  iwn_auth(struct iwn_softc *, int);
>  int  iwn_run(struct iwn_softc *);
>  int  iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
> @@ -516,6 +518,7 @@ iwn_attach(struct device *parent, struct
>   if_attach(ifp);
>   ieee80211_ifattach(ifp);
>   ic->ic_node_alloc = iwn_node_alloc;
> + ic->ic_bgscan_start = iwn_bgscan;
>   ic->ic_newassoc = iwn_newassoc;
>   ic->ic_updateedca = iwn_updateedca;
>   ic->ic_set_key = iwn_set_key;
> @@ -1761,18 +1764,20 @@ iwn_newstate(struct ieee80211com *ic, en
>   struct iwn_node *wn = (void *)ni;
>   int error;
>  
> - timeout_del(>calib_to);
> -
> - if (ic->ic_state == IEEE80211_S_RUN &&
> - (ni->ni_flags & IEEE80211_NODE_HT))
> + if (ic->ic_state == IEEE80211_S_RUN) {
>   ieee80211_mira_cancel_timeouts(>mn);
> + timeout_del(>calib_to);
> + sc->calib.state = IWN_CALIB_STATE_INIT;
> + if (sc->sc_flags & IWN_FLAG_BGSCAN)
> + iwn_scan_abort(sc);
> + }
>  
>   switch (nstate) {
>   case IEEE80211_S_SCAN:
>   /* Make the link LED blink while we're scanning. */
>   iwn_set_led(sc, IWN_LED_LINK, 10, 10);
>  
> - if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ)) != 0) {
> + if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ, 0)) != 0) {
>   printf("%s: could not initiate scan\n",
>   sc->sc_dev.dv_xname);
>   return error;
> @@ -1971,11 +1976,13 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   struct ieee80211_frame *wh;
>   struct ieee80211_rxinfo rxi;
>   struct ieee80211_node *ni;
> + struct ieee80211_channel *bss_chan = NULL;
>   struct mbuf *m, *m1;
>   struct iwn_rx_stat *stat;
>   caddr_t head;
>   uint32_t flags;
>   int error, len, rssi;
> + uint8_t chan;
>  
>   if (desc->type == IWN_MPDU_RX_DONE) {
>   /* Check for prior RX_PHY notification. */
> @@ -2131,6 +2138,16 @@ iwn_rx_done(struct iwn_softc *sc, struct
>  
>   rssi = ops->get_rssi(stat);
>  
> + chan = stat->chan;
> + if (chan > IEEE80211_CHAN_MAX)
> + chan = IEEE80211_CHAN_MAX;
> +
> + if (ni == ic->ic_bss) {
> + bss_chan = ni->ni_chan;
> + /* Fix current channel. */
> + ni->ni_chan = >ic_channels[chan];
> + }
> +
>  #if NBPFILTER > 0
>   if (sc->sc_drvbpf != NULL) {
>   struct mbuf mb;
> @@ -2140,9 +2157,8 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   tap->wr_flags = 0;
>   if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
>   tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> - tap->wr_chan_freq =
> - htole16(ic->ic_channels[stat->chan].ic_freq);
> - chan_flags = ic->ic_channels[stat->chan].ic_flags;
> + tap->wr_chan_freq = htole16(ic->ic_channels[chan].ic_freq);
> + chan_flags = ic->ic_channels[chan].ic_flags;
>   if (ic->ic_curmode != IEEE80211_MODE_11N)
>   chan_flags &= ~IEEE80211_CHAN_HT;
>   tap->wr_chan_flags = htole16(chan_flags);
> @@ -2187,6 +2203,10 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   rxi.rxi_tstamp = 0; /* unused */
>   ieee80211_input(ifp, m, ni, );
>  
> + /* Restore BSS channel. */
> + if (ni == ic->ic_bss)
> + ni->ni_chan = bss_chan;
> +
>   /* Node is no longer needed. */
>   ieee80211_release_node(ic, ni);
>  }
> @@ -2586,6 +2606,9 @@ iwn_notif_intr(struct iwn_softc *sc)
>   DPRINTFN(2, ("scanning 

Re: background scan for iwn(4)

2017-12-13 Thread Mike Burns
On 2017-12-13 17.17.41 +0100, Stefan Sperling wrote:
> Since nobody is reporting problems with iwm(4), I took some time to write the
> corresponding diff for iwn(4) as well. I hope this increases test coverage :)
> 
> Works for me on:
> iwn0 at pci3 dev 0 function 0 "Intel Centrino Advanced-N 6200" rev 0x35: msi, 
> MIMO 2T2R, MoW

Nothing is broken on:

iwn0 at pci2 dev 0 function 0 "Intel Centrino Advanced-N 6205" rev 0x96:
msi, MIMO 2T2R, MoW, address 84:3a:4b:0a:ae:8

I only have the one AP. I tried to figure out how to make my phone into
an AP but my laptop didn't want to connect to it.

-Mike

> 
> Index: if_iwn.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.194
> diff -u -p -r1.194 if_iwn.c
> --- if_iwn.c  26 Oct 2017 15:00:28 -  1.194
> +++ if_iwn.c  13 Dec 2017 16:07:07 -
> @@ -222,7 +222,9 @@ int   iwn_config(struct iwn_softc *);
>  uint16_t iwn_get_active_dwell_time(struct iwn_softc *, uint16_t, 
> uint8_t);
>  uint16_t iwn_limit_dwell(struct iwn_softc *, uint16_t);
>  uint16_t iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t);
> -int  iwn_scan(struct iwn_softc *, uint16_t);
> +int  iwn_scan(struct iwn_softc *, uint16_t, int);
> +void iwn_scan_abort(struct iwn_softc *);
> +int  iwn_bgscan(struct ieee80211com *);
>  int  iwn_auth(struct iwn_softc *, int);
>  int  iwn_run(struct iwn_softc *);
>  int  iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
> @@ -516,6 +518,7 @@ iwn_attach(struct device *parent, struct
>   if_attach(ifp);
>   ieee80211_ifattach(ifp);
>   ic->ic_node_alloc = iwn_node_alloc;
> + ic->ic_bgscan_start = iwn_bgscan;
>   ic->ic_newassoc = iwn_newassoc;
>   ic->ic_updateedca = iwn_updateedca;
>   ic->ic_set_key = iwn_set_key;
> @@ -1761,18 +1764,20 @@ iwn_newstate(struct ieee80211com *ic, en
>   struct iwn_node *wn = (void *)ni;
>   int error;
>  
> - timeout_del(>calib_to);
> -
> - if (ic->ic_state == IEEE80211_S_RUN &&
> - (ni->ni_flags & IEEE80211_NODE_HT))
> + if (ic->ic_state == IEEE80211_S_RUN) {
>   ieee80211_mira_cancel_timeouts(>mn);
> + timeout_del(>calib_to);
> + sc->calib.state = IWN_CALIB_STATE_INIT;
> + if (sc->sc_flags & IWN_FLAG_BGSCAN)
> + iwn_scan_abort(sc);
> + }
>  
>   switch (nstate) {
>   case IEEE80211_S_SCAN:
>   /* Make the link LED blink while we're scanning. */
>   iwn_set_led(sc, IWN_LED_LINK, 10, 10);
>  
> - if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ)) != 0) {
> + if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ, 0)) != 0) {
>   printf("%s: could not initiate scan\n",
>   sc->sc_dev.dv_xname);
>   return error;
> @@ -1971,11 +1976,13 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   struct ieee80211_frame *wh;
>   struct ieee80211_rxinfo rxi;
>   struct ieee80211_node *ni;
> + struct ieee80211_channel *bss_chan = NULL;
>   struct mbuf *m, *m1;
>   struct iwn_rx_stat *stat;
>   caddr_t head;
>   uint32_t flags;
>   int error, len, rssi;
> + uint8_t chan;
>  
>   if (desc->type == IWN_MPDU_RX_DONE) {
>   /* Check for prior RX_PHY notification. */
> @@ -2131,6 +2138,16 @@ iwn_rx_done(struct iwn_softc *sc, struct
>  
>   rssi = ops->get_rssi(stat);
>  
> + chan = stat->chan;
> + if (chan > IEEE80211_CHAN_MAX)
> + chan = IEEE80211_CHAN_MAX;
> +
> + if (ni == ic->ic_bss) {
> + bss_chan = ni->ni_chan;
> + /* Fix current channel. */
> + ni->ni_chan = >ic_channels[chan];
> + }
> +
>  #if NBPFILTER > 0
>   if (sc->sc_drvbpf != NULL) {
>   struct mbuf mb;
> @@ -2140,9 +2157,8 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   tap->wr_flags = 0;
>   if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
>   tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> - tap->wr_chan_freq =
> - htole16(ic->ic_channels[stat->chan].ic_freq);
> - chan_flags = ic->ic_channels[stat->chan].ic_flags;
> + tap->wr_chan_freq = htole16(ic->ic_channels[chan].ic_freq);
> + chan_flags = ic->ic_channels[chan].ic_flags;
>   if (ic->ic_curmode != IEEE80211_MODE_11N)
>   chan_flags &= ~IEEE80211_CHAN_HT;
>   tap->wr_chan_flags = htole16(chan_flags);
> @@ -2187,6 +2203,10 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   rxi.rxi_tstamp = 0; /* unused */
>   ieee80211_input(ifp, m, ni, );
>  
> + /* Restore BSS channel. */
> + if (ni == ic->ic_bss)
> + ni->ni_chan = bss_chan;
> +
>   /* Node is no longer needed. */
>   

Re: background scan for iwn(4)

2017-12-13 Thread Sebastian Benoit
Stefan Sperling(s...@stsp.name) on 2017.12.13 17:17:41 +0100:
> Since nobody is reporting problems with iwm(4), I took some time to write the
> corresponding diff for iwn(4) as well. I hope this increases test coverage :)
> 
> Works for me on:
> iwn0 at pci3 dev 0 function 0 "Intel Centrino Advanced-N 6200" rev 0x35: msi, 
> MIMO 2T2R, MoW

works on my 

iwn0 at pci2 dev 0 function 0 "Intel Centrino Advanced-N 6205" rev 0x34: msi, 
MIMO 2T2R, MoW

/Benno


> 
> Index: if_iwn.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.194
> diff -u -p -r1.194 if_iwn.c
> --- if_iwn.c  26 Oct 2017 15:00:28 -  1.194
> +++ if_iwn.c  13 Dec 2017 16:07:07 -
> @@ -222,7 +222,9 @@ int   iwn_config(struct iwn_softc *);
>  uint16_t iwn_get_active_dwell_time(struct iwn_softc *, uint16_t, 
> uint8_t);
>  uint16_t iwn_limit_dwell(struct iwn_softc *, uint16_t);
>  uint16_t iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t);
> -int  iwn_scan(struct iwn_softc *, uint16_t);
> +int  iwn_scan(struct iwn_softc *, uint16_t, int);
> +void iwn_scan_abort(struct iwn_softc *);
> +int  iwn_bgscan(struct ieee80211com *);
>  int  iwn_auth(struct iwn_softc *, int);
>  int  iwn_run(struct iwn_softc *);
>  int  iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
> @@ -516,6 +518,7 @@ iwn_attach(struct device *parent, struct
>   if_attach(ifp);
>   ieee80211_ifattach(ifp);
>   ic->ic_node_alloc = iwn_node_alloc;
> + ic->ic_bgscan_start = iwn_bgscan;
>   ic->ic_newassoc = iwn_newassoc;
>   ic->ic_updateedca = iwn_updateedca;
>   ic->ic_set_key = iwn_set_key;
> @@ -1761,18 +1764,20 @@ iwn_newstate(struct ieee80211com *ic, en
>   struct iwn_node *wn = (void *)ni;
>   int error;
>  
> - timeout_del(>calib_to);
> -
> - if (ic->ic_state == IEEE80211_S_RUN &&
> - (ni->ni_flags & IEEE80211_NODE_HT))
> + if (ic->ic_state == IEEE80211_S_RUN) {
>   ieee80211_mira_cancel_timeouts(>mn);
> + timeout_del(>calib_to);
> + sc->calib.state = IWN_CALIB_STATE_INIT;
> + if (sc->sc_flags & IWN_FLAG_BGSCAN)
> + iwn_scan_abort(sc);
> + }
>  
>   switch (nstate) {
>   case IEEE80211_S_SCAN:
>   /* Make the link LED blink while we're scanning. */
>   iwn_set_led(sc, IWN_LED_LINK, 10, 10);
>  
> - if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ)) != 0) {
> + if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ, 0)) != 0) {
>   printf("%s: could not initiate scan\n",
>   sc->sc_dev.dv_xname);
>   return error;
> @@ -1971,11 +1976,13 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   struct ieee80211_frame *wh;
>   struct ieee80211_rxinfo rxi;
>   struct ieee80211_node *ni;
> + struct ieee80211_channel *bss_chan = NULL;
>   struct mbuf *m, *m1;
>   struct iwn_rx_stat *stat;
>   caddr_t head;
>   uint32_t flags;
>   int error, len, rssi;
> + uint8_t chan;
>  
>   if (desc->type == IWN_MPDU_RX_DONE) {
>   /* Check for prior RX_PHY notification. */
> @@ -2131,6 +2138,16 @@ iwn_rx_done(struct iwn_softc *sc, struct
>  
>   rssi = ops->get_rssi(stat);
>  
> + chan = stat->chan;
> + if (chan > IEEE80211_CHAN_MAX)
> + chan = IEEE80211_CHAN_MAX;
> +
> + if (ni == ic->ic_bss) {
> + bss_chan = ni->ni_chan;
> + /* Fix current channel. */
> + ni->ni_chan = >ic_channels[chan];
> + }
> +
>  #if NBPFILTER > 0
>   if (sc->sc_drvbpf != NULL) {
>   struct mbuf mb;
> @@ -2140,9 +2157,8 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   tap->wr_flags = 0;
>   if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
>   tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> - tap->wr_chan_freq =
> - htole16(ic->ic_channels[stat->chan].ic_freq);
> - chan_flags = ic->ic_channels[stat->chan].ic_flags;
> + tap->wr_chan_freq = htole16(ic->ic_channels[chan].ic_freq);
> + chan_flags = ic->ic_channels[chan].ic_flags;
>   if (ic->ic_curmode != IEEE80211_MODE_11N)
>   chan_flags &= ~IEEE80211_CHAN_HT;
>   tap->wr_chan_flags = htole16(chan_flags);
> @@ -2187,6 +2203,10 @@ iwn_rx_done(struct iwn_softc *sc, struct
>   rxi.rxi_tstamp = 0; /* unused */
>   ieee80211_input(ifp, m, ni, );
>  
> + /* Restore BSS channel. */
> + if (ni == ic->ic_bss)
> + ni->ni_chan = bss_chan;
> +
>   /* Node is no longer needed. */
>   ieee80211_release_node(ic, ni);
>  }
> @@ -2586,6 +2606,9 @@ iwn_notif_intr(struct iwn_softc *sc)
>   DPRINTFN(2, ("scanning channel %d