Subversion Repositories HelenOS

Rev

Rev 4192 | Go to most recent revision | Details | 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:
24
 *  2009 Lukas Medjrech ported to HelenOS
25
 */
26
 
27
/** @addtogroup dp8390
28
 *  @{
29
 */
30
 
31
#include <assert.h>
32
 
33
#include <errno.h>
34
 
35
#include "../../include/byteorder.h"
36
 
37
#include "dp8390_drv.h"
38
#include "dp8390_port.h"
39
 
40
/*
41
 * dp8390.c
42
 *
43
 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
44
 *
45
 * Modified Mar 10 1994 by Philip Homburg
46
 *  Become a generic dp8390 driver.
47
 *
48
 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
49
 *  Added support for 3c503 boards.
50
 */
51
 
52
#include "local.h"
53
#include "dp8390.h"
54
 
55
//static u16_t eth_ign_proto;
56
//static char *progname;
57
 
58
/* Configuration */
59
/*typedef struct dp_conf
60
{
61
    port_t dpc_port;
62
    int dpc_irq;
63
    phys_bytes dpc_mem;
64
    char *dpc_envvar;
65
} dp_conf_t;
66
*/
67
//dp_conf_t dp_conf[]=  /* Card addresses */
68
//{
69
    /* I/O port, IRQ,  Buffer address,  Env. var. */
70
/*  {  0x280,     3,    0xD0000,        "DPETH0"    },
71
    {  0x300,     5,    0xC8000,        "DPETH1"    },
72
    {  0x380,    10,    0xD8000,        "DPETH2"    },
73
};
74
*/
75
/* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
76
 * the error: "array size is negative".
77
 */
78
//extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
79
 
80
/* Card inits configured out? */
81
#if !ENABLE_WDETH
82
#define wdeth_probe(dep)    (0)
83
#endif
84
#if !ENABLE_NE2000
85
#define ne_probe(dep)       (0)
86
#endif
87
#if !ENABLE_3C503
88
#define el2_probe(dep)      (0)
89
#endif
90
 
91
/* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
92
 * on writes to the CR register. Additional CR_STAs do not appear to hurt
93
 * genuine dp8390s
94
 */
95
#define CR_EXTRA    CR_STA
96
 
97
//#if ENABLE_PCI
98
//_PROTOTYPE( static void pci_conf, (void)              );
99
//#endif
100
//_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
101
//                          int vectored)   );
102
//_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int)  );
103
//_PROTOTYPE( static void do_vread, (message *mp, int vectored)     );
104
//_PROTOTYPE( static void do_vread_s, (message *mp)         );
105
//_PROTOTYPE( static void do_init, (message *mp)                );
106
//_PROTOTYPE( static void do_int, (dpeth_t *dep)                );
107
//_PROTOTYPE( static void do_getstat, (message *mp)         );
108
//_PROTOTYPE( static void do_getstat_s, (message *mp)           );
109
//_PROTOTYPE( static void do_getname, (message *mp)         );
110
//_PROTOTYPE( static void do_stop, (message *mp)                );
111
_PROTOTYPE( static void dp_init, (dpeth_t *dep)             );
112
//_PROTOTYPE( static void dp_confaddr, (dpeth_t *dep)           );
113
_PROTOTYPE( static void dp_reinit, (dpeth_t *dep)           );
114
_PROTOTYPE( static void dp_reset, (dpeth_t *dep)            );
115
//_PROTOTYPE( static void dp_check_ints, (dpeth_t *dep)         );
116
_PROTOTYPE( static void dp_recv, (dpeth_t *dep)             );
117
_PROTOTYPE( static void dp_send, (dpeth_t *dep)             );
118
//_PROTOTYPE( static void dp8390_stop, (void)               );
119
_PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
120
                size_t offset, size_t size, void *dst)  );
121
//_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
122
//              size_t offset, size_t size, void *dst)  );
123
//_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
124
//              size_t offset, size_t size, void *dst)  );
125
_PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
126
                            int length) );
