Annotation of sys/dev/ic/rlnreg.h, Revision 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