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