static int ag7240_recv(struct eth_device *dev) { int length; ag7240_desc_t *f; ag7240_mac_t *mac; mac = (ag7240_mac_t *)dev->priv; for (;;) { f = mac->fifo_rx[mac->next_rx]; if (ag7240_rx_owned_by_dma(f)) break; length = f->pkt_size; NetReceive(NetRxPackets[mac->next_rx] , length - 4); flush_cache((u32) NetRxPackets[mac->next_rx] , PKTSIZE_ALIGN); ag7240_rx_give_to_dma(f); if (++mac->next_rx >= NO_OF_RX_FIFOS) mac->next_rx = 0; } if (!(ag7240_reg_rd(mac, AG7240_DMA_RX_CTRL))) { ag7240_reg_wr(mac, AG7240_DMA_RX_DESC, virt_to_phys(f)); ag7240_reg_wr(mac, AG7240_DMA_RX_CTRL, 1); } return (0); }
/* Get a data block via Ethernet */ int eth_rx (void) { unsigned long idx, length; // Determine if a frame has been received length = 0; idx = ENETMAC->rxconsumeindex; if (ENETMAC->rxproduceindex != idx) { // Clear interrupt ENETMAC->intclear = MACINT_RXDONEINTEN; // Frame received, get size of RX packet length = (pRXStatus[idx].statusinfo & 0x7FF); /* Pass the packet up to the protocol layer */ if (length > 0) { memcpy((void *) NetRxPackets[0], (void *) pRXVBuffs [idx], length); NetReceive (NetRxPackets[0], (unsigned short) length); } // Return DMA buffer idx++; if (idx >= ENET_MAX_TX_PACKETS) { idx = 0; } ENETMAC->rxconsumeindex = (unsigned long) idx; } return (int) length; }
/* Get a data block via Ethernet */ static int cs8900_recv(struct eth_device *dev) { int i; u16 rxlen; u16 *addr; u16 status; struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv); status = get_reg(dev, PP_RER); if ((status & PP_RER_RxOK) == 0) return 0; status = REG_READ(&priv->regs->rtdata); rxlen = REG_READ(&priv->regs->rtdata); if (rxlen > PKTSIZE_ALIGN + PKTALIGN) debug("packet too big!\n"); for (addr = (u16 *) NetRxPackets[0], i = rxlen >> 1; i > 0; i--) *addr++ = REG_READ(&priv->regs->rtdata); if (rxlen & 1) *addr++ = REG_READ(&priv->regs->rtdata); /* Pass the packet up to the protocol layers. */ NetReceive (NetRxPackets[0], rxlen); return rxlen; }
static int uec_recv(struct eth_device* dev) { uec_private_t *uec = dev->priv; volatile qe_bd_t *bd; u16 status; u16 len; u8 *data; bd = uec->rxBd; status = bd->status; while (!(status & RxBD_EMPTY)) { if (!(status & RxBD_ERROR)) { data = BD_DATA(bd); len = BD_LENGTH(bd); NetReceive(data, len); } else { printf("%s: Rx error\n", dev->name); } status &= BD_CLEAN; BD_LENGTH_SET(bd, 0); BD_STATUS_SET(bd, status | RxBD_EMPTY); BD_ADVANCE(bd, status, uec->p_rx_bd_ring); status = bd->status; } uec->rxBd = bd; return 1; }
/* Check for received packets */ s32 eth_rx (void) { s32 nLen = 0; ETH *eth = &m_eth; /* check if packet ready */ if ( (GET_REG( REG_BDMASTAT)) & ETH_S_BRxRDF) { /* process all waiting packets */ while ( !eth->m_curRX_FD->m_frameDataPtr.bf.owner) { nLen = eth->m_curRX_FD->m_status.bf.len; /* call back u-boot -- may call eth_send() */ NetReceive ((u8 *)eth->m_curRX_FD->m_frameDataPtr.ui, nLen); /* set owner back to CPU */ eth->m_curRX_FD->m_frameDataPtr.bf.owner = 1; /* clear status */ eth->m_curRX_FD->m_status.ui = 0x0; /* advance to next descriptor */ eth->m_curRX_FD = eth->m_curRX_FD->m_nextFD; /* clear received frame bit */ PUT_REG( REG_BDMASTAT, ETH_S_BRxRDF); } } return nLen; }
static int tsec_recv(struct eth_device *dev) { int length; struct tsec_private *priv = (struct tsec_private *)dev->priv; tsec_t *regs = priv->regs; while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { length = rtx.rxbd[rxIdx].length; /* Send the packet up if there were no errors */ if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) { NetReceive(NetRxPackets[rxIdx], length - 4); } else { printf("Got error %x\n", (rtx.rxbd[rxIdx].status & RXBD_STATS)); } rtx.rxbd[rxIdx].length = 0; /* Set the wrap bit if this is the last element in the list */ rtx.rxbd[rxIdx].status = RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); rxIdx = (rxIdx + 1) % PKTBUFSRX; } if (in_be32(®s->ievent) & IEVENT_BSY) { out_be32(®s->ievent, IEVENT_BSY); out_be32(®s->rstat, RSTAT_CLEAR_RHALT); } return -1; }
static int ethoc_rx(struct eth_device *dev, int limit) { struct ethoc *priv = (struct ethoc *)dev->priv; int count; for (count = 0; count < limit; ++count) { u32 entry; struct ethoc_bd bd; entry = priv->num_tx + (priv->cur_rx % priv->num_rx); ethoc_read_bd(dev, entry, &bd); if (bd.stat & RX_BD_EMPTY) break; debug("%s(): RX buffer %d, %x received\n", __func__, priv->cur_rx, bd.stat); if (ethoc_update_rx_stats(&bd) == 0) { int size = bd.stat >> 16; size -= 4; /* strip the CRC */ NetReceive((void *)bd.addr, size); } /* clear the buffer descriptor so it can be reused */ flush_dcache(bd.addr, PKTSIZE_ALIGN); bd.stat &= ~RX_BD_STATS; bd.stat |= RX_BD_EMPTY; ethoc_write_bd(dev, entry, &bd); priv->cur_rx++; }
static int dw_eth_recv(struct eth_device *dev) { struct dw_eth_dev *priv = dev->priv; u32 desc_num = priv->rx_currdescnum; struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; u32 status = desc_p->txrx_status; int length = 0; /* Check if the owner is the CPU */ if (!(status & DESC_RXSTS_OWNBYDMA)) { length = (status & DESC_RXSTS_FRMLENMSK) >> \ DESC_RXSTS_FRMLENSHFT; NetReceive(desc_p->dmamac_addr, length); /* * Make the current descriptor valid again and go to * the next one */ desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; /* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM) desc_num = 0; }
static int au1x00_recv(struct eth_device* dev){ volatile mac_fifo_t *fifo_rx = (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS); int length; u32 status; for(;;){ if(!(fifo_rx[next_rx].addr&RX_T_DONE)){ /* Nothing has been received */ return(-1); } status = fifo_rx[next_rx].status; length = status&0x3FFF; if(status&RX_ERROR){ printf("Rx error 0x%x\n", status); } else{ /* Pass the packet up to the protocol layers. */ NetReceive(NetRxPackets[next_rx], length - 4); } fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE; next_rx++; if(next_rx>=NO_OF_FIFOS){ next_rx=0; } } /* for */ return(0); /* Does anyone use this? */ }
/* Get a data block via Ethernet */ static int jz_eth_rx (struct eth_device* dev) { int i; unsigned short rxlen; unsigned short *addr; unsigned short status; dev = dev; status = get_reg (PP_RER); if ((status & PP_RER_RxOK) == 0) return 0; status = CS8900_RTDATA; /* stat */ rxlen = CS8900_RTDATA; /* len */ #ifdef DEBUG if (rxlen > PKTSIZE_ALIGN + PKTALIGN) printf ("packet too big!\n"); #endif for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0; i--) *addr++ = CS8900_RTDATA; if (rxlen & 1) *addr++ = CS8900_RTDATA; /* Pass the packet up to the protocol layers. */ NetReceive (NetRxPackets[0], rxlen); return rxlen; }
int eth_rx (void) { int nLen = 0; unsigned int unStatus; unStatus = *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA; if (!unStatus) /* no packet available, return immediately */ return 0; DEBUG_FN (DEBUG_RX); /* unLen always < max(nLen) and discard checksum */ nLen = (int) aRxBufferDesc[0].unLen - 4; /* acknowledge status register */ *get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus; aRxBufferDesc[0].unLen = 1522; aRxBufferDesc[0].s.bits.uFull = 0; /* Buffer A descriptor available again */ *get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1; /* NetReceive may call eth_send. Due to a possible bug of the NS9750 we * have to acknowledge the received frame before sending a new one */ if (unStatus & NS9750_ETH_EINTR_RXDONEA) NetReceive (NetRxPackets[0], nLen); return nLen; }
static int macb_recv(struct eth_device *netdev) { struct macb_device *macb = to_macb(netdev); unsigned int rx_tail = macb->rx_tail; void *buffer; int length; int wrapped = 0; u32 status; for (;;) { macb_invalidate_ring_desc(macb, RX); if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) return -1; status = macb->rx_ring[rx_tail].ctrl; if (status & RXBUF_FRAME_START) { if (rx_tail != macb->rx_tail) reclaim_rx_buffers(macb, rx_tail); wrapped = 0; } if (status & RXBUF_FRAME_END) { buffer = macb->rx_buffer + 128 * macb->rx_tail; length = status & RXBUF_FRMLEN_MASK; macb_invalidate_rx_buffer(macb); if (wrapped) { unsigned int headlen, taillen; headlen = 128 * (MACB_RX_RING_SIZE - macb->rx_tail); taillen = length - headlen; memcpy((void *)NetRxPackets[0], buffer, headlen); memcpy((void *)NetRxPackets[0] + headlen, macb->rx_buffer, taillen); buffer = (void *)NetRxPackets[0]; } NetReceive(buffer, length); if (++rx_tail >= MACB_RX_RING_SIZE) rx_tail = 0; reclaim_rx_buffers(macb, rx_tail); } else { if (++rx_tail >= MACB_RX_RING_SIZE) { wrapped = 1; rx_tail = 0; } } barrier(); } return 0; }
int mac_receive(void) { PSRxDesc pRD; int length = 0, tmp; DWORD isr_status; /* 1.store ISR */ MACvReadISR(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId, &isr_status); /* 2.disable IMR */ MACvIntDisable(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId); /* 3clear ISR */ MACvWriteISR(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId, isr_status); /* 4.handle ISR */ /* 5.handle received packets until owner==chip */ /* printf("enter mac_receive\n"); */ while (TRUE) { pRD = sg_aAdapter->apRD[sg_aAdapter->idxRxCurDesc]; /* a.check RD status */ /* if owner==chip break; */ if (pRD->m_rd0RD0.f1Owner == B_OWNED_BY_CHIP) { /* printf("receive done \n"); */ break; } /* if ok, net_receive() */ if (pRD->m_rd0RD0.byRSR1&RSR1_RXOK) { NetReceive((volatile uchar *)pRD->m_dwRxBufferAddr, pRD->m_rd0RD0.f15FrameLen-4); length += (pRD->m_rd0RD0.f15FrameLen-4); #if MACDBG printf("receive ok\n"); #endif } else { /* else, error handling */ printf("receive error status:%02X %02X%\n", pRD->m_rd0RD0.byRSR1, pRD->m_rd0RD0.byRSR0); /* handler will do later */ } /* b.set own==chip */ pRD->m_rd0RD0.f1Owner = B_OWNED_BY_CHIP; /* c.increase to next RD */ tmp = (++sg_aAdapter->idxRxCurDesc); sg_aAdapter->idxRxCurDesc = tmp % sg_aAdapter->cbRD; #if MACDBG printf("jump to next RD =%d\n", sg_aAdapter->idxRxCurDesc); #endif } /* 6.enable IMR */ MACvIntEnable(sg_aAdapter->dwIoBase, sg_aAdapter->byRevId, IMR_MASK_VALUE); return length; }
void uboot_push_packet_len(int len) { PRINTK("pushed len = %d\n", len); if (len >= 2000) { printf("NE2000: packet too big\n"); return; } dp83902a_recv(&pbuf[0], len); /*Just pass it to the upper layer*/ NetReceive(&pbuf[0], len); }
/* Get a data block via Ethernet */ extern int eth_rx (void) { dbg_info("%s,%s,%d\n",__FILE__,__FUNCTION__,__LINE__); if( ETH_FrameReceive((UINT8 *)NetRxPackets[0],&rxlen) ==1 ) /* Pass the packet up to the protocol layers. */ NetReceive (NetRxPackets[0], rxlen); return rxlen; }
int ll_temac_recv_fifo(struct eth_device *dev) { int i, length = 0; u32 *buf = (u32 *)NetRxPackets[0]; struct ll_temac *ll_temac = dev->priv; struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; if (in_be32(&fifo_ctrl->isr) & LL_FIFO_ISR_RC) { /* reset isr */ out_be32(&fifo_ctrl->isr, ~0UL); /* * MAYBE here: * while (fifo_ctrl->isr); */ /* * The length is written (into RLR) by the XPS LL FIFO * when the packet is received across the RX LocalLink * interface and the receive data FIFO had enough * locations that all of the packet data has been saved. * The RLR should only be read when a receive packet is * available for processing (the receive occupancy is * not zero). Once the RLR is read, the receive packet * data should be read from the receive data FIFO before * the RLR is read again. * * [F] page 17, Receive Length Register (RLR) */ if (in_be32(&fifo_ctrl->rdfo) & LL_FIFO_RDFO_MASK) { length = in_be32(&fifo_ctrl->rlf) & LL_FIFO_RLF_MASK; } else { printf("%s: Got error, no receive occupancy\n", __func__); return -1; } if (length > PKTSIZE_ALIGN) { printf("%s: Got error, receive package too big (%i)\n", __func__, length); ll_temac_reset_fifo(dev); return -1; } for (i = 0; i < length; i += 4) *buf++ = in_be32(&fifo_ctrl->rdfd); NetReceive(NetRxPackets[0], length); } return 0; }
int ll_temac_recv_sdma(struct eth_device *dev) { int length, pb_idx; struct cdmac_bd *rx_dp = &cdmac_bd.rx[rx_idx]; struct ll_temac *ll_temac = dev->priv; phys_addr_t *ra = ll_temac->sdma_reg_addr; if (ll_temac_sdma_error(dev)) { if (ll_temac_reset_sdma(dev)) return -1; ll_temac_init_sdma(dev); } flush_cache((u32)rx_dp, sizeof(*rx_dp)); if (!(rx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)) return 0; if (rx_dp->sca.stctrl & (CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP)) { pb_idx = rx_idx; length = rx_dp->sca.app[4] & CDMAC_BD_APP4_RXBYTECNT_MASK; } else { pb_idx = -1; length = 0; printf("%s: Got part of package, unsupported (%x)\n", __func__, rx_dp->sca.stctrl); } /* flip the buffer */ flush_cache((u32)rx_dp->phys_buf_p, length); /* reset the current descriptor */ rx_dp->sca.stctrl = 0; rx_dp->sca.app[4] = 0; flush_cache((u32)rx_dp, sizeof(*rx_dp)); /* Find next empty buffer descriptor, preparation for next iteration */ rx_idx = (rx_idx + 1) % PKTBUFSRX; rx_dp = &cdmac_bd.rx[rx_idx]; flush_cache((u32)rx_dp, sizeof(*rx_dp)); /* DMA start by writing to respective TAILDESC_PTR */ ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); if (length > 0 && pb_idx != -1) NetReceive(NetRxPackets[pb_idx], length); return 0; }
/************************************************************************** RECV - Receive a frame ***************************************************************************/ static int rtl_recv(struct eth_device *dev) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ int cur_rx; int length = 0; #ifdef DEBUG_RTL8169_RX printf ("%s\n", __FUNCTION__); #endif ioaddr = dev->iobase; cur_rx = tpc->cur_rx; rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]); if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { unsigned char rxdata[RX_BUF_LEN]; length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. status) & 0x00001FFF) - 4; rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length); memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); if (cur_rx == NUM_RX_DESC - 1) tpc->RxDescArray[cur_rx].status = cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); else tpc->RxDescArray[cur_rx].status = cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx])); rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); NetReceive(rxdata, length); } else { puts("Error Rx"); } cur_rx = (cur_rx + 1) % NUM_RX_DESC; tpc->cur_rx = cur_rx; return 1; } else { ushort sts = RTL_R8(IntrStatus); RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); udelay(100); /* wait */ } tpc->cur_rx = cur_rx; return (0); /* initially as this is called to flush the input */ }
static int axiemac_recv(struct eth_device *dev) { u32 length; struct axidma_priv *priv = dev->priv; u32 temp; /* Wait for an incoming packet */ if (!isrxready(dev)) return 0; debug("axiemac: RX data ready\n"); /* Disable IRQ for a moment till packet is handled */ temp = in_be32(&priv->dmarx->control); temp &= ~XAXIDMA_IRQ_ALL_MASK; out_be32(&priv->dmarx->control, temp); length = rx_bd.app4 & 0xFFFF; /* max length mask */ #ifdef DEBUG print_buffer(&rxframe, &rxframe[0], 1, length, 16); #endif /* Pass the received frame up for processing */ if (length) NetReceive(rxframe, length); #ifdef DEBUG /* It is useful to clear buffer to be sure that it is consistent */ memset(rxframe, 0, sizeof(rxframe)); #endif /* Setup RxBD */ /* Clear the whole buffer and setup it again - all flags are cleared */ memset(&rx_bd, 0, sizeof(rx_bd)); rx_bd.next = (u32)&rx_bd; rx_bd.phys = (u32)&rxframe; rx_bd.cntrl = sizeof(rxframe); /* Write bd to HW */ flush_cache((u32)&rx_bd, sizeof(rx_bd)); /* It is necessary to flush rxframe because if you don't do it * then cache will contain previous packet */ flush_cache((u32)&rxframe, sizeof(rxframe)); /* Rx BD is ready - start again */ out_be32(&priv->dmarx->tail, (u32)&rx_bd); debug("axiemac: RX completed, framelength = %d\n", length); return length; }
static int ag7100_recv(struct eth_device *dev) //struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) { ag7100_priv_data_t *ag7100_priv = (ag7100_priv_data_t *)dev->priv; ag7100RxBuf_t *rxBuf; unsigned long oldIntrState; unsigned char *RxBufData; struct eth_drv_sg *sg_item; int i; ARRIVE(); intDisable(oldIntrState); rxBuf = ag7100_priv->rxRecvdListHead; ag7100_priv->rxRecvdListHead = ag7100_priv->rxRecvdListHead->next; intEnable(oldIntrState); #if 0 //by Zhangyu if ((char *)sg_list->buf != NULL) { /* Copy out from driver Rx buffer to sg_list */ RxBufData = rxBuf->data; sg_item = sg_list; for (i=0; i<sg_len; sg_item++, i++) { char *segment_addr; int segment_len; segment_addr = (char *)sg_item->buf; segment_len = sg_item->len; #if defined(CONFIG_ATHRS26_PHY) && defined(HEADER_EN) /* remove header */ if ((ag7100_priv->enetUnit == 0) && (i == 0)) { RxBufData += 2; segment_len -= 2; } #endif memcpy(segment_addr, RxBufData, segment_len); RxBufData += segment_len; } } else { /* Handle according to convention: bit bucket the packet */ } #endif RxBufData = rxBuf->data; NetReceive(RxBufData, AG7100_RX_BUF_SIZE); /* Free driver Rx buffer */ ag7100_rxbuf_free(ag7100_priv, rxBuf); LEAVE(); }
static int fm_eth_recv(struct eth_device *dev) { struct fm_eth *fm_eth; struct fm_port_global_pram *pram; struct fm_port_bd *rxbd, *rxbd_base; u16 status, len; u8 *data; u16 offset_out; fm_eth = (struct fm_eth *)dev->priv; pram = fm_eth->rx_pram; rxbd = fm_eth->cur_rxbd; status = rxbd->status; while (!(status & RxBD_EMPTY)) { if (!(status & RxBD_ERROR)) { data = (u8 *)rxbd->buf_ptr_lo; len = rxbd->len; NetReceive(data, len); } else { printf("%s: Rx error\n", dev->name); return 0; } /* clear the RxBDs */ rxbd->status = RxBD_EMPTY; rxbd->len = 0; sync(); /* advance RxBD */ rxbd++; rxbd_base = (struct fm_port_bd *)fm_eth->rx_bd_ring; if (rxbd >= (rxbd_base + RX_BD_RING_SIZE)) rxbd = rxbd_base; /* read next status */ status = rxbd->status; /* update RxQD */ offset_out = muram_readw(&pram->rxqd.offset_out); offset_out += sizeof(struct fm_port_bd); if (offset_out >= muram_readw(&pram->rxqd.bd_ring_size)) offset_out = 0; muram_writew(&pram->rxqd.offset_out, offset_out); sync(); } fm_eth->cur_rxbd = (void *)rxbd; return 1; }
int eth_rx(void) { u32 RecvFrameLength; XStatus Result; RecvFrameLength = PKTSIZE; Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength); if (Result == XST_SUCCESS) { NetReceive(etherrxbuff, RecvFrameLength); return (1); } else { return (0); } }
/* * This function handles receipt of a packet from the network */ static int keystone2_eth_rcv_packet(struct eth_device *dev) { void *hd; int pkt_size; u32 *pkt; hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size); if (hd == NULL) return 0; NetReceive((uchar *)pkt, pkt_size); ksnav_release_rxhd(&netcp_pktdma, hd); return pkt_size; }
/* * Process received frames (if any) */ static int lpc18xx_eth_recv(struct eth_device *dev) { struct lpc18xx_eth_dev *mac = to_lpc18xx_eth(dev); int len; /* Index of the buffer where the next packet will be available */ u32 idx; u32 status; len = 0; idx = mac->rx_cons_idx; status = mac->dma->rx_bd[idx].status; /* * Determine if a frame has been received */ if (status & ETH_RDES0_OWN_MSK) goto out; if (status & ETH_RDES0_ES_MSK) { printf("%s: Received packet has errors.\n", __func__); goto out; } /* * Frame received, get size of RX packet */ len = (status & ETH_RDES0_FL_MSK) >> ETH_RDES0_FL_BITS; /* * Pass the packet up to the protocol layer */ if (len > 0) NetReceive(&mac->dma->rx_buf[idx][0], len); /* * Feed descriptor back to the Ethernet MAC */ mac->dma->rx_bd[idx].status = ETH_RDES0_OWN_MSK; LPC18XX_ETH->dma_rec_poll_dm = 1; mac->rx_cons_idx = (idx + 1) % CONFIG_SYS_RX_ETH_BUFFER; out: return len; }
int amazon_se_switch_recv(struct eth_device *dev) { int length = 0; int tmp; amazon_se_rx_descriptor_t * rx_desc; int anchor_num=0; int i; for (;;) { rx_desc = KSEG1ADDR(&rx_des_ring[rx_num]); if ((rx_desc->status.field.C == 0) || (rx_desc->status.field.OWN == 1)) { break; } length = rx_desc->status.field.DataLen; if (length) { /*tmp=(int)KSEG1ADDR(NetRxPackets[rx_num]); printf("%08x\n",tmp); */ NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_num]), length - 4); // serial_putc('*'); } else { printf("Zero length!!!\n"); } rx_desc->status.field.Sop=0; rx_desc->status.field.Eop=0; rx_desc->status.field.C=0; rx_desc->status.field.DataLen=PKTSIZE_ALIGN; rx_desc->status.field.OWN=1; rx_num++; if(rx_num==NUM_RX_DESC) rx_num=0; } return length; }
static int dw_eth_recv(struct eth_device *dev) { struct dw_eth_dev *priv = dev->priv; u32 status, desc_num = priv->rx_currdescnum; struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; int length = 0; uint32_t desc_start = (uint32_t)desc_p; uint32_t desc_end = desc_start + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); uint32_t data_start = (uint32_t)desc_p->dmamac_addr; uint32_t data_end; /* Invalidate entire buffer descriptor */ invalidate_dcache_range(desc_start, desc_end); status = desc_p->txrx_status; /* Check if the owner is the CPU */ if (!(status & DESC_RXSTS_OWNBYDMA)) { length = (status & DESC_RXSTS_FRMLENMSK) >> \ DESC_RXSTS_FRMLENSHFT; /* Invalidate received data */ data_end = data_start + roundup(length, ARCH_DMA_MINALIGN); invalidate_dcache_range(data_start, data_end); NetReceive(desc_p->dmamac_addr, length); /* * Make the current descriptor valid again and go to * the next one */ desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; /* Flush only status field - others weren't changed */ flush_dcache_range(desc_start, desc_end); /* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM) desc_num = 0; }
int eth_rx(void) { int length; for (;;) { /* section 16.9.23.2 */ if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { length = -1; break; /* nothing received - leave for() loop */ } length = rtx->rxbd[rxIdx].cbd_datlen; if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) { #ifdef ET_DEBUG printf("err: %x\n", rtx->rxbd[rxIdx].cbd_sc); #endif } else { /* Pass the packet up to the protocol layers. */ NetReceive(NetRxPackets[rxIdx], length - 4); } /* Give the buffer back to the SCC. */ rtx->rxbd[rxIdx].cbd_datlen = 0; /* wrap around buffer index when necessary */ if ((rxIdx + 1) >= PKTBUFSRX) { rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); rxIdx = 0; } else { rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; rxIdx++; } } return length; }
/* Get a data block via Ethernet */ extern int eth_rx (void) { int i; unsigned short rxlen; unsigned short *addr, data; unsigned short status; status = get_reg (PP_RER); if ((status & PP_RER_RxOK) == 0) return 0; status = CS8900_RTDATA; /* stat */ rxlen = CS8900_RTDATA; /* len */ #ifdef DEBUG if (rxlen > PKTSIZE_ALIGN + PKTALIGN) printf ("packet too big!\n"); #endif // printf("Recv %04x %04x\n", status, rxlen); for (addr = (unsigned short *) NetRxPackets[0], i = rxlen >> 1; i > 0; i--) { data = CS8900_RTDATA; *addr++ = SW(data); } if (rxlen & 1) { data = CS8900_RTDATA; *addr++ = SW(data); } // for ( i = 0 ; i < 10 ; i++) // { // printf("%04x ", addr[i]); // } // printf("\n"); /* Pass the packet up to the protocol layers. */ NetReceive (NetRxPackets[0], rxlen); return rxlen; }
int eth_rx (void) { int size; if (!(rbfp->addr & RBF_OWNER)) return 0; size = rbfp->size & RBF_SIZE; NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size); rbfp->addr &= ~RBF_OWNER; if (rbfp->addr & RBF_WRAP) rbfp = &rbfdt[0]; else rbfp++; p_mac->EMAC_RSR |= AT91C_EMAC_REC; return size; }
static int at91emac_recv(struct eth_device *netdev) { emac_device *dev; at91_emac_t *emac; rbf_t *rbfp; int size; emac = (at91_emac_t *) netdev->iobase; dev = (emac_device *) netdev->priv; rbfp = &dev->rbfdt[dev->rbindex]; while (rbfp->addr & RBF_OWNER) { size = rbfp->size & RBF_SIZE; NetReceive(NetRxPackets[dev->rbindex], size); DEBUG_AT91EMAC("Recv[%d]: %d bytes @ %x \n", dev->rbindex, size, rbfp->addr); rbfp->addr &= ~RBF_OWNER; rbfp->size = 0; if (dev->rbindex < (RBF_FRAMEMAX-1)) dev->rbindex++; else dev->rbindex = 0; rbfp = &(dev->rbfdt[dev->rbindex]); if (!(rbfp->addr & RBF_OWNER)) writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC, &emac->rsr); } if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) { /* EMAC silicon bug 41.3.1 workaround 1 */ writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl); writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl); dev->rbindex = 0; printf("%s: reset receiver (EMAC dead lock bug)\n", netdev->name); } return 0; }