Changeset b1d15e7 in mainline
- Timestamp:
- 2011-01-06T20:16:24Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c2f3e0b
- Parents:
- 196ef08 (diff), e0854e3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/srv
- Files:
-
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/dp8390.c
r196ef08 rb1d15e7 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 /** @} -
uspace/srv/hw/netif/dp8390/dp8390.h
r196ef08 rb1d15e7 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 … … 37 50 38 51 #include <net/packet.h> 39 40 52 #include "dp8390_port.h" 41 #include "local.h" 42 43 /** Input/output size. 44 */ 45 #define DP8390_IO_SIZE 0x020 46 47 /* 48 dp8390.h 49 50 Created: before Dec 28, 1992 by Philip Homburg 51 */ 53 54 /** Input/output size */ 55 #define DP8390_IO_SIZE 0x0020 52 56 53 57 /* National Semiconductor DP8390 Network Interface Controller. */ 54 58 55 /* Page 0, for reading ------------- */ 56 #define DP_CR 0x0 /* Read side of Command Register */ 57 #define DP_CLDA0 0x1 /* Current Local Dma Address 0 */ 58 #define DP_CLDA1 0x2 /* Current Local Dma Address 1 */ 59 #define DP_BNRY 0x3 /* Boundary Pointer */ 60 #define DP_TSR 0x4 /* Transmit Status Register */ 61 #define DP_NCR 0x5 /* Number of Collisions Register */ 62 #define DP_FIFO 0x6 /* Fifo ?? */ 63 #define DP_ISR 0x7 /* Interrupt Status Register */ 64 #define DP_CRDA0 0x8 /* Current Remote Dma Address 0 */ 65 #define DP_CRDA1 0x9 /* Current Remote Dma Address 1 */ 66 #define DP_DUM1 0xA /* unused */ 67 #define DP_DUM2 0xB /* unused */ 68 #define DP_RSR 0xC /* Receive Status Register */ 69 #define DP_CNTR0 0xD /* Tally Counter 0 */ 70 #define DP_CNTR1 0xE /* Tally Counter 1 */ 71 #define DP_CNTR2 0xF /* Tally Counter 2 */ 72 73 /* Page 0, for writing ------------- */ 74 #define DP_CR 0x0 /* Write side of Command Register */ 75 #define DP_PSTART 0x1 /* Page Start Register */ 76 #define DP_PSTOP 0x2 /* Page Stop Register */ 77 #define DP_BNRY 0x3 /* Boundary Pointer */ 78 #define DP_TPSR 0x4 /* Transmit Page Start Register */ 79 #define DP_TBCR0 0x5 /* Transmit Byte Count Register 0 */ 80 #define DP_TBCR1 0x6 /* Transmit Byte Count Register 1 */ 81 #define DP_ISR 0x7 /* Interrupt Status Register */ 82 #define DP_RSAR0 0x8 /* Remote Start Address Register 0 */ 83 #define DP_RSAR1 0x9 /* Remote Start Address Register 1 */ 84 #define DP_RBCR0 0xA /* Remote Byte Count Register 0 */ 85 #define DP_RBCR1 0xB /* Remote Byte Count Register 1 */ 86 #define DP_RCR 0xC /* Receive Configuration Register */ 87 #define DP_TCR 0xD /* Transmit Configuration Register */ 88 #define DP_DCR 0xE /* Data Configuration Register */ 89 #define DP_IMR 0xF /* Interrupt Mask Register */ 90 91 /* Page 1, read/write -------------- */ 92 #define DP_CR 0x0 /* Command Register */ 59 /** Page 0, for reading */ 60 #define DP_CR 0x00 /**< Command Register */ 61 #define DP_CLDA0 0x01 /**< Current Local DMA Address 0 */ 62 #define DP_CLDA1 0x02 /**< Current Local DMA Address 1 */ 63 #define DP_BNRY 0x03 /**< Boundary Pointer */ 64 #define DP_TSR 0x04 /**< Transmit Status Register */ 65 #define DP_NCR 0x05 /**< Number of Collisions Register */ 66 #define DP_FIFO 0x06 /**< FIFO */ 67 #define DP_ISR 0x07 /**< Interrupt Status Register */ 68 #define DP_CRDA0 0x08 /**< Current Remote DMA Address 0 */ 69 #define DP_CRDA1 0x09 /**< Current Remote DMA Address 1 */ 70 #define DP_RSR 0x0c /**< Receive Status Register */ 71 #define DP_CNTR0 0x0d /**< Tally Counter 0 */ 72 #define DP_CNTR1 0x0e /**< Tally Counter 1 */ 73 #define DP_CNTR2 0x0f /**< Tally Counter 2 */ 74 75 /** Page 0, for writing */ 76 #define DP_PSTART 0x01 /**< Page Start Register*/ 77 #define DP_PSTOP 0x02 /**< Page Stop Register */ 78 #define DP_TPSR 0x04 /**< Transmit Page Start Register */ 79 #define DP_TBCR0 0x05 /**< Transmit Byte Count Register 0 */ 80 #define DP_TBCR1 0x06 /**< Transmit Byte Count Register 1 */ 81 #define DP_RSAR0 0x08 /**< Remote Start Address Register 0 */ 82 #define DP_RSAR1 0x09 /**< Remote Start Address Register 1 */ 83 #define DP_RBCR0 0x0a /**< Remote Byte Count Register 0 */ 84 #define DP_RBCR1 0x0b /**< Remote Byte Count Register 1 */ 85 #define DP_RCR 0x0c /**< Receive Configuration Register */ 86 #define DP_TCR 0x0d /**< Transmit Configuration Register */ 87 #define DP_DCR 0x0e /**< Data Configuration Register */ 88 #define DP_IMR 0x0f /**< Interrupt Mask Register */ 89 90 /** Page 1, read/write */ 93 91 #define DP_PAR0 0x1 /* Physical Address Register 0 */ 94 92 #define DP_PAR1 0x2 /* Physical Address Register 1 */ … … 199 197 #define RSR_DFR 0x80 /* In later manuals: Deferring */ 200 198 201 /** Type definition of the receive header. 202 */ 203 typedef struct dp_rcvhdr 204 { 205 /** Copy of rsr. 206 */ 207 u8_t dr_status; 208 /** Pointer to next packet. 209 */ 210 u8_t dr_next; 211 /** Receive Byte Count Low. 212 */ 213 u8_t dr_rbcl; 214 /** Receive Byte Count High. 215 */ 216 u8_t dr_rbch; 199 /** Type definition of the receive header 200 * 201 */ 202 typedef struct dp_rcvhdr { 203 /** Copy of rsr */ 204 uint8_t dr_status; 205 206 /** Pointer to next packet */ 207 uint8_t dr_next; 208 209 /** Receive Byte Count Low */ 210 uint8_t dr_rbcl; 211 212 /** Receive Byte Count High */ 213 uint8_t dr_rbch; 217 214 } dp_rcvhdr_t; 218 215 219 /** Page size. 220 */ 221 #define DP_PAGESIZE 256 222 223 /* Some macros to simplify accessing the dp8390 */ 224 /** Reads 1 byte from the zero page register. 216 /** Page size */ 217 #define DP_PAGESIZE 256 218 219 /** Read 1 byte from the zero page register. 225 220 * @param[in] dep The network interface structure. 226 221 * @param[in] reg The register offset. 227 222 * @returns The read value. 228 223 */ 229 #define inb_reg0(dep, reg) (inb(dep->de_dp8390_port+reg))230 231 /** Write s1 byte zero page register.224 #define inb_reg0(dep, reg) (inb(dep->de_dp8390_port + reg)) 225 226 /** Write 1 byte zero page register. 232 227 * @param[in] dep The network interface structure. 233 228 * @param[in] reg The register offset. 234 229 * @param[in] data The value to be written. 235 230 */ 236 #define outb_reg0(dep, reg, data) (outb(dep->de_dp8390_port+reg, data))237 238 /** Read s1 byte from the first page register.231 #define outb_reg0(dep, reg, data) (outb(dep->de_dp8390_port + reg, data)) 232 233 /** Read 1 byte from the first page register. 239 234 * @param[in] dep The network interface structure. 240 235 * @param[in] reg The register offset. 241 236 * @returns The read value. 242 237 */ 243 #define inb_reg1(dep, reg) (inb(dep->de_dp8390_port+reg))244 245 /** Write s1 byte first page register.238 #define inb_reg1(dep, reg) (inb(dep->de_dp8390_port + reg)) 239 240 /** Write 1 byte first page register. 246 241 * @param[in] dep The network interface structure. 247 242 * @param[in] reg The register offset. 248 243 * @param[in] data The value to be written. 249 244 */ 250 #define outb_reg1(dep, reg, data) (outb(dep->de_dp8390_port+reg, data))245 #define outb_reg1(dep, reg, data) (outb(dep->de_dp8390_port + reg, data)) 251 246 252 247 /* Software interface to the dp8390 driver */ 253 248 254 249 struct dpeth; 255 struct iovec_dat; 256 //struct iovec_dat_s; 257 _PROTOTYPE(typedef void (*dp_initf_t), (struct dpeth *dep) ); 258 _PROTOTYPE(typedef void (*dp_stopf_t), (struct dpeth *dep) ); 259 _PROTOTYPE(typedef void (*dp_user2nicf_t), (struct dpeth *dep, 260 struct iovec_dat *iovp, vir_bytes offset, 261 int nic_addr, vir_bytes count) ); 262 //_PROTOTYPE(typedef void (*dp_user2nicf_s_t), (struct dpeth *dep, 263 // struct iovec_dat_s *iovp, vir_bytes offset, 264 // int nic_addr, vir_bytes count) ); 265 _PROTOTYPE(typedef void (*dp_nic2userf_t), (struct dpeth *dep, 266 int nic_addr, struct iovec_dat *iovp, 267 vir_bytes offset, vir_bytes count) ); 268 //_PROTOTYPE(typedef void (*dp_nic2userf_s_t), (struct dpeth *dep, 269 // int nic_addr, struct iovec_dat_s *iovp, 270 // vir_bytes offset, vir_bytes count) ); 271 //#if 0 272 //_PROTOTYPE(typedef void (*dp_getheaderf_t), (struct dpeth *dep, 273 // int page, struct dp_rcvhdr *h, u16_t *eth_type) ); 274 //#endif 275 _PROTOTYPE(typedef void (*dp_getblock_t), (struct dpeth *dep, 276 int page, size_t offset, size_t size, void *dst) ); 277 278 /* iovectors are handled IOVEC_NR entries at a time. */ 279 //#define IOVEC_NR 16 280 // no vectors allowed 281 #define IOVEC_NR 1 282 283 /* 284 typedef int irq_hook_t; 285 */ 286 typedef struct iovec_dat 287 { 288 iovec_t iod_iovec[IOVEC_NR]; 289 int iod_iovec_s; 290 // no direct process access 291 int iod_proc_nr; 292 vir_bytes iod_iovec_addr; 293 } iovec_dat_t; 294 /* 295 typedef struct iovec_dat_s 296 { 297 iovec_s_t iod_iovec[IOVEC_NR]; 298 int iod_iovec_s; 299 int iod_proc_nr; 300 cp_grant_id_t iod_grant; 301 vir_bytes iod_iovec_offset; 302 } iovec_dat_s_t; 303 */ 304 #define SENDQ_NR 1 /* Maximum size of the send queue */ 305 #define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */ 306 307 /** Maximum number of waiting packets to be sent or received. 308 */ 309 #define MAX_PACKETS 4 310 311 typedef struct dpeth 312 { 313 /** Outgoing packets queue. 314 */ 315 packet_t *packet_queue; 316 /** Outgoing packets count. 317 */ 318 int packet_count; 319 320 /** Received packets queue. 321 */ 322 packet_t *received_queue; 323 /** Received packets count. 324 */ 325 int received_count; 326 327 /* The de_base_port field is the starting point of the probe. 328 * The conf routine also fills de_linmem and de_irq. If the probe 250 251 typedef void (*dp_initf_t)(struct dpeth *dep); 252 typedef void (*dp_stopf_t)(struct dpeth *dep); 253 typedef void (*dp_user2nicf_t)(struct dpeth *dep, void *buf, size_t offset, int nic_addr, size_t size); 254 typedef void (*dp_nic2userf_t)(struct dpeth *dep, int nic_addr, void *buf, size_t offset, size_t size); 255 typedef void (*dp_getblock_t)(struct dpeth *dep, int page, size_t offset, size_t size, void *dst); 256 257 #define SENDQ_NR 2 /* Maximum size of the send queue */ 258 #define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */ 259 260 typedef struct dpeth { 261 /* 262 * The de_base_port field is the starting point of the probe. 263 * The conf routine also fills de_irq. If the probe 329 264 * routine knows the irq and/or memory address because they are 330 265 * hardwired in the board, the probe should modify these fields. 331 266 * Futhermore, the probe routine should also fill in de_initf and 332 * de_stopf fields with the appropriate function pointers and set 333 * de_prog_IO iff programmed I/O is to be used. 267 * de_stopf fields with the appropriate function pointers. 334 268 */ 335 269 port_t de_base_port; 336 phys_bytes de_linmem;337 char *de_locmem;338 270 int de_irq; 339 int de_int_pending; 340 // irq_hook_t de_hook; 341 dp_initf_t de_initf; 342 dp_stopf_t de_stopf; 343 int de_prog_IO; 271 dp_initf_t de_initf; 272 dp_stopf_t de_stopf; 344 273 char de_name[sizeof("dp8390#n")]; 345 346 /* The initf function fills the following fields. Only cards that do 274 275 /* 276 * The initf function fills the following fields. Only cards that do 347 277 * programmed I/O fill in the de_pata_port field. 348 278 * In addition, the init routine has to fill in the sendq data … … 357 287 int de_startpage; 358 288 int de_stoppage; 359 360 /* should be here - read even for ne2k isa init... */ 361 char de_pci; /* TRUE iff PCI device */ 362 363 #if ENABLE_PCI 364 /* PCI config */ 365 // char de_pci; /* TRUE iff PCI device */ 366 // u8_t de_pcibus; 367 // u8_t de_pcidev; 368 // u8_t de_pcifunc; 369 #endif 370 289 371 290 /* Do it yourself send queue */ 372 struct sendq 373 { 374 int sq_filled; /* this buffer contains a packet */ 375 int sq_size; /* with this size */ 376 int sq_sendpage; /* starting page of the buffer */ 291 struct sendq { 292 int sq_filled; /* this buffer contains a packet */ 293 int sq_size; /* with this size */ 294 int sq_sendpage; /* starting page of the buffer */ 377 295 } de_sendq[SENDQ_NR]; 296 378 297 int de_sendq_nr; 379 int de_sendq_head; 380 int de_sendq_tail; 381 298 int de_sendq_head; /* Enqueue at the head */ 299 int de_sendq_tail; /* Dequeue at the tail */ 300 382 301 /* Fields for internal use by the dp8390 driver. */ 383 302 int de_flags; 384 303 int de_mode; 385 304 eth_stat_t de_stat; 386 iovec_dat_t de_read_iovec; 387 // iovec_dat_s_t de_read_iovec_s; 388 // int de_safecopy_read; 389 iovec_dat_t de_write_iovec; 390 // iovec_dat_s_t de_write_iovec_s; 391 iovec_dat_t de_tmp_iovec; 392 // iovec_dat_s_t de_tmp_iovec_s; 393 vir_bytes de_read_s; 394 // int de_client; 395 // message de_sendmsg; 396 dp_user2nicf_t de_user2nicf; 397 // dp_user2nicf_s_t de_user2nicf_s; 305 dp_user2nicf_t de_user2nicf; 398 306 dp_nic2userf_t de_nic2userf; 399 // dp_nic2userf_s_t de_nic2userf_s;400 307 dp_getblock_t de_getblockf; 401 308 } dpeth_t; 402 309 403 #define DEI_DEFAULT 0x8000 404 405 #define DEF_EMPTY 0x000 406 #define DEF_PACK_SEND 0x001 407 #define DEF_PACK_RECV 0x002 408 #define DEF_SEND_AVAIL 0x004 409 #define DEF_READING 0x010 410 #define DEF_PROMISC 0x040 411 #define DEF_MULTI 0x080 412 #define DEF_BROAD 0x100 413 #define DEF_ENABLED 0x200 414 #define DEF_STOPPED 0x400 415 416 #define DEM_DISABLED 0x0 417 #define DEM_SINK 0x1 418 #define DEM_ENABLED 0x2 419 420 //#if !__minix_vmd 421 #define debug 1 /* Standard Minix lacks debug variable */ 422 //#endif 423 424 /* 425 * $PchId: dp8390.h,v 1.10 2005/02/10 17:26:06 philip Exp $ 426 */ 310 #define DEF_EMPTY 0x000 311 #define DEF_PACK_SEND 0x001 312 #define DEF_SEND_AVAIL 0x004 313 #define DEF_PROMISC 0x040 314 #define DEF_MULTI 0x080 315 #define DEF_BROAD 0x100 316 #define DEF_ENABLED 0x200 317 #define DEF_STOPPED 0x400 318 319 #define DEM_DISABLED 0x0 320 #define DEM_ENABLED 0x2 427 321 428 322 #endif -
uspace/srv/hw/netif/dp8390/dp8390_drv.h
r196ef08 rb1d15e7 55 55 /** Processes the interrupt. 56 56 * @param[in,out] dep The network interface structure. 57 * @param[in] isr The interrupt status register.58 57 */ 59 void dp_check_ints( dpeth_t *dep, int isr);58 void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, int isr); 60 59 61 60 /** Probes and initializes the network interface. … … 70 69 * @param[in] packet The packet t be sent. 71 70 * @param[in] from_int The value indicating whether the sending is initialized from the interrupt handler. 72 * @returns 71 * @returns 73 72 */ 74 73 int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int); 75 76 /** Prints out network interface information.77 * @param[in] dep The network interface structure.78 */79 void dp8390_dump(dpeth_t * dep);80 74 81 75 #endif -
uspace/srv/hw/netif/dp8390/dp8390_module.c
r196ef08 rb1d15e7 43 43 #include <ipc/ipc.h> 44 44 #include <ipc/services.h> 45 46 45 #include <net/modules.h> 47 46 #include <packet_client.h> … … 51 50 #include <netif_interface.h> 52 51 #include <netif_local.h> 53 54 52 #include "dp8390.h" 55 53 #include "dp8390_drv.h" … … 60 58 #define NAME "dp8390" 61 59 62 /** Returns the device from the interrupt call. 60 /** Return the device from the interrupt call. 61 * 63 62 * @param[in] call The interrupt call. 64 */ 65 #define IRQ_GET_DEVICE(call) (device_id_t) IPC_GET_IMETHOD(*call) 66 67 /** Returns the interrupt status register from the interrupt call. 63 * 64 */ 65 #define IRQ_GET_DEVICE(call) ((device_id_t) IPC_GET_IMETHOD(call)) 66 67 /** Return the ISR from the interrupt call. 68 * 68 69 * @param[in] call The interrupt call. 69 */ 70 #define IPC_GET_ISR(call) (int) IPC_GET_ARG2(*call) 70 * 71 */ 72 #define IRQ_GET_ISR(call) ((int) IPC_GET_ARG2(call)) 71 73 72 74 /** DP8390 kernel interrupt command sequence. 73 75 */ 74 static irq_cmd_t dp8390_cmds[] = { 75 { .cmd = CMD_PIO_READ_8, 76 static irq_cmd_t dp8390_cmds[] = { 77 { 78 .cmd = CMD_PIO_READ_8, 76 79 .addr = NULL, 77 80 .dstarg = 2 78 81 }, 79 82 { 83 .cmd = CMD_BTEST, 84 .value = 0x7f, 85 .srcarg = 2, 86 .dstarg = 3, 87 }, 88 { 80 89 .cmd = CMD_PREDICATE, 81 .value = 1,82 .srcarg = 290 .value = 2, 91 .srcarg = 3 83 92 }, 84 93 { 94 .cmd = CMD_PIO_WRITE_8, 95 .addr = NULL, 96 .value = 0xff 97 }, 98 { 85 99 .cmd = CMD_ACCEPT 86 100 } … … 89 103 /** DP8390 kernel interrupt code. 90 104 */ 91 static irq_code_t 105 static irq_code_t dp8390_code = { 92 106 sizeof(dp8390_cmds) / sizeof(irq_cmd_t), 93 107 dp8390_cmds … … 99 113 * @param[in] call The interrupt message. 100 114 */ 101 static void irq_handler(ipc_callid_t iid, ipc_call_t * call) 102 { 103 netif_device_t * device; 104 dpeth_t * dep; 105 packet_t *received; 106 device_id_t device_id; 107 int phone; 108 109 device_id = IRQ_GET_DEVICE(call); 115 static void irq_handler(ipc_callid_t iid, ipc_call_t *call) 116 { 117 device_id_t device_id = IRQ_GET_DEVICE(*call); 118 netif_device_t *device; 119 int nil_phone; 120 dpeth_t *dep; 121 110 122 fibril_rwlock_write_lock(&netif_globals.lock); 111 if(find_device(device_id, &device) != EOK){ 112 fibril_rwlock_write_unlock(&netif_globals.lock); 113 return; 114 } 115 dep = (dpeth_t *) device->specific; 116 if (dep->de_mode != DEM_ENABLED){ 117 fibril_rwlock_write_unlock(&netif_globals.lock); 118 return; 119 } 120 assert(dep->de_flags &DEF_ENABLED); 121 dep->de_int_pending = 0; 122 dp_check_ints(dep, IPC_GET_ISR(call)); 123 if(dep->received_queue){ 124 received = dep->received_queue; 125 phone = device->nil_phone; 126 dep->received_queue = NULL; 127 dep->received_count = 0; 128 fibril_rwlock_write_unlock(&netif_globals.lock); 129 nil_received_msg(phone, device_id, received, SERVICE_NONE); 130 }else{ 131 fibril_rwlock_write_unlock(&netif_globals.lock); 132 } 133 ipc_answer_0(iid, EOK); 123 124 if (find_device(device_id, &device) == EOK) { 125 nil_phone = device->nil_phone; 126 dep = (dpeth_t *) device->specific; 127 } else 128 dep = NULL; 129 130 fibril_rwlock_write_unlock(&netif_globals.lock); 131 132 if ((dep != NULL) && (dep->de_mode == DEM_ENABLED)) { 133 assert(dep->de_flags & DEF_ENABLED); 134 dp_check_ints(nil_phone, device_id, dep, IRQ_GET_ISR(*call)); 135 } 134 136 } 135 137 … … 139 141 * @returns The new state. 140 142 */ 141 static int change_state(netif_device_t * 143 static int change_state(netif_device_t *device, device_state_t state) 142 144 { 143 145 if (device->state != state) { … … 153 155 } 154 156 155 int netif_specific_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 157 int netif_specific_message(ipc_callid_t callid, ipc_call_t *call, 158 ipc_call_t *answer, int *answer_count) 159 { 156 160 return ENOTSUP; 157 161 } … … 162 166 eth_stat_t * de_stat; 163 167 int rc; 164 165 if (! stats){168 169 if (!stats) 166 170 return EBADMEM; 167 }171 168 172 rc = find_device(device_id, &device); 169 173 if (rc != EOK) 170 174 return rc; 175 171 176 de_stat = &((dpeth_t *) device->specific)->de_stat; 177 172 178 null_device_stats(stats); 173 179 stats->receive_errors = de_stat->ets_recvErr; … … 183 189 stats->send_heartbeat_errors = de_stat->ets_CDheartbeat; 184 190 stats->send_window_errors = de_stat->ets_OWC; 185 return EOK; 186 } 187 188 int netif_get_addr_message(device_id_t device_id, measured_string_t *address){ 189 netif_device_t * device; 190 int rc; 191 192 if(! address){ 191 192 return EOK; 193 } 194 195 int netif_get_addr_message(device_id_t device_id, measured_string_t *address) 196 { 197 netif_device_t *device; 198 int rc; 199 200 if (!address) 193 201 return EBADMEM; 194 }202 195 203 rc = find_device(device_id, &device); 196 204 if (rc != EOK) 197 205 return rc; 206 198 207 address->value = (char *) (&((dpeth_t *) device->specific)->de_address); 199 208 address->length = sizeof(ether_addr_t); … … 201 210 } 202 211 203 204 205 int netif_probe_message(device_id_t device_id, int irq, uintptr_t io){ 206 netif_device_t * device; 207 dpeth_t * dep; 208 int rc; 209 212 int netif_probe_message(device_id_t device_id, int irq, uintptr_t io) 213 { 214 netif_device_t *device; 215 dpeth_t *dep; 216 int rc; 217 210 218 device = (netif_device_t *) malloc(sizeof(netif_device_t)); 211 if (! device){219 if (!device) 212 220 return ENOMEM; 213 }221 214 222 dep = (dpeth_t *) malloc(sizeof(dpeth_t)); 215 if (! dep){223 if (!dep) { 216 224 free(device); 217 225 return ENOMEM; 218 226 } 227 219 228 bzero(device, sizeof(netif_device_t)); 220 229 bzero(dep, sizeof(dpeth_t)); … … 225 234 dep->de_irq = irq; 226 235 dep->de_mode = DEM_DISABLED; 236 227 237 //TODO address? 228 238 rc = pio_enable((void *) io, DP8390_IO_SIZE, (void **) &dep->de_base_port); … … 231 241 free(device); 232 242 return rc; 233 } 243 } 244 234 245 rc = do_probe(dep); 235 246 if (rc != EOK) { … … 238 249 return rc; 239 250 } 251 240 252 rc = netif_device_map_add(&netif_globals.device_map, device->device_id, device); 241 if (rc != EOK) {253 if (rc != EOK) { 242 254 free(dep); 243 255 free(device); 244 256 return rc; 245 257 } 246 return EOK; 247 } 248 249 int netif_send_message(device_id_t device_id, packet_t *packet, services_t sender){ 250 netif_device_t * device; 251 dpeth_t * dep; 258 259 return EOK; 260 } 261 262 int netif_send_message(device_id_t device_id, packet_t *packet, 263 services_t sender) 264 { 265 netif_device_t *device; 266 dpeth_t *dep; 252 267 packet_t *next; 253 268 int rc; 254 269 255 270 rc = find_device(device_id, &device); 256 271 if (rc != EOK) 257 272 return rc; 258 if(device->state != NETIF_ACTIVE){ 273 274 if (device->state != NETIF_ACTIVE){ 259 275 netif_pq_release(packet_get_id(packet)); 260 276 return EFORWARD; 261 277 } 278 262 279 dep = (dpeth_t *) device->specific; 263 // process packet queue 264 do{ 280 281 /* Process packet queue */ 282 do { 265 283 next = pq_detach(packet); 266 if(do_pwrite(dep, packet, FALSE) != EBUSY){ 284 285 if (do_pwrite(dep, packet, false) != EBUSY) 267 286 netif_pq_release(packet_get_id(packet)); 268 }287 269 288 packet = next; 270 }while(packet); 271 return EOK; 272 } 273 274 int netif_start_message(netif_device_t * device){ 275 dpeth_t * dep; 276 int rc; 277 278 if(device->state != NETIF_ACTIVE){ 289 } while (packet); 290 291 return EOK; 292 } 293 294 int netif_start_message(netif_device_t * device) 295 { 296 dpeth_t *dep; 297 int rc; 298 299 if (device->state != NETIF_ACTIVE) { 279 300 dep = (dpeth_t *) device->specific; 280 301 dp8390_cmds[0].addr = (void *) (uintptr_t) (dep->de_dp8390_port + DP_ISR); 281 dp8390_cmds[2].addr = dp8390_cmds[0].addr; 302 dp8390_cmds[3].addr = dp8390_cmds[0].addr; 303 282 304 rc = ipc_register_irq(dep->de_irq, device->device_id, device->device_id, &dp8390_code); 283 305 if (rc != EOK) 284 306 return rc; 307 285 308 rc = do_init(dep, DL_BROAD_REQ); 286 309 if (rc != EOK) { … … 288 311 return rc; 289 312 } 313 290 314 return change_state(device, NETIF_ACTIVE); 291 315 } 292 return EOK; 293 } 294 295 int netif_stop_message(netif_device_t * device){ 296 dpeth_t * dep; 297 298 if(device->state != NETIF_STOPPED){ 316 317 return EOK; 318 } 319 320 int netif_stop_message(netif_device_t * device) 321 { 322 dpeth_t *dep; 323 324 if (device->state != NETIF_STOPPED) { 299 325 dep = (dpeth_t *) device->specific; 300 326 do_stop(dep); … … 302 328 return change_state(device, NETIF_STOPPED); 303 329 } 304 return EOK; 305 } 306 307 int netif_initialize(void){ 330 331 return EOK; 332 } 333 334 int netif_initialize(void) 335 { 308 336 sysarg_t phonehash; 309 310 337 async_set_interrupt_received(irq_handler); 311 312 338 return ipc_connect_to_me(PHONE_NS, SERVICE_DP8390, 0, 0, &phonehash); 313 339 } … … 319 345 * 320 346 */ 321 static void netif_client_connection(ipc_callid_t iid, ipc_call_t * 347 static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall) 322 348 { 323 349 /* … … 327 353 ipc_answer_0(iid, EOK); 328 354 329 while (true) {355 while (true) { 330 356 ipc_call_t answer; 331 357 int answer_count; … … 351 377 } 352 378 353 /** Start sthe module.379 /** Start the module. 354 380 * 355 381 * @param argc The count of the command line arguments. Ignored parameter. … … 362 388 int main(int argc, char *argv[]) 363 389 { 364 int rc;365 366 390 /* Start the module */ 367 rc = netif_module_start(netif_client_connection); 368 return rc; 391 return netif_module_start(netif_client_connection); 369 392 } 370 393 -
uspace/srv/hw/netif/dp8390/dp8390_port.h
r196ef08 rb1d15e7 44 44 #include <sys/types.h> 45 45 46 /** Macro for difining functions.47 * @param[in] function The function type and name definition.48 * @param[in] params The function parameters definition.49 */50 #define _PROTOTYPE(function, params) function params51 52 /** Success error code.53 */54 #define OK EOK55 56 /** Type definition of the unsigned byte.57 */58 typedef uint8_t u8_t;59 60 /** Type definition of the unsigned short.61 */62 typedef uint16_t u16_t;63 64 46 /** Compares two memory blocks. 65 47 * @param[in] first The first memory block. … … 70 52 * @returns 1 if the second is greater than the first. 71 53 */ 72 #define memcmp(first, second, size) 54 #define memcmp(first, second, size) bcmp((char *) (first), (char *) (second), (size)) 73 55 74 56 /** Reads 1 byte. … … 76 58 * @returns The read value. 77 59 */ 78 #define inb(port) 60 #define inb(port) pio_read_8((ioport8_t *) (port)) 79 61 80 62 /** Reads 1 word (2 bytes). … … 82 64 * @returns The read value. 83 65 */ 84 #define inw(port) 66 #define inw(port) pio_read_16((ioport16_t *) (port)) 85 67 86 68 /** Writes 1 byte. … … 88 70 * @param[in] value The value to be written. 89 71 */ 90 #define outb(port, value) 72 #define outb(port, value) pio_write_8((ioport8_t *) (port), (value)) 91 73 92 74 /** Writes 1 word (2 bytes). … … 94 76 * @param[in] value The value to be written. 95 77 */ 96 #define outw(port, value) 78 #define outw(port, value) pio_write_16((ioport16_t *) (port), (value)) 97 79 98 /** Prints out the driver critical error. 99 * Does not call the system panic(). 100 */ 101 #define panic(...) printf("%s%s%d", __VA_ARGS__) 80 /* Bits in 'DL_MODE' field of DL requests. */ 81 #define DL_NOMODE 0x0 82 #define DL_PROMISC_REQ 0x2 83 #define DL_MULTI_REQ 0x4 84 #define DL_BROAD_REQ 0x8 102 85 103 /** Copies a memory block.104 * @param proc The source process. Ignored parameter.105 * @param src_s Ignored parameter.106 * @param[in] src The source address.107 * @param me The current proces. Ignored parameter.108 * @param dst_s Ignored parameter.109 * @param[in] dst The destination address.110 * @param[in] bytes The block size in bytes.111 * @returns EOK.112 */113 #define sys_vircopy(proc, src_s, src, me, dst_s, dst, bytes) ({memcpy((void *)(dst), (void *)(src), (bytes)); EOK;})114 115 /** Reads a memory block byte by byte.116 * @param[in] port The address to be written.117 * @param proc The source process. Ignored parameter.118 * @param[in] dst The destination address.119 * @param[in] bytes The block size in bytes.120 */121 #define do_vir_insb(port, proc, dst, bytes) insb((port), (void *)(dst), (bytes))122 123 /** Reads a memory block word by word (2 bytes).124 * @param[in] port The address to be written.125 * @param proc The source process. Ignored parameter.126 * @param[in] dst The destination address.127 * @param[in] bytes The block size in bytes.128 */129 #define do_vir_insw(port, proc, dst, bytes) insw((port), (void *)(dst), (bytes))130 131 /** Writes a memory block byte by byte.132 * @param[in] port The address to be written.133 * @param proc The source process. Ignored parameter.134 * @param[in] src The source address.135 * @param[in] bytes The block size in bytes.136 */137 #define do_vir_outsb(port, proc, src, bytes) outsb((port), (void *)(src), (bytes))138 139 /** Writes a memory block word by word (2 bytes).140 * @param[in] port The address to be written.141 * @param proc The source process. Ignored parameter.142 * @param[in] src The source address.143 * @param[in] bytes The block size in bytes.144 */145 #define do_vir_outsw(port, proc, src, bytes) outsw((port), (void *)(src), (bytes))146 147 /* com.h */148 /* Bits in 'DL_MODE' field of DL requests. */149 # define DL_NOMODE 0x0150 # define DL_PROMISC_REQ 0x2151 # define DL_MULTI_REQ 0x4152 # define DL_BROAD_REQ 0x8153 154 /* const.h */155 /** True value.156 */157 #define TRUE 1 /* used for turning integers into Booleans */158 159 /** False value.160 */161 #define FALSE 0 /* used for turning integers into Booleans */162 163 /** No number value.164 */165 #define NO_NUM 0x8000 /* used as numerical argument to panic() */166 167 /* devio.h */168 //typedef u16_t port_t;169 86 /** Type definition of a port. 170 87 */ 171 88 typedef long port_t; 172 89 173 /* dl_eth.h */174 90 /** Ethernet statistics. 175 91 */ 176 typedef struct eth_stat 177 { 92 typedef struct eth_stat { 178 93 /** Number of receive errors. 179 94 */ … … 226 141 } eth_stat_t; 227 142 228 /* errno.h */229 /** Generic error.230 */231 #define EGENERIC EINVAL232 233 /* ether.h */234 143 /** Minimum Ethernet packet size in bytes. 235 144 */ 236 #define ETH_MIN_PACK_SIZE 145 #define ETH_MIN_PACK_SIZE 60 237 146 238 147 /** Maximum Ethernet packet size in bytes. 239 148 */ 240 #define ETH_MAX_PACK_SIZE_TAGGED 149 #define ETH_MAX_PACK_SIZE_TAGGED 1518 241 150 242 151 /** Ethernet address type definition. 243 152 */ 244 typedef struct ether_addr 245 { 153 typedef struct ether_addr { 246 154 /** Address data. 247 155 */ 248 u 8_t ea_addr[6];156 uint8_t ea_addr[6]; 249 157 } ether_addr_t; 250 251 /* type.h */252 /** Type definition of the physical addresses and lengths in bytes.253 */254 typedef unsigned long phys_bytes;255 256 /** Type definition of the virtual addresses and lengths in bytes.257 */258 typedef unsigned long vir_bytes;259 260 /** Type definition of the input/output vector.261 */262 typedef struct {263 /** Address of an I/O buffer.264 */265 vir_bytes iov_addr;266 /** Sizeof an I/O buffer.267 */268 vir_bytes iov_size;269 } iovec_t;270 158 271 159 #endif -
uspace/srv/hw/netif/dp8390/ne2000.c
r196ef08 rb1d15e7 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 … … 35 48 #include <stdio.h> 36 49 #include <unistd.h> 37 38 50 #include "dp8390_port.h" 39 40 /*41 ne2000.c42 43 Driver for the ne2000 ethernet cards. This file contains only the ne200044 specific code, the rest is in dp8390.c45 46 Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>47 */48 49 //#include "../drivers.h"50 51 //#include <net/gen/ether.h>52 //#include <net/gen/eth_io.h>53 //#if __minix_vmd54 //#include "config.h"55 //#endif56 57 #include "local.h"58 51 #include "dp8390.h" 59 52 #include "ne2000.h" 60 53 61 #if ENABLE_NE2000 62 63 /** Number of bytes to transfer. 64 */ 65 #define N 100 66 67 //#define MILLIS_TO_TICKS(m) (((m)*HZ/1000)+1) 68 69 /** Sleeps for the defined millicesonds. 70 * @param[in] millis The number of milliseconds to sleep. 71 */ 72 #define milli_delay(millis) usleep((millis) * 1000) 73 74 /** Type definition of the testing function. 75 */ 76 _PROTOTYPE(typedef int (*testf_t), (dpeth_t *dep, int pos, u8_t *pat) ); 77 78 /** First data pattern. 79 */ 80 u8_t pat0[]= {0x00, 0x00, 0x00, 0x00}; 81 82 /** Second data pattern. 83 */ 84 u8_t pat1[]= {0xFF, 0xFF, 0xFF, 0xFF}; 85 86 /** Third data pattern. 87 */ 88 u8_t pat2[]= {0xA5, 0x5A, 0x69, 0x96}; 89 90 /** Fourth data pattern. 91 */ 92 u8_t pat3[]= {0x96, 0x69, 0x5A, 0xA5}; 54 /** Number of bytes to transfer */ 55 #define N 100 56 57 typedef int (*testf_t)(dpeth_t *dep, int pos, uint8_t *pat); 58 59 /** Data patterns */ 60 uint8_t pat0[] = {0x00, 0x00, 0x00, 0x00}; 61 uint8_t pat1[] = {0xFF, 0xFF, 0xFF, 0xFF}; 62 uint8_t pat2[] = {0xA5, 0x5A, 0x69, 0x96}; 63 uint8_t pat3[] = {0x96, 0x69, 0x5A, 0xA5}; 93 64 94 65 /** Tests 8 bit NE2000 network interface. … … 97 68 * @param[in] pat The data pattern to be written. 98 69 * @returns True on success. 99 * @returns FALSEotherwise.100 */ 101 static int test_8(dpeth_t *dep, int pos, u 8_t *pat);70 * @returns false otherwise. 71 */ 72 static int test_8(dpeth_t *dep, int pos, uint8_t *pat); 102 73 103 74 /** Tests 16 bit NE2000 network interface. … … 106 77 * @param[in] pat The data pattern to be written. 107 78 * @returns True on success. 108 * @returns FALSEotherwise.109 */ 110 static int test_16(dpeth_t *dep, int pos, u 8_t *pat);79 * @returns false otherwise. 80 */ 81 static int test_16(dpeth_t *dep, int pos, uint8_t *pat); 111 82 112 83 /** Stops the NE2000 network interface. … … 114 85 */ 115 86 static void ne_stop(dpeth_t *dep); 116 //_PROTOTYPE(static void milli_delay, (unsigned long millis) );117 87 118 88 /** Initializes the NE2000 network interface. … … 121 91 void ne_init(struct dpeth *dep); 122 92 123 /*===========================================================================* 124 * ne_probe * 125 *===========================================================================*/ 126 int ne_probe(dep) 127 dpeth_t *dep; 93 int ne_probe(dpeth_t *dep) 128 94 { 129 95 int byte; … … 131 97 int loc1, loc2; 132 98 testf_t f; 133 134 dep->de_dp8390_port= dep->de_base_port + NE_DP8390; 135 136 /* We probe for an ne1000 or an ne2000 by testing whether the 99 100 dep->de_dp8390_port = dep->de_base_port + NE_DP8390; 101 102 /* 103 * We probe for an ne1000 or an ne2000 by testing whether the 137 104 * on board is reachable through the dp8390. Note that the 138 105 * ne1000 is an 8bit card and has a memory region distict from 139 106 * the 16bit ne2000 140 107 */ 141 142 for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++) 143 { 108 109 for (dep->de_16bit = 0; dep->de_16bit < 2; dep->de_16bit++) { 144 110 /* Reset the ethernet card */ 145 111 byte= inb_ne(dep, NE_RESET); 146 milli_delay(2);112 usleep(2000); 147 113 outb_ne(dep, NE_RESET, byte); 148 milli_delay(2);149 114 usleep(2000); 115 150 116 /* Reset the dp8390 */ 151 117 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 152 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)118 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++) 153 119 ; /* Do nothing */ 154 120 155 121 /* Check if the dp8390 is really there */ 156 if ((inb_reg0(dep, DP_CR) &(CR_STP|CR_DM_ABORT)) != 157 (CR_STP|CR_DM_ABORT)) 158 { 122 if ((inb_reg0(dep, DP_CR) & (CR_STP | CR_DM_ABORT)) != 123 (CR_STP | CR_DM_ABORT)) 159 124 return 0; 160 } 161 125 162 126 /* Disable the receiver and init TCR and DCR. */ 163 127 outb_reg0(dep, DP_RCR, RCR_MON); 164 128 outb_reg0(dep, DP_TCR, TCR_NORMAL); 165 if (dep->de_16bit) 166 { 129 if (dep->de_16bit) { 167 130 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | 168 DCR_BMS); 131 DCR_BMS); 132 } else { 133 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | 134 DCR_BMS); 169 135 } 170 else 171 { 172 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | 173 DCR_BMS); 174 } 175 176 if (dep->de_16bit) 177 { 136 137 if (dep->de_16bit) { 178 138 loc1= NE2000_START; 179 139 loc2= NE2000_START + NE2000_SIZE - 4; 180 140 f= test_16; 181 } 182 else 183 { 141 } else { 184 142 loc1= NE1000_START; 185 143 loc2= NE1000_START + NE1000_SIZE - 4; 186 144 f= test_8; 187 145 } 188 if (f(dep, loc1, pat0) && f(dep, loc1, pat1) && 189 f(dep, loc1, pat2) && f(dep, loc1, pat3) && 190 f(dep, loc2, pat0) && f(dep, loc2, pat1) && 191 f(dep, loc2, pat2) && f(dep, loc2, pat3)) 192 { 193 /* We don't need a memory segment */ 194 dep->de_linmem= 0; 195 if (!dep->de_pci) 196 dep->de_initf= ne_init; 197 dep->de_stopf= ne_stop; 198 dep->de_prog_IO= 1; 146 147 if (f(dep, loc1, pat0) && f(dep, loc1, pat1) && 148 f(dep, loc1, pat2) && f(dep, loc1, pat3) && 149 f(dep, loc2, pat0) && f(dep, loc2, pat1) && 150 f(dep, loc2, pat2) && f(dep, loc2, pat3)) { 151 dep->de_initf = ne_init; 152 dep->de_stopf = ne_stop; 199 153 return 1; 200 154 } 201 155 } 156 202 157 return 0; 203 158 } 204 159 205 /*===========================================================================* 206 * ne_init * 207 *===========================================================================*/ 208 void ne_init(dep) 209 dpeth_t *dep; 160 void ne_init(dpeth_t *dep) 210 161 { 211 162 int i; 212 163 int word, sendq_nr; 213 164 214 165 /* Setup a transfer to get the ethernet address. */ 215 166 if (dep->de_16bit) … … 217 168 else 218 169 outb_reg0(dep, DP_RBCR0, 6); 170 219 171 outb_reg0(dep, DP_RBCR1, 0); 220 172 outb_reg0(dep, DP_RSAR0, 0); 221 173 outb_reg0(dep, DP_RSAR1, 0); 222 174 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 223 224 for (i= 0; i<6; i++) 225 { 226 if (dep->de_16bit) 227 { 228 word= inw_ne(dep, NE_DATA); 229 dep->de_address.ea_addr[i]= word; 230 } 231 else 232 { 175 176 for (i = 0; i < 6; i++) { 177 if (dep->de_16bit) { 178 word = inw_ne(dep, NE_DATA); 179 dep->de_address.ea_addr[i] = word; 180 } else 233 181 dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA); 234 235 }182 } 183 236 184 dep->de_data_port= dep->de_base_port + NE_DATA; 237 if (dep->de_16bit) 238 { 239 dep->de_ramsize= NE2000_SIZE; 240 dep->de_offset_page= NE2000_START / DP_PAGESIZE; 241 } 242 else 243 { 244 dep->de_ramsize= NE1000_SIZE; 245 dep->de_offset_page= NE1000_START / DP_PAGESIZE; 246 } 247 185 if (dep->de_16bit) { 186 dep->de_ramsize = NE2000_SIZE; 187 dep->de_offset_page = NE2000_START / DP_PAGESIZE; 188 } else { 189 dep->de_ramsize = NE1000_SIZE; 190 dep->de_offset_page = NE1000_START / DP_PAGESIZE; 191 } 192 248 193 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */ 249 sendq_nr= dep->de_ramsize / 0x2000; 194 sendq_nr = dep->de_ramsize / 0x2000; 195 250 196 if (sendq_nr < 1) 251 sendq_nr = 1;197 sendq_nr = 1; 252 198 else if (sendq_nr > SENDQ_NR) 253 sendq_nr= SENDQ_NR; 254 dep->de_sendq_nr= sendq_nr; 255 for (i= 0; i<sendq_nr; i++) 256 { 257 dep->de_sendq[i].sq_sendpage= dep->de_offset_page + 258 i*SENDQ_PAGES; 259 } 260 261 dep->de_startpage= dep->de_offset_page + i*SENDQ_PAGES; 262 dep->de_stoppage= dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE; 263 264 /* Can't override the default IRQ. */ 265 dep->de_irq &= ~DEI_DEFAULT; 266 267 if (!debug) 268 { 269 printf("%s: NE%d000 at %#lx:%d\n", 270 dep->de_name, dep->de_16bit ? 2 : 1, 271 dep->de_base_port, dep->de_irq); 272 } 273 else 274 { 275 printf("%s: Novell NE%d000 ethernet card at I/O address " 276 "%#lx, memory size %#lx, irq %d\n", 277 dep->de_name, dep->de_16bit ? 2 : 1, 278 dep->de_base_port, dep->de_ramsize, dep->de_irq); 279 } 280 } 281 282 /*===========================================================================* 283 * test_8 * 284 *===========================================================================*/ 285 static int test_8(dep, pos, pat) 286 dpeth_t *dep; 287 int pos; 288 u8_t *pat; 289 { 290 u8_t buf[4]; 199 sendq_nr = SENDQ_NR; 200 201 dep->de_sendq_nr = sendq_nr; 202 for (i = 0; i < sendq_nr; i++) 203 dep->de_sendq[i].sq_sendpage = dep->de_offset_page + i * SENDQ_PAGES; 204 205 dep->de_startpage = dep->de_offset_page + i * SENDQ_PAGES; 206 dep->de_stoppage = dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE; 207 208 printf("%s: Novell NE%d000 ethernet card at I/O address " 209 "%#lx, memory size %#lx, irq %d\n", 210 dep->de_name, dep->de_16bit ? 2 : 1, 211 dep->de_base_port, dep->de_ramsize, dep->de_irq); 212 } 213 214 static int test_8(dpeth_t *dep, int pos, uint8_t *pat) 215 { 216 uint8_t buf[4]; 291 217 int i; 292 int r; 293 294 outb_reg0(dep, DP_ISR, 0xFF); 295 218 219 outb_reg0(dep, DP_ISR, 0xff); 220 296 221 /* Setup a transfer to put the pattern. */ 297 222 outb_reg0(dep, DP_RBCR0, 4); 298 223 outb_reg0(dep, DP_RBCR1, 0); 299 outb_reg0(dep, DP_RSAR0, pos & 0xFF);224 outb_reg0(dep, DP_RSAR0, pos & 0xff); 300 225 outb_reg0(dep, DP_RSAR1, pos >> 8); 301 226 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 302 303 for (i = 0; i<4; i++)227 228 for (i = 0; i < 4; i++) 304 229 outb_ne(dep, NE_DATA, pat[i]); 305 306 for (i= 0; i<N; i++) 307 { 230 231 for (i = 0; i < N; i++) { 232 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 233 break; 234 } 235 236 if (i == N) { 237 printf("%s: NE1000 remote DMA test failed\n", dep->de_name); 238 return 0; 239 } 240 241 outb_reg0(dep, DP_RBCR0, 4); 242 outb_reg0(dep, DP_RBCR1, 0); 243 outb_reg0(dep, DP_RSAR0, pos & 0xff); 244 outb_reg0(dep, DP_RSAR1, pos >> 8); 245 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 246 247 for (i = 0; i < 4; i++) 248 buf[i] = inb_ne(dep, NE_DATA); 249 250 return (memcmp(buf, pat, 4) == 0); 251 } 252 253 static int test_16(dpeth_t *dep, int pos, uint8_t *pat) 254 { 255 uint8_t buf[4]; 256 int i; 257 258 outb_reg0(dep, DP_ISR, 0xff); 259 260 /* Setup a transfer to put the pattern. */ 261 outb_reg0(dep, DP_RBCR0, 4); 262 outb_reg0(dep, DP_RBCR1, 0); 263 outb_reg0(dep, DP_RSAR0, pos & 0xff); 264 outb_reg0(dep, DP_RSAR1, pos >> 8); 265 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 266 267 for (i = 0; i < 4; i += 2) 268 outw_ne(dep, NE_DATA, *(uint16_t *)(pat + i)); 269 270 for (i = 0; i < N; i++) { 308 271 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 309 272 break; 310 273 } 311 if (i == N) 312 { 313 if (debug) 314 { 315 printf("%s: NE1000 remote DMA test failed\n", 316 dep->de_name); 317 } 274 275 if (i == N) { 276 printf("%s: NE2000 remote DMA test failed\n", dep->de_name); 318 277 return 0; 319 278 } 320 279 321 280 outb_reg0(dep, DP_RBCR0, 4); 322 281 outb_reg0(dep, DP_RBCR1, 0); 323 outb_reg0(dep, DP_RSAR0, pos & 0xFF);282 outb_reg0(dep, DP_RSAR0, pos & 0xff); 324 283 outb_reg0(dep, DP_RSAR1, pos >> 8); 325 284 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 326 327 for (i= 0; i<4; i++) 328 buf[i]= inb_ne(dep, NE_DATA); 329 330 r= (memcmp(buf, pat, 4) == 0); 331 return r; 332 } 333 334 /*===========================================================================* 335 * test_16 * 336 *===========================================================================*/ 337 static int test_16(dep, pos, pat) 338 dpeth_t *dep; 339 int pos; 340 u8_t *pat; 341 { 342 u8_t buf[4]; 343 int i; 344 int r; 345 346 outb_reg0(dep, DP_ISR, 0xFF); 347 348 /* Setup a transfer to put the pattern. */ 349 outb_reg0(dep, DP_RBCR0, 4); 350 outb_reg0(dep, DP_RBCR1, 0); 351 outb_reg0(dep, DP_RSAR0, pos &0xFF); 352 outb_reg0(dep, DP_RSAR1, pos >> 8); 353 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 354 355 for (i= 0; i<4; i += 2) 356 { 357 outw_ne(dep, NE_DATA, *(u16_t *)(pat+i)); 358 } 359 360 for (i= 0; i<N; i++) 361 { 362 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 363 break; 364 } 365 if (i == N) 366 { 367 if (debug) 368 { 369 printf("%s: NE2000 remote DMA test failed\n", 370 dep->de_name); 371 } 372 return 0; 373 } 374 375 outb_reg0(dep, DP_RBCR0, 4); 376 outb_reg0(dep, DP_RBCR1, 0); 377 outb_reg0(dep, DP_RSAR0, pos &0xFF); 378 outb_reg0(dep, DP_RSAR1, pos >> 8); 379 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 380 381 for (i= 0; i<4; i += 2) 382 { 383 *(u16_t *)(buf+i)= inw_ne(dep, NE_DATA); 384 } 385 386 r= (memcmp(buf, pat, 4) == 0); 387 return r; 388 } 389 390 /*===========================================================================* 391 * ne_stop * 392 *===========================================================================*/ 393 static void ne_stop(dep) 394 dpeth_t *dep; 395 { 396 int byte; 397 285 286 for (i = 0; i < 4; i += 2) 287 *(uint16_t *)(buf + i) = inw_ne(dep, NE_DATA); 288 289 return (memcmp(buf, pat, 4) == 0); 290 } 291 292 static void ne_stop(dpeth_t *dep) 293 { 398 294 /* Reset the ethernet card */ 399 byte= inb_ne(dep, NE_RESET);400 milli_delay(2);295 int byte = inb_ne(dep, NE_RESET); 296 usleep(2000); 401 297 outb_ne(dep, NE_RESET, byte); 402 298 } 403 /*404 static void milli_delay(unsigned long millis)405 {406 tickdelay(MILLIS_TO_TICKS(millis));407 }408 */409 #endif /* ENABLE_NE2000 */410 411 /*412 * $PchId: ne2000.c,v 1.10 2004/08/03 12:03:00 philip Exp $413 */414 299 415 300 /** @} -
uspace/srv/hw/netif/dp8390/ne2000.h
r196ef08 rb1d15e7 1 1 /* 2 * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 2 * Copyright (c) 2009 Lukas Mejdrech 3 * Copyright (c) 2011 Martin Decky 4 * All rights reserved. 3 5 * 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 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 8 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. 9 17 * 10 * Disclaimer 11 * 12 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 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 Mejdrech25 28 */ 26 29 27 30 /* 28 ne2000.h 29 30 Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com> 31 */ 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 * 38 */ 32 39 33 40 /** @addtogroup ne2k … … 43 50 44 51 #include <libarch/ddi.h> 45 46 52 #include "dp8390_port.h" 47 53 48 54 /** DP8390 register offset. 49 55 */ 50 #define NE_DP8390 56 #define NE_DP8390 0x00 51 57 52 58 /** Data register. 53 59 */ 54 #define NE_DATA 60 #define NE_DATA 0x10 55 61 56 62 /** Reset register. 57 63 */ 58 #define NE_RESET 0x1F64 #define NE_RESET 0x1f 59 65 60 66 /** NE1000 data start. 61 67 */ 62 #define NE1000_START 68 #define NE1000_START 0x2000 63 69 64 70 /** NE1000 data size. 65 71 */ 66 #define NE1000_SIZE 72 #define NE1000_SIZE 0x2000 67 73 68 74 /** NE2000 data start. 69 75 */ 70 #define NE2000_START 76 #define NE2000_START 0x4000 71 77 72 78 /** NE2000 data size. 73 79 */ 74 #define NE2000_SIZE 80 #define NE2000_SIZE 0x4000 75 81 76 82 /** Reads 1 byte register. … … 79 85 * @returns The read value. 80 86 */ 81 #define inb_ne(dep, reg) (inb(dep->de_base_port+reg))87 #define inb_ne(dep, reg) (inb(dep->de_base_port + reg)) 82 88 83 89 /** Writes 1 byte register. … … 86 92 * @param[in] data The value to be written. 87 93 */ 88 #define outb_ne(dep, reg, data) (outb(dep->de_base_port+reg, data))94 #define outb_ne(dep, reg, data) (outb(dep->de_base_port + reg, data)) 89 95 90 96 /** Reads 1 word (2 bytes) register. … … 93 99 * @returns The read value. 94 100 */ 95 #define inw_ne(dep, reg) (inw(dep->de_base_port+reg))101 #define inw_ne(dep, reg) (inw(dep->de_base_port + reg)) 96 102 97 103 /** Writes 1 word (2 bytes) register. … … 100 106 * @param[in] data The value to be written. 101 107 */ 102 #define outw_ne(dep, reg, data) (outw(dep->de_base_port+reg, data))108 #define outw_ne(dep, reg, data) (outw(dep->de_base_port + reg, data)) 103 109 104 #endif /* __NET_NETIF_NE2000_H__ */ 110 struct dpeth; 105 111 106 /* 107 * $PchId: ne2000.h,v 1.4 2004/08/03 12:03:20 philip Exp $ 108 */ 112 int ne_probe(struct dpeth *dep); 113 114 #endif 109 115 110 116 /** @} -
uspace/srv/net/tl/icmp/icmp.c
r196ef08 rb1d15e7 529 529 icmp_code_t code; 530 530 int rc; 531 531 532 532 switch (error) { 533 533 case SERVICE_NONE:
Note:
See TracChangeset
for help on using the changeset viewer.