linux/drivers/net/ethernet/realtek/atp.h
<<
>>
Prefs
   1/* Linux header file for the ATP pocket ethernet adapter. */
   2/* v1.09 8/9/2000 becker@scyld.com. */
   3
   4#include <linux/if_ether.h>
   5#include <linux/types.h>
   6
   7/* The header prepended to received packets. */
   8struct rx_header {
   9        ushort pad;             /* Pad. */
  10        ushort rx_count;
  11        ushort rx_status;       /* Unknown bit assignments :-<.  */
  12        ushort cur_addr;        /* Apparently the current buffer address(?) */
  13};
  14
  15#define PAR_DATA        0
  16#define PAR_STATUS      1
  17#define PAR_CONTROL 2
  18
  19#define Ctrl_LNibRead   0x08    /* LP_PSELECP */
  20#define Ctrl_HNibRead   0
  21#define Ctrl_LNibWrite  0x08    /* LP_PSELECP */
  22#define Ctrl_HNibWrite  0
  23#define Ctrl_SelData    0x04    /* LP_PINITP */
  24#define Ctrl_IRQEN      0x10    /* LP_PINTEN */
  25
  26#define EOW     0xE0
  27#define EOC     0xE0
  28#define WrAddr  0x40    /* Set address of EPLC read, write register. */
  29#define RdAddr  0xC0
  30#define HNib    0x10
  31
  32enum page0_regs {
  33        /* The first six registers hold
  34         * the ethernet physical station address.
  35         */
  36        PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5,
  37        TxCNT0 = 6, TxCNT1 = 7,         /* The transmit byte count. */
  38        TxSTAT = 8, RxSTAT = 9,         /* Tx and Rx status. */
  39        ISR = 10, IMR = 11,             /* Interrupt status and mask. */
  40        CMR1 = 12,                      /* Command register 1. */
  41        CMR2 = 13,                      /* Command register 2. */
  42        MODSEL = 14,            /* Mode select register. */
  43        MAR = 14,                       /* Memory address register (?). */
  44        CMR2_h = 0x1d,
  45};
  46
  47enum eepage_regs {
  48        PROM_CMD = 6,
  49        PROM_DATA = 7   /* Note that PROM_CMD is in the "high" bits. */
  50};
  51
  52#define ISR_TxOK        0x01
  53#define ISR_RxOK        0x04
  54#define ISR_TxErr       0x02
  55#define ISRh_RxErr      0x11    /* ISR, high nibble */
  56
  57#define CMR1h_MUX       0x08    /* Select printer multiplexor on 8012. */
  58#define CMR1h_RESET     0x04    /* Reset. */
  59#define CMR1h_RxENABLE  0x02    /* Rx unit enable.  */
  60#define CMR1h_TxENABLE  0x01    /* Tx unit enable.  */
  61#define CMR1h_TxRxOFF   0x00
  62#define CMR1_ReXmit     0x08    /* Trigger a retransmit. */
  63#define CMR1_Xmit       0x04    /* Trigger a transmit. */
  64#define CMR1_IRQ        0x02    /* Interrupt active. */
  65#define CMR1_BufEnb     0x01    /* Enable the buffer(?). */
  66#define CMR1_NextPkt    0x01    /* Enable the buffer(?). */
  67
  68#define CMR2_NULL       8
  69#define CMR2_IRQOUT     9
  70#define CMR2_RAMTEST    10
  71#define CMR2_EEPROM     12      /* Set to page 1, for reading the EEPROM. */
  72
  73#define CMR2h_OFF       0       /* No accept mode. */
  74#define CMR2h_Physical  1       /* Accept a physical address match only. */
  75#define CMR2h_Normal    2       /* Accept physical and broadcast address. */
  76#define CMR2h_PROMISC   3       /* Promiscuous mode. */
  77
  78/* An inline function used below: it differs from inb() by explicitly
  79 * return an unsigned char, saving a truncation.
  80 */
  81static inline unsigned char inbyte(unsigned short port)
  82{
  83        unsigned char _v;
  84
  85        __asm__ __volatile__ ("inb %w1,%b0" : "=a" (_v) : "d" (port));
  86        return _v;
  87}
  88
  89/* Read register OFFSET.
  90 * This command should always be terminated with read_end().
  91 */
  92static inline unsigned char read_nibble(short port, unsigned char offset)
  93{
  94        unsigned char retval;
  95
  96        outb(EOC+offset, port + PAR_DATA);
  97        outb(RdAddr+offset, port + PAR_DATA);
  98        inbyte(port + PAR_STATUS);      /* Settling time delay */
  99        retval = inbyte(port + PAR_STATUS);
 100        outb(EOC+offset, port + PAR_DATA);
 101
 102        return retval;
 103}
 104
 105/* Functions for bulk data read.  The interrupt line is always disabled. */
 106/* Get a byte using read mode 0, reading data from the control lines. */
 107static inline unsigned char read_byte_mode0(short ioaddr)
 108{
 109        unsigned char low_nib;
 110
 111        outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
 112        inbyte(ioaddr + PAR_STATUS);
 113        low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
 114        outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
 115        inbyte(ioaddr + PAR_STATUS);    /* Settling time delay -- needed!  */
 116        inbyte(ioaddr + PAR_STATUS);    /* Settling time delay -- needed!  */
 117        return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
 118}
 119
 120/* The same as read_byte_mode0(), but does multiple inb()s for stability. */
 121static inline unsigned char read_byte_mode2(short ioaddr)
 122{
 123        unsigned char low_nib;
 124
 125        outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
 126        inbyte(ioaddr + PAR_STATUS);
 127        low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
 128        outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
 129        inbyte(ioaddr + PAR_STATUS);    /* Settling time delay -- needed!  */
 130        return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
 131}
 132
 133/* Read a byte through the data register. */
 134static inline unsigned char read_byte_mode4(short ioaddr)
 135{
 136        unsigned char low_nib;
 137
 138        outb(RdAddr | MAR, ioaddr + PAR_DATA);
 139        low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
 140        outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
 141        return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
 142}
 143
 144/* Read a byte through the data register, double reading to allow settling. */
 145static inline unsigned char read_byte_mode6(short ioaddr)
 146{
 147        unsigned char low_nib;
 148
 149        outb(RdAddr | MAR, ioaddr + PAR_DATA);
 150        inbyte(ioaddr + PAR_STATUS);
 151        low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
 152        outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
 153        inbyte(ioaddr + PAR_STATUS);
 154        return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
 155}
 156
 157static inline void
 158write_reg(short port, unsigned char reg, unsigned char value)
 159{
 160        unsigned char outval;
 161
 162        outb(EOC | reg, port + PAR_DATA);
 163        outval = WrAddr | reg;
 164        outb(outval, port + PAR_DATA);
 165        outb(outval, port + PAR_DATA);  /* Double write for PS/2. */
 166
 167        outval &= 0xf0;
 168        outval |= value;
 169        outb(outval, port + PAR_DATA);
 170        outval &= 0x1f;
 171        outb(outval, port + PAR_DATA);
 172        outb(outval, port + PAR_DATA);
 173
 174        outb(EOC | outval, port + PAR_DATA);
 175}
 176
 177static inline void
 178write_reg_high(short port, unsigned char reg, unsigned char value)
 179{
 180        unsigned char outval = EOC | HNib | reg;
 181
 182        outb(outval, port + PAR_DATA);
 183        outval &= WrAddr | HNib | 0x0f;
 184        outb(outval, port + PAR_DATA);
 185        outb(outval, port + PAR_DATA);  /* Double write for PS/2. */
 186
 187        outval = WrAddr | HNib | value;
 188        outb(outval, port + PAR_DATA);
 189        outval &= HNib | 0x0f;          /* HNib | value */
 190        outb(outval, port + PAR_DATA);
 191        outb(outval, port + PAR_DATA);
 192
 193        outb(EOC | HNib | outval, port + PAR_DATA);
 194}
 195
 196/* Write a byte out using nibble mode.  The low nibble is written first. */
 197static inline void
 198write_reg_byte(short port, unsigned char reg, unsigned char value)
 199{
 200        unsigned char outval;
 201
 202        outb(EOC | reg, port + PAR_DATA); /* Reset the address register. */
 203        outval = WrAddr | reg;
 204        outb(outval, port + PAR_DATA);
 205        outb(outval, port + PAR_DATA);  /* Double write for PS/2. */
 206
 207        outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA);
 208        outb(value & 0x0f, port + PAR_DATA);
 209        value >>= 4;
 210        outb(value, port + PAR_DATA);
 211        outb(0x10 | value, port + PAR_DATA);
 212        outb(0x10 | value, port + PAR_DATA);
 213
 214        outb(EOC  | value, port + PAR_DATA); /* Reset the address register. */
 215}
 216
 217/* Bulk data writes to the packet buffer.  The interrupt line remains enabled.
 218 * The first, faster method uses only the dataport (data modes 0, 2 & 4).
 219 * The second (backup) method uses data and control regs (modes 1, 3 & 5).
 220 * It should only be needed when there is skew between the individual data
 221 * lines.
 222 */
 223static inline void write_byte_mode0(short ioaddr, unsigned char value)
 224{
 225        outb(value & 0x0f, ioaddr + PAR_DATA);
 226        outb((value>>4) | 0x10, ioaddr + PAR_DATA);
 227}
 228
 229static inline void write_byte_mode1(short ioaddr, unsigned char value)
 230{
 231        outb(value & 0x0f, ioaddr + PAR_DATA);
 232        outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL);
 233        outb((value>>4) | 0x10, ioaddr + PAR_DATA);
 234        outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL);
 235}
 236
 237/* Write 16bit VALUE to the packet buffer: the same as above just doubled. */
 238static inline void write_word_mode0(short ioaddr, unsigned short value)
 239{
 240        outb(value & 0x0f, ioaddr + PAR_DATA);
 241        value >>= 4;
 242        outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
 243        value >>= 4;
 244        outb(value & 0x0f, ioaddr + PAR_DATA);
 245        value >>= 4;
 246        outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
 247}
 248
 249/*  EEPROM_Ctrl bits. */
 250#define EE_SHIFT_CLK    0x04    /* EEPROM shift clock. */
 251#define EE_CS           0x02    /* EEPROM chip select. */
 252#define EE_CLK_HIGH     0x12
 253#define EE_CLK_LOW      0x16
 254#define EE_DATA_WRITE   0x01    /* EEPROM chip data in. */
 255#define EE_DATA_READ    0x08    /* EEPROM chip data out. */
 256
 257/* Delay between EEPROM clock transitions. */
 258#define eeprom_delay(ticks) \
 259do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; } } while (0)
 260
 261/* The EEPROM commands include the alway-set leading bit. */
 262#define EE_WRITE_CMD(offset)    (((5 << 6) + (offset)) << 17)
 263#define EE_READ(offset)         (((6 << 6) + (offset)) << 17)
 264#define EE_ERASE(offset)        (((7 << 6) + (offset)) << 17)
 265#define EE_CMD_SIZE     27      /* The command+address+data size. */
 266