Changeset 050249d in rtems


Ignore:
Timestamp:
Sep 7, 2007, 3:01:15 PM (12 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
e422da8
Parents:
13279f5d
Message:

2007-09-07 Daniel Hellstrom <daniel@…>

  • libchip/network/greth.c, libchip/network/greth.h: GRETH_GBIT support and GBIT PHY support for 10/100 MAC, also auto negotiation updated.
Location:
c/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/ChangeLog

    r13279f5d r050249d  
     12007-09-07      Daniel Hellstrom <daniel@gaisler.com>
     2
     3        * libchip/network/greth.c, libchip/network/greth.h: GRETH_GBIT support
     4        and GBIT PHY support for 10/100 MAC, also auto negotiation updated.
     5
    162007-08-02      Joel Sherrill <joel.sherrill@OARcorp.com>
    27
  • c/src/libchip/network/greth.c

    r13279f5d r050249d  
    11/*
    2  *  RTEMS driver for Opencores Ethernet Controller
    3  *
    4  *  Weakly based on dec21140 rtems driver and open_eth linux driver
    5  *  Written by Jiri Gaisler, Gaisler Research
     2 * Gaisler Research ethernet MAC driver
     3 * adapted from Opencores driver by Marko Isomaki
    64 *
    75 *  The license and distribution terms for this file may be
     
    108 *
    119 *  $Id$
     10 *
     11 * 2007-09-07, Ported GBIT support from 4.6.5
    1212 */
    1313
     
    1919#include <inttypes.h>
    2020#include <errno.h>
     21#include <rtems/bspIo.h>
    2122#include <stdlib.h>
    2223#include <stdio.h>
     
    4849#endif
    4950
    50 /*
    51 #define GRETH_DEBUG
    52 */
     51
     52/* #define GRETH_DEBUG */
    5353
    5454#ifdef CPU_U32_FIX
     
    9191# error "Driver must have MCLBYTES > RBUF_SIZE"
    9292#endif
     93
     94/* 4s Autonegotiation Timeout */
     95#ifndef GRETH_AUTONEGO_TIMEOUT_MS
     96#define GRETH_AUTONEGO_TIMEOUT_MS 4000
     97#endif
     98
     99/* For optimizing the autonegotiation time */
     100#define GRETH_AUTONEGO_PRINT_TIME
    93101
    94102/* Ethernet buffer descriptor */
     
    98106   uint32_t *addr;         /* Buffer pointer */
    99107} greth_rxtxdesc;
     108
    100109
    101110/*
     
    114123   
    115124   unsigned int tx_ptr;
     125   unsigned int tx_dptr;
     126   unsigned int tx_cnt;
    116127   unsigned int rx_ptr;
    117128   unsigned int txbufs;
     
    120131   greth_rxtxdesc *rxdesc;
    121132   struct mbuf **rxmbuf;
     133   struct mbuf **txmbuf;
    122134   rtems_vector_number vector;
    123    
     135   
     136   /*Status*/
     137   struct phy_device_info phydev;
     138   int fd;
     139   int sp;
     140   int gb;
     141   int gbit_mac;
     142   int auto_neg;
     143   unsigned int auto_neg_time;
     144   
    124145   /*
    125146    * Statistics
     
    140161   unsigned long txRetryLimit;
    141162   unsigned long txUnderrun;
     163
    142164};
    143165
     
    157179greth_interrupt_handler (rtems_vector_number v)
    158180{
    159     uint32_t status;
    160     /* read and clear interrupt cause */
    161 
    162     status = greth.regs->status;
    163     greth.regs->status = status;
    164 
    165     /* Frame received? */
    166     if (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ))
    167       {
    168         greth.rxInterrupts++;
    169         rtems_event_send (greth.rxDaemonTid, INTERRUPT_EVENT);
    170       }
     181        uint32_t status;
     182        /* read and clear interrupt cause */
     183       
     184        status = greth.regs->status;
     185        greth.regs->status = status;
     186       
     187        /* Frame received? */
     188        if (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ))
     189        {
     190                greth.rxInterrupts++;
     191                rtems_event_send (greth.rxDaemonTid, INTERRUPT_EVENT);
     192        }
    171193#ifdef GRETH_SUSPEND_NOTXBUF
    172     if (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ))
    173       {
    174         greth.txInterrupts++;
    175         rtems_event_send (greth.txDaemonTid, GRETH_TX_WAIT_EVENT);
    176       }
    177 #endif
    178       /*
    179 #ifdef __leon__
    180       LEON_Clear_interrupt(v-0x10);
    181 #endif
    182       */
    183 }
    184 
    185 static uint32_t read_mii(uint32_t addr)
     194        if (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ))
     195        {
     196                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}
     206
     207static uint32_t read_mii(uint32_t phy_addr, uint32_t reg_addr)
    186208{
    187209    while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
    188     greth.regs->mdio_ctrl = addr << 6 | GRETH_MDIO_READ;
     210    greth.regs->mdio_ctrl = (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_READ;
    189211    while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
    190212    if (!(greth.regs->mdio_ctrl & GRETH_MDIO_LINKFAIL))
     
    196218}
    197219
    198 static void write_mii(uint32_t addr, uint32_t data)
     220static void write_mii(uint32_t phy_addr, uint32_t reg_addr, uint32_t data)
    199221{
    200222    while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
    201     greth.regs->mdio_ctrl = 
    202     ((data & 0xFFFF) << 16) | (addr << 8) | GRETH_MDIO_WRITE;
     223    greth.regs->mdio_ctrl =
     224     ((data & 0xFFFF) << 16) | (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_WRITE;
    203225    while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
    204226}
     227
     228static void print_init_info(struct greth_softc *sc)
     229{
     230        printf("greth: driver attached\n");
     231        printf("**** PHY ****\n");
     232        printf("Vendor: %x   Device: %x   Revision: %d\n",sc->phydev.vendor, sc->phydev.device, sc->phydev.rev);
     233        printf("Current Operating Mode: ");
     234        if (sc->gb) {
     235                printf("1000 Mbit ");
     236        } else if (sc->sp) {
     237                printf("100 Mbit ");
     238        } else {
     239                printf("10 Mbit ");
     240        }
     241        if (sc->fd) {
     242                printf("Full Duplex\n");
     243        } else {
     244                printf("Half Duplex\n");
     245        }
     246#ifdef GRETH_AUTONEGO_PRINT_TIME
     247        if ( sc->auto_neg ){
     248          printf("Autonegotiation Time: %dms\n",sc->auto_neg_time);
     249        }
     250#endif
     251}
     252
     253
    205254/*
    206255 * Initialize the ethernet hardware
     
    211260    struct mbuf *m;
    212261    int i;
    213     int fd;
    214    
     262    int phyaddr;
     263    int phyctrl;
     264    int phystatus;
     265    int tmp1;
     266    int tmp2;
     267    unsigned int msecs;
     268    rtems_clock_time_value tstart, tnow;
     269
    215270    greth_regs *regs;
    216271
    217272    regs = sc->regs;
    218 
     273   
    219274    /* Reset the controller.  */
    220275    greth.rxInterrupts = 0;
     
    225280    regs->ctrl = 0;                     /* Reset OFF */
    226281   
    227     /* reset PHY and wait for complettion */
    228     /*
    229     */
    230     write_mii(0, 0x8000);
    231     while (read_mii(0) & 0x8000) {}
    232     fd = regs->mdio_ctrl >> 24; /*duplex mode*/
    233     printf(
    234       "greth: driver attached, PHY config: 0x%04" PRIx32 "\n", read_mii(0));
     282    /* Check if mac is gbit capable*/
     283    sc->gbit_mac = (regs->ctrl >> 27) & 1; 
     284   
     285    /* Get the phy address which assumed to have been set
     286       correctly with the reset value in hardware*/
     287    phyaddr = (regs->mdio_ctrl >> 11) & 0x1F;
     288
     289    /* get phy control register default values */
     290    while ((phyctrl = read_mii(phyaddr, 0)) & 0x8000) {}
     291   
     292    /* reset PHY and wait for completion */
     293    write_mii(phyaddr, 0, 0x8000 | phyctrl);
     294
     295    while ((read_mii(phyaddr, 0)) & 0x8000) {}
     296   
     297    /* Check if PHY is autoneg capable and then determine operating mode,
     298       otherwise force it to 10 Mbit halfduplex */
     299    sc->gb = 0;
     300    sc->fd = 0;
     301    sc->sp = 0;
     302    sc->auto_neg = 0;
     303    sc->auto_neg_time = 0;
     304    if ((phyctrl >> 12) & 1) {
     305            /*wait for auto negotiation to complete*/
     306            msecs = 0;
     307            sc->auto_neg = 1;
     308            if ( rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&tstart) == RTEMS_NOT_DEFINED){
     309                /* Not inited, set to epoch */
     310                rtems_time_of_day time;
     311                time.year   = 1988;
     312                time.month  = 1;
     313                time.day    = 1;
     314                time.hour   = 0;
     315                time.minute = 0;
     316                time.second = 0;
     317                time.ticks  = 0;
     318                rtems_clock_set(&time);
     319
     320                tstart.seconds = 0;
     321                tstart.microseconds = 0;
     322                rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&tstart);
     323            }
     324            while (!(((phystatus = read_mii(phyaddr, 1)) >> 5) & 1)) {
     325                    if ( rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&tnow) != RTEMS_SUCCESSFUL )
     326                      printk("rtems_clock_get failed\n\r");
     327                    msecs = (tnow.seconds-tstart.seconds)*1000+(tnow.microseconds-tstart.microseconds)/1000;
     328                    if ( msecs > GRETH_AUTONEGO_TIMEOUT_MS ){
     329                            sc->auto_neg_time = msecs;
     330                            printk("Auto negotiation timed out. Selecting default config\n\r");
     331                            tmp1 = read_mii(phyaddr, 0);
     332                            sc->gb = ((phyctrl >> 6) & 1) && !((phyctrl >> 13) & 1);
     333                            sc->sp = !((phyctrl >> 6) & 1) && ((phyctrl >> 13) & 1);
     334                            sc->fd = (phyctrl >> 8) & 1;
     335                            goto auto_neg_done;
     336                    }
     337            }
     338            sc->auto_neg_time = msecs;
     339            sc->phydev.adv = read_mii(phyaddr, 4);
     340            sc->phydev.part = read_mii(phyaddr, 5);
     341            if ((phystatus >> 8) & 1) {
     342                    sc->phydev.extadv = read_mii(phyaddr, 9);
     343                    sc->phydev.extpart = read_mii(phyaddr, 10);
     344                       if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000FD) &&
     345                            (sc->phydev.extpart & GRETH_MII_EXTPRT_1000FD)) {
     346                               sc->gb = 1;
     347                               sc->fd = 1;
     348                       }
     349                       if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000HD) &&
     350                            (sc->phydev.extpart & GRETH_MII_EXTPRT_1000HD)) {
     351                               sc->gb = 1;
     352                               sc->fd = 0;
     353                       }
     354            }
     355            if ((sc->gb == 0) || ((sc->gb == 1) && (sc->gbit_mac == 0))) {
     356                    if ( (sc->phydev.adv & GRETH_MII_100TXFD) &&
     357                         (sc->phydev.part & GRETH_MII_100TXFD)) {
     358                            sc->sp = 1;
     359                            sc->fd = 1;
     360                    }
     361                    if ( (sc->phydev.adv & GRETH_MII_100TXHD) &&
     362                         (sc->phydev.part & GRETH_MII_100TXHD)) {
     363                            sc->sp = 1;
     364                            sc->fd = 0;
     365                    }
     366                    if ( (sc->phydev.adv & GRETH_MII_10FD) &&
     367                         (sc->phydev.part & GRETH_MII_10FD)) {
     368                            sc->fd = 1;
     369                    }
     370            }
     371    }
     372auto_neg_done:
     373    sc->phydev.vendor = 0;
     374    sc->phydev.device = 0;
     375    sc->phydev.rev = 0;
     376    phystatus = read_mii(phyaddr, 1);
     377   
     378    /*Read out PHY info if extended registers are available */
     379    if (phystatus & 1) { 
     380            tmp1 = read_mii(phyaddr, 2);
     381            tmp2 = read_mii(phyaddr, 3);
     382
     383            sc->phydev.vendor = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
     384            sc->phydev.rev = tmp2 & 0xF;
     385            sc->phydev.device = (tmp2 >> 4) & 0x3F;
     386    }
     387
     388    /* Force to 10 mbit half duplex if the 10/100 MAC is used with a 1000 PHY*/
     389    /*check if marvell 88EE1111 PHY. Needs special reset handling */
     390    if ((phystatus & 1) && (sc->phydev.vendor == 0x005043) && (sc->phydev.device == 0x0C)) {
     391            if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {
     392                    write_mii(phyaddr, 0, sc->sp << 13);
     393                    write_mii(phyaddr, 0, 0x8000);
     394                    sc->gb = 0;
     395                    sc->sp = 0;
     396                    sc->fd = 0;
     397            }
     398    } else {
     399            if (((sc->gb) && !(sc->gbit_mac))  || !((phyctrl >> 12) & 1)) {
     400                    write_mii(phyaddr, 0, sc->sp << 13);
     401                    sc->gb = 0;
     402                    sc->sp = 0;
     403                    sc->fd = 0;
     404            }
     405    }
     406    while ((read_mii(phyaddr, 0)) & 0x8000) {}
     407
     408    regs->ctrl = 0;
     409    regs->ctrl = GRETH_CTRL_RST;        /* Reset ON */
     410    regs->ctrl = 0;
    235411
    236412    /* Initialize rx/tx descriptor pointers */
     
    238414    sc->rxdesc = (greth_rxtxdesc *) almalloc(1024);
    239415    sc->tx_ptr = 0;
     416    sc->tx_dptr = 0;
     417    sc->tx_cnt = 0;
    240418    sc->rx_ptr = 0;
    241419    regs->txdesc = (int) sc->txdesc;
     
    243421   
    244422    sc->rxmbuf = calloc(sc->rxbufs, sizeof(*sc->rxmbuf));
     423    sc->txmbuf = calloc(sc->txbufs, sizeof(*sc->txmbuf));
    245424
    246425    for (i = 0; i < sc->txbufs; i++)
    247426      {
    248           sc->txdesc[i].addr = (uint32_t *) calloc(1, GRETH_MAXBUF_LEN);
     427              sc->txdesc[i].ctrl = 0;
     428              if (!(sc->gbit_mac)) {
     429                      sc->txdesc[i].addr = malloc(GRETH_MAXBUF_LEN);
     430              }
    249431#ifdef GRETH_DEBUG
    250           printf("TXBUF: %08x\n", (int) sc->txdesc[i].addr);
     432              /* printf("TXBUF: %08x\n", (int) sc->txdesc[i].addr); */
    251433#endif
    252434      }
    253     /*printf("RXbufs: %i\n", sc->rxbufs);*/
    254435    for (i = 0; i < sc->rxbufs; i++)
    255436      {
     
    257438          MGETHDR (m, M_WAIT, MT_DATA);
    258439          MCLGET (m, M_WAIT);
     440          if (sc->gbit_mac)
     441                  m->m_data += 2;
    259442          m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
    260443          sc->rxmbuf[i] = m;
     
    262445          sc->rxdesc[i].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
    263446#ifdef GRETH_DEBUG
    264           printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr);
     447/*        printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr); */
    265448#endif
    266449      }
     
    285468#endif
    286469
    287     regs->ctrl |= GRETH_CTRL_RXEN | (fd << 4) | GRETH_CTRL_RXIRQ;
     470    regs->ctrl |= GRETH_CTRL_RXEN | (sc->fd << 4) | GRETH_CTRL_RXIRQ | (sc->sp << 7) | (sc->gb << 8);
     471
     472    print_init_info(sc);
    288473}
    289474
     
    298483    rtems_event_set events;
    299484   
    300     /*printf("Started RxDaemon\n");*/
    301485    for (;;)
    302486      {
     
    308492    printf ("r\n");
    309493#endif
    310     /*printf("Packet received\n");*/
    311             while (!((len_status =
    312                    dp->rxdesc[dp->rx_ptr].ctrl) & GRETH_RXD_ENABLE))
     494    while (!((len_status =
     495                    dp->rxdesc[dp->rx_ptr].ctrl) & GRETH_RXD_ENABLE))
    313496            {
    314               /*printf("Status: %x\n", dp->rxdesc[dp->rx_ptr].ctrl);*/
    315                 bad = 0;
    316 
    317                 if (len_status & GRETH_RXD_TOOLONG)
    318                   {
    319                       dp->rxLengthError++;
    320                       bad = 1;
    321                   }
    322                 if (len_status & GRETH_RXD_DRIBBLE)
    323                   {
    324                       dp->rxNonOctet++;
    325                       bad = 1;
    326                   }
    327                 if (len_status & GRETH_RXD_CRCERR)
    328                   {
    329                       dp->rxBadCRC++;
    330                       bad = 1;
    331                   }
    332                 if (len_status & GRETH_RXD_OVERRUN)
    333                   {
    334                       dp->rxOverrun++;
    335                       bad = 1;
    336                   }
    337                 if (!bad)
    338                   {
    339                     /*printf("Received Ok packet\n");*/
    340                       /* pass on the packet in the receive buffer */
    341                     len = len_status & 0x7FF;
    342                     m = dp->rxmbuf[dp->rx_ptr];
    343                     m->m_len = m->m_pkthdr.len =
    344                       len - sizeof (struct ether_header);
    345                     /*printf("Packet of length: %i\n", len);*/
    346                     eh = mtod (m, struct ether_header *);
    347                     m->m_data += sizeof (struct ether_header);
    348                     /*printf("Mbuf handling done\n");*/
     497                    bad = 0;
     498                    if (len_status & GRETH_RXD_TOOLONG)
     499                    {
     500                            dp->rxLengthError++;
     501                            bad = 1;
     502                    }
     503                    if (len_status & GRETH_RXD_DRIBBLE)
     504                    {
     505                            dp->rxNonOctet++;
     506                            bad = 1;
     507                    }
     508                    if (len_status & GRETH_RXD_CRCERR)
     509                    {
     510                            dp->rxBadCRC++;
     511                            bad = 1;
     512                    }
     513                    if (len_status & GRETH_RXD_OVERRUN)
     514                    {
     515                            dp->rxOverrun++;
     516                            bad = 1;
     517                    }
     518                    if (len_status & GRETH_RXD_LENERR)
     519                    {
     520                            dp->rxLengthError++;
     521                            bad = 1;
     522                    }
     523                    if (!bad)
     524                    {
     525                            /* pass on the packet in the receive buffer */
     526                            len = len_status & 0x7FF;
     527                            m = dp->rxmbuf[dp->rx_ptr];
     528#ifdef GRETH_DEBUG
     529                            int i;
     530                            printf("RX: 0x%08x, Len: %d : ", (int) m->m_data, len);
     531                            for (i=0; i<len; i++)
     532                                    printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
     533                            printf("\n");
     534#endif
     535                            m->m_len = m->m_pkthdr.len =
     536                                    len - sizeof (struct ether_header);
     537
     538                            eh = mtod (m, struct ether_header *);
     539                            m->m_data += sizeof (struct ether_header);
    349540#ifdef CPU_U32_FIX
    350                     /*printf("Ip aligning\n");*/
    351                     ipalign(m); /* Align packet on 32-bit boundary */
    352 #endif
    353                     /*printf("Calling stack\n");*/
    354                     /*printf("Ifp: %x, Eh: %x, M: %x\n", (int)ifp, (int)eh, (int)m);*/
    355                     ether_input (ifp, eh, m);
    356                     /*printf("Returned from stack\n");*/
    357                     /* get a new mbuf */
    358                     /*printf("Getting new mbuf\n");*/
    359                     MGETHDR (m, M_WAIT, MT_DATA);
    360                     MCLGET (m, M_WAIT);
    361                     /*printf("Got new mbuf\n");*/
    362                     dp->rxmbuf[dp->rx_ptr] = m;
    363                     m->m_pkthdr.rcvif = ifp;
    364                     dp->rxdesc[dp->rx_ptr].addr =
    365                       (uint32_t *) mtod (m, uint32_t *);
    366                     dp->rxPackets++;
    367                   }
    368                 /*printf("Reenabling desc\n");*/
    369                 dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
    370                 if (dp->rx_ptr == dp->rxbufs - 1) {
    371                   dp->rxdesc[dp->rx_ptr].ctrl |= GRETH_RXD_WRAP;
    372                 }
    373                 dp->regs->ctrl |= GRETH_CTRL_RXEN;
    374                 /*printf("rxptr: %i\n", dp->rx_ptr);*/
    375                 dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
    376                 /*printf("RxDesc reenabled\n");*/
     541                            if(!(dp->gbit_mac))
     542                                    ipalign(m); /* Align packet on 32-bit boundary */
     543#endif
     544
     545                            ether_input (ifp, eh, m);
     546                            MGETHDR (m, M_WAIT, MT_DATA);
     547                            MCLGET (m, M_WAIT);
     548                            if (dp->gbit_mac)
     549                                    m->m_data += 2;
     550                            dp->rxmbuf[dp->rx_ptr] = m;
     551                            m->m_pkthdr.rcvif = ifp;
     552                            dp->rxdesc[dp->rx_ptr].addr =
     553                                    (uint32_t *) mtod (m, uint32_t *);
     554                            dp->rxPackets++;
     555                    }
     556                    if (dp->rx_ptr == dp->rxbufs - 1) {
     557                            dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ | GRETH_RXD_WRAP;
     558                    } else {
     559                            dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
     560                    }
     561                    dp->regs->ctrl |= GRETH_CTRL_RXEN;
     562                    dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
    377563            }
    378564      }
     
    411597    temp = (unsigned char *) dp->txdesc[dp->tx_ptr].addr;
    412598#ifdef GRETH_DEBUG
    413     printf("TXD: 0x%08x\n", (int) m->m_data);
     599    printf("TXD: 0x%08x : BUF: 0x%08x\n", (int) m->m_data, (int) temp);
    414600#endif
    415601    for (;;)
    416         {
     602    {
    417603#ifdef GRETH_DEBUG
    418           int i;
    419           printf("MBUF: 0x%08x : ", (int) m->m_data);
    420           for (i=0;i<m->m_len;i++)
    421             printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
    422           printf("\n");
    423 #endif
    424           len += m->m_len;
    425           if (len <= RBUF_SIZE)
    426             memcpy ((void *) temp, (char *) m->m_data, m->m_len);
    427           temp += m->m_len;
    428           if ((m = m->m_next) == NULL)
    429               break;
    430         }
    431 
     604            int i;
     605            printf("MBUF: 0x%08x : ", (int) m->m_data);
     606            for (i=0;i<m->m_len;i++)
     607                    printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
     608            printf("\n");
     609#endif
     610            len += m->m_len;
     611            if (len <= RBUF_SIZE)
     612                    memcpy ((void *) temp, (char *) m->m_data, m->m_len);
     613            temp += m->m_len;
     614            if ((m = m->m_next) == NULL)
     615                    break;
     616    }
     617   
    432618    m_freem (n);
    433 
     619   
    434620    /* don't send long packets */
    435621
    436622    if (len <= GRETH_MAXBUF_LEN) {
    437       if (dp->tx_ptr < dp->txbufs-1) {
    438         dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | len;
    439       } else {
    440         dp->txdesc[dp->tx_ptr].ctrl =
    441           GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
    442       }
    443       dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
    444       dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
     623            if (dp->tx_ptr < dp->txbufs-1) {
     624                    dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | len;
     625            } else {
     626                    dp->txdesc[dp->tx_ptr].ctrl =
     627                            GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
     628            }
     629            dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
     630            dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
    445631    }
    446632    inside = 0;
     633}
     634
     635
     636static void
     637sendpacket_gbit (struct ifnet *ifp, struct mbuf *m)
     638{
     639        struct greth_softc *dp = ifp->if_softc;
     640        unsigned int len;
     641
     642        /*printf("Send packet entered\n");*/
     643        if (inside) printf ("error: sendpacket re-entered!!\n");
     644        inside = 1;
     645        /*
     646         * Waiting for Transmitter ready
     647         */
     648       
     649        len = 0;
     650#ifdef GRETH_DEBUG
     651        printf("TXD: 0x%08x\n", (int) m->m_data);
     652#endif
     653        for (;;)
     654        {
     655                while (dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE)
     656                {
     657#ifdef GRETH_SUSPEND_NOTXBUF
     658                        dp->txdesc[dp->tx_ptr].ctrl |= GRETH_TXD_IRQ;
     659                        rtems_event_set events;
     660                        rtems_bsdnet_event_receive (GRETH_TX_WAIT_EVENT,
     661                                                    RTEMS_WAIT | RTEMS_EVENT_ANY,
     662                                                    TOD_MILLISECONDS_TO_TICKS(500), &events);
     663#endif
     664                }
     665#ifdef GRETH_DEBUG
     666                int i;
     667                printf("MBUF: 0x%08x, Len: %d : ", (int) m->m_data, m->m_len);
     668                for (i=0; i<m->m_len; i++)
     669                        printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
     670                printf("\n");
     671#endif
     672            len += m->m_len;
     673            dp->txdesc[dp->tx_ptr].addr = (uint32_t *)m->m_data;
     674            if (dp->tx_ptr < dp->txbufs-1) {
     675                    if ((m->m_next) == NULL) {
     676                            dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | GRETH_TXD_CS | m->m_len;
     677                            break;
     678                    } else {
     679                            dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | GRETH_TXD_MORE | GRETH_TXD_CS | m->m_len;
     680                    }
     681            } else {
     682                    if ((m->m_next) == NULL) {
     683                            dp->txdesc[dp->tx_ptr].ctrl =
     684                                    GRETH_TXD_WRAP | GRETH_TXD_ENABLE | GRETH_TXD_CS | m->m_len;
     685                            break;
     686                    } else {
     687                            dp->txdesc[dp->tx_ptr].ctrl =
     688                                    GRETH_TXD_WRAP | GRETH_TXD_ENABLE | GRETH_TXD_MORE | GRETH_TXD_CS | m->m_len;
     689                    }
     690            }
     691            dp->txmbuf[dp->tx_ptr] = m;
     692            dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
     693            dp->tx_cnt++;
     694            m = m->m_next;
     695           
     696    }
     697        dp->txmbuf[dp->tx_ptr] = m;
     698        dp->tx_cnt++;
     699        dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
     700        dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
     701        inside = 0;
    447702}
    448703
     
    459714   
    460715    for (;;)
    461       {
    462           /*
    463            * Wait for packet
    464            */
    465 
    466         rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
    467                                       RTEMS_EVENT_ANY | RTEMS_WAIT,
    468                                       RTEMS_NO_TIMEOUT, &events);
     716    {
     717            /*
     718             * Wait for packet
     719             */
     720           
     721            rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
     722                                        RTEMS_EVENT_ANY | RTEMS_WAIT,
     723                                        RTEMS_NO_TIMEOUT, &events);
    469724#ifdef GRETH_DEBUG
    470     printf ("t\n");
    471 #endif
    472 
    473           /*
    474            * Send packets till queue is empty
    475            */
    476           for (;;)
     725            printf ("t\n");
     726#endif
     727           
     728            /*
     729             * Send packets till queue is empty
     730             */
     731           
     732           
     733            for (;;)
    477734            {
    478                 /*
    479                  * Get the next mbuf chain to transmit.
    480                  */
    481                 IF_DEQUEUE (&ifp->if_snd, m);
    482                 if (!m)
    483                     break;
    484                
    485                 sendpacket (ifp, m);
    486             }
    487           ifp->if_flags &= ~IFF_OACTIVE;
    488       }
     735                    /*
     736                     * Get the next mbuf chain to transmit.
     737                     */
     738                    IF_DEQUEUE (&ifp->if_snd, m);
     739                    if (!m)
     740                            break;
     741                    sendpacket(ifp, m);
     742            }
     743            ifp->if_flags &= ~IFF_OACTIVE;
     744    }
     745}
     746
     747/*
     748 * Driver transmit daemon
     749 */
     750void
     751greth_txDaemon_gbit (void *arg)
     752{
     753    struct greth_softc *sc = (struct greth_softc *) arg;
     754    struct ifnet *ifp = &sc->arpcom.ac_if;
     755    struct mbuf *m;
     756    rtems_event_set events;
     757   
     758    for (;;)
     759    {
     760            /*
     761             * Wait for packet
     762             */
     763           
     764            rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
     765                                        RTEMS_EVENT_ANY | RTEMS_WAIT,
     766                                        RTEMS_NO_TIMEOUT, &events);
     767#ifdef GRETH_DEBUG
     768            printf ("t\n");
     769#endif
     770           
     771            /*
     772             * Send packets till queue is empty
     773             */
     774            for (;;)
     775            {
     776                    while((sc->tx_cnt > 0) && !(sc->txdesc[sc->tx_dptr].ctrl & GRETH_TXD_ENABLE)) {
     777                            m_free(sc->txmbuf[sc->tx_dptr]);
     778                            sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;
     779                            sc->tx_cnt--;
     780                    }
     781                    /*
     782                     * Get the next mbuf chain to transmit.
     783                     */
     784                    IF_DEQUEUE (&ifp->if_snd, m);
     785                    if (!m)
     786                            break;
     787                    sendpacket_gbit(ifp, m);
     788            }
     789            ifp->if_flags &= ~IFF_OACTIVE;
     790    }
    489791}
    490792
     
    522824          sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
    523825                                                  greth_rxDaemon, sc);
    524           sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
    525                                                   greth_txDaemon, sc);
     826          if (sc->gbit_mac) {
     827                  sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
     828                                                          greth_txDaemon_gbit, sc);
     829          } else {
     830                  sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
     831                                                          greth_txDaemon, sc);
     832          }
     833         
    526834      }
    527835
  • c/src/libchip/network/greth.h

    r13279f5d r050249d  
    99 *  $Id$
    1010 */
     11
    1112
    1213#ifndef _GR_ETH_
     
    3738#define GRETH_TOTAL_BD           128
    3839#define GRETH_MAXBUF_LEN         1520
    39                                  
     40                               
    4041/* Tx BD */                     
    4142#define GRETH_TXD_ENABLE      0x0800 /* Tx BD Enable */
    4243#define GRETH_TXD_WRAP        0x1000 /* Tx BD Wrap (last BD) */
    4344#define GRETH_TXD_IRQ         0x2000 /* Tx BD IRQ Enable */
     45#define GRETH_TXD_MORE        0x20000 /* Tx BD More (more descs for packet) */
     46#define GRETH_TXD_IPCS        0x40000 /* Tx BD insert ip chksum */
     47#define GRETH_TXD_TCPCS       0x80000 /* Tx BD insert tcp chksum */
     48#define GRETH_TXD_UDPCS       0x100000 /* Tx BD insert udp chksum */
    4449
    4550#define GRETH_TXD_UNDERRUN    0x4000 /* Tx BD Underrun Status */
    4651#define GRETH_TXD_RETLIM      0x8000 /* Tx BD Retransmission Limit Status */
     52#define GRETH_TXD_LATECOL     0x10000 /* Tx BD Late Collision */
     53
    4754#define GRETH_TXD_STATS       (GRETH_TXD_UNDERRUN            | \
    48                                GRETH_TXD_RETLIM)
     55                               GRETH_TXD_RETLIM              | \
     56                               GRETH_TXD_LATECOL)
     57
     58#define GRETH_TXD_CS          (GRETH_TXD_IPCS            | \
     59                               GRETH_TXD_TCPCS           | \
     60                               GRETH_TXD_UDPCS)
    4961                               
    5062/* Rx BD */                     
     
    5769#define GRETH_RXD_CRCERR      0x10000 /* Rx BD CRC Error Status */
    5870#define GRETH_RXD_OVERRUN     0x20000 /* Rx BD Overrun Status */
     71#define GRETH_RXD_LENERR      0x40000 /* Rx BD Length Error */
     72#define GRETH_RXD_ID          0x40000 /* Rx BD IP Detected */
     73#define GRETH_RXD_IR          0x40000 /* Rx BD IP Chksum Error */
     74#define GRETH_RXD_UD          0x40000 /* Rx BD UDP Detected*/
     75#define GRETH_RXD_UR          0x40000 /* Rx BD UDP Chksum Error */
     76#define GRETH_RXD_TD          0x40000 /* Rx BD TCP Detected */
     77#define GRETH_RXD_TR          0x40000 /* Rx BD TCP Chksum Error */
     78
     79
    5980#define GRETH_RXD_STATS       (GRETH_RXD_OVERRUN             | \
    6081                               GRETH_RXD_DRIBBLE             | \
     
    87108#define GRETH_MDIO_PHYADR       0x0000F800 /* PHY address */
    88109#define GRETH_MDIO_DATA         0xFFFF0000 /* MDIO DATA */
    89  
     110
     111
     112/* MII registers */
     113#define GRETH_MII_EXTADV_1000FD 0x00000200
     114#define GRETH_MII_EXTADV_1000HD 0x00000100
     115#define GRETH_MII_EXTPRT_1000FD 0x00000800
     116#define GRETH_MII_EXTPRT_1000HD 0x00000400
     117
     118#define GRETH_MII_100T4         0x00000200
     119#define GRETH_MII_100TXFD       0x00000100
     120#define GRETH_MII_100TXHD       0x00000080
     121#define GRETH_MII_10FD          0x00000040
     122#define GRETH_MII_10HD          0x00000020
     123
     124
     125
    90126/* Attach routine */
    91127
     
    95131);
    96132
     133/* PHY data */
     134struct phy_device_info
     135{
     136   int vendor;
     137   int device;
     138   int rev;
     139   
     140   int adv;
     141   int part;
     142
     143   int extadv;
     144   int extpart;
     145};
     146
    97147/*
    98148#ifdef CPU_U32_FIX
    99149void ipalign(struct mbuf *m);
    100150#endif
     151
    101152*/
    102 
    103153#endif
    104154
Note: See TracChangeset for help on using the changeset viewer.