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

📄 tlan.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 4 页
字号:
	nic->transmit = tlan_transmit;	return 1;#else	nic->disable = tlan_disable;	nic->poll = tlan_poll;	nic->transmit = tlan_transmit;	return nic;#endif}/***********************************************************************************************************************************************************	ThunderLAN Driver Eeprom routines	The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A	EEPROM.  These functions are based on information in Microchip's	data sheet.  I don't know how well this functions will work with	other EEPROMs.***********************************************************************************************************************************************************/	/***************************************************************	 *	TLan_EeSendStart	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		io_base		The IO port base address for the	 *				TLAN device with the EEPROM to	 *				use.	 *	 *	This function sends a start cycle to an EEPROM attached	 *	to a TLAN chip.	 *	 **************************************************************/void TLan_EeSendStart(u16 io_base){	u16 sio;	outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);	sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);	TLan_SetBit(TLAN_NET_SIO_EDATA, sio);	TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);	TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);	TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);}				/* TLan_EeSendStart */	/***************************************************************	 *	TLan_EeSendByte	 *	 *	Returns:	 *		If the correct ack was received, 0, otherwise 1	 *	Parms:	io_base		The IO port base address for the	 *				TLAN device with the EEPROM to	 *				use.	 *		data		The 8 bits of information to	 *				send to the EEPROM.	 *		stop		If TLAN_EEPROM_STOP is passed, a	 *				stop cycle is sent after the	 *				byte is sent after the ack is	 *				read.	 *	 *	This function sends a byte on the serial EEPROM line,	 *	driving the clock to send each bit. The function then	 *	reverses transmission direction and reads an acknowledge	 *	bit.	 *	 **************************************************************/int TLan_EeSendByte(u16 io_base, u8 data, int stop){	int err;	u8 place;	u16 sio;	outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);	sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;	/* Assume clock is low, tx is enabled; */	for (place = 0x80; place != 0; place >>= 1) {		if (place & data)			TLan_SetBit(TLAN_NET_SIO_EDATA, sio);		else			TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);		TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);		TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);	}	TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio);	TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);	err = TLan_GetBit(TLAN_NET_SIO_EDATA, sio);	TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);	TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);	if ((!err) && stop) {		TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);	/* STOP, raise data while clock is high */		TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);		TLan_SetBit(TLAN_NET_SIO_EDATA, sio);	}	return (err);}				/* TLan_EeSendByte */	/***************************************************************	 *	TLan_EeReceiveByte	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		io_base		The IO port base address for the	 *				TLAN device with the EEPROM to	 *				use.	 *		data		An address to a char to hold the	 *				data sent from the EEPROM.	 *		stop		If TLAN_EEPROM_STOP is passed, a	 *				stop cycle is sent after the	 *				byte is received, and no ack is	 *				sent.	 *	 *	This function receives 8 bits of data from the EEPROM	 *	over the serial link.  It then sends and ack bit, or no	 *	ack and a stop bit.  This function is used to retrieve	 *	data after the address of a byte in the EEPROM has been	 *	sent.	 *	 **************************************************************/void TLan_EeReceiveByte(u16 io_base, u8 * data, int stop){	u8 place;	u16 sio;	outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);	sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;	*data = 0;	/* Assume clock is low, tx is enabled; */	TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio);	for (place = 0x80; place; place >>= 1) {		TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);		if (TLan_GetBit(TLAN_NET_SIO_EDATA, sio))			*data |= place;		TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);	}	TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);	if (!stop) {		TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);	/* Ack = 0 */		TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);		TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);	} else {		TLan_SetBit(TLAN_NET_SIO_EDATA, sio);	/* No ack = 1 (?) */		TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);		TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);		TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);	/* STOP, raise data while clock is high */		TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);		TLan_SetBit(TLAN_NET_SIO_EDATA, sio);	}}				/* TLan_EeReceiveByte */	/***************************************************************	 *	TLan_EeReadByte	 *	 *	Returns:	 *		No error = 0, else, the stage at which the error	 *		occurred.	 *	Parms:	 *		io_base		The IO port base address for the	 *				TLAN device with the EEPROM to	 *				use.	 *		ee_addr		The address of the byte in the	 *				EEPROM whose contents are to be	 *				retrieved.	 *		data		An address to a char to hold the	 *				data obtained from the EEPROM.	 *	 *	This function reads a byte of information from an byte	 *	cell in the EEPROM.	 *	 **************************************************************/int TLan_EeReadByte(u16 io_base, u8 ee_addr, u8 * data){	int err;	int ret = 0;	TLan_EeSendStart(io_base);	err = TLan_EeSendByte(io_base, 0xA0, TLAN_EEPROM_ACK);	if (err) {		ret = 1;		goto fail;	}	err = TLan_EeSendByte(io_base, ee_addr, TLAN_EEPROM_ACK);	if (err) {		ret = 2;		goto fail;	}	TLan_EeSendStart(io_base);	err = TLan_EeSendByte(io_base, 0xA1, TLAN_EEPROM_ACK);	if (err) {		ret = 3;		goto fail;	}	TLan_EeReceiveByte(io_base, data, TLAN_EEPROM_STOP);      fail:	return ret;}				/* TLan_EeReadByte *//***********************************************************************************************************************************************************	ThunderLAN Driver MII Routines	These routines are based on the information in Chap. 2 of the	"ThunderLAN Programmer's Guide", pp. 15-24.***********************************************************************************************************************************************************/	/***************************************************************	 *	TLan_MiiReadReg	 *	 *	Returns:	 *		0	if ack received ok	 *		1	otherwise.	 *	 *	Parms:	 *		dev		The device structure containing	 *				The io address and interrupt count	 *				for this device.	 *		phy		The address of the PHY to be queried.	 *		reg		The register whose contents are to be	 *				retreived.	 *		val		A pointer to a variable to store the	 *				retrieved value.	 *	 *	This function uses the TLAN's MII bus to retreive the contents	 *	of a given register on a PHY.  It sends the appropriate info	 *	and then reads the 16-bit register value from the MII bus via	 *	the TLAN SIO register.	 *	 **************************************************************/int TLan_MiiReadReg(struct nic *nic __unused, u16 phy, u16 reg, u16 * val){	u8 nack;	u16 sio, tmp;	u32 i;	int err;	int minten;	err = FALSE;	outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);	sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_MiiSync(BASE);	minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio);	if (minten)		TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);	TLan_MiiSendData(BASE, 0x1, 2);	/* Start ( 01b ) */	TLan_MiiSendData(BASE, 0x2, 2);	/* Read  ( 10b ) */	TLan_MiiSendData(BASE, phy, 5);	/* Device #      */	TLan_MiiSendData(BASE, reg, 5);	/* Register #    */	TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);	/* Change direction */	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);	/* Clock Idle bit */	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);	/* Wait 300ns */	nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio);	/* Check for ACK */	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);	/* Finish ACK */	if (nack) {		/* No ACK, so fake it */		for (i = 0; i < 16; i++) {			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		}		tmp = 0xffff;		err = TRUE;	} else {		/* ACK, so read data */		for (tmp = 0, i = 0x8000; i; i >>= 1) {			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);			if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))				tmp |= i;			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		}	}	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);	/* Idle cycle */	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);	if (minten)		TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);	*val = tmp;	return err;}				/* TLan_MiiReadReg */	/***************************************************************	 *	TLan_MiiSendData	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		base_port	The base IO port of the adapter	in	 *				question.	 *		dev		The address of the PHY to be queried.	 *		data		The value to be placed on the MII bus.	 *		num_bits	The number of bits in data that are to	 *				be placed on the MII bus.	 *	 *	This function sends on sequence of bits on the MII	 *	configuration bus.	 *	 **************************************************************/void TLan_MiiSendData(u16 base_port, u32 data, unsigned num_bits){	u16 sio;	u32 i;	if (num_bits == 0)		return;	outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);	sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_SetBit(TLAN_NET_SIO_MTXEN, sio);	for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {		TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		(void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio);		if (data & i)			TLan_SetBit(TLAN_NET_SIO_MDATA, sio);		else			TLan_ClearBit(TLAN_NET_SIO_MDATA, sio);		TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		(void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio);	}}				/* TLan_MiiSendData */	/***************************************************************	 *	TLan_MiiSync	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		base_port	The base IO port of the adapter in	 *				question.	 *	 *	This functions syncs all PHYs in terms of the MII configuration	 *	bus.	 *	 **************************************************************/void TLan_MiiSync(u16 base_port){	int i;	u16 sio;	outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);	sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);	for (i = 0; i < 32; i++) {		TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		TLan_SetBit(TLAN_NET_SIO_MCLK, sio);	}}				/* TLan_MiiSync */	/***************************************************************	 *	TLan_MiiWriteReg	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		dev		The device structure for the device	 *				to write to.	 *		phy		The address of the PHY to be written to.	 *		reg		The register whose contents are to be	 *				written.	 *		val		The value to be written to the register.	 *	 *	This function uses the TLAN's MII bus to write the contents of a	 *	given register on a PHY.  It sends the appropriate info and then	 *	writes the 16-bit register value from the MII configuration bus	 *	via the TLAN SIO register.	 *	 **************************************************************/void TLan_MiiWriteReg(struct nic *nic __unused, u16 phy, u16 reg, u16 val){	u16 sio;	int minten;	outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);	sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_MiiSync(BASE);	minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio);	if (minten)		TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);	TLan_MiiSendData(BASE, 0x1, 2);	/* Start ( 01b ) */	TLan_MiiSendData(BASE, 0x1, 2);	/* Write ( 01b ) */	TLan_MiiSendData(BASE, phy, 5);	/* Device #      */	TLan_MiiSendData(BASE, reg, 5);	/* Register #    */	TLan_MiiSendData(BASE, 0x2, 2);	/* Send ACK */	TLan_MiiSendData(BASE, val, 16);	/* Send Data */	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);	/* Idle cycle */

⌨️ 快捷键说明

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