source: mainline/uspace/srv/net/netif/dp8390/dp8390.c@ 936835e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 936835e was aadf01e, checked in by Lukas Mejdrech <lukasmejdrech@…>, 16 years ago

Coding style (no functional change)

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