Commit a6127b44 authored by Kalle Valo's avatar Kalle Valo

Merge tag 'iwlwifi-for-kalle-2017-10-06' of...

Merge tag 'iwlwifi-for-kalle-2017-10-06' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes

Second set of iwlwifi fixes for 4.14

* Fix support for 3168 device series;
* Fix a potential crash when using FW debugging recording;
* Improve channel flags parsing to avoid warnings on too long traces;
* Return -ENODATA when the temperature is not available, since the
  -EIO we were returning was causing fatal errors in userspace;
* Avoid printing too many messages in dmesg when using monitor mode,
  since this can become very noisy and completely flood the logs;
parents c503dd38 44fd09da
...@@ -309,6 +309,7 @@ const struct iwl_cfg iwl3168_2ac_cfg = { ...@@ -309,6 +309,7 @@ const struct iwl_cfg iwl3168_2ac_cfg = {
.nvm_calib_ver = IWL3168_TX_POWER_VERSION, .nvm_calib_ver = IWL3168_TX_POWER_VERSION,
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
.dccm_len = IWL7265_DCCM_LEN, .dccm_len = IWL7265_DCCM_LEN,
.nvm_type = IWL_NVM_SDP,
}; };
const struct iwl_cfg iwl7265_2ac_cfg = { const struct iwl_cfg iwl7265_2ac_cfg = {
......
...@@ -164,7 +164,7 @@ static const struct iwl_tt_params iwl8000_tt_params = { ...@@ -164,7 +164,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
.default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \ .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \
.thermal_params = &iwl8000_tt_params, \ .thermal_params = &iwl8000_tt_params, \
.apmg_not_supported = true, \ .apmg_not_supported = true, \
.ext_nvm = true, \ .nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true .dbgc_supported = true
#define IWL_DEVICE_8000 \ #define IWL_DEVICE_8000 \
......
...@@ -148,7 +148,7 @@ static const struct iwl_tt_params iwl9000_tt_params = { ...@@ -148,7 +148,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.vht_mu_mimo_supported = true, \ .vht_mu_mimo_supported = true, \
.mac_addr_from_csr = true, \ .mac_addr_from_csr = true, \
.rf_id = true, \ .rf_id = true, \
.ext_nvm = true, \ .nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true .dbgc_supported = true
const struct iwl_cfg iwl9160_2ac_cfg = { const struct iwl_cfg iwl9160_2ac_cfg = {
......
...@@ -133,7 +133,7 @@ static const struct iwl_ht_params iwl_a000_ht_params = { ...@@ -133,7 +133,7 @@ static const struct iwl_ht_params iwl_a000_ht_params = {
.use_tfh = true, \ .use_tfh = true, \
.rf_id = true, \ .rf_id = true, \
.gen2 = true, \ .gen2 = true, \
.ext_nvm = true, \ .nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true .dbgc_supported = true
const struct iwl_cfg iwla000_2ac_cfg_hr = { const struct iwl_cfg iwla000_2ac_cfg_hr = {
......
...@@ -108,6 +108,7 @@ enum iwl_nvm_access_target { ...@@ -108,6 +108,7 @@ enum iwl_nvm_access_target {
* @NVM_SECTION_TYPE_REGULATORY: regulatory section * @NVM_SECTION_TYPE_REGULATORY: regulatory section
* @NVM_SECTION_TYPE_CALIBRATION: calibration section * @NVM_SECTION_TYPE_CALIBRATION: calibration section
* @NVM_SECTION_TYPE_PRODUCTION: production section * @NVM_SECTION_TYPE_PRODUCTION: production section
* @NVM_SECTION_TYPE_REGULATORY_SDP: regulatory section used by 3168 series
* @NVM_SECTION_TYPE_MAC_OVERRIDE: MAC override section * @NVM_SECTION_TYPE_MAC_OVERRIDE: MAC override section
* @NVM_SECTION_TYPE_PHY_SKU: PHY SKU section * @NVM_SECTION_TYPE_PHY_SKU: PHY SKU section
* @NVM_MAX_NUM_SECTIONS: number of sections * @NVM_MAX_NUM_SECTIONS: number of sections
...@@ -117,6 +118,7 @@ enum iwl_nvm_section_type { ...@@ -117,6 +118,7 @@ enum iwl_nvm_section_type {
NVM_SECTION_TYPE_REGULATORY = 3, NVM_SECTION_TYPE_REGULATORY = 3,
NVM_SECTION_TYPE_CALIBRATION = 4, NVM_SECTION_TYPE_CALIBRATION = 4,
NVM_SECTION_TYPE_PRODUCTION = 5, NVM_SECTION_TYPE_PRODUCTION = 5,
NVM_SECTION_TYPE_REGULATORY_SDP = 8,
NVM_SECTION_TYPE_MAC_OVERRIDE = 11, NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
NVM_SECTION_TYPE_PHY_SKU = 12, NVM_SECTION_TYPE_PHY_SKU = 12,
NVM_MAX_NUM_SECTIONS = 13, NVM_MAX_NUM_SECTIONS = 13,
......
...@@ -1086,7 +1086,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) ...@@ -1086,7 +1086,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
/* stop recording */ /* stop recording */
iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100); iwl_fw_dbg_stop_recording(fwrt);
iwl_fw_error_dump(fwrt); iwl_fw_error_dump(fwrt);
...@@ -1104,10 +1104,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) ...@@ -1104,10 +1104,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE); u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE);
u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL); u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL);
/* stop recording */ iwl_fw_dbg_stop_recording(fwrt);
iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0);
udelay(100);
iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0);
/* wait before we collect the data till the DBGC stop */ /* wait before we collect the data till the DBGC stop */
udelay(500); udelay(500);
......
...@@ -68,6 +68,8 @@ ...@@ -68,6 +68,8 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <net/cfg80211.h> #include <net/cfg80211.h>
#include "runtime.h" #include "runtime.h"
#include "iwl-prph.h"
#include "iwl-io.h"
#include "file.h" #include "file.h"
#include "error-dump.h" #include "error-dump.h"
...@@ -194,8 +196,21 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, ...@@ -194,8 +196,21 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
iwl_fw_dbg_get_trigger((fwrt)->fw,\ iwl_fw_dbg_get_trigger((fwrt)->fw,\
(trig))) (trig)))
static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt)
{
if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100);
} else {
iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0);
udelay(100);
iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0);
}
}
static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt) static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
{ {
iwl_fw_dbg_stop_recording(fwrt);
fwrt->dump.conf = FW_DBG_INVALID; fwrt->dump.conf = FW_DBG_INVALID;
} }
......
...@@ -108,6 +108,18 @@ enum iwl_led_mode { ...@@ -108,6 +108,18 @@ enum iwl_led_mode {
IWL_LED_DISABLE, IWL_LED_DISABLE,
}; };
/**
* enum iwl_nvm_type - nvm formats
* @IWL_NVM: the regular format
* @IWL_NVM_EXT: extended NVM format
* @IWL_NVM_SDP: NVM format used by 3168 series
*/
enum iwl_nvm_type {
IWL_NVM,
IWL_NVM_EXT,
IWL_NVM_SDP,
};
/* /*
* This is the threshold value of plcp error rate per 100mSecs. It is * This is the threshold value of plcp error rate per 100mSecs. It is
* used to set and check for the validity of plcp_delta. * used to set and check for the validity of plcp_delta.
...@@ -320,7 +332,7 @@ struct iwl_pwr_tx_backoff { ...@@ -320,7 +332,7 @@ struct iwl_pwr_tx_backoff {
* @integrated: discrete or integrated * @integrated: discrete or integrated
* @gen2: a000 and on transport operation * @gen2: a000 and on transport operation
* @cdb: CDB support * @cdb: CDB support
* @ext_nvm: extended NVM format * @nvm_type: see &enum iwl_nvm_type
* *
* We enable the driver to be backward compatible wrt. hardware features. * We enable the driver to be backward compatible wrt. hardware features.
* API differences in uCode shouldn't be handled here but through TLVs * API differences in uCode shouldn't be handled here but through TLVs
...@@ -342,6 +354,7 @@ struct iwl_cfg { ...@@ -342,6 +354,7 @@ struct iwl_cfg {
const struct iwl_tt_params *thermal_params; const struct iwl_tt_params *thermal_params;
enum iwl_device_family device_family; enum iwl_device_family device_family;
enum iwl_led_mode led_mode; enum iwl_led_mode led_mode;
enum iwl_nvm_type nvm_type;
u32 max_data_size; u32 max_data_size;
u32 max_inst_size; u32 max_inst_size;
netdev_features_t features; netdev_features_t features;
...@@ -369,7 +382,6 @@ struct iwl_cfg { ...@@ -369,7 +382,6 @@ struct iwl_cfg {
use_tfh:1, use_tfh:1,
gen2:1, gen2:1,
cdb:1, cdb:1,
ext_nvm:1,
dbgc_supported:1; dbgc_supported:1;
u8 valid_tx_ant; u8 valid_tx_ant;
u8 valid_rx_ant; u8 valid_rx_ant;
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
#include "iwl-csr.h" #include "iwl-csr.h"
/* NVM offsets (in words) definitions */ /* NVM offsets (in words) definitions */
enum wkp_nvm_offsets { enum nvm_offsets {
/* NVM HW-Section offset (in words) definitions */ /* NVM HW-Section offset (in words) definitions */
SUBSYSTEM_ID = 0x0A, SUBSYSTEM_ID = 0x0A,
HW_ADDR = 0x15, HW_ADDR = 0x15,
...@@ -92,7 +92,10 @@ enum wkp_nvm_offsets { ...@@ -92,7 +92,10 @@ enum wkp_nvm_offsets {
/* NVM calibration section offset (in words) definitions */ /* NVM calibration section offset (in words) definitions */
NVM_CALIB_SECTION = 0x2B8, NVM_CALIB_SECTION = 0x2B8,
XTAL_CALIB = 0x316 - NVM_CALIB_SECTION XTAL_CALIB = 0x316 - NVM_CALIB_SECTION,
/* NVM REGULATORY -Section offset (in words) definitions */
NVM_CHANNELS_SDP = 0,
}; };
enum ext_nvm_offsets { enum ext_nvm_offsets {
...@@ -206,8 +209,36 @@ enum iwl_nvm_channel_flags { ...@@ -206,8 +209,36 @@ enum iwl_nvm_channel_flags {
NVM_CHANNEL_DC_HIGH = BIT(12), NVM_CHANNEL_DC_HIGH = BIT(12),
}; };
static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
int chan, u16 flags)
{
#define CHECK_AND_PRINT_I(x) \ #define CHECK_AND_PRINT_I(x) \
((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") ((flags & NVM_CHANNEL_##x) ? " " #x : "")
if (!(flags & NVM_CHANNEL_VALID)) {
IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n",
chan, flags);
return;
}
/* Note: already can print up to 101 characters, 110 is the limit! */
IWL_DEBUG_DEV(dev, level,
"Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n",
chan, flags,
CHECK_AND_PRINT_I(VALID),
CHECK_AND_PRINT_I(IBSS),
CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(DC_HIGH));
#undef CHECK_AND_PRINT_I
}
static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
u16 nvm_flags, const struct iwl_cfg *cfg) u16 nvm_flags, const struct iwl_cfg *cfg)
...@@ -215,7 +246,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, ...@@ -215,7 +246,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
u32 flags = IEEE80211_CHAN_NO_HT40; u32 flags = IEEE80211_CHAN_NO_HT40;
u32 last_5ghz_ht = LAST_5GHZ_HT; u32 last_5ghz_ht = LAST_5GHZ_HT;
if (cfg->ext_nvm) if (cfg->nvm_type == IWL_NVM_EXT)
last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) { if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
...@@ -268,7 +299,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -268,7 +299,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
int num_of_ch, num_2ghz_channels; int num_of_ch, num_2ghz_channels;
const u8 *nvm_chan; const u8 *nvm_chan;
if (!cfg->ext_nvm) { if (cfg->nvm_type != IWL_NVM_EXT) {
num_of_ch = IWL_NUM_CHANNELS; num_of_ch = IWL_NUM_CHANNELS;
nvm_chan = &iwl_nvm_channels[0]; nvm_chan = &iwl_nvm_channels[0];
num_2ghz_channels = NUM_2GHZ_CHANNELS; num_2ghz_channels = NUM_2GHZ_CHANNELS;
...@@ -302,12 +333,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -302,12 +333,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
* supported, hence we still want to add them to * supported, hence we still want to add them to
* the list of supported channels to cfg80211. * the list of supported channels to cfg80211.
*/ */
IWL_DEBUG_EEPROM(dev, iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
"Ch. %d Flags %x [%sGHz] - No traffic\n", nvm_chan[ch_idx], ch_flags);
nvm_chan[ch_idx],
ch_flags,
(ch_idx >= num_2ghz_channels) ?
"5.2" : "2.4");
continue; continue;
} }
...@@ -337,27 +364,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, ...@@ -337,27 +364,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
else else
channel->flags = 0; channel->flags = 0;
IWL_DEBUG_EEPROM(dev, iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
"Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n", channel->hw_value, ch_flags);
channel->hw_value, IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n",
is_5ghz ? "5.2" : "2.4", channel->hw_value, channel->max_power);
ch_flags,
CHECK_AND_PRINT_I(VALID),
CHECK_AND_PRINT_I(IBSS),
CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(DC_HIGH),
channel->max_power,
((ch_flags & NVM_CHANNEL_IBSS) &&
!(ch_flags & NVM_CHANNEL_RADAR))
? "" : "not ");
} }
return n_channels; return n_channels;
...@@ -484,7 +494,7 @@ IWL_EXPORT_SYMBOL(iwl_init_sbands); ...@@ -484,7 +494,7 @@ IWL_EXPORT_SYMBOL(iwl_init_sbands);
static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
const __le16 *phy_sku) const __le16 *phy_sku)
{ {
if (!cfg->ext_nvm) if (cfg->nvm_type != IWL_NVM_EXT)
return le16_to_cpup(nvm_sw + SKU); return le16_to_cpup(nvm_sw + SKU);
return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000));
...@@ -492,7 +502,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, ...@@ -492,7 +502,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
{ {
if (!cfg->ext_nvm) if (cfg->nvm_type != IWL_NVM_EXT)
return le16_to_cpup(nvm_sw + NVM_VERSION); return le16_to_cpup(nvm_sw + NVM_VERSION);
else else
return le32_to_cpup((__le32 *)(nvm_sw + return le32_to_cpup((__le32 *)(nvm_sw +
...@@ -502,7 +512,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) ...@@ -502,7 +512,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
const __le16 *phy_sku) const __le16 *phy_sku)
{ {
if (!cfg->ext_nvm) if (cfg->nvm_type != IWL_NVM_EXT)
return le16_to_cpup(nvm_sw + RADIO_CFG); return le16_to_cpup(nvm_sw + RADIO_CFG);
return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM)); return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM));
...@@ -513,7 +523,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) ...@@ -513,7 +523,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
{ {
int n_hw_addr; int n_hw_addr;
if (!cfg->ext_nvm) if (cfg->nvm_type != IWL_NVM_EXT)
return le16_to_cpup(nvm_sw + N_HW_ADDRS); return le16_to_cpup(nvm_sw + N_HW_ADDRS);
n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000));
...@@ -525,7 +535,7 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg, ...@@ -525,7 +535,7 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
struct iwl_nvm_data *data, struct iwl_nvm_data *data,
u32 radio_cfg) u32 radio_cfg)
{ {
if (!cfg->ext_nvm) { if (cfg->nvm_type != IWL_NVM_EXT) {
data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(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_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
...@@ -634,7 +644,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans, ...@@ -634,7 +644,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
{ {
if (cfg->mac_addr_from_csr) { if (cfg->mac_addr_from_csr) {
iwl_set_hw_address_from_csr(trans, data); iwl_set_hw_address_from_csr(trans, data);
} else if (!cfg->ext_nvm) { } else if (cfg->nvm_type != IWL_NVM_EXT) {
const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR); const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR);
/* The byte order is little endian 16 bit, meaning 214365 */ /* The byte order is little endian 16 bit, meaning 214365 */
...@@ -706,7 +716,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -706,7 +716,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
u16 lar_config; u16 lar_config;
const __le16 *ch_section; const __le16 *ch_section;
if (!cfg->ext_nvm) if (cfg->nvm_type != IWL_NVM_EXT)
data = kzalloc(sizeof(*data) + data = kzalloc(sizeof(*data) +
sizeof(struct ieee80211_channel) * sizeof(struct ieee80211_channel) *
IWL_NUM_CHANNELS, IWL_NUM_CHANNELS,
...@@ -740,7 +750,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -740,7 +750,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
if (!cfg->ext_nvm) { if (cfg->nvm_type != IWL_NVM_EXT) {
/* Checking for required sections */ /* Checking for required sections */
if (!nvm_calib) { if (!nvm_calib) {
IWL_ERR(trans, IWL_ERR(trans,
...@@ -748,11 +758,15 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -748,11 +758,15 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
kfree(data); kfree(data);
return NULL; return NULL;
} }
ch_section = cfg->nvm_type == IWL_NVM_SDP ?
&regulatory[NVM_CHANNELS_SDP] :
&nvm_sw[NVM_CHANNELS];
/* in family 8000 Xtal calibration values moved to OTP */ /* in family 8000 Xtal calibration values moved to OTP */
data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
lar_enabled = true; lar_enabled = true;
ch_section = &nvm_sw[NVM_CHANNELS];
} else { } else {
u16 lar_offset = data->nvm_version < 0xE39 ? u16 lar_offset = data->nvm_version < 0xE39 ?
NVM_LAR_OFFSET_OLD : NVM_LAR_OFFSET_OLD :
...@@ -786,7 +800,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan, ...@@ -786,7 +800,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
u32 flags = NL80211_RRF_NO_HT40; u32 flags = NL80211_RRF_NO_HT40;
u32 last_5ghz_ht = LAST_5GHZ_HT; u32 last_5ghz_ht = LAST_5GHZ_HT;
if (cfg->ext_nvm) if (cfg->nvm_type == IWL_NVM_EXT)
last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
if (ch_idx < NUM_2GHZ_CHANNELS && if (ch_idx < NUM_2GHZ_CHANNELS &&
...@@ -834,7 +848,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, ...@@ -834,7 +848,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
int ch_idx; int ch_idx;
u16 ch_flags; u16 ch_flags;
u32 reg_rule_flags, prev_reg_rule_flags = 0; u32 reg_rule_flags, prev_reg_rule_flags = 0;
const u8 *nvm_chan = cfg->ext_nvm ? const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
iwl_ext_nvm_channels : iwl_nvm_channels; iwl_ext_nvm_channels : iwl_nvm_channels;
struct ieee80211_regdomain *regd; struct ieee80211_regdomain *regd;
int size_of_regd; int size_of_regd;
...@@ -843,7 +857,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, ...@@ -843,7 +857,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
int center_freq, prev_center_freq = 0; int center_freq, prev_center_freq = 0;
int valid_rules = 0; int valid_rules = 0;
bool new_rule; bool new_rule;
int max_num_ch = cfg->ext_nvm ? int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS;
if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
...@@ -873,12 +887,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, ...@@ -873,12 +887,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
new_rule = false; new_rule = false;
if (!(ch_flags & NVM_CHANNEL_VALID)) { if (!(ch_flags & NVM_CHANNEL_VALID)) {
IWL_DEBUG_DEV(dev, IWL_DL_LAR, iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
"Ch. %d Flags %x [%sGHz] - No traffic\n", nvm_chan[ch_idx], ch_flags);
nvm_chan[ch_idx],
ch_flags,
(ch_idx >= NUM_2GHZ_CHANNELS) ?
"5.2" : "2.4");
continue; continue;
} }
...@@ -914,31 +924,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, ...@@ -914,31 +924,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
prev_center_freq = center_freq; prev_center_freq = center_freq;
prev_reg_rule_flags = reg_rule_flags; prev_reg_rule_flags = reg_rule_flags;
IWL_DEBUG_DEV(dev, IWL_DL_LAR, iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
"Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x)\n", nvm_chan[ch_idx], ch_flags);
center_freq,
band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
CHECK_AND_PRINT_I(VALID),
CHECK_AND_PRINT_I(IBSS),
CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(INDOOR_ONLY),
CHECK_AND_PRINT_I(GO_CONCURRENT),
CHECK_AND_PRINT_I(UNIFORM),
CHECK_AND_PRINT_I(20MHZ),
CHECK_AND_PRINT_I(40MHZ),
CHECK_AND_PRINT_I(80MHZ),
CHECK_AND_PRINT_I(160MHZ),
CHECK_AND_PRINT_I(DC_HIGH),
ch_flags);
IWL_DEBUG_DEV(dev, IWL_DL_LAR,
"Ch. %d [%sGHz] reg_flags 0x%x: %s\n",
center_freq,
band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
reg_rule_flags,
((ch_flags & NVM_CHANNEL_ACTIVE) &&
!(ch_flags & NVM_CHANNEL_RADAR))
? "Ad-Hoc" : "");
} }
regd->n_reg_rules = valid_rules; regd->n_reg_rules = valid_rules;
......
...@@ -1077,6 +1077,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) ...@@ -1077,6 +1077,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
mvm->vif_count = 0; mvm->vif_count = 0;
mvm->rx_ba_sessions = 0; mvm->rx_ba_sessions = 0;
mvm->fwrt.dump.conf = FW_DBG_INVALID; mvm->fwrt.dump.conf = FW_DBG_INVALID;
mvm->monitor_on = false;
/* keep statistics ticking */ /* keep statistics ticking */
iwl_mvm_accu_radio_stats(mvm); iwl_mvm_accu_radio_stats(mvm);
...@@ -1437,6 +1438,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, ...@@ -1437,6 +1438,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
mvm->p2p_device_vif = vif; mvm->p2p_device_vif = vif;
} }
if (vif->type == NL80211_IFTYPE_MONITOR)
mvm->monitor_on = true;
iwl_mvm_vif_dbgfs_register(mvm, vif); iwl_mvm_vif_dbgfs_register(mvm, vif);
goto out_unlock; goto out_unlock;
...@@ -1526,6 +1530,9 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, ...@@ -1526,6 +1530,9 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
iwl_mvm_power_update_mac(mvm); iwl_mvm_power_update_mac(mvm);
iwl_mvm_mac_ctxt_remove(mvm, vif); iwl_mvm_mac_ctxt_remove(mvm, vif);
if (vif->type == NL80211_IFTYPE_MONITOR)
mvm->monitor_on = false;
out_release: out_release:
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
} }
......
...@@ -1015,6 +1015,9 @@ struct iwl_mvm { ...@@ -1015,6 +1015,9 @@ struct iwl_mvm {
bool drop_bcn_ap_mode; bool drop_bcn_ap_mode;
struct delayed_work cs_tx_unblock_dwork; struct delayed_work cs_tx_unblock_dwork;
/* does a monitor vif exist (only one can exist hence bool) */
bool monitor_on;
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
struct iwl_mvm_sar_profile sar_profiles[IWL_MVM_SAR_PROFILE_NUM]; struct iwl_mvm_sar_profile sar_profiles[IWL_MVM_SAR_PROFILE_NUM];
struct iwl_mvm_geo_profile geo_profiles[IWL_NUM_GEO_PROFILES]; struct iwl_mvm_geo_profile geo_profiles[IWL_NUM_GEO_PROFILES];
...@@ -1159,7 +1162,7 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) ...@@ -1159,7 +1162,7 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm)
* Enable LAR only if it is supported by the FW (TLV) && * Enable LAR only if it is supported by the FW (TLV) &&
* enabled in the NVM * enabled in the NVM
*/ */
if (mvm->cfg->ext_nvm) if (mvm->cfg->nvm_type == IWL_NVM_EXT)
return nvm_lar && tlv_lar; return nvm_lar && tlv_lar;
else else
return tlv_lar; return tlv_lar;
......
...@@ -295,18 +295,24 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) ...@@ -295,18 +295,24 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
const __be16 *hw; const __be16 *hw;
const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku; const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku;
bool lar_enabled; bool lar_enabled;
int regulatory_type;
/* Checking for required sections */ /* Checking for required sections */
if (!mvm->trans->cfg->ext_nvm) { if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) {
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n"); IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n");
return NULL; return NULL;
} }
} else { } else {
if (mvm->trans->cfg->nvm_type == IWL_NVM_SDP)
regulatory_type = NVM_SECTION_TYPE_REGULATORY_SDP;
else
regulatory_type = NVM_SECTION_TYPE_REGULATORY;
/* SW and REGULATORY sections are mandatory */ /* SW and REGULATORY sections are mandatory */
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
!mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) { !mvm->nvm_sections[regulatory_type].data) {
IWL_ERR(mvm, IWL_ERR(mvm,
"Can't parse empty family 8000 OTP/NVM sections\n"); "Can't parse empty family 8000 OTP/NVM sections\n");
return NULL; return NULL;
...@@ -330,11 +336,14 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) ...@@ -330,11 +336,14 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data; hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
mac_override = mac_override =
(const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data; (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data;
phy_sku = (const __le16 *)sections[NVM_SECTION_TYPE_PHY_SKU].data; phy_sku = (const __le16 *)sections[NVM_SECTION_TYPE_PHY_SKU].data;
regulatory = mvm->trans->cfg->nvm_type == IWL_NVM_SDP ?
(const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY_SDP].data :
(const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
lar_enabled = !iwlwifi_mod_params.lar_disable && lar_enabled = !iwlwifi_mod_params.lar_disable &&
fw_has_capa(&mvm->fw->ucode_capa, fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_LAR_SUPPORT); IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
...@@ -394,7 +403,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) ...@@ -394,7 +403,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
/* Maximal size depends on NVM version */ /* Maximal size depends on NVM version */
if (!mvm->trans->cfg->ext_nvm) if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT)
max_section_size = IWL_MAX_NVM_SECTION_SIZE; max_section_size = IWL_MAX_NVM_SECTION_SIZE;
else else
max_section_size = IWL_MAX_EXT_NVM_SECTION_SIZE; max_section_size = IWL_MAX_EXT_NVM_SECTION_SIZE;
...@@ -465,7 +474,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) ...@@ -465,7 +474,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
break; break;
} }
if (!mvm->trans->cfg->ext_nvm) { if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) {
section_size = section_size =
2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1)); 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2)); section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
...@@ -740,7 +749,7 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm) ...@@ -740,7 +749,7 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm)
struct ieee80211_regdomain *regd; struct ieee80211_regdomain *regd;
char mcc[3]; char mcc[3];
if (mvm->cfg->ext_nvm) { if (mvm->cfg->nvm_type == IWL_NVM_EXT) {
tlv_lar = fw_has_capa(&mvm->fw->ucode_capa, tlv_lar = fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_LAR_SUPPORT); IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
nvm_lar = mvm->nvm_data->lar_enabled; nvm_lar = mvm->nvm_data->lar_enabled;
......
...@@ -244,6 +244,8 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm, ...@@ -244,6 +244,8 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
return 0; return 0;
default: default:
/* Expected in monitor (not having the keys) */
if (!mvm->monitor_on)
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
} }
......
...@@ -277,6 +277,8 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, ...@@ -277,6 +277,8 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
stats->flag |= RX_FLAG_DECRYPTED; stats->flag |= RX_FLAG_DECRYPTED;
return 0; return 0;
default: default:
/* Expected in monitor (not having the keys) */
if (!mvm->monitor_on)
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status);
} }
......
...@@ -631,7 +631,7 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device, ...@@ -631,7 +631,7 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
if (!iwl_mvm_firmware_running(mvm) || if (!iwl_mvm_firmware_running(mvm) ||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) { mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
ret = -EIO; ret = -ENODATA;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment