Subversion Repositories HelenOS

Rev

Rev 4743 | Details | Compare with Previous | Last modification | View Log | RSS feed

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