diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index 6c950d6bc88d..f28a9829d60d 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -71,15 +71,14 @@ __FBSDID("$FreeBSD$"); void ieee80211_scan_attach(struct ieee80211com *ic) { - /* - * For now, the swscan module does both the - * allocation (so it can pad it) and sets up the net80211 - * bits. - * - * I'll split this stuff later. + * If there's no scan method pointer, attach the + * swscan set as a default. */ - ieee80211_swscan_attach(ic); + if (ic->ic_scan_methods == NULL) + ieee80211_swscan_attach(ic); + else + ic->ic_scan_methods->sc_attach(ic); } void @@ -88,12 +87,11 @@ ieee80211_scan_detach(struct ieee80211com *ic) /* * Ideally we'd do the ss_ops detach call here; - * but then ieee80211_swscan_detach would need - * to be split in two. + * but then sc_detach() would need to be split in two. * * I'll do that later. */ - ieee80211_swscan_detach(ic); + ic->ic_scan_methods->sc_detach(ic); } static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = { @@ -122,6 +120,8 @@ static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = { void ieee80211_scan_vattach(struct ieee80211vap *vap) { + struct ieee80211com *ic = vap->iv_ic; + vap->iv_bgscanidle = (IEEE80211_BGSCAN_IDLE_DEFAULT*1000)/hz; vap->iv_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT*hz; vap->iv_scanvalid = IEEE80211_SCAN_VALID_DEFAULT*hz; @@ -129,7 +129,7 @@ ieee80211_scan_vattach(struct ieee80211vap *vap) vap->iv_roaming = IEEE80211_ROAMING_AUTO; memcpy(vap->iv_roamparms, defroam, sizeof(defroam)); - ieee80211_swscan_vattach(vap); + ic->ic_scan_methods->sc_vattach(vap); } void @@ -141,7 +141,7 @@ ieee80211_scan_vdetach(struct ieee80211vap *vap) IEEE80211_LOCK(ic); ss = ic->ic_scan; - ieee80211_swscan_vdetach(vap); + ic->ic_scan_methods->sc_vdetach(vap); if (ss != NULL && ss->ss_vap == vap) { if (ss->ss_ops != NULL) { @@ -314,6 +314,7 @@ ieee80211_start_scan(struct ieee80211vap *vap, int flags, u_int nssid, const struct ieee80211_scan_ssid ssids[]) { const struct ieee80211_scanner *scan; + struct ieee80211com *ic = vap->iv_ic; scan = ieee80211_scanner_get(vap->iv_opmode); if (scan == NULL) { @@ -324,8 +325,7 @@ ieee80211_start_scan(struct ieee80211vap *vap, int flags, return 0; } - /* XXX ops */ - return ieee80211_swscan_start_scan(scan, vap, flags, duration, + return ic->ic_scan_methods->sc_start_scan(scan, vap, flags, duration, mindwell, maxdwell, nssid, ssids); } @@ -376,11 +376,10 @@ ieee80211_check_scan(struct ieee80211vap *vap, int flags, /* * XXX TODO: separate things out a bit better. - * XXX TODO: ops */ ieee80211_scan_update_locked(vap, scan); - result = ieee80211_swscan_check_scan(scan, vap, flags, duration, + result = ic->ic_scan_methods->sc_check_scan(scan, vap, flags, duration, mindwell, maxdwell, nssid, ssids); IEEE80211_UNLOCK(ic); @@ -408,6 +407,7 @@ ieee80211_check_scan_current(struct ieee80211vap *vap) int ieee80211_bg_scan(struct ieee80211vap *vap, int flags) { + struct ieee80211com *ic = vap->iv_ic; const struct ieee80211_scanner *scan; // IEEE80211_UNLOCK_ASSERT(sc); @@ -425,10 +425,8 @@ ieee80211_bg_scan(struct ieee80211vap *vap, int flags) * XXX TODO: pull apart the bgscan logic into whatever * belongs here and whatever belongs in the software * scanner. - * - * XXX TODO: ops */ - return (ieee80211_swscan_bg_scan(scan, vap, flags)); + return (ic->ic_scan_methods->sc_bg_scan(scan, vap, flags)); } /* @@ -437,9 +435,9 @@ ieee80211_bg_scan(struct ieee80211vap *vap, int flags) void ieee80211_cancel_scan(struct ieee80211vap *vap) { + struct ieee80211com *ic = vap->iv_ic; - /* XXX TODO: ops */ - ieee80211_swscan_cancel_scan(vap); + ic->ic_scan_methods->sc_cancel_scan(vap); } /* @@ -448,9 +446,9 @@ ieee80211_cancel_scan(struct ieee80211vap *vap) void ieee80211_cancel_anyscan(struct ieee80211vap *vap) { + struct ieee80211com *ic = vap->iv_ic; - /* XXX TODO: ops */ - ieee80211_swscan_cancel_anyscan(vap); + ic->ic_scan_methods->sc_cancel_anyscan(vap); } /* @@ -460,9 +458,9 @@ ieee80211_cancel_anyscan(struct ieee80211vap *vap) void ieee80211_scan_next(struct ieee80211vap *vap) { + struct ieee80211com *ic = vap->iv_ic; - /* XXX TODO: ops */ - ieee80211_swscan_scan_next(vap); + ic->ic_scan_methods->sc_scan_next(vap); } /* @@ -481,8 +479,7 @@ ieee80211_scan_done(struct ieee80211vap *vap) ss = ic->ic_scan; ss->ss_next = ss->ss_last; /* all channels are complete */ - /* XXX TODO: ops */ - ieee80211_swscan_scan_done(vap); + ic->ic_scan_methods->sc_scan_done(vap); IEEE80211_UNLOCK(ic); } @@ -504,8 +501,7 @@ ieee80211_probe_curchan(struct ieee80211vap *vap, int force) return; } - /* XXX TODO: ops */ - ieee80211_swscan_probe_curchan(vap, force); + ic->ic_scan_methods->sc_scan_probe_curchan(vap, force); } #ifdef IEEE80211_DEBUG @@ -567,8 +563,9 @@ ieee80211_add_scan(struct ieee80211vap *vap, const struct ieee80211_frame *wh, int subtype, int rssi, int noise) { + struct ieee80211com *ic = vap->iv_ic; - return (ieee80211_swscan_add_scan(vap, curchan, sp, wh, subtype, + return (ic->ic_scan_methods->sc_add_scan(vap, curchan, sp, wh, subtype, rssi, noise)); } diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h index 8b54186af517..f568b651151c 100644 --- a/sys/net80211/ieee80211_scan.h +++ b/sys/net80211/ieee80211_scan.h @@ -79,6 +79,39 @@ struct ieee80211_scan_ssid { }; #define IEEE80211_SCAN_MAX_SSID 1 /* max # ssid's to probe */ +/* + * High-level implementation visible to ieee80211_scan.[ch]. + * + * The default scanner (ieee80211_scan_sw.[ch]) implements a software + * driven scanner. Firmware driven scanning needs a different set of + * behaviours. + */ +struct ieee80211_scan_methods { + void (*sc_attach)(struct ieee80211com *); + void (*sc_detach)(struct ieee80211com *); + void (*sc_vattach)(struct ieee80211vap *); + void (*sc_vdetach)(struct ieee80211vap *); + void (*sc_set_scan_duration)(struct ieee80211vap *, u_int); + int (*sc_start_scan)(const struct ieee80211_scanner *, + struct ieee80211vap *, int, u_int, u_int, u_int, u_int, + const struct ieee80211_scan_ssid ssids[]); + int (*sc_check_scan)(const struct ieee80211_scanner *, + struct ieee80211vap *, int, u_int, u_int, u_int, u_int, + const struct ieee80211_scan_ssid ssids[]); + int (*sc_bg_scan)(const struct ieee80211_scanner *, + struct ieee80211vap *, int); + void (*sc_cancel_scan)(struct ieee80211vap *); + void (*sc_cancel_anyscan)(struct ieee80211vap *); + void (*sc_scan_next)(struct ieee80211vap *); + void (*sc_scan_done)(struct ieee80211vap *); + void (*sc_scan_probe_curchan)(struct ieee80211vap *, int); + void (*sc_add_scan)(struct ieee80211vap *, + struct ieee80211_channel *, + const struct ieee80211_scanparams *, + const struct ieee80211_frame *, + int, int, int); +}; + /* * Scan state visible to the 802.11 layer. Scan parameters and * results are stored in this data structure. The ieee80211_scan_state diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c index 9012619b6ab1..eb58386fc907 100644 --- a/sys/net80211/ieee80211_scan_sw.c +++ b/sys/net80211/ieee80211_scan_sw.c @@ -102,33 +102,7 @@ static void scan_task(void *, int); MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state"); -void -ieee80211_swscan_attach(struct ieee80211com *ic) -{ - struct scan_state *ss; - - ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state), - M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); - if (ss == NULL) { - ic->ic_scan = NULL; - return; - } - callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0); - cv_init(&ss->ss_scan_cv, "scan"); - TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss); - - ic->ic_scan = &ss->base; - ss->base.ss_ic = ic; - - ic->ic_scan_curchan = scan_curchan; - ic->ic_scan_mindwell = scan_mindwell; - - /* - * TODO: all of the non-vap scan calls should be methods! - */ -} - -void +static void ieee80211_swscan_detach(struct ieee80211com *ic) { struct ieee80211_scan_state *ss = ic->ic_scan; @@ -159,7 +133,7 @@ ieee80211_swscan_detach(struct ieee80211com *ic) } } -void +static void ieee80211_swscan_vattach(struct ieee80211vap *vap) { /* nothing to do for now */ @@ -169,7 +143,7 @@ ieee80211_swscan_vattach(struct ieee80211vap *vap) } -void +static void ieee80211_swscan_vdetach(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; @@ -185,7 +159,7 @@ ieee80211_swscan_vdetach(struct ieee80211vap *vap) } } -void +static void ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration) { struct ieee80211com *ic = vap->iv_ic; @@ -278,7 +252,7 @@ ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan, * * Called without the comlock held; grab the comlock as appropriate. */ -int +static int ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan, struct ieee80211vap *vap, int flags, u_int duration, u_int mindwell, u_int maxdwell, @@ -305,7 +279,7 @@ ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan, * * XXX TODO: split out! */ -int +static int ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan, struct ieee80211vap *vap, int flags, u_int duration, u_int mindwell, u_int maxdwell, @@ -363,7 +337,7 @@ ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan, * Restart a previous scan. If the previous scan completed * then we start again using the existing channel list. */ -int +static int ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan, struct ieee80211vap *vap, int flags) { @@ -454,7 +428,7 @@ ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan, /* * Cancel any scan currently going on for the specified vap. */ -void +static void ieee80211_swscan_cancel_scan(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; @@ -488,7 +462,7 @@ ieee80211_swscan_cancel_scan(struct ieee80211vap *vap) /* * Cancel any scan currently going on. */ -void +static void ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; @@ -522,7 +496,7 @@ ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap) * Public access to scan_next for drivers that manage * scanning themselves (e.g. for firmware-based devices). */ -void +static void ieee80211_swscan_scan_next(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; @@ -540,7 +514,7 @@ ieee80211_swscan_scan_next(struct ieee80211vap *vap) * Public access to scan_next for drivers that are not able to scan single * channels (e.g. for firmware-based devices). */ -void +static void ieee80211_swscan_scan_done(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; @@ -559,7 +533,7 @@ ieee80211_swscan_scan_done(struct ieee80211vap *vap) * listen for beacons on the channel; if we receive something * then we'll transmit a probe request. */ -void +static void ieee80211_swscan_probe_curchan(struct ieee80211vap *vap, int force) { struct ieee80211com *ic = vap->iv_ic; @@ -887,7 +861,7 @@ done: /* * Process a beacon or probe response frame. */ -void +static void ieee80211_swscan_add_scan(struct ieee80211vap *vap, struct ieee80211_channel *curchan, const struct ieee80211_scanparams *sp, @@ -935,3 +909,50 @@ ieee80211_swscan_add_scan(struct ieee80211vap *vap, } } +static struct ieee80211_scan_methods swscan_methods = { + .sc_attach = ieee80211_swscan_attach, + .sc_detach = ieee80211_swscan_detach, + .sc_vattach = ieee80211_swscan_vattach, + .sc_vdetach = ieee80211_swscan_vdetach, + .sc_set_scan_duration = ieee80211_swscan_set_scan_duration, + .sc_start_scan = ieee80211_swscan_start_scan, + .sc_check_scan = ieee80211_swscan_check_scan, + .sc_bg_scan = ieee80211_swscan_bg_scan, + .sc_cancel_scan = ieee80211_swscan_cancel_scan, + .sc_cancel_anyscan = ieee80211_swscan_cancel_anyscan, + .sc_scan_next = ieee80211_swscan_scan_next, + .sc_scan_done = ieee80211_swscan_scan_done, + .sc_scan_probe_curchan = ieee80211_swscan_probe_curchan, + .sc_add_scan = ieee80211_swscan_add_scan +}; + +/* + * Default scan attach method. + */ +void +ieee80211_swscan_attach(struct ieee80211com *ic) +{ + struct scan_state *ss; + + /* + * Setup the default methods + */ + ic->ic_scan_methods = &swscan_methods; + + /* Allocate initial scan state */ + ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state), + M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); + if (ss == NULL) { + ic->ic_scan = NULL; + return; + } + callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0); + cv_init(&ss->ss_scan_cv, "scan"); + TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss); + + ic->ic_scan = &ss->base; + ss->base.ss_ic = ic; + + ic->ic_scan_curchan = scan_curchan; + ic->ic_scan_mindwell = scan_mindwell; +} diff --git a/sys/net80211/ieee80211_scan_sw.h b/sys/net80211/ieee80211_scan_sw.h index 7bb0cc378642..8408933bfeb3 100644 --- a/sys/net80211/ieee80211_scan_sw.h +++ b/sys/net80211/ieee80211_scan_sw.h @@ -28,34 +28,5 @@ #define __NET80211_IEEE80211_SCAN_SW_H__ extern void ieee80211_swscan_attach(struct ieee80211com *ic); -extern void ieee80211_swscan_detach(struct ieee80211com *ic); - -extern void ieee80211_swscan_vattach(struct ieee80211vap *vap); -extern void ieee80211_swscan_vdetach(struct ieee80211vap *vap); - -extern int ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan, - struct ieee80211vap *vap, int flags, - u_int duration, u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]); -extern void ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, - u_int duration); -extern void ieee80211_swscan_run_scan_task(struct ieee80211vap *vap); -extern int ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan, - struct ieee80211vap *vap, int flags, - u_int duration, u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]); -extern int ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan, - struct ieee80211vap *vap, int flags); -extern void ieee80211_swscan_cancel_scan(struct ieee80211vap *vap); -extern void ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap); -extern void ieee80211_swscan_scan_next(struct ieee80211vap *vap); -extern void ieee80211_swscan_scan_done(struct ieee80211vap *vap); -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); #endif /* __NET80211_IEEE80211_SCAN_SW_H__ */ diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index ec21a0c5c573..26238b88e4f1 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -197,6 +197,7 @@ struct ieee80211com { struct ieee80211_dfs_state ic_dfs; /* DFS state */ struct ieee80211_scan_state *ic_scan; /* scan state */ + struct ieee80211_scan_methods *ic_scan_methods; /* scan methods */ int ic_lastdata; /* time of last data frame */ int ic_lastscan; /* time last scan completed */