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/ic/ne2000.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 /*      $OpenBSD: ne2000.c,v 1.28 2022/01/09 05:42:38 jsg Exp $ */
    2 /*      $NetBSD: ne2000.c,v 1.12 1998/06/10 01:15:50 thorpej Exp $      */
    3 
    4 /*-
    5  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
   10  * NASA Ames Research Center.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   31  * POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 /*
   35  * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
   36  * adapters.
   37  *
   38  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
   39  *
   40  * Copyright (C) 1993, David Greenman.  This software may be used, modified,
   41  * copied, distributed, and sold, in both source and binary form provided that
   42  * the above copyright and these terms are retained.  Under no circumstances is
   43  * the author responsible for the proper functioning of this software, nor does
   44  * the author assume any responsibility for damages incurred with its use.
   45  */
   46 
   47 /*
   48  * Common code shared by all NE2000-compatible Ethernet interfaces.
   49  */
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/device.h>
   54 #include <sys/socket.h>
   55 #include <sys/mbuf.h>
   56 #include <sys/syslog.h>
   57 
   58 #include <net/if.h>
   59 #include <net/if_media.h>
   60 
   61 #include <netinet/in.h>
   62 #include <netinet/if_ether.h>
   63 
   64 #include <machine/bus.h>
   65 
   66 #include <dev/ic/dp8390reg.h>
   67 #include <dev/ic/dp8390var.h>
   68 
   69 #include <dev/ic/ne2000reg.h>
   70 #include <dev/ic/ne2000var.h>
   71 
   72 #include <dev/ic/ax88190reg.h>
   73 
   74 int     ne2000_write_mbuf(struct dp8390_softc *, struct mbuf *, int);
   75 int     ne2000_ring_copy(struct dp8390_softc *, int, caddr_t, u_short);
   76 void    ne2000_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *);
   77 int     ne2000_test_mem(struct dp8390_softc *);
   78 
   79 void    ne2000_writemem(bus_space_tag_t, bus_space_handle_t,
   80             bus_space_tag_t, bus_space_handle_t, u_int8_t *, int, size_t, int);
   81 void    ne2000_readmem(bus_space_tag_t, bus_space_handle_t,
   82             bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int);
   83 
   84 #define ASIC_BARRIER(asict, asich) \
   85         bus_space_barrier((asict), (asich), 0, 0x10, \
   86             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
   87 
   88 struct cfdriver ne_cd = {
   89         NULL, "ne", DV_IFNET
   90 };
   91 
   92 int
   93 ne2000_attach(struct ne2000_softc *nsc, u_int8_t *myea)
   94 {
   95         struct dp8390_softc *dsc = &nsc->sc_dp8390;
   96         bus_space_tag_t nict = dsc->sc_regt;
   97         bus_space_handle_t nich = dsc->sc_regh;
   98         bus_space_tag_t asict = nsc->sc_asict;
   99         bus_space_handle_t asich = nsc->sc_asich;
  100         u_int8_t romdata[16];
  101         int memsize, i, useword;
  102 
  103         /*
  104          * Detect it again unless caller specified it; this gives us
  105          * the memory size.
  106          */
  107         if (nsc->sc_type == NE2000_TYPE_UNKNOWN)
  108                 nsc->sc_type = ne2000_detect(nsc);
  109 
  110         /*
  111          * 8k of memory for NE1000, 16k otherwise.
  112          */
  113         switch (nsc->sc_type) {
  114         case NE2000_TYPE_UNKNOWN:
  115         default:
  116                 printf(": where did the card go?\n");
  117                 return (1);
  118         case NE2000_TYPE_NE1000:
  119                 memsize = 8192;
  120                 useword = 0;
  121                 break;
  122         case NE2000_TYPE_NE2000:
  123         case NE2000_TYPE_AX88190:               /* XXX really? */
  124         case NE2000_TYPE_AX88790:
  125         case NE2000_TYPE_DL10019:
  126         case NE2000_TYPE_DL10022:
  127                 memsize = 8192 * 2;
  128                 useword = 1;
  129                 break;
  130         }
  131 
  132         nsc->sc_useword = useword;
  133 
  134         dsc->cr_proto = ED_CR_RD2;
  135         if (nsc->sc_type == NE2000_TYPE_AX88190 ||
  136             nsc->sc_type == NE2000_TYPE_AX88790) {
  137                 dsc->rcr_proto = ED_RCR_INTT;
  138                 dsc->sc_flags |= DP8390_DO_AX88190_WORKAROUND;
  139         } else
  140                 dsc->rcr_proto = 0;
  141 
  142         /*
  143          * DCR gets:
  144          *
  145          *      FIFO threshold to 8, No auto-init Remote DMA,
  146          *      byte order=80x86.
  147          *
  148          * NE1000 gets byte-wide DMA, NE2000 gets word-wide DMA.
  149          */
  150         dsc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0);
  151 
  152         dsc->test_mem = ne2000_test_mem;
  153         dsc->ring_copy = ne2000_ring_copy;
  154         dsc->write_mbuf = ne2000_write_mbuf;
  155         dsc->read_hdr = ne2000_read_hdr;
  156 
  157         /* Registers are linear. */
  158         for (i = 0; i < 16; i++)
  159                 dsc->sc_reg_map[i] = i;
  160 
  161         /*
  162          * NIC memory doesn't start at zero on an NE board.
  163          * The start address is tied to the bus width.
  164          * (It happens to be computed the same way as mem size.)
  165          */
  166         dsc->mem_start = memsize;
  167 
  168 #ifdef GWETHER
  169         {
  170                 int x, mstart = 0;
  171                 int8_t pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE],
  172                     tbuf[ED_PAGE_SIZE];
  173 
  174                 for (i = 0; i < ED_PAGE_SIZE; i++)
  175                         pbuf0[i] = 0;
  176 
  177                 /* Search for the start of RAM. */
  178                 for (x = 1; x < 256; x++) {
  179                         ne2000_writemem(nict, nich, asict, asich, pbuf0,
  180                             x << ED_PAGE_SHIFT, ED_PAGE_SIZE, useword);
  181                         ne2000_readmem(nict, nich, asict, asich,
  182                             x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE, useword);
  183                         if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
  184                                 for (i = 0; i < ED_PAGE_SIZE; i++)
  185                                         pbuf[i] = 255 - x;
  186                                 ne2000_writemem(nict, nich, asict, asich,
  187                                     pbuf, x << ED_PAGE_SHIFT, ED_PAGE_SIZE,
  188                                     useword);
  189                                 ne2000_readmem(nict, nich, asict, asich,
  190                                     x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE,
  191                                     useword);
  192                                 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
  193                                         mstart = x << ED_PAGE_SHIFT;
  194                                         memsize = ED_PAGE_SIZE;
  195                                         break;
  196                                 }
  197                         }
  198                 }
  199 
  200                 if (mstart == 0) {
  201                         printf(": cannot find start of RAM\n");
  202                         return;
  203                 }
  204 
  205                 /* Search for the end of RAM. */
  206                 for (++x; x < 256; x++) {
  207                         ne2000_writemem(nict, nich, asict, asich, pbuf0,
  208                             x << ED_PAGE_SHIFT, ED_PAGE_SIZE, useword);
  209                         ne2000_readmem(nict, nich, asict, asich,
  210                             x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE, useword);
  211                         if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
  212                                 for (i = 0; i < ED_PAGE_SIZE; i++)
  213                                         pbuf[i] = 255 - x;
  214                                 ne2000_writemem(nict, nich, asict, asich,
  215                                     pbuf, x << ED_PAGE_SHIFT, ED_PAGE_SIZE,
  216                                     useword);
  217                                 ne2000_readmem(nict, nich, asict, asich,
  218                                     x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE,
  219                                     useword);
  220                                 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
  221                                         memsize += ED_PAGE_SIZE;
  222                                 else
  223                                         break;
  224                         } else
  225                                 break;
  226                 }
  227 
  228                 printf(": RAM start 0x%x, size %d\n",
  229                     mstart, memsize);
  230 
  231                 dsc->mem_start = mstart;
  232         }
  233 #endif /* GWETHER */
  234 
  235         dsc->mem_size = memsize;
  236 
  237         if (myea == NULL) {
  238                 /* Read the station address. */
  239                 if (nsc->sc_type == NE2000_TYPE_AX88190 ||
  240                     nsc->sc_type == NE2000_TYPE_AX88790) {
  241                         /* Select page 0 registers. */
  242                         NIC_BARRIER(nict, nich);
  243                         bus_space_write_1(nict, nich, ED_P0_CR,
  244                             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
  245                         NIC_BARRIER(nict, nich);
  246                         /* Select word transfer. */
  247                         bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS);
  248                         NIC_BARRIER(nict, nich);
  249                         ne2000_readmem(nict, nich, asict, asich,
  250                             AX88190_NODEID_OFFSET, dsc->sc_arpcom.ac_enaddr,
  251                             ETHER_ADDR_LEN, useword);
  252                 } else {
  253                         ne2000_readmem(nict, nich, asict, asich, 0, romdata,
  254                             sizeof(romdata), useword);
  255                         for (i = 0; i < ETHER_ADDR_LEN; i++)
  256                                 dsc->sc_arpcom.ac_enaddr[i] =
  257                                     romdata[i * (useword ? 2 : 1)];
  258                 }
  259         } else
  260                 bcopy(myea, dsc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
  261 
  262         /* Clear any pending interrupts that might have occurred above. */
  263         NIC_BARRIER(nict, nich);
  264         bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
  265         NIC_BARRIER(nict, nich);
  266 
  267         if (dsc->sc_media_init == NULL)
  268                 dsc->sc_media_init = dp8390_media_init;
  269 
  270         if (dp8390_config(dsc)) {
  271                 printf(": setup failed\n");
  272                 return (1);
  273         }
  274 
  275         return (0);
  276 }
  277 
  278 /*
  279  * Detect an NE-2000 or compatible.  Returns a model code.
  280  */
  281 int
  282 ne2000_detect(struct ne2000_softc *nsc)
  283 {
  284         struct dp8390_softc *dsc = &nsc->sc_dp8390;
  285         bus_space_tag_t nict = dsc->sc_regt;
  286         bus_space_handle_t nich = dsc->sc_regh;
  287         bus_space_tag_t asict = nsc->sc_asict;
  288         bus_space_handle_t asich = nsc->sc_asich;
  289         static u_int8_t test_pattern[32] = "THIS is A memory TEST pattern";
  290         u_int8_t test_buffer[32], tmp;
  291         int state, i, rv = 0;
  292 
  293         state = dsc->sc_enabled;
  294         dsc->sc_enabled = 0;
  295 
  296         /* Reset the board. */
  297 #ifdef GWETHER
  298         bus_space_write_1(asict, asich, NE2000_ASIC_RESET, 0);
  299         ASIC_BARRIER(asict, asich);
  300         delay(200);
  301 #endif /* GWETHER */
  302         tmp = bus_space_read_1(asict, asich, NE2000_ASIC_RESET);
  303         ASIC_BARRIER(asict, asich);
  304         delay(10000);
  305 
  306         /*
  307          * I don't know if this is necessary; probably cruft leftover from
  308          * Clarkson packet driver code. Doesn't do a thing on the boards I've
  309          * tested. -DG [note that a outb(0x84, 0) seems to work here, and is
  310          * non-invasive...but some boards don't seem to reset and I don't have
  311          * complete documentation on what the 'right' thing to do is...so we do
  312          * the invasive thing for now.  Yuck.]
  313          */
  314         bus_space_write_1(asict, asich, NE2000_ASIC_RESET, tmp);
  315         ASIC_BARRIER(asict, asich);
  316         delay(5000);
  317 
  318         /*
  319          * This is needed because some NE clones apparently don't reset the
  320          * NIC properly (or the NIC chip doesn't reset fully on power-up).
  321          * XXX - this makes the probe invasive!  Done against my better
  322          * judgement.  -DLG
  323          */
  324         bus_space_write_1(nict, nich, ED_P0_CR,
  325             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
  326         NIC_BARRIER(nict, nich);
  327 
  328         delay(5000);
  329 
  330         /*
  331          * Generic probe routine for testing for the existence of a DS8390.
  332          * Must be performed  after the NIC has just been reset.  This
  333          * works by looking at certain register values that are guaranteed
  334          * to be initialized a certain way after power-up or reset.
  335          *
  336          * Specifically:
  337          *
  338          *      Register                reset bits      set bits
  339          *      --------                ----------      --------
  340          *      CR                      TXP, STA        RD2, STP
  341          *      ISR                                     RST
  342          *      IMR                     <all>
  343          *      DCR                                     LAS
  344          *      TCR                     LB1, LB0
  345          *
  346          * We only look at CR and ISR, however, since looking at the others
  347          * would require changing register pages, which would be intrusive
  348          * if this isn't an 8390.
  349          */
  350 
  351         tmp = bus_space_read_1(nict, nich, ED_P0_CR);
  352         if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
  353             (ED_CR_RD2 | ED_CR_STP))
  354                 goto out;
  355 
  356         tmp = bus_space_read_1(nict, nich, ED_P0_ISR);
  357         if ((tmp & ED_ISR_RST) != ED_ISR_RST)
  358                 goto out;
  359 
  360         bus_space_write_1(nict, nich,
  361             ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
  362         NIC_BARRIER(nict, nich);
  363 
  364         for (i = 0; i < 100; i++) {
  365                 if ((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RST) ==
  366                     ED_ISR_RST) {
  367                         /* Ack the reset bit. */
  368                         bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RST);
  369                         NIC_BARRIER(nict, nich);
  370                         break;
  371                 }
  372                 delay(100);
  373         }
  374 
  375 #if 0
  376         /* XXX */
  377         if (i == 100)
  378                 goto out;
  379 #endif
  380 
  381         /*
  382          * Test the ability to read and write to the NIC memory.  This has
  383          * the side effect of determining if this is an NE1000 or an NE2000.
  384          */
  385 
  386         /*
  387          * This prevents packets from being stored in the NIC memory when
  388          * the readmem routine turns on the start bit in the CR.
  389          */
  390         bus_space_write_1(nict, nich, ED_P0_RCR, ED_RCR_MON);
  391         NIC_BARRIER(nict, nich);
  392 
  393         /* Temporarily initialize DCR for byte operations. */
  394         bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
  395 
  396         bus_space_write_1(nict, nich, ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
  397         bus_space_write_1(nict, nich, ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT);
  398 
  399         /*
  400          * Write a test pattern in byte mode.  If this fails, then there
  401          * probably isn't any memory at 8k - which likely means that the
  402          * board is an NE2000.
  403          */
  404         ne2000_writemem(nict, nich, asict, asich, test_pattern, 8192,
  405             sizeof(test_pattern), 0);
  406         ne2000_readmem(nict, nich, asict, asich, 8192, test_buffer,
  407             sizeof(test_buffer), 0);
  408 
  409         if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
  410                 /* not an NE1000 - try NE2000 */
  411                 bus_space_write_1(nict, nich, ED_P0_DCR,
  412                     ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
  413                 bus_space_write_1(nict, nich, ED_P0_PSTART,
  414                     16384 >> ED_PAGE_SHIFT);
  415                 bus_space_write_1(nict, nich, ED_P0_PSTOP,
  416                     32768 >> ED_PAGE_SHIFT);
  417 
  418                 /*
  419                  * Write the test pattern in word mode.  If this also fails,
  420                  * then we don't know what this board is.
  421                  */
  422                 ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384,
  423                     sizeof(test_pattern), 1);
  424                 ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer,
  425                     sizeof(test_buffer), 1);
  426 
  427                 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
  428                         goto out;       /* not an NE2000 either */
  429 
  430                 rv = NE2000_TYPE_NE2000;
  431         } else {
  432                 /* We're an NE1000. */
  433                 rv = NE2000_TYPE_NE1000;
  434         }
  435 
  436         /* Clear any pending interrupts that might have occurred above. */
  437         NIC_BARRIER(nict, nich);
  438         bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
  439 
  440  out:
  441         dsc->sc_enabled = state;
  442 
  443         return (rv);
  444 }
  445 
  446 /*
  447  * Write an mbuf chain to the destination NIC memory address using programmed
  448  * I/O.
  449  */
  450 int
  451 ne2000_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
  452 {
  453         struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
  454         bus_space_tag_t nict = sc->sc_regt;
  455         bus_space_handle_t nich = sc->sc_regh;
  456         bus_space_tag_t asict = nsc->sc_asict;
  457         bus_space_handle_t asich = nsc->sc_asich;
  458         int savelen;
  459         int maxwait = 100;      /* about 120us */
  460 
  461         savelen = m->m_pkthdr.len;
  462 
  463         /* Select page 0 registers. */
  464         NIC_BARRIER(nict, nich);
  465         bus_space_write_1(nict, nich, ED_P0_CR,
  466             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
  467         NIC_BARRIER(nict, nich);
  468 
  469         /* Reset remote DMA complete flag. */
  470         bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC);
  471         NIC_BARRIER(nict, nich);
  472 
  473         /* Set up DMA byte count. */
  474         bus_space_write_1(nict, nich, ED_P0_RBCR0, savelen);
  475         bus_space_write_1(nict, nich, ED_P0_RBCR1, savelen >> 8);
  476 
  477         /* Set up destination address in NIC mem. */
  478         bus_space_write_1(nict, nich, ED_P0_RSAR0, buf);
  479         bus_space_write_1(nict, nich, ED_P0_RSAR1, buf >> 8);
  480 
  481         /* Set remote DMA write. */
  482         NIC_BARRIER(nict, nich);
  483         bus_space_write_1(nict, nich,
  484             ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
  485         NIC_BARRIER(nict, nich);
  486 
  487         /*
  488          * Transfer the mbuf chain to the NIC memory.  NE2000 cards
  489          * require that data be transferred as words, and only words,
  490          * so that case requires some extra code to patch over odd-length
  491          * mbufs.
  492          */
  493         if (nsc->sc_type == NE2000_TYPE_NE1000) {
  494                 /* NE1000s are easy. */
  495                 for (; m != 0; m = m->m_next) {
  496                         if (m->m_len) {
  497                                 bus_space_write_multi_1(asict, asich,
  498                                     NE2000_ASIC_DATA, mtod(m, u_int8_t *),
  499                                     m->m_len);
  500                         }
  501                 }
  502         } else {
  503                 /* NE2000s are a bit trickier. */
  504                 u_int8_t *data, savebyte[2];
  505                 int l, leftover;
  506 #ifdef DIAGNOSTIC
  507                 u_int8_t *lim;
  508 #endif
  509                 /* Start out with no leftover data. */
  510                 leftover = 0;
  511                 savebyte[0] = savebyte[1] = 0;
  512 
  513                 for (; m != 0; m = m->m_next) {
  514                         l = m->m_len;
  515                         if (l == 0)
  516                                 continue;
  517                         data = mtod(m, u_int8_t *);
  518 #ifdef DIAGNOSTIC
  519                         lim = data + l;
  520 #endif
  521                         while (l > 0) {
  522                                 if (leftover) {
  523                                         /*
  524                                          * Data left over (from mbuf or
  525                                          * realignment).  Buffer the next
  526                                          * byte, and write it and the
  527                                          * leftover data out.
  528                                          */
  529                                         savebyte[1] = *data++;
  530                                         l--;
  531                                         bus_space_write_raw_multi_2(asict,
  532                                             asich, NE2000_ASIC_DATA,
  533                                             savebyte, 2);
  534                                         leftover = 0;
  535                                 } else if (ALIGNED_POINTER(data,
  536                                            u_int16_t) == 0) {
  537                                         /*
  538                                          * Unaligned data; buffer the next
  539                                          * byte.
  540                                          */
  541                                         savebyte[0] = *data++;
  542                                         l--;
  543                                         leftover = 1;
  544                                 } else {
  545                                         /*
  546                                          * Aligned data; output contiguous
  547                                          * words as much as we can, then
  548                                          * buffer the remaining byte, if any.
  549                                          */
  550                                         leftover = l & 1;
  551                                         l &= ~1;
  552                                         bus_space_write_raw_multi_2(asict,
  553                                             asich, NE2000_ASIC_DATA, data, l);
  554                                         data += l;
  555                                         if (leftover)
  556                                                 savebyte[0] = *data++;
  557                                         l = 0;
  558                                 }
  559                         }
  560                         if (l < 0)
  561                                 panic("ne2000_write_mbuf: negative len");
  562 #ifdef DIAGNOSTIC
  563                         if (data != lim)
  564                                 panic("ne2000_write_mbuf: data != lim");
  565 #endif
  566                 }
  567                 if (leftover) {
  568                         savebyte[1] = 0;
  569                         bus_space_write_raw_multi_2(asict, asich,
  570                             NE2000_ASIC_DATA, savebyte, 2);
  571                 }
  572         }
  573         NIC_BARRIER(nict, nich);
  574 
  575         /* AX88796 doesn't seem to have remote DMA complete */
  576         if (sc->sc_flags & DP8390_NO_REMOTE_DMA_COMPLETE)
  577                 return (savelen);
  578 
  579         /*
  580          * Wait for remote DMA to complete.  This is necessary because on the
  581          * transmit side, data is handled internally by the NIC in bursts, and
  582          * we can't start another remote DMA until this one completes.  Not
  583          * waiting causes really bad things to happen - like the NIC wedging
  584          * the bus.
  585          */
  586         while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) !=
  587             ED_ISR_RDC) && --maxwait) {
  588                 bus_space_read_1(nict, nich, ED_P0_CRDA1);
  589                 bus_space_read_1(nict, nich, ED_P0_CRDA0);
  590                 NIC_BARRIER(nict, nich);
  591                 DELAY(1);
  592         }
  593 
  594         if (maxwait == 0) {
  595                 log(LOG_WARNING,
  596                     "%s: remote transmit DMA failed to complete\n",
  597                     sc->sc_dev.dv_xname);
  598                 dp8390_reset(sc);
  599         }
  600 
  601         return (savelen);
  602 }
  603 
  604 /*
  605  * Given a source and destination address, copy 'amount' of a packet from
  606  * the ring buffer into a linear destination buffer.  Takes into account
  607  * ring-wrap.
  608  */
  609 int
  610 ne2000_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst,
  611     u_short amount)
  612 {
  613         struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
  614         bus_space_tag_t nict = sc->sc_regt;
  615         bus_space_handle_t nich = sc->sc_regh;
  616         bus_space_tag_t asict = nsc->sc_asict;
  617         bus_space_handle_t asich = nsc->sc_asich;
  618         u_short tmp_amount;
  619         int useword = nsc->sc_useword;
  620 
  621         /* Does copy wrap to lower addr in ring buffer? */
  622         if (src + amount > sc->mem_end) {
  623                 tmp_amount = sc->mem_end - src;
  624 
  625                 /* Copy amount up to end of NIC memory. */
  626                 ne2000_readmem(nict, nich, asict, asich, src,
  627                     (u_int8_t *)dst, tmp_amount, useword);
  628 
  629                 amount -= tmp_amount;
  630                 src = sc->mem_ring;
  631                 dst += tmp_amount;
  632         }
  633 
  634         ne2000_readmem(nict, nich, asict, asich, src, (u_int8_t *)dst,
  635             amount, useword);
  636 
  637         return (src + amount);
  638 }
  639 
  640 void
  641 ne2000_read_hdr(struct dp8390_softc *sc, int buf, struct dp8390_ring *hdr)
  642 {
  643         struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
  644 
  645         ne2000_readmem(sc->sc_regt, sc->sc_regh, nsc->sc_asict, nsc->sc_asich,
  646             buf, (u_int8_t *)hdr, sizeof(struct dp8390_ring),
  647             nsc->sc_useword);
  648 #if BYTE_ORDER == BIG_ENDIAN
  649         hdr->count = swap16(hdr->count);
  650 #endif
  651 }
  652 
  653 int
  654 ne2000_test_mem(struct dp8390_softc *sc)
  655 {
  656         /* Noop. */
  657         return (0);
  658 }
  659 
  660 /*
  661  * Given a NIC memory source address and a host memory destination address,
  662  * copy 'amount' from NIC to host using programmed i/o.  The 'amount' is
  663  * rounded up to a word - ok as long as mbufs are word sized.
  664  */
  665 void
  666 ne2000_readmem(bus_space_tag_t nict, bus_space_handle_t nich,
  667     bus_space_tag_t asict, bus_space_handle_t asich, int src,
  668     u_int8_t *dst, size_t amount, int useword)
  669 {
  670 
  671         /* Select page 0 registers. */
  672         NIC_BARRIER(nict, nich);
  673         bus_space_write_1(nict, nich, ED_P0_CR,
  674             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
  675         NIC_BARRIER(nict, nich);
  676 
  677         /* Round up to a word. */
  678         if (amount & 1)
  679                 ++amount;
  680 
  681         /* Set up DMA byte count. */
  682         bus_space_write_1(nict, nich, ED_P0_RBCR0, amount);
  683         bus_space_write_1(nict, nich, ED_P0_RBCR1, amount >> 8);
  684 
  685         /* Set up source address in NIC mem. */
  686         bus_space_write_1(nict, nich, ED_P0_RSAR0, src);
  687         bus_space_write_1(nict, nich, ED_P0_RSAR1, src >> 8);
  688 
  689         NIC_BARRIER(nict, nich);
  690         bus_space_write_1(nict, nich, ED_P0_CR,
  691             ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
  692 
  693         ASIC_BARRIER(asict, asich);
  694         if (useword)
  695                 bus_space_read_raw_multi_2(asict, asich, NE2000_ASIC_DATA,
  696                     dst, amount);
  697         else
  698                 bus_space_read_multi_1(asict, asich, NE2000_ASIC_DATA,
  699                     dst, amount);
  700 }
  701 
  702 /*
  703  * Stripped down routine for writing a linear buffer to NIC memory.  Only
  704  * used in the probe routine to test the memory.  'len' must be even.
  705  */
  706 void
  707 ne2000_writemem(bus_space_tag_t nict, bus_space_handle_t nich,
  708     bus_space_tag_t asict, bus_space_handle_t asich, u_int8_t *src,
  709     int dst, size_t len, int useword)
  710 {
  711         int maxwait = 100;      /* about 120us */
  712 
  713         /* Select page 0 registers. */
  714         NIC_BARRIER(nict, nich);
  715         bus_space_write_1(nict, nich, ED_P0_CR,
  716             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
  717         NIC_BARRIER(nict, nich);
  718 
  719         /* Reset remote DMA complete flag. */
  720         bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC);
  721         NIC_BARRIER(nict, nich);
  722 
  723         /* Set up DMA byte count. */
  724         bus_space_write_1(nict, nich, ED_P0_RBCR0, len);
  725         bus_space_write_1(nict, nich, ED_P0_RBCR1, len >> 8);
  726 
  727         /* Set up destination address in NIC mem. */
  728         bus_space_write_1(nict, nich, ED_P0_RSAR0, dst);
  729         bus_space_write_1(nict, nich, ED_P0_RSAR1, dst >> 8);
  730 
  731         /* Set remote DMA write. */
  732         NIC_BARRIER(nict, nich);
  733         bus_space_write_1(nict, nich, ED_P0_CR,
  734             ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
  735         NIC_BARRIER(nict, nich);
  736 
  737         ASIC_BARRIER(asict, asich);
  738         if (useword)
  739                 bus_space_write_raw_multi_2(asict, asich, NE2000_ASIC_DATA,
  740                     src, len);
  741         else
  742                 bus_space_write_multi_1(asict, asich, NE2000_ASIC_DATA,
  743                     src, len);
  744         ASIC_BARRIER(asict, asich);
  745 
  746         /*
  747          * Wait for remote DMA to complete.  This is necessary because on the
  748          * transmit side, data is handled internally by the NIC in bursts, and
  749          * we can't start another remote DMA until this one completes.  Not
  750          * waiting causes really bad things to happen - like the NIC wedging
  751          * the bus.
  752          */
  753         while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) !=
  754             ED_ISR_RDC) && --maxwait)
  755                 DELAY(1);
  756 }
  757 
  758 int
  759 ne2000_detach(struct ne2000_softc *sc, int flags)
  760 {
  761         return (dp8390_detach(&sc->sc_dp8390, flags));
  762 }

Cache object: cc41d4ff49410636fe68cec211fe6ffc


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