static int netx_eth_rx (struct eth_device *edev) { struct netx_eth_priv *priv = (struct netx_eth_priv *)edev->priv; int xcno = priv->xcno; unsigned int val, frameno, seg, len; if(!PFIFO_REG( PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(xcno)))) { return 0; } val = PFIFO_REG( PFIFO_BASE(IND_FIFO_PORT_LO(xcno)) ); frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT; seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT; len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT; /* get data */ memcpy((void*)NetRxPackets[0], (void *)(SRAM_BASE(seg) + frameno * 1560), len); /* pass to barebox */ net_receive(NetRxPackets[0], len); PFIFO_REG(PFIFO_BASE(EMPTY_PTR_FIFO(xcno))) = FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno); return 0; }
static int netx_eth_send (struct eth_device *edev, void *packet, int length) { struct netx_eth_priv *priv = (struct netx_eth_priv *)edev->priv; int xcno = priv->xcno; unsigned int val; int timeout = 500; unsigned char *dst = (unsigned char *)(SRAM_BASE(xcno) + 1560); memcpy(dst, (void *)packet, length); if( length < 60 ) { memset(dst + length, 0, 60 - length); length = 60; } PFIFO_REG(PFIFO_BASE(REQ_FIFO_PORT_LO(xcno))) = FIFO_PTR_SEGMENT(xcno) | FIFO_PTR_FRAMENO(1) | FIFO_PTR_FRAMELEN(length); while (!PFIFO_REG( PFIFO_FILL_LEVEL(CON_FIFO_PORT_LO(xcno))) && timeout) { timeout--; udelay(100); } #if 0 if (!timeout) { loadxc(0); loadxc(1); eth_init(gd->bd); return -1; } #endif val = PFIFO_REG( PFIFO_BASE(CON_FIFO_PORT_LO(xcno)) ); if((val & FIFO_PTR_ERROR_MASK) & 0x8) printf("error sending frame: %d\n",val); return 0; }
static int netx_eth_init_dev(struct eth_device *edev) { struct netx_eth_priv *priv = (struct netx_eth_priv *)edev->priv; int xcno = priv->xcno; int i; loadxc(xcno); /* Fill empty pointer fifo */ for (i = 2; i <= 18; i++) PFIFO_REG( PFIFO_BASE(EMPTY_PTR_FIFO(xcno)) ) = FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(xcno); return 0; }