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