if_ed_novell.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2005, M. Warner Losh 5 * All rights reserved. 6 * Copyright (c) 1995, David Greenman 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice unmodified, this list of conditions, and the following 14 * disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: stable/11/sys/dev/ed/if_ed_novell.c 330897 2018-03-14 03:19:51Z eadler $"); 35 36#include "opt_ed.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/mbuf.h> 42#include <sys/kernel.h> 43#include <sys/socket.h> 44#include <sys/syslog.h> 45 46#include <sys/bus.h> 47 48#include <machine/bus.h> 49#include <sys/rman.h> 50#include <machine/resource.h> 51 52#include <net/ethernet.h> 53#include <net/if.h> 54#include <net/if_arp.h> 55#include <net/if_dl.h> 56#include <net/if_mib.h> 57#include <net/if_media.h> 58 59#include <net/bpf.h> 60 61#include <dev/ed/if_edreg.h> 62#include <dev/ed/if_edvar.h> 63 64static int ed_probe_gwether(device_t); 65 66/* 67 * Probe and vendor-specific initialization routine for NE1000/2000 boards 68 */ 69int 70ed_probe_Novell_generic(device_t dev, int flags) 71{ 72 struct ed_softc *sc = device_get_softc(dev); 73 u_int memsize; 74 int error; 75 u_char tmp; 76 static char test_pattern[32] = "THIS is A memory TEST pattern"; 77 char test_buffer[32]; 78 79 /* Reset the board */ 80 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) { 81 ed_asic_outb(sc, ED_NOVELL_RESET, 0); 82 DELAY(200); 83 } 84 tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 85 86 /* 87 * I don't know if this is necessary; probably cruft leftover from 88 * Clarkson packet driver code. Doesn't do a thing on the boards I've 89 * tested. -DG 90 */ 91 ed_asic_outb(sc, ED_NOVELL_RESET, tmp); 92 DELAY(5000); 93 94 /* 95 * This is needed because some NE clones apparently don't reset the 96 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 97 * - this makes the probe invasive! ...Done against my better 98 * judgement. -DLG 99 */ 100 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 101 DELAY(5000); 102 103 /* Make sure that we really have an 8390 based board */ 104 if (!ed_probe_generic8390(sc)) 105 return (ENXIO); 106 107 sc->vendor = ED_VENDOR_NOVELL; 108 sc->mem_shared = 0; 109 sc->cr_proto = ED_CR_RD2; 110 111 /* 112 * Test the ability to read and write to the NIC memory. This has the 113 * side affect of determining if this is an NE1000 or an NE2000. 114 */ 115 116 /* 117 * This prevents packets from being stored in the NIC memory when the 118 * readmem routine turns on the start bit in the CR. 119 */ 120 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); 121 122 /* Temporarily initialize DCR for byte operations */ 123 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 124 125 ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE); 126 ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE); 127 128 /* 129 * Some devices identify themselves. Some of those devices 130 * can't handle being probed, so we allow forcing a mode. If 131 * these flags are set, force it, otherwise probe. 132 */ 133 if (flags & ED_FLAGS_FORCE_8BIT_MODE) { 134 sc->isa16bit = 0; 135 sc->type = ED_TYPE_NE1000; 136 sc->type_str = "NE1000"; 137 } else if (flags & ED_FLAGS_FORCE_16BIT_MODE) { 138 sc->isa16bit = 1; 139 sc->type = ED_TYPE_NE2000; 140 sc->type_str = "NE2000"; 141 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 142 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE); 143 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE); 144 } else { 145 /* 146 * Write a test pattern in byte mode. If this fails, then there 147 * probably isn't any memory at 8k - which likely means that the board 148 * is an NE2000. 149 */ 150 ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern)); 151 ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern)); 152 153 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { 154 sc->type = ED_TYPE_NE1000; 155 sc->type_str = "NE1000"; 156 sc->isa16bit = 0; 157 } else { 158 /* Not an NE1000 - try NE2000 */ 159 sc->isa16bit = 1; 160 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 161 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE); 162 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE); 163 /* 164 * Write a test pattern in word mode. If this also fails, then 165 * we don't know what this board is. 166 */ 167 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); 168 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); 169 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { 170 sc->type = ED_TYPE_NE2000; 171 sc->type_str = "NE2000"; 172 } else { 173 return (ENXIO); 174 } 175 } 176 } 177 sc->chip_type = ED_CHIP_TYPE_DP8390; 178 179 /* 8k of memory plus an additional 8k if 16bit */ 180 memsize = 8192 + sc->isa16bit * 8192; 181 sc->mem_size = memsize; 182 183 /* NIC memory doesn't start at zero on an NE board */ 184 /* The start address is tied to the bus width */ 185 sc->mem_start = 8192 + sc->isa16bit * 8192; 186 sc->mem_end = sc->mem_start + memsize; 187 sc->tx_page_start = memsize / ED_PAGE_SIZE; 188 189 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) { 190 error = ed_probe_gwether(dev); 191 if (error) 192 return (error); 193 } 194 195 /* 196 * Use one xmit buffer if < 16k, two buffers otherwise (if not told 197 * otherwise). 198 */ 199 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) 200 sc->txb_cnt = 1; 201 else 202 sc->txb_cnt = 2; 203 204 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 205 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 206 207 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 208 /* clear any pending interrupts that might have occurred above */ 209 ed_nic_outb(sc, ED_P0_ISR, 0xff); 210 211 sc->sc_write_mbufs = ed_pio_write_mbufs; 212 return (0); 213} 214 215int 216ed_probe_Novell(device_t dev, int port_rid, int flags) 217{ 218 struct ed_softc *sc = device_get_softc(dev); 219 int error; 220 221 error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); 222 if (error) 223 return (error); 224 225 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 226 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 227 228 return ed_probe_Novell_generic(dev, flags); 229} 230 231static int 232ed_probe_gwether(device_t dev) 233{ 234 int x, i, msize = 0; 235 bus_size_t mstart = 0; 236 char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE]; 237 struct ed_softc *sc = device_get_softc(dev); 238 239 for (i = 0; i < ED_PAGE_SIZE; i++) 240 pbuf0[i] = 0; 241 242 /* Clear all the memory. */ 243 for (x = 1; x < 256; x++) 244 ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE); 245 246 /* Search for the start of RAM. */ 247 for (x = 1; x < 256; x++) { 248 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 249 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { 250 for (i = 0; i < ED_PAGE_SIZE; i++) 251 pbuf[i] = 255 - x; 252 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); 253 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 254 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) { 255 mstart = x * ED_PAGE_SIZE; 256 msize = ED_PAGE_SIZE; 257 break; 258 } 259 } 260 } 261 if (mstart == 0) { 262 device_printf(dev, "Cannot find start of RAM.\n"); 263 return (ENXIO); 264 } 265 266 /* Probe the size of RAM. */ 267 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) { 268 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 269 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { 270 for (i = 0; i < ED_PAGE_SIZE; i++) 271 pbuf[i] = 255 - x; 272 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); 273 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 274 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) 275 msize += ED_PAGE_SIZE; 276 else { 277 break; 278 } 279 } else { 280 break; 281 } 282 } 283 284 if (msize == 0) { 285 device_printf(dev, 286 "Cannot find any RAM, start : %d, x = %d.\n", 287 (int)mstart, x); 288 return (ENXIO); 289 } 290 if (bootverbose) 291 device_printf(dev, 292 "RAM start at %d, size : %d.\n", (int)mstart, msize); 293 294 sc->mem_size = msize; 295 sc->mem_start = mstart; 296 sc->mem_end = msize + mstart; 297 sc->tx_page_start = mstart / ED_PAGE_SIZE; 298 return 0; 299} 300 301void 302ed_Novell_read_mac(struct ed_softc *sc) 303{ 304 int n; 305 uint8_t romdata[16]; 306 307 /* 308 * Most ne1000/ne2000 compatible cards have their MAC address 309 * located in the first few words of the address space. This seems 310 * universally true for ISA and PCI implementations, but PC Card 311 * devices seem to have more variance. 312 */ 313 ed_pio_readmem(sc, 0, romdata, 16); 314 for (n = 0; n < ETHER_ADDR_LEN; n++) 315 sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)]; 316} 317