Changeset 8136102 in mainline
- Timestamp:
- 2011-01-11T01:33:58Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6b22c97
- Parents:
- 6643a19 (diff), 7300c37 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/netif/netif_skel.c
r6643a19 r8136102 130 130 if (result > NETIF_NULL) { 131 131 int phone = device->nil_phone; 132 nil_device_state_msg(phone, device_id, result); 132 133 fibril_rwlock_write_unlock(&netif_globals.lock); 133 nil_device_state_msg(phone, device_id, result);134 134 return EOK; 135 135 } … … 166 166 if (result > NETIF_NULL) { 167 167 int phone = device->nil_phone; 168 nil_device_state_msg(phone, device_id, result); 168 169 fibril_rwlock_write_unlock(&netif_globals.lock); 169 nil_device_state_msg(phone, device_id, result);170 170 return EOK; 171 171 } -
uspace/srv/hw/netif/dp8390/dp8390.c
r6643a19 r8136102 54 54 #include <errno.h> 55 55 #include <libarch/ddi.h> 56 #include <netif_skel.h>57 56 #include <net/packet.h> 58 #include <nil_interface.h>59 57 #include <packet_client.h> 60 58 #include "dp8390.h" … … 81 79 82 80 /** NE2000 retry count */ 83 #define NE2K_RETRY 10081 #define NE2K_RETRY 0x1000 84 82 85 83 /** NE2000 error messages rate limiting */ … … 186 184 memcpy(&word, buf, 1); 187 185 pio_write_16(ne2k->data_port, word); 186 } 187 } 188 189 static void ne2k_init(ne2k_t *ne2k) 190 { 191 unsigned int i; 192 193 /* Reset the ethernet card */ 194 uint8_t val = pio_read_8(ne2k->port + NE2K_RESET); 195 usleep(2000); 196 pio_write_8(ne2k->port + NE2K_RESET, val); 197 usleep(2000); 198 199 /* Reset the DP8390 */ 200 pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT); 201 for (i = 0; i < NE2K_RETRY; i++) { 202 if (pio_read_8(ne2k->port + DP_ISR) != 0) 203 break; 188 204 } 189 205 } … … 210 226 ne2k->up = false; 211 227 212 /* Reset the ethernet card */ 213 uint8_t val = pio_read_8(ne2k->port + NE2K_RESET); 214 usleep(2000); 215 pio_write_8(ne2k->port + NE2K_RESET, val); 216 usleep(2000); 217 218 /* Reset the DP8390 */ 219 pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT); 220 for (i = 0; i < 0x1000; i++) { 221 if (pio_read_8(ne2k->port + DP_ISR) != 0) 222 break; 223 } 228 ne2k_init(ne2k); 224 229 225 230 /* Check if the DP8390 is really there */ 226 val = pio_read_8(ne2k->port + DP_CR);231 uint8_t val = pio_read_8(ne2k->port + DP_CR); 227 232 if ((val & (CR_STP | CR_DM_ABORT)) != (CR_STP | CR_DM_ABORT)) 228 233 return EXDEV; … … 242 247 for (i = 0; i < ETH_ADDR; i++) 243 248 ne2k->mac[i] = pio_read_16(ne2k->data_port); 249 250 ne2k->probed = true; 251 return EOK; 252 } 253 254 /** Start the network interface. 255 * 256 * @param[in,out] ne2k Network interface structure. 257 * 258 * @return EOK on success. 259 * @return EXDEV if the network interface is disabled. 260 * 261 */ 262 int ne2k_up(ne2k_t *ne2k) 263 { 264 if (!ne2k->probed) 265 return EXDEV; 266 267 ne2k_init(ne2k); 244 268 245 269 /* … … 318 342 319 343 /* Step 10: */ 320 pio_write_8(ne2k->port + DP_CR, CR_ DM_ABORT | CR_STA);344 pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_DM_ABORT | CR_STA); 321 345 322 346 /* Step 11: */ … … 329 353 330 354 /* Finish the initialization */ 331 ne2k->probed = true;332 return EOK;333 }334 335 /** Start the network interface.336 *337 * @param[in,out] ne2k Network interface structure.338 *339 * @return EOK on success.340 * @return EXDEV if the network interface is disabled.341 *342 */343 int ne2k_up(ne2k_t *ne2k)344 {345 if (!ne2k->probed)346 return EXDEV;347 348 pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_STA);349 pio_write_8(ne2k->port + DP_RCR, RCR_AB);350 351 355 ne2k->up = true; 352 356 return EOK; … … 362 366 if ((ne2k->probed) && (ne2k->up)) { 363 367 pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT); 364 365 /* Reset the ethernet card */ 366 uint8_t val = pio_read_8(ne2k->port + NE2K_RESET); 367 usleep(2000); 368 pio_write_8(ne2k->port + NE2K_RESET, val); 369 368 ne2k_init(ne2k); 370 369 ne2k->up = false; 371 370 } … … 420 419 pio_write_8(ne2k->port + DP_RBCR1, 0); 421 420 422 for (i = 0; i < 0x1000; i++) {421 for (i = 0; i < NE2K_RETRY; i++) { 423 422 if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RST) != 0) 424 423 break; … … 430 429 431 430 /* Acknowledge the ISR_RDC (remote DMA) interrupt */ 432 for (i = 0; i < 0x1000; i++) {431 for (i = 0; i < NE2K_RETRY; i++) { 433 432 if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RDC) != 0) 434 433 break; … … 448 447 } 449 448 450 static uint8_t ne2k_isr_ack(ne2k_t *ne2k) 451 { 452 uint8_t isr = pio_read_8(ne2k->port + DP_ISR); 453 if (isr != 0) 454 pio_write_8(ne2k->port + DP_ISR, isr); 455 456 return isr; 457 } 458 459 static void ne2k_receive_frame(ne2k_t *ne2k, uint8_t page, size_t length, 460 int nil_phone, device_id_t device_id) 461 { 462 packet_t *packet = netif_packet_get_1(length); 463 if (!packet) 464 return; 465 466 void *buf = packet_suffix(packet, length); 449 static frame_t *ne2k_receive_frame(ne2k_t *ne2k, uint8_t page, size_t length) 450 { 451 frame_t *frame = (frame_t *) malloc(sizeof(frame_t)); 452 if (frame == NULL) 453 return NULL; 454 455 link_initialize(&frame->link); 456 457 frame->packet = netif_packet_get_1(length); 458 if (frame->packet == NULL) { 459 free(frame); 460 return NULL; 461 } 462 463 void *buf = packet_suffix(frame->packet, length); 467 464 bzero(buf, length); 468 465 uint8_t last = page + length / DP_PAGE; … … 481 478 482 479 ne2k->stats.receive_packets++; 483 nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE); 484 } 485 486 static void ne2k_receive(ne2k_t *ne2k, int nil_phone, device_id_t device_id) 487 { 480 return frame; 481 } 482 483 static link_t *ne2k_receive(ne2k_t *ne2k) 484 { 485 /* 486 * Allocate memory for the list of received frames. 487 * If the allocation fails here we still receive the 488 * frames from the network, but they will be lost. 489 */ 490 link_t *frames = (link_t *) malloc(sizeof(link_t)); 491 if (frames != NULL) 492 list_initialize(frames); 493 488 494 while (true) { 489 495 uint8_t boundary = pio_read_8(ne2k->port + DP_BNRY) + 1; … … 534 540 ne2k->overruns++; 535 541 next = current; 536 } else if ((header.status & RSR_PRX) && (ne2k->up)) 537 ne2k_receive_frame(ne2k, boundary, length, nil_phone, device_id); 542 } else if ((header.status & RSR_PRX) && (ne2k->up)) { 543 frame_t *frame = ne2k_receive_frame(ne2k, boundary, length); 544 if ((frame != NULL) && (frames != NULL)) 545 list_append(&frame->link, frames); 546 } 538 547 539 548 /* … … 550 559 pio_write_8(ne2k->port + DP_BNRY, next); 551 560 } 552 } 553 554 void ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, int nil_phone, device_id_t device_id) 555 { 556 bool signal = false; 557 bool stopped = false; 558 559 for (; (isr & 0x7f) != 0; isr = ne2k_isr_ack(ne2k)) { 560 if (isr & (ISR_PTX | ISR_TXE)) { 561 if (isr & ISR_TXE) 562 ne2k->stats.send_errors++; 563 else { 564 uint8_t tsr = pio_read_8(ne2k->port + DP_TSR); 565 566 if (tsr & TSR_PTX) 567 ne2k->stats.send_packets++; 568 569 if (tsr & TSR_COL) 570 ne2k->stats.collisions++; 571 572 if (tsr & TSR_ABT) 573 ne2k->stats.send_aborted_errors++; 574 575 if (tsr & TSR_CRS) 576 ne2k->stats.send_carrier_errors++; 577 578 if (tsr & TSR_FU) { 579 ne2k->underruns++; 580 if (ne2k->underruns < NE2K_ERL) 581 fprintf(stderr, "%s: FIFO underrun\n", NAME); 582 } 583 584 if (tsr & TSR_CDH) { 585 ne2k->stats.send_heartbeat_errors++; 586 if (ne2k->stats.send_heartbeat_errors < NE2K_ERL) 587 fprintf(stderr, "%s: CD heartbeat failure\n", NAME); 588 } 589 590 if (tsr & TSR_OWC) 591 ne2k->stats.send_window_errors++; 561 562 return frames; 563 } 564 565 link_t *ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, uint8_t tsr) 566 { 567 /* List of received frames */ 568 link_t *frames = NULL; 569 570 if (isr & (ISR_PTX | ISR_TXE)) { 571 if (isr & ISR_TXE) 572 ne2k->stats.send_errors++; 573 else { 574 if (tsr & TSR_PTX) 575 ne2k->stats.send_packets++; 576 577 if (tsr & TSR_COL) 578 ne2k->stats.collisions++; 579 580 if (tsr & TSR_ABT) 581 ne2k->stats.send_aborted_errors++; 582 583 if (tsr & TSR_CRS) 584 ne2k->stats.send_carrier_errors++; 585 586 if (tsr & TSR_FU) { 587 ne2k->underruns++; 588 if (ne2k->underruns < NE2K_ERL) 589 fprintf(stderr, "%s: FIFO underrun\n", NAME); 592 590 } 593 591 594 fibril_mutex_lock(&ne2k->sq_mutex); 595 596 if (ne2k->sq.dirty) { 597 /* Prepare the buffer for next packet */ 598 ne2k->sq.dirty = false; 599 ne2k->sq.size = 0; 600 signal = true; 601 } else { 602 ne2k->misses++; 603 if (ne2k->misses < NE2K_ERL) 604 fprintf(stderr, "%s: Spurious PTX interrupt\n", NAME); 592 if (tsr & TSR_CDH) { 593 ne2k->stats.send_heartbeat_errors++; 594 if (ne2k->stats.send_heartbeat_errors < NE2K_ERL) 595 fprintf(stderr, "%s: CD heartbeat failure\n", NAME); 605 596 } 606 597 607 fibril_mutex_unlock(&ne2k->sq_mutex); 598 if (tsr & TSR_OWC) 599 ne2k->stats.send_window_errors++; 608 600 } 609 601 610 if (isr & ISR_PRX)611 ne2k_receive(ne2k, nil_phone, device_id);612 613 if (isr & ISR_RXE)614 ne2k->s tats.receive_errors++;615 616 if (isr & ISR_CNT) {617 ne2k->stats.receive_crc_errors +=618 pio_read_8(ne2k->port + DP_CNTR0);619 ne2k->stats.receive_frame_errors +=620 pio_read_8(ne2k->port + DP_CNTR1);621 ne2k->stats.receive_missed_errors +=622 pio_read_8(ne2k->port + DP_CNTR2);602 fibril_mutex_lock(&ne2k->sq_mutex); 603 604 if (ne2k->sq.dirty) { 605 /* Prepare the buffer for next packet */ 606 ne2k->sq.dirty = false; 607 ne2k->sq.size = 0; 608 609 /* Signal a next frame to be sent */ 610 fibril_condvar_broadcast(&ne2k->sq_cv); 611 } else { 612 ne2k->misses++; 613 if (ne2k->misses < NE2K_ERL) 614 fprintf(stderr, "%s: Spurious PTX interrupt\n", NAME); 623 615 } 624 616 625 if (isr & ISR_RST) { 626 /* 627 * This means we got an interrupt but the ethernet 628 * chip is shutdown. We set the flag 'stopped' 629 * and continue processing arrived packets. When the 630 * receive buffer is empty, we reset the DP8390. 631 */ 632 stopped = true; 633 } 634 } 635 636 if (stopped) { 617 fibril_mutex_unlock(&ne2k->sq_mutex); 618 } 619 620 if (isr & ISR_RXE) 621 ne2k->stats.receive_errors++; 622 623 if (isr & ISR_CNT) { 624 ne2k->stats.receive_crc_errors += 625 pio_read_8(ne2k->port + DP_CNTR0); 626 ne2k->stats.receive_frame_errors += 627 pio_read_8(ne2k->port + DP_CNTR1); 628 ne2k->stats.receive_missed_errors += 629 pio_read_8(ne2k->port + DP_CNTR2); 630 } 631 632 if (isr & ISR_PRX) 633 frames = ne2k_receive(ne2k); 634 635 if (isr & ISR_RST) { 637 636 /* 638 637 * The chip is stopped, and all arrived … … 642 641 } 643 642 644 /* Signal a next frame to be sent */ 645 if (signal) 646 fibril_condvar_broadcast(&ne2k->sq_cv); 643 /* Unmask interrupts to be processed in the next round */ 644 pio_write_8(ne2k->port + DP_IMR, 645 IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE); 646 647 return frames; 647 648 } 648 649 -
uspace/srv/hw/netif/dp8390/dp8390.h
r6643a19 r8136102 50 50 51 51 #include <fibril_synch.h> 52 #include <adt/list.h> 52 53 #include <net/packet.h> 54 #include <netif_skel.h> 53 55 54 56 /** Module name */ … … 230 232 } ne2k_t; 231 233 234 typedef struct { 235 link_t link; 236 packet_t *packet; 237 } frame_t; 238 232 239 extern int ne2k_probe(ne2k_t *, void *, int); 233 240 extern int ne2k_up(ne2k_t *); 234 241 extern void ne2k_down(ne2k_t *); 235 242 extern void ne2k_send(ne2k_t *, packet_t *); 236 extern void ne2k_interrupt(ne2k_t *, uint8_t isr, int, device_id_t);243 extern link_t *ne2k_interrupt(ne2k_t *, uint8_t, uint8_t); 237 244 238 245 #endif -
uspace/srv/hw/netif/dp8390/ne2000.c
r6643a19 r8136102 68 68 #define IRQ_GET_ISR(call) ((int) IPC_GET_ARG2(call)) 69 69 70 /** Return the TSR from the interrupt call. 71 * 72 * @param[in] call The interrupt call. 73 * 74 */ 75 #define IRQ_GET_TSR(call) ((int) IPC_GET_ARG3(call)) 76 70 77 static int irc_service = 0; 71 78 static int irc_phone = -1; … … 76 83 static irq_cmd_t ne2k_cmds[] = { 77 84 { 85 /* Read Interrupt Status Register */ 78 86 .cmd = CMD_PIO_READ_8, 79 87 .addr = NULL, … … 81 89 }, 82 90 { 91 /* Mask supported interrupt causes */ 83 92 .cmd = CMD_BTEST, 84 .value = 0x7f, 93 .value = (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW | 94 ISR_CNT | ISR_RDC), 85 95 .srcarg = 2, 86 96 .dstarg = 3, 87 97 }, 88 98 { 99 /* Predicate for accepting the interrupt */ 89 100 .cmd = CMD_PREDICATE, 90 .value = 2,101 .value = 4, 91 102 .srcarg = 3 92 103 }, 93 104 { 105 /* 106 * Mask future interrupts via 107 * Interrupt Mask Register 108 */ 109 .cmd = CMD_PIO_WRITE_8, 110 .addr = NULL, 111 .value = 0 112 }, 113 { 114 /* Acknowledge the current interrupt */ 94 115 .cmd = CMD_PIO_WRITE_A_8, 95 116 .addr = NULL, 96 117 .srcarg = 3 118 }, 119 { 120 /* Read Transmit Status Register */ 121 .cmd = CMD_PIO_READ_8, 122 .addr = NULL, 123 .dstarg = 3 97 124 }, 98 125 { … … 111 138 /** Handle the interrupt notification. 112 139 * 113 * This is the interrupt notification function. 140 * This is the interrupt notification function. It is quarantied 141 * that there is only a single instance of this notification 142 * function running at one time until the return from the 143 * ne2k_interrupt() function (where the interrupts are unmasked 144 * again). 114 145 * 115 146 * @param[in] iid Interrupt notification identifier. … … 134 165 fibril_rwlock_read_unlock(&netif_globals.lock); 135 166 136 if (ne2k != NULL) 137 ne2k_interrupt(ne2k, IRQ_GET_ISR(*call), nil_phone, device_id); 167 if (ne2k != NULL) { 168 link_t *frames = 169 ne2k_interrupt(ne2k, IRQ_GET_ISR(*call), IRQ_GET_TSR(*call)); 170 171 if (frames != NULL) { 172 while (!list_empty(frames)) { 173 frame_t *frame = 174 list_get_instance(frames->next, frame_t, link); 175 176 list_remove(&frame->link); 177 nil_received_msg(nil_phone, device_id, frame->packet, 178 SERVICE_NONE); 179 free(frame); 180 } 181 182 free(frames); 183 } 184 } 138 185 } 139 186 … … 265 312 266 313 ne2k_cmds[0].addr = ne2k->port + DP_ISR; 267 ne2k_cmds[3].addr = ne2k_cmds[0].addr; 314 ne2k_cmds[3].addr = ne2k->port + DP_IMR; 315 ne2k_cmds[4].addr = ne2k_cmds[0].addr; 268 316 269 317 int rc = ipc_register_irq(ne2k->irq, device->device_id, … … 278 326 } 279 327 328 change_state(device, NETIF_ACTIVE); 329 280 330 if (irc_service) 281 331 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, ne2k->irq); 282 283 change_state(device, NETIF_ACTIVE);284 332 } 285 333
Note:
See TracChangeset
for help on using the changeset viewer.