示例#1
0
文件: ibmlana.c 项目: xricson/knoppix
static void ibmlana_set_multicast_list(struct net_device *dev)
{
	/* first stop the SONIC... */
	StopSONIC(dev);
	/* ...then reinit it with the new flags */
	InitBoard(dev);
}
示例#2
0
static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	int retval = 0, tmplen, addr;
	unsigned long flags;
	tda_t tda;
	int baddr;

	/* if we get called with a NULL descriptor, the Ethernet layer thinks 
	   our card is stuck an we should reset it.  We'll do this completely: */

	if (skb == NULL) {
		printk("%s: Resetting SONIC\n", dev->name);
		StopSONIC(dev);
		InitBoard(dev);
		return 0;	/* don't try to free the block here ;-) */
	}

	/* find out if there are free slots for a frame to transmit. If not,
	   the upper layer is in deep desperation and we simply ignore the frame. */

	if (priv->txusedcnt >= TXBUFCNT) {
		retval = -EIO;
		priv->stat.tx_dropped++;
		goto tx_done;
	}

	/* copy the frame data into the next free transmit buffer - fillup missing */

	tmplen = skb->len;
	if (tmplen < 60)
		tmplen = 60;
	baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
	IBMLANA_TOIO(dev->mem_start + baddr, skb->data, skb->len);

	/* copy filler into RAM - in case we're filling up... 
	   we're filling a bit more than necessary, but that doesn't harm
	   since the buffer is far larger... 
	   Sorry Linus for the filler string but I couldn't resist ;-) */

	if (tmplen > skb->len) {
		char *fill = "NetBSD is a nice OS too! ";
		unsigned int destoffs = skb->len, l = strlen(fill);

		while (destoffs < tmplen) {
			IBMLANA_TOIO(dev->mem_start + baddr + destoffs,
				     fill, l);
			destoffs += l;
		}
	}

	/* set up the new frame descriptor */

	addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
	IBMLANA_FROMIO(&tda, dev->mem_start + addr, sizeof(tda_t));
	tda.length = tda.fraglength = tmplen;
	IBMLANA_TOIO(dev->mem_start + addr, &tda, sizeof(tda_t));

	/* if there were no active descriptors, trigger the SONIC */

	save_flags(flags);
	cli();

	priv->txusedcnt++;
	priv->txused[priv->nexttxdescr] = 1;

	/* are all transmission slots used up ? */

	if (priv->txusedcnt >= TXBUFCNT)
#if (LINUX_VERSION_CODE >= 0x02032a)
		netif_stop_queue(dev);
#else
		dev->tbusy = 1;
#endif

	if (priv->txusedcnt == 1)
		StartTx(dev, priv->nexttxdescr);
	priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT;

	restore_flags(flags);

      tx_done:

	/* When did that change exactly ? */

#if (LINUX_VERSION_CODE >= 0x20200)
	dev_kfree_skb(skb);
#else
	dev_kfree_skb(skb, FREE_WRITE);
#endif
	return retval;
}