1 /* daynaport.c: A Macintosh 8390 based ethernet driver for linux. */ 5 Written 1993-94 by Donald Becker. 7 Copyright 1993 United States Government as represented by the 8 Director, National Security Agency. 10 This software may be used and distributed according to the terms 11 of the GNU Public License, incorporated herein by reference. 15 The block output routines may be wrong for non Dayna 18 Fix this driver so that it will attempt to use the info 19 (i.e. iobase, iosize) given to it by the new and improved 22 Despite its misleading filename, this driver is not Dayna-specific 24 /* Cabletron E6100 card support added by Tony Mantler (eek@escape.ca) April 1999 */ 26 static const char*version
= 27 "daynaport.c: v0.02 1999-05-17 Alan Cox (Alan.Cox@linux.org) and others\n"; 28 static int version_printed
; 30 #include <linux/module.h> 31 #include <linux/init.h> 32 #include <linux/kernel.h> 33 #include <linux/sched.h> 34 #include <linux/errno.h> 35 #include <linux/string.h> 36 #include <linux/nubus.h> 38 #include <asm/system.h> 39 #include <asm/hwtest.h> 40 #include <asm/macints.h> 41 #include <linux/delay.h> 43 #include <linux/netdevice.h> 44 #include <linux/etherdevice.h> 47 intns8390_probe1(struct net_device
*dev
,int word16
,char*name
,int id
, 48 int prom
,struct nubus_dev
*ndev
); 50 static intns8390_open(struct net_device
*dev
); 51 static voidns8390_no_reset(struct net_device
*dev
); 52 static intns8390_close_card(struct net_device
*dev
); 55 static voidinterlan_reset(struct net_device
*dev
); 58 static voiddayna_get_8390_hdr(struct net_device
*dev
,struct e8390_pkt_hdr
*hdr
, 60 static voiddayna_block_input(struct net_device
*dev
,int count
, 61 struct sk_buff
*skb
,int ring_offset
); 62 static voiddayna_block_output(struct net_device
*dev
,int count
, 63 const unsigned char*buf
,const int start_page
); 65 /* Sane (32-bit chunk memory read/write) */ 66 static voidsane_get_8390_hdr(struct net_device
*dev
,struct e8390_pkt_hdr
*hdr
, 68 static voidsane_block_input(struct net_device
*dev
,int count
, 69 struct sk_buff
*skb
,int ring_offset
); 70 static voidsane_block_output(struct net_device
*dev
,int count
, 71 const unsigned char*buf
,const int start_page
); 73 /* Slow Sane (16-bit chunk memory read/write) */ 74 static voidslow_sane_get_8390_hdr(struct net_device
*dev
,struct e8390_pkt_hdr
*hdr
, 76 static voidslow_sane_block_input(struct net_device
*dev
,int count
, 77 struct sk_buff
*skb
,int ring_offset
); 78 static voidslow_sane_block_output(struct net_device
*dev
,int count
, 79 const unsigned char*buf
,const int start_page
); 82 #define WD_START_PG 0x00/* First page of TX buffer */ 83 #define WD03_STOP_PG 0x20/* Last page +1 of RX ring */ 84 #define WD13_STOP_PG 0x40/* Last page +1 of RX ring */ 86 #define CABLETRON_RX_START_PG 0x00/* First page of RX buffer */ 87 #define CABLETRON_RX_STOP_PG 0x30/* Last page +1 of RX ring */ 88 #define CABLETRON_TX_START_PG CABLETRON_RX_STOP_PG/* First page of TX buffer */ 91 #define DAYNA_MAC_BASE 0xf0007 92 #define DAYNA_8390_BASE 0x80000/* 3 */ 93 #define DAYNA_8390_MEM 0x00000 94 #define DAYNA_MEMSIZE 0x04000/* First word of each long ! */ 96 #define APPLE_8390_BASE 0xE0000 97 #define APPLE_8390_MEM 0xD0000 98 #define APPLE_MEMSIZE 8192/* FIXME: need to dynamically check */ 100 #define KINETICS_MAC_BASE 0xf0004/* first byte of each long */ 101 #define KINETICS_8390_BASE 0x80000 102 #define KINETICS_8390_MEM 0x00000/* first word of each long */ 103 #define KINETICS_MEMSIZE 8192/* FIXME: need to dynamically check */ 104 /*#define KINETICS_MEMSIZE (0x10000/2) * CSA: on the board I have, at least */ 106 #define CABLETRON_8390_BASE 0x90000 107 #define CABLETRON_8390_MEM 0x00000 109 static inttest_8390(volatilechar*ptr
,int scale
) 114 if(hwreg_present(&ptr
[0x00])==0) 116 if(hwreg_present(&ptr
[0x0D<<scale
])==0) 118 if(hwreg_present(&ptr
[0x0D<<scale
])==0) 120 ptr
[0x00]=E8390_NODMA
+E8390_PAGE1
+E8390_STOP
; 121 regd
=ptr
[0x0D<<scale
]; 122 ptr
[0x0D<<scale
]=0xFF; 123 ptr
[0x00]=E8390_NODMA
+E8390_PAGE0
; 125 if(ptr
[0x0D<<scale
]!=0) 127 ptr
[0x0D<<scale
]=regd
; 130 /* printk("NS8390 found at %p scaled %d\n", ptr,scale);*/ 134 * Identify the species of NS8390 card/driver we need 147 int __init
ns8390_ident(struct nubus_dev
* ndev
) 149 /* This really needs to be tested and tested hard. */ 151 /* Summary of what we know so far -- 152 * SW: 0x0104 -- asante, 16 bit, back4_offsets 153 * SW: 0x010b -- daynaport, 16 bit, fwrd4_offsets 154 * SW: 0x010c -- farallon, 16 bit, back4_offsets, no long word access 155 * SW: 0x011a -- focus, [no details yet] 156 * SW: ?????? -- interlan, 16 bit, back4_offsets, funny reset 157 * SW: ?????? -- kinetics, 8 bit, back4_offsets 158 * -- so i've this hypothesis going that says DrSW&1 says whether the 159 * map is forward or backwards -- and maybe DrSW&256 says what the 160 * register spacing is -- for all cards that report a DrSW in some 162 * This would allow the "apple compatible" driver to drive many 163 * seemingly different types of cards. More DrSW info is needed 164 * to investigate this properly. [CSA, 21-May-1999] 166 /* Dayna ex Kinetics board */ 167 if(ndev
->dr_sw
== NUBUS_DRSW_DAYNA
) 169 if(ndev
->dr_sw
== NUBUS_DRSW_ASANTE
) 170 return NS8390_ASANTE
; 171 if(ndev
->dr_sw
== NUBUS_DRSW_FARALLON
)/* farallon or sonic systems */ 172 return NS8390_FARALLON
; 173 if(ndev
->dr_sw
== NUBUS_DRSW_KINETICS
) 174 return NS8390_KINETICS
; 175 /* My ATI Engineering card with this combination crashes the */ 176 /* driver trying to xmit packets. Best not touch it for now. */ 177 /* - 1999-05-20 (funaho@jurai.org) */ 178 if(ndev
->dr_sw
== NUBUS_DRSW_FOCUS
) 181 /* Check the HW on this one, because it shares the same DrSW as 182 the on-board SONIC chips */ 183 if(ndev
->dr_hw
== NUBUS_DRHW_CABLETRON
) 184 return NS8390_CABLETRON
; 185 /* does anyone have one of these? */ 186 if(ndev
->dr_hw
== NUBUS_DRHW_INTERLAN
) 187 return NS8390_INTERLAN
; 189 /* FIXME: what do genuine Apple boards look like? */ 194 * Memory probe for 8390 cards 197 int __init
apple_8390_mem_probe(volatileunsigned short*p
) 202 * 1. Check each block size of memory doesn't fault 203 * 2. Write a value to it 204 * 3. Check all previous blocks are unaffected 209 volatileunsigned short*m
=p
+4096*i
; 210 /* Unwriteable - we have a fully decoded card and the 213 if(hwreg_present(m
)==0) 220 /* Partial decode and wrap ? */ 221 if(p
[4096*j
]!=(0xA5A0|j
)) 223 /* This is the first misdecode, so it had 224 one less page than we tried */ 229 /* Ok it still decodes.. move on 8K */ 232 * We don't look past 16K. That should cover most cards 233 * and above 16K there isnt really any gain. 239 * Probe for 8390 cards. 240 * The ns8390_probe1() routine initializes the card and fills the 241 * station address field. 243 * The NuBus interface has changed! We now scan for these somewhat 244 * like how the PCI and Zorro drivers do. It's not clear whether 245 * this is actually better, but it makes things more consistent. 247 * dev->mem_start points 248 * at the memory ring, dev->mem_end gives the end of it. 251 int __init
mac8390_probe(struct net_device
*dev
) 254 volatileunsigned short*i
; 255 volatileunsigned char*p
; 258 static struct nubus_dev
* ndev
= NULL
; 260 /* Find the first card that hasn't already been seen */ 261 while((ndev
=nubus_find_type(NUBUS_CAT_NETWORK
, 262 NUBUS_TYPE_ETHERNET
, ndev
)) != NULL
) { 263 /* Have we seen it already? */ 264 if(slots
& (1<<ndev
->board
->slot
)) 266 slots
|=1<<ndev
->board
->slot
; 268 /* Is it one of ours? */ 269 if((id
=ns8390_ident(ndev
)) != -1) 273 /* Hm. No more cards, then */ 277 dev
=init_etherdev(dev
,0); 279 if(!version_printed
) { 280 printk(KERN_INFO
"%s", version
); 285 * Dayna specific init 289 dev
->base_addr
= (int)(ndev
->board
->slot_addr
+DAYNA_8390_BASE
); 290 dev
->mem_start
= (int)(ndev
->board
->slot_addr
+DAYNA_8390_MEM
); 291 dev
->mem_end
= dev
->mem_start
+DAYNA_MEMSIZE
;/* 8K it seems */ 293 printk(KERN_INFO
"%s: daynaport. testing board: ", dev
->name
); 297 i
= (void*)dev
->mem_start
; 298 memset((void*)i
,0xAA, DAYNA_MEMSIZE
); 299 while(i
<(volatileunsigned short*)dev
->mem_end
) 303 *i
=0x5678;/* make sure we catch byte smearing */ 306 i
+=2;/* Skip a word */ 309 printk("controller - "); 311 p
=(void*)dev
->base_addr
; 316 if(test_8390(p
,0)==0) 318 if(test_8390(p
,1)==0) 320 if(test_8390(p
,2)==0) 322 if(test_8390(p
,3)==0) 330 dev
->irq
=SLOT2IRQ(ndev
->board
->slot
); 331 if(ns8390_probe1(dev
,0,"dayna", id
, -1, ndev
)==0) 335 if(id
==NS8390_CABLETRON
) { 336 int memsize
=16<<10;/* fix this */ 338 dev
->base_addr
=(int)(ndev
->board
->slot_addr
+CABLETRON_8390_BASE
); 339 dev
->mem_start
=(int)(ndev
->board
->slot_addr
+CABLETRON_8390_MEM
); 340 dev
->mem_end
=dev
->mem_start
+memsize
; 341 dev
->irq
=SLOT2IRQ(ndev
->board
->slot
); 343 /* The base address is unreadable if 0x00 has been written to the command register */ 344 /* Reset the chip by writing E8390_NODMA+E8390_PAGE0+E8390_STOP just to be sure */ 345 i
= (void*)dev
->base_addr
; 348 printk(KERN_INFO
"%s: cabletron: testing board: ", dev
->name
); 349 printk("%dK memory - ", memsize
>>10); 350 i
=(void*)dev
->mem_start
; 351 while(i
<(volatileunsigned short*)(dev
->mem_start
+memsize
)) 359 i
+=2;/* Skip a word */ 363 if(ns8390_probe1(dev
,1,"cabletron", id
, -1, ndev
)==0) 366 /* Apple, Farallon, Asante */ 367 if(id
==NS8390_APPLE
|| id
==NS8390_FARALLON
|| id
==NS8390_ASANTE
) 371 dev
->base_addr
=(int)(ndev
->board
->slot_addr
+APPLE_8390_BASE
); 372 dev
->mem_start
=(int)(ndev
->board
->slot_addr
+APPLE_8390_MEM
); 374 memsize
=apple_8390_mem_probe((void*)dev
->mem_start
); 376 dev
->mem_end
=dev
->mem_start
+memsize
; 377 dev
->irq
=SLOT2IRQ(ndev
->board
->slot
); 381 case NS8390_FARALLON
: 382 printk(KERN_INFO
"%s: farallon: testing board: ", dev
->name
); 385 printk(KERN_INFO
"%s: asante: testing board: ", dev
->name
); 389 printk(KERN_INFO
"%s: apple/clone: testing board: ", dev
->name
); 393 printk("%dK memory - ", memsize
>>10); 395 i
=(void*)dev
->mem_start
; 396 memset((void*)i
,0xAA, memsize
); 397 while(i
<(volatileunsigned short*)dev
->mem_end
) 404 i
+=2;/* Skip a word */ 410 case NS8390_FARALLON
: 411 if(ns8390_probe1(dev
,1,"farallon", id
, -1, ndev
)==0) 415 if(ns8390_probe1(dev
,1,"asante", id
, -1, ndev
)==0) 420 if(ns8390_probe1(dev
,1,"apple/clone", id
, -1, ndev
)==0) 426 if(id
==NS8390_INTERLAN
) 428 /* As apple and asante */ 429 dev
->base_addr
=(int)(ndev
->board
->slot_addr
+APPLE_8390_BASE
); 430 dev
->mem_start
=(int)(ndev
->board
->slot_addr
+APPLE_8390_MEM
); 431 dev
->mem_end
=dev
->mem_start
+APPLE_MEMSIZE
;/* 8K it seems */ 432 dev
->irq
=SLOT2IRQ(ndev
->board
->slot
); 433 if(ns8390_probe1(dev
,1,"interlan", id
, -1, ndev
)==0) 436 /* Kinetics (Shiva Etherport) */ 437 if(id
==NS8390_KINETICS
) 439 dev
->base_addr
=(int)(ndev
->board
->slot_addr
+KINETICS_8390_BASE
); 440 dev
->mem_start
=(int)(ndev
->board
->slot_addr
+KINETICS_8390_MEM
); 441 dev
->mem_end
=dev
->mem_start
+KINETICS_MEMSIZE
;/* 8K it seems */ 442 dev
->irq
=SLOT2IRQ(ndev
->board
->slot
); 443 if(ns8390_probe1(dev
,0,"kinetics", id
, -1, ndev
)==0) 447 /* We should hopefully not get here */ 448 printk(KERN_ERR
"Probe unsucessful.\n"); 452 printk(KERN_ERR
"failed at %p in %p - %p.\n", i
, 453 (void*)dev
->mem_start
, (void*)dev
->mem_end
); 457 int __init
mac8390_ethernet_addr(struct nubus_dev
* ndev
, 458 unsigned char addr
[6]) 460 struct nubus_dir dir
; 461 struct nubus_dirent ent
; 463 /* Get the functional resource for this device */ 464 if(nubus_get_func_dir(ndev
, &dir
) == -1) 466 if(nubus_find_rsrc(&dir
, NUBUS_RESID_MAC_ADDRESS
, &ent
) == -1) 469 nubus_get_rsrc_mem(addr
, &ent
,6); 473 int __init
ns8390_probe1(struct net_device
*dev
,int word16
,char*model_name
, 474 int type
,int promoff
,struct nubus_dev
*ndev
) 476 static u32 fwrd4_offsets
[16]={ 482 static u32 back4_offsets
[16]={ 488 static u32 fwrd2_offsets
[16]={ 495 unsigned char*prom
= (unsigned char*) ndev
->board
->slot_addr
+ promoff
; 497 /* Allocate dev->priv and fill in 8390 specific dev fields. */ 500 printk("%s: unable to get memory for dev->priv.\n", dev
->name
); 504 /* OK, we are certain this is going to work. Setup the device. */ 506 ei_status
.name
= model_name
; 507 ei_status
.word16
= word16
; 509 if(type
==NS8390_CABLETRON
) { 510 /* Cabletron card puts the RX buffer before the TX buffer */ 511 ei_status
.tx_start_page
= CABLETRON_TX_START_PG
; 512 ei_status
.rx_start_page
= CABLETRON_RX_START_PG
; 513 ei_status
.stop_page
= CABLETRON_RX_STOP_PG
; 514 dev
->rmem_start
= dev
->mem_start
; 515 dev
->rmem_end
= dev
->mem_start
+ CABLETRON_RX_STOP_PG
*256; 517 ei_status
.tx_start_page
= WD_START_PG
; 518 ei_status
.rx_start_page
= WD_START_PG
+ TX_PAGES
; 519 ei_status
.stop_page
= (dev
->mem_end
- dev
->mem_start
)/256; 520 dev
->rmem_start
= dev
->mem_start
+ TX_PAGES
*256; 521 dev
->rmem_end
= dev
->mem_end
; 524 if(promoff
==-1)/* Use nubus resources ? */ 526 if(mac8390_ethernet_addr(ndev
, dev
->dev_addr
)) 528 printk("mac_ns8390: MAC address not in resources!\n"); 532 else/* Pull it off the card */ 536 /* These should go in the end I hope */ 537 if(type
==NS8390_DAYNA
) 539 if(type
==NS8390_INTERLAN
|| type
==NS8390_KINETICS
) 543 dev
->dev_addr
[i
]=*prom
; 547 printk("%02X",dev
->dev_addr
[i
++]); 551 printk(KERN_INFO
"%s: %s in slot %X (type %s)\n", 552 dev
->name
, ndev
->board
->name
, ndev
->board
->slot
, model_name
); 553 printk(KERN_INFO
"MAC "); 556 for(i
=0; i
<6; i
++) { 557 printk("%2.2x", dev
->dev_addr
[i
]); 562 printk(" IRQ %d, shared memory at %#lx-%#lx.\n", 563 dev
->irq
, dev
->mem_start
, dev
->mem_end
-1); 567 case NS8390_DAYNA
:/* Dayna card */ 568 case NS8390_KINETICS
:/* Kinetics -- 8 bit config, but 16 bit mem */ 569 /* 16 bit, 4 word offsets */ 570 ei_status
.reset_8390
= &ns8390_no_reset
; 571 ei_status
.block_input
= &dayna_block_input
; 572 ei_status
.block_output
= &dayna_block_output
; 573 ei_status
.get_8390_hdr
= &dayna_get_8390_hdr
; 574 ei_status
.reg_offset
= fwrd4_offsets
; 576 case NS8390_CABLETRON
:/* Cabletron */ 577 /* 16 bit card, register map is short forward */ 578 ei_status
.reset_8390
= &ns8390_no_reset
; 579 /* Ctron card won't accept 32bit values read or written to it */ 580 ei_status
.block_input
= &slow_sane_block_input
; 581 ei_status
.block_output
= &slow_sane_block_output
; 582 ei_status
.get_8390_hdr
= &slow_sane_get_8390_hdr
; 583 ei_status
.reg_offset
= fwrd2_offsets
; 585 case NS8390_FARALLON
: 586 case NS8390_APPLE
:/* Apple/Asante/Farallon */ 587 /* 16 bit card, register map is reversed */ 588 ei_status
.reset_8390
= &ns8390_no_reset
; 589 ei_status
.block_input
= &slow_sane_block_input
; 590 ei_status
.block_output
= &slow_sane_block_output
; 591 ei_status
.get_8390_hdr
= &slow_sane_get_8390_hdr
; 592 ei_status
.reg_offset
= back4_offsets
; 595 /* 16 bit card, register map is reversed */ 596 ei_status
.reset_8390
= &ns8390_no_reset
; 597 ei_status
.block_input
= &sane_block_input
; 598 ei_status
.block_output
= &sane_block_output
; 599 ei_status
.get_8390_hdr
= &sane_get_8390_hdr
; 600 ei_status
.reg_offset
= back4_offsets
; 602 case NS8390_INTERLAN
:/* Interlan */ 603 /* 16 bit card, map is forward */ 604 ei_status
.reset_8390
= &interlan_reset
; 605 ei_status
.block_input
= &sane_block_input
; 606 ei_status
.block_output
= &sane_block_output
; 607 ei_status
.get_8390_hdr
= &sane_get_8390_hdr
; 608 ei_status
.reg_offset
= back4_offsets
; 610 #if 0/* i think this suffered code rot. my kinetics card has much 611 * different settings. -- CSA [22-May-1999] */ 612 case NS8390_KINETICS
:/* Kinetics */ 613 /* 8bit card, map is forward */ 614 ei_status
.reset_8390
= &ns8390_no_reset
; 615 ei_status
.block_input
= &sane_block_input
; 616 ei_status
.block_output
= &sane_block_output
; 617 ei_status
.get_8390_hdr
= &sane_get_8390_hdr
; 618 ei_status
.reg_offset
= back4_offsets
; 622 panic("Detected a card I can't drive - whoops\n"); 624 dev
->open
= &ns8390_open
; 625 dev
->stop
= &ns8390_close_card
; 632 static intns8390_open(struct net_device
*dev
) 637 /* At least on my card (a Focus Enhancements PDS card) I start */ 638 /* getting interrupts right away, so the driver needs to be */ 639 /* completely initialized before enabling the interrupt. */ 640 /* - funaho@jurai.org (1999-05-17) */ 642 /* Non-slow interrupt, works around issues with the SONIC driver */ 643 if(request_irq(dev
->irq
, ei_interrupt
,0,"8390 Ethernet", dev
)) 645 printk("%s: unable to get IRQ %d.\n", dev
->name
, dev
->irq
); 652 static voidns8390_no_reset(struct net_device
*dev
) 655 printk("Need to reset the NS8390 t=%lu...", jiffies
); 657 if(ei_debug
>1)printk("reset not supported\n"); 661 static intns8390_close_card(struct net_device
*dev
) 664 printk("%s: Shutting down ethercard.\n", dev
->name
); 665 free_irq(dev
->irq
, dev
); 672 * Interlan Specific Code Starts Here 675 static voidinterlan_reset(struct net_device
*dev
) 677 unsigned char*target
=nubus_slot_addr(IRQ2SLOT(dev
->irq
)); 679 printk("Need to reset the NS8390 t=%lu...", jiffies
); 681 /* This write resets the card */ 683 if(ei_debug
>1)printk("reset complete\n"); 688 * Daynaport code (some is used by other drivers) 692 /* Grab the 8390 specific header. Similar to the block_input routine, but 693 we don't need to be concerned with ring wrap as the header will be at 694 the start of a page, so we optimize accordingly. */ 697 /* Block input and output are easy on shared memory ethercards, and trivial 698 on the Daynaport card where there is no choice of how to do it. 699 The only complications are that the ring buffer wraps. 702 static voiddayna_memcpy_fromcard(struct net_device
*dev
,void*to
,int from
,int count
) 704 volatileunsigned short*ptr
; 705 unsigned short*target
=to
; 706 from
<<=1;/* word, skip overhead */ 707 ptr
=(unsigned short*)(dev
->mem_start
+from
); 712 *((char*)target
)++ = *(((char*)ptr
++)-1); 717 *target
++=*ptr
++;/* Copy and */ 718 ptr
++;/* skip cruft */ 727 unsigned short v
=*ptr
; 728 *((char*)target
)=v
>>8; 732 static voiddayna_memcpy_tocard(struct net_device
*dev
,int to
,const void*from
,int count
) 734 volatileunsigned short*ptr
; 735 const unsigned short*src
=from
; 736 to
<<=1;/* word, skip overhead */ 737 ptr
=(unsigned short*)(dev
->mem_start
+to
); 741 if(to
&2) {/* avoid a byte write (stomps on other data) */ 742 ptr
[-1] = (ptr
[-1]&0xFF00)|*((unsigned char*)src
)++; 748 *ptr
++=*src
++;/* Copy and */ 749 ptr
++;/* skip cruft */ 758 unsigned short v
=*src
; 759 /* card doesn't like byte writes */ 760 *ptr
=(*ptr
&0x00FF)|(v
&0xFF00); 764 static voiddayna_get_8390_hdr(struct net_device
*dev
,struct e8390_pkt_hdr
*hdr
,int ring_page
) 766 unsigned long hdr_start
= (ring_page
- WD_START_PG
)<<8; 767 dayna_memcpy_fromcard(dev
, (void*)hdr
, hdr_start
,4); 768 /* Register endianism - fix here rather than 8390.c */ 769 hdr
->count
=(hdr
->count
&0xFF)<<8|(hdr
->count
>>8); 772 static voiddayna_block_input(struct net_device
*dev
,int count
,struct sk_buff
*skb
,int ring_offset
) 774 unsigned long xfer_base
= ring_offset
- (WD_START_PG
<<8); 775 unsigned long xfer_start
= xfer_base
+dev
->mem_start
; 778 * Note the offset maths is done in card memory space which 779 * is word per long onto our space. 782 if(xfer_start
+ count
> dev
->rmem_end
) 784 /* We must wrap the input move. */ 785 int semi_count
= dev
->rmem_end
- xfer_start
; 786 dayna_memcpy_fromcard(dev
, skb
->data
, xfer_base
, semi_count
); 788 dayna_memcpy_fromcard(dev
, skb
->data
+ semi_count
, 789 dev
->rmem_start
- dev
->mem_start
, count
); 793 dayna_memcpy_fromcard(dev
, skb
->data
, xfer_base
, count
); 797 static voiddayna_block_output(struct net_device
*dev
,int count
,const unsigned char*buf
, 800 long shmem
= (start_page
- WD_START_PG
)<<8; 802 dayna_memcpy_tocard(dev
, shmem
, buf
, count
); 806 * Cards with full width memory 810 static voidsane_get_8390_hdr(struct net_device
*dev
,struct e8390_pkt_hdr
*hdr
,int ring_page
) 812 unsigned long hdr_start
= (ring_page
- WD_START_PG
)<<8; 813 memcpy((void*)hdr
, (char*)dev
->mem_start
+hdr_start
,4); 814 /* Register endianism - fix here rather than 8390.c */ 815 hdr
->count
=(hdr
->count
&0xFF)<<8|(hdr
->count
>>8); 818 static voidsane_block_input(struct net_device
*dev
,int count
,struct sk_buff
*skb
,int ring_offset
) 820 unsigned long xfer_base
= ring_offset
- (WD_START_PG
<<8); 821 unsigned long xfer_start
= xfer_base
+dev
->mem_start
; 823 if(xfer_start
+ count
> dev
->rmem_end
) 825 /* We must wrap the input move. */ 826 int semi_count
= dev
->rmem_end
- xfer_start
; 827 memcpy(skb
->data
, (char*)dev
->mem_start
+xfer_base
, semi_count
); 829 memcpy(skb
->data
+ semi_count
, 830 (char*)dev
->rmem_start
, count
); 834 memcpy(skb
->data
, (char*)dev
->mem_start
+xfer_base
, count
); 839 static voidsane_block_output(struct net_device
*dev
,int count
,const unsigned char*buf
, 842 long shmem
= (start_page
- WD_START_PG
)<<8; 844 memcpy((char*)dev
->mem_start
+shmem
, buf
, count
); 847 static voidword_memcpy_tocard(void*tp
,const void*fp
,int count
) 849 volatileunsigned short*to
= tp
; 850 const unsigned short*from
= fp
; 859 static voidword_memcpy_fromcard(void*tp
,const void*fp
,int count
) 861 unsigned short*to
= tp
; 862 constvolatileunsigned short*from
= fp
; 871 static voidslow_sane_get_8390_hdr(struct net_device
*dev
,struct e8390_pkt_hdr
*hdr
,int ring_page
) 873 unsigned long hdr_start
= (ring_page
- WD_START_PG
)<<8; 874 word_memcpy_fromcard((void*)hdr
, (char*)dev
->mem_start
+hdr_start
,4); 875 /* Register endianism - fix here rather than 8390.c */ 876 hdr
->count
=(hdr
->count
&0xFF)<<8|(hdr
->count
>>8); 879 static voidslow_sane_block_input(struct net_device
*dev
,int count
,struct sk_buff
*skb
,int ring_offset
) 881 unsigned long xfer_base
= ring_offset
- (WD_START_PG
<<8); 882 unsigned long xfer_start
= xfer_base
+dev
->mem_start
; 884 if(xfer_start
+ count
> dev
->rmem_end
) 886 /* We must wrap the input move. */ 887 int semi_count
= dev
->rmem_end
- xfer_start
; 888 word_memcpy_fromcard(skb
->data
, (char*)dev
->mem_start
+xfer_base
, semi_count
); 890 word_memcpy_fromcard(skb
->data
+ semi_count
, 891 (char*)dev
->rmem_start
, count
); 895 word_memcpy_fromcard(skb
->data
, (char*)dev
->mem_start
+xfer_base
, count
); 899 static voidslow_sane_block_output(struct net_device
*dev
,int count
,const unsigned char*buf
, 902 long shmem
= (start_page
- WD_START_PG
)<<8; 904 word_memcpy_tocard((char*)dev
->mem_start
+shmem
, buf
, count
); 906 long shmem
= (start_page
- WD_START_PG
)<<8; 907 volatileunsigned short*to
=(unsigned short*)(dev
->mem_start
+shmem
); 909 unsigned short*bp
=(unsigned short*)buf
; 924 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c daynaport.c" 928 * kept-new-versions: 5