127
//_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
128
//                          int length) );
129
//_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp, 
130
//      vir_bytes offset, int nic_addr, vir_bytes count)    );
131
//_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp, 
132
//      vir_bytes offset, int nic_addr, vir_bytes count)    );
133
//_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
134
//              iovec_dat_t *iovp, vir_bytes offset,
135
//              int nic_addr, vir_bytes count)      );
136
//_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
137
//              iovec_dat_s_t *iovp, vir_bytes offset,
138
//              int nic_addr, vir_bytes count)      );
139
//_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
140
//              iovec_dat_t *iovp, vir_bytes offset,
141
//              int nic_addr, vir_bytes count)      );
142
//_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
143
//              iovec_dat_s_t *iovp, vir_bytes offset,
144
//              int nic_addr, vir_bytes count)      );
145
_PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
146
        iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
147
//_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr, 
148
//      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
149
//_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr, 
150
//      iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
151
//_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr, 
152
//      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
153
//_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr, 
154
//      iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
155
//_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr, 
156
//      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
157
//_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp)        );
158
//_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp)        );
159
_PROTOTYPE( static void conf_hw, (dpeth_t *dep)             );
160
//_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp)   );
161
_PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep)           );
162
//_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp)       );
163
//_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp)       );
164
_PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block)   );
165
//_PROTOTYPE( static void mess_reply, (message *req, message *reply)    );
166
//_PROTOTYPE( static void get_userdata, (int user_proc,
167
//      vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
168
//_PROTOTYPE( static void get_userdata_s, (int user_proc,
169
//      cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
170
//      void *loc_addr) );
171
//_PROTOTYPE( static void put_userdata, (int user_proc,
172
//      vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
173
//_PROTOTYPE( static void put_userdata_s, (int user_proc,
174
//      cp_grant_id_t grant, size_t count, void *loc_addr)  );
175
//_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size)               );
176
//_PROTOTYPE( static void insw, (port_t port, void *buf, size_t size)               );
177
//_PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
178
//                  vir_bytes buf, size_t size) );
179
//_PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
180
//                  vir_bytes buf, size_t size) );
181
//_PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
182
//                  vir_bytes buf, size_t size) );
183
//_PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
184
//                  vir_bytes buf, size_t size) );
185
 
186
int do_probe( dpeth_t * dep ){
187
    /* This is the default, try to (re)locate the device. */
188
    conf_hw(dep);
189
    if (dep->de_mode == DEM_DISABLED)
190
    {
191
        /* Probe failed, or the device is configured off. */
192
        return EXDEV;//ENXIO;
193
    }
194
    if (dep->de_mode == DEM_ENABLED)
195
        dp_init(dep);
196
    return EOK;
197
}
198
 
199
/*===========================================================================*
200
 *              do_init                      *
201
 *===========================================================================*/
202
int do_init( dpeth_t * dep, int mode ){
203
    if (dep->de_mode == DEM_DISABLED)
204
    {
205
        // might call do_probe()
206
        return EXDEV;
207
    }
208
 
209
    if (dep->de_mode == DEM_SINK)
210
    {
211
//      strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
212
//      dep->de_address.ea_addr[5] = port;
213
//      dp_confaddr(dep);
214
        //TODO ether address?
215
//      reply_mess.m_type = DL_CONF_REPLY;
216
//      reply_mess.m3_i1 = mp->DL_PORT;
217
//      reply_mess.m3_i2 = DE_PORT_NR;
218
//      *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
219
//      mess_reply(mp, &reply_mess);
220
//      return;
221
        return EOK;
222
    }
223
    //TODO assert?
224
    assert(dep->de_mode == DEM_ENABLED);
225
    assert(dep->de_flags & DEF_ENABLED);
226
 
227
    dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
228
 
229
    if (mode & DL_PROMISC_REQ)
230
        dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
231
    if (mode & DL_MULTI_REQ)
232
        dep->de_flags |= DEF_MULTI;
233
    if (mode & DL_BROAD_REQ)
234
        dep->de_flags |= DEF_BROAD;
235
 
236
//  dep->de_client = mp->m_source;
237
    dp_reinit(dep);
238
 
239
    //TODO ether address?
240
//  reply_mess.m_type = DL_CONF_REPLY;
241
//  reply_mess.m3_i1 = mp->DL_PORT;
242
//  reply_mess.m3_i2 = DE_PORT_NR;
243
//  *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
244
 
245
//  mess_reply(mp, &reply_mess);
246
    return EOK;
247
}
248
 
