예제 #1
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;
}
예제 #2
0
static int
netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);
	unsigned char *buf = skb->data;
	unsigned int len = skb->len;

	spin_lock_irq(&priv->lock);
	memcpy_toio(priv->sram_base + 1560, (void *)buf, len);
	if (len < 60) {
		memset_io(priv->sram_base + 1560 + len, 0, 60 - len);
		len = 60;
	}

	pfifo_push(REQ_FIFO_PORT_LO(priv->id),
	           FIFO_PTR_SEGMENT(priv->id) |
	           FIFO_PTR_FRAMENO(1) |
	           FIFO_PTR_FRAMELEN(len));

	ndev->stats.tx_packets++;
	ndev->stats.tx_bytes += skb->len;

	netif_stop_queue(ndev);
	spin_unlock_irq(&priv->lock);
	dev_kfree_skb(skb);

	return NETDEV_TX_OK;
}
예제 #3
0
파일: netx_eth.c 프로젝트: cpdesign/barebox
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;
}
예제 #4
0
파일: netx_eth.c 프로젝트: bmourit/barebox
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;
}
예제 #5
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);
}
예제 #6
0
파일: netx_eth.c 프로젝트: cpdesign/barebox
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;
}