示例#1
0
/******************************************************************************
*
* ae531x_DmaIntClear - Clear DMA interrupts
*
* RETURNS: N/A
*/
static void
ae531x_DmaIntClear(ae531x_MAC_t *MACInfo)
{
    /* clear all interrupt requests */
    ae531x_WriteDmaReg(MACInfo, DmaStatus,
                      ae531x_ReadDmaReg(MACInfo, DmaStatus));  
}
示例#2
0
/******************************************************************************
*
* ae531x_DmaReset - Reset DMA and TLI controllers
*
* RETURNS: N/A
*/
void
ae531x_DmaReset(ae531x_MAC_t *MACInfo)
{
    int           i;
    UINT32        descAddr;
    unsigned long oldIntrState;

    ARRIVE();

    /* Disable device interrupts prior to any errors during stop */
    intDisable(oldIntrState);

    /* Disable MAC rx and tx */
    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));

    /* Reset dma controller */
    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn);

    /* Delay 2 usec */
    sysUDelay(2);

    /* Flush the rx queue */
    descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr;
    MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr;
    for (i=0;
         i<(MACInfo->rxDescCount);
         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {
            AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);
    }

    /* Flush the tx queue */
    descAddr = (UINT32)MACInfo->txQueue.firstDescAddr;
    MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr;
    MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr;
    for (i=0;
         i<(MACInfo->txDescCount);
         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {
            AE531X_DESC_STATUS_SET (descAddr, 0);
    }

    /* Set init register values  */
    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit);

    /* Install the first Tx and Rx queues on the device */
    ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr,
                      (UINT32)MACInfo->rxQueue.firstDescAddr);
    ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr,
                      (UINT32)MACInfo->txQueue.firstDescAddr);

    ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward);

    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);

    AE531X_PRINT(AE531X_DEBUG_RESET,
              ("eth%d: DMA RESET!\n", MACInfo->unit));

    /* Turn on device interrupts -- enable most errors */
    ae531x_DmaIntClear(MACInfo);    /* clear interrupt requests  */
    ae531x_DmaIntEnable(MACInfo);   /* enable interrupts */

    ae531x_EndResetMode(MACInfo);

    intEnable(oldIntrState);

    LEAVE();
}
示例#3
0
/******************************************************************************
*
* ae531x_DmaIntDisable - Disable DMA interrupts
*
* RETURNS: N/A
*/
void
ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo)
{
    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);
}
示例#4
0
/******************************************************************************
 *
 * ae531x_AckIntr - clear interrupt bits in the status register.
 * Note: Interrupt bits are *cleared* by writing a 1.
 */
void
ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data)
{
      ae531x_WriteDmaReg(MACInfo, DmaStatus, data);
}
示例#5
0
static int ae531x_poll(struct eth_device *dev)
{
    ae531xRxBuf_t *rxBuf, *newRxBuf;
    char *rxBufData;
    int unused_length;
    VIRT_ADDR   rxDesc;
    int length;
    ae531x_MAC_t *MACInfo;
    unsigned int cmdsts;
    ae531x_priv_data_t *ae531x_priv;

    ae531x_priv = (ae531x_priv_data_t *)dev->priv;
    MACInfo = (ae531x_MAC_t *)&ae531x_priv->MACInfo;

    do {
        for(;;) {
            rxDesc = MACInfo->rxQueue.curDescAddr;
            cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc));

            if (cmdsts & DescOwnByDma) {
                /* There's nothing left to process in the RX ring */
                goto rx_all_done;
            }

            AE531X_PRINT(AE531X_DEBUG_RX,
                  ("consume rxDesc %p with cmdsts=0x%x\n",
                   (void *)rxDesc, cmdsts));
   
            AE531X_CONSUME_DESC((&MACInfo->rxQueue));
    
            A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE);

            /*  Process a packet */
            length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN;
            if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) ==
                           (DescRxFirst | DescRxLast) ) {
                /* Descriptor status indicates "NO errors" */

                rxBuf = AE531X_DESC_SWPTR_GET(rxDesc);
                /*
                 * Allocate a replacement buffer
                 * We want to get another buffer ready for Rx ASAP.
                 */
                newRxBuf = ae531x_rxbuf_alloc(MACInfo, &rxBufData, &unused_length);
                if(newRxBuf == NULL ) {
                    /*
                     * Give this descriptor back to the DMA engine,
                     * and drop the received packet.
                     */
                    AE531X_PRINT(AE531X_DEBUG_ERROR,
                              ("Can't allocate new rx buf\n"));
                } else {
		   //diag_printf("rxBufData=%p\n",rxBufData);
                    AE531X_DESC_BUFPTR_SET(rxDesc, virt_to_bus(rxBufData));
                    AE531X_DESC_SWPTR_SET(rxDesc, newRxBuf);
                }

                AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);
                rxDesc = NULL; /* sanity -- cannot use rxDesc now */
                sysWbFlush();
    
                if (newRxBuf == NULL) {
                    goto no_rx_bufs;
                } else {
                    /* Sync data cache w.r.t. DMA */
                    A_DATA_CACHE_INVAL(rxBuf->data, length);
        
                    /* Send the data up the stack */
                    AE531X_PRINT(AE531X_DEBUG_RX,
                              ("Send data up stack: rxBuf=%p data=%p length=%d\n",
                               (void *)rxBuf, (void *)rxBuf->data, length));

                    {
                        unsigned long oldIntrState;

                        rxBuf->next = NULL;
                        intDisable(oldIntrState);
                        if (ae531xRxRecvdListHead) {
                            ae531xRxRecvdListTail->next = rxBuf;
                            ae531xRxRecvdListTail = rxBuf;
                        } else {
                            ae531xRxRecvdListHead = rxBuf;
                            ae531xRxRecvdListTail = rxBuf;
                        }
                        intEnable(oldIntrState);
                    }
                     NetReceive(rxBuf->data, length);
			    /* Free driver Rx buffer */
    			ae531x_rxbuf_free(rxBuf);
                }
            } else {
                AE531X_PRINT(AE531X_DEBUG_ERROR,
                          ("Bad receive.  rxDesc=%p  cmdsts=0x%8.8x\n",
                           (void *)rxDesc, cmdsts));
            }
        }
    } while (ae531x_ReadDmaReg(MACInfo, DmaStatus) & DmaIntRxCompleted);

