Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
This commit is contained in:
commit
0971f7d991
|
@ -109,7 +109,7 @@ extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
|
|||
|
||||
struct iwl_ucode_capabilities;
|
||||
|
||||
extern struct ieee80211_ops iwlagn_hw_ops;
|
||||
extern const struct ieee80211_ops iwlagn_hw_ops;
|
||||
|
||||
static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
|
||||
{
|
||||
|
@ -480,7 +480,7 @@ do { \
|
|||
} while (0)
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
|
||||
extern const char *iwl_dvm_cmd_strings[REPLY_MAX];
|
||||
extern const char *const iwl_dvm_cmd_strings[REPLY_MAX];
|
||||
|
||||
static inline const char *iwl_dvm_get_cmd_string(u8 cmd)
|
||||
{
|
||||
|
|
|
@ -317,7 +317,7 @@ static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
|
|||
.nrg_th_cca = 62,
|
||||
};
|
||||
|
||||
static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
|
||||
static const struct iwl_sensitivity_ranges iwl5150_sensitivity = {
|
||||
.min_nrg_cck = 95,
|
||||
.auto_corr_min_ofdm = 90,
|
||||
.auto_corr_min_ofdm_mrc = 170,
|
||||
|
|
|
@ -1564,7 +1564,7 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
|
|||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
|
||||
struct ieee80211_ops iwlagn_hw_ops = {
|
||||
const struct ieee80211_ops iwlagn_hw_ops = {
|
||||
.tx = iwlagn_mac_tx,
|
||||
.start = iwlagn_mac_start,
|
||||
.stop = iwlagn_mac_stop,
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define IWL_CMD_ENTRY(x) [x] = #x
|
||||
|
||||
const char *iwl_dvm_cmd_strings[REPLY_MAX] = {
|
||||
const char *const iwl_dvm_cmd_strings[REPLY_MAX] = {
|
||||
IWL_CMD_ENTRY(REPLY_ALIVE),
|
||||
IWL_CMD_ENTRY(REPLY_ERROR),
|
||||
IWL_CMD_ENTRY(REPLY_ECHO),
|
||||
|
|
|
@ -404,6 +404,38 @@ static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
{
|
||||
const struct iwl_ucode_api *ucode_api = (void *)data;
|
||||
u32 api_index = le32_to_cpu(ucode_api->api_index);
|
||||
|
||||
if (api_index >= IWL_API_ARRAY_SIZE) {
|
||||
IWL_ERR(drv, "api_index larger than supported by driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
capa->api[api_index] = le32_to_cpu(ucode_api->api_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
{
|
||||
const struct iwl_ucode_capa *ucode_capa = (void *)data;
|
||||
u32 api_index = le32_to_cpu(ucode_capa->api_index);
|
||||
|
||||
if (api_index >= IWL_CAPABILITIES_ARRAY_SIZE) {
|
||||
IWL_ERR(drv, "api_index larger than supported by driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
capa->capa[api_index] = le32_to_cpu(ucode_capa->api_capa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
const struct firmware *ucode_raw,
|
||||
struct iwl_firmware_pieces *pieces)
|
||||
|
@ -638,6 +670,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
*/
|
||||
capa->flags = le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_API_CHANGES_SET:
|
||||
if (tlv_len != sizeof(struct iwl_ucode_api))
|
||||
goto invalid_tlv_len;
|
||||
if (iwl_set_ucode_api_flags(drv, tlv_data, capa))
|
||||
goto tlv_error;
|
||||
break;
|
||||
case IWL_UCODE_TLV_ENABLED_CAPABILITIES:
|
||||
if (tlv_len != sizeof(struct iwl_ucode_capa))
|
||||
goto invalid_tlv_len;
|
||||
if (iwl_set_ucode_capabilities(drv, tlv_data, capa))
|
||||
goto tlv_error;
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
|
@ -728,6 +772,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
|
||||
drv->fw.valid_tx_ant = (drv->fw.phy_config &
|
||||
FW_PHY_CFG_TX_CHAIN) >>
|
||||
FW_PHY_CFG_TX_CHAIN_POS;
|
||||
drv->fw.valid_rx_ant = (drv->fw.phy_config &
|
||||
FW_PHY_CFG_RX_CHAIN) >>
|
||||
FW_PHY_CFG_RX_CHAIN_POS;
|
||||
break;
|
||||
case IWL_UCODE_TLV_SECURE_SEC_RT:
|
||||
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
|
||||
|
@ -1301,8 +1351,7 @@ MODULE_PARM_DESC(antenna_coupling,
|
|||
|
||||
module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
|
||||
MODULE_PARM_DESC(wd_disable,
|
||||
"Disable stuck queue watchdog timer 0=system default, "
|
||||
"1=disable, 2=enable (default: 0)");
|
||||
"Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)");
|
||||
|
||||
module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(nvm_file, "NVM file name");
|
||||
|
|
|
@ -70,6 +70,20 @@
|
|||
#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
|
||||
/* radio config bits (actual values from NVM definition) */
|
||||
#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
|
||||
#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
|
||||
#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
|
||||
#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
|
||||
#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
|
||||
#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
|
||||
|
||||
#define NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(x) (x & 0xF)
|
||||
#define NVM_RF_CFG_DASH_MSK_FAMILY_8000(x) ((x >> 4) & 0xF)
|
||||
#define NVM_RF_CFG_STEP_MSK_FAMILY_8000(x) ((x >> 8) & 0xF)
|
||||
#define NVM_RF_CFG_TYPE_MSK_FAMILY_8000(x) ((x >> 12) & 0xFFF)
|
||||
#define NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(x) ((x >> 24) & 0xF)
|
||||
#define NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(x) ((x >> 28) & 0xF)
|
||||
|
||||
/**
|
||||
* DOC: Driver system flows - drv component
|
||||
|
|
|
@ -81,16 +81,17 @@ struct iwl_nvm_data {
|
|||
bool sku_cap_band_24GHz_enable;
|
||||
bool sku_cap_band_52GHz_enable;
|
||||
bool sku_cap_11n_enable;
|
||||
bool sku_cap_11ac_enable;
|
||||
bool sku_cap_amt_enable;
|
||||
bool sku_cap_ipan_enable;
|
||||
|
||||
u8 radio_cfg_type;
|
||||
u16 radio_cfg_type;
|
||||
u8 radio_cfg_step;
|
||||
u8 radio_cfg_dash;
|
||||
u8 radio_cfg_pnum;
|
||||
u8 valid_tx_ant, valid_rx_ant;
|
||||
|
||||
u16 nvm_version;
|
||||
u32 nvm_version;
|
||||
s8 max_tx_pwr_half_dbm;
|
||||
|
||||
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
|
||||
|
|
|
@ -126,6 +126,8 @@ enum iwl_ucode_tlv_type {
|
|||
IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26,
|
||||
IWL_UCODE_TLV_NUM_OF_CPU = 27,
|
||||
IWL_UCODE_TLV_CSCHEME = 28,
|
||||
IWL_UCODE_TLV_API_CHANGES_SET = 29,
|
||||
IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
|
||||
};
|
||||
|
||||
struct iwl_ucode_tlv {
|
||||
|
@ -158,4 +160,19 @@ struct iwl_tlv_ucode_header {
|
|||
u8 data[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* ucode TLVs
|
||||
*
|
||||
* ability to get extension for: flags & capabilities from ucode binaries files
|
||||
*/
|
||||
struct iwl_ucode_api {
|
||||
__le32 api_index;
|
||||
__le32 api_flags;
|
||||
} __packed;
|
||||
|
||||
struct iwl_ucode_capa {
|
||||
__le32 api_index;
|
||||
__le32 api_capa;
|
||||
} __packed;
|
||||
|
||||
#endif /* __iwl_fw_file_h__ */
|
||||
|
|
|
@ -92,8 +92,8 @@
|
|||
* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
|
||||
* @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
|
||||
* containing CAM (Continuous Active Mode) indication.
|
||||
* @IWL_UCODE_TLV_FLAGS_P2P_PS: P2P client power save is supported (only on a
|
||||
* single bound interface).
|
||||
* @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
|
||||
* P2P client interfaces simultaneously if they are in different bindings.
|
||||
* @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
|
||||
* @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
|
||||
* @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
|
||||
|
@ -118,7 +118,7 @@ enum iwl_ucode_tlv_flag {
|
|||
IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
|
||||
IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
|
||||
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
|
||||
IWL_UCODE_TLV_FLAGS_P2P_PS = BIT(21),
|
||||
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
|
||||
IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
|
||||
IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
|
||||
IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
|
||||
|
@ -165,11 +165,15 @@ enum iwl_ucode_sec {
|
|||
* just an offset to the HW address.
|
||||
*/
|
||||
#define IWL_UCODE_SECTION_MAX 12
|
||||
#define IWL_API_ARRAY_SIZE 1
|
||||
#define IWL_CAPABILITIES_ARRAY_SIZE 1
|
||||
|
||||
struct iwl_ucode_capabilities {
|
||||
u32 max_probe_length;
|
||||
u32 standard_phy_calibration_size;
|
||||
u32 flags;
|
||||
u32 api[IWL_API_ARRAY_SIZE];
|
||||
u32 capa[IWL_CAPABILITIES_ARRAY_SIZE];
|
||||
};
|
||||
|
||||
/* one for each uCode image (inst/data, init/runtime/wowlan) */
|
||||
|
@ -288,22 +292,12 @@ struct iwl_fw {
|
|||
|
||||
struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
|
||||
u32 phy_config;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
|
||||
bool mvm_fw;
|
||||
|
||||
struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
|
||||
};
|
||||
|
||||
static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
|
||||
{
|
||||
return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >>
|
||||
FW_PHY_CFG_TX_CHAIN_POS;
|
||||
}
|
||||
|
||||
static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
|
||||
{
|
||||
return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >>
|
||||
FW_PHY_CFG_RX_CHAIN_POS;
|
||||
}
|
||||
|
||||
#endif /* __iwl_fw_h__ */
|
||||
|
|
|
@ -93,7 +93,7 @@ enum iwl_power_level {
|
|||
* use IWL_DISABLE_HT_* constants
|
||||
* @amsdu_size_8K: enable 8K amsdu size, default = 0
|
||||
* @restart_fw: restart firmware, default = 1
|
||||
* @wd_disable: enable stuck queue check, default = 0
|
||||
* @wd_disable: disable stuck queue check, default = 1
|
||||
* @bt_coex_active: enable bt coex, default = true
|
||||
* @led_mode: system default, default = 0
|
||||
* @power_save: disable power save, default = false
|
||||
|
|
|
@ -71,7 +71,7 @@ enum wkp_nvm_offsets {
|
|||
/* NVM HW-Section offset (in words) definitions */
|
||||
HW_ADDR = 0x15,
|
||||
|
||||
/* NVM SW-Section offset (in words) definitions */
|
||||
/* NVM SW-Section offset (in words) definitions */
|
||||
NVM_SW_SECTION = 0x1C0,
|
||||
NVM_VERSION = 0,
|
||||
RADIO_CFG = 1,
|
||||
|
@ -79,11 +79,32 @@ enum wkp_nvm_offsets {
|
|||
N_HW_ADDRS = 3,
|
||||
NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
|
||||
|
||||
/* NVM calibration section offset (in words) definitions */
|
||||
/* NVM calibration section offset (in words) definitions */
|
||||
NVM_CALIB_SECTION = 0x2B8,
|
||||
XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
|
||||
};
|
||||
|
||||
enum family_8000_nvm_offsets {
|
||||
/* NVM HW-Section offset (in words) definitions */
|
||||
HW_ADDR0_FAMILY_8000 = 0x12,
|
||||
HW_ADDR1_FAMILY_8000 = 0x16,
|
||||
MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
|
||||
|
||||
/* NVM SW-Section offset (in words) definitions */
|
||||
NVM_SW_SECTION_FAMILY_8000 = 0x1C0,
|
||||
NVM_VERSION_FAMILY_8000 = 0,
|
||||
RADIO_CFG_FAMILY_8000 = 2,
|
||||
SKU_FAMILY_8000 = 4,
|
||||
N_HW_ADDRS_FAMILY_8000 = 5,
|
||||
|
||||
/* NVM REGULATORY -Section offset (in words) definitions */
|
||||
NVM_CHANNELS_FAMILY_8000 = 0,
|
||||
|
||||
/* NVM calibration section offset (in words) definitions */
|
||||
NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
|
||||
XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
|
||||
};
|
||||
|
||||
/* SKU Capabilities (actual values from NVM definition) */
|
||||
enum nvm_sku_bits {
|
||||
NVM_SKU_CAP_BAND_24GHZ = BIT(0),
|
||||
|
@ -92,14 +113,6 @@ enum nvm_sku_bits {
|
|||
NVM_SKU_CAP_11AC_ENABLE = BIT(3),
|
||||
};
|
||||
|
||||
/* radio config bits (actual values from NVM definition) */
|
||||
#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
|
||||
#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
|
||||
#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
|
||||
#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
|
||||
#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
|
||||
#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
|
||||
|
||||
/*
|
||||
* These are the channel numbers in the order that they are stored in the NVM
|
||||
*/
|
||||
|
@ -112,7 +125,17 @@ static const u8 iwl_nvm_channels[] = {
|
|||
149, 153, 157, 161, 165
|
||||
};
|
||||
|
||||
static const u8 iwl_nvm_channels_family_8000[] = {
|
||||
/* 2.4 GHz */
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
/* 5 GHz */
|
||||
36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
|
||||
96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
|
||||
149, 153, 157, 161, 165, 169, 173, 177, 181
|
||||
};
|
||||
|
||||
#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
|
||||
#define IWL_NUM_CHANNELS_FAMILY_8000 ARRAY_SIZE(iwl_nvm_channels_family_8000)
|
||||
#define NUM_2GHZ_CHANNELS 14
|
||||
#define FIRST_2GHZ_HT_MINUS 5
|
||||
#define LAST_2GHZ_HT_PLUS 9
|
||||
|
@ -179,8 +202,18 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||
struct ieee80211_channel *channel;
|
||||
u16 ch_flags;
|
||||
bool is_5ghz;
|
||||
int num_of_ch;
|
||||
const u8 *nvm_chan;
|
||||
|
||||
for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
num_of_ch = IWL_NUM_CHANNELS;
|
||||
nvm_chan = &iwl_nvm_channels[0];
|
||||
} else {
|
||||
num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
|
||||
nvm_chan = &iwl_nvm_channels_family_8000[0];
|
||||
}
|
||||
|
||||
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
|
||||
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
|
||||
|
||||
if (ch_idx >= NUM_2GHZ_CHANNELS &&
|
||||
|
@ -190,7 +223,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||
if (!(ch_flags & NVM_CHANNEL_VALID)) {
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
"Ch. %d Flags %x [%sGHz] - No traffic\n",
|
||||
iwl_nvm_channels[ch_idx],
|
||||
nvm_chan[ch_idx],
|
||||
ch_flags,
|
||||
(ch_idx >= NUM_2GHZ_CHANNELS) ?
|
||||
"5.2" : "2.4");
|
||||
|
@ -200,7 +233,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||
channel = &data->channels[n_channels];
|
||||
n_channels++;
|
||||
|
||||
channel->hw_value = iwl_nvm_channels[ch_idx];
|
||||
channel->hw_value = nvm_chan[ch_idx];
|
||||
channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
|
||||
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
|
||||
channel->center_freq =
|
||||
|
@ -211,11 +244,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||
channel->flags = IEEE80211_CHAN_NO_HT40;
|
||||
if (ch_idx < NUM_2GHZ_CHANNELS &&
|
||||
(ch_flags & NVM_CHANNEL_40MHZ)) {
|
||||
if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
|
||||
if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
|
||||
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
|
||||
if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
|
||||
if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
|
||||
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
|
||||
} else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
|
||||
} else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
|
||||
(ch_flags & NVM_CHANNEL_40MHZ)) {
|
||||
if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
|
||||
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
|
||||
|
@ -307,14 +340,23 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
|
|||
}
|
||||
|
||||
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data, const __le16 *nvm_sw,
|
||||
bool enable_vht, u8 tx_chains, u8 rx_chains)
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 *ch_section, bool enable_vht,
|
||||
u8 tx_chains, u8 rx_chains)
|
||||
{
|
||||
int n_channels = iwl_init_channel_map(dev, cfg, data,
|
||||
&nvm_sw[NVM_CHANNELS]);
|
||||
int n_channels;
|
||||
int n_used = 0;
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
n_channels = iwl_init_channel_map(
|
||||
dev, cfg, data,
|
||||
&ch_section[NVM_CHANNELS]);
|
||||
else
|
||||
n_channels = iwl_init_channel_map(
|
||||
dev, cfg, data,
|
||||
&ch_section[NVM_CHANNELS_FAMILY_8000]);
|
||||
|
||||
sband = &data->bands[IEEE80211_BAND_2GHZ];
|
||||
sband->band = IEEE80211_BAND_2GHZ;
|
||||
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
|
||||
|
@ -340,67 +382,150 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
|||
n_used, n_channels);
|
||||
}
|
||||
|
||||
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, u8 tx_chains, u8 rx_chains)
|
||||
static int iwl_get_sku(const struct iwl_cfg *cfg,
|
||||
const __le16 *nvm_sw)
|
||||
{
|
||||
struct iwl_nvm_data *data;
|
||||
u8 hw_addr[ETH_ALEN];
|
||||
u16 radio_cfg, sku;
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
return le16_to_cpup(nvm_sw + SKU);
|
||||
else
|
||||
return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data) +
|
||||
sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return NULL;
|
||||
static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
|
||||
const __le16 *nvm_sw)
|
||||
{
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
return le16_to_cpup(nvm_sw + NVM_VERSION);
|
||||
else
|
||||
return le32_to_cpup((__le32 *)(nvm_sw +
|
||||
NVM_VERSION_FAMILY_8000));
|
||||
}
|
||||
|
||||
data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
|
||||
static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
|
||||
const __le16 *nvm_sw)
|
||||
{
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
return le16_to_cpup(nvm_sw + RADIO_CFG);
|
||||
else
|
||||
return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
|
||||
}
|
||||
|
||||
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);
|
||||
#define N_HW_ADDRS_MASK_FAMILY_8000 0xF
|
||||
static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
|
||||
const __le16 *nvm_sw)
|
||||
{
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
return le16_to_cpup(nvm_sw + N_HW_ADDRS);
|
||||
else
|
||||
return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000))
|
||||
& N_HW_ADDRS_MASK_FAMILY_8000;
|
||||
}
|
||||
|
||||
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;
|
||||
static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
u32 radio_cfg)
|
||||
{
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
|
||||
/* set the radio configuration for family 8000 */
|
||||
data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK_FAMILY_8000(radio_cfg);
|
||||
data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
|
||||
data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
|
||||
data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
|
||||
}
|
||||
|
||||
data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
|
||||
data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
|
||||
static void iwl_set_hw_address(const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 *nvm_sec)
|
||||
{
|
||||
u8 hw_addr[ETH_ALEN];
|
||||
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
|
||||
else
|
||||
memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
|
||||
ETH_ALEN);
|
||||
|
||||
/* The byte order is little endian 16 bit, meaning 214365 */
|
||||
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, sku & NVM_SKU_CAP_11AC_ENABLE,
|
||||
tx_chains, rx_chains);
|
||||
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(cfg, data, mac_override);
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, regulatory,
|
||||
sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
|
||||
rx_chains);
|
||||
}
|
||||
|
||||
data->calib_version = 255;
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
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, u8 tx_chains, u8 rx_chains);
|
||||
const __le16 *nvm_calib, const __le16 *regulatory,
|
||||
const __le16 *mac_override, u8 tx_chains, u8 rx_chains);
|
||||
|
||||
#endif /* __iwl_nvm_parse_h__ */
|
||||
|
|
|
@ -393,7 +393,7 @@ struct iwl_trans_config {
|
|||
bool rx_buf_size_8k;
|
||||
bool bc_table_dword;
|
||||
unsigned int queue_watchdog_timeout;
|
||||
const char **command_names;
|
||||
const char *const *command_names;
|
||||
};
|
||||
|
||||
struct iwl_trans;
|
||||
|
|
|
@ -591,7 +591,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
|
||||
((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
|
||||
(vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
|
||||
mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)))
|
||||
mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)))
|
||||
MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
|
||||
S_IRUSR);
|
||||
|
||||
|
|
|
@ -531,6 +531,76 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
|
|||
}
|
||||
#undef PRINT_STAT_LE32
|
||||
|
||||
static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
|
||||
char __user *user_buf, size_t count,
|
||||
loff_t *ppos,
|
||||
struct iwl_mvm_frame_stats *stats)
|
||||
{
|
||||
char *buff;
|
||||
int pos = 0, idx, i;
|
||||
int ret;
|
||||
size_t bufsz = 1024;
|
||||
|
||||
buff = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!buff)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&mvm->drv_stats_lock);
|
||||
pos += scnprintf(buff + pos, bufsz - pos,
|
||||
"Legacy/HT/VHT\t:\t%d/%d/%d\n",
|
||||
stats->legacy_frames,
|
||||
stats->ht_frames,
|
||||
stats->vht_frames);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "20/40/80\t:\t%d/%d/%d\n",
|
||||
stats->bw_20_frames,
|
||||
stats->bw_40_frames,
|
||||
stats->bw_80_frames);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "NGI/SGI\t\t:\t%d/%d\n",
|
||||
stats->ngi_frames,
|
||||
stats->sgi_frames);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "SISO/MIMO2\t:\t%d/%d\n",
|
||||
stats->siso_frames,
|
||||
stats->mimo2_frames);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "FAIL/SCSS\t:\t%d/%d\n",
|
||||
stats->fail_frames,
|
||||
stats->success_frames);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "MPDUs agg\t:\t%d\n",
|
||||
stats->agg_frames);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "A-MPDUs\t\t:\t%d\n",
|
||||
stats->ampdu_count);
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "Avg MPDUs/A-MPDU:\t%d\n",
|
||||
stats->ampdu_count > 0 ?
|
||||
(stats->agg_frames / stats->ampdu_count) : 0);
|
||||
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "Last Rates\n");
|
||||
|
||||
idx = stats->last_frame_idx - 1;
|
||||
for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) {
|
||||
idx = (idx + 1) % ARRAY_SIZE(stats->last_rates);
|
||||
if (stats->last_rates[idx] == 0)
|
||||
continue;
|
||||
pos += scnprintf(buff + pos, bufsz - pos, "Rate[%d]: ",
|
||||
(int)(ARRAY_SIZE(stats->last_rates) - i));
|
||||
pos += rs_pretty_print_rate(buff + pos, stats->last_rates[idx]);
|
||||
}
|
||||
spin_unlock_bh(&mvm->drv_stats_lock);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos);
|
||||
kfree(buff);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
|
||||
char __user *user_buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
|
||||
return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos,
|
||||
&mvm->drv_rx_stats);
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
@ -591,7 +661,7 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
|
|||
return -EINVAL;
|
||||
if (scan_rx_ant > ANT_ABC)
|
||||
return -EINVAL;
|
||||
if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
|
||||
if (scan_rx_ant & ~mvm->fw->valid_rx_ant)
|
||||
return -EINVAL;
|
||||
|
||||
mvm->scan_rx_ant = scan_rx_ant;
|
||||
|
@ -907,6 +977,49 @@ static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
|
|||
#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
|
||||
MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
|
||||
|
||||
static ssize_t
|
||||
iwl_dbgfs_prph_reg_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
int pos = 0;
|
||||
char buf[32];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
|
||||
if (!mvm->dbgfs_prph_reg_addr)
|
||||
return -EINVAL;
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
|
||||
mvm->dbgfs_prph_reg_addr,
|
||||
iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
u8 args;
|
||||
u32 value;
|
||||
|
||||
args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
|
||||
/* if we only want to set the reg address - nothing more to do */
|
||||
if (args == 1)
|
||||
goto out;
|
||||
|
||||
/* otherwise, make sure we have both address and value */
|
||||
if (args != 2)
|
||||
return -EINVAL;
|
||||
|
||||
iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
|
||||
out:
|
||||
return count;
|
||||
}
|
||||
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
|
||||
|
||||
/* Device wide debugfs entries */
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
|
||||
|
@ -916,6 +1029,7 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
|
|||
MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
|
||||
|
@ -947,10 +1061,12 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
|||
MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
|
||||
S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
|
||||
S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
|
|
|
@ -257,7 +257,8 @@ enum {
|
|||
|
||||
/* Bit 17-18: (0) SS, (1) SS*2 */
|
||||
#define RATE_MCS_STBC_POS 17
|
||||
#define RATE_MCS_STBC_MSK (1 << RATE_MCS_STBC_POS)
|
||||
#define RATE_MCS_HT_STBC_MSK (3 << RATE_MCS_STBC_POS)
|
||||
#define RATE_MCS_VHT_STBC_MSK (1 << RATE_MCS_STBC_POS)
|
||||
|
||||
/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */
|
||||
#define RATE_MCS_BF_POS 19
|
||||
|
|
|
@ -306,7 +306,6 @@ struct iwl_phy_cfg_cmd {
|
|||
#define PHY_CFG_RX_CHAIN_B BIT(13)
|
||||
#define PHY_CFG_RX_CHAIN_C BIT(14)
|
||||
|
||||
#define NVM_MAX_NUM_SECTIONS 11
|
||||
|
||||
/* Target of the NVM_ACCESS_CMD */
|
||||
enum {
|
||||
|
@ -318,8 +317,11 @@ enum {
|
|||
/* Section types for NVM_ACCESS_CMD */
|
||||
enum {
|
||||
NVM_SECTION_TYPE_SW = 1,
|
||||
NVM_SECTION_TYPE_REGULATORY = 3,
|
||||
NVM_SECTION_TYPE_CALIBRATION = 4,
|
||||
NVM_SECTION_TYPE_PRODUCTION = 5,
|
||||
NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
|
||||
NVM_MAX_NUM_SECTIONS = 12,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -710,6 +712,7 @@ enum {
|
|||
TE_V2_NOTIF_HOST_FRAG_END = BIT(5),
|
||||
TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6),
|
||||
TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7),
|
||||
T2_V2_START_IMMEDIATELY = BIT(11),
|
||||
|
||||
TE_V2_NOTIF_MSK = 0xff,
|
||||
|
||||
|
|
|
@ -130,7 +130,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
} else {
|
||||
palive2 = (void *)pkt->data;
|
||||
|
||||
mvm->support_umac_log = true;
|
||||
mvm->error_event_table =
|
||||
le32_to_cpu(palive2->error_event_table_ptr);
|
||||
mvm->log_event_table =
|
||||
|
@ -141,6 +140,9 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
|
||||
alive_data->valid = le16_to_cpu(palive2->status) ==
|
||||
IWL_ALIVE_STATUS_OK;
|
||||
if (mvm->umac_error_event_table)
|
||||
mvm->support_umac_log = true;
|
||||
|
||||
IWL_DEBUG_FW(mvm,
|
||||
"Alive VER2 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
|
||||
le16_to_cpu(palive2->status), palive2->ver_type,
|
||||
|
@ -320,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
|||
}
|
||||
|
||||
/* Send TX valid antennas before triggering calibrations */
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
|
||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
@ -356,8 +358,6 @@ out:
|
|||
GFP_KERNEL);
|
||||
if (!mvm->nvm_data)
|
||||
return -ENOMEM;
|
||||
mvm->nvm_data->valid_rx_ant = 1;
|
||||
mvm->nvm_data->valid_tx_ant = 1;
|
||||
mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels;
|
||||
mvm->nvm_data->bands[0].n_channels = 1;
|
||||
mvm->nvm_data->bands[0].n_bitrates = 1;
|
||||
|
@ -369,8 +369,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define UCODE_CALIB_TIMEOUT (2*HZ)
|
||||
|
||||
int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
{
|
||||
int ret, i;
|
||||
|
@ -422,7 +420,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
|
||||
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
|
||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
@ -507,7 +505,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
|
|||
goto error;
|
||||
}
|
||||
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
|
||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
|
|
@ -952,7 +952,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
|
|||
TX_CMD_FLG_TSF);
|
||||
|
||||
mvm->mgmt_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
|
||||
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
|
||||
mvm->mgmt_last_antenna_idx);
|
||||
|
||||
beacon_cmd.tx.rate_n_flags =
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include <linux/ip.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#include "iwl-op-mode.h"
|
||||
|
@ -280,6 +281,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
|
||||
hw->queues = mvm->first_agg_queue;
|
||||
hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
|
||||
hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
|
||||
IEEE80211_RADIOTAP_MCS_HAVE_STBC;
|
||||
hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC;
|
||||
hw->rate_control_algorithm = "iwl-mvm-rs";
|
||||
|
||||
/*
|
||||
|
@ -1301,7 +1305,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
mvmvif->ap_ibss_active = true;
|
||||
|
||||
/* power updated needs to be done before quotas */
|
||||
mvm->bound_vif_cnt++;
|
||||
iwl_mvm_power_update_mac(mvm, vif);
|
||||
|
||||
ret = iwl_mvm_update_quotas(mvm, vif);
|
||||
|
@ -1320,7 +1323,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
return 0;
|
||||
|
||||
out_quota_failed:
|
||||
mvm->bound_vif_cnt--;
|
||||
iwl_mvm_power_update_mac(mvm, vif);
|
||||
mvmvif->ap_ibss_active = false;
|
||||
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
|
||||
|
@ -1357,7 +1359,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
|
|||
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
|
||||
mvm->bound_vif_cnt--;
|
||||
iwl_mvm_power_update_mac(mvm, vif);
|
||||
|
||||
iwl_mvm_mac_ctxt_remove(mvm, vif);
|
||||
|
@ -2093,7 +2094,6 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
* Power state must be updated before quotas,
|
||||
* otherwise fw will complain.
|
||||
*/
|
||||
mvm->bound_vif_cnt++;
|
||||
iwl_mvm_power_update_mac(mvm, vif);
|
||||
|
||||
/* Setting the quota at this stage is only required for monitor
|
||||
|
@ -2111,7 +2111,6 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
|
||||
out_remove_binding:
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
mvm->bound_vif_cnt--;
|
||||
iwl_mvm_power_update_mac(mvm, vif);
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
@ -2144,7 +2143,6 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
mvm->bound_vif_cnt--;
|
||||
iwl_mvm_power_update_mac(mvm, vif);
|
||||
|
||||
out_unlock:
|
||||
|
@ -2235,7 +2233,7 @@ static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
|
|||
}
|
||||
#endif
|
||||
|
||||
struct ieee80211_ops iwl_mvm_hw_ops = {
|
||||
const struct ieee80211_ops iwl_mvm_hw_ops = {
|
||||
.tx = iwl_mvm_mac_tx,
|
||||
.ampdu_action = iwl_mvm_mac_ampdu_action,
|
||||
.start = iwl_mvm_mac_start,
|
||||
|
|
|
@ -91,8 +91,7 @@ enum iwl_mvm_tx_fifo {
|
|||
IWL_MVM_TX_FIFO_MCAST = 5,
|
||||
};
|
||||
|
||||
extern struct ieee80211_ops iwl_mvm_hw_ops;
|
||||
extern const struct iwl_mvm_power_ops pm_mac_ops;
|
||||
extern const struct ieee80211_ops iwl_mvm_hw_ops;
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_mod_params - module parameters for iwlmvm
|
||||
|
@ -426,6 +425,28 @@ struct iwl_mvm_tt_mgmt {
|
|||
bool throttle;
|
||||
};
|
||||
|
||||
#define IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES 8
|
||||
|
||||
struct iwl_mvm_frame_stats {
|
||||
u32 legacy_frames;
|
||||
u32 ht_frames;
|
||||
u32 vht_frames;
|
||||
u32 bw_20_frames;
|
||||
u32 bw_40_frames;
|
||||
u32 bw_80_frames;
|
||||
u32 bw_160_frames;
|
||||
u32 sgi_frames;
|
||||
u32 ngi_frames;
|
||||
u32 siso_frames;
|
||||
u32 mimo2_frames;
|
||||
u32 agg_frames;
|
||||
u32 ampdu_count;
|
||||
u32 success_frames;
|
||||
u32 fail_frames;
|
||||
u32 last_rates[IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES];
|
||||
int last_frame_idx;
|
||||
};
|
||||
|
||||
struct iwl_mvm {
|
||||
/* for logger access */
|
||||
struct device *dev;
|
||||
|
@ -519,6 +540,7 @@ struct iwl_mvm {
|
|||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct dentry *debugfs_dir;
|
||||
u32 dbgfs_sram_offset, dbgfs_sram_len;
|
||||
u32 dbgfs_prph_reg_addr;
|
||||
bool disable_power_off;
|
||||
bool disable_power_off_d3;
|
||||
|
||||
|
@ -526,6 +548,9 @@ struct iwl_mvm {
|
|||
struct debugfs_blob_wrapper nvm_sw_blob;
|
||||
struct debugfs_blob_wrapper nvm_calib_blob;
|
||||
struct debugfs_blob_wrapper nvm_prod_blob;
|
||||
|
||||
struct iwl_mvm_frame_stats drv_rx_stats;
|
||||
spinlock_t drv_stats_lock;
|
||||
#endif
|
||||
|
||||
struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
|
||||
|
@ -587,8 +612,6 @@ struct iwl_mvm {
|
|||
u8 first_agg_queue;
|
||||
u8 last_agg_queue;
|
||||
|
||||
u8 bound_vif_cnt;
|
||||
|
||||
/* Indicate if device power save is allowed */
|
||||
bool ps_disabled;
|
||||
/* Indicate if device power management is allowed */
|
||||
|
@ -812,6 +835,10 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
|
||||
/* rate scaling */
|
||||
int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
|
||||
void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_frame_stats *stats,
|
||||
u32 rate, bool agg);
|
||||
int rs_pretty_print_rate(char *buf, const u32 rate);
|
||||
|
||||
/* power management */
|
||||
int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm);
|
||||
|
|
|
@ -228,13 +228,23 @@ static struct iwl_nvm_data *
|
|||
iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_nvm_section *sections = mvm->nvm_sections;
|
||||
const __le16 *hw, *sw, *calib;
|
||||
const __le16 *hw, *sw, *calib, *regulatory, *mac_override;
|
||||
|
||||
/* Checking for required sections */
|
||||
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
|
||||
!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
|
||||
IWL_ERR(mvm, "Can't parse empty NVM sections\n");
|
||||
return NULL;
|
||||
if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
|
||||
!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
|
||||
IWL_ERR(mvm, "Can't parse empty NVM sections\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
|
||||
!mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data ||
|
||||
!mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
|
||||
IWL_ERR(mvm,
|
||||
"Can't parse empty family 8000 NVM sections\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(!mvm->cfg))
|
||||
|
@ -243,9 +253,14 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
|||
hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
|
||||
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
|
||||
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
|
||||
regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
|
||||
mac_override =
|
||||
(const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data;
|
||||
|
||||
return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
|
||||
iwl_fw_valid_tx_ant(mvm->fw),
|
||||
iwl_fw_valid_rx_ant(mvm->fw));
|
||||
regulatory, mac_override,
|
||||
mvm->fw->valid_tx_ant,
|
||||
mvm->fw->valid_rx_ant);
|
||||
}
|
||||
|
||||
#define MAX_NVM_FILE_LEN 16384
|
||||
|
@ -285,6 +300,8 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
|
|||
|
||||
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
|
||||
#define NVM_WORD2_ID(x) (x >> 12)
|
||||
#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8))
|
||||
#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4)
|
||||
|
||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
|
||||
|
||||
|
@ -335,8 +352,16 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
|
|||
break;
|
||||
}
|
||||
|
||||
section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
|
||||
section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
|
||||
if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
section_size =
|
||||
2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
|
||||
section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
|
||||
} else {
|
||||
section_size = 2 * NVM_WORD2_LEN_FAMILY_8000(
|
||||
le16_to_cpu(file_sec->word2));
|
||||
section_id = NVM_WORD1_ID_FAMILY_8000(
|
||||
le16_to_cpu(file_sec->word1));
|
||||
}
|
||||
|
||||
if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
|
||||
IWL_ERR(mvm, "ERROR - section too large (%d)\n",
|
||||
|
@ -406,6 +431,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
|
|||
{
|
||||
int ret, i, section;
|
||||
u8 *nvm_buffer, *temp;
|
||||
int nvm_to_read[NVM_MAX_NUM_SECTIONS];
|
||||
int num_of_sections_to_read;
|
||||
|
||||
if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
|
||||
return -EINVAL;
|
||||
|
@ -418,12 +445,20 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
|
|||
return ret;
|
||||
} else {
|
||||
/* list of NVM sections we are allowed/need to read */
|
||||
int nvm_to_read[] = {
|
||||
mvm->cfg->nvm_hw_section_num,
|
||||
NVM_SECTION_TYPE_SW,
|
||||
NVM_SECTION_TYPE_CALIBRATION,
|
||||
NVM_SECTION_TYPE_PRODUCTION,
|
||||
};
|
||||
if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
nvm_to_read[0] = mvm->cfg->nvm_hw_section_num;
|
||||
nvm_to_read[1] = NVM_SECTION_TYPE_SW;
|
||||
nvm_to_read[2] = NVM_SECTION_TYPE_CALIBRATION;
|
||||
nvm_to_read[3] = NVM_SECTION_TYPE_PRODUCTION;
|
||||
num_of_sections_to_read = 4;
|
||||
} else {
|
||||
nvm_to_read[0] = NVM_SECTION_TYPE_SW;
|
||||
nvm_to_read[1] = NVM_SECTION_TYPE_CALIBRATION;
|
||||
nvm_to_read[2] = NVM_SECTION_TYPE_PRODUCTION;
|
||||
nvm_to_read[3] = NVM_SECTION_TYPE_REGULATORY;
|
||||
nvm_to_read[4] = NVM_SECTION_TYPE_MAC_OVERRIDE;
|
||||
num_of_sections_to_read = 5;
|
||||
}
|
||||
|
||||
/* Read From FW NVM */
|
||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
|
||||
|
@ -433,7 +468,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
|
|||
GFP_KERNEL);
|
||||
if (!nvm_buffer)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
|
||||
for (i = 0; i < num_of_sections_to_read; i++) {
|
||||
section = nvm_to_read[i];
|
||||
/* we override the constness for initial read */
|
||||
ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
|
||||
|
|
|
@ -245,7 +245,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
|||
#undef RX_HANDLER
|
||||
#define CMD(x) [x] = #x
|
||||
|
||||
static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
|
||||
static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
|
||||
CMD(MVM_ALIVE),
|
||||
CMD(REPLY_ERROR),
|
||||
CMD(INIT_COMPLETE_NOTIF),
|
||||
|
|
|
@ -156,13 +156,13 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
|
|||
idle_cnt = chains_static;
|
||||
active_cnt = chains_dynamic;
|
||||
|
||||
cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) <<
|
||||
cmd->rxchain_info = cpu_to_le32(mvm->fw->valid_rx_ant <<
|
||||
PHY_RX_CHAIN_VALID_POS);
|
||||
cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
|
||||
cmd->rxchain_info |= cpu_to_le32(active_cnt <<
|
||||
PHY_RX_CHAIN_MIMO_CNT_POS);
|
||||
|
||||
cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw));
|
||||
cmd->txchain_info = cpu_to_le32(mvm->fw->valid_tx_ant);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -425,7 +425,7 @@ static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm,
|
|||
return 0;
|
||||
|
||||
if (vif->p2p &&
|
||||
!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
|
||||
!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM))
|
||||
return 0;
|
||||
|
||||
iwl_mvm_power_build_cmd(mvm, vif, &cmd);
|
||||
|
@ -511,8 +511,11 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
|
|||
struct iwl_power_constraint {
|
||||
struct ieee80211_vif *bf_vif;
|
||||
struct ieee80211_vif *bss_vif;
|
||||
u16 bss_phyctx_id;
|
||||
u16 p2p_phyctx_id;
|
||||
bool pm_disabled;
|
||||
bool ps_disabled;
|
||||
struct iwl_mvm *mvm;
|
||||
};
|
||||
|
||||
static void iwl_mvm_power_iterator(void *_data, u8 *mac,
|
||||
|
@ -520,6 +523,7 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
|
|||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_power_constraint *power_iterator = _data;
|
||||
struct iwl_mvm *mvm = power_iterator->mvm;
|
||||
|
||||
switch (ieee80211_vif_type_p2p(vif)) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
|
@ -539,11 +543,28 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
|
|||
break;
|
||||
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
/* no BSS power mgmt if we have a P2P client*/
|
||||
power_iterator->pm_disabled = true;
|
||||
if (mvmvif->phy_ctxt)
|
||||
power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id;
|
||||
|
||||
IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n",
|
||||
power_iterator->p2p_phyctx_id,
|
||||
power_iterator->bss_phyctx_id);
|
||||
if (!(mvm->fw->ucode_capa.flags &
|
||||
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) {
|
||||
/* no BSS power mgmt if we have a P2P client*/
|
||||
power_iterator->pm_disabled = true;
|
||||
} else if (power_iterator->p2p_phyctx_id < MAX_PHYS &&
|
||||
power_iterator->bss_phyctx_id < MAX_PHYS &&
|
||||
power_iterator->p2p_phyctx_id ==
|
||||
power_iterator->bss_phyctx_id) {
|
||||
power_iterator->pm_disabled = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (mvmvif->phy_ctxt)
|
||||
power_iterator->bss_phyctx_id = mvmvif->phy_ctxt->id;
|
||||
|
||||
/* we should have only one BSS vif */
|
||||
WARN_ON(power_iterator->bss_vif);
|
||||
power_iterator->bss_vif = vif;
|
||||
|
@ -551,6 +572,17 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
|
|||
if (mvmvif->bf_data.bf_enabled &&
|
||||
!WARN_ON(power_iterator->bf_vif))
|
||||
power_iterator->bf_vif = vif;
|
||||
|
||||
IWL_DEBUG_POWER(mvm, "bss: p2p_id=%d, bss_id=%d\n",
|
||||
power_iterator->p2p_phyctx_id,
|
||||
power_iterator->bss_phyctx_id);
|
||||
if (mvm->fw->ucode_capa.flags &
|
||||
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM &&
|
||||
(power_iterator->p2p_phyctx_id < MAX_PHYS &&
|
||||
power_iterator->bss_phyctx_id < MAX_PHYS &&
|
||||
power_iterator->p2p_phyctx_id ==
|
||||
power_iterator->bss_phyctx_id))
|
||||
power_iterator->pm_disabled = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -572,16 +604,16 @@ iwl_mvm_power_get_global_constraint(struct iwl_mvm *mvm,
|
|||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_power_iterator, constraint);
|
||||
|
||||
/* TODO: remove this and determine this variable in the iterator */
|
||||
if (mvm->bound_vif_cnt > 1)
|
||||
constraint->pm_disabled = true;
|
||||
}
|
||||
|
||||
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_power_constraint constraint = {};
|
||||
struct iwl_power_constraint constraint = {
|
||||
.p2p_phyctx_id = MAX_PHYS,
|
||||
.bss_phyctx_id = MAX_PHYS,
|
||||
.mvm = mvm,
|
||||
};
|
||||
bool ba_enable;
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
if (sta->smps_mode == IEEE80211_SMPS_STATIC)
|
||||
return false;
|
||||
|
||||
if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
|
||||
if (num_of_ant(mvm->fw->valid_tx_ant) < 2)
|
||||
return false;
|
||||
|
||||
if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
|
||||
|
@ -917,7 +917,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
|
|||
|
||||
|
||||
if (num_of_ant(rate->ant) > 1)
|
||||
rate->ant = first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
|
||||
rate->ant = first_antenna(mvm->fw->valid_tx_ant);
|
||||
|
||||
/* Relevant in both switching to SISO or Legacy */
|
||||
rate->sgi = false;
|
||||
|
@ -1477,7 +1477,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
|||
const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
|
||||
const struct rs_tx_column *next_col;
|
||||
allow_column_func_t allow_func;
|
||||
u8 valid_ants = iwl_fw_valid_tx_ant(mvm->fw);
|
||||
u8 valid_ants = mvm->fw->valid_tx_ant;
|
||||
const u16 *expected_tpt_tbl;
|
||||
s32 tpt, max_expected_tpt;
|
||||
|
||||
|
@ -2089,7 +2089,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
|
|||
|
||||
i = lq_sta->last_txrate_idx;
|
||||
|
||||
valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
|
||||
valid_tx_ant = mvm->fw->valid_tx_ant;
|
||||
|
||||
if (!lq_sta->search_better_tbl)
|
||||
active_tbl = lq_sta->active_tbl;
|
||||
|
@ -2240,6 +2240,73 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_frame_stats *stats)
|
||||
{
|
||||
spin_lock_bh(&mvm->drv_stats_lock);
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
spin_unlock_bh(&mvm->drv_stats_lock);
|
||||
}
|
||||
|
||||
void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_frame_stats *stats,
|
||||
u32 rate, bool agg)
|
||||
{
|
||||
u8 nss = 0, mcs = 0;
|
||||
|
||||
spin_lock(&mvm->drv_stats_lock);
|
||||
|
||||
if (agg)
|
||||
stats->agg_frames++;
|
||||
|
||||
stats->success_frames++;
|
||||
|
||||
switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
|
||||
case RATE_MCS_CHAN_WIDTH_20:
|
||||
stats->bw_20_frames++;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_40:
|
||||
stats->bw_40_frames++;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_80:
|
||||
stats->bw_80_frames++;
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "bad BW. rate 0x%x", rate);
|
||||
}
|
||||
|
||||
if (rate & RATE_MCS_HT_MSK) {
|
||||
stats->ht_frames++;
|
||||
mcs = rate & RATE_HT_MCS_RATE_CODE_MSK;
|
||||
nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
|
||||
} else if (rate & RATE_MCS_VHT_MSK) {
|
||||
stats->vht_frames++;
|
||||
mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
|
||||
RATE_VHT_MCS_NSS_POS) + 1;
|
||||
} else {
|
||||
stats->legacy_frames++;
|
||||
}
|
||||
|
||||
if (nss == 1)
|
||||
stats->siso_frames++;
|
||||
else if (nss == 2)
|
||||
stats->mimo2_frames++;
|
||||
|
||||
if (rate & RATE_MCS_SGI_MSK)
|
||||
stats->sgi_frames++;
|
||||
else
|
||||
stats->ngi_frames++;
|
||||
|
||||
stats->last_rates[stats->last_frame_idx] = rate;
|
||||
stats->last_frame_idx = (stats->last_frame_idx + 1) %
|
||||
ARRAY_SIZE(stats->last_rates);
|
||||
|
||||
spin_unlock(&mvm->drv_stats_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called after adding a new station to initialize rate scaling
|
||||
*/
|
||||
|
@ -2319,7 +2386,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
|
||||
/* These values will be overridden later */
|
||||
lq_sta->lq.single_stream_ant_msk =
|
||||
first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
|
||||
first_antenna(mvm->fw->valid_tx_ant);
|
||||
lq_sta->lq.dual_stream_ant_msk = ANT_AB;
|
||||
|
||||
/* as default allow aggregation for all tids */
|
||||
|
@ -2334,7 +2401,9 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
lq_sta->dbg_fixed_rate = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
|
||||
#endif
|
||||
rs_initialize_lq(mvm, sta, lq_sta, band, init);
|
||||
}
|
||||
|
||||
|
@ -2445,7 +2514,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
|||
|
||||
memcpy(&rate, initial_rate, sizeof(rate));
|
||||
|
||||
valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
|
||||
valid_tx_ant = mvm->fw->valid_tx_ant;
|
||||
|
||||
if (is_siso(&rate)) {
|
||||
num_rates = RS_INITIAL_SISO_NUM_RATES;
|
||||
|
@ -2546,7 +2615,7 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
static int rs_pretty_print_rate(char *buf, const u32 rate)
|
||||
int rs_pretty_print_rate(char *buf, const u32 rate)
|
||||
{
|
||||
|
||||
char *type, *bw;
|
||||
|
@ -2595,7 +2664,7 @@ static int rs_pretty_print_rate(char *buf, const u32 rate)
|
|||
return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
|
||||
type, rs_pretty_ant(ant), bw, mcs, nss,
|
||||
(rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
|
||||
(rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
|
||||
(rate & RATE_MCS_HT_STBC_MSK) ? "STBC " : "",
|
||||
(rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
|
||||
(rate & RATE_MCS_BF_MSK) ? "BF " : "",
|
||||
(rate & RATE_MCS_ZLF_MSK) ? "ZLF " : "");
|
||||
|
@ -2676,9 +2745,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
|||
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
|
||||
lq_sta->dbg_fixed_rate);
|
||||
desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
|
||||
(iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "",
|
||||
(iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
|
||||
(iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
|
||||
(mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "",
|
||||
(mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "",
|
||||
(mvm->fw->valid_tx_ant & ANT_C) ? "ANT_C" : "");
|
||||
desc += sprintf(buff+desc, "lq type %s\n",
|
||||
(is_legacy(rate)) ? "legacy" :
|
||||
is_vht(rate) ? "VHT" : "HT");
|
||||
|
|
|
@ -77,6 +77,15 @@ int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
|
|||
|
||||
memcpy(&mvm->last_phy_info, pkt->data, sizeof(mvm->last_phy_info));
|
||||
mvm->ampdu_ref++;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
if (mvm->last_phy_info.phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
|
||||
spin_lock(&mvm->drv_stats_lock);
|
||||
mvm->drv_rx_stats.ampdu_count++;
|
||||
spin_unlock(&mvm->drv_stats_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -368,21 +377,33 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
|
|||
rx_status.flag |= RX_FLAG_SHORT_GI;
|
||||
if (rate_n_flags & RATE_HT_MCS_GF_MSK)
|
||||
rx_status.flag |= RX_FLAG_HT_GF;
|
||||
if (rate_n_flags & RATE_MCS_LDPC_MSK)
|
||||
rx_status.flag |= RX_FLAG_LDPC;
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_HT_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status.flag |= RX_FLAG_HT;
|
||||
rx_status.rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
|
||||
rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT;
|
||||
} else if (rate_n_flags & RATE_MCS_VHT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_VHT_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status.vht_nss =
|
||||
((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
|
||||
RATE_VHT_MCS_NSS_POS) + 1;
|
||||
rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
rx_status.flag |= RX_FLAG_VHT;
|
||||
rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT;
|
||||
} else {
|
||||
rx_status.rate_idx =
|
||||
iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
|
||||
rx_status.band);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags,
|
||||
rx_status.flag & RX_FLAG_AMPDU_DETAILS);
|
||||
#endif
|
||||
iwl_mvm_pass_packet_to_mac80211(mvm, hdr, len, ampdu_status,
|
||||
rxb, &rx_status);
|
||||
return 0;
|
||||
|
|
|
@ -82,7 +82,7 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
|
|||
if (mvm->scan_rx_ant != ANT_NONE)
|
||||
rx_ant = mvm->scan_rx_ant;
|
||||
else
|
||||
rx_ant = iwl_fw_valid_rx_ant(mvm->fw);
|
||||
rx_ant = mvm->fw->valid_rx_ant;
|
||||
rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
|
||||
rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
|
||||
rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
|
||||
|
@ -124,7 +124,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
|
|||
u32 tx_ant;
|
||||
|
||||
mvm->scan_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
|
||||
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
|
||||
mvm->scan_last_antenna_idx);
|
||||
tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
|
||||
|
||||
|
|
|
@ -438,7 +438,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
|
|||
time_cmd.duration = cpu_to_le32(duration);
|
||||
time_cmd.repeat = 1;
|
||||
time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
|
||||
TE_V2_NOTIF_HOST_EVENT_END);
|
||||
TE_V2_NOTIF_HOST_EVENT_END |
|
||||
T2_V2_START_IMMEDIATELY);
|
||||
|
||||
iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
|
||||
}
|
||||
|
@ -553,7 +554,8 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
|
||||
time_cmd.repeat = 1;
|
||||
time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
|
||||
TE_V2_NOTIF_HOST_EVENT_END);
|
||||
TE_V2_NOTIF_HOST_EVENT_END |
|
||||
T2_V2_START_IMMEDIATELY);
|
||||
|
||||
return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
|
|||
* it
|
||||
*/
|
||||
WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU);
|
||||
} else if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
|
||||
} else if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
|
||||
tx_cmd->pm_frame_timeout = cpu_to_le16(2);
|
||||
} else {
|
||||
tx_cmd->pm_frame_timeout = 0;
|
||||
|
@ -207,7 +207,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
|
|||
rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
|
||||
|
||||
mvm->mgmt_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
|
||||
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
|
||||
mvm->mgmt_last_antenna_idx);
|
||||
rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
|
||||
|
||||
|
|
|
@ -289,8 +289,8 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
|
|||
return last_idx;
|
||||
}
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
static const struct {
|
||||
const char *name;
|
||||
u8 num;
|
||||
} advanced_lookup[] = {
|
||||
{ "NMI_INTERRUPT_WDG", 0x34 },
|
||||
|
@ -589,7 +589,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
|
||||
if (num_of_ant(iwl_fw_valid_rx_ant(mvm->fw)) == 1)
|
||||
if (num_of_ant(mvm->fw->valid_rx_ant) == 1)
|
||||
return;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
|
|
|
@ -304,7 +304,7 @@ struct iwl_trans_pcie {
|
|||
bool bc_table_dword;
|
||||
u32 rx_page_order;
|
||||
|
||||
const char **command_names;
|
||||
const char *const *command_names;
|
||||
|
||||
/* queue watchdog */
|
||||
unsigned long wd_timeout;
|
||||
|
|
|
@ -155,37 +155,26 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
|
|||
if (rxq->need_update == 0)
|
||||
goto exit_unlock;
|
||||
|
||||
if (trans->cfg->base_params->shadow_reg_enable) {
|
||||
/* shadow register enabled */
|
||||
/* Device expects a multiple of 8 */
|
||||
rxq->write_actual = (rxq->write & ~0x7);
|
||||
iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
|
||||
} else {
|
||||
/* If power-saving is in use, make sure device is awake */
|
||||
if (test_bit(STATUS_TPOWER_PMI, &trans->status)) {
|
||||
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
|
||||
/*
|
||||
* explicitly wake up the NIC if:
|
||||
* 1. shadow registers aren't enabled
|
||||
* 2. there is a chance that the NIC is asleep
|
||||
*/
|
||||
if (!trans->cfg->base_params->shadow_reg_enable &&
|
||||
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
|
||||
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
|
||||
|
||||
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"Rx queue requesting wakeup,"
|
||||
" GP1 = 0x%x\n", reg);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
goto exit_unlock;
|
||||
}
|
||||
|
||||
rxq->write_actual = (rxq->write & ~0x7);
|
||||
iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
|
||||
rxq->write_actual);
|
||||
|
||||
/* Else device is assumed to be awake */
|
||||
} else {
|
||||
/* Device expects a multiple of 8 */
|
||||
rxq->write_actual = (rxq->write & ~0x7);
|
||||
iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
|
||||
rxq->write_actual);
|
||||
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
|
||||
IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup, GP1 = 0x%x\n",
|
||||
reg);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
goto exit_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
rxq->write_actual = round_down(rxq->write, 8);
|
||||
iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
|
||||
rxq->need_update = 0;
|
||||
|
||||
exit_unlock:
|
||||
|
|
|
@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
|
|||
IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
|
||||
le32_to_cpu(txq->scratchbufs[i].scratch));
|
||||
|
||||
iwl_trans_fw_error(trans);
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -296,43 +296,38 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
|
|||
if (txq->need_update == 0)
|
||||
return;
|
||||
|
||||
if (trans->cfg->base_params->shadow_reg_enable ||
|
||||
txq_id == trans_pcie->cmd_queue) {
|
||||
/* shadow register enabled */
|
||||
iwl_write32(trans, HBUS_TARG_WRPTR,
|
||||
txq->q.write_ptr | (txq_id << 8));
|
||||
} else {
|
||||
/* if we're trying to save power */
|
||||
if (test_bit(STATUS_TPOWER_PMI, &trans->status)) {
|
||||
/* wake up nic if it's powered down ...
|
||||
* uCode will wake up, and interrupt us again, so next
|
||||
* time we'll skip this part. */
|
||||
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
|
||||
|
||||
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"Tx queue %d requesting wakeup,"
|
||||
" GP1 = 0x%x\n", txq_id, reg);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id,
|
||||
txq->q.write_ptr);
|
||||
|
||||
iwl_write_direct32(trans, HBUS_TARG_WRPTR,
|
||||
txq->q.write_ptr | (txq_id << 8));
|
||||
|
||||
/*
|
||||
* explicitly wake up the NIC if:
|
||||
* 1. shadow registers aren't enabled
|
||||
* 2. NIC is woken up for CMD regardless of shadow outside this function
|
||||
* 3. there is a chance that the NIC is asleep
|
||||
*/
|
||||
if (!trans->cfg->base_params->shadow_reg_enable &&
|
||||
txq_id != trans_pcie->cmd_queue &&
|
||||
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
|
||||
/*
|
||||
* else not in power-save mode,
|
||||
* uCode will never sleep when we're
|
||||
* trying to tx (during RFKILL, we're not trying to tx).
|
||||
* wake up nic if it's powered down ...
|
||||
* uCode will wake up, and interrupt us again, so next
|
||||
* time we'll skip this part.
|
||||
*/
|
||||
} else
|
||||
iwl_write32(trans, HBUS_TARG_WRPTR,
|
||||
txq->q.write_ptr | (txq_id << 8));
|
||||
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
|
||||
|
||||
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
|
||||
IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
|
||||
txq_id, reg);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if not in power-save mode, uCode will never sleep when we're
|
||||
* trying to tx (during RFKILL, we're not trying to tx).
|
||||
*/
|
||||
IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->q.write_ptr);
|
||||
iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8));
|
||||
|
||||
txq->need_update = 0;
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1024,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
|
|||
if (nfreed++ > 0) {
|
||||
IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
|
||||
idx, q->write_ptr, q->read_ptr);
|
||||
iwl_trans_fw_error(trans);
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1588,6 +1583,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
|
|||
get_cmd_string(trans_pcie, cmd->id));
|
||||
ret = -ETIMEDOUT;
|
||||
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
|
||||
iwl_trans_fw_error(trans);
|
||||
|
||||
goto cancel;
|
||||
|
|
Loading…
Reference in New Issue