Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci add bwfm pci support, from openbsd



details:   https://anonhg.NetBSD.org/src/rev/872454bd2d13
branches:  trunk
changeset: 318968:872454bd2d13
user:      maya <maya%NetBSD.org@localhost>
date:      Fri May 11 07:42:22 2018 +0000
description:
add bwfm pci support, from openbsd

Tested on BCM43602.

diffstat:

 sys/dev/pci/files.pci     |     6 +-
 sys/dev/pci/if_bwfm_pci.c |  2062 +++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/pci/if_bwfm_pci.h |   279 ++++++
 3 files changed, 2346 insertions(+), 1 deletions(-)

diffs (truncated from 2369 to 300 lines):

diff -r f83464c086ae -r 872454bd2d13 sys/dev/pci/files.pci
--- a/sys/dev/pci/files.pci     Fri May 11 07:41:11 2018 +0000
+++ b/sys/dev/pci/files.pci     Fri May 11 07:42:22 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.pci,v 1.394 2018/03/01 04:29:37 pgoyette Exp $
+#      $NetBSD: files.pci,v 1.395 2018/05/11 07:42:22 maya Exp $
 #
 # Config file and device description for machine-independent PCI code.
 # Included by ports that need it.  Requires that the SCSI files be
@@ -1073,6 +1073,10 @@
 attach bwi at pci with bwi_pci
 file   dev/pci/if_bwi_pci.c            bwi_pci
 
+# Broadcom FullMAC USB wireless adapter
+attach bwfm at pci with bwfm_pci: firmload
+file   dev/pci/if_bwfm_pci.c           bwfm_pci
+
 # Marvell Serial-ATA Host Controller
 attach mvsata at pci with mvsata_pci
 file   dev/pci/mvsata_pci.c            mvsata_pci
