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