Changeset 15093362 in rtems


Ignore:
Timestamp:
02/18/00 13:53:06 (24 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Children:
2de8b1b
Parents:
56616af3
Message:

Patch from Eric Norum <eric@…> to address these issues:

1) Coalesce outgoing packet into a single mbuf when the packet is spread

over more mbufs than configured transmit buffer descriptors.

2) Add dianostic counters for successful and failed coalesce attempts.
3) Add diagnostic counter for transmit retries.

NOTE: (1) lead to deadlock and the same design based on underlying
hardware characteristics is currently also in the Sonic and
i386ex/network driver.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/m68k/gen68360/network/network.c

    r56616af3 r15093362  
    100100        unsigned long   txLostCarrier;
    101101        unsigned long   txRawWait;
     102        unsigned long   txCoalesced;
     103        unsigned long   txCoalesceFailed;
     104        unsigned long   txRetry;
    102105};
    103106static struct scc_softc scc_softc[NSCCDRIVER];
     
    345348        int nRetired;
    346349        struct mbuf *m, *n;
     350        int retries = 0;
     351        int saveStatus = 0;
    347352
    348353        i = sc->txBdTail;
     
    351356           &&  (((status = (sc->txBdBase + i)->status) & M360_BD_READY) == 0)) {
    352357                /*
    353                  * See if anything went wrong
    354                  */
    355                 if (status & (M360_BD_DEFER |
    356                                 M360_BD_HEARTBEAT |
    357                                 M360_BD_LATE_COLLISION |
     358                 * Check for errors which stop the transmitter.
     359                 */
     360                if (status & (M360_BD_LATE_COLLISION |
    358361                                M360_BD_RETRY_LIMIT |
    359                                 M360_BD_UNDERRUN |
    360                                 M360_BD_CARRIER_LOST)) {
    361                         /*
    362                          * Check for errors which stop the transmitter.
    363                          */
    364                         if (status & (M360_BD_LATE_COLLISION |
    365                                         M360_BD_RETRY_LIMIT |
    366                                         M360_BD_UNDERRUN)) {
    367                                 int j;
    368 
    369                                 if (status & M360_BD_LATE_COLLISION)
    370                                         scc_softc[0].txLateCollision++;
    371                                 if (status & M360_BD_RETRY_LIMIT)
    372                                         scc_softc[0].txRetryLimit++;
    373                                 if (status & M360_BD_UNDERRUN)
    374                                         scc_softc[0].txUnderrun++;
    375 
    376                                 /*
    377                                  * Reenable buffer descriptors
    378                                  */
    379                                 j = sc->txBdTail;
    380                                 for (;;) {
    381                                         status = (sc->txBdBase + j)->status;
    382                                         if (status & M360_BD_READY)
    383                                                 break;
    384                                         (sc->txBdBase + j)->status = M360_BD_READY |
    385                                                 (status & (M360_BD_PAD |
    386                                                            M360_BD_WRAP |
    387                                                            M360_BD_INTERRUPT |
    388                                                            M360_BD_LAST |
    389                                                            M360_BD_TX_CRC));
    390                                         if (status & M360_BD_LAST)
    391                                                 break;
    392                                         if (++j == sc->txBdCount)
    393                                                 j = 0;
    394                                 }
    395 
    396                                 /*
    397                                  * Move transmitter back to the first
    398                                  * buffer descriptor in the frame.
    399                                  */
    400                                 m360.scc1p._tbptr = m360.scc1p.tbase +
    401                                         sc->txBdTail * sizeof (m360BufferDescriptor_t);
    402 
    403                                 /*
    404                                  * Restart the transmitter
    405                                  */
    406                                 M360ExecuteRISC (M360_CR_OP_RESTART_TX | M360_CR_CHAN_SCC1);
    407                                 continue;
     362                                M360_BD_UNDERRUN)) {
     363                        int j;
     364
     365                        if (status & M360_BD_LATE_COLLISION)
     366                                sc->txLateCollision++;
     367                        if (status & M360_BD_RETRY_LIMIT)
     368                                sc->txRetryLimit++;
     369                        if (status & M360_BD_UNDERRUN)
     370                                sc->txUnderrun++;
     371
     372                        /*
     373                         * Reenable buffer descriptors
     374                         */
     375                        j = sc->txBdTail;
     376                        for (;;) {
     377                                status = (sc->txBdBase + j)->status;
     378                                if (status & M360_BD_READY)
     379                                        break;
     380                                (sc->txBdBase + j)->status = M360_BD_READY |
     381                                        (status & (M360_BD_PAD |
     382                                                   M360_BD_WRAP |
     383                                                   M360_BD_INTERRUPT |
     384                                                   M360_BD_LAST |
     385                                                   M360_BD_TX_CRC));
     386                                if (status & M360_BD_LAST)
     387                                        break;
     388                                if (++j == sc->txBdCount)
     389                                        j = 0;
    408390                        }
    409                         if (status & M360_BD_DEFER)
    410                                 scc_softc[0].txDeferred++;
    411                         if (status & M360_BD_HEARTBEAT)
    412                                 scc_softc[0].txHeartbeat++;
    413                         if (status & M360_BD_CARRIER_LOST)
    414                                 scc_softc[0].txLostCarrier++;
    415                 }
     391
     392                        /*
     393                         * Move transmitter back to the first
     394                         * buffer descriptor in the frame.
     395                         */
     396                        m360.scc1p._tbptr = m360.scc1p.tbase +
     397                                sc->txBdTail * sizeof (m360BufferDescriptor_t);
     398
     399                        /*
     400                         * Restart the transmitter
     401                         */
     402                        M360ExecuteRISC (M360_CR_OP_RESTART_TX | M360_CR_CHAN_SCC1);
     403                        continue;
     404                }
     405                saveStatus |= status;
     406                retries += (status >> 2) & 0xF;
    416407                nRetired++;
    417408                if (status & M360_BD_LAST) {
     
    420411                         * Free all the associated buffer descriptors.
    421412                         */
     413                        if (saveStatus & M360_BD_DEFER)
     414                                sc->txDeferred++;
     415                        if (saveStatus & M360_BD_HEARTBEAT)
     416                                sc->txHeartbeat++;
     417                        if (saveStatus & M360_BD_CARRIER_LOST)
     418                                sc->txLostCarrier++;
     419                        saveStatus = 0;
     420                        sc->txRetry += retries;
     421                        retries = 0;
    422422                        sc->txBdActiveCount -= nRetired;
    423423                        while (nRetired) {
     
    602602        while (m) {
    603603                /*
     604                 * There are more mbufs in the packet than there
     605                 * are transmit buffer descriptors.
     606                 * Coalesce into a single buffer.
     607                 */
     608                if (nAdded == sc->txBdCount) {
     609                        struct mbuf *nm;
     610                        int j;
     611                        char *dest;
     612
     613                        /*
     614                         * Get the pointer to the first mbuf of the packet
     615                         */
     616                        if (sc->txBdTail != sc->txBdHead)
     617                                rtems_panic ("sendpacket coalesce");
     618                        m = sc->txMbuf[sc->txBdTail];
     619
     620                        /*
     621                         * Rescind the buffer descriptor READY bits
     622                         */
     623                        for (j = 0 ; j < sc->txBdCount ; j++)
     624                                (sc->txBdBase + j)->status = 0;
     625
     626                        /*
     627                         * Allocate an mbuf cluster
     628                         * Toss the packet if allocation fails
     629                         */
     630                        MGETHDR (nm, M_DONTWAIT, MT_DATA);
     631                        if (nm == NULL) {
     632                                sc->txCoalesceFailed++;
     633                                m_freem (m);
     634                                return;
     635                        }
     636                        MCLGET (nm, M_DONTWAIT);
     637                        if (nm->m_ext.ext_buf == NULL) {
     638                                sc->txCoalesceFailed++;
     639                                m_freem (m);
     640                                m_free (nm);
     641                                return;
     642                        }
     643                        nm->m_pkthdr = m->m_pkthdr;
     644                        nm->m_len = nm->m_pkthdr.len;
     645
     646                        /*
     647                         * Copy data from packet chain to mbuf cluster
     648                         */
     649                        sc->txCoalesced++;
     650                        dest = nm->m_ext.ext_buf;
     651                        while (m) {
     652                                struct mbuf *n;
     653
     654                                if (m->m_len) {
     655                                        memcpy (dest, mtod(m, caddr_t), m->m_len);
     656                                        dest += m->m_len;
     657                                }
     658                                MFREE (m, n);
     659                                m = n;
     660                        }
     661                       
     662                        /*
     663                         * Redo the send with the new mbuf cluster
     664                         */
     665                        m = nm;
     666                        nAdded = 0;
     667                        status = 0;
     668                        continue;
     669                }
     670
     671                /*
    604672                 * Wait for buffer descriptor to become available.
    605673                 */
     
    816884        printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
    817885        printf ("           Underrun:%-8lu", sc->txUnderrun);
    818         printf (" Raw output wait:%-8lu\n", sc->txRawWait);
     886        printf (" Raw output wait:%-8lu", sc->txRawWait);
     887        printf ("       Coalesced:%-8lu\n", sc->txCoalesced);
     888        printf ("    Coalesce failed:%-8lu", sc->txCoalesceFailed);
     889        printf ("         Retries:%-8lu\n", sc->txRetry);
    819890}
    820891
Note: See TracChangeset for help on using the changeset viewer.