249
/*===========================================================================*
250
 *              do_stop                      *
251
 *===========================================================================*/
252
void do_stop( dpeth_t * dep ){
253
    if(( dep->de_mode != DEM_SINK ) && ( dep->de_mode == DEM_ENABLED ) && ( dep->de_flags & DEF_ENABLED )){
254
        outb_reg0( dep, DP_CR, CR_STP | CR_DM_ABORT );
255
        ( dep->de_stopf )( dep );
256
 
257
        dep->de_flags = DEF_EMPTY;
258
    }
259
}
260
 
261
/*===========================================================================*
262
 *              dp_init                      *
263
 *===========================================================================*/
264
void dp_init(dep)
265
dpeth_t *dep;
266
{
267
    int dp_rcr_reg;
268
    int i;//, r;
269
 
270
    /* General initialization */
271
    dep->de_flags = DEF_EMPTY;
272
    (*dep->de_initf)(dep);
273
 
274
//  dp_confaddr(dep);
275
 
276
    if (debug)
277
    {
278
        printf("%s: Ethernet address ", dep->de_name);
279
        for (i= 0; i < 6; i++)
280
            printf("%x%c", dep->de_address.ea_addr[i],
281
                            i < 5 ? ':' : '\n');
282
    }
283
 
284
    /* Map buffer */
285
    map_hw_buffer(dep);
286
 
287
    /* Initialization of the dp8390 following the mandatory procedure
288
     * in reference manual ("DP8390D/NS32490D NIC Network Interface
289
     * Controller", National Semiconductor, July 1995, Page 29).
290
     */
291
    /* Step 1: */
292
    outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
293
    /* Step 2: */
294
    if (dep->de_16bit)
295
        outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
296
    else
297
        outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
298
    /* Step 3: */
299
    outb_reg0(dep, DP_RBCR0, 0);
300
    outb_reg0(dep, DP_RBCR1, 0);
301
    /* Step 4: */
302
    dp_rcr_reg = 0;
303
    if (dep->de_flags & DEF_PROMISC)
304
        dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
305
    if (dep->de_flags & DEF_BROAD)
306
        dp_rcr_reg |= RCR_AB;
307
    if (dep->de_flags & DEF_MULTI)
308
        dp_rcr_reg |= RCR_AM;
309
    outb_reg0(dep, DP_RCR, dp_rcr_reg);
310
    /* Step 5: */
311
    outb_reg0(dep, DP_TCR, TCR_INTERNAL);
312
    /* Step 6: */
313
    outb_reg0(dep, DP_BNRY, dep->de_startpage);
314
    outb_reg0(dep, DP_PSTART, dep->de_startpage);
315
    outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
316
    /* Step 7: */
317
    outb_reg0(dep, DP_ISR, 0xFF);
318
    /* Step 8: */
319
    outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
320
        IMR_OVWE | IMR_CNTE);
321
    /* Step 9: */
322
    outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
323
 
324
    outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
325
    outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
326
    outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
327
    outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
328
    outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
329
    outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
330
 
331
    outb_reg1(dep, DP_MAR0, 0xff);
332
    outb_reg1(dep, DP_MAR1, 0xff);
333
    outb_reg1(dep, DP_MAR2, 0xff);
334
    outb_reg1(dep, DP_MAR3, 0xff);
335
    outb_reg1(dep, DP_MAR4, 0xff);
