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

📄 e1000_nvm.c

📁 DELL755 Intel 网卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/** *  e1000_read_nvm_microwire - Reads EEPROM's using microwire *  @hw: pointer to the HW structure *  @offset: offset of word in the EEPROM to read *  @words: number of words to read *  @data: word read from the EEPROM * *  Reads a 16 bit word from the EEPROM. **/s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,                             u16 *data){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 i = 0;	s32 ret_val;	u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;	DEBUGFUNC("e1000_read_nvm_microwire");	/*	 * A check for invalid values:  offset too large, too many words,	 * and not enough words.	 */	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||	    (words == 0)) {		DEBUGOUT("nvm parameter(s) out of bounds\n");		ret_val = -E1000_ERR_NVM;		goto out;	}	ret_val = nvm->ops.acquire(hw);	if (ret_val)		goto out;	ret_val = e1000_ready_nvm_eeprom(hw);	if (ret_val)		goto release;	for (i = 0; i < words; i++) {		/* Send the READ command (opcode + addr) */		e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);		e1000_shift_out_eec_bits(hw, (u16)(offset + i),					nvm->address_bits);		/*		 * Read the data.  For microwire, each word requires the		 * overhead of setup and tear-down.		 */		data[i] = e1000_shift_in_eec_bits(hw, 16);		e1000_standby_nvm(hw);	}release:	nvm->ops.release(hw);out:	return ret_val;}/** *  e1000_read_nvm_eerd - Reads EEPROM using EERD register *  @hw: pointer to the HW structure *  @offset: offset of word in the EEPROM to read *  @words: number of words to read *  @data: word read from the EEPROM * *  Reads a 16 bit word from the EEPROM using the EERD register. **/s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 i, eerd = 0;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_read_nvm_eerd");	/*	 * A check for invalid values:  offset too large, too many words,	 * too many words for the offset, and not enough words.	 */	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||	    (words == 0)) {		DEBUGOUT("nvm parameter(s) out of bounds\n");		ret_val = -E1000_ERR_NVM;		goto out;	}	for (i = 0; i < words; i++) {		eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +		       E1000_NVM_RW_REG_START;		E1000_WRITE_REG(hw, E1000_EERD, eerd);		ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);		if (ret_val)			break;		data[i] = (E1000_READ_REG(hw, E1000_EERD) >>		           E1000_NVM_RW_REG_DATA);	}out:	return ret_val;}/** *  e1000_write_nvm_spi - Write to EEPROM using SPI *  @hw: pointer to the HW structure *  @offset: offset within the EEPROM to be written to *  @words: number of words to write *  @data: 16 bit word(s) to be written to the EEPROM * *  Writes data to EEPROM at offset using SPI interface. * *  If e1000_update_nvm_checksum is not called after this function , the *  EEPROM will most likely contain an invalid checksum. **/s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data){	struct e1000_nvm_info *nvm = &hw->nvm;	s32 ret_val;	u16 widx = 0;	DEBUGFUNC("e1000_write_nvm_spi");	/*	 * A check for invalid values:  offset too large, too many words,	 * and not enough words.	 */	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||	    (words == 0)) {		DEBUGOUT("nvm parameter(s) out of bounds\n");		ret_val = -E1000_ERR_NVM;		goto out;	}	ret_val = nvm->ops.acquire(hw);	if (ret_val)		goto out;	while (widx < words) {		u8 write_opcode = NVM_WRITE_OPCODE_SPI;		ret_val = e1000_ready_nvm_eeprom(hw);		if (ret_val)			goto release;		e1000_standby_nvm(hw);		/* Send the WRITE ENABLE command (8 bit opcode) */		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,		                         nvm->opcode_bits);		e1000_standby_nvm(hw);		/*		 * Some SPI eeproms use the 8th address bit embedded in the		 * opcode		 */		if ((nvm->address_bits == 8) && (offset >= 128))			write_opcode |= NVM_A8_OPCODE_SPI;		/* Send the Write command (8-bit opcode + addr) */		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),		                         nvm->address_bits);		/* Loop to allow for up to whole page write of eeprom */		while (widx < words) {			u16 word_out = data[widx];			word_out = (word_out >> 8) | (word_out << 8);			e1000_shift_out_eec_bits(hw, word_out, 16);			widx++;			if ((((offset + widx) * 2) % nvm->page_size) == 0) {				e1000_standby_nvm(hw);				break;			}		}	}	msec_delay(nvm->semaphore_delay);release:	nvm->ops.release(hw);out:	return ret_val;}/** *  e1000_write_nvm_microwire - Writes EEPROM using microwire *  @hw: pointer to the HW structure *  @offset: offset within the EEPROM to be written to *  @words: number of words to write *  @data: 16 bit word(s) to be written to the EEPROM * *  Writes data to EEPROM at offset using microwire interface. * *  If e1000_update_nvm_checksum is not called after this function , the *  EEPROM will most likely contain an invalid checksum. **/s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,                              u16 *data){	struct e1000_nvm_info *nvm = &hw->nvm;	s32  ret_val;	u32 eecd;	u16 words_written = 0;	u16 widx = 0;	DEBUGFUNC("e1000_write_nvm_microwire");	/*	 * A check for invalid values:  offset too large, too many words,	 * and not enough words.	 */	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||	    (words == 0)) {		DEBUGOUT("nvm parameter(s) out of bounds\n");		ret_val = -E1000_ERR_NVM;		goto out;	}	ret_val = nvm->ops.acquire(hw);	if (ret_val)		goto out;	ret_val = e1000_ready_nvm_eeprom(hw);	if (ret_val)		goto release;	e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,	                         (u16)(nvm->opcode_bits + 2));	e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));	e1000_standby_nvm(hw);	while (words_written < words) {		e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,		                         nvm->opcode_bits);		e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),		                         nvm->address_bits);		e1000_shift_out_eec_bits(hw, data[words_written], 16);		e1000_standby_nvm(hw);		for (widx = 0; widx < 200; widx++) {			eecd = E1000_READ_REG(hw, E1000_EECD);			if (eecd & E1000_EECD_DO)				break;			usec_delay(50);		}		if (widx == 200) {			DEBUGOUT("NVM Write did not complete\n");			ret_val = -E1000_ERR_NVM;			goto release;		}		e1000_standby_nvm(hw);		words_written++;	}	e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,	                         (u16)(nvm->opcode_bits + 2));	e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));release:	nvm->ops.release(hw);out:	return ret_val;}/** *  e1000_read_pba_num_generic - Read device part number *  @hw: pointer to the HW structure *  @pba_num: pointer to device part number * *  Reads the product board assembly (PBA) number from the EEPROM and stores *  the value in pba_num. **/s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num){	s32  ret_val;	u16 nvm_data;	DEBUGFUNC("e1000_read_pba_num_generic");	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);	if (ret_val) {		DEBUGOUT("NVM Read Error\n");		goto out;	}	*pba_num = (u32)(nvm_data << 16);	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);	if (ret_val) {		DEBUGOUT("NVM Read Error\n");		goto out;	}	*pba_num |= nvm_data;out:	return ret_val;}/** *  e1000_read_mac_addr_generic - Read device MAC address *  @hw: pointer to the HW structure * *  Reads the device MAC address from the EEPROM and stores the value. *  Since devices with two ports use the same EEPROM, we increment the *  last bit in the MAC address for the second port. **/s32 e1000_read_mac_addr_generic(struct e1000_hw *hw){	s32  ret_val = E1000_SUCCESS;	u16 offset, nvm_data, i;	DEBUGFUNC("e1000_read_mac_addr");	for (i = 0; i < ETH_ADDR_LEN; i += 2) {		offset = i >> 1;		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);		if (ret_val) {			DEBUGOUT("NVM Read Error\n");			goto out;		}		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);	}	/* Flip last bit of mac address if we're on second port */	if (hw->bus.func == E1000_FUNC_1)		hw->mac.perm_addr[5] ^= 1;	for (i = 0; i < ETH_ADDR_LEN; i++)		hw->mac.addr[i] = hw->mac.perm_addr[i];out:	return ret_val;}/** *  e1000_validate_nvm_checksum_generic - Validate EEPROM checksum *  @hw: pointer to the HW structure * *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM *  and then verifies that the sum of the EEPROM is equal to 0xBABA. **/s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	u16 checksum = 0;	u16 i, nvm_data;	DEBUGFUNC("e1000_validate_nvm_checksum_generic");	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);		if (ret_val) {			DEBUGOUT("NVM Read Error\n");			goto out;		}		checksum += nvm_data;	}	if (checksum != (u16) NVM_SUM) {		DEBUGOUT("NVM Checksum Invalid\n");		ret_val = -E1000_ERR_NVM;		goto out;	}out:	return ret_val;}/** *  e1000_update_nvm_checksum_generic - Update EEPROM checksum *  @hw: pointer to the HW structure * *  Updates the EEPROM checksum by reading/adding each word of the EEPROM *  up to the checksum.  Then calculates the EEPROM checksum and writes the *  value to the EEPROM. **/s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw){	s32  ret_val;	u16 checksum = 0;	u16 i, nvm_data;	DEBUGFUNC("e1000_update_nvm_checksum");	for (i = 0; i < NVM_CHECKSUM_REG; i++) {		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);		if (ret_val) {			DEBUGOUT("NVM Read Error while updating checksum.\n");			goto out;		}		checksum += nvm_data;	}	checksum = (u16) NVM_SUM - checksum;	ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);	if (ret_val) {		DEBUGOUT("NVM Write Error while updating checksum.\n");	}out:	return ret_val;}/** *  e1000_reload_nvm_generic - Reloads EEPROM *  @hw: pointer to the HW structure * *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the *  extended control register. **/void e1000_reload_nvm_generic(struct e1000_hw *hw){	u32 ctrl_ext;	DEBUGFUNC("e1000_reload_nvm_generic");	usec_delay(10);	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);	ctrl_ext |= E1000_CTRL_EXT_EE_RST;	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);	E1000_WRITE_FLUSH(hw);}

⌨️ 快捷键说明

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