Ejemplo n.º 1
0
void pnic_lnk_change(struct net_device *dev, int csr5)
{
	struct tulip_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->base_addr;
	int phy_reg = ioread32(ioaddr + 0xB8);

	if (tulip_debug > 1)
		netdev_dbg(dev, "PNIC link changed state %08x, CSR5 %08x\n",
			   phy_reg, csr5);
	if (ioread32(ioaddr + CSR5) & TPLnkFail) {
		iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
		/* If we use an external MII, then we mustn't use the
		 * internal negotiation.
		 */
		if (tulip_media_cap[dev->if_port] & MediaIsMII)
			return;
		if (! tp->nwayset || time_after(jiffies, dev_trans_start(dev) + 1*HZ)) {
			tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
			iowrite32(tp->csr6, ioaddr + CSR6);
			iowrite32(0x30, ioaddr + CSR12);
			iowrite32(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
			dev->trans_start = jiffies;
		}
	} else if (ioread32(ioaddr + CSR5) & TPLnkPass) {
		if (tulip_media_cap[dev->if_port] & MediaIsMII) {
			spin_lock(&tp->lock);
			tulip_check_duplex(dev);
			spin_unlock(&tp->lock);
		} else {
			pnic_do_nway(dev);
		}
		iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7);
	}
}
Ejemplo n.º 2
0
static void fjes_tx_stall_task(struct work_struct *work)
{
	struct fjes_adapter *adapter = container_of(work,
			struct fjes_adapter, tx_stall_task);
	struct net_device *netdev = adapter->netdev;
	struct fjes_hw *hw = &adapter->hw;
	int all_queue_available, sendable;
	enum ep_partner_status pstatus;
	int max_epid, my_epid, epid;
	union ep_buffer_info *info;
	int i;

	if (((long)jiffies -
		dev_trans_start(netdev)) > FJES_TX_TX_STALL_TIMEOUT) {
		netif_wake_queue(netdev);
		return;
	}

	my_epid = hw->my_epid;
	max_epid = hw->max_epid;

	for (i = 0; i < 5; i++) {
		all_queue_available = 1;

		for (epid = 0; epid < max_epid; epid++) {
			if (my_epid == epid)
				continue;

			pstatus = fjes_hw_get_partner_ep_status(hw, epid);
			sendable = (pstatus == EP_PARTNER_SHARED);
			if (!sendable)
				continue;

			info = adapter->hw.ep_shm_info[epid].tx.info;

			if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE))
				return;

			if (EP_RING_FULL(info->v1i.head, info->v1i.tail,
					 info->v1i.count_max)) {
				all_queue_available = 0;
				break;
			}
		}

		if (all_queue_available) {
			netif_wake_queue(netdev);
			return;
		}
	}

	usleep_range(50, 100);

	queue_work(adapter->txrx_wq, &adapter->tx_stall_task);
}
Ejemplo n.º 3
0
static void
qcaspi_netdev_tx_timeout(struct net_device *dev)
{
	struct qcaspi *qca = netdev_priv(dev);

	netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
		    jiffies, jiffies - dev_trans_start(dev));
	qca->net_dev->stats.tx_errors++;
	/* Trigger tx queue flush and QCA7000 reset */
	qca->sync = QCASPI_SYNC_UNKNOWN;

	if (qca->spi_thread)
		wake_up_process(qca->spi_thread);
}
Ejemplo n.º 4
0
static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	unsigned long flags;
	int	transmit_from;
	int	len;
	int	tickssofar;
	u8	*buffer = skb->data;
	int	i;

	if (free_tx_pages <= 0) {	/* Do timeouts, to avoid hangs. */
		tickssofar = jiffies - dev_trans_start(dev);
		if (tickssofar < HZ/20)
			return NETDEV_TX_BUSY;
		/* else */
		printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
		/* Restart the adapter. */
		spin_lock_irqsave(&de600_lock, flags);
		if (adapter_init(dev)) {
			spin_unlock_irqrestore(&de600_lock, flags);
			return NETDEV_TX_BUSY;
		}
		spin_unlock_irqrestore(&de600_lock, flags);
	}

	/* Start real output */
	pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages);

	if ((len = skb->len) < RUNT)
		len = RUNT;

	spin_lock_irqsave(&de600_lock, flags);
	select_nic();
	tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
	tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */

	if(check_lost)
	{
		/* This costs about 40 instructions per packet... */
		de600_setup_address(NODE_ADDRESS, RW_ADDR);
		de600_read_byte(READ_DATA, dev);
		if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
			if (adapter_init(dev)) {
				spin_unlock_irqrestore(&de600_lock, flags);
				return NETDEV_TX_BUSY;
			}
		}
	}

	de600_setup_address(transmit_from, RW_ADDR);
	for (i = 0;  i < skb->len ; ++i, ++buffer)
		de600_put_byte(*buffer);
	for (; i < len; ++i)
		de600_put_byte(0);

	if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
		dev->trans_start = jiffies;
		netif_start_queue(dev); /* allow more packets into adapter */
		/* Send page and generate a faked interrupt */
		de600_setup_address(transmit_from, TX_ADDR);
		de600_put_command(TX_ENABLE);
	}
	else {
		if (free_tx_pages)
			netif_start_queue(dev);
		else
			netif_stop_queue(dev);
		select_prn();
	}
	spin_unlock_irqrestore(&de600_lock, flags);
	dev_kfree_skb(skb);
	return NETDEV_TX_OK;
}