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), ð_type); |
814 | 2*sizeof(ether_addr_t), sizeof(eth_type), ð_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 |