rx_all_done:
    ae531x_SetDmaReg(MACInfo, DmaIntrEnb,
                     DmaIeRxCompleted | DmaIeRxNoBuffer);
    ae531x_WriteDmaReg(MACInfo, DmaRxPollDemand, 0);

no_rx_bufs:

    return;
}
示例#6
0
static int ae531x_send(struct eth_device *dev, volatile void *packet, int length)
{
    ae531x_priv_data_t *ae531x_priv;
    ae531x_MAC_t *MACInfo;
    UINT32 ctrlen;
    VIRT_ADDR txDesc;
    ae531xTxBuf_t *TxBuf;
    unsigned char *TxBufData, *TxBufDataStart;
    int i;
    volatile UINT32 regval;

    ae531x_priv = (ae531x_priv_data_t *)dev->priv;
    MACInfo = (ae531x_MAC_t *)&ae531x_priv->MACInfo;

    /* Check if this port is up, else toss packet */
    if (!MACInfo->port_is_up) 
    {
        goto dropFrame;
    }

    if (ae531x_IsInResetMode(MACInfo)) 
    {
        goto dropFrame;
    }

     ae531x_TxReap(MACInfo);

    txDesc = MACInfo->txQueue.curDescAddr;
    if (txDesc == MACInfo->txQueue.reapDescAddr) 
    {
        goto dropFrame;
    }


    AE531X_CONSUME_DESC((&MACInfo->txQueue));
    ae531xTxAvail--;

    /* Allocate a transmit data buffer */
    ae531x_txbuf_alloc(MACInfo, &TxBuf);
    AE531X_DESC_SWPTR_SET(txDesc, TxBuf);

    TxBufDataStart = TxBufData = TxBuf->data;

    if (length< 60)
    {
        length= 60;
    }
   memcpy(TxBufData, packet, length);

    TxBufData += length;

    /* Update the descriptor */
    AE531X_DESC_BUFPTR_SET(txDesc, virt_to_bus(TxBufDataStart));
    ctrlen = AE531X_DESC_CTRLEN_GET(txDesc);
    ctrlen = (ctrlen & (DescEndOfRing)) |
                            DescTxFirst |
                             DescTxLast |
                        DescTxIntEnable;

    ctrlen |= ((length << DescSize1Shift) & DescSize1Mask);

    AE531X_DESC_CTRLEN_SET(txDesc, ctrlen);

    AE531X_DESC_STATUS_SET(txDesc, DescOwnByDma);

    /* Alert DMA engine to resume Tx */
    ae531x_WriteDmaReg(MACInfo, DmaTxPollDemand, 0);
    sysWbFlush();


dropFrame:
    return length;
}