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

📄 de2104x.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
		/* TP selected.  If there is only TP and BNC, then it's BNC */		else if (((de->media_supported & DE_AUI_BNC) == SUPPORTED_BNC) &&			 de_ok_to_advertise(de, DE_MEDIA_BNC))			de->media_type = DE_MEDIA_BNC;		/* TP selected.  If there is only TP and AUI, then it's AUI */		else if (((de->media_supported & DE_AUI_BNC) == SUPPORTED_AUI) &&			 de_ok_to_advertise(de, DE_MEDIA_AUI))			de->media_type = DE_MEDIA_AUI;		/* otherwise, ignore the hint */		else			have_media = 0;		if (have_media)			goto set_media;	}	/*	 * Absent or ambiguous activity hint, move to next advertised	 * media state.  If de->media_type is left unchanged, this	 * simply resets the PHY and reloads the current media settings.	 */	if (de->media_type == DE_MEDIA_AUI) {		u32 next_states[] = { DE_MEDIA_BNC, DE_MEDIA_TP_AUTO };		de_next_media(de, next_states, ARRAY_SIZE(next_states));	} else if (de->media_type == DE_MEDIA_BNC) {		u32 next_states[] = { DE_MEDIA_TP_AUTO, DE_MEDIA_AUI };		de_next_media(de, next_states, ARRAY_SIZE(next_states));	} else {		u32 next_states[] = { DE_MEDIA_AUI, DE_MEDIA_BNC, DE_MEDIA_TP_AUTO };		de_next_media(de, next_states, ARRAY_SIZE(next_states));	}	set_media:	spin_lock_irqsave(&de->lock, flags);	de_stop_rxtx(de);	spin_unlock_irqrestore(&de->lock, flags);	de_set_media(de);	de_start_rxtx(de);no_link_yet:	de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;	add_timer(&de->media_timer);	if (netif_msg_timer(de))		printk(KERN_INFO "%s: no link, trying media %s, status %x\n",		       dev->name, media_name[de->media_type], status);}static void de_media_interrupt (struct de_private *de, u32 status){	if (status & LinkPass) {		de_link_up(de);		mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK);		return;	}		if (!(status & LinkFail))		BUG();	if (netif_carrier_ok(de->dev)) {		de_link_down(de);		mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);	}}static int de_reset_mac (struct de_private *de){	u32 status, tmp;	/*	 * Reset MAC.  de4x5.c and tulip.c examined for "advice"	 * in this area.	 */	if (dr32(BusMode) == 0xffffffff)		return -EBUSY;	/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */	dw32 (BusMode, CmdReset);	mdelay (1);	dw32 (BusMode, de_bus_mode);	mdelay (1);	for (tmp = 0; tmp < 5; tmp++) {		dr32 (BusMode);		mdelay (1);	}	mdelay (1);	status = dr32(MacStatus);	if (status & (RxState | TxState))		return -EBUSY;	if (status == 0xffffffff)		return -ENODEV;	return 0;}static void de_adapter_wake (struct de_private *de){	u32 pmctl;	if (de->de21040)		return;	pci_read_config_dword(de->pdev, PCIPM, &pmctl);	if (pmctl & PM_Mask) {		pmctl &= ~PM_Mask;		pci_write_config_dword(de->pdev, PCIPM, pmctl);		/* de4x5.c delays, so we do too */		msleep(10);	}}static void de_adapter_sleep (struct de_private *de){	u32 pmctl;	if (de->de21040)		return;	pci_read_config_dword(de->pdev, PCIPM, &pmctl);	pmctl |= PM_Sleep;	pci_write_config_dword(de->pdev, PCIPM, pmctl);}static int de_init_hw (struct de_private *de){	struct net_device *dev = de->dev;	u32 macmode;	int rc;	de_adapter_wake(de);		macmode = dr32(MacMode) & ~MacModeClear;	rc = de_reset_mac(de);	if (rc)		return rc;	de_set_media(de); /* reset phy */	dw32(RxRingAddr, de->ring_dma);	dw32(TxRingAddr, de->ring_dma + (sizeof(struct de_desc) * DE_RX_RING_SIZE));	dw32(MacMode, RxTx | macmode);	dr32(RxMissed); /* self-clearing */	dw32(IntrMask, de_intr_mask);	de_set_rx_mode(dev);	return 0;}static int de_refill_rx (struct de_private *de){	unsigned i;	for (i = 0; i < DE_RX_RING_SIZE; i++) {		struct sk_buff *skb;		skb = dev_alloc_skb(de->rx_buf_sz);		if (!skb)			goto err_out;		skb->dev = de->dev;		de->rx_skb[i].mapping = pci_map_single(de->pdev,			skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE);		de->rx_skb[i].skb = skb;		de->rx_ring[i].opts1 = cpu_to_le32(DescOwn);		if (i == (DE_RX_RING_SIZE - 1))			de->rx_ring[i].opts2 =				cpu_to_le32(RingEnd | de->rx_buf_sz);		else			de->rx_ring[i].opts2 = cpu_to_le32(de->rx_buf_sz);		de->rx_ring[i].addr1 = cpu_to_le32(de->rx_skb[i].mapping);		de->rx_ring[i].addr2 = 0;	}	return 0;err_out:	de_clean_rings(de);	return -ENOMEM;}static int de_init_rings (struct de_private *de){	memset(de->tx_ring, 0, sizeof(struct de_desc) * DE_TX_RING_SIZE);	de->tx_ring[DE_TX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd);	de->rx_tail = 0;	de->tx_head = de->tx_tail = 0;	return de_refill_rx (de);}static int de_alloc_rings (struct de_private *de){	de->rx_ring = pci_alloc_consistent(de->pdev, DE_RING_BYTES, &de->ring_dma);	if (!de->rx_ring)		return -ENOMEM;	de->tx_ring = &de->rx_ring[DE_RX_RING_SIZE];	return de_init_rings(de);}static void de_clean_rings (struct de_private *de){	unsigned i;	memset(de->rx_ring, 0, sizeof(struct de_desc) * DE_RX_RING_SIZE);	de->rx_ring[DE_RX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd);	wmb();	memset(de->tx_ring, 0, sizeof(struct de_desc) * DE_TX_RING_SIZE);	de->tx_ring[DE_TX_RING_SIZE - 1].opts2 = cpu_to_le32(RingEnd);	wmb();	for (i = 0; i < DE_RX_RING_SIZE; i++) {		if (de->rx_skb[i].skb) {			pci_unmap_single(de->pdev, de->rx_skb[i].mapping,					 de->rx_buf_sz, PCI_DMA_FROMDEVICE);			dev_kfree_skb(de->rx_skb[i].skb);		}	}	for (i = 0; i < DE_TX_RING_SIZE; i++) {		struct sk_buff *skb = de->tx_skb[i].skb;		if ((skb) && (skb != DE_DUMMY_SKB)) {			if (skb != DE_SETUP_SKB) {				dev_kfree_skb(skb);				de->net_stats.tx_dropped++;				pci_unmap_single(de->pdev,					de->tx_skb[i].mapping,					skb->len, PCI_DMA_TODEVICE);			} else {				pci_unmap_single(de->pdev,					de->tx_skb[i].mapping,					sizeof(de->setup_frame),					PCI_DMA_TODEVICE);			}		}	}	memset(&de->rx_skb, 0, sizeof(struct ring_info) * DE_RX_RING_SIZE);	memset(&de->tx_skb, 0, sizeof(struct ring_info) * DE_TX_RING_SIZE);}static void de_free_rings (struct de_private *de){	de_clean_rings(de);	pci_free_consistent(de->pdev, DE_RING_BYTES, de->rx_ring, de->ring_dma);	de->rx_ring = NULL;	de->tx_ring = NULL;}static int de_open (struct net_device *dev){	struct de_private *de = dev->priv;	int rc;	unsigned long flags;	if (netif_msg_ifup(de))		printk(KERN_DEBUG "%s: enabling interface\n", dev->name);	de->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);	rc = de_alloc_rings(de);	if (rc) {		printk(KERN_ERR "%s: ring allocation failure, err=%d\n",		       dev->name, rc);		return rc;	}	rc = de_init_hw(de);	if (rc) {		printk(KERN_ERR "%s: h/w init failure, err=%d\n",		       dev->name, rc);		goto err_out_free;	}	rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev);	if (rc) {		printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n",		       dev->name, dev->irq, rc);		goto err_out_hw;	}	netif_start_queue(dev);	mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK);	return 0;err_out_hw:	spin_lock_irqsave(&de->lock, flags);	de_stop_hw(de);	spin_unlock_irqrestore(&de->lock, flags);err_out_free:	de_free_rings(de);	return rc;}static int de_close (struct net_device *dev){	struct de_private *de = dev->priv;	unsigned long flags;	if (netif_msg_ifdown(de))		printk(KERN_DEBUG "%s: disabling interface\n", dev->name);	del_timer_sync(&de->media_timer);	spin_lock_irqsave(&de->lock, flags);	de_stop_hw(de);	netif_stop_queue(dev);	netif_carrier_off(dev);	spin_unlock_irqrestore(&de->lock, flags);		free_irq(dev->irq, dev);	de_free_rings(de);	de_adapter_sleep(de);	pci_disable_device(de->pdev);	return 0;}static void de_tx_timeout (struct net_device *dev){	struct de_private *de = dev->priv;	printk(KERN_DEBUG "%s: NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",	       dev->name, dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),	       de->rx_tail, de->tx_head, de->tx_tail);	del_timer_sync(&de->media_timer);	disable_irq(dev->irq);	spin_lock_irq(&de->lock);	de_stop_hw(de);	netif_stop_queue(dev);	netif_carrier_off(dev);	spin_unlock_irq(&de->lock);	enable_irq(dev->irq);			/* Update the error counts. */	__de_get_stats(de);	synchronize_irq(dev->irq);	de_clean_rings(de);	de_init_hw(de);		netif_wake_queue(dev);}static void __de_get_regs(struct de_private *de, u8 *buf){	int i;	u32 *rbuf = (u32 *)buf;		/* read all CSRs */	for (i = 0; i < DE_NUM_REGS; i++)		rbuf[i] = dr32(i * 8);	/* handle self-clearing RxMissed counter, CSR8 */	de_rx_missed(de, rbuf[8]);}static int __de_get_settings(struct de_private *de, struct ethtool_cmd *ecmd){	ecmd->supported = de->media_supported;	ecmd->transceiver = XCVR_INTERNAL;	ecmd->phy_address = 0;	ecmd->advertising = de->media_advertise;		switch (de->media_type) {	case DE_MEDIA_AUI:		ecmd->port = PORT_AUI;		ecmd->speed = 5;		break;	case DE_MEDIA_BNC:		ecmd->port = PORT_BNC;		ecmd->speed = 2;		break;	default:		ecmd->port = PORT_TP;		ecmd->speed = SPEED_10;		break;	}		if (dr32(MacMode) & FullDuplex)		ecmd->duplex = DUPLEX_FULL;	else		ecmd->duplex = DUPLEX_HALF;	if (de->media_lock)		ecmd->autoneg = AUTONEG_DISABLE;	else		ecmd->autoneg = AUTONEG_ENABLE;	/* ignore maxtxpkt, maxrxpkt for now */	return 0;}static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd){	u32 new_media;	unsigned int media_lock;	if (ecmd->speed != SPEED_10 && ecmd->speed != 5 && ecmd->speed != 2)		return -EINVAL;	if (de->de21040 && ecmd->speed == 2)		return -EINVAL;	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)		return -EINVAL;	if (ecmd->port != PORT_TP && ecmd->port != PORT_AUI && ecmd->port != PORT_BNC)		return -EINVAL;	if (de->de21040 && ecmd->port == PORT_BNC)		return -EINVAL;	if (ecmd->transceiver != XCVR_INTERNAL)		return -EINVAL;	if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)		return -EINVAL;	if (ecmd->advertising & ~de->media_supported)		return -EINVAL;	if (ecmd->autoneg == AUTONEG_ENABLE &&	    (!(ecmd->advertising & ADVERTISED_Autoneg)))		return -EINVAL;		switch (ecmd->port) {	case PORT_AUI:		new_media = DE_MEDIA_AUI;		if (!(ecmd->advertising & ADVERTISED_AUI))			return -EINVAL;		break;	case PORT_BNC:		new_media = DE_MEDIA_BNC;		if (!(ecmd->advertising & ADVERTISED_BNC))			return -EINVAL;		break;	default:		if (ecmd->autoneg == AUTONEG_ENABLE)			new_media = DE_MEDIA_TP_AUTO;		else if (ecmd->duplex == DUPLEX_FULL)			new_media = DE_MEDIA_TP_FD;		else			new_media = DE_MEDIA_TP;		if (!(ecmd->advertising & ADVERTISED_TP))			return -EINVAL;		if (!(ecmd->advertising & (ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half)))			return -EINVAL;		break;	}		media_lock = (ecmd->autoneg == AUTONEG_ENABLE) ? 0 : 1;		if ((new_media == de->media_type) &&	    (media_lock == de->media_lock) &&	    (ecmd->advertising == de->media_advertise))		return 0; /* nothing to change */	    	de_link_down(de);	de_stop_rxtx(de);		de->media_type = new_media;	de->media_lock = media_lock;	de->media_advertise = ecmd->advertising;	de_set_media(de);		return 0;}static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info){	struct de_private *de = dev->priv;	strcpy (info->driver, DRV_NAME);	strcpy (info->version, DRV_VERSION);	strcpy (info->bus_info, pci_name(de->pdev));	info->eedump_len = DE_EEPROM_SIZE;}static int de_get_regs_len(struct net_device *dev){	return DE_REGS_SIZE;}static int de_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd){	struct de_private *de = dev->priv;	int rc;	spin_lock_irq(&de->lock);	rc = __de_get_settings(de, ecmd);	spin_unlock_irq(&de->lock);	return rc;}static int de_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd){	struct de_private *de = dev->priv;	int rc;	spin_lock_irq(&de->lock);	rc = __de_set_settings(de, ecmd);	spin_unlock_irq(&de->lock);	return rc;}static u32 de_get_msglevel(struct net_device *dev){	struct de_private *de = dev->priv;	return de->msg_enable;}static void de_set_msglevel(struct net_device *dev, u32 msglvl){	struct de_private *de = dev->priv;	de->msg_enable = msglvl;}static int de_get_eeprom(struct net_device *dev,			 struct ethtool_eeprom *eeprom, u8 *data){	struct de_private *de = dev->priv;	if (!de->ee_data)		return -EOPNOTSUPP;	if ((eeprom->offset != 0) || (eeprom->magic != 0) ||	    (eeprom->len != DE_EEPROM_SIZE))		return -EINVAL;	memcpy(data, de->ee_data, eeprom->len);

⌨️ 快捷键说明

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