Changeset 93fb170c in mainline for uspace/srv/hw/netif/dp8390/dp8390.c
- Timestamp:
- 2011-01-08T18:51:31Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 15be932
- Parents:
- 8f748215 (diff), a523af4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/dp8390.c
r8f748215 r93fb170c 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 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.