From owner-svn-src-head@FreeBSD.ORG Sun May 10 22:07:57 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 84027E00; Sun, 10 May 2015 22:07:57 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6520711DE; Sun, 10 May 2015 22:07:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4AM7v2K097461; Sun, 10 May 2015 22:07:57 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4AM7sDJ097440; Sun, 10 May 2015 22:07:54 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201505102207.t4AM7sDJ097440@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sun, 10 May 2015 22:07:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282742 - in head/sys: dev/if_ndis net80211 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 May 2015 22:07:57 -0000 Author: adrian Date: Sun May 10 22:07:53 2015 New Revision: 282742 URL: https://svnweb.freebsd.org/changeset/base/282742 Log: Prepare for supporting driver-overridden curchan when submitting scan results. Right now the scan infrastructure assumes the channel is under net80211 control, and that when receiving beacon frames for scanning, the current channel is indeed what ic_curchan is set to. But firmware NICs with firmware scan support need more than this - they can do background scans whilst hiding the off-channel behaviour from net80211. Ie, net80211 still thinks everything is associated and on the main channel, but it's getting scan results from all the background traffic. However sta_add() pays attention to ic_curchan and discards scan results that aren't on the right channel. CCK beacon frames can be decoded from adjacent channels so the receive path and sta_add discard these as appropriate. This is fine for software scanning like for ath(4), but not for firmware NICs. So with those, the whole concept of background firmware scanning won't work without major hacks (eg, overriding ic_curchan before calling the beacon input / scan add.) As part of my scan overhaul, modify sta_add() and the scan_add() APIs to take an explicit current channel. The normal RX path will set it to ic_curchan so it's a no-op. However, drivers may decide to (eventually!) override the scan method to set the "right" current channel based on what the firmware reports the scan state is. So for example, iwn, rsu and other NICs will eventually do this: * driver issues scan start firmware command; * firmware sends a "scan start on channel X" notify; * firmware sends a bunch of beacon RX's as part of the scan results; * .. and the driver will replace scan_add() curchan with channel X, so scan results are correct. * firmware sends a "scan start on channel Y" notify; * firmware sends more beacons... * .. the driver replaces scan_add() curchan with channel Y. Note: * Eventually, net80211 should eventually grow the idea of a per-packet current channel. It's possible in various modes (eg WAVE, P2P, etc) that individual frames can come in from different channels and that is under firmware control rather than driver/net80211 control, so we should support that. Modified: head/sys/dev/if_ndis/if_ndis.c head/sys/net80211/ieee80211_adhoc.c head/sys/net80211/ieee80211_hostap.c head/sys/net80211/ieee80211_mesh.c head/sys/net80211/ieee80211_scan.c head/sys/net80211/ieee80211_scan.h head/sys/net80211/ieee80211_scan_sta.c head/sys/net80211/ieee80211_scan_sw.c head/sys/net80211/ieee80211_scan_sw.h head/sys/net80211/ieee80211_sta.c Modified: head/sys/dev/if_ndis/if_ndis.c ============================================================================== --- head/sys/dev/if_ndis/if_ndis.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/dev/if_ndis/if_ndis.c Sun May 10 22:07:53 2015 (r282742) @@ -3316,7 +3316,7 @@ done: DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n", ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag, rssi)); - ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise); + ieee80211_add_scan(vap, ic->ic_curchan, &sp, &wh, 0, rssi, noise); wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); } free(bl, M_DEVBUF); Modified: head/sys/net80211/ieee80211_adhoc.c ============================================================================== --- head/sys/net80211/ieee80211_adhoc.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_adhoc.c Sun May 10 22:07:53 2015 (r282742) @@ -735,7 +735,8 @@ adhoc_recv_mgmt(struct ieee80211_node *n ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); + ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh, + subtype, rssi, nf); return; } if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { Modified: head/sys/net80211/ieee80211_hostap.c ============================================================================== --- head/sys/net80211/ieee80211_hostap.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_hostap.c Sun May 10 22:07:53 2015 (r282742) @@ -1737,7 +1737,8 @@ hostap_recv_mgmt(struct ieee80211_node * ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); + ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh, + subtype, rssi, nf); return; } /* Modified: head/sys/net80211/ieee80211_mesh.c ============================================================================== --- head/sys/net80211/ieee80211_mesh.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_mesh.c Sun May 10 22:07:53 2015 (r282742) @@ -1906,7 +1906,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, + ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh, subtype, rssi, nf); return; } Modified: head/sys/net80211/ieee80211_scan.c ============================================================================== --- head/sys/net80211/ieee80211_scan.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_scan.c Sun May 10 22:07:53 2015 (r282742) @@ -562,12 +562,14 @@ ieee80211_scan_dump_probe_beacon(uint8_t */ void ieee80211_add_scan(struct ieee80211vap *vap, + struct ieee80211_channel *curchan, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, int subtype, int rssi, int noise) { - return (ieee80211_swscan_add_scan(vap, sp, wh, subtype, rssi, noise)); + return (ieee80211_swscan_add_scan(vap, curchan, sp, wh, subtype, + rssi, noise)); } /* Modified: head/sys/net80211/ieee80211_scan.h ============================================================================== --- head/sys/net80211/ieee80211_scan.h Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_scan.h Sun May 10 22:07:53 2015 (r282742) @@ -148,6 +148,7 @@ struct ieee80211_channel *ieee80211_scan struct ieee80211_scanparams; void ieee80211_add_scan(struct ieee80211vap *, + struct ieee80211_channel *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, int subtype, int rssi, int noise); @@ -273,6 +274,7 @@ struct ieee80211_scanner { struct ieee80211_scan_state *, int); /* add an entry to the cache */ int (*scan_add)(struct ieee80211_scan_state *, + struct ieee80211_channel *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, int subtype, int rssi, int noise); Modified: head/sys/net80211/ieee80211_scan_sta.c ============================================================================== --- head/sys/net80211/ieee80211_scan_sta.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_scan_sta.c Sun May 10 22:07:53 2015 (r282742) @@ -228,6 +228,7 @@ sta_flush_table(struct sta_table *st) */ static int sta_add(struct ieee80211_scan_state *ss, + struct ieee80211_channel *curchan, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, int subtype, int rssi, int noise) @@ -310,15 +311,15 @@ found: * IEEE80211_BPARSE_OFFCHAN. */ c = ieee80211_find_channel_byieee(ic, sp->chan, - ic->ic_curchan->ic_flags); + curchan->ic_flags); if (c != NULL) { ise->se_chan = c; } else if (ise->se_chan == NULL) { /* should not happen, pick something */ - ise->se_chan = ic->ic_curchan; + ise->se_chan = curchan; } } else - ise->se_chan = ic->ic_curchan; + ise->se_chan = curchan; if (IEEE80211_IS_CHAN_HT(ise->se_chan) && sp->htcap == NULL) { /* Demote legacy networks to a non-HT channel. */ c = ieee80211_find_channel(ic, ise->se_chan->ic_freq, Modified: head/sys/net80211/ieee80211_scan_sw.c ============================================================================== --- head/sys/net80211/ieee80211_scan_sw.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_scan_sw.c Sun May 10 22:07:53 2015 (r282742) @@ -900,6 +900,7 @@ done: */ void ieee80211_swscan_add_scan(struct ieee80211vap *vap, + struct ieee80211_channel *curchan, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, int subtype, int rssi, int noise) @@ -922,7 +923,7 @@ ieee80211_swscan_add_scan(struct ieee802 ieee80211_scan_dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi); #endif if (ss->ss_ops != NULL && - ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise)) { + ss->ss_ops->scan_add(ss, curchan, sp, wh, subtype, rssi, noise)) { /* * If we've reached the min dwell time terminate * the timer so we'll switch to the next channel. Modified: head/sys/net80211/ieee80211_scan_sw.h ============================================================================== --- head/sys/net80211/ieee80211_scan_sw.h Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_scan_sw.h Sun May 10 22:07:53 2015 (r282742) @@ -53,6 +53,7 @@ extern void ieee80211_swscan_scan_done(s extern void ieee80211_swscan_probe_curchan(struct ieee80211vap *vap, int force); extern void ieee80211_swscan_add_scan(struct ieee80211vap *vap, + struct ieee80211_channel *curchan, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, int subtype, int rssi, int noise); Modified: head/sys/net80211/ieee80211_sta.c ============================================================================== --- head/sys/net80211/ieee80211_sta.c Sun May 10 22:04:42 2015 (r282741) +++ head/sys/net80211/ieee80211_sta.c Sun May 10 22:07:53 2015 (r282742) @@ -1484,8 +1484,8 @@ sta_recv_mgmt(struct ieee80211_node *ni, * our ap. */ if (ic->ic_flags & IEEE80211_F_SCAN) { - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, nf); + ieee80211_add_scan(vap, ic->ic_curchan, + &scan, wh, subtype, rssi, nf); } else if (contbgscan(vap)) { ieee80211_bg_scan(vap, 0); } else if (startbgscan(vap)) { @@ -1529,7 +1529,8 @@ sta_recv_mgmt(struct ieee80211_node *ni, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); + ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh, + subtype, rssi, nf); return; } break;