Exemplo n.º 1
0
static int
ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	struct net_device *dev;
	int i, ret = 0;

	ether1_banner();

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	dev = alloc_etherdev(sizeof(struct ether1_priv));
	if (!dev) {
		ret = -ENOMEM;
		goto release;
	}

	SET_NETDEV_DEV(dev, &ec->dev);

	dev->irq = ec->irq;
	priv(dev)->base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
	if (!priv(dev)->base) {
		ret = -ENOMEM;
		goto free;
	}

	if ((priv(dev)->bus_type = ether1_reset(dev)) == 0) {
		ret = -ENODEV;
		goto free;
	}

	for (i = 0; i < 6; i++)
		dev->dev_addr[i] = readb(IDPROM_ADDRESS + (i << 2));

	if (ether1_init_2(dev)) {
		ret = -ENODEV;
		goto free;
	}

	dev->netdev_ops		= &ether1_netdev_ops;
	dev->watchdog_timeo	= 5 * HZ / 100;

	ret = register_netdev(dev);
	if (ret)
		goto free;

	printk(KERN_INFO "%s: ether1 in slot %d, %pM\n",
		dev->name, ec->slot_no, dev->dev_addr);
    
	ecard_set_drvdata(ec, dev);
	return 0;

 free:
	free_netdev(dev);
 release:
	ecard_release_resources(ec);
 out:
	return ret;
}
Exemplo n.º 2
0
static int
ether1_close (struct net_device *dev)
{
	ether1_reset (dev);

	free_irq(dev->irq, dev);

	return 0;
}
Exemplo n.º 3
0
static void
ether1_timeout(struct net_device *dev)
{
	printk(KERN_WARNING "%s: transmit timeout, network cable problem?\n",
		dev->name);
	printk(KERN_WARNING "%s: resetting device\n", dev->name);

	ether1_reset (dev);

	if (ether1_init_for_open (dev))
		printk (KERN_ERR "%s: unable to restart interface\n", dev->name);

	dev->stats.tx_errors++;
	netif_wake_queue(dev);
}
Exemplo n.º 4
0
static int
ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
{
	int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
	unsigned long flags;
	tx_t tx;
	tbd_t tbd;
	nop_t nop;

	if (priv(dev)->restart) {
		printk(KERN_WARNING "%s: resetting device\n", dev->name);

		ether1_reset(dev);

		if (ether1_init_for_open(dev))
			printk(KERN_ERR "%s: unable to restart interface\n", dev->name);
		else
			priv(dev)->restart = 0;
	}

	if (skb->len < ETH_ZLEN) {
		if (skb_padto(skb, ETH_ZLEN))
			goto out;
	}

	/*
	 * insert packet followed by a nop
	 */
	txaddr = ether1_txalloc (dev, TX_SIZE);
	tbdaddr = ether1_txalloc (dev, TBD_SIZE);
	dataddr = ether1_txalloc (dev, skb->len);
	nopaddr = ether1_txalloc (dev, NOP_SIZE);

	tx.tx_status = 0;
	tx.tx_command = CMD_TX | CMD_INTR;
	tx.tx_link = nopaddr;
	tx.tx_tbdoffset = tbdaddr;
	tbd.tbd_opts = TBD_EOL | skb->len;
	tbd.tbd_link = I82586_NULL;
	tbd.tbd_bufl = dataddr;
	tbd.tbd_bufh = 0;
	nop.nop_status = 0;
	nop.nop_command = CMD_NOP;
	nop.nop_link = nopaddr;

	local_irq_save(flags);
	ether1_writebuffer (dev, &tx, txaddr, TX_SIZE);
	ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE);
	ether1_writebuffer (dev, skb->data, dataddr, skb->len);
	ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE);
	tmp = priv(dev)->tx_link;
	priv(dev)->tx_link = nopaddr;

	/* now reset the previous nop pointer */
	ether1_writew(dev, txaddr, tmp, nop_t, nop_link, NORMALIRQS);

	local_irq_restore(flags);

	/* handle transmit */

	/* check to see if we have room for a full sized ether frame */
	tmp = priv(dev)->tx_head;
	tst = ether1_txalloc (dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN);
	priv(dev)->tx_head = tmp;
	dev_kfree_skb (skb);

	if (tst == -1)
		netif_stop_queue(dev);

 out:
	return NETDEV_TX_OK;
}
Exemplo n.º 5
0
static int
ether1_init_for_open (struct net_device *dev)
{
	int i, status, addr, next, next2;
	int failures = 0;
	unsigned long timeout;

	writeb(CTRL_RST|CTRL_ACK, REG_CONTROL);

	for (i = 0; i < 6; i++)
		init_sa.sa_addr[i] = dev->dev_addr[i];

	/* load data structures into ether1 RAM */
	ether1_writebuffer (dev, &init_scp,  SCP_ADDR,  SCP_SIZE);
	ether1_writebuffer (dev, &init_iscp, ISCP_ADDR, ISCP_SIZE);
	ether1_writebuffer (dev, &init_scb,  SCB_ADDR,  SCB_SIZE);
	ether1_writebuffer (dev, &init_cfg,  CFG_ADDR,  CFG_SIZE);
	ether1_writebuffer (dev, &init_sa,   SA_ADDR,   SA_SIZE);
	ether1_writebuffer (dev, &init_mc,   MC_ADDR,   MC_SIZE);
	ether1_writebuffer (dev, &init_tdr,  TDR_ADDR,  TDR_SIZE);
	ether1_writebuffer (dev, &init_nop,  NOP_ADDR,  NOP_SIZE);

	if (ether1_readw(dev, CFG_ADDR, cfg_t, cfg_command, NORMALIRQS) != CMD_CONFIG) {
		printk (KERN_ERR "%s: detected either RAM fault or compiler bug\n",
			dev->name);
		return 1;
	}

	/*
	 * setup circularly linked list of { rfd, rbd, buffer }, with
	 * all rfds circularly linked, rbds circularly linked.
	 * First rfd is linked to scp, first rbd is linked to first
	 * rfd.  Last rbd has a suspend command.
	 */
	addr = RX_AREA_START;
	do {
		next = addr + RFD_SIZE + RBD_SIZE + ETH_FRAME_LEN + 10;
		next2 = next + RFD_SIZE + RBD_SIZE + ETH_FRAME_LEN + 10;

		if (next2 >= RX_AREA_END) {
			next = RX_AREA_START;
			init_rfd.rfd_command = RFD_CMDEL | RFD_CMDSUSPEND;
			priv(dev)->rx_tail = addr;
		} else
			init_rfd.rfd_command = 0;
		if (addr == RX_AREA_START)
			init_rfd.rfd_rbdoffset = addr + RFD_SIZE;
		else
			init_rfd.rfd_rbdoffset = 0;
		init_rfd.rfd_link = next;
		init_rbd.rbd_link = next + RFD_SIZE;
		init_rbd.rbd_bufl = addr + RFD_SIZE + RBD_SIZE;

		ether1_writebuffer (dev, &init_rfd, addr, RFD_SIZE);
		ether1_writebuffer (dev, &init_rbd, addr + RFD_SIZE, RBD_SIZE);
		addr = next;
	} while (next2 < RX_AREA_END);

	priv(dev)->tx_link = NOP_ADDR;
	priv(dev)->tx_head = NOP_ADDR + NOP_SIZE;
	priv(dev)->tx_tail = TDR_ADDR;
	priv(dev)->rx_head = RX_AREA_START;

	/* release reset & give 586 a prod */
	priv(dev)->resetting = 1;
	priv(dev)->initialising = 1;
	writeb(CTRL_RST, REG_CONTROL);
	writeb(0, REG_CONTROL);
	writeb(CTRL_CA, REG_CONTROL);

	/* 586 should now unset iscp.busy */
	timeout = jiffies + HZ/2;
	while (ether1_readw(dev, ISCP_ADDR, iscp_t, iscp_busy, DISABLEIRQS) == 1) {
		if (time_after(jiffies, timeout)) {
			printk (KERN_WARNING "%s: can't initialise 82586: iscp is busy\n", dev->name);
			return 1;
		}
	}

	/* check status of commands that we issued */
	timeout += HZ/10;
	while (((status = ether1_readw(dev, CFG_ADDR, cfg_t, cfg_status, DISABLEIRQS))
			& STAT_COMPLETE) == 0) {
		if (time_after(jiffies, timeout))
			break;
	}

	if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
		printk (KERN_WARNING "%s: can't initialise 82586: config status %04X\n", dev->name, status);
		printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
			ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
		failures += 1;
	}

	timeout += HZ/10;
	while (((status = ether1_readw(dev, SA_ADDR, sa_t, sa_status, DISABLEIRQS))
			& STAT_COMPLETE) == 0) {
		if (time_after(jiffies, timeout))
			break;
	}

	if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
		printk (KERN_WARNING "%s: can't initialise 82586: set address status %04X\n", dev->name, status);
		printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
			ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
		failures += 1;
	}

	timeout += HZ/10;
	while (((status = ether1_readw(dev, MC_ADDR, mc_t, mc_status, DISABLEIRQS))
			& STAT_COMPLETE) == 0) {
		if (time_after(jiffies, timeout))
			break;
	}

	if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
		printk (KERN_WARNING "%s: can't initialise 82586: set multicast status %04X\n", dev->name, status);
		printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
			ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
		failures += 1;
	}

	timeout += HZ;
	while (((status = ether1_readw(dev, TDR_ADDR, tdr_t, tdr_status, DISABLEIRQS))
			& STAT_COMPLETE) == 0) {
		if (time_after(jiffies, timeout))
			break;
	}

	if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
		printk (KERN_WARNING "%s: can't tdr (ignored)\n", dev->name);
		printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
			ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
			ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
	} else {
		status = ether1_readw(dev, TDR_ADDR, tdr_t, tdr_result, DISABLEIRQS);
		if (status & TDR_XCVRPROB)
			printk (KERN_WARNING "%s: i/f failed tdr: transceiver problem\n", dev->name);
		else if ((status & (TDR_SHORT|TDR_OPEN)) && (status & TDR_TIME)) {
#ifdef FANCY
			printk (KERN_WARNING "%s: i/f failed tdr: cable %s %d.%d us away\n", dev->name,
				status & TDR_SHORT ? "short" : "open", (status & TDR_TIME) / 10,
				(status & TDR_TIME) % 10);
#else
			printk (KERN_WARNING "%s: i/f failed tdr: cable %s %d clks away\n", dev->name,
				status & TDR_SHORT ? "short" : "open", (status & TDR_TIME));
#endif
		}
	}

	if (failures)
		ether1_reset (dev);
	return failures ? 1 : 0;
}
Exemplo n.º 6
0
static int __devinit
ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	struct net_device *dev;
	int i, ret = 0;

	ether1_banner();

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	dev = alloc_etherdev(sizeof(struct ether1_priv));
	if (!dev) {
		ret = -ENOMEM;
		goto release;
	}

	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &ec->dev);

	dev->irq = ec->irq;
	priv(dev)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
				  ecard_resource_len(ec, ECARD_RES_IOCFAST));
	if (!priv(dev)->base) {
		ret = -ENOMEM;
		goto free;
	}

	if ((priv(dev)->bus_type = ether1_reset(dev)) == 0) {
		ret = -ENODEV;
		goto free;
	}

	for (i = 0; i < 6; i++)
		dev->dev_addr[i] = readb(IDPROM_ADDRESS + (i << 2));

	if (ether1_init_2(dev)) {
		ret = -ENODEV;
		goto free;
	}

	dev->open		= ether1_open;
	dev->stop		= ether1_close;
	dev->hard_start_xmit    = ether1_sendpacket;
	dev->get_stats		= ether1_getstats;
	dev->set_multicast_list = ether1_setmulticastlist;
	dev->tx_timeout		= ether1_timeout;
	dev->watchdog_timeo	= 5 * HZ / 100;

	ret = register_netdev(dev);
	if (ret)
		goto free;

	printk(KERN_INFO "%s: ether1 in slot %d, ",
		dev->name, ec->slot_no);
    
	for (i = 0; i < 6; i++)
		printk ("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');

	ecard_set_drvdata(ec, dev);
	return 0;

 free:
	if (priv(dev)->base)
		iounmap(priv(dev)->base);
	free_netdev(dev);
 release:
	ecard_release_resources(ec);
 out:
	return ret;
}