cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sun3_82586.c (32725B)


      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 */
     25
     26static int debuglevel = 0; /* debug-printk 0: off 1: a few 2: more */
     27static int automatic_resume = 0; /* experimental .. better should be zero */
     28static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */
     29static int fifo=0x8;	/* don't change */
     30
     31#include <linux/kernel.h>
     32#include <linux/module.h>
     33#include <linux/string.h>
     34#include <linux/errno.h>
     35#include <linux/ioport.h>
     36#include <linux/interrupt.h>
     37#include <linux/delay.h>
     38#include <linux/init.h>
     39#include <linux/bitops.h>
     40#include <asm/io.h>
     41#include <asm/idprom.h>
     42#include <asm/machines.h>
     43#include <asm/sun3mmu.h>
     44#include <asm/dvma.h>
     45#include <asm/byteorder.h>
     46
     47#include <linux/netdevice.h>
     48#include <linux/etherdevice.h>
     49#include <linux/skbuff.h>
     50
     51#include "sun3_82586.h"
     52
     53#define DRV_NAME "sun3_82586"
     54
     55#define DEBUG       /* debug on */
     56#define SYSBUSVAL 0 /* 16 Bit */
     57#define SUN3_82586_TOTAL_SIZE	PAGE_SIZE
     58
     59#define sun3_attn586()  {*(volatile unsigned char *)(dev->base_addr) |= IEOB_ATTEN; *(volatile unsigned char *)(dev->base_addr) &= ~IEOB_ATTEN;}
     60#define sun3_reset586() {*(volatile unsigned char *)(dev->base_addr) = 0; udelay(100); *(volatile unsigned char *)(dev->base_addr) = IEOB_NORSET;}
     61#define sun3_disint()   {*(volatile unsigned char *)(dev->base_addr) &= ~IEOB_IENAB;}
     62#define sun3_enaint()   {*(volatile unsigned char *)(dev->base_addr) |= IEOB_IENAB;}
     63#define sun3_active()   {*(volatile unsigned char *)(dev->base_addr) |= (IEOB_IENAB|IEOB_ONAIR|IEOB_NORSET);}
     64
     65#define make32(ptr16) (p->memtop + (swab16((unsigned short) (ptr16))) )
     66#define make24(ptr32) (char *)swab32(( ((unsigned long) (ptr32)) - p->base))
     67#define make16(ptr32) (swab16((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop )))
     68
     69/******************* how to calculate the buffers *****************************
     70
     71  * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
     72  * --------------- in a different (more stable?) mode. Only in this mode it's
     73  *                 possible to configure the driver with 'NO_NOPCOMMANDS'
     74
     75sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
     76sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
     77sizeof(rfd) = 24; sizeof(rbd) = 12;
     78sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
     79sizeof(nop_cmd) = 8;
     80
     81  * if you don't know the driver, better do not change these values: */
     82
     83#define RECV_BUFF_SIZE 1536 /* slightly oversized */
     84#define XMIT_BUFF_SIZE 1536 /* slightly oversized */
     85#define NUM_XMIT_BUFFS 1    /* config for 32K shmem */
     86#define NUM_RECV_BUFFS_8 4 /* config for 32K shared mem */
     87#define NUM_RECV_BUFFS_16 9 /* config for 32K shared mem */
     88#define NUM_RECV_BUFFS_32 16 /* config for 32K shared mem */
     89#define NO_NOPCOMMANDS      /* only possible with NUM_XMIT_BUFFS=1 */
     90
     91/**************************************************************************/
     92
     93/* different DELAYs */
     94#define DELAY(x) mdelay(32 * x);
     95#define DELAY_16(); { udelay(16); }
     96#define DELAY_18(); { udelay(4); }
     97
     98/* wait for command with timeout: */
     99#define WAIT_4_SCB_CMD() \
    100{ int i; \
    101  for(i=0;i<16384;i++) { \
    102    if(!p->scb->cmd_cuc) break; \
    103    DELAY_18(); \
    104    if(i == 16383) { \
    105      printk("%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_cuc,p->scb->cus); \
    106       if(!p->reseted) { p->reseted = 1; sun3_reset586(); } } } }
    107
    108#define WAIT_4_SCB_CMD_RUC() { int i; \
    109  for(i=0;i<16384;i++) { \
    110    if(!p->scb->cmd_ruc) break; \
    111    DELAY_18(); \
    112    if(i == 16383) { \
    113      printk("%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_ruc,p->scb->rus); \
    114       if(!p->reseted) { p->reseted = 1; sun3_reset586(); } } } }
    115
    116#define WAIT_4_STAT_COMPL(addr) { int i; \
    117   for(i=0;i<32767;i++) { \
    118     if(swab16((addr)->cmd_status) & STAT_COMPL) break; \
    119     DELAY_16(); DELAY_16(); } }
    120
    121static int     sun3_82586_probe1(struct net_device *dev,int ioaddr);
    122static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id);
    123static int     sun3_82586_open(struct net_device *dev);
    124static int     sun3_82586_close(struct net_device *dev);
    125static netdev_tx_t     sun3_82586_send_packet(struct sk_buff *,
    126					      struct net_device *);
    127static struct  net_device_stats *sun3_82586_get_stats(struct net_device *dev);
    128static void    set_multicast_list(struct net_device *dev);
    129static void    sun3_82586_timeout(struct net_device *dev, unsigned int txqueue);
    130#if 0
    131static void    sun3_82586_dump(struct net_device *,void *);
    132#endif
    133
    134/* helper-functions */
    135static int     init586(struct net_device *dev);
    136static int     check586(struct net_device *dev,char *where,unsigned size);
    137static void    alloc586(struct net_device *dev);
    138static void    startrecv586(struct net_device *dev);
    139static void   *alloc_rfa(struct net_device *dev,void *ptr);
    140static void    sun3_82586_rcv_int(struct net_device *dev);
    141static void    sun3_82586_xmt_int(struct net_device *dev);
    142static void    sun3_82586_rnr_int(struct net_device *dev);
    143
    144struct priv
    145{
    146	unsigned long base;
    147	char *memtop;
    148	long int lock;
    149	int reseted;
    150	volatile struct rfd_struct	*rfd_last,*rfd_top,*rfd_first;
    151	volatile struct scp_struct	*scp;	/* volatile is important */
    152	volatile struct iscp_struct	*iscp;	/* volatile is important */
    153	volatile struct scb_struct	*scb;	/* volatile is important */
    154	volatile struct tbd_struct	*xmit_buffs[NUM_XMIT_BUFFS];
    155	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
    156#if (NUM_XMIT_BUFFS == 1)
    157	volatile struct nop_cmd_struct *nop_cmds[2];
    158#else
    159	volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
    160#endif
    161	volatile int		nop_point,num_recv_buffs;
    162	volatile char		*xmit_cbuffs[NUM_XMIT_BUFFS];
    163	volatile int		xmit_count,xmit_last;
    164};
    165
    166/**********************************************
    167 * close device
    168 */
    169static int sun3_82586_close(struct net_device *dev)
    170{
    171	free_irq(dev->irq, dev);
    172
    173	sun3_reset586(); /* the hard way to stop the receiver */
    174
    175	netif_stop_queue(dev);
    176
    177	return 0;
    178}
    179
    180/**********************************************
    181 * open device
    182 */
    183static int sun3_82586_open(struct net_device *dev)
    184{
    185	int ret;
    186
    187	sun3_disint();
    188	alloc586(dev);
    189	init586(dev);
    190	startrecv586(dev);
    191	sun3_enaint();
    192
    193	ret = request_irq(dev->irq, sun3_82586_interrupt,0,dev->name,dev);
    194	if (ret)
    195	{
    196		sun3_reset586();
    197		return ret;
    198	}
    199
    200	netif_start_queue(dev);
    201
    202	return 0; /* most done by init */
    203}
    204
    205/**********************************************
    206 * Check to see if there's an 82586 out there.
    207 */
    208static int check586(struct net_device *dev,char *where,unsigned size)
    209{
    210	struct priv pb;
    211	struct priv *p = &pb;
    212	char *iscp_addr;
    213	int i;
    214
    215	p->base = (unsigned long) dvma_btov(0);
    216	p->memtop = (char *)dvma_btov((unsigned long)where);
    217	p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
    218	memset((char *)p->scp,0, sizeof(struct scp_struct));
    219	for(i=0;i<sizeof(struct scp_struct);i++) /* memory was writeable? */
    220		if(((char *)p->scp)[i])
    221			return 0;
    222	p->scp->sysbus = SYSBUSVAL;				/* 1 = 8Bit-Bus, 0 = 16 Bit */
    223	if(p->scp->sysbus != SYSBUSVAL)
    224		return 0;
    225
    226	iscp_addr = (char *)dvma_btov((unsigned long)where);
    227
    228	p->iscp = (struct iscp_struct *) iscp_addr;
    229	memset((char *)p->iscp,0, sizeof(struct iscp_struct));
    230
    231	p->scp->iscp = make24(p->iscp);
    232	p->iscp->busy = 1;
    233
    234	sun3_reset586();
    235	sun3_attn586();
    236	DELAY(1);	/* wait a while... */
    237
    238	if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
    239		return 0;
    240
    241	return 1;
    242}
    243
    244/******************************************************************
    245 * set iscp at the right place, called by sun3_82586_probe1 and open586.
    246 */
    247static void alloc586(struct net_device *dev)
    248{
    249	struct priv *p = netdev_priv(dev);
    250
    251	sun3_reset586();
    252	DELAY(1);
    253
    254	p->scp	= (struct scp_struct *)	(p->base + SCP_DEFAULT_ADDRESS);
    255	p->iscp	= (struct iscp_struct *) dvma_btov(dev->mem_start);
    256	p->scb  = (struct scb_struct *)  ((char *)p->iscp + sizeof(struct iscp_struct));
    257
    258	memset((char *) p->iscp,0,sizeof(struct iscp_struct));
    259	memset((char *) p->scp ,0,sizeof(struct scp_struct));
    260
    261	p->scp->iscp = make24(p->iscp);
    262	p->scp->sysbus = SYSBUSVAL;
    263	p->iscp->scb_offset = make16(p->scb);
    264	p->iscp->scb_base = make24(dvma_btov(dev->mem_start));
    265
    266	p->iscp->busy = 1;
    267	sun3_reset586();
    268	sun3_attn586();
    269
    270	DELAY(1);
    271
    272	if(p->iscp->busy)
    273		printk("%s: Init-Problems (alloc).\n",dev->name);
    274
    275	p->reseted = 0;
    276
    277	memset((char *)p->scb,0,sizeof(struct scb_struct));
    278}
    279
    280static int __init sun3_82586_probe(void)
    281{
    282	struct net_device *dev;
    283	unsigned long ioaddr;
    284	static int found = 0;
    285	int err = -ENOMEM;
    286
    287	/* check that this machine has an onboard 82586 */
    288	switch(idprom->id_machtype) {
    289	case SM_SUN3|SM_3_160:
    290	case SM_SUN3|SM_3_260:
    291		/* these machines have 82586 */
    292		break;
    293
    294	default:
    295		return -ENODEV;
    296	}
    297
    298	if (found)
    299		return -ENODEV;
    300
    301	ioaddr = (unsigned long)ioremap(IE_OBIO, SUN3_82586_TOTAL_SIZE);
    302	if (!ioaddr)
    303		return -ENOMEM;
    304	found = 1;
    305
    306	dev = alloc_etherdev(sizeof(struct priv));
    307	if (!dev)
    308		goto out;
    309	dev->irq = IE_IRQ;
    310	dev->base_addr = ioaddr;
    311	err = sun3_82586_probe1(dev, ioaddr);
    312	if (err)
    313		goto out1;
    314	err = register_netdev(dev);
    315	if (err)
    316		goto out2;
    317	return 0;
    318
    319out2:
    320	release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
    321out1:
    322	free_netdev(dev);
    323out:
    324	iounmap((void __iomem *)ioaddr);
    325	return err;
    326}
    327module_init(sun3_82586_probe);
    328
    329static const struct net_device_ops sun3_82586_netdev_ops = {
    330	.ndo_open		= sun3_82586_open,
    331	.ndo_stop		= sun3_82586_close,
    332	.ndo_start_xmit		= sun3_82586_send_packet,
    333	.ndo_set_rx_mode	= set_multicast_list,
    334	.ndo_tx_timeout		= sun3_82586_timeout,
    335	.ndo_get_stats		= sun3_82586_get_stats,
    336	.ndo_validate_addr	= eth_validate_addr,
    337	.ndo_set_mac_address	= eth_mac_addr,
    338};
    339
    340static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
    341{
    342	int size, retval;
    343
    344	if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, DRV_NAME))
    345		return -EBUSY;
    346
    347	/* copy in the ethernet address from the prom */
    348	eth_hw_addr_set(dev, idprom->id_ethaddr);
    349
    350	printk("%s: SUN3 Intel 82586 found at %lx, ",dev->name,dev->base_addr);
    351
    352	/*
    353	 * check (or search) IO-Memory, 32K
    354	 */
    355	size = 0x8000;
    356
    357	dev->mem_start = (unsigned long)dvma_malloc_align(0x8000, 0x1000);
    358	dev->mem_end = dev->mem_start + size;
    359
    360	if(size != 0x2000 && size != 0x4000 && size != 0x8000) {
    361		printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 or 0x8000 bytes.\n",dev->name,size);
    362		retval = -ENODEV;
    363		goto out;
    364	}
    365	if(!check586(dev,(char *) dev->mem_start,size)) {
    366		printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size);
    367		retval = -ENODEV;
    368		goto out;
    369	}
    370
    371	((struct priv *)netdev_priv(dev))->memtop =
    372					(char *)dvma_btov(dev->mem_start);
    373	((struct priv *)netdev_priv(dev))->base = (unsigned long) dvma_btov(0);
    374	alloc586(dev);
    375
    376	/* set number of receive-buffs according to memsize */
    377	if(size == 0x2000)
    378		((struct priv *)netdev_priv(dev))->num_recv_buffs =
    379							NUM_RECV_BUFFS_8;
    380	else if(size == 0x4000)
    381		((struct priv *)netdev_priv(dev))->num_recv_buffs =
    382							NUM_RECV_BUFFS_16;
    383	else
    384		((struct priv *)netdev_priv(dev))->num_recv_buffs =
    385							NUM_RECV_BUFFS_32;
    386
    387	printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq);
    388
    389	dev->netdev_ops		= &sun3_82586_netdev_ops;
    390	dev->watchdog_timeo	= HZ/20;
    391
    392	dev->if_port 		= 0;
    393	return 0;
    394out:
    395	release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
    396	return retval;
    397}
    398
    399
    400static int init586(struct net_device *dev)
    401{
    402	void *ptr;
    403	int i,result=0;
    404	struct priv *p = netdev_priv(dev);
    405	volatile struct configure_cmd_struct	*cfg_cmd;
    406	volatile struct iasetup_cmd_struct *ias_cmd;
    407	volatile struct tdr_cmd_struct *tdr_cmd;
    408	volatile struct mcsetup_cmd_struct *mc_cmd;
    409	struct netdev_hw_addr *ha;
    410	int num_addrs=netdev_mc_count(dev);
    411
    412	ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
    413
    414	cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
    415	cfg_cmd->cmd_status	= 0;
    416	cfg_cmd->cmd_cmd	= swab16(CMD_CONFIGURE | CMD_LAST);
    417	cfg_cmd->cmd_link	= 0xffff;
    418
    419	cfg_cmd->byte_cnt	= 0x0a; /* number of cfg bytes */
    420	cfg_cmd->fifo		= fifo; /* fifo-limit (8=tx:32/rx:64) */
    421	cfg_cmd->sav_bf		= 0x40; /* hold or discard bad recv frames (bit 7) */
    422	cfg_cmd->adr_len	= 0x2e; /* addr_len |!src_insert |pre-len |loopback */
    423	cfg_cmd->priority	= 0x00;
    424	cfg_cmd->ifs		= 0x60;
    425	cfg_cmd->time_low	= 0x00;
    426	cfg_cmd->time_high	= 0xf2;
    427	cfg_cmd->promisc	= 0;
    428	if(dev->flags & IFF_ALLMULTI) {
    429		int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
    430		if(num_addrs > len)	{
    431			printk("%s: switching to promisc. mode\n",dev->name);
    432			cfg_cmd->promisc = 1;
    433		}
    434	}
    435	if(dev->flags&IFF_PROMISC)
    436		cfg_cmd->promisc = 1;
    437	cfg_cmd->carr_coll	= 0x00;
    438
    439	p->scb->cbl_offset	= make16(cfg_cmd);
    440	p->scb->cmd_ruc		= 0;
    441
    442	p->scb->cmd_cuc		= CUC_START; /* cmd.-unit start */
    443	sun3_attn586();
    444
    445	WAIT_4_STAT_COMPL(cfg_cmd);
    446
    447	if((swab16(cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
    448	{
    449		printk("%s: configure command failed: %x\n",dev->name,swab16(cfg_cmd->cmd_status));
    450		return 1;
    451	}
    452
    453	/*
    454	 * individual address setup
    455	 */
    456
    457	ias_cmd = (struct iasetup_cmd_struct *)ptr;
    458
    459	ias_cmd->cmd_status	= 0;
    460	ias_cmd->cmd_cmd	= swab16(CMD_IASETUP | CMD_LAST);
    461	ias_cmd->cmd_link	= 0xffff;
    462
    463	memcpy((char *)&ias_cmd->iaddr,(const char *) dev->dev_addr,ETH_ALEN);
    464
    465	p->scb->cbl_offset = make16(ias_cmd);
    466
    467	p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
    468	sun3_attn586();
    469
    470	WAIT_4_STAT_COMPL(ias_cmd);
    471
    472	if((swab16(ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
    473		printk("%s (82586): individual address setup command failed: %04x\n",dev->name,swab16(ias_cmd->cmd_status));
    474		return 1;
    475	}
    476
    477	/*
    478	 * TDR, wire check .. e.g. no resistor e.t.c
    479	 */
    480
    481	tdr_cmd = (struct tdr_cmd_struct *)ptr;
    482
    483	tdr_cmd->cmd_status	= 0;
    484	tdr_cmd->cmd_cmd	= swab16(CMD_TDR | CMD_LAST);
    485	tdr_cmd->cmd_link	= 0xffff;
    486	tdr_cmd->status		= 0;
    487
    488	p->scb->cbl_offset = make16(tdr_cmd);
    489	p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
    490	sun3_attn586();
    491
    492	WAIT_4_STAT_COMPL(tdr_cmd);
    493
    494	if(!(swab16(tdr_cmd->cmd_status) & STAT_COMPL))
    495	{
    496		printk("%s: Problems while running the TDR.\n",dev->name);
    497	}
    498	else
    499	{
    500		DELAY_16(); /* wait for result */
    501		result = swab16(tdr_cmd->status);
    502
    503		p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
    504		sun3_attn586(); /* ack the interrupts */
    505
    506		if(result & TDR_LNK_OK)
    507			;
    508		else if(result & TDR_XCVR_PRB)
    509			printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
    510		else if(result & TDR_ET_OPN)
    511			printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
    512		else if(result & TDR_ET_SRT)
    513		{
    514			if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
    515				printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
    516		}
    517		else
    518			printk("%s: TDR: Unknown status %04x\n",dev->name,result);
    519	}
    520
    521	/*
    522	 * Multicast setup
    523	 */
    524	if(num_addrs && !(dev->flags & IFF_PROMISC) )
    525	{
    526		mc_cmd = (struct mcsetup_cmd_struct *) ptr;
    527		mc_cmd->cmd_status = 0;
    528		mc_cmd->cmd_cmd = swab16(CMD_MCSETUP | CMD_LAST);
    529		mc_cmd->cmd_link = 0xffff;
    530		mc_cmd->mc_cnt = swab16(num_addrs * 6);
    531
    532		i = 0;
    533		netdev_for_each_mc_addr(ha, dev)
    534			memcpy((char *) mc_cmd->mc_list[i++],
    535			       ha->addr, ETH_ALEN);
    536
    537		p->scb->cbl_offset = make16(mc_cmd);
    538		p->scb->cmd_cuc = CUC_START;
    539		sun3_attn586();
    540
    541		WAIT_4_STAT_COMPL(mc_cmd);
    542
    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	}
    546
    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
    569
    570	ptr = alloc_rfa(dev,ptr); /* init receive-frame-area */
    571
    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(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	}
    597
    598	p->xmit_count = 0;
    599	p->xmit_last	= 0;
    600#ifndef NO_NOPCOMMANDS
    601	p->nop_point	= 0;
    602#endif
    603
    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
    616
    617	/*
    618	 * ack. interrupts
    619	 */
    620	p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
    621	sun3_attn586();
    622	DELAY_16();
    623
    624	sun3_enaint();
    625	sun3_active();
    626
    627	return 0;
    628}
    629
    630/******************************************************
    631 * This is a helper routine for sun3_82586_rnr_int() and init586().
    632 * It sets up the Receive Frame Area (RFA).
    633 */
    634
    635static 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 = netdev_priv(dev);
    641
    642	memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd));
    643	p->rfd_first = rfd;
    644
    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 */
    650
    651	ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd) );
    652
    653	rbd = (struct rbd_struct *) ptr;
    654	ptr = (void *) (rbd + p->num_recv_buffs);
    655
    656	 /* clr descriptors */
    657	memset((char *) rbd,0,sizeof(struct rbd_struct)*(p->num_recv_buffs));
    658
    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	}
    666
    667	p->rfd_top	= p->rfd_first;
    668	p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd);
    669
    670	p->scb->rfa_offset		= make16(p->rfd_first);
    671	p->rfd_first->rbd_offset	= make16(rbd);
    672
    673	return ptr;
    674}
    675
    676
    677/**************************************************
    678 * Interrupt Handler ...
    679 */
    680
    681static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id)
    682{
    683	struct net_device *dev = dev_id;
    684	unsigned short stat;
    685	int cnt=0;
    686	struct priv *p;
    687
    688	if (!dev) {
    689		printk ("sun3_82586-interrupt: irq %d for unknown device.\n",irq);
    690		return IRQ_NONE;
    691	}
    692	p = netdev_priv(dev);
    693
    694	if(debuglevel > 1)
    695		printk("I");
    696
    697	WAIT_4_SCB_CMD(); /* wait for last command	*/
    698
    699	while((stat=p->scb->cus & STAT_MASK))
    700	{
    701		p->scb->cmd_cuc = stat;
    702		sun3_attn586();
    703
    704		if(stat & STAT_FR)	 /* received a frame */
    705			sun3_82586_rcv_int(dev);
    706
    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		}
    723
    724		if(stat & STAT_CX)		/* command with I-bit set complete */
    725			 sun3_82586_xmt_int(dev);
    726
    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
    734
    735		if(debuglevel > 1)
    736			printk("%d",cnt++);
    737
    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	}
    746
    747	if(debuglevel > 1)
    748		printk("i");
    749	return IRQ_HANDLED;
    750}
    751
    752/*******************************************************
    753 * receive-interrupt
    754 */
    755
    756static 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 = netdev_priv(dev);
    763
    764	if(debuglevel > 0)
    765		printk("R");
    766
    767	for(;(status = p->rfd_top->stat_high) & RFD_COMPL;)
    768	{
    769			rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
    770
    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 = netdev_alloc_skb(dev, totlen + 2);
    778					if(skb != NULL)
    779					{
    780						skb_reserve(skb,2);
    781						skb_put(skb,totlen);
    782						skb_copy_to_linear_data(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen);
    783						skb->protocol=eth_type_trans(skb,dev);
    784						netif_rx(skb);
    785						dev->stats.rx_packets++;
    786					}
    787					else
    788						dev->stats.rx_dropped++;
    789				}
    790				else
    791				{
    792					int rstat;
    793						 /* free all RBD's until RBD_LAST is set */
    794					totlen = 0;
    795					while(!((rstat=swab16(rbd->status)) & RBD_LAST))
    796					{
    797						totlen += rstat & RBD_MASK;
    798						if(!rstat)
    799						{
    800							printk("%s: Whoops .. no end mark in RBD list\n",dev->name);
    801							break;
    802						}
    803						rbd->status = 0;
    804						rbd = (struct rbd_struct *) make32(rbd->next);
    805					}
    806					totlen += rstat & RBD_MASK;
    807					rbd->status = 0;
    808					printk("%s: received oversized frame! length: %d\n",dev->name,totlen);
    809					dev->stats.rx_dropped++;
    810			 }
    811		}
    812		else /* frame !(ok), only with 'save-bad-frames' */
    813		{
    814			printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
    815			dev->stats.rx_errors++;
    816		}
    817		p->rfd_top->stat_high = 0;
    818		p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */
    819		p->rfd_top->rbd_offset = 0xffff;
    820		p->rfd_last->last = 0;				/* delete RFD_SUSP	*/
    821		p->rfd_last = p->rfd_top;
    822		p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
    823		p->scb->rfa_offset = make16(p->rfd_top);
    824
    825		if(debuglevel > 0)
    826			printk("%d",cnt++);
    827	}
    828
    829	if(automatic_resume)
    830	{
    831		WAIT_4_SCB_CMD();
    832		p->scb->cmd_ruc = RUC_RESUME;
    833		sun3_attn586();
    834		WAIT_4_SCB_CMD_RUC();
    835	}
    836
    837#ifdef WAIT_4_BUSY
    838	{
    839		int i;
    840		for(i=0;i<1024;i++)
    841		{
    842			if(p->rfd_top->status)
    843				break;
    844			DELAY_16();
    845			if(i == 1023)
    846				printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);
    847		}
    848	}
    849#endif
    850
    851#if 0
    852	if(!at_least_one)
    853	{
    854		int i;
    855		volatile struct rfd_struct *rfds=p->rfd_top;
    856		volatile struct rbd_struct *rbds;
    857		printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);
    858		for(i=0;i< (p->num_recv_buffs+4);i++)
    859		{
    860			rbds = (struct rbd_struct *) make32(rfds->rbd_offset);
    861			printk("%04x:%04x ",rfds->status,rbds->status);
    862			rfds = (struct rfd_struct *) make32(rfds->next);
    863		}
    864		printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
    865		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);
    866	}
    867	old_at_least = at_least_one;
    868#endif
    869
    870	if(debuglevel > 0)
    871		printk("r");
    872}
    873
    874/**********************************************************
    875 * handle 'Receiver went not ready'.
    876 */
    877
    878static void sun3_82586_rnr_int(struct net_device *dev)
    879{
    880	struct priv *p = netdev_priv(dev);
    881
    882	dev->stats.rx_errors++;
    883
    884	WAIT_4_SCB_CMD();		/* wait for the last cmd, WAIT_4_FULLSTAT?? */
    885	p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
    886	sun3_attn586();
    887	WAIT_4_SCB_CMD_RUC();		/* wait for accept cmd. */
    888
    889	alloc_rfa(dev,(char *)p->rfd_first);
    890/* maybe add a check here, before restarting the RU */
    891	startrecv586(dev); /* restart RU */
    892
    893	printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);
    894
    895}
    896
    897/**********************************************************
    898 * handle xmit - interrupt
    899 */
    900
    901static void sun3_82586_xmt_int(struct net_device *dev)
    902{
    903	int status;
    904	struct priv *p = netdev_priv(dev);
    905
    906	if(debuglevel > 0)
    907		printk("X");
    908
    909	status = swab16(p->xmit_cmds[p->xmit_last]->cmd_status);
    910	if(!(status & STAT_COMPL))
    911		printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
    912
    913	if(status & STAT_OK)
    914	{
    915		dev->stats.tx_packets++;
    916		dev->stats.collisions += (status & TCMD_MAXCOLLMASK);
    917	}
    918	else
    919	{
    920		dev->stats.tx_errors++;
    921		if(status & TCMD_LATECOLL) {
    922			printk("%s: late collision detected.\n",dev->name);
    923			dev->stats.collisions++;
    924		}
    925		else if(status & TCMD_NOCARRIER) {
    926			dev->stats.tx_carrier_errors++;
    927			printk("%s: no carrier detected.\n",dev->name);
    928		}
    929		else if(status & TCMD_LOSTCTS)
    930			printk("%s: loss of CTS detected.\n",dev->name);
    931		else if(status & TCMD_UNDERRUN) {
    932			dev->stats.tx_fifo_errors++;
    933			printk("%s: DMA underrun detected.\n",dev->name);
    934		}
    935		else if(status & TCMD_MAXCOLL) {
    936			printk("%s: Max. collisions exceeded.\n",dev->name);
    937			dev->stats.collisions += 16;
    938		}
    939	}
    940
    941#if (NUM_XMIT_BUFFS > 1)
    942	if( (++p->xmit_last) == NUM_XMIT_BUFFS)
    943		p->xmit_last = 0;
    944#endif
    945	netif_wake_queue(dev);
    946}
    947
    948/***********************************************************
    949 * (re)start the receiver
    950 */
    951
    952static void startrecv586(struct net_device *dev)
    953{
    954	struct priv *p = netdev_priv(dev);
    955
    956	WAIT_4_SCB_CMD();
    957	WAIT_4_SCB_CMD_RUC();
    958	p->scb->rfa_offset = make16(p->rfd_first);
    959	p->scb->cmd_ruc = RUC_START;
    960	sun3_attn586();		/* start cmd. */
    961	WAIT_4_SCB_CMD_RUC();	/* wait for accept cmd. (no timeout!!) */
    962}
    963
    964static void sun3_82586_timeout(struct net_device *dev, unsigned int txqueue)
    965{
    966	struct priv *p = netdev_priv(dev);
    967#ifndef NO_NOPCOMMANDS
    968	if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */
    969	{
    970		netif_wake_queue(dev);
    971#ifdef DEBUG
    972		printk("%s: strange ... timeout with CU active?!?\n",dev->name);
    973		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);
    974#endif
    975		p->scb->cmd_cuc = CUC_ABORT;
    976		sun3_attn586();
    977		WAIT_4_SCB_CMD();
    978		p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
    979		p->scb->cmd_cuc = CUC_START;
    980		sun3_attn586();
    981		WAIT_4_SCB_CMD();
    982		netif_trans_update(dev); /* prevent tx timeout */
    983		return 0;
    984	}
    985#endif
    986	{
    987#ifdef DEBUG
    988		printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);
    989		printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status));
    990		printk("%s: check, whether you set the right interrupt number!\n",dev->name);
    991#endif
    992		sun3_82586_close(dev);
    993		sun3_82586_open(dev);
    994	}
    995	netif_trans_update(dev); /* prevent tx timeout */
    996}
    997
    998/******************************************************
    999 * send frame
   1000 */
   1001
   1002static netdev_tx_t
   1003sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
   1004{
   1005	int len,i;
   1006#ifndef NO_NOPCOMMANDS
   1007	int next_nop;
   1008#endif
   1009	struct priv *p = netdev_priv(dev);
   1010
   1011	if(skb->len > XMIT_BUFF_SIZE)
   1012	{
   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 NETDEV_TX_OK;
   1015	}
   1016
   1017	netif_stop_queue(dev);
   1018
   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 NETDEV_TX_BUSY;
   1023	}
   1024	else
   1025#endif
   1026	{
   1027		len = skb->len;
   1028		if (len < ETH_ZLEN) {
   1029			memset((void *)p->xmit_cbuffs[p->xmit_count], 0,
   1030			       ETH_ZLEN);
   1031			len = ETH_ZLEN;
   1032		}
   1033		skb_copy_from_linear_data(skb, (void *)p->xmit_cbuffs[p->xmit_count], skb->len);
   1034
   1035#if (NUM_XMIT_BUFFS == 1)
   1036#	ifdef NO_NOPCOMMANDS
   1037
   1038#ifdef DEBUG
   1039		if(p->scb->cus & CU_ACTIVE)
   1040		{
   1041			printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);
   1042			printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,swab16(p->xmit_cmds[0]->cmd_status));
   1043		}
   1044#endif
   1045
   1046		p->xmit_buffs[0]->size = swab16(TBD_LAST | len);
   1047		for(i=0;i<16;i++)
   1048		{
   1049			p->xmit_cmds[0]->cmd_status = 0;
   1050			WAIT_4_SCB_CMD();
   1051			if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)
   1052				p->scb->cmd_cuc = CUC_RESUME;
   1053			else
   1054			{
   1055				p->scb->cbl_offset = make16(p->xmit_cmds[0]);
   1056				p->scb->cmd_cuc = CUC_START;
   1057			}
   1058
   1059			sun3_attn586();
   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);
   1069		}
   1070#	else
   1071		next_nop = (p->nop_point + 1) & 0x1;
   1072		p->xmit_buffs[0]->size = swab16(TBD_LAST | len);
   1073
   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;
   1077
   1078		p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
   1079		p->nop_point = next_nop;
   1080		dev_kfree_skb(skb);
   1081#	endif
   1082#else
   1083		p->xmit_buffs[p->xmit_count]->size = swab16(TBD_LAST | len);
   1084		if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
   1085			next_nop = 0;
   1086
   1087		p->xmit_cmds[p->xmit_count]->cmd_status	= 0;
   1088		/* linkpointer of xmit-command already points to next nop cmd */
   1089		p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));
   1090		p->nop_cmds[next_nop]->cmd_status = 0;
   1091
   1092		p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
   1093		p->xmit_count = next_nop;
   1094
   1095		{
   1096			unsigned long flags;
   1097			local_irq_save(flags);
   1098			if(p->xmit_count != p->xmit_last)
   1099				netif_wake_queue(dev);
   1100			p->lock = 0;
   1101			local_irq_restore(flags);
   1102		}
   1103		dev_kfree_skb(skb);
   1104#endif
   1105	}
   1106	return NETDEV_TX_OK;
   1107}
   1108
   1109/*******************************************
   1110 * Someone wanna have the statistics
   1111 */
   1112
   1113static struct net_device_stats *sun3_82586_get_stats(struct net_device *dev)
   1114{
   1115	struct priv *p = netdev_priv(dev);
   1116	unsigned short crc,aln,rsc,ovrn;
   1117
   1118	crc = swab16(p->scb->crc_errs); /* get error-statistic from the ni82586 */
   1119	p->scb->crc_errs = 0;
   1120	aln = swab16(p->scb->aln_errs);
   1121	p->scb->aln_errs = 0;
   1122	rsc = swab16(p->scb->rsc_errs);
   1123	p->scb->rsc_errs = 0;
   1124	ovrn = swab16(p->scb->ovrn_errs);
   1125	p->scb->ovrn_errs = 0;
   1126
   1127	dev->stats.rx_crc_errors += crc;
   1128	dev->stats.rx_fifo_errors += ovrn;
   1129	dev->stats.rx_frame_errors += aln;
   1130	dev->stats.rx_dropped += rsc;
   1131
   1132	return &dev->stats;
   1133}
   1134
   1135/********************************************************
   1136 * Set MC list ..
   1137 */
   1138
   1139static void set_multicast_list(struct net_device *dev)
   1140{
   1141	netif_stop_queue(dev);
   1142	sun3_disint();
   1143	alloc586(dev);
   1144	init586(dev);
   1145	startrecv586(dev);
   1146	sun3_enaint();
   1147	netif_wake_queue(dev);
   1148}
   1149
   1150#if 0
   1151/*
   1152 * DUMP .. we expect a not running CMD unit and enough space
   1153 */
   1154void sun3_82586_dump(struct net_device *dev,void *ptr)
   1155{
   1156	struct priv *p = netdev_priv(dev);
   1157	struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;
   1158	int i;
   1159
   1160	p->scb->cmd_cuc = CUC_ABORT;
   1161	sun3_attn586();
   1162	WAIT_4_SCB_CMD();
   1163	WAIT_4_SCB_CMD_RUC();
   1164
   1165	dump_cmd->cmd_status = 0;
   1166	dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;
   1167	dump_cmd->dump_offset = make16((dump_cmd + 1));
   1168	dump_cmd->cmd_link = 0xffff;
   1169
   1170	p->scb->cbl_offset = make16(dump_cmd);
   1171	p->scb->cmd_cuc = CUC_START;
   1172	sun3_attn586();
   1173	WAIT_4_STAT_COMPL(dump_cmd);
   1174
   1175	if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
   1176				printk("%s: Can't get dump information.\n",dev->name);
   1177
   1178	for(i=0;i<170;i++) {
   1179		printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);
   1180		if(i % 24 == 23)
   1181			printk("\n");
   1182	}
   1183	printk("\n");
   1184}
   1185#endif