Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/netif/dp8390/dp8390.c

    r7922dea r7e752b2  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
    3  * Copyright (c) 2011 Martin Decky
    4  * All rights reserved.
     2 * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
    53 *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
     4 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
     5 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
     6 * * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission.
     7 * * Any deviations from these conditions require written permission from the copyright holder in advance
    98 *
    10  * - Redistributions of source code must retain the above copyright
    11  *   notice, this list of conditions and the following disclaimer.
    12  * - Redistributions in binary form must reproduce the above copyright
    13  *   notice, this list of conditions and the following disclaimer in the
    14  *   documentation and/or other materials provided with the distribution.
    15  * - The name of the author may not be used to endorse or promote products
    16  *   derived from this software without specific prior written permission.
    179 *
    18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     10 * Disclaimer
     11 *
     12 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
    1913 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    2014 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     15 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    2216 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    2317 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     
    2620 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    2721 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  */
    29 
    30 /*
    31  * This code is based upon the NE2000 driver for MINIX,
    32  * distributed according to a BSD-style license.
    3322 *
    34  * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
    35  * Copyright (c) 1992, 1994 Philip Homburg
    36  * Copyright (c) 1996 G. Falzoni
    37  *
     23 * Changes:
     24 *  2009 ported to HelenOS, Lukas Mejdrech
    3825 */
    3926
     
    4936#include <byteorder.h>
    5037#include <errno.h>
     38
    5139#include <netif_local.h>
    5240#include <net/packet.h>
    53 #include <nil_interface.h>
    5441#include <packet_client.h>
     42
    5543#include "dp8390_drv.h"
    5644#include "dp8390_port.h"
     45
     46/*
     47 * dp8390.c
     48 *
     49 * Created:     before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
     50 *
     51 * Modified Mar 10 1994 by Philip Homburg
     52 *      Become a generic dp8390 driver.
     53 *
     54 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
     55 *      Added support for 3c503 boards.
     56 */
     57
     58#include "local.h"
    5759#include "dp8390.h"
    58 #include "ne2000.h"
    59 
    60 /** Read a memory block byte by byte.
    61  *
     60
     61/** Queues the outgoing packet.
     62 *  @param[in] dep The network interface structure.
     63 *  @param[in] packet The outgoing packet.
     64 *  @return EOK on success.
     65 *  @return EINVAL
     66 */
     67int queue_packet(dpeth_t * dep, packet_t *packet);
     68
     69/** Reads a memory block byte by byte.
    6270 *  @param[in] port The source address.
    6371 *  @param[out] buf The destination buffer.
    6472 *  @param[in] size The memory block size in bytes.
    65  *
    6673 */
    6774static void outsb(port_t port, void * buf, size_t size);
    6875
    69 /** Read a memory block word by word.
    70  *
     76/** Reads a memory block word by word.
    7177 *  @param[in] port The source address.
    7278 *  @param[out] buf The destination buffer.
    7379 *  @param[in] size The memory block size in bytes.
    74  *
    7580 */
    7681static void outsw(port_t port, void * buf, size_t size);
    7782
    78 /*
    79  * Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
     83//static u16_t eth_ign_proto;
     84//static char *progname;
     85
     86/* Configuration */
     87/*typedef struct dp_conf
     88{
     89        port_t dpc_port;
     90        int dpc_irq;
     91        phys_bytes dpc_mem;
     92        char *dpc_envvar;
     93} dp_conf_t;
     94*/
     95//dp_conf_t dp_conf[]=  /* Card addresses */
     96//{
     97        /* I/O port, IRQ,  Buffer address,  Env. var. */
     98/*      { 0x280,     3,    0xD0000,        "DPETH0"     },
     99        { 0x300,     5,    0xC8000,        "DPETH1"     },
     100        { 0x380,    10,    0xD8000,        "DPETH2"     },
     101};
     102*/
     103/* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
     104 * the error: "array size is negative".
     105 */
     106//extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
     107
     108/* Card inits configured out? */
     109#if !ENABLE_WDETH
     110#define wdeth_probe(dep)        (0)
     111#endif
     112#if !ENABLE_NE2000
     113#define ne_probe(dep)           (0)
     114#endif
     115#if !ENABLE_3C503
     116#define el2_probe(dep)          (0)
     117#endif
     118
     119/* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
    80120 * on writes to the CR register. Additional CR_STAs do not appear to hurt
    81  * genuine dp8390s.
     121 * genuine dp8390s
    82122 */
    83 #define CR_EXTRA  CR_STA
    84 
    85 static void dp_init(dpeth_t *dep);
    86 static void dp_reinit(dpeth_t *dep);
    87 static void dp_reset(dpeth_t *dep);
    88 static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep);
    89 static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length);
    90 static void conf_hw(dpeth_t *dep);
    91 static void insb(port_t port, void *buf, size_t size);
    92 static void insw(port_t port, void *buf, size_t size);
    93 
    94 int do_probe(dpeth_t *dep)
    95 {
     123#define CR_EXTRA        CR_STA
     124
     125//#if ENABLE_PCI
     126//_PROTOTYPE(static void pci_conf, (void)                               );
     127//#endif
     128//_PROTOTYPE(static void do_vwrite, (message *mp, int from_int,
     129//                                                      int vectored)   );
     130//_PROTOTYPE(static void do_vwrite_s, (message *mp, int from_int)       );
     131//_PROTOTYPE(static void do_vread, (message *mp, int vectored)          );
     132//_PROTOTYPE(static void do_vread_s, (message *mp)                      );
     133//_PROTOTYPE(static void do_init, (message *mp)                         );
     134//_PROTOTYPE(static void do_int, (dpeth_t *dep)                         );
     135//_PROTOTYPE(static void do_getstat, (message *mp)                      );
     136//_PROTOTYPE(static void do_getstat_s, (message *mp)                    );
     137//_PROTOTYPE(static void do_getname, (message *mp)                      );
     138//_PROTOTYPE(static void do_stop, (message *mp)                         );
     139_PROTOTYPE(static void dp_init, (dpeth_t *dep)                          );
     140//_PROTOTYPE(static void dp_confaddr, (dpeth_t *dep)                    );
     141_PROTOTYPE(static void dp_reinit, (dpeth_t *dep)                        );
     142_PROTOTYPE(static void dp_reset, (dpeth_t *dep)                 );
     143//_PROTOTYPE(static void dp_check_ints, (dpeth_t *dep)                  );
     144_PROTOTYPE(static void dp_recv, (dpeth_t *dep)                          );
     145_PROTOTYPE(static void dp_send, (dpeth_t *dep)                          );
     146//_PROTOTYPE(static void dp8390_stop, (void)                            );
     147_PROTOTYPE(static void dp_getblock, (dpeth_t *dep, int page,
     148                                size_t offset, size_t size, void *dst)  );
     149_PROTOTYPE(static void dp_pio8_getblock, (dpeth_t *dep, int page,
     150                                size_t offset, size_t size, void *dst)  );
     151_PROTOTYPE(static void dp_pio16_getblock, (dpeth_t *dep, int page,
     152                                size_t offset, size_t size, void *dst)  );
     153_PROTOTYPE(static int dp_pkt2user, (dpeth_t *dep, int page,
     154                                                        int length) );
     155//_PROTOTYPE(static int dp_pkt2user_s, (dpeth_t *dep, int page,
     156//                                                      int length)     );
     157_PROTOTYPE(static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
     158                vir_bytes offset, int nic_addr, vir_bytes count) );
     159//_PROTOTYPE(static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
     160//              vir_bytes offset, int nic_addr, vir_bytes count)        );
     161_PROTOTYPE(static void dp_pio8_user2nic, (dpeth_t *dep,
     162                                iovec_dat_t *iovp, vir_bytes offset,
     163                                int nic_addr, vir_bytes count) );
     164//_PROTOTYPE(static void dp_pio8_user2nic_s, (dpeth_t *dep,
     165//                              iovec_dat_s_t *iovp, vir_bytes offset,
     166//                              int nic_addr, vir_bytes count)          );
     167_PROTOTYPE(static void dp_pio16_user2nic, (dpeth_t *dep,
     168                                iovec_dat_t *iovp, vir_bytes offset,
     169                                int nic_addr, vir_bytes count) );
     170//_PROTOTYPE(static void dp_pio16_user2nic_s, (dpeth_t *dep,
     171//                              iovec_dat_s_t *iovp, vir_bytes offset,
     172//                              int nic_addr, vir_bytes count)          );
     173_PROTOTYPE(static void dp_nic2user, (dpeth_t *dep, int nic_addr,
     174                iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
     175//_PROTOTYPE(static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
     176//              iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
     177_PROTOTYPE(static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
     178                iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
     179//_PROTOTYPE(static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
     180//              iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
     181_PROTOTYPE(static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
     182                iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
     183//_PROTOTYPE(static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
     184//              iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
     185_PROTOTYPE(static void dp_next_iovec, (iovec_dat_t *iovp)               );
     186//_PROTOTYPE(static void dp_next_iovec_s, (iovec_dat_s_t *iovp)         );
     187_PROTOTYPE(static void conf_hw, (dpeth_t *dep)                          );
     188//_PROTOTYPE(static void update_conf, (dpeth_t *dep, dp_conf_t *dcp)    );
     189_PROTOTYPE(static void map_hw_buffer, (dpeth_t *dep)                    );
     190//_PROTOTYPE(static int calc_iovec_size, (iovec_dat_t *iovp)            );
     191//_PROTOTYPE(static int calc_iovec_size_s, (iovec_dat_s_t *iovp)                );
     192_PROTOTYPE(static void reply, (dpeth_t *dep, int err, int may_block)    );
     193//_PROTOTYPE(static void mess_reply, (message *req, message *reply)     );
     194_PROTOTYPE(static void get_userdata, (int user_proc,
     195                vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
     196//_PROTOTYPE(static void get_userdata_s, (int user_proc,
     197//              cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
     198//              void *loc_addr) );
     199//_PROTOTYPE(static void put_userdata, (int user_proc,
     200//              vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
     201//_PROTOTYPE(static void put_userdata_s, (int user_proc,
     202//              cp_grant_id_t grant, size_t count, void *loc_addr)      );
     203_PROTOTYPE(static void insb, (port_t port, void *buf, size_t size)                              );
     204_PROTOTYPE(static void insw, (port_t port, void *buf, size_t size)                              );
     205//_PROTOTYPE(static void do_vir_insb, (port_t port, int proc,
     206//                                      vir_bytes buf, size_t size)     );
     207//_PROTOTYPE(static void do_vir_insw, (port_t port, int proc,
     208//                                      vir_bytes buf, size_t size)     );
     209//_PROTOTYPE(static void do_vir_outsb, (port_t port, int proc,
     210//                                      vir_bytes buf, size_t size)     );
     211//_PROTOTYPE(static void do_vir_outsw, (port_t port, int proc,
     212//                                      vir_bytes buf, size_t size)     );
     213
     214int do_probe(dpeth_t * dep){
    96215        /* This is the default, try to (re)locate the device. */
    97216        conf_hw(dep);
    98         if (!dep->up)
     217        if (dep->de_mode == DEM_DISABLED)
     218        {
    99219                /* Probe failed, or the device is configured off. */
     220                return EXDEV;//ENXIO;
     221        }
     222        if (dep->de_mode == DEM_ENABLED)
     223                dp_init(dep);
     224        return EOK;
     225}
     226
     227/*===========================================================================*
     228 *                              dp8390_dump                                  *
     229 *===========================================================================*/
     230void dp8390_dump(dpeth_t * dep)
     231{
     232//      dpeth_t *dep;
     233        int /*i,*/ isr;
     234
     235//      printf("\n");
     236//      for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
     237//      {
     238#if XXX
     239                if (dep->de_mode == DEM_DISABLED)
     240                        printf("dp8390 port %d is disabled\n", i);
     241                else if (dep->de_mode == DEM_SINK)
     242                        printf("dp8390 port %d is in sink mode\n", i);
     243#endif
     244
     245                if (dep->de_mode != DEM_ENABLED)
     246//                      continue;
     247                        return;
     248
     249//              printf("dp8390 statistics of port %d:\n", i);
     250
     251                printf("recvErr    :%8ld\t", dep->de_stat.ets_recvErr);
     252                printf("sendErr    :%8ld\t", dep->de_stat.ets_sendErr);
     253                printf("OVW        :%8ld\n", dep->de_stat.ets_OVW);
     254
     255                printf("CRCerr     :%8ld\t", dep->de_stat.ets_CRCerr);
     256                printf("frameAll   :%8ld\t", dep->de_stat.ets_frameAll);
     257                printf("missedP    :%8ld\n", dep->de_stat.ets_missedP);
     258
     259                printf("packetR    :%8ld\t", dep->de_stat.ets_packetR);
     260                printf("packetT    :%8ld\t", dep->de_stat.ets_packetT);
     261                printf("transDef   :%8ld\n", dep->de_stat.ets_transDef);
     262
     263                printf("collision  :%8ld\t", dep->de_stat.ets_collision);
     264                printf("transAb    :%8ld\t", dep->de_stat.ets_transAb);
     265                printf("carrSense  :%8ld\n", dep->de_stat.ets_carrSense);
     266
     267                printf("fifoUnder  :%8ld\t", dep->de_stat.ets_fifoUnder);
     268                printf("fifoOver   :%8ld\t", dep->de_stat.ets_fifoOver);
     269                printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
     270
     271                printf("OWC        :%8ld\t", dep->de_stat.ets_OWC);
     272
     273                isr= inb_reg0(dep, DP_ISR);
     274                printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
     275                                        inb_reg0(dep, DP_ISR), dep->de_flags);
     276//      }
     277}
     278
     279/*===========================================================================*
     280 *                              do_init                                      *
     281 *===========================================================================*/
     282int do_init(dpeth_t * dep, int mode){
     283        if (dep->de_mode == DEM_DISABLED)
     284        {
     285                // might call do_probe()
    100286                return EXDEV;
    101        
    102         if (dep->up)
    103                 dp_init(dep);
    104        
     287        }
     288
     289        if (dep->de_mode == DEM_SINK)
     290        {
     291//              strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
     292//              dep->de_address.ea_addr[5] = port;
     293//              dp_confaddr(dep);
     294//              reply_mess.m_type = DL_CONF_REPLY;
     295//              reply_mess.m3_i1 = mp->DL_PORT;
     296//              reply_mess.m3_i2 = DE_PORT_NR;
     297//              *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
     298//              mess_reply(mp, &reply_mess);
     299//              return;
     300                return EOK;
     301        }
     302        assert(dep->de_mode == DEM_ENABLED);
     303        assert(dep->de_flags &DEF_ENABLED);
     304
     305        dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
     306
     307        if (mode &DL_PROMISC_REQ)
     308                dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
     309        if (mode &DL_MULTI_REQ)
     310                dep->de_flags |= DEF_MULTI;
     311        if (mode &DL_BROAD_REQ)
     312                dep->de_flags |= DEF_BROAD;
     313
     314//      dep->de_client = mp->m_source;
     315        dp_reinit(dep);
     316
     317//      reply_mess.m_type = DL_CONF_REPLY;
     318//      reply_mess.m3_i1 = mp->DL_PORT;
     319//      reply_mess.m3_i2 = DE_PORT_NR;
     320//      *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
     321
     322//      mess_reply(mp, &reply_mess);
    105323        return EOK;
    106324}
    107325
    108 /** Initialize and/or start the network interface.
    109  *
    110  *  @param[in,out] dep The network interface structure.
    111  *
    112  *  @return EOK on success.
    113  *  @return EXDEV if the network interface is disabled.
    114  *
    115  */
    116 int do_init(dpeth_t *dep)
    117 {
    118         if (!dep->up)
    119                 /* FIXME: Perhaps call do_probe()? */
    120                 return EXDEV;
    121        
    122         assert(dep->up);
    123         assert(dep->enabled);
    124        
    125         dp_reinit(dep);
    126         return EOK;
    127 }
    128 
    129 void do_stop(dpeth_t *dep)
    130 {
    131         if ((dep->up) && (dep->enabled)) {
     326/*===========================================================================*
     327 *                              do_stop                                      *
     328 *===========================================================================*/
     329void do_stop(dpeth_t * dep){
     330        if((dep->de_mode != DEM_SINK) && (dep->de_mode == DEM_ENABLED) && (dep->de_flags &DEF_ENABLED)){
    132331                outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    133                 ne_stop(dep);
    134                
    135                 dep->enabled = false;
    136                 dep->stopped = false;
    137                 dep->sending = false;
    138                 dep->send_avail = false;
    139         }
    140 }
    141 
    142 static void dp_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size)
    143 {
    144         size_t ecount = size & ~1;
    145        
    146         outb_reg0(dep, DP_ISR, ISR_RDC);
    147        
    148         if (dep->de_16bit) {
    149                 outb_reg0(dep, DP_RBCR0, ecount & 0xff);
    150                 outb_reg0(dep, DP_RBCR1, ecount >> 8);
    151         } else {
    152                 outb_reg0(dep, DP_RBCR0, size & 0xff);
    153                 outb_reg0(dep, DP_RBCR1, size >> 8);
    154         }
    155        
    156         outb_reg0(dep, DP_RSAR0, nic_addr & 0xff);
    157         outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    158         outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
    159        
    160         if (dep->de_16bit) {
    161                 void *ptr = buf + offset;
    162                
    163                 if (ecount != 0) {
    164                         outsw(dep->de_data_port, ptr, ecount);
    165                         size -= ecount;
    166                         offset += ecount;
    167                         ptr += ecount;
    168                 }
    169                
    170                 if (size) {
    171                         assert(size == 1);
    172                        
    173                         uint16_t two_bytes;
    174                        
    175                         memcpy(&(((uint8_t *) &two_bytes)[0]), ptr, 1);
    176                         outw(dep->de_data_port, two_bytes);
    177                 }
    178         } else
    179                 outsb(dep->de_data_port, buf + offset, size);
    180        
    181         unsigned int i;
    182         for (i = 0; i < 100; i++) {
    183                 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
    184                         break;
    185         }
    186        
    187         if (i == 100)
    188                 fprintf(stderr, "Remote DMA failed to complete\n");
    189 }
    190 
    191 int do_pwrite(dpeth_t *dep, packet_t *packet, int from_int)
    192 {
     332                (dep->de_stopf)(dep);
     333
     334                dep->de_flags = DEF_EMPTY;
     335        }
     336}
     337
     338int queue_packet(dpeth_t * dep, packet_t *packet){
     339        packet_t *tmp;
     340
     341        if(dep->packet_count >= MAX_PACKETS){
     342                netif_pq_release(packet_get_id(packet));
     343                return ELIMIT;
     344        }
     345
     346        tmp = dep->packet_queue;
     347        while(pq_next(tmp)){
     348                tmp = pq_next(tmp);
     349        }
     350        if(pq_add(&tmp, packet, 0, 0) != EOK){
     351                return EINVAL;
     352        }
     353        if(! dep->packet_count){
     354                dep->packet_queue = packet;
     355        }
     356        ++ dep->packet_count;
     357        return EBUSY;
     358}
     359
     360/*===========================================================================*
     361 *                      based on        do_vwrite                                    *
     362 *===========================================================================*/
     363int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int)
     364{
     365//      int port, count, size;
    193366        int size;
    194367        int sendq_head;
    195        
    196         assert(dep->up);
    197         assert(dep->enabled);
    198        
    199         if (dep->send_avail) {
    200                 fprintf(stderr, "Send already in progress\n");
    201                 return EBUSY;
    202         }
    203        
    204         sendq_head = dep->de_sendq_head;
    205         if (dep->de_sendq[sendq_head].sq_filled) {
    206                 if (from_int)
    207                         fprintf(stderr, "dp8390: should not be sending\n");
    208                 dep->send_avail = true;
    209                 dep->sending = false;
    210                
    211                 return EBUSY;
    212         }
    213        
    214         assert(!dep->sending);
    215        
    216         void *buf = packet_get_data(packet);
     368/*      dpeth_t *dep;
     369
     370        port = mp->DL_PORT;
     371        count = mp->DL_COUNT;
     372        if (port < 0 || port >= DE_PORT_NR)
     373                panic("", "dp8390: illegal port", port);
     374        dep= &de_table[port];
     375        dep->de_client= mp->DL_PROC;
     376*/
     377        if (dep->de_mode == DEM_SINK)
     378        {
     379                assert(!from_int);
     380//              dep->de_flags |= DEF_PACK_SEND;
     381                reply(dep, OK, FALSE);
     382//              return;
     383                return EOK;
     384        }
     385        assert(dep->de_mode == DEM_ENABLED);
     386        assert(dep->de_flags &DEF_ENABLED);
     387        if(dep->packet_queue && (! from_int)){
     388//      if (dep->de_flags &DEF_SEND_AVAIL){
     389//              panic("", "dp8390: send already in progress", NO_NUM);
     390                return queue_packet(dep, packet);
     391        }
     392
     393        sendq_head= dep->de_sendq_head;
     394//      if (dep->de_sendq[sendq_head].sq_filled)
     395//      {
     396//              if (from_int)
     397//                      panic("", "dp8390: should not be sending\n", NO_NUM);
     398//              dep->de_sendmsg= *mp;
     399//              dep->de_flags |= DEF_SEND_AVAIL;
     400//              reply(dep, OK, FALSE);
     401//              return;
     402//              return queue_packet(dep, packet);
     403//      }
     404//      assert(!(dep->de_flags &DEF_PACK_SEND));
     405
     406/*      if (vectored)
     407        {
     408                get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
     409                        (count > IOVEC_NR ? IOVEC_NR : count) *
     410                        sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
     411                dep->de_write_iovec.iod_iovec_s = count;
     412                dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
     413                dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
     414
     415                dep->de_tmp_iovec = dep->de_write_iovec;
     416                size = calc_iovec_size(&dep->de_tmp_iovec);
     417        }
     418        else
     419        {
     420                dep->de_write_iovec.iod_iovec[0].iov_addr =
     421                        (vir_bytes) mp->DL_ADDR;
     422                dep->de_write_iovec.iod_iovec[0].iov_size =
     423                        mp->DL_COUNT;
     424                dep->de_write_iovec.iod_iovec_s = 1;
     425                dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
     426                dep->de_write_iovec.iod_iovec_addr = 0;
     427                size= mp->DL_COUNT;
     428        }
     429*/
    217430        size = packet_get_data_length(packet);
    218        
    219         if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) {
    220                 fprintf(stderr, "dp8390: invalid packet size\n");
     431        dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) packet_get_data(packet);
     432        dep->de_write_iovec.iod_iovec[0].iov_size = size;
     433        dep->de_write_iovec.iod_iovec_s = 1;
     434        dep->de_write_iovec.iod_iovec_addr = (uintptr_t) NULL;
     435
     436        if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
     437        {
     438                panic("", "dp8390: invalid packet size", size);
    221439                return EINVAL;
    222440        }
    223        
    224         dp_user2nic(dep, buf, 0, dep->de_sendq[sendq_head].sq_sendpage
    225             * DP_PAGESIZE, size);
    226         dep->de_sendq[sendq_head].sq_filled = true;
    227        
    228         if (dep->de_sendq_tail == sendq_head) {
     441        (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
     442                dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
     443                size);
     444        dep->de_sendq[sendq_head].sq_filled= TRUE;
     445        if (dep->de_sendq_tail == sendq_head)
     446        {
    229447                outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
    230448                outb_reg0(dep, DP_TBCR1, size >> 8);
    231                 outb_reg0(dep, DP_TBCR0, size & 0xff);
    232                 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);  /* there it goes .. */
    233         } else
    234                 dep->de_sendq[sendq_head].sq_size = size;
     449                outb_reg0(dep, DP_TBCR0, size &0xff);
     450                outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
     451        }
     452        else
     453                dep->de_sendq[sendq_head].sq_size= size;
    235454       
    236455        if (++sendq_head == dep->de_sendq_nr)
    237                 sendq_head = 0;
    238        
     456                sendq_head= 0;
    239457        assert(sendq_head < SENDQ_NR);
    240         dep->de_sendq_head = sendq_head;
    241         dep->sending = true;
    242        
     458        dep->de_sendq_head= sendq_head;
     459
     460//      dep->de_flags |= DEF_PACK_SEND;
     461
     462        /* If the interrupt handler called, don't send a reply. The reply
     463         * will be sent after all interrupts are handled.
     464         */
    243465        if (from_int)
    244466                return EOK;
    245        
    246         dep->sending = false;
    247        
     467        reply(dep, OK, FALSE);
     468
     469        assert(dep->de_mode == DEM_ENABLED);
     470        assert(dep->de_flags &DEF_ENABLED);
    248471        return EOK;
    249472}
    250473
    251 void dp_init(dpeth_t *dep)
     474/*===========================================================================*
     475 *                              dp_init                                      *
     476 *===========================================================================*/
     477void dp_init(dep)
     478dpeth_t *dep;
    252479{
    253480        int dp_rcr_reg;
    254         int i;
    255        
     481        int i;//, r;
     482
    256483        /* General initialization */
    257         dep->enabled = false;
    258         dep->stopped = false;
    259         dep->sending = false;
    260         dep->send_avail = false;
    261         ne_init(dep);
    262        
    263         printf("Ethernet address ");
    264         for (i = 0; i < 6; i++)
    265                 printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n');
    266        
    267         /*
    268          * Initialization of the dp8390 following the mandatory procedure
     484        dep->de_flags = DEF_EMPTY;
     485        (*dep->de_initf)(dep);
     486
     487//      dp_confaddr(dep);
     488
     489        if (debug)
     490        {
     491                printf("%s: Ethernet address ", dep->de_name);
     492                for (i= 0; i < 6; i++)
     493                        printf("%x%c", dep->de_address.ea_addr[i],
     494                                                        i < 5 ? ':' : '\n');
     495        }
     496
     497        /* Map buffer */
     498        map_hw_buffer(dep);
     499
     500        /* Initialization of the dp8390 following the mandatory procedure
    269501         * in reference manual ("DP8390D/NS32490D NIC Network Interface
    270502         * Controller", National Semiconductor, July 1995, Page 29).
    271503         */
    272        
    273504        /* Step 1: */
    274505        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
    275        
    276506        /* Step 2: */
    277507        if (dep->de_16bit)
     
    279509        else
    280510                outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
    281        
    282511        /* Step 3: */
    283512        outb_reg0(dep, DP_RBCR0, 0);
    284513        outb_reg0(dep, DP_RBCR1, 0);
    285        
    286514        /* Step 4: */
    287         dp_rcr_reg = RCR_AB;  /* Enable broadcasts */
    288        
     515        dp_rcr_reg = 0;
     516        if (dep->de_flags &DEF_PROMISC)
     517                dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
     518        if (dep->de_flags &DEF_BROAD)
     519                dp_rcr_reg |= RCR_AB;
     520        if (dep->de_flags &DEF_MULTI)
     521                dp_rcr_reg |= RCR_AM;
    289522        outb_reg0(dep, DP_RCR, dp_rcr_reg);
    290        
    291523        /* Step 5: */
    292524        outb_reg0(dep, DP_TCR, TCR_INTERNAL);
    293        
    294525        /* Step 6: */
    295526        outb_reg0(dep, DP_BNRY, dep->de_startpage);
    296527        outb_reg0(dep, DP_PSTART, dep->de_startpage);
    297528        outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
    298        
    299529        /* Step 7: */
    300530        outb_reg0(dep, DP_ISR, 0xFF);
    301        
    302531        /* Step 8: */
    303532        outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
    304             IMR_OVWE | IMR_CNTE);
    305        
     533                IMR_OVWE | IMR_CNTE);
    306534        /* Step 9: */
    307535        outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
    308        
     536
    309537        outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
    310538        outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
     
    313541        outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
    314542        outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
    315        
     543
    316544        outb_reg1(dep, DP_MAR0, 0xff);
    317545        outb_reg1(dep, DP_MAR1, 0xff);
     
    322550        outb_reg1(dep, DP_MAR6, 0xff);
    323551        outb_reg1(dep, DP_MAR7, 0xff);
    324        
     552
    325553        outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
    326        
    327554        /* Step 10: */
    328555        outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
    329        
    330556        /* Step 11: */
    331557        outb_reg0(dep, DP_TCR, TCR_NORMAL);
    332        
    333         inb_reg0(dep, DP_CNTR0);  /* Reset counters by reading */
     558
     559        inb_reg0(dep, DP_CNTR0);                /* reset counters by reading */
    334560        inb_reg0(dep, DP_CNTR1);
    335561        inb_reg0(dep, DP_CNTR2);
    336        
     562
    337563        /* Finish the initialization. */
    338         dep->enabled = true;
    339         for (i = 0; i < dep->de_sendq_nr; i++)
     564        dep->de_flags |= DEF_ENABLED;
     565        for (i= 0; i<dep->de_sendq_nr; i++)
    340566                dep->de_sendq[i].sq_filled= 0;
    341        
    342         dep->de_sendq_head = 0;
    343         dep->de_sendq_tail = 0;
    344 }
    345 
    346 static void dp_reinit(dpeth_t *dep)
     567        dep->de_sendq_head= 0;
     568        dep->de_sendq_tail= 0;
     569        if (!dep->de_prog_IO)
     570        {
     571                dep->de_user2nicf= dp_user2nic;
     572//              dep->de_user2nicf_s= dp_user2nic_s;
     573                dep->de_nic2userf= dp_nic2user;
     574//              dep->de_nic2userf_s= dp_nic2user_s;
     575                dep->de_getblockf= dp_getblock;
     576        }
     577        else if (dep->de_16bit)
     578        {
     579                dep->de_user2nicf= dp_pio16_user2nic;
     580//              dep->de_user2nicf_s= dp_pio16_user2nic_s;
     581                dep->de_nic2userf= dp_pio16_nic2user;
     582//              dep->de_nic2userf_s= dp_pio16_nic2user_s;
     583                dep->de_getblockf= dp_pio16_getblock;
     584        }
     585        else
     586        {
     587                dep->de_user2nicf= dp_pio8_user2nic;
     588//              dep->de_user2nicf_s= dp_pio8_user2nic_s;
     589                dep->de_nic2userf= dp_pio8_nic2user;
     590//              dep->de_nic2userf_s= dp_pio8_nic2user_s;
     591                dep->de_getblockf= dp_pio8_getblock;
     592        }
     593
     594        /* Set the interrupt handler and policy. Do not automatically
     595         * reenable interrupts. Return the IRQ line number on interrupts.
     596         */
     597/*      dep->de_hook = dep->de_irq;
     598        r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
     599        if (r != OK)
     600                panic("DP8390", "sys_irqsetpolicy failed", r);
     601
     602        r= sys_irqenable(&dep->de_hook);
     603        if (r != OK)
     604        {
     605                panic("DP8390", "unable enable interrupts", r);
     606        }
     607*/
     608}
     609
     610/*===========================================================================*
     611 *                              dp_reinit                                    *
     612 *===========================================================================*/
     613static void dp_reinit(dep)
     614dpeth_t *dep;
    347615{
    348616        int dp_rcr_reg;
    349        
     617
    350618        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
    351        
    352         /* Enable broadcasts */
    353         dp_rcr_reg = RCR_AB;
    354        
     619
     620        dp_rcr_reg = 0;
     621        if (dep->de_flags &DEF_PROMISC)
     622                dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
     623        if (dep->de_flags &DEF_BROAD)
     624                dp_rcr_reg |= RCR_AB;
     625        if (dep->de_flags &DEF_MULTI)
     626                dp_rcr_reg |= RCR_AM;
    355627        outb_reg0(dep, DP_RCR, dp_rcr_reg);
    356628}
    357629
    358 static void dp_reset(dpeth_t *dep)
     630/*===========================================================================*
     631 *                              dp_reset                                     *
     632 *===========================================================================*/
     633static void dp_reset(dep)
     634dpeth_t *dep;
    359635{
    360636        int i;
    361        
     637
    362638        /* Stop chip */
    363639        outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    364640        outb_reg0(dep, DP_RBCR0, 0);
    365641        outb_reg0(dep, DP_RBCR1, 0);
    366        
    367         for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
     642        for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)
    368643                ; /* Do nothing */
    369        
    370         outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
    371         outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT);
     644        outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
     645        outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
    372646        outb_reg0(dep, DP_TCR, TCR_NORMAL);
    373        
    374         /* Acknowledge the ISR_RDC (remote DMA) interrupt. */
    375         for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
     647
     648        /* Acknowledge the ISR_RDC (remote dma) interrupt. */
     649        for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
    376650                ; /* Do nothing */
    377        
    378         outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
    379        
    380         /*
    381          * Reset the transmit ring. If we were transmitting a packet, we
     651        outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) &~ISR_RDC);
     652
     653        /* Reset the transmit ring. If we were transmitting a packet, we
    382654         * pretend that the packet is processed. Higher layers will
    383655         * retransmit if the packet wasn't actually sent.
    384656         */
    385         dep->de_sendq_head = 0;
    386         dep->de_sendq_tail = 0;
    387        
    388         for (i = 0; i < dep->de_sendq_nr; i++)
    389                 dep->de_sendq[i].sq_filled = 0;
    390        
    391         dep->send_avail = false;
    392         dep->stopped = false;
    393 }
    394 
    395 static uint8_t isr_acknowledge(dpeth_t *dep)
    396 {
    397         uint8_t isr = inb_reg0(dep, DP_ISR);
    398         if (isr != 0)
     657        dep->de_sendq_head= dep->de_sendq_tail= 0;
     658        for (i= 0; i<dep->de_sendq_nr; i++)
     659                dep->de_sendq[i].sq_filled= 0;
     660        dp_send(dep);
     661        dep->de_flags &= ~DEF_STOPPED;
     662}
     663
     664/*===========================================================================*
     665 *                              dp_check_ints                                *
     666 *===========================================================================*/
     667void dp_check_ints(dep, isr)
     668dpeth_t *dep;
     669int isr;
     670{
     671        int /*isr,*/ tsr;
     672        int size, sendq_tail;
     673
     674        if (!(dep->de_flags &DEF_ENABLED))
     675                panic("", "dp8390: got premature interrupt", NO_NUM);
     676
     677        for(;;)
     678        {
     679//              isr = inb_reg0(dep, DP_ISR);
     680                if (!isr)
     681                        break;
    399682                outb_reg0(dep, DP_ISR, isr);
    400        
    401         return isr;
    402 }
    403 
    404 void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, uint8_t isr)
    405 {
    406         int tsr;
    407         int size, sendq_tail;
    408        
    409         for (; (isr & 0x7f) != 0; isr = isr_acknowledge(dep)) {
    410                 if (isr & (ISR_PTX | ISR_TXE)) {
    411                         if (isr & ISR_TXE)
     683                if (isr &(ISR_PTX|ISR_TXE))
     684                {
     685                        if (isr &ISR_TXE)
     686                        {
     687#if DEBUG
     688 {printf("%s: got send Error\n", dep->de_name);}
     689#endif
    412690                                dep->de_stat.ets_sendErr++;
    413                         else {
     691                        }
     692                        else
     693                        {
    414694                                tsr = inb_reg0(dep, DP_TSR);
    415                                
    416                                 if (tsr & TSR_PTX)
    417                                         dep->de_stat.ets_packetT++;
    418                                
    419                                 if (tsr & TSR_COL)
    420                                         dep->de_stat.ets_collision++;
    421                                
    422                                 if (tsr & TSR_ABT)
    423                                         dep->de_stat.ets_transAb++;
    424                                
    425                                 if (tsr & TSR_CRS)
    426                                         dep->de_stat.ets_carrSense++;
    427                                
    428                                 if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10))
    429                                         printf("FIFO underrun\n");
    430                                
    431                                 if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10))
    432                                         printf("CD heart beat failure\n");
    433                                
    434                                 if (tsr & TSR_OWC)
    435                                         dep->de_stat.ets_OWC++;
     695
     696                                if (tsr &TSR_PTX) dep->de_stat.ets_packetT++;
     697#if 0   /* Reserved in later manuals, should be ignored */
     698                                if (!(tsr &TSR_DFR))
     699                                {
     700                                        /* In most (all?) implementations of
     701                                         * the dp8390, this bit is set
     702                                         * when the packet is not deferred
     703                                         */
     704                                        dep->de_stat.ets_transDef++;
     705                                }
     706#endif
     707                                if (tsr &TSR_COL) dep->de_stat.ets_collision++;
     708                                if (tsr &TSR_ABT) dep->de_stat.ets_transAb++;
     709                                if (tsr &TSR_CRS) dep->de_stat.ets_carrSense++;
     710                                if (tsr &TSR_FU
     711                                        && ++dep->de_stat.ets_fifoUnder <= 10)
     712                                {
     713                                        printf("%s: fifo underrun\n",
     714                                                dep->de_name);
     715                                }
     716                                if (tsr &TSR_CDH
     717                                        && ++dep->de_stat.ets_CDheartbeat <= 10)
     718                                {
     719                                        printf("%s: CD heart beat failure\n",
     720                                                dep->de_name);
     721                                }
     722                                if (tsr &TSR_OWC) dep->de_stat.ets_OWC++;
    436723                        }
    437                        
    438                         sendq_tail = dep->de_sendq_tail;
    439                        
    440                         if (!(dep->de_sendq[sendq_tail].sq_filled)) {
    441                                 printf("PTX interrupt, but no frame to send\n");
     724                        sendq_tail= dep->de_sendq_tail;
     725
     726                        if (!(dep->de_sendq[sendq_tail].sq_filled))
     727                        {
     728                                /* Software bug? */
     729                                assert(!debug);
     730
     731                                /* Or hardware bug? */
     732                                printf(
     733                                "%s: transmit interrupt, but not sending\n",
     734                                        dep->de_name);
    442735                                continue;
    443736                        }
    444                        
    445                         dep->de_sendq[sendq_tail].sq_filled = false;
    446                        
     737                        dep->de_sendq[sendq_tail].sq_filled= 0;
    447738                        if (++sendq_tail == dep->de_sendq_nr)
    448                                 sendq_tail = 0;
    449                        
    450                         dep->de_sendq_tail = sendq_tail;
    451                        
    452                         if (dep->de_sendq[sendq_tail].sq_filled) {
    453                                 size = dep->de_sendq[sendq_tail].sq_size;
     739                                sendq_tail= 0;
     740                        dep->de_sendq_tail= sendq_tail;
     741                        if (dep->de_sendq[sendq_tail].sq_filled)
     742                        {
     743                                size= dep->de_sendq[sendq_tail].sq_size;
    454744                                outb_reg0(dep, DP_TPSR,
    455                                     dep->de_sendq[sendq_tail].sq_sendpage);
     745                                        dep->de_sendq[sendq_tail].sq_sendpage);
    456746                                outb_reg0(dep, DP_TBCR1, size >> 8);
    457                                 outb_reg0(dep, DP_TBCR0, size & 0xff);
     747                                outb_reg0(dep, DP_TBCR0, size &0xff);
    458748                                outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
    459749                        }
    460                        
    461                         dep->send_avail = false;
     750//                      if (dep->de_flags &DEF_SEND_AVAIL)
     751                                dp_send(dep);
     752                }
     753
     754                if (isr &ISR_PRX)
     755                {
     756                        /* Only call dp_recv if there is a read request */
     757//                      if (dep->de_flags) &DEF_READING)
     758                                dp_recv(dep);
    462759                }
    463760               
    464                 if (isr & ISR_PRX)
    465                         dp_recv(nil_phone, device_id, dep);
    466                
    467                 if (isr & ISR_RXE)
    468                         dep->de_stat.ets_recvErr++;
    469                
    470                 if (isr & ISR_CNT) {
     761                if (isr &ISR_RXE) dep->de_stat.ets_recvErr++;
     762                if (isr &ISR_CNT)
     763                {
    471764                        dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
    472765                        dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
    473766                        dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
    474767                }
    475                
    476                 if (isr & ISR_OVW)
     768                if (isr &ISR_OVW)
     769                {
    477770                        dep->de_stat.ets_OVW++;
    478                
    479                 if (isr & ISR_RDC) {
     771#if 0
     772                        {printW(); printf(
     773                                "%s: got overwrite warning\n", dep->de_name);}
     774#endif
     775/*                      if (dep->de_flags &DEF_READING)
     776                        {
     777                                printf(
     778"dp_check_ints: strange: overwrite warning and pending read request\n");
     779                                dp_recv(dep);
     780                        }
     781*/              }
     782                if (isr &ISR_RDC)
     783                {
    480784                        /* Nothing to do */
    481785                }
    482                
    483                 if (isr & ISR_RST) {
    484                         /*
    485                          * This means we got an interrupt but the ethernet
    486                          * chip is shutdown. We set the flag 'stopped'
     786                if (isr &ISR_RST)
     787                {
     788                        /* this means we got an interrupt but the ethernet
     789                         * chip is shutdown. We set the flag DEF_STOPPED,
    487790                         * and continue processing arrived packets. When the
    488791                         * receive buffer is empty, we reset the dp8390.
    489792                         */
    490                         dep->stopped = true;
     793#if 0
     794                         {printW(); printf(
     795                                "%s: NIC stopped\n", dep->de_name);}
     796#endif
     797                        dep->de_flags |= DEF_STOPPED;
    491798                        break;
    492799                }
    493         }
    494        
    495         if (dep->stopped) {
    496                 /*
    497                  * The chip is stopped, and all arrived
    498                  * frames are delivered.
     800                isr = inb_reg0(dep, DP_ISR);
     801        }
     802//      if ((dep->de_flags &(DEF_READING|DEF_STOPPED)) ==
     803//                                              (DEF_READING|DEF_STOPPED))
     804        if ((dep->de_flags &DEF_STOPPED) == DEF_STOPPED)
     805        {
     806                /* The chip is stopped, and all arrived packets are
     807                 * delivered.
    499808                 */
    500809                dp_reset(dep);
    501810        }
    502        
    503         dep->sending = false;
    504 }
    505 
    506 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst)
    507 {
    508         offset = page * DP_PAGESIZE + offset;
    509        
    510         outb_reg0(dep, DP_RBCR0, size & 0xff);
    511         outb_reg0(dep, DP_RBCR1, size >> 8);
    512         outb_reg0(dep, DP_RSAR0, offset & 0xff);
    513         outb_reg0(dep, DP_RSAR1, offset >> 8);
    514         outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    515        
    516         if (dep->de_16bit) {
    517                 assert((size % 2) == 0);
    518                 insw(dep->de_data_port, dst, size);
    519         } else
    520                 insb(dep->de_data_port, dst, size);
    521 }
    522 
    523 static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep)
     811}
     812
     813/*===========================================================================*
     814 *                              dp_recv                                      *
     815 *===========================================================================*/
     816static void dp_recv(dep)
     817dpeth_t *dep;
    524818{
    525819        dp_rcvhdr_t header;
     820        //unsigned pageno, curr, next;
    526821        int pageno, curr, next;
    527         size_t length;
     822        vir_bytes length;
    528823        int packet_processed, r;
    529         uint16_t eth_type;
    530        
    531         packet_processed = false;
     824        u16_t eth_type;
     825
     826        packet_processed = FALSE;
    532827        pageno = inb_reg0(dep, DP_BNRY) + 1;
    533         if (pageno == dep->de_stoppage)
    534                 pageno = dep->de_startpage;
    535        
    536         do {
     828        if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
     829
     830        do
     831        {
    537832                outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
    538833                curr = inb_reg1(dep, DP_CURR);
    539834                outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
    540                
    541                 if (curr == pageno)
    542                         break;
    543                
    544                 dp_getblock(dep, pageno, (size_t) 0, sizeof(header), &header);
    545                 dp_getblock(dep, pageno, sizeof(header) +
    546                     2 * sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
    547                
    548                 length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t);
     835
     836                if (curr == pageno) break;
     837
     838                (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
     839                        &header);
     840                (dep->de_getblockf)(dep, pageno, sizeof(header) +
     841                        2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
     842
     843                length = (header.dr_rbcl | (header.dr_rbch << 8)) -
     844                        sizeof(dp_rcvhdr_t);
    549845                next = header.dr_next;
    550                 if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) {
    551                         printf("Packet with strange length arrived: %zu\n", length);
     846                if (length < ETH_MIN_PACK_SIZE ||
     847                        length > ETH_MAX_PACK_SIZE_TAGGED)
     848                {
     849                        printf("%s: packet with strange length arrived: %d\n",
     850                                dep->de_name, (int) length);
    552851                        next= curr;
    553                 } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) {
    554                         printf("Strange next page\n");
     852                }
     853                else if (next < dep->de_startpage || next >= dep->de_stoppage)
     854                {
     855                        printf("%s: strange next page\n", dep->de_name);
    555856                        next= curr;
    556                 } else if (header.dr_status & RSR_FO) {
    557                         /*
    558                          * This is very serious, so we issue a warning and
    559                          * reset the buffers
     857                }
     858/*              else if (eth_type == eth_ign_proto)
     859                {
     860*/                      /* Hack: ignore packets of a given protocol, useful
     861                         * if you share a net with 80 computers sending
     862                         * Amoeba FLIP broadcasts.  (Protocol 0x8146.)
    560863                         */
    561                         printf("FIFO overrun, resetting receive buffer\n");
     864/*                      static int first= 1;
     865                        if (first)
     866                        {
     867                                first= 0;
     868                                printf("%s: dropping proto 0x%04x packets\n",
     869                                        dep->de_name,
     870                                        ntohs(eth_ign_proto));
     871                        }
     872                        dep->de_stat.ets_packetR++;
     873                }
     874*/              else if (header.dr_status &RSR_FO)
     875                {
     876                        /* This is very serious, so we issue a warning and
     877                         * reset the buffers */
     878                        printf("%s: fifo overrun, resetting receive buffer\n",
     879                                dep->de_name);
    562880                        dep->de_stat.ets_fifoOver++;
    563881                        next = curr;
    564                 } else if ((header.dr_status & RSR_PRX) && (dep->enabled)) {
    565                         r = dp_pkt2user(nil_phone, device_id, dep, pageno, length);
    566                         if (r != EOK)
     882                }
     883                else if ((header.dr_status &RSR_PRX) &&
     884                                           (dep->de_flags &DEF_ENABLED))
     885                {
     886//                      if (dep->de_safecopy_read)
     887//                              r = dp_pkt2user_s(dep, pageno, length);
     888//                      else
     889                                r = dp_pkt2user(dep, pageno, length);
     890                        if (r != OK)
    567891                                return;
    568                        
    569                         packet_processed = true;
     892
     893                        packet_processed = TRUE;
    570894                        dep->de_stat.ets_packetR++;
    571895                }
    572                
    573896                if (next == dep->de_startpage)
    574897                        outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
    575898                else
    576899                        outb_reg0(dep, DP_BNRY, next - 1);
    577                
     900
    578901                pageno = next;
    579         } while (!packet_processed);
    580 }
    581 
    582 static void dp_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size)
    583 {
    584         size_t ecount = size & ~1;
    585        
    586         if (dep->de_16bit) {
    587                 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
    588                 outb_reg0(dep, DP_RBCR1, ecount >> 8);
    589         } else {
    590                 outb_reg0(dep, DP_RBCR0, size & 0xff);
    591                 outb_reg0(dep, DP_RBCR1, size >> 8);
    592         }
    593        
    594         outb_reg0(dep, DP_RSAR0, nic_addr & 0xff);
     902        }
     903        while (!packet_processed);
     904}
     905
     906/*===========================================================================*
     907 *                              dp_send                                      *
     908 *===========================================================================*/
     909static void dp_send(dep)
     910dpeth_t *dep;
     911{
     912        packet_t *packet;
     913
     914//      if (!(dep->de_flags &DEF_SEND_AVAIL))
     915//              return;
     916
     917        if(dep->packet_queue){
     918                packet = dep->packet_queue;
     919                dep->packet_queue = pq_detach(packet);
     920                do_pwrite(dep, packet, TRUE);
     921                netif_pq_release(packet_get_id(packet));
     922                -- dep->packet_count;
     923        }
     924//      if(! dep->packet_queue){
     925//              dep->de_flags &= ~DEF_SEND_AVAIL;
     926//      }
     927/*      switch(dep->de_sendmsg.m_type)
     928        {
     929        case DL_WRITE:  do_vwrite(&dep->de_sendmsg, TRUE, FALSE);       break;
     930        case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE);        break;
     931        case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE);  break;
     932        default:
     933                panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
     934                break;
     935        }
     936*/
     937}
     938
     939/*===========================================================================*
     940 *                              dp_getblock                                  *
     941 *===========================================================================*/
     942static void dp_getblock(dep, page, offset, size, dst)
     943dpeth_t *dep;
     944int page;
     945size_t offset;
     946size_t size;
     947void *dst;
     948{
     949//      int r;
     950
     951        offset = page * DP_PAGESIZE + offset;
     952
     953        memcpy(dst, dep->de_locmem + offset, size);
     954}
     955
     956/*===========================================================================*
     957 *                              dp_pio8_getblock                             *
     958 *===========================================================================*/
     959static void dp_pio8_getblock(dep, page, offset, size, dst)
     960dpeth_t *dep;
     961int page;
     962size_t offset;
     963size_t size;
     964void *dst;
     965{
     966        offset = page * DP_PAGESIZE + offset;
     967        outb_reg0(dep, DP_RBCR0, size &0xFF);
     968        outb_reg0(dep, DP_RBCR1, size >> 8);
     969        outb_reg0(dep, DP_RSAR0, offset &0xFF);
     970        outb_reg0(dep, DP_RSAR1, offset >> 8);
     971        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
     972
     973        insb(dep->de_data_port, dst, size);
     974}
     975
     976/*===========================================================================*
     977 *                              dp_pio16_getblock                            *
     978 *===========================================================================*/
     979static void dp_pio16_getblock(dep, page, offset, size, dst)
     980dpeth_t *dep;
     981int page;
     982size_t offset;
     983size_t size;
     984void *dst;
     985{
     986        offset = page * DP_PAGESIZE + offset;
     987        outb_reg0(dep, DP_RBCR0, size &0xFF);
     988        outb_reg0(dep, DP_RBCR1, size >> 8);
     989        outb_reg0(dep, DP_RSAR0, offset &0xFF);
     990        outb_reg0(dep, DP_RSAR1, offset >> 8);
     991        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
     992
     993        assert (!(size &1));
     994        insw(dep->de_data_port, dst, size);
     995}
     996
     997/*===========================================================================*
     998 *                              dp_pkt2user                                  *
     999 *===========================================================================*/
     1000static int dp_pkt2user(dep, page, length)
     1001dpeth_t *dep;
     1002int page, length;
     1003{
     1004        int last, count;
     1005        packet_t *packet;
     1006
     1007//      if (!(dep->de_flags &DEF_READING))
     1008//              return EGENERIC;
     1009
     1010        packet = netif_packet_get_1(length);
     1011        if(! packet){
     1012                return ENOMEM;
     1013        }
     1014        dep->de_read_iovec.iod_iovec[0].iov_addr = (vir_bytes) packet_suffix(packet, length);
     1015        dep->de_read_iovec.iod_iovec[0].iov_size = length;
     1016        dep->de_read_iovec.iod_iovec_s = 1;
     1017        dep->de_read_iovec.iod_iovec_addr = (uintptr_t) NULL;
     1018
     1019        last = page + (length - 1) / DP_PAGESIZE;
     1020        if (last >= dep->de_stoppage)
     1021        {
     1022                count = (dep->de_stoppage - page) * DP_PAGESIZE -
     1023                        sizeof(dp_rcvhdr_t);
     1024
     1025                /* Save read_iovec since we need it twice. */
     1026                dep->de_tmp_iovec = dep->de_read_iovec;
     1027                (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
     1028                        sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
     1029                (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
     1030                        &dep->de_read_iovec, count, length - count);
     1031        }
     1032        else
     1033        {
     1034                (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
     1035                        sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
     1036        }
     1037
     1038        dep->de_read_s = length;
     1039        dep->de_flags |= DEF_PACK_RECV;
     1040//      dep->de_flags &= ~DEF_READING;
     1041
     1042        if(dep->received_count >= MAX_PACKETS){
     1043                netif_pq_release(packet_get_id(packet));
     1044                return ELIMIT;
     1045        }else{
     1046                if(pq_add(&dep->received_queue, packet, 0, 0) == EOK){
     1047                        ++ dep->received_count;
     1048                }else{
     1049                        netif_pq_release(packet_get_id(packet));
     1050                }
     1051        }
     1052        return OK;
     1053}
     1054
     1055/*===========================================================================*
     1056 *                              dp_user2nic                                  *
     1057 *===========================================================================*/
     1058static void dp_user2nic(dep, iovp, offset, nic_addr, count)
     1059dpeth_t *dep;
     1060iovec_dat_t *iovp;
     1061vir_bytes offset;
     1062int nic_addr;
     1063vir_bytes count;
     1064{
     1065        vir_bytes vir_hw;//, vir_user;
     1066        //int bytes, i, r;
     1067        int i, r;
     1068        vir_bytes bytes;
     1069
     1070        vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
     1071
     1072        i= 0;
     1073        while (count > 0)
     1074        {
     1075                if (i >= IOVEC_NR)
     1076                {
     1077                        dp_next_iovec(iovp);
     1078                        i= 0;
     1079                        continue;
     1080                }
     1081                assert(i < iovp->iod_iovec_s);
     1082                if (offset >= iovp->iod_iovec[i].iov_size)
     1083                {
     1084                        offset -= iovp->iod_iovec[i].iov_size;
     1085                        i++;
     1086                        continue;
     1087                }
     1088                bytes = iovp->iod_iovec[i].iov_size - offset;
     1089                if (bytes > count)
     1090                        bytes = count;
     1091
     1092                r= sys_vircopy(iovp->iod_proc_nr, D,
     1093                        iovp->iod_iovec[i].iov_addr + offset,
     1094                        SELF, D, vir_hw, bytes);
     1095                if (r != OK)
     1096                        panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
     1097
     1098                count -= bytes;
     1099                vir_hw += bytes;
     1100                offset += bytes;
     1101        }
     1102        assert(count == 0);
     1103}
     1104
     1105/*===========================================================================*
     1106 *                              dp_pio8_user2nic                             *
     1107 *===========================================================================*/
     1108static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
     1109dpeth_t *dep;
     1110iovec_dat_t *iovp;
     1111vir_bytes offset;
     1112int nic_addr;
     1113vir_bytes count;
     1114{
     1115//      phys_bytes phys_user;
     1116        int i;
     1117        vir_bytes bytes;
     1118
     1119        outb_reg0(dep, DP_ISR, ISR_RDC);
     1120
     1121        outb_reg0(dep, DP_RBCR0, count &0xFF);
     1122        outb_reg0(dep, DP_RBCR1, count >> 8);
     1123        outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
     1124        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
     1125        outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
     1126
     1127        i= 0;
     1128        while (count > 0)
     1129        {
     1130                if (i >= IOVEC_NR)
     1131                {
     1132                        dp_next_iovec(iovp);
     1133                        i= 0;
     1134                        continue;
     1135                }
     1136                assert(i < iovp->iod_iovec_s);
     1137                if (offset >= iovp->iod_iovec[i].iov_size)
     1138                {
     1139                        offset -= iovp->iod_iovec[i].iov_size;
     1140                        i++;
     1141                        continue;
     1142                }
     1143                bytes = iovp->iod_iovec[i].iov_size - offset;
     1144                if (bytes > count)
     1145                        bytes = count;
     1146
     1147                do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
     1148                        iovp->iod_iovec[i].iov_addr + offset, bytes);
     1149                count -= bytes;
     1150                offset += bytes;
     1151        }
     1152        assert(count == 0);
     1153
     1154        for (i= 0; i<100; i++)
     1155        {
     1156                if (inb_reg0(dep, DP_ISR) &ISR_RDC)
     1157                        break;
     1158        }
     1159        if (i == 100)
     1160        {
     1161                panic("", "dp8390: remote dma failed to complete", NO_NUM);
     1162        }
     1163}
     1164
     1165/*===========================================================================*
     1166 *                              dp_pio16_user2nic                            *
     1167 *===========================================================================*/
     1168static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
     1169dpeth_t *dep;
     1170iovec_dat_t *iovp;
     1171vir_bytes offset;
     1172int nic_addr;
     1173vir_bytes count;
     1174{
     1175        vir_bytes vir_user;
     1176        vir_bytes ecount;
     1177        int i, r, user_proc;
     1178        vir_bytes bytes;
     1179        //u8_t two_bytes[2];
     1180        u16_t two_bytes;
     1181        int odd_byte;
     1182
     1183        ecount= (count+1) &~1;
     1184        odd_byte= 0;
     1185
     1186        outb_reg0(dep, DP_ISR, ISR_RDC);
     1187        outb_reg0(dep, DP_RBCR0, ecount &0xFF);
     1188        outb_reg0(dep, DP_RBCR1, ecount >> 8);
     1189        outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
     1190        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
     1191        outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
     1192
     1193        i= 0;
     1194        while (count > 0)
     1195        {
     1196                if (i >= IOVEC_NR)
     1197                {
     1198                        dp_next_iovec(iovp);
     1199                        i= 0;
     1200                        continue;
     1201                }
     1202                assert(i < iovp->iod_iovec_s);
     1203                if (offset >= iovp->iod_iovec[i].iov_size)
     1204                {
     1205                        offset -= iovp->iod_iovec[i].iov_size;
     1206                        i++;
     1207                        continue;
     1208                }
     1209                bytes = iovp->iod_iovec[i].iov_size - offset;
     1210                if (bytes > count)
     1211                        bytes = count;
     1212
     1213                user_proc= iovp->iod_proc_nr;
     1214                vir_user= iovp->iod_iovec[i].iov_addr + offset;
     1215                if (odd_byte)
     1216                {
     1217                        r= sys_vircopy(user_proc, D, vir_user,
     1218                        //      SELF, D, (vir_bytes)&two_bytes[1], 1);
     1219                                SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]), 1);
     1220                        if (r != OK)
     1221                        {
     1222                                panic("DP8390",
     1223                                        "dp_pio16_user2nic: sys_vircopy failed",
     1224                                        r);
     1225                        }
     1226                        //outw(dep->de_data_port, *(u16_t *)two_bytes);
     1227                        outw(dep->de_data_port, two_bytes);
     1228                        count--;
     1229                        offset++;
     1230                        bytes--;
     1231                        vir_user++;
     1232                        odd_byte= 0;
     1233                        if (!bytes)
     1234                                continue;
     1235                }
     1236                ecount= bytes &~1;
     1237                if (ecount != 0)
     1238                {
     1239                        do_vir_outsw(dep->de_data_port, user_proc, vir_user,
     1240                                ecount);
     1241                        count -= ecount;
     1242                        offset += ecount;
     1243                        bytes -= ecount;
     1244                        vir_user += ecount;
     1245                }
     1246                if (bytes)
     1247                {
     1248                        assert(bytes == 1);
     1249                        r= sys_vircopy(user_proc, D, vir_user,
     1250                        //      SELF, D, (vir_bytes)&two_bytes[0], 1);
     1251                                SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]), 1);
     1252                        if (r != OK)
     1253                        {
     1254                                panic("DP8390",
     1255                                        "dp_pio16_user2nic: sys_vircopy failed",
     1256                                        r);
     1257                        }
     1258                        count--;
     1259                        offset++;
     1260                        bytes--;
     1261                        vir_user++;
     1262                        odd_byte= 1;
     1263                }
     1264        }
     1265        assert(count == 0);
     1266
     1267        if (odd_byte)
     1268                //outw(dep->de_data_port, *(u16_t *)two_bytes);
     1269                outw(dep->de_data_port, two_bytes);
     1270
     1271        for (i= 0; i<100; i++)
     1272        {
     1273                if (inb_reg0(dep, DP_ISR) &ISR_RDC)
     1274                        break;
     1275        }
     1276        if (i == 100)
     1277        {
     1278                panic("", "dp8390: remote dma failed to complete", NO_NUM);
     1279        }
     1280}
     1281
     1282/*===========================================================================*
     1283 *                              dp_nic2user                                  *
     1284 *===========================================================================*/
     1285static void dp_nic2user(dep, nic_addr, iovp, offset, count)
     1286dpeth_t *dep;
     1287int nic_addr;
     1288iovec_dat_t *iovp;
     1289vir_bytes offset;
     1290vir_bytes count;
     1291{
     1292        vir_bytes vir_hw;//, vir_user;
     1293        vir_bytes bytes;
     1294        int i, r;
     1295
     1296        vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
     1297
     1298        i= 0;
     1299        while (count > 0)
     1300        {
     1301                if (i >= IOVEC_NR)
     1302                {
     1303                        dp_next_iovec(iovp);
     1304                        i= 0;
     1305                        continue;
     1306                }
     1307                assert(i < iovp->iod_iovec_s);
     1308                if (offset >= iovp->iod_iovec[i].iov_size)
     1309                {
     1310                        offset -= iovp->iod_iovec[i].iov_size;
     1311                        i++;
     1312                        continue;
     1313                }
     1314                bytes = iovp->iod_iovec[i].iov_size - offset;
     1315                if (bytes > count)
     1316                        bytes = count;
     1317
     1318                r= sys_vircopy(SELF, D, vir_hw,
     1319                        iovp->iod_proc_nr, D,
     1320                        iovp->iod_iovec[i].iov_addr + offset, bytes);
     1321                if (r != OK)
     1322                        panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
     1323
     1324                count -= bytes;
     1325                vir_hw += bytes;
     1326                offset += bytes;
     1327        }
     1328        assert(count == 0);
     1329}
     1330
     1331/*===========================================================================*
     1332 *                              dp_pio8_nic2user                             *
     1333 *===========================================================================*/
     1334static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
     1335dpeth_t *dep;
     1336int nic_addr;
     1337iovec_dat_t *iovp;
     1338vir_bytes offset;
     1339vir_bytes count;
     1340{
     1341//      phys_bytes phys_user;
     1342        int i;
     1343        vir_bytes bytes;
     1344
     1345        outb_reg0(dep, DP_RBCR0, count &0xFF);
     1346        outb_reg0(dep, DP_RBCR1, count >> 8);
     1347        outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
    5951348        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    5961349        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
     1350
     1351        i= 0;
     1352        while (count > 0)
     1353        {
     1354                if (i >= IOVEC_NR)
     1355                {
     1356                        dp_next_iovec(iovp);
     1357                        i= 0;
     1358                        continue;
     1359                }
     1360                assert(i < iovp->iod_iovec_s);
     1361                if (offset >= iovp->iod_iovec[i].iov_size)
     1362                {
     1363                        offset -= iovp->iod_iovec[i].iov_size;
     1364                        i++;
     1365                        continue;
     1366                }
     1367                bytes = iovp->iod_iovec[i].iov_size - offset;
     1368                if (bytes > count)
     1369                        bytes = count;
     1370
     1371                do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
     1372                        iovp->iod_iovec[i].iov_addr + offset, bytes);
     1373                count -= bytes;
     1374                offset += bytes;
     1375        }
     1376        assert(count == 0);
     1377}
     1378
     1379/*===========================================================================*
     1380 *                              dp_pio16_nic2user                            *
     1381 *===========================================================================*/
     1382static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
     1383dpeth_t *dep;
     1384int nic_addr;
     1385iovec_dat_t *iovp;
     1386vir_bytes offset;
     1387vir_bytes count;
     1388{
     1389        vir_bytes vir_user;
     1390        vir_bytes ecount;
     1391        int i, r, user_proc;
     1392        vir_bytes bytes;
     1393        //u8_t two_bytes[2];
     1394        u16_t two_bytes;
     1395        int odd_byte;
     1396
     1397        ecount= (count+1) &~1;
     1398        odd_byte= 0;
     1399
     1400        outb_reg0(dep, DP_RBCR0, ecount &0xFF);
     1401        outb_reg0(dep, DP_RBCR1, ecount >> 8);
     1402        outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
     1403        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
     1404        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
     1405
     1406        i= 0;
     1407        while (count > 0)
     1408        {
     1409                if (i >= IOVEC_NR)
     1410                {
     1411                        dp_next_iovec(iovp);
     1412                        i= 0;
     1413                        continue;
     1414                }
     1415                assert(i < iovp->iod_iovec_s);
     1416                if (offset >= iovp->iod_iovec[i].iov_size)
     1417                {
     1418                        offset -= iovp->iod_iovec[i].iov_size;
     1419                        i++;
     1420                        continue;
     1421                }
     1422                bytes = iovp->iod_iovec[i].iov_size - offset;
     1423                if (bytes > count)
     1424                        bytes = count;
     1425
     1426                user_proc= iovp->iod_proc_nr;
     1427                vir_user= iovp->iod_iovec[i].iov_addr + offset;
     1428                if (odd_byte)
     1429                {
     1430                        //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
     1431                        r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]),
     1432                                user_proc, D, vir_user,  1);
     1433                        if (r != OK)
     1434                        {
     1435                                panic("DP8390",
     1436                                        "dp_pio16_nic2user: sys_vircopy failed",
     1437                                        r);
     1438                        }
     1439                        count--;
     1440                        offset++;
     1441                        bytes--;
     1442                        vir_user++;
     1443                        odd_byte= 0;
     1444                        if (!bytes)
     1445                                continue;
     1446                }
     1447                ecount= bytes &~1;
     1448                if (ecount != 0)
     1449                {
     1450                        do_vir_insw(dep->de_data_port, user_proc, vir_user,
     1451                                ecount);
     1452                        count -= ecount;
     1453                        offset += ecount;
     1454                        bytes -= ecount;
     1455                        vir_user += ecount;
     1456                }
     1457                if (bytes)
     1458                {
     1459                        assert(bytes == 1);
     1460                        //*(u16_t *)two_bytes= inw(dep->de_data_port);
     1461                        two_bytes= inw(dep->de_data_port);
     1462                        //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
     1463                        r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]),
     1464                                user_proc, D, vir_user,  1);
     1465                        if (r != OK)
     1466                        {
     1467                                panic("DP8390",
     1468                                        "dp_pio16_nic2user: sys_vircopy failed",
     1469                                        r);
     1470                        }
     1471                        count--;
     1472                        offset++;
     1473                        bytes--;
     1474                        vir_user++;
     1475                        odd_byte= 1;
     1476                }
     1477        }
     1478        assert(count == 0);
     1479}
     1480
     1481/*===========================================================================*
     1482 *                              dp_next_iovec                                *
     1483 *===========================================================================*/
     1484static void dp_next_iovec(iovp)
     1485iovec_dat_t *iovp;
     1486{
     1487        assert(iovp->iod_iovec_s > IOVEC_NR);
     1488
     1489        iovp->iod_iovec_s -= IOVEC_NR;
     1490
     1491        iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
     1492
     1493        get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
     1494                (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
     1495                sizeof(iovec_t), iovp->iod_iovec);
     1496}
     1497
     1498/*===========================================================================*
     1499 *                              conf_hw                                      *
     1500 *===========================================================================*/
     1501static void conf_hw(dep)
     1502dpeth_t *dep;
     1503{
     1504//      static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0        /* ,... */};
     1505
     1506//      int ifnr;
     1507//      dp_conf_t *dcp;
     1508
     1509//      dep->de_mode= DEM_DISABLED;     /* Superfluous */
     1510//      ifnr= dep-de_table;
     1511
     1512//      dcp= &dp_conf[ifnr];
     1513//      update_conf(dep, dcp);
     1514//      if (dep->de_mode != DEM_ENABLED)
     1515//              return;
     1516        if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
     1517        {
     1518                printf("%s: No ethernet card found at %#lx\n",
     1519                    dep->de_name, dep->de_base_port);
     1520                dep->de_mode= DEM_DISABLED;
     1521                return;
     1522        }
     1523
     1524/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
     1525
     1526        dep->de_mode = DEM_ENABLED;
     1527
     1528        dep->de_flags = DEF_EMPTY;
     1529//      dep->de_stat = empty_stat;
     1530}
     1531
     1532/*===========================================================================*
     1533 *                              map_hw_buffer                                *
     1534 *===========================================================================*/
     1535static void map_hw_buffer(dep)
     1536dpeth_t *dep;
     1537{
     1538//      int r;
     1539//      size_t o, size;
     1540//      char *buf, *abuf;
     1541
     1542        if (dep->de_prog_IO)
     1543        {
     1544#if 0
     1545                if(debug){
     1546                        printf(
     1547                        "map_hw_buffer: programmed I/O, no need to map buffer\n");
     1548                }
     1549#endif
     1550                dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
     1551                return;
     1552        }else{
     1553                printf("map_hw_buffer: no buffer!\n");
     1554        }
     1555
     1556//      size = dep->de_ramsize + PAGE_SIZE;     /* Add PAGE_SIZE for
     1557//                                               * alignment
     1558//                                               */
     1559//      buf= malloc(size);
     1560//      if (buf == NULL)
     1561//              panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
     1562//      o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
     1563//      abuf= buf + o;
     1564//      printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
     1565
     1566//      r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
     1567//                      dep->de_ramsize, (phys_bytes)dep->de_linmem);
     1568//      if (r != OK)
     1569//              panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
     1570//      dep->de_locmem = abuf;
     1571}
     1572
     1573/*===========================================================================*
     1574 *                              reply                                        *
     1575 *===========================================================================*/
     1576static void reply(dep, err, may_block)
     1577dpeth_t *dep;
     1578int err;
     1579int may_block;
     1580{
     1581/*      message reply;
     1582        int status;
     1583        int r;
     1584
     1585        status = 0;
     1586        if (dep->de_flags &DEF_PACK_SEND)
     1587                status |= DL_PACK_SEND;
     1588        if (dep->de_flags &DEF_PACK_RECV)
     1589                status |= DL_PACK_RECV;
     1590
     1591        reply.m_type = DL_TASK_REPLY;
     1592        reply.DL_PORT = dep - de_table;
     1593        reply.DL_PROC = dep->de_client;
     1594        reply.DL_STAT = status | ((u32_t) err << 16);
     1595        reply.DL_COUNT = dep->de_read_s;
     1596        reply.DL_CLCK = 0;      *//* Don't know */
     1597/*      r= send(dep->de_client, &reply);
     1598
     1599        if (r == ELOCKED && may_block)
     1600        {
     1601#if 0
     1602                printf("send locked\n");
     1603#endif
     1604                return;
     1605        }
     1606
     1607        if (r < 0)
     1608                panic("", "dp8390: send failed:", r);
    5971609       
    598         if (dep->de_16bit) {
    599                 void *ptr = buf + offset;
    600                
    601                 if (ecount != 0) {
    602                         insw(dep->de_data_port, ptr, ecount);
    603                         size -= ecount;
    604                         offset += ecount;
    605                         ptr += ecount;
    606                 }
    607                
    608                 if (size) {
    609                         assert(size == 1);
    610                        
    611                         uint16_t two_bytes = inw(dep->de_data_port);
    612                         memcpy(ptr, &(((uint8_t *) &two_bytes)[0]), 1);
    613                 }
    614         } else
    615                 insb(dep->de_data_port, buf + offset, size);
    616 }
    617 
    618 static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length)
    619 {
    620         int last, count;
    621         packet_t *packet;
    622        
    623         packet = netif_packet_get_1(length);
    624         if (!packet)
    625                 return ENOMEM;
    626        
    627         void *buf = packet_suffix(packet, length);
    628        
    629         last = page + (length - 1) / DP_PAGESIZE;
    630         if (last >= dep->de_stoppage) {
    631                 count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t);
    632                
    633                 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t),
    634                     buf, 0, count);
    635                 dp_nic2user(dep, dep->de_startpage * DP_PAGESIZE,
    636                     buf, count, length - count);
    637         } else {
    638                 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t),
    639                     buf, 0, length);
    640         }
    641        
    642         nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE);
    643        
    644         return EOK;
    645 }
    646 
    647 static void conf_hw(dpeth_t *dep)
    648 {
    649         if (!ne_probe(dep)) {
    650                 printf("No ethernet card found at %#lx\n", dep->de_base_port);
    651                 dep->up = false;
    652                 return;
    653         }
    654        
    655         dep->up = true;
    656         dep->enabled = false;
    657         dep->stopped = false;
    658         dep->sending = false;
    659         dep->send_avail = false;
     1610*/      dep->de_read_s = 0;
     1611//      dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
     1612}
     1613
     1614/*===========================================================================*
     1615 *                              get_userdata                                 *
     1616 *===========================================================================*/
     1617static void get_userdata(user_proc, user_addr, count, loc_addr)
     1618int user_proc;
     1619vir_bytes user_addr;
     1620vir_bytes count;
     1621void *loc_addr;
     1622{
     1623        int r;
     1624
     1625        r= sys_vircopy(user_proc, D, user_addr,
     1626                SELF, D, (vir_bytes)loc_addr, count);
     1627        if (r != OK)
     1628                panic("DP8390", "get_userdata: sys_vircopy failed", r);
    6601629}
    6611630
     
    6631632{
    6641633        size_t i;
    665        
    666         for (i = 0; i < size; i++)
     1634
     1635        for(i = 0; i < size; ++ i){
    6671636                *((uint8_t *) buf + i) = inb(port);
     1637        }
    6681638}
    6691639
     
    6711641{
    6721642        size_t i;
    673        
    674         for (i = 0; i * 2 < size; i++)
     1643
     1644        for(i = 0; i * 2 < size; ++ i){
    6751645                *((uint16_t *) buf + i) = inw(port);
     1646        }
    6761647}
    6771648
     
    6791650{
    6801651        size_t i;
    681        
    682         for (i = 0; i < size; i++)
     1652
     1653        for(i = 0; i < size; ++ i){
    6831654                outb(port, *((uint8_t *) buf + i));
     1655        }
    6841656}
    6851657
     
    6871659{
    6881660        size_t i;
    689        
    690         for (i = 0; i * 2 < size; i++)
     1661
     1662        for(i = 0; i * 2 < size; ++ i){
    6911663                outw(port, *((uint16_t *) buf + i));
    692 }
     1664        }
     1665}
     1666
     1667/*
     1668 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
     1669 */
    6931670
    6941671/** @}
Note: See TracChangeset for help on using the changeset viewer.