source: rtems/bsps/shared/net/open_eth.c @ cb68253

5
Last change on this file since cb68253 was cb68253, checked in by Sebastian Huber <sebastian.huber@…>, on 09/07/18 at 04:19:02

network: Use kernel/user space header files

Add and use <machine/rtems-bsd-kernel-space.h> and
<machine/rtems-bsd-user-space.h> similar to the libbsd to avoid command
line defines and defines scattered throught the code base.

Simplify cpukit/libnetworking/Makefile.am.

Update #3375.

  • Property mode set to 100644
File size: 17.3 KB
Line 
1/*
2 *  RTEMS driver for Opencores Ethernet Controller
3 *
4 *  Weakly based on dec21140 rtems driver and open_eth linux driver
5 *  Written by Jiri Gaisler, Gaisler Research
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 *
11 */
12
13/*
14 *  This driver current only supports architectures with the old style
15 *  exception processing.  The following checks try to keep this
16 *  from being compiled on systems which can't support this driver.
17 *
18 *  NOTE: The i386, ARM, and PowerPC use a different interrupt API than
19 *        that used by this driver.
20 */
21
22#include <machine/rtems-bsd-kernel-space.h>
23
24#if defined(__i386__) || defined(__arm__) || defined(__PPC__)
25  #define OPENETH_NOT_SUPPORTED
26#endif
27
28#if !defined(OPENETH_NOT_SUPPORTED)
29#include <bsp.h>
30#include <rtems.h>
31
32#include <bsp.h>
33
34#include <inttypes.h>
35#include <stdlib.h>
36#include <stdio.h>
37#include <stdarg.h>
38#include <errno.h>
39
40#include <rtems/error.h>
41#include <rtems/rtems_bsdnet.h>
42#include <libchip/open_eth.h>
43
44#include <sys/param.h>
45#include <sys/mbuf.h>
46
47#include <sys/socket.h>
48#include <sys/sockio.h>
49#include <net/if.h>
50#include <netinet/in.h>
51#include <netinet/if_ether.h>
52
53#ifdef malloc
54#undef malloc
55#endif
56#ifdef free
57#undef free
58#endif
59
60extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
61
62 /*
63#define OPEN_ETH_DEBUG
64 */
65
66#ifdef CPU_U32_FIX
67extern void ipalign(struct mbuf *m);
68#endif
69
70/* message descriptor entry */
71struct MDTX
72{
73    char  *buf;
74};
75
76struct MDRX
77{
78    struct mbuf *m;
79};
80
81/*
82 * Number of OCs supported by this driver
83 */
84#define NOCDRIVER       1
85
86/*
87 * Receive buffer size -- Allow for a full ethernet packet including CRC
88 */
89#define RBUF_SIZE       1536
90
91#define ET_MINLEN 64            /* minimum message length */
92
93/*
94 * RTEMS event used by interrupt handler to signal driver tasks.
95 * This must not be any of the events used by the network task synchronization.
96 */
97#define INTERRUPT_EVENT RTEMS_EVENT_1
98
99/*
100 * RTEMS event used to start transmit daemon.
101 * This must not be the same as INTERRUPT_EVENT.
102 */
103#define START_TRANSMIT_EVENT    RTEMS_EVENT_2
104
105 /* event to send when tx buffers become available */
106#define OPEN_ETH_TX_WAIT_EVENT  RTEMS_EVENT_3
107
108 /* suspend when all TX descriptors exhausted */
109 /*
110#define OETH_SUSPEND_NOTXBUF
111 */
112
113#if (MCLBYTES < RBUF_SIZE)
114# error "Driver must have MCLBYTES > RBUF_SIZE"
115#endif
116
117/*
118 * Per-device data
119 */
120struct open_eth_softc
121{
122
123    struct arpcom arpcom;
124
125    oeth_regs *regs;
126
127    int acceptBroadcast;
128    rtems_id rxDaemonTid;
129    rtems_id txDaemonTid;
130
131    unsigned int tx_ptr;
132    unsigned int rx_ptr;
133    unsigned int txbufs;
134    unsigned int rxbufs;
135    struct MDTX *txdesc;
136    struct MDRX *rxdesc;
137    rtems_vector_number vector;
138    unsigned int en100MHz;
139
140    /*
141     * Statistics
142     */
143    unsigned long rxInterrupts;
144    unsigned long rxPackets;
145    unsigned long rxLengthError;
146    unsigned long rxNonOctet;
147    unsigned long rxBadCRC;
148    unsigned long rxOverrun;
149    unsigned long rxMiss;
150    unsigned long rxCollision;
151
152    unsigned long txInterrupts;
153    unsigned long txDeferred;
154    unsigned long txHeartbeat;
155    unsigned long txLateCollision;
156    unsigned long txRetryLimit;
157    unsigned long txUnderrun;
158    unsigned long txLostCarrier;
159    unsigned long txRawWait;
160};
161
162static struct open_eth_softc oc;
163
164/* OPEN_ETH interrupt handler */
165
166static rtems_isr
167open_eth_interrupt_handler (rtems_vector_number v)
168{
169    uint32_t status;
170
171    /* read and clear interrupt cause */
172
173    status = oc.regs->int_src;
174    oc.regs->int_src = status;
175
176    /* Frame received? */
177
178    if (status & (OETH_INT_RXF | OETH_INT_RXE))
179      {
180          oc.rxInterrupts++;
181          rtems_bsdnet_event_send (oc.rxDaemonTid, INTERRUPT_EVENT);
182      }
183#ifdef OETH_SUSPEND_NOTXBUF
184    if (status & (OETH_INT_MASK_TXB | OETH_INT_MASK_TXC | OETH_INT_MASK_TXE))
185      {
186          oc.txInterrupts++;
187          rtems_bsdnet_event_send (oc.txDaemonTid, OPEN_ETH_TX_WAIT_EVENT);
188      }
189#endif
190      /*
191#ifdef __leon__
192      LEON_Clear_interrupt(v-0x10);
193#endif
194      */
195}
196
197static uint32_t read_mii(uint32_t addr)
198{
199    while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
200    oc.regs->miiaddress = addr << 8;
201    oc.regs->miicommand = OETH_MIICOMMAND_RSTAT;
202    while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
203    if (!(oc.regs->miistatus & OETH_MIISTATUS_NVALID))
204        return(oc.regs->miirx_data);
205    else {
206        printf("open_eth: failed to read mii\n");
207        return (0);
208    }
209}
210
211static void write_mii(uint32_t addr, uint32_t data)
212{
213    while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
214    oc.regs->miiaddress = addr << 8;
215    oc.regs->miitx_data = data;
216    oc.regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
217    while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
218}
219/*
220 * Initialize the ethernet hardware
221 */
222static void
223open_eth_initialize_hardware (struct open_eth_softc *sc)
224{
225    struct mbuf *m;
226    int i;
227    int mii_cr = 0;
228
229    oeth_regs *regs;
230
231    regs = sc->regs;
232
233    /* Reset the controller.  */
234
235    regs->ctrlmoder = 0;
236    regs->moder = OETH_MODER_RST;       /* Reset ON */
237    regs->moder = 0;                    /* Reset OFF */
238
239    /* reset PHY and wait for complettion */
240    mii_cr = 0x3300;
241    if (!sc->en100MHz) mii_cr = 0;
242    write_mii(0, mii_cr | 0x8000);
243    while (read_mii(0) & 0x8000) {}
244    if (!sc->en100MHz) write_mii(0, 0);
245    mii_cr = read_mii(0);
246    printf("open_eth: driver attached, PHY config : 0x%04" PRIx32 "\n", read_mii(0));
247
248#ifdef OPEN_ETH_DEBUG
249    printf("mii_cr: %04x\n", mii_cr);
250    for (i=0;i<21;i++)
251      printf("mii_reg %2d : 0x%04x\n", i, read_mii(i));
252#endif
253
254    /* Setting TXBD base to sc->txbufs  */
255
256    regs->tx_bd_num = sc->txbufs;
257
258    /* Initialize rx/tx pointers.  */
259
260    sc->rx_ptr = 0;
261    sc->tx_ptr = 0;
262
263    /* Set min/max packet length */
264    regs->packet_len = 0x00400600;
265
266    /* Set IPGT register to recomended value */
267    regs->ipgt = 0x00000015;
268
269    /* Set IPGR1 register to recomended value */
270    regs->ipgr1 = 0x0000000c;
271
272    /* Set IPGR2 register to recomended value */
273    regs->ipgr2 = 0x00000012;
274
275    /* Set COLLCONF register to recomended value */
276    regs->collconf = 0x000f003f;
277
278    /* initialize TX descriptors */
279
280    sc->txdesc = calloc(sc->txbufs, sizeof(*sc->txdesc));
281    for (i = 0; i < sc->txbufs; i++)
282      {
283          sc->regs->xd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
284          sc->txdesc[i].buf = calloc(1, OETH_MAXBUF_LEN);
285#ifdef OPEN_ETH_DEBUG
286          printf("TXBUF: %08x\n", (int) sc->txdesc[i].buf);
287#endif
288      }
289    sc->regs->xd[sc->txbufs - 1].len_status |= OETH_TX_BD_WRAP;
290
291    /* allocate RX buffers */
292
293    sc->rxdesc = calloc(sc->rxbufs, sizeof(*sc->rxdesc));
294    for (i = 0; i < sc->rxbufs; i++)
295      {
296
297          MGETHDR (m, M_WAIT, MT_DATA);
298          MCLGET (m, M_WAIT);
299          m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
300          sc->rxdesc[i].m = m;
301          sc->regs->xd[i + sc->txbufs].addr = mtod (m, uint32_t*);
302          sc->regs->xd[i + sc->txbufs].len_status =
303              OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ;
304#ifdef OPEN_ETH_DEBUG
305          printf("RXBUF: %08x\n", (int) sc->rxdesc[i].m);
306#endif
307      }
308    sc->regs->xd[sc->rxbufs + sc->txbufs - 1].len_status |= OETH_RX_BD_WRAP;
309
310
311    /* set ethernet address.  */
312
313    regs->mac_addr1 = sc->arpcom.ac_enaddr[0] << 8 | sc->arpcom.ac_enaddr[1];
314
315    uint32_t mac_addr0;
316    mac_addr0 = sc->arpcom.ac_enaddr[2];
317    mac_addr0 <<= 8;
318    mac_addr0 |= sc->arpcom.ac_enaddr[3];
319    mac_addr0 <<= 8;
320    mac_addr0 |= sc->arpcom.ac_enaddr[4];
321    mac_addr0 <<= 8;
322    mac_addr0 |= sc->arpcom.ac_enaddr[5];
323   
324    regs->mac_addr0 = mac_addr0;
325
326    /* install interrupt vector */
327    set_vector (open_eth_interrupt_handler, sc->vector, 1);
328
329    /* clear all pending interrupts */
330
331    regs->int_src = 0xffffffff;
332
333    /* MAC mode register: PAD, IFG, CRCEN */
334
335    regs->moder = OETH_MODER_PAD | OETH_MODER_CRCEN | ((mii_cr & 0x100) << 2);
336
337    /* enable interrupts */
338
339    regs->int_mask = OETH_INT_MASK_RXF | OETH_INT_MASK_RXE | OETH_INT_MASK_RXC;
340
341#ifdef OETH_SUSPEND_NOTXBUF
342    regs->int_mask |= OETH_INT_MASK_TXB | OETH_INT_MASK_TXC | OETH_INT_MASK_TXE | OETH_INT_BUSY;*/
343    sc->regs->xd[(sc->txbufs - 1)/2].len_status |= OETH_TX_BD_IRQ;
344    sc->regs->xd[sc->txbufs - 1].len_status |= OETH_TX_BD_IRQ;
345#endif
346
347    regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
348}
349
350static void
351open_eth_rxDaemon (void *arg)
352{
353    struct ether_header *eh;
354    struct open_eth_softc *dp = (struct open_eth_softc *) &oc;
355    struct ifnet *ifp = &dp->arpcom.ac_if;
356    struct mbuf *m;
357    unsigned int len;
358    uint32_t len_status;
359    unsigned int bad;
360    rtems_event_set events;
361
362
363    for (;;)
364      {
365
366          rtems_bsdnet_event_receive (INTERRUPT_EVENT,
367                                      RTEMS_WAIT | RTEMS_EVENT_ANY,
368                                      RTEMS_NO_TIMEOUT, &events);
369#ifdef OPEN_ETH_DEBUG
370    printf ("r\n");
371#endif
372
373          while (!
374                 ((len_status =
375                   dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status) & OETH_RX_BD_EMPTY))
376            {
377                bad = 0;
378                if (len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT))
379                  {
380                      dp->rxLengthError++;
381                      bad = 1;
382                  }
383                if (len_status & OETH_RX_BD_DRIBBLE)
384                  {
385                      dp->rxNonOctet++;
386                      bad = 1;
387                  }
388                if (len_status & OETH_RX_BD_CRCERR)
389                  {
390                      dp->rxBadCRC++;
391                      bad = 1;
392                  }
393                if (len_status & OETH_RX_BD_OVERRUN)
394                  {
395                      dp->rxOverrun++;
396                      bad = 1;
397                  }
398                if (len_status & OETH_RX_BD_MISS)
399                  {
400                      dp->rxMiss++;
401                      bad = 1;
402                  }
403                if (len_status & OETH_RX_BD_LATECOL)
404                  {
405                      dp->rxCollision++;
406                      bad = 1;
407                  }
408
409                if (!bad)
410                  {
411                      /* pass on the packet in the receive buffer */
412                      len = len_status >> 16;
413                      m = (struct mbuf *) (dp->rxdesc[dp->rx_ptr].m);
414                      m->m_len = m->m_pkthdr.len =
415                          len - sizeof (struct ether_header);
416                      eh = mtod (m, struct ether_header *);
417                      m->m_data += sizeof (struct ether_header);
418#ifdef CPU_U32_FIX
419                      ipalign(m);       /* Align packet on 32-bit boundary */
420#endif
421
422                      ether_input (ifp, eh, m);
423
424                      /* get a new mbuf */
425                      MGETHDR (m, M_WAIT, MT_DATA);
426                      MCLGET (m, M_WAIT);
427                      m->m_pkthdr.rcvif = ifp;
428                      dp->rxdesc[dp->rx_ptr].m = m;
429                      dp->regs->xd[dp->rx_ptr + dp->txbufs].addr =
430                          (uint32_t*) mtod (m, void *);
431                      dp->rxPackets++;
432                  }
433
434                dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status =
435                  (dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status &
436                    ~OETH_TX_BD_STATS) | OETH_TX_BD_READY;
437                dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
438            }
439      }
440}
441
442static int inside = 0;
443static void
444sendpacket (struct ifnet *ifp, struct mbuf *m)
445{
446    struct open_eth_softc *dp = ifp->if_softc;
447    unsigned char *temp;
448    struct mbuf *n;
449    uint32_t len, len_status;
450
451    if (inside) printf ("error: sendpacket re-entered!!\n");
452    inside = 1;
453    /*
454     * Waiting for Transmitter ready
455     */
456    n = m;
457
458    while (dp->regs->xd[dp->tx_ptr].len_status & OETH_TX_BD_READY)
459      {
460#ifdef OETH_SUSPEND_NOTXBUF
461          rtems_event_set events;
462          rtems_bsdnet_event_receive (OPEN_ETH_TX_WAIT_EVENT,
463                                      RTEMS_WAIT | RTEMS_EVENT_ANY,
464                                      RTEMS_MILLISECONDS_TO_TICKS(500), &events);
465#endif
466      }
467
468    len = 0;
469    temp = (unsigned char *) dp->txdesc[dp->tx_ptr].buf;
470    dp->regs->xd[dp->tx_ptr].addr = (uint32_t*) temp;
471
472#ifdef OPEN_ETH_DEBUG
473    printf("TXD: 0x%08x\n", (int) m->m_data);
474#endif
475    for (;;)
476        {
477#ifdef OPEN_ETH_DEBUG
478          int i;
479          printf("MBUF: 0x%08x : ", (int) m->m_data);
480          for (i=0;i<m->m_len;i++)
481            printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
482          printf("\n");
483#endif
484          len += m->m_len;
485          if (len <= RBUF_SIZE)
486            memcpy ((void *) temp, (char *) m->m_data, m->m_len);
487          temp += m->m_len;
488          if ((m = m->m_next) == NULL)
489              break;
490        }
491
492    m_freem (n);
493
494    /* don't send long packets */
495
496    if (len <= RBUF_SIZE) {
497
498     /* Clear all of the status flags.  */
499     len_status = dp->regs->xd[dp->tx_ptr].len_status & ~OETH_TX_BD_STATS;
500
501     /* If the frame is short, tell CPM to pad it.  */
502     if (len < ET_MINLEN) {
503        len_status |= OETH_TX_BD_PAD;
504        len = ET_MINLEN;
505     }
506     else
507        len_status &= ~OETH_TX_BD_PAD;
508
509      /* write buffer descriptor length and status */
510      len_status &= 0x0000ffff;
511      len_status |= (len << 16) | (OETH_TX_BD_READY | OETH_TX_BD_CRC);
512      dp->regs->xd[dp->tx_ptr].len_status = len_status;
513      dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
514
515    }
516    inside = 0;
517}
518
519/*
520 * Driver transmit daemon
521 */
522static void
523open_eth_txDaemon (void *arg)
524{
525    struct open_eth_softc *sc = (struct open_eth_softc *) arg;
526    struct ifnet *ifp = &sc->arpcom.ac_if;
527    struct mbuf *m;
528    rtems_event_set events;
529
530    for (;;)
531      {
532          /*
533           * Wait for packet
534           */
535
536          rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
537                                      RTEMS_EVENT_ANY | RTEMS_WAIT,
538                                      RTEMS_NO_TIMEOUT, &events);
539#ifdef OPEN_ETH_DEBUG
540    printf ("t\n");
541#endif
542
543          /*
544           * Send packets till queue is empty
545           */
546          for (;;)
547            {
548                /*
549                 * Get the next mbuf chain to transmit.
550                 */
551                IF_DEQUEUE (&ifp->if_snd, m);
552                if (!m)
553                    break;
554                sendpacket (ifp, m);
555            }
556          ifp->if_flags &= ~IFF_OACTIVE;
557      }
558}
559
560
561static void
562open_eth_start (struct ifnet *ifp)
563{
564    struct open_eth_softc *sc = ifp->if_softc;
565
566    rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
567    ifp->if_flags |= IFF_OACTIVE;
568}
569
570/*
571 * Initialize and start the device
572 */
573static void
574open_eth_init (void *arg)
575{
576    struct open_eth_softc *sc = arg;
577    struct ifnet *ifp = &sc->arpcom.ac_if;
578
579    if (sc->txDaemonTid == 0)
580      {
581
582          /*
583           * Set up OPEN_ETH hardware
584           */
585          open_eth_initialize_hardware (sc);
586
587          /*
588           * Start driver tasks
589           */
590          sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
591                                                  open_eth_rxDaemon, sc);
592          sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
593                                                  open_eth_txDaemon, sc);
594      }
595
596    /*
597     * Tell the world that we're running.
598     */
599    ifp->if_flags |= IFF_RUNNING;
600
601}
602
603/*
604 * Stop the device
605 */
606static void
607open_eth_stop (struct open_eth_softc *sc)
608{
609    struct ifnet *ifp = &sc->arpcom.ac_if;
610
611    ifp->if_flags &= ~IFF_RUNNING;
612
613    sc->regs->moder = 0;                /* RX/TX OFF */
614    sc->regs->moder = OETH_MODER_RST;   /* Reset ON */
615    sc->regs->moder = 0;                /* Reset OFF */
616}
617
618
619/*
620 * Show interface statistics
621 */
622static void
623open_eth_stats (struct open_eth_softc *sc)
624{
625    printf ("         Rx Packets:%-8lu", sc->rxPackets);
626    printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
627    printf ("          Length:%-8lu", sc->rxLengthError);
628    printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
629    printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
630    printf ("         Overrun:%-8lu", sc->rxOverrun);
631    printf ("            Miss:%-8lu", sc->rxMiss);
632    printf ("       Collision:%-8lu\n", sc->rxCollision);
633
634    printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
635    printf ("        Deferred:%-8lu", sc->txDeferred);
636    printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
637    printf ("         No Carrier:%-8lu", sc->txLostCarrier);
638    printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
639    printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
640    printf ("           Underrun:%-8lu", sc->txUnderrun);
641    printf (" Raw output wait:%-8lu\n", sc->txRawWait);
642}
643
644/*
645 * Driver ioctl handler
646 */
647static int
648open_eth_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
649{
650    struct open_eth_softc *sc = ifp->if_softc;
651    int error = 0;
652
653    switch (command)
654      {
655      case SIOCGIFADDR:
656      case SIOCSIFADDR:
657          ether_ioctl (ifp, command, data);
658          break;
659
660      case SIOCSIFFLAGS:
661          switch (ifp->if_flags & (IFF_UP | IFF_RUNNING))
662            {
663            case IFF_RUNNING:
664                open_eth_stop (sc);
665                break;
666
667            case IFF_UP:
668                open_eth_init (sc);
669                break;
670
671            case IFF_UP | IFF_RUNNING:
672                open_eth_stop (sc);
673                open_eth_init (sc);
674                break;
675
676            default:
677                break;
678            }
679          break;
680
681      case SIO_RTEMS_SHOW_STATS:
682          open_eth_stats (sc);
683          break;
684
685          /*
686           * FIXME: All sorts of multicast commands need to be added here!
687           */
688      default:
689          error = EINVAL;
690          break;
691      }
692
693    return error;
694}
695
696/*
697 * Attach an OPEN_ETH driver to the system
698 */
699int
700rtems_open_eth_driver_attach (struct rtems_bsdnet_ifconfig *config,
701                              open_eth_configuration_t * chip)
702{
703    struct open_eth_softc *sc;
704    struct ifnet *ifp;
705    int mtu;
706    int unitNumber;
707    char *unitName;
708
709      /* parse driver name */
710    if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
711        return 0;
712
713    sc = &oc;
714    ifp = &sc->arpcom.ac_if;
715    memset (sc, 0, sizeof (*sc));
716
717    if (config->hardware_address)
718      {
719          memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
720                  ETHER_ADDR_LEN);
721      }
722    else
723      {
724          memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
725      }
726
727    if (config->mtu)
728        mtu = config->mtu;
729    else
730        mtu = ETHERMTU;
731
732    sc->acceptBroadcast = !config->ignore_broadcast;
733    sc->regs = chip->base_address;
734    sc->vector = chip->vector;
735    sc->txbufs = chip->txd_count;
736    sc->rxbufs = chip->rxd_count;
737    sc->en100MHz = chip->en100MHz;
738
739
740    /*
741     * Set up network interface values
742     */
743    ifp->if_softc = sc;
744    ifp->if_unit = unitNumber;
745    ifp->if_name = unitName;
746    ifp->if_mtu = mtu;
747    ifp->if_init = open_eth_init;
748    ifp->if_ioctl = open_eth_ioctl;
749    ifp->if_start = open_eth_start;
750    ifp->if_output = ether_output;
751    ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
752    if (ifp->if_snd.ifq_maxlen == 0)
753        ifp->if_snd.ifq_maxlen = ifqmaxlen;
754
755    /*
756     * Attach the interface
757     */
758    if_attach (ifp);
759    ether_ifattach (ifp);
760
761#ifdef OPEN_ETH_DEBUG
762    printf ("OPEN_ETH : driver has been attached\n");
763#endif
764    return 1;
765};
766
767#endif  /* OPENETH_NOT_SUPPORTED */
Note: See TracBrowser for help on using the repository browser.