Changeset ae1f70e in mainline for uspace/srv/hw/netif/dp8390/dp8390.c


Ignore:
Timestamp:
2011-01-07T08:54:28Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0f191a2, 8f8a0cd6
Parents:
f03d3786 (diff), 3d5e190 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

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

    rf03d3786 rae1f70e  
    11/*
    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:
    3  *
    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
    8  *
    9  *
    10  * Disclaimer
    11  *
    12  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
     2 * Copyright (c) 2009 Lukas Mejdrech
     3 * Copyright (c) 2011 Martin Decky
     4 * All rights reserved.
     5 *
     6 * Redistribution and use in source and binary forms, with or without
     7 * modification, are permitted provided that the following conditions
     8 * are met:
     9 *
     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.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    1319 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    1420 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    15  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    1622 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1723 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     
    2026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    2127 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    22  *
    23  * Changes:
    24  *  2009 ported to HelenOS, Lukas Mejdrech
     28 */
     29
     30/*
     31 * This code is based upon the NE2000 driver for MINIX,
     32 * distributed according to a BSD-style license.
     33 *
     34 * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
     35 * Copyright (c) 1992, 1994 Philip Homburg
     36 * Copyright (c) 1996 G. Falzoni
     37 *
    2538 */
    2639
     
    3649#include <byteorder.h>
    3750#include <errno.h>
    38 
    3951#include <netif_local.h>
    4052#include <net/packet.h>
     53#include <nil_interface.h>
    4154#include <packet_client.h>
    42 
    4355#include "dp8390_drv.h"
    4456#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"
    5957#include "dp8390.h"
    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  */
    67 int queue_packet(dpeth_t * dep, packet_t *packet);
    68 
    69 /** Reads a memory block byte by byte.
     58#include "ne2000.h"
     59
     60/** Read a memory block byte by byte.
     61 *
    7062 *  @param[in] port The source address.
    7163 *  @param[out] buf The destination buffer.
    7264 *  @param[in] size The memory block size in bytes.
     65 *
    7366 */
    7467static void outsb(port_t port, void * buf, size_t size);
    7568
    76 /** Reads a memory block word by word.
     69/** Read a memory block word by word.
     70 *
    7771 *  @param[in] port The source address.
    7872 *  @param[out] buf The destination buffer.
    7973 *  @param[in] size The memory block size in bytes.
     74 *
    8075 */
    8176static void outsw(port_t port, void * buf, size_t size);
    8277
    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
     78/*
     79 * Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
    12080 * on writes to the CR register. Additional CR_STAs do not appear to hurt
    121  * genuine dp8390s
    122  */
    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 
    214 int do_probe(dpeth_t * dep){
     81 * genuine dp8390s.
     82 */
     83#define CR_EXTRA  CR_STA
     84
     85static void dp_init(dpeth_t *dep);
     86static void dp_reinit(dpeth_t *dep);
     87static void dp_reset(dpeth_t *dep);
     88static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep);
     89static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length);
     90static void conf_hw(dpeth_t *dep);
     91static void insb(port_t port, void *buf, size_t size);
     92static void insw(port_t port, void *buf, size_t size);
     93
     94int do_probe(dpeth_t *dep)
     95{
    21596        /* This is the default, try to (re)locate the device. */
    21697        conf_hw(dep);
    217         if (dep->de_mode == DEM_DISABLED)
    218         {
     98        if (!dep->up)
    21999                /* Probe failed, or the device is configured off. */
    220                 return EXDEV;//ENXIO;
    221         }
    222         if (dep->de_mode == DEM_ENABLED)
     100                return EXDEV;
     101       
     102        if (dep->up)
    223103                dp_init(dep);
     104       
    224105        return EOK;
    225106}
    226107
    227 /*===========================================================================*
    228  *                              dp8390_dump                                  *
    229  *===========================================================================*/
    230 void 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  *===========================================================================*/
    282 int do_init(dpeth_t * dep, int mode){
    283         if (dep->de_mode == DEM_DISABLED)
    284         {
    285                 // might call do_probe()
     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 */
     116int do_init(dpeth_t *dep)
     117{
     118        if (!dep->up)
     119                /* FIXME: Perhaps call do_probe()? */
    286120                return EXDEV;
    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;
     121       
     122        assert(dep->up);
     123        assert(dep->enabled);
     124       
    315125        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);
    323126        return EOK;
    324127}
    325128
    326 /*===========================================================================*
    327  *                              do_stop                                      *
    328  *===========================================================================*/
    329 void do_stop(dpeth_t * dep){
    330         if((dep->de_mode != DEM_SINK) && (dep->de_mode == DEM_ENABLED) && (dep->de_flags &DEF_ENABLED)){
     129void do_stop(dpeth_t *dep)
     130{
     131        if ((dep->up) && (dep->enabled)) {
    331132                outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    332                 (dep->de_stopf)(dep);
    333 
    334                 dep->de_flags = DEF_EMPTY;
    335         }
    336 }
    337 
    338 int 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  *===========================================================================*/
    363 int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int)
    364 {
    365 //      int port, count, size;
     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
     142static 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
     191int do_pwrite(dpeth_t *dep, packet_t *packet, int from_int)
     192{
    366193        int size;
    367194        int sendq_head;
    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 */
     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);
    430217        size = packet_get_data_length(packet);
    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);
     218       
     219        if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) {
     220                fprintf(stderr, "dp8390: invalid packet size\n");
    439221                return EINVAL;
    440222        }
    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         {
     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) {
    447229                outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
    448230                outb_reg0(dep, DP_TBCR1, size >> 8);
    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;
     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;
    454235       
    455236        if (++sendq_head == dep->de_sendq_nr)
    456                 sendq_head= 0;
     237                sendq_head = 0;
     238       
    457239        assert(sendq_head < SENDQ_NR);
    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          */
     240        dep->de_sendq_head = sendq_head;
     241        dep->sending = true;
     242       
    465243        if (from_int)
    466244                return EOK;
    467         reply(dep, OK, FALSE);
    468 
    469         assert(dep->de_mode == DEM_ENABLED);
    470         assert(dep->de_flags &DEF_ENABLED);
     245       
     246        dep->sending = false;
     247       
    471248        return EOK;
    472249}
    473250
    474 /*===========================================================================*
    475  *                              dp_init                                      *
    476  *===========================================================================*/
    477 void dp_init(dep)
    478 dpeth_t *dep;
     251void dp_init(dpeth_t *dep)
    479252{
    480253        int dp_rcr_reg;
    481         int i;//, r;
    482 
     254        int i;
     255       
    483256        /* General initialization */
    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
     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
    501269         * in reference manual ("DP8390D/NS32490D NIC Network Interface
    502270         * Controller", National Semiconductor, July 1995, Page 29).
    503271         */
     272       
    504273        /* Step 1: */
    505274        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
     275       
    506276        /* Step 2: */
    507277        if (dep->de_16bit)
     
    509279        else
    510280                outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
     281       
    511282        /* Step 3: */
    512283        outb_reg0(dep, DP_RBCR0, 0);
    513284        outb_reg0(dep, DP_RBCR1, 0);
     285       
    514286        /* Step 4: */
    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;
     287        dp_rcr_reg = RCR_AB;  /* Enable broadcasts */
     288       
    522289        outb_reg0(dep, DP_RCR, dp_rcr_reg);
     290       
    523291        /* Step 5: */
    524292        outb_reg0(dep, DP_TCR, TCR_INTERNAL);
     293       
    525294        /* Step 6: */
    526295        outb_reg0(dep, DP_BNRY, dep->de_startpage);
    527296        outb_reg0(dep, DP_PSTART, dep->de_startpage);
    528297        outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
     298       
    529299        /* Step 7: */
    530300        outb_reg0(dep, DP_ISR, 0xFF);
     301       
    531302        /* Step 8: */
    532303        outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
    533                 IMR_OVWE | IMR_CNTE);
     304            IMR_OVWE | IMR_CNTE);
     305       
    534306        /* Step 9: */
    535307        outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
    536 
     308       
    537309        outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
    538310        outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
     
    541313        outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
    542314        outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
    543 
     315       
    544316        outb_reg1(dep, DP_MAR0, 0xff);
    545317        outb_reg1(dep, DP_MAR1, 0xff);
     
    550322        outb_reg1(dep, DP_MAR6, 0xff);
    551323        outb_reg1(dep, DP_MAR7, 0xff);
    552 
     324       
    553325        outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
     326       
    554327        /* Step 10: */
    555328        outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
     329       
    556330        /* Step 11: */
    557331        outb_reg0(dep, DP_TCR, TCR_NORMAL);
    558 
    559         inb_reg0(dep, DP_CNTR0);                /* reset counters by reading */
     332       
     333        inb_reg0(dep, DP_CNTR0);  /* Reset counters by reading */
    560334        inb_reg0(dep, DP_CNTR1);
    561335        inb_reg0(dep, DP_CNTR2);
    562 
     336       
    563337        /* Finish the initialization. */
    564         dep->de_flags |= DEF_ENABLED;
    565         for (i= 0; i<dep->de_sendq_nr; i++)
     338        dep->enabled = true;
     339        for (i = 0; i < dep->de_sendq_nr; i++)
    566340                dep->de_sendq[i].sq_filled= 0;
    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  *===========================================================================*/
    613 static void dp_reinit(dep)
    614 dpeth_t *dep;
     341       
     342        dep->de_sendq_head = 0;
     343        dep->de_sendq_tail = 0;
     344}
     345
     346static void dp_reinit(dpeth_t *dep)
    615347{
    616348        int dp_rcr_reg;
    617 
     349       
    618350        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
    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;
     351       
     352        /* Enable broadcasts */
     353        dp_rcr_reg = RCR_AB;
     354       
    627355        outb_reg0(dep, DP_RCR, dp_rcr_reg);
    628356}
    629357
    630 /*===========================================================================*
    631  *                              dp_reset                                     *
    632  *===========================================================================*/
    633 static void dp_reset(dep)
    634 dpeth_t *dep;
     358static void dp_reset(dpeth_t *dep)
    635359{
    636360        int i;
    637 
     361       
    638362        /* Stop chip */
    639363        outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    640364        outb_reg0(dep, DP_RBCR0, 0);
    641365        outb_reg0(dep, DP_RBCR1, 0);
    642         for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)
     366       
     367        for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
    643368                ; /* Do nothing */
    644         outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
    645         outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
     369       
     370        outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
     371        outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT);
    646372        outb_reg0(dep, DP_TCR, TCR_NORMAL);
    647 
    648         /* Acknowledge the ISR_RDC (remote dma) interrupt. */
    649         for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
     373       
     374        /* Acknowledge the ISR_RDC (remote DMA) interrupt. */
     375        for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
    650376                ; /* Do nothing */
    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
     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
    654382         * pretend that the packet is processed. Higher layers will
    655383         * retransmit if the packet wasn't actually sent.
    656384         */
    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  *===========================================================================*/
    667 void dp_check_ints(dep, isr)
    668 dpeth_t *dep;
    669 int isr;
    670 {
    671         int /*isr,*/ tsr;
     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
     395static uint8_t isr_acknowledge(dpeth_t *dep)
     396{
     397        uint8_t isr = inb_reg0(dep, DP_ISR);
     398        if (isr != 0)
     399                outb_reg0(dep, DP_ISR, isr);
     400       
     401        return isr;
     402}
     403
     404void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, uint8_t isr)
     405{
     406        int tsr;
    672407        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;
    682                 outb_reg0(dep, DP_ISR, isr);
    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
     408       
     409        for (; (isr & 0x7f) != 0; isr = isr_acknowledge(dep)) {
     410                if (isr & (ISR_PTX | ISR_TXE)) {
     411                        if (isr & ISR_TXE)
    690412                                dep->de_stat.ets_sendErr++;
     413                        else {
     414                                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++;
    691436                        }
    692                         else
    693                         {
    694                                 tsr = inb_reg0(dep, DP_TSR);
    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++;
    723                         }
    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);
     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");
    735442                                continue;
    736443                        }
    737                         dep->de_sendq[sendq_tail].sq_filled= 0;
     444                       
     445                        dep->de_sendq[sendq_tail].sq_filled = false;
     446                       
    738447                        if (++sendq_tail == dep->de_sendq_nr)
    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;
     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;
    744454                                outb_reg0(dep, DP_TPSR,
    745                                         dep->de_sendq[sendq_tail].sq_sendpage);
     455                                    dep->de_sendq[sendq_tail].sq_sendpage);
    746456                                outb_reg0(dep, DP_TBCR1, size >> 8);
    747                                 outb_reg0(dep, DP_TBCR0, size &0xff);
     457                                outb_reg0(dep, DP_TBCR0, size & 0xff);
    748458                                outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
    749459                        }
    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);
    759                 }
    760                
    761                 if (isr &ISR_RXE) dep->de_stat.ets_recvErr++;
    762                 if (isr &ISR_CNT)
    763                 {
     460                       
     461                        dep->send_avail = false;
     462                }
     463               
     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) {
    764471                        dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
    765472                        dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
    766473                        dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
    767474                }
    768                 if (isr &ISR_OVW)
    769                 {
     475               
     476                if (isr & ISR_OVW)
    770477                        dep->de_stat.ets_OVW++;
    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                 {
     478               
     479                if (isr & ISR_RDC) {
    784480                        /* Nothing to do */
    785481                }
    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,
     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'
    790487                         * and continue processing arrived packets. When the
    791488                         * receive buffer is empty, we reset the dp8390.
    792489                         */
    793 #if 0
    794                          {printW(); printf(
    795                                 "%s: NIC stopped\n", dep->de_name);}
    796 #endif
    797                         dep->de_flags |= DEF_STOPPED;
     490                        dep->stopped = true;
    798491                        break;
    799492                }
    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.
     493        }
     494       
     495        if (dep->stopped) {
     496                /*
     497                 * The chip is stopped, and all arrived
     498                 * frames are delivered.
    808499                 */
    809500                dp_reset(dep);
    810501        }
    811 }
    812 
    813 /*===========================================================================*
    814  *                              dp_recv                                      *
    815  *===========================================================================*/
    816 static void dp_recv(dep)
    817 dpeth_t *dep;
     502       
     503        dep->sending = false;
     504}
     505
     506static 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
     523static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep)
    818524{
    819525        dp_rcvhdr_t header;
    820         //unsigned pageno, curr, next;
    821526        int pageno, curr, next;
    822         vir_bytes length;
     527        size_t length;
    823528        int packet_processed, r;
    824         u16_t eth_type;
    825 
    826         packet_processed = FALSE;
     529        uint16_t eth_type;
     530       
     531        packet_processed = false;
    827532        pageno = inb_reg0(dep, DP_BNRY) + 1;
    828         if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
    829 
    830         do
    831         {
     533        if (pageno == dep->de_stoppage)
     534                pageno = dep->de_startpage;
     535       
     536        do {
    832537                outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
    833538                curr = inb_reg1(dep, DP_CURR);
    834539                outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
    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);
     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);
    845549                next = header.dr_next;
    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);
     550                if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) {
     551                        printf("Packet with strange length arrived: %zu\n", length);
    851552                        next= curr;
    852                 }
    853                 else if (next < dep->de_startpage || next >= dep->de_stoppage)
    854                 {
    855                         printf("%s: strange next page\n", dep->de_name);
     553                } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) {
     554                        printf("Strange next page\n");
    856555                        next= curr;
    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.)
     556                } else if (header.dr_status & RSR_FO) {
     557                        /*
     558                         * This is very serious, so we issue a warning and
     559                         * reset the buffers
    863560                         */
    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);
     561                        printf("FIFO overrun, resetting receive buffer\n");
    880562                        dep->de_stat.ets_fifoOver++;
    881563                        next = curr;
    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)
     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)
    891567                                return;
    892 
    893                         packet_processed = TRUE;
     568                       
     569                        packet_processed = true;
    894570                        dep->de_stat.ets_packetR++;
    895571                }
     572               
    896573                if (next == dep->de_startpage)
    897574                        outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
    898575                else
    899576                        outb_reg0(dep, DP_BNRY, next - 1);
    900 
     577               
    901578                pageno = next;
    902         }
    903         while (!packet_processed);
    904 }
    905 
    906 /*===========================================================================*
    907  *                              dp_send                                      *
    908  *===========================================================================*/
    909 static void dp_send(dep)
    910 dpeth_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  *===========================================================================*/
    942 static void dp_getblock(dep, page, offset, size, dst)
    943 dpeth_t *dep;
    944 int page;
    945 size_t offset;
    946 size_t size;
    947 void *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  *===========================================================================*/
    959 static void dp_pio8_getblock(dep, page, offset, size, dst)
    960 dpeth_t *dep;
    961 int page;
    962 size_t offset;
    963 size_t size;
    964 void *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);
     579        } while (!packet_processed);
     580}
     581
     582static 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);
     595        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    971596        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  *===========================================================================*/
    979 static void dp_pio16_getblock(dep, page, offset, size, dst)
    980 dpeth_t *dep;
    981 int page;
    982 size_t offset;
    983 size_t size;
    984 void *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  *===========================================================================*/
    1000 static int dp_pkt2user(dep, page, length)
    1001 dpeth_t *dep;
    1002 int page, length;
     597       
     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
     618static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length)
    1003619{
    1004620        int last, count;
    1005621        packet_t *packet;
    1006 
    1007 //      if (!(dep->de_flags &DEF_READING))
    1008 //              return EGENERIC;
    1009 
     622       
    1010623        packet = netif_packet_get_1(length);
    1011         if(! packet){
     624        if (!packet)
    1012625                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 
     626       
     627        void *buf = packet_suffix(packet, length);
     628       
    1019629        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  *===========================================================================*/
    1058 static void dp_user2nic(dep, iovp, offset, nic_addr, count)
    1059 dpeth_t *dep;
    1060 iovec_dat_t *iovp;
    1061 vir_bytes offset;
    1062 int nic_addr;
    1063 vir_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  *===========================================================================*/
    1108 static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
    1109 dpeth_t *dep;
    1110 iovec_dat_t *iovp;
    1111 vir_bytes offset;
    1112 int nic_addr;
    1113 vir_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  *===========================================================================*/
    1168 static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
    1169 dpeth_t *dep;
    1170 iovec_dat_t *iovp;
    1171 vir_bytes offset;
    1172 int nic_addr;
    1173 vir_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  *===========================================================================*/
    1285 static void dp_nic2user(dep, nic_addr, iovp, offset, count)
    1286 dpeth_t *dep;
    1287 int nic_addr;
    1288 iovec_dat_t *iovp;
    1289 vir_bytes offset;
    1290 vir_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  *===========================================================================*/
    1334 static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
    1335 dpeth_t *dep;
    1336 int nic_addr;
    1337 iovec_dat_t *iovp;
    1338 vir_bytes offset;
    1339 vir_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);
    1348         outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    1349         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  *===========================================================================*/
    1382 static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
    1383 dpeth_t *dep;
    1384 int nic_addr;
    1385 iovec_dat_t *iovp;
    1386 vir_bytes offset;
    1387 vir_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  *===========================================================================*/
    1484 static void dp_next_iovec(iovp)
    1485 iovec_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  *===========================================================================*/
    1501 static void conf_hw(dep)
    1502 dpeth_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;
     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
     647static 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;
    1521652                return;
    1522653        }
    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  *===========================================================================*/
    1535 static void map_hw_buffer(dep)
    1536 dpeth_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  *===========================================================================*/
    1576 static void reply(dep, err, may_block)
    1577 dpeth_t *dep;
    1578 int err;
    1579 int 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);
    1609        
    1610 */      dep->de_read_s = 0;
    1611 //      dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
    1612 }
    1613 
    1614 /*===========================================================================*
    1615  *                              get_userdata                                 *
    1616  *===========================================================================*/
    1617 static void get_userdata(user_proc, user_addr, count, loc_addr)
    1618 int user_proc;
    1619 vir_bytes user_addr;
    1620 vir_bytes count;
    1621 void *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);
     654       
     655        dep->up = true;
     656        dep->enabled = false;
     657        dep->stopped = false;
     658        dep->sending = false;
     659        dep->send_avail = false;
    1629660}
    1630661
     
    1632663{
    1633664        size_t i;
    1634 
    1635         for(i = 0; i < size; ++ i){
     665       
     666        for (i = 0; i < size; i++)
    1636667                *((uint8_t *) buf + i) = inb(port);
    1637         }
    1638668}
    1639669
     
    1641671{
    1642672        size_t i;
    1643 
    1644         for(i = 0; i * 2 < size; ++ i){
     673       
     674        for (i = 0; i * 2 < size; i++)
    1645675                *((uint16_t *) buf + i) = inw(port);
    1646         }
    1647676}
    1648677
     
    1650679{
    1651680        size_t i;
    1652 
    1653         for(i = 0; i < size; ++ i){
     681       
     682        for (i = 0; i < size; i++)
    1654683                outb(port, *((uint8_t *) buf + i));
    1655         }
    1656684}
    1657685
     
    1659687{
    1660688        size_t i;
    1661 
    1662         for(i = 0; i * 2 < size; ++ i){
     689       
     690        for (i = 0; i * 2 < size; i++)
    1663691                outw(port, *((uint16_t *) buf + i));
    1664         }
    1665 }
    1666 
    1667 /*
    1668  * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
    1669  */
     692}
    1670693
    1671694/** @}
Note: See TracChangeset for help on using the changeset viewer.