svn commit: r313311 - head/sys/dev/iwm
Adrian Chadd
adrian at FreeBSD.org
Mon Feb 6 03:06:13 UTC 2017
Author: adrian
Date: Mon Feb 6 03:06:11 2017
New Revision: 313311
URL: https://svnweb.freebsd.org/changeset/base/313311
Log:
[iwm] Sync nvm parsing code with Linux iwlwifi.
* sc->sc_nvm becomes sc->nvm_data and is now a pointer instead of an
inlined struct.
* Add sc->eeprom_size and sc->nvm_hw_section_num configuration values to
struct iwm_softc.
* For now continue to avoid negative error return-values, and use pointer
variables for some return values, as before.
* Continue to omit LAR (location aware regulatory) related code as well.
Tested:
* Intel 7260, STA mode (2GHz)
Obtained from: dragonflybsd commit 39f8331b1a6f295291e08c377da12a8e7a5436c0
Modified:
head/sys/dev/iwm/if_iwm.c
head/sys/dev/iwm/if_iwm_scan.c
head/sys/dev/iwm/if_iwm_util.c
head/sys/dev/iwm/if_iwmreg.h
head/sys/dev/iwm/if_iwmvar.h
Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c Mon Feb 6 02:20:05 2017 (r313310)
+++ head/sys/dev/iwm/if_iwm.c Mon Feb 6 03:06:11 2017 (r313311)
@@ -260,20 +260,23 @@ static int iwm_post_alive(struct iwm_sof
static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
uint16_t, uint8_t *, uint16_t *);
static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
- uint16_t *, size_t);
+ uint16_t *, uint32_t);
static uint32_t iwm_eeprom_channel_flags(uint16_t);
static void iwm_add_channel_band(struct iwm_softc *,
struct ieee80211_channel[], int, int *, int, size_t,
const uint8_t[]);
static void iwm_init_channel_map(struct ieee80211com *, int, int *,
struct ieee80211_channel[]);
-static int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
- const uint16_t *, const uint16_t *,
- const uint16_t *, const uint16_t *,
- const uint16_t *);
-static void iwm_set_hw_address_8000(struct iwm_softc *,
- struct iwm_nvm_data *,
- const uint16_t *, const uint16_t *);
+static struct iwm_nvm_data *
+ iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
+ const uint16_t *, const uint16_t *,
+ const uint16_t *, const uint16_t *,
+ const uint16_t *);
+static void iwm_free_nvm_data(struct iwm_nvm_data *);
+static void iwm_set_hw_address_family_8000(struct iwm_softc *,
+ struct iwm_nvm_data *,
+ const uint16_t *,
+ const uint16_t *);
static int iwm_get_sku(const struct iwm_softc *, const uint16_t *,
const uint16_t *);
static int iwm_get_nvm_version(const struct iwm_softc *, const uint16_t *);
@@ -283,8 +286,8 @@ static int iwm_get_n_hw_addrs(const stru
const uint16_t *);
static void iwm_set_radio_cfg(const struct iwm_softc *,
struct iwm_nvm_data *, uint32_t);
-static int iwm_parse_nvm_sections(struct iwm_softc *,
- struct iwm_nvm_section *);
+static struct iwm_nvm_data *
+ iwm_parse_nvm_sections(struct iwm_softc *, struct iwm_nvm_section *);
static int iwm_nvm_init(struct iwm_softc *);
static int iwm_firmware_load_sect(struct iwm_softc *, uint32_t,
const uint8_t *, uint32_t);
@@ -1646,21 +1649,11 @@ iwm_post_alive(struct iwm_softc *sc)
* iwlwifi/mvm/nvm.c
*/
-/* list of NVM sections we are allowed/need to read */
-const int nvm_to_read[] = {
- IWM_NVM_SECTION_TYPE_HW,
- IWM_NVM_SECTION_TYPE_SW,
- IWM_NVM_SECTION_TYPE_REGULATORY,
- IWM_NVM_SECTION_TYPE_CALIBRATION,
- IWM_NVM_SECTION_TYPE_PRODUCTION,
- IWM_NVM_SECTION_TYPE_HW_8000,
- IWM_NVM_SECTION_TYPE_MAC_OVERRIDE,
- IWM_NVM_SECTION_TYPE_PHY_SKU,
-};
+#define IWM_NVM_HW_SECTION_NUM_FAMILY_7000 0
+#define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10
/* Default NVM size to read */
#define IWM_NVM_DEFAULT_CHUNK_SIZE (2*1024)
-#define IWM_MAX_NVM_SECTION_SIZE 8192
#define IWM_NVM_WRITE_OPCODE 1
#define IWM_NVM_READ_OPCODE 0
@@ -1675,7 +1668,6 @@ static int
iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
uint16_t offset, uint16_t length, uint8_t *data, uint16_t *len)
{
- offset = 0;
struct iwm_nvm_access_cmd nvm_access_cmd = {
.offset = htole16(offset),
.length = htole16(length),
@@ -1702,17 +1694,9 @@ iwm_nvm_read_chunk(struct iwm_softc *sc,
}
pkt = cmd.resp_pkt;
- if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
- device_printf(sc->sc_dev,
- "Bad return from IWM_NVM_ACCES_COMMAND (0x%08X)\n",
- pkt->hdr.flags);
- ret = EIO;
- goto exit;
- }
/* Extract NVM response */
nvm_resp = (void *)pkt->data;
-
ret = le16toh(nvm_resp->status);
bytes_read = le16toh(nvm_resp->length);
offset_read = le16toh(nvm_resp->offset);
@@ -1758,6 +1742,7 @@ iwm_nvm_read_chunk(struct iwm_softc *sc,
goto exit;
}
+ /* Write data to NVM */
memcpy(data + offset, resp_data, bytes_read);
*len = bytes_read;
@@ -1778,34 +1763,40 @@ iwm_nvm_read_chunk(struct iwm_softc *sc,
*/
static int
iwm_nvm_read_section(struct iwm_softc *sc,
- uint16_t section, uint8_t *data, uint16_t *len, size_t max_len)
+ uint16_t section, uint8_t *data, uint16_t *len, uint32_t size_read)
{
- uint16_t chunklen, seglen;
- int error = 0;
+ uint16_t seglen, length, offset = 0;
+ int ret;
- IWM_DPRINTF(sc, IWM_DEBUG_RESET,
- "reading NVM section %d\n", section);
+ /* Set nvm section read length */
+ length = IWM_NVM_DEFAULT_CHUNK_SIZE;
- chunklen = seglen = IWM_NVM_DEFAULT_CHUNK_SIZE;
- *len = 0;
+ seglen = length;
- /* Read NVM chunks until exhausted (reading less than requested) */
- while (seglen == chunklen && *len < max_len) {
- error = iwm_nvm_read_chunk(sc,
- section, *len, chunklen, data, &seglen);
- if (error) {
- IWM_DPRINTF(sc, IWM_DEBUG_RESET,
- "Cannot read from NVM section "
- "%d at offset %d\n", section, *len);
- return error;
+ /* Read the NVM until exhausted (reading less than requested) */
+ while (seglen == length) {
+ /* Check no memory assumptions fail and cause an overflow */
+ if ((size_read + offset + length) >
+ sc->eeprom_size) {
+ device_printf(sc->sc_dev,
+ "EEPROM size is too small for NVM\n");
+ return ENOBUFS;
}
- *len += seglen;
+
+ ret = iwm_nvm_read_chunk(sc, section, offset, length, data, &seglen);
+ if (ret) {
+ IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET,
+ "Cannot read NVM from section %d offset %d, length %d\n",
+ section, offset, length);
+ return ret;
+ }
+ offset += seglen;
}
- IWM_DPRINTF(sc, IWM_DEBUG_RESET,
- "NVM section %d read completed (%d bytes, error=%d)\n",
- section, *len, error);
- return error;
+ IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET,
+ "NVM section %d read completed\n", section);
+ *len = offset;
+ return 0;
}
/*
@@ -1889,7 +1880,7 @@ enum nvm_sku_bits {
* @IWM_NVM_CHANNEL_IBSS: usable as an IBSS channel
* @IWM_NVM_CHANNEL_ACTIVE: active scanning allowed
* @IWM_NVM_CHANNEL_RADAR: radar detection required
- * XXX cannot find this (DFS) flag in iwl-nvm-parse.c
+ * XXX cannot find this (DFS) flag in iwm-nvm-parse.c
* @IWM_NVM_CHANNEL_DFS: dynamic freq selection candidate
* @IWM_NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
* @IWM_NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
@@ -1908,6 +1899,10 @@ enum iwm_nvm_channel_flags {
IWM_NVM_CHANNEL_160MHZ = (1 << 11),
};
+/* lower blocks contain EEPROM image and calibration data */
+#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(uint16_t)) /* 16 KB */
+#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */
+
/*
* Translate EEPROM flags to net80211.
*/
@@ -1935,7 +1930,7 @@ iwm_add_channel_band(struct iwm_softc *s
int maxchans, int *nchans, int ch_idx, size_t ch_num,
const uint8_t bands[])
{
- const uint16_t * const nvm_ch_flags = sc->sc_nvm.nvm_ch_flags;
+ const uint16_t * const nvm_ch_flags = sc->nvm_data->nvm_ch_flags;
uint32_t nflags;
uint16_t ch_flags;
uint8_t ieee;
@@ -1976,7 +1971,7 @@ iwm_init_channel_map(struct ieee80211com
struct ieee80211_channel chans[])
{
struct iwm_softc *sc = ic->ic_softc;
- struct iwm_nvm_data *data = &sc->sc_nvm;
+ struct iwm_nvm_data *data = sc->nvm_data;
uint8_t bands[IEEE80211_MODE_BYTES];
size_t ch_num;
@@ -2005,7 +2000,7 @@ iwm_init_channel_map(struct ieee80211com
}
static void
-iwm_set_hw_address_8000(struct iwm_softc *sc, struct iwm_nvm_data *data,
+iwm_set_hw_address_family_8000(struct iwm_softc *sc, struct iwm_nvm_data *data,
const uint16_t *mac_override, const uint16_t *nvm_hw)
{
const uint8_t *hw_addr;
@@ -2128,15 +2123,57 @@ iwm_set_radio_cfg(const struct iwm_softc
}
static int
+iwm_set_hw_address(struct iwm_softc *sc, struct iwm_nvm_data *data,
+ const uint16_t *nvm_hw, const uint16_t *mac_override)
+{
+#ifdef notyet /* for FAMILY 9000 */
+ if (cfg->mac_addr_from_csr) {
+ iwm_set_hw_address_from_csr(sc, data);
+ } else
+#endif
+ if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
+ const uint8_t *hw_addr = (const uint8_t *)(nvm_hw + IWM_HW_ADDR);
+
+ /* The byte order is little endian 16 bit, meaning 214365 */
+ data->hw_addr[0] = hw_addr[1];
+ data->hw_addr[1] = hw_addr[0];
+ data->hw_addr[2] = hw_addr[3];
+ data->hw_addr[3] = hw_addr[2];
+ data->hw_addr[4] = hw_addr[5];
+ data->hw_addr[5] = hw_addr[4];
+ } else {
+ iwm_set_hw_address_family_8000(sc, data, mac_override, nvm_hw);
+ }
+
+ if (!iwm_is_valid_ether_addr(data->hw_addr)) {
+ device_printf(sc->sc_dev, "no valid mac address was found\n");
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static struct iwm_nvm_data *
iwm_parse_nvm_data(struct iwm_softc *sc,
const uint16_t *nvm_hw, const uint16_t *nvm_sw,
const uint16_t *nvm_calib, const uint16_t *mac_override,
const uint16_t *phy_sku, const uint16_t *regulatory)
{
- struct iwm_nvm_data *data = &sc->sc_nvm;
- uint8_t hw_addr[IEEE80211_ADDR_LEN];
+ struct iwm_nvm_data *data;
uint32_t sku, radio_cfg;
+ if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
+ data = malloc(sizeof(*data) +
+ IWM_NUM_CHANNELS * sizeof(uint16_t),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
+ } else {
+ data = malloc(sizeof(*data) +
+ IWM_NUM_CHANNELS_8000 * sizeof(uint16_t),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
+ }
+ if (!data)
+ return NULL;
+
data->nvm_version = iwm_get_nvm_version(sc, nvm_sw);
radio_cfg = iwm_get_radio_cfg(sc, nvm_sw, phy_sku);
@@ -2149,17 +2186,10 @@ iwm_parse_nvm_data(struct iwm_softc *sc,
data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw);
- /* The byte order is little endian 16 bit, meaning 214365 */
- if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
- IEEE80211_ADDR_COPY(hw_addr, nvm_hw + IWM_HW_ADDR);
- data->hw_addr[0] = hw_addr[1];
- data->hw_addr[1] = hw_addr[0];
- data->hw_addr[2] = hw_addr[3];
- data->hw_addr[3] = hw_addr[2];
- data->hw_addr[4] = hw_addr[5];
- data->hw_addr[5] = hw_addr[4];
- } else {
- iwm_set_hw_address_8000(sc, data, mac_override, nvm_hw);
+ /* If no valid mac address was found - bail out */
+ if (iwm_set_hw_address(sc, data, nvm_hw, mac_override)) {
+ free(data, M_DEVBUF);
+ return NULL;
}
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
@@ -2170,14 +2200,17 @@ iwm_parse_nvm_data(struct iwm_softc *sc,
IWM_NUM_CHANNELS_8000 * sizeof(uint16_t));
}
- return 0;
+ return data;
}
-/*
- * END NVM PARSE
- */
+static void
+iwm_free_nvm_data(struct iwm_nvm_data *data)
+{
+ if (data != NULL)
+ free(data, M_DEVBUF);
+}
-static int
+static struct iwm_nvm_data *
iwm_parse_nvm_sections(struct iwm_softc *sc, struct iwm_nvm_section *sections)
{
const uint16_t *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku;
@@ -2185,42 +2218,38 @@ iwm_parse_nvm_sections(struct iwm_softc
/* Checking for required sections */
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
- !sections[IWM_NVM_SECTION_TYPE_HW].data) {
+ !sections[sc->nvm_hw_section_num].data) {
device_printf(sc->sc_dev,
"Can't parse empty OTP/NVM sections\n");
- return ENOENT;
+ return NULL;
}
-
- hw = (const uint16_t *) sections[IWM_NVM_SECTION_TYPE_HW].data;
} else if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
/* SW and REGULATORY sections are mandatory */
if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
!sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) {
device_printf(sc->sc_dev,
"Can't parse empty OTP/NVM sections\n");
- return ENOENT;
+ return NULL;
}
/* MAC_OVERRIDE or at least HW section must exist */
- if (!sections[IWM_NVM_SECTION_TYPE_HW_8000].data &&
+ if (!sections[sc->nvm_hw_section_num].data &&
!sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
device_printf(sc->sc_dev,
"Can't parse mac_address, empty sections\n");
- return ENOENT;
+ return NULL;
}
/* PHY_SKU section is mandatory in B0 */
if (!sections[IWM_NVM_SECTION_TYPE_PHY_SKU].data) {
device_printf(sc->sc_dev,
"Can't parse phy_sku in B0, empty sections\n");
- return ENOENT;
+ return NULL;
}
-
- hw = (const uint16_t *)
- sections[IWM_NVM_SECTION_TYPE_HW_8000].data;
} else {
panic("unknown device family %d\n", sc->sc_device_family);
}
+ hw = (const uint16_t *) sections[sc->nvm_hw_section_num].data;
sw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_SW].data;
calib = (const uint16_t *)
sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
@@ -2237,46 +2266,57 @@ iwm_parse_nvm_sections(struct iwm_softc
static int
iwm_nvm_init(struct iwm_softc *sc)
{
- struct iwm_nvm_section nvm_sections[IWM_NVM_NUM_OF_SECTIONS];
- int i, section, error;
+ struct iwm_nvm_section nvm_sections[IWM_NVM_MAX_NUM_SECTIONS];
+ int i, ret, section;
+ uint32_t size_read = 0;
+ uint8_t *nvm_buffer, *temp;
uint16_t len;
- uint8_t *buf;
- const size_t bufsz = IWM_MAX_NVM_SECTION_SIZE;
- memset(nvm_sections, 0 , sizeof(nvm_sections));
+ memset(nvm_sections, 0, sizeof(nvm_sections));
- buf = malloc(bufsz, M_DEVBUF, M_NOWAIT);
- if (buf == NULL)
- return ENOMEM;
+ if (sc->nvm_hw_section_num >= IWM_NVM_MAX_NUM_SECTIONS)
+ return EINVAL;
- for (i = 0; i < nitems(nvm_to_read); i++) {
- section = nvm_to_read[i];
- KASSERT(section <= nitems(nvm_sections),
- ("too many sections"));
+ /* load NVM values from nic */
+ /* Read From FW NVM */
+ IWM_DPRINTF(sc, IWM_DEBUG_EEPROM, "Read from NVM\n");
- error = iwm_nvm_read_section(sc, section, buf, &len, bufsz);
- if (error) {
- error = 0;
+ nvm_buffer = malloc(sc->eeprom_size, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!nvm_buffer)
+ return ENOMEM;
+ for (section = 0; section < IWM_NVM_MAX_NUM_SECTIONS; section++) {
+ /* we override the constness for initial read */
+ ret = iwm_nvm_read_section(sc, section, nvm_buffer,
+ &len, size_read);
+ if (ret)
continue;
- }
- nvm_sections[section].data = malloc(len, M_DEVBUF, M_NOWAIT);
- if (nvm_sections[section].data == NULL) {
- error = ENOMEM;
+ size_read += len;
+ temp = malloc(len, M_DEVBUF, M_NOWAIT);
+ if (!temp) {
+ ret = ENOMEM;
break;
}
- memcpy(nvm_sections[section].data, buf, len);
+ memcpy(temp, nvm_buffer, len);
+
+ nvm_sections[section].data = temp;
nvm_sections[section].length = len;
}
- free(buf, M_DEVBUF);
- if (error == 0)
- error = iwm_parse_nvm_sections(sc, nvm_sections);
+ if (!size_read)
+ device_printf(sc->sc_dev, "OTP is blank\n");
+ free(nvm_buffer, M_DEVBUF);
- for (i = 0; i < IWM_NVM_NUM_OF_SECTIONS; i++) {
+ sc->nvm_data = iwm_parse_nvm_sections(sc, nvm_sections);
+ if (!sc->nvm_data)
+ return EINVAL;
+ IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET,
+ "nvm version = %x\n", sc->nvm_data->nvm_version);
+
+ for (i = 0; i < IWM_NVM_MAX_NUM_SECTIONS; i++) {
if (nvm_sections[i].data != NULL)
free(nvm_sections[i].data, M_DEVBUF);
}
- return error;
+ return 0;
}
/*
@@ -2673,7 +2713,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc
device_printf(sc->sc_dev, "failed to read nvm\n");
return error;
}
- IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->sc_nvm.hw_addr);
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->nvm_data->hw_addr);
return 0;
}
@@ -2694,7 +2734,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc
__func__,
((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN)
>> IWM_FW_PHY_CFG_TX_CHAIN_POS),
- sc->sc_nvm.valid_tx_ant,
+ sc->nvm_data->valid_tx_ant,
iwm_fw_valid_tx_ant(sc));
@@ -5648,6 +5688,8 @@ iwm_dev_check(device_t dev)
case PCI_PRODUCT_INTEL_WL_3160_2:
sc->sc_fwname = "iwm3160fw";
sc->host_interrupt_operation_mode = 1;
+ sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000;
+ sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000;
sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
return (0);
@@ -5655,6 +5697,8 @@ iwm_dev_check(device_t dev)
case PCI_PRODUCT_INTEL_WL_3165_2:
sc->sc_fwname = "iwm7265fw";
sc->host_interrupt_operation_mode = 0;
+ sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000;
+ sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000;
sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
return (0);
@@ -5662,6 +5706,8 @@ iwm_dev_check(device_t dev)
case PCI_PRODUCT_INTEL_WL_7260_2:
sc->sc_fwname = "iwm7260fw";
sc->host_interrupt_operation_mode = 1;
+ sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000;
+ sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000;
sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
return (0);
@@ -5669,6 +5715,8 @@ iwm_dev_check(device_t dev)
case PCI_PRODUCT_INTEL_WL_7265_2:
sc->sc_fwname = "iwm7265fw";
sc->host_interrupt_operation_mode = 0;
+ sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000;
+ sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000;
sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
return (0);
@@ -5676,6 +5724,8 @@ iwm_dev_check(device_t dev)
case PCI_PRODUCT_INTEL_WL_8260_2:
sc->sc_fwname = "iwm8000Cfw";
sc->host_interrupt_operation_mode = 0;
+ sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000;
+ sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_8000;
sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
return (0);
@@ -5993,10 +6043,10 @@ iwm_preinit(void *arg)
device_printf(dev,
"hw rev 0x%x, fw ver %s, address %s\n",
sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
- sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
+ sc->sc_fwver, ether_sprintf(sc->nvm_data->hw_addr));
/* not all hardware can do 5GHz band */
- if (!sc->sc_nvm.sku_cap_band_52GHz_enable)
+ if (!sc->nvm_data->sku_cap_band_52GHz_enable)
memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0,
sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A]));
IWM_UNLOCK(sc);
@@ -6236,6 +6286,8 @@ iwm_detach_local(struct iwm_softc *sc, i
iwm_phy_db_free(sc->sc_phy_db);
sc->sc_phy_db = NULL;
+ iwm_free_nvm_data(sc->nvm_data);
+
/* Free descriptor rings */
iwm_free_rx_ring(sc, &sc->rxq);
for (i = 0; i < nitems(sc->txq); i++)
Modified: head/sys/dev/iwm/if_iwm_scan.c
==============================================================================
--- head/sys/dev/iwm/if_iwm_scan.c Mon Feb 6 02:20:05 2017 (r313310)
+++ head/sys/dev/iwm/if_iwm_scan.c Mon Feb 6 03:06:11 2017 (r313311)
@@ -407,7 +407,7 @@ iwm_mvm_fill_probe_req(struct iwm_softc
remain -= 3;
}
- if (sc->sc_nvm.sku_cap_band_52GHz_enable) {
+ if (sc->nvm_data->sku_cap_band_52GHz_enable) {
/* Fill in 5GHz IEs. */
rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
@@ -674,7 +674,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
req->scan_flags |= htole32(IWM_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED);
req->flags = htole32(IWM_PHY_BAND_24);
- if (sc->sc_nvm.sku_cap_band_52GHz_enable)
+ if (sc->nvm_data->sku_cap_band_52GHz_enable)
req->flags |= htole32(IWM_PHY_BAND_5);
req->filter_flags =
htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON);
Modified: head/sys/dev/iwm/if_iwm_util.c
==============================================================================
--- head/sys/dev/iwm/if_iwm_util.c Mon Feb 6 02:20:05 2017 (r313310)
+++ head/sys/dev/iwm/if_iwm_util.c Mon Feb 6 03:06:11 2017 (r313311)
@@ -437,8 +437,8 @@ iwm_fw_valid_tx_ant(struct iwm_softc *sc
tx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN)
>> IWM_FW_PHY_CFG_TX_CHAIN_POS);
- if (sc->sc_nvm.valid_tx_ant)
- tx_ant &= sc->sc_nvm.valid_tx_ant;
+ if (sc->nvm_data->valid_tx_ant)
+ tx_ant &= sc->nvm_data->valid_tx_ant;
return tx_ant;
}
@@ -451,8 +451,8 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc
rx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RX_CHAIN)
>> IWM_FW_PHY_CFG_RX_CHAIN_POS);
- if (sc->sc_nvm.valid_rx_ant)
- rx_ant &= sc->sc_nvm.valid_rx_ant;
+ if (sc->nvm_data->valid_rx_ant)
+ rx_ant &= sc->nvm_data->valid_rx_ant;
return rx_ant;
}
Modified: head/sys/dev/iwm/if_iwmreg.h
==============================================================================
--- head/sys/dev/iwm/if_iwmreg.h Mon Feb 6 02:20:05 2017 (r313310)
+++ head/sys/dev/iwm/if_iwmreg.h Mon Feb 6 03:06:11 2017 (r313311)
@@ -2023,18 +2023,13 @@ enum {
/* Section types for IWM_NVM_ACCESS_CMD */
enum {
- IWM_NVM_SECTION_TYPE_HW = 0,
- IWM_NVM_SECTION_TYPE_SW,
- IWM_NVM_SECTION_TYPE_PAPD,
- IWM_NVM_SECTION_TYPE_REGULATORY,
- IWM_NVM_SECTION_TYPE_CALIBRATION,
- IWM_NVM_SECTION_TYPE_PRODUCTION,
- IWM_NVM_SECTION_TYPE_POST_FCS_CALIB,
- /* 7, 8, 9 unknown */
- IWM_NVM_SECTION_TYPE_HW_8000 = 10,
- IWM_NVM_SECTION_TYPE_MAC_OVERRIDE,
- IWM_NVM_SECTION_TYPE_PHY_SKU,
- IWM_NVM_NUM_OF_SECTIONS,
+ IWM_NVM_SECTION_TYPE_SW = 1,
+ IWM_NVM_SECTION_TYPE_REGULATORY = 3,
+ IWM_NVM_SECTION_TYPE_CALIBRATION = 4,
+ IWM_NVM_SECTION_TYPE_PRODUCTION = 5,
+ IWM_NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
+ IWM_NVM_SECTION_TYPE_PHY_SKU = 12,
+ IWM_NVM_MAX_NUM_SECTIONS = 13,
};
/**
Modified: head/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- head/sys/dev/iwm/if_iwmvar.h Mon Feb 6 02:20:05 2017 (r313310)
+++ head/sys/dev/iwm/if_iwmvar.h Mon Feb 6 03:06:11 2017 (r313311)
@@ -192,10 +192,10 @@ struct iwm_nvm_data {
#define IWM_NUM_CHANNELS 39
#define IWM_NUM_CHANNELS_8000 51
- uint16_t nvm_ch_flags[IWM_NUM_CHANNELS_8000];
-
uint16_t nvm_version;
uint8_t max_tx_pwr_half_dbm;
+
+ uint16_t nvm_ch_flags[];
};
/* max bufs per tfd the driver will use */
@@ -291,10 +291,6 @@ struct iwm_ucode_status {
#define IWM_CMD_RESP_MAX PAGE_SIZE
-/* lower blocks contain EEPROM image and calibration data */
-#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 16384
-#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 32768
-
#define IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
#define IWM_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
@@ -455,7 +451,7 @@ struct iwm_softc {
int sc_fw_phy_config;
struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX];
- struct iwm_nvm_data sc_nvm;
+ struct iwm_nvm_data *nvm_data;
struct iwm_phy_db *sc_phy_db;
struct iwm_bf_data sc_bf;
@@ -493,6 +489,9 @@ struct iwm_softc {
struct iwm_tx_radiotap_header sc_txtap;
int sc_max_rssi;
+
+ uint16_t eeprom_size;
+ uint8_t nvm_hw_section_num;
};
#define IWM_LOCK_INIT(_sc) \
More information about the svn-src-all
mailing list