/* Get the SW semaphore */ while (i < timeout) {
swsm = rd32(E1000_SWSM); if (!(swsm & E1000_SWSM_SMBI)) break;
udelay(50);
i++;
}
if (i == timeout) { /* In rare circumstances, the SW semaphore may already be held *unintentionally.Clearthesemaphoreoncebeforegivingup.
*/ if (hw->dev_spec._82575.clear_semaphore_once) {
hw->dev_spec._82575.clear_semaphore_once = false;
igb_put_hw_semaphore(hw); for (i = 0; i < timeout; i++) {
swsm = rd32(E1000_SWSM); if (!(swsm & E1000_SWSM_SMBI)) break;
udelay(50);
}
}
/* If we do not have the semaphore here, we have to give up. */ if (i == timeout) {
hw_dbg("Driver can't access device - SMBI bit is set.\n"); return -E1000_ERR_NVM;
}
}
/* Get the FW semaphore. */ for (i = 0; i < timeout; i++) {
swsm = rd32(E1000_SWSM);
wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
/* Semaphore acquired if bit latched */ if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) break;
udelay(50);
}
if (i == timeout) { /* Release semaphores */
igb_put_hw_semaphore(hw);
hw_dbg("Driver can't access the NVM\n"); return -E1000_ERR_NVM;
}
/* We cannot hold synchronization semaphores for too long, *becauseofforcefultakeoverprocedure.Howeveritismoreefficient *toreadinburststhansynchronizingaccessforeachword.
*/ for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i); if (!(hw->nvm.ops.acquire(hw))) {
status = igb_read_nvm_eerd(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
/* A check for invalid values: offset too large, too many words, *toomanywordsfortheoffset,andnotenoughwords.
*/ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; goto out;
}
for (i = 0; i < words; i++) {
eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
(data[i] << E1000_NVM_RW_REG_DATA) |
E1000_NVM_RW_REG_START;
wr32(E1000_SRWR, eewr);
for (k = 0; k < attempts; k++) { if (E1000_NVM_RW_REG_DONE &
rd32(E1000_SRWR)) {
ret_val = 0; break;
}
udelay(5);
}
/* We cannot hold synchronization semaphores for too long, *becauseofforcefultakeoverprocedure.Howeveritismoreefficient *towriteinburststhansynchronizingaccessforeachword.
*/ for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i); if (!(hw->nvm.ops.acquire(hw))) {
status = igb_write_nvm_srwr(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = rd32(E1000_INVM_DATA_REG(i)); /* Get record type */
record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) break; if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
hw_dbg("Read INVM Word 0x%02x = %x\n",
address, *data);
status = 0; break;
}
}
} if (status)
hw_dbg("Requested word 0x%02x not found in OTP\n", address); return status;
}
/* Read iNVM memory */ for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = rd32(E1000_INVM_DATA_REG(i));
buffer[i] = invm_dword;
}
/* Read version number */ for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have first version location used */ if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
version = 0;
status = 0; break;
} /* Check if we have second version location used */ elseif ((i == 1) &&
((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
version = FIELD_GET(E1000_INVM_VER_FIELD_ONE, *record);
status = 0; break;
} /* Check if we have odd version location *usedanditisthelastoneused
*/ elseif ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
(i != 1))) {
version = FIELD_GET(E1000_INVM_VER_FIELD_TWO,
*next_record);
status = 0; break;
} /* Check if we have even version location *usedanditisthelastoneused
*/ elseif (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
((*record & 0x3) == 0)) {
version = FIELD_GET(E1000_INVM_VER_FIELD_ONE, *record);
status = 0; break;
}
}
if (!status) {
invm_ver->invm_major = FIELD_GET(E1000_INVM_MAJOR_MASK,
version);
invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
} /* Read Image Type */ for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have image type in first location used */ if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
invm_ver->invm_img_type = 0;
status = 0; break;
} /* Check if we have image type in first location used */ elseif ((((*record & 0x3) == 0) &&
((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
((((*record & 0x3) != 0) && (i != 1)))) {
invm_ver->invm_img_type =
FIELD_GET(E1000_INVM_IMGTYPE_FIELD,
*next_record);
status = 0; break;
}
} return status;
}
/* Replace the read function with semaphore grabbing with *theonethatskipsthisforawhile. *Wehavesemaphoretakenalreadyhere.
*/
read_op_ptr = hw->nvm.ops.read;
hw->nvm.ops.read = igb_read_nvm_eerd;
status = igb_validate_nvm_checksum(hw);
/* Revert original read operation. */
hw->nvm.ops.read = read_op_ptr;
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
/* Read the first word from the EEPROM. If this times out or fails, do *notcontinueorwecouldbeinforaverylongwaitwhileevery *EEPROMreadfails
*/
ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data); if (ret_val) {
hw_dbg("EEPROM read failed\n"); goto out;
}
if (!(hw->nvm.ops.acquire(hw))) { /* Do not use hw->nvm.ops.write, hw->nvm.ops.read *becausewedonotwanttotakethesynchronization *semaphorestwicehere.
*/
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data); if (ret_val) {
hw->nvm.ops.release(hw);
hw_dbg("NVM Read Error while updating checksum.\n"); goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
&checksum); if (ret_val) {
hw->nvm.ops.release(hw);
hw_dbg("NVM Write Error while updating checksum.\n"); goto out;
}
while (timeout) { if (rd32(E1000_EEMNGCTL_I210) & mask) break;
usleep_range(1000, 2000);
timeout--;
} if (!timeout)
hw_dbg("MNG configuration cycle has not completed.\n");
return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-10-04)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.