Changeset abe95c9 in mainline


Ignore:
Timestamp:
2011-01-10T22:49:14Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
43b4314
Parents:
6643a19
Message:

avoid multiple overlapped interrupt request handling by handling interrupts one at a time
(using the Interrupt Mask Register)

Location:
uspace/srv/hw/netif/dp8390
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/netif/dp8390/dp8390.c

    r6643a19 rabe95c9  
    446446        ne2k->sq.dirty = false;
    447447        fibril_mutex_unlock(&ne2k->sq_mutex);
    448 }
    449 
    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;
    457448}
    458449
     
    554545void ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, int nil_phone, device_id_t device_id)
    555546{
    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++;
     547        if (isr & (ISR_PTX | ISR_TXE)) {
     548                if (isr & ISR_TXE)
     549                        ne2k->stats.send_errors++;
     550                else {
     551                        uint8_t tsr = pio_read_8(ne2k->port + DP_TSR);
     552                       
     553                        if (tsr & TSR_PTX)
     554                                ne2k->stats.send_packets++;
     555                       
     556                        if (tsr & TSR_COL)
     557                                ne2k->stats.collisions++;
     558                       
     559                        if (tsr & TSR_ABT)
     560                                ne2k->stats.send_aborted_errors++;
     561                       
     562                        if (tsr & TSR_CRS)
     563                                ne2k->stats.send_carrier_errors++;
     564                       
     565                        if (tsr & TSR_FU) {
     566                                ne2k->underruns++;
     567                                if (ne2k->underruns < NE2K_ERL)
     568                                        fprintf(stderr, "%s: FIFO underrun\n", NAME);
    592569                        }
    593570                       
    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);
     571                        if (tsr & TSR_CDH) {
     572                                ne2k->stats.send_heartbeat_errors++;
     573                                if (ne2k->stats.send_heartbeat_errors < NE2K_ERL)
     574                                        fprintf(stderr, "%s: CD heartbeat failure\n", NAME);
    605575                        }
    606576                       
    607                         fibril_mutex_unlock(&ne2k->sq_mutex);
     577                        if (tsr & TSR_OWC)
     578                                ne2k->stats.send_window_errors++;
    608579                }
    609580               
    610                 if (isr & ISR_PRX)
    611                         ne2k_receive(ne2k, nil_phone, device_id);
    612                
    613                 if (isr & ISR_RXE)
    614                         ne2k->stats.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);
     581                fibril_mutex_lock(&ne2k->sq_mutex);
     582               
     583                if (ne2k->sq.dirty) {
     584                        /* Prepare the buffer for next packet */
     585                        ne2k->sq.dirty = false;
     586                        ne2k->sq.size = 0;
     587                       
     588                        /* Signal a next frame to be sent */
     589                        fibril_condvar_broadcast(&ne2k->sq_cv);
     590                } else {
     591                        ne2k->misses++;
     592                        if (ne2k->misses < NE2K_ERL)
     593                                fprintf(stderr, "%s: Spurious PTX interrupt\n", NAME);
    623594                }
    624595               
    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) {
     596                fibril_mutex_unlock(&ne2k->sq_mutex);
     597        }
     598       
     599        if (isr & ISR_PRX)
     600                ne2k_receive(ne2k, nil_phone, device_id);
     601       
     602        if (isr & ISR_RXE)
     603                ne2k->stats.receive_errors++;
     604       
     605        if (isr & ISR_CNT) {
     606                ne2k->stats.receive_crc_errors +=
     607                    pio_read_8(ne2k->port + DP_CNTR0);
     608                ne2k->stats.receive_frame_errors +=
     609                    pio_read_8(ne2k->port + DP_CNTR1);
     610                ne2k->stats.receive_missed_errors +=
     611                    pio_read_8(ne2k->port + DP_CNTR2);
     612        }
     613       
     614        if (isr & ISR_RST) {
    637615                /*
    638616                 * The chip is stopped, and all arrived
     
    642620        }
    643621       
    644         /* Signal a next frame to be sent */
    645         if (signal)
    646                 fibril_condvar_broadcast(&ne2k->sq_cv);
     622        /* Unmask interrupts to be processed in the next round */
     623        pio_write_8(ne2k->port + DP_IMR,
     624            IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE);
    647625}
    648626
  • uspace/srv/hw/netif/dp8390/ne2000.c

    r6643a19 rabe95c9  
    7676static irq_cmd_t ne2k_cmds[] = {
    7777        {
     78                /* Read Interrupt Status Register */
    7879                .cmd = CMD_PIO_READ_8,
    7980                .addr = NULL,
     
    8182        },
    8283        {
     84                /* Mask supported interrupt causes */
    8385                .cmd = CMD_BTEST,
    84                 .value = 0x7f,
     86                .value = (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW |
     87                    ISR_CNT | ISR_RDC),
    8588                .srcarg = 2,
    8689                .dstarg = 3,
    8790        },
    8891        {
     92                /* Predicate for accepting the interrupt */
    8993                .cmd = CMD_PREDICATE,
    90                 .value = 2,
     94                .value = 3,
    9195                .srcarg = 3
    9296        },
    9397        {
     98                /*
     99                 * Mask future interrupts via
     100                 * Interrupt Mask Register
     101                 */
     102                .cmd = CMD_PIO_WRITE_8,
     103                .addr = NULL,
     104                .value = 0
     105        },
     106        {
     107                /* Acknowledge the current interrupt */
    94108                .cmd = CMD_PIO_WRITE_A_8,
    95109                .addr = NULL,
     
    265279               
    266280                ne2k_cmds[0].addr = ne2k->port + DP_ISR;
    267                 ne2k_cmds[3].addr = ne2k_cmds[0].addr;
     281                ne2k_cmds[3].addr = ne2k->port + DP_IMR;
     282                ne2k_cmds[4].addr = ne2k_cmds[0].addr;
    268283               
    269284                int rc = ipc_register_irq(ne2k->irq, device->device_id,
Note: See TracChangeset for help on using the changeset viewer.