336
    outb_reg1(dep, DP_MAR5, 0xff);
337
    outb_reg1(dep, DP_MAR6, 0xff);
338
    outb_reg1(dep, DP_MAR7, 0xff);
339
 
340
    outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
341
    /* Step 10: */
342
    outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
343
    /* Step 11: */
344
    outb_reg0(dep, DP_TCR, TCR_NORMAL);
345
 
346
    inb_reg0(dep, DP_CNTR0);        /* reset counters by reading */
347
    inb_reg0(dep, DP_CNTR1);
348
    inb_reg0(dep, DP_CNTR2);
349
 
350
    /* Finish the initialization. */
351
    dep->de_flags |= DEF_ENABLED;
352
    for (i= 0; i<dep->de_sendq_nr; i++)
353
        dep->de_sendq[i].sq_filled= 0;
354
    dep->de_sendq_head= 0;
355
    dep->de_sendq_tail= 0;
356
//  if (!dep->de_prog_IO)
357
//  {
358
//      dep->de_user2nicf= dp_user2nic;
359
//      dep->de_user2nicf_s= dp_user2nic_s;
360
        dep->de_nic2userf= dp_nic2user;
361
//      dep->de_nic2userf_s= dp_nic2user_s;
362
        dep->de_getblockf= dp_getblock;
363
//  }
364
//  else if (dep->de_16bit)
365
//  {
366
//      dep->de_user2nicf= dp_pio16_user2nic;
367
//      dep->de_user2nicf_s= dp_pio16_user2nic_s;
368
//      dep->de_nic2userf= dp_pio16_nic2user;
369
//      dep->de_nic2userf_s= dp_pio16_nic2user_s;
370
//      dep->de_getblockf= dp_pio16_getblock;
371
//  }
372
//  else
373
//  {
374
//      dep->de_user2nicf= dp_pio8_user2nic;
375
//      dep->de_user2nicf_s= dp_pio8_user2nic_s;
376
//      dep->de_nic2userf= dp_pio8_nic2user;
377
//      dep->de_nic2userf_s= dp_pio8_nic2user_s;
378
//      dep->de_getblockf= dp_pio8_getblock;
379
//  }
380
 
381
    /* Set the interrupt handler and policy. Do not automatically
382
     * reenable interrupts. Return the IRQ line number on interrupts.
383
     */
384
/*  dep->de_hook = dep->de_irq;
385
    r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
386
    if (r != OK)
387
        panic("DP8390", "sys_irqsetpolicy failed", r);
388
 
389
    r= sys_irqenable(&dep->de_hook);
390
    if (r != OK)
391
    {
392
        panic("DP8390", "unable enable interrupts", r);
393
    }
394
*/
395
}
396
 
397
/*===========================================================================*
398
 *              dp_reinit                    *
399
 *===========================================================================*/
400
static void dp_reinit(dep)
401
dpeth_t *dep;
402
{
403
    int dp_rcr_reg;
404
 
405
    outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
406
 
407
    dp_rcr_reg = 0;
408
    if (dep->de_flags & DEF_PROMISC)
409
        dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
410
    if (dep->de_flags & DEF_BROAD)
411
        dp_rcr_reg |= RCR_AB;
412
    if (dep->de_flags & DEF_MULTI)
413
        dp_rcr_reg |= RCR_AM;
414
    outb_reg0(dep, DP_RCR, dp_rcr_reg);
415
}
416
 
417
/*===========================================================================*
418
 *              dp_reset                     *
419
 *===========================================================================*/
