The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sn/if_sn.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Gardner Buchanan.
   16  * 4. The name of Gardner Buchanan may not be used to endorse or promote
   17  *    products derived from this software without specific prior written
   18  *    permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: src/sys/dev/sn/if_sn.c,v 1.41.2.2 2006/01/29 15:39:06 emaste Exp $");
   34 
   35 /*
   36  * This is a driver for SMC's 9000 series of Ethernet adapters.
   37  *
   38  * This FreeBSD driver is derived from the smc9194 Linux driver by
   39  * Erik Stahlman and is Copyright (C) 1996 by Erik Stahlman.
   40  * This driver also shamelessly borrows from the FreeBSD ep driver
   41  * which is Copyright (C) 1994 Herb Peyerl <hpeyerl@novatel.ca>
   42  * All rights reserved.
   43  *
   44  * It is set up for my SMC91C92 equipped Ampro LittleBoard embedded
   45  * PC.  It is adapted from Erik Stahlman's Linux driver which worked
   46  * with his EFA Info*Express SVC VLB adaptor.  According to SMC's databook,
   47  * it will work for the entire SMC 9xxx series. (Ha Ha)
   48  *
   49  * "Features" of the SMC chip:
   50  *   4608 byte packet memory. (for the 91C92.  Others have more)
   51  *   EEPROM for configuration
   52  *   AUI/TP selection
   53  *
   54  * Authors:
   55  *      Erik Stahlman                   erik@vt.edu
   56  *      Herb Peyerl                     hpeyerl@novatel.ca
   57  *      Andres Vega Garcia              avega@sophia.inria.fr
   58  *      Serge Babkin                    babkin@hq.icb.chel.su
   59  *      Gardner Buchanan                gbuchanan@shl.com
   60  *
   61  * Sources:
   62  *    o   SMC databook
   63  *    o   "smc9194.c:v0.10(FIXED) 02/15/96 by Erik Stahlman (erik@vt.edu)"
   64  *    o   "if_ep.c,v 1.19 1995/01/24 20:53:45 davidg Exp"
   65  *
   66  * Known Bugs:
   67  *    o   Setting of the hardware address isn't supported.
   68  *    o   Hardware padding isn't used.
   69  */
   70 
   71 /*
   72  * Modifications for Megahertz X-Jack Ethernet Card (XJ-10BT)
   73  * 
   74  * Copyright (c) 1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>
   75  *                       BSD-nomads, Tokyo, Japan.
   76  */
   77 /*
   78  * Multicast support by Kei TANAKA <kei@pal.xerox.com>
   79  * Special thanks to itojun@itojun.org
   80  */
   81 
   82 #include <sys/param.h>
   83 #include <sys/systm.h>
   84 #include <sys/errno.h>
   85 #include <sys/sockio.h>
   86 #include <sys/mbuf.h>
   87 #include <sys/socket.h>
   88 #include <sys/syslog.h>
   89 
   90 #include <sys/module.h>
   91 #include <sys/bus.h>
   92 
   93 #include <machine/bus.h>
   94 #include <machine/resource.h>
   95 #include <sys/rman.h> 
   96 
   97 #include <net/ethernet.h>
   98 #include <net/if.h>
   99 #include <net/if_arp.h>
  100 #include <net/if_dl.h>
  101 #include <net/if_types.h>
  102 #include <net/if_mib.h>
  103 
  104 #ifdef INET
  105 #include <netinet/in.h>
  106 #include <netinet/in_systm.h>
  107 #include <netinet/in_var.h>
  108 #include <netinet/ip.h>
  109 #endif
  110 
  111 #include <net/bpf.h>
  112 #include <net/bpfdesc.h>
  113 
  114 
  115 #include <dev/sn/if_snreg.h>
  116 #include <dev/sn/if_snvar.h>
  117 
  118 /* Exported variables */
  119 devclass_t sn_devclass;
  120 
  121 static int snioctl(struct ifnet * ifp, u_long, caddr_t);
  122 
  123 static void snresume(struct ifnet *);
  124 
  125 static void sninit_locked(void *);
  126 static void snstart_locked(struct ifnet *);
  127 
  128 static void sninit(void *);
  129 static void snread(struct ifnet *);
  130 static void snstart(struct ifnet *);
  131 static void snstop(struct sn_softc *);
  132 static void snwatchdog(struct ifnet *);
  133 
  134 static void sn_setmcast(struct sn_softc *);
  135 static int sn_getmcf(struct arpcom *ac, u_char *mcf);
  136 
  137 /* I (GB) have been unlucky getting the hardware padding
  138  * to work properly.
  139  */
  140 #define SW_PAD
  141 
  142 static const char *chip_ids[15] = {
  143         NULL, NULL, NULL,
  144          /* 3 */ "SMC91C90/91C92",
  145          /* 4 */ "SMC91C94",
  146          /* 5 */ "SMC91C95",
  147         NULL,
  148          /* 7 */ "SMC91C100",
  149          /* 8 */ "SMC91C100FD",
  150         NULL, NULL, NULL,
  151         NULL, NULL, NULL
  152 };
  153 
  154 int
  155 sn_attach(device_t dev)
  156 {
  157         struct sn_softc *sc = device_get_softc(dev);
  158         struct ifnet    *ifp = &sc->arpcom.ac_if;
  159         uint16_t        i, w;
  160         uint8_t         *p;
  161         int             rev;
  162         uint16_t        address;
  163         int             j;
  164         int             err;
  165 
  166         sc->dev = dev;
  167         sn_activate(dev);
  168         SN_LOCK_INIT(sc);
  169         snstop(sc);
  170         sc->pages_wanted = -1;
  171 
  172         SMC_SELECT_BANK(sc, 3);
  173         rev = (CSR_READ_2(sc, REVISION_REG_W) >> 4) & 0xf;
  174         if (chip_ids[rev])
  175                 device_printf(dev, " %s ", chip_ids[rev]);
  176         else
  177                 device_printf(dev, " unsupported chip");
  178 
  179         SMC_SELECT_BANK(sc, 1);
  180         i = CSR_READ_2(sc, CONFIG_REG_W);
  181         printf(i & CR_AUI_SELECT ? "AUI" : "UTP");
  182 
  183         if (sc->pccard_enaddr)
  184                 for (j = 0; j < 3; j++) {
  185                         w = (uint16_t)sc->arpcom.ac_enaddr[j * 2] | 
  186                             (((uint16_t)sc->arpcom.ac_enaddr[j * 2 + 1]) << 8);
  187                         CSR_WRITE_2(sc, IAR_ADDR0_REG_W + j * 2, w);
  188                 }
  189 
  190         /*
  191          * Read the station address from the chip. The MAC address is bank 1,
  192          * regs 4 - 9
  193          */
  194         SMC_SELECT_BANK(sc, 1);
  195         p = (uint8_t *) &sc->arpcom.ac_enaddr;
  196         for (i = 0; i < 6; i += 2) {
  197                 address = CSR_READ_2(sc, IAR_ADDR0_REG_W + i);
  198                 p[i + 1] = address >> 8;
  199                 p[i] = address & 0xFF;
  200         }
  201         ifp->if_softc = sc;
  202         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  203         ifp->if_mtu = ETHERMTU;
  204         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  205         ifp->if_start = snstart;
  206         ifp->if_ioctl = snioctl;
  207         ifp->if_watchdog = snwatchdog;
  208         ifp->if_init = sninit;
  209         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  210         ifp->if_timer = 0;
  211 
  212         ether_ifattach(ifp, sc->arpcom.ac_enaddr);
  213 
  214         /*
  215          * Activate the interrupt so we can get card interrupts.  This
  216          * needs to be done last so that we don't have/hold the lock
  217          * during startup to avoid LORs in the network layer.
  218          */
  219         if ((err = bus_setup_intr(dev, sc->irq_res,
  220             INTR_TYPE_NET | INTR_MPSAFE, sn_intr, sc, &sc->intrhand)) != 0) {
  221                 sn_detach(dev);
  222                 return err;
  223         }
  224         return 0;
  225 }
  226 
  227 
  228 int
  229 sn_detach(device_t dev)
  230 {
  231         struct sn_softc *sc = device_get_softc(dev);
  232 
  233         snstop(sc);
  234         sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING; 
  235         ether_ifdetach(&sc->arpcom.ac_if);
  236         sn_deactivate(dev);
  237         SN_LOCK_DESTORY(sc);
  238         return 0;
  239 }
  240 
  241 static void
  242 sninit(void *xsc)
  243 {
  244         struct sn_softc *sc = xsc;
  245         SN_LOCK(sc);
  246         sninit_locked(sc);
  247         SN_UNLOCK(sc);
  248 }
  249 
  250 /*
  251  * Reset and initialize the chip
  252  */
  253 static void
  254 sninit_locked(void *xsc)
  255 {
  256         struct sn_softc *sc = xsc;
  257         struct ifnet *ifp = &sc->arpcom.ac_if;
  258         int             flags;
  259         int             mask;
  260 
  261         SN_ASSERT_LOCKED(sc);
  262 
  263         /*
  264          * This resets the registers mostly to defaults, but doesn't affect
  265          * EEPROM.  After the reset cycle, we pause briefly for the chip to
  266          * be happy.
  267          */
  268         SMC_SELECT_BANK(sc, 0);
  269         CSR_WRITE_2(sc, RECV_CONTROL_REG_W, RCR_SOFTRESET);
  270         SMC_DELAY(sc);
  271         CSR_WRITE_2(sc, RECV_CONTROL_REG_W, 0x0000);
  272         SMC_DELAY(sc);
  273         SMC_DELAY(sc);
  274 
  275         CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, 0x0000);
  276 
  277         /*
  278          * Set the control register to automatically release succesfully
  279          * transmitted packets (making the best use out of our limited
  280          * memory) and to enable the EPH interrupt on certain TX errors.
  281          */
  282         SMC_SELECT_BANK(sc, 1);
  283         CSR_WRITE_2(sc, CONTROL_REG_W, (CTR_AUTO_RELEASE | CTR_TE_ENABLE |
  284                                     CTR_CR_ENABLE | CTR_LE_ENABLE));
  285 
  286         /* Set squelch level to 240mV (default 480mV) */
  287         flags = CSR_READ_2(sc, CONFIG_REG_W);
  288         flags |= CR_SET_SQLCH;
  289         CSR_WRITE_2(sc, CONFIG_REG_W, flags);
  290 
  291         /*
  292          * Reset the MMU and wait for it to be un-busy.
  293          */
  294         SMC_SELECT_BANK(sc, 2);
  295         CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_RESET);
  296         while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY)      /* NOTHING */
  297                 ;
  298 
  299         /*
  300          * Disable all interrupts
  301          */
  302         CSR_WRITE_1(sc, INTR_MASK_REG_B, 0x00);
  303 
  304         sn_setmcast(sc);
  305 
  306         /*
  307          * Set the transmitter control.  We want it enabled.
  308          */
  309         flags = TCR_ENABLE;
  310 
  311 #ifndef SW_PAD
  312         /*
  313          * I (GB) have been unlucky getting this to work.
  314          */
  315         flags |= TCR_PAD_ENABLE;
  316 #endif  /* SW_PAD */
  317 
  318         CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, flags);
  319 
  320 
  321         /*
  322          * Now, enable interrupts
  323          */
  324         SMC_SELECT_BANK(sc, 2);
  325 
  326         mask = IM_EPH_INT |
  327                 IM_RX_OVRN_INT |
  328                 IM_RCV_INT |
  329                 IM_TX_INT;
  330 
  331         CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
  332         sc->intr_mask = mask;
  333         sc->pages_wanted = -1;
  334 
  335 
  336         /*
  337          * Mark the interface running but not active.
  338          */
  339         ifp->if_flags |= IFF_RUNNING;
  340         ifp->if_flags &= ~IFF_OACTIVE;
  341 
  342         /*
  343          * Attempt to push out any waiting packets.
  344          */
  345         snstart_locked(ifp);
  346 }
  347 
  348 static void
  349 snstart(struct ifnet *ifp)
  350 {
  351         struct sn_softc *sc = ifp->if_softc;
  352         SN_LOCK(sc);
  353         snstart_locked(ifp);
  354         SN_UNLOCK(sc);
  355 }
  356 
  357 
  358 static void
  359 snstart_locked(struct ifnet *ifp)
  360 {
  361         struct sn_softc *sc = ifp->if_softc;
  362         u_int           len;
  363         struct mbuf     *m;
  364         struct mbuf     *top;
  365         int             pad;
  366         int             mask;
  367         uint16_t        length;
  368         uint16_t        numPages;
  369         uint8_t         packet_no;
  370         int             time_out;
  371         int             junk = 0;
  372 
  373         SN_ASSERT_LOCKED(sc);
  374 
  375         if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE)
  376                 return;
  377         if (sc->pages_wanted != -1) {
  378                 if_printf(ifp, "snstart() while memory allocation pending\n");
  379                 return;
  380         }
  381 startagain:
  382 
  383         /*
  384          * Sneak a peek at the next packet
  385          */
  386         m = sc->arpcom.ac_if.if_snd.ifq_head;
  387         if (m == 0)
  388                 return;
  389         /*
  390          * Compute the frame length and set pad to give an overall even
  391          * number of bytes.  Below we assume that the packet length is even.
  392          */
  393         for (len = 0, top = m; m; m = m->m_next)
  394                 len += m->m_len;
  395 
  396         pad = (len & 1);
  397 
  398         /*
  399          * We drop packets that are too large. Perhaps we should truncate
  400          * them instead?
  401          */
  402         if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
  403                 if_printf(ifp, "large packet discarded (A)\n");
  404                 ++sc->arpcom.ac_if.if_oerrors;
  405                 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
  406                 m_freem(m);
  407                 goto readcheck;
  408         }
  409 #ifdef SW_PAD
  410 
  411         /*
  412          * If HW padding is not turned on, then pad to ETHER_MIN_LEN.
  413          */
  414         if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
  415                 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
  416 
  417 #endif  /* SW_PAD */
  418 
  419         length = pad + len;
  420 
  421         /*
  422          * The MMU wants the number of pages to be the number of 256 byte
  423          * 'pages', minus 1 (A packet can't ever have 0 pages. We also
  424          * include space for the status word, byte count and control bytes in
  425          * the allocation request.
  426          */
  427         numPages = (length + 6) >> 8;
  428 
  429 
  430         /*
  431          * Now, try to allocate the memory
  432          */
  433         SMC_SELECT_BANK(sc, 2);
  434         CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ALLOC | numPages);
  435 
  436         /*
  437          * Wait a short amount of time to see if the allocation request
  438          * completes.  Otherwise, I enable the interrupt and wait for
  439          * completion asyncronously.
  440          */
  441 
  442         time_out = MEMORY_WAIT_TIME;
  443         do {
  444                 if (CSR_READ_1(sc, INTR_STAT_REG_B) & IM_ALLOC_INT)
  445                         break;
  446         } while (--time_out);
  447 
  448         if (!time_out || junk > 10) {
  449 
  450                 /*
  451                  * No memory now.  Oh well, wait until the chip finds memory
  452                  * later.   Remember how many pages we were asking for and
  453                  * enable the allocation completion interrupt. Also set a
  454                  * watchdog in case  we miss the interrupt. We mark the
  455                  * interface active since there is no point in attempting an
  456                  * snstart() until after the memory is available.
  457                  */
  458                 mask = CSR_READ_1(sc, INTR_MASK_REG_B) | IM_ALLOC_INT;
  459                 CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
  460                 sc->intr_mask = mask;
  461 
  462                 sc->arpcom.ac_if.if_timer = 1;
  463                 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
  464                 sc->pages_wanted = numPages;
  465                 return;
  466         }
  467         /*
  468          * The memory allocation completed.  Check the results.
  469          */
  470         packet_no = CSR_READ_1(sc, ALLOC_RESULT_REG_B);
  471         if (packet_no & ARR_FAILED) {
  472                 if (junk++ > 10)
  473                         if_printf(ifp, "Memory allocation failed\n");
  474                 goto startagain;
  475         }
  476         /*
  477          * We have a packet number, so tell the card to use it.
  478          */
  479         CSR_WRITE_1(sc, PACKET_NUM_REG_B, packet_no);
  480 
  481         /*
  482          * Point to the beginning of the packet
  483          */
  484         CSR_WRITE_2(sc, POINTER_REG_W, PTR_AUTOINC | 0x0000);
  485 
  486         /*
  487          * Send the packet length (+6 for status, length and control byte)
  488          * and the status word (set to zeros)
  489          */
  490         CSR_WRITE_2(sc, DATA_REG_W, 0);
  491         CSR_WRITE_1(sc, DATA_REG_B, (length + 6) & 0xFF);
  492         CSR_WRITE_1(sc, DATA_REG_B, (length + 6) >> 8);
  493 
  494         /*
  495          * Get the packet from the kernel.  This will include the Ethernet
  496          * frame header, MAC Addresses etc.
  497          */
  498         IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
  499 
  500         /*
  501          * Push out the data to the card.
  502          */
  503         for (top = m; m != 0; m = m->m_next) {
  504 
  505                 /*
  506                  * Push out words.
  507                  */
  508                 CSR_WRITE_MULTI_2(sc, DATA_REG_W, mtod(m, uint16_t *),
  509                     m->m_len / 2);
  510 
  511                 /*
  512                  * Push out remaining byte.
  513                  */
  514                 if (m->m_len & 1)
  515                         CSR_WRITE_1(sc, DATA_REG_B,
  516                             *(mtod(m, caddr_t) + m->m_len - 1));
  517         }
  518 
  519         /*
  520          * Push out padding.
  521          */
  522         while (pad > 1) {
  523                 CSR_WRITE_2(sc, DATA_REG_W, 0);
  524                 pad -= 2;
  525         }
  526         if (pad)
  527                 CSR_WRITE_1(sc, DATA_REG_B, 0);
  528 
  529         /*
  530          * Push out control byte and unused packet byte The control byte is 0
  531          * meaning the packet is even lengthed and no special CRC handling is
  532          * desired.
  533          */
  534         CSR_WRITE_2(sc, DATA_REG_W, 0);
  535 
  536         /*
  537          * Enable the interrupts and let the chipset deal with it Also set a
  538          * watchdog in case we miss the interrupt.
  539          */
  540         mask = CSR_READ_1(sc, INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
  541         CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
  542         sc->intr_mask = mask;
  543 
  544         CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ENQUEUE);
  545 
  546         sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
  547         sc->arpcom.ac_if.if_timer = 1;
  548 
  549         BPF_MTAP(ifp, top);
  550 
  551         sc->arpcom.ac_if.if_opackets++;
  552         m_freem(top);
  553 
  554 
  555 readcheck:
  556 
  557         /*
  558          * Is another packet coming in?  We don't want to overflow the tiny
  559          * RX FIFO.  If nothing has arrived then attempt to queue another
  560          * transmit packet.
  561          */
  562         if (CSR_READ_2(sc, FIFO_PORTS_REG_W) & FIFO_REMPTY)
  563                 goto startagain;
  564         return;
  565 }
  566 
  567 
  568 
  569 /* Resume a packet transmit operation after a memory allocation
  570  * has completed.
  571  *
  572  * This is basically a hacked up copy of snstart() which handles
  573  * a completed memory allocation the same way snstart() does.
  574  * It then passes control to snstart to handle any other queued
  575  * packets.
  576  */
  577 static void
  578 snresume(struct ifnet *ifp)
  579 {
  580         struct sn_softc *sc = ifp->if_softc;
  581         u_int           len;
  582         struct mbuf     *m;
  583         struct mbuf    *top;
  584         int             pad;
  585         int             mask;
  586         uint16_t        length;
  587         uint16_t        numPages;
  588         uint16_t        pages_wanted;
  589         uint8_t         packet_no;
  590 
  591         if (sc->pages_wanted < 0)
  592                 return;
  593 
  594         pages_wanted = sc->pages_wanted;
  595         sc->pages_wanted = -1;
  596 
  597         /*
  598          * Sneak a peek at the next packet
  599          */
  600         m = sc->arpcom.ac_if.if_snd.ifq_head;
  601         if (m == 0) {
  602                 if_printf(ifp, "snresume() with nothing to send\n");
  603                 return;
  604         }
  605         /*
  606          * Compute the frame length and set pad to give an overall even
  607          * number of bytes.  Below we assume that the packet length is even.
  608          */
  609         for (len = 0, top = m; m; m = m->m_next)
  610                 len += m->m_len;
  611 
  612         pad = (len & 1);
  613 
  614         /*
  615          * We drop packets that are too large. Perhaps we should truncate
  616          * them instead?
  617          */
  618         if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
  619                 if_printf(ifp, "large packet discarded (B)\n");
  620                 ++sc->arpcom.ac_if.if_oerrors;
  621                 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
  622                 m_freem(m);
  623                 return;
  624         }
  625 #ifdef SW_PAD
  626 
  627         /*
  628          * If HW padding is not turned on, then pad to ETHER_MIN_LEN.
  629          */
  630         if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
  631                 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
  632 
  633 #endif  /* SW_PAD */
  634 
  635         length = pad + len;
  636 
  637 
  638         /*
  639          * The MMU wants the number of pages to be the number of 256 byte
  640          * 'pages', minus 1 (A packet can't ever have 0 pages. We also
  641          * include space for the status word, byte count and control bytes in
  642          * the allocation request.
  643          */
  644         numPages = (length + 6) >> 8;
  645 
  646 
  647         SMC_SELECT_BANK(sc, 2);
  648 
  649         /*
  650          * The memory allocation completed.  Check the results. If it failed,
  651          * we simply set a watchdog timer and hope for the best.
  652          */
  653         packet_no = CSR_READ_1(sc, ALLOC_RESULT_REG_B);
  654         if (packet_no & ARR_FAILED) {
  655                 if_printf(ifp, "Memory allocation failed.  Weird.\n");
  656                 sc->arpcom.ac_if.if_timer = 1;
  657                 goto try_start;
  658         }
  659         /*
  660          * We have a packet number, so tell the card to use it.
  661          */
  662         CSR_WRITE_1(sc, PACKET_NUM_REG_B, packet_no);
  663 
  664         /*
  665          * Now, numPages should match the pages_wanted recorded when the
  666          * memory allocation was initiated.
  667          */
  668         if (pages_wanted != numPages) {
  669                 if_printf(ifp, "memory allocation wrong size.  Weird.\n");
  670                 /*
  671                  * If the allocation was the wrong size we simply release the
  672                  * memory once it is granted. Wait for the MMU to be un-busy.
  673                  */
  674                 while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY)      /* NOTHING */
  675                         ;
  676                 CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_FREEPKT);
  677 
  678                 return;
  679         }
  680         /*
  681          * Point to the beginning of the packet
  682          */
  683         CSR_WRITE_2(sc, POINTER_REG_W, PTR_AUTOINC | 0x0000);
  684 
  685         /*
  686          * Send the packet length (+6 for status, length and control byte)
  687          * and the status word (set to zeros)
  688          */
  689         CSR_WRITE_2(sc, DATA_REG_W, 0);
  690         CSR_WRITE_1(sc, DATA_REG_B, (length + 6) & 0xFF);
  691         CSR_WRITE_1(sc, DATA_REG_B, (length + 6) >> 8);
  692 
  693         /*
  694          * Get the packet from the kernel.  This will include the Ethernet
  695          * frame header, MAC Addresses etc.
  696          */
  697         IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
  698 
  699         /*
  700          * Push out the data to the card.
  701          */
  702         for (top = m; m != 0; m = m->m_next) {
  703 
  704                 /*
  705                  * Push out words.
  706                  */
  707                 CSR_WRITE_MULTI_2(sc, DATA_REG_W, mtod(m, uint16_t *),
  708                     m->m_len / 2);
  709                 /*
  710                  * Push out remaining byte.
  711                  */
  712                 if (m->m_len & 1)
  713                         CSR_WRITE_1(sc, DATA_REG_B,
  714                             *(mtod(m, caddr_t) + m->m_len - 1));
  715         }
  716 
  717         /*
  718          * Push out padding.
  719          */
  720         while (pad > 1) {
  721                 CSR_WRITE_2(sc, DATA_REG_W, 0);
  722                 pad -= 2;
  723         }
  724         if (pad)
  725                 CSR_WRITE_1(sc, DATA_REG_B, 0);
  726 
  727         /*
  728          * Push out control byte and unused packet byte The control byte is 0
  729          * meaning the packet is even lengthed and no special CRC handling is
  730          * desired.
  731          */
  732         CSR_WRITE_2(sc, DATA_REG_W, 0);
  733 
  734         /*
  735          * Enable the interrupts and let the chipset deal with it Also set a
  736          * watchdog in case we miss the interrupt.
  737          */
  738         mask = CSR_READ_1(sc, INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
  739         CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
  740         sc->intr_mask = mask;
  741         CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ENQUEUE);
  742 
  743         BPF_MTAP(ifp, top);
  744 
  745         sc->arpcom.ac_if.if_opackets++;
  746         m_freem(top);
  747 
  748 try_start:
  749 
  750         /*
  751          * Now pass control to snstart() to queue any additional packets
  752          */
  753         sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
  754         snstart(ifp);
  755 
  756         /*
  757          * We've sent something, so we're active.  Set a watchdog in case the
  758          * TX_EMPTY interrupt is lost.
  759          */
  760         sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
  761         sc->arpcom.ac_if.if_timer = 1;
  762 
  763         return;
  764 }
  765 
  766 
  767 void
  768 sn_intr(void *arg)
  769 {
  770         int             status, interrupts;
  771         struct sn_softc *sc = (struct sn_softc *) arg;
  772         struct ifnet   *ifp = &sc->arpcom.ac_if;
  773 
  774         /*
  775          * Chip state registers
  776          */
  777         uint8_t          mask;
  778         uint8_t         packet_no;
  779         uint16_t        tx_status;
  780         uint16_t        card_stats;
  781 
  782         SN_LOCK(sc);
  783 
  784         /*
  785          * Clear the watchdog.
  786          */
  787         ifp->if_timer = 0;
  788 
  789         SMC_SELECT_BANK(sc, 2);
  790 
  791         /*
  792          * Obtain the current interrupt mask and clear the hardware mask
  793          * while servicing interrupts.
  794          */
  795         mask = CSR_READ_1(sc, INTR_MASK_REG_B);
  796         CSR_WRITE_1(sc, INTR_MASK_REG_B, 0x00);
  797 
  798         /*
  799          * Get the set of interrupts which occurred and eliminate any which
  800          * are masked.
  801          */
  802         interrupts = CSR_READ_1(sc, INTR_STAT_REG_B);
  803         status = interrupts & mask;
  804 
  805         /*
  806          * Now, process each of the interrupt types.
  807          */
  808 
  809         /*
  810          * Receive Overrun.
  811          */
  812         if (status & IM_RX_OVRN_INT) {
  813                 /*
  814                  * Acknowlege Interrupt
  815                  */
  816                 SMC_SELECT_BANK(sc, 2);
  817                 CSR_WRITE_1(sc, INTR_ACK_REG_B, IM_RX_OVRN_INT);
  818 
  819                 ++sc->arpcom.ac_if.if_ierrors;
  820         }
  821         /*
  822          * Got a packet.
  823          */
  824         if (status & IM_RCV_INT) {
  825                 int             packet_number;
  826 
  827                 SMC_SELECT_BANK(sc, 2);
  828                 packet_number = CSR_READ_2(sc, FIFO_PORTS_REG_W);
  829 
  830                 if (packet_number & FIFO_REMPTY) {
  831                         /*
  832                          * we got called , but nothing was on the FIFO
  833                          */
  834                         printf("sn: Receive interrupt with nothing on FIFO\n");
  835                         goto out;
  836                 }
  837                 snread(ifp);
  838         }
  839         /*
  840          * An on-card memory allocation came through.
  841          */
  842         if (status & IM_ALLOC_INT) {
  843                 /*
  844                  * Disable this interrupt.
  845                  */
  846                 mask &= ~IM_ALLOC_INT;
  847                 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
  848                 snresume(&sc->arpcom.ac_if);
  849         }
  850         /*
  851          * TX Completion.  Handle a transmit error message. This will only be
  852          * called when there is an error, because of the AUTO_RELEASE mode.
  853          */
  854         if (status & IM_TX_INT) {
  855                 /*
  856                  * Acknowlege Interrupt
  857                  */
  858                 SMC_SELECT_BANK(sc, 2);
  859                 CSR_WRITE_1(sc, INTR_ACK_REG_B, IM_TX_INT);
  860 
  861                 packet_no = CSR_READ_2(sc, FIFO_PORTS_REG_W);
  862                 packet_no &= FIFO_TX_MASK;
  863 
  864                 /*
  865                  * select this as the packet to read from
  866                  */
  867                 CSR_WRITE_1(sc, PACKET_NUM_REG_B, packet_no);
  868 
  869                 /*
  870                  * Position the pointer to the first word from this packet
  871                  */
  872                 CSR_WRITE_2(sc, POINTER_REG_W, PTR_AUTOINC | PTR_READ | 0x0000);
  873 
  874                 /*
  875                  * Fetch the TX status word.  The value found here will be a
  876                  * copy of the EPH_STATUS_REG_W at the time the transmit
  877                  * failed.
  878                  */
  879                 tx_status = CSR_READ_2(sc, DATA_REG_W);
  880 
  881                 if (tx_status & EPHSR_TX_SUC) {
  882                         device_printf(sc->dev, 
  883                             "Successful packet caused interrupt\n");
  884                 } else {
  885                         ++sc->arpcom.ac_if.if_oerrors;
  886                 }
  887 
  888                 if (tx_status & EPHSR_LATCOL)
  889                         ++sc->arpcom.ac_if.if_collisions;
  890 
  891                 /*
  892                  * Some of these errors will have disabled transmit.
  893                  * Re-enable transmit now.
  894                  */
  895                 SMC_SELECT_BANK(sc, 0);
  896 
  897 #ifdef SW_PAD
  898                 CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, TCR_ENABLE);
  899 #else
  900                 CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, TCR_ENABLE | TCR_PAD_ENABLE);
  901 #endif  /* SW_PAD */
  902 
  903                 /*
  904                  * kill the failed packet. Wait for the MMU to be un-busy.
  905                  */
  906                 SMC_SELECT_BANK(sc, 2);
  907                 while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY)      /* NOTHING */
  908                         ;
  909                 CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_FREEPKT);
  910 
  911                 /*
  912                  * Attempt to queue more transmits.
  913                  */
  914                 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
  915                 snstart_locked(&sc->arpcom.ac_if);
  916         }
  917         /*
  918          * Transmit underrun.  We use this opportunity to update transmit
  919          * statistics from the card.
  920          */
  921         if (status & IM_TX_EMPTY_INT) {
  922 
  923                 /*
  924                  * Acknowlege Interrupt
  925                  */
  926                 SMC_SELECT_BANK(sc, 2);
  927                 CSR_WRITE_1(sc, INTR_ACK_REG_B, IM_TX_EMPTY_INT);
  928 
  929                 /*
  930                  * Disable this interrupt.
  931                  */
  932                 mask &= ~IM_TX_EMPTY_INT;
  933 
  934                 SMC_SELECT_BANK(sc, 0);
  935                 card_stats = CSR_READ_2(sc, COUNTER_REG_W);
  936 
  937                 /*
  938                  * Single collisions
  939                  */
  940                 sc->arpcom.ac_if.if_collisions += card_stats & ECR_COLN_MASK;
  941 
  942                 /*
  943                  * Multiple collisions
  944                  */
  945                 sc->arpcom.ac_if.if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4;
  946 
  947                 SMC_SELECT_BANK(sc, 2);
  948 
  949                 /*
  950                  * Attempt to enqueue some more stuff.
  951                  */
  952                 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
  953                 snstart_locked(&sc->arpcom.ac_if);
  954         }
  955         /*
  956          * Some other error.  Try to fix it by resetting the adapter.
  957          */
  958         if (status & IM_EPH_INT) {
  959                 snstop(sc);
  960                 sninit_locked(sc);
  961         }
  962 
  963 out:
  964         /*
  965          * Handled all interrupt sources.
  966          */
  967 
  968         SMC_SELECT_BANK(sc, 2);
  969 
  970         /*
  971          * Reestablish interrupts from mask which have not been deselected
  972          * during this interrupt.  Note that the hardware mask, which was set
  973          * to 0x00 at the start of this service routine, may have been
  974          * updated by one or more of the interrupt handers and we must let
  975          * those new interrupts stay enabled here.
  976          */
  977         mask |= CSR_READ_1(sc, INTR_MASK_REG_B);
  978         CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
  979         sc->intr_mask = mask;
  980         SN_UNLOCK(sc);
  981 }
  982 
  983 static void
  984 snread(struct ifnet *ifp)
  985 {
  986         struct sn_softc *sc = ifp->if_softc;
  987         struct ether_header *eh;
  988         struct mbuf    *m;
  989         short           status;
  990         int             packet_number;
  991         uint16_t        packet_length;
  992         uint8_t        *data;
  993 
  994         SMC_SELECT_BANK(sc, 2);
  995 #if 0
  996         packet_number = CSR_READ_2(sc, FIFO_PORTS_REG_W);
  997 
  998         if (packet_number & FIFO_REMPTY) {
  999 
 1000                 /*
 1001                  * we got called , but nothing was on the FIFO
 1002                  */
 1003                 printf("sn: Receive interrupt with nothing on FIFO\n");
 1004                 return;
 1005         }
 1006 #endif
 1007 read_another:
 1008 
 1009         /*
 1010          * Start reading from the start of the packet. Since PTR_RCV is set,
 1011          * packet number is found in FIFO_PORTS_REG_W, FIFO_RX_MASK.
 1012          */
 1013         CSR_WRITE_2(sc, POINTER_REG_W, PTR_READ | PTR_RCV | PTR_AUTOINC | 0x0000);
 1014 
 1015         /*
 1016          * First two words are status and packet_length
 1017          */
 1018         status = CSR_READ_2(sc, DATA_REG_W);
 1019         packet_length = CSR_READ_2(sc, DATA_REG_W) & RLEN_MASK;
 1020 
 1021         /*
 1022          * The packet length contains 3 extra words: status, length, and a
 1023          * extra word with the control byte.
 1024          */
 1025         packet_length -= 6;
 1026 
 1027         /*
 1028          * Account for receive errors and discard.
 1029          */
 1030         if (status & RS_ERRORS) {
 1031                 ++sc->arpcom.ac_if.if_ierrors;
 1032                 goto out;
 1033         }
 1034         /*
 1035          * A packet is received.
 1036          */
 1037 
 1038         /*
 1039          * Adjust for odd-length packet.
 1040          */
 1041         if (status & RS_ODDFRAME)
 1042                 packet_length++;
 1043 
 1044         /*
 1045          * Allocate a header mbuf from the kernel.
 1046          */
 1047         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1048         if (m == NULL)
 1049                 goto out;
 1050 
 1051         m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
 1052         m->m_pkthdr.len = m->m_len = packet_length;
 1053 
 1054         /*
 1055          * Attach an mbuf cluster
 1056          */
 1057         MCLGET(m, M_DONTWAIT);
 1058 
 1059         /*
 1060          * Insist on getting a cluster
 1061          */
 1062         if ((m->m_flags & M_EXT) == 0) {
 1063                 m_freem(m);
 1064                 ++sc->arpcom.ac_if.if_ierrors;
 1065                 printf("sn: snread() kernel memory allocation problem\n");
 1066                 goto out;
 1067         }
 1068         eh = mtod(m, struct ether_header *);
 1069 
 1070         /*
 1071          * Get packet, including link layer address, from interface.
 1072          */
 1073         data = (uint8_t *) eh;
 1074         CSR_READ_MULTI_2(sc, DATA_REG_W, (uint16_t *) data, packet_length >> 1);
 1075         if (packet_length & 1) {
 1076                 data += packet_length & ~1;
 1077                 *data = CSR_READ_1(sc, DATA_REG_B);
 1078         }
 1079         ++sc->arpcom.ac_if.if_ipackets;
 1080 
 1081         /*
 1082          * Remove link layer addresses and whatnot.
 1083          */
 1084         m->m_pkthdr.len = m->m_len = packet_length;
 1085 
 1086         /*
 1087          * Drop locks before calling if_input() since it may re-enter
 1088          * snstart() in the netisr case.  This would result in a
 1089          * lock reversal.  Better performance might be obtained by
 1090          * chaining all packets received, dropping the lock, and then
 1091          * calling if_input() on each one.
 1092          */
 1093         SN_UNLOCK(sc);
 1094         (*ifp->if_input)(ifp, m);
 1095         SN_LOCK(sc);
 1096 
 1097 out:
 1098 
 1099         /*
 1100          * Error or good, tell the card to get rid of this packet Wait for
 1101          * the MMU to be un-busy.
 1102          */
 1103         SMC_SELECT_BANK(sc, 2);
 1104         while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY)      /* NOTHING */
 1105                 ;
 1106         CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_RELEASE);
 1107 
 1108         /*
 1109          * Check whether another packet is ready
 1110          */
 1111         packet_number = CSR_READ_2(sc, FIFO_PORTS_REG_W);
 1112         if (packet_number & FIFO_REMPTY) {
 1113                 return;
 1114         }
 1115         goto read_another;
 1116 }
 1117 
 1118 
 1119 /*
 1120  * Handle IOCTLS.  This function is completely stolen from if_ep.c
 1121  * As with its progenitor, it does not handle hardware address
 1122  * changes.
 1123  */
 1124 static int
 1125 snioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1126 {
 1127         struct sn_softc *sc = ifp->if_softc;
 1128         int             error = 0;
 1129 
 1130         switch (cmd) {
 1131         case SIOCSIFFLAGS:
 1132                 SN_LOCK(sc);
 1133                 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
 1134                         ifp->if_flags &= ~IFF_RUNNING;
 1135                         snstop(sc);
 1136                 } else {
 1137                         /* reinitialize card on any parameter change */
 1138                         sninit_locked(sc);
 1139                 }
 1140                 SN_UNLOCK(sc);
 1141                 break;
 1142 
 1143 #ifdef notdef
 1144         case SIOCGHWADDR:
 1145                 bcopy((caddr_t) sc->sc_addr, (caddr_t) & ifr->ifr_data,
 1146                       sizeof(sc->sc_addr));
 1147                 break;
 1148 #endif
 1149 
 1150         case SIOCADDMULTI:
 1151                 /* update multicast filter list. */
 1152                 SN_LOCK(sc);
 1153                 sn_setmcast(sc);
 1154                 error = 0;
 1155                 SN_UNLOCK(sc);
 1156                 break;
 1157         case SIOCDELMULTI:
 1158                 /* update multicast filter list. */
 1159                 SN_LOCK(sc);
 1160                 sn_setmcast(sc);
 1161                 error = 0;
 1162                 SN_UNLOCK(sc);
 1163                 break;
 1164         default:
 1165                 error = EINVAL;
 1166                 error = ether_ioctl(ifp, cmd, data);
 1167                 break;
 1168         }
 1169         return (error);
 1170 }
 1171 
 1172 static void
 1173 snwatchdog(struct ifnet *ifp)
 1174 {
 1175         sn_intr(ifp->if_softc);
 1176 }
 1177 
 1178 
 1179 /* 1. zero the interrupt mask
 1180  * 2. clear the enable receive flag
 1181  * 3. clear the enable xmit flags
 1182  */
 1183 static void
 1184 snstop(struct sn_softc *sc)
 1185 {
 1186         
 1187         struct ifnet   *ifp = &sc->arpcom.ac_if;
 1188 
 1189         /*
 1190          * Clear interrupt mask; disable all interrupts.
 1191          */
 1192         SMC_SELECT_BANK(sc, 2);
 1193         CSR_WRITE_1(sc, INTR_MASK_REG_B, 0x00);
 1194 
 1195         /*
 1196          * Disable transmitter and Receiver
 1197          */
 1198         SMC_SELECT_BANK(sc, 0);
 1199         CSR_WRITE_2(sc, RECV_CONTROL_REG_W, 0x0000);
 1200         CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, 0x0000);
 1201 
 1202         /*
 1203          * Cancel watchdog.
 1204          */
 1205         ifp->if_timer = 0;
 1206 }
 1207 
 1208 
 1209 int
 1210 sn_activate(device_t dev)
 1211 {
 1212         struct sn_softc *sc = device_get_softc(dev);
 1213 
 1214         sc->port_rid = 0;
 1215         sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
 1216             0, ~0, SMC_IO_EXTENT, RF_ACTIVE);
 1217         if (!sc->port_res) {
 1218                 if (bootverbose)
 1219                         device_printf(dev, "Cannot allocate ioport\n");
 1220                 return ENOMEM;
 1221         }
 1222 
 1223         sc->irq_rid = 0;
 1224         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 
 1225             RF_ACTIVE);
 1226         if (!sc->irq_res) {
 1227                 if (bootverbose)
 1228                         device_printf(dev, "Cannot allocate irq\n");
 1229                 sn_deactivate(dev);
 1230                 return ENOMEM;
 1231         }
 1232         sc->bst = rman_get_bustag(sc->port_res);
 1233         sc->bsh = rman_get_bushandle(sc->port_res);
 1234         return (0);
 1235 }
 1236 
 1237 void
 1238 sn_deactivate(device_t dev)
 1239 {
 1240         struct sn_softc *sc = device_get_softc(dev);
 1241         
 1242         if (sc->intrhand)
 1243                 bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
 1244         sc->intrhand = 0;
 1245         if (sc->port_res)
 1246                 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, 
 1247                     sc->port_res);
 1248         sc->port_res = 0;
 1249         if (sc->irq_res)
 1250                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, 
 1251                     sc->irq_res);
 1252         sc->irq_res = 0;
 1253         return;
 1254 }
 1255 
 1256 /*
 1257  * Function: sn_probe( device_t dev, int pccard )
 1258  *
 1259  * Purpose:
 1260  *      Tests to see if a given ioaddr points to an SMC9xxx chip.
 1261  *      Tries to cause as little damage as possible if it's not a SMC chip.
 1262  *      Returns a 0 on success
 1263  *
 1264  * Algorithm:
 1265  *      (1) see if the high byte of BANK_SELECT is 0x33
 1266  *      (2) compare the ioaddr with the base register's address
 1267  *      (3) see if I recognize the chip ID in the appropriate register
 1268  *
 1269  *
 1270  */
 1271 int 
 1272 sn_probe(device_t dev, int pccard)
 1273 {
 1274         struct sn_softc *sc = device_get_softc(dev);
 1275         uint16_t        bank;
 1276         uint16_t        revision_register;
 1277         uint16_t        base_address_register;
 1278         int             err;
 1279 
 1280         if ((err = sn_activate(dev)) != 0)
 1281                 return err;
 1282 
 1283         /*
 1284          * First, see if the high byte is 0x33
 1285          */
 1286         bank = CSR_READ_2(sc, BANK_SELECT_REG_W);
 1287         if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
 1288 #ifdef  SN_DEBUG
 1289                 device_printf(dev, "test1 failed\n");
 1290 #endif
 1291                 goto error;
 1292         }
 1293         /*
 1294          * The above MIGHT indicate a device, but I need to write to further
 1295          * test this.  Go to bank 0, then test that the register still
 1296          * reports the high byte is 0x33.
 1297          */
 1298         CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x0000);
 1299         bank = CSR_READ_2(sc, BANK_SELECT_REG_W);
 1300         if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
 1301 #ifdef  SN_DEBUG
 1302                 device_printf(dev, "test2 failed\n");
 1303 #endif
 1304                 goto error;
 1305         }
 1306         /*
 1307          * well, we've already written once, so hopefully another time won't
 1308          * hurt.  This time, I need to switch the bank register to bank 1, so
 1309          * I can access the base address register.  The contents of the
 1310          * BASE_ADDR_REG_W register, after some jiggery pokery, is expected
 1311          * to match the I/O port address where the adapter is being probed.
 1312          */
 1313         CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x0001);
 1314         base_address_register = (CSR_READ_2(sc, BASE_ADDR_REG_W) >> 3) & 0x3e0;
 1315 
 1316         /*
 1317          * This test is nonsence on PC-card architecture, so if 
 1318          * pccard == 1, skip this test. (hosokawa)
 1319          */
 1320         if (!pccard && rman_get_start(sc->port_res) != base_address_register) {
 1321 
 1322                 /*
 1323                  * Well, the base address register didn't match.  Must not
 1324                  * have been a SMC chip after all.
 1325                  */
 1326 #ifdef  SN_DEBUG
 1327                 device_printf(dev, "test3 failed ioaddr = 0x%x, "
 1328                     "base_address_register = 0x%x\n",
 1329                     rman_get_start(sc->port_res), base_address_register);
 1330 #endif
 1331                 goto error;
 1332         }
 1333 
 1334         /*
 1335          * Check if the revision register is something that I recognize.
 1336          * These might need to be added to later, as future revisions could
 1337          * be added.
 1338          */
 1339         CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x3);
 1340         revision_register = CSR_READ_2(sc, REVISION_REG_W);
 1341         if (!chip_ids[(revision_register >> 4) & 0xF]) {
 1342 
 1343                 /*
 1344                  * I don't regonize this chip, so...
 1345                  */
 1346 #ifdef  SN_DEBUG
 1347                 device_printf(dev, "test4 failed\n");
 1348 #endif
 1349                 goto error;
 1350         }
 1351 
 1352         /*
 1353          * at this point I'll assume that the chip is an SMC9xxx. It might be
 1354          * prudent to check a listing of MAC addresses against the hardware
 1355          * address, or do some other tests.
 1356          */
 1357         sn_deactivate(dev);
 1358         return 0;
 1359  error:
 1360         sn_deactivate(dev);
 1361         return ENXIO;
 1362 }
 1363 
 1364 #define MCFSZ 8
 1365 
 1366 static void
 1367 sn_setmcast(struct sn_softc *sc)
 1368 {
 1369         struct ifnet *ifp = (struct ifnet *)sc;
 1370         int flags;
 1371         uint8_t mcf[MCFSZ];
 1372 
 1373         SN_ASSERT_LOCKED(sc);
 1374 
 1375         /*
 1376          * Set the receiver filter.  We want receive enabled and auto strip
 1377          * of CRC from received packet.  If we are promiscuous then set that
 1378          * bit too.
 1379          */
 1380         flags = RCR_ENABLE | RCR_STRIP_CRC;
 1381   
 1382         if (ifp->if_flags & IFF_PROMISC) {
 1383                 flags |= RCR_PROMISC | RCR_ALMUL;
 1384         } else if (ifp->if_flags & IFF_ALLMULTI) {
 1385                 flags |= RCR_ALMUL;
 1386         } else {
 1387                 if (sn_getmcf(&sc->arpcom, mcf)) {
 1388                         /* set filter */
 1389                         SMC_SELECT_BANK(sc, 3);
 1390                         CSR_WRITE_2(sc, MULTICAST1_REG_W,
 1391                             ((uint16_t)mcf[1] << 8) |  mcf[0]);
 1392                         CSR_WRITE_2(sc, MULTICAST2_REG_W,
 1393                             ((uint16_t)mcf[3] << 8) |  mcf[2]);
 1394                         CSR_WRITE_2(sc, MULTICAST3_REG_W,
 1395                             ((uint16_t)mcf[5] << 8) |  mcf[4]);
 1396                         CSR_WRITE_2(sc, MULTICAST4_REG_W,
 1397                             ((uint16_t)mcf[7] << 8) |  mcf[6]);
 1398                 } else {
 1399                         flags |= RCR_ALMUL;
 1400                 }
 1401         }
 1402         SMC_SELECT_BANK(sc, 0);
 1403         CSR_WRITE_2(sc, RECV_CONTROL_REG_W, flags);
 1404 }
 1405 
 1406 static int
 1407 sn_getmcf(struct arpcom *ac, uint8_t *mcf)
 1408 {
 1409         int i;
 1410         uint32_t index, index2;
 1411         uint8_t *af = mcf;
 1412         struct ifmultiaddr *ifma;
 1413 
 1414         bzero(mcf, MCFSZ);
 1415 
 1416         IF_ADDR_LOCK(ifp);
 1417         TAILQ_FOREACH(ifma, &ac->ac_if.if_multiaddrs, ifma_link) {
 1418             if (ifma->ifma_addr->sa_family != AF_LINK) {
 1419                 IF_ADDR_UNLOCK(ifp);
 1420                 return 0;
 1421             }
 1422             index = ether_crc32_le(LLADDR((struct sockaddr_dl *)
 1423                 ifma->ifma_addr), ETHER_ADDR_LEN) & 0x3f;
 1424             index2 = 0;
 1425             for (i = 0; i < 6; i++) {
 1426                 index2 <<= 1;
 1427                 index2 |= (index & 0x01);
 1428                 index >>= 1;
 1429             }
 1430             af[index2 >> 3] |= 1 << (index2 & 7);
 1431         }
 1432         IF_ADDR_UNLOCK(ifp);
 1433         return 1;  /* use multicast filter */
 1434 }

Cache object: d3adba0d25a2f2d65847b5928ea80752


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.