Subversion Repositories HelenOS

Rev

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