LCOV - code coverage report
Current view: top level - dev/ic - ne2000.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 242 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ne2000.c,v 1.27 2015/11/24 17:11:39 mpi 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           0 : ne2000_attach(struct ne2000_softc *nsc, u_int8_t *myea)
      94             : {
      95           0 :         struct dp8390_softc *dsc = &nsc->sc_dp8390;
      96           0 :         bus_space_tag_t nict = dsc->sc_regt;
      97           0 :         bus_space_handle_t nich = dsc->sc_regh;
      98           0 :         bus_space_tag_t asict = nsc->sc_asict;
      99           0 :         bus_space_handle_t asich = nsc->sc_asich;
     100           0 :         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           0 :         if (nsc->sc_type == NE2000_TYPE_UNKNOWN)
     108           0 :                 nsc->sc_type = ne2000_detect(nsc);
     109             : 
     110             :         /*
     111             :          * 8k of memory for NE1000, 16k otherwise.
     112             :          */
     113           0 :         switch (nsc->sc_type) {
     114             :         case NE2000_TYPE_UNKNOWN:
     115             :         default:
     116           0 :                 printf(": where did the card go?\n");
     117           0 :                 return (1);
     118             :         case NE2000_TYPE_NE1000:
     119             :                 memsize = 8192;
     120             :                 useword = 0;
     121           0 :                 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           0 :                 break;
     130             :         }
     131             : 
     132           0 :         nsc->sc_useword = useword;
     133             : 
     134           0 :         dsc->cr_proto = ED_CR_RD2;
     135           0 :         if (nsc->sc_type == NE2000_TYPE_AX88190 ||
     136           0 :             nsc->sc_type == NE2000_TYPE_AX88790) {
     137           0 :                 dsc->rcr_proto = ED_RCR_INTT;
     138           0 :                 dsc->sc_flags |= DP8390_DO_AX88190_WORKAROUND;
     139           0 :         } else
     140           0 :                 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           0 :         dsc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0);
     151             : 
     152           0 :         dsc->test_mem = ne2000_test_mem;
     153           0 :         dsc->ring_copy = ne2000_ring_copy;
     154           0 :         dsc->write_mbuf = ne2000_write_mbuf;
     155           0 :         dsc->read_hdr = ne2000_read_hdr;
     156             : 
     157             :         /* Registers are linear. */
     158           0 :         for (i = 0; i < 16; i++)
     159           0 :                 dsc->sc_reg_map[i] = i;
     160             : 
     161             :         /*
     162             :          * NIC memory doens'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           0 :         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           0 :         dsc->mem_size = memsize;
     236             : 
     237           0 :         if (myea == NULL) {
     238             :                 /* Read the station address. */
     239           0 :                 if (nsc->sc_type == NE2000_TYPE_AX88190 ||
     240           0 :                     nsc->sc_type == NE2000_TYPE_AX88790) {
     241             :                         /* Select page 0 registers. */
     242           0 :                         NIC_BARRIER(nict, nich);
     243           0 :                         bus_space_write_1(nict, nich, ED_P0_CR,
     244             :                             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
     245           0 :                         NIC_BARRIER(nict, nich);
     246             :                         /* Select word transfer. */
     247           0 :                         bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS);
     248           0 :                         NIC_BARRIER(nict, nich);
     249           0 :                         ne2000_readmem(nict, nich, asict, asich,
     250           0 :                             AX88190_NODEID_OFFSET, dsc->sc_arpcom.ac_enaddr,
     251             :                             ETHER_ADDR_LEN, useword);
     252           0 :                 } else {
     253           0 :                         ne2000_readmem(nict, nich, asict, asich, 0, romdata,
     254             :                             sizeof(romdata), useword);
     255           0 :                         for (i = 0; i < ETHER_ADDR_LEN; i++)
     256           0 :                                 dsc->sc_arpcom.ac_enaddr[i] =
     257           0 :                                     romdata[i * (useword ? 2 : 1)];
     258             :                 }
     259             :         } else
     260           0 :                 bcopy(myea, dsc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
     261             : 
     262             :         /* Clear any pending interrupts that might have occurred above. */
     263           0 :         NIC_BARRIER(nict, nich);
     264           0 :         bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
     265           0 :         NIC_BARRIER(nict, nich);
     266             : 
     267           0 :         if (dsc->sc_media_init == NULL)
     268           0 :                 dsc->sc_media_init = dp8390_media_init;
     269             : 
     270           0 :         if (dp8390_config(dsc)) {
     271           0 :                 printf(": setup failed\n");
     272           0 :                 return (1);
     273             :         }
     274             : 
     275           0 :         return (0);
     276           0 : }
     277             : 
     278             : /*
     279             :  * Detect an NE-2000 or compatible.  Returns a model code.
     280             :  */
     281             : int
     282           0 : ne2000_detect(struct ne2000_softc *nsc)
     283             : {
     284           0 :         struct dp8390_softc *dsc = &nsc->sc_dp8390;
     285           0 :         bus_space_tag_t nict = dsc->sc_regt;
     286           0 :         bus_space_handle_t nich = dsc->sc_regh;
     287           0 :         bus_space_tag_t asict = nsc->sc_asict;
     288           0 :         bus_space_handle_t asich = nsc->sc_asich;
     289             :         static u_int8_t test_pattern[32] = "THIS is A memory TEST pattern";
     290           0 :         u_int8_t test_buffer[32], tmp;
     291             :         int state, i, rv = 0;
     292             : 
     293           0 :         state = dsc->sc_enabled;
     294           0 :         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           0 :         tmp = bus_space_read_1(asict, asich, NE2000_ASIC_RESET);
     303           0 :         ASIC_BARRIER(asict, asich);
     304           0 :         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           0 :         bus_space_write_1(asict, asich, NE2000_ASIC_RESET, tmp);
     315           0 :         ASIC_BARRIER(asict, asich);
     316           0 :         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           0 :         bus_space_write_1(nict, nich, ED_P0_CR,
     325             :             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
     326           0 :         NIC_BARRIER(nict, nich);
     327             : 
     328           0 :         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           0 :         tmp = bus_space_read_1(nict, nich, ED_P0_CR);
     352           0 :         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           0 :         tmp = bus_space_read_1(nict, nich, ED_P0_ISR);
     357           0 :         if ((tmp & ED_ISR_RST) != ED_ISR_RST)
     358             :                 goto out;
     359             : 
     360           0 :         bus_space_write_1(nict, nich,
     361             :             ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
     362           0 :         NIC_BARRIER(nict, nich);
     363             : 
     364           0 :         for (i = 0; i < 100; i++) {
     365           0 :                 if ((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RST) ==
     366             :                     ED_ISR_RST) {
     367             :                         /* Ack the reset bit. */
     368           0 :                         bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RST);
     369           0 :                         NIC_BARRIER(nict, nich);
     370           0 :                         break;
     371             :                 }
     372           0 :                 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           0 :         bus_space_write_1(nict, nich, ED_P0_RCR, ED_RCR_MON);
     391           0 :         NIC_BARRIER(nict, nich);
     392             : 
     393             :         /* Temporarily initialize DCR for byte operations. */
     394           0 :         bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
     395             : 
     396           0 :         bus_space_write_1(nict, nich, ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
     397           0 :         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           0 :         ne2000_writemem(nict, nich, asict, asich, test_pattern, 8192,
     405             :             sizeof(test_pattern), 0);
     406           0 :         ne2000_readmem(nict, nich, asict, asich, 8192, test_buffer,
     407             :             sizeof(test_buffer), 0);
     408             : 
     409           0 :         if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
     410             :                 /* not an NE1000 - try NE2000 */
     411           0 :                 bus_space_write_1(nict, nich, ED_P0_DCR,
     412             :                     ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
     413           0 :                 bus_space_write_1(nict, nich, ED_P0_PSTART,
     414             :                     16384 >> ED_PAGE_SHIFT);
     415           0 :                 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           0 :                 ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384,
     423             :                     sizeof(test_pattern), 1);
     424           0 :                 ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer,
     425             :                     sizeof(test_buffer), 1);
     426             : 
     427           0 :                 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
     428             :                         goto out;       /* not an NE2000 either */
     429             : 
     430             :                 rv = NE2000_TYPE_NE2000;
     431           0 :         } else {
     432             :                 /* We're an NE1000. */
     433             :                 rv = NE2000_TYPE_NE1000;
     434             :         }
     435             : 
     436             :         /* Clear any pending interrupts that might have occurred above. */
     437           0 :         NIC_BARRIER(nict, nich);
     438           0 :         bus_space_write_1(nict, nich, ED_P0_ISR, 0xff);
     439             : 
     440             :  out:
     441           0 :         dsc->sc_enabled = state;
     442             : 
     443           0 :         return (rv);
     444           0 : }
     445             : 
     446             : /*
     447             :  * Write an mbuf chain to the destination NIC memory address using programmed
     448             :  * I/O.
     449             :  */
     450             : int
     451           0 : ne2000_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
     452             : {
     453           0 :         struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
     454           0 :         bus_space_tag_t nict = sc->sc_regt;
     455           0 :         bus_space_handle_t nich = sc->sc_regh;
     456           0 :         bus_space_tag_t asict = nsc->sc_asict;
     457           0 :         bus_space_handle_t asich = nsc->sc_asich;
     458             :         int savelen;
     459             :         int maxwait = 100;      /* about 120us */
     460             : 
     461           0 :         savelen = m->m_pkthdr.len;
     462             : 
     463             :         /* Select page 0 registers. */
     464           0 :         NIC_BARRIER(nict, nich);
     465           0 :         bus_space_write_1(nict, nich, ED_P0_CR,
     466             :             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
     467           0 :         NIC_BARRIER(nict, nich);
     468             : 
     469             :         /* Reset remote DMA complete flag. */
     470           0 :         bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC);
     471           0 :         NIC_BARRIER(nict, nich);
     472             : 
     473             :         /* Set up DMA byte count. */
     474           0 :         bus_space_write_1(nict, nich, ED_P0_RBCR0, savelen);
     475           0 :         bus_space_write_1(nict, nich, ED_P0_RBCR1, savelen >> 8);
     476             : 
     477             :         /* Set up destination address in NIC mem. */
     478           0 :         bus_space_write_1(nict, nich, ED_P0_RSAR0, buf);
     479           0 :         bus_space_write_1(nict, nich, ED_P0_RSAR1, buf >> 8);
     480             : 
     481             :         /* Set remote DMA write. */
     482           0 :         NIC_BARRIER(nict, nich);
     483           0 :         bus_space_write_1(nict, nich,
     484             :             ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
     485           0 :         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           0 :         if (nsc->sc_type == NE2000_TYPE_NE1000) {
     494             :                 /* NE1000s are easy. */
     495           0 :                 for (; m != 0; m = m->m_next) {
     496           0 :                         if (m->m_len) {
     497           0 :                                 bus_space_write_multi_1(asict, asich,
     498             :                                     NE2000_ASIC_DATA, mtod(m, u_int8_t *),
     499             :                                     m->m_len);
     500           0 :                         }
     501             :                 }
     502             :         } else {
     503             :                 /* NE2000s are a bit trickier. */
     504           0 :                 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           0 :                 savebyte[0] = savebyte[1] = 0;
     512             : 
     513           0 :                 for (; m != 0; m = m->m_next) {
     514           0 :                         l = m->m_len;
     515           0 :                         if (l == 0)
     516             :                                 continue;
     517           0 :                         data = mtod(m, u_int8_t *);
     518             : #ifdef DIAGNOSTIC
     519           0 :                         lim = data + l;
     520             : #endif
     521           0 :                         while (l > 0) {
     522           0 :                                 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           0 :                                         savebyte[1] = *data++;
     530           0 :                                         l--;
     531           0 :                                         bus_space_write_raw_multi_2(asict,
     532             :                                             asich, NE2000_ASIC_DATA,
     533             :                                             savebyte, 2);
     534             :                                         leftover = 0;
     535           0 :                                 } 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           0 :                                         leftover = l & 1;
     551           0 :                                         l &= ~1;
     552           0 :                                         bus_space_write_raw_multi_2(asict,
     553             :                                             asich, NE2000_ASIC_DATA, data, l);
     554           0 :                                         data += l;
     555           0 :                                         if (leftover)
     556           0 :                                                 savebyte[0] = *data++;
     557             :                                         l = 0;
     558             :                                 }
     559             :                         }
     560           0 :                         if (l < 0)
     561           0 :                                 panic("ne2000_write_mbuf: negative len");
     562             : #ifdef DIAGNOSTIC
     563           0 :                         if (data != lim)
     564           0 :                                 panic("ne2000_write_mbuf: data != lim");
     565             : #endif
     566             :                 }
     567           0 :                 if (leftover) {
     568           0 :                         savebyte[1] = 0;
     569           0 :                         bus_space_write_raw_multi_2(asict, asich,
     570             :                             NE2000_ASIC_DATA, savebyte, 2);
     571           0 :                 }
     572           0 :         }
     573           0 :         NIC_BARRIER(nict, nich);
     574             : 
     575             :         /* AX88796 doesn't seem to have remote DMA complete */
     576           0 :         if (sc->sc_flags & DP8390_NO_REMOTE_DMA_COMPLETE)
     577           0 :                 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           0 :         while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) !=
     587           0 :             ED_ISR_RDC) && --maxwait) {
     588           0 :                 bus_space_read_1(nict, nich, ED_P0_CRDA1);
     589           0 :                 bus_space_read_1(nict, nich, ED_P0_CRDA0);
     590           0 :                 NIC_BARRIER(nict, nich);
     591           0 :                 DELAY(1);
     592             :         }
     593             : 
     594           0 :         if (maxwait == 0) {
     595           0 :                 log(LOG_WARNING,
     596             :                     "%s: remote transmit DMA failed to complete\n",
     597           0 :                     sc->sc_dev.dv_xname);
     598           0 :                 dp8390_reset(sc);
     599           0 :         }
     600             : 
     601           0 :         return (savelen);
     602           0 : }
     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           0 : ne2000_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst,
     611             :     u_short amount)
     612             : {
     613           0 :         struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
     614           0 :         bus_space_tag_t nict = sc->sc_regt;
     615           0 :         bus_space_handle_t nich = sc->sc_regh;
     616           0 :         bus_space_tag_t asict = nsc->sc_asict;
     617           0 :         bus_space_handle_t asich = nsc->sc_asich;
     618             :         u_short tmp_amount;
     619           0 :         int useword = nsc->sc_useword;
     620             : 
     621             :         /* Does copy wrap to lower addr in ring buffer? */
     622           0 :         if (src + amount > sc->mem_end) {
     623           0 :                 tmp_amount = sc->mem_end - src;
     624             : 
     625             :                 /* Copy amount up to end of NIC memory. */
     626           0 :                 ne2000_readmem(nict, nich, asict, asich, src,
     627           0 :                     (u_int8_t *)dst, tmp_amount, useword);
     628             : 
     629           0 :                 amount -= tmp_amount;
     630           0 :                 src = sc->mem_ring;
     631           0 :                 dst += tmp_amount;
     632           0 :         }
     633             : 
     634           0 :         ne2000_readmem(nict, nich, asict, asich, src, (u_int8_t *)dst,
     635           0 :             amount, useword);
     636             : 
     637           0 :         return (src + amount);
     638             : }
     639             : 
     640             : void
     641           0 : ne2000_read_hdr(struct dp8390_softc *sc, int buf, struct dp8390_ring *hdr)
     642             : {
     643           0 :         struct ne2000_softc *nsc = (struct ne2000_softc *)sc;
     644             : 
     645           0 :         ne2000_readmem(sc->sc_regt, sc->sc_regh, nsc->sc_asict, nsc->sc_asich,
     646           0 :             buf, (u_int8_t *)hdr, sizeof(struct dp8390_ring),
     647           0 :             nsc->sc_useword);
     648             : #if BYTE_ORDER == BIG_ENDIAN
     649             :         hdr->count = swap16(hdr->count);
     650             : #endif
     651           0 : }
     652             : 
     653             : int
     654           0 : ne2000_test_mem(struct dp8390_softc *sc)
     655             : {
     656             :         /* Noop. */
     657           0 :         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           0 : 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           0 :         NIC_BARRIER(nict, nich);
     673           0 :         bus_space_write_1(nict, nich, ED_P0_CR,
     674             :             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
     675           0 :         NIC_BARRIER(nict, nich);
     676             : 
     677             :         /* Round up to a word. */
     678           0 :         if (amount & 1)
     679           0 :                 ++amount;
     680             : 
     681             :         /* Set up DMA byte count. */
     682           0 :         bus_space_write_1(nict, nich, ED_P0_RBCR0, amount);
     683           0 :         bus_space_write_1(nict, nich, ED_P0_RBCR1, amount >> 8);
     684             : 
     685             :         /* Set up source address in NIC mem. */
     686           0 :         bus_space_write_1(nict, nich, ED_P0_RSAR0, src);
     687           0 :         bus_space_write_1(nict, nich, ED_P0_RSAR1, src >> 8);
     688             : 
     689           0 :         NIC_BARRIER(nict, nich);
     690           0 :         bus_space_write_1(nict, nich, ED_P0_CR,
     691             :             ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
     692             : 
     693           0 :         ASIC_BARRIER(asict, asich);
     694           0 :         if (useword)
     695           0 :                 bus_space_read_raw_multi_2(asict, asich, NE2000_ASIC_DATA,
     696             :                     dst, amount);
     697             :         else
     698           0 :                 bus_space_read_multi_1(asict, asich, NE2000_ASIC_DATA,
     699             :                     dst, amount);
     700           0 : }
     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           0 : 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           0 :         NIC_BARRIER(nict, nich);
     715           0 :         bus_space_write_1(nict, nich, ED_P0_CR,
     716             :             ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
     717           0 :         NIC_BARRIER(nict, nich);
     718             : 
     719             :         /* Reset remote DMA complete flag. */
     720           0 :         bus_space_write_1(nict, nich, ED_P0_ISR, ED_ISR_RDC);
     721           0 :         NIC_BARRIER(nict, nich);
     722             : 
     723             :         /* Set up DMA byte count. */
     724           0 :         bus_space_write_1(nict, nich, ED_P0_RBCR0, len);
     725           0 :         bus_space_write_1(nict, nich, ED_P0_RBCR1, len >> 8);
     726             : 
     727             :         /* Set up destination address in NIC mem. */
     728           0 :         bus_space_write_1(nict, nich, ED_P0_RSAR0, dst);
     729           0 :         bus_space_write_1(nict, nich, ED_P0_RSAR1, dst >> 8);
     730             : 
     731             :         /* Set remote DMA write. */
     732           0 :         NIC_BARRIER(nict, nich);
     733           0 :         bus_space_write_1(nict, nich, ED_P0_CR,
     734             :             ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
     735           0 :         NIC_BARRIER(nict, nich);
     736             : 
     737           0 :         ASIC_BARRIER(asict, asich);
     738           0 :         if (useword)
     739           0 :                 bus_space_write_raw_multi_2(asict, asich, NE2000_ASIC_DATA,
     740             :                     src, len);
     741             :         else
     742           0 :                 bus_space_write_multi_1(asict, asich, NE2000_ASIC_DATA,
     743             :                     src, len);
     744           0 :         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           0 :         while (((bus_space_read_1(nict, nich, ED_P0_ISR) & ED_ISR_RDC) !=
     754           0 :             ED_ISR_RDC) && --maxwait)
     755           0 :                 DELAY(1);
     756           0 : }
     757             : 
     758             : int
     759           0 : ne2000_detach(struct ne2000_softc *sc, int flags)
     760             : {
     761           0 :         return (dp8390_detach(&sc->sc_dp8390, flags));
     762             : }

Generated by: LCOV version 1.13