Annotation of sys/dev/ic/rlnreg.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: rlnreg.h,v 1.3 2002/03/14 01:26:55 millert Exp $ */
2: /*
3: * David Leonard <d@openbsd.org>, 1999. Public Domain.
4: *
5: * RangeLAN2 registers
6: */
7:
8: /*
9: * The RangeLAN2 cards provide four control registers for transferring
10: * messaged between the host and the card using programmed i/o.
11: *
12: * A transfer protocol is followed when sending asynchronous messages to,
13: * and receiving messages from, the card.
14: *
15: * DATA
16: * 7 6 5 4 3 2 1 0
17: * +-------+-------+-------+-------+-------+-------+-------+-------+
18: * | data |
19: * +-------+-------+-------+-------+-------+-------+-------+-------+
20: *
21: * STATUS
22: * 7 6 5 4 3 2 1 0
23: * +-------+-------+-------+-------+-------+-------+-------+-------+
24: * |WAKEUP | tx message state |CLRNAK | rx message state |
25: * +-------+-------+-------+-------+-------+-------+-------+-------+
26: *
27: * CONTROL
28: * 7 6 5 4 3 2 1 0
29: * +-------+-------+-------+-------+-------+-------+-------+-------+
30: * | | | 16BIT | RESET | | | TXINT | RXINT |
31: * +-------+-------+-------+-------+-------+-------+-------+-------+
32: *
33: * INTSEL
34: * 7 6 5 4 3 2 1 0
35: * +-------+-------+-------+-------+-------+-------+-------+-------+
36: * | | | |ENABLE | interrupt line |
37: * +-------+-------+-------+-------+-------+-------+-------+-------+
38: */
39:
40: /* Register offsets. */
41: #define RLN_REG_DATA 0
42: #define RLN_REG_STATUS 2
43: #define RLN_REG_CONTROL 4
44: #define RLN_REG_EOI 5
45: #define RLN_REG_INTSEL 6
46: #define RLN_NPORTS 8
47:
48: /*
49: * A short delay is needed (16ms?) after register writes on some cards.
50: * XXX This is done by performing an innocent and harmless bus read. (i386)
51: * This is what Proxim's driver does, anyway.
52: */
53: #define _rln_regacc_delay() \
54: bus_space_read_1(I386_BUS_SPACE_IO, 0, 0x61)
55:
56: static void _rln_register_write_1(struct rln_softc *, u_int8_t,
57: u_int8_t);
58: static void _rln_register_write_2(struct rln_softc *, u_int8_t,
59: u_int16_t);
60: static u_int8_t _rln_register_read_1(struct rln_softc *, u_int8_t);
61: static u_int16_t _rln_register_read_2(struct rln_softc *, u_int8_t);
62: static int rln_status_rx_ready(struct rln_softc *);
63:
64: /* Write to a register. */
65: static inline void
66: _rln_register_write_1(sc, regoff, value)
67: struct rln_softc *sc;
68: u_int8_t regoff;
69: u_int8_t value;
70: {
71:
72: #ifdef RLNDEBUG_REG
73: printf(" %c<%02x", "DDS3CEI7"[regoff], value);
74: #endif
75: bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (regoff), (value));
76: _rln_regacc_delay();
77: }
78:
79: static inline void
80: _rln_register_write_2(sc, regoff, value)
81: struct rln_softc *sc;
82: u_int8_t regoff;
83: u_int16_t value;
84: {
85:
86: #ifdef RLNDEBUG_REG
87: printf(" %c<%04x", "DDS3CEI7"[regoff], value);
88: #endif
89: bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (regoff), (value));
90: _rln_regacc_delay();
91: }
92:
93: /* Read from a register. */
94: static inline u_int8_t
95: _rln_register_read_1(sc, regoff)
96: struct rln_softc *sc;
97: u_int8_t regoff;
98: {
99: u_int8_t ret;
100:
101: ret = bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (regoff));
102: #ifdef RLNDEBUG_REG
103: if (ret != (sc)->dbg_oreg[regoff]) {
104: /* avoid spewing out too much debug info */
105: printf(" %c>%02x", "DDS3CEI7"[regoff], ret);
106: (sc)->dbg_oreg[regoff] = ret;
107: }
108: #endif
109: return (ret);
110: }
111:
112:
113: static inline u_int16_t
114: _rln_register_read_2(sc, regoff)
115: struct rln_softc *sc;
116: u_int8_t regoff;
117: {
118: u_int16_t ret;
119:
120: ret = bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, (regoff));
121: #ifdef RLNDEBUG_REG
122: if (ret != (sc)->dbg_oreg[regoff]) {
123: printf(" %c>%04x", "DDS3CEI7"[regoff], ret);
124: (sc)->dbg_oreg[regoff] = ret;
125: }
126: #endif
127: return (ret);
128: }
129:
130: /* 8-bit data register access. */
131: #define rln_data_write_1(sc, value) \
132: _rln_register_write_1(sc, RLN_REG_DATA, (value))
133: #define rln_data_read_1(sc) \
134: _rln_register_read_1(sc, RLN_REG_DATA)
135: #define rln_data_write_multi_1(sc, buf, len) \
136: bus_space_write_multi_1((sc)->sc_iot, (sc)->sc_ioh, \
137: RLN_REG_DATA, (buf), (len))
138: #define rln_data_read_multi_1(sc, buf, len) \
139: bus_space_read_multi_1((sc)->sc_iot, (sc)->sc_ioh, \
140: RLN_REG_DATA, (buf), (len))
141:
142: /* 16-bit data register access. */
143: #define rln_data_write_2(sc, value) \
144: _rln_register_write_2(sc, RLN_REG_DATA, (value))
145: #define rln_data_read_2(sc) \
146: _rln_register_read_2(sc, RLN_REG_DATA)
147: #define rln_data_write_multi_2(sc, buf, len) \
148: bus_space_write_multi_2((sc)->sc_iot, (sc)->sc_ioh, \
149: RLN_REG_DATA, (buf), (len))
150: #define rln_data_read_multi_2(sc, buf, len) \
151: bus_space_read_multi_2((sc)->sc_iot, (sc)->sc_ioh, \
152: RLN_REG_DATA, (buf), (len))
153:
154: /* Status register. */
155: #define RLN_STATUS_CLRNAK 0x08
156: #define RLN_STATUS_WAKEUP 0x80
157:
158: #define RLN_STATUS_TX_IDLE 0x00
159: #define RLN_STATUS_TX_HILEN_AVAIL 0x01
160: #define RLN_STATUS_TX_HILEN_ACCEPT 0x02
161: #define RLN_STATUS_TX_XFR_COMPLETE 0x03
162: #define RLN_STATUS_TX_XFR 0x04
163: #define RLN_STATUS_TX_ERROR 0x05
164: #define RLN_STATUS_TX_LOLEN_AVAIL 0x06
165: #define RLN_STATUS_TX_LOLEN_ACCEPT 0x07
166: #define RLN_STATUS_TX_MASK 0x0f
167:
168: #define RLN_STATUS_RX_IDLE 0x00
169: #define RLN_STATUS_RX_HILEN_AVAIL 0x10
170: #define RLN_STATUS_RX_HILEN_ACCEPT 0x20
171: #define RLN_STATUS_RX_XFR_COMPLETE 0x30
172: #define RLN_STATUS_RX_XFR 0x40
173: #define RLN_STATUS_RX_ERROR 0x50
174: #define RLN_STATUS_RX_LOLEN_AVAIL 0x60
175: #define RLN_STATUS_RX_LOLEN_ACCEPT 0x70
176: #define RLN_STATUS_RX_MASK 0x70
177:
178: #define rln_status_write(sc, value) \
179: _rln_register_write_1(sc, RLN_REG_STATUS, (value))
180: #define rln_status_set(sc, bits) \
181: rln_status_write(sc, (sc)->sc_status |= (bits))
182: #define rln_status_clear(sc, bits) \
183: rln_status_write(sc, (sc)->sc_status &= ~(bits))
184: #define _rln_status_setmask(sc, mask, bits) \
185: do { \
186: int _s; \
187: \
188: _s = splhigh(); \
189: (sc)->sc_status = ((sc)->sc_status & (mask)) | (bits); \
190: rln_status_write(sc, (sc)->sc_status); \
191: splx(_s); \
192: } while (0);
193: #define rln_status_rx_write(sc, state) \
194: _rln_status_setmask((sc), ~RLN_STATUS_RX_MASK, state)
195: #define rln_status_tx_write(sc, state) \
196: _rln_status_setmask((sc), ~RLN_STATUS_TX_MASK, state)
197: #define rln_status_read(sc) \
198: _rln_register_read_1(sc, RLN_REG_STATUS)
199: #define rln_status_rx_read(sc) \
200: (rln_status_read(sc) & ~RLN_STATUS_TX_MASK)
201: #define rln_status_tx_read(sc) \
202: (rln_status_read(sc) & ~RLN_STATUS_RX_MASK)
203:
204: static inline int
205: rln_status_rx_ready(sc)
206: struct rln_softc *sc;
207: {
208: u_int8_t status;
209:
210: status = rln_status_rx_read(sc);
211: return (status == RLN_STATUS_RX_LOLEN_AVAIL ||
212: status == RLN_STATUS_RX_HILEN_AVAIL ||
213: status == RLN_STATUS_RX_ERROR);
214: }
215:
216: #define rln_status_tx_int(sc) do { \
217: int _s = splhigh(); \
218: \
219: rln_control_clear(sc, RLN_CONTROL_TXINT); \
220: rln_control_set(sc, RLN_CONTROL_TXINT); \
221: splx(_s); \
222: } while (0)
223: #define rln_status_rx_int(sc) do { \
224: int _s = splhigh(); \
225: \
226: rln_control_clear(sc, RLN_CONTROL_RXINT); \
227: rln_control_set(sc, RLN_CONTROL_RXINT); \
228: splx(_s); \
229: } while (0)
230:
231: /* Control register. */
232: #define RLN_CONTROL_RXINT 0x01
233: #define RLN_CONTROL_TXINT 0x02
234: #define RLN_CONTROL_BIT2 0x04
235: #define RLN_CONTROL_BIT3 0x08
236: #define RLN_CONTROL_RESET 0x10
237: #define RLN_CONTROL_16BIT 0x20
238: #define RLN_CONTROL_MASK 0x3f
239:
240: #define rln_control_write(sc, value) \
241: _rln_register_write_1(sc, RLN_REG_CONTROL, \
242: (sc)->sc_control = (value))
243: #define rln_control_read(sc) \
244: _rln_register_read_1(sc, RLN_REG_CONTROL)
245: #define rln_control_set(sc, bits) \
246: rln_control_write(sc, (sc)->sc_control | (bits))
247: #define rln_control_clear(sc, bits) \
248: rln_control_write(sc, (sc)->sc_control & ~(bits))
249: #define rln_control_outofstandby(sc) do { \
250: rln_control_write(sc, (sc)->sc_control | RLN_CONTROL_RESET);\
251: DELAY(30000); \
252: rln_control_write(sc, (sc)->sc_control); \
253: } while (0)
254:
255: /* Interrupt selection register. */
256: #define RLN_INTSEL_IRQMASK 0x07
257: #define RLN_INTSEL_ENABLE 0x10
258: #define RLN_INTSEL_BIT7 0x80
259:
260: #define rln_intsel_disable(sc) do { \
261: int _s; \
262: \
263: _s = splhigh(); \
264: _rln_register_write_1(sc, RLN_REG_INTSEL, \
265: (sc)->sc_intsel &= ~RLN_INTSEL_ENABLE); \
266: splx(_s); \
267: } while (0)
268: #define rln_intsel_enable(sc) do { \
269: int _s; \
270: \
271: _s = splhigh(); \
272: _rln_register_write_1(sc, RLN_REG_INTSEL, \
273: (sc)->sc_intsel |= RLN_INTSEL_ENABLE); \
274: splx(_s); \
275: } while (0)
276: #define rln_intsel_write(sc, value) \
277: _rln_register_write_1(sc, RLN_REG_INTSEL, \
278: (sc)->sc_intsel |= (value))
279:
280: /* End of interrupt signal, used on some newer cards. */
281: #define rln_eoi(sc) \
282: (void) _rln_register_read_1(sc, RLN_REG_EOI)
283:
CVSweb