if_sn.c revision 81122
164562Sgshapiro/* 2261370Sgshapiro * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com> 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * Redistribution and use in source and binary forms, with or without 690792Sgshapiro * modification, are permitted provided that the following conditions 790792Sgshapiro * are met: 890792Sgshapiro * 1. Redistributions of source code must retain the above copyright 9261370Sgshapiro * notice, this list of conditions and the following disclaimer. 1090792Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright 1190792Sgshapiro * notice, this list of conditions and the following disclaimer in the 1264562Sgshapiro * documentation and/or other materials provided with the distribution. 1364562Sgshapiro * 3. All advertising materials mentioning features or use of this software 1464562Sgshapiro * must display the following acknowledgement: 1564562Sgshapiro * This product includes software developed by Gardner Buchanan. 1664562Sgshapiro * 4. The name of Gardner Buchanan may not be used to endorse or promote 1764562Sgshapiro * products derived from this software without specific prior written 1890792Sgshapiro * permission. 1990792Sgshapiro * 2064562Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2164562Sgshapiro * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2264562Sgshapiro * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2364562Sgshapiro * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2464562Sgshapiro * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2564562Sgshapiro * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26110560Sgshapiro * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2764562Sgshapiro * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2864562Sgshapiro * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2964562Sgshapiro * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3090792Sgshapiro * 3164562Sgshapiro * $FreeBSD: head/sys/dev/sn/if_sn.c 81122 2001-08-04 05:27:52Z imp $ 3290792Sgshapiro */ 3364562Sgshapiro 3464562Sgshapiro/* 3564562Sgshapiro * This is a driver for SMC's 9000 series of Ethernet adapters. 3690792Sgshapiro * 3790792Sgshapiro * This FreeBSD driver is derived from the smc9194 Linux driver by 3890792Sgshapiro * Erik Stahlman and is Copyright (C) 1996 by Erik Stahlman. 3990792Sgshapiro * This driver also shamelessly borrows from the FreeBSD ep driver 4064562Sgshapiro * which is Copyright (C) 1994 Herb Peyerl <hpeyerl@novatel.ca> 4190792Sgshapiro * All rights reserved. 4290792Sgshapiro * 4364562Sgshapiro * It is set up for my SMC91C92 equipped Ampro LittleBoard embedded 4464562Sgshapiro * PC. It is adapted from Erik Stahlman's Linux driver which worked 4564562Sgshapiro * with his EFA Info*Express SVC VLB adaptor. According to SMC's databook, 4664562Sgshapiro * it will work for the entire SMC 9xxx series. (Ha Ha) 4771345Sgshapiro * 4864562Sgshapiro * "Features" of the SMC chip: 4964562Sgshapiro * 4608 byte packet memory. (for the 91C92. Others have more) 5090792Sgshapiro * EEPROM for configuration 5164562Sgshapiro * AUI/TP selection 5264562Sgshapiro * 5364562Sgshapiro * Authors: 5464562Sgshapiro * Erik Stahlman erik@vt.edu 5564562Sgshapiro * Herb Peyerl hpeyerl@novatel.ca 5664562Sgshapiro * Andres Vega Garcia avega@sophia.inria.fr 5764562Sgshapiro * Serge Babkin babkin@hq.icb.chel.su 5864562Sgshapiro * Gardner Buchanan gbuchanan@shl.com 5990792Sgshapiro * 6064562Sgshapiro * Sources: 6164562Sgshapiro * o SMC databook 6264562Sgshapiro * o "smc9194.c:v0.10(FIXED) 02/15/96 by Erik Stahlman (erik@vt.edu)" 6390792Sgshapiro * o "if_ep.c,v 1.19 1995/01/24 20:53:45 davidg Exp" 6464562Sgshapiro * 6564562Sgshapiro * Known Bugs: 6664562Sgshapiro * o The hardware multicast filter isn't used yet. 6764562Sgshapiro * o Setting of the hardware address isn't supported. 6864562Sgshapiro * o Hardware padding isn't used. 6964562Sgshapiro */ 7064562Sgshapiro 7164562Sgshapiro/* 7264562Sgshapiro * Modifications for Megahertz X-Jack Ethernet Card (XJ-10BT) 7364562Sgshapiro * 7464562Sgshapiro * Copyright (c) 1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org> 7590792Sgshapiro * BSD-nomads, Tokyo, Japan. 7664562Sgshapiro */ 7790792Sgshapiro/* 7864562Sgshapiro * Multicast support by Kei TANAKA <kei@pal.xerox.com> 7964562Sgshapiro * Special thanks to itojun@itojun.org 8090792Sgshapiro */ 8164562Sgshapiro 8264562Sgshapiro#include <sys/param.h> 8364562Sgshapiro#include <sys/systm.h> 8464562Sgshapiro#include <sys/errno.h> 8564562Sgshapiro#include <sys/sockio.h> 8664562Sgshapiro#include <sys/mbuf.h> 8764562Sgshapiro#include <sys/socket.h> 8864562Sgshapiro#include <sys/syslog.h> 8964562Sgshapiro 9090792Sgshapiro#include <sys/module.h> 9164562Sgshapiro#include <sys/bus.h> 9264562Sgshapiro 9364562Sgshapiro#include <machine/bus.h> 9490792Sgshapiro#include <machine/resource.h> 9564562Sgshapiro#include <sys/rman.h> 9664562Sgshapiro 9764562Sgshapiro#include <net/ethernet.h> 9864562Sgshapiro#include <net/if.h> 9964562Sgshapiro#include <net/if_arp.h> 10064562Sgshapiro#include <net/if_dl.h> 10164562Sgshapiro#include <net/if_types.h> 10264562Sgshapiro#include <net/if_mib.h> 10364562Sgshapiro 10464562Sgshapiro#ifdef INET 10564562Sgshapiro#include <netinet/in.h> 10664562Sgshapiro#include <netinet/in_systm.h> 10790792Sgshapiro#include <netinet/in_var.h> 10864562Sgshapiro#include <netinet/ip.h> 10964562Sgshapiro#endif 11090792Sgshapiro 11164562Sgshapiro#ifdef NS 11264562Sgshapiro#include <netns/ns.h> 11390792Sgshapiro#include <netns/ns_if.h> 11464562Sgshapiro#endif 11564562Sgshapiro 11664562Sgshapiro#include <net/bpf.h> 11764562Sgshapiro#include <net/bpfdesc.h> 11864562Sgshapiro 11964562Sgshapiro 12064562Sgshapiro#include <dev/sn/if_snreg.h> 12164562Sgshapiro#include <dev/sn/if_snvar.h> 12264562Sgshapiro 12364562Sgshapiro/* Exported variables */ 12464562Sgshapirodevclass_t sn_devclass; 12564562Sgshapiro 12664562Sgshapirostatic int snioctl(struct ifnet * ifp, u_long, caddr_t); 12764562Sgshapiro 12890792Sgshapirostatic void snresume(struct ifnet *); 12964562Sgshapiro 13064562Sgshapirovoid sninit(void *); 13190792Sgshapirovoid snread(struct ifnet *); 13264562Sgshapirovoid snreset(struct sn_softc *); 13364562Sgshapirovoid snstart(struct ifnet *); 13490792Sgshapirovoid snstop(struct sn_softc *); 13564562Sgshapirovoid snwatchdog(struct ifnet *); 13664562Sgshapiro 13764562Sgshapirostatic void sn_setmcast(struct sn_softc *); 13864562Sgshapirostatic int sn_getmcf(struct arpcom *ac, u_char *mcf); 13964562Sgshapirostatic u_int smc_crc(u_char *); 14064562Sgshapiro 14164562Sgshapiro/* I (GB) have been unlucky getting the hardware padding 14264562Sgshapiro * to work properly. 14364562Sgshapiro */ 14464562Sgshapiro#define SW_PAD 14590792Sgshapiro 14690792Sgshapirostatic const char *chip_ids[15] = { 14764562Sgshapiro NULL, NULL, NULL, 14890792Sgshapiro /* 3 */ "SMC91C90/91C92", 14964562Sgshapiro /* 4 */ "SMC91C94", 15064562Sgshapiro /* 5 */ "SMC91C95", 15164562Sgshapiro NULL, 15264562Sgshapiro /* 7 */ "SMC91C100", 15364562Sgshapiro /* 8 */ "SMC91C100FD", 15464562Sgshapiro NULL, NULL, NULL, 15564562Sgshapiro NULL, NULL, NULL 15664562Sgshapiro}; 15764562Sgshapiro 15864562Sgshapiroint 15964562Sgshapirosn_attach(device_t dev) 16090792Sgshapiro{ 16190792Sgshapiro struct sn_softc *sc = device_get_softc(dev); 16264562Sgshapiro struct ifnet *ifp = &sc->arpcom.ac_if; 16390792Sgshapiro u_short i; 16464562Sgshapiro u_char *p; 16564562Sgshapiro struct ifaddr *ifa; 16664562Sgshapiro struct sockaddr_dl *sdl; 16764562Sgshapiro int rev; 16864562Sgshapiro u_short address; 16964562Sgshapiro int j; 17064562Sgshapiro 17164562Sgshapiro sn_activate(dev); 17264562Sgshapiro 17364562Sgshapiro snstop(sc); 17490792Sgshapiro 17564562Sgshapiro sc->dev = dev; 17690792Sgshapiro sc->pages_wanted = -1; 17764562Sgshapiro 17866494Sgshapiro device_printf(dev, " "); 17964562Sgshapiro 18064562Sgshapiro SMC_SELECT_BANK(3); 18164562Sgshapiro rev = inw(BASE + REVISION_REG_W); 18264562Sgshapiro if (chip_ids[(rev >> 4) & 0xF]) 18364562Sgshapiro printf("%s ", chip_ids[(rev >> 4) & 0xF]); 18464562Sgshapiro 18564562Sgshapiro SMC_SELECT_BANK(1); 18664562Sgshapiro i = inw(BASE + CONFIG_REG_W); 18764562Sgshapiro printf(i & CR_AUI_SELECT ? "AUI" : "UTP"); 18864562Sgshapiro 18964562Sgshapiro if (sc->pccard_enaddr) 19066494Sgshapiro for (j = 0; j < 3; j++) { 19164562Sgshapiro u_short w; 19264562Sgshapiro 19364562Sgshapiro w = (u_short)sc->arpcom.ac_enaddr[j * 2] | 19490792Sgshapiro (((u_short)sc->arpcom.ac_enaddr[j * 2 + 1]) << 8); 19564562Sgshapiro outw(BASE + IAR_ADDR0_REG_W + j * 2, w); 19664562Sgshapiro } 19764562Sgshapiro 19864562Sgshapiro /* 19964562Sgshapiro * Read the station address from the chip. The MAC address is bank 1, 20064562Sgshapiro * regs 4 - 9 20164562Sgshapiro */ 20264562Sgshapiro SMC_SELECT_BANK(1); 20390792Sgshapiro p = (u_char *) & sc->arpcom.ac_enaddr; 20464562Sgshapiro for (i = 0; i < 6; i += 2) { 20564562Sgshapiro address = inw(BASE + IAR_ADDR0_REG_W + i); 20664562Sgshapiro p[i + 1] = address >> 8; 20790792Sgshapiro p[i] = address & 0xFF; 20864562Sgshapiro } 20964562Sgshapiro printf(" MAC address %6D\n", sc->arpcom.ac_enaddr, ":"); 21064562Sgshapiro ifp->if_softc = sc; 21164562Sgshapiro ifp->if_unit = device_get_unit(dev); 21264562Sgshapiro ifp->if_name = "sn"; 21364562Sgshapiro ifp->if_mtu = ETHERMTU; 21464562Sgshapiro ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 21564562Sgshapiro ifp->if_output = ether_output; 21664562Sgshapiro ifp->if_start = snstart; 21764562Sgshapiro ifp->if_ioctl = snioctl; 21890792Sgshapiro ifp->if_watchdog = snwatchdog; 21990792Sgshapiro ifp->if_init = sninit; 22090792Sgshapiro ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 22164562Sgshapiro ifp->if_timer = 0; 22290792Sgshapiro 22364562Sgshapiro ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 22464562Sgshapiro 22564562Sgshapiro /* 22664562Sgshapiro * Fill the hardware address into ifa_addr if we find an AF_LINK 22764562Sgshapiro * entry. We need to do this so bpf's can get the hardware addr of 22864562Sgshapiro * this card. netstat likes this too! 22964562Sgshapiro */ 23064562Sgshapiro ifa = TAILQ_FIRST(&ifp->if_addrhead); 23164562Sgshapiro while ((ifa != 0) && (ifa->ifa_addr != 0) && 23264562Sgshapiro (ifa->ifa_addr->sa_family != AF_LINK)) 23364562Sgshapiro ifa = TAILQ_NEXT(ifa, ifa_link); 23464562Sgshapiro 23564562Sgshapiro if ((ifa != 0) && (ifa->ifa_addr != 0)) { 23664562Sgshapiro sdl = (struct sockaddr_dl *) ifa->ifa_addr; 23790792Sgshapiro sdl->sdl_type = IFT_ETHER; 23864562Sgshapiro sdl->sdl_alen = ETHER_ADDR_LEN; 23964562Sgshapiro sdl->sdl_slen = 0; 24064562Sgshapiro bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN); 24190792Sgshapiro } 24264562Sgshapiro 24364562Sgshapiro return 0; 24490792Sgshapiro} 24564562Sgshapiro 24690792Sgshapiro 24764562Sgshapiroint 24864562Sgshapirosn_detach(device_t dev) 24964562Sgshapiro{ 25064562Sgshapiro struct sn_softc *sc = device_get_softc(dev); 25164562Sgshapiro 25264562Sgshapiro sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING; 25390792Sgshapiro ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED); 25464562Sgshapiro sn_deactivate(dev); 25564562Sgshapiro return 0; 25664562Sgshapiro} 25764562Sgshapiro 25864562Sgshapiro/* 25964562Sgshapiro * Reset and initialize the chip 26064562Sgshapiro */ 26164562Sgshapirovoid 26264562Sgshapirosninit(void *xsc) 26364562Sgshapiro{ 26464562Sgshapiro register struct sn_softc *sc = xsc; 26590792Sgshapiro register struct ifnet *ifp = &sc->arpcom.ac_if; 26664562Sgshapiro int s; 26764562Sgshapiro int flags; 26864562Sgshapiro int mask; 26990792Sgshapiro 27064562Sgshapiro s = splimp(); 27164562Sgshapiro 27264562Sgshapiro /* 27364562Sgshapiro * This resets the registers mostly to defaults, but doesn't affect 27464562Sgshapiro * EEPROM. After the reset cycle, we pause briefly for the chip to 27564562Sgshapiro * be happy. 27664562Sgshapiro */ 27764562Sgshapiro SMC_SELECT_BANK(0); 27864562Sgshapiro outw(BASE + RECV_CONTROL_REG_W, RCR_SOFTRESET); 27964562Sgshapiro SMC_DELAY(); 28064562Sgshapiro outw(BASE + RECV_CONTROL_REG_W, 0x0000); 28164562Sgshapiro SMC_DELAY(); 28264562Sgshapiro SMC_DELAY(); 28364562Sgshapiro 28464562Sgshapiro outw(BASE + TXMIT_CONTROL_REG_W, 0x0000); 28590792Sgshapiro 28690792Sgshapiro /* 28790792Sgshapiro * Set the control register to automatically release succesfully 28864562Sgshapiro * transmitted packets (making the best use out of our limited 28964562Sgshapiro * memory) and to enable the EPH interrupt on certain TX errors. 29064562Sgshapiro */ 29164562Sgshapiro SMC_SELECT_BANK(1); 29264562Sgshapiro outw(BASE + CONTROL_REG_W, (CTR_AUTO_RELEASE | CTR_TE_ENABLE | 29364562Sgshapiro CTR_CR_ENABLE | CTR_LE_ENABLE)); 29464562Sgshapiro 29564562Sgshapiro /* Set squelch level to 240mV (default 480mV) */ 29664562Sgshapiro flags = inw(BASE + CONFIG_REG_W); 29764562Sgshapiro flags |= CR_SET_SQLCH; 29864562Sgshapiro outw(BASE + CONFIG_REG_W, flags); 29964562Sgshapiro 30064562Sgshapiro /* 30171345Sgshapiro * Reset the MMU and wait for it to be un-busy. 30264562Sgshapiro */ 30371345Sgshapiro SMC_SELECT_BANK(2); 30471345Sgshapiro outw(BASE + MMU_CMD_REG_W, MMUCR_RESET); 30564562Sgshapiro while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */ 30664562Sgshapiro ; 30764562Sgshapiro 30890792Sgshapiro /* 30964562Sgshapiro * Disable all interrupts 31064562Sgshapiro */ 31190792Sgshapiro outb(BASE + INTR_MASK_REG_B, 0x00); 31264562Sgshapiro 31364562Sgshapiro sn_setmcast(sc); 31464562Sgshapiro 31564562Sgshapiro /* 31664562Sgshapiro * Set the transmitter control. We want it enabled. 31764562Sgshapiro */ 31864562Sgshapiro flags = TCR_ENABLE; 31964562Sgshapiro 32064562Sgshapiro#ifndef SW_PAD 32164562Sgshapiro /* 32264562Sgshapiro * I (GB) have been unlucky getting this to work. 32364562Sgshapiro */ 32490792Sgshapiro flags |= TCR_PAD_ENABLE; 32564562Sgshapiro#endif /* SW_PAD */ 32690792Sgshapiro 32764562Sgshapiro outw(BASE + TXMIT_CONTROL_REG_W, flags); 32864562Sgshapiro 32964562Sgshapiro 33064562Sgshapiro /* 33164562Sgshapiro * Now, enable interrupts 33264562Sgshapiro */ 33364562Sgshapiro SMC_SELECT_BANK(2); 33464562Sgshapiro 33564562Sgshapiro mask = IM_EPH_INT | 33664562Sgshapiro IM_RX_OVRN_INT | 33764562Sgshapiro IM_RCV_INT | 33864562Sgshapiro IM_TX_INT; 33964562Sgshapiro 34064562Sgshapiro outb(BASE + INTR_MASK_REG_B, mask); 34164562Sgshapiro sc->intr_mask = mask; 34264562Sgshapiro sc->pages_wanted = -1; 34364562Sgshapiro 34464562Sgshapiro 34564562Sgshapiro /* 34664562Sgshapiro * Mark the interface running but not active. 34764562Sgshapiro */ 34864562Sgshapiro ifp->if_flags |= IFF_RUNNING; 34964562Sgshapiro ifp->if_flags &= ~IFF_OACTIVE; 35064562Sgshapiro 35164562Sgshapiro /* 35264562Sgshapiro * Attempt to push out any waiting packets. 35364562Sgshapiro */ 35464562Sgshapiro snstart(ifp); 35564562Sgshapiro 35664562Sgshapiro splx(s); 35764562Sgshapiro} 35866494Sgshapiro 35966494Sgshapiro 36064562Sgshapirovoid 361snstart(struct ifnet *ifp) 362{ 363 register struct sn_softc *sc = ifp->if_softc; 364 register u_int len; 365 register struct mbuf *m; 366 struct mbuf *top; 367 int s, pad; 368 int mask; 369 u_short length; 370 u_short numPages; 371 u_char packet_no; 372 int time_out; 373 int junk = 0; 374 375 s = splimp(); 376 377 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) { 378 splx(s); 379 return; 380 } 381 if (sc->pages_wanted != -1) { 382 splx(s); 383 printf("sn%d: snstart() while memory allocation pending\n", 384 ifp->if_unit); 385 return; 386 } 387startagain: 388 389 /* 390 * Sneak a peek at the next packet 391 */ 392 m = sc->arpcom.ac_if.if_snd.ifq_head; 393 if (m == 0) { 394 splx(s); 395 return; 396 } 397 /* 398 * Compute the frame length and set pad to give an overall even 399 * number of bytes. Below we assume that the packet length is even. 400 */ 401 for (len = 0, top = m; m; m = m->m_next) 402 len += m->m_len; 403 404 pad = (len & 1); 405 406 /* 407 * We drop packets that are too large. Perhaps we should truncate 408 * them instead? 409 */ 410 if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) { 411 printf("sn%d: large packet discarded (A)\n", ifp->if_unit); 412 ++sc->arpcom.ac_if.if_oerrors; 413 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 414 m_freem(m); 415 goto readcheck; 416 } 417#ifdef SW_PAD 418 419 /* 420 * If HW padding is not turned on, then pad to ETHER_MIN_LEN. 421 */ 422 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) 423 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len; 424 425#endif /* SW_PAD */ 426 427 length = pad + len; 428 429 /* 430 * The MMU wants the number of pages to be the number of 256 byte 431 * 'pages', minus 1 (A packet can't ever have 0 pages. We also 432 * include space for the status word, byte count and control bytes in 433 * the allocation request. 434 */ 435 numPages = (length + 6) >> 8; 436 437 438 /* 439 * Now, try to allocate the memory 440 */ 441 SMC_SELECT_BANK(2); 442 outw(BASE + MMU_CMD_REG_W, MMUCR_ALLOC | numPages); 443 444 /* 445 * Wait a short amount of time to see if the allocation request 446 * completes. Otherwise, I enable the interrupt and wait for 447 * completion asyncronously. 448 */ 449 450 time_out = MEMORY_WAIT_TIME; 451 do { 452 if (inb(BASE + INTR_STAT_REG_B) & IM_ALLOC_INT) 453 break; 454 } while (--time_out); 455 456 if (!time_out || junk > 10) { 457 458 /* 459 * No memory now. Oh well, wait until the chip finds memory 460 * later. Remember how many pages we were asking for and 461 * enable the allocation completion interrupt. Also set a 462 * watchdog in case we miss the interrupt. We mark the 463 * interface active since there is no point in attempting an 464 * snstart() until after the memory is available. 465 */ 466 mask = inb(BASE + INTR_MASK_REG_B) | IM_ALLOC_INT; 467 outb(BASE + INTR_MASK_REG_B, mask); 468 sc->intr_mask = mask; 469 470 sc->arpcom.ac_if.if_timer = 1; 471 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE; 472 sc->pages_wanted = numPages; 473 474 splx(s); 475 return; 476 } 477 /* 478 * The memory allocation completed. Check the results. 479 */ 480 packet_no = inb(BASE + ALLOC_RESULT_REG_B); 481 if (packet_no & ARR_FAILED) { 482 if (junk++ > 10) 483 printf("sn%d: Memory allocation failed\n", ifp->if_unit); 484 goto startagain; 485 } 486 /* 487 * We have a packet number, so tell the card to use it. 488 */ 489 outb(BASE + PACKET_NUM_REG_B, packet_no); 490 491 /* 492 * Point to the beginning of the packet 493 */ 494 outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000); 495 496 /* 497 * Send the packet length (+6 for status, length and control byte) 498 * and the status word (set to zeros) 499 */ 500 outw(BASE + DATA_REG_W, 0); 501 outb(BASE + DATA_REG_B, (length + 6) & 0xFF); 502 outb(BASE + DATA_REG_B, (length + 6) >> 8); 503 504 /* 505 * Get the packet from the kernel. This will include the Ethernet 506 * frame header, MAC Addresses etc. 507 */ 508 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 509 510 /* 511 * Push out the data to the card. 512 */ 513 for (top = m; m != 0; m = m->m_next) { 514 515 /* 516 * Push out words. 517 */ 518 outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2); 519 520 /* 521 * Push out remaining byte. 522 */ 523 if (m->m_len & 1) 524 outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1)); 525 } 526 527 /* 528 * Push out padding. 529 */ 530 while (pad > 1) { 531 outw(BASE + DATA_REG_W, 0); 532 pad -= 2; 533 } 534 if (pad) 535 outb(BASE + DATA_REG_B, 0); 536 537 /* 538 * Push out control byte and unused packet byte The control byte is 0 539 * meaning the packet is even lengthed and no special CRC handling is 540 * desired. 541 */ 542 outw(BASE + DATA_REG_W, 0); 543 544 /* 545 * Enable the interrupts and let the chipset deal with it Also set a 546 * watchdog in case we miss the interrupt. 547 */ 548 mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT); 549 outb(BASE + INTR_MASK_REG_B, mask); 550 sc->intr_mask = mask; 551 552 outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE); 553 554 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE; 555 sc->arpcom.ac_if.if_timer = 1; 556 557 if (ifp->if_bpf) { 558 bpf_mtap(ifp, top); 559 } 560 561 sc->arpcom.ac_if.if_opackets++; 562 m_freem(top); 563 564 565readcheck: 566 567 /* 568 * Is another packet coming in? We don't want to overflow the tiny 569 * RX FIFO. If nothing has arrived then attempt to queue another 570 * transmit packet. 571 */ 572 if (inw(BASE + FIFO_PORTS_REG_W) & FIFO_REMPTY) 573 goto startagain; 574 575 splx(s); 576 return; 577} 578 579 580 581/* Resume a packet transmit operation after a memory allocation 582 * has completed. 583 * 584 * This is basically a hacked up copy of snstart() which handles 585 * a completed memory allocation the same way snstart() does. 586 * It then passes control to snstart to handle any other queued 587 * packets. 588 */ 589static void 590snresume(struct ifnet *ifp) 591{ 592 register struct sn_softc *sc = ifp->if_softc; 593 register u_int len; 594 register struct mbuf *m; 595 struct mbuf *top; 596 int pad; 597 int mask; 598 u_short length; 599 u_short numPages; 600 u_short pages_wanted; 601 u_char packet_no; 602 603 if (sc->pages_wanted < 0) 604 return; 605 606 pages_wanted = sc->pages_wanted; 607 sc->pages_wanted = -1; 608 609 /* 610 * Sneak a peek at the next packet 611 */ 612 m = sc->arpcom.ac_if.if_snd.ifq_head; 613 if (m == 0) { 614 printf("sn%d: snresume() with nothing to send\n", ifp->if_unit); 615 return; 616 } 617 /* 618 * Compute the frame length and set pad to give an overall even 619 * number of bytes. Below we assume that the packet length is even. 620 */ 621 for (len = 0, top = m; m; m = m->m_next) 622 len += m->m_len; 623 624 pad = (len & 1); 625 626 /* 627 * We drop packets that are too large. Perhaps we should truncate 628 * them instead? 629 */ 630 if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) { 631 printf("sn%d: large packet discarded (B)\n", ifp->if_unit); 632 ++sc->arpcom.ac_if.if_oerrors; 633 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 634 m_freem(m); 635 return; 636 } 637#ifdef SW_PAD 638 639 /* 640 * If HW padding is not turned on, then pad to ETHER_MIN_LEN. 641 */ 642 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) 643 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len; 644 645#endif /* SW_PAD */ 646 647 length = pad + len; 648 649 650 /* 651 * The MMU wants the number of pages to be the number of 256 byte 652 * 'pages', minus 1 (A packet can't ever have 0 pages. We also 653 * include space for the status word, byte count and control bytes in 654 * the allocation request. 655 */ 656 numPages = (length + 6) >> 8; 657 658 659 SMC_SELECT_BANK(2); 660 661 /* 662 * The memory allocation completed. Check the results. If it failed, 663 * we simply set a watchdog timer and hope for the best. 664 */ 665 packet_no = inb(BASE + ALLOC_RESULT_REG_B); 666 if (packet_no & ARR_FAILED) { 667 printf("sn%d: Memory allocation failed. Weird.\n", ifp->if_unit); 668 sc->arpcom.ac_if.if_timer = 1; 669 goto try_start; 670 } 671 /* 672 * We have a packet number, so tell the card to use it. 673 */ 674 outb(BASE + PACKET_NUM_REG_B, packet_no); 675 676 /* 677 * Now, numPages should match the pages_wanted recorded when the 678 * memory allocation was initiated. 679 */ 680 if (pages_wanted != numPages) { 681 printf("sn%d: memory allocation wrong size. Weird.\n", ifp->if_unit); 682 /* 683 * If the allocation was the wrong size we simply release the 684 * memory once it is granted. Wait for the MMU to be un-busy. 685 */ 686 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */ 687 ; 688 outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT); 689 690 return; 691 } 692 /* 693 * Point to the beginning of the packet 694 */ 695 outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000); 696 697 /* 698 * Send the packet length (+6 for status, length and control byte) 699 * and the status word (set to zeros) 700 */ 701 outw(BASE + DATA_REG_W, 0); 702 outb(BASE + DATA_REG_B, (length + 6) & 0xFF); 703 outb(BASE + DATA_REG_B, (length + 6) >> 8); 704 705 /* 706 * Get the packet from the kernel. This will include the Ethernet 707 * frame header, MAC Addresses etc. 708 */ 709 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); 710 711 /* 712 * Push out the data to the card. 713 */ 714 for (top = m; m != 0; m = m->m_next) { 715 716 /* 717 * Push out words. 718 */ 719 outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2); 720 721 /* 722 * Push out remaining byte. 723 */ 724 if (m->m_len & 1) 725 outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1)); 726 } 727 728 /* 729 * Push out padding. 730 */ 731 while (pad > 1) { 732 outw(BASE + DATA_REG_W, 0); 733 pad -= 2; 734 } 735 if (pad) 736 outb(BASE + DATA_REG_B, 0); 737 738 /* 739 * Push out control byte and unused packet byte The control byte is 0 740 * meaning the packet is even lengthed and no special CRC handling is 741 * desired. 742 */ 743 outw(BASE + DATA_REG_W, 0); 744 745 /* 746 * Enable the interrupts and let the chipset deal with it Also set a 747 * watchdog in case we miss the interrupt. 748 */ 749 mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT); 750 outb(BASE + INTR_MASK_REG_B, mask); 751 sc->intr_mask = mask; 752 outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE); 753 754 if (ifp->if_bpf) { 755 bpf_mtap(ifp, top); 756 } 757 758 sc->arpcom.ac_if.if_opackets++; 759 m_freem(top); 760 761try_start: 762 763 /* 764 * Now pass control to snstart() to queue any additional packets 765 */ 766 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 767 snstart(ifp); 768 769 /* 770 * We've sent something, so we're active. Set a watchdog in case the 771 * TX_EMPTY interrupt is lost. 772 */ 773 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE; 774 sc->arpcom.ac_if.if_timer = 1; 775 776 return; 777} 778 779 780void 781sn_intr(void *arg) 782{ 783 int status, interrupts; 784 register struct sn_softc *sc = (struct sn_softc *) arg; 785 struct ifnet *ifp = &sc->arpcom.ac_if; 786 int x; 787 788 /* 789 * Chip state registers 790 */ 791 u_char mask; 792 u_char packet_no; 793 u_short tx_status; 794 u_short card_stats; 795 796 /* 797 * if_ep.c did this, so I do too. Yet if_ed.c doesn't. I wonder... 798 */ 799 x = splbio(); 800 801 /* 802 * Clear the watchdog. 803 */ 804 ifp->if_timer = 0; 805 806 SMC_SELECT_BANK(2); 807 808 /* 809 * Obtain the current interrupt mask and clear the hardware mask 810 * while servicing interrupts. 811 */ 812 mask = inb(BASE + INTR_MASK_REG_B); 813 outb(BASE + INTR_MASK_REG_B, 0x00); 814 815 /* 816 * Get the set of interrupts which occurred and eliminate any which 817 * are masked. 818 */ 819 interrupts = inb(BASE + INTR_STAT_REG_B); 820 status = interrupts & mask; 821 822 /* 823 * Now, process each of the interrupt types. 824 */ 825 826 /* 827 * Receive Overrun. 828 */ 829 if (status & IM_RX_OVRN_INT) { 830 831 /* 832 * Acknowlege Interrupt 833 */ 834 SMC_SELECT_BANK(2); 835 outb(BASE + INTR_ACK_REG_B, IM_RX_OVRN_INT); 836 837 ++sc->arpcom.ac_if.if_ierrors; 838 } 839 /* 840 * Got a packet. 841 */ 842 if (status & IM_RCV_INT) { 843#if 1 844 int packet_number; 845 846 SMC_SELECT_BANK(2); 847 packet_number = inw(BASE + FIFO_PORTS_REG_W); 848 849 if (packet_number & FIFO_REMPTY) { 850 851 /* 852 * we got called , but nothing was on the FIFO 853 */ 854 printf("sn: Receive interrupt with nothing on FIFO\n"); 855 856 goto out; 857 } 858#endif 859 snread(ifp); 860 } 861 /* 862 * An on-card memory allocation came through. 863 */ 864 if (status & IM_ALLOC_INT) { 865 866 /* 867 * Disable this interrupt. 868 */ 869 mask &= ~IM_ALLOC_INT; 870 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 871 snresume(&sc->arpcom.ac_if); 872 } 873 /* 874 * TX Completion. Handle a transmit error message. This will only be 875 * called when there is an error, because of the AUTO_RELEASE mode. 876 */ 877 if (status & IM_TX_INT) { 878 879 /* 880 * Acknowlege Interrupt 881 */ 882 SMC_SELECT_BANK(2); 883 outb(BASE + INTR_ACK_REG_B, IM_TX_INT); 884 885 packet_no = inw(BASE + FIFO_PORTS_REG_W); 886 packet_no &= FIFO_TX_MASK; 887 888 /* 889 * select this as the packet to read from 890 */ 891 outb(BASE + PACKET_NUM_REG_B, packet_no); 892 893 /* 894 * Position the pointer to the first word from this packet 895 */ 896 outw(BASE + POINTER_REG_W, PTR_AUTOINC | PTR_READ | 0x0000); 897 898 /* 899 * Fetch the TX status word. The value found here will be a 900 * copy of the EPH_STATUS_REG_W at the time the transmit 901 * failed. 902 */ 903 tx_status = inw(BASE + DATA_REG_W); 904 905 if (tx_status & EPHSR_TX_SUC) { 906 device_printf(sc->dev, 907 "Successful packet caused interrupt\n"); 908 } else { 909 ++sc->arpcom.ac_if.if_oerrors; 910 } 911 912 if (tx_status & EPHSR_LATCOL) 913 ++sc->arpcom.ac_if.if_collisions; 914 915 /* 916 * Some of these errors will have disabled transmit. 917 * Re-enable transmit now. 918 */ 919 SMC_SELECT_BANK(0); 920 921#ifdef SW_PAD 922 outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE); 923#else 924 outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE | TCR_PAD_ENABLE); 925#endif /* SW_PAD */ 926 927 /* 928 * kill the failed packet. Wait for the MMU to be un-busy. 929 */ 930 SMC_SELECT_BANK(2); 931 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */ 932 ; 933 outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT); 934 935 /* 936 * Attempt to queue more transmits. 937 */ 938 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 939 snstart(&sc->arpcom.ac_if); 940 } 941 /* 942 * Transmit underrun. We use this opportunity to update transmit 943 * statistics from the card. 944 */ 945 if (status & IM_TX_EMPTY_INT) { 946 947 /* 948 * Acknowlege Interrupt 949 */ 950 SMC_SELECT_BANK(2); 951 outb(BASE + INTR_ACK_REG_B, IM_TX_EMPTY_INT); 952 953 /* 954 * Disable this interrupt. 955 */ 956 mask &= ~IM_TX_EMPTY_INT; 957 958 SMC_SELECT_BANK(0); 959 card_stats = inw(BASE + COUNTER_REG_W); 960 961 /* 962 * Single collisions 963 */ 964 sc->arpcom.ac_if.if_collisions += card_stats & ECR_COLN_MASK; 965 966 /* 967 * Multiple collisions 968 */ 969 sc->arpcom.ac_if.if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4; 970 971 SMC_SELECT_BANK(2); 972 973 /* 974 * Attempt to enqueue some more stuff. 975 */ 976 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 977 snstart(&sc->arpcom.ac_if); 978 } 979 /* 980 * Some other error. Try to fix it by resetting the adapter. 981 */ 982 if (status & IM_EPH_INT) { 983 snstop(sc); 984 sninit(sc); 985 } 986 987out: 988 /* 989 * Handled all interrupt sources. 990 */ 991 992 SMC_SELECT_BANK(2); 993 994 /* 995 * Reestablish interrupts from mask which have not been deselected 996 * during this interrupt. Note that the hardware mask, which was set 997 * to 0x00 at the start of this service routine, may have been 998 * updated by one or more of the interrupt handers and we must let 999 * those new interrupts stay enabled here. 1000 */ 1001 mask |= inb(BASE + INTR_MASK_REG_B); 1002 outb(BASE + INTR_MASK_REG_B, mask); 1003 sc->intr_mask = mask; 1004 1005 splx(x); 1006} 1007 1008void 1009snread(register struct ifnet *ifp) 1010{ 1011 struct sn_softc *sc = ifp->if_softc; 1012 struct ether_header *eh; 1013 struct mbuf *m; 1014 short status; 1015 int packet_number; 1016 u_short packet_length; 1017 u_char *data; 1018 1019 SMC_SELECT_BANK(2); 1020#if 0 1021 packet_number = inw(BASE + FIFO_PORTS_REG_W); 1022 1023 if (packet_number & FIFO_REMPTY) { 1024 1025 /* 1026 * we got called , but nothing was on the FIFO 1027 */ 1028 printf("sn: Receive interrupt with nothing on FIFO\n"); 1029 return; 1030 } 1031#endif 1032read_another: 1033 1034 /* 1035 * Start reading from the start of the packet. Since PTR_RCV is set, 1036 * packet number is found in FIFO_PORTS_REG_W, FIFO_RX_MASK. 1037 */ 1038 outw(BASE + POINTER_REG_W, PTR_READ | PTR_RCV | PTR_AUTOINC | 0x0000); 1039 1040 /* 1041 * First two words are status and packet_length 1042 */ 1043 status = inw(BASE + DATA_REG_W); 1044 packet_length = inw(BASE + DATA_REG_W) & RLEN_MASK; 1045 1046 /* 1047 * The packet length contains 3 extra words: status, length, and a 1048 * extra word with the control byte. 1049 */ 1050 packet_length -= 6; 1051 1052 /* 1053 * Account for receive errors and discard. 1054 */ 1055 if (status & RS_ERRORS) { 1056 ++sc->arpcom.ac_if.if_ierrors; 1057 goto out; 1058 } 1059 /* 1060 * A packet is received. 1061 */ 1062 1063 /* 1064 * Adjust for odd-length packet. 1065 */ 1066 if (status & RS_ODDFRAME) 1067 packet_length++; 1068 1069 /* 1070 * Allocate a header mbuf from the kernel. 1071 */ 1072 MGETHDR(m, M_DONTWAIT, MT_DATA); 1073 if (m == NULL) 1074 goto out; 1075 1076 m->m_pkthdr.rcvif = &sc->arpcom.ac_if; 1077 m->m_pkthdr.len = m->m_len = packet_length; 1078 1079 /* 1080 * Attach an mbuf cluster 1081 */ 1082 MCLGET(m, M_DONTWAIT); 1083 1084 /* 1085 * Insist on getting a cluster 1086 */ 1087 if ((m->m_flags & M_EXT) == 0) { 1088 m_freem(m); 1089 ++sc->arpcom.ac_if.if_ierrors; 1090 printf("sn: snread() kernel memory allocation problem\n"); 1091 goto out; 1092 } 1093 eh = mtod(m, struct ether_header *); 1094 1095 /* 1096 * Get packet, including link layer address, from interface. 1097 */ 1098 1099 data = (u_char *) eh; 1100 insw(BASE + DATA_REG_W, data, packet_length >> 1); 1101 if (packet_length & 1) { 1102 data += packet_length & ~1; 1103 *data = inb(BASE + DATA_REG_B); 1104 } 1105 ++sc->arpcom.ac_if.if_ipackets; 1106 1107 /* 1108 * Remove link layer addresses and whatnot. 1109 */ 1110 m->m_pkthdr.len = m->m_len = packet_length - sizeof(struct ether_header); 1111 m->m_data += sizeof(struct ether_header); 1112 1113 ether_input(&sc->arpcom.ac_if, eh, m); 1114 1115out: 1116 1117 /* 1118 * Error or good, tell the card to get rid of this packet Wait for 1119 * the MMU to be un-busy. 1120 */ 1121 SMC_SELECT_BANK(2); 1122 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */ 1123 ; 1124 outw(BASE + MMU_CMD_REG_W, MMUCR_RELEASE); 1125 1126 /* 1127 * Check whether another packet is ready 1128 */ 1129 packet_number = inw(BASE + FIFO_PORTS_REG_W); 1130 if (packet_number & FIFO_REMPTY) { 1131 return; 1132 } 1133 goto read_another; 1134} 1135 1136 1137/* 1138 * Handle IOCTLS. This function is completely stolen from if_ep.c 1139 * As with its progenitor, it does not handle hardware address 1140 * changes. 1141 */ 1142static int 1143snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data) 1144{ 1145 struct sn_softc *sc = ifp->if_softc; 1146 int s, error = 0; 1147 1148 s = splimp(); 1149 1150 switch (cmd) { 1151 case SIOCSIFADDR: 1152 case SIOCGIFADDR: 1153 case SIOCSIFMTU: 1154 error = ether_ioctl(ifp, cmd, data); 1155 break; 1156 1157 case SIOCSIFFLAGS: 1158 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { 1159 ifp->if_flags &= ~IFF_RUNNING; 1160 snstop(sc); 1161 break; 1162 } else { 1163 /* reinitialize card on any parameter change */ 1164 sninit(sc); 1165 break; 1166 } 1167 break; 1168 1169#ifdef notdef 1170 case SIOCGHWADDR: 1171 bcopy((caddr_t) sc->sc_addr, (caddr_t) & ifr->ifr_data, 1172 sizeof(sc->sc_addr)); 1173 break; 1174#endif 1175 1176 case SIOCADDMULTI: 1177 /* update multicast filter list. */ 1178 sn_setmcast(sc); 1179 error = 0; 1180 break; 1181 case SIOCDELMULTI: 1182 /* update multicast filter list. */ 1183 sn_setmcast(sc); 1184 error = 0; 1185 break; 1186 default: 1187 error = EINVAL; 1188 } 1189 1190 splx(s); 1191 1192 return (error); 1193} 1194 1195void 1196snreset(struct sn_softc *sc) 1197{ 1198 int s; 1199 1200 s = splimp(); 1201 snstop(sc); 1202 sninit(sc); 1203 1204 splx(s); 1205} 1206 1207void 1208snwatchdog(struct ifnet *ifp) 1209{ 1210 int s; 1211 s = splimp(); 1212 sn_intr(ifp->if_softc); 1213 splx(s); 1214} 1215 1216 1217/* 1. zero the interrupt mask 1218 * 2. clear the enable receive flag 1219 * 3. clear the enable xmit flags 1220 */ 1221void 1222snstop(struct sn_softc *sc) 1223{ 1224 1225 struct ifnet *ifp = &sc->arpcom.ac_if; 1226 1227 /* 1228 * Clear interrupt mask; disable all interrupts. 1229 */ 1230 SMC_SELECT_BANK(2); 1231 outb(BASE + INTR_MASK_REG_B, 0x00); 1232 1233 /* 1234 * Disable transmitter and Receiver 1235 */ 1236 SMC_SELECT_BANK(0); 1237 outw(BASE + RECV_CONTROL_REG_W, 0x0000); 1238 outw(BASE + TXMIT_CONTROL_REG_W, 0x0000); 1239 1240 /* 1241 * Cancel watchdog. 1242 */ 1243 ifp->if_timer = 0; 1244} 1245 1246 1247int 1248sn_activate(device_t dev) 1249{ 1250 struct sn_softc *sc = device_get_softc(dev); 1251 int err; 1252 1253 sc->port_rid = 0; 1254 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, 1255 0, ~0, SMC_IO_EXTENT, RF_ACTIVE); 1256 if (!sc->port_res) { 1257 if (bootverbose) 1258 device_printf(dev, "Cannot allocate ioport\n"); 1259 return ENOMEM; 1260 } 1261 1262 sc->irq_rid = 0; 1263 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 1264 0, ~0, 1, RF_ACTIVE); 1265 if (!sc->irq_res) { 1266 if (bootverbose) 1267 device_printf(dev, "Cannot allocate irq\n"); 1268 sn_deactivate(dev); 1269 return ENOMEM; 1270 } 1271 if ((err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, sn_intr, sc, 1272 &sc->intrhand)) != 0) { 1273 sn_deactivate(dev); 1274 return err; 1275 } 1276 1277 sc->sn_io_addr = rman_get_start(sc->port_res); 1278 return (0); 1279} 1280 1281void 1282sn_deactivate(device_t dev) 1283{ 1284 struct sn_softc *sc = device_get_softc(dev); 1285 1286 if (sc->intrhand) 1287 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 1288 sc->intrhand = 0; 1289 if (sc->port_res) 1290 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, 1291 sc->port_res); 1292 sc->port_res = 0; 1293 if (sc->irq_res) 1294 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, 1295 sc->irq_res); 1296 sc->irq_res = 0; 1297 return; 1298} 1299 1300/* 1301 * Function: sn_probe( device_t dev, int pccard ) 1302 * 1303 * Purpose: 1304 * Tests to see if a given ioaddr points to an SMC9xxx chip. 1305 * Tries to cause as little damage as possible if it's not a SMC chip. 1306 * Returns a 0 on success 1307 * 1308 * Algorithm: 1309 * (1) see if the high byte of BANK_SELECT is 0x33 1310 * (2) compare the ioaddr with the base register's address 1311 * (3) see if I recognize the chip ID in the appropriate register 1312 * 1313 * 1314 */ 1315int 1316sn_probe(device_t dev, int pccard) 1317{ 1318 struct sn_softc *sc = device_get_softc(dev); 1319 u_int bank; 1320 u_short revision_register; 1321 u_short base_address_register; 1322 u_short ioaddr; 1323 int err; 1324 1325 if ((err = sn_activate(dev)) != 0) 1326 return err; 1327 1328 ioaddr = sc->sn_io_addr; 1329#ifdef SN_DEBUG 1330 device_printf(dev, "ioaddr is 0x%x\n", ioaddr); 1331#endif 1332 /* 1333 * First, see if the high byte is 0x33 1334 */ 1335 bank = inw(ioaddr + BANK_SELECT_REG_W); 1336 if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) { 1337#ifdef SN_DEBUG 1338 device_printf(dev, "test1 failed\n"); 1339#endif 1340 goto error; 1341 } 1342 /* 1343 * The above MIGHT indicate a device, but I need to write to further 1344 * test this. Go to bank 0, then test that the register still 1345 * reports the high byte is 0x33. 1346 */ 1347 outw(ioaddr + BANK_SELECT_REG_W, 0x0000); 1348 bank = inw(ioaddr + BANK_SELECT_REG_W); 1349 if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) { 1350#ifdef SN_DEBUG 1351 device_printf(dev, "test2 failed\n"); 1352#endif 1353 goto error; 1354 } 1355 /* 1356 * well, we've already written once, so hopefully another time won't 1357 * hurt. This time, I need to switch the bank register to bank 1, so 1358 * I can access the base address register. The contents of the 1359 * BASE_ADDR_REG_W register, after some jiggery pokery, is expected 1360 * to match the I/O port address where the adapter is being probed. 1361 */ 1362 outw(ioaddr + BANK_SELECT_REG_W, 0x0001); 1363 base_address_register = inw(ioaddr + BASE_ADDR_REG_W); 1364 1365 /* 1366 * This test is nonsence on PC-card architecture, so if 1367 * pccard == 1, skip this test. (hosokawa) 1368 */ 1369 if (!pccard && (ioaddr != (base_address_register >> 3 & 0x3E0))) { 1370 1371 /* 1372 * Well, the base address register didn't match. Must not 1373 * have been a SMC chip after all. 1374 */ 1375#ifdef SN_DEBUG 1376 device_printf(dev, "test3 failed ioaddr = 0x%x, " 1377 "base_address_register = 0x%x\n", ioaddr, 1378 base_address_register >> 3 & 0x3E0); 1379#endif 1380 goto error; 1381 } 1382 1383 /* 1384 * Check if the revision register is something that I recognize. 1385 * These might need to be added to later, as future revisions could 1386 * be added. 1387 */ 1388 outw(ioaddr + BANK_SELECT_REG_W, 0x3); 1389 revision_register = inw(ioaddr + REVISION_REG_W); 1390 if (!chip_ids[(revision_register >> 4) & 0xF]) { 1391 1392 /* 1393 * I don't regonize this chip, so... 1394 */ 1395#ifdef SN_DEBUG 1396 device_printf(dev, "test4 failed\n"); 1397#endif 1398 goto error; 1399 } 1400 1401 /* 1402 * at this point I'll assume that the chip is an SMC9xxx. It might be 1403 * prudent to check a listing of MAC addresses against the hardware 1404 * address, or do some other tests. 1405 */ 1406 sn_deactivate(dev); 1407 return 0; 1408 error: 1409 sn_deactivate(dev); 1410 return ENXIO; 1411} 1412 1413#define MCFSZ 8 1414 1415static void 1416sn_setmcast(struct sn_softc *sc) 1417{ 1418 struct ifnet *ifp = (struct ifnet *)sc; 1419 int flags; 1420 1421 /* 1422 * Set the receiver filter. We want receive enabled and auto strip 1423 * of CRC from received packet. If we are promiscuous then set that 1424 * bit too. 1425 */ 1426 flags = RCR_ENABLE | RCR_STRIP_CRC; 1427 1428 if (ifp->if_flags & IFF_PROMISC) { 1429 flags |= RCR_PROMISC | RCR_ALMUL; 1430 } else if (ifp->if_flags & IFF_ALLMULTI) { 1431 flags |= RCR_ALMUL; 1432 } else { 1433 u_char mcf[MCFSZ]; 1434 if (sn_getmcf(&sc->arpcom, mcf)) { 1435 /* set filter */ 1436 SMC_SELECT_BANK(3); 1437 outw(BASE + MULTICAST1_REG_W, 1438 ((u_short)mcf[1] << 8) | mcf[0]); 1439 outw(BASE + MULTICAST2_REG_W, 1440 ((u_short)mcf[3] << 8) | mcf[2]); 1441 outw(BASE + MULTICAST3_REG_W, 1442 ((u_short)mcf[5] << 8) | mcf[4]); 1443 outw(BASE + MULTICAST4_REG_W, 1444 ((u_short)mcf[7] << 8) | mcf[6]); 1445 } else { 1446 flags |= RCR_ALMUL; 1447 } 1448 } 1449 SMC_SELECT_BANK(0); 1450 outw(BASE + RECV_CONTROL_REG_W, flags); 1451} 1452 1453static int 1454sn_getmcf(struct arpcom *ac, u_char *mcf) 1455{ 1456 int i; 1457 register u_int index, index2; 1458 register u_char *af = (u_char *) mcf; 1459 struct ifmultiaddr *ifma; 1460 1461 bzero(mcf, MCFSZ); 1462 1463 TAILQ_FOREACH(ifma, &ac->ac_if.if_multiaddrs, ifma_link) { 1464 if (ifma->ifma_addr->sa_family != AF_LINK) 1465 return 0; 1466 index = smc_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) & 0x3f; 1467 index2 = 0; 1468 for (i = 0; i < 6; i++) { 1469 index2 <<= 1; 1470 index2 |= (index & 0x01); 1471 index >>= 1; 1472 } 1473 af[index2 >> 3] |= 1 << (index2 & 7); 1474 } 1475 return 1; /* use multicast filter */ 1476} 1477 1478static u_int 1479smc_crc(u_char *s) 1480{ 1481 int perByte; 1482 int perBit; 1483 const u_int poly = 0xedb88320; 1484 u_int v = 0xffffffff; 1485 u_char c; 1486 1487 for (perByte = 0; perByte < ETHER_ADDR_LEN; perByte++) { 1488 c = s[perByte]; 1489 for (perBit = 0; perBit < 8; perBit++) { 1490 v = (v >> 1)^(((v ^ c) & 0x01) ? poly : 0); 1491 c >>= 1; 1492 } 1493 } 1494 return v; 1495} 1496