struct iwl_nvm_data * iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, const __le16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *mac_override, const __le16 *phy_sku, u8 tx_chains, u8 rx_chains, bool lar_fw_supported) { struct device *dev = trans->dev; struct iwl_nvm_data *data; bool lar_enabled; u32 sku, radio_cfg; u16 lar_config; const __le16 *ch_section; if (cfg->device_family != IWL_DEVICE_FAMILY_8000) data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, GFP_KERNEL); else data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS_FAMILY_8000, GFP_KERNEL); if (!data) return NULL; data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw, phy_sku); iwl_set_radio_cfg(cfg, data, radio_cfg); if (data->valid_tx_ant) tx_chains &= data->valid_tx_ant; if (data->valid_rx_ant) rx_chains &= data->valid_rx_ant; sku = iwl_get_sku(cfg, nvm_sw, phy_sku); data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) data->sku_cap_11n_enable = false; data->sku_cap_11ac_enable = data->sku_cap_11n_enable && (sku & NVM_SKU_CAP_11AC_ENABLE); data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE; data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { /* Checking for required sections */ if (!nvm_calib) { IWL_ERR(trans, "Can't parse empty Calib NVM sections\n"); kfree(data); return NULL; } /* in family 8000 Xtal calibration values moved to OTP */ data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); lar_enabled = true; ch_section = nvm_sw; } else { u16 lar_offset = data->nvm_version < 0xE39 ? NVM_LAR_OFFSET_FAMILY_8000_OLD : NVM_LAR_OFFSET_FAMILY_8000; lar_config = le16_to_cpup(regulatory + lar_offset); data->lar_enabled = !!(lar_config & NVM_LAR_ENABLED_FAMILY_8000); lar_enabled = data->lar_enabled; ch_section = regulatory; } /* If no valid mac address was found - bail out */ if (iwl_set_hw_address(trans, cfg, data, nvm_hw, mac_override)) { kfree(data); return NULL; } iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains, lar_fw_supported && lar_enabled); data->calib_version = 255; return data; }
struct iwl_nvm_data * iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, const __le16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib) { struct iwl_nvm_data *data; u8 hw_addr[ETH_ALEN]; u16 radio_cfg, sku; data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, GFP_KERNEL); if (!data) return NULL; data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION); radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG); data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg); data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg); data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg); data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg); sku = le16_to_cpup(nvm_sw + SKU); data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) data->sku_cap_11n_enable = false; /* check overrides (some devices have wrong NVM) */ if (cfg->valid_tx_ant) data->valid_tx_ant = cfg->valid_tx_ant; if (cfg->valid_rx_ant) data->valid_rx_ant = cfg->valid_rx_ant; if (!data->valid_tx_ant || !data->valid_rx_ant) { IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n", data->valid_tx_ant, data->valid_rx_ant); kfree(data); return NULL; } data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS); data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN); 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]; iwl_init_sbands(dev, cfg, data, nvm_sw); data->calib_version = 255; /* TODO: this value will prevent some checks from failing, we need to check if this field is still needed, and if it does, where is it in the NVM*/ return data; }
struct iwl_nvm_data * iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, const __le16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *mac_override, u8 tx_chains, u8 rx_chains) { struct iwl_nvm_data *data; u32 sku; u32 radio_cfg; if (cfg->device_family != IWL_DEVICE_FAMILY_8000) data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, GFP_KERNEL); else data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS_FAMILY_8000, GFP_KERNEL); if (!data) return NULL; data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw); iwl_set_radio_cfg(cfg, data, radio_cfg); sku = iwl_get_sku(cfg, nvm_sw); data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE; if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) data->sku_cap_11n_enable = false; data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { /* Checking for required sections */ if (!nvm_calib) { IWL_ERR_DEV(dev, "Can't parse empty Calib NVM sections\n"); kfree(data); return NULL; } /* in family 8000 Xtal calibration values moved to OTP */ data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); } if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { iwl_set_hw_address(cfg, data, nvm_hw); iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, rx_chains); } else { /* MAC address in family 8000 */ iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw); iwl_init_sbands(dev, cfg, data, regulatory, sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, rx_chains); } data->calib_version = 255; return data; }
struct iwl_nvm_data * iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, const __le16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *mac_override, const __le16 *phy_sku, u8 tx_chains, u8 rx_chains, bool lar_fw_supported, u32 mac_addr0, u32 mac_addr1, u32 hw_id) { struct iwl_nvm_data *data; u32 sku; u32 radio_cfg; u16 lar_config; if (cfg->device_family != IWL_DEVICE_FAMILY_8000) data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, GFP_KERNEL); else data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS_FAMILY_8000, GFP_KERNEL); if (!data) return NULL; data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw, phy_sku); iwl_set_radio_cfg(cfg, data, radio_cfg); if (data->valid_tx_ant) tx_chains &= data->valid_tx_ant; if (data->valid_rx_ant) rx_chains &= data->valid_rx_ant; sku = iwl_get_sku(cfg, nvm_sw, phy_sku); data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) data->sku_cap_11n_enable = false; data->sku_cap_11ac_enable = data->sku_cap_11n_enable && (sku & NVM_SKU_CAP_11AC_ENABLE); data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE; /* * OTP 0x52 bug work around * define antenna 1x1 according to MIMO disabled */ if (hw_id == IWL_4165_DEVICE_ID && data->sku_cap_mimo_disabled) { data->valid_tx_ant = ANT_B; data->valid_rx_ant = ANT_B; tx_chains = ANT_B; rx_chains = ANT_B; } data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { /* Checking for required sections */ if (!nvm_calib) { IWL_ERR_DEV(dev, "Can't parse empty Calib NVM sections\n"); kfree(data); return NULL; } /* in family 8000 Xtal calibration values moved to OTP */ data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); } if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { iwl_set_hw_address(cfg, data, nvm_hw); iwl_init_sbands(dev, cfg, data, nvm_sw, tx_chains, rx_chains, lar_fw_supported); } else { u16 lar_offset = data->nvm_version < 0xE39 ? NVM_LAR_OFFSET_FAMILY_8000_OLD : NVM_LAR_OFFSET_FAMILY_8000; lar_config = le16_to_cpup(regulatory + lar_offset); data->lar_enabled = !!(lar_config & NVM_LAR_ENABLED_FAMILY_8000); /* MAC address in family 8000 */ iwl_set_hw_address_family_8000(dev, cfg, data, mac_override, nvm_hw, mac_addr0, mac_addr1); iwl_init_sbands(dev, cfg, data, regulatory, tx_chains, rx_chains, lar_fw_supported && data->lar_enabled); } data->calib_version = 255; return data; }