[iwm] Sync iwm_nvm_read_chunk() function with Linux iwlwifi.

This fixes an error handling detail in iwm_nvm_read_chunk(), where an
error response from the firmware for an NVM read shouldn't be fatal if
the offset was non-zero.

Approved by:	adrian (mentor)
Obtained from:	DragonFlyBSD git 250a1c33fca1725121fe499f9cebc90267d209f9
Differential Revision:	https://reviews.freebsd.org/D8542
This commit is contained in:
Imre Vadász 2016-11-17 20:00:20 +00:00
parent 0e75a50173
commit b22fe30db1

View File

@ -1666,8 +1666,10 @@ const int nvm_to_read[] = {
#define IWM_NVM_READ_OPCODE 0
/* load nvm chunk response */
#define IWM_READ_NVM_CHUNK_SUCCEED 0
#define IWM_READ_NVM_CHUNK_INVALID_ADDRESS 1
enum {
IWM_READ_NVM_CHUNK_SUCCEED = 0,
IWM_READ_NVM_CHUNK_NOT_VALID_ADDRESS = 1
};
static int
iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
@ -1684,12 +1686,10 @@ iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
struct iwm_rx_packet *pkt;
struct iwm_host_cmd cmd = {
.id = IWM_NVM_ACCESS_CMD,
.flags = IWM_CMD_SYNC | IWM_CMD_WANT_SKB |
IWM_CMD_SEND_IN_RFKILL,
.flags = IWM_CMD_WANT_SKB | IWM_CMD_SEND_IN_RFKILL,
.data = { &nvm_access_cmd, },
};
int ret, offset_read;
size_t bytes_read;
int ret, bytes_read, offset_read;
uint8_t *resp_data;
cmd.len[0] = sizeof(struct iwm_nvm_access_cmd);
@ -1718,9 +1718,26 @@ iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
offset_read = le16toh(nvm_resp->offset);
resp_data = nvm_resp->data;
if (ret) {
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
"NVM access command failed with status %d\n", ret);
ret = EINVAL;
if ((offset != 0) &&
(ret == IWM_READ_NVM_CHUNK_NOT_VALID_ADDRESS)) {
/*
* meaning of NOT_VALID_ADDRESS:
* driver try to read chunk from address that is
* multiple of 2K and got an error since addr is empty.
* meaning of (offset != 0): driver already
* read valid data from another chunk so this case
* is not an error.
*/
IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET,
"NVM access command failed on offset 0x%x since that section size is multiple 2K\n",
offset);
*len = 0;
ret = 0;
} else {
IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET,
"NVM access command failed with status %d\n", ret);
ret = EIO;
}
goto exit;
}
@ -1735,7 +1752,7 @@ iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
if (bytes_read > length) {
device_printf(sc->sc_dev,
"NVM ACCESS response with too much data "
"(%d bytes requested, %zd bytes received)\n",
"(%d bytes requested, %d bytes received)\n",
length, bytes_read);
ret = EINVAL;
goto exit;