diff -r f83464c086ae -r 872454bd2d13 sys/dev/pci/if_bwfm_pci.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/if_bwfm_pci.c Fri May 11 07:42:22 2018 +0000
@@ -0,0 +1,2062 @@
+/*     $NetBSD: if_bwfm_pci.c,v 1.1 2018/05/11 07:42:22 maya Exp $     */
+/*     $OpenBSD: if_bwfm_pci.c,v 1.18 2018/02/08 05:00:38 patrick Exp $        */
+/*
+ * Copyright (c) 2010-2016 Broadcom Corporation
+ * Copyright (c) 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/kmem.h>
+#include <sys/device.h>
+#include <sys/pool.h>
+#include <sys/workqueue.h>
+#include <sys/socket.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_ether.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+
+#include <net80211/ieee80211_var.h>
+
+#include <dev/firmload.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/ic/bwfmvar.h>
+#include <dev/ic/bwfmreg.h>
+#include <dev/pci/if_bwfm_pci.h>
+
+#define BWFM_DMA_D2H_SCRATCH_BUF_LEN           8
+#define BWFM_DMA_D2H_RINGUPD_BUF_LEN           1024
+#define BWFM_DMA_H2D_IOCTL_BUF_LEN             ETHER_MAX_LEN
+
+#define BWFM_NUM_TX_MSGRINGS                   2
+#define BWFM_NUM_RX_MSGRINGS                   3
+
+#define BWFM_NUM_TX_PKTIDS                     2048
+#define BWFM_NUM_RX_PKTIDS                     1024
+
+#define BWFM_NUM_TX_DESCS                      1
+#define BWFM_NUM_RX_DESCS                      1
+
+#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 = 2;
+#else
+#define DPRINTF(x)     do { ; } while (0)
+#define DPRINTFN(n, x) do { ; } while (0)
+#endif
+
+#define DEVNAME(sc)    device_xname((sc)->sc_sc.sc_dev)
+#define letoh16                htole16
+#define letoh32                htole32
+#define nitems(x)      __arraycount(x)
+
+enum ring_status {
+       RING_CLOSED,
+       RING_CLOSING,
+       RING_OPEN,
+       RING_OPENING,
+};
+
+struct bwfm_pci_msgring {
+       uint32_t                 w_idx_addr;
+       uint32_t                 r_idx_addr;
+       uint32_t                 w_ptr;
+       uint32_t                 r_ptr;
+       int                      nitem;
+       int                      itemsz;
+       enum ring_status         status;
+       struct bwfm_pci_dmamem  *ring;
+       struct mbuf             *m;
+
+       int                      fifo;
+       uint8_t                  mac[ETHER_ADDR_LEN];
+};
+
+struct bwfm_pci_buf {
+       bus_dmamap_t     bb_map;
+       struct mbuf     *bb_m;
+};
+
+struct bwfm_pci_pkts {
+       struct bwfm_pci_buf     *pkts;
+       uint32_t                 npkt;
+       int                      last;
+};
+
+struct if_rxring {
+       u_int   rxr_total;
+       u_int   rxr_inuse;
+};
+
+struct bwfm_cmd_flowring_create {
+       struct work              wq_cookie;
+       struct bwfm_pci_softc   *sc;
+       struct mbuf             *m;
+       int                      flowid;
+       int                      prio;
+};
+
+struct bwfm_pci_softc {
+       struct bwfm_softc        sc_sc;
+       pci_chipset_tag_t        sc_pc;
+       pcitag_t                 sc_tag;
+       pcireg_t                 sc_id;
+       void                    *sc_ih;
+       pci_intr_handle_t       *sc_pihp;
+
+       bus_space_tag_t          sc_reg_iot;
+       bus_space_handle_t       sc_reg_ioh;
+       bus_size_t               sc_reg_ios;
+
+       bus_space_tag_t          sc_tcm_iot;
+       bus_space_handle_t       sc_tcm_ioh;
+       bus_size_t               sc_tcm_ios;
+
+       bus_dma_tag_t            sc_dmat;
+
+       uint32_t                 sc_shared_address;
+       uint32_t                 sc_shared_flags;
+       uint8_t                  sc_shared_version;
+
+       uint8_t                  sc_dma_idx_sz;
+       struct bwfm_pci_dmamem  *sc_dma_idx_buf;
+       size_t                   sc_dma_idx_bufsz;
+
+       uint16_t                 sc_max_rxbufpost;
+       uint32_t                 sc_rx_dataoffset;
+       uint32_t                 sc_htod_mb_data_addr;
+       uint32_t                 sc_dtoh_mb_data_addr;
+       uint32_t                 sc_ring_info_addr;
+
+       uint32_t                 sc_console_base_addr;
+       uint32_t                 sc_console_buf_addr;
+       uint32_t                 sc_console_buf_size;
+       uint32_t                 sc_console_readidx;
+
+       struct pool              sc_flowring_pool;
+       struct workqueue        *flowring_wq;
+
+       uint16_t                 sc_max_flowrings;
+       uint16_t                 sc_max_submissionrings;
+       uint16_t                 sc_max_completionrings;
+
+       struct bwfm_pci_msgring  sc_ctrl_submit;
+       struct bwfm_pci_msgring  sc_rxpost_submit;
+       struct bwfm_pci_msgring  sc_ctrl_complete;
+       struct bwfm_pci_msgring  sc_tx_complete;
+       struct bwfm_pci_msgring  sc_rx_complete;
+       struct bwfm_pci_msgring *sc_flowrings;
+
+       struct bwfm_pci_dmamem  *sc_scratch_buf;
+       struct bwfm_pci_dmamem  *sc_ringupd_buf;
+
+       struct bwfm_pci_dmamem  *sc_ioctl_buf;
+       int                      sc_ioctl_reqid;
+       uint32_t                 sc_ioctl_resp_pktid;
+       uint32_t                 sc_ioctl_resp_ret_len;
+       uint32_t                 sc_ioctl_resp_status;
+       int                      sc_ioctl_poll;
+
+       struct if_rxring         sc_ioctl_ring;
+       struct if_rxring         sc_event_ring;
+       struct if_rxring         sc_rxbuf_ring;
+
+       struct bwfm_pci_pkts     sc_rx_pkts;
+       struct bwfm_pci_pkts     sc_tx_pkts;
+       int                      sc_tx_pkts_full;
+};
+
+struct bwfm_pci_dmamem {
+       bus_dmamap_t            bdm_map;
+       bus_dma_segment_t       bdm_seg;
+       size_t                  bdm_size;
+       char *                  bdm_kva;
+};
+
+#define BWFM_PCI_DMA_MAP(_bdm) ((_bdm)->bdm_map)
+#define BWFM_PCI_DMA_LEN(_bdm) ((_bdm)->bdm_size)
+#define BWFM_PCI_DMA_DVA(_bdm) ((_bdm)->bdm_map->dm_segs[0].ds_addr)
+#define BWFM_PCI_DMA_KVA(_bdm) ((_bdm)->bdm_kva)
+
+static u_int    if_rxr_get(struct if_rxring *rxr, unsigned int max);
+static void     if_rxr_put(struct if_rxring *rxr, unsigned int n);
+static void     if_rxr_init(struct if_rxring *rxr, unsigned int lwm, unsigned int hwm);
+
+int             bwfm_pci_match(device_t parent, cfdata_t match, void *aux);
+void            bwfm_pci_attachhook(device_t);
+void            bwfm_pci_attach(device_t, device_t, void *);
+int             bwfm_pci_detach(device_t, int);
+
+int             bwfm_pci_intr(void *);
+void            bwfm_pci_intr_enable(struct bwfm_pci_softc *);
+void            bwfm_pci_intr_disable(struct bwfm_pci_softc *);
+int             bwfm_pci_load_microcode(struct bwfm_pci_softc *, const u_char *,
+                   size_t);
+void            bwfm_pci_select_core(struct bwfm_pci_softc *, int );
+
+struct bwfm_pci_dmamem *
+                bwfm_pci_dmamem_alloc(struct bwfm_pci_softc *, bus_size_t,
+                   bus_size_t);
+void            bwfm_pci_dmamem_free(struct bwfm_pci_softc *, struct bwfm_pci_dmamem *);
+int             bwfm_pci_pktid_avail(struct bwfm_pci_softc *,
+                   struct bwfm_pci_pkts *);
+int             bwfm_pci_pktid_new(struct bwfm_pci_softc *,
+                   struct bwfm_pci_pkts *, struct mbuf *,
+                   uint32_t *, paddr_t *);
+struct mbuf *   bwfm_pci_pktid_free(struct bwfm_pci_softc *,
+                   struct bwfm_pci_pkts *, uint32_t);
+void            bwfm_pci_fill_rx_ioctl_ring(struct bwfm_pci_softc *,
+                   struct if_rxring *, uint32_t);
+void            bwfm_pci_fill_rx_buf_ring(struct bwfm_pci_softc *);
+void            bwfm_pci_fill_rx_rings(struct bwfm_pci_softc *);
+int             bwfm_pci_setup_ring(struct bwfm_pci_softc *, struct bwfm_pci_msgring *,
+                   int, size_t, uint32_t, uint32_t, int, uint32_t, uint32_t *);
+int             bwfm_pci_setup_flowring(struct bwfm_pci_softc *, struct bwfm_pci_msgring *,
+                   int, size_t);
+
+void            bwfm_pci_ring_bell(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void            bwfm_pci_ring_update_rptr(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void            bwfm_pci_ring_update_wptr(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void            bwfm_pci_ring_write_rptr(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void            bwfm_pci_ring_write_wptr(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void *          bwfm_pci_ring_write_reserve(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void *          bwfm_pci_ring_write_reserve_multi(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *, int, int *);
+void *          bwfm_pci_ring_read_avail(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *, int *);
+void            bwfm_pci_ring_read_commit(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *, int);
+void            bwfm_pci_ring_write_commit(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void            bwfm_pci_ring_write_cancel(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *, int);
+
+void            bwfm_pci_ring_rx(struct bwfm_pci_softc *,
+                   struct bwfm_pci_msgring *);
+void            bwfm_pci_msg_rx(struct bwfm_pci_softc *, void *);
+
+uint32_t        bwfm_pci_buscore_read(struct bwfm_softc *, uint32_t);
+void            bwfm_pci_buscore_write(struct bwfm_softc *, uint32_t,
+                   uint32_t);
+int             bwfm_pci_buscore_prepare(struct bwfm_softc *);
+int             bwfm_pci_buscore_reset(struct bwfm_softc *);
+void            bwfm_pci_buscore_activate(struct bwfm_softc *, const uint32_t);
+
+int             bwfm_pci_flowring_lookup(struct bwfm_pci_softc *,
+                    struct mbuf *);



Home | Main Index | Thread Index | Old Index