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