diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-05-23 11:32:15 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-05-23 11:32:15 +0000 |
commit | dd88e4465076e42fbff2e48b51551ee3ffcb12e3 (patch) | |
tree | 0e3bf29876e050a7881ce20e2c0e7b293e17b5db /sys/dev/ic/bwfm.c | |
parent | 1273bf5390ec444749315bdf85be0a891c7eb445 (diff) |
Implement a separate initialization stage so that we can still use
and initialize bwfm(4) later in the case that the firmware was not
available on bootup and was only later installed.
ok stsp@
Diffstat (limited to 'sys/dev/ic/bwfm.c')
-rw-r--r-- | sys/dev/ic/bwfm.c | 112 |
1 files changed, 77 insertions, 35 deletions
diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 718d904b4f1..63af1755fc7 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.45 2018/05/17 06:53:45 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.46 2018/05/23 11:32:14 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -169,24 +169,10 @@ bwfm_attach(struct bwfm_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - uint32_t bandlist[3], tmp; - int i, j, nbands, nmode, vhtmode; TAILQ_INIT(&sc->sc_bcdc_rxctlq); TAILQ_INIT(&sc->sc_bcdc_txctlq); - if (bwfm_fwvar_cmd_get_int(sc, BWFM_C_GET_VERSION, &tmp)) { - printf("%s: could not read io type\n", DEVNAME(sc)); - return; - } else - sc->sc_io_type = tmp; - if (bwfm_fwvar_var_get_data(sc, "cur_etheraddr", ic->ic_myaddr, - sizeof(ic->ic_myaddr))) { - printf("%s: could not read mac address\n", DEVNAME(sc)); - return; - } - printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(ic->ic_myaddr)); - /* Init host async commands ring. */ sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0; sc->sc_taskq = taskq_create(DEVNAME(sc), 1, IPL_SOFTNET, 0); @@ -204,6 +190,63 @@ bwfm_attach(struct bwfm_softc *sc) IEEE80211_C_SCANALL | /* device scans all channels at once */ IEEE80211_C_SCANALLBAND; /* device scans all bands at once */ + /* IBSS channel undefined for now. */ + ic->ic_ibss_chan = &ic->ic_channels[0]; + + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = bwfm_ioctl; + ifp->if_start = bwfm_start; + ifp->if_watchdog = bwfm_watchdog; + memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); + + if_attach(ifp); + ieee80211_ifattach(ifp); + + sc->sc_newstate = ic->ic_newstate; + ic->ic_newstate = bwfm_newstate; + ic->ic_send_mgmt = bwfm_send_mgmt; + ic->ic_set_key = bwfm_set_key; + ic->ic_delete_key = bwfm_delete_key; + + ieee80211_media_init(ifp, bwfm_media_change, ieee80211_media_status); +} + +void +bwfm_attachhook(struct device *self) +{ + struct bwfm_softc *sc = (struct bwfm_softc *)self; + + if (sc->sc_bus_ops->bs_preinit != NULL && + sc->sc_bus_ops->bs_preinit(sc)) + return; + if (bwfm_preinit(sc)) + return; + sc->sc_initialized = 1; +} + +int +bwfm_preinit(struct bwfm_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = &ic->ic_if; + int i, j, nbands, nmode, vhtmode; + uint32_t bandlist[3], tmp; + + if (sc->sc_initialized) + return 0; + + if (bwfm_fwvar_cmd_get_int(sc, BWFM_C_GET_VERSION, &tmp)) { + printf("%s: could not read io type\n", DEVNAME(sc)); + return 1; + } else + sc->sc_io_type = tmp; + if (bwfm_fwvar_var_get_data(sc, "cur_etheraddr", ic->ic_myaddr, + sizeof(ic->ic_myaddr))) { + printf("%s: could not read mac address\n", DEVNAME(sc)); + return 1; + } + if (bwfm_fwvar_var_get_int(sc, "nmode", &nmode)) nmode = 0; if (bwfm_fwvar_var_get_int(sc, "vhtmode", &vhtmode)) @@ -211,7 +254,7 @@ bwfm_attach(struct bwfm_softc *sc) if (bwfm_fwvar_cmd_get_data(sc, BWFM_C_GET_BANDLIST, bandlist, sizeof(bandlist))) { printf("%s: couldn't get supported band list\n", DEVNAME(sc)); - return; + return 1; } nbands = letoh32(bandlist[0]); for (i = 1; i <= nbands && i < nitems(bandlist); i++) { @@ -260,26 +303,15 @@ bwfm_attach(struct bwfm_softc *sc) } } - /* IBSS channel undefined for now. */ - ic->ic_ibss_chan = &ic->ic_channels[0]; + /* Configure channel information obtained from firmware. */ + ieee80211_channel_init(ifp); - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = bwfm_ioctl; - ifp->if_start = bwfm_start; - ifp->if_watchdog = bwfm_watchdog; - memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); - - if_attach(ifp); - ieee80211_ifattach(ifp); - - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = bwfm_newstate; - ic->ic_send_mgmt = bwfm_send_mgmt; - ic->ic_set_key = bwfm_set_key; - ic->ic_delete_key = bwfm_delete_key; + /* Configure MAC address. */ + if (if_setlladdr(ifp, ic->ic_myaddr)) + printf("%s: could not set MAC address\n", DEVNAME(sc)); ieee80211_media_init(ifp, bwfm_media_change, ieee80211_media_status); + return 0; } int @@ -341,8 +373,18 @@ bwfm_init(struct ifnet *ifp) struct bwfm_join_pref_params join_pref[2]; int pm; - if (sc->sc_bus_ops->bs_init) - sc->sc_bus_ops->bs_init(sc); + if (!sc->sc_initialized) { + if (sc->sc_bus_ops->bs_preinit != NULL && + sc->sc_bus_ops->bs_preinit(sc)) { + printf("%s: could not init bus\n", DEVNAME(sc)); + return; + } + if (bwfm_preinit(sc)) { + printf("%s: could not init\n", DEVNAME(sc)); + return; + } + sc->sc_initialized = 1; + } if (bwfm_fwvar_var_set_int(sc, "mpc", 1)) { printf("%s: could not set mpc\n", DEVNAME(sc)); |