Subversion Repositories HelenOS

Rev

Rev 4351 | Rev 4708 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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