1 /* $OpenBSD: musyccvar.h,v 1.9 2006/02/06 17:29:11 jmc Exp $ */
2
3 /*
4 * Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland
5 * Written by: Claudio Jeker <jeker@accoom.net>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19 #ifndef __MUSYCCVAR_H__
20 #define __MUSYCCVAR_H__
21
22 #include <sys/queue.h>
23
24 #define PPP_HEADER_LEN 4 /* should be globaly defined by sppp */
25
26 /* some defaults */
27 #define MUSYCC_NUMCHAN 32 /* 32 channels per group */
28 #define MUSYCC_NUMPORT 8 /* max 8 ports per controller */
29 #define MUSYCC_SREQNUM 16 /* pending SREQ */
30 #define MUSYCC_SREQMASK (MUSYCC_SREQNUM - 1)
31 #define MUSYCC_SREQTIMEOUT 2
32
33 /* dma ring sizes */
34 #define MUSYCC_DMA_CNT 256
35 #define MUSYCC_DMA_MAPSIZE (MUSYCC_DMA_CNT * sizeof(struct dma_desc))
36 #define MUSYCC_DMA_SIZE 32
37
38 struct musycc_softc;
39 struct ebus_softc;
40
41 /* DMA descriptor for data */
42 struct dma_desc {
43 u_int32_t status;
44 u_int32_t data;
45 u_int32_t next;
46 /* Software only */
47 struct mbuf *mbuf;
48 struct dma_desc *nextdesc;
49 bus_dmamap_t map;
50 };
51
52 #define MUSYCC_INTLEN 512 /* 512 pending interrupts is enough */
53 struct musycc_intdesc {
54 u_int32_t md_intrq[MUSYCC_INTLEN];
55 };
56
57 struct musycc_dma_data {
58 /*
59 * received dma ring. rx_prod points to the frist descriptors that
60 * is under musycc control (first empty).
61 */
62 struct dma_desc *rx_prod;
63 int rx_cnt;
64
65 struct dma_desc *tx_pend; /* finished pointer */
66 struct dma_desc *tx_cur; /* current insertion pointer */
67 int tx_cnt; /* number of descriptors */
68 int tx_use; /* number of used descriptors */
69 int tx_pkts; /* number of packets in queue */
70 };
71
72 enum musycc_state {
73 CHAN_FLOAT, /* unconnected channel */
74 CHAN_IDLE,
75 CHAN_RUNNING,
76 CHAN_FAULT,
77 CHAN_TRANSIENT /* dummy state to protect ongoing state changes */
78 };
79
80 enum musycc_event {
81 EV_NULL, /* null event, ignore */
82 EV_ACTIVATE, /* activate channel go to running state */
83 EV_STOP, /* stop dma engine */
84 EV_IDLE, /* free timeslots et al. and go to idle state */
85 EV_WATCHDOG /* watchdog event, stop dma engine */
86 };
87
88 /* group structure */
89 struct musycc_group {
90 struct musycc_softc *mg_hdlc; /* main controller */
91 struct musycc_grpdesc *mg_group; /* group descriptor */
92 u_int8_t mg_gnum; /* group number */
93 u_int8_t mg_port; /* port number */
94 u_int8_t mg_loaded; /* sreq(5) done? */
95 u_int64_t mg_fifomask; /* fifo allocation mask */
96
97 struct channel_softc *mg_channels[MUSYCC_NUMCHAN];
98 struct musycc_dma_data mg_dma_d[MUSYCC_NUMCHAN];
99 struct dma_desc *mg_freelist;
100 int mg_freecnt;
101
102 struct {
103 long timeout;
104 u_int32_t sreq;
105 enum musycc_event event;
106 } mg_sreq[MUSYCC_SREQNUM];
107 int mg_sreqpend;
108 int mg_sreqprod;
109
110 struct dma_desc *mg_dma_pool;
111 bus_dma_tag_t mg_dmat; /* bus dma tag */
112 caddr_t mg_listkva;
113 bus_dmamap_t mg_listmap;
114 bus_dma_segment_t mg_listseg[1];
115 int mg_listnseg;
116 bus_dmamap_t mg_tx_sparemap;
117 bus_dmamap_t mg_rx_sparemap;
118 };
119
120 /* attach arguments for framer devices */
121 struct musycc_attach_args {
122 char ma_product[64];
123 bus_size_t ma_base;
124 bus_size_t ma_size;
125 u_int32_t ma_type;
126 u_int8_t ma_gnum;
127 u_int8_t ma_port;
128 u_int8_t ma_flags;
129 char ma_slot;
130 };
131
132 /* generic ebus device handle */
133 struct ebus_dev {
134 bus_size_t base;
135 bus_size_t size;
136 bus_space_tag_t st;
137 bus_space_handle_t sh;
138 };
139
140 /* Softc for each HDLC channel config */
141 struct channel_softc {
142 struct sppp cc_ppp; /* sppp network attachement */
143 struct ifnet *cc_ifp; /* pointer to the active ifp */
144 struct musycc_group *cc_group;
145 struct device *cc_parent; /* parent framer */
146
147 u_int32_t cc_tslots; /* timeslot map */
148 int cc_unit;
149 enum musycc_state cc_state; /* state machine info */
150 u_int8_t cc_channel; /* HDLC channel */
151 u_int8_t cc_locked;
152 };
153
154 /* Softc for the HDLC Controller (function 0) */
155 struct musycc_softc {
156 struct device mc_dev; /* generic device structures */
157 void *mc_ih; /* interrupt handler cookie */
158 bus_space_tag_t mc_st; /* bus space tag */
159 bus_space_handle_t mc_sh; /* bus space handle */
160 bus_dma_tag_t mc_dmat; /* bus dma tag */
161 bus_size_t mc_iosize; /* size of bus space */
162
163 caddr_t mc_groupkva; /* group configuration mem */
164 bus_dmamap_t mc_cfgmap;
165 bus_dma_segment_t mc_cfgseg[1];
166 bus_dmamap_t mc_intrmap;
167 bus_dma_segment_t mc_intrseg[1];
168 int mc_cfgnseg;
169 int mc_intrnseg;
170
171 struct musycc_group *mc_groups; /* mc_ngroups groups */
172 struct musycc_intdesc *mc_intrd;
173 u_int32_t mc_global_conf; /* global config descriptor */
174 u_int32_t mc_intrqptr; /* interrupt queue pointer */
175 int mc_ngroups;
176 int mc_nports;
177
178 struct musycc_softc *mc_other; /* the other EBUS/HDLC dev */
179 bus_size_t mc_ledbase;
180 u_int8_t mc_ledmask;
181 u_int8_t mc_ledstate; /* current state of the LEDs */
182 int bus, device; /* location of card */
183 SLIST_ENTRY(musycc_softc) list; /* list of all hdlc ctrls */
184 };
185
186 int musycc_attach_common(struct musycc_softc *, u_int32_t, u_int32_t);
187 void musycc_set_port(struct musycc_group *, int);
188 int musycc_init_channel(struct channel_softc *, char);
189 void musycc_stop_channel(struct channel_softc *);
190 void musycc_free_channel(struct musycc_group *, int);
191 void musycc_start(struct ifnet *);
192 void musycc_watchdog(struct ifnet *);
193 void musycc_tick(struct channel_softc *);
194
195 int musycc_intr(void *);
196 int ebus_intr(void *);
197
198 /* EBUS API */
199 int ebus_attach_device(struct ebus_dev *, struct musycc_softc *,
200 bus_size_t, bus_size_t);
201 u_int8_t ebus_read(struct ebus_dev *, bus_size_t);
202 void ebus_write(struct ebus_dev *, bus_size_t, u_int8_t);
203 void ebus_read_buf(struct ebus_dev *, bus_size_t, void *, size_t);
204 void ebus_set_led(struct channel_softc *, int, u_int8_t);
205
206 #define MUSYCC_LED_GREEN 0x1
207 #define MUSYCC_LED_RED 0x2
208 #define MUSYCC_LED_MASK 0x3
209
210 /* channel API */
211 struct channel_softc *musycc_channel_create(const char *, u_int8_t);
212 void musycc_attach_sppp(struct channel_softc *,
213 int (*)(struct ifnet *, u_long, caddr_t));
214 int musycc_channel_attach(struct musycc_softc *,
215 struct channel_softc *, struct device *, u_int8_t);
216 void musycc_channel_detach(struct ifnet *);
217
218
219 #ifndef ACCOOM_DEBUG
220 #define ACCOOM_PRINTF(n, x)
221 #else
222 extern int accoom_debug;
223
224 #define ACCOOM_PRINTF(n, x) \
225 do { \
226 if (accoom_debug >= n) \
227 printf x; \
228 } while (0)
229 #endif
230
231 #endif