420
static void dp_reset(dep)
421
dpeth_t *dep;
422
{
423
    int i;
424
 
425
    /* Stop chip */
426
    outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
427
    outb_reg0(dep, DP_RBCR0, 0);
428
    outb_reg0(dep, DP_RBCR1, 0);
429
    for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
430
        ; /* Do nothing */
431
    outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
432
    outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
433
    outb_reg0(dep, DP_TCR, TCR_NORMAL);
434
 
435
    /* Acknowledge the ISR_RDC (remote dma) interrupt. */
436
    for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
437
        ; /* Do nothing */
438
    outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
439
 
440
    /* Reset the transmit ring. If we were transmitting a packet, we
441
     * pretend that the packet is processed. Higher layers will
442
     * retransmit if the packet wasn't actually sent.
443
     */
444
    dep->de_sendq_head= dep->de_sendq_tail= 0;
445
    for (i= 0; i<dep->de_sendq_nr; i++)
446
        dep->de_sendq[i].sq_filled= 0;
447
    dp_send(dep);
448
    dep->de_flags &= ~DEF_STOPPED;
449
}
450
 
451
/*===========================================================================*
452
 *              dp_check_ints                    *
453
 *===========================================================================*/
454
void dp_check_ints(dep)
455
dpeth_t *dep;
456
{
457
    int isr, tsr;
458
    int size, sendq_tail;
459
 
460
    if (!(dep->de_flags & DEF_ENABLED))
461
        panic("", "dp8390: got premature interrupt", NO_NUM);
462
 
463
    for(;;)
464
    {
465
        isr = inb_reg0(dep, DP_ISR);
466
        if (!isr)
467
            break;
468
        outb_reg0(dep, DP_ISR, isr);
469
        if (isr & (ISR_PTX|ISR_TXE))
470
        {
471
            if (isr & ISR_TXE)
472
            {
473
#if DEBUG
474
 { printf("%s: got send Error\n", dep->de_name); }
475
#endif
476
                dep->de_stat.ets_sendErr++;
477
            }
478
            else
479
            {
480
                tsr = inb_reg0(dep, DP_TSR);
481
 
482
                if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
483
#if 0   /* Reserved in later manuals, should be ignored */
484
                if (!(tsr & TSR_DFR))
485
                {
486
                    /* In most (all?) implementations of
487
                     * the dp8390, this bit is set
488
                     * when the packet is not deferred
489
                     */
490
                    dep->de_stat.ets_transDef++;
491
                }
492
#endif
493
                if (tsr & TSR_COL) dep->de_stat.ets_collision++;
494
                if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
495
                if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
496
                if (tsr & TSR_FU
497
                    && ++dep->de_stat.ets_fifoUnder <= 10)
498
                {
499
                    printf("%s: fifo underrun\n",
500
                        dep->de_name);
501
                }
502
                if (tsr & TSR_CDH
503
                    && ++dep->de_stat.ets_CDheartbeat <= 10)
504
                {
505
                    printf("%s: CD heart beat failure\n",
506
                        dep->de_name);
507
                }
508
                if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
509
            }
510
            sendq_tail= dep->de_sendq_tail;
511
 
512
            if (!(dep->de_sendq[sendq_tail].sq_filled))
513
            {
514
                /* Software bug? */
515
                assert(!debug);
516
 
517
                /* Or hardware bug? */
518
                printf(
519
                "%s: transmit interrupt, but not sending\n",
520
                    dep->de_name);
521
                continue;
522
            }
523
            dep->de_sendq[sendq_tail].sq_filled= 0;
524
            if (++sendq_tail == dep->de_sendq_nr)
525
                sendq_tail= 0;
526
            dep->de_sendq_tail= sendq_tail;
527
            if (dep->de_sendq[sendq_tail].sq_filled)
528
            {
529
                size= dep->de_sendq[sendq_tail].sq_size;
530
                outb_reg0(dep, DP_TPSR,
531
                    dep->de_sendq[sendq_tail].sq_sendpage);
532
                outb_reg0(dep, DP_TBCR1, size >> 8);
533
                outb_reg0(dep, DP_TBCR0, size & 0xff);
534
                outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
535
            }
536
            if (dep->de_flags & DEF_SEND_AVAIL)
537
                dp_send(dep);
538
        }
539
 
540
        if (isr & ISR_PRX)
541
        {
542
            /* Only call dp_recv if there is a read request */
543
            if (dep->de_flags & DEF_READING)
544
                dp_recv(dep);
545
        }
546
 
547
        if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
548
        if (isr & ISR_CNT)
549
        {
550
            dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
551
            dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
552
            dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
553
        }
554
        if (isr & ISR_OVW)
555
        {
556
            dep->de_stat.ets_OVW++;
557
#if 0
558
            { printW(); printf(
559
                "%s: got overwrite warning\n", dep->de_name); }
560
#endif
561
            if (dep->de_flags & DEF_READING)
562
            {
563
                printf(
564
"dp_check_ints: strange: overwrite warning and pending read request\n");
565
                dp_recv(dep);
566
            }
567
        }
568
        if (isr & ISR_RDC)
569
        {
570
            /* Nothing to do */
571
        }
572
        if (isr & ISR_RST)
573
        {
574
            /* this means we got an interrupt but the ethernet
575
             * chip is shutdown. We set the flag DEF_STOPPED,
576
             * and continue processing arrived packets. When the
577
             * receive buffer is empty, we reset the dp8390.
578
             */
579
#if 0
580
             { printW(); printf(
581
                "%s: NIC stopped\n", dep->de_name); }
582
#endif
583
            dep->de_flags |= DEF_STOPPED;
584
            break;
585
        }
586
    }
587
    if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
588
                        (DEF_READING|DEF_STOPPED))
