diff options
Diffstat (limited to 'sys/dev/pci/musyccvar.h')
-rw-r--r-- | sys/dev/pci/musyccvar.h | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/sys/dev/pci/musyccvar.h b/sys/dev/pci/musyccvar.h new file mode 100644 index 00000000000..a45ed09f660 --- /dev/null +++ b/sys/dev/pci/musyccvar.h @@ -0,0 +1,234 @@ +/* $OpenBSD: musyccvar.h,v 1.1 2005/08/13 22:49:48 claudio Exp $ */ +/* $Id: musyccvar.h,v 1.1 2005/08/13 22:49:48 claudio Exp $ */ + +/* + * Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland + * Written by: Claudio Jeker <jeker@accoom.net> + * + * Permission to use, copy, modify, and 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. + */ +#ifndef __MUSYCCVAR_H__ +#define __MUSYCCVAR_H__ + +#include <sys/queue.h> + +#define PPP_HEADER_LEN 4 /* should be globaly defined by sppp */ + +/* some defaults */ +#define MUSYCC_NUMCHAN 32 /* 32 channels per group */ +#define MUSYCC_NUMPORT 8 /* max 8 ports per controller */ +#define MUSYCC_SREQNUM 16 /* pending SREQ */ +#define MUSYCC_SREQMASK (MUSYCC_SREQNUM - 1) + +/* dma ring sizes */ +#define MUSYCC_DMA_CNT 256 +#define MUSYCC_DMA_MAPSIZE (MUSYCC_DMA_CNT * sizeof(struct dma_desc)) +#define MUSYCC_DMA_MIN 3 +#define MUSYCC_DMA_MAX 64 + +struct musycc_softc; +struct ebus_softc; + +/* DMA descriptor for data */ +struct dma_desc { + u_int32_t status; + u_int32_t data; + u_int32_t next; + /* Software only */ + struct mbuf *mbuf; + struct dma_desc *nextdesc; + bus_dmamap_t map; +}; + +#define MUSYCC_INTLEN 512 /* 512 pending interrups is enough */ +struct musycc_intdesc { + u_int32_t md_intrq[MUSYCC_INTLEN]; +}; + +struct musycc_dma_data { + /* + * received dma ring. rx_prod points to the frist descriptors that + * is under musycc control (first empty). + */ + struct dma_desc *rx_prod; + int rx_cnt; + + struct dma_desc *tx_pend; /* finished pointer */ + struct dma_desc *tx_cur; /* current insertion pointer */ + int tx_cnt; /* number of descriptors */ + int tx_use; /* number of used descriptors */ + int tx_pkts; /* number of packets in queue */ +}; + +enum musycc_state { + CHAN_FLOAT, /* unconnected channel */ + CHAN_IDLE, + CHAN_RUNNING, + CHAN_FAULT, + CHAN_TRANSIENT /* dummy state to protect ongoing state changes */ +}; + +enum musycc_event { + EV_NULL, /* null event, ignore */ + EV_ACTIVATE, /* activate channel go to running state */ + EV_STOP, /* stop dma engine */ + EV_IDLE, /* free timeslots et al. and go to idle state */ + EV_WATCHDOG /* watchdog event, stop dma engine */ +}; + +/* group structure */ +struct musycc_group { + struct musycc_softc *mg_hdlc; /* main controller */ + struct musycc_grpdesc *mg_group; /* group descriptor */ + u_int8_t mg_gnum; /* group number */ + u_int8_t mg_port; /* port number */ + u_int8_t mg_loaded; /* sreq(5) done? */ + u_int64_t mg_fifomask; /* fifo allocation mask */ + + struct channel_softc *mg_channels[MUSYCC_NUMCHAN]; + struct musycc_dma_data mg_dma_d[MUSYCC_NUMCHAN]; + struct dma_desc *mg_freelist; + int mg_freecnt; + + struct { + u_int32_t sreq; + enum musycc_event event; + } mg_sreq[MUSYCC_SREQNUM]; + int mg_sreqpend; + int mg_sreqprod; + + struct dma_desc *mg_dma_pool; + bus_dma_tag_t mg_dmat; /* bus dma tag */ + caddr_t mg_listkva; + bus_dmamap_t mg_listmap; + bus_dma_segment_t mg_listseg[1]; + int mg_listnseg; + bus_dmamap_t mg_tx_sparemap; + bus_dmamap_t mg_rx_sparemap; +}; + +/* attach arguments for framer devices */ +struct musycc_attach_args { + char ma_product[64]; + bus_size_t ma_base; + bus_size_t ma_size; + u_int32_t ma_type; + u_int8_t ma_gnum; + u_int8_t ma_port; + char ma_slot; +}; + +/* generic ebus device handle */ +struct ebus_dev { + bus_size_t base; + bus_size_t size; + bus_space_tag_t st; + bus_space_handle_t sh; +}; + +/* Softc for each HDLC channel config */ +struct channel_softc { + struct sppp cc_ppp; /* sppp network attachement */ + struct ifnet *cc_ifp; /* pointer to the active ifp */ + struct musycc_group *cc_group; + struct device *cc_parent; /* parent framer */ + + u_int32_t cc_tslots; /* timeslot map */ + int cc_unit; + enum musycc_state cc_state; /* state machine info */ + u_int8_t cc_channel; /* HDLC channel */ + u_int8_t cc_locked; +}; + +/* Softc for the HDLC Controller (function 0) */ +struct musycc_softc { + struct device mc_dev; /* generic device structures */ + void *mc_ih; /* interrupt handler cookie */ + bus_space_tag_t mc_st; /* bus space tag */ + bus_space_handle_t mc_sh; /* bus space handle */ + bus_dma_tag_t mc_dmat; /* bus dma tag */ + bus_size_t mc_iosize; /* size of bus space */ + + caddr_t mc_groupkva; /* group configuration mem */ + bus_dmamap_t mc_cfgmap; + bus_dma_segment_t mc_cfgseg[1]; + bus_dmamap_t mc_intrmap; + bus_dma_segment_t mc_intrseg[1]; + int mc_cfgnseg; + int mc_intrnseg; + + struct musycc_group *mc_groups; /* mc_ngroups groups */ + struct musycc_intdesc *mc_intrd; + u_int32_t mc_global_conf; /* global config descriptor */ + u_int32_t mc_intrqptr; /* interrupt queue pointer */ + int mc_ngroups; + int mc_nports; + + int bus, device; /* location of card */ + struct ebus_softc *mc_ebus; /* corresponding EBUS bridge */ + SLIST_ENTRY(musycc_softc) list; /* list of all hdlc ctrls */ +}; + +/* Softc for the EBUS bridge (function 1) */ +struct ebus_softc { + struct device ec_dev; /* generic device structures */ + void *ec_ih; /* interrupt handler cookie */ + bus_space_tag_t ec_st; /* bus space tag */ + bus_space_handle_t ec_sh; /* bus space handle */ + bus_dma_tag_t ec_dmat; /* bus dma tag */ + struct musycc_softc *ec_hdlc; /* corresponding HDLC + controller */ + bus_size_t ec_ledbase; + u_int8_t ec_ledmask; +}; + +int musycc_attach_common(struct musycc_softc *, u_int32_t, u_int32_t); +int musycc_init_channel(struct channel_softc *, char); +void musycc_stop_channel(struct channel_softc *); +void musycc_free_channel(struct musycc_group *, int); +void musycc_start(struct ifnet *); +void musycc_watchdog(struct ifnet *); + +int musycc_intr(void *); +int ebus_intr(void *); + +/* EBUS API */ +int ebus_attach_device(struct ebus_dev *, struct musycc_softc *, + bus_size_t, bus_size_t); +u_int8_t ebus_read(struct ebus_dev *, bus_size_t); +void ebus_write(struct ebus_dev *, bus_size_t, u_int8_t); +void ebus_read_buf(struct ebus_dev *, bus_size_t, void *, size_t); +void ebus_set_led(struct ebus_softc *, u_int8_t); + +/* channel API */ +struct channel_softc *musycc_channel_create(const char *, u_int8_t); +void musycc_attach_sppp(struct channel_softc *, + int (*)(struct ifnet *, u_long, caddr_t)); +int musycc_channel_attach(struct musycc_softc *, + struct channel_softc *, struct device *, u_int8_t); +void musycc_channel_detach(struct ifnet *); + + +#ifndef ACCOOM_DEBUG +#define ACCOOM_PRINTF(n, x) +#else +extern int accoom_debug; + +#define ACCOOM_PRINTF(n, x) \ + do { \ + if (accoom_debug >= n) \ + printf x; \ + } while (0) +#endif + +#endif |