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

📄 dl2k.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 4 页
字号:
static intmii_getbit (struct net_device *dev){	long ioaddr = dev->base_addr + PhyCtrl;	u8 data;	data = (readb (ioaddr) & 0xf8) | MII_READ;	writeb (data, ioaddr);	mii_delay ();	writeb (data | MII_CLK, ioaddr);	mii_delay ();	return ((readb (ioaddr) >> 1) & 1);}static voidmii_send_bits (struct net_device *dev, u32 data, int len){	int i;	for (i = len - 1; i >= 0; i--) {		mii_sendbit (dev, data & (1 << i));	}}static intmii_read (struct net_device *dev, int phy_addr, int reg_num){	u32 cmd;	int i;	u32 retval = 0;	/* Preamble */	mii_send_bits (dev, 0xffffffff, 32);	/* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */	/* ST,OP = 0110'b for read operation */	cmd = (0x06 << 10 | phy_addr << 5 | reg_num);	mii_send_bits (dev, cmd, 14);	/* Turnaround */	if (mii_getbit (dev))		goto err_out;	/* Read data */	for (i = 0; i < 16; i++) {		retval |= mii_getbit (dev);		retval <<= 1;	}	/* End cycle */	mii_getbit (dev);	return (retval >> 1) & 0xffff;      err_out:	return 0;}static intmii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data){	u32 cmd;	/* Preamble */	mii_send_bits (dev, 0xffffffff, 32);	/* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */	/* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */	cmd = (0x5002 << 16) | (phy_addr << 23) | (reg_num << 18) | data;	mii_send_bits (dev, cmd, 32);	/* End cycle */	mii_getbit (dev);	return 0;}static intmii_wait_link (struct net_device *dev, int wait){	BMSR_t bmsr;	int phy_addr;	struct netdev_private *np;	np = dev->priv;	phy_addr = np->phy_addr;	do {		bmsr.image = mii_read (dev, phy_addr, MII_BMSR);		if (bmsr.bits.link_status)			return 0;		mdelay (1);	} while (--wait > 0);	return -1;}static intmii_get_media (struct net_device *dev){	ANAR_t negotiate;	BMSR_t bmsr;	BMCR_t bmcr;	MSCR_t mscr;	MSSR_t mssr;	int phy_addr;	struct netdev_private *np;	np = dev->priv;	phy_addr = np->phy_addr;	bmsr.image = mii_read (dev, phy_addr, MII_BMSR);	if (np->an_enable) {		if (!bmsr.bits.an_complete) {			/* Auto-Negotiation not completed */			return -1;		}		negotiate.image = mii_read (dev, phy_addr, MII_ANAR) & 			mii_read (dev, phy_addr, MII_ANLPAR);		mscr.image = mii_read (dev, phy_addr, MII_MSCR);		mssr.image = mii_read (dev, phy_addr, MII_MSSR);		if (mscr.bits.media_1000BT_FD & mssr.bits.lp_1000BT_FD) {			np->speed = 1000;			np->full_duplex = 1;			printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");		} else if (mscr.bits.media_1000BT_HD & mssr.bits.lp_1000BT_HD) {			np->speed = 1000;			np->full_duplex = 0;			printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n");		} else if (negotiate.bits.media_100BX_FD) {			np->speed = 100;			np->full_duplex = 1;			printk (KERN_INFO "Auto 100 Mbps, Full duplex\n");		} else if (negotiate.bits.media_100BX_HD) {			np->speed = 100;			np->full_duplex = 0;			printk (KERN_INFO "Auto 100 Mbps, Half duplex\n");		} else if (negotiate.bits.media_10BT_FD) {			np->speed = 10;			np->full_duplex = 1;			printk (KERN_INFO "Auto 10 Mbps, Full duplex\n");		} else if (negotiate.bits.media_10BT_HD) {			np->speed = 10;			np->full_duplex = 0;			printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");		}		if (negotiate.bits.pause) {			np->tx_flow &= 1;			np->rx_flow &= 1;		} else if (negotiate.bits.asymmetric) {			np->tx_flow = 0;			np->rx_flow &= 1;		}		/* else tx_flow, rx_flow = user select  */	} else {		bmcr.image = mii_read (dev, phy_addr, MII_BMCR);		if (bmcr.bits.speed100 == 1 && bmcr.bits.speed1000 == 0) {			printk (KERN_INFO "Operating at 100 Mbps, ");		} else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) {			printk (KERN_INFO "Operating at 10 Mbps, ");		} else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) {			printk (KERN_INFO "Operating at 1000 Mbps, ");		}		if (bmcr.bits.duplex_mode) {			printk ("Full duplex\n");		} else {			printk ("Half duplex\n");		}	}	if (np->tx_flow) 		printk(KERN_INFO "Enable Tx Flow Control\n");	else			printk(KERN_INFO "Disable Tx Flow Control\n");	if (np->rx_flow)		printk(KERN_INFO "Enable Rx Flow Control\n");	else		printk(KERN_INFO "Disable Rx Flow Control\n");	return 0;}static intmii_set_media (struct net_device *dev){	PHY_SCR_t pscr;	BMCR_t bmcr;	BMSR_t bmsr;	ANAR_t anar;	int phy_addr;	struct netdev_private *np;	np = dev->priv;	phy_addr = np->phy_addr;	/* Does user set speed? */	if (np->an_enable) {		/* Advertise capabilities */		bmsr.image = mii_read (dev, phy_addr, MII_BMSR);		anar.image = mii_read (dev, phy_addr, MII_ANAR);		anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD;		anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD;		anar.bits.media_100BT4 = bmsr.bits.media_100BT4;		anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD;		anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD;		anar.bits.pause = 1;		anar.bits.asymmetric = 1;		mii_write (dev, phy_addr, MII_ANAR, anar.image);		/* Enable Auto crossover */		pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);		pscr.bits.mdi_crossover_mode = 3;	/* 11'b */		mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);				/* Soft reset PHY */		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);		bmcr.image = 0;		bmcr.bits.an_enable = 1;		bmcr.bits.restart_an = 1;		bmcr.bits.reset = 1;		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		mdelay(1);	} else {		/* Force speed setting */		/* 1) Disable Auto crossover */		pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);		pscr.bits.mdi_crossover_mode = 0;		mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);		/* 2) PHY Reset */		bmcr.image = mii_read (dev, phy_addr, MII_BMCR);		bmcr.bits.reset = 1;		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		/* 3) Power Down */		bmcr.image = 0x1940;	/* must be 0x1940 */		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		mdelay (100);	/* wait a certain time */		/* 4) Advertise nothing */		mii_write (dev, phy_addr, MII_ANAR, 0);		/* 5) Set media and Power Up */		bmcr.image = 0;		bmcr.bits.power_down = 1;		if (np->speed == 100) {			bmcr.bits.speed100 = 1;			bmcr.bits.speed1000 = 0;			printk (KERN_INFO "Manual 100 Mbps, ");		} else if (np->speed == 10) {			bmcr.bits.speed100 = 0;			bmcr.bits.speed1000 = 0;			printk (KERN_INFO "Manual 10 Mbps, ");		}		if (np->full_duplex) {			bmcr.bits.duplex_mode = 1;			printk ("Full duplex\n");		} else {			bmcr.bits.duplex_mode = 0;			printk ("Half duplex\n");		}#if 0		/* Set 1000BaseT Master/Slave setting */		mscr.image = mii_read (dev, phy_addr, MII_MSCR);		mscr.bits.cfg_enable = 1;		mscr.bits.cfg_value = 0;#endif		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		mdelay(10);	}	return 0;}static intmii_get_media_pcs (struct net_device *dev){	ANAR_PCS_t negotiate;	BMSR_t bmsr;	BMCR_t bmcr;	int phy_addr;	struct netdev_private *np;	np = dev->priv;	phy_addr = np->phy_addr;	bmsr.image = mii_read (dev, phy_addr, PCS_BMSR);	if (np->an_enable) {		if (!bmsr.bits.an_complete) {			/* Auto-Negotiation not completed */			return -1;		}		negotiate.image = mii_read (dev, phy_addr, PCS_ANAR) & 			mii_read (dev, phy_addr, PCS_ANLPAR);		np->speed = 1000;		if (negotiate.bits.full_duplex) {			printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");			np->full_duplex = 1;		} else {			printk (KERN_INFO "Auto 1000 Mbps, half duplex\n");			np->full_duplex = 0;		}		if (negotiate.bits.pause) {			np->tx_flow &= 1;			np->rx_flow &= 1;		} else if (negotiate.bits.asymmetric) {			np->tx_flow = 0;			np->rx_flow &= 1;		}		/* else tx_flow, rx_flow = user select  */	} else {		bmcr.image = mii_read (dev, phy_addr, PCS_BMCR);		printk (KERN_INFO "Operating at 1000 Mbps, ");		if (bmcr.bits.duplex_mode) {			printk ("Full duplex\n");		} else {			printk ("Half duplex\n");		}	}	if (np->tx_flow) 		printk(KERN_INFO "Enable Tx Flow Control\n");	else			printk(KERN_INFO "Disable Tx Flow Control\n");	if (np->rx_flow)		printk(KERN_INFO "Enable Rx Flow Control\n");	else		printk(KERN_INFO "Disable Rx Flow Control\n");	return 0;}static intmii_set_media_pcs (struct net_device *dev){	BMCR_t bmcr;	ESR_t esr;	ANAR_PCS_t anar;	int phy_addr;	struct netdev_private *np;	np = dev->priv;	phy_addr = np->phy_addr;	/* Auto-Negotiation? */	if (np->an_enable) {		/* Advertise capabilities */		esr.image = mii_read (dev, phy_addr, PCS_ESR);		anar.image = mii_read (dev, phy_addr, MII_ANAR);		anar.bits.half_duplex = 			esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD;		anar.bits.full_duplex = 			esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD;		anar.bits.pause = 1;		anar.bits.asymmetric = 1;		mii_write (dev, phy_addr, MII_ANAR, anar.image);		/* Soft reset PHY */		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);		bmcr.image = 0;		bmcr.bits.an_enable = 1;		bmcr.bits.restart_an = 1;		bmcr.bits.reset = 1;		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		mdelay(1);	} else {		/* Force speed setting */		/* PHY Reset */		bmcr.image = 0;		bmcr.bits.reset = 1;		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		mdelay(10);		bmcr.image = 0;		bmcr.bits.an_enable = 0;		if (np->full_duplex) {			bmcr.bits.duplex_mode = 1;			printk (KERN_INFO "Manual full duplex\n");		} else {			bmcr.bits.duplex_mode = 0;			printk (KERN_INFO "Manual half duplex\n");		}		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);		mdelay(10);		/*  Advertise nothing */		mii_write (dev, phy_addr, MII_ANAR, 0);	}	return 0;}static intrio_close (struct net_device *dev){	long ioaddr = dev->base_addr;	struct netdev_private *np = dev->priv;	struct sk_buff *skb;	int i;	netif_stop_queue (dev);	/* Disable interrupts */	writew (0, ioaddr + IntEnable);	/* Stop Tx and Rx logics */	writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);	synchronize_irq (dev->irq);	free_irq (dev->irq, dev);	del_timer_sync (&np->timer);		/* Free all the skbuffs in the queue. */	for (i = 0; i < RX_RING_SIZE; i++) {		np->rx_ring[i].status = 0;		np->rx_ring[i].fraginfo = 0;		skb = np->rx_skbuff[i];		if (skb) {			pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo,					  skb->len, PCI_DMA_FROMDEVICE);			dev_kfree_skb (skb);			np->rx_skbuff[i] = NULL;		}	}	for (i = 0; i < TX_RING_SIZE; i++) {		skb = np->tx_skbuff[i];		if (skb) {			pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo,					  skb->len, PCI_DMA_TODEVICE);			dev_kfree_skb (skb);			np->tx_skbuff[i] = NULL;		}	}	return 0;}static void __devexitrio_remove1 (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata (pdev);	if (dev) {		struct netdev_private *np = dev->priv;		unregister_netdev (dev);		pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring,				     np->rx_ring_dma);		pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring,				     np->tx_ring_dma);#ifdef MEM_MAPPING		iounmap ((char *) (dev->base_addr));#endif		free_netdev (dev);		pci_release_regions (pdev);		pci_disable_device (pdev);	}	pci_set_drvdata (pdev, NULL);}static struct pci_driver rio_driver = {	.name		= "dl2k",	.id_table	= rio_pci_tbl,	.probe		= rio_probe1,	.remove		= __devexit_p(rio_remove1),};static int __initrio_init (void){	return pci_module_init (&rio_driver);}static void __exitrio_exit (void){	pci_unregister_driver (&rio_driver);}module_init (rio_init);module_exit (rio_exit);/* Compile command:  gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.cRead Documentation/networking/dl2k.txt for details.*/

⌨️ 快捷键说明

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