589
    {
590
        /* The chip is stopped, and all arrived packets are
591
         * delivered.
592
         */
593
        dp_reset(dep);
594
    }
595
}
596
 
597
/*===========================================================================*
598
 *              dp_recv                      *
599
 *===========================================================================*/
600
static void dp_recv(dep)
601
dpeth_t *dep;
602
{
603
    dp_rcvhdr_t header;
604
    unsigned pageno, curr, next;
605
    vir_bytes length;
606
    int packet_processed, r;
607
    u16_t eth_type;
608
 
609
    packet_processed = FALSE;
610
    pageno = inb_reg0(dep, DP_BNRY) + 1;
611
    if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
612
 
613
    do
614
    {
615
        outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
616
        curr = inb_reg1(dep, DP_CURR);
617
        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
618
 
619
        if (curr == pageno) break;
620
 
621
        (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
622
            &header);
623
        (dep->de_getblockf)(dep, pageno, sizeof(header) +
624
            2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
625
 
626
        length = (header.dr_rbcl | (header.dr_rbch << 8)) -
627
            sizeof(dp_rcvhdr_t);
628
        next = header.dr_next;
629
        if (length < ETH_MIN_PACK_SIZE ||
630
            length > ETH_MAX_PACK_SIZE_TAGGED)
631
        {
632
            printf("%s: packet with strange length arrived: %d\n",
633
                dep->de_name, (int) length);
634
            next= curr;
635
        }
636
        else if (next < dep->de_startpage || next >= dep->de_stoppage)
637
        {
638
            printf("%s: strange next page\n", dep->de_name);
639
            next= curr;
640
        }
641
/*      else if (eth_type == eth_ign_proto)
642
        {
643
*/          /* Hack: ignore packets of a given protocol, useful
644
             * if you share a net with 80 computers sending
645
             * Amoeba FLIP broadcasts.  (Protocol 0x8146.)
646
             */
647
/*          static int first= 1;
648
            if (first)
649
            {
650
                first= 0;
651
                printf("%s: dropping proto 0x%04x packets\n",
652
                    dep->de_name,
653
                    ntohs(eth_ign_proto));
654
            }
655
            dep->de_stat.ets_packetR++;
656
        }
657
*/      else if (header.dr_status & RSR_FO)
658
        {
659
            /* This is very serious, so we issue a warning and
660
             * reset the buffers */
661
            printf("%s: fifo overrun, resetting receive buffer\n",
662
                dep->de_name);
663
            dep->de_stat.ets_fifoOver++;
664
            next = curr;
665
        }
666
        else if ((header.dr_status & RSR_PRX) &&
667
                       (dep->de_flags & DEF_ENABLED))
668
        {
669
//          if (dep->de_safecopy_read)
670
//              r = dp_pkt2user_s(dep, pageno, length);
671
//          else
672
                r = dp_pkt2user(dep, pageno, length);
673
            if (r != OK)
674
                return;
675
 
676
            packet_processed = TRUE;
677
            dep->de_stat.ets_packetR++;
678
        }
679
        if (next == dep->de_startpage)
680
            outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
681
        else
682
            outb_reg0(dep, DP_BNRY, next - 1);
683
 
684
        pageno = next;
685
    }
686
    while (!packet_processed);
687
}
688
 
689
/*===========================================================================*
690
 *              dp_send                      *
691
 *===========================================================================*/
692
static void dp_send(dep)
693
dpeth_t *dep;
694
{
695
/*  if (!(dep->de_flags & DEF_SEND_AVAIL))
696
        return;
697
 
698
    dep->de_flags &= ~DEF_SEND_AVAIL;
699
    switch(dep->de_sendmsg.m_type)
700
    {
701
    case DL_WRITE:  do_vwrite(&dep->de_sendmsg, TRUE, FALSE);   break;
702
    case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE);    break;
703
    case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE);  break;
704
    default:
705
        panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
706
        break;
707
    }
708
*/
709
}
710
 
711
/*===========================================================================*
712
 *              dp_getblock                  *
713
 *===========================================================================*/
714
static void dp_getblock(dep, page, offset, size, dst)
715
dpeth_t *dep;
716
int page;
717
size_t offset;
718
size_t size;
719
void *dst;
720
{
721
//  int r;
722
 
723
    offset = page * DP_PAGESIZE + offset;
724
 
725
    memcpy(dst, dep->de_locmem + offset, size);
726
}
727
 
728
/*===========================================================================*
729
 *              dp_pkt2user                  *
730
 *===========================================================================*/
731
static int dp_pkt2user(dep, page, length)
732
dpeth_t *dep;
733
int page, length;
734
{
735
    int last, count;
736
 
737
    if (!(dep->de_flags & DEF_READING))
738
        return EGENERIC;
739
 
740
    last = page + (length - 1) / DP_PAGESIZE;
741
    if (last >= dep->de_stoppage)
742
    {
743
        count = (dep->de_stoppage - page) * DP_PAGESIZE -
744
            sizeof(dp_rcvhdr_t);
745
 
746
        /* Save read_iovec since we need it twice. */
747
        dep->de_tmp_iovec = dep->de_read_iovec;
748
        (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
749
            sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
750
        (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
751
                &dep->de_read_iovec, count, length - count);
752
    }
753
    else
754
    {
755
        (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
756
            sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
757
    }
758
 
759
    dep->de_read_s = length;
760
    dep->de_flags |= DEF_PACK_RECV;
761
    dep->de_flags &= ~DEF_READING;
762
 
763
    return OK;
764
}
765
 
766
/*===========================================================================*
767
 *              dp_nic2user                  *
768
 *===========================================================================*/
769
static void dp_nic2user(dep, nic_addr, iovp, offset, count)
770
dpeth_t *dep;
771
int nic_addr;
772
iovec_dat_t *iovp;
773
vir_bytes offset;
774
vir_bytes count;
775
{
776
/*  vir_bytes vir_hw, vir_user;
777
    int bytes, i, r;
778
 
779
    vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
780
 
781
    i= 0;
782
    while (count > 0)
783
    {
784
        if (i >= IOVEC_NR)
785
        {
786
            dp_next_iovec(iovp);
787
            i= 0;
788
            continue;
789
        }
790
        assert(i < iovp->iod_iovec_s);
791
        if (offset >= iovp->iod_iovec[i].iov_size)
792
        {
793
            offset -= iovp->iod_iovec[i].iov_size;
794
            i++;
795
            continue;
796
        }
797
        bytes = iovp->iod_iovec[i].iov_size - offset;
798
        if (bytes > count)
799
            bytes = count;
800
 
801
        r= sys_vircopy(SELF, D, vir_hw,
802
            iovp->iod_proc_nr, D,
803
            iovp->iod_iovec[i].iov_addr + offset, bytes);
804
        if (r != OK)
805
            panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
806
 
807
        count -= bytes;
808
        vir_hw += bytes;
809
        offset += bytes;
810
    }
811
    assert(count == 0);
812
*/
813
    printf("n2u");
814
}
815
 
816
/*===========================================================================*
817
 *              conf_hw                      *
818
 *===========================================================================*/
819
static void conf_hw(dep)
820
dpeth_t *dep;
821
{
822
//  static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0    /* ,... */ };
823
 
824
//  int ifnr;
825
//  dp_conf_t *dcp;
826
 
827
//  dep->de_mode= DEM_DISABLED; /* Superfluous */
828
//  ifnr= dep-de_table;
829
 
830
//  dcp= &dp_conf[ifnr];
831
//  update_conf(dep, dcp);
832
//  if (dep->de_mode != DEM_ENABLED)
833
//      return;
834
    if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
835
    {
836
        printf("%s: No ethernet card found at 0x%x\n",
837
            dep->de_name, dep->de_base_port);
838
        dep->de_mode= DEM_DISABLED;
839
        return;
840
    }
841
 
842
/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
843
 
844
    dep->de_mode = DEM_ENABLED;
845
 
846
    dep->de_flags = DEF_EMPTY;
847
//  dep->de_stat = empty_stat;
848
}
849
 
850
/*===========================================================================*
851
 *              map_hw_buffer                    *
852
 *===========================================================================*/
853
static void map_hw_buffer(dep)
854
dpeth_t *dep;
855
{
856
//  int r;
857
//  size_t o, size;
858
//  char *buf, *abuf;
859
 
860
    if (dep->de_prog_IO)
861
    {
862
//#if 0
863
        if(debug){
864
            printf(
865
            "map_hw_buffer: programmed I/O, no need to map buffer\n");
866
        }
867
//#endif
868
        dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
869
        return;
870
    }
871
 
872
//  size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
873
//                       * alignment
874
//                       */
875
//  buf= malloc(size);
876
//  if (buf == NULL)
877
//      panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
878
//  o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
879
//  abuf= buf + o;
880
//  printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
881
 
882
//  r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
883
//          dep->de_ramsize, (phys_bytes)dep->de_linmem);
884
//  if (r != OK)
885
//      panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
886
//  dep->de_locmem = abuf;
887
}
888
 
889
/*===========================================================================*
890
 *              reply                        *
891
 *===========================================================================*/
892
static void reply(dep, err, may_block)
893
dpeth_t *dep;
894
int err;
895
int may_block;
896
{
897
/*  message reply;
898
    int status;
899
    int r;
900
 
901
    status = 0;
902
    if (dep->de_flags & DEF_PACK_SEND)
903
        status |= DL_PACK_SEND;
904
    if (dep->de_flags & DEF_PACK_RECV)
905
        status |= DL_PACK_RECV;
906
 
907
    reply.m_type = DL_TASK_REPLY;
908
    reply.DL_PORT = dep - de_table;
909
    reply.DL_PROC = dep->de_client;
910
    reply.DL_STAT = status | ((u32_t) err << 16);
911
    reply.DL_COUNT = dep->de_read_s;
912
    reply.DL_CLCK = 0;  *//* Don't know */
913
/*  r= send(dep->de_client, &reply);
914
 
915
    if (r == ELOCKED && may_block)
916
    {
917
#if 0
918
        printf("send locked\n");
919
#endif
920
        return;
921
    }
922
 
923
    if (r < 0)
924
        panic("", "dp8390: send failed:", r);
925
 
926
    dep->de_read_s = 0;
927
*/  dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
928
}
929
 
930
/*
931
 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
932
 */
933
 
934
/** @}
935
 */