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. */ |
| 291 | struct sbus_dev *myri_sdev; /* Our SBUS 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) */ |