Changeset b5902b8 in rtems


Ignore:
Timestamp:
Feb 2, 2012, 7:06:51 PM (8 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10
Children:
c5ee0804
Parents:
1fe0257
Message:

PR 2011/networking - GRETH: performance improvements and one bugfix

GRETH driver updated, 10-15% performance improvements for GBIT MAC,
unnecessary RX interrupts not taken which under heavy load saves approx.
1500 interrupts/s, one task removed saving about 5kb memory and 1 bug
solved.

BUG: RX interrupt was enabled before the RX-daemon was created which could
result in a faulty call to rtems_event_send.

Signed-off-by: Daniel Hellstrom <daniel@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/libchip/network/greth.c

    r1fe0257 rb5902b8  
    8383#define GRETH_TX_WAIT_EVENT  RTEMS_EVENT_3
    8484
    85  /* suspend when all TX descriptors exhausted */
    86  /*
    87 #define GRETH_SUSPEND_NOTXBUF
    88  */
    89 
    9085#if (MCLBYTES < RBUF_SIZE)
    9186# error "Driver must have MCLBYTES > RBUF_SIZE"
     
    119114
    120115   int acceptBroadcast;
    121    rtems_id rxDaemonTid;
    122    rtems_id txDaemonTid;
     116   rtems_id daemonTid;
    123117
    124118   unsigned int tx_ptr;
     
    134128   rtems_vector_number vector;
    135129
     130   /* TX descriptor interrupt generation */
     131   int tx_int_gen;
     132   int tx_int_gen_cur;
     133   struct mbuf *next_tx_mbuf;
     134   int max_fragsize;
     135
    136136   /*Status*/
    137137   struct phy_device_info phydev;
     
    166166static struct greth_softc greth;
    167167
     168int greth_process_tx_gbit(struct greth_softc *sc);
     169int greth_process_tx(struct greth_softc *sc);
     170
    168171static char *almalloc(int sz)
    169172{
     
    176179/* GRETH interrupt handler */
    177180
    178 static rtems_isr
     181rtems_isr
    179182greth_interrupt_handler (rtems_vector_number v)
    180183{
    181184        uint32_t status;
     185        uint32_t ctrl;
     186        rtems_event_set events = 0;
     187
    182188        /* read and clear interrupt cause */
    183 
    184189        status = greth.regs->status;
    185190        greth.regs->status = status;
     191        ctrl = greth.regs->ctrl;
    186192
    187193        /* Frame received? */
    188         if (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ))
     194        if ((ctrl & GRETH_CTRL_RXIRQ) && (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ)))
    189195        {
    190196                greth.rxInterrupts++;
    191                 rtems_event_send (greth.rxDaemonTid, INTERRUPT_EVENT);
    192         }
    193 #ifdef GRETH_SUSPEND_NOTXBUF
    194         if (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ))
     197                /* Stop RX-Error and RX-Packet interrupts */
     198                ctrl &= ~GRETH_CTRL_RXIRQ;
     199                events |= INTERRUPT_EVENT;
     200        }
     201       
     202        if ( (ctrl & GRETH_CTRL_TXIRQ) && (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ)) )
    195203        {
    196204                greth.txInterrupts++;
    197                 rtems_event_send (greth.txDaemonTid, GRETH_TX_WAIT_EVENT);
    198         }
    199 #endif
    200         /*
    201           #ifdef __leon__
    202           LEON_Clear_interrupt(v-0x10);
    203           #endif
    204         */
     205                ctrl &= ~GRETH_CTRL_TXIRQ;
     206                events |= GRETH_TX_WAIT_EVENT;
     207        }
     208       
     209        /* Clear interrupt sources */
     210        greth.regs->ctrl = ctrl;
     211       
     212        /* Send the event(s) */
     213        if ( events )
     214            rtems_event_send (greth.daemonTid, events);
    205215}
    206216
     
    229239{
    230240        printf("greth: driver attached\n");
     241                if ( sc->auto_neg == -1 ){
     242                        printf("Auto negotiation timed out. Selecting default config\n");
     243                }
    231244        printf("**** PHY ****\n");
    232245        printf("Vendor: %x   Device: %x   Revision: %d\n",sc->phydev.vendor, sc->phydev.device, sc->phydev.rev);
     
    267280    unsigned int msecs;
    268281    struct timeval tstart, tnow;
    269     int anegtout;
    270282
    271283    greth_regs *regs;
     
    303315    sc->auto_neg = 0;
    304316    sc->auto_neg_time = 0;
    305     /* the anegtout variable is needed because print cannot be done before mac has
    306        been reconfigured due to a possible deadlock situation if rtems
    307        is run through the edcl with uart polling (-u)*/
    308     anegtout = 0;
    309317    if ((phyctrl >> 12) & 1) {
    310318            /*wait for auto negotiation to complete*/
     
    333341                    if ( msecs > GRETH_AUTONEGO_TIMEOUT_MS ){
    334342                            sc->auto_neg_time = msecs;
    335                             anegtout = 1
     343                            sc->auto_neg = -1; /* Failed */
    336344                            tmp1 = read_mii(phyaddr, 0);
    337345                            sc->gb = ((phyctrl >> 6) & 1) && !((phyctrl >> 13) & 1);
     
    382390
    383391    /*Read out PHY info if extended registers are available */
    384     if (phystatus & 1) {
     392    if (phystatus & 1) { 
    385393            tmp1 = read_mii(phyaddr, 2);
    386394            tmp2 = read_mii(phyaddr, 3);
     
    469477    regs->mac_addr_lsb = mac_addr_lsb;
    470478
     479    if ( sc->rxbufs < 10 ) {
     480        sc->tx_int_gen = sc->tx_int_gen_cur = 1;
     481    }else{
     482        sc->tx_int_gen = sc->tx_int_gen_cur = sc->txbufs/2;
     483    }
     484    sc->next_tx_mbuf = NULL;
     485   
     486    if ( !sc->gbit_mac )
     487        sc->max_fragsize = 1;
     488
     489    /* clear all pending interrupts */
     490    regs->status = 0xffffffff;
     491   
    471492    /* install interrupt vector */
    472493    set_vector(greth_interrupt_handler, sc->vector, 1);
    473494
    474     /* clear all pending interrupts */
    475 
    476     regs->status = 0xffffffff;
    477 
    478 #ifdef GRETH_SUSPEND_NOTXBUF
    479     regs->ctrl |= GRETH_CTRL_TXIRQ;
    480 #endif
    481 
    482495    regs->ctrl |= GRETH_CTRL_RXEN | (sc->fd << 4) | GRETH_CTRL_RXIRQ | (sc->sp << 7) | (sc->gb << 8);
    483    
    484     if (anegtout) {
    485             printk("Auto negotiation timed out. Selecting default config\n\r");
    486     }
    487    
     496
    488497    print_init_info(sc);
    489498}
    490499
    491 static void
    492 greth_rxDaemon (void *arg)
     500void
     501greth_Daemon (void *arg)
    493502{
    494503    struct ether_header *eh;
     
    498507    unsigned int len, len_status, bad;
    499508    rtems_event_set events;
     509    rtems_interrupt_level level;
     510    int first;
    500511
    501512    for (;;)
    502513      {
    503         rtems_bsdnet_event_receive (INTERRUPT_EVENT,
     514        rtems_bsdnet_event_receive (INTERRUPT_EVENT | GRETH_TX_WAIT_EVENT,
    504515                                    RTEMS_WAIT | RTEMS_EVENT_ANY,
    505516                                    RTEMS_NO_TIMEOUT, &events);
    506517
     518        if ( events & GRETH_TX_WAIT_EVENT ){
     519            /* TX interrupt.
     520             * We only end up here when all TX descriptors has been used,
     521             * and
     522             */
     523            if ( dp->gbit_mac )
     524                greth_process_tx_gbit(dp);
     525            else
     526                greth_process_tx(dp);
     527           
     528            /* If we didn't get a RX interrupt we don't process it */
     529            if ( (events & INTERRUPT_EVENT) == 0 )
     530                continue;
     531        }
     532
    507533#ifdef GRETH_ETH_DEBUG
    508534    printf ("r\n");
    509535#endif
     536    first=1;
     537    /* Scan for Received packets */
     538again:
    510539    while (!((len_status =
    511540                    dp->rxdesc[dp->rx_ptr].ctrl) & GRETH_RXD_ENABLE))
     
    575604                            dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
    576605                    }
     606                    rtems_interrupt_disable(level);
    577607                    dp->regs->ctrl |= GRETH_CTRL_RXEN;
     608                    rtems_interrupt_enable(level);
    578609                    dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
    579610            }
     611
     612        /* Always scan twice to avoid deadlock */
     613        if ( first ){
     614            first=0;
     615            rtems_interrupt_disable(level);
     616            dp->regs->ctrl |= GRETH_CTRL_RXIRQ;
     617            rtems_interrupt_enable(level);
     618            goto again;
     619        }
     620
    580621      }
    581622
     
    583624
    584625static int inside = 0;
    585 static void
     626static int
    586627sendpacket (struct ifnet *ifp, struct mbuf *m)
    587628{
     
    590631    struct mbuf *n;
    591632    unsigned int len;
     633    rtems_interrupt_level level;
    592634
    593635    /*printf("Send packet entered\n");*/
    594636    if (inside) printf ("error: sendpacket re-entered!!\n");
    595637    inside = 1;
     638
    596639    /*
    597      * Waiting for Transmitter ready
     640     * Is there a free descriptor available?
    598641     */
     642    if ( dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE ){
     643            /* No. */
     644            inside = 0;
     645            return 1;
     646    }
     647
     648    /* Remember head of chain */
    599649    n = m;
    600 
    601     while (dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE)
    602       {
    603 #ifdef GRETH_SUSPEND_NOTXBUF
    604         dp->txdesc[dp->tx_ptr].ctrl |= GRETH_TXD_IRQ;
    605         rtems_event_set events;
    606         rtems_bsdnet_event_receive (GRETH_TX_WAIT_EVENT,
    607                                     RTEMS_WAIT | RTEMS_EVENT_ANY,
    608                                     TOD_MILLISECONDS_TO_TICKS(500), &events);
    609 #endif
    610       }
    611650
    612651    len = 0;
     
    643682                            GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
    644683            }
     684            dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
     685            rtems_interrupt_disable(level);
    645686            dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
    646             dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
     687            rtems_interrupt_enable(level);
     688           
    647689    }
    648690    inside = 0;
    649 }
    650 
    651 
    652 static void
     691   
     692    return 0;
     693}
     694
     695
     696int
    653697sendpacket_gbit (struct ifnet *ifp, struct mbuf *m)
    654698{
    655699        struct greth_softc *dp = ifp->if_softc;
    656700        unsigned int len;
    657 
    658         /*printf("Send packet entered\n");*/
     701       
     702        unsigned int ctrl;
     703        int frags;
     704        struct mbuf *mtmp;
     705        int int_en;
     706        rtems_interrupt_level level;
     707
    659708        if (inside) printf ("error: sendpacket re-entered!!\n");
    660709        inside = 1;
    661         /*
    662          * Waiting for Transmitter ready
    663          */
    664710
    665711        len = 0;
     
    667713        printf("TXD: 0x%08x\n", (int) m->m_data);
    668714#endif
     715        /* Get number of fragments too see if we have enough
     716         * resources.
     717         */
     718        frags=1;
     719        mtmp=m;
     720        while(mtmp->m_next){
     721            frags++;
     722            mtmp = mtmp->m_next;
     723        }
     724       
     725        if ( frags > dp->max_fragsize )
     726            dp->max_fragsize = frags;
     727       
     728        if ( frags > dp->txbufs ){
     729            inside = 0;
     730            printf("GRETH: MBUF-chain cannot be sent. Increase descriptor count.\n");
     731            return -1;
     732        }
     733       
     734        if ( frags > (dp->txbufs-dp->tx_cnt) ){
     735            inside = 0;
     736            /* Return number of fragments */
     737            return frags;
     738        }
     739       
     740       
     741        /* Enable interrupt from descriptor every tx_int_gen
     742         * descriptor. Typically every 16 descriptor. This
     743         * is only to reduce the number of interrupts during
     744         * heavy load.
     745         */
     746        dp->tx_int_gen_cur-=frags;
     747        if ( dp->tx_int_gen_cur <= 0 ){
     748            dp->tx_int_gen_cur = dp->tx_int_gen;
     749            int_en = GRETH_TXD_IRQ;
     750        }else{
     751            int_en = 0;
     752        }
     753       
     754        /* At this stage we know that enough descriptors are available */
    669755        for (;;)
    670756        {
    671                 while (dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE)
    672                 {
    673 #ifdef GRETH_SUSPEND_NOTXBUF
    674                         dp->txdesc[dp->tx_ptr].ctrl |= GRETH_TXD_IRQ;
    675                         rtems_event_set events;
    676                         rtems_bsdnet_event_receive (GRETH_TX_WAIT_EVENT,
    677                                                     RTEMS_WAIT | RTEMS_EVENT_ANY,
    678                                                     TOD_MILLISECONDS_TO_TICKS(500), &events);
    679 #endif
    680                 }
     757               
    681758#ifdef GRETH_DEBUG
    682                 int i;
    683                 printf("MBUF: 0x%08x, Len: %d : ", (int) m->m_data, m->m_len);
    684                 for (i=0; i<m->m_len; i++)
    685                         printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
    686                 printf("\n");
     759            int i;
     760            printf("MBUF: 0x%08x, Len: %d : ", (int) m->m_data, m->m_len);
     761            for (i=0; i<m->m_len; i++)
     762                printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
     763            printf("\n");
    687764#endif
    688765            len += m->m_len;
    689766            dp->txdesc[dp->tx_ptr].addr = (uint32_t *)m->m_data;
     767
     768            /* Wrap around? */
    690769            if (dp->tx_ptr < dp->txbufs-1) {
    691                     if ((m->m_next) == NULL) {
    692                             dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | GRETH_TXD_CS | m->m_len;
    693                             break;
    694                     } else {
    695                             dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | GRETH_TXD_MORE | GRETH_TXD_CS | m->m_len;
    696                     }
    697             } else {
    698                     if ((m->m_next) == NULL) {
    699                             dp->txdesc[dp->tx_ptr].ctrl =
    700                                     GRETH_TXD_WRAP | GRETH_TXD_ENABLE | GRETH_TXD_CS | m->m_len;
    701                             break;
    702                     } else {
    703                             dp->txdesc[dp->tx_ptr].ctrl =
    704                                     GRETH_TXD_WRAP | GRETH_TXD_ENABLE | GRETH_TXD_MORE | GRETH_TXD_CS | m->m_len;
    705                     }
    706             }
     770                ctrl = GRETH_TXD_ENABLE | GRETH_TXD_CS;
     771            }else{
     772                ctrl = GRETH_TXD_ENABLE | GRETH_TXD_CS | GRETH_TXD_WRAP;
     773            }
     774
     775            /* Enable Descriptor */
     776            if ((m->m_next) == NULL) {
     777                dp->txdesc[dp->tx_ptr].ctrl = ctrl | int_en | m->m_len;
     778                break;
     779            }else{
     780                dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_MORE | ctrl | int_en | m->m_len;
     781            }
     782
     783            /* Next */
    707784            dp->txmbuf[dp->tx_ptr] = m;
    708785            dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
    709786            dp->tx_cnt++;
    710787            m = m->m_next;
    711 
    712     }
     788        }
    713789        dp->txmbuf[dp->tx_ptr] = m;
     790        dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
    714791        dp->tx_cnt++;
     792
     793        /* Tell Hardware about newly enabled descriptor */
     794        rtems_interrupt_disable(level);
    715795        dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
    716         dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
     796        rtems_interrupt_enable(level);
     797
    717798        inside = 0;
    718 }
    719 
    720 /*
    721  * Driver transmit daemon
    722  */
    723 void
    724 greth_txDaemon (void *arg)
    725 {
    726     struct greth_softc *sc = (struct greth_softc *) arg;
     799
     800        return 0;
     801}
     802
     803int greth_process_tx_gbit(struct greth_softc *sc)
     804{
    727805    struct ifnet *ifp = &sc->arpcom.ac_if;
    728806    struct mbuf *m;
    729     rtems_event_set events;
    730 
    731     for (;;)
    732     {
     807    rtems_interrupt_level level;
     808    int first=1;
     809
     810    /*
     811     * Send packets till queue is empty
     812     */
     813    for (;;){
     814        /* Reap Sent packets */
     815        while((sc->tx_cnt > 0) && !(sc->txdesc[sc->tx_dptr].ctrl) && !(sc->txdesc[sc->tx_dptr].ctrl & GRETH_TXD_ENABLE)) {
     816            m_free(sc->txmbuf[sc->tx_dptr]);
     817            sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;
     818            sc->tx_cnt--;
     819        }
     820
     821        if ( sc->next_tx_mbuf ){
     822            /* Get packet we tried but faild to transmit last time */
     823            m = sc->next_tx_mbuf;
     824            sc->next_tx_mbuf = NULL; /* Mark packet taken */
     825        }else{
    733826            /*
    734              * Wait for packet
     827             * Get the next mbuf chain to transmit from Stack.
    735828             */
    736 
    737             rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
    738                                         RTEMS_EVENT_ANY | RTEMS_WAIT,
    739                                         RTEMS_NO_TIMEOUT, &events);
    740 #ifdef GRETH_DEBUG
    741             printf ("t\n");
    742 #endif
    743 
    744             /*
    745              * Send packets till queue is empty
     829            IF_DEQUEUE (&ifp->if_snd, m);
     830            if (!m){
     831                /* Hardware has sent all schedule packets, this
     832                 * makes the stack enter at greth_start next time
     833                 * a packet is to be sent.
     834                 */
     835                ifp->if_flags &= ~IFF_OACTIVE;
     836                break;
     837            }
     838        }
     839
     840        /* Are there free descriptors available? */
     841        /* Try to send packet, if it a negative number is returned. */
     842        if ( (sc->tx_cnt >= sc->txbufs) || sendpacket_gbit(ifp, m) ){
     843            /* Not enough resources */
     844
     845            /* Since we have taken the mbuf out of the "send chain"
     846             * we must remember to use that next time we come back.
     847             * or else we have dropped a packet.
    746848             */
    747 
    748 
    749             for (;;)
    750             {
    751                     /*
    752                      * Get the next mbuf chain to transmit.
    753                      */
    754                     IF_DEQUEUE (&ifp->if_snd, m);
    755                     if (!m)
    756                             break;
    757                     sendpacket(ifp, m);
    758             }
    759             ifp->if_flags &= ~IFF_OACTIVE;
     849            sc->next_tx_mbuf = m;
     850
     851            /* Not enough resources, enable interrupt for transmissions
     852             * this way we will be informed when more TX-descriptors are
     853             * available.
     854             */
     855            if ( first ){
     856                first = 0;
     857                rtems_interrupt_disable(level);
     858                ifp->if_flags |= IFF_OACTIVE;
     859                sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
     860                rtems_interrupt_enable(level);
     861
     862                /* We must check again to be sure that we didn't
     863                 * miss an interrupt (if a packet was sent just before
     864                 * enabling interrupts)
     865                 */
     866                continue;
     867            }
     868
     869            return -1;
     870        }else{
     871            /* Sent Ok, proceed to process more packets if available */
     872        }
    760873    }
    761 }
    762 
    763 /*
    764  * Driver transmit daemon
    765  */
    766 void
    767 greth_txDaemon_gbit (void *arg)
    768 {
    769     struct greth_softc *sc = (struct greth_softc *) arg;
     874    return 0;
     875}
     876
     877int greth_process_tx(struct greth_softc *sc)
     878{
    770879    struct ifnet *ifp = &sc->arpcom.ac_if;
    771880    struct mbuf *m;
    772     rtems_event_set events;
    773 
    774     for (;;)
    775     {
     881    rtems_interrupt_level level;
     882    int first=1;
     883
     884    /*
     885     * Send packets till queue is empty
     886     */
     887    for (;;){
     888        if ( sc->next_tx_mbuf ){
     889            /* Get packet we tried but failed to transmit last time */
     890            m = sc->next_tx_mbuf;
     891            sc->next_tx_mbuf = NULL; /* Mark packet taken */
     892        }else{
    776893            /*
    777              * Wait for packet
     894             * Get the next mbuf chain to transmit from Stack.
    778895             */
    779 
    780             rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
    781                                         RTEMS_EVENT_ANY | RTEMS_WAIT,
    782                                         RTEMS_NO_TIMEOUT, &events);
    783 #ifdef GRETH_DEBUG
    784             printf ("t\n");
    785 #endif
    786 
    787             /*
    788              * Send packets till queue is empty
     896            IF_DEQUEUE (&ifp->if_snd, m);
     897            if (!m){
     898                /* Hardware has sent all schedule packets, this
     899                 * makes the stack enter at greth_start next time
     900                 * a packet is to be sent.
     901                 */
     902                ifp->if_flags &= ~IFF_OACTIVE;
     903                break;
     904            }
     905        }
     906
     907        /* Try to send packet, failed if it a non-zero number is returned. */
     908        if ( sendpacket(ifp, m) ){
     909            /* Not enough resources */
     910
     911            /* Since we have taken the mbuf out of the "send chain"
     912             * we must remember to use that next time we come back.
     913             * or else we have dropped a packet.
    789914             */
    790             for (;;)
    791             {
    792                     while((sc->tx_cnt > 0) && !(sc->txdesc[sc->tx_dptr].ctrl & GRETH_TXD_ENABLE)) {
    793                             m_free(sc->txmbuf[sc->tx_dptr]);
    794                             sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;
    795                             sc->tx_cnt--;
    796                     }
    797                     /*
    798                      * Get the next mbuf chain to transmit.
    799                      */
    800                     IF_DEQUEUE (&ifp->if_snd, m);
    801                     if (!m)
    802                             break;
    803                     sendpacket_gbit(ifp, m);
    804             }
    805             ifp->if_flags &= ~IFF_OACTIVE;
     915            sc->next_tx_mbuf = m;
     916
     917            /* Not enough resources, enable interrupt for transmissions
     918             * this way we will be informed when more TX-descriptors are
     919             * available.
     920             */
     921            if ( first ){
     922                first = 0;
     923                rtems_interrupt_disable(level);
     924                ifp->if_flags |= IFF_OACTIVE;
     925                sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
     926                rtems_interrupt_enable(level);
     927
     928                /* We must check again to be sure that we didn't
     929                 * miss an interrupt (if a packet was sent just before
     930                 * enabling interrupts)
     931                 */
     932                continue;
     933            }
     934
     935            return -1;
     936        }else{
     937            /* Sent Ok, proceed to process more packets if available */
     938        }
    806939    }
    807 }
    808 
     940    return 0;
     941}
    809942
    810943static void
     
    813946    struct greth_softc *sc = ifp->if_softc;
    814947
    815     ifp->if_flags |= IFF_OACTIVE;
    816     rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
    817 
     948    if ( ifp->if_flags & IFF_OACTIVE )
     949            return;
     950
     951    if ( sc->gbit_mac ){
     952        /* No use trying to handle this if we are waiting on GRETH
     953         * to send the previously scheduled packets.
     954         */
     955
     956        greth_process_tx_gbit(sc);
     957    }else{
     958        greth_process_tx(sc);
     959    }
    818960}
    819961
     
    827969    struct ifnet *ifp = &sc->arpcom.ac_if;
    828970
    829     if (sc->txDaemonTid == 0)
    830       {
    831 
    832           /*
    833            * Set up GRETH hardware
    834            */
    835           greth_initialize_hardware (sc);
    836 
    837           /*
    838            * Start driver tasks
    839            */
    840           sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
    841                                                   greth_rxDaemon, sc);
    842           if (sc->gbit_mac) {
    843                   sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
    844                                                           greth_txDaemon_gbit, sc);
    845           } else {
    846                   sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
    847                                                           greth_txDaemon, sc);
    848           }
    849 
    850       }
     971    if (sc->daemonTid == 0) {
     972
     973        /*
     974         * Start driver tasks
     975         */
     976        sc->daemonTid = rtems_bsdnet_newproc ("DCrxtx", 4096,
     977                                              greth_Daemon, sc);
     978
     979        /*
     980         * Set up GRETH hardware
     981         */
     982        greth_initialize_hardware (sc);
     983
     984    }
    851985
    852986    /*
     
    854988     */
    855989    ifp->if_flags |= IFF_RUNNING;
    856 
    857990}
    858991
     
    8701003    sc->regs->ctrl = GRETH_CTRL_RST;    /* Reset ON */
    8711004    sc->regs->ctrl = 0;                 /* Reset OFF */
     1005   
     1006    sc->next_tx_mbuf = NULL;
    8721007}
    8731008
     
    8861021  printf ("         Overrun:%-8lu", sc->rxOverrun);
    8871022  printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
     1023  printf ("      Maximal Frags:%-8d", sc->max_fragsize);
     1024  printf ("      GBIT MAC:%-8d", sc->gbit_mac);
    8881025}
    8891026
Note: See TracChangeset for help on using the changeset viewer.