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

📄 e100_eeprom.c

📁 Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.    This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the Free   Software Foundation; either version 2 of the License, or (at your option)   any later version.    This program is distributed in the hope that it will be useful, but WITHOUT   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   more details.    You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc., 59   Temple Place - Suite 330, Boston, MA  02111-1307, USA.    The full GNU General Public License is included in this distribution in the  file called LICENSE.    Contact Information:  Linux NICS <linux.nics@intel.com>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************//***********************************************************************                                                                     ** INTEL CORPORATION                                                   **                                                                     ** This software is supplied under the terms of the license included   ** above.  All use of this driver must be in accordance with the terms ** of that license.                                                    **                                                                     ** Module Name:  e100_eeprom.c                                         **                                                                     ** Abstract:     This module contains routines to read and write to a  **               serial EEPROM                                         **                                                                     ** Environment:  This file is intended to be specific to the Linux     **               operating system.                                     **                                                                     ***********************************************************************/#include "e100.h"#define CSR_EEPROM_CONTROL_FIELD(bdp) ((bdp)->scb->scb_eprm_cntrl)#define CSR_GENERAL_CONTROL2_FIELD(bdp) \	           ((bdp)->scb->scb_ext.d102_scb.scb_gen_ctrl2)#define EEPROM_STALL_TIME	4#define EEPROM_CHECKSUM		((u16) 0xBABA)#define EEPROM_MAX_WORD_SIZE	256void e100_eeprom_cleanup(struct e100_private *adapter);u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);static void e100_eeprom_write_word(struct e100_private *adapter, u16 reg,				   u16 data);void e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,			     u16 size);u16 e100_eeprom_size(struct e100_private *adapter);u16 e100_eeprom_read(struct e100_private *adapter, u16 reg);static void shift_out_bits(struct e100_private *adapter, u16 data, u16 count);static u16 shift_in_bits(struct e100_private *adapter);static void raise_clock(struct e100_private *adapter, u16 *x);static void lower_clock(struct e100_private *adapter, u16 *x);static u16 eeprom_wait_cmd_done(struct e100_private *adapter);static void eeprom_stand_by(struct e100_private *adapter);//----------------------------------------------------------------------------------------// Procedure:   eeprom_set_semaphore//// Description: This function set (write 1) Gamla EEPROM semaphore bit (bit 23 word 0x1C in the CSR).//// Arguments://      Adapter                 - Adapter context//// Returns:  true if success//           else return false ////----------------------------------------------------------------------------------------inline u8eeprom_set_semaphore(struct e100_private *adapter){	u16 data = 0;	unsigned long expiration_time = jiffies + HZ / 100 + 1;	do {		// Get current value of General Control 2		data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));		// Set bit 23 word 0x1C in the CSR.		data |= SCB_GCR2_EEPROM_ACCESS_SEMAPHORE;		writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));		// Check to see if this bit set or not.		data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));		if (data & SCB_GCR2_EEPROM_ACCESS_SEMAPHORE) {			return true;		}		if (time_before(jiffies, expiration_time))			yield();		else			return false;	} while (true);}//----------------------------------------------------------------------------------------// Procedure:   eeprom_reset_semaphore//// Description: This function reset (write 0) Gamla EEPROM semaphore bit //              (bit 23 word 0x1C in the CSR).//// Arguments:  struct e100_private * adapter - Adapter context//----------------------------------------------------------------------------------------inline voideeprom_reset_semaphore(struct e100_private *adapter){	u16 data = 0;	data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));	data &= ~(SCB_GCR2_EEPROM_ACCESS_SEMAPHORE);	writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));}//----------------------------------------------------------------------------------------// Procedure:   e100_eeprom_size//// Description: This routine determines the size of the EEPROM.  This value should be//              checked for validity - ie. is it too big or too small.  The size returned//              is then passed to the read/write functions.//// Returns://      Size of the eeprom, or zero if an error occurred//----------------------------------------------------------------------------------------u16e100_eeprom_size(struct e100_private *adapter){	u16 x, size = 1;	// must be one to accumulate a product	// if we've already stored this data, read from memory	if (adapter->eeprom_size) {		return adapter->eeprom_size;	}	// otherwise, read from the eeprom	// Set EEPROM semaphore.	if (adapter->rev_id >= D102_REV_ID) {		if (!eeprom_set_semaphore(adapter))			return 0;	}	// enable the eeprom by setting EECS.	x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));	x &= ~(EEDI | EEDO | EESK);	x |= EECS;	writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));	// write the read opcode	shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);	// experiment to discover the size of the eeprom.  request register zero	// and wait for the eeprom to tell us it has accepted the entire address.	x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));	do {		size *= 2;	// each bit of address doubles eeprom size		x |= EEDO;	// set bit to detect "dummy zero"		x &= ~EEDI;	// address consists of all zeros		writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));		readw(&(adapter->scb->scb_status));		udelay(EEPROM_STALL_TIME);		raise_clock(adapter, &x);		lower_clock(adapter, &x);		// check for "dummy zero"		x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));		if (size > EEPROM_MAX_WORD_SIZE) {			size = 0;			break;		}	} while (x & EEDO);	// read in the value requested	(void) shift_in_bits(adapter);	e100_eeprom_cleanup(adapter);	// Clear EEPROM Semaphore.	if (adapter->rev_id >= D102_REV_ID) {		eeprom_reset_semaphore(adapter);	}	return size;}//----------------------------------------------------------------------------------------// Procedure:   eeprom_address_size//// Description: determines the number of bits in an address for the eeprom acceptable//              values are 64, 128, and 256// Arguments: size of the eeprom// Returns: bits in an address for that size eeprom//----------------------------------------------------------------------------------------static inline inteeprom_address_size(u16 size){	int isize = size;		return (ffs(isize) - 1);}//----------------------------------------------------------------------------------------// Procedure:   e100_eeprom_read//// Description: This routine serially reads one word out of the EEPROM.//// Arguments://      adapter - our adapter context//      reg - EEPROM word to read.//// Returns://      Contents of EEPROM word (reg).//----------------------------------------------------------------------------------------u16e100_eeprom_read(struct e100_private *adapter, u16 reg){	u16 x, data, bits;	// Set EEPROM semaphore.	if (adapter->rev_id >= D102_REV_ID) {		if (!eeprom_set_semaphore(adapter))			return 0;	}	// eeprom size is initialized to zero	if (!adapter->eeprom_size)		adapter->eeprom_size = e100_eeprom_size(adapter);	bits = eeprom_address_size(adapter->eeprom_size);	// select EEPROM, reset bits, set EECS	x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));	x &= ~(EEDI | EEDO | EESK);	x |= EECS;	writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));	// write the read opcode and register number in that order	// The opcode is 3bits in length, reg is 'bits' bits long	shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);	shift_out_bits(adapter, reg, bits);	// Now read the data (16 bits) in from the selected EEPROM word	data = shift_in_bits(adapter);	e100_eeprom_cleanup(adapter);	// Clear EEPROM Semaphore.	if (adapter->rev_id >= D102_REV_ID) {		eeprom_reset_semaphore(adapter);	}	return data;}//----------------------------------------------------------------------------------------// Procedure:   shift_out_bits//// Description: This routine shifts data bits out to the EEPROM.//// Arguments://      data - data to send to the EEPROM.//      count - number of data bits to shift out.//// Returns: (none)//----------------------------------------------------------------------------------------

⌨️ 快捷键说明

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