Changes in uspace/srv/hw/netif/dp8390/dp8390.c [7e752b2:e0854e3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/dp8390.c
r7e752b2 re0854e3 1 1 /* 2 * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 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 2 * Copyright (c) 2009 Lukas Mejdrech 3 * Copyright (c) 2011 Martin Decky 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * - The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 13 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 14 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORSBE LIABLE FOR ANY DIRECT, INDIRECT,21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 16 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, … … 20 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * 23 * Changes: 24 * 2009 ported to HelenOS, Lukas Mejdrech 28 */ 29 30 /* 31 * This code is based upon the NE2000 driver for MINIX, 32 * distributed according to a BSD-style license. 33 * 34 * Copyright (c) 1987, 1997, 2006 Vrije Universiteit 35 * Copyright (c) 1992, 1994 Philip Homburg 36 * Copyright (c) 1996 G. Falzoni 37 * 25 38 */ 26 39 … … 36 49 #include <byteorder.h> 37 50 #include <errno.h> 38 39 51 #include <netif_local.h> 40 52 #include <net/packet.h> 53 #include <nil_interface.h> 41 54 #include <packet_client.h> 42 43 55 #include "dp8390_drv.h" 44 56 #include "dp8390_port.h" 45 46 /*47 * dp8390.c48 *49 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>50 *51 * Modified Mar 10 1994 by Philip Homburg52 * Become a generic dp8390 driver.53 *54 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>55 * Added support for 3c503 boards.56 */57 58 #include "local.h"59 57 #include "dp8390.h" 60 61 /** Queues the outgoing packet. 62 * @param[in] dep The network interface structure. 63 * @param[in] packet The outgoing packet. 64 * @return EOK on success. 65 * @return EINVAL 66 */ 67 int queue_packet(dpeth_t * dep, packet_t *packet); 68 69 /** Reads a memory block byte by byte. 58 #include "ne2000.h" 59 60 /** Read a memory block byte by byte. 61 * 70 62 * @param[in] port The source address. 71 63 * @param[out] buf The destination buffer. 72 64 * @param[in] size The memory block size in bytes. 65 * 73 66 */ 74 67 static void outsb(port_t port, void * buf, size_t size); 75 68 76 /** Reads a memory block word by word. 69 /** Read a memory block word by word. 70 * 77 71 * @param[in] port The source address. 78 72 * @param[out] buf The destination buffer. 79 73 * @param[in] size The memory block size in bytes. 74 * 80 75 */ 81 76 static void outsw(port_t port, void * buf, size_t size); 82 77 83 //static u16_t eth_ign_proto; 84 //static char *progname; 85 86 /* Configuration */ 87 /*typedef struct dp_conf 88 { 89 port_t dpc_port; 90 int dpc_irq; 91 phys_bytes dpc_mem; 92 char *dpc_envvar; 93 } dp_conf_t; 94 */ 95 //dp_conf_t dp_conf[]= /* Card addresses */ 96 //{ 97 /* I/O port, IRQ, Buffer address, Env. var. */ 98 /* { 0x280, 3, 0xD0000, "DPETH0" }, 99 { 0x300, 5, 0xC8000, "DPETH1" }, 100 { 0x380, 10, 0xD8000, "DPETH2" }, 101 }; 102 */ 103 /* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see 104 * the error: "array size is negative". 78 /* 79 * Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA 80 * on writes to the CR register. Additional CR_STAs do not appear to hurt 81 * genuine dp8390s. 105 82 */ 106 //extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1]; 107 108 /* Card inits configured out? */ 109 #if !ENABLE_WDETH 110 #define wdeth_probe(dep) (0) 111 #endif 112 #if !ENABLE_NE2000 113 #define ne_probe(dep) (0) 114 #endif 115 #if !ENABLE_3C503 116 #define el2_probe(dep) (0) 117 #endif 118 119 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA 120 * on writes to the CR register. Additional CR_STAs do not appear to hurt 121 * genuine dp8390s 122 */ 123 #define CR_EXTRA CR_STA 124 125 //#if ENABLE_PCI 126 //_PROTOTYPE(static void pci_conf, (void) ); 127 //#endif 128 //_PROTOTYPE(static void do_vwrite, (message *mp, int from_int, 129 // int vectored) ); 130 //_PROTOTYPE(static void do_vwrite_s, (message *mp, int from_int) ); 131 //_PROTOTYPE(static void do_vread, (message *mp, int vectored) ); 132 //_PROTOTYPE(static void do_vread_s, (message *mp) ); 133 //_PROTOTYPE(static void do_init, (message *mp) ); 134 //_PROTOTYPE(static void do_int, (dpeth_t *dep) ); 135 //_PROTOTYPE(static void do_getstat, (message *mp) ); 136 //_PROTOTYPE(static void do_getstat_s, (message *mp) ); 137 //_PROTOTYPE(static void do_getname, (message *mp) ); 138 //_PROTOTYPE(static void do_stop, (message *mp) ); 139 _PROTOTYPE(static void dp_init, (dpeth_t *dep) ); 140 //_PROTOTYPE(static void dp_confaddr, (dpeth_t *dep) ); 141 _PROTOTYPE(static void dp_reinit, (dpeth_t *dep) ); 142 _PROTOTYPE(static void dp_reset, (dpeth_t *dep) ); 143 //_PROTOTYPE(static void dp_check_ints, (dpeth_t *dep) ); 144 _PROTOTYPE(static void dp_recv, (dpeth_t *dep) ); 145 _PROTOTYPE(static void dp_send, (dpeth_t *dep) ); 146 //_PROTOTYPE(static void dp8390_stop, (void) ); 147 _PROTOTYPE(static void dp_getblock, (dpeth_t *dep, int page, 148 size_t offset, size_t size, void *dst) ); 149 _PROTOTYPE(static void dp_pio8_getblock, (dpeth_t *dep, int page, 150 size_t offset, size_t size, void *dst) ); 151 _PROTOTYPE(static void dp_pio16_getblock, (dpeth_t *dep, int page, 152 size_t offset, size_t size, void *dst) ); 153 _PROTOTYPE(static int dp_pkt2user, (dpeth_t *dep, int page, 154 int length) ); 155 //_PROTOTYPE(static int dp_pkt2user_s, (dpeth_t *dep, int page, 156 // int length) ); 157 _PROTOTYPE(static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp, 158 vir_bytes offset, int nic_addr, vir_bytes count) ); 159 //_PROTOTYPE(static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp, 160 // vir_bytes offset, int nic_addr, vir_bytes count) ); 161 _PROTOTYPE(static void dp_pio8_user2nic, (dpeth_t *dep, 162 iovec_dat_t *iovp, vir_bytes offset, 163 int nic_addr, vir_bytes count) ); 164 //_PROTOTYPE(static void dp_pio8_user2nic_s, (dpeth_t *dep, 165 // iovec_dat_s_t *iovp, vir_bytes offset, 166 // int nic_addr, vir_bytes count) ); 167 _PROTOTYPE(static void dp_pio16_user2nic, (dpeth_t *dep, 168 iovec_dat_t *iovp, vir_bytes offset, 169 int nic_addr, vir_bytes count) ); 170 //_PROTOTYPE(static void dp_pio16_user2nic_s, (dpeth_t *dep, 171 // iovec_dat_s_t *iovp, vir_bytes offset, 172 // int nic_addr, vir_bytes count) ); 173 _PROTOTYPE(static void dp_nic2user, (dpeth_t *dep, int nic_addr, 174 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) ); 175 //_PROTOTYPE(static void dp_nic2user_s, (dpeth_t *dep, int nic_addr, 176 // iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) ); 177 _PROTOTYPE(static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr, 178 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) ); 179 //_PROTOTYPE(static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr, 180 // iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) ); 181 _PROTOTYPE(static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr, 182 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) ); 183 //_PROTOTYPE(static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr, 184 // iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) ); 185 _PROTOTYPE(static void dp_next_iovec, (iovec_dat_t *iovp) ); 186 //_PROTOTYPE(static void dp_next_iovec_s, (iovec_dat_s_t *iovp) ); 187 _PROTOTYPE(static void conf_hw, (dpeth_t *dep) ); 188 //_PROTOTYPE(static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) ); 189 _PROTOTYPE(static void map_hw_buffer, (dpeth_t *dep) ); 190 //_PROTOTYPE(static int calc_iovec_size, (iovec_dat_t *iovp) ); 191 //_PROTOTYPE(static int calc_iovec_size_s, (iovec_dat_s_t *iovp) ); 192 _PROTOTYPE(static void reply, (dpeth_t *dep, int err, int may_block) ); 193 //_PROTOTYPE(static void mess_reply, (message *req, message *reply) ); 194 _PROTOTYPE(static void get_userdata, (int user_proc, 195 vir_bytes user_addr, vir_bytes count, void *loc_addr) ); 196 //_PROTOTYPE(static void get_userdata_s, (int user_proc, 197 // cp_grant_id_t grant, vir_bytes offset, vir_bytes count, 198 // void *loc_addr) ); 199 //_PROTOTYPE(static void put_userdata, (int user_proc, 200 // vir_bytes user_addr, vir_bytes count, void *loc_addr) ); 201 //_PROTOTYPE(static void put_userdata_s, (int user_proc, 202 // cp_grant_id_t grant, size_t count, void *loc_addr) ); 203 _PROTOTYPE(static void insb, (port_t port, void *buf, size_t size) ); 204 _PROTOTYPE(static void insw, (port_t port, void *buf, size_t size) ); 205 //_PROTOTYPE(static void do_vir_insb, (port_t port, int proc, 206 // vir_bytes buf, size_t size) ); 207 //_PROTOTYPE(static void do_vir_insw, (port_t port, int proc, 208 // vir_bytes buf, size_t size) ); 209 //_PROTOTYPE(static void do_vir_outsb, (port_t port, int proc, 210 // vir_bytes buf, size_t size) ); 211 //_PROTOTYPE(static void do_vir_outsw, (port_t port, int proc, 212 // vir_bytes buf, size_t size) ); 213 214 int do_probe(dpeth_t * dep){ 83 #define CR_EXTRA CR_STA 84 85 static void dp_init(dpeth_t *dep); 86 static void dp_reinit(dpeth_t *dep); 87 static void dp_reset(dpeth_t *dep); 88 static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep); 89 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst); 90 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst); 91 static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length); 92 static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size); 93 static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size); 94 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size); 95 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size); 96 static void conf_hw(dpeth_t *dep); 97 static void insb(port_t port, void *buf, size_t size); 98 static void insw(port_t port, void *buf, size_t size); 99 100 int do_probe(dpeth_t *dep) 101 { 215 102 /* This is the default, try to (re)locate the device. */ 216 103 conf_hw(dep); 217 104 if (dep->de_mode == DEM_DISABLED) 218 {219 105 /* Probe failed, or the device is configured off. */ 220 return EXDEV; //ENXIO;221 }106 return EXDEV; 107 222 108 if (dep->de_mode == DEM_ENABLED) 223 109 dp_init(dep); 110 224 111 return EOK; 225 112 } 226 113 227 /*===========================================================================* 228 * dp8390_dump * 229 *===========================================================================*/ 230 void dp8390_dump(dpeth_t * dep) 231 { 232 // dpeth_t *dep; 233 int /*i,*/ isr; 234 235 // printf("\n"); 236 // for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++) 237 // { 238 #if XXX 239 if (dep->de_mode == DEM_DISABLED) 240 printf("dp8390 port %d is disabled\n", i); 241 else if (dep->de_mode == DEM_SINK) 242 printf("dp8390 port %d is in sink mode\n", i); 243 #endif 244 245 if (dep->de_mode != DEM_ENABLED) 246 // continue; 247 return; 248 249 // printf("dp8390 statistics of port %d:\n", i); 250 251 printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr); 252 printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr); 253 printf("OVW :%8ld\n", dep->de_stat.ets_OVW); 254 255 printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr); 256 printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll); 257 printf("missedP :%8ld\n", dep->de_stat.ets_missedP); 258 259 printf("packetR :%8ld\t", dep->de_stat.ets_packetR); 260 printf("packetT :%8ld\t", dep->de_stat.ets_packetT); 261 printf("transDef :%8ld\n", dep->de_stat.ets_transDef); 262 263 printf("collision :%8ld\t", dep->de_stat.ets_collision); 264 printf("transAb :%8ld\t", dep->de_stat.ets_transAb); 265 printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense); 266 267 printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder); 268 printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver); 269 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat); 270 271 printf("OWC :%8ld\t", dep->de_stat.ets_OWC); 272 273 isr= inb_reg0(dep, DP_ISR); 274 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr, 275 inb_reg0(dep, DP_ISR), dep->de_flags); 276 // } 277 } 278 279 /*===========================================================================* 280 * do_init * 281 *===========================================================================*/ 282 int do_init(dpeth_t * dep, int mode){ 114 int do_init(dpeth_t *dep, int mode) 115 { 283 116 if (dep->de_mode == DEM_DISABLED) 284 { 285 // might call do_probe() 117 /* FIXME: Perhaps call do_probe()? */ 286 118 return EXDEV; 287 } 288 289 if (dep->de_mode == DEM_SINK) 290 { 291 // strncpy((char *) dep->de_address.ea_addr, "ZDP", 6); 292 // dep->de_address.ea_addr[5] = port; 293 // dp_confaddr(dep); 294 // reply_mess.m_type = DL_CONF_REPLY; 295 // reply_mess.m3_i1 = mp->DL_PORT; 296 // reply_mess.m3_i2 = DE_PORT_NR; 297 // *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address; 298 // mess_reply(mp, &reply_mess); 299 // return; 300 return EOK; 301 } 119 302 120 assert(dep->de_mode == DEM_ENABLED); 303 assert(dep->de_flags & DEF_ENABLED);304 121 assert(dep->de_flags & DEF_ENABLED); 122 305 123 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD); 306 124 307 125 if (mode &DL_PROMISC_REQ) 308 126 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; 127 309 128 if (mode &DL_MULTI_REQ) 310 129 dep->de_flags |= DEF_MULTI; 130 311 131 if (mode &DL_BROAD_REQ) 312 132 dep->de_flags |= DEF_BROAD; 313 314 // dep->de_client = mp->m_source; 133 315 134 dp_reinit(dep); 316 317 // reply_mess.m_type = DL_CONF_REPLY;318 // reply_mess.m3_i1 = mp->DL_PORT;319 // reply_mess.m3_i2 = DE_PORT_NR;320 // *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;321 322 // mess_reply(mp, &reply_mess);323 135 return EOK; 324 136 } 325 137 326 /*===========================================================================* 327 * do_stop * 328 *===========================================================================*/ 329 void do_stop(dpeth_t * dep){ 330 if((dep->de_mode != DEM_SINK) && (dep->de_mode == DEM_ENABLED) && (dep->de_flags &DEF_ENABLED)){ 138 void do_stop(dpeth_t *dep) 139 { 140 if ((dep->de_mode == DEM_ENABLED) 141 && (dep->de_flags & DEF_ENABLED)) { 331 142 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 332 143 (dep->de_stopf)(dep); 333 334 144 dep->de_flags = DEF_EMPTY; 335 145 } 336 146 } 337 147 338 int queue_packet(dpeth_t * dep, packet_t *packet){ 339 packet_t *tmp; 340 341 if(dep->packet_count >= MAX_PACKETS){ 342 netif_pq_release(packet_get_id(packet)); 343 return ELIMIT; 344 } 345 346 tmp = dep->packet_queue; 347 while(pq_next(tmp)){ 348 tmp = pq_next(tmp); 349 } 350 if(pq_add(&tmp, packet, 0, 0) != EOK){ 351 return EINVAL; 352 } 353 if(! dep->packet_count){ 354 dep->packet_queue = packet; 355 } 356 ++ dep->packet_count; 357 return EBUSY; 358 } 359 360 /*===========================================================================* 361 * based on do_vwrite * 362 *===========================================================================*/ 363 int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int) 364 { 365 // int port, count, size; 148 int do_pwrite(dpeth_t *dep, packet_t *packet, int from_int) 149 { 366 150 int size; 367 151 int sendq_head; 368 /* dpeth_t *dep; 369 370 port = mp->DL_PORT; 371 count = mp->DL_COUNT; 372 if (port < 0 || port >= DE_PORT_NR) 373 panic("", "dp8390: illegal port", port); 374 dep= &de_table[port]; 375 dep->de_client= mp->DL_PROC; 376 */ 377 if (dep->de_mode == DEM_SINK) 378 { 379 assert(!from_int); 380 // dep->de_flags |= DEF_PACK_SEND; 381 reply(dep, OK, FALSE); 382 // return; 383 return EOK; 384 } 152 385 153 assert(dep->de_mode == DEM_ENABLED); 386 assert(dep->de_flags &DEF_ENABLED); 387 if(dep->packet_queue && (! from_int)){ 388 // if (dep->de_flags &DEF_SEND_AVAIL){ 389 // panic("", "dp8390: send already in progress", NO_NUM); 390 return queue_packet(dep, packet); 391 } 392 393 sendq_head= dep->de_sendq_head; 394 // if (dep->de_sendq[sendq_head].sq_filled) 395 // { 396 // if (from_int) 397 // panic("", "dp8390: should not be sending\n", NO_NUM); 398 // dep->de_sendmsg= *mp; 399 // dep->de_flags |= DEF_SEND_AVAIL; 400 // reply(dep, OK, FALSE); 401 // return; 402 // return queue_packet(dep, packet); 403 // } 404 // assert(!(dep->de_flags &DEF_PACK_SEND)); 405 406 /* if (vectored) 407 { 408 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, 409 (count > IOVEC_NR ? IOVEC_NR : count) * 410 sizeof(iovec_t), dep->de_write_iovec.iod_iovec); 411 dep->de_write_iovec.iod_iovec_s = count; 412 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; 413 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR; 414 415 dep->de_tmp_iovec = dep->de_write_iovec; 416 size = calc_iovec_size(&dep->de_tmp_iovec); 417 } 418 else 419 { 420 dep->de_write_iovec.iod_iovec[0].iov_addr = 421 (vir_bytes) mp->DL_ADDR; 422 dep->de_write_iovec.iod_iovec[0].iov_size = 423 mp->DL_COUNT; 424 dep->de_write_iovec.iod_iovec_s = 1; 425 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; 426 dep->de_write_iovec.iod_iovec_addr = 0; 427 size= mp->DL_COUNT; 428 } 429 */ 154 assert(dep->de_flags & DEF_ENABLED); 155 156 if (dep->de_flags & DEF_SEND_AVAIL) { 157 fprintf(stderr, "dp8390: send already in progress\n"); 158 return EBUSY; 159 } 160 161 sendq_head = dep->de_sendq_head; 162 if (dep->de_sendq[sendq_head].sq_filled) { 163 if (from_int) 164 fprintf(stderr, "dp8390: should not be sending\n"); 165 dep->de_flags |= DEF_SEND_AVAIL; 166 dep->de_flags &= ~DEF_PACK_SEND; 167 168 return EBUSY; 169 } 170 171 assert(!(dep->de_flags & DEF_PACK_SEND)); 172 173 void *buf = packet_get_data(packet); 430 174 size = packet_get_data_length(packet); 431 dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) packet_get_data(packet); 432 dep->de_write_iovec.iod_iovec[0].iov_size = size; 433 dep->de_write_iovec.iod_iovec_s = 1; 434 dep->de_write_iovec.iod_iovec_addr = (uintptr_t) NULL; 435 436 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) 437 { 438 panic("", "dp8390: invalid packet size", size); 175 176 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) { 177 fprintf(stderr, "dp8390: invalid packet size\n"); 439 178 return EINVAL; 440 179 } 441 (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,442 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,443 444 dep->de_sendq[sendq_head].sq_filled = TRUE;445 if (dep->de_sendq_tail == sendq_head)446 {180 181 (dep->de_user2nicf)(dep, buf, 0, 182 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, size); 183 dep->de_sendq[sendq_head].sq_filled = true; 184 185 if (dep->de_sendq_tail == sendq_head) { 447 186 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage); 448 187 outb_reg0(dep, DP_TBCR1, size >> 8); 449 outb_reg0(dep, DP_TBCR0, size &0xff); 450 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */ 451 } 452 else 453 dep->de_sendq[sendq_head].sq_size= size; 188 outb_reg0(dep, DP_TBCR0, size & 0xff); 189 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA); /* there it goes .. */ 190 } else 191 dep->de_sendq[sendq_head].sq_size = size; 454 192 455 193 if (++sendq_head == dep->de_sendq_nr) 456 sendq_head= 0; 194 sendq_head = 0; 195 457 196 assert(sendq_head < SENDQ_NR); 458 dep->de_sendq_head= sendq_head; 459 460 // dep->de_flags |= DEF_PACK_SEND; 461 462 /* If the interrupt handler called, don't send a reply. The reply 463 * will be sent after all interrupts are handled. 464 */ 197 dep->de_sendq_head = sendq_head; 198 199 dep->de_flags |= DEF_PACK_SEND; 200 465 201 if (from_int) 466 202 return EOK; 467 reply(dep, OK, FALSE); 468 469 assert(dep->de_mode == DEM_ENABLED); 470 assert(dep->de_flags &DEF_ENABLED); 203 204 dep->de_flags &= ~DEF_PACK_SEND; 205 471 206 return EOK; 472 207 } 473 208 474 /*===========================================================================* 475 * dp_init * 476 *===========================================================================*/ 477 void dp_init(dep) 478 dpeth_t *dep; 209 void dp_init(dpeth_t *dep) 479 210 { 480 211 int dp_rcr_reg; 481 int i; //, r;482 212 int i; 213 483 214 /* General initialization */ 484 215 dep->de_flags = DEF_EMPTY; 485 216 (*dep->de_initf)(dep); 486 487 // dp_confaddr(dep); 488 489 if (debug) 490 { 491 printf("%s: Ethernet address ", dep->de_name); 492 for (i= 0; i < 6; i++) 493 printf("%x%c", dep->de_address.ea_addr[i], 494 i < 5 ? ':' : '\n'); 495 } 496 497 /* Map buffer */ 498 map_hw_buffer(dep); 499 500 /* Initialization of the dp8390 following the mandatory procedure 217 218 printf("%s: Ethernet address ", dep->de_name); 219 for (i = 0; i < 6; i++) 220 printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n'); 221 222 /* 223 * Initialization of the dp8390 following the mandatory procedure 501 224 * in reference manual ("DP8390D/NS32490D NIC Network Interface 502 225 * Controller", National Semiconductor, July 1995, Page 29). 503 226 */ 227 504 228 /* Step 1: */ 505 229 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT); 230 506 231 /* Step 2: */ 507 232 if (dep->de_16bit) … … 509 234 else 510 235 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS); 236 511 237 /* Step 3: */ 512 238 outb_reg0(dep, DP_RBCR0, 0); 513 239 outb_reg0(dep, DP_RBCR1, 0); 240 514 241 /* Step 4: */ 515 242 dp_rcr_reg = 0; 516 if (dep->de_flags &DEF_PROMISC) 243 244 if (dep->de_flags & DEF_PROMISC) 517 245 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 518 if (dep->de_flags &DEF_BROAD) 246 247 if (dep->de_flags & DEF_BROAD) 519 248 dp_rcr_reg |= RCR_AB; 520 if (dep->de_flags &DEF_MULTI) 249 250 if (dep->de_flags & DEF_MULTI) 521 251 dp_rcr_reg |= RCR_AM; 252 522 253 outb_reg0(dep, DP_RCR, dp_rcr_reg); 254 523 255 /* Step 5: */ 524 256 outb_reg0(dep, DP_TCR, TCR_INTERNAL); 257 525 258 /* Step 6: */ 526 259 outb_reg0(dep, DP_BNRY, dep->de_startpage); 527 260 outb_reg0(dep, DP_PSTART, dep->de_startpage); 528 261 outb_reg0(dep, DP_PSTOP, dep->de_stoppage); 262 529 263 /* Step 7: */ 530 264 outb_reg0(dep, DP_ISR, 0xFF); 265 531 266 /* Step 8: */ 532 267 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | 533 IMR_OVWE | IMR_CNTE); 268 IMR_OVWE | IMR_CNTE); 269 534 270 /* Step 9: */ 535 271 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP); 536 272 537 273 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]); 538 274 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]); … … 541 277 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]); 542 278 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]); 543 279 544 280 outb_reg1(dep, DP_MAR0, 0xff); 545 281 outb_reg1(dep, DP_MAR1, 0xff); … … 550 286 outb_reg1(dep, DP_MAR6, 0xff); 551 287 outb_reg1(dep, DP_MAR7, 0xff); 552 288 553 289 outb_reg1(dep, DP_CURR, dep->de_startpage + 1); 290 554 291 /* Step 10: */ 555 292 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA); 293 556 294 /* Step 11: */ 557 295 outb_reg0(dep, DP_TCR, TCR_NORMAL); 558 559 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */296 297 inb_reg0(dep, DP_CNTR0); /* Reset counters by reading */ 560 298 inb_reg0(dep, DP_CNTR1); 561 299 inb_reg0(dep, DP_CNTR2); 562 300 563 301 /* Finish the initialization. */ 564 302 dep->de_flags |= DEF_ENABLED; 565 for (i = 0; i<dep->de_sendq_nr; i++)303 for (i = 0; i < dep->de_sendq_nr; i++) 566 304 dep->de_sendq[i].sq_filled= 0; 567 dep->de_sendq_head= 0; 568 dep->de_sendq_tail= 0; 569 if (!dep->de_prog_IO) 570 { 571 dep->de_user2nicf= dp_user2nic; 572 // dep->de_user2nicf_s= dp_user2nic_s; 573 dep->de_nic2userf= dp_nic2user; 574 // dep->de_nic2userf_s= dp_nic2user_s; 575 dep->de_getblockf= dp_getblock; 576 } 577 else if (dep->de_16bit) 578 { 305 306 dep->de_sendq_head = 0; 307 dep->de_sendq_tail = 0; 308 309 if (dep->de_16bit) { 579 310 dep->de_user2nicf= dp_pio16_user2nic; 580 // dep->de_user2nicf_s= dp_pio16_user2nic_s;581 311 dep->de_nic2userf= dp_pio16_nic2user; 582 // dep->de_nic2userf_s= dp_pio16_nic2user_s;583 312 dep->de_getblockf= dp_pio16_getblock; 584 } 585 else 586 { 313 } else { 587 314 dep->de_user2nicf= dp_pio8_user2nic; 588 // dep->de_user2nicf_s= dp_pio8_user2nic_s;589 315 dep->de_nic2userf= dp_pio8_nic2user; 590 // dep->de_nic2userf_s= dp_pio8_nic2user_s;591 316 dep->de_getblockf= dp_pio8_getblock; 592 317 } 593 594 /* Set the interrupt handler and policy. Do not automatically 595 * reenable interrupts. Return the IRQ line number on interrupts. 596 */ 597 /* dep->de_hook = dep->de_irq; 598 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook); 599 if (r != OK) 600 panic("DP8390", "sys_irqsetpolicy failed", r); 601 602 r= sys_irqenable(&dep->de_hook); 603 if (r != OK) 604 { 605 panic("DP8390", "unable enable interrupts", r); 606 } 607 */ 608 } 609 610 /*===========================================================================* 611 * dp_reinit * 612 *===========================================================================*/ 613 static void dp_reinit(dep) 614 dpeth_t *dep; 318 } 319 320 static void dp_reinit(dpeth_t *dep) 615 321 { 616 322 int dp_rcr_reg; 617 323 618 324 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 619 325 620 326 dp_rcr_reg = 0; 621 if (dep->de_flags &DEF_PROMISC) 327 328 if (dep->de_flags & DEF_PROMISC) 622 329 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 623 if (dep->de_flags &DEF_BROAD) 330 331 if (dep->de_flags & DEF_BROAD) 624 332 dp_rcr_reg |= RCR_AB; 625 if (dep->de_flags &DEF_MULTI) 333 334 if (dep->de_flags & DEF_MULTI) 626 335 dp_rcr_reg |= RCR_AM; 336 627 337 outb_reg0(dep, DP_RCR, dp_rcr_reg); 628 338 } 629 339 630 /*===========================================================================* 631 * dp_reset * 632 *===========================================================================*/ 633 static void dp_reset(dep) 634 dpeth_t *dep; 340 static void dp_reset(dpeth_t *dep) 635 341 { 636 342 int i; 637 343 638 344 /* Stop chip */ 639 345 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 640 346 outb_reg0(dep, DP_RBCR0, 0); 641 347 outb_reg0(dep, DP_RBCR1, 0); 642 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++) 348 349 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++) 643 350 ; /* Do nothing */ 644 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST); 645 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT); 351 352 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST); 353 outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT); 646 354 outb_reg0(dep, DP_TCR, TCR_NORMAL); 647 648 /* Acknowledge the ISR_RDC (remote dma) interrupt. */649 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)355 356 /* Acknowledge the ISR_RDC (remote DMA) interrupt. */ 357 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++) 650 358 ; /* Do nothing */ 651 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) &~ISR_RDC); 652 653 /* Reset the transmit ring. If we were transmitting a packet, we 359 360 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC); 361 362 /* 363 * Reset the transmit ring. If we were transmitting a packet, we 654 364 * pretend that the packet is processed. Higher layers will 655 365 * retransmit if the packet wasn't actually sent. 656 366 */ 657 dep->de_sendq_head= dep->de_sendq_tail= 0; 658 for (i= 0; i<dep->de_sendq_nr; i++) 659 dep->de_sendq[i].sq_filled= 0; 660 dp_send(dep); 367 dep->de_sendq_head = 0; 368 dep->de_sendq_tail = 0; 369 370 for (i = 0; i < dep->de_sendq_nr; i++) 371 dep->de_sendq[i].sq_filled = 0; 372 373 dep->de_flags &= ~DEF_SEND_AVAIL; 661 374 dep->de_flags &= ~DEF_STOPPED; 662 375 } 663 376 664 /*===========================================================================* 665 * dp_check_ints * 666 *===========================================================================*/ 667 void dp_check_ints(dep, isr) 668 dpeth_t *dep; 669 int isr; 670 { 671 int /*isr,*/ tsr; 377 void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, int isr) 378 { 379 int tsr; 672 380 int size, sendq_tail; 673 674 if (!(dep->de_flags &DEF_ENABLED)) 675 panic("", "dp8390: got premature interrupt", NO_NUM); 676 677 for(;;) 678 { 679 // isr = inb_reg0(dep, DP_ISR); 680 if (!isr) 681 break; 381 382 if (!(dep->de_flags & DEF_ENABLED)) 383 fprintf(stderr, "dp8390: got premature interrupt\n"); 384 385 for (; isr; isr = inb_reg0(dep, DP_ISR)) { 682 386 outb_reg0(dep, DP_ISR, isr); 683 if (isr &(ISR_PTX|ISR_TXE)) 684 { 685 if (isr &ISR_TXE) 686 { 687 #if DEBUG 688 {printf("%s: got send Error\n", dep->de_name);} 689 #endif 387 388 if (isr & (ISR_PTX | ISR_TXE)) { 389 if (isr & ISR_TXE) 690 390 dep->de_stat.ets_sendErr++; 391 else { 392 tsr = inb_reg0(dep, DP_TSR); 393 394 if (tsr & TSR_PTX) 395 dep->de_stat.ets_packetT++; 396 397 if (tsr & TSR_COL) 398 dep->de_stat.ets_collision++; 399 400 if (tsr & TSR_ABT) 401 dep->de_stat.ets_transAb++; 402 403 if (tsr & TSR_CRS) 404 dep->de_stat.ets_carrSense++; 405 406 if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10)) 407 printf("%s: fifo underrun\n", dep->de_name); 408 409 if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10)) 410 printf("%s: CD heart beat failure\n", dep->de_name); 411 412 if (tsr & TSR_OWC) 413 dep->de_stat.ets_OWC++; 691 414 } 692 else 693 { 694 tsr = inb_reg0(dep, DP_TSR); 695 696 if (tsr &TSR_PTX) dep->de_stat.ets_packetT++; 697 #if 0 /* Reserved in later manuals, should be ignored */ 698 if (!(tsr &TSR_DFR)) 699 { 700 /* In most (all?) implementations of 701 * the dp8390, this bit is set 702 * when the packet is not deferred 703 */ 704 dep->de_stat.ets_transDef++; 705 } 706 #endif 707 if (tsr &TSR_COL) dep->de_stat.ets_collision++; 708 if (tsr &TSR_ABT) dep->de_stat.ets_transAb++; 709 if (tsr &TSR_CRS) dep->de_stat.ets_carrSense++; 710 if (tsr &TSR_FU 711 && ++dep->de_stat.ets_fifoUnder <= 10) 712 { 713 printf("%s: fifo underrun\n", 714 dep->de_name); 715 } 716 if (tsr &TSR_CDH 717 && ++dep->de_stat.ets_CDheartbeat <= 10) 718 { 719 printf("%s: CD heart beat failure\n", 720 dep->de_name); 721 } 722 if (tsr &TSR_OWC) dep->de_stat.ets_OWC++; 723 } 724 sendq_tail= dep->de_sendq_tail; 725 726 if (!(dep->de_sendq[sendq_tail].sq_filled)) 727 { 728 /* Software bug? */ 729 assert(!debug); 730 415 416 sendq_tail = dep->de_sendq_tail; 417 418 if (!(dep->de_sendq[sendq_tail].sq_filled)) { 731 419 /* Or hardware bug? */ 732 printf( 733 "%s: transmit interrupt, but not sending\n", 734 dep->de_name); 420 printf("%s: transmit interrupt, but not sending\n", dep->de_name); 735 421 continue; 736 422 } 737 dep->de_sendq[sendq_tail].sq_filled= 0; 423 424 dep->de_sendq[sendq_tail].sq_filled = 0; 425 738 426 if (++sendq_tail == dep->de_sendq_nr) 739 sendq_tail= 0; 740 dep->de_sendq_tail= sendq_tail; 741 if (dep->de_sendq[sendq_tail].sq_filled) 742 { 743 size= dep->de_sendq[sendq_tail].sq_size; 427 sendq_tail = 0; 428 429 dep->de_sendq_tail = sendq_tail; 430 431 if (dep->de_sendq[sendq_tail].sq_filled) { 432 size = dep->de_sendq[sendq_tail].sq_size; 744 433 outb_reg0(dep, DP_TPSR, 745 434 dep->de_sendq[sendq_tail].sq_sendpage); 746 435 outb_reg0(dep, DP_TBCR1, size >> 8); 747 outb_reg0(dep, DP_TBCR0, size & 0xff);436 outb_reg0(dep, DP_TBCR0, size & 0xff); 748 437 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA); 749 438 } 750 // if (dep->de_flags &DEF_SEND_AVAIL) 751 dp_send(dep);439 440 dep->de_flags &= ~DEF_SEND_AVAIL; 752 441 } 753 754 if (isr &ISR_PRX) 755 { 756 /* Only call dp_recv if there is a read request */ 757 // if (dep->de_flags) &DEF_READING) 758 dp_recv(dep); 759 } 760 761 if (isr &ISR_RXE) dep->de_stat.ets_recvErr++; 762 if (isr &ISR_CNT) 763 { 442 443 if (isr & ISR_PRX) 444 dp_recv(nil_phone, device_id, dep); 445 446 if (isr & ISR_RXE) 447 dep->de_stat.ets_recvErr++; 448 449 if (isr & ISR_CNT) { 764 450 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0); 765 451 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1); 766 452 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2); 767 453 } 768 if (isr &ISR_OVW)769 {454 455 if (isr & ISR_OVW) 770 456 dep->de_stat.ets_OVW++; 771 #if 0 772 {printW(); printf( 773 "%s: got overwrite warning\n", dep->de_name);} 774 #endif 775 /* if (dep->de_flags &DEF_READING) 776 { 777 printf( 778 "dp_check_ints: strange: overwrite warning and pending read request\n"); 779 dp_recv(dep); 780 } 781 */ } 782 if (isr &ISR_RDC) 783 { 457 458 if (isr & ISR_RDC) { 784 459 /* Nothing to do */ 785 460 } 786 if (isr &ISR_RST) 787 { 788 /* this means we got an interrupt but the ethernet 461 462 if (isr & ISR_RST) { 463 /* 464 * This means we got an interrupt but the ethernet 789 465 * chip is shutdown. We set the flag DEF_STOPPED, 790 466 * and continue processing arrived packets. When the 791 467 * receive buffer is empty, we reset the dp8390. 792 468 */ 793 #if 0794 {printW(); printf(795 "%s: NIC stopped\n", dep->de_name);}796 #endif797 469 dep->de_flags |= DEF_STOPPED; 798 470 break; 799 471 } 800 isr = inb_reg0(dep, DP_ISR); 801 } 802 // if ((dep->de_flags &(DEF_READING|DEF_STOPPED)) == 803 // (DEF_READING|DEF_STOPPED)) 804 if ((dep->de_flags &DEF_STOPPED) == DEF_STOPPED) 805 { 806 /* The chip is stopped, and all arrived packets are 807 * delivered. 472 } 473 474 if ((dep->de_flags & DEF_STOPPED) == DEF_STOPPED) { 475 /* 476 * The chip is stopped, and all arrived packets 477 * are delivered. 808 478 */ 809 479 dp_reset(dep); 810 480 } 811 } 812 813 /*===========================================================================* 814 * dp_recv * 815 *===========================================================================*/ 816 static void dp_recv(dep) 817 dpeth_t *dep; 481 482 dep->de_flags &= ~DEF_PACK_SEND; 483 } 484 485 static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep) 818 486 { 819 487 dp_rcvhdr_t header; 820 //unsigned pageno, curr, next;821 488 int pageno, curr, next; 822 vir_byteslength;489 size_t length; 823 490 int packet_processed, r; 824 u 16_t eth_type;825 826 packet_processed = FALSE;491 uint16_t eth_type; 492 493 packet_processed = false; 827 494 pageno = inb_reg0(dep, DP_BNRY) + 1; 828 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;829 830 do831 {495 if (pageno == dep->de_stoppage) 496 pageno = dep->de_startpage; 497 498 do { 832 499 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA); 833 500 curr = inb_reg1(dep, DP_CURR); 834 501 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 835 836 if (curr == pageno) break; 837 838 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header), 839 &header); 840 (dep->de_getblockf)(dep, pageno, sizeof(header) + 841 2*sizeof(ether_addr_t), sizeof(eth_type), ð_type); 842 843 length = (header.dr_rbcl | (header.dr_rbch << 8)) - 844 sizeof(dp_rcvhdr_t); 502 503 if (curr == pageno) 504 break; 505 506 (dep->de_getblockf)(dep, pageno, (size_t) 0, sizeof(header), &header); 507 (dep->de_getblockf)(dep, pageno, sizeof(header) + 2 * sizeof(ether_addr_t), sizeof(eth_type), ð_type); 508 509 length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t); 845 510 next = header.dr_next; 846 if (length < ETH_MIN_PACK_SIZE || 847 length > ETH_MAX_PACK_SIZE_TAGGED) 848 { 849 printf("%s: packet with strange length arrived: %d\n", 850 dep->de_name, (int) length); 511 if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) { 512 printf("%s: packet with strange length arrived: %d\n", dep->de_name, (int) length); 851 513 next= curr; 852 } 853 else if (next < dep->de_startpage || next >= dep->de_stoppage) 854 { 514 } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) { 855 515 printf("%s: strange next page\n", dep->de_name); 856 516 next= curr; 857 } 858 /* else if (eth_type == eth_ign_proto) 859 { 860 */ /* Hack: ignore packets of a given protocol, useful 861 * if you share a net with 80 computers sending 862 * Amoeba FLIP broadcasts. (Protocol 0x8146.) 517 } else if (header.dr_status & RSR_FO) { 518 /* 519 * This is very serious, so we issue a warning and 520 * reset the buffers 863 521 */ 864 /* static int first= 1; 865 if (first) 866 { 867 first= 0; 868 printf("%s: dropping proto 0x%04x packets\n", 869 dep->de_name, 870 ntohs(eth_ign_proto)); 871 } 522 printf("%s: fifo overrun, resetting receive buffer\n", dep->de_name); 523 dep->de_stat.ets_fifoOver++; 524 next = curr; 525 } else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) { 526 r = dp_pkt2user(nil_phone, device_id, dep, pageno, length); 527 if (r != EOK) 528 return; 529 530 packet_processed = true; 872 531 dep->de_stat.ets_packetR++; 873 532 } 874 */ else if (header.dr_status &RSR_FO) 875 { 876 /* This is very serious, so we issue a warning and 877 * reset the buffers */ 878 printf("%s: fifo overrun, resetting receive buffer\n", 879 dep->de_name); 880 dep->de_stat.ets_fifoOver++; 881 next = curr; 882 } 883 else if ((header.dr_status &RSR_PRX) && 884 (dep->de_flags &DEF_ENABLED)) 885 { 886 // if (dep->de_safecopy_read) 887 // r = dp_pkt2user_s(dep, pageno, length); 888 // else 889 r = dp_pkt2user(dep, pageno, length); 890 if (r != OK) 891 return; 892 893 packet_processed = TRUE; 894 dep->de_stat.ets_packetR++; 895 } 533 896 534 if (next == dep->de_startpage) 897 535 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1); 898 536 else 899 537 outb_reg0(dep, DP_BNRY, next - 1); 900 538 901 539 pageno = next; 902 } 903 while (!packet_processed); 904 } 905 906 /*===========================================================================* 907 * dp_send * 908 *===========================================================================*/ 909 static void dp_send(dep) 910 dpeth_t *dep; 911 { 912 packet_t *packet; 913 914 // if (!(dep->de_flags &DEF_SEND_AVAIL)) 915 // return; 916 917 if(dep->packet_queue){ 918 packet = dep->packet_queue; 919 dep->packet_queue = pq_detach(packet); 920 do_pwrite(dep, packet, TRUE); 921 netif_pq_release(packet_get_id(packet)); 922 -- dep->packet_count; 923 } 924 // if(! dep->packet_queue){ 925 // dep->de_flags &= ~DEF_SEND_AVAIL; 926 // } 927 /* switch(dep->de_sendmsg.m_type) 928 { 929 case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break; 930 case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break; 931 case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break; 932 default: 933 panic("", "dp8390: wrong type", dep->de_sendmsg.m_type); 934 break; 935 } 936 */ 937 } 938 939 /*===========================================================================* 940 * dp_getblock * 941 *===========================================================================*/ 942 static void dp_getblock(dep, page, offset, size, dst) 943 dpeth_t *dep; 944 int page; 945 size_t offset; 946 size_t size; 947 void *dst; 948 { 949 // int r; 950 951 offset = page * DP_PAGESIZE + offset; 952 953 memcpy(dst, dep->de_locmem + offset, size); 954 } 955 956 /*===========================================================================* 957 * dp_pio8_getblock * 958 *===========================================================================*/ 959 static void dp_pio8_getblock(dep, page, offset, size, dst) 960 dpeth_t *dep; 961 int page; 962 size_t offset; 963 size_t size; 964 void *dst; 540 } while (!packet_processed); 541 } 542 543 static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst) 965 544 { 966 545 offset = page * DP_PAGESIZE + offset; … … 970 549 outb_reg0(dep, DP_RSAR1, offset >> 8); 971 550 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 972 551 973 552 insb(dep->de_data_port, dst, size); 974 553 } 975 554 976 /*===========================================================================* 977 * dp_pio16_getblock * 978 *===========================================================================*/ 979 static void dp_pio16_getblock(dep, page, offset, size, dst) 980 dpeth_t *dep; 981 int page; 982 size_t offset; 983 size_t size; 984 void *dst; 555 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst) 985 556 { 986 557 offset = page * DP_PAGESIZE + offset; … … 990 561 outb_reg0(dep, DP_RSAR1, offset >> 8); 991 562 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 992 993 assert (!(size &1)); 563 564 assert(!(size & 1)); 565 994 566 insw(dep->de_data_port, dst, size); 995 567 } 996 568 997 /*===========================================================================* 998 * dp_pkt2user * 999 *===========================================================================*/ 1000 static int dp_pkt2user(dep, page, length) 1001 dpeth_t *dep; 1002 int page, length; 569 static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length) 1003 570 { 1004 571 int last, count; 1005 572 packet_t *packet; 1006 1007 // if (!(dep->de_flags &DEF_READING)) 1008 // return EGENERIC; 1009 573 1010 574 packet = netif_packet_get_1(length); 1011 if (! packet){575 if (!packet) 1012 576 return ENOMEM; 1013 } 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 = (uintptr_t) NULL; 1018 577 578 void *buf = packet_suffix(packet, length); 579 1019 580 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; 581 if (last >= dep->de_stoppage) { 582 count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t); 583 1027 584 (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 { 585 sizeof(dp_rcvhdr_t), buf, 0, count); 586 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE, 587 buf, count, length - count); 588 } else { 1034 589 (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 *===========================================================================*/ 1058 static void dp_user2nic(dep, iovp, offset, nic_addr, count) 1059 dpeth_t *dep; 1060 iovec_dat_t *iovp; 1061 vir_bytes offset; 1062 int nic_addr; 1063 vir_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 *===========================================================================*/ 1108 static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count) 1109 dpeth_t *dep; 1110 iovec_dat_t *iovp; 1111 vir_bytes offset; 1112 int nic_addr; 1113 vir_bytes count; 1114 { 1115 // phys_bytes phys_user; 1116 int i; 1117 vir_bytes bytes; 1118 590 sizeof(dp_rcvhdr_t), buf, 0, length); 591 } 592 593 nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE); 594 595 return EOK; 596 } 597 598 static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 599 { 1119 600 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);601 602 outb_reg0(dep, DP_RBCR0, size & 0xFF); 603 outb_reg0(dep, DP_RBCR1, size >> 8); 604 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 1124 605 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1125 606 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) 607 608 outsb(dep->de_data_port, buf + offset, size); 609 610 unsigned int i; 611 for (i = 0; i < 100; i++) { 612 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 1157 613 break; 1158 614 } 615 1159 616 if (i == 100) 1160 { 1161 panic("", "dp8390: remote dma failed to complete", NO_NUM); 1162 } 1163 } 1164 1165 /*===========================================================================* 1166 * dp_pio16_user2nic * 1167 *===========================================================================*/ 1168 static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count) 1169 dpeth_t *dep; 1170 iovec_dat_t *iovp; 1171 vir_bytes offset; 1172 int nic_addr; 1173 vir_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 617 fprintf(stderr, "dp8390: remote DMA failed to complete\n"); 618 } 619 620 static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 621 { 622 void *vir_user; 623 size_t ecount; 624 uint16_t two_bytes; 625 626 ecount = size & ~1; 627 1186 628 outb_reg0(dep, DP_ISR, ISR_RDC); 1187 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);629 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 1188 630 outb_reg0(dep, DP_RBCR1, ecount >> 8); 1189 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);631 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 1190 632 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1191 633 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); 634 635 vir_user = buf + offset; 636 if (ecount != 0) { 637 outsw(dep->de_data_port, vir_user, ecount); 638 size -= ecount; 639 offset += ecount; 640 vir_user += ecount; 641 } 642 643 if (size) { 644 assert(size == 1); 645 646 memcpy(&(((uint8_t *) &two_bytes)[0]), vir_user, 1); 1269 647 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) 648 } 649 650 unsigned int i; 651 for (i = 0; i < 100; i++) { 652 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 1274 653 break; 1275 654 } 655 1276 656 if (i == 100) 1277 { 1278 panic("", "dp8390: remote dma failed to complete", NO_NUM); 1279 } 1280 } 1281 1282 /*===========================================================================* 1283 * dp_nic2user * 1284 *===========================================================================*/ 1285 static void dp_nic2user(dep, nic_addr, iovp, offset, count) 1286 dpeth_t *dep; 1287 int nic_addr; 1288 iovec_dat_t *iovp; 1289 vir_bytes offset; 1290 vir_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 *===========================================================================*/ 1334 static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count) 1335 dpeth_t *dep; 1336 int nic_addr; 1337 iovec_dat_t *iovp; 1338 vir_bytes offset; 1339 vir_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); 657 fprintf(stderr, "dp8390: remote dma failed to complete\n"); 658 } 659 660 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 661 { 662 outb_reg0(dep, DP_RBCR0, size & 0xFF); 663 outb_reg0(dep, DP_RBCR1, size >> 8); 664 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 1348 665 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1349 666 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 *===========================================================================*/ 1382 static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count) 1383 dpeth_t *dep; 1384 int nic_addr; 1385 iovec_dat_t *iovp; 1386 vir_bytes offset; 1387 vir_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); 667 668 insb(dep->de_data_port, buf + offset, size); 669 } 670 671 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 672 { 673 void *vir_user; 674 size_t ecount; 675 uint16_t two_bytes; 676 677 ecount = size & ~1; 678 679 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 1401 680 outb_reg0(dep, DP_RBCR1, ecount >> 8); 1402 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);681 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 1403 682 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1404 683 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 *===========================================================================*/ 1484 static void dp_next_iovec(iovp) 1485 iovec_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 *===========================================================================*/ 1501 static void conf_hw(dep) 1502 dpeth_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 { 684 685 vir_user = buf + offset; 686 if (ecount != 0) { 687 insw(dep->de_data_port, vir_user, ecount); 688 size -= ecount; 689 offset += ecount; 690 vir_user += ecount; 691 } 692 693 if (size) { 694 assert(size == 1); 695 696 two_bytes = inw(dep->de_data_port); 697 memcpy(vir_user, &(((uint8_t *) &two_bytes)[0]), 1); 698 } 699 } 700 701 static void conf_hw(dpeth_t *dep) 702 { 703 if (!ne_probe(dep)) { 1518 704 printf("%s: No ethernet card found at %#lx\n", 1519 705 dep->de_name, dep->de_base_port); … … 1521 707 return; 1522 708 } 1523 1524 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000; 1525 709 1526 710 dep->de_mode = DEM_ENABLED; 1527 1528 711 dep->de_flags = DEF_EMPTY; 1529 // dep->de_stat = empty_stat;1530 }1531 1532 /*===========================================================================*1533 * map_hw_buffer *1534 *===========================================================================*/1535 static void map_hw_buffer(dep)1536 dpeth_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 01545 if(debug){1546 printf(1547 "map_hw_buffer: programmed I/O, no need to map buffer\n");1548 }1549 #endif1550 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 for1557 // * alignment1558 // */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 *===========================================================================*/1576 static void reply(dep, err, may_block)1577 dpeth_t *dep;1578 int err;1579 int 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 01602 printf("send locked\n");1603 #endif1604 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 *===========================================================================*/1617 static void get_userdata(user_proc, user_addr, count, loc_addr)1618 int user_proc;1619 vir_bytes user_addr;1620 vir_bytes count;1621 void *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 712 } 1630 713 … … 1632 715 { 1633 716 size_t i; 1634 1635 for (i = 0; i < size; ++ i){717 718 for (i = 0; i < size; i++) 1636 719 *((uint8_t *) buf + i) = inb(port); 1637 }1638 720 } 1639 721 … … 1641 723 { 1642 724 size_t i; 1643 1644 for (i = 0; i * 2 < size; ++ i){725 726 for (i = 0; i * 2 < size; i++) 1645 727 *((uint16_t *) buf + i) = inw(port); 1646 }1647 728 } 1648 729 … … 1650 731 { 1651 732 size_t i; 1652 1653 for (i = 0; i < size; ++ i){733 734 for (i = 0; i < size; i++) 1654 735 outb(port, *((uint8_t *) buf + i)); 1655 }1656 736 } 1657 737 … … 1659 739 { 1660 740 size_t i; 1661 1662 for (i = 0; i * 2 < size; ++ i){741 742 for (i = 0; i * 2 < size; i++) 1663 743 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 */ 744 } 1670 745 1671 746 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.