/* $NetBSD: wd80x3.c,v 1.10 2008/12/14 18:46:33 christos Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Device driver for National Semiconductor DS8390/WD83C690 based ethernet * adapters. * * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. * * Copyright (C) 1993, David Greenman. This software may be used, modified, * copied, distributed, and sold, in both source and binary form provided that * the above copyright and these terms are retained. Under no circumstances is * the author responsible for the proper functioning of this software, nor does * the author assume any responsibility for damages incurred with its use. */ /* * Device driver for the Western Digital/SMC 8003 and 8013 series, * and the SMC Elite Ultra (8216). */ #include #include #include #include #ifdef _STANDALONE #include #include #endif #include "etherdrv.h" #include #include "dp8390.h" #include #ifndef BASEREG #define BASEREG 0x240 #define BASEMEM 0xd0000 #endif #define WD_BASEREG BASEREG #define WD_BASEMEM BASEMEM #ifndef _STANDALONE extern int mapio(void); #endif u_char eth_myaddr[6]; static uint8_t we_type; static int we_is16bit; #ifdef _STANDALONE static struct btinfo_netif bi_netif; #endif const char * we_params(void) { const char *typestr; dp8390_memsize = 8192; we_type = inb(WD_BASEREG + WE_CARD_ID); switch (we_type) { #ifdef SUPPORT_WD80X3 case WE_TYPE_WD8003S: typestr = "WD8003S"; break; case WE_TYPE_WD8003E: typestr = "WD8003E"; break; case WE_TYPE_WD8003EB: typestr = "WD8003EB"; break; case WE_TYPE_WD8003W: typestr = "WD8003W"; break; case WE_TYPE_WD8013EBT: typestr = "WD8013EBT"; dp8390_memsize = 16384; we_is16bit = 1; break; case WE_TYPE_WD8013W: typestr = "WD8013W"; dp8390_memsize = 16384; we_is16bit = 1; break; case WE_TYPE_WD8013EP: /* also WD8003EP */ if (inb(WD_BASEREG + WE_ICR) & WE_ICR_16BIT) { we_is16bit = 1; dp8390_memsize = 16384; typestr = "WD8013EP"; } else typestr = "WD8003EP"; break; case WE_TYPE_WD8013WC: typestr = "WD8013WC"; dp8390_memsize = 16384; we_is16bit = 1; break; case WE_TYPE_WD8013EBP: typestr = "WD8013EBP"; dp8390_memsize = 16384; we_is16bit = 1; break; case WE_TYPE_WD8013EPC: typestr = "WD8013EPC"; dp8390_memsize = 16384; we_is16bit = 1; break; #endif #ifdef SUPPORT_SMC_ULTRA case WE_TYPE_SMC8216C: case WE_TYPE_SMC8216T: { uint8_t hwr; typestr = (we_type == WE_TYPE_SMC8216C) ? "SMC8216/SMC8216C" : "SMC8216T"; hwr = inb(WD_BASEREG + WE790_HWR); outb(WD_BASEREG + WE790_HWR, hwr | WE790_HWR_SWH); switch (inb(WD_BASEREG + WE790_RAR) & WE790_RAR_SZ64) { case WE790_RAR_SZ64: dp8390_memsize = 65536; break; case WE790_RAR_SZ32: dp8390_memsize = 32768; break; case WE790_RAR_SZ16: dp8390_memsize = 16384; break; case WE790_RAR_SZ8: /* 8216 has 16K shared mem -- 8416 has 8K */ typestr = (we_type == WE_TYPE_SMC8216C) ? "SMC8416C/SMC8416BT" : "SMC8416T"; dp8390_memsize = 8192; break; } outb(WD_BASEREG + WE790_HWR, hwr); we_is16bit = 1; #ifdef SUPPORT_WD80X3 dp8390_is790 = 1; #endif break; } #endif default: /* Not one we recognize. */ return NULL; } /* * Make some adjustments to initial values depending on what is * found in the ICR. */ if (we_is16bit && (we_type != WE_TYPE_WD8013EBT) && (inb(WD_BASEREG + WE_ICR) & WE_ICR_16BIT) == 0) { we_is16bit = 0; dp8390_memsize = 8192; } #ifdef WE_DEBUG { int i; printf("we_params: type = 0x%x, typestr = %s, is16bit = %d, " "memsize = %d\n", we_type, typestr, we_is16bit, dp8390_memsize); for (i = 0; i < 8; i++) printf(" %d -> 0x%x\n", i, inb(WD_BASEREG + i)); } #endif return typestr; } int EtherInit(unsigned char *myadr) { const char *typestr; uint8_t x; int i; uint8_t laar_proto; uint8_t msr_proto; dp8390_iobase = WD_BASEREG + WE_NIC_OFFSET; dp8390_membase = WD_BASEMEM; #ifndef _STANDALONE if (mapio()) { printf("no IO access\n"); return 0; } #endif for (x = 0, i = 0; i < 8; i++) x += inb(WD_BASEREG + WE_PROM + i); if (x != WE_ROM_CHECKSUM_TOTAL) return 0; /* reset the ethernet card */ outb(WD_BASEREG + WE_MSR, WE_MSR_RST); delay(100); outb(WD_BASEREG + WE_MSR, inb(WD_BASEREG + WE_MSR) & ~WE_MSR_RST); delay(5000); typestr = we_params(); if (!typestr) return 0; printf("Using %s board, port 0x%x, iomem 0x%x, iosiz %d\n", typestr, WD_BASEREG, WD_BASEMEM, dp8390_memsize); /* get ethernet address */ for (i = 0; i < 6; i++) eth_myaddr[i] = myadr[i]= inb(WD_BASEREG + WE_PROM + i); /* * Set upper address bits and 8/16 bit access to shared memory. */ if (dp8390_is790) { laar_proto = inb(WD_BASEREG + WE_LAAR) & ~WE_LAAR_M16EN; outb(WD_BASEREG + WE_LAAR, laar_proto | (we_is16bit ? WE_LAAR_M16EN : 0)); } else if ((we_type & WE_SOFTCONFIG) || (we_type == WE_TYPE_WD8013EBT)) { laar_proto = (WD_BASEMEM >> 19) & WE_LAAR_ADDRHI; if (we_is16bit) laar_proto |= WE_LAAR_L16EN; outb(WD_BASEREG + WE_LAAR, laar_proto | (we_is16bit ? WE_LAAR_M16EN : 0)); } /* * Set address and enable interface shared memory. */ if (dp8390_is790) { /* XXX MAGIC CONSTANTS XXX */ x = inb(WD_BASEREG + 0x04); outb(WD_BASEREG + 0x04, x | 0x80); outb(WD_BASEREG + 0x0b, ((WD_BASEMEM >> 13) & 0x0f) | ((WD_BASEMEM >> 11) & 0x40) | (inb(WD_BASEREG + 0x0b) & 0xb0)); outb(WD_BASEREG + 0x04, x); msr_proto = 0x00; dp8390_cr_proto = 0x00; } else { msr_proto = (WD_BASEMEM >> 13) & WE_MSR_ADDR; dp8390_cr_proto = ED_CR_RD2; } outb(WD_BASEREG + WE_MSR, msr_proto | WE_MSR_MENB); delay(2); /* * DCR gets: * * FIFO threshold to 8, No auto-init Remote DMA, * byte order=80x86. * * 16-bit cards also get word-wide DMA transfers. */ dp8390_dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (we_is16bit ? ED_DCR_WTS : 0); if (dp8390_config()) return 0; #ifdef _STANDALONE strncpy(bi_netif.ifname, "we", sizeof(bi_netif.ifname)); bi_netif.bus = BI_BUS_ISA; bi_netif.addr.iobase = WD_BASEREG; BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif)); #endif return 1; } /* * Stop ethernet board */ void EtherStop(void) { /* stop dp8390, followed by a board reset */ dp8390_stop(); outb(WD_BASEREG + WE_MSR, WE_MSR_RST); outb(WD_BASEREG + WE_MSR, 0); }