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

📄 uli526x.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (db->tx_packet_cnt < TX_DESC_CNT) {		/* Resource Empty */		db->tx_packet_cnt++;		txptr->tdes0 = cpu_to_le32(0x80000000);		update_cr6(db->cr6_data | 0x2000, dev->base_addr);		outl(0x1, dev->base_addr + DCR1);	/* Issue Tx polling */		update_cr6(db->cr6_data, dev->base_addr);		dev->trans_start = jiffies;	} else		printk(KERN_ERR DRV_NAME ": No Tx resource - Send_filter_frame!\n");}/* *	Allocate rx buffer, *	As possible as allocate maxiumn Rx buffer */static void allocate_rx_buffer(struct uli526x_board_info *db){	struct rx_desc *rxptr;	struct sk_buff *skb;	rxptr = db->rx_insert_ptr;	while(db->rx_avail_cnt < RX_DESC_CNT) {		if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )			break;		rxptr->rx_skb_ptr = skb; /* FIXME (?) */		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );		wmb();		rxptr->rdes0 = cpu_to_le32(0x80000000);		rxptr = rxptr->next_rx_desc;		db->rx_avail_cnt++;	}	db->rx_insert_ptr = rxptr;}/* *	Read one word data from the serial ROM */static u16 read_srom_word(long ioaddr, int offset){	int i;	u16 srom_data = 0;	long cr9_ioaddr = ioaddr + DCR9;	outl(CR9_SROM_READ, cr9_ioaddr);	outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);	/* Send the Read Command 110b */	SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);	SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);	SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);	/* Send the offset */	for (i = 5; i >= 0; i--) {		srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;		SROM_CLK_WRITE(srom_data, cr9_ioaddr);	}	outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);	for (i = 16; i > 0; i--) {		outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);		udelay(5);		srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0);		outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);		udelay(5);	}	outl(CR9_SROM_READ, cr9_ioaddr);	return srom_data;}/* *	Auto sense the media mode */static u8 uli526x_sense_speed(struct uli526x_board_info * db){	u8 ErrFlag = 0;	u16 phy_mode;	phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);	phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);	if ( (phy_mode & 0x24) == 0x24 ) {				phy_mode = ((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)<<7);		if(phy_mode&0x8000)			phy_mode = 0x8000;		else if(phy_mode&0x4000)			phy_mode = 0x4000;		else if(phy_mode&0x2000)			phy_mode = 0x2000;		else			phy_mode = 0x1000;				/* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */		switch (phy_mode) {		case 0x1000: db->op_mode = ULI526X_10MHF; break;		case 0x2000: db->op_mode = ULI526X_10MFD; break;		case 0x4000: db->op_mode = ULI526X_100MHF; break;		case 0x8000: db->op_mode = ULI526X_100MFD; break;		default: db->op_mode = ULI526X_10MHF; ErrFlag = 1; break;		}	} else {		db->op_mode = ULI526X_10MHF;		ULI526X_DBUG(0, "Link Failed :", phy_mode);		ErrFlag = 1;	}	return ErrFlag;}/* *	Set 10/100 phyxcer capability *	AUTO mode : phyxcer register4 is NIC capability *	Force mode: phyxcer register4 is the force media */static void uli526x_set_phyxcer(struct uli526x_board_info *db){	u16 phy_reg;		/* Phyxcer capability setting */	phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;	if (db->media_mode & ULI526X_AUTO) {		/* AUTO Mode */		phy_reg |= db->PHY_reg4;	} else {		/* Force Mode */		switch(db->media_mode) {		case ULI526X_10MHF: phy_reg |= 0x20; break;		case ULI526X_10MFD: phy_reg |= 0x40; break;		case ULI526X_100MHF: phy_reg |= 0x80; break;		case ULI526X_100MFD: phy_reg |= 0x100; break;		}			}  	/* Write new capability to Phyxcer Reg4 */	if ( !(phy_reg & 0x01e0)) {		phy_reg|=db->PHY_reg4;		db->media_mode|=ULI526X_AUTO;	}	phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id); 	/* Restart Auto-Negotiation */	phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);	udelay(50);}/* *	Process op-mode 	AUTO mode : PHY controller in Auto-negotiation Mode *	Force mode: PHY controller in force mode with HUB *			N-way force capability with SWITCH */static void uli526x_process_mode(struct uli526x_board_info *db){	u16 phy_reg;	/* Full Duplex Mode Check */	if (db->op_mode & 0x4)		db->cr6_data |= CR6_FDM;	/* Set Full Duplex Bit */	else		db->cr6_data &= ~CR6_FDM;	/* Clear Full Duplex Bit */	update_cr6(db->cr6_data, db->ioaddr);	/* 10/100M phyxcer force mode need */	if ( !(db->media_mode & 0x8)) {		/* Forece Mode */		phy_reg = phy_read(db->ioaddr, db->phy_addr, 6, db->chip_id);		if ( !(phy_reg & 0x1) ) {			/* parter without N-Way capability */			phy_reg = 0x0;			switch(db->op_mode) {			case ULI526X_10MHF: phy_reg = 0x0; break;			case ULI526X_10MFD: phy_reg = 0x100; break;			case ULI526X_100MHF: phy_reg = 0x2000; break;			case ULI526X_100MFD: phy_reg = 0x2100; break;			}			phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);       			phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);		}	}}/* *	Write a word to Phy register */static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id){	u16 i;	unsigned long ioaddr;	if(chip_id == PCI_ULI5263_ID)	{		phy_writeby_cr10(iobase, phy_addr, offset, phy_data);		return;	}	/* M5261/M5263 Chip */	ioaddr = iobase + DCR9;	/* Send 33 synchronization clock to Phy controller */	for (i = 0; i < 35; i++)		phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	/* Send start command(01) to Phy */	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	/* Send write command(01) to Phy */	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	/* Send Phy address */	for (i = 0x10; i > 0; i = i >> 1)		phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);	/* Send register address */	for (i = 0x10; i > 0; i = i >> 1)		phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);	/* written trasnition */	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);	/* Write a word data to PHY controller */	for ( i = 0x8000; i > 0; i >>= 1)		phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);	}/* *	Read a word data from phy register */static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id){	int i;	u16 phy_data;	unsigned long ioaddr;	if(chip_id == PCI_ULI5263_ID)		return phy_readby_cr10(iobase, phy_addr, offset);	/* M5261/M5263 Chip */	ioaddr = iobase + DCR9;		/* Send 33 synchronization clock to Phy controller */	for (i = 0; i < 35; i++)		phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	/* Send start command(01) to Phy */	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	/* Send read command(10) to Phy */	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);	/* Send Phy address */	for (i = 0x10; i > 0; i = i >> 1)		phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);	/* Send register address */	for (i = 0x10; i > 0; i = i >> 1)		phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);	/* Skip transition state */	phy_read_1bit(ioaddr, chip_id);	/* read 16bit data */	for (phy_data = 0, i = 0; i < 16; i++) {		phy_data <<= 1;		phy_data |= phy_read_1bit(ioaddr, chip_id);	}	return phy_data;}static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset){	unsigned long ioaddr,cr10_value;		ioaddr = iobase + DCR10;	cr10_value = phy_addr;	cr10_value = (cr10_value<<5) + offset;	cr10_value = (cr10_value<<16) + 0x08000000;	outl(cr10_value,ioaddr);	udelay(1);	while(1)	{		cr10_value = inl(ioaddr);		if(cr10_value&0x10000000)			break;	}	return (cr10_value&0x0ffff);}static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data){	unsigned long ioaddr,cr10_value;		ioaddr = iobase + DCR10;	cr10_value = phy_addr;	cr10_value = (cr10_value<<5) + offset;	cr10_value = (cr10_value<<16) + 0x04000000 + phy_data;	outl(cr10_value,ioaddr);	udelay(1);}/* *	Write one bit data to Phy Controller */static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id){	outl(phy_data , ioaddr);			/* MII Clock Low */	udelay(1);	outl(phy_data  | MDCLKH, ioaddr);	/* MII Clock High */	udelay(1);	outl(phy_data , ioaddr);			/* MII Clock Low */	udelay(1);}/* *	Read one bit phy data from PHY controller */static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id){	u16 phy_data;		outl(0x50000 , ioaddr);	udelay(1);	phy_data = ( inl(ioaddr) >> 19 ) & 0x1;	outl(0x40000 , ioaddr);	udelay(1);	return phy_data;}static struct pci_device_id uli526x_pci_tbl[] = {	{ 0x10B9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5261_ID },	{ 0x10B9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5263_ID },	{ 0, }};MODULE_DEVICE_TABLE(pci, uli526x_pci_tbl);static struct pci_driver uli526x_driver = {	.name		= "uli526x",	.id_table	= uli526x_pci_tbl,	.probe		= uli526x_init_one,	.remove		= __devexit_p(uli526x_remove_one),};MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw");MODULE_DESCRIPTION("ULi M5261/M5263 fast ethernet driver");MODULE_LICENSE("GPL");MODULE_PARM(debug, "i");MODULE_PARM(mode, "i");MODULE_PARM(cr6set, "i");MODULE_PARM_DESC(debug, "ULi M5261/M5263 enable debugging (0-1)");MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA");/*	Description: *	when user used insmod to add module, system invoked init_module() *	to register the services. */static int __init uli526x_init_module(void){	int rc;	printk(version);	printed_version = 1;	ULI526X_DBUG(0, "init_module() ", debug);	if (debug)		uli526x_debug = debug;	/* set debug flag */	if (cr6set)		uli526x_cr6_user_set = cr6set; 	switch(mode) {   	case ULI526X_10MHF:	case ULI526X_100MHF:	case ULI526X_10MFD:	case ULI526X_100MFD:		uli526x_media_mode = mode;		break;	default:uli526x_media_mode = ULI526X_AUTO;		break;	}	rc = pci_module_init(&uli526x_driver);	if (rc < 0)		return rc;	return 0;}/* *	Description: *	when user used rmmod to delete module, system invoked clean_module() *	to un-register all registered services. */static void __exit uli526x_cleanup_module(void){	ULI526X_DBUG(0, "uli526x_clean_module() ", debug);	pci_unregister_driver(&uli526x_driver);}module_init(uli526x_init_module);module_exit(uli526x_cleanup_module);

⌨️ 快捷键说明

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