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 void netx_eth_receive(struct net_device *ndev) { struct netx_eth_priv *priv = netdev_priv(ndev); unsigned int val, frameno, seg, len; unsigned char *data; struct sk_buff *skb; val = pfifo_pop(IND_FIFO_PORT_LO(priv->id)); 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; skb = netdev_alloc_skb(ndev, len); if (unlikely(skb == NULL)) { printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", ndev->name); ndev->stats.rx_dropped++; return; } data = skb_put(skb, len); memcpy_fromio(data, priv->sram_base + frameno * 1560, len); pfifo_push(EMPTY_PTR_FIFO(priv->id), FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno)); skb->protocol = eth_type_trans(skb, ndev); netif_rx(skb); ndev->stats.rx_packets++; ndev->stats.rx_bytes += len; }
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; }
static void netx_eth_timeout(struct net_device *ndev) { struct netx_eth_priv *priv = netdev_priv(ndev); int i; printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name); spin_lock_irq(&priv->lock); xc_reset(priv->xc); xc_start(priv->xc); for (i=2; i<=18; i++) pfifo_push(EMPTY_PTR_FIFO(priv->id), FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id)); spin_unlock_irq(&priv->lock); netif_wake_queue(ndev); }