⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winbond-840.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
					   skb->data[4], skb->data[5], skb->data[6], skb->data[7],					   skb->data[8], skb->data[9], skb->data[10],					   skb->data[11], skb->data[12], skb->data[13],					   skb->data[14], skb->data[15], skb->data[16],					   skb->data[17]);#endif			skb->protocol = eth_type_trans(skb, dev);			netif_rx(skb);			dev->last_rx = jiffies;			np->stats.rx_packets++;			np->stats.rx_bytes += pkt_len;		}		entry = (++np->cur_rx) % RX_RING_SIZE;		np->rx_head_desc = &np->rx_ring[entry];	}	/* Refill the Rx ring buffers. */	for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {		struct sk_buff *skb;		entry = np->dirty_rx % RX_RING_SIZE;		if (np->rx_skbuff[entry] == NULL) {			skb = dev_alloc_skb(np->rx_buf_sz);			np->rx_skbuff[entry] = skb;			if (skb == NULL)				break;			/* Better luck next round. */			skb->dev = dev;			/* Mark as being used by this device. */			np->rx_addr[entry] = pci_map_single(np->pci_dev,							skb->data,							skb->len, PCI_DMA_FROMDEVICE);			np->rx_ring[entry].buffer1 = np->rx_addr[entry];		}		wmb();		np->rx_ring[entry].status = DescOwn;	}	return 0;}static void netdev_error(struct net_device *dev, int intr_status){	struct netdev_private *np = netdev_priv(dev);	void __iomem *ioaddr = np->base_addr;	if (debug > 2)		printk(KERN_DEBUG "%s: Abnormal event, %8.8x.\n",			   dev->name, intr_status);	if (intr_status == 0xffffffff)		return;	spin_lock(&np->lock);	if (intr_status & TxFIFOUnderflow) {		int new;		/* Bump up the Tx threshold */#if 0		/* This causes lots of dropped packets,		 * and under high load even tx_timeouts		 */		new = np->csr6 + 0x4000;#else		new = (np->csr6 >> 14)&0x7f;		if (new < 64)			new *= 2;		 else		 	new = 127; /* load full packet before starting */		new = (np->csr6 & ~(0x7F << 14)) | (new<<14);#endif		printk(KERN_DEBUG "%s: Tx underflow, new csr6 %8.8x.\n",			   dev->name, new);		update_csr6(dev, new);	}	if (intr_status & IntrRxDied) {		/* Missed a Rx frame. */		np->stats.rx_errors++;	}	if (intr_status & TimerInt) {		/* Re-enable other interrupts. */		if (netif_device_present(dev))			iowrite32(0x1A0F5, ioaddr + IntrEnable);	}	np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;	iowrite32(0, ioaddr + RxStartDemand);	spin_unlock(&np->lock);}static struct net_device_stats *get_stats(struct net_device *dev){	struct netdev_private *np = netdev_priv(dev);	void __iomem *ioaddr = np->base_addr;	/* The chip only need report frame silently dropped. */	spin_lock_irq(&np->lock);	if (netif_running(dev) && netif_device_present(dev))		np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;	spin_unlock_irq(&np->lock);	return &np->stats;}static u32 __set_rx_mode(struct net_device *dev){	struct netdev_private *np = netdev_priv(dev);	void __iomem *ioaddr = np->base_addr;	u32 mc_filter[2];			/* Multicast hash filter */	u32 rx_mode;	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */		/* Unconditionally log net taps. */		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);		memset(mc_filter, 0xff, sizeof(mc_filter));		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAllPhys			| AcceptMyPhys;	} else if ((dev->mc_count > multicast_filter_limit)			   ||  (dev->flags & IFF_ALLMULTI)) {		/* Too many to match, or accept all multicasts. */		memset(mc_filter, 0xff, sizeof(mc_filter));		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;	} else {		struct dev_mc_list *mclist;		int i;		memset(mc_filter, 0, sizeof(mc_filter));		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;			 i++, mclist = mclist->next) {			int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;			filterbit &= 0x3f;			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);		}		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;	}	iowrite32(mc_filter[0], ioaddr + MulticastFilter0);	iowrite32(mc_filter[1], ioaddr + MulticastFilter1);	return rx_mode;}static void set_rx_mode(struct net_device *dev){	struct netdev_private *np = netdev_priv(dev);	u32 rx_mode = __set_rx_mode(dev);	spin_lock_irq(&np->lock);	update_csr6(dev, (np->csr6 & ~0x00F8) | rx_mode);	spin_unlock_irq(&np->lock);}static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info){	struct netdev_private *np = netdev_priv(dev);	strcpy (info->driver, DRV_NAME);	strcpy (info->version, DRV_VERSION);	strcpy (info->bus_info, pci_name(np->pci_dev));}static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd){	struct netdev_private *np = netdev_priv(dev);	int rc;	spin_lock_irq(&np->lock);	rc = mii_ethtool_gset(&np->mii_if, cmd);	spin_unlock_irq(&np->lock);	return rc;}static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd){	struct netdev_private *np = netdev_priv(dev);	int rc;	spin_lock_irq(&np->lock);	rc = mii_ethtool_sset(&np->mii_if, cmd);	spin_unlock_irq(&np->lock);	return rc;}static int netdev_nway_reset(struct net_device *dev){	struct netdev_private *np = netdev_priv(dev);	return mii_nway_restart(&np->mii_if);}static u32 netdev_get_link(struct net_device *dev){	struct netdev_private *np = netdev_priv(dev);	return mii_link_ok(&np->mii_if);}static u32 netdev_get_msglevel(struct net_device *dev){	return debug;}static void netdev_set_msglevel(struct net_device *dev, u32 value){	debug = value;}static struct ethtool_ops netdev_ethtool_ops = {	.get_drvinfo		= netdev_get_drvinfo,	.get_settings		= netdev_get_settings,	.set_settings		= netdev_set_settings,	.nway_reset		= netdev_nway_reset,	.get_link		= netdev_get_link,	.get_msglevel		= netdev_get_msglevel,	.set_msglevel		= netdev_set_msglevel,	.get_sg			= ethtool_op_get_sg,	.get_tx_csum		= ethtool_op_get_tx_csum,};static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){	struct mii_ioctl_data *data = if_mii(rq);	struct netdev_private *np = netdev_priv(dev);	switch(cmd) {	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */		data->phy_id = ((struct netdev_private *)netdev_priv(dev))->phys[0] & 0x1f;		/* Fall Through */	case SIOCGMIIREG:		/* Read MII PHY register. */		spin_lock_irq(&np->lock);		data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);		spin_unlock_irq(&np->lock);		return 0;	case SIOCSMIIREG:		/* Write MII PHY register. */		if (!capable(CAP_NET_ADMIN))			return -EPERM;		spin_lock_irq(&np->lock);		mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);		spin_unlock_irq(&np->lock);		return 0;	default:		return -EOPNOTSUPP;	}}static int netdev_close(struct net_device *dev){	struct netdev_private *np = netdev_priv(dev);	void __iomem *ioaddr = np->base_addr;	netif_stop_queue(dev);	if (debug > 1) {		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %8.8x "			   "Config %8.8x.\n", dev->name, ioread32(ioaddr + IntrStatus),			   ioread32(ioaddr + NetworkConfig));		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);	} 	/* Stop the chip's Tx and Rx processes. */	spin_lock_irq(&np->lock);	netif_device_detach(dev);	update_csr6(dev, 0);	iowrite32(0x0000, ioaddr + IntrEnable);	spin_unlock_irq(&np->lock);	free_irq(dev->irq, dev);	wmb();	netif_device_attach(dev);	if (ioread32(ioaddr + NetworkConfig) != 0xffffffff)		np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;#ifdef __i386__	if (debug > 2) {		int i;		printk(KERN_DEBUG"  Tx ring at %8.8x:\n",			   (int)np->tx_ring);		for (i = 0; i < TX_RING_SIZE; i++)			printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n",				   i, np->tx_ring[i].length,				   np->tx_ring[i].status, np->tx_ring[i].buffer1);		printk("\n"KERN_DEBUG "  Rx ring %8.8x:\n",			   (int)np->rx_ring);		for (i = 0; i < RX_RING_SIZE; i++) {			printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",				   i, np->rx_ring[i].length,				   np->rx_ring[i].status, np->rx_ring[i].buffer1);		}	}#endif /* __i386__ debugging only */	del_timer_sync(&np->timer);	free_rxtx_rings(np);	free_ringdesc(np);	return 0;}static void __devexit w840_remove1 (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);		if (dev) {		struct netdev_private *np = netdev_priv(dev);		unregister_netdev(dev);		pci_release_regions(pdev);		pci_iounmap(pdev, np->base_addr);		free_netdev(dev);	}	pci_set_drvdata(pdev, NULL);}#ifdef CONFIG_PM/* * suspend/resume synchronization: * - open, close, do_ioctl: * 	rtnl_lock, & netif_device_detach after the rtnl_unlock. * - get_stats: * 	spin_lock_irq(np->lock), doesn't touch hw if not present * - hard_start_xmit: * 	netif_stop_queue + spin_unlock_wait(&dev->xmit_lock); * - tx_timeout: * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock); * - set_multicast_list * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock); * - interrupt handler * 	doesn't touch hw if not present, synchronize_irq waits for * 	running instances of the interrupt handler. * * Disabling hw requires clearing csr6 & IntrEnable. * update_csr6 & all function that write IntrEnable check netif_device_present * before settings any bits. * * Detach must occur under spin_unlock_irq(), interrupts from a detached * device would cause an irq storm. */static int w840_suspend (struct pci_dev *pdev, pm_message_t state){	struct net_device *dev = pci_get_drvdata (pdev);	struct netdev_private *np = netdev_priv(dev);	void __iomem *ioaddr = np->base_addr;	rtnl_lock();	if (netif_running (dev)) {		del_timer_sync(&np->timer);		spin_lock_irq(&np->lock);		netif_device_detach(dev);		update_csr6(dev, 0);		iowrite32(0, ioaddr + IntrEnable);		netif_stop_queue(dev);		spin_unlock_irq(&np->lock);		spin_unlock_wait(&dev->xmit_lock);		synchronize_irq(dev->irq);			np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;		/* no more hardware accesses behind this line. */		if (np->csr6) BUG();		if (ioread32(ioaddr + IntrEnable)) BUG();		/* pci_power_off(pdev, -1); */		free_rxtx_rings(np);	} else {		netif_device_detach(dev);	}	rtnl_unlock();	return 0;}static int w840_resume (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata (pdev);	struct netdev_private *np = netdev_priv(dev);	rtnl_lock();	if (netif_device_present(dev))		goto out; /* device not suspended */	if (netif_running(dev)) {		pci_enable_device(pdev);	/*	pci_power_on(pdev); */		spin_lock_irq(&np->lock);		iowrite32(1, np->base_addr+PCIBusCfg);		ioread32(np->base_addr+PCIBusCfg);		udelay(1);		netif_device_attach(dev);		init_rxtx_rings(dev);		init_registers(dev);		spin_unlock_irq(&np->lock);		netif_wake_queue(dev);		mod_timer(&np->timer, jiffies + 1*HZ);	} else {		netif_device_attach(dev);	}out:	rtnl_unlock();	return 0;}#endifstatic struct pci_driver w840_driver = {	.name		= DRV_NAME,	.id_table	= w840_pci_tbl,	.probe		= w840_probe1,	.remove		= __devexit_p(w840_remove1),#ifdef CONFIG_PM	.suspend	= w840_suspend,	.resume		= w840_resume,#endif};static int __init w840_init(void){	printk(version);	return pci_module_init(&w840_driver);}static void __exit w840_exit(void){	pci_unregister_driver(&w840_driver);}module_init(w840_init);module_exit(w840_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -