source: mainline/uspace/srv/net/netif/dp8390/dp8390.c@ 536ded4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 536ded4 was 1e2e0c1e, checked in by Lukas Mejdrech <lukasmejdrech@…>, 16 years ago
  • change in the pq_add interface
  • Property mode set to 100644
File size: 45.1 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 ) return ENOMEM;
1014 dep->de_read_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_suffix( packet, length );
1015 dep->de_read_iovec.iod_iovec[0].iov_size = length;
1016 dep->de_read_iovec.iod_iovec_s = 1;
1017 dep->de_read_iovec.iod_iovec_addr = NULL;
1018
1019 last = page + (length - 1) / DP_PAGESIZE;
1020 if (last >= dep->de_stoppage)
1021 {
1022 count = (dep->de_stoppage - page) * DP_PAGESIZE -
1023 sizeof(dp_rcvhdr_t);
1024
1025 /* Save read_iovec since we need it twice. */
1026 dep->de_tmp_iovec = dep->de_read_iovec;
1027 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1028 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
1029 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
1030 &dep->de_read_iovec, count, length - count);
1031 }
1032 else
1033 {
1034 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1035 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
1036 }
1037
1038 dep->de_read_s = length;
1039 dep->de_flags |= DEF_PACK_RECV;
1040// dep->de_flags &= ~DEF_READING;
1041
1042 if( dep->received_count >= MAX_PACKETS ){
1043 netif_pq_release( packet_get_id( packet ));
1044 return ELIMIT;
1045 }else{
1046 if( pq_add( & dep->received_queue, packet, 0, 0 ) == EOK ){
1047 ++ dep->received_count;
1048 }else{
1049 netif_pq_release( packet_get_id( packet ));
1050 }
1051 }
1052 return OK;
1053}
1054
1055/*===========================================================================*
1056 * dp_user2nic *
1057 *===========================================================================*/
1058static void dp_user2nic(dep, iovp, offset, nic_addr, count)
1059dpeth_t *dep;
1060iovec_dat_t *iovp;
1061vir_bytes offset;
1062int nic_addr;
1063vir_bytes count;
1064{
1065 vir_bytes vir_hw;//, vir_user;
1066 //int bytes, i, r;
1067 int i, r;
1068 vir_bytes bytes;
1069
1070 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1071
1072 i= 0;
1073 while (count > 0)
1074 {
1075 if (i >= IOVEC_NR)
1076 {
1077 dp_next_iovec(iovp);
1078 i= 0;
1079 continue;
1080 }
1081 assert(i < iovp->iod_iovec_s);
1082 if (offset >= iovp->iod_iovec[i].iov_size)
1083 {
1084 offset -= iovp->iod_iovec[i].iov_size;
1085 i++;
1086 continue;
1087 }
1088 bytes = iovp->iod_iovec[i].iov_size - offset;
1089 if (bytes > count)
1090 bytes = count;
1091
1092 r= sys_vircopy(iovp->iod_proc_nr, D,
1093 iovp->iod_iovec[i].iov_addr + offset,
1094 SELF, D, vir_hw, bytes);
1095 if (r != OK)
1096 panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
1097
1098 count -= bytes;
1099 vir_hw += bytes;
1100 offset += bytes;
1101 }
1102 assert(count == 0);
1103}
1104
1105/*===========================================================================*
1106 * dp_pio8_user2nic *
1107 *===========================================================================*/
1108static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
1109dpeth_t *dep;
1110iovec_dat_t *iovp;
1111vir_bytes offset;
1112int nic_addr;
1113vir_bytes count;
1114{
1115// phys_bytes phys_user;
1116 int i;
1117 vir_bytes bytes;
1118
1119 outb_reg0(dep, DP_ISR, ISR_RDC);
1120
1121 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1122 outb_reg0(dep, DP_RBCR1, count >> 8);
1123 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1124 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1125 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1126
1127 i= 0;
1128 while (count > 0)
1129 {
1130 if (i >= IOVEC_NR)
1131 {
1132 dp_next_iovec(iovp);
1133 i= 0;
1134 continue;
1135 }
1136 assert(i < iovp->iod_iovec_s);
1137 if (offset >= iovp->iod_iovec[i].iov_size)
1138 {
1139 offset -= iovp->iod_iovec[i].iov_size;
1140 i++;
1141 continue;
1142 }
1143 bytes = iovp->iod_iovec[i].iov_size - offset;
1144 if (bytes > count)
1145 bytes = count;
1146
1147 do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
1148 iovp->iod_iovec[i].iov_addr + offset, bytes);
1149 count -= bytes;
1150 offset += bytes;
1151 }
1152 assert(count == 0);
1153
1154 for (i= 0; i<100; i++)
1155 {
1156 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1157 break;
1158 }
1159 if (i == 100)
1160 {
1161 panic("", "dp8390: remote dma failed to complete", NO_NUM);
1162 }
1163}
1164
1165/*===========================================================================*
1166 * dp_pio16_user2nic *
1167 *===========================================================================*/
1168static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
1169dpeth_t *dep;
1170iovec_dat_t *iovp;
1171vir_bytes offset;
1172int nic_addr;
1173vir_bytes count;
1174{
1175 vir_bytes vir_user;
1176 vir_bytes ecount;
1177 int i, r, user_proc;
1178 vir_bytes bytes;
1179 //u8_t two_bytes[2];
1180 u16_t two_bytes;
1181 int odd_byte;
1182
1183 ecount= (count+1) & ~1;
1184 odd_byte= 0;
1185
1186 outb_reg0(dep, DP_ISR, ISR_RDC);
1187 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1188 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1189 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1190 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1191 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1192
1193 i= 0;
1194 while (count > 0)
1195 {
1196 if (i >= IOVEC_NR)
1197 {
1198 dp_next_iovec(iovp);
1199 i= 0;
1200 continue;
1201 }
1202 assert(i < iovp->iod_iovec_s);
1203 if (offset >= iovp->iod_iovec[i].iov_size)
1204 {
1205 offset -= iovp->iod_iovec[i].iov_size;
1206 i++;
1207 continue;
1208 }
1209 bytes = iovp->iod_iovec[i].iov_size - offset;
1210 if (bytes > count)
1211 bytes = count;
1212
1213 user_proc= iovp->iod_proc_nr;
1214 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1215 if (odd_byte)
1216 {
1217 r= sys_vircopy(user_proc, D, vir_user,
1218 // SELF, D, (vir_bytes)&two_bytes[1], 1);
1219 SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]), 1);
1220 if (r != OK)
1221 {
1222 panic("DP8390",
1223 "dp_pio16_user2nic: sys_vircopy failed",
1224 r);
1225 }
1226 //outw(dep->de_data_port, *(u16_t *)two_bytes);
1227 outw(dep->de_data_port, two_bytes);
1228 count--;
1229 offset++;
1230 bytes--;
1231 vir_user++;
1232 odd_byte= 0;
1233 if (!bytes)
1234 continue;
1235 }
1236 ecount= bytes & ~1;
1237 if (ecount != 0)
1238 {
1239 do_vir_outsw(dep->de_data_port, user_proc, vir_user,
1240 ecount);
1241 count -= ecount;
1242 offset += ecount;
1243 bytes -= ecount;
1244 vir_user += ecount;
1245 }
1246 if (bytes)
1247 {
1248 assert(bytes == 1);
1249 r= sys_vircopy(user_proc, D, vir_user,
1250 // SELF, D, (vir_bytes)&two_bytes[0], 1);
1251 SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]), 1);
1252 if (r != OK)
1253 {
1254 panic("DP8390",
1255 "dp_pio16_user2nic: sys_vircopy failed",
1256 r);
1257 }
1258 count--;
1259 offset++;
1260 bytes--;
1261 vir_user++;
1262 odd_byte= 1;
1263 }
1264 }
1265 assert(count == 0);
1266
1267 if (odd_byte)
1268 //outw(dep->de_data_port, *(u16_t *)two_bytes);
1269 outw(dep->de_data_port, two_bytes);
1270
1271 for (i= 0; i<100; i++)
1272 {
1273 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1274 break;
1275 }
1276 if (i == 100)
1277 {
1278 panic("", "dp8390: remote dma failed to complete", NO_NUM);
1279 }
1280}
1281
1282/*===========================================================================*
1283 * dp_nic2user *
1284 *===========================================================================*/
1285static void dp_nic2user(dep, nic_addr, iovp, offset, count)
1286dpeth_t *dep;
1287int nic_addr;
1288iovec_dat_t *iovp;
1289vir_bytes offset;
1290vir_bytes count;
1291{
1292 vir_bytes vir_hw;//, vir_user;
1293 vir_bytes bytes;
1294 int i, r;
1295
1296 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1297
1298 i= 0;
1299 while (count > 0)
1300 {
1301 if (i >= IOVEC_NR)
1302 {
1303 dp_next_iovec(iovp);
1304 i= 0;
1305 continue;
1306 }
1307 assert(i < iovp->iod_iovec_s);
1308 if (offset >= iovp->iod_iovec[i].iov_size)
1309 {
1310 offset -= iovp->iod_iovec[i].iov_size;
1311 i++;
1312 continue;
1313 }
1314 bytes = iovp->iod_iovec[i].iov_size - offset;
1315 if (bytes > count)
1316 bytes = count;
1317
1318 r= sys_vircopy(SELF, D, vir_hw,
1319 iovp->iod_proc_nr, D,
1320 iovp->iod_iovec[i].iov_addr + offset, bytes);
1321 if (r != OK)
1322 panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
1323
1324 count -= bytes;
1325 vir_hw += bytes;
1326 offset += bytes;
1327 }
1328 assert(count == 0);
1329}
1330
1331/*===========================================================================*
1332 * dp_pio8_nic2user *
1333 *===========================================================================*/
1334static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
1335dpeth_t *dep;
1336int nic_addr;
1337iovec_dat_t *iovp;
1338vir_bytes offset;
1339vir_bytes count;
1340{
1341// phys_bytes phys_user;
1342 int i;
1343 vir_bytes bytes;
1344
1345 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1346 outb_reg0(dep, DP_RBCR1, count >> 8);
1347 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1348 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1349 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1350
1351 i= 0;
1352 while (count > 0)
1353 {
1354 if (i >= IOVEC_NR)
1355 {
1356 dp_next_iovec(iovp);
1357 i= 0;
1358 continue;
1359 }
1360 assert(i < iovp->iod_iovec_s);
1361 if (offset >= iovp->iod_iovec[i].iov_size)
1362 {
1363 offset -= iovp->iod_iovec[i].iov_size;
1364 i++;
1365 continue;
1366 }
1367 bytes = iovp->iod_iovec[i].iov_size - offset;
1368 if (bytes > count)
1369 bytes = count;
1370
1371 do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
1372 iovp->iod_iovec[i].iov_addr + offset, bytes);
1373 count -= bytes;
1374 offset += bytes;
1375 }
1376 assert(count == 0);
1377}
1378
1379/*===========================================================================*
1380 * dp_pio16_nic2user *
1381 *===========================================================================*/
1382static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
1383dpeth_t *dep;
1384int nic_addr;
1385iovec_dat_t *iovp;
1386vir_bytes offset;
1387vir_bytes count;
1388{
1389 vir_bytes vir_user;
1390 vir_bytes ecount;
1391 int i, r, user_proc;
1392 vir_bytes bytes;
1393 //u8_t two_bytes[2];
1394 u16_t two_bytes;
1395 int odd_byte;
1396
1397 ecount= (count+1) & ~1;
1398 odd_byte= 0;
1399
1400 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1401 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1402 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1403 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1404 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1405
1406 i= 0;
1407 while (count > 0)
1408 {
1409 if (i >= IOVEC_NR)
1410 {
1411 dp_next_iovec(iovp);
1412 i= 0;
1413 continue;
1414 }
1415 assert(i < iovp->iod_iovec_s);
1416 if (offset >= iovp->iod_iovec[i].iov_size)
1417 {
1418 offset -= iovp->iod_iovec[i].iov_size;
1419 i++;
1420 continue;
1421 }
1422 bytes = iovp->iod_iovec[i].iov_size - offset;
1423 if (bytes > count)
1424 bytes = count;
1425
1426 user_proc= iovp->iod_proc_nr;
1427 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1428 if (odd_byte)
1429 {
1430 //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
1431 r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]),
1432 user_proc, D, vir_user, 1);
1433 if (r != OK)
1434 {
1435 panic("DP8390",
1436 "dp_pio16_nic2user: sys_vircopy failed",
1437 r);
1438 }
1439 count--;
1440 offset++;
1441 bytes--;
1442 vir_user++;
1443 odd_byte= 0;
1444 if (!bytes)
1445 continue;
1446 }
1447 ecount= bytes & ~1;
1448 if (ecount != 0)
1449 {
1450 do_vir_insw(dep->de_data_port, user_proc, vir_user,
1451 ecount);
1452 count -= ecount;
1453 offset += ecount;
1454 bytes -= ecount;
1455 vir_user += ecount;
1456 }
1457 if (bytes)
1458 {
1459 assert(bytes == 1);
1460 //*(u16_t *)two_bytes= inw(dep->de_data_port);
1461 two_bytes= inw(dep->de_data_port);
1462 //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
1463 r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]),
1464 user_proc, D, vir_user, 1);
1465 if (r != OK)
1466 {
1467 panic("DP8390",
1468 "dp_pio16_nic2user: sys_vircopy failed",
1469 r);
1470 }
1471 count--;
1472 offset++;
1473 bytes--;
1474 vir_user++;
1475 odd_byte= 1;
1476 }
1477 }
1478 assert(count == 0);
1479}
1480
1481/*===========================================================================*
1482 * dp_next_iovec *
1483 *===========================================================================*/
1484static void dp_next_iovec(iovp)
1485iovec_dat_t *iovp;
1486{
1487 assert(iovp->iod_iovec_s > IOVEC_NR);
1488
1489 iovp->iod_iovec_s -= IOVEC_NR;
1490
1491 iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
1492
1493 get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
1494 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
1495 sizeof(iovec_t), iovp->iod_iovec);
1496}
1497
1498/*===========================================================================*
1499 * conf_hw *
1500 *===========================================================================*/
1501static void conf_hw(dep)
1502dpeth_t *dep;
1503{
1504// static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
1505
1506// int ifnr;
1507// dp_conf_t *dcp;
1508
1509// dep->de_mode= DEM_DISABLED; /* Superfluous */
1510// ifnr= dep-de_table;
1511
1512// dcp= &dp_conf[ifnr];
1513// update_conf(dep, dcp);
1514// if (dep->de_mode != DEM_ENABLED)
1515// return;
1516 if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
1517 {
1518 printf("%s: No ethernet card found at 0x%x\n",
1519 dep->de_name, dep->de_base_port);
1520 dep->de_mode= DEM_DISABLED;
1521 return;
1522 }
1523
1524/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
1525
1526 dep->de_mode = DEM_ENABLED;
1527
1528 dep->de_flags = DEF_EMPTY;
1529// dep->de_stat = empty_stat;
1530}
1531
1532/*===========================================================================*
1533 * map_hw_buffer *
1534 *===========================================================================*/
1535static void map_hw_buffer(dep)
1536dpeth_t *dep;
1537{
1538// int r;
1539// size_t o, size;
1540// char *buf, *abuf;
1541
1542 if (dep->de_prog_IO)
1543 {
1544#if 0
1545 if(debug){
1546 printf(
1547 "map_hw_buffer: programmed I/O, no need to map buffer\n");
1548 }
1549#endif
1550 dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
1551 return;
1552 }else{
1553 printf( "map_hw_buffer: no buffer!\n" );
1554 }
1555
1556// size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
1557// * alignment
1558// */
1559// buf= malloc(size);
1560// if (buf == NULL)
1561// panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
1562// o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
1563// abuf= buf + o;
1564// printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
1565
1566// r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
1567// dep->de_ramsize, (phys_bytes)dep->de_linmem);
1568// if (r != OK)
1569// panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
1570// dep->de_locmem = abuf;
1571}
1572
1573/*===========================================================================*
1574 * reply *
1575 *===========================================================================*/
1576static void reply(dep, err, may_block)
1577dpeth_t *dep;
1578int err;
1579int may_block;
1580{
1581/* message reply;
1582 int status;
1583 int r;
1584
1585 status = 0;
1586 if (dep->de_flags & DEF_PACK_SEND)
1587 status |= DL_PACK_SEND;
1588 if (dep->de_flags & DEF_PACK_RECV)
1589 status |= DL_PACK_RECV;
1590
1591 reply.m_type = DL_TASK_REPLY;
1592 reply.DL_PORT = dep - de_table;
1593 reply.DL_PROC = dep->de_client;
1594 reply.DL_STAT = status | ((u32_t) err << 16);
1595 reply.DL_COUNT = dep->de_read_s;
1596 reply.DL_CLCK = 0; *//* Don't know */
1597/* r= send(dep->de_client, &reply);
1598
1599 if (r == ELOCKED && may_block)
1600 {
1601#if 0
1602 printf("send locked\n");
1603#endif
1604 return;
1605 }
1606
1607 if (r < 0)
1608 panic("", "dp8390: send failed:", r);
1609
1610*/ dep->de_read_s = 0;
1611// dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
1612}
1613
1614/*===========================================================================*
1615 * get_userdata *
1616 *===========================================================================*/
1617static void get_userdata(user_proc, user_addr, count, loc_addr)
1618int user_proc;
1619vir_bytes user_addr;
1620vir_bytes count;
1621void *loc_addr;
1622{
1623 int r;
1624
1625 r= sys_vircopy(user_proc, D, user_addr,
1626 SELF, D, (vir_bytes)loc_addr, count);
1627 if (r != OK)
1628 panic("DP8390", "get_userdata: sys_vircopy failed", r);
1629}
1630
1631static void insb(port_t port, void *buf, size_t size)
1632{
1633 size_t i;
1634
1635 for( i = 0; i < size; ++ i ){
1636 *(( uint8_t * ) buf + i ) = inb( port );
1637 }
1638}
1639
1640static void insw(port_t port, void *buf, size_t size)
1641{
1642 size_t i;
1643
1644 for( i = 0; i * 2 < size; ++ i ){
1645 *(( uint16_t * ) buf + i ) = inw( port );
1646 }
1647}
1648
1649static void outsb(port_t port, void *buf, size_t size)
1650{
1651 size_t i;
1652
1653 for( i = 0; i < size; ++ i ){
1654 outb( port, *(( uint8_t * ) buf + i ));
1655 }
1656}
1657
1658static void outsw(port_t port, void *buf, size_t size)
1659{
1660 size_t i;
1661
1662 for( i = 0; i * 2 < size; ++ i ){
1663 outw( port, *(( uint16_t * ) buf + i ));
1664 }
1665}
1666
1667/*
1668 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
1669 */
1670
1671/** @}
1672 */
Note: See TracBrowser for help on using the repository browser.