ia64/linux-2.6.18-xen.hg

view drivers/net/sun3_82586.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * Sun3 i82586 Ethernet driver
3 *
4 * Cloned from ni52.c for the Sun3 by Sam Creasey (sammy@sammy.net)
5 *
6 * Original copyright follows:
7 * --------------------------
8 *
9 * net-3-driver for the NI5210 card (i82586 Ethernet chip)
10 *
11 * This is an extension to the Linux operating system, and is covered by the
12 * same Gnu Public License that covers that work.
13 *
14 * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later)
15 * Copyrights (c) 1994,1995,1996 by M.Hipp (hippm@informatik.uni-tuebingen.de)
16 * --------------------------
17 *
18 * Consult ni52.c for further notes from the original driver.
19 *
20 * This incarnation currently supports the OBIO version of the i82586 chip
21 * used in certain sun3 models. It should be fairly doable to expand this
22 * to support VME if I should every acquire such a board.
23 *
24 */
26 static int debuglevel = 0; /* debug-printk 0: off 1: a few 2: more */
27 static int automatic_resume = 0; /* experimental .. better should be zero */
28 static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */
29 static int fifo=0x8; /* don't change */
31 /* #define REALLY_SLOW_IO */
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/string.h>
36 #include <linux/errno.h>
37 #include <linux/ioport.h>
38 #include <linux/slab.h>
39 #include <linux/interrupt.h>
40 #include <linux/delay.h>
41 #include <linux/init.h>
42 #include <linux/bitops.h>
43 #include <asm/io.h>
44 #include <asm/idprom.h>
45 #include <asm/machines.h>
46 #include <asm/sun3mmu.h>
47 #include <asm/dvma.h>
48 #include <asm/byteorder.h>
50 #include <linux/netdevice.h>
51 #include <linux/etherdevice.h>
52 #include <linux/skbuff.h>
54 #include "sun3_82586.h"
56 #define DRV_NAME "sun3_82586"
58 #define DEBUG /* debug on */
59 #define SYSBUSVAL 0 /* 16 Bit */
60 #define SUN3_82586_TOTAL_SIZE PAGE_SIZE
62 #define sun3_attn586() {*(volatile unsigned char *)(dev->base_addr) |= IEOB_ATTEN; *(volatile unsigned char *)(dev->base_addr) &= ~IEOB_ATTEN;}
63 #define sun3_reset586() {*(volatile unsigned char *)(dev->base_addr) = 0; udelay(100); *(volatile unsigned char *)(dev->base_addr) = IEOB_NORSET;}
64 #define sun3_disint() {*(volatile unsigned char *)(dev->base_addr) &= ~IEOB_IENAB;}
65 #define sun3_enaint() {*(volatile unsigned char *)(dev->base_addr) |= IEOB_IENAB;}
66 #define sun3_active() {*(volatile unsigned char *)(dev->base_addr) |= (IEOB_IENAB|IEOB_ONAIR|IEOB_NORSET);}
68 #define make32(ptr16) (p->memtop + (swab16((unsigned short) (ptr16))) )
69 #define make24(ptr32) (char *)swab32(( ((unsigned long) (ptr32)) - p->base))
70 #define make16(ptr32) (swab16((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop )))
72 /******************* how to calculate the buffers *****************************
74 * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
75 * --------------- in a different (more stable?) mode. Only in this mode it's
76 * possible to configure the driver with 'NO_NOPCOMMANDS'
78 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
79 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
80 sizeof(rfd) = 24; sizeof(rbd) = 12;
81 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
82 sizeof(nop_cmd) = 8;
84 * if you don't know the driver, better do not change these values: */
86 #define RECV_BUFF_SIZE 1536 /* slightly oversized */
87 #define XMIT_BUFF_SIZE 1536 /* slightly oversized */
88 #define NUM_XMIT_BUFFS 1 /* config for 32K shmem */
89 #define NUM_RECV_BUFFS_8 4 /* config for 32K shared mem */
90 #define NUM_RECV_BUFFS_16 9 /* config for 32K shared mem */
91 #define NUM_RECV_BUFFS_32 16 /* config for 32K shared mem */
92 #define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
94 /**************************************************************************/
96 /* different DELAYs */
97 #define DELAY(x) mdelay(32 * x);
98 #define DELAY_16(); { udelay(16); }
99 #define DELAY_18(); { udelay(4); }
101 /* wait for command with timeout: */
102 #define WAIT_4_SCB_CMD() \
103 { int i; \
104 for(i=0;i<16384;i++) { \
105 if(!p->scb->cmd_cuc) break; \
106 DELAY_18(); \
107 if(i == 16383) { \
108 printk("%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_cuc,p->scb->cus); \
109 if(!p->reseted) { p->reseted = 1; sun3_reset586(); } } } }
111 #define WAIT_4_SCB_CMD_RUC() { int i; \
112 for(i=0;i<16384;i++) { \
113 if(!p->scb->cmd_ruc) break; \
114 DELAY_18(); \
115 if(i == 16383) { \
116 printk("%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_ruc,p->scb->rus); \
117 if(!p->reseted) { p->reseted = 1; sun3_reset586(); } } } }
119 #define WAIT_4_STAT_COMPL(addr) { int i; \
120 for(i=0;i<32767;i++) { \
121 if(swab16((addr)->cmd_status) & STAT_COMPL) break; \
122 DELAY_16(); DELAY_16(); } }
124 static int sun3_82586_probe1(struct net_device *dev,int ioaddr);
125 static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr);
126 static int sun3_82586_open(struct net_device *dev);
127 static int sun3_82586_close(struct net_device *dev);
128 static int sun3_82586_send_packet(struct sk_buff *,struct net_device *);
129 static struct net_device_stats *sun3_82586_get_stats(struct net_device *dev);
130 static void set_multicast_list(struct net_device *dev);
131 static void sun3_82586_timeout(struct net_device *dev);
132 #if 0
133 static void sun3_82586_dump(struct net_device *,void *);
134 #endif
136 /* helper-functions */
137 static int init586(struct net_device *dev);
138 static int check586(struct net_device *dev,char *where,unsigned size);
139 static void alloc586(struct net_device *dev);
140 static void startrecv586(struct net_device *dev);
141 static void *alloc_rfa(struct net_device *dev,void *ptr);
142 static void sun3_82586_rcv_int(struct net_device *dev);
143 static void sun3_82586_xmt_int(struct net_device *dev);
144 static void sun3_82586_rnr_int(struct net_device *dev);
146 struct priv
147 {
148 struct net_device_stats stats;
149 unsigned long base;
150 char *memtop;
151 long int lock;
152 int reseted;
153 volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first;
154 volatile struct scp_struct *scp; /* volatile is important */
155 volatile struct iscp_struct *iscp; /* volatile is important */
156 volatile struct scb_struct *scb; /* volatile is important */
157 volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
158 volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
159 #if (NUM_XMIT_BUFFS == 1)
160 volatile struct nop_cmd_struct *nop_cmds[2];
161 #else
162 volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
163 #endif
164 volatile int nop_point,num_recv_buffs;
165 volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
166 volatile int xmit_count,xmit_last;
167 };
169 /**********************************************
170 * close device
171 */
172 static int sun3_82586_close(struct net_device *dev)
173 {
174 free_irq(dev->irq, dev);
176 sun3_reset586(); /* the hard way to stop the receiver */
178 netif_stop_queue(dev);
180 return 0;
181 }
183 /**********************************************
184 * open device
185 */
186 static int sun3_82586_open(struct net_device *dev)
187 {
188 int ret;
190 sun3_disint();
191 alloc586(dev);
192 init586(dev);
193 startrecv586(dev);
194 sun3_enaint();
196 ret = request_irq(dev->irq, &sun3_82586_interrupt,0,dev->name,dev);
197 if (ret)
198 {
199 sun3_reset586();
200 return ret;
201 }
203 netif_start_queue(dev);
205 return 0; /* most done by init */
206 }
208 /**********************************************
209 * Check to see if there's an 82586 out there.
210 */
211 static int check586(struct net_device *dev,char *where,unsigned size)
212 {
213 struct priv pb;
214 struct priv *p = /* (struct priv *) dev->priv*/ &pb;
215 char *iscp_addr;
216 int i;
218 p->base = (unsigned long) dvma_btov(0);
219 p->memtop = (char *)dvma_btov((unsigned long)where);
220 p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
221 memset((char *)p->scp,0, sizeof(struct scp_struct));
222 for(i=0;i<sizeof(struct scp_struct);i++) /* memory was writeable? */
223 if(((char *)p->scp)[i])
224 return 0;
225 p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
226 if(p->scp->sysbus != SYSBUSVAL)
227 return 0;
229 iscp_addr = (char *)dvma_btov((unsigned long)where);
231 p->iscp = (struct iscp_struct *) iscp_addr;
232 memset((char *)p->iscp,0, sizeof(struct iscp_struct));
234 p->scp->iscp = make24(p->iscp);
235 p->iscp->busy = 1;
237 sun3_reset586();
238 sun3_attn586();
239 DELAY(1); /* wait a while... */
241 if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
242 return 0;
244 return 1;
245 }
247 /******************************************************************
248 * set iscp at the right place, called by sun3_82586_probe1 and open586.
249 */
250 static void alloc586(struct net_device *dev)
251 {
252 struct priv *p = (struct priv *) dev->priv;
254 sun3_reset586();
255 DELAY(1);
257 p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
258 p->iscp = (struct iscp_struct *) dvma_btov(dev->mem_start);
259 p->scb = (struct scb_struct *) ((char *)p->iscp + sizeof(struct iscp_struct));
261 memset((char *) p->iscp,0,sizeof(struct iscp_struct));
262 memset((char *) p->scp ,0,sizeof(struct scp_struct));
264 p->scp->iscp = make24(p->iscp);
265 p->scp->sysbus = SYSBUSVAL;
266 p->iscp->scb_offset = make16(p->scb);
267 p->iscp->scb_base = make24(dvma_btov(dev->mem_start));
269 p->iscp->busy = 1;
270 sun3_reset586();
271 sun3_attn586();
273 DELAY(1);
275 if(p->iscp->busy)
276 printk("%s: Init-Problems (alloc).\n",dev->name);
278 p->reseted = 0;
280 memset((char *)p->scb,0,sizeof(struct scb_struct));
281 }
283 struct net_device * __init sun3_82586_probe(int unit)
284 {
285 struct net_device *dev;
286 unsigned long ioaddr;
287 static int found = 0;
288 int err = -ENOMEM;
290 /* check that this machine has an onboard 82586 */
291 switch(idprom->id_machtype) {
292 case SM_SUN3|SM_3_160:
293 case SM_SUN3|SM_3_260:
294 /* these machines have 82586 */
295 break;
297 default:
298 return ERR_PTR(-ENODEV);
299 }
301 if (found)
302 return ERR_PTR(-ENODEV);
304 ioaddr = (unsigned long)ioremap(IE_OBIO, SUN3_82586_TOTAL_SIZE);
305 if (!ioaddr)
306 return ERR_PTR(-ENOMEM);
307 found = 1;
309 dev = alloc_etherdev(sizeof(struct priv));
310 if (!dev)
311 goto out;
312 if (unit >= 0) {
313 sprintf(dev->name, "eth%d", unit);
314 netdev_boot_setup_check(dev);
315 }
316 SET_MODULE_OWNER(dev);
318 dev->irq = IE_IRQ;
319 dev->base_addr = ioaddr;
320 err = sun3_82586_probe1(dev, ioaddr);
321 if (err)
322 goto out1;
323 err = register_netdev(dev);
324 if (err)
325 goto out2;
326 return dev;
328 out2:
329 release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
330 out1:
331 free_netdev(dev);
332 out:
333 iounmap((void *)ioaddr);
334 return ERR_PTR(err);
335 }
337 static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
338 {
339 int i, size, retval;
341 if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, DRV_NAME))
342 return -EBUSY;
344 /* copy in the ethernet address from the prom */
345 for(i = 0; i < 6 ; i++)
346 dev->dev_addr[i] = idprom->id_ethaddr[i];
348 printk("%s: SUN3 Intel 82586 found at %lx, ",dev->name,dev->base_addr);
350 /*
351 * check (or search) IO-Memory, 32K
352 */
353 size = 0x8000;
355 dev->mem_start = (unsigned long)dvma_malloc_align(0x8000, 0x1000);
356 dev->mem_end = dev->mem_start + size;
358 if(size != 0x2000 && size != 0x4000 && size != 0x8000) {
359 printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 or 0x8000 bytes.\n",dev->name,size);
360 retval = -ENODEV;
361 goto out;
362 }
363 if(!check586(dev,(char *) dev->mem_start,size)) {
364 printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size);
365 retval = -ENODEV;
366 goto out;
367 }
369 ((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start);
370 ((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0);
371 alloc586(dev);
373 /* set number of receive-buffs according to memsize */
374 if(size == 0x2000)
375 ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
376 else if(size == 0x4000)
377 ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
378 else
379 ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_32;
381 printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq);
383 dev->open = sun3_82586_open;
384 dev->stop = sun3_82586_close;
385 dev->get_stats = sun3_82586_get_stats;
386 dev->tx_timeout = sun3_82586_timeout;
387 dev->watchdog_timeo = HZ/20;
388 dev->hard_start_xmit = sun3_82586_send_packet;
389 dev->set_multicast_list = set_multicast_list;
391 dev->if_port = 0;
392 return 0;
393 out:
394 release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
395 return retval;
396 }
399 static int init586(struct net_device *dev)
400 {
401 void *ptr;
402 int i,result=0;
403 struct priv *p = (struct priv *) dev->priv;
404 volatile struct configure_cmd_struct *cfg_cmd;
405 volatile struct iasetup_cmd_struct *ias_cmd;
406 volatile struct tdr_cmd_struct *tdr_cmd;
407 volatile struct mcsetup_cmd_struct *mc_cmd;
408 struct dev_mc_list *dmi=dev->mc_list;
409 int num_addrs=dev->mc_count;
411 ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
413 cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
414 cfg_cmd->cmd_status = 0;
415 cfg_cmd->cmd_cmd = swab16(CMD_CONFIGURE | CMD_LAST);
416 cfg_cmd->cmd_link = 0xffff;
418 cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
419 cfg_cmd->fifo = fifo; /* fifo-limit (8=tx:32/rx:64) */
420 cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
421 cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
422 cfg_cmd->priority = 0x00;
423 cfg_cmd->ifs = 0x60;
424 cfg_cmd->time_low = 0x00;
425 cfg_cmd->time_high = 0xf2;
426 cfg_cmd->promisc = 0;
427 if(dev->flags & IFF_ALLMULTI) {
428 int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
429 if(num_addrs > len) {
430 printk("%s: switching to promisc. mode\n",dev->name);
431 dev->flags|=IFF_PROMISC;
432 }
433 }
434 if(dev->flags&IFF_PROMISC)
435 {
436 cfg_cmd->promisc=1;
437 dev->flags|=IFF_PROMISC;
438 }
439 cfg_cmd->carr_coll = 0x00;
441 p->scb->cbl_offset = make16(cfg_cmd);
442 p->scb->cmd_ruc = 0;
444 p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
445 sun3_attn586();
447 WAIT_4_STAT_COMPL(cfg_cmd);
449 if((swab16(cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
450 {
451 printk("%s: configure command failed: %x\n",dev->name,swab16(cfg_cmd->cmd_status));
452 return 1;
453 }
455 /*
456 * individual address setup
457 */
459 ias_cmd = (struct iasetup_cmd_struct *)ptr;
461 ias_cmd->cmd_status = 0;
462 ias_cmd->cmd_cmd = swab16(CMD_IASETUP | CMD_LAST);
463 ias_cmd->cmd_link = 0xffff;
465 memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
467 p->scb->cbl_offset = make16(ias_cmd);
469 p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
470 sun3_attn586();
472 WAIT_4_STAT_COMPL(ias_cmd);
474 if((swab16(ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
475 printk("%s (82586): individual address setup command failed: %04x\n",dev->name,swab16(ias_cmd->cmd_status));
476 return 1;
477 }
479 /*
480 * TDR, wire check .. e.g. no resistor e.t.c
481 */
483 tdr_cmd = (struct tdr_cmd_struct *)ptr;
485 tdr_cmd->cmd_status = 0;
486 tdr_cmd->cmd_cmd = swab16(CMD_TDR | CMD_LAST);
487 tdr_cmd->cmd_link = 0xffff;
488 tdr_cmd->status = 0;
490 p->scb->cbl_offset = make16(tdr_cmd);
491 p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
492 sun3_attn586();
494 WAIT_4_STAT_COMPL(tdr_cmd);
496 if(!(swab16(tdr_cmd->cmd_status) & STAT_COMPL))
497 {
498 printk("%s: Problems while running the TDR.\n",dev->name);
499 }
500 else
501 {
502 DELAY_16(); /* wait for result */
503 result = swab16(tdr_cmd->status);
505 p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
506 sun3_attn586(); /* ack the interrupts */
508 if(result & TDR_LNK_OK)
509 ;
510 else if(result & TDR_XCVR_PRB)
511 printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
512 else if(result & TDR_ET_OPN)
513 printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
514 else if(result & TDR_ET_SRT)
515 {
516 if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
517 printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
518 }
519 else
520 printk("%s: TDR: Unknown status %04x\n",dev->name,result);
521 }
523 /*
524 * Multicast setup
525 */
526 if(num_addrs && !(dev->flags & IFF_PROMISC) )
527 {
528 mc_cmd = (struct mcsetup_cmd_struct *) ptr;
529 mc_cmd->cmd_status = 0;
530 mc_cmd->cmd_cmd = swab16(CMD_MCSETUP | CMD_LAST);
531 mc_cmd->cmd_link = 0xffff;
532 mc_cmd->mc_cnt = swab16(num_addrs * 6);
534 for(i=0;i<num_addrs;i++,dmi=dmi->next)
535 memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
537 p->scb->cbl_offset = make16(mc_cmd);
538 p->scb->cmd_cuc = CUC_START;
539 sun3_attn586();
541 WAIT_4_STAT_COMPL(mc_cmd);
543 if( (swab16(mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
544 printk("%s: Can't apply multicast-address-list.\n",dev->name);
545 }
547 /*
548 * alloc nop/xmit-cmds
549 */
550 #if (NUM_XMIT_BUFFS == 1)
551 for(i=0;i<2;i++)
552 {
553 p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
554 p->nop_cmds[i]->cmd_cmd = swab16(CMD_NOP);
555 p->nop_cmds[i]->cmd_status = 0;
556 p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
557 ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
558 }
559 #else
560 for(i=0;i<NUM_XMIT_BUFFS;i++)
561 {
562 p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
563 p->nop_cmds[i]->cmd_cmd = swab16(CMD_NOP);
564 p->nop_cmds[i]->cmd_status = 0;
565 p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
566 ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
567 }
568 #endif
570 ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
572 /*
573 * alloc xmit-buffs / init xmit_cmds
574 */
575 for(i=0;i<NUM_XMIT_BUFFS;i++)
576 {
577 p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
578 ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
579 p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
580 ptr = (char *) ptr + XMIT_BUFF_SIZE;
581 p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
582 ptr = (char *) ptr + sizeof(struct tbd_struct);
583 if((void *)ptr > (void *)dev->mem_end)
584 {
585 printk("%s: not enough shared-mem for your configuration!\n",dev->name);
586 return 1;
587 }
588 memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
589 memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
590 p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]);
591 p->xmit_cmds[i]->cmd_status = swab16(STAT_COMPL);
592 p->xmit_cmds[i]->cmd_cmd = swab16(CMD_XMIT | CMD_INT);
593 p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
594 p->xmit_buffs[i]->next = 0xffff;
595 p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
596 }
598 p->xmit_count = 0;
599 p->xmit_last = 0;
600 #ifndef NO_NOPCOMMANDS
601 p->nop_point = 0;
602 #endif
604 /*
605 * 'start transmitter'
606 */
607 #ifndef NO_NOPCOMMANDS
608 p->scb->cbl_offset = make16(p->nop_cmds[0]);
609 p->scb->cmd_cuc = CUC_START;
610 sun3_attn586();
611 WAIT_4_SCB_CMD();
612 #else
613 p->xmit_cmds[0]->cmd_link = make16(p->xmit_cmds[0]);
614 p->xmit_cmds[0]->cmd_cmd = swab16(CMD_XMIT | CMD_SUSPEND | CMD_INT);
615 #endif
617 /*
618 * ack. interrupts
619 */
620 p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
621 sun3_attn586();
622 DELAY_16();
624 sun3_enaint();
625 sun3_active();
627 return 0;
628 }
630 /******************************************************
631 * This is a helper routine for sun3_82586_rnr_int() and init586().
632 * It sets up the Receive Frame Area (RFA).
633 */
635 static void *alloc_rfa(struct net_device *dev,void *ptr)
636 {
637 volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
638 volatile struct rbd_struct *rbd;
639 int i;
640 struct priv *p = (struct priv *) dev->priv;
642 memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd));
643 p->rfd_first = rfd;
645 for(i = 0; i < (p->num_recv_buffs+rfdadd); i++) {
646 rfd[i].next = make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd) );
647 rfd[i].rbd_offset = 0xffff;
648 }
649 rfd[p->num_recv_buffs-1+rfdadd].last = RFD_SUSP; /* RU suspend */
651 ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd) );
653 rbd = (struct rbd_struct *) ptr;
654 ptr = (void *) (rbd + p->num_recv_buffs);
656 /* clr descriptors */
657 memset((char *) rbd,0,sizeof(struct rbd_struct)*(p->num_recv_buffs));
659 for(i=0;i<p->num_recv_buffs;i++)
660 {
661 rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
662 rbd[i].size = swab16(RECV_BUFF_SIZE);
663 rbd[i].buffer = make24(ptr);
664 ptr = (char *) ptr + RECV_BUFF_SIZE;
665 }
667 p->rfd_top = p->rfd_first;
668 p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd);
670 p->scb->rfa_offset = make16(p->rfd_first);
671 p->rfd_first->rbd_offset = make16(rbd);
673 return ptr;
674 }
677 /**************************************************
678 * Interrupt Handler ...
679 */
681 static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr)
682 {
683 struct net_device *dev = dev_id;
684 unsigned short stat;
685 int cnt=0;
686 struct priv *p;
688 if (!dev) {
689 printk ("sun3_82586-interrupt: irq %d for unknown device.\n",irq);
690 return IRQ_NONE;
691 }
692 p = (struct priv *) dev->priv;
694 if(debuglevel > 1)
695 printk("I");
697 WAIT_4_SCB_CMD(); /* wait for last command */
699 while((stat=p->scb->cus & STAT_MASK))
700 {
701 p->scb->cmd_cuc = stat;
702 sun3_attn586();
704 if(stat & STAT_FR) /* received a frame */
705 sun3_82586_rcv_int(dev);
707 if(stat & STAT_RNR) /* RU went 'not ready' */
708 {
709 printk("(R)");
710 if(p->scb->rus & RU_SUSPEND) /* special case: RU_SUSPEND */
711 {
712 WAIT_4_SCB_CMD();
713 p->scb->cmd_ruc = RUC_RESUME;
714 sun3_attn586();
715 WAIT_4_SCB_CMD_RUC();
716 }
717 else
718 {
719 printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus);
720 sun3_82586_rnr_int(dev);
721 }
722 }
724 if(stat & STAT_CX) /* command with I-bit set complete */
725 sun3_82586_xmt_int(dev);
727 #ifndef NO_NOPCOMMANDS
728 if(stat & STAT_CNA) /* CU went 'not ready' */
729 {
730 if(netif_running(dev))
731 printk("%s: oops! CU has left active state. stat: %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->cus);
732 }
733 #endif
735 if(debuglevel > 1)
736 printk("%d",cnt++);
738 WAIT_4_SCB_CMD(); /* wait for ack. (sun3_82586_xmt_int can be faster than ack!!) */
739 if(p->scb->cmd_cuc) /* timed out? */
740 {
741 printk("%s: Acknowledge timed out.\n",dev->name);
742 sun3_disint();
743 break;
744 }
745 }
747 if(debuglevel > 1)
748 printk("i");
749 return IRQ_HANDLED;
750 }
752 /*******************************************************
753 * receive-interrupt
754 */
756 static void sun3_82586_rcv_int(struct net_device *dev)
757 {
758 int status,cnt=0;
759 unsigned short totlen;
760 struct sk_buff *skb;
761 struct rbd_struct *rbd;
762 struct priv *p = (struct priv *) dev->priv;
764 if(debuglevel > 0)
765 printk("R");
767 for(;(status = p->rfd_top->stat_high) & RFD_COMPL;)
768 {
769 rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
771 if(status & RFD_OK) /* frame received without error? */
772 {
773 if( (totlen = swab16(rbd->status)) & RBD_LAST) /* the first and the last buffer? */
774 {
775 totlen &= RBD_MASK; /* length of this frame */
776 rbd->status = 0;
777 skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
778 if(skb != NULL)
779 {
780 skb->dev = dev;
781 skb_reserve(skb,2);
782 skb_put(skb,totlen);
783 eth_copy_and_sum(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen,0);
784 skb->protocol=eth_type_trans(skb,dev);
785 netif_rx(skb);
786 p->stats.rx_packets++;
787 }
788 else
789 p->stats.rx_dropped++;
790 }
791 else
792 {
793 int rstat;
794 /* free all RBD's until RBD_LAST is set */
795 totlen = 0;
796 while(!((rstat=swab16(rbd->status)) & RBD_LAST))
797 {
798 totlen += rstat & RBD_MASK;
799 if(!rstat)
800 {
801 printk("%s: Whoops .. no end mark in RBD list\n",dev->name);
802 break;
803 }
804 rbd->status = 0;
805 rbd = (struct rbd_struct *) make32(rbd->next);
806 }
807 totlen += rstat & RBD_MASK;
808 rbd->status = 0;
809 printk("%s: received oversized frame! length: %d\n",dev->name,totlen);
810 p->stats.rx_dropped++;
811 }
812 }
813 else /* frame !(ok), only with 'save-bad-frames' */
814 {
815 printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
816 p->stats.rx_errors++;
817 }
818 p->rfd_top->stat_high = 0;
819 p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */
820 p->rfd_top->rbd_offset = 0xffff;
821 p->rfd_last->last = 0; /* delete RFD_SUSP */
822 p->rfd_last = p->rfd_top;
823 p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
824 p->scb->rfa_offset = make16(p->rfd_top);
826 if(debuglevel > 0)
827 printk("%d",cnt++);
828 }
830 if(automatic_resume)
831 {
832 WAIT_4_SCB_CMD();
833 p->scb->cmd_ruc = RUC_RESUME;
834 sun3_attn586();
835 WAIT_4_SCB_CMD_RUC();
836 }
838 #ifdef WAIT_4_BUSY
839 {
840 int i;
841 for(i=0;i<1024;i++)
842 {
843 if(p->rfd_top->status)
844 break;
845 DELAY_16();
846 if(i == 1023)
847 printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);
848 }
849 }
850 #endif
852 #if 0
853 if(!at_least_one)
854 {
855 int i;
856 volatile struct rfd_struct *rfds=p->rfd_top;
857 volatile struct rbd_struct *rbds;
858 printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);
859 for(i=0;i< (p->num_recv_buffs+4);i++)
860 {
861 rbds = (struct rbd_struct *) make32(rfds->rbd_offset);
862 printk("%04x:%04x ",rfds->status,rbds->status);
863 rfds = (struct rfd_struct *) make32(rfds->next);
864 }
865 printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
866 printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);
867 }
868 old_at_least = at_least_one;
869 #endif
871 if(debuglevel > 0)
872 printk("r");
873 }
875 /**********************************************************
876 * handle 'Receiver went not ready'.
877 */
879 static void sun3_82586_rnr_int(struct net_device *dev)
880 {
881 struct priv *p = (struct priv *) dev->priv;
883 p->stats.rx_errors++;
885 WAIT_4_SCB_CMD(); /* wait for the last cmd, WAIT_4_FULLSTAT?? */
886 p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
887 sun3_attn586();
888 WAIT_4_SCB_CMD_RUC(); /* wait for accept cmd. */
890 alloc_rfa(dev,(char *)p->rfd_first);
891 /* maybe add a check here, before restarting the RU */
892 startrecv586(dev); /* restart RU */
894 printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);
896 }
898 /**********************************************************
899 * handle xmit - interrupt
900 */
902 static void sun3_82586_xmt_int(struct net_device *dev)
903 {
904 int status;
905 struct priv *p = (struct priv *) dev->priv;
907 if(debuglevel > 0)
908 printk("X");
910 status = swab16(p->xmit_cmds[p->xmit_last]->cmd_status);
911 if(!(status & STAT_COMPL))
912 printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
914 if(status & STAT_OK)
915 {
916 p->stats.tx_packets++;
917 p->stats.collisions += (status & TCMD_MAXCOLLMASK);
918 }
919 else
920 {
921 p->stats.tx_errors++;
922 if(status & TCMD_LATECOLL) {
923 printk("%s: late collision detected.\n",dev->name);
924 p->stats.collisions++;
925 }
926 else if(status & TCMD_NOCARRIER) {
927 p->stats.tx_carrier_errors++;
928 printk("%s: no carrier detected.\n",dev->name);
929 }
930 else if(status & TCMD_LOSTCTS)
931 printk("%s: loss of CTS detected.\n",dev->name);
932 else if(status & TCMD_UNDERRUN) {
933 p->stats.tx_fifo_errors++;
934 printk("%s: DMA underrun detected.\n",dev->name);
935 }
936 else if(status & TCMD_MAXCOLL) {
937 printk("%s: Max. collisions exceeded.\n",dev->name);
938 p->stats.collisions += 16;
939 }
940 }
942 #if (NUM_XMIT_BUFFS > 1)
943 if( (++p->xmit_last) == NUM_XMIT_BUFFS)
944 p->xmit_last = 0;
945 #endif
946 netif_wake_queue(dev);
947 }
949 /***********************************************************
950 * (re)start the receiver
951 */
953 static void startrecv586(struct net_device *dev)
954 {
955 struct priv *p = (struct priv *) dev->priv;
957 WAIT_4_SCB_CMD();
958 WAIT_4_SCB_CMD_RUC();
959 p->scb->rfa_offset = make16(p->rfd_first);
960 p->scb->cmd_ruc = RUC_START;
961 sun3_attn586(); /* start cmd. */
962 WAIT_4_SCB_CMD_RUC(); /* wait for accept cmd. (no timeout!!) */
963 }
965 static void sun3_82586_timeout(struct net_device *dev)
966 {
967 struct priv *p = (struct priv *) dev->priv;
968 #ifndef NO_NOPCOMMANDS
969 if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */
970 {
971 netif_wake_queue(dev);
972 #ifdef DEBUG
973 printk("%s: strange ... timeout with CU active?!?\n",dev->name);
974 printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)swab16(p->xmit_cmds[0]->cmd_status),(int)swab16(p->nop_cmds[0]->cmd_status),(int)swab16(p->nop_cmds[1]->cmd_status),(int)p->nop_point);
975 #endif
976 p->scb->cmd_cuc = CUC_ABORT;
977 sun3_attn586();
978 WAIT_4_SCB_CMD();
979 p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
980 p->scb->cmd_cuc = CUC_START;
981 sun3_attn586();
982 WAIT_4_SCB_CMD();
983 dev->trans_start = jiffies;
984 return 0;
985 }
986 #endif
987 {
988 #ifdef DEBUG
989 printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);
990 printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status));
991 printk("%s: check, whether you set the right interrupt number!\n",dev->name);
992 #endif
993 sun3_82586_close(dev);
994 sun3_82586_open(dev);
995 }
996 dev->trans_start = jiffies;
997 }
999 /******************************************************
1000 * send frame
1001 */
1003 static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
1005 int len,i;
1006 #ifndef NO_NOPCOMMANDS
1007 int next_nop;
1008 #endif
1009 struct priv *p = (struct priv *) dev->priv;
1011 if(skb->len > XMIT_BUFF_SIZE)
1013 printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
1014 return 0;
1017 netif_stop_queue(dev);
1019 #if(NUM_XMIT_BUFFS > 1)
1020 if(test_and_set_bit(0,(void *) &p->lock)) {
1021 printk("%s: Queue was locked\n",dev->name);
1022 return 1;
1024 else
1025 #endif
1027 len = skb->len;
1028 if (len < ETH_ZLEN) {
1029 memset((char *)p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN);
1030 len = ETH_ZLEN;
1032 memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
1034 #if (NUM_XMIT_BUFFS == 1)
1035 # ifdef NO_NOPCOMMANDS
1037 #ifdef DEBUG
1038 if(p->scb->cus & CU_ACTIVE)
1040 printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);
1041 printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,swab16(p->xmit_cmds[0]->cmd_status));
1043 #endif
1045 p->xmit_buffs[0]->size = swab16(TBD_LAST | len);
1046 for(i=0;i<16;i++)
1048 p->xmit_cmds[0]->cmd_status = 0;
1049 WAIT_4_SCB_CMD();
1050 if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)
1051 p->scb->cmd_cuc = CUC_RESUME;
1052 else
1054 p->scb->cbl_offset = make16(p->xmit_cmds[0]);
1055 p->scb->cmd_cuc = CUC_START;
1058 sun3_attn586();
1059 dev->trans_start = jiffies;
1060 if(!i)
1061 dev_kfree_skb(skb);
1062 WAIT_4_SCB_CMD();
1063 if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
1064 break;
1065 if(p->xmit_cmds[0]->cmd_status)
1066 break;
1067 if(i==15)
1068 printk("%s: Can't start transmit-command.\n",dev->name);
1070 # else
1071 next_nop = (p->nop_point + 1) & 0x1;
1072 p->xmit_buffs[0]->size = swab16(TBD_LAST | len);
1074 p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
1075 = make16((p->nop_cmds[next_nop]));
1076 p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
1078 p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
1079 dev->trans_start = jiffies;
1080 p->nop_point = next_nop;
1081 dev_kfree_skb(skb);
1082 # endif
1083 #else
1084 p->xmit_buffs[p->xmit_count]->size = swab16(TBD_LAST | len);
1085 if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
1086 next_nop = 0;
1088 p->xmit_cmds[p->xmit_count]->cmd_status = 0;
1089 /* linkpointer of xmit-command already points to next nop cmd */
1090 p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));
1091 p->nop_cmds[next_nop]->cmd_status = 0;
1093 p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
1094 dev->trans_start = jiffies;
1095 p->xmit_count = next_nop;
1098 unsigned long flags;
1099 local_irq_save(flags);
1100 if(p->xmit_count != p->xmit_last)
1101 netif_wake_queue(dev);
1102 p->lock = 0;
1103 local_irq_restore(flags);
1105 dev_kfree_skb(skb);
1106 #endif
1108 return 0;
1111 /*******************************************
1112 * Someone wanna have the statistics
1113 */
1115 static struct net_device_stats *sun3_82586_get_stats(struct net_device *dev)
1117 struct priv *p = (struct priv *) dev->priv;
1118 unsigned short crc,aln,rsc,ovrn;
1120 crc = swab16(p->scb->crc_errs); /* get error-statistic from the ni82586 */
1121 p->scb->crc_errs = 0;
1122 aln = swab16(p->scb->aln_errs);
1123 p->scb->aln_errs = 0;
1124 rsc = swab16(p->scb->rsc_errs);
1125 p->scb->rsc_errs = 0;
1126 ovrn = swab16(p->scb->ovrn_errs);
1127 p->scb->ovrn_errs = 0;
1129 p->stats.rx_crc_errors += crc;
1130 p->stats.rx_fifo_errors += ovrn;
1131 p->stats.rx_frame_errors += aln;
1132 p->stats.rx_dropped += rsc;
1134 return &p->stats;
1137 /********************************************************
1138 * Set MC list ..
1139 */
1141 static void set_multicast_list(struct net_device *dev)
1143 netif_stop_queue(dev);
1144 sun3_disint();
1145 alloc586(dev);
1146 init586(dev);
1147 startrecv586(dev);
1148 sun3_enaint();
1149 netif_wake_queue(dev);
1152 #ifdef MODULE
1153 #error This code is not currently supported as a module
1154 static struct net_device *dev_sun3_82586;
1156 int init_module(void)
1158 dev_sun3_82586 = sun3_82586_probe(-1);
1159 if (IS_ERR(dev_sun3_82586))
1160 return PTR_ERR(dev_sun3_82586);
1161 return 0;
1164 void cleanup_module(void)
1166 unsigned long ioaddr = dev_sun3_82586->base_addr;
1167 unregister_netdev(dev_sun3_82586);
1168 release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
1169 iounmap((void *)ioaddr);
1170 free_netdev(dev_sun3_82586);
1172 #endif /* MODULE */
1174 #if 0
1175 /*
1176 * DUMP .. we expect a not running CMD unit and enough space
1177 */
1178 void sun3_82586_dump(struct net_device *dev,void *ptr)
1180 struct priv *p = (struct priv *) dev->priv;
1181 struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;
1182 int i;
1184 p->scb->cmd_cuc = CUC_ABORT;
1185 sun3_attn586();
1186 WAIT_4_SCB_CMD();
1187 WAIT_4_SCB_CMD_RUC();
1189 dump_cmd->cmd_status = 0;
1190 dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;
1191 dump_cmd->dump_offset = make16((dump_cmd + 1));
1192 dump_cmd->cmd_link = 0xffff;
1194 p->scb->cbl_offset = make16(dump_cmd);
1195 p->scb->cmd_cuc = CUC_START;
1196 sun3_attn586();
1197 WAIT_4_STAT_COMPL(dump_cmd);
1199 if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
1200 printk("%s: Can't get dump information.\n",dev->name);
1202 for(i=0;i<170;i++) {
1203 printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);
1204 if(i % 24 == 23)
1205 printk("\n");
1207 printk("\n");
1209 #endif
1211 MODULE_LICENSE("GPL");