/*
 * Open/initialize the board. This is called (in the current kernel)
 * sometime after booting when the 'ifconfig' program is run.
 *
 * This routine should set everything up anew at each open, even
 * registers that "should" only need to be set once at boot, so that
 * there is non-reboot way to recover if something goes wrong.
 */
static int
net_open(struct net_device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	struct sk_buff *skb;
	int irqval;
	int i;

	MOD_INC_USE_COUNT;

	/* For now we always do Eth1 */
	lp->uEth = uETH1;

	BUGMSG("%s:Opening Ethernet interface ", dev->name);
	if(lp->uEth == uETH1) {
		BUGMSG("1\n");
		dev->irq = IRQ_ETH1;
	} else {
		BUGMSG("2\n");
		dev->irq = IRQ_ETH2;
	}
	irqval = request_irq(dev->irq, &net_interrupt, SA_INTERRUPT, cardname, NULL);

	if (irqval) {
		printk("%s: unable to get IRQ %d (irqval=%d).\n",
			   dev->name, dev->irq, irqval);
		return -EAGAIN;
	}

	/* Allocate Ethernet RX buffers */
	for( i = 0; i < ETH_RXQ_SIZE; i++ ) {
		skb = dev_alloc_skb( PKT_BUF_SZ );
		if (skb == NULL) {
			printk("%s: Could not allocate RX Ring buffer\n", dev->name);
			while(i != 0)
				dev_kfree_skb(lp->rx_frames[--i]);

			return -ENOMEM;
		}
		skb->dev = dev;
		skb->protocol = eth_type_trans(skb, dev);
		skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
		/* word align IP header */
		skb_reserve( skb, 2 );
    		lp->rx_frames[i] = skb;
	}
	lp->rxq_ptr = 0;
	lp->txq_p = 0;
	lp->txq_c = 0;

	BUGMSG("%s: Resetting hardware\n", dev->name);
	/* Reset the hardware here. */
	chipset_init( dev, 1 );
	lp->open_time = jiffies;

	BUGMSG("%s: netif_start_queue\n", dev->name);
	netif_start_queue(dev);
	return 0;
}
Example #2
0
static int
net_send_packet(struct sk_buff *skb, struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	int ioaddr = dev->base_addr;

	if (dev->tbusy) {
		/* If we get here, some higher level has decided we are broken.
		   There should really be a "kick me" function call instead. */
		int tickssofar = jiffies - dev->trans_start;
		if (tickssofar < 5)
			return 1;
		printk("%s: transmit timed out, %s?\n", dev->name,
			   tx_done(dev) ? "IRQ conflict" : "network cable problem");
		/* Try to restart the adaptor. */
		chipset_init(dev, 1);
		dev->tbusy=0;
		dev->trans_start = jiffies;
	}

	/* If some higher layer thinks we've missed an tx-done interrupt
	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
	   itself. */
	if (skb == NULL) {
		dev_tint(dev);
		return 0;
	}

	/* For ethernet, fill in the header.  This should really be done by a
	   higher level, rather than duplicated for each ethernet adaptor. */
	if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
		skb->dev = dev;
		arp_queue (skb);
		return 0;
	}
	skb->arp=1;

	/* Block a timer-based transmit from overlapping.  This could better be
	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
	if (set_bit(0, (void*)&dev->tbusy) != 0)
		printk("%s: Transmitter access conflict.\n", dev->name);
	else {
		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
		unsigned char *buf = skb->data;

		hardware_send_packet(ioaddr, buf, length);
		dev->trans_start = jiffies;
	}
	if (skb->free)
		kfree_skb (skb, FREE_WRITE);

	/* You might need to clean up and record Tx statistics here. */
	if (inw(ioaddr) == /*RU*/81)
		lp->stats.tx_aborted_errors++;

	return 0;
}
Example #3
0
static int cl_set_var(struct fb_info *info, const struct fb_var_screeninfo *var) {
	cirrus_chip_info.doubleVCLK = 0;
	cirrus_chip_info.multiplexing = 0;
	cirrus_chip_info.screen_info = var;
	cirrus_chip_info.screen_base = info->screen_base;

	chipset_init(&cirrus_chip_info);

	setup_resolution(&cirrus_chip_info);

	cirrus_setup_bits_per_pixel(&cirrus_chip_info);

	vga_display_enable(1);

	return 0;
}