Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.24 862 lines 24 kB view raw
1/* mac8390.c: New driver for 8390-based Nubus (or Nubus-alike) 2 Ethernet cards on Linux */ 3/* Based on the former daynaport.c driver, by Alan Cox. Some code 4 taken from or inspired by skeleton.c by Donald Becker, acenic.c by 5 Jes Sorensen, and ne2k-pci.c by Donald Becker and Paul Gortmaker. 6 7 This software may be used and distributed according to the terms of 8 the GNU Public License, incorporated herein by reference. */ 9 10/* 2000-02-28: support added for Dayna and Kinetics cards by 11 A.G.deWijn@phys.uu.nl */ 12/* 2000-04-04: support added for Dayna2 by bart@etpmod.phys.tue.nl */ 13/* 2001-04-18: support for DaynaPort E/LC-M by rayk@knightsmanor.org */ 14/* 2001-05-15: support for Cabletron ported from old daynaport driver 15 * and fixed access to Sonic Sys card which masquerades as a Farallon 16 * by rayk@knightsmanor.org */ 17/* 2002-12-30: Try to support more cards, some clues from NetBSD driver */ 18/* 2003-12-26: Make sure Asante cards always work. */ 19 20#include <linux/module.h> 21#include <linux/kernel.h> 22#include <linux/types.h> 23#include <linux/fcntl.h> 24#include <linux/interrupt.h> 25#include <linux/ptrace.h> 26#include <linux/ioport.h> 27#include <linux/nubus.h> 28#include <linux/in.h> 29#include <linux/slab.h> 30#include <linux/string.h> 31#include <linux/errno.h> 32#include <linux/init.h> 33#include <linux/netdevice.h> 34#include <linux/etherdevice.h> 35#include <linux/skbuff.h> 36#include <linux/bitops.h> 37 38#include <asm/system.h> 39#include <asm/io.h> 40#include <asm/dma.h> 41#include <asm/hwtest.h> 42#include <asm/macints.h> 43 44static char version[] = 45 "mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n"; 46 47#define EI_SHIFT(x) (ei_local->reg_offset[x]) 48#define ei_inb(port) in_8(port) 49#define ei_outb(val,port) out_8(port,val) 50#define ei_inb_p(port) in_8(port) 51#define ei_outb_p(val,port) out_8(port,val) 52 53#include "lib8390.c" 54 55#define WD_START_PG 0x00 /* First page of TX buffer */ 56#define CABLETRON_RX_START_PG 0x00 /* First page of RX buffer */ 57#define CABLETRON_RX_STOP_PG 0x30 /* Last page +1 of RX ring */ 58#define CABLETRON_TX_START_PG CABLETRON_RX_STOP_PG /* First page of TX buffer */ 59 60/* Unfortunately it seems we have to hardcode these for the moment */ 61/* Shouldn't the card know about this? Does anyone know where to read it off the card? Do we trust the data provided by the card? */ 62 63#define DAYNA_8390_BASE 0x80000 64#define DAYNA_8390_MEM 0x00000 65 66#define CABLETRON_8390_BASE 0x90000 67#define CABLETRON_8390_MEM 0x00000 68 69#define INTERLAN_8390_BASE 0xE0000 70#define INTERLAN_8390_MEM 0xD0000 71 72enum mac8390_type { 73 MAC8390_NONE = -1, 74 MAC8390_APPLE, 75 MAC8390_ASANTE, 76 MAC8390_FARALLON, 77 MAC8390_CABLETRON, 78 MAC8390_DAYNA, 79 MAC8390_INTERLAN, 80 MAC8390_KINETICS, 81}; 82 83static const char * cardname[] = { 84 "apple", 85 "asante", 86 "farallon", 87 "cabletron", 88 "dayna", 89 "interlan", 90 "kinetics", 91}; 92 93static int word16[] = { 94 1, /* apple */ 95 1, /* asante */ 96 1, /* farallon */ 97 1, /* cabletron */ 98 0, /* dayna */ 99 1, /* interlan */ 100 0, /* kinetics */ 101}; 102 103/* on which cards do we use NuBus resources? */ 104static int useresources[] = { 105 1, /* apple */ 106 1, /* asante */ 107 1, /* farallon */ 108 0, /* cabletron */ 109 0, /* dayna */ 110 0, /* interlan */ 111 0, /* kinetics */ 112}; 113 114enum mac8390_access { 115 ACCESS_UNKNOWN = 0, 116 ACCESS_32, 117 ACCESS_16, 118}; 119 120extern enum mac8390_type mac8390_ident(struct nubus_dev * dev); 121extern int mac8390_memsize(unsigned long membase); 122extern int mac8390_memtest(struct net_device * dev); 123static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, 124 enum mac8390_type type); 125 126static int mac8390_open(struct net_device * dev); 127static int mac8390_close(struct net_device * dev); 128static void mac8390_no_reset(struct net_device *dev); 129static void interlan_reset(struct net_device *dev); 130 131/* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/ 132static void sane_get_8390_hdr(struct net_device *dev, 133 struct e8390_pkt_hdr *hdr, int ring_page); 134static void sane_block_input(struct net_device * dev, int count, 135 struct sk_buff * skb, int ring_offset); 136static void sane_block_output(struct net_device * dev, int count, 137 const unsigned char * buf, const int start_page); 138 139/* dayna_memcpy to and from card */ 140static void dayna_memcpy_fromcard(struct net_device *dev, void *to, 141 int from, int count); 142static void dayna_memcpy_tocard(struct net_device *dev, int to, 143 const void *from, int count); 144 145/* Dayna - Dayna/Kinetics use this */ 146static void dayna_get_8390_hdr(struct net_device *dev, 147 struct e8390_pkt_hdr *hdr, int ring_page); 148static void dayna_block_input(struct net_device *dev, int count, 149 struct sk_buff *skb, int ring_offset); 150static void dayna_block_output(struct net_device *dev, int count, 151 const unsigned char *buf, int start_page); 152 153#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) 154#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) 155 156/* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */ 157static void slow_sane_get_8390_hdr(struct net_device *dev, 158 struct e8390_pkt_hdr *hdr, int ring_page); 159static void slow_sane_block_input(struct net_device *dev, int count, 160 struct sk_buff *skb, int ring_offset); 161static void slow_sane_block_output(struct net_device *dev, int count, 162 const unsigned char *buf, int start_page); 163static void word_memcpy_tocard(void *tp, const void *fp, int count); 164static void word_memcpy_fromcard(void *tp, const void *fp, int count); 165 166enum mac8390_type __init mac8390_ident(struct nubus_dev * dev) 167{ 168 switch (dev->dr_sw) { 169 case NUBUS_DRSW_3COM: 170 switch (dev->dr_hw) { 171 case NUBUS_DRHW_APPLE_SONIC_NB: 172 case NUBUS_DRHW_APPLE_SONIC_LC: 173 case NUBUS_DRHW_SONNET: 174 return MAC8390_NONE; 175 break; 176 default: 177 return MAC8390_APPLE; 178 break; 179 } 180 break; 181 182 case NUBUS_DRSW_APPLE: 183 switch (dev->dr_hw) { 184 case NUBUS_DRHW_ASANTE_LC: 185 return MAC8390_NONE; 186 break; 187 case NUBUS_DRHW_CABLETRON: 188 return MAC8390_CABLETRON; 189 break; 190 default: 191 return MAC8390_APPLE; 192 break; 193 } 194 break; 195 196 case NUBUS_DRSW_ASANTE: 197 return MAC8390_ASANTE; 198 break; 199 200 case NUBUS_DRSW_TECHWORKS: 201 case NUBUS_DRSW_DAYNA2: 202 case NUBUS_DRSW_DAYNA_LC: 203 if (dev->dr_hw == NUBUS_DRHW_CABLETRON) 204 return MAC8390_CABLETRON; 205 else 206 return MAC8390_APPLE; 207 break; 208 209 case NUBUS_DRSW_FARALLON: 210 return MAC8390_FARALLON; 211 break; 212 213 case NUBUS_DRSW_KINETICS: 214 switch (dev->dr_hw) { 215 case NUBUS_DRHW_INTERLAN: 216 return MAC8390_INTERLAN; 217 break; 218 default: 219 return MAC8390_KINETICS; 220 break; 221 } 222 break; 223 224 case NUBUS_DRSW_DAYNA: 225 // These correspond to Dayna Sonic cards 226 // which use the macsonic driver 227 if (dev->dr_hw == NUBUS_DRHW_SMC9194 || 228 dev->dr_hw == NUBUS_DRHW_INTERLAN ) 229 return MAC8390_NONE; 230 else 231 return MAC8390_DAYNA; 232 break; 233 } 234 return MAC8390_NONE; 235} 236 237enum mac8390_access __init mac8390_testio(volatile unsigned long membase) 238{ 239 unsigned long outdata = 0xA5A0B5B0; 240 unsigned long indata = 0x00000000; 241 /* Try writing 32 bits */ 242 memcpy((char *)membase, (char *)&outdata, 4); 243 /* Now compare them */ 244 if (memcmp((char *)&outdata, (char *)membase, 4) == 0) 245 return ACCESS_32; 246 /* Write 16 bit output */ 247 word_memcpy_tocard((char *)membase, (char *)&outdata, 4); 248 /* Now read it back */ 249 word_memcpy_fromcard((char *)&indata, (char *)membase, 4); 250 if (outdata == indata) 251 return ACCESS_16; 252 return ACCESS_UNKNOWN; 253} 254 255int __init mac8390_memsize(unsigned long membase) 256{ 257 unsigned long flags; 258 int i, j; 259 260 local_irq_save(flags); 261 /* Check up to 32K in 4K increments */ 262 for (i = 0; i < 8; i++) { 263 volatile unsigned short *m = (unsigned short *) (membase + (i * 0x1000)); 264 265 /* Unwriteable - we have a fully decoded card and the 266 RAM end located */ 267 if (hwreg_present(m) == 0) 268 break; 269 270 /* write a distinctive byte */ 271 *m = 0xA5A0 | i; 272 /* check that we read back what we wrote */ 273 if (*m != (0xA5A0 | i)) 274 break; 275 276 /* check for partial decode and wrap */ 277 for (j = 0; j < i; j++) { 278 volatile unsigned short *p = (unsigned short *) (membase + (j * 0x1000)); 279 if (*p != (0xA5A0 | j)) 280 break; 281 } 282 } 283 local_irq_restore(flags); 284 /* in any case, we stopped once we tried one block too many, 285 or once we reached 32K */ 286 return i * 0x1000; 287} 288 289struct net_device * __init mac8390_probe(int unit) 290{ 291 struct net_device *dev; 292 volatile unsigned short *i; 293 int version_disp = 0; 294 struct nubus_dev * ndev = NULL; 295 int err = -ENODEV; 296 297 struct nubus_dir dir; 298 struct nubus_dirent ent; 299 int offset; 300 static unsigned int slots; 301 302 enum mac8390_type cardtype; 303 304 /* probably should check for Nubus instead */ 305 306 if (!MACH_IS_MAC) 307 return ERR_PTR(-ENODEV); 308 309 dev = ____alloc_ei_netdev(0); 310 if (!dev) 311 return ERR_PTR(-ENOMEM); 312 313 if (unit >= 0) 314 sprintf(dev->name, "eth%d", unit); 315 316 while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) { 317 /* Have we seen it already? */ 318 if (slots & (1<<ndev->board->slot)) 319 continue; 320 slots |= 1<<ndev->board->slot; 321 322 if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE) 323 continue; 324 325 if (version_disp == 0) { 326 version_disp = 1; 327 printk(version); 328 } 329 330 dev->irq = SLOT2IRQ(ndev->board->slot); 331 /* This is getting to be a habit */ 332 dev->base_addr = ndev->board->slot_addr | ((ndev->board->slot&0xf) << 20); 333 334 /* Get some Nubus info - we will trust the card's idea 335 of where its memory and registers are. */ 336 337 if (nubus_get_func_dir(ndev, &dir) == -1) { 338 printk(KERN_ERR "%s: Unable to get Nubus functional" 339 " directory for slot %X!\n", 340 dev->name, ndev->board->slot); 341 continue; 342 } 343 344 /* Get the MAC address */ 345 if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) { 346 printk(KERN_INFO "%s: Couldn't get MAC address!\n", 347 dev->name); 348 continue; 349 } else { 350 nubus_get_rsrc_mem(dev->dev_addr, &ent, 6); 351 } 352 353 if (useresources[cardtype] == 1) { 354 nubus_rewinddir(&dir); 355 if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) { 356 printk(KERN_ERR "%s: Memory offset resource" 357 " for slot %X not found!\n", 358 dev->name, ndev->board->slot); 359 continue; 360 } 361 nubus_get_rsrc_mem(&offset, &ent, 4); 362 dev->mem_start = dev->base_addr + offset; 363 /* yes, this is how the Apple driver does it */ 364 dev->base_addr = dev->mem_start + 0x10000; 365 nubus_rewinddir(&dir); 366 if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, &ent) == -1) { 367 printk(KERN_INFO "%s: Memory length resource" 368 " for slot %X not found" 369 ", probing\n", 370 dev->name, ndev->board->slot); 371 offset = mac8390_memsize(dev->mem_start); 372 } else { 373 nubus_get_rsrc_mem(&offset, &ent, 4); 374 } 375 dev->mem_end = dev->mem_start + offset; 376 } else { 377 switch (cardtype) { 378 case MAC8390_KINETICS: 379 case MAC8390_DAYNA: /* it's the same */ 380 dev->base_addr = 381 (int)(ndev->board->slot_addr + 382 DAYNA_8390_BASE); 383 dev->mem_start = 384 (int)(ndev->board->slot_addr + 385 DAYNA_8390_MEM); 386 dev->mem_end = 387 dev->mem_start + 388 mac8390_memsize(dev->mem_start); 389 break; 390 case MAC8390_INTERLAN: 391 dev->base_addr = 392 (int)(ndev->board->slot_addr + 393 INTERLAN_8390_BASE); 394 dev->mem_start = 395 (int)(ndev->board->slot_addr + 396 INTERLAN_8390_MEM); 397 dev->mem_end = 398 dev->mem_start + 399 mac8390_memsize(dev->mem_start); 400 break; 401 case MAC8390_CABLETRON: 402 dev->base_addr = 403 (int)(ndev->board->slot_addr + 404 CABLETRON_8390_BASE); 405 dev->mem_start = 406 (int)(ndev->board->slot_addr + 407 CABLETRON_8390_MEM); 408 /* The base address is unreadable if 0x00 409 * has been written to the command register 410 * Reset the chip by writing E8390_NODMA + 411 * E8390_PAGE0 + E8390_STOP just to be 412 * sure 413 */ 414 i = (void *)dev->base_addr; 415 *i = 0x21; 416 dev->mem_end = 417 dev->mem_start + 418 mac8390_memsize(dev->mem_start); 419 break; 420 421 default: 422 printk(KERN_ERR "Card type %s is" 423 " unsupported, sorry\n", 424 ndev->board->name); 425 continue; 426 } 427 } 428 429 /* Do the nasty 8390 stuff */ 430 if (!mac8390_initdev(dev, ndev, cardtype)) 431 break; 432 } 433 434 if (!ndev) 435 goto out; 436 err = register_netdev(dev); 437 if (err) 438 goto out; 439 return dev; 440 441out: 442 free_netdev(dev); 443 return ERR_PTR(err); 444} 445 446#ifdef MODULE 447MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others"); 448MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver"); 449MODULE_LICENSE("GPL"); 450 451/* overkill, of course */ 452static struct net_device *dev_mac8390[15]; 453int init_module(void) 454{ 455 int i; 456 for (i = 0; i < 15; i++) { 457 struct net_device *dev = mac8390_probe(-1); 458 if (IS_ERR(dev)) 459 break; 460 dev_mac890[i] = dev; 461 } 462 if (!i) { 463 printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n"); 464 return -ENODEV; 465 } 466 return 0; 467} 468 469void cleanup_module(void) 470{ 471 int i; 472 for (i = 0; i < 15; i++) { 473 struct net_device *dev = dev_mac890[i]; 474 if (dev) { 475 unregister_netdev(dev); 476 free_netdev(dev); 477 } 478 } 479} 480 481#endif /* MODULE */ 482 483static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, 484 enum mac8390_type type) 485{ 486 static u32 fwrd4_offsets[16]={ 487 0, 4, 8, 12, 488 16, 20, 24, 28, 489 32, 36, 40, 44, 490 48, 52, 56, 60 491 }; 492 static u32 back4_offsets[16]={ 493 60, 56, 52, 48, 494 44, 40, 36, 32, 495 28, 24, 20, 16, 496 12, 8, 4, 0 497 }; 498 static u32 fwrd2_offsets[16]={ 499 0, 2, 4, 6, 500 8, 10, 12, 14, 501 16, 18, 20, 22, 502 24, 26, 28, 30 503 }; 504 505 int access_bitmode = 0; 506 507 /* Now fill in our stuff */ 508 dev->open = &mac8390_open; 509 dev->stop = &mac8390_close; 510#ifdef CONFIG_NET_POLL_CONTROLLER 511 dev->poll_controller = __ei_poll; 512#endif 513 514 /* GAR, ei_status is actually a macro even though it looks global */ 515 ei_status.name = cardname[type]; 516 ei_status.word16 = word16[type]; 517 518 /* Cabletron's TX/RX buffers are backwards */ 519 if (type == MAC8390_CABLETRON) { 520 ei_status.tx_start_page = CABLETRON_TX_START_PG; 521 ei_status.rx_start_page = CABLETRON_RX_START_PG; 522 ei_status.stop_page = CABLETRON_RX_STOP_PG; 523 ei_status.rmem_start = dev->mem_start; 524 ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256; 525 } else { 526 ei_status.tx_start_page = WD_START_PG; 527 ei_status.rx_start_page = WD_START_PG + TX_PAGES; 528 ei_status.stop_page = (dev->mem_end - dev->mem_start)/256; 529 ei_status.rmem_start = dev->mem_start + TX_PAGES*256; 530 ei_status.rmem_end = dev->mem_end; 531 } 532 533 /* Fill in model-specific information and functions */ 534 switch(type) { 535 case MAC8390_FARALLON: 536 case MAC8390_APPLE: 537 switch(mac8390_testio(dev->mem_start)) { 538 case ACCESS_UNKNOWN: 539 printk("Don't know how to access card memory!\n"); 540 return -ENODEV; 541 break; 542 543 case ACCESS_16: 544 /* 16 bit card, register map is reversed */ 545 ei_status.reset_8390 = &mac8390_no_reset; 546 ei_status.block_input = &slow_sane_block_input; 547 ei_status.block_output = &slow_sane_block_output; 548 ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; 549 ei_status.reg_offset = back4_offsets; 550 break; 551 552 case ACCESS_32: 553 /* 32 bit card, register map is reversed */ 554 ei_status.reset_8390 = &mac8390_no_reset; 555 ei_status.block_input = &sane_block_input; 556 ei_status.block_output = &sane_block_output; 557 ei_status.get_8390_hdr = &sane_get_8390_hdr; 558 ei_status.reg_offset = back4_offsets; 559 access_bitmode = 1; 560 break; 561 } 562 break; 563 564 case MAC8390_ASANTE: 565 /* Some Asante cards pass the 32 bit test 566 * but overwrite system memory when run at 32 bit. 567 * so we run them all at 16 bit. 568 */ 569 ei_status.reset_8390 = &mac8390_no_reset; 570 ei_status.block_input = &slow_sane_block_input; 571 ei_status.block_output = &slow_sane_block_output; 572 ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; 573 ei_status.reg_offset = back4_offsets; 574 break; 575 576 case MAC8390_CABLETRON: 577 /* 16 bit card, register map is short forward */ 578 ei_status.reset_8390 = &mac8390_no_reset; 579 ei_status.block_input = &slow_sane_block_input; 580 ei_status.block_output = &slow_sane_block_output; 581 ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; 582 ei_status.reg_offset = fwrd2_offsets; 583 break; 584 585 case MAC8390_DAYNA: 586 case MAC8390_KINETICS: 587 /* 16 bit memory, register map is forward */ 588 /* dayna and similar */ 589 ei_status.reset_8390 = &mac8390_no_reset; 590 ei_status.block_input = &dayna_block_input; 591 ei_status.block_output = &dayna_block_output; 592 ei_status.get_8390_hdr = &dayna_get_8390_hdr; 593 ei_status.reg_offset = fwrd4_offsets; 594 break; 595 596 case MAC8390_INTERLAN: 597 /* 16 bit memory, register map is forward */ 598 ei_status.reset_8390 = &interlan_reset; 599 ei_status.block_input = &slow_sane_block_input; 600 ei_status.block_output = &slow_sane_block_output; 601 ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; 602 ei_status.reg_offset = fwrd4_offsets; 603 break; 604 605 default: 606 printk(KERN_ERR "Card type %s is unsupported, sorry\n", ndev->board->name); 607 return -ENODEV; 608 } 609 610 __NS8390_init(dev, 0); 611 612 /* Good, done, now spit out some messages */ 613 printk(KERN_INFO "%s: %s in slot %X (type %s)\n", 614 dev->name, ndev->board->name, ndev->board->slot, cardname[type]); 615 printk(KERN_INFO "MAC "); 616 { 617 int i; 618 for (i = 0; i < 6; i++) { 619 printk("%2.2x", dev->dev_addr[i]); 620 if (i < 5) 621 printk(":"); 622 } 623 } 624 printk(" IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", 625 dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4, 626 dev->mem_start, access_bitmode?32:16); 627 return 0; 628} 629 630static int mac8390_open(struct net_device *dev) 631{ 632 __ei_open(dev); 633 if (request_irq(dev->irq, __ei_interrupt, 0, "8390 Ethernet", dev)) { 634 printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq); 635 return -EAGAIN; 636 } 637 return 0; 638} 639 640static int mac8390_close(struct net_device *dev) 641{ 642 free_irq(dev->irq, dev); 643 __ei_close(dev); 644 return 0; 645} 646 647static void mac8390_no_reset(struct net_device *dev) 648{ 649 ei_status.txing = 0; 650 if (ei_debug > 1) 651 printk("reset not supported\n"); 652 return; 653} 654 655static void interlan_reset(struct net_device *dev) 656{ 657 unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq)); 658 if (ei_debug > 1) 659 printk("Need to reset the NS8390 t=%lu...", jiffies); 660 ei_status.txing = 0; 661 target[0xC0000] = 0; 662 if (ei_debug > 1) 663 printk("reset complete\n"); 664 return; 665} 666 667/* dayna_memcpy_fromio/dayna_memcpy_toio */ 668/* directly from daynaport.c by Alan Cox */ 669static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count) 670{ 671 volatile unsigned char *ptr; 672 unsigned char *target=to; 673 from<<=1; /* word, skip overhead */ 674 ptr=(unsigned char *)(dev->mem_start+from); 675 /* Leading byte? */ 676 if (from&2) { 677 *target++ = ptr[-1]; 678 ptr += 2; 679 count--; 680 } 681 while(count>=2) 682 { 683 *(unsigned short *)target = *(unsigned short volatile *)ptr; 684 ptr += 4; /* skip cruft */ 685 target += 2; 686 count-=2; 687 } 688 /* Trailing byte? */ 689 if(count) 690 *target = *ptr; 691} 692 693static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count) 694{ 695 volatile unsigned short *ptr; 696 const unsigned char *src=from; 697 to<<=1; /* word, skip overhead */ 698 ptr=(unsigned short *)(dev->mem_start+to); 699 /* Leading byte? */ 700 if (to&2) { /* avoid a byte write (stomps on other data) */ 701 ptr[-1] = (ptr[-1]&0xFF00)|*src++; 702 ptr++; 703 count--; 704 } 705 while(count>=2) 706 { 707 *ptr++=*(unsigned short *)src; /* Copy and */ 708 ptr++; /* skip cruft */ 709 src += 2; 710 count-=2; 711 } 712 /* Trailing byte? */ 713 if(count) 714 { 715 /* card doesn't like byte writes */ 716 *ptr=(*ptr&0x00FF)|(*src << 8); 717 } 718} 719 720/* sane block input/output */ 721static void sane_get_8390_hdr(struct net_device *dev, 722 struct e8390_pkt_hdr *hdr, int ring_page) 723{ 724 unsigned long hdr_start = (ring_page - WD_START_PG)<<8; 725 memcpy_fromio((void *)hdr, (char *)dev->mem_start + hdr_start, 4); 726 /* Fix endianness */ 727 hdr->count = swab16(hdr->count); 728} 729 730static void sane_block_input(struct net_device *dev, int count, 731 struct sk_buff *skb, int ring_offset) 732{ 733 unsigned long xfer_base = ring_offset - (WD_START_PG<<8); 734 unsigned long xfer_start = xfer_base + dev->mem_start; 735 736 if (xfer_start + count > ei_status.rmem_end) { 737 /* We must wrap the input move. */ 738 int semi_count = ei_status.rmem_end - xfer_start; 739 memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, semi_count); 740 count -= semi_count; 741 memcpy_toio(skb->data + semi_count, (char *)ei_status.rmem_start, count); 742 } else { 743 memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, count); 744 } 745} 746 747static void sane_block_output(struct net_device *dev, int count, 748 const unsigned char *buf, int start_page) 749{ 750 long shmem = (start_page - WD_START_PG)<<8; 751 752 memcpy_toio((char *)dev->mem_start + shmem, buf, count); 753} 754 755/* dayna block input/output */ 756static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) 757{ 758 unsigned long hdr_start = (ring_page - WD_START_PG)<<8; 759 760 dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4); 761 /* Fix endianness */ 762 hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); 763} 764 765static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) 766{ 767 unsigned long xfer_base = ring_offset - (WD_START_PG<<8); 768 unsigned long xfer_start = xfer_base+dev->mem_start; 769 770 /* Note the offset math is done in card memory space which is word 771 per long onto our space. */ 772 773 if (xfer_start + count > ei_status.rmem_end) 774 { 775 /* We must wrap the input move. */ 776 int semi_count = ei_status.rmem_end - xfer_start; 777 dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count); 778 count -= semi_count; 779 dayna_memcpy_fromcard(dev, skb->data + semi_count, 780 ei_status.rmem_start - dev->mem_start, 781 count); 782 } 783 else 784 { 785 dayna_memcpy_fromcard(dev, skb->data, xfer_base, count); 786 } 787} 788 789static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf, 790 int start_page) 791{ 792 long shmem = (start_page - WD_START_PG)<<8; 793 794 dayna_memcpy_tocard(dev, shmem, buf, count); 795} 796 797/* Cabletron block I/O */ 798static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, 799 int ring_page) 800{ 801 unsigned long hdr_start = (ring_page - WD_START_PG)<<8; 802 word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4); 803 /* Register endianism - fix here rather than 8390.c */ 804 hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8); 805} 806 807static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, 808 int ring_offset) 809{ 810 unsigned long xfer_base = ring_offset - (WD_START_PG<<8); 811 unsigned long xfer_start = xfer_base+dev->mem_start; 812 813 if (xfer_start + count > ei_status.rmem_end) 814 { 815 /* We must wrap the input move. */ 816 int semi_count = ei_status.rmem_end - xfer_start; 817 word_memcpy_fromcard(skb->data, (char *)dev->mem_start + 818 xfer_base, semi_count); 819 count -= semi_count; 820 word_memcpy_fromcard(skb->data + semi_count, 821 (char *)ei_status.rmem_start, count); 822 } 823 else 824 { 825 word_memcpy_fromcard(skb->data, (char *)dev->mem_start + 826 xfer_base, count); 827 } 828} 829 830static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf, 831 int start_page) 832{ 833 long shmem = (start_page - WD_START_PG)<<8; 834 835 word_memcpy_tocard((char *)dev->mem_start + shmem, buf, count); 836} 837 838static void word_memcpy_tocard(void *tp, const void *fp, int count) 839{ 840 volatile unsigned short *to = tp; 841 const unsigned short *from = fp; 842 843 count++; 844 count/=2; 845 846 while(count--) 847 *to++=*from++; 848} 849 850static void word_memcpy_fromcard(void *tp, const void *fp, int count) 851{ 852 unsigned short *to = tp; 853 const volatile unsigned short *from = fp; 854 855 count++; 856 count/=2; 857 858 while(count--) 859 *to++=*from++; 860} 861 862