home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / drivers / net / atp.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  8.6 KB  |  265 lines

  1. #include <linux/if_ether.h>
  2. #include <linux/types.h>
  3. #include <asm/io.h>
  4.  
  5. struct net_local {
  6. #ifdef __KERNEL__
  7.     struct enet_statistics stats;
  8. #endif
  9.     ushort saved_tx_size;
  10.     unsigned char
  11.     re_tx,            /* Number of packet retransmissions. */
  12.     tx_unit_busy,
  13.     addr_mode,        /* Current Rx filter e.g. promiscuous, etc. */
  14.     pac_cnt_in_tx_buf;
  15. };
  16.  
  17. struct rx_header {
  18.     ushort pad;            /* The first read is always corrupted. */
  19.     ushort rx_count;
  20.     ushort rx_status;        /* Unknown bit assignments :-<.  */
  21.     ushort cur_addr;        /* Apparently the current buffer address(?) */
  22. };
  23.  
  24. #define PAR_DATA    0
  25. #define PAR_STATUS    1
  26. #define PAR_CONTROL 2
  27.  
  28. #define Ctrl_LNibRead    0x08    /* LP_PSELECP */
  29. #define Ctrl_HNibRead    0
  30. #define Ctrl_LNibWrite    0x08    /* LP_PSELECP */
  31. #define Ctrl_HNibWrite    0
  32. #define Ctrl_SelData    0x04    /* LP_PINITP */
  33. #define Ctrl_IRQEN    0x10    /* LP_PINTEN */
  34.  
  35. #define EOW    0xE0
  36. #define EOC    0xE0
  37. #define WrAddr    0x40    /* Set address of EPLC read, write register. */
  38. #define RdAddr    0xC0
  39. #define HNib    0x10
  40.  
  41. enum page0_regs
  42. {
  43.     /* The first six registers hold the ethernet physical station address. */
  44.     PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5,
  45.     TxCNT0 = 6, TxCNT1 = 7,        /* The transmit byte count. */
  46.     TxSTAT = 8, RxSTAT = 9,        /* Tx and Rx status. */
  47.     ISR = 10, IMR = 11,            /* Interrupt status and mask. */
  48.     CMR1 = 12,                /* Command register 1. */
  49.     CMR2 = 13,                /* Command register 2. */
  50.     MAR = 14,                /* Memory address register. */
  51.     CMR2_h = 0x1d, };
  52.  
  53. enum eepage_regs
  54. { PROM_CMD = 6, PROM_DATA = 7 };    /* Note that PROM_CMD is in the "high" bits. */
  55.  
  56.  
  57. #define ISR_TxOK    0x01
  58. #define ISR_RxOK    0x04
  59. #define ISR_TxErr    0x02
  60. #define ISRh_RxErr    0x11    /* ISR, high nibble */
  61.  
  62. #define CMR1h_RESET    0x04    /* Reset. */
  63. #define CMR1h_RxENABLE    0x02    /* Rx unit enable.  */
  64. #define CMR1h_TxENABLE    0x01    /* Tx unit enable.  */
  65. #define CMR1h_TxRxOFF    0x00
  66. #define CMR1_ReXmit    0x08    /* Trigger a retransmit. */
  67. #define CMR1_Xmit    0x04    /* Trigger a transmit. */
  68. #define    CMR1_IRQ    0x02    /* Interrupt active. */
  69. #define    CMR1_BufEnb    0x01    /* Enable the buffer(?). */
  70. #define    CMR1_NextPkt    0x01    /* Enable the buffer(?). */
  71.  
  72. #define CMR2_NULL    8
  73. #define CMR2_IRQOUT    9
  74. #define CMR2_RAMTEST    10
  75. #define CMR2_EEPROM    12    /* Set to page 1, for reading the EEPROM. */
  76.  
  77. #define CMR2h_OFF    0    /* No accept mode. */
  78. #define CMR2h_Physical    1    /* Accept a physical address match only. */
  79. #define CMR2h_Normal    2    /* Accept physical and broadcast address. */
  80. #define CMR2h_PROMISC    3    /* Promiscuous mode. */
  81.  
  82. /* An inline function used below: it differs from inb() by explicitly return an unsigned
  83.    char, saving a truncation. */
  84. extern inline unsigned char inbyte(unsigned short port)
  85. {
  86.     unsigned char _v;
  87.     __asm__ __volatile__ ("inb %w1,%b0" :"=a" (_v):"d" (port));
  88.     return _v;
  89. }
  90.  
  91. /* Read register OFFSET.
  92.    This command should always be terminated with read_end(). */
  93. extern inline unsigned char read_nibble(short port, unsigned char offset)
  94. {
  95.     unsigned char retval;
  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. */
  107. extern 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. */
  121. extern 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. */
  134. extern 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. */
  145. extern 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.  
  157. extern inline void
  158. write_reg(short port, unsigned char reg, unsigned char value)
  159. {
  160.     unsigned char outval;
  161.     outb(EOC | reg, port + PAR_DATA);
  162.     outval = WrAddr | reg;
  163.     outb(outval, port + PAR_DATA);
  164.     outb(outval, port + PAR_DATA);    /* Double write for PS/2. */
  165.  
  166.     outval &= 0xf0;
  167.     outval |= value;
  168.     outb(outval, port + PAR_DATA);
  169.     outval &= 0x1f;
  170.     outb(outval, port + PAR_DATA);
  171.     outb(outval, port + PAR_DATA);
  172.  
  173.     outb(EOC | outval, port + PAR_DATA);
  174. }
  175.  
  176. extern inline void
  177. write_reg_high(short port, unsigned char reg, unsigned char value)
  178. {
  179.     unsigned char outval = EOC | HNib | reg;
  180.  
  181.     outb(outval, port + PAR_DATA);
  182.     outval &= WrAddr | HNib | 0x0f;
  183.     outb(outval, port + PAR_DATA);
  184.     outb(outval, port + PAR_DATA);    /* Double write for PS/2. */
  185.  
  186.     outval = WrAddr | HNib | value;
  187.     outb(outval, port + PAR_DATA);
  188.     outval &= HNib | 0x0f;        /* HNib | value */
  189.     outb(outval, port + PAR_DATA);
  190.     outb(outval, port + PAR_DATA);
  191.  
  192.     outb(EOC | HNib | outval, port + PAR_DATA);
  193. }
  194.  
  195. /* Write a byte out using nibble mode.  The low nibble is written first. */
  196. extern inline void
  197. write_reg_byte(short port, unsigned char reg, unsigned char value)
  198. {
  199.     unsigned char outval;
  200.     outb(EOC | reg, port + PAR_DATA);     /* Reset the address register. */
  201.     outval = WrAddr | reg;
  202.     outb(outval, port + PAR_DATA);
  203.     outb(outval, port + PAR_DATA);    /* Double write for PS/2. */
  204.  
  205.     outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA);
  206.     outb(value & 0x0f, port + PAR_DATA);
  207.     value >>= 4;
  208.     outb(value, port + PAR_DATA);
  209.     outb(0x10 | value, port + PAR_DATA);
  210.     outb(0x10 | value, port + PAR_DATA);
  211.  
  212.     outb(EOC  | value, port + PAR_DATA);     /* Reset the address register. */
  213. }
  214.  
  215. /*
  216.  * Bulk data writes to the packet buffer.  The interrupt line remains enabled.
  217.  * The first, faster method uses only the dataport (data modes 0, 2 & 4).
  218.  * The second (backup) method uses data and control regs (modes 1, 3 & 5).
  219.  * It should only be needed when there is skew between the individual data
  220.  * lines.
  221.  */
  222. extern inline void write_byte_mode0(short ioaddr, unsigned char value)
  223. {
  224.     outb(value & 0x0f, ioaddr + PAR_DATA);
  225.     outb((value>>4) | 0x10, ioaddr + PAR_DATA);
  226. }
  227.  
  228. extern inline void write_byte_mode1(short ioaddr, unsigned char value)
  229. {
  230.     outb(value & 0x0f, ioaddr + PAR_DATA);
  231.     outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL);
  232.     outb((value>>4) | 0x10, ioaddr + PAR_DATA);
  233.     outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL);
  234. }
  235.  
  236. /* Write 16bit VALUE to the packet buffer: the same as above just doubled. */
  237. extern inline void write_word_mode0(short ioaddr, unsigned short value)
  238. {
  239.     outb(value & 0x0f, ioaddr + PAR_DATA);
  240.     value >>= 4;
  241.     outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
  242.     value >>= 4;
  243.     outb(value & 0x0f, ioaddr + PAR_DATA);
  244.     value >>= 4;
  245.     outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
  246. }
  247.  
  248. /*  EEPROM_Ctrl bits. */
  249. #define EE_SHIFT_CLK    0x04    /* EEPROM shift clock. */
  250. #define EE_CS        0x02    /* EEPROM chip select. */
  251. #define EE_CLK_HIGH    0x12
  252. #define EE_CLK_LOW    0x16
  253. #define EE_DATA_WRITE    0x01    /* EEPROM chip data in. */
  254. #define EE_DATA_READ    0x08    /* EEPROM chip data out. */
  255.  
  256. /* Delay between EEPROM clock transitions. */
  257. #define eeprom_delay(ticks) \
  258. do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
  259.  
  260. /* The EEPROM commands include the alway-set leading bit. */
  261. #define EE_WRITE_CMD(offset)    (((5 << 6) + (offset)) << 17)
  262. #define EE_READ(offset)     (((6 << 6) + (offset)) << 17)
  263. #define EE_ERASE(offset)    (((7 << 6) + (offset)) << 17)
  264. #define EE_CMD_SIZE    27    /* The command+address+data size. */
  265.