Changes in / [f03d3786:ae1f70e] in mainline
- Files:
-
- 2 added
- 4 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ddi/irq.h
rf03d3786 rae1f70e 54 54 /** Read 4 bytes from the I/O space. */ 55 55 CMD_PIO_READ_32, 56 56 57 /** Write 1 byte to the I/O space. */ 57 58 CMD_PIO_WRITE_8, … … 62 63 63 64 /** 64 * Perform a bit test on the source argument and store the result into 65 * the destination argument. 65 * Write 1 byte from the source argument 66 * to the I/O space. 67 */ 68 CMD_PIO_WRITE_A_8, 69 /** 70 * Write 2 bytes from the source argument 71 * to the I/O space. 72 */ 73 CMD_PIO_WRITE_A_16, 74 /** 75 * Write 4 bytes from the source argument 76 * to the I/O space. 77 */ 78 CMD_PIO_WRITE_A_32, 79 80 /** 81 * Perform a bit masking on the source argument 82 * and store the result into the destination argument. 66 83 */ 67 84 CMD_BTEST, 68 85 69 86 /** 70 * Predicate the execution of the following N commands by the boolean 71 * value of the source argument. 87 * Predicate the execution of the following 88 * N commands by the boolean value of the source 89 * argument. 72 90 */ 73 91 CMD_PREDICATE, … … 75 93 /** Accept the interrupt. */ 76 94 CMD_ACCEPT, 95 77 96 /** Decline the interrupt. */ 78 97 CMD_DECLINE, -
kernel/generic/src/ipc/irq.c
rf03d3786 rae1f70e 404 404 (uint32_t) code->cmds[i].value); 405 405 break; 406 case CMD_PIO_WRITE_A_8: 407 if (srcarg) { 408 pio_write_8((ioport8_t *) code->cmds[i].addr, 409 (uint8_t) scratch[srcarg]); 410 } 411 break; 412 case CMD_PIO_WRITE_A_16: 413 if (srcarg) { 414 pio_write_16((ioport16_t *) code->cmds[i].addr, 415 (uint16_t) scratch[srcarg]); 416 } 417 break; 418 case CMD_PIO_WRITE_A_32: 419 if (srcarg) { 420 pio_write_32((ioport32_t *) code->cmds[i].addr, 421 (uint32_t) scratch[srcarg]); 422 } 423 break; 406 424 case CMD_BTEST: 407 425 if ((srcarg) && (dstarg)) { -
uspace/Makefile
rf03d3786 rae1f70e 83 83 srv/hw/char/s3c24xx_uart \ 84 84 srv/hw/netif/dp8390 \ 85 srv/net/cfg \86 85 srv/net/netif/lo \ 87 86 srv/net/il/arp \ -
uspace/srv/hw/netif/dp8390/dp8390.c
rf03d3786 rae1f70e 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". 105 */ 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 78 /* 79 * Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA 120 80 * 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){ 81 * genuine dp8390s. 82 */ 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 int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length); 90 static void conf_hw(dpeth_t *dep); 91 static void insb(port_t port, void *buf, size_t size); 92 static void insw(port_t port, void *buf, size_t size); 93 94 int do_probe(dpeth_t *dep) 95 { 215 96 /* This is the default, try to (re)locate the device. */ 216 97 conf_hw(dep); 217 if (dep->de_mode == DEM_DISABLED) 218 { 98 if (!dep->up) 219 99 /* Probe failed, or the device is configured off. */ 220 return EXDEV; //ENXIO;221 }222 if (dep-> de_mode == DEM_ENABLED)100 return EXDEV; 101 102 if (dep->up) 223 103 dp_init(dep); 104 224 105 return EOK; 225 106 } 226 107 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){ 283 if (dep->de_mode == DEM_DISABLED) 284 { 285 // might call do_probe() 108 /** Initialize and/or start the network interface. 109 * 110 * @param[in,out] dep The network interface structure. 111 * 112 * @return EOK on success. 113 * @return EXDEV if the network interface is disabled. 114 * 115 */ 116 int do_init(dpeth_t *dep) 117 { 118 if (!dep->up) 119 /* FIXME: Perhaps call do_probe()? */ 286 120 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 } 302 assert(dep->de_mode == DEM_ENABLED); 303 assert(dep->de_flags &DEF_ENABLED); 304 305 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD); 306 307 if (mode &DL_PROMISC_REQ) 308 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; 309 if (mode &DL_MULTI_REQ) 310 dep->de_flags |= DEF_MULTI; 311 if (mode &DL_BROAD_REQ) 312 dep->de_flags |= DEF_BROAD; 313 314 // dep->de_client = mp->m_source; 121 122 assert(dep->up); 123 assert(dep->enabled); 124 315 125 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 126 return EOK; 324 127 } 325 128 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)){ 129 void do_stop(dpeth_t *dep) 130 { 131 if ((dep->up) && (dep->enabled)) { 331 132 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 332 (dep->de_stopf)(dep); 333 334 dep->de_flags = DEF_EMPTY; 335 } 336 } 337 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; 133 ne_stop(dep); 134 135 dep->enabled = false; 136 dep->stopped = false; 137 dep->sending = false; 138 dep->send_avail = false; 139 } 140 } 141 142 static void dp_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 143 { 144 size_t ecount = size & ~1; 145 146 outb_reg0(dep, DP_ISR, ISR_RDC); 147 148 if (dep->de_16bit) { 149 outb_reg0(dep, DP_RBCR0, ecount & 0xff); 150 outb_reg0(dep, DP_RBCR1, ecount >> 8); 151 } else { 152 outb_reg0(dep, DP_RBCR0, size & 0xff); 153 outb_reg0(dep, DP_RBCR1, size >> 8); 154 } 155 156 outb_reg0(dep, DP_RSAR0, nic_addr & 0xff); 157 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 158 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 159 160 if (dep->de_16bit) { 161 void *ptr = buf + offset; 162 163 if (ecount != 0) { 164 outsw(dep->de_data_port, ptr, ecount); 165 size -= ecount; 166 offset += ecount; 167 ptr += ecount; 168 } 169 170 if (size) { 171 assert(size == 1); 172 173 uint16_t two_bytes; 174 175 memcpy(&(((uint8_t *) &two_bytes)[0]), ptr, 1); 176 outw(dep->de_data_port, two_bytes); 177 } 178 } else 179 outsb(dep->de_data_port, buf + offset, size); 180 181 unsigned int i; 182 for (i = 0; i < 100; i++) { 183 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 184 break; 185 } 186 187 if (i == 100) 188 fprintf(stderr, "Remote DMA failed to complete\n"); 189 } 190 191 int do_pwrite(dpeth_t *dep, packet_t *packet, int from_int) 192 { 366 193 int size; 367 194 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 } 385 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 */ 195 196 assert(dep->up); 197 assert(dep->enabled); 198 199 if (dep->send_avail) { 200 fprintf(stderr, "Send already in progress\n"); 201 return EBUSY; 202 } 203 204 sendq_head = dep->de_sendq_head; 205 if (dep->de_sendq[sendq_head].sq_filled) { 206 if (from_int) 207 fprintf(stderr, "dp8390: should not be sending\n"); 208 dep->send_avail = true; 209 dep->sending = false; 210 211 return EBUSY; 212 } 213 214 assert(!dep->sending); 215 216 void *buf = packet_get_data(packet); 430 217 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); 218 219 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) { 220 fprintf(stderr, "dp8390: invalid packet size\n"); 439 221 return EINVAL; 440 222 } 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 {223 224 dp_user2nic(dep, buf, 0, dep->de_sendq[sendq_head].sq_sendpage 225 * DP_PAGESIZE, size); 226 dep->de_sendq[sendq_head].sq_filled = true; 227 228 if (dep->de_sendq_tail == sendq_head) { 447 229 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage); 448 230 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; 231 outb_reg0(dep, DP_TBCR0, size & 0xff); 232 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA); /* there it goes .. */ 233 } else 234 dep->de_sendq[sendq_head].sq_size = size; 454 235 455 236 if (++sendq_head == dep->de_sendq_nr) 456 sendq_head= 0; 237 sendq_head = 0; 238 457 239 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 */ 240 dep->de_sendq_head = sendq_head; 241 dep->sending = true; 242 465 243 if (from_int) 466 244 return EOK; 467 reply(dep, OK, FALSE); 468 469 assert(dep->de_mode == DEM_ENABLED); 470 assert(dep->de_flags &DEF_ENABLED); 245 246 dep->sending = false; 247 471 248 return EOK; 472 249 } 473 250 474 /*===========================================================================* 475 * dp_init * 476 *===========================================================================*/ 477 void dp_init(dep) 478 dpeth_t *dep; 251 void dp_init(dpeth_t *dep) 479 252 { 480 253 int dp_rcr_reg; 481 int i; //, r;482 254 int i; 255 483 256 /* General initialization */ 484 dep->de_flags = DEF_EMPTY; 485 (*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 257 dep->enabled = false; 258 dep->stopped = false; 259 dep->sending = false; 260 dep->send_avail = false; 261 ne_init(dep); 262 263 printf("Ethernet address "); 264 for (i = 0; i < 6; i++) 265 printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n'); 266 267 /* 268 * Initialization of the dp8390 following the mandatory procedure 501 269 * in reference manual ("DP8390D/NS32490D NIC Network Interface 502 270 * Controller", National Semiconductor, July 1995, Page 29). 503 271 */ 272 504 273 /* Step 1: */ 505 274 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT); 275 506 276 /* Step 2: */ 507 277 if (dep->de_16bit) … … 509 279 else 510 280 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS); 281 511 282 /* Step 3: */ 512 283 outb_reg0(dep, DP_RBCR0, 0); 513 284 outb_reg0(dep, DP_RBCR1, 0); 285 514 286 /* Step 4: */ 515 dp_rcr_reg = 0; 516 if (dep->de_flags &DEF_PROMISC) 517 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 518 if (dep->de_flags &DEF_BROAD) 519 dp_rcr_reg |= RCR_AB; 520 if (dep->de_flags &DEF_MULTI) 521 dp_rcr_reg |= RCR_AM; 287 dp_rcr_reg = RCR_AB; /* Enable broadcasts */ 288 522 289 outb_reg0(dep, DP_RCR, dp_rcr_reg); 290 523 291 /* Step 5: */ 524 292 outb_reg0(dep, DP_TCR, TCR_INTERNAL); 293 525 294 /* Step 6: */ 526 295 outb_reg0(dep, DP_BNRY, dep->de_startpage); 527 296 outb_reg0(dep, DP_PSTART, dep->de_startpage); 528 297 outb_reg0(dep, DP_PSTOP, dep->de_stoppage); 298 529 299 /* Step 7: */ 530 300 outb_reg0(dep, DP_ISR, 0xFF); 301 531 302 /* Step 8: */ 532 303 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | 533 IMR_OVWE | IMR_CNTE); 304 IMR_OVWE | IMR_CNTE); 305 534 306 /* Step 9: */ 535 307 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP); 536 308 537 309 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]); 538 310 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]); … … 541 313 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]); 542 314 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]); 543 315 544 316 outb_reg1(dep, DP_MAR0, 0xff); 545 317 outb_reg1(dep, DP_MAR1, 0xff); … … 550 322 outb_reg1(dep, DP_MAR6, 0xff); 551 323 outb_reg1(dep, DP_MAR7, 0xff); 552 324 553 325 outb_reg1(dep, DP_CURR, dep->de_startpage + 1); 326 554 327 /* Step 10: */ 555 328 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA); 329 556 330 /* Step 11: */ 557 331 outb_reg0(dep, DP_TCR, TCR_NORMAL); 558 559 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */332 333 inb_reg0(dep, DP_CNTR0); /* Reset counters by reading */ 560 334 inb_reg0(dep, DP_CNTR1); 561 335 inb_reg0(dep, DP_CNTR2); 562 336 563 337 /* Finish the initialization. */ 564 dep-> de_flags |= DEF_ENABLED;565 for (i = 0; i<dep->de_sendq_nr; i++)338 dep->enabled = true; 339 for (i = 0; i < dep->de_sendq_nr; i++) 566 340 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 { 579 dep->de_user2nicf= dp_pio16_user2nic; 580 // dep->de_user2nicf_s= dp_pio16_user2nic_s; 581 dep->de_nic2userf= dp_pio16_nic2user; 582 // dep->de_nic2userf_s= dp_pio16_nic2user_s; 583 dep->de_getblockf= dp_pio16_getblock; 584 } 585 else 586 { 587 dep->de_user2nicf= dp_pio8_user2nic; 588 // dep->de_user2nicf_s= dp_pio8_user2nic_s; 589 dep->de_nic2userf= dp_pio8_nic2user; 590 // dep->de_nic2userf_s= dp_pio8_nic2user_s; 591 dep->de_getblockf= dp_pio8_getblock; 592 } 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; 341 342 dep->de_sendq_head = 0; 343 dep->de_sendq_tail = 0; 344 } 345 346 static void dp_reinit(dpeth_t *dep) 615 347 { 616 348 int dp_rcr_reg; 617 349 618 350 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA); 619 620 dp_rcr_reg = 0; 621 if (dep->de_flags &DEF_PROMISC) 622 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM; 623 if (dep->de_flags &DEF_BROAD) 624 dp_rcr_reg |= RCR_AB; 625 if (dep->de_flags &DEF_MULTI) 626 dp_rcr_reg |= RCR_AM; 351 352 /* Enable broadcasts */ 353 dp_rcr_reg = RCR_AB; 354 627 355 outb_reg0(dep, DP_RCR, dp_rcr_reg); 628 356 } 629 357 630 /*===========================================================================* 631 * dp_reset * 632 *===========================================================================*/ 633 static void dp_reset(dep) 634 dpeth_t *dep; 358 static void dp_reset(dpeth_t *dep) 635 359 { 636 360 int i; 637 361 638 362 /* Stop chip */ 639 363 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT); 640 364 outb_reg0(dep, DP_RBCR0, 0); 641 365 outb_reg0(dep, DP_RBCR1, 0); 642 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++) 366 367 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++) 643 368 ; /* Do nothing */ 644 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST); 645 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT); 369 370 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST); 371 outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT); 646 372 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++)373 374 /* Acknowledge the ISR_RDC (remote DMA) interrupt. */ 375 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++) 650 376 ; /* 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 377 378 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC); 379 380 /* 381 * Reset the transmit ring. If we were transmitting a packet, we 654 382 * pretend that the packet is processed. Higher layers will 655 383 * retransmit if the packet wasn't actually sent. 656 384 */ 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); 661 dep->de_flags &= ~DEF_STOPPED; 662 } 663 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; 385 dep->de_sendq_head = 0; 386 dep->de_sendq_tail = 0; 387 388 for (i = 0; i < dep->de_sendq_nr; i++) 389 dep->de_sendq[i].sq_filled = 0; 390 391 dep->send_avail = false; 392 dep->stopped = false; 393 } 394 395 static uint8_t isr_acknowledge(dpeth_t *dep) 396 { 397 uint8_t isr = inb_reg0(dep, DP_ISR); 398 if (isr != 0) 399 outb_reg0(dep, DP_ISR, isr); 400 401 return isr; 402 } 403 404 void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, uint8_t isr) 405 { 406 int tsr; 672 407 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; 682 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 408 409 for (; (isr & 0x7f) != 0; isr = isr_acknowledge(dep)) { 410 if (isr & (ISR_PTX | ISR_TXE)) { 411 if (isr & ISR_TXE) 690 412 dep->de_stat.ets_sendErr++; 413 else { 414 tsr = inb_reg0(dep, DP_TSR); 415 416 if (tsr & TSR_PTX) 417 dep->de_stat.ets_packetT++; 418 419 if (tsr & TSR_COL) 420 dep->de_stat.ets_collision++; 421 422 if (tsr & TSR_ABT) 423 dep->de_stat.ets_transAb++; 424 425 if (tsr & TSR_CRS) 426 dep->de_stat.ets_carrSense++; 427 428 if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10)) 429 printf("FIFO underrun\n"); 430 431 if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10)) 432 printf("CD heart beat failure\n"); 433 434 if (tsr & TSR_OWC) 435 dep->de_stat.ets_OWC++; 691 436 } 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 731 /* Or hardware bug? */ 732 printf( 733 "%s: transmit interrupt, but not sending\n", 734 dep->de_name); 437 438 sendq_tail = dep->de_sendq_tail; 439 440 if (!(dep->de_sendq[sendq_tail].sq_filled)) { 441 printf("PTX interrupt, but no frame to send\n"); 735 442 continue; 736 443 } 737 dep->de_sendq[sendq_tail].sq_filled= 0; 444 445 dep->de_sendq[sendq_tail].sq_filled = false; 446 738 447 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; 448 sendq_tail = 0; 449 450 dep->de_sendq_tail = sendq_tail; 451 452 if (dep->de_sendq[sendq_tail].sq_filled) { 453 size = dep->de_sendq[sendq_tail].sq_size; 744 454 outb_reg0(dep, DP_TPSR, 745 455 dep->de_sendq[sendq_tail].sq_sendpage); 746 456 outb_reg0(dep, DP_TBCR1, size >> 8); 747 outb_reg0(dep, DP_TBCR0, size & 0xff);457 outb_reg0(dep, DP_TBCR0, size & 0xff); 748 458 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA); 749 459 } 750 // if (dep->de_flags &DEF_SEND_AVAIL) 751 dp_send(dep); 752 } 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 { 460 461 dep->send_avail = false; 462 } 463 464 if (isr & ISR_PRX) 465 dp_recv(nil_phone, device_id, dep); 466 467 if (isr & ISR_RXE) 468 dep->de_stat.ets_recvErr++; 469 470 if (isr & ISR_CNT) { 764 471 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0); 765 472 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1); 766 473 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2); 767 474 } 768 if (isr &ISR_OVW)769 {475 476 if (isr & ISR_OVW) 770 477 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 { 478 479 if (isr & ISR_RDC) { 784 480 /* Nothing to do */ 785 481 } 786 if (isr &ISR_RST) 787 { 788 /* this means we got an interrupt but the ethernet 789 * chip is shutdown. We set the flag DEF_STOPPED, 482 483 if (isr & ISR_RST) { 484 /* 485 * This means we got an interrupt but the ethernet 486 * chip is shutdown. We set the flag 'stopped' 790 487 * and continue processing arrived packets. When the 791 488 * receive buffer is empty, we reset the dp8390. 792 489 */ 793 #if 0 794 {printW(); printf( 795 "%s: NIC stopped\n", dep->de_name);} 796 #endif 797 dep->de_flags |= DEF_STOPPED; 490 dep->stopped = true; 798 491 break; 799 492 } 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. 493 } 494 495 if (dep->stopped) { 496 /* 497 * The chip is stopped, and all arrived 498 * frames are delivered. 808 499 */ 809 500 dp_reset(dep); 810 501 } 811 } 812 813 /*===========================================================================* 814 * dp_recv * 815 *===========================================================================*/ 816 static void dp_recv(dep) 817 dpeth_t *dep; 502 503 dep->sending = false; 504 } 505 506 static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst) 507 { 508 offset = page * DP_PAGESIZE + offset; 509 510 outb_reg0(dep, DP_RBCR0, size & 0xff); 511 outb_reg0(dep, DP_RBCR1, size >> 8); 512 outb_reg0(dep, DP_RSAR0, offset & 0xff); 513 outb_reg0(dep, DP_RSAR1, offset >> 8); 514 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 515 516 if (dep->de_16bit) { 517 assert((size % 2) == 0); 518 insw(dep->de_data_port, dst, size); 519 } else 520 insb(dep->de_data_port, dst, size); 521 } 522 523 static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep) 818 524 { 819 525 dp_rcvhdr_t header; 820 //unsigned pageno, curr, next;821 526 int pageno, curr, next; 822 vir_byteslength;527 size_t length; 823 528 int packet_processed, r; 824 u 16_t eth_type;825 826 packet_processed = FALSE;529 uint16_t eth_type; 530 531 packet_processed = false; 827 532 pageno = inb_reg0(dep, DP_BNRY) + 1; 828 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;829 830 do831 {533 if (pageno == dep->de_stoppage) 534 pageno = dep->de_startpage; 535 536 do { 832 537 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA); 833 538 curr = inb_reg1(dep, DP_CURR); 834 539 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); 540 541 if (curr == pageno) 542 break; 543 544 dp_getblock(dep, pageno, (size_t) 0, sizeof(header), &header); 545 dp_getblock(dep, pageno, sizeof(header) + 546 2 * sizeof(ether_addr_t), sizeof(eth_type), ð_type); 547 548 length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t); 845 549 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); 550 if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) { 551 printf("Packet with strange length arrived: %zu\n", length); 851 552 next= curr; 852 } 853 else if (next < dep->de_startpage || next >= dep->de_stoppage) 854 { 855 printf("%s: strange next page\n", dep->de_name); 553 } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) { 554 printf("Strange next page\n"); 856 555 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.) 556 } else if (header.dr_status & RSR_FO) { 557 /* 558 * This is very serious, so we issue a warning and 559 * reset the buffers 863 560 */ 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 } 872 dep->de_stat.ets_packetR++; 873 } 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); 561 printf("FIFO overrun, resetting receive buffer\n"); 880 562 dep->de_stat.ets_fifoOver++; 881 563 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) 564 } else if ((header.dr_status & RSR_PRX) && (dep->enabled)) { 565 r = dp_pkt2user(nil_phone, device_id, dep, pageno, length); 566 if (r != EOK) 891 567 return; 892 893 packet_processed = TRUE;568 569 packet_processed = true; 894 570 dep->de_stat.ets_packetR++; 895 571 } 572 896 573 if (next == dep->de_startpage) 897 574 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1); 898 575 else 899 576 outb_reg0(dep, DP_BNRY, next - 1); 900 577 901 578 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; 965 { 966 offset = page * DP_PAGESIZE + offset; 967 outb_reg0(dep, DP_RBCR0, size &0xFF); 968 outb_reg0(dep, DP_RBCR1, size >> 8); 969 outb_reg0(dep, DP_RSAR0, offset &0xFF); 970 outb_reg0(dep, DP_RSAR1, offset >> 8); 579 } while (!packet_processed); 580 } 581 582 static void dp_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 583 { 584 size_t ecount = size & ~1; 585 586 if (dep->de_16bit) { 587 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); 588 outb_reg0(dep, DP_RBCR1, ecount >> 8); 589 } else { 590 outb_reg0(dep, DP_RBCR0, size & 0xff); 591 outb_reg0(dep, DP_RBCR1, size >> 8); 592 } 593 594 outb_reg0(dep, DP_RSAR0, nic_addr & 0xff); 595 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 971 596 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 972 973 insb(dep->de_data_port, dst, size); 974 } 975 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; 985 { 986 offset = page * DP_PAGESIZE + offset; 987 outb_reg0(dep, DP_RBCR0, size &0xFF); 988 outb_reg0(dep, DP_RBCR1, size >> 8); 989 outb_reg0(dep, DP_RSAR0, offset &0xFF); 990 outb_reg0(dep, DP_RSAR1, offset >> 8); 991 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 992 993 assert (!(size &1)); 994 insw(dep->de_data_port, dst, size); 995 } 996 997 /*===========================================================================* 998 * dp_pkt2user * 999 *===========================================================================*/ 1000 static int dp_pkt2user(dep, page, length) 1001 dpeth_t *dep; 1002 int page, length; 597 598 if (dep->de_16bit) { 599 void *ptr = buf + offset; 600 601 if (ecount != 0) { 602 insw(dep->de_data_port, ptr, ecount); 603 size -= ecount; 604 offset += ecount; 605 ptr += ecount; 606 } 607 608 if (size) { 609 assert(size == 1); 610 611 uint16_t two_bytes = inw(dep->de_data_port); 612 memcpy(ptr, &(((uint8_t *) &two_bytes)[0]), 1); 613 } 614 } else 615 insb(dep->de_data_port, buf + offset, size); 616 } 617 618 static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length) 1003 619 { 1004 620 int last, count; 1005 621 packet_t *packet; 1006 1007 // if (!(dep->de_flags &DEF_READING)) 1008 // return EGENERIC; 1009 622 1010 623 packet = netif_packet_get_1(length); 1011 if (! packet){624 if (!packet) 1012 625 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 626 627 void *buf = packet_suffix(packet, length); 628 1019 629 last = page + (length - 1) / DP_PAGESIZE; 1020 if (last >= dep->de_stoppage) 1021 { 1022 count = (dep->de_stoppage - page) * DP_PAGESIZE - 1023 sizeof(dp_rcvhdr_t); 1024 1025 /* Save read_iovec since we need it twice. */ 1026 dep->de_tmp_iovec = dep->de_read_iovec; 1027 (dep->de_nic2userf)(dep, page * DP_PAGESIZE + 1028 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count); 1029 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE, 1030 &dep->de_read_iovec, count, length - count); 1031 } 1032 else 1033 { 1034 (dep->de_nic2userf)(dep, page * DP_PAGESIZE + 1035 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length); 1036 } 1037 1038 dep->de_read_s = length; 1039 dep->de_flags |= DEF_PACK_RECV; 1040 // dep->de_flags &= ~DEF_READING; 1041 1042 if(dep->received_count >= MAX_PACKETS){ 1043 netif_pq_release(packet_get_id(packet)); 1044 return ELIMIT; 1045 }else{ 1046 if(pq_add(&dep->received_queue, packet, 0, 0) == EOK){ 1047 ++ dep->received_count; 1048 }else{ 1049 netif_pq_release(packet_get_id(packet)); 1050 } 1051 } 1052 return OK; 1053 } 1054 1055 /*===========================================================================* 1056 * dp_user2nic * 1057 *===========================================================================*/ 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 1119 outb_reg0(dep, DP_ISR, ISR_RDC); 1120 1121 outb_reg0(dep, DP_RBCR0, count &0xFF); 1122 outb_reg0(dep, DP_RBCR1, count >> 8); 1123 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF); 1124 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1125 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 1126 1127 i= 0; 1128 while (count > 0) 1129 { 1130 if (i >= IOVEC_NR) 1131 { 1132 dp_next_iovec(iovp); 1133 i= 0; 1134 continue; 1135 } 1136 assert(i < iovp->iod_iovec_s); 1137 if (offset >= iovp->iod_iovec[i].iov_size) 1138 { 1139 offset -= iovp->iod_iovec[i].iov_size; 1140 i++; 1141 continue; 1142 } 1143 bytes = iovp->iod_iovec[i].iov_size - offset; 1144 if (bytes > count) 1145 bytes = count; 1146 1147 do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr, 1148 iovp->iod_iovec[i].iov_addr + offset, bytes); 1149 count -= bytes; 1150 offset += bytes; 1151 } 1152 assert(count == 0); 1153 1154 for (i= 0; i<100; i++) 1155 { 1156 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 1157 break; 1158 } 1159 if (i == 100) 1160 { 1161 panic("", "dp8390: remote dma failed to complete", NO_NUM); 1162 } 1163 } 1164 1165 /*===========================================================================* 1166 * dp_pio16_user2nic * 1167 *===========================================================================*/ 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 1186 outb_reg0(dep, DP_ISR, ISR_RDC); 1187 outb_reg0(dep, DP_RBCR0, ecount &0xFF); 1188 outb_reg0(dep, DP_RBCR1, ecount >> 8); 1189 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF); 1190 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1191 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 1192 1193 i= 0; 1194 while (count > 0) 1195 { 1196 if (i >= IOVEC_NR) 1197 { 1198 dp_next_iovec(iovp); 1199 i= 0; 1200 continue; 1201 } 1202 assert(i < iovp->iod_iovec_s); 1203 if (offset >= iovp->iod_iovec[i].iov_size) 1204 { 1205 offset -= iovp->iod_iovec[i].iov_size; 1206 i++; 1207 continue; 1208 } 1209 bytes = iovp->iod_iovec[i].iov_size - offset; 1210 if (bytes > count) 1211 bytes = count; 1212 1213 user_proc= iovp->iod_proc_nr; 1214 vir_user= iovp->iod_iovec[i].iov_addr + offset; 1215 if (odd_byte) 1216 { 1217 r= sys_vircopy(user_proc, D, vir_user, 1218 // SELF, D, (vir_bytes)&two_bytes[1], 1); 1219 SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]), 1); 1220 if (r != OK) 1221 { 1222 panic("DP8390", 1223 "dp_pio16_user2nic: sys_vircopy failed", 1224 r); 1225 } 1226 //outw(dep->de_data_port, *(u16_t *)two_bytes); 1227 outw(dep->de_data_port, two_bytes); 1228 count--; 1229 offset++; 1230 bytes--; 1231 vir_user++; 1232 odd_byte= 0; 1233 if (!bytes) 1234 continue; 1235 } 1236 ecount= bytes &~1; 1237 if (ecount != 0) 1238 { 1239 do_vir_outsw(dep->de_data_port, user_proc, vir_user, 1240 ecount); 1241 count -= ecount; 1242 offset += ecount; 1243 bytes -= ecount; 1244 vir_user += ecount; 1245 } 1246 if (bytes) 1247 { 1248 assert(bytes == 1); 1249 r= sys_vircopy(user_proc, D, vir_user, 1250 // SELF, D, (vir_bytes)&two_bytes[0], 1); 1251 SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]), 1); 1252 if (r != OK) 1253 { 1254 panic("DP8390", 1255 "dp_pio16_user2nic: sys_vircopy failed", 1256 r); 1257 } 1258 count--; 1259 offset++; 1260 bytes--; 1261 vir_user++; 1262 odd_byte= 1; 1263 } 1264 } 1265 assert(count == 0); 1266 1267 if (odd_byte) 1268 //outw(dep->de_data_port, *(u16_t *)two_bytes); 1269 outw(dep->de_data_port, two_bytes); 1270 1271 for (i= 0; i<100; i++) 1272 { 1273 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 1274 break; 1275 } 1276 if (i == 100) 1277 { 1278 panic("", "dp8390: remote dma failed to complete", NO_NUM); 1279 } 1280 } 1281 1282 /*===========================================================================* 1283 * dp_nic2user * 1284 *===========================================================================*/ 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); 1348 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1349 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 1350 1351 i= 0; 1352 while (count > 0) 1353 { 1354 if (i >= IOVEC_NR) 1355 { 1356 dp_next_iovec(iovp); 1357 i= 0; 1358 continue; 1359 } 1360 assert(i < iovp->iod_iovec_s); 1361 if (offset >= iovp->iod_iovec[i].iov_size) 1362 { 1363 offset -= iovp->iod_iovec[i].iov_size; 1364 i++; 1365 continue; 1366 } 1367 bytes = iovp->iod_iovec[i].iov_size - offset; 1368 if (bytes > count) 1369 bytes = count; 1370 1371 do_vir_insb(dep->de_data_port, iovp->iod_proc_nr, 1372 iovp->iod_iovec[i].iov_addr + offset, bytes); 1373 count -= bytes; 1374 offset += bytes; 1375 } 1376 assert(count == 0); 1377 } 1378 1379 /*===========================================================================* 1380 * dp_pio16_nic2user * 1381 *===========================================================================*/ 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); 1401 outb_reg0(dep, DP_RBCR1, ecount >> 8); 1402 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF); 1403 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 1404 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 1405 1406 i= 0; 1407 while (count > 0) 1408 { 1409 if (i >= IOVEC_NR) 1410 { 1411 dp_next_iovec(iovp); 1412 i= 0; 1413 continue; 1414 } 1415 assert(i < iovp->iod_iovec_s); 1416 if (offset >= iovp->iod_iovec[i].iov_size) 1417 { 1418 offset -= iovp->iod_iovec[i].iov_size; 1419 i++; 1420 continue; 1421 } 1422 bytes = iovp->iod_iovec[i].iov_size - offset; 1423 if (bytes > count) 1424 bytes = count; 1425 1426 user_proc= iovp->iod_proc_nr; 1427 vir_user= iovp->iod_iovec[i].iov_addr + offset; 1428 if (odd_byte) 1429 { 1430 //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1], 1431 r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]), 1432 user_proc, D, vir_user, 1); 1433 if (r != OK) 1434 { 1435 panic("DP8390", 1436 "dp_pio16_nic2user: sys_vircopy failed", 1437 r); 1438 } 1439 count--; 1440 offset++; 1441 bytes--; 1442 vir_user++; 1443 odd_byte= 0; 1444 if (!bytes) 1445 continue; 1446 } 1447 ecount= bytes &~1; 1448 if (ecount != 0) 1449 { 1450 do_vir_insw(dep->de_data_port, user_proc, vir_user, 1451 ecount); 1452 count -= ecount; 1453 offset += ecount; 1454 bytes -= ecount; 1455 vir_user += ecount; 1456 } 1457 if (bytes) 1458 { 1459 assert(bytes == 1); 1460 //*(u16_t *)two_bytes= inw(dep->de_data_port); 1461 two_bytes= inw(dep->de_data_port); 1462 //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0], 1463 r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]), 1464 user_proc, D, vir_user, 1); 1465 if (r != OK) 1466 { 1467 panic("DP8390", 1468 "dp_pio16_nic2user: sys_vircopy failed", 1469 r); 1470 } 1471 count--; 1472 offset++; 1473 bytes--; 1474 vir_user++; 1475 odd_byte= 1; 1476 } 1477 } 1478 assert(count == 0); 1479 } 1480 1481 /*===========================================================================* 1482 * dp_next_iovec * 1483 *===========================================================================*/ 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 { 1518 printf("%s: No ethernet card found at %#lx\n", 1519 dep->de_name, dep->de_base_port); 1520 dep->de_mode= DEM_DISABLED; 630 if (last >= dep->de_stoppage) { 631 count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t); 632 633 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 634 buf, 0, count); 635 dp_nic2user(dep, dep->de_startpage * DP_PAGESIZE, 636 buf, count, length - count); 637 } else { 638 dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t), 639 buf, 0, length); 640 } 641 642 nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE); 643 644 return EOK; 645 } 646 647 static void conf_hw(dpeth_t *dep) 648 { 649 if (!ne_probe(dep)) { 650 printf("No ethernet card found at %#lx\n", dep->de_base_port); 651 dep->up = false; 1521 652 return; 1522 653 } 1523 1524 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000; 1525 1526 dep->de_mode = DEM_ENABLED; 1527 1528 dep->de_flags = DEF_EMPTY; 1529 // dep->de_stat = empty_stat; 1530 } 1531 1532 /*===========================================================================* 1533 * map_hw_buffer * 1534 *===========================================================================*/ 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 0 1545 if(debug){ 1546 printf( 1547 "map_hw_buffer: programmed I/O, no need to map buffer\n"); 1548 } 1549 #endif 1550 dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */ 1551 return; 1552 }else{ 1553 printf("map_hw_buffer: no buffer!\n"); 1554 } 1555 1556 // size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for 1557 // * alignment 1558 // */ 1559 // buf= malloc(size); 1560 // if (buf == NULL) 1561 // panic(__FILE__, "map_hw_buffer: cannot malloc size", size); 1562 // o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE); 1563 // abuf= buf + o; 1564 // printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf); 1565 1566 // r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf, 1567 // dep->de_ramsize, (phys_bytes)dep->de_linmem); 1568 // if (r != OK) 1569 // panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r); 1570 // dep->de_locmem = abuf; 1571 } 1572 1573 /*===========================================================================* 1574 * reply * 1575 *===========================================================================*/ 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 0 1602 printf("send locked\n"); 1603 #endif 1604 return; 1605 } 1606 1607 if (r < 0) 1608 panic("", "dp8390: send failed:", r); 1609 1610 */ dep->de_read_s = 0; 1611 // dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV); 1612 } 1613 1614 /*===========================================================================* 1615 * get_userdata * 1616 *===========================================================================*/ 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); 654 655 dep->up = true; 656 dep->enabled = false; 657 dep->stopped = false; 658 dep->sending = false; 659 dep->send_avail = false; 1629 660 } 1630 661 … … 1632 663 { 1633 664 size_t i; 1634 1635 for (i = 0; i < size; ++ i){665 666 for (i = 0; i < size; i++) 1636 667 *((uint8_t *) buf + i) = inb(port); 1637 }1638 668 } 1639 669 … … 1641 671 { 1642 672 size_t i; 1643 1644 for (i = 0; i * 2 < size; ++ i){673 674 for (i = 0; i * 2 < size; i++) 1645 675 *((uint16_t *) buf + i) = inw(port); 1646 }1647 676 } 1648 677 … … 1650 679 { 1651 680 size_t i; 1652 1653 for (i = 0; i < size; ++ i){681 682 for (i = 0; i < size; i++) 1654 683 outb(port, *((uint8_t *) buf + i)); 1655 }1656 684 } 1657 685 … … 1659 687 { 1660 688 size_t i; 1661 1662 for (i = 0; i * 2 < size; ++ i){689 690 for (i = 0; i * 2 < size; i++) 1663 691 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 */ 692 } 1670 693 1671 694 /** @} -
uspace/srv/hw/netif/dp8390/dp8390.h
rf03d3786 rae1f70e 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 */ 93 #define DP_PAR0 0x1 /* Physical Address Register 0 */ 94 #define DP_PAR1 0x2 /* Physical Address Register 1 */ 95 #define DP_PAR2 0x3 /* Physical Address Register 2 */ 96 #define DP_PAR3 0x4 /* Physical Address Register 3 */ 97 #define DP_PAR4 0x5 /* Physical Address Register 4 */ 98 #define DP_PAR5 0x6 /* Physical Address Register 5 */ 99 #define DP_CURR 0x7 /* Current Page Register */ 100 #define DP_MAR0 0x8 /* Multicast Address Register 0 */ 101 #define DP_MAR1 0x9 /* Multicast Address Register 1 */ 102 #define DP_MAR2 0xA /* Multicast Address Register 2 */ 103 #define DP_MAR3 0xB /* Multicast Address Register 3 */ 104 #define DP_MAR4 0xC /* Multicast Address Register 4 */ 105 #define DP_MAR5 0xD /* Multicast Address Register 5 */ 106 #define DP_MAR6 0xE /* Multicast Address Register 6 */ 107 #define DP_MAR7 0xF /* Multicast Address Register 7 */ 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 */ 91 #define DP_PAR0 0x01 /**< Physical Address Register 0 */ 92 #define DP_PAR1 0x02 /**< Physical Address Register 1 */ 93 #define DP_PAR2 0x03 /**< Physical Address Register 2 */ 94 #define DP_PAR3 0x04 /**< Physical Address Register 3 */ 95 #define DP_PAR4 0x05 /**< Physical Address Register 4 */ 96 #define DP_PAR5 0x06 /**< Physical Address Register 5 */ 97 #define DP_CURR 0x07 /**< Current Page Register */ 98 #define DP_MAR0 0x08 /**< Multicast Address Register 0 */ 99 #define DP_MAR1 0x09 /**< Multicast Address Register 1 */ 100 #define DP_MAR2 0x0a /**< Multicast Address Register 2 */ 101 #define DP_MAR3 0x0b /**< Multicast Address Register 3 */ 102 #define DP_MAR4 0x0c /**< Multicast Address Register 4 */ 103 #define DP_MAR5 0x0d /**< Multicast Address Register 5 */ 104 #define DP_MAR6 0x0e /**< Multicast Address Register 6 */ 105 #define DP_MAR7 0x0f /**< Multicast Address Register 7 */ 108 106 109 107 /* Bits in dp_cr */ … … 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)) 251 252 /* Software interface to the dp8390 driver */ 253 254 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 245 #define outb_reg1(dep, reg, data) (outb(dep->de_dp8390_port + reg, data)) 246 247 #define SENDQ_NR 2 /* Maximum size of the send queue */ 248 #define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */ 249 250 typedef struct dpeth { 251 /* 252 * The de_base_port field is the starting point of the probe. 253 * The conf routine also fills de_irq. If the probe 329 254 * routine knows the irq and/or memory address because they are 330 255 * hardwired in the board, the probe should modify these fields. 331 * Futhermore, the probe routine should also fill in de_initf and332 * de_stopf fields with the appropriate function pointers and set333 * de_prog_IO iff programmed I/O is to be used.334 256 */ 335 257 port_t de_base_port; 336 phys_bytes de_linmem;337 char *de_locmem;338 258 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; 344 char de_name[sizeof("dp8390#n")]; 345 346 /* The initf function fills the following fields. Only cards that do 347 * programmed I/O fill in the de_pata_port field. 348 * In addition, the init routine has to fill in the sendq data 349 * structures. 350 */ 259 351 260 ether_addr_t de_address; 352 261 port_t de_dp8390_port; … … 357 266 int de_startpage; 358 267 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; 268 269 /* Do it yourself send queue */ 270 struct sendq { 271 int sq_filled; /* this buffer contains a packet */ 272 int sq_size; /* with this size */ 273 int sq_sendpage; /* starting page of the buffer */ 274 } de_sendq[SENDQ_NR]; 275 276 int de_sendq_nr; 277 int de_sendq_head; /* Enqueue at the head */ 278 int de_sendq_tail; /* Dequeue at the tail */ 279 280 /* Fields for internal use by the dp8390 driver. */ 281 eth_stat_t de_stat; 282 283 /* Driver flags */ 284 bool up; 285 bool enabled; 286 bool stopped; 287 bool sending; 288 bool send_avail; 289 } dpeth_t; 290 369 291 #endif 370 292 371 /* Do it yourself send queue */372 struct sendq373 {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 */377 } de_sendq[SENDQ_NR];378 int de_sendq_nr;379 int de_sendq_head; /* Enqueue at the head */380 int de_sendq_tail; /* Dequeue at the tail */381 382 /* Fields for internal use by the dp8390 driver. */383 int de_flags;384 int de_mode;385 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;398 dp_nic2userf_t de_nic2userf;399 // dp_nic2userf_s_t de_nic2userf_s;400 dp_getblock_t de_getblockf;401 } dpeth_t;402 403 #define DEI_DEFAULT 0x8000404 405 #define DEF_EMPTY 0x000406 #define DEF_PACK_SEND 0x001407 #define DEF_PACK_RECV 0x002408 #define DEF_SEND_AVAIL 0x004409 #define DEF_READING 0x010410 #define DEF_PROMISC 0x040411 #define DEF_MULTI 0x080412 #define DEF_BROAD 0x100413 #define DEF_ENABLED 0x200414 #define DEF_STOPPED 0x400415 416 #define DEM_DISABLED 0x0417 #define DEM_SINK 0x1418 #define DEM_ENABLED 0x2419 420 //#if !__minix_vmd421 #define debug 1 /* Standard Minix lacks debug variable */422 //#endif423 424 /*425 * $PchId: dp8390.h,v 1.10 2005/02/10 17:26:06 philip Exp $426 */427 428 #endif429 430 293 /** @} 431 294 */ -
uspace/srv/hw/netif/dp8390/dp8390_drv.h
rf03d3786 rae1f70e 40 40 #include "dp8390.h" 41 41 42 /** Initializes and/or starts the network interface. 43 * @param[in,out] dep The network interface structure. 44 * @param[in] mode The state mode. 45 * @returns EOK on success. 46 * @returns EXDEV if the network interface is disabled. 47 */ 48 int do_init(dpeth_t *dep, int mode); 42 int do_init(dpeth_t *dep); 49 43 50 44 /** Stops the network interface. … … 55 49 /** Processes the interrupt. 56 50 * @param[in,out] dep The network interface structure. 57 * @param[in] isr The interrupt status register.58 51 */ 59 void dp_check_ints( dpeth_t *dep, int isr);52 void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, uint8_t isr); 60 53 61 54 /** Probes and initializes the network interface. … … 70 63 * @param[in] packet The packet t be sent. 71 64 * @param[in] from_int The value indicating whether the sending is initialized from the interrupt handler. 72 * @returns 65 * @returns 73 66 */ 74 67 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 68 81 69 #endif -
uspace/srv/hw/netif/dp8390/dp8390_module.c
rf03d3786 rae1f70e 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_A_8, 95 .addr = NULL, 96 .srcarg = 3 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->up)) { 133 assert(dep->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)); … … 224 233 device->state = NETIF_STOPPED; 225 234 dep->de_irq = irq; 226 dep->de_mode = DEM_DISABLED; 235 dep->up = false; 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; 285 rc = do_init(dep, DL_BROAD_REQ); 307 308 rc = do_init(dep); 286 309 if (rc != EOK) { 287 310 ipc_unregister_irq(dep->de_irq, device->device_id); 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
rf03d3786 rae1f70e 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__)102 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 80 /** Type definition of a port. 170 81 */ 171 82 typedef long port_t; 172 83 173 /* dl_eth.h */174 84 /** Ethernet statistics. 175 85 */ 176 typedef struct eth_stat 177 { 86 typedef struct eth_stat { 178 87 /** Number of receive errors. 179 88 */ … … 226 135 } eth_stat_t; 227 136 228 /* errno.h */229 /** Generic error.230 */231 #define EGENERIC EINVAL232 233 /* ether.h */234 137 /** Minimum Ethernet packet size in bytes. 235 138 */ 236 #define ETH_MIN_PACK_SIZE 139 #define ETH_MIN_PACK_SIZE 60 237 140 238 141 /** Maximum Ethernet packet size in bytes. 239 142 */ 240 #define ETH_MAX_PACK_SIZE_TAGGED 143 #define ETH_MAX_PACK_SIZE_TAGGED 1518 241 144 242 145 /** Ethernet address type definition. 243 146 */ 244 typedef struct ether_addr 245 { 147 typedef struct ether_addr { 246 148 /** Address data. 247 149 */ 248 u 8_t ea_addr[6];150 uint8_t ea_addr[6]; 249 151 } 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 152 271 153 #endif -
uspace/srv/hw/netif/dp8390/ne2000.c
rf03d3786 rae1f70e 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 FALSE otherwise. 109 */ 110 static int test_16(dpeth_t *dep, int pos, u8_t *pat); 111 112 /** Stops the NE2000 network interface. 113 * @param[in,out] dep The network interface structure. 114 */ 115 static void ne_stop(dpeth_t *dep); 116 //_PROTOTYPE(static void milli_delay, (unsigned long millis) ); 117 118 /** Initializes the NE2000 network interface. 119 * @param[in,out] dep The network interface structure. 120 */ 121 void ne_init(struct dpeth *dep); 122 123 /*===========================================================================* 124 * ne_probe * 125 *===========================================================================*/ 126 int ne_probe(dep) 127 dpeth_t *dep; 79 * @returns false otherwise. 80 */ 81 static int test_16(dpeth_t *dep, int pos, uint8_t *pat); 82 83 int ne_probe(dpeth_t *dep) 128 84 { 129 85 int byte; … … 131 87 int loc1, loc2; 132 88 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 89 90 dep->de_dp8390_port = dep->de_base_port + NE_DP8390; 91 92 /* 93 * We probe for an ne1000 or an ne2000 by testing whether the 137 94 * on board is reachable through the dp8390. Note that the 138 95 * ne1000 is an 8bit card and has a memory region distict from 139 96 * the 16bit ne2000 140 97 */ 141 142 for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++) 143 { 98 99 for (dep->de_16bit = 0; dep->de_16bit < 2; dep->de_16bit++) { 144 100 /* Reset the ethernet card */ 145 101 byte= inb_ne(dep, NE_RESET); 146 milli_delay(2);102 usleep(2000); 147 103 outb_ne(dep, NE_RESET, byte); 148 milli_delay(2);149 104 usleep(2000); 105 150 106 /* Reset the dp8390 */ 151 107 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++)108 for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++) 153 109 ; /* Do nothing */ 154 110 155 111 /* 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 { 112 if ((inb_reg0(dep, DP_CR) & (CR_STP | CR_DM_ABORT)) != 113 (CR_STP | CR_DM_ABORT)) 159 114 return 0; 160 } 161 115 162 116 /* Disable the receiver and init TCR and DCR. */ 163 117 outb_reg0(dep, DP_RCR, RCR_MON); 164 118 outb_reg0(dep, DP_TCR, TCR_NORMAL); 165 if (dep->de_16bit) 166 { 119 if (dep->de_16bit) { 167 120 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | 168 DCR_BMS); 121 DCR_BMS); 122 } else { 123 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | 124 DCR_BMS); 169 125 } 170 else 171 { 172 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | 173 DCR_BMS); 126 127 if (dep->de_16bit) { 128 loc1 = NE2000_START; 129 loc2 = NE2000_START + NE2000_SIZE - 4; 130 f = test_16; 131 } else { 132 loc1 = NE1000_START; 133 loc2 = NE1000_START + NE1000_SIZE - 4; 134 f = test_8; 174 135 } 175 176 if (dep->de_16bit) 177 { 178 loc1= NE2000_START; 179 loc2= NE2000_START + NE2000_SIZE - 4; 180 f= test_16; 181 } 182 else 183 { 184 loc1= NE1000_START; 185 loc2= NE1000_START + NE1000_SIZE - 4; 186 f= test_8; 187 } 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; 136 137 if (f(dep, loc1, pat0) && f(dep, loc1, pat1) && 138 f(dep, loc1, pat2) && f(dep, loc1, pat3) && 139 f(dep, loc2, pat0) && f(dep, loc2, pat1) && 140 f(dep, loc2, pat2) && f(dep, loc2, pat3)) { 199 141 return 1; 200 142 } 201 143 } 144 202 145 return 0; 203 146 } 204 147 205 /*===========================================================================* 206 * ne_init * 207 *===========================================================================*/ 208 void ne_init(dep) 209 dpeth_t *dep; 148 /** Initializes the NE2000 network interface. 149 * 150 * @param[in,out] dep The network interface structure. 151 * 152 */ 153 void ne_init(dpeth_t *dep) 210 154 { 211 155 int i; 212 156 int word, sendq_nr; 213 157 214 158 /* Setup a transfer to get the ethernet address. */ 215 159 if (dep->de_16bit) … … 217 161 else 218 162 outb_reg0(dep, DP_RBCR0, 6); 163 219 164 outb_reg0(dep, DP_RBCR1, 0); 220 165 outb_reg0(dep, DP_RSAR0, 0); 221 166 outb_reg0(dep, DP_RSAR1, 0); 222 167 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 { 168 169 for (i = 0; i < 6; i++) { 170 if (dep->de_16bit) { 171 word = inw_ne(dep, NE_DATA); 172 dep->de_address.ea_addr[i] = word; 173 } else 233 174 dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA); 234 235 }175 } 176 236 177 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 178 if (dep->de_16bit) { 179 dep->de_ramsize = NE2000_SIZE; 180 dep->de_offset_page = NE2000_START / DP_PAGESIZE; 181 } else { 182 dep->de_ramsize = NE1000_SIZE; 183 dep->de_offset_page = NE1000_START / DP_PAGESIZE; 184 } 185 248 186 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */ 249 sendq_nr= dep->de_ramsize / 0x2000; 187 sendq_nr = dep->de_ramsize / 0x2000; 188 250 189 if (sendq_nr < 1) 251 sendq_nr = 1;190 sendq_nr = 1; 252 191 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]; 291 int i; 292 int r; 293 294 outb_reg0(dep, DP_ISR, 0xFF); 295 192 sendq_nr = SENDQ_NR; 193 194 dep->de_sendq_nr = sendq_nr; 195 for (i = 0; i < sendq_nr; i++) 196 dep->de_sendq[i].sq_sendpage = dep->de_offset_page + i * SENDQ_PAGES; 197 198 dep->de_startpage = dep->de_offset_page + i * SENDQ_PAGES; 199 dep->de_stoppage = dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE; 200 201 printf("Novell NE%d000 ethernet card at I/O address " 202 "%#lx, memory size %#lx, irq %d\n", 203 dep->de_16bit ? 2 : 1, dep->de_base_port, dep->de_ramsize, 204 dep->de_irq); 205 } 206 207 static int test_8(dpeth_t *dep, int pos, uint8_t *pat) 208 { 209 uint8_t buf[4]; 210 int i; 211 212 outb_reg0(dep, DP_ISR, 0xff); 213 296 214 /* Setup a transfer to put the pattern. */ 297 215 outb_reg0(dep, DP_RBCR0, 4); 298 216 outb_reg0(dep, DP_RBCR1, 0); 299 outb_reg0(dep, DP_RSAR0, pos & 0xFF);217 outb_reg0(dep, DP_RSAR0, pos & 0xff); 300 218 outb_reg0(dep, DP_RSAR1, pos >> 8); 301 219 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 302 303 for (i = 0; i<4; i++)220 221 for (i = 0; i < 4; i++) 304 222 outb_ne(dep, NE_DATA, pat[i]); 305 306 for (i= 0; i<N; i++) 307 { 223 224 for (i = 0; i < N; i++) { 225 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 226 break; 227 } 228 229 if (i == N) { 230 printf("NE1000 remote DMA test failed\n"); 231 return 0; 232 } 233 234 outb_reg0(dep, DP_RBCR0, 4); 235 outb_reg0(dep, DP_RBCR1, 0); 236 outb_reg0(dep, DP_RSAR0, pos & 0xff); 237 outb_reg0(dep, DP_RSAR1, pos >> 8); 238 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 239 240 for (i = 0; i < 4; i++) 241 buf[i] = inb_ne(dep, NE_DATA); 242 243 return (memcmp(buf, pat, 4) == 0); 244 } 245 246 static int test_16(dpeth_t *dep, int pos, uint8_t *pat) 247 { 248 uint8_t buf[4]; 249 int i; 250 251 outb_reg0(dep, DP_ISR, 0xff); 252 253 /* Setup a transfer to put the pattern. */ 254 outb_reg0(dep, DP_RBCR0, 4); 255 outb_reg0(dep, DP_RBCR1, 0); 256 outb_reg0(dep, DP_RSAR0, pos & 0xff); 257 outb_reg0(dep, DP_RSAR1, pos >> 8); 258 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 259 260 for (i = 0; i < 4; i += 2) 261 outw_ne(dep, NE_DATA, *(uint16_t *)(pat + i)); 262 263 for (i = 0; i < N; i++) { 308 264 if (inb_reg0(dep, DP_ISR) &ISR_RDC) 309 265 break; 310 266 } 311 if (i == N) 312 { 313 if (debug) 314 { 315 printf("%s: NE1000 remote DMA test failed\n", 316 dep->de_name); 317 } 267 268 if (i == N) { 269 printf("NE2000 remote DMA test failed\n"); 318 270 return 0; 319 271 } 320 321 outb_reg0(dep, DP_RBCR0, 4); 322 outb_reg0(dep, DP_RBCR1, 0); 323 outb_reg0(dep, DP_RSAR0, pos & 0xFF);272 273 outb_reg0(dep, DP_RBCR0, 4); 274 outb_reg0(dep, DP_RBCR1, 0); 275 outb_reg0(dep, DP_RSAR0, pos & 0xff); 324 276 outb_reg0(dep, DP_RSAR1, pos >> 8); 325 277 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 278 279 for (i = 0; i < 4; i += 2) 280 *(uint16_t *)(buf + i) = inw_ne(dep, NE_DATA); 281 282 return (memcmp(buf, pat, 4) == 0); 283 } 284 285 /** Stop the NE2000 network interface. 286 * 287 * @param[in,out] dep The network interface structure. 288 * 289 */ 290 void ne_stop(dpeth_t *dep) 291 { 398 292 /* Reset the ethernet card */ 399 byte= inb_ne(dep, NE_RESET);400 milli_delay(2);293 int byte = inb_ne(dep, NE_RESET); 294 usleep(2000); 401 295 outb_ne(dep, NE_RESET, byte); 402 296 } 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 297 415 298 /** @} -
uspace/srv/hw/netif/dp8390/ne2000.h
rf03d3786 rae1f70e 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 extern int ne_probe(struct dpeth *); 113 extern void ne_init(struct dpeth *); 114 extern void ne_stop(struct dpeth *); 115 116 #endif 109 117 110 118 /** @} -
uspace/srv/net/tl/icmp/icmp.c
rf03d3786 rae1f70e 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.