brintos

brintos / linux-shallow public Read only

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