source: mainline/uspace/srv/net/netif/dp8390/dp8390.c@ 5297fe8

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