Exemplo n.º 1
0
//****************************************************************************
//
// Low-Level transmit routine.  Should do the actual transmission of the
// packet. The packet is contained in the pbuf that is passed to the function.
// This pbuf might be chained.
//
//****************************************************************************
err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
    struct pbuf *q;
    int i;
    unsigned char *pucBuf;
    unsigned long ulTemp;
    unsigned char *pucTemp = (unsigned char *)&ulTemp;

    //
    // Wait for space available in the TX FIFO.
    //
    while(!EthernetSpaceAvail(ETH_BASE))
    {
    }

    //
    // Fill in the first two bytes of the payload data (configured as padding
    // with ETH_PAD_SIZE = 2) with the total length of the payload data
    // (minus the Ethernet MAC layer header).
    //
    pucBuf = p->payload;
    ulTemp = p->tot_len - 16;
    *pucBuf++ = pucTemp[0];
    *pucBuf++ = pucTemp[1];

    //
    // Copy data from the pbuf(s) into the TX Fifo.
    // For now, assume every pbuf is full, except possibly the last one.
    //
    for(q = p; q != NULL; q = q->next)
    {
        pucBuf = q->payload;

        //
        // Send the data from the pbuf to the interface, one pbuf at a
        // time. The size of the data in each pbuf is kept in the ->len
        // variable.
        //
        for(i = 0; i < q->len; i += 4)
        {
            pucTemp[0] = *pucBuf++;
            pucTemp[1] = *pucBuf++;
            pucTemp[2] = *pucBuf++;
            pucTemp[3] = *pucBuf++;
            HWREG(ETH_BASE + MAC_O_DATA) = ulTemp;
        }
    }

    //
    // Wakeup the transmitter.
    //
    HWREG(ETH_BASE + MAC_O_TR) = MAC_TR_NEWTX;

#if LINK_STATS
    lwip_stats.link.xmit++;
#endif

    return ERR_OK;
}
Exemplo n.º 2
0
//****************************************************************************
//
// Low-Level transmit routine.  Should do the actual transmission of the
// packet. The packet is contained in the pbuf that is passed to the function.
// This pbuf might be chained.
//
//****************************************************************************
rt_err_t luminaryif_tx(rt_device_t dev, struct pbuf *p)
{
    int iBuf;
    unsigned char *pucBuf;
    unsigned long *pulBuf;
    struct pbuf *q;
    int iGather;
    unsigned long ulGather;
    unsigned char *pucGather;
    unsigned long ulTemp;	

    /* lock tx operation */
    rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
	
    //
    // Wait for space available in the TX FIFO.
    //
    while(!EthernetSpaceAvail(ETH_BASE))
    {
    }

//
    // Fill in the first two bytes of the payload data (configured as padding
    // with ETH_PAD_SIZE = 2) with the total length of the payload data
    // (minus the Ethernet MAC layer header).
    //
    *((unsigned short *)(p->payload)) = p->tot_len - 16;

    //
    // Initialize the gather register.
    //
    iGather = 0;
    pucGather = (unsigned char *)&ulGather;
    ulGather = 0;

    //
    // Copy data from the pbuf(s) into the TX Fifo.
    //
    for(q = p; q != NULL; q = q->next)
    {
        //
        // Intialize a char pointer and index to the pbuf payload data.
        //
        pucBuf = (unsigned char *)q->payload;
        iBuf = 0;

        //
        // If the gather buffer has leftover data from a previous pbuf
        // in the chain, fill it up and write it to the Tx FIFO.
        //
        while((iBuf < q->len) && (iGather != 0))
        {
            //
            // Copy a byte from the pbuf into the gather buffer.
            //
            pucGather[iGather] = pucBuf[iBuf++];

            //
            // Increment the gather buffer index modulo 4.
            //
            iGather = ((iGather + 1) % 4);
        }

        //
        // If the gather index is 0 and the pbuf index is non-zero,
        // we have a gather buffer to write into the Tx FIFO.
        //
        if((iGather == 0) && (iBuf != 0))
        {
            HWREG(ETH_BASE + MAC_O_DATA) = ulGather;
            ulGather = 0;
        }

        //
        // Copy words of pbuf data into the Tx FIFO, but don't go past
        // the end of the pbuf.
        //
        if((iBuf % 4) != 0)
        {
            while((iBuf + 4) <= q->len)
            {
                ulTemp  = (pucBuf[iBuf++] <<  0);
                ulTemp |= (pucBuf[iBuf++] <<  8);
                ulTemp |= (pucBuf[iBuf++] << 16);
                ulTemp |= (pucBuf[iBuf++] << 24);		
                HWREG(ETH_BASE + MAC_O_DATA) = ulTemp;
            }
        }
        else
        {
            //
            // Initialze a long pointer into the pbuf for 32-bit access.
            //
            pulBuf = (unsigned long *)&pucBuf[iBuf];

            while((iBuf + 4) <= q->len)
            {
                HWREG(ETH_BASE + MAC_O_DATA) = *pulBuf++;
                iBuf += 4;
            }
        }
        //
        // Check if leftover data in the pbuf and save it in the gather
        // buffer for the next time.
        //
        while(iBuf < q->len)
        {
            //
            // Copy a byte from the pbuf into the gather buffer.
            //
            pucGather[iGather] = pucBuf[iBuf++];

            //
            // Increment the gather buffer index modulo 4.
            //
            iGather = ((iGather + 1) % 4);
        }
    }

    //
    // Send any leftover data to the FIFO.
    //
    HWREG(ETH_BASE + MAC_O_DATA) = ulGather;

    //
    // Wakeup the transmitter.
    //
    HWREG(ETH_BASE + MAC_O_TR) = MAC_TR_NEWTX;

#if LINK_STATS
    lwip_stats.link.xmit++;
#endif

    return(ERR_OK);
}