| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* myri_sbus.h: Defines for MyriCOM MyriNET SBUS card driver. | 
|  | 2 | * | 
|  | 3 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | 
|  | 4 | */ | 
|  | 5 |  | 
|  | 6 | #ifndef _MYRI_SBUS_H | 
|  | 7 | #define _MYRI_SBUS_H | 
|  | 8 |  | 
|  | 9 | /* LANAI Registers */ | 
|  | 10 | #define LANAI_IPF0	0x00UL		/* Context zero state registers.*/ | 
|  | 11 | #define LANAI_CUR0	0x04UL | 
|  | 12 | #define LANAI_PREV0	0x08UL | 
|  | 13 | #define LANAI_DATA0	0x0cUL | 
|  | 14 | #define LANAI_DPF0	0x10UL | 
|  | 15 | #define LANAI_IPF1	0x14UL		/* Context one state registers.	*/ | 
|  | 16 | #define LANAI_CUR1	0x18UL | 
|  | 17 | #define LANAI_PREV1	0x1cUL | 
|  | 18 | #define LANAI_DATA1	0x20UL | 
|  | 19 | #define LANAI_DPF1	0x24UL | 
|  | 20 | #define LANAI_ISTAT	0x28UL		/* Interrupt status.		*/ | 
|  | 21 | #define LANAI_EIMASK	0x2cUL		/* External IRQ mask.		*/ | 
|  | 22 | #define LANAI_ITIMER	0x30UL		/* IRQ timer.			*/ | 
|  | 23 | #define LANAI_RTC	0x34UL		/* Real Time Clock		*/ | 
|  | 24 | #define LANAI_CSUM	0x38UL		/* Checksum.			*/ | 
|  | 25 | #define LANAI_DMAXADDR	0x3cUL		/* SBUS DMA external address.	*/ | 
|  | 26 | #define LANAI_DMALADDR	0x40UL		/* SBUS DMA local address.	*/ | 
|  | 27 | #define LANAI_DMACTR	0x44UL		/* SBUS DMA counter.		*/ | 
|  | 28 | #define LANAI_RXDMAPTR	0x48UL		/* Receive DMA pointer.		*/ | 
|  | 29 | #define LANAI_RXDMALIM	0x4cUL		/* Receive DMA limit.		*/ | 
|  | 30 | #define LANAI_TXDMAPTR	0x50UL		/* Transmit DMA pointer.	*/ | 
|  | 31 | #define LANAI_TXDMALIM	0x54UL		/* Transmit DMA limit.		*/ | 
|  | 32 | #define LANAI_TXDMALIMT	0x58UL		/* Transmit DMA limit w/tail.	*/ | 
|  | 33 | /* 0x5cUL, reserved */ | 
|  | 34 | #define LANAI_RBYTE	0x60UL		/* Receive byte.		*/ | 
|  | 35 | /* 0x64-->0x6c, reserved */ | 
|  | 36 | #define LANAI_RHALF	0x70UL		/* Receive half-word.		*/ | 
|  | 37 | /* 0x72UL, reserved */ | 
|  | 38 | #define LANAI_RWORD	0x74UL		/* Receive word.		*/ | 
|  | 39 | #define LANAI_SALIGN	0x78UL		/* Send align.			*/ | 
|  | 40 | #define LANAI_SBYTE	0x7cUL		/* SingleSend send-byte.	*/ | 
|  | 41 | #define LANAI_SHALF	0x80UL		/* SingleSend send-halfword.	*/ | 
|  | 42 | #define LANAI_SWORD	0x84UL		/* SingleSend send-word.	*/ | 
|  | 43 | #define LANAI_SSENDT	0x88UL		/* SingleSend special.		*/ | 
|  | 44 | #define LANAI_DMADIR	0x8cUL		/* DMA direction.		*/ | 
|  | 45 | #define LANAI_DMASTAT	0x90UL		/* DMA status.			*/ | 
|  | 46 | #define LANAI_TIMEO	0x94UL		/* Timeout register.		*/ | 
|  | 47 | #define LANAI_MYRINET	0x98UL		/* XXX MAGIC myricom thing	*/ | 
|  | 48 | #define LANAI_HWDEBUG	0x9cUL		/* Hardware debugging reg.	*/ | 
|  | 49 | #define LANAI_LEDS	0xa0UL		/* LED control.			*/ | 
|  | 50 | #define LANAI_VERS	0xa4UL		/* Version register.		*/ | 
|  | 51 | #define LANAI_LINKON	0xa8UL		/* Link activation reg.		*/ | 
|  | 52 | /* 0xac-->0x104, reserved */ | 
|  | 53 | #define LANAI_CVAL	0x108UL		/* Clock value register.	*/ | 
|  | 54 | #define LANAI_REG_SIZE	0x10cUL | 
|  | 55 |  | 
|  | 56 | /* Interrupt status bits. */ | 
|  | 57 | #define ISTAT_DEBUG	0x80000000 | 
|  | 58 | #define ISTAT_HOST	0x40000000 | 
|  | 59 | #define ISTAT_LAN7	0x00800000 | 
|  | 60 | #define ISTAT_LAN6	0x00400000 | 
|  | 61 | #define ISTAT_LAN5	0x00200000 | 
|  | 62 | #define ISTAT_LAN4	0x00100000 | 
|  | 63 | #define ISTAT_LAN3	0x00080000 | 
|  | 64 | #define ISTAT_LAN2	0x00040000 | 
|  | 65 | #define ISTAT_LAN1	0x00020000 | 
|  | 66 | #define ISTAT_LAN0	0x00010000 | 
|  | 67 | #define ISTAT_WRDY	0x00008000 | 
|  | 68 | #define ISTAT_HRDY	0x00004000 | 
|  | 69 | #define ISTAT_SRDY	0x00002000 | 
|  | 70 | #define ISTAT_LINK	0x00001000 | 
|  | 71 | #define ISTAT_FRES	0x00000800 | 
|  | 72 | #define ISTAT_NRES	0x00000800 | 
|  | 73 | #define ISTAT_WAKE	0x00000400 | 
|  | 74 | #define ISTAT_OB2	0x00000200 | 
|  | 75 | #define ISTAT_OB1	0x00000100 | 
|  | 76 | #define ISTAT_TAIL	0x00000080 | 
|  | 77 | #define ISTAT_WDOG	0x00000040 | 
|  | 78 | #define ISTAT_TIME	0x00000020 | 
|  | 79 | #define ISTAT_DMA	0x00000010 | 
|  | 80 | #define ISTAT_SEND	0x00000008 | 
|  | 81 | #define ISTAT_BUF	0x00000004 | 
|  | 82 | #define ISTAT_RECV	0x00000002 | 
|  | 83 | #define ISTAT_BRDY	0x00000001 | 
|  | 84 |  | 
|  | 85 | /* MYRI Registers */ | 
|  | 86 | #define MYRI_RESETOFF	0x00UL | 
|  | 87 | #define MYRI_RESETON	0x04UL | 
|  | 88 | #define MYRI_IRQOFF	0x08UL | 
|  | 89 | #define MYRI_IRQON	0x0cUL | 
|  | 90 | #define MYRI_WAKEUPOFF	0x10UL | 
|  | 91 | #define MYRI_WAKEUPON	0x14UL | 
|  | 92 | #define MYRI_IRQREAD	0x18UL | 
|  | 93 | /* 0x1c-->0x3ffc, reserved */ | 
|  | 94 | #define MYRI_LOCALMEM	0x4000UL | 
|  | 95 | #define MYRI_REG_SIZE	0x25000UL | 
|  | 96 |  | 
|  | 97 | /* Shared memory interrupt mask. */ | 
|  | 98 | #define SHMEM_IMASK_RX		0x00000002 | 
|  | 99 | #define SHMEM_IMASK_TX		0x00000001 | 
|  | 100 |  | 
|  | 101 | /* Just to make things readable. */ | 
|  | 102 | #define KERNEL_CHANNEL		0 | 
|  | 103 |  | 
|  | 104 | /* The size of this must be >= 129 bytes. */ | 
|  | 105 | struct myri_eeprom { | 
|  | 106 | unsigned int		cval; | 
|  | 107 | unsigned short		cpuvers; | 
|  | 108 | unsigned char		id[6]; | 
|  | 109 | unsigned int		ramsz; | 
|  | 110 | unsigned char		fvers[32]; | 
|  | 111 | unsigned char		mvers[16]; | 
|  | 112 | unsigned short		dlval; | 
|  | 113 | unsigned short		brd_type; | 
|  | 114 | unsigned short		bus_type; | 
|  | 115 | unsigned short		prod_code; | 
|  | 116 | unsigned int		serial_num; | 
|  | 117 | unsigned short		_reserved[24]; | 
|  | 118 | unsigned int		_unused[2]; | 
|  | 119 | }; | 
|  | 120 |  | 
|  | 121 | /* EEPROM bus types, only SBUS is valid in this driver. */ | 
|  | 122 | #define BUS_TYPE_SBUS		1 | 
|  | 123 |  | 
|  | 124 | /* EEPROM CPU revisions. */ | 
|  | 125 | #define CPUVERS_2_3		0x0203 | 
|  | 126 | #define CPUVERS_3_0		0x0300 | 
|  | 127 | #define CPUVERS_3_1		0x0301 | 
|  | 128 | #define CPUVERS_3_2		0x0302 | 
|  | 129 | #define CPUVERS_4_0		0x0400 | 
|  | 130 | #define CPUVERS_4_1		0x0401 | 
|  | 131 | #define CPUVERS_4_2		0x0402 | 
|  | 132 | #define CPUVERS_5_0		0x0500 | 
|  | 133 |  | 
|  | 134 | /* MYRI Control Registers */ | 
|  | 135 | #define MYRICTRL_CTRL		0x00UL | 
|  | 136 | #define MYRICTRL_IRQLVL		0x02UL | 
|  | 137 | #define MYRICTRL_REG_SIZE	0x04UL | 
|  | 138 |  | 
|  | 139 | /* Global control register defines. */ | 
|  | 140 | #define CONTROL_ROFF		0x8000	/* Reset OFF.		*/ | 
|  | 141 | #define CONTROL_RON		0x4000	/* Reset ON.		*/ | 
|  | 142 | #define CONTROL_EIRQ		0x2000	/* Enable IRQ's.	*/ | 
|  | 143 | #define CONTROL_DIRQ		0x1000	/* Disable IRQ's.	*/ | 
|  | 144 | #define CONTROL_WON		0x0800	/* Wake-up ON.		*/ | 
|  | 145 |  | 
|  | 146 | #define MYRI_SCATTER_ENTRIES	8 | 
|  | 147 | #define MYRI_GATHER_ENTRIES	16 | 
|  | 148 |  | 
|  | 149 | struct myri_sglist { | 
|  | 150 | u32 addr; | 
|  | 151 | u32 len; | 
|  | 152 | }; | 
|  | 153 |  | 
|  | 154 | struct myri_rxd { | 
|  | 155 | struct myri_sglist myri_scatters[MYRI_SCATTER_ENTRIES];	/* DMA scatter list.*/ | 
|  | 156 | u32 csum;	/* HW computed checksum.    */ | 
|  | 157 | u32 ctx; | 
|  | 158 | u32 num_sg;	/* Total scatter entries.   */ | 
|  | 159 | }; | 
|  | 160 |  | 
|  | 161 | struct myri_txd { | 
|  | 162 | struct myri_sglist myri_gathers[MYRI_GATHER_ENTRIES]; /* DMA scatter list.  */ | 
|  | 163 | u32 num_sg;	/* Total scatter entries.   */ | 
|  | 164 | u16 addr[4];	/* XXX address              */ | 
|  | 165 | u32 chan; | 
|  | 166 | u32 len;	/* Total length of packet.  */ | 
|  | 167 | u32 csum_off;	/* Where data to csum is.   */ | 
|  | 168 | u32 csum_field;	/* Where csum goes in pkt.  */ | 
|  | 169 | }; | 
|  | 170 |  | 
|  | 171 | #define MYRINET_MTU        8432 | 
|  | 172 | #define RX_ALLOC_SIZE      8448 | 
|  | 173 | #define MYRI_PAD_LEN       2 | 
|  | 174 | #define RX_COPY_THRESHOLD  256 | 
|  | 175 |  | 
|  | 176 | /* These numbers are cast in stone, new firmware is needed if | 
|  | 177 | * you want to change them. | 
|  | 178 | */ | 
|  | 179 | #define TX_RING_MAXSIZE    16 | 
|  | 180 | #define RX_RING_MAXSIZE    16 | 
|  | 181 |  | 
|  | 182 | #define TX_RING_SIZE       16 | 
|  | 183 | #define RX_RING_SIZE       16 | 
|  | 184 |  | 
|  | 185 | /* GRRR... */ | 
|  | 186 | static __inline__ int NEXT_RX(int num) | 
|  | 187 | { | 
|  | 188 | /* XXX >=??? */ | 
|  | 189 | if(++num > RX_RING_SIZE) | 
|  | 190 | num = 0; | 
|  | 191 | return num; | 
|  | 192 | } | 
|  | 193 |  | 
|  | 194 | static __inline__ int PREV_RX(int num) | 
|  | 195 | { | 
|  | 196 | if(--num < 0) | 
|  | 197 | num = RX_RING_SIZE; | 
|  | 198 | return num; | 
|  | 199 | } | 
|  | 200 |  | 
|  | 201 | #define NEXT_TX(num)	(((num) + 1) & (TX_RING_SIZE - 1)) | 
|  | 202 | #define PREV_TX(num)	(((num) - 1) & (TX_RING_SIZE - 1)) | 
|  | 203 |  | 
|  | 204 | #define TX_BUFFS_AVAIL(head, tail)		\ | 
|  | 205 | ((head) <= (tail) ?			\ | 
|  | 206 | (head) + (TX_RING_SIZE - 1) - (tail) :	\ | 
|  | 207 | (head) - (tail) - 1) | 
|  | 208 |  | 
|  | 209 | struct sendq { | 
|  | 210 | u32	tail; | 
|  | 211 | u32	head; | 
|  | 212 | u32	hdebug; | 
|  | 213 | u32	mdebug; | 
|  | 214 | struct myri_txd	myri_txd[TX_RING_MAXSIZE]; | 
|  | 215 | }; | 
|  | 216 |  | 
|  | 217 | struct recvq { | 
|  | 218 | u32	head; | 
|  | 219 | u32	tail; | 
|  | 220 | u32	hdebug; | 
|  | 221 | u32	mdebug; | 
|  | 222 | struct myri_rxd	myri_rxd[RX_RING_MAXSIZE + 1]; | 
|  | 223 | }; | 
|  | 224 |  | 
|  | 225 | #define MYRI_MLIST_SIZE 8 | 
|  | 226 |  | 
|  | 227 | struct mclist { | 
|  | 228 | u32 maxlen; | 
|  | 229 | u32 len; | 
|  | 230 | u32 cache; | 
|  | 231 | struct pair { | 
|  | 232 | u8 addr[8]; | 
|  | 233 | u32 val; | 
|  | 234 | } mc_pairs[MYRI_MLIST_SIZE]; | 
|  | 235 | u8 bcast_addr[8]; | 
|  | 236 | }; | 
|  | 237 |  | 
|  | 238 | struct myri_channel { | 
|  | 239 | u32		state;		/* State of the channel.	*/ | 
|  | 240 | u32		busy;		/* Channel is busy.		*/ | 
|  | 241 | struct sendq	sendq;		/* Device tx queue.		*/ | 
|  | 242 | struct recvq	recvq;		/* Device rx queue.		*/ | 
|  | 243 | struct recvq	recvqa;		/* Device rx queue acked.	*/ | 
|  | 244 | u32		rbytes;		/* Receive bytes.		*/ | 
|  | 245 | u32		sbytes;		/* Send bytes.			*/ | 
|  | 246 | u32		rmsgs;		/* Receive messages.		*/ | 
|  | 247 | u32		smsgs;		/* Send messages.		*/ | 
|  | 248 | struct mclist	mclist;		/* Device multicast list.	*/ | 
|  | 249 | }; | 
|  | 250 |  | 
|  | 251 | /* Values for per-channel state. */ | 
|  | 252 | #define STATE_WFH	0		/* Waiting for HOST.		*/ | 
|  | 253 | #define STATE_WFN	1		/* Waiting for NET.		*/ | 
|  | 254 | #define STATE_READY	2		/* Ready.			*/ | 
|  | 255 |  | 
|  | 256 | struct myri_shmem { | 
|  | 257 | u8	addr[8];		/* Board's address.		*/ | 
|  | 258 | u32	nchan;			/* Number of channels.		*/ | 
|  | 259 | u32	burst;			/* SBUS dma burst enable.	*/ | 
|  | 260 | u32	shakedown;		/* DarkkkkStarrr Crashesss...	*/ | 
|  | 261 | u32	send;			/* Send wanted.			*/ | 
|  | 262 | u32	imask;			/* Interrupt enable mask.	*/ | 
|  | 263 | u32	mlevel;			/* Map level.			*/ | 
|  | 264 | u32	debug[4];		/* Misc. debug areas.		*/ | 
|  | 265 | struct myri_channel channel;	/* Only one channel on a host.	*/ | 
|  | 266 | }; | 
|  | 267 |  | 
|  | 268 | struct myri_eth { | 
|  | 269 | /* These are frequently accessed, keep together | 
|  | 270 | * to obtain good cache hit rates. | 
|  | 271 | */ | 
|  | 272 | spinlock_t			irq_lock; | 
|  | 273 | struct myri_shmem __iomem	*shmem;		/* Shared data structures.    */ | 
|  | 274 | void __iomem			*cregs;		/* Control register space.    */ | 
|  | 275 | struct recvq __iomem		*rqack;		/* Where we ack rx's.         */ | 
|  | 276 | struct recvq __iomem		*rq;		/* Where we put buffers.      */ | 
|  | 277 | struct sendq __iomem		*sq;		/* Where we stuff tx's.       */ | 
|  | 278 | struct net_device		*dev;		/* Linux/NET dev struct.      */ | 
|  | 279 | int				tx_old;		/* To speed up tx cleaning.   */ | 
|  | 280 | void __iomem			*lregs;		/* Quick ptr to LANAI regs.   */ | 
|  | 281 | struct sk_buff	       *rx_skbs[RX_RING_SIZE+1];/* RX skb's                   */ | 
|  | 282 | struct sk_buff	       *tx_skbs[TX_RING_SIZE];  /* TX skb's                   */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 283 |  | 
|  | 284 | /* These are less frequently accessed. */ | 
|  | 285 | void __iomem			*regs;          /* MyriCOM register space.    */ | 
|  | 286 | void __iomem			*lanai;		/* View 2 of register space.  */ | 
|  | 287 | unsigned int			myri_bursts;	/* SBUS bursts.               */ | 
|  | 288 | struct myri_eeprom		eeprom;		/* Local copy of EEPROM.      */ | 
|  | 289 | unsigned int			reg_size;	/* Size of register space.    */ | 
|  | 290 | unsigned int			shmem_base;	/* Offset to shared ram.      */ | 
| David S. Miller | 9e6b6e7 | 2008-08-26 23:36:58 -0700 | [diff] [blame] | 291 | struct of_device		*myri_op;	/* Our OF device struct.    */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 292 | }; | 
|  | 293 |  | 
|  | 294 | /* We use this to acquire receive skb's that we can DMA directly into. */ | 
|  | 295 | #define ALIGNED_RX_SKB_ADDR(addr) \ | 
|  | 296 | ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr)) | 
| Al Viro | 9e24974 | 2005-10-21 03:22:29 -0400 | [diff] [blame] | 297 | static inline struct sk_buff *myri_alloc_skb(unsigned int length, gfp_t gfp_flags) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 298 | { | 
|  | 299 | struct sk_buff *skb; | 
|  | 300 |  | 
|  | 301 | skb = alloc_skb(length + 64, gfp_flags); | 
|  | 302 | if(skb) { | 
|  | 303 | int offset = ALIGNED_RX_SKB_ADDR(skb->data); | 
|  | 304 |  | 
|  | 305 | if(offset) | 
|  | 306 | skb_reserve(skb, offset); | 
|  | 307 | } | 
|  | 308 | return skb; | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | #endif /* !(_MYRI_SBUS_H) */ |