1/*- 2 * Copyright (c) 2005, M. Warner Losh 3 * All rights reserved. 4 * Copyright (c) 1995, David Greenman 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
|
32 33#include "opt_ed.h" 34 35#ifdef ED_3C503 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/sockio.h> 40#include <sys/mbuf.h> 41#include <sys/kernel.h> 42#include <sys/socket.h> 43#include <sys/syslog.h> 44 45#include <sys/bus.h> 46 47#include <machine/bus.h> 48#include <sys/rman.h> 49#include <machine/resource.h> 50 51#include <net/ethernet.h> 52#include <net/if.h> 53#include <net/if_arp.h> 54#include <net/if_dl.h> 55#include <net/if_mib.h> 56#include <net/if_media.h> 57 58#include <net/bpf.h> 59 60#include <dev/ed/if_edreg.h> 61#include <dev/ed/if_edvar.h> 62 63static void ed_3c503_mediachg(struct ed_softc *sc); 64 65/* 66 * Probe and vendor-specific initialization routine for 3Com 3c503 boards 67 */ 68int 69ed_probe_3Com(device_t dev, int port_rid, int flags) 70{ 71 struct ed_softc *sc = device_get_softc(dev); 72 int error; 73 int i; 74 u_int memsize; 75 u_char isa16bit; 76 u_long conf_maddr, conf_msize, irq, junk, pmem; 77 78 error = ed_alloc_port(dev, 0, ED_3COM_IO_PORTS); 79 if (error) 80 return (error); 81 82 sc->asic_offset = ED_3COM_ASIC_OFFSET; 83 sc->nic_offset = ED_3COM_NIC_OFFSET; 84 85 /* 86 * Verify that the kernel configured I/O address matches the board 87 * configured address 88 */ 89 switch (ed_asic_inb(sc, ED_3COM_BCFR)) { 90 case ED_3COM_BCFR_300: 91 if (rman_get_start(sc->port_res) != 0x300) 92 return (ENXIO); 93 break; 94 case ED_3COM_BCFR_310: 95 if (rman_get_start(sc->port_res) != 0x310) 96 return (ENXIO); 97 break; 98 case ED_3COM_BCFR_330: 99 if (rman_get_start(sc->port_res) != 0x330) 100 return (ENXIO); 101 break; 102 case ED_3COM_BCFR_350: 103 if (rman_get_start(sc->port_res) != 0x350) 104 return (ENXIO); 105 break; 106 case ED_3COM_BCFR_250: 107 if (rman_get_start(sc->port_res) != 0x250) 108 return (ENXIO); 109 break; 110 case ED_3COM_BCFR_280: 111 if (rman_get_start(sc->port_res) != 0x280) 112 return (ENXIO); 113 break; 114 case ED_3COM_BCFR_2A0: 115 if (rman_get_start(sc->port_res) != 0x2a0) 116 return (ENXIO); 117 break; 118 case ED_3COM_BCFR_2E0: 119 if (rman_get_start(sc->port_res) != 0x2e0) 120 return (ENXIO); 121 break; 122 default: 123 return (ENXIO); 124 } 125 126 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 127 &conf_maddr, &conf_msize); 128 if (error) 129 return (error); 130 131 /* 132 * Verify that the kernel shared memory address matches the board 133 * configured address. 134 */ 135 switch (ed_asic_inb(sc, ED_3COM_PCFR)) { 136 case ED_3COM_PCFR_DC000: 137 if (conf_maddr != 0xdc000) 138 return (ENXIO); 139 break; 140 case ED_3COM_PCFR_D8000: 141 if (conf_maddr != 0xd8000) 142 return (ENXIO); 143 break; 144 case ED_3COM_PCFR_CC000: 145 if (conf_maddr != 0xcc000) 146 return (ENXIO); 147 break; 148 case ED_3COM_PCFR_C8000: 149 if (conf_maddr != 0xc8000) 150 return (ENXIO); 151 break; 152 default: 153 return (ENXIO); 154 } 155 156 157 /* 158 * Reset NIC and ASIC. Enable on-board transceiver throughout reset 159 * sequence because it'll lock up if the cable isn't connected if we 160 * don't. 161 */ 162 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_RST | ED_3COM_CR_XSEL); 163 164 /* 165 * Wait for a while, then un-reset it 166 */ 167 DELAY(50); 168 169 /* 170 * The 3Com ASIC defaults to rather strange settings for the CR after 171 * a reset - it's important to set it again after the following outb 172 * (this is done when we map the PROM below). 173 */ 174 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 175 176 /* 177 * Wait a bit for the NIC to recover from the reset 178 */ 179 DELAY(5000); 180 181 sc->vendor = ED_VENDOR_3COM; 182 sc->type_str = "3c503"; 183 sc->mem_shared = 1; 184 sc->cr_proto = ED_CR_RD2; 185 186 /* 187 * Hmmm...a 16bit 3Com board has 16k of memory, but only an 8k window 188 * to it. 189 */ 190 memsize = 8192; 191 192 /* 193 * Get station address from on-board ROM 194 */ 195 196 /* 197 * First, map ethernet address PROM over the top of where the NIC 198 * registers normally appear. 199 */ 200 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_EALO | ED_3COM_CR_XSEL); 201 202 for (i = 0; i < ETHER_ADDR_LEN; ++i) 203 sc->enaddr[i] = ed_nic_inb(sc, i); 204 205 /* 206 * Unmap PROM - select NIC registers. The proper setting of the 207 * tranceiver is set in ed_init so that the attach code is given a 208 * chance to set the default based on a compile-time config option 209 */ 210 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 211 212 /* 213 * Determine if this is an 8bit or 16bit board 214 */ 215 216 /* 217 * select page 0 registers 218 */ 219 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 220 221 /* 222 * Attempt to clear WTS bit. If it doesn't clear, then this is a 16bit 223 * board. 224 */ 225 ed_nic_outb(sc, ED_P0_DCR, 0); 226 227 /* 228 * select page 2 registers 229 */ 230 ed_nic_outb(sc, ED_P0_CR, ED_CR_PAGE_2 | ED_CR_RD2 | ED_CR_STP); 231 232 /* 233 * The 3c503 forces the WTS bit to a one if this is a 16bit board 234 */ 235 if (ed_nic_inb(sc, ED_P2_DCR) & ED_DCR_WTS) 236 isa16bit = 1; 237 else 238 isa16bit = 0; 239 240 /* 241 * select page 0 registers 242 */ 243 ed_nic_outb(sc, ED_P2_CR, ED_CR_RD2 | ED_CR_STP); 244 245 error = ed_alloc_memory(dev, 0, memsize); 246 if (error) 247 return (error); 248 249 pmem = rman_get_start(sc->mem_res); 250 error = ed_isa_mem_ok(dev, pmem, memsize); 251 if (error) 252 return (error); 253 254 sc->mem_start = 0; 255 sc->mem_size = memsize; 256 sc->mem_end = sc->mem_start + memsize; 257 258 /* 259 * We have an entire 8k window to put the transmit buffers on the 260 * 16bit boards. But since the 16bit 3c503's shared memory is only 261 * fast enough to overlap the loading of one full-size packet, trying 262 * to load more than 2 buffers can actually leave the transmitter idle 263 * during the load. So 2 seems the best value. (Although a mix of 264 * variable-sized packets might change this assumption. Nonetheless, 265 * we optimize for linear transfers of same-size packets.) 266 */ 267 if (isa16bit) { 268 if (flags & ED_FLAGS_NO_MULTI_BUFFERING) 269 sc->txb_cnt = 1; 270 else 271 sc->txb_cnt = 2; 272 273 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_16BIT; 274 sc->rec_page_start = ED_3COM_RX_PAGE_OFFSET_16BIT; 275 sc->rec_page_stop = memsize / ED_PAGE_SIZE + 276 ED_3COM_RX_PAGE_OFFSET_16BIT; 277 sc->mem_ring = sc->mem_start; 278 } else { 279 sc->txb_cnt = 1; 280 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_8BIT; 281 sc->rec_page_start = ED_TXBUF_SIZE + ED_3COM_TX_PAGE_OFFSET_8BIT; 282 sc->rec_page_stop = memsize / ED_PAGE_SIZE + 283 ED_3COM_TX_PAGE_OFFSET_8BIT; 284 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE); 285 } 286 287 sc->isa16bit = isa16bit; 288 289 /* 290 * Initialize GA page start/stop registers. Probably only needed if 291 * doing DMA, but what the hell. 292 */ 293 ed_asic_outb(sc, ED_3COM_PSTR, sc->rec_page_start); 294 ed_asic_outb(sc, ED_3COM_PSPR, sc->rec_page_stop); 295 296 /* 297 * Set IRQ. 3c503 only allows a choice of irq 2-5. 298 */ 299 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk); 300 if (error) 301 return (error); 302 303 switch (irq) { 304 case 2: 305 case 9: 306 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2); 307 break; 308 case 3: 309 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3); 310 break; 311 case 4: 312 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4); 313 break; 314 case 5: 315 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5); 316 break; 317 default: 318 device_printf(dev, "Invalid irq configuration (%ld) must be 3-5,9 for 3c503\n", 319 irq); 320 return (ENXIO); 321 } 322 323 /* 324 * Initialize GA configuration register. Set bank and enable shared 325 * mem. 326 */ 327 ed_asic_outb(sc, ED_3COM_GACFR, ED_3COM_GACFR_RSEL |
|