LOCAL void ns16550TxStartup ( NS16550_CHAN * pChan /* pointer to channel */ ) { char mask; if (pChan->channelMode == SIO_MODE_INT) { if (pChan->options & CLOCAL) { /* No modem control */ pChan->ier |= TxFIFO_BIT; ns16550RegWr(REGPTR(IER,pChan) , pChan->ier); } else { mask = ns16550RegRd(REGPTR(MSR, pChan)) & MSR_CTS; /* if the CTS is asserted enable Tx interrupt */ if (mask & MSR_CTS) pChan->ier |= TxFIFO_BIT; /* enable Tx interrupt */ else pChan->ier &= (~TxFIFO_BIT); /* disable Tx interrupt */ ns16550RegWr(REGPTR(IER, pChan) , pChan->ier); } } sysWbFlush(); }
/****************************************************************************** * * ae531x_DmaTxStop - Stop Tx * * RETURNS: N/A */ void ae531x_DmaTxStop(ae531x_MAC_t *MACInfo) { ae531x_ClearDmaReg(MACInfo, DmaControl, DmaTxStart); sysWbFlush(); }
/****************************************************************************** * * ae531x_DmaTxStart - Start Tx * * RETURNS: N/A */ void ae531x_DmaTxStart(ae531x_MAC_t *MACInfo) { ae531x_SetDmaReg(MACInfo, DmaControl, DmaTxStart); sysWbFlush(); }
void ns16550Int ( NS16550_CHAN * pChan /* pointer to channel */ ) { FAST volatile char intStatus; /* read the Interrrupt Status Register (Int. Ident.) */ intStatus = ns16550RegRd((REGPTR(IIR, pChan))) & 0x0f; /* * This UART chip always produces level active interrupts, and the IIR * only indicates the highest priority interrupt. * In the case that receive and transmit interrupts happened at * the same time, we must clear both interrupt pending to prevent * edge-triggered interrupt(output from interrupt controller) from locking * up. One way doing it is to disable all the interrupts at the beginning * of the ISR and enable at the end. */ ns16550RegWr(REGPTR(IER,pChan) , 0); /* disable interrupt */ switch (intStatus) { case IIR_RLS: /* overrun,parity error and break interrupt */ intStatus = ns16550RegRd(REGPTR(LSR, pChan)); /* read LSR to reset interrupt */ break; case IIR_RDA: /* received data available */ case IIR_TIMEOUT: /* * receiver FIFO interrupt. In some case, IIR_RDA will * not be indicated in IIR register when there is more * than one character in FIFO. */ ns16550IntRd (pChan); /* RxChar Avail */ break; case IIR_THRE: /* transmitter holding register ready */ { char outChar; if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR) ns16550RegWr(REGPTR(THR, pChan) , outChar); /* char to Transmit Holding Reg */ else pChan->ier &= (~TxFIFO_BIT); /* indicates to disable Tx Int */ } break; case IIR_MSTAT: /* modem status register */ { char msr; msr = ns16550RegRd(REGPTR(MSR, pChan)); /* if CTS is asserted by modem, enable tx interrupt */ if ((msr & MSR_CTS) && (msr & MSR_DCTS)) pChan->ier |= TxFIFO_BIT; else pChan->ier &= (~TxFIFO_BIT); } break; default: break; } ns16550RegWr(REGPTR(IER, pChan) , pChan->ier); /* enable interrupts accordingly */ sysWbFlush(); }
LOCAL STATUS cacheLsn2ePipeFlush (void) { sysWbFlush (); return (OK); }
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; }
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; }