Subversion Repositories HelenOS

Rev

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