Changeset d9d75fc in rtems


Ignore:
Timestamp:
Aug 31, 1998, 11:06:50 PM (21 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
4cf89a8
Parents:
b285860
Message:

Patch from Emmanuel Raguet <raguet@…>:

I have reworked the ethernet driver for the BSP pc386 and
here is the patch to apply.

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/libcsupport/src/newlibc.c

    rb285860 rd9d75fc  
    354354/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
    355355#if !defined(RTEMS_UNIX) && !defined(_AM29K)
    356 #if !defined(pc386)
    357356void _exit(int status)
    358357{
     
    360359    rtems_shutdown_executive(status);
    361360}
    362 #endif
    363 
    364361#else
    365362
  • c/src/exec/libnetworking/rtems/rtems_bsdnet.h

    rb285860 rd9d75fc  
    6969        int             rbuf_count;
    7070        int             xbuf_count;
     71
     72  /*
     73   * For external ethernet controller board the following
     74   * parameters are needed
     75   */
     76  unsigned int                  port;   /* port of the board */
     77  unsigned int                  irno;   /* irq of the board */
     78  unsigned int                  bpar;   /* memory of the board */
     79
    7180};
    7281
  • c/src/lib/libbsp/i386/pc386/Makefile.in

    rb285860 rd9d75fc  
    1212include $(RTEMS_ROOT)/make/directory.cfg
    1313
    14 # # We only build the Network library if HAS_NETWORKING was defined
    15 # NETWORK_yes_V = network
    16 # NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
     14# We only build the Network library if HAS_NETWORKING was defined
     15NETWORK_yes_V = network
     16NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
    1717
    1818# wrapup is the one that actually builds and installs the library
  • c/src/lib/libbsp/i386/pc386/include/Makefile.in

    rb285860 rd9d75fc  
    1010
    1111# This driver needs to be reworked for the BSD stack.
    12 # # We only install wd80x3.h if HAS_NETWORKING was defined
    13 # WD80X3_yes_V = $(srcdir)/wd80x3.h
    14 # WD80X3 = $(WD80X3_$(HAS_NETWORKING)_V)
     12# We only install wd80x3.h if HAS_NETWORKING was defined
     13WD80X3_yes_V = $(srcdir)/wd80x3.h
     14WD80X3 = $(WD80X3_$(HAS_NETWORKING)_V)
    1515
    1616H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h  $(srcdir)/crt.h \
  • c/src/lib/libbsp/i386/pc386/network/Makefile.in

    rb285860 rd9d75fc  
    2828#
    2929
    30 DEFINES  +=
     30DEFINES  += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
     31     -DDIAGNOSTIC -DBOOTP_COMPAT
    3132CPPFLAGS +=
    3233CFLAGS   +=
  • c/src/lib/libbsp/i386/pc386/network/network.c

    rb285860 rd9d75fc  
    11/*
    2  * XXX This driver needs to be reworked to support the new BSD stack
     2 * RTEMS driver for M68360 WD1 Ethernet
    33 *
    4  * RTEMS/KA9Q driver for WD8003 Ethernet Controller
    5  *
     4 * W. Eric Norum
     5 * Saskatchewan Accelerator Laboratory
     6 * University of Saskatchewan
     7 * Saskatoon, Saskatchewan, CANADA
     8 * eric@skatter.usask.ca
    69 *
    710 *  $Id$
    811 */
     12
    913#include <bsp.h>
    1014#include <wd80x3.h>
     15
     16#include <stdio.h>
     17#include <stdarg.h>
    1118#include <rtems/error.h>
    12 #include <ka9q/rtems_ka9q.h>
    13 #include <ka9q/global.h>
    14 #include <ka9q/enet.h>
    15 #include <ka9q/iface.h>
    16 #include <ka9q/netuser.h>
    17 #include <ka9q/trace.h>
    18 #include <ka9q/commands.h>
    19 #include <ka9q/domain.h>
     19#include <rtems/rtems_bsdnet.h>
     20
     21#include <sys/param.h>
     22#include <sys/mbuf.h>
     23#include <sys/socket.h>
     24#include <sys/sockio.h>
     25
     26#include <net/if.h>
     27
     28#include <netinet/in.h>
     29#include <netinet/if_ether.h>
     30
    2031#include <irq.h>
    2132
     
    2334
    2435/*
    25  * Number of SCCs supported by this driver
    26  */
    27 #define NSCCDRIVER      1
     36 * Number of WDs supported by this driver
     37 */
     38#define NWDDRIVER       1
    2839
    2940/*
     
    3243 * since a single frame often uses four or more buffer descriptors.
    3344 */
    34 
    3545#define RX_BUF_COUNT     15
    3646#define TX_BUF_COUNT     4
     
    3848
    3949/*
    40  * RTEMS event used by interrupt handler to signal daemons.
    41  * This must *not* be the same event used by the KA9Q task synchronization.
     50 * RTEMS event used by interrupt handler to signal driver tasks.
     51 * This must not be any of the events used by the network task synchronization.
    4252 */
    4353#define INTERRUPT_EVENT RTEMS_EVENT_1
    4454
    4555/*
    46  * Receive buffer size -- Allow for a full ethernet packet plus a pointer
    47  */
    48 #define RBUF_SIZE       (1520 + sizeof (struct iface *))
    49 
    50 /*
    51  * Hardware-specific storage
    52  */
    53 typedef struct  {
     56 * RTEMS event used to start transmit daemon.
     57 * This must not be the same as INTERRUPT_EVENT.
     58 */
     59#define START_TRANSMIT_EVENT    RTEMS_EVENT_2
     60
     61/*
     62 * Receive buffer size -- Allow for a full ethernet packet including CRC
     63 */
     64#define RBUF_SIZE       1520
     65
     66#if (MCLBYTES < RBUF_SIZE)
     67# error "Driver must have MCLBYTES > RBUF_SIZE"
     68#endif
     69
     70/*
     71 * Per-device data
     72 */
     73struct wd_softc {
     74  struct arpcom                 arpcom;
    5475  rtems_irq_connect_data        irqInfo;
    5576  struct mbuf                   **rxMbuf;
    5677  struct mbuf                   **txMbuf;
    57   unsigned int                  port;
    58   unsigned char                 *base;
    59   unsigned long                 bpar;
     78  int                           acceptBroadcast;
    6079  int                           rxBdCount;
    6180  int                           txBdCount;
     
    6382  int                           txBdTail;
    6483  int                           txBdActiveCount;
    65   struct iface                  *iface;
    66   rtems_id                      txWaitTid;
     84  rtems_id                      rxDaemonTid;
     85  rtems_id                      txDaemonTid;
     86
     87  unsigned int                  port;
     88  unsigned char                 *base;
     89  unsigned long                 bpar;
    6790 
    6891  /*
    6992   * Statistics
    7093   */
    71   unsigned long                 rxInterrupts;
    72   unsigned long                 rxNotFirst;
    73   unsigned long                 rxNotLast;
    74   unsigned long                 rxGiant;
    75   unsigned long                 rxNonOctet;
    76   unsigned long                 rxRunt;
    77   unsigned long                 rxBadCRC;
    78   unsigned long                 rxOverrun;
    79   unsigned long                 rxCollision;
    80  
    81   unsigned long                 txInterrupts;
    82   unsigned long                 txDeferred;
    83   unsigned long                 txHeartbeat;
    84   unsigned long                 txLateCollision;
    85   unsigned long                 txRetryLimit;
    86   unsigned long                 txUnderrun;
    87   unsigned long                 txLostCarrier;
    88   unsigned long                 txRawWait;
    89 }wd80x3EnetDriver;
     94  unsigned long rxInterrupts;
     95  unsigned long rxNotFirst;
     96  unsigned long rxNotLast;
     97  unsigned long rxGiant;
     98  unsigned long rxNonOctet;
     99  unsigned long rxRunt;
     100  unsigned long rxBadCRC;
     101  unsigned long rxOverrun;
     102  unsigned long rxCollision;
     103 
     104  unsigned long txInterrupts;
     105  unsigned long txDeferred;
     106  unsigned long txHeartbeat;
     107  unsigned long txLateCollision;
     108  unsigned long txRetryLimit;
     109  unsigned long txUnderrun;
     110  unsigned long txLostCarrier;
     111  unsigned long txRawWait;
     112};
    90113
    91114#define RO 0x10
     
    97120
    98121static unsigned long loopc;
    99 
    100 static wd80x3EnetDriver wd8003EnetDriver[NSCCDRIVER];
    101 
    102 /*
    103  * WD8003 interrupt handler. The code as it is cleraly showes that
    104  * only one driver is connected. In order to change this a table
    105  * making the correspondance between the current irq number and
    106  * the corresponding wd8003EnetDriver structure could be used...
    107  */
    108 static void wd8003Enet_interrupt_handler ()
     122static volatile unsigned long overrun;
     123static volatile unsigned long resend;
     124static struct wd_softc wd_softc[NWDDRIVER];
     125
     126/*
     127 * WD interrupt handler
     128 */
     129static rtems_isr
     130wd8003Enet_interrupt_handler (rtems_vector_number v)
    109131{
    110132  unsigned int tport, nowTicks, bootTicks;
    111133  unsigned char status, status2;
    112134
    113   struct iface *iface = (struct iface *)(wd8003EnetDriver[0].iface);
    114   wd80x3EnetDriver *dp = (wd80x3EnetDriver *)&wd8003EnetDriver[0];
    115   struct mbuf *bp;
    116   unsigned int i2;
    117   unsigned int len;
    118   unsigned char start, next, current;
    119   char *shp, *temp;
    120 
    121   tport = wd8003EnetDriver[0].port ;
    122 
    123   /*
    124    * Drop chips interrupt
    125    */
     135  tport = wd_softc[0].port ;
     136
     137  /*
     138   * Read status
     139   */
     140  inport_byte(tport+ISR, status);
    126141  outport_byte(tport+IMR, 0x00);
    127 
    128   /*
    129    * Read status
    130    */
    131   inport_byte(tport+ISR, status);
    132142
    133143  /*
     
    146156    outport_byte(tport+TCR, MSK_LOOP);          /* loopback mode */
    147157    outport_byte(tport+CMDR, MSK_STA + MSK_RD2);        /* start */
     158    overrun = 1 ;
     159    if ((status & (MSK_PTX+MSK_TXE)) == 0)
     160        resend = 1;
    148161  }
    149  
     162
    150163  /*
    151164   * Frame received?
    152    */       
    153   while (status & (MSK_PRX+MSK_RXE)) {
     165   */
     166  if (status & (MSK_PRX+MSK_RXE)) {
    154167    outport_byte(tport+ISR, status & (MSK_PRX+MSK_RXE));
    155     inport_byte(tport+BNRY, start);
    156     start += 1;
    157     shp = dp->base + 1 + (SHAPAGE * start);
    158     next = *shp++;
    159     len = *((short *)shp)++ - 4;
    160     if (start >= OUTPAGE || next >= OUTPAGE)
    161       break;
    162     bp = ambufw (RBUF_SIZE);
    163     bp->data += sizeof (struct iface *);
    164     temp = bp->data;
    165     bp->cnt = len;
    166 
    167     if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){
    168       memcpy(temp, shp, i2);
    169       len -= i2;
    170       temp += i2;
    171       shp = dp->base;
    172     }
    173     memcpy(temp, shp, len);
    174 
    175     net_route (iface, &bp);
    176     outport_byte(tport+BNRY, next-1);
    177     outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
    178     inport_byte(tport+CURR, current);
    179     outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
    180     if (current == next)
    181       break;
     168    wd_softc[0].rxInterrupts++;
     169    rtems_event_send (wd_softc[0].rxDaemonTid, INTERRUPT_EVENT);   
    182170  }
    183171
    184   /*
    185    * Ring overwrite
    186    */
    187   if (status & MSK_OVW) {     
    188     outport_byte(tport+ISR, MSK_OVW);   /* reset IR */
    189     outport_byte(tport+TCR, 0);         /* out of loopback */
    190     if ((status & (MSK_PTX+MSK_TXE)) == 0)
    191       outport_byte(tport+CMDR, MSK_TXP + MSK_RD2);      /* resend */
    192   }
    193 
    194   /*
    195    * Enable chip interrupts
    196    */
    197   outport_byte(tport+IMR, 0x15);
    198172}
    199173
     
    215189 */
    216190static void
    217 wd8003Enet_initialize_hardware (wd80x3EnetDriver *dp, int broadcastFlag)
     191wd8003Enet_initialize_hardware (struct wd_softc *sc)
    218192{
    219193  int  i1, ultra;
    220194  char cc1, cc2;
    221195  unsigned char  temp;
    222   rtems_status_code sc;
     196  rtems_status_code st;
    223197  unsigned int tport;
    224 
    225   tport = dp->port;
     198  unsigned char *hwaddr;
     199
     200  tport = sc->port;
    226201
    227202  /* address from board ROM */
     
    229204  outport_byte(tport+0x04, temp & 0x7f);
    230205
     206  hwaddr = sc->arpcom.ac_enaddr;
    231207  for (i1=cc2=0; i1<8; i1++) {
    232208    inport_byte(tport + ADDROM + i1, cc1);
    233209    cc2 += cc1;
    234210    if (i1 < 6)
    235       dp->iface->hwaddr[i1] = cc1;
     211      hwaddr[i1] = cc1;
    236212  }
    237213 
     
    240216  outport_byte(tport+W83CREG, MSK_RESET);       /* reset board, set buffer */
    241217  outport_byte(tport+W83CREG, 0);
    242   outport_byte(tport+W83CREG, MSK_ENASH + (int)((dp->bpar>>13)&0x3f));
     218  outport_byte(tport+W83CREG, MSK_ENASH + (int)((sc->bpar>>13)&0x3f));
    243219
    244220  outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
     
    259235  outport_byte(tport+BNRY, -1);                 /* init BNRY */
    260236  outport_byte(tport+ISR, -1);                  /* clear IR's */
    261   outport_byte(tport+IMR, 0x15);                /* 0x17 enable interrupt */
     237  outport_byte(tport+IMR, 0x15);                /* enable interrupt */
    262238
    263239  outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
    264240
    265241  for (i1=0; i1<6; i1++)                        /* initial physical addr */
    266     outport_byte(tport+PAR+i1, dp->iface->hwaddr[i1]);
     242    outport_byte(tport+PAR+i1, hwaddr[i1]);
    267243
    268244  for (i1=0; i1<MARsize; i1++)                  /* clear multicast */
     
    284260   * Set up interrupts
    285261   */
    286   dp->irqInfo.hdl = wd8003Enet_interrupt_handler;
    287   dp->irqInfo.on  = nopOn;
    288   dp->irqInfo.off = nopOn;
    289   dp->irqInfo.isOn = wdIsOn;
    290  
    291   sc = pc386_install_rtems_irq_handler (&dp->irqInfo);
    292   if (!sc)
     262  sc->irqInfo.hdl = wd8003Enet_interrupt_handler;
     263  sc->irqInfo.on  = nopOn;
     264  sc->irqInfo.off = nopOn;
     265  sc->irqInfo.isOn = wdIsOn;
     266 
     267  st = pc386_install_rtems_irq_handler (&sc->irqInfo);
     268  if (!st)
    293269    rtems_panic ("Can't attach WD interrupt handler for irq %d\n",
    294                   dp->irqInfo.name);
    295 }
    296 
    297 
    298 /*
    299  * Send raw packet (caller provides header).
    300  * This code runs in the context of the interface transmit
    301  * task or in the context of the network task.
    302  */
    303 static int
    304 wd8003Enet_raw (struct iface *iface, struct mbuf **bpp)
    305 {
    306   wd80x3EnetDriver *dp = &wd8003EnetDriver[iface->dev];
    307   struct mbuf *bp;
    308   unsigned int len, tport;
    309   char *shp;
    310 
    311   tport = dp->port;
    312  
    313   /*
    314    * Fill in some logging data
    315    */
    316   iface->rawsndcnt++;
    317   iface->lastsent = secclock ();
    318   dump (iface, IF_TRACE_OUT, *bpp);
    319  
    320   /*
    321    * It would not do to have two tasks active in the transmit
    322    * loop at the same time.
    323    * The blocking is simple-minded since the odds of two tasks
    324    * simultaneously attempting to use this code are low.  The only
    325    * way that two tasks can try to run here is:
    326    *    1) Task A enters this code and ends up having to
    327    *       wait for a transmit buffer descriptor.
    328    *    2) Task B  gains control and tries to transmit a packet.
    329    * The RTEMS/KA9Q scheduling semaphore ensures that there
    330    * are no race conditions associated with manipulating the
    331    * txWaitTid variable.
    332    */
    333 
    334   if (dp->txWaitTid) {
    335     dp->txRawWait++;
    336     while (dp->txWaitTid)
    337       rtems_ka9q_ppause (10);
    338   }
    339  
    340   if (dp->txWaitTid == 0)               
    341     rtems_task_ident (0, 0, &dp->txWaitTid);
    342 
    343   bp = *bpp;
     270                  sc->irqInfo.name);
     271}
     272
     273static void
     274wd_rxDaemon (void *arg)
     275{
     276  unsigned int tport;
     277  struct ether_header *eh;
     278  struct wd_softc *dp = (struct wd_softc *)&wd_softc[0];
     279  struct ifnet *ifp = &dp->arpcom.ac_if;
     280  struct mbuf *m;
     281  unsigned int i2;
     282  unsigned int len;
     283  volatile unsigned char start, next, current;
     284  char *shp, *temp;
     285  rtems_event_set events;
     286
     287  tport = wd_softc[0].port ;
     288
     289  for (;;){
     290
     291
     292    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
     293                                RTEMS_WAIT|RTEMS_EVENT_ANY,
     294                                RTEMS_NO_TIMEOUT,
     295                                &events);
     296
     297    for (;;){
     298      inport_byte(tport+BNRY, start);
     299
     300      outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
     301      inport_byte(tport+CURR, current);
     302      outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
     303
     304      start += 1;
     305      if (start >= OUTPAGE){
     306        start = 0;
     307      }
     308
     309      if (current == start)
     310        break;
     311     
     312      shp = dp->base + 1 + (SHAPAGE * start);
     313      next = *shp++;
     314      len = *((short *)shp)++ - 4;
     315
     316      if (next >= OUTPAGE){
     317        next = 0;
     318      }
     319     
     320      MGETHDR (m, M_WAIT, MT_DATA);
     321      MCLGET (m, M_WAIT);
     322      m->m_pkthdr.rcvif = ifp;
     323     
     324      temp = m->m_data;
     325      m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
     326     
     327      if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){
     328        memcpy(temp, shp, i2);
     329        len -= i2;
     330        temp += i2;
     331        shp = dp->base;
     332      }
     333      memcpy(temp, shp, len);
     334     
     335      eh = mtod (m, struct ether_header *);
     336      m->m_data += sizeof(struct ether_header);
     337      ether_input (ifp, eh, m);
     338     
     339      outport_byte(tport+BNRY, next-1);
     340    }
     341   
     342  /*
     343   * Ring overwrite
     344   */
     345    if (overrun){     
     346      outport_byte(tport+ISR, MSK_OVW);         /* reset IR */
     347      outport_byte(tport+TCR, 0);               /* out of loopback */
     348      if (resend  == 1)
     349        outport_byte(tport+CMDR, MSK_TXP + MSK_RD2);    /* resend */
     350      resend = 0;
     351      overrun = 0;
     352    }
     353   
     354    outport_byte(tport+IMR, 0x15);  /* re-enable IT rx */
     355  }     
     356}
     357
     358static void
     359sendpacket (struct ifnet *ifp, struct mbuf *m)
     360{
     361        struct wd_softc *dp = ifp->if_softc;
     362        struct mbuf *n;
     363        unsigned int len, tport;
     364        char *shp;
     365
     366        tport = dp->port;
     367
     368
     369
    344370  len = 0;
    345371  shp = dp->base + (SHAPAGE * OUTPAGE);
    346372
    347   /*rtems_interrupt_disable(level);*/
     373  n = m;
    348374 
    349375  for (;;){
    350     len += bp->cnt;
    351     memcpy(shp, (char *)bp->data, bp->cnt);
    352     shp += bp->cnt ;
    353     if ((bp = bp->next) == NULL)
     376    len += m->m_len;
     377    memcpy(shp, (char *)m->m_data, m->m_len);
     378    shp += m->m_len ;
     379    if ((m = m->m_next) == NULL)
    354380      break;
    355381  }
    356382
    357   free_p(bpp);
    358 
     383  m_freem(n);
     384 
    359385  if (len < ET_MINLEN) len = ET_MINLEN;
    360386  outport_byte(tport+TBCR0, len);
     
    362388  outport_byte(tport+TPSR, OUTPAGE);
    363389  outport_byte(tport+CMDR, MSK_TXP + MSK_RD2);
    364 
    365   /*
    366    * Show that we've finished with the packet
    367    */
    368   dp->txWaitTid = 0;
    369   return 0;
    370  
    371 }
    372 
    373 
    374 /*
    375  * Shut down the interface
    376  * FIXME: This is a pretty simple-minded routine.  It doesn't worry
    377  * about cleaning up mbufs, shutting down daemons, etc.
    378  */
    379 static int
    380 wd8003Enet_stop (struct iface *iface)
     390}
     391
     392/*
     393 * Driver transmit daemon
     394 */
     395void
     396wd_txDaemon (void *arg)
     397{
     398        struct wd_softc *sc = (struct wd_softc *)arg;
     399        struct ifnet *ifp = &sc->arpcom.ac_if;
     400        struct mbuf *m;
     401        rtems_event_set events;
     402
     403        for (;;) {
     404                /*
     405                 * Wait for packet
     406                 */
     407                rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
     408
     409                /*
     410                 * Send packets till queue is empty
     411                 */
     412                for (;;) {
     413                        /*
     414                         * Get the next mbuf chain to transmit.
     415                         */
     416                        IF_DEQUEUE(&ifp->if_snd, m);
     417                        if (!m)
     418                                break;
     419                        sendpacket (ifp, m);
     420                }
     421                ifp->if_flags &= ~IFF_OACTIVE;
     422        }
     423}
     424
     425/*
     426 * Send packet (caller provides header).
     427 */
     428static void
     429wd_start (struct ifnet *ifp)
     430{
     431        struct wd_softc *sc = ifp->if_softc;
     432
     433        rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
     434        ifp->if_flags |= IFF_OACTIVE;
     435}
     436
     437/*
     438 * Initialize and start the device
     439 */
     440static void
     441wd_init (void *arg)
     442{
     443  struct wd_softc *sc = arg;
     444  struct ifnet *ifp = &sc->arpcom.ac_if;
     445
     446  if (sc->txDaemonTid == 0) {
     447   
     448    /*
     449     * Set up WD hardware
     450     */
     451    wd8003Enet_initialize_hardware (sc);
     452   
     453    /*
     454     * Start driver tasks
     455     */
     456    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, wd_txDaemon, sc);
     457    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, wd_rxDaemon, sc);
     458  }
     459
     460  /*
     461   * Tell the world that we're running.
     462   */
     463  ifp->if_flags |= IFF_RUNNING;
     464
     465}
     466
     467/*
     468 * Stop the device
     469 */
     470static void
     471wd_stop (struct wd_softc *sc)
    381472{
    382473  unsigned int tport;
    383474  unsigned char temp;
     475  struct ifnet *ifp = &sc->arpcom.ac_if;
     476
     477  ifp->if_flags &= ~IFF_RUNNING;
     478
    384479  /*
    385480   * Stop the transmitter
    386481   */
    387   tport=wd8003EnetDriver[0].port ;
     482  tport=wd_softc[0].port ;
    388483  inport_byte(tport+0x04,temp);
    389484  outport_byte(tport+0x04, temp & 0x7f);
    390485  outport_byte(tport + CMDR, MSK_STP + MSK_RD2);
    391   return 0;
    392 }
     486
     487}
     488
    393489
    394490/*
     
    396492 */
    397493static void
    398 wd8003Enet_show (struct iface *iface)
    399 {
    400   printf ("      Rx Interrupts:%-8lu", wd8003EnetDriver[0].rxInterrupts);
    401   printf ("       Not First:%-8lu", wd8003EnetDriver[0].rxNotFirst);
    402   printf ("        Not Last:%-8lu\n", wd8003EnetDriver[0].rxNotLast);
    403   printf ("              Giant:%-8lu", wd8003EnetDriver[0].rxGiant);
    404   printf ("            Runt:%-8lu", wd8003EnetDriver[0].rxRunt);
    405   printf ("       Non-octet:%-8lu\n", wd8003EnetDriver[0].rxNonOctet);
    406   printf ("            Bad CRC:%-8lu", wd8003EnetDriver[0].rxBadCRC);
    407   printf ("         Overrun:%-8lu", wd8003EnetDriver[0].rxOverrun);
    408   printf ("       Collision:%-8lu\n", wd8003EnetDriver[0].rxCollision);
    409   printf ("      Tx Interrupts:%-8lu", wd8003EnetDriver[0].txInterrupts);
    410   printf ("        Deferred:%-8lu", wd8003EnetDriver[0].txDeferred);
    411   printf (" Missed Hearbeat:%-8lu\n", wd8003EnetDriver[0].txHeartbeat);
    412   printf ("         No Carrier:%-8lu", wd8003EnetDriver[0].txLostCarrier);
    413   printf ("Retransmit Limit:%-8lu", wd8003EnetDriver[0].txRetryLimit);
    414   printf ("  Late Collision:%-8lu\n", wd8003EnetDriver[0].txLateCollision);
    415   printf ("           Underrun:%-8lu", wd8003EnetDriver[0].txUnderrun);
    416   printf (" Raw output wait:%-8lu\n", wd8003EnetDriver[0].txRawWait);
    417 }
    418 
    419 /*
    420  * Attach an WD8003 driver to the system
    421  * This is the only `extern' function in the driver.
    422  *
    423  * argv[0]: interface label, e.g., "rtems"
    424  * The remainder of the arguemnts are key/value pairs:
    425  * mtu ##                  --  maximum transmission unit, default 1500
    426  * broadcast y/n           -- accept or ignore broadcast packets, default yes
    427  * rbuf ##                 -- Set number of receive buffer descriptors
    428  * rbuf ##                 -- Set number of transmit buffer descriptors
    429  * ip ###.###.###.###      -- IP address
    430  * ether ##:##:##:##:##:## -- Ethernet address
    431  * irno                    -- Set controller irq
    432  * port                    -- Set io port
    433  * bpar                    -- Set RAM address
     494wd_stats (struct wd_softc *sc)
     495{
     496        printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
     497        printf ("       Not First:%-8lu", sc->rxNotFirst);
     498        printf ("        Not Last:%-8lu\n", sc->rxNotLast);
     499        printf ("              Giant:%-8lu", sc->rxGiant);
     500        printf ("            Runt:%-8lu", sc->rxRunt);
     501        printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
     502        printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
     503        printf ("         Overrun:%-8lu", sc->rxOverrun);
     504        printf ("       Collision:%-8lu\n", sc->rxCollision);
     505
     506        printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
     507        printf ("        Deferred:%-8lu", sc->txDeferred);
     508        printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
     509        printf ("         No Carrier:%-8lu", sc->txLostCarrier);
     510        printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
     511        printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
     512        printf ("           Underrun:%-8lu", sc->txUnderrun);
     513        printf (" Raw output wait:%-8lu\n", sc->txRawWait);
     514}
     515
     516/*
     517 * Driver ioctl handler
     518 */
     519static int
     520wd_ioctl (struct ifnet *ifp, int command, caddr_t data)
     521{
     522        struct wd_softc *sc = ifp->if_softc;
     523        int error = 0;
     524
     525        switch (command) {
     526        case SIOCGIFADDR:
     527        case SIOCSIFADDR:
     528                ether_ioctl (ifp, command, data);
     529                break;
     530
     531        case SIOCSIFFLAGS:
     532                switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
     533                case IFF_RUNNING:
     534                        wd_stop (sc);
     535                        break;
     536
     537                case IFF_UP:
     538                        wd_init (sc);
     539                        break;
     540
     541                case IFF_UP | IFF_RUNNING:
     542                        wd_stop (sc);
     543                        wd_init (sc);
     544                        break;
     545
     546                default:
     547                        break;
     548                }
     549                break;
     550
     551        case SIO_RTEMS_SHOW_STATS:
     552                wd_stats (sc);
     553                break;
     554               
     555        /*
     556         * FIXME: All sorts of multicast commands need to be added here!
     557         */
     558        default:
     559                error = EINVAL;
     560                break;
     561        }
     562        return error;
     563}
     564
     565/*
     566 * Attach an WD driver to the system
    434567 */
    435568int
    436 rtems_ka9q_driver_attach (int argc, char *argv[], void *p)
    437 {
    438   struct iface *iface;
    439   wd80x3EnetDriver *dp;
    440   char *cp;
    441   int i;
    442   int argIndex;
    443   int broadcastFlag;
    444   char cbuf[30];
    445  
    446   /*
    447    * Find a free driver
    448    */
    449   for (i = 0 ; i < NSCCDRIVER ; i++) {
    450     if (wd8003EnetDriver[i].iface == NULL)
    451       break;
    452   }
    453   if (i >= NSCCDRIVER) {
    454     printf ("Too many SCC drivers.\n");
    455     return -1;
    456   }
    457   if (if_lookup (argv[0]) != NULL) {
    458     printf ("Interface %s already exists\n", argv[0]);
    459     return -1;
    460   }
    461   dp = &wd8003EnetDriver[i];
    462  
    463   /*
    464    * Create an inteface descriptor
    465    */
    466   iface = callocw (1, sizeof *iface);
    467   iface->name = strdup (argv[0]);
    468  
    469   /*
    470    * Set default values
    471    */
    472   broadcastFlag = 1;
    473   dp->txWaitTid = 0;
    474   dp->rxBdCount = RX_BUF_COUNT;
    475   dp->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
    476   dp->irqInfo.name = (rtems_irq_symbolic_name) 5;
    477   dp->port = 0x240;
    478   dp->base = (unsigned char*) 0xD0000;
    479   dp->bpar = 0xD0000;
    480   iface->mtu = 1500;
    481   iface->addr = Ip_addr;
    482   iface->hwaddr = mallocw (EADDR_LEN);
    483   memset (iface->hwaddr, 0x08, EADDR_LEN);
    484  
    485   /*
    486    * Parse arguments
    487    */
    488   for (argIndex = 1 ; argIndex < (argc - 1) ; argIndex++) {
    489     if (strcmp ("mtu", argv[argIndex]) == 0) {
    490       iface->mtu = atoi (argv[++argIndex]);
    491     }
    492     else if (strcmp ("broadcast", argv[argIndex]) == 0) {
    493       if (*argv[++argIndex] == 'n')
    494         broadcastFlag = 0;
    495     }
    496     else if (strcmp ("rbuf", argv[argIndex]) == 0) {
    497       dp->rxBdCount = atoi (argv[++argIndex]);
    498     }
    499     else if (strcmp ("tbuf", argv[argIndex]) == 0) {
    500       dp->txBdCount = atoi (argv[++argIndex]) * TX_BD_PER_BUF;
    501     }
    502     else if (strcmp ("ip", argv[argIndex]) == 0) {
    503       iface->addr = resolve (argv[++argIndex]);
    504     }
    505     else if (strcmp ("ether", argv[argIndex]) == 0) {
    506       argIndex++;
    507       gether (iface->hwaddr, argv[argIndex]);
    508     }
    509     else if (strcmp ("irno", argv[argIndex]) == 0) {
    510       dp->irqInfo.name = (rtems_irq_symbolic_name) atoi (argv[++argIndex]);
    511     }
    512     else if (strcmp ("port", argv[argIndex]) == 0) {
    513       sscanf(argv[++argIndex], "%x", &(dp->port));
    514     }
    515     else if (strcmp ("bpar", argv[argIndex]) == 0) {
    516       sscanf(argv[++argIndex], "%x", (unsigned *) &(dp->bpar));
    517       dp->base = (unsigned char *)(dp->bpar);
    518     }
    519     else {
    520       printf ("Argument %d (%s) is invalid.\n", argIndex, argv[argIndex]);
    521       return -1;
    522     }
    523   }
    524   printf ("Ethernet address: %s\n", pether (cbuf, iface->hwaddr));
    525   printf ("Internet address: %s\n", inet_ntoa(iface->addr));
    526   printf ("Irno: %X, port: %X, bpar: %X, base: %X\n",dp->irqInfo.name, dp->port,
    527           (unsigned) dp->bpar, (unsigned) dp->base);
    528   fflush(stdout);
    529   /*   
    530    * Fill in remainder of interface configuration
    531    */   
    532   iface->dev = i;
    533   iface->raw = wd8003Enet_raw;
    534   iface->stop = wd8003Enet_stop;
    535   iface->show = wd8003Enet_show;
    536   dp->iface = iface;
    537   setencap (iface, "Ethernet");
    538  
    539   /*
    540    * Set up SCC hardware
    541    */
    542   wd8003Enet_initialize_hardware (dp, broadcastFlag);
    543   fflush(stdout);
    544  
    545   /*
    546    * Chain onto list of interfaces
    547    */
    548   iface->next = Ifaces;
    549   Ifaces = iface;
    550    
    551   /* calibrate a delay loop for 2 milliseconds */
    552   rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &loopc );
    553   loopc /= 500;
    554  
    555   /*
    556    * Start I/O daemons
    557    */
    558   cp = if_name (iface, " tx");
    559   iface->txproc = newproc (cp, 1024, if_tx, iface->dev, iface, NULL, 0);
    560   free (cp);
    561   return 0;
    562 }       
    563 
    564 
    565 
    566 
    567 
    568 
    569 
     569rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *config)
     570{
     571        struct wd_softc *sc;
     572        struct ifnet *ifp;
     573        int mtu;
     574        int i;
     575
     576        /*
     577         * Find a free driver
     578         */
     579        for (i = 0 ; i < NWDDRIVER ; i++) {
     580                sc = &wd_softc[i];
     581                ifp = &sc->arpcom.ac_if;
     582                if (ifp->if_softc == NULL)
     583                        break;
     584        }
     585        if (i >= NWDDRIVER) {
     586                printf ("Too many WD drivers.\n");
     587                return 0;
     588        }
     589
     590        /*
     591         * Process options
     592         */
     593        if (config->hardware_address) {
     594          memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
     595                  ETHER_ADDR_LEN);
     596        }
     597        else {
     598          memset (sc->arpcom.ac_enaddr, 0x08,ETHER_ADDR_LEN);
     599        }
     600        if (config->mtu)
     601                mtu = config->mtu;
     602        else
     603                mtu = ETHERMTU;
     604
     605
     606        if (config->irno)
     607                sc->irqInfo.name = config->irno;
     608        else
     609                sc->irqInfo.name = 5;
     610
     611        if (config->port)
     612                sc->port = config->port;
     613        else
     614                sc->port = 0x240;
     615
     616        if (config->bpar) {
     617                sc->bpar = config->bpar;
     618                sc->base = (unsigned char*) config->bpar;
     619        }
     620        else {
     621                sc->bpar = 0xD0000;
     622                sc->base = (unsigned char*) 0xD0000;
     623        }
     624       
     625        sc->acceptBroadcast = !config->ignore_broadcast;
     626
     627        /*
     628         * Set up network interface values
     629         */
     630        ifp->if_softc = sc;
     631        ifp->if_unit = i + 1;
     632        ifp->if_name = "wd";
     633        ifp->if_mtu = mtu;
     634        ifp->if_init = wd_init;
     635        ifp->if_ioctl = wd_ioctl;
     636        ifp->if_start = wd_start;
     637        ifp->if_output = ether_output;
     638        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
     639        if (ifp->if_snd.ifq_maxlen == 0)
     640                ifp->if_snd.ifq_maxlen = ifqmaxlen;
     641
     642        /* calibrate a delay loop for 2 milliseconds */
     643        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &loopc );
     644        loopc /= 500;
     645
     646        /*
     647         * init some variables
     648         */
     649        overrun = 0;
     650        resend = 0;
     651
     652        /*
     653         * Attach the interface
     654         */
     655        if_attach (ifp);
     656        ether_ifattach (ifp);
     657        return 1;
     658};
  • c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in

    rb285860 rd9d75fc  
    99PROJECT_ROOT = @PROJECT_ROOT@
    1010
    11 # # We only build the Network library if HAS_NETWORKING was defined
    12 # NETWORK_yes_V = network
    13 # NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
     11# We only build the Network library if HAS_NETWORKING was defined
     12NETWORK_yes_V = network
     13NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
    1414
    1515BSP_PIECES=startup clock console timer pc386dev $(NETWORK)
  • c/src/lib/libc/newlibc.c

    rb285860 rd9d75fc  
    354354/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
    355355#if !defined(RTEMS_UNIX) && !defined(_AM29K)
    356 #if !defined(pc386)
    357356void _exit(int status)
    358357{
     
    360359    rtems_shutdown_executive(status);
    361360}
    362 #endif
    363 
    364361#else
    365362
  • c/src/lib/libnetworking/rtems/rtems_bsdnet.h

    rb285860 rd9d75fc  
    6969        int             rbuf_count;
    7070        int             xbuf_count;
     71
     72  /*
     73   * For external ethernet controller board the following
     74   * parameters are needed
     75   */
     76  unsigned int                  port;   /* port of the board */
     77  unsigned int                  irno;   /* irq of the board */
     78  unsigned int                  bpar;   /* memory of the board */
     79
    7180};
    7281
  • c/src/libnetworking/rtems/rtems_bsdnet.h

    rb285860 rd9d75fc  
    6969        int             rbuf_count;
    7070        int             xbuf_count;
     71
     72  /*
     73   * For external ethernet controller board the following
     74   * parameters are needed
     75   */
     76  unsigned int                  port;   /* port of the board */
     77  unsigned int                  irno;   /* irq of the board */
     78  unsigned int                  bpar;   /* memory of the board */
     79
    7180};
    7281
  • cpukit/libcsupport/src/newlibc.c

    rb285860 rd9d75fc  
    354354/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
    355355#if !defined(RTEMS_UNIX) && !defined(_AM29K)
    356 #if !defined(pc386)
    357356void _exit(int status)
    358357{
     
    360359    rtems_shutdown_executive(status);
    361360}
    362 #endif
    363 
    364361#else
    365362
  • cpukit/libnetworking/rtems/rtems_bsdnet.h

    rb285860 rd9d75fc  
    6969        int             rbuf_count;
    7070        int             xbuf_count;
     71
     72  /*
     73   * For external ethernet controller board the following
     74   * parameters are needed
     75   */
     76  unsigned int                  port;   /* port of the board */
     77  unsigned int                  irno;   /* irq of the board */
     78  unsigned int                  bpar;   /* memory of the board */
     79
    7180};
    7281
Note: See TracChangeset for help on using the changeset viewer.