home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / unix / bsd / 10656 < prev    next >
Encoding:
Text File  |  1992-12-27  |  33.2 KB  |  1,089 lines

  1. Newsgroups: comp.unix.bsd
  2. Path: sparky!uunet!europa.asd.contel.com!gatech!rpi!psinntp!psinntp!dg-rtp!ponds.uucp!rivers
  3. From: rivers@ponds.uucp (Thomas David Rivers)
  4. Subject: NE2000 test results (previous driver performs better).
  5. Summary: Here's a better driver (repost).
  6. Message-ID: <1992Dec27.181634.523@ponds.uucp>
  7. Keywords:  ether, speed, 386bsd NE2000
  8. Date: Sun, 27 Dec 1992 18:16:34 GMT
  9. Lines: 1078
  10.  
  11.  
  12.  Well, since Curt Mayer (curt@hoptoad.uucp) had re-written the
  13.  NE2000 driver for us, I decided to take some time and give it
  14.  a good shaking out.
  15.  
  16.  My test machines (ponds and lakes) are:
  17.  
  18.      ponds            lakes
  19.    386DX, 33mhz              386DX, 33mhz
  20.    NE2000 clone               NE2000 clone
  21.    8-meg memory               12-meg memory
  22.    Hercules              ET4000 clone (running XFree86 1.1)
  23.    IDE 240Meg.              SCSI -663 meg
  24.    Wangtek (EN2099)           Wangtek (5150ES)
  25.    40-meg swap on wd0          40-meg swap on sd0
  26.  
  27.  They are directly connected by 6 feet on ethernet cable,  With a
  28.  50-ohm terminator on lakes, and a 50-ohm grounded terminator on ponds.
  29.  There is nothing else on this "network".
  30.  
  31.   So, here are some timings from the driver posted to comp.unix.bsd by
  32.  Ralf Friedl (PA Peter) <friedl@informatik.uni-kl.de>, on Jul 15th.
  33.  These are arrived by  moving a copy of the 386bsd kernel from 
  34.  lakes to ponds (444736 bytes) using binary ftp (no hash).
  35.  
  36.    Time to Transfer (seconds)  Kbytes/Sec
  37.      4.3                        1e+02
  38.      3.3                        1.3e+02
  39.      3.4                    1.3e+02
  40.      2.8            1.6e+02
  41.      4.2            1e+02
  42.  
  43.  These appear to be rather good time, approaching what you would
  44.  expect the bandwidth to be on such a network (few collisions...)
  45.  
  46.  Ok, so I installed the driver posted by Curt.  My original intent
  47.  was to install it on both machines, then only one. However, when 
  48.  that kernel came up on "lakes" the network didn't function (lots of
  49.  overun-type errors from the driver: ne0 ... error: isr 15; 
  50.  ne0 ... error: isr 14, etc...) 
  51.  
  52.  Thus, I was only able to get Curt's driver to run on "ponds".  The 
  53.  following times reflect that situation (ponds is running Curt Mayer's
  54.  driver, lakes is running the driver posted in July.)  There was *no*
  55.  other change in the test, hardware, etc...  Since the times appeared
  56.  so much worse, I ran more tests than before.
  57.  
  58.    Time to Transfer (seconds)  Kbytes/Sec
  59.      10                42 
  60.      10                42
  61.      11                39
  62.      10                42
  63.      15                29
  64.      6.3            69
  65.      9.4            46
  66.  
  67.  These numbers don't approach those of the other driver.  Also, just to
  68.  get a feel for NFS mounts, rlogin, etc... I tried out several NFS
  69.  configurations, rlogin'ing and so forth - generally it seemed to be
  70.  much slower.
  71.  
  72.  OK, so I thought I may have seriously goofed things up, since these
  73.  numbers were so much lower than the other driver.  So, I rebooted
  74.  ponds with the (saved) kernel containing the Friedl drivers, and
  75.  ran some tests.  Again, the only change I made was to reboot the
  76.  machine - no other modifications.  The test results returned to a set
  77.  similar to above, indicating that it was indeed the NE2000 driver
  78.  which explained the slowdown.
  79.  
  80.  
  81.  I have sent this driver to several people (who had requested an
  82.  improved driver from this news group.)  But, I would like other
  83.  people to do the same comparison (or a comparison in different
  84.  circumstances) to validate my results.  As such, I am *reposting*
  85.  this same driver again....  (also, there were several people
  86.  who requested this code, to whom I could not send mail (it bounced))
  87.  
  88.         - Dave Rivers -
  89.         (rivers@ponds.uucp)
  90.  
  91. ----------------- cut here ----------------------------
  92. Path: utnet-news!news.u-tokyo.ac.jp!ccut!wnoc-tyo-news!nec-tyo!nec-gw!mips!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!ames!network.ucsd.edu!nosc!jadpc!Ralf Friedl (PA Peter) <friedl@informatik.uni-kl.de>
  93. From: friedl@informatik.uni-kl.de (PA Peter)
  94. Newsgroups: comp.unix.bsd
  95. Subject: Device driver for NE1000/NE2000
  96. Message-ID: <9207152126.aa00382@superieur.informatik.uni-kl.de>
  97. Date: 15 Jul 92 19:53:32 GMT
  98. Sender: 386bsd-gate@jadpc.cts.com
  99. Reply-To: Ralf Friedl (PA Peter) <friedl@informatik.uni-kl.de>
  100. Organization: J. Deitch & Associates
  101. Lines: 212
  102. Originator: 386bsd-gate@jadpc.cts.com
  103. Precedence: bulk
  104.  
  105.  
  106. Below is a diff for the original net2 NE2000 driver, so that the driver can
  107. be used with both NE1000 and NE2000 or compatible interface cards. The type of
  108. the card is determined during the boot in the autoconfiguration phase, so it is
  109. not necessary to specify it at compile time.
  110.  
  111. The driver may also work with more that one card at the same time, but I didn't
  112. try it.
  113.  
  114. The driver includes a file "machine/asm.h". This is used for inline versions of
  115. the in../out.. function. If you don't have something like that, just remove the
  116. line, and the functions in locore.s will be used.
  117.  
  118. Enjoy
  119.  
  120. ----
  121. Ralf Friedl
  122. friedl@informatik.uni-kl.de
  123.  
  124.  
  125. #!/bin/sh
  126. # This is a shell archive (shar 3.32)
  127. # made 07/31/1992 07:20 UTC by shin@angora.nc.u-tokyo.ac.jp
  128. # Source directory /tmp
  129. #
  130. # existing files WILL be overwritten
  131. #
  132. # This shar contains:
  133. # length  mode       name
  134. # ------ ---------- ------------------------------------------
  135. #  24098 -rw-r--r-- if_ne.c
  136. #   2982 -rw-r--r-- if_nereg.h
  137. #
  138. if touch 2>&1 | fgrep 'amc' > /dev/null
  139.  then TOUCH=touch
  140.  else TOUCH=true
  141. fi
  142. # ============= if_ne.c ==============
  143. echo "x - extracting if_ne.c (Text)"
  144. sed 's/^X//' << 'SHAR_EOF' > if_ne.c &&
  145. X/*-
  146. X * Copyright (c) 1990, 1991 William F. Jolitz.
  147. X * Copyright (c) 1990 The Regents of the University of California.
  148. X * All rights reserved.
  149. X *
  150. X * Redistribution and use in source and binary forms, with or without
  151. X * modification, are permitted provided that the following conditions
  152. X * are met:
  153. X * 1. Redistributions of source code must retain the above copyright
  154. X *    notice, this list of conditions and the following disclaimer.
  155. X * 2. Redistributions in binary form must reproduce the above copyright
  156. X *    notice, this list of conditions and the following disclaimer in the
  157. X *    documentation and/or other materials provided with the distribution.
  158. X * 3. All advertising materials mentioning features or use of this software
  159. X *    must display the following acknowledgement:
  160. X *    This product includes software developed by the University of
  161. X *    California, Berkeley and its contributors.
  162. X * 4. Neither the name of the University nor the names of its contributors
  163. X *    may be used to endorse or promote products derived from this software
  164. X *    without specific prior written permission.
  165. X *
  166. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  167. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  168. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  169. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  170. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  171. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  172. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  173. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  174. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  175. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  176. X * SUCH DAMAGE.
  177. X *
  178. X *    @(#)if_ne.c    7.4 (Berkeley) 5/21/91
  179. X */
  180. X
  181. X/*
  182. X  * NE1000/NE2000 Ethernet driver
  183. X *
  184. X * Parts inspired from Tim Tucker's if_wd driver for the wd8003,
  185. X * insight on the ne2000 gained from Robert Clements PC/FTP driver.
  186. X */
  187. X
  188. X#include "ne.h"
  189. X#if NNE > 0
  190. X
  191. X#include "param.h"
  192. X#include "systm.h"
  193. X#include "mbuf.h"
  194. X#include "buf.h"
  195. X#include "protosw.h"
  196. X#include "socket.h"
  197. X#include "ioctl.h"
  198. X#include "errno.h"
  199. X#include "syslog.h"
  200. X
  201. X#include "net/if.h"
  202. X#include "net/netisr.h"
  203. X#include "net/route.h"
  204. X
  205. X#ifdef INET
  206. X#include "netinet/in.h"
  207. X#include "netinet/in_systm.h"
  208. X#include "netinet/in_var.h"
  209. X#include "netinet/ip.h"
  210. X#include "netinet/if_ether.h"
  211. X#endif
  212. X
  213. X#ifdef NS
  214. X#include "netns/ns.h"
  215. X#include "netns/ns_if.h"
  216. X#endif
  217. X
  218. X#include "i386/isa/isa_device.h"
  219. X#include "i386/isa/if_nereg.h"
  220. X#include "i386/isa/icu.h"
  221. X/* #include "machine/asm.h" */
  222. X
  223. Xint    neprobe(), neattach(), neintr();
  224. Xint    nestart(),neinit(), ether_output(), neioctl();
  225. X
  226. Xstruct    isa_driver nedriver = {
  227. X    neprobe, neattach, "ne",
  228. X};
  229. X
  230. Xstruct    mbuf *neget();
  231. X
  232. X#define ETHER_MIN_LEN 64
  233. X#define ETHER_MAX_LEN 1536
  234. X
  235. X/* Word Transfers, Burst Mode Select, Fifo at 8 bytes */
  236. X#define DCR_CTRL2      DSDC_WTS|DSDC_BMS|DSDC_FT1
  237. X/* No Word Transfers, Burst Mode Select, Fifo at 8 bytes */
  238. X#define DCR_CTRL1      DSDC_BMS|DSDC_FT1
  239. X
  240. X
  241. X/*
  242. X * Ethernet software status per interface.
  243. X *
  244. X * Each interface is referenced by a network interface structure,
  245. X * ns_if, which the routing code uses to locate the interface.
  246. X * This structure contains the output queue for the interface, its address, ...
  247. X */
  248. Xstruct    ne_softc {
  249. X    struct    arpcom ns_ac;        /* Ethernet common part */
  250. X#define    ns_if    ns_ac.ac_if        /* network-visible interface */
  251. X#define    ns_addr    ns_ac.ac_enaddr        /* hardware Ethernet address */
  252. X    int    ns_flags;
  253. X#define    DSF_LOCK    1        /* block re-entering enstart */
  254. X    int    ns_oactive ;
  255. X    int    ns_mask ;
  256. X    int    ns_ba;            /* byte addr in buffer ram of inc pkt */
  257. X    int    ns_cur;            /* current page being filled */
  258. X    u_short ns_iobase;
  259. X    u_short ns_board;               /* Board-Type: 0:NE1000, 1:NE2000 */
  260. X    u_short ns_tbuf;
  261. X    u_short ns_rbuf;
  262. X    u_short ns_rbufend;
  263. X    struct    prhdr    ns_ph;        /* hardware header of incoming packet*/
  264. X    struct    ether_header ns_eh;    /* header of incoming packet */
  265. X    u_char    ns_pb[2048 /*ETHERMTU+sizeof(long)*/];
  266. X} ne_softc[NNE] ;
  267. X#define    ENBUFSIZE    (sizeof(struct ether_header) + ETHERMTU + 2 + ETHER_MIN_LEN)
  268. X
  269. Xu_char boarddata[16];
  270. Xvoid nefetch (struct ne_softc *ns, void *up, u_int ad, u_int len);
  271. Xvoid neput (struct ne_softc *ns, void *up, u_int ad, u_int len);
  272. X
  273. X
  274. Xneprobe(dvp)
  275. X    struct isa_device *dvp;
  276. X{
  277. X    int val,i, test, unit;
  278. X    u_short iobase;
  279. X    register struct ne_softc *ns;
  280. X
  281. X        unit = dvp->id_unit;
  282. X        if (unit >= NNE)
  283. X                return (0);
  284. X        ns = &ne_softc[unit];
  285. X        if (ns->ns_iobase)
  286. X                /* Unit already configured */
  287. X                return (0);
  288. X        iobase = ns->ns_iobase = dvp->id_iobase;
  289. X
  290. X    /* Reset the bastard */
  291. X        val = inb(iobase+ne_reset);
  292. X /*     DELAY(2000000); */
  293. X        outb(iobase+ne_reset,val);
  294. X
  295. X    outb(iobase+ds_cmd, DSCM_STOP|DSCM_NODMA);
  296. X    
  297. X        if (inb (iobase + ds_cmd) != (DSCM_STOP | DSCM_NODMA))
  298. X                return (0);
  299. X    i = 1000000;
  300. X    while ((inb(iobase+ds0_isr)&DSIS_RESET) == 0 && i-- > 0);
  301. X    if (i < 0) return (0);
  302. X
  303. X    outb(iobase+ds0_isr, 0xff);
  304. X
  305. X        /* No Word Transfers, Burst Mode Select, Fifo at 8 bytes */
  306. X        outb (iobase+ds0_dcr, DCR_CTRL1);
  307. X
  308. X    outb(iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP);
  309. X    DELAY(10000);
  310. X
  311. X    /* Check cmd reg and fail if not right */
  312. X    if ((i=inb(iobase+ds_cmd)) != (DSCM_NODMA|DSCM_PG0|DSCM_STOP))
  313. X        return(0);
  314. X
  315. X        outb(iobase+ds0_tcr, 0);
  316. X        outb(iobase+ds0_rcr, DSRC_MON);
  317. X        outb(iobase+ds0_pstart, RBUF1/DS_PGSIZE);
  318. X        outb(iobase+ds0_pstop, RBUFEND1/DS_PGSIZE);
  319. X        outb(iobase+ds0_bnry, RBUFEND1/DS_PGSIZE);
  320. X        outb(iobase+ds0_imr, 0);
  321. X        outb(iobase+ds0_isr, 0);
  322. X        outb(iobase+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP);
  323. X        outb(iobase+ds1_curr, RBUF1/DS_PGSIZE);
  324. X        outb(iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP);
  325. X        test = 0xA55A55AA;
  326. X        neput (ns, &test, TBUF1, sizeof (test));
  327. X        nefetch (ns, &test, TBUF1, sizeof (test));
  328. X        if (test == 0xA55A55AA) {
  329. X                ns->ns_board = 0;       /* NE1000 */
  330. X                ns->ns_tbuf = TBUF1;
  331. X                ns->ns_rbuf = RBUF1;
  332. X                ns->ns_rbufend = RBUFEND1;
  333. X        }
  334. X        else {
  335. X                ns->ns_board = 1;       /* NE2000 */
  336. X                ns->ns_tbuf = TBUF2;
  337. X                ns->ns_rbuf = RBUF2;
  338. X                ns->ns_rbufend = RBUFEND2;
  339. X                outb(iobase+ds0_dcr, DCR_CTRL2);
  340. X        }
  341. X
  342. X#ifdef NEDEBUG
  343. X#define    PAT(n)    (0xa55a + 37*(n))
  344. X#define    RCON    37
  345. X    {    int i, rom, pat;
  346. X
  347. X        rom=1;
  348. X        printf("ne ram ");
  349. X        
  350. X        for (i = 0; i < 0xfff0; i+=4) {
  351. X            pat = PAT(i);
  352. X                        neput (ns, &pat,i,4);
  353. X                        nefetch (ns, &pat,i,4);
  354. X            if (pat == PAT(i)) {
  355. X                if (rom) {
  356. X                    rom=0;
  357. X                    printf(" %x", i);
  358. X                }
  359. X            } else {
  360. X                if (!rom) {
  361. X                    rom=1;
  362. X                    printf("..%x ", i);
  363. X                }
  364. X            }
  365. X            pat=0;
  366. X            neput (ns, &pat,i,4);
  367. X        }
  368. X        printf("\n");
  369. X    }
  370. X#endif
  371. X
  372. X    /* Extract board address */
  373. X        nefetch (ns, boarddata, 0, sizeof(boarddata));
  374. X        if (ns->ns_board)
  375. X                for (i = 0; i < 6; i++)
  376. X                        ns->ns_addr[i] = boarddata[2 * i];
  377. X        else
  378. X                for (i = 0; i < 6; i++)
  379. X                        ns->ns_addr[i] = boarddata[i];
  380. X    return (1);
  381. X}
  382. X
  383. X/*
  384. X * Fetch from onboard ROM/RAM
  385. X */
  386. Xvoid nefetch (struct ne_softc *ns, void *up, u_int ad, u_int len)
  387. X{
  388. X    u_char cmd;
  389. X    const u_short iobase = ns->ns_iobase;
  390. X
  391. X        if (len == 0)
  392. X                return;
  393. X        cmd = inb(iobase+ds_cmd);
  394. X        outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START);
  395. X
  396. X    /* Setup remote dma */
  397. X        outb (iobase+ds0_isr, DSIS_RDC);
  398. X        outb (iobase+ds0_rbcr0, len);
  399. X        outb (iobase+ds0_rbcr1, len>>8);
  400. X        outb (iobase+ds0_rsar0, ad);
  401. X        outb (iobase+ds0_rsar1, ad>>8);
  402. X
  403. X    /* Execute & extract from card */
  404. X        outb (iobase+ds_cmd, DSCM_RREAD|DSCM_PG0|DSCM_START);
  405. X        if (ns->ns_board)
  406. X                insw (iobase+ne_data, up, len/2);
  407. X        else
  408. X                insb (iobase+ne_data, up, len/1);
  409. X
  410. X    /* Wait till done, then shutdown feature */
  411. X        while ((inb (iobase+ds0_isr) & DSIS_RDC) == 0)
  412. X                ;
  413. X        outb (iobase+ds0_isr, DSIS_RDC);
  414. X        outb (iobase+ds_cmd, cmd);
  415. X}
  416. X
  417. X/*
  418. X * Put to onboard RAM
  419. X */
  420. Xvoid neput (struct ne_softc *ns, void *up, u_int ad, u_int len)
  421. X{
  422. X    u_char cmd;
  423. X    const u_short iobase = ns->ns_iobase;
  424. X
  425. X        if (len == 0)
  426. X                return;
  427. X        cmd = inb(iobase+ds_cmd);
  428. X        outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START);
  429. X
  430. X    /* Setup for remote dma */
  431. X    outb (iobase+ds0_isr, DSIS_RDC);
  432. X    if(len&1) len++;        /* roundup to words */
  433. X        outb (iobase+ds0_rbcr0, len);
  434. X        outb (iobase+ds0_rbcr1, len>>8);
  435. X        outb (iobase+ds0_rsar0, ad);
  436. X        outb (iobase+ds0_rsar1, ad>>8);
  437. X
  438. X    /* Execute & stuff to card */
  439. X        outb (iobase+ds_cmd, DSCM_RWRITE|DSCM_PG0|DSCM_START);
  440. X        if (ns->ns_board)
  441. X                outsw (iobase+ne_data, up, len/2);
  442. X        else
  443. X                outsb (iobase+ne_data, up, len/1);
  444. X    
  445. X    /* Wait till done, then shutdown feature */
  446. X        while ((inb (iobase+ds0_isr) & DSIS_RDC) == 0)
  447. X                ;
  448. X        outb (iobase+ds0_isr, DSIS_RDC);
  449. X        outb (iobase+ds_cmd, cmd);
  450. X}
  451. X
  452. X/*
  453. X * Reset of interface.
  454. X */
  455. Xnereset(unit, uban)
  456. X    int unit, uban;
  457. X{
  458. X    if (unit >= NNE)
  459. X        return;
  460. X    printf("ne%d: reset\n", unit);
  461. X    ne_softc[unit].ns_flags &= ~DSF_LOCK;
  462. X    neinit(unit);
  463. X}
  464. X/*
  465. X * Interface exists: make available by filling in network interface
  466. X * record.  System will initialize the interface when it is ready
  467. X * to accept packets.  We get the ethernet address here.
  468. X */
  469. Xneattach(dvp)
  470. X    struct isa_device *dvp;
  471. X{
  472. X    int unit = dvp->id_unit;
  473. X    register struct ne_softc *ns = &ne_softc[unit];
  474. X    register struct ifnet *ifp = &ns->ns_if;
  475. X
  476. X    ifp->if_unit = unit;
  477. X    ifp->if_name = nedriver.name ;
  478. X    ifp->if_mtu = ETHERMTU;
  479. X    printf (" ethernet address %s", ether_sprintf(ns->ns_addr)) ;
  480. X    ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
  481. X    ifp->if_init = neinit;
  482. X    ifp->if_output = ether_output;
  483. X    ifp->if_start = nestart;
  484. X    ifp->if_ioctl = neioctl;
  485. X    ifp->if_reset = nereset;
  486. X    ifp->if_watchdog = 0;
  487. X    if_attach(ifp);
  488. X}
  489. X
  490. X/*
  491. X * Initialization of interface; set up initialization block
  492. X * and transmit/receive descriptor rings.
  493. X */
  494. Xneinit(unit)
  495. X    int unit;
  496. X{
  497. X    register struct ne_softc *ns = &ne_softc[unit];
  498. X    struct ifnet *ifp = &ns->ns_if;
  499. X    int s;
  500. X    register i; char *cp;
  501. X    const u_short iobase = ns->ns_iobase;
  502. X
  503. X     if (ifp->if_addrlist == (struct ifaddr *)0) return;
  504. X    if (ifp->if_flags & IFF_RUNNING) return;
  505. X
  506. X    s = splimp();
  507. X
  508. X    /* set physical address on ethernet */
  509. X        outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP);
  510. X        for (i=0 ; i < 6 ; i++) outb(iobase+ds1_par0+i,ns->ns_addr[i]);
  511. X
  512. X    /* clr logical address hash filter for now */
  513. X    for (i=0 ; i < 8 ; i++) outb(iobase+ds1_mar0+i,0xff);
  514. X
  515. X    /* init regs */
  516. X        outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP);
  517. X        outb (iobase+ds0_rbcr0, 0);
  518. X        outb (iobase+ds0_rbcr1, 0);
  519. X        outb (iobase+ds0_imr, 0);
  520. X        outb (iobase+ds0_isr, 0xff);
  521. X        outb(iobase+ds0_tcr, 0);
  522. X        outb (iobase+ds0_rcr, DSRC_MON);
  523. X        outb (iobase+ds0_tpsr, 0);
  524. X        outb(iobase+ds0_pstart, ns->ns_rbuf/DS_PGSIZE);
  525. X        outb(iobase+ds0_pstop, ns->ns_rbufend/DS_PGSIZE);
  526. X        outb(iobase+ds0_bnry, ns->ns_rbuf/DS_PGSIZE);
  527. X        outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP);
  528. X        outb(iobase+ds1_curr, ns->ns_rbuf/DS_PGSIZE);
  529. X        ns->ns_cur = ns->ns_rbuf/DS_PGSIZE;
  530. X        outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START);
  531. X        outb (iobase+ds0_rcr, DSRC_AB);
  532. X        if (ns->ns_board)
  533. X                outb(iobase+ds0_dcr, DCR_CTRL2);
  534. X        else
  535. X                outb(iobase+ds0_dcr, DCR_CTRL1);
  536. X        outb (iobase+ds0_imr, 0xff);
  537. X
  538. X    ns->ns_if.if_flags |= IFF_RUNNING;
  539. X    ns->ns_oactive = 0; ns->ns_mask = ~0;
  540. X    nestart(ifp);
  541. X    splx(s);
  542. X}
  543. X
  544. X/*
  545. X * Setup output on interface.
  546. X * Get another datagram to send off of the interface queue,
  547. X * and map it to the interface before starting the output.
  548. X * called only at splimp or interrupt level.
  549. X */
  550. Xnestart(ifp)
  551. X    struct ifnet *ifp;
  552. X{
  553. X    register struct ne_softc *ns = &ne_softc[ifp->if_unit];
  554. X    struct mbuf *m0, *m;
  555. X    int buffer;
  556. X    int len = 0, i, total,t;
  557. X    const u_short iobase = ns->ns_iobase;
  558. X
  559. X    /*
  560. X     * The DS8390 has only one transmit buffer, if it is busy we
  561. X     * must wait until the transmit interrupt completes.
  562. X     */
  563. X    outb(iobase+ds_cmd,DSCM_NODMA|DSCM_START);
  564. X
  565. X    if (ns->ns_flags & DSF_LOCK)
  566. X        return;
  567. X
  568. X    if (inb(iobase+ds_cmd) & DSCM_TRANS)
  569. X        return;
  570. X
  571. X    if ((ns->ns_if.if_flags & IFF_RUNNING) == 0)
  572. X        return;
  573. X
  574. X    IF_DEQUEUE(&ns->ns_if.if_snd, m);
  575. X    if (m == 0)
  576. X        return;
  577. X
  578. X    /*
  579. X     * Copy the mbuf chain into the transmit buffer
  580. X     */
  581. X
  582. X    ns->ns_flags |= DSF_LOCK;    /* prevent entering nestart */
  583. X    buffer = ns->ns_tbuf; len = i = 0;
  584. X    t = 0;
  585. X    for (m0 = m; m != 0; m = m->m_next)
  586. X        t += m->m_len;
  587. X        
  588. X    m = m0;
  589. X    total = t;
  590. X    for (m0 = m; m != 0; ) {
  591. X        
  592. X        if (m->m_len&1 && t > m->m_len) {
  593. X            neput (ns, mtod(m, caddr_t), buffer, m->m_len - 1);
  594. X            t -= m->m_len - 1;
  595. X            buffer += m->m_len - 1;
  596. X            m->m_data += m->m_len - 1;
  597. X            m->m_len = 1;
  598. X            m = m_pullup(m, 2);
  599. X        } else {
  600. X                        if (m->m_len) {
  601. X                                neput (ns, mtod(m, caddr_t), buffer, m->m_len);
  602. X                                buffer += m->m_len;
  603. X                                t -= m->m_len;
  604. X                        }
  605. X            MFREE(m, m0);
  606. X            m = m0;
  607. X        }
  608. X    }
  609. X
  610. X    /*
  611. X     * Init transmit length registers, and set transmit start flag.
  612. X     */
  613. X
  614. X    len = total;
  615. X    if (len < ETHER_MIN_LEN) len = ETHER_MIN_LEN;
  616. X        outb(iobase+ds0_tbcr0,len&0xff);
  617. X        outb(iobase+ds0_tbcr1,(len>>8)&0xff);
  618. X        outb(iobase+ds0_tpsr, ns->ns_tbuf/DS_PGSIZE);
  619. X        outb(iobase+ds_cmd, DSCM_TRANS|DSCM_NODMA|DSCM_START);
  620. X}
  621. X
  622. X/* buffer successor/predecessor in ring? */
  623. X#define succ1(n) (((n)+1 >= RBUFEND1/DS_PGSIZE) ? RBUF1/DS_PGSIZE : (n)+1)
  624. X#define pred1(n) (((n)-1 < RBUF1/DS_PGSIZE) ? RBUFEND1/DS_PGSIZE-1 : (n)-1)
  625. X#define succ2(n) (((n)+1 >= RBUFEND2/DS_PGSIZE) ? RBUF2/DS_PGSIZE : (n)+1)
  626. X#define pred2(n) (((n)-1 < RBUF2/DS_PGSIZE) ? RBUFEND2/DS_PGSIZE-1 : (n)-1)
  627. X
  628. X/*
  629. X * Controller interrupt.
  630. X */
  631. Xneintr(unit)
  632. X{
  633. X    register struct ne_softc *ns = &ne_softc[unit];
  634. X    u_char cmd,isr;
  635. X    const u_short iobase = ns->ns_iobase;
  636. X
  637. X    /* Save cmd, clear interrupt */
  638. X    cmd = inb (iobase+ds_cmd);
  639. Xloop:
  640. X        isr = inb (iobase+ds0_isr);
  641. X        outb(iobase+ds_cmd,DSCM_NODMA|DSCM_START);
  642. X        outb(iobase+ds0_isr, isr);
  643. X
  644. X    /* Receiver error */
  645. X    if (isr & DSIS_RXE) {
  646. X        /* need to read these registers to clear status */
  647. X                (void) inb(iobase+ ds0_rsr);
  648. X                (void) inb(iobase+ 0xD);
  649. X                (void) inb(iobase + 0xE);
  650. X                (void) inb(iobase + 0xF);
  651. X        ns->ns_if.if_ierrors++;
  652. X    }
  653. X
  654. X    /* We received something; rummage thru tiny ring buffer */
  655. X    if (isr & (DSIS_RX|DSIS_RXE|DSIS_ROVRN)) {
  656. X        u_char pend,lastfree;
  657. X
  658. X                outb(iobase+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG1);
  659. X                pend = inb(iobase+ds1_curr);
  660. X                outb(iobase+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG0);
  661. X                lastfree = inb(iobase+ds0_bnry);
  662. X
  663. X        /* Have we wrapped? */
  664. X                if (lastfree >= ns->ns_rbufend/DS_PGSIZE)
  665. X                        lastfree = ns->ns_rbuf/DS_PGSIZE;
  666. X        if (pend < lastfree && ns->ns_cur < pend)
  667. X            lastfree = ns->ns_cur;
  668. X                else    if (ns->ns_cur > lastfree)
  669. X                        lastfree = ns->ns_cur;
  670. X
  671. X        /* Something in the buffer? */
  672. X        while (pend != lastfree) {
  673. X            u_char nxt;
  674. X
  675. X            /* Extract header from microcephalic board */
  676. X            nefetch (ns, &ns->ns_ph,lastfree*DS_PGSIZE,
  677. X                sizeof(ns->ns_ph));
  678. X            ns->ns_ba = lastfree*DS_PGSIZE+sizeof(ns->ns_ph);
  679. X
  680. X            /* Incipient paranoia */
  681. X            if (ns->ns_ph.pr_status == DSRS_RPC ||
  682. X                /* for dequna's */
  683. X                ns->ns_ph.pr_status == 0x21)
  684. X                nerecv (ns);
  685. X#ifdef NEDEBUG
  686. X            else  {
  687. X                printf("cur %x pnd %x lfr %x ",
  688. X                    ns->ns_cur, pend, lastfree);
  689. X                printf("nxt %x len %x ", ns->ns_ph.pr_nxtpg,
  690. X                    (ns->ns_ph.pr_sz1<<8)+ ns->ns_ph.pr_sz0);
  691. X                printf("Bogus Sts %x\n", ns->ns_ph.pr_status);    
  692. X            }
  693. X#endif
  694. X
  695. X            nxt = ns->ns_ph.pr_nxtpg ;
  696. X
  697. X            /* Sanity check */
  698. X            if ( nxt >= ns->ns_rbuf/DS_PGSIZE && nxt <= ns->ns_rbufend/DS_PGSIZE
  699. X                && nxt <= pend)
  700. X                ns->ns_cur = nxt;
  701. X            else    ns->ns_cur = nxt = pend;
  702. X
  703. X            /* Set the boundaries */
  704. X            lastfree = nxt;
  705. X                        if (ns->ns_board)
  706. X                                outb(iobase+ds0_bnry, pred2(nxt));
  707. X                        else
  708. X                                outb(iobase+ds0_bnry, pred1(nxt));
  709. X                        outb(iobase+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG1);
  710. X                        pend = inb(iobase+ds1_curr);
  711. X                        outb(iobase+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG0);
  712. X        }
  713. X        outb(iobase+ds_cmd, DSCM_START|DSCM_NODMA);
  714. X    }
  715. X
  716. X    /* Transmit error */
  717. X    if (isr & DSIS_TXE) {
  718. X        ns->ns_flags &= ~DSF_LOCK;
  719. X        /* Need to read these registers to clear status */
  720. X        ns->ns_if.if_collisions += inb(iobase+ds0_tbcr0);
  721. X        ns->ns_if.if_oerrors++;
  722. X    }
  723. X
  724. X    /* Packet Transmitted */
  725. X    if (isr & DSIS_TX) {
  726. X        ns->ns_flags &= ~DSF_LOCK;
  727. X        ++ns->ns_if.if_opackets;
  728. X        ns->ns_if.if_collisions += inb(iobase+ds0_tbcr0);
  729. X    }
  730. X
  731. X    /* Receiver ovverun? */
  732. X    if (isr & DSIS_ROVRN) {
  733. X        log(LOG_ERR, "ne%d: error: isr %x\n", ns-ne_softc, isr
  734. X            /*, DSIS_BITS*/);
  735. X                outb(iobase+ds0_rbcr0, 0);
  736. X                outb(iobase+ds0_rbcr1, 0);
  737. X                outb(iobase+ds0_tcr, DSTC_LB0);
  738. X                outb(iobase+ds0_rcr, DSRC_MON);
  739. X                outb(iobase+ds_cmd, DSCM_START|DSCM_NODMA);
  740. X                outb(iobase+ds0_rcr, DSRC_AB);
  741. X                outb(iobase+ds0_tcr, 0);
  742. X    }
  743. X
  744. X    /* Any more to send? */
  745. X    outb (iobase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START);
  746. X    nestart(&ns->ns_if);
  747. X        outb (iobase+ds_cmd, cmd);
  748. X        outb (iobase+ds0_imr, 0xff);
  749. X
  750. X
  751. X    /* Still more to do? */
  752. X    isr = inb (iobase+ds0_isr);
  753. X    if(isr) goto loop;
  754. X}
  755. X
  756. X/*
  757. X * Ethernet interface receiver interface.
  758. X * If input error just drop packet.
  759. X * Otherwise examine packet to determine type.  If can't determine length
  760. X * from type, then have to drop packet.  Othewise decapsulate
  761. X * packet based on type and pass to type specific higher-level
  762. X * input routine.
  763. X */
  764. Xnerecv(ns)
  765. X    register struct ne_softc *ns;
  766. X{
  767. X    int len,i;
  768. X
  769. X    ns->ns_if.if_ipackets++;
  770. X    len = ns->ns_ph.pr_sz0 + (ns->ns_ph.pr_sz1<<8);
  771. X    if(len < ETHER_MIN_LEN || len > ETHER_MAX_LEN)
  772. X        return;
  773. X
  774. X    /* this need not be so torturous - one/two bcopys at most into mbufs */
  775. X    nefetch (ns, ns->ns_pb, ns->ns_ba, min(len,DS_PGSIZE-sizeof(ns->ns_ph)));
  776. X    if (len > DS_PGSIZE-sizeof(ns->ns_ph)) {
  777. X        int l = len - (DS_PGSIZE-sizeof(ns->ns_ph)), b, m;
  778. X        u_char *p = ns->ns_pb + (DS_PGSIZE-sizeof(ns->ns_ph));
  779. X
  780. X                for (;;) {
  781. X                        if (ns->ns_board == 1)
  782. X                                ns->ns_cur = succ2 (ns->ns_cur);
  783. X                        else
  784. X                                ns->ns_cur = succ1 (ns->ns_cur);
  785. X            b = ns->ns_cur*DS_PGSIZE;
  786. X                        if (l >= DS_PGSIZE) {
  787. X                                nefetch (ns, p, b, DS_PGSIZE);
  788. X                                p += DS_PGSIZE; l -= DS_PGSIZE;
  789. X                                continue;
  790. X                        }
  791. X                        if (l > 0)
  792. X                                nefetch (ns, p, b, l);
  793. X                        break;
  794. X        }
  795. X    }
  796. X    /* don't forget checksum! */
  797. X    len -= sizeof(struct ether_header) + sizeof(long);
  798. X            
  799. X    neread(ns,(caddr_t)(ns->ns_pb), len);
  800. X}
  801. X
  802. X/*
  803. X * Pass a packet to the higher levels.
  804. X * We deal with the trailer protocol here.
  805. X */
  806. Xneread(ns, buf, len)
  807. X    register struct ne_softc *ns;
  808. X    char *buf;
  809. X    int len;
  810. X{
  811. X    register struct ether_header *eh;
  812. X        struct mbuf *m;
  813. X    int off, resid;
  814. X    register struct ifqueue *inq;
  815. X
  816. X    /*
  817. X     * Deal with trailer protocol: if type is trailer type
  818. X     * get true type from first 16-bit word past data.
  819. X     * Remember that type was trailer by setting off.
  820. X     */
  821. X    eh = (struct ether_header *)buf;
  822. X    eh->ether_type = ntohs((u_short)eh->ether_type);
  823. X#define    nedataaddr(eh, off, type)    ((type)(((caddr_t)((eh)+1)+(off))))
  824. X    if (eh->ether_type >= ETHERTYPE_TRAIL &&
  825. X        eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
  826. X        off = (eh->ether_type - ETHERTYPE_TRAIL) * 512;
  827. X        if (off >= ETHERMTU) return;        /* sanity */
  828. X        eh->ether_type = ntohs(*nedataaddr(eh, off, u_short *));
  829. X        resid = ntohs(*(nedataaddr(eh, off+2, u_short *)));
  830. X        if (off + resid > len) return;        /* sanity */
  831. X        len = off + resid;
  832. X    } else    off = 0;
  833. X
  834. X    if (len == 0) return;
  835. X
  836. X    /*
  837. X     * Pull packet off interface.  Off is nonzero if packet
  838. X     * has trailing header; neget will then force this header
  839. X     * information to be at the front, but we still have to drop
  840. X     * the type and length which are at the front of any trailer data.
  841. X     */
  842. X    m = neget(buf, len, off, &ns->ns_if);
  843. X    if (m == 0) return;
  844. X
  845. X    ether_input(&ns->ns_if, eh, m);
  846. X}
  847. X
  848. X/*
  849. X * Supporting routines
  850. X */
  851. X
  852. X/*
  853. X * Pull read data off a interface.
  854. X * Len is length of data, with local net header stripped.
  855. X * Off is non-zero if a trailer protocol was used, and
  856. X * gives the offset of the trailer information.
  857. X * We copy the trailer information and then all the normal
  858. X * data into mbufs.  When full cluster sized units are present
  859. X * we copy into clusters.
  860. X */
  861. Xstruct mbuf *
  862. Xneget(buf, totlen, off0, ifp)
  863. X    caddr_t buf;
  864. X    int totlen, off0;
  865. X    struct ifnet *ifp;
  866. X{
  867. X    struct mbuf *top, **mp, *m, *p;
  868. X    int off = off0, len;
  869. X    register caddr_t cp = buf;
  870. X    char *epkt;
  871. X
  872. X    buf += sizeof(struct ether_header);
  873. X    cp = buf;
  874. X    epkt = cp + totlen;
  875. X
  876. X
  877. X    if (off) {
  878. X        cp += off + 2 * sizeof(u_short);
  879. X        totlen -= 2 * sizeof(u_short);
  880. X    }
  881. X
  882. X    MGETHDR(m, M_DONTWAIT, MT_DATA);
  883. X    if (m == 0)
  884. X        return (0);
  885. X    m->m_pkthdr.rcvif = ifp;
  886. X    m->m_pkthdr.len = totlen;
  887. X    m->m_len = MHLEN;
  888. X
  889. X    top = 0;
  890. X    mp = ⊤
  891. X    while (totlen > 0) {
  892. X        if (top) {
  893. X            MGET(m, M_DONTWAIT, MT_DATA);
  894. X            if (m == 0) {
  895. X                m_freem(top);
  896. X                return (0);
  897. X            }
  898. X            m->m_len = MLEN;
  899. X        }
  900. X        len = min(totlen, epkt - cp);
  901. X        if (len >= MINCLSIZE) {
  902. X            MCLGET(m, M_DONTWAIT);
  903. X            if (m->m_flags & M_EXT)
  904. X                m->m_len = len = min(len, MCLBYTES);
  905. X            else
  906. X                len = m->m_len;
  907. X        } else {
  908. X            /*
  909. X             * Place initial small packet/header at end of mbuf.
  910. X             */
  911. X            if (len < m->m_len) {
  912. X                if (top == 0 && len + max_linkhdr <= m->m_len)
  913. X                    m->m_data += max_linkhdr;
  914. X                m->m_len = len;
  915. X            } else
  916. X                len = m->m_len;
  917. X        }
  918. X        bcopy(cp, mtod(m, caddr_t), (unsigned)len);
  919. X        cp += len;
  920. X        *mp = m;
  921. X        mp = &m->m_next;
  922. X        totlen -= len;
  923. X        if (cp == epkt)
  924. X            cp = buf;
  925. X    }
  926. X    return (top);
  927. X}
  928. X
  929. X/*
  930. X * Process an ioctl request.
  931. X */
  932. Xneioctl(ifp, cmd, data)
  933. X    register struct ifnet *ifp;
  934. X    int cmd;
  935. X    caddr_t data;
  936. X{
  937. X    register struct ifaddr *ifa = (struct ifaddr *)data;
  938. X    struct ne_softc *ns = &ne_softc[ifp->if_unit];
  939. X    struct ifreq *ifr = (struct ifreq *)data;
  940. X    int s = splimp(), error = 0;
  941. X
  942. X
  943. X    switch (cmd) {
  944. X
  945. X    case SIOCSIFADDR:
  946. X        ifp->if_flags |= IFF_UP;
  947. X
  948. X        switch (ifa->ifa_addr->sa_family) {
  949. X#ifdef INET
  950. X        case AF_INET:
  951. X            neinit(ifp->if_unit);    /* before arpwhohas */
  952. X            ((struct arpcom *)ifp)->ac_ipaddr =
  953. X                IA_SIN(ifa)->sin_addr;
  954. X            arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
  955. X            break;
  956. X#endif
  957. X#ifdef NS
  958. X        case AF_NS:
  959. X            {
  960. X            register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
  961. X
  962. X            if (ns_nullhost(*ina))
  963. X                ina->x_host = *(union ns_host *)(ns->ns_addr);
  964. X            else {
  965. X                /* 
  966. X                 * The manual says we can't change the address 
  967. X                 * while the receiver is armed,
  968. X                 * so reset everything
  969. X                 */
  970. X                ifp->if_flags &= ~IFF_RUNNING; 
  971. X                bcopy((caddr_t)ina->x_host.c_host,
  972. X                    (caddr_t)ns->ns_addr, sizeof(ns->ns_addr));
  973. X            }
  974. X            neinit(ifp->if_unit); /* does ne_setaddr() */
  975. X            break;
  976. X            }
  977. X#endif
  978. X        default:
  979. X            neinit(ifp->if_unit);
  980. X            break;
  981. X        }
  982. X        break;
  983. X
  984. X    case SIOCSIFFLAGS:
  985. X        if ((ifp->if_flags & IFF_UP) == 0 &&
  986. X            ifp->if_flags & IFF_RUNNING) {
  987. X            ifp->if_flags &= ~IFF_RUNNING;
  988. X            outb(ns->ns_iobase+ds_cmd,DSCM_STOP|DSCM_NODMA);
  989. X        } else if (ifp->if_flags & IFF_UP &&
  990. X            (ifp->if_flags & IFF_RUNNING) == 0)
  991. X            neinit(ifp->if_unit);
  992. X        break;
  993. X
  994. X#ifdef notdef
  995. X    case SIOCGHWADDR:
  996. X        bcopy((caddr_t)ns->ns_addr, (caddr_t) &ifr->ifr_data,
  997. X            sizeof(ns->ns_addr));
  998. X        break;
  999. X#endif
  1000. X
  1001. X    default:
  1002. X        error = EINVAL;
  1003. X    }
  1004. X    splx(s);
  1005. X    return (error);
  1006. X}
  1007. X#endif
  1008. SHAR_EOF
  1009. $TOUCH -am 0731160392 if_ne.c &&
  1010. chmod 0644 if_ne.c ||
  1011. echo "restore of if_ne.c failed"
  1012. set `wc -c if_ne.c`;Wc_c=$1
  1013. if test "$Wc_c" != "24098"; then
  1014.     echo original size 24098, current size $Wc_c
  1015. fi
  1016. # ============= if_nereg.h ==============
  1017. echo "x - extracting if_nereg.h (Text)"
  1018. sed 's/^X//' << 'SHAR_EOF' > if_nereg.h &&
  1019. X/*-
  1020. X * Copyright (c) 1991 The Regents of the University of California.
  1021. X * All rights reserved.
  1022. X *
  1023. X * Redistribution and use in source and binary forms, with or without
  1024. X * modification, are permitted provided that the following conditions
  1025. X * are met:
  1026. X * 1. Redistributions of source code must retain the above copyright
  1027. X *    notice, this list of conditions and the following disclaimer.
  1028. X * 2. Redistributions in binary form must reproduce the above copyright
  1029. X *    notice, this list of conditions and the following disclaimer in the
  1030. X *    documentation and/or other materials provided with the distribution.
  1031. X * 3. All advertising materials mentioning features or use of this software
  1032. X *    must display the following acknowledgement:
  1033. X *    This product includes software developed by the University of
  1034. X *    California, Berkeley and its contributors.
  1035. X * 4. Neither the name of the University nor the names of its contributors
  1036. X *    may be used to endorse or promote products derived from this software
  1037. X *    without specific prior written permission.
  1038. X *
  1039. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1040. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1041. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1042. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1043. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1044. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1045. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1046. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1047. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1048. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1049. X * SUCH DAMAGE.
  1050. X *
  1051. X *    @(#)if_nereg.h    7.1 (Berkeley) 5/9/91
  1052. X */
  1053. X
  1054. X/*
  1055. X * NE2000 Ethernet Card registers
  1056. X */
  1057. X
  1058. X/* The NE1000/NE2000 uses a DS8390 Ethernet controller in at the beginning of
  1059. X   its i/o space */
  1060. X#include "ic/ds8390.h"
  1061. X
  1062. X#define ne_data        0x10    /* Data Transfer port */
  1063. X#define ne_reset    0x1f    /* Card Reset port */
  1064. X
  1065. X#define        PKTSZ   0x600
  1066. X#define        TBUF(board)     (0x2000 * (board))      /* Starting location of Transmit Buffer */
  1067. X#define        RBUF(board)     (TBUF(board)+PKTSZ)     /* Starting location of Receive Buffer */
  1068. X#define        RBUFEND(board)  (0x4000 * (board))      /* Ending location of Tr ansmit Buffer */
  1069. X
  1070. X#define        TBUF1           TBUF(1)         /* Starting location of Transmit Buffer */
  1071. X#define        RBUF1           RBUF(1)         /* Starting location of Receive Buffer */
  1072. X#define        RBUFEND1        RBUFEND(1)      /* Ending location of Transmit Buffer */
  1073. X#define        TBUF2           TBUF(2)         /* Starting location of Transmit Buffer */
  1074. X#define        RBUF2           RBUF(2)         /* Starting location of Receive Buffer */
  1075. X#define        RBUFEND2        RBUFEND(2)      /* Ending location of Transmit Buffer */
  1076. X
  1077. SHAR_EOF
  1078. $TOUCH -am 0731160792 if_nereg.h &&
  1079. chmod 0644 if_nereg.h ||
  1080. echo "restore of if_nereg.h failed"
  1081. set `wc -c if_nereg.h`;Wc_c=$1
  1082. if test "$Wc_c" != "2982"; then
  1083.     echo original size 2982, current size $Wc_c
  1084. fi
  1085. exit 0
  1086.