Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src/sys/dev Backport of bfwm code, requested by maya in ticke...
details: https://anonhg.NetBSD.org/src/rev/858d3c5838a5
branches: netbsd-8
changeset: 445506:858d3c5838a5
user: martin <martin%NetBSD.org@localhost>
date: Wed Oct 31 09:23:00 2018 +0000
description:
Backport of bfwm code, requested by maya in ticket #1072:
sys/dev/ic/bwfm.c 1.14
sys/dev/ic/bwfmreg.h 1.3
sys/dev/ic/bwfmvar.h 1.3
sys/dev/pci/if_bwfm_pci.c 1.4
sys/dev/pci/if_bwfm_pci.h 1.8
sys/dev/usb/if_bwfm_usb.c 1.8
via patch.
diffstat:
sys/dev/ic/bwfm.c | 1978 ++++++++++++++++++++++++++++++++++++++++++
sys/dev/ic/bwfmreg.h | 646 +++++++++++++
sys/dev/ic/bwfmvar.h | 183 +++
sys/dev/pci/if_bwfm_pci.c | 2102 +++++++++++++++++++++++++++++++++++++++++++++
sys/dev/pci/if_bwfm_pci.h | 279 +++++
sys/dev/usb/if_bwfm_usb.c | 904 +++++++++++++++++++
6 files changed, 6092 insertions(+), 0 deletions(-)
diffs (truncated from 6116 to 300 lines):
diff -r 1eab06eaeed5 -r 858d3c5838a5 sys/dev/ic/bwfm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/bwfm.c Wed Oct 31 09:23:00 2018 +0000
@@ -0,0 +1,1978 @@
+/* $NetBSD: bwfm.c,v 1.14.2.2 2018/10/31 09:23:00 martin Exp $ */
+/* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
+/*
+ * Copyright (c) 2010-2016 Broadcom Corporation
+ * Copyright (c) 2016,2017 Patrick Wildt <patrick%blueri.se@localhost>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/kmem.h>
+#include <sys/workqueue.h>
+#include <sys/pcq.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_ether.h>
+
+#include <netinet/in.h>
+
+#include <net80211/ieee80211_var.h>
+
+#include <dev/ic/bwfmvar.h>
+#include <dev/ic/bwfmreg.h>
+
+/* #define BWFM_DEBUG */
+#ifdef BWFM_DEBUG
+#define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0)
+#define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0)
+static int bwfm_debug = 1;
+#else
+#define DPRINTF(x) do { ; } while (0)
+#define DPRINTFN(n, x) do { ; } while (0)
+#endif
+
+#define DEVNAME(sc) device_xname((sc)->sc_dev)
+
+void bwfm_start(struct ifnet *);
+int bwfm_init(struct ifnet *);
+void bwfm_stop(struct ifnet *, int);
+void bwfm_watchdog(struct ifnet *);
+int bwfm_ioctl(struct ifnet *, u_long, void *);
+int bwfm_media_change(struct ifnet *);
+
+int bwfm_send_mgmt(struct ieee80211com *, struct ieee80211_node *,
+ int, int);
+void bwfm_recv_mgmt(struct ieee80211com *, struct mbuf *,
+ struct ieee80211_node *, int, int, uint32_t);
+int bwfm_key_set(struct ieee80211com *, const struct ieee80211_key *,
+ const uint8_t *);
+int bwfm_key_delete(struct ieee80211com *, const struct ieee80211_key *);
+int bwfm_newstate(struct ieee80211com *, enum ieee80211_state, int);
+void bwfm_newstate_cb(struct bwfm_softc *, struct bwfm_cmd_newstate *);
+void bwfm_newassoc(struct ieee80211_node *, int);
+void bwfm_task(struct work *, void *);
+
+int bwfm_chip_attach(struct bwfm_softc *);
+int bwfm_chip_detach(struct bwfm_softc *, int);
+struct bwfm_core *bwfm_chip_get_core(struct bwfm_softc *, int);
+struct bwfm_core *bwfm_chip_get_pmu(struct bwfm_softc *);
+int bwfm_chip_ai_isup(struct bwfm_softc *, struct bwfm_core *);
+void bwfm_chip_ai_disable(struct bwfm_softc *, struct bwfm_core *,
+ uint32_t, uint32_t);
+void bwfm_chip_ai_reset(struct bwfm_softc *, struct bwfm_core *,
+ uint32_t, uint32_t, uint32_t);
+void bwfm_chip_dmp_erom_scan(struct bwfm_softc *);
+int bwfm_chip_dmp_get_regaddr(struct bwfm_softc *, uint32_t *,
+ uint32_t *, uint32_t *);
+int bwfm_chip_cr4_set_active(struct bwfm_softc *, const uint32_t);
+void bwfm_chip_cr4_set_passive(struct bwfm_softc *);
+int bwfm_chip_ca7_set_active(struct bwfm_softc *, const uint32_t);
+void bwfm_chip_ca7_set_passive(struct bwfm_softc *);
+int bwfm_chip_cm3_set_active(struct bwfm_softc *);
+void bwfm_chip_cm3_set_passive(struct bwfm_softc *);
+void bwfm_chip_socram_ramsize(struct bwfm_softc *, struct bwfm_core *);
+void bwfm_chip_sysmem_ramsize(struct bwfm_softc *, struct bwfm_core *);
+void bwfm_chip_tcm_ramsize(struct bwfm_softc *, struct bwfm_core *);
+void bwfm_chip_tcm_rambase(struct bwfm_softc *);
+
+int bwfm_proto_bcdc_query_dcmd(struct bwfm_softc *, int,
+ int, char *, size_t *);
+int bwfm_proto_bcdc_set_dcmd(struct bwfm_softc *, int,
+ int, char *, size_t);
+
+int bwfm_fwvar_cmd_get_data(struct bwfm_softc *, int, void *, size_t);
+int bwfm_fwvar_cmd_set_data(struct bwfm_softc *, int, void *, size_t);
+int bwfm_fwvar_cmd_get_int(struct bwfm_softc *, int, uint32_t *);
+int bwfm_fwvar_cmd_set_int(struct bwfm_softc *, int, uint32_t);
+int bwfm_fwvar_var_get_data(struct bwfm_softc *, const char *, void *, size_t);
+int bwfm_fwvar_var_set_data(struct bwfm_softc *, const char *, void *, size_t);
+int bwfm_fwvar_var_get_int(struct bwfm_softc *, const char *, uint32_t *);
+int bwfm_fwvar_var_set_int(struct bwfm_softc *, const char *, uint32_t);
+
+struct ieee80211_channel *bwfm_bss2chan(struct bwfm_softc *, struct bwfm_bss_info *);
+void bwfm_scan(struct bwfm_softc *);
+void bwfm_connect(struct bwfm_softc *);
+
+void bwfm_rx(struct bwfm_softc *, struct mbuf *);
+void bwfm_rx_event(struct bwfm_softc *, char *, size_t);
+void bwfm_scan_node(struct bwfm_softc *, struct bwfm_bss_info *, size_t);
+
+uint8_t bwfm_2ghz_channels[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+};
+uint8_t bwfm_5ghz_channels[] = {
+ 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165,
+};
+
+struct bwfm_proto_ops bwfm_proto_bcdc_ops = {
+ .proto_query_dcmd = bwfm_proto_bcdc_query_dcmd,
+ .proto_set_dcmd = bwfm_proto_bcdc_set_dcmd,
+};
+
+void
+bwfm_attach(struct bwfm_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &sc->sc_if;
+ struct bwfm_task *t;
+ char fw_version[BWFM_DCMD_SMLEN];
+ uint32_t bandlist[3];
+ uint32_t tmp;
+ int i, j, error;
+
+ error = workqueue_create(&sc->sc_taskq, DEVNAME(sc),
+ bwfm_task, sc, PRI_NONE, IPL_NET, 0);
+ if (error != 0) {
+ printf("%s: could not create workqueue\n", DEVNAME(sc));
+ return;
+ }
+ sc->sc_freetask = pcq_create(BWFM_TASK_COUNT, KM_SLEEP);
+ for (i = 0; i < BWFM_TASK_COUNT; i++) {
+ t = &sc->sc_task[i];
+ t->t_sc = sc;
+ pcq_put(sc->sc_freetask, t);
+ }
+
+ /* Stop the device in case it was previously initialized */
+ bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1);
+
+ 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;
+ }
+
+ memset(fw_version, 0, sizeof(fw_version));
+ if (bwfm_fwvar_var_get_data(sc, "ver", fw_version, sizeof(fw_version)) == 0)
+ printf("%s: %s", DEVNAME(sc), fw_version);
+ printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(ic->ic_myaddr));
+
+ ic->ic_ifp = ifp;
+ ic->ic_phytype = IEEE80211_T_OFDM;
+ ic->ic_opmode = IEEE80211_M_STA;
+ ic->ic_state = IEEE80211_S_INIT;
+
+ ic->ic_caps =
+ IEEE80211_C_WEP |
+ IEEE80211_C_TKIP |
+ IEEE80211_C_AES |
+ IEEE80211_C_AES_CCM |
+#if notyet
+ IEEE80211_C_MONITOR | /* monitor mode suported */
+ IEEE80211_C_IBSS |
+ IEEE80211_C_TXPMGT |
+ IEEE80211_C_WME |
+#endif
+ IEEE80211_C_SHSLOT | /* short slot time supported */
+ IEEE80211_C_SHPREAMBLE | /* short preamble supported */
+ IEEE80211_C_WPA | /* 802.11i */
+ /* IEEE80211_C_WPA_4WAY */0; /* WPA 4-way handshake in hw */
+
+ /* IBSS channel undefined for now. */
+ ic->ic_ibss_chan = &ic->ic_channels[0];
+
+ 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;
+ }
+ const u_int nbands = le32toh(bandlist[0]);
+ for (i = 1; i <= MIN(nbands, __arraycount(bandlist) - 1); i++) {
+ switch (le32toh(bandlist[i])) {
+ case BWFM_BAND_2G:
+ ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
+ ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
+
+ for (j = 0; j < __arraycount(bwfm_2ghz_channels); j++) {
+ uint8_t chan = bwfm_2ghz_channels[j];
+ ic->ic_channels[chan].ic_freq =
+ ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
+ ic->ic_channels[chan].ic_flags =
+ IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
+ IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
+ }
+ break;
+ case BWFM_BAND_5G:
+ ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
+
+ for (j = 0; j < __arraycount(bwfm_5ghz_channels); j++) {
+ uint8_t chan = bwfm_5ghz_channels[j];
+ ic->ic_channels[chan].ic_freq =
+ ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
+ ic->ic_channels[chan].ic_flags =
+ IEEE80211_CHAN_A;
+ }
+ break;
+ }
+ }
+
+ ifp->if_softc = sc;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_init = bwfm_init;
+ ifp->if_ioctl = bwfm_ioctl;
+ ifp->if_start = bwfm_start;
+ ifp->if_stop = bwfm_stop;
+ ifp->if_watchdog = bwfm_watchdog;
+ IFQ_SET_READY(&ifp->if_snd);
+ memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
+
+ error = if_initialize(ifp);
+ if (error != 0) {
+ printf("%s: if_initialize failed(%d)\n", DEVNAME(sc), error);
+ pcq_destroy(sc->sc_freetask);
+ workqueue_destroy(sc->sc_taskq);
+
+ return; /* Error */
+ }
+
+ ieee80211_ifattach(ic);
+ ifp->if_percpuq = if_percpuq_create(ifp);
+ if_deferred_start_init(ifp, NULL);
+ if_register(ifp);
+
+ sc->sc_newstate = ic->ic_newstate;
+ ic->ic_newstate = bwfm_newstate;
+ ic->ic_newassoc = bwfm_newassoc;
+ ic->ic_send_mgmt = bwfm_send_mgmt;
+ ic->ic_recv_mgmt = bwfm_recv_mgmt;
+ ic->ic_crypto.cs_key_set = bwfm_key_set;
+ ic->ic_crypto.cs_key_delete = bwfm_key_delete;
+ ieee80211_media_init(ic, bwfm_media_change, ieee80211_media_status);
+
+ ieee80211_announce(ic);
+
+ sc->sc_if_attached = true;
+}
+
+int
+bwfm_detach(struct bwfm_softc *sc, int flags)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = ic->ic_ifp;
+
+ if (sc->sc_if_attached) {
+ bpf_detach(ifp);
+ ieee80211_ifdetach(ic);
+ if_detach(ifp);
+ }
+
+ if (sc->sc_taskq)
+ workqueue_destroy(sc->sc_taskq);
+ if (sc->sc_freetask)
+ pcq_destroy(sc->sc_freetask);
+
+ return 0;
+}
+
+void
+bwfm_start(struct ifnet *ifp)
+{
+ struct bwfm_softc *sc = ifp->if_softc;
Home |
Main Index |
Thread Index |
Old Index