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

Cache object: 16276557885407c71dceba82cbcb01c2


[ 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.