forked from Minki/linux
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
This commit is contained in:
commit
31c5770b5d
@ -1266,7 +1266,3 @@ module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
|
|||||||
bool, S_IRUGO);
|
bool, S_IRUGO);
|
||||||
MODULE_PARM_DESC(auto_agg,
|
MODULE_PARM_DESC(auto_agg,
|
||||||
"enable agg w/o check traffic load (default: enable)");
|
"enable agg w/o check traffic load (default: enable)");
|
||||||
|
|
||||||
module_param_named(5ghz_disable, iwlwifi_mod_params.disable_5ghz,
|
|
||||||
bool, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(5ghz_disable, "disable 5GHz band (default: 0 [enabled])");
|
|
||||||
|
@ -154,6 +154,19 @@ struct iwl_tlv_calib_ctrl {
|
|||||||
__le32 event_trigger;
|
__le32 event_trigger;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
enum iwl_fw_phy_cfg {
|
||||||
|
FW_PHY_CFG_RADIO_TYPE_POS = 0,
|
||||||
|
FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
|
||||||
|
FW_PHY_CFG_RADIO_STEP_POS = 2,
|
||||||
|
FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
|
||||||
|
FW_PHY_CFG_RADIO_DASH_POS = 4,
|
||||||
|
FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
|
||||||
|
FW_PHY_CFG_TX_CHAIN_POS = 16,
|
||||||
|
FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
|
||||||
|
FW_PHY_CFG_RX_CHAIN_POS = 20,
|
||||||
|
FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_fw - variables associated with the firmware
|
* struct iwl_fw - variables associated with the firmware
|
||||||
*
|
*
|
||||||
@ -190,4 +203,16 @@ struct iwl_fw {
|
|||||||
bool mvm_fw;
|
bool mvm_fw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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__ */
|
#endif /* __iwl_fw_h__ */
|
||||||
|
@ -103,7 +103,6 @@ enum iwl_power_level {
|
|||||||
* @ant_coupling: antenna coupling in dB, default = 0
|
* @ant_coupling: antenna coupling in dB, default = 0
|
||||||
* @bt_ch_announce: BT channel inhibition, default = enable
|
* @bt_ch_announce: BT channel inhibition, default = enable
|
||||||
* @auto_agg: enable agg. without check, default = true
|
* @auto_agg: enable agg. without check, default = true
|
||||||
* @disable_5ghz: disable 5GHz capability, default = false
|
|
||||||
*/
|
*/
|
||||||
struct iwl_mod_params {
|
struct iwl_mod_params {
|
||||||
int sw_crypto;
|
int sw_crypto;
|
||||||
@ -120,7 +119,6 @@ struct iwl_mod_params {
|
|||||||
int ant_coupling;
|
int ant_coupling;
|
||||||
bool bt_ch_announce;
|
bool bt_ch_announce;
|
||||||
bool auto_agg;
|
bool auto_agg;
|
||||||
bool disable_5ghz;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* #__iwl_modparams_h__ */
|
#endif /* #__iwl_modparams_h__ */
|
||||||
|
@ -272,7 +272,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
|
|||||||
|
|
||||||
reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
||||||
skb = iwl_test_alloc_reply(tst, reply_len + 20);
|
skb = iwl_test_alloc_reply(tst, reply_len + 20);
|
||||||
reply_buf = kmalloc(reply_len, GFP_KERNEL);
|
reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL);
|
||||||
if (!skb || !reply_buf) {
|
if (!skb || !reply_buf) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
kfree(reply_buf);
|
kfree(reply_buf);
|
||||||
@ -280,7 +280,6 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The reply is in a page, that we cannot send to user space. */
|
/* The reply is in a page, that we cannot send to user space. */
|
||||||
memcpy(reply_buf, &(pkt->hdr), reply_len);
|
|
||||||
iwl_free_resp(&cmd);
|
iwl_free_resp(&cmd);
|
||||||
|
|
||||||
if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
|
if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
|
||||||
|
@ -125,15 +125,15 @@ enum iwl_bt_kill_msk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
|
static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
|
||||||
0xffffffff,
|
[BT_KILL_MSK_DEFAULT] = 0xffff0000,
|
||||||
0xfffffc00,
|
[BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
|
||||||
0,
|
[BT_KILL_MSK_REDUCED_TXPOW] = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
|
static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
|
||||||
0xffffffff,
|
[BT_KILL_MSK_DEFAULT] = 0xffff0000,
|
||||||
0xfffffc00,
|
[BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
|
||||||
0,
|
[BT_KILL_MSK_REDUCED_TXPOW] = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)
|
#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)
|
||||||
@ -188,6 +188,8 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
|
|||||||
|
|
||||||
/* BT Antenna Coupling Threshold (dB) */
|
/* BT Antenna Coupling Threshold (dB) */
|
||||||
#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
|
#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
|
||||||
|
#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3)
|
||||||
|
|
||||||
|
|
||||||
int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
|
int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
|
||||||
{
|
{
|
||||||
@ -201,8 +203,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
|
|||||||
|
|
||||||
cmd.flags = iwlwifi_mod_params.bt_coex_active ?
|
cmd.flags = iwlwifi_mod_params.bt_coex_active ?
|
||||||
BT_COEX_NW : BT_COEX_DISABLE;
|
BT_COEX_NW : BT_COEX_DISABLE;
|
||||||
cmd.flags |= iwlwifi_mod_params.bt_ch_announce ?
|
cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? BT_CH_PRIMARY_EN : 0;
|
||||||
BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0;
|
|
||||||
cmd.flags |= BT_SYNC_2_BT_DISABLE;
|
cmd.flags |= BT_SYNC_2_BT_DISABLE;
|
||||||
|
|
||||||
cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
|
cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
|
||||||
@ -275,7 +276,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
|
|||||||
if (data->notif->bt_status)
|
if (data->notif->bt_status)
|
||||||
smps_mode = IEEE80211_SMPS_DYNAMIC;
|
smps_mode = IEEE80211_SMPS_DYNAMIC;
|
||||||
|
|
||||||
if (data->notif->bt_traffic_load)
|
if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD)
|
||||||
smps_mode = IEEE80211_SMPS_STATIC;
|
smps_mode = IEEE80211_SMPS_STATIC;
|
||||||
|
|
||||||
IWL_DEBUG_COEX(data->mvm,
|
IWL_DEBUG_COEX(data->mvm,
|
||||||
@ -327,7 +328,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
IWL_DEBUG_COEX(mvm,
|
IWL_DEBUG_COEX(mvm,
|
||||||
"Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n",
|
"Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n",
|
||||||
bt_kill_msk,
|
bt_kill_msk,
|
||||||
BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
|
BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
|
||||||
BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
|
BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
|
||||||
|
@ -866,17 +866,13 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|||||||
cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
|
cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
|
||||||
|
|
||||||
if (wowlan->rfkill_release)
|
if (wowlan->rfkill_release)
|
||||||
d3_cfg_cmd.wakeup_flags |=
|
wowlan_config_cmd.wakeup_filter |=
|
||||||
cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
|
cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
|
||||||
|
|
||||||
if (wowlan->tcp) {
|
if (wowlan->tcp) {
|
||||||
/*
|
/*
|
||||||
* The firmware currently doesn't really look at these, only
|
* Set the "link change" (really "link lost") flag as well
|
||||||
* the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that
|
* since that implies losing the TCP connection.
|
||||||
* reason bit since losing the connection to the AP implies
|
|
||||||
* losing the TCP connection.
|
|
||||||
* Set the flags anyway as long as they exist, in case this
|
|
||||||
* will be changed in the firmware.
|
|
||||||
*/
|
*/
|
||||||
wowlan_config_cmd.wakeup_filter |=
|
wowlan_config_cmd.wakeup_filter |=
|
||||||
cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
|
cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
|
||||||
|
@ -537,6 +537,12 @@ struct iwl_mac_beacon_cmd {
|
|||||||
struct ieee80211_hdr frame[0];
|
struct ieee80211_hdr frame[0];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct iwl_beacon_notif {
|
||||||
|
struct iwl_mvm_tx_resp beacon_notify_hdr;
|
||||||
|
__le64 tsf;
|
||||||
|
__le32 ibss_mgr_status;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum iwl_dump_control - dump (flush) control flags
|
* enum iwl_dump_control - dump (flush) control flags
|
||||||
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
|
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
|
||||||
|
@ -151,6 +151,7 @@ enum {
|
|||||||
|
|
||||||
SET_CALIB_DEFAULT_CMD = 0x8e,
|
SET_CALIB_DEFAULT_CMD = 0x8e,
|
||||||
|
|
||||||
|
BEACON_NOTIFICATION = 0x90,
|
||||||
BEACON_TEMPLATE_CMD = 0x91,
|
BEACON_TEMPLATE_CMD = 0x91,
|
||||||
TX_ANT_CONFIGURATION_CMD = 0x98,
|
TX_ANT_CONFIGURATION_CMD = 0x98,
|
||||||
BT_CONFIG = 0x9b,
|
BT_CONFIG = 0x9b,
|
||||||
@ -278,38 +279,7 @@ enum {
|
|||||||
NVM_ACCESS_TARGET_EEPROM = 2,
|
NVM_ACCESS_TARGET_EEPROM = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/* Section types for NVM_ACCESS_CMD */
|
||||||
* struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
|
|
||||||
* @op_code: 0 - read, 1 - write.
|
|
||||||
* @target: NVM_ACCESS_TARGET_*. should be 0 for read.
|
|
||||||
* @cache_refresh: 0 - None, 1- NVM.
|
|
||||||
* @offset: offset in the nvm data.
|
|
||||||
* @length: of the chunk.
|
|
||||||
* @data: empty on read, the NVM chunk on write
|
|
||||||
*/
|
|
||||||
struct iwl_nvm_access_cmd_ver1 {
|
|
||||||
u8 op_code;
|
|
||||||
u8 target;
|
|
||||||
u8 cache_refresh;
|
|
||||||
u8 reserved;
|
|
||||||
__le16 offset;
|
|
||||||
__le16 length;
|
|
||||||
u8 data[];
|
|
||||||
} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
|
|
||||||
* @offset: the offset in the nvm data
|
|
||||||
* @length: of the chunk
|
|
||||||
* @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
|
|
||||||
*/
|
|
||||||
struct iwl_nvm_access_resp_ver1 {
|
|
||||||
__le16 offset;
|
|
||||||
__le16 length;
|
|
||||||
u8 data[];
|
|
||||||
} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
|
|
||||||
|
|
||||||
/* Section types for NVM_ACCESS_CMD version 2 */
|
|
||||||
enum {
|
enum {
|
||||||
NVM_SECTION_TYPE_HW = 0,
|
NVM_SECTION_TYPE_HW = 0,
|
||||||
NVM_SECTION_TYPE_SW,
|
NVM_SECTION_TYPE_SW,
|
||||||
@ -330,7 +300,7 @@ enum {
|
|||||||
* @length: in bytes, to read/write
|
* @length: in bytes, to read/write
|
||||||
* @data: if write operation, the data to write. On read its empty
|
* @data: if write operation, the data to write. On read its empty
|
||||||
*/
|
*/
|
||||||
struct iwl_nvm_access_cmd_ver2 {
|
struct iwl_nvm_access_cmd {
|
||||||
u8 op_code;
|
u8 op_code;
|
||||||
u8 target;
|
u8 target;
|
||||||
__le16 type;
|
__le16 type;
|
||||||
@ -347,7 +317,7 @@ struct iwl_nvm_access_cmd_ver2 {
|
|||||||
* @status: 0 for success, fail otherwise
|
* @status: 0 for success, fail otherwise
|
||||||
* @data: if read operation, the data returned. Empty on write.
|
* @data: if read operation, the data returned. Empty on write.
|
||||||
*/
|
*/
|
||||||
struct iwl_nvm_access_resp_ver2 {
|
struct iwl_nvm_access_resp {
|
||||||
__le16 offset;
|
__le16 offset;
|
||||||
__le16 length;
|
__le16 length;
|
||||||
__le16 type;
|
__le16 type;
|
||||||
|
@ -114,7 +114,7 @@ static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
|
|||||||
.valid = cpu_to_le32(valid_tx_ant),
|
.valid = cpu_to_le32(valid_tx_ant),
|
||||||
};
|
};
|
||||||
|
|
||||||
IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant);
|
IWL_DEBUG_FW(mvm, "select valid tx ant: %u\n", valid_tx_ant);
|
||||||
return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
|
return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
|
||||||
sizeof(tx_ant_cmd), &tx_ant_cmd);
|
sizeof(tx_ant_cmd), &tx_ant_cmd);
|
||||||
}
|
}
|
||||||
@ -134,9 +134,10 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||||||
alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
|
alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
|
||||||
|
|
||||||
alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
|
alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
|
||||||
IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n",
|
IWL_DEBUG_FW(mvm,
|
||||||
|
"Alive ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
|
||||||
le16_to_cpu(palive->status), palive->ver_type,
|
le16_to_cpu(palive->status), palive->ver_type,
|
||||||
palive->ver_subtype);
|
palive->ver_subtype, palive->flags);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -326,16 +327,14 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
|||||||
WARN_ON(ret);
|
WARN_ON(ret);
|
||||||
|
|
||||||
/* Send TX valid antennas before triggering calibrations */
|
/* Send TX valid antennas before triggering calibrations */
|
||||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
|
ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* WkP doesn't have all calibrations, need to set default values */
|
/* need to set default values */
|
||||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
ret = iwl_set_default_calibrations(mvm);
|
||||||
ret = iwl_set_default_calibrations(mvm);
|
if (ret)
|
||||||
if (ret)
|
goto error;
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send phy configurations command to init uCode
|
* Send phy configurations command to init uCode
|
||||||
@ -414,7 +413,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
|
ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -468,7 +467,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
|
ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
|
|||||||
u32 qmask, ac;
|
u32 qmask, ac;
|
||||||
|
|
||||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
|
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
|
||||||
return BIT(IWL_OFFCHANNEL_QUEUE);
|
return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
|
||||||
|
|
||||||
qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
|
qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
|
||||||
BIT(vif->cab_queue) : 0;
|
BIT(vif->cab_queue) : 0;
|
||||||
@ -692,7 +692,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
|
|||||||
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
|
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
|
||||||
|
|
||||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||||
/* No other data to be filled */
|
|
||||||
|
cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
|
||||||
|
MAC_FILTER_IN_CONTROL_AND_MGMT |
|
||||||
|
MAC_FILTER_IN_BEACON |
|
||||||
|
MAC_FILTER_IN_PROBE_REQUEST);
|
||||||
|
|
||||||
return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
|
return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,7 +803,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
|
|||||||
TX_CMD_FLG_TSF);
|
TX_CMD_FLG_TSF);
|
||||||
|
|
||||||
mvm->mgmt_last_antenna_idx =
|
mvm->mgmt_last_antenna_idx =
|
||||||
iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
|
iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
|
||||||
mvm->mgmt_last_antenna_idx);
|
mvm->mgmt_last_antenna_idx);
|
||||||
|
|
||||||
beacon_cmd.tx.rate_n_flags =
|
beacon_cmd.tx.rate_n_flags =
|
||||||
@ -1013,3 +1018,22 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||||||
mvmvif->uploaded = false;
|
mvmvif->uploaded = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
|
||||||
|
struct iwl_rx_cmd_buffer *rxb,
|
||||||
|
struct iwl_device_cmd *cmd)
|
||||||
|
{
|
||||||
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
|
struct iwl_beacon_notif *beacon = (void *)pkt->data;
|
||||||
|
u16 status __maybe_unused =
|
||||||
|
le16_to_cpu(beacon->beacon_notify_hdr.status.status);
|
||||||
|
u32 rate __maybe_unused =
|
||||||
|
le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
|
||||||
|
|
||||||
|
IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
|
||||||
|
status & TX_STATUS_MSK,
|
||||||
|
beacon->beacon_notify_hdr.failure_frame,
|
||||||
|
le64_to_cpu(beacon->tsf),
|
||||||
|
rate);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -143,8 +143,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||||||
IEEE80211_HW_AMPDU_AGGREGATION |
|
IEEE80211_HW_AMPDU_AGGREGATION |
|
||||||
IEEE80211_HW_TIMING_BEACON_ONLY;
|
IEEE80211_HW_TIMING_BEACON_ONLY;
|
||||||
|
|
||||||
hw->queues = IWL_FIRST_AMPDU_QUEUE;
|
hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
|
||||||
hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
|
hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
|
||||||
hw->rate_control_algorithm = "iwl-mvm-rs";
|
hw->rate_control_algorithm = "iwl-mvm-rs";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -174,7 +174,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||||||
hw->wiphy->n_iface_combinations =
|
hw->wiphy->n_iface_combinations =
|
||||||
ARRAY_SIZE(iwl_mvm_iface_combinations);
|
ARRAY_SIZE(iwl_mvm_iface_combinations);
|
||||||
|
|
||||||
hw->wiphy->max_remain_on_channel_duration = 500;
|
hw->wiphy->max_remain_on_channel_duration = 10000;
|
||||||
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
|
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
|
||||||
|
|
||||||
/* Extract MAC address */
|
/* Extract MAC address */
|
||||||
@ -257,7 +257,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
|||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE &&
|
if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
|
||||||
!test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
|
!test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
|
||||||
goto drop;
|
goto drop;
|
||||||
|
|
||||||
@ -1087,6 +1087,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
|||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SET_KEY:
|
case SET_KEY:
|
||||||
|
if (vif->type == NL80211_IFTYPE_AP && !sta) {
|
||||||
|
/* GTK on AP interface is a TX-only key, return 0 */
|
||||||
|
ret = 0;
|
||||||
|
key->hw_key_idx = STA_KEY_IDX_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
|
IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
|
||||||
ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
|
ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -1095,11 +1102,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
|||||||
* can't add key for RX, but we don't need it
|
* can't add key for RX, but we don't need it
|
||||||
* in the device for TX so still return 0
|
* in the device for TX so still return 0
|
||||||
*/
|
*/
|
||||||
|
key->hw_key_idx = STA_KEY_IDX_INVALID;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DISABLE_KEY:
|
case DISABLE_KEY:
|
||||||
|
if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
|
IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
|
||||||
ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
|
ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
|
||||||
break;
|
break;
|
||||||
@ -1148,7 +1161,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
|
|||||||
&chandef, 1, 1);
|
&chandef, 1, 1);
|
||||||
|
|
||||||
/* Schedule the time events */
|
/* Schedule the time events */
|
||||||
ret = iwl_mvm_start_p2p_roc(mvm, vif, duration);
|
ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
|
||||||
|
|
||||||
mutex_unlock(&mvm->mutex);
|
mutex_unlock(&mvm->mutex);
|
||||||
IWL_DEBUG_MAC80211(mvm, "leave\n");
|
IWL_DEBUG_MAC80211(mvm, "leave\n");
|
||||||
@ -1252,6 +1265,7 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||||||
* will handle quota settings.
|
* will handle quota settings.
|
||||||
*/
|
*/
|
||||||
if (vif->type == NL80211_IFTYPE_MONITOR) {
|
if (vif->type == NL80211_IFTYPE_MONITOR) {
|
||||||
|
mvmvif->monitor_active = true;
|
||||||
ret = iwl_mvm_update_quotas(mvm, vif);
|
ret = iwl_mvm_update_quotas(mvm, vif);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_remove_binding;
|
goto out_remove_binding;
|
||||||
@ -1282,15 +1296,16 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
|||||||
if (vif->type == NL80211_IFTYPE_AP)
|
if (vif->type == NL80211_IFTYPE_AP)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
|
||||||
switch (vif->type) {
|
switch (vif->type) {
|
||||||
case NL80211_IFTYPE_MONITOR:
|
case NL80211_IFTYPE_MONITOR:
|
||||||
iwl_mvm_update_quotas(mvm, vif);
|
mvmvif->monitor_active = false;
|
||||||
|
iwl_mvm_update_quotas(mvm, NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mvmvif->phy_ctxt = NULL;
|
mvmvif->phy_ctxt = NULL;
|
||||||
mutex_unlock(&mvm->mutex);
|
mutex_unlock(&mvm->mutex);
|
||||||
|
@ -90,10 +90,6 @@ enum iwl_mvm_tx_fifo {
|
|||||||
IWL_MVM_TX_FIFO_VO,
|
IWL_MVM_TX_FIFO_VO,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Placeholder */
|
|
||||||
#define IWL_OFFCHANNEL_QUEUE 8
|
|
||||||
#define IWL_FIRST_AMPDU_QUEUE 11
|
|
||||||
|
|
||||||
extern struct ieee80211_ops iwl_mvm_hw_ops;
|
extern struct ieee80211_ops iwl_mvm_hw_ops;
|
||||||
/**
|
/**
|
||||||
* struct iwl_mvm_mod_params - module parameters for iwlmvm
|
* struct iwl_mvm_mod_params - module parameters for iwlmvm
|
||||||
@ -161,6 +157,8 @@ enum iwl_power_scheme {
|
|||||||
* @uploaded: indicates the MAC context has been added to the device
|
* @uploaded: indicates the MAC context has been added to the device
|
||||||
* @ap_active: indicates that ap context is configured, and that the interface
|
* @ap_active: indicates that ap context is configured, and that the interface
|
||||||
* should get quota etc.
|
* should get quota etc.
|
||||||
|
* @monitor_active: indicates that monitor context is configured, and that the
|
||||||
|
* interface should get quota etc.
|
||||||
* @queue_params: QoS params for this MAC
|
* @queue_params: QoS params for this MAC
|
||||||
* @bcast_sta: station used for broadcast packets. Used by the following
|
* @bcast_sta: station used for broadcast packets. Used by the following
|
||||||
* vifs: P2P_DEVICE, GO and AP.
|
* vifs: P2P_DEVICE, GO and AP.
|
||||||
@ -173,6 +171,7 @@ struct iwl_mvm_vif {
|
|||||||
|
|
||||||
bool uploaded;
|
bool uploaded;
|
||||||
bool ap_active;
|
bool ap_active;
|
||||||
|
bool monitor_active;
|
||||||
|
|
||||||
u32 ap_beacon_time;
|
u32 ap_beacon_time;
|
||||||
|
|
||||||
@ -281,10 +280,7 @@ struct iwl_mvm {
|
|||||||
atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
|
atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
|
||||||
|
|
||||||
struct iwl_nvm_data *nvm_data;
|
struct iwl_nvm_data *nvm_data;
|
||||||
/* eeprom blob for debugfs/testmode */
|
/* NVM sections */
|
||||||
u8 *eeprom_blob;
|
|
||||||
size_t eeprom_blob_size;
|
|
||||||
/* NVM sections for 7000 family */
|
|
||||||
struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
|
struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
|
||||||
|
|
||||||
/* EEPROM MAC addresses */
|
/* EEPROM MAC addresses */
|
||||||
@ -451,6 +447,9 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
|
|||||||
struct ieee80211_vif *vif);
|
struct ieee80211_vif *vif);
|
||||||
int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
|
int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
|
||||||
struct ieee80211_vif *vif);
|
struct ieee80211_vif *vif);
|
||||||
|
int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
|
||||||
|
struct iwl_rx_cmd_buffer *rxb,
|
||||||
|
struct iwl_device_cmd *cmd);
|
||||||
|
|
||||||
/* Bindings */
|
/* Bindings */
|
||||||
int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||||
|
@ -77,26 +77,8 @@ static const int nvm_to_read[] = {
|
|||||||
/* Default NVM size to read */
|
/* Default NVM size to read */
|
||||||
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
|
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
|
||||||
|
|
||||||
/* used to simplify the shared operations on NCM_ACCESS_CMD versions */
|
static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd,
|
||||||
union iwl_nvm_access_cmd {
|
u16 offset, u16 length, u16 section)
|
||||||
struct iwl_nvm_access_cmd_ver1 ver1;
|
|
||||||
struct iwl_nvm_access_cmd_ver2 ver2;
|
|
||||||
};
|
|
||||||
union iwl_nvm_access_resp {
|
|
||||||
struct iwl_nvm_access_resp_ver1 ver1;
|
|
||||||
struct iwl_nvm_access_resp_ver2 ver2;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
|
|
||||||
u16 offset, u16 length)
|
|
||||||
{
|
|
||||||
cmd->offset = cpu_to_le16(offset);
|
|
||||||
cmd->length = cpu_to_le16(length);
|
|
||||||
cmd->cache_refresh = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
|
|
||||||
u16 offset, u16 length, u16 section)
|
|
||||||
{
|
{
|
||||||
cmd->offset = cpu_to_le16(offset);
|
cmd->offset = cpu_to_le16(offset);
|
||||||
cmd->length = cpu_to_le16(length);
|
cmd->length = cpu_to_le16(length);
|
||||||
@ -106,8 +88,8 @@ static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
|
|||||||
static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
|
static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
|
||||||
u16 offset, u16 length, u8 *data)
|
u16 offset, u16 length, u8 *data)
|
||||||
{
|
{
|
||||||
union iwl_nvm_access_cmd nvm_access_cmd;
|
struct iwl_nvm_access_cmd nvm_access_cmd = {};
|
||||||
union iwl_nvm_access_resp *nvm_resp;
|
struct iwl_nvm_access_resp *nvm_resp;
|
||||||
struct iwl_rx_packet *pkt;
|
struct iwl_rx_packet *pkt;
|
||||||
struct iwl_host_cmd cmd = {
|
struct iwl_host_cmd cmd = {
|
||||||
.id = NVM_ACCESS_CMD,
|
.id = NVM_ACCESS_CMD,
|
||||||
@ -117,18 +99,8 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
|
|||||||
int ret, bytes_read, offset_read;
|
int ret, bytes_read, offset_read;
|
||||||
u8 *resp_data;
|
u8 *resp_data;
|
||||||
|
|
||||||
memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd));
|
iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
|
||||||
|
cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
|
||||||
/* TODO: not sure family should be the decider, maybe FW version? */
|
|
||||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
|
||||||
iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
|
|
||||||
offset, length, section);
|
|
||||||
cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
|
|
||||||
} else {
|
|
||||||
iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
|
|
||||||
offset, length);
|
|
||||||
cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -144,17 +116,10 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
|
|||||||
|
|
||||||
/* Extract NVM response */
|
/* Extract NVM response */
|
||||||
nvm_resp = (void *)pkt->data;
|
nvm_resp = (void *)pkt->data;
|
||||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
ret = le16_to_cpu(nvm_resp->status);
|
||||||
ret = le16_to_cpu(nvm_resp->ver2.status);
|
bytes_read = le16_to_cpu(nvm_resp->length);
|
||||||
bytes_read = le16_to_cpu(nvm_resp->ver2.length);
|
offset_read = le16_to_cpu(nvm_resp->offset);
|
||||||
offset_read = le16_to_cpu(nvm_resp->ver2.offset);
|
resp_data = nvm_resp->data;
|
||||||
resp_data = nvm_resp->ver2.data;
|
|
||||||
} else {
|
|
||||||
ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
|
|
||||||
bytes_read = le16_to_cpu(nvm_resp->ver1.length);
|
|
||||||
offset_read = le16_to_cpu(nvm_resp->ver1.offset);
|
|
||||||
resp_data = nvm_resp->ver1.data;
|
|
||||||
}
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERR(mvm,
|
IWL_ERR(mvm,
|
||||||
"NVM access command failed with status %d (device: %s)\n",
|
"NVM access command failed with status %d (device: %s)\n",
|
||||||
@ -194,17 +159,10 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
|
|||||||
{
|
{
|
||||||
u16 length, offset = 0;
|
u16 length, offset = 0;
|
||||||
int ret;
|
int ret;
|
||||||
bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
|
|
||||||
|
|
||||||
/* Set nvm section read length */
|
/* Set nvm section read length */
|
||||||
length = IWL_NVM_DEFAULT_CHUNK_SIZE;
|
length = IWL_NVM_DEFAULT_CHUNK_SIZE;
|
||||||
|
|
||||||
/*
|
|
||||||
* if length is greater than EEPROM size, truncate it because uCode
|
|
||||||
* doesn't check it by itself, and exit the loop when reached.
|
|
||||||
*/
|
|
||||||
if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
|
|
||||||
length = mvm->cfg->base_params->eeprom_size;
|
|
||||||
ret = length;
|
ret = length;
|
||||||
|
|
||||||
/* Read the NVM until exhausted (reading less than requested) */
|
/* Read the NVM until exhausted (reading less than requested) */
|
||||||
@ -217,8 +175,6 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
offset += ret;
|
offset += ret;
|
||||||
if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_INFO(mvm, "NVM section %d read completed\n", section);
|
IWL_INFO(mvm, "NVM section %d read completed\n", section);
|
||||||
@ -252,63 +208,31 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
|
|||||||
int ret, i, section;
|
int ret, i, section;
|
||||||
u8 *nvm_buffer, *temp;
|
u8 *nvm_buffer, *temp;
|
||||||
|
|
||||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
/* TODO: find correct NVM max size for a section */
|
||||||
/* TODO: find correct NVM max size for a section */
|
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
|
||||||
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
|
GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
if (!nvm_buffer)
|
||||||
if (!nvm_buffer)
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
|
||||||
for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
|
section = nvm_to_read[i];
|
||||||
section = nvm_to_read[i];
|
/* we override the constness for initial read */
|
||||||
/* we override the constness for initial read */
|
ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
|
||||||
ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
|
|
||||||
if (!temp) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mvm->nvm_sections[section].data = temp;
|
|
||||||
mvm->nvm_sections[section].length = ret;
|
|
||||||
}
|
|
||||||
kfree(nvm_buffer);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
break;
|
||||||
} else {
|
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
|
||||||
/* allocate eeprom */
|
if (!temp) {
|
||||||
mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size;
|
ret = -ENOMEM;
|
||||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n",
|
break;
|
||||||
mvm->eeprom_blob_size);
|
|
||||||
mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
|
|
||||||
if (!mvm->eeprom_blob)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
|
|
||||||
if (ret != mvm->eeprom_blob_size) {
|
|
||||||
IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
|
|
||||||
ret, mvm->eeprom_blob_size);
|
|
||||||
kfree(mvm->eeprom_blob);
|
|
||||||
mvm->eeprom_blob = NULL;
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
mvm->nvm_sections[section].data = temp;
|
||||||
|
mvm->nvm_sections[section].length = ret;
|
||||||
}
|
}
|
||||||
|
kfree(nvm_buffer);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
|
mvm->nvm_data = iwl_parse_nvm_sections(mvm);
|
||||||
mvm->nvm_data = iwl_parse_nvm_sections(mvm);
|
|
||||||
else
|
|
||||||
mvm->nvm_data =
|
|
||||||
iwl_parse_eeprom_data(mvm->trans->dev,
|
|
||||||
mvm->cfg,
|
|
||||||
mvm->eeprom_blob,
|
|
||||||
mvm->eeprom_blob_size);
|
|
||||||
|
|
||||||
if (!mvm->nvm_data) {
|
|
||||||
kfree(mvm->eeprom_blob);
|
|
||||||
mvm->eeprom_blob = NULL;
|
|
||||||
ret = -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -143,21 +143,12 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
|
|||||||
u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
|
u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
|
||||||
u32 reg_val = 0;
|
u32 reg_val = 0;
|
||||||
|
|
||||||
/*
|
radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >>
|
||||||
* We can't upload the correct value to the INIT image
|
FW_PHY_CFG_RADIO_TYPE_POS;
|
||||||
* as we don't have nvm_data by that time.
|
radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >>
|
||||||
*
|
FW_PHY_CFG_RADIO_STEP_POS;
|
||||||
* TODO: Figure out what we should do here
|
radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >>
|
||||||
*/
|
FW_PHY_CFG_RADIO_DASH_POS;
|
||||||
if (mvm->nvm_data) {
|
|
||||||
radio_cfg_type = mvm->nvm_data->radio_cfg_type;
|
|
||||||
radio_cfg_step = mvm->nvm_data->radio_cfg_step;
|
|
||||||
radio_cfg_dash = mvm->nvm_data->radio_cfg_dash;
|
|
||||||
} else {
|
|
||||||
radio_cfg_type = 0;
|
|
||||||
radio_cfg_step = 0;
|
|
||||||
radio_cfg_dash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SKU control */
|
/* SKU control */
|
||||||
reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
|
reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
|
||||||
@ -175,7 +166,6 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
|
|||||||
|
|
||||||
/* silicon bits */
|
/* silicon bits */
|
||||||
reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
|
reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
|
||||||
reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
|
|
||||||
|
|
||||||
iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
|
iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
|
||||||
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
|
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
|
||||||
@ -231,6 +221,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
|||||||
RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
|
RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
|
||||||
|
|
||||||
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
|
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
|
||||||
|
RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
|
||||||
|
|
||||||
RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
|
RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
|
||||||
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
|
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
|
||||||
@ -276,6 +267,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
|
|||||||
CMD(WEP_KEY),
|
CMD(WEP_KEY),
|
||||||
CMD(REPLY_RX_PHY_CMD),
|
CMD(REPLY_RX_PHY_CMD),
|
||||||
CMD(REPLY_RX_MPDU_CMD),
|
CMD(REPLY_RX_MPDU_CMD),
|
||||||
|
CMD(BEACON_NOTIFICATION),
|
||||||
CMD(BEACON_TEMPLATE_CMD),
|
CMD(BEACON_TEMPLATE_CMD),
|
||||||
CMD(STATISTICS_NOTIFICATION),
|
CMD(STATISTICS_NOTIFICATION),
|
||||||
CMD(TX_ANT_CONFIGURATION_CMD),
|
CMD(TX_ANT_CONFIGURATION_CMD),
|
||||||
@ -319,16 +311,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||||||
};
|
};
|
||||||
int err, scan_size;
|
int err, scan_size;
|
||||||
|
|
||||||
switch (cfg->device_family) {
|
|
||||||
case IWL_DEVICE_FAMILY_6030:
|
|
||||||
case IWL_DEVICE_FAMILY_6005:
|
|
||||||
case IWL_DEVICE_FAMILY_7000:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
* 1. Allocating and configuring HW data
|
* 1. Allocating and configuring HW data
|
||||||
********************************/
|
********************************/
|
||||||
@ -444,7 +426,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||||||
out_free:
|
out_free:
|
||||||
iwl_phy_db_free(mvm->phy_db);
|
iwl_phy_db_free(mvm->phy_db);
|
||||||
kfree(mvm->scan_cmd);
|
kfree(mvm->scan_cmd);
|
||||||
kfree(mvm->eeprom_blob);
|
|
||||||
iwl_trans_stop_hw(trans, true);
|
iwl_trans_stop_hw(trans, true);
|
||||||
ieee80211_free_hw(mvm->hw);
|
ieee80211_free_hw(mvm->hw);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -466,7 +447,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
|||||||
iwl_phy_db_free(mvm->phy_db);
|
iwl_phy_db_free(mvm->phy_db);
|
||||||
mvm->phy_db = NULL;
|
mvm->phy_db = NULL;
|
||||||
|
|
||||||
kfree(mvm->eeprom_blob);
|
|
||||||
iwl_free_nvm_data(mvm->nvm_data);
|
iwl_free_nvm_data(mvm->nvm_data);
|
||||||
for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
|
for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
|
||||||
kfree(mvm->nvm_sections[i].data);
|
kfree(mvm->nvm_sections[i].data);
|
||||||
|
@ -142,7 +142,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
|
|||||||
struct cfg80211_chan_def *chandef,
|
struct cfg80211_chan_def *chandef,
|
||||||
u8 chains_static, u8 chains_dynamic)
|
u8 chains_static, u8 chains_dynamic)
|
||||||
{
|
{
|
||||||
u8 valid_rx_chains, active_cnt, idle_cnt;
|
u8 active_cnt, idle_cnt;
|
||||||
|
|
||||||
/* Set the channel info data */
|
/* Set the channel info data */
|
||||||
cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
|
cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
|
||||||
@ -158,17 +158,16 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
|
|||||||
* Need to add on chain noise calibration limitations, and
|
* Need to add on chain noise calibration limitations, and
|
||||||
* BT coex considerations.
|
* BT coex considerations.
|
||||||
*/
|
*/
|
||||||
valid_rx_chains = mvm->nvm_data->valid_rx_ant;
|
|
||||||
idle_cnt = chains_static;
|
idle_cnt = chains_static;
|
||||||
active_cnt = chains_dynamic;
|
active_cnt = chains_dynamic;
|
||||||
|
|
||||||
cmd->rxchain_info = cpu_to_le32(valid_rx_chains <<
|
cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) <<
|
||||||
PHY_RX_CHAIN_VALID_POS);
|
PHY_RX_CHAIN_VALID_POS);
|
||||||
cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
|
cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
|
||||||
cmd->rxchain_info |= cpu_to_le32(active_cnt <<
|
cmd->rxchain_info |= cpu_to_le32(active_cnt <<
|
||||||
PHY_RX_CHAIN_MIMO_CNT_POS);
|
PHY_RX_CHAIN_MIMO_CNT_POS);
|
||||||
|
|
||||||
cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant);
|
cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,7 +114,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
|
|||||||
data->n_interfaces[id]++;
|
data->n_interfaces[id]++;
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_MONITOR:
|
case NL80211_IFTYPE_MONITOR:
|
||||||
data->n_interfaces[id]++;
|
if (mvmvif->monitor_active)
|
||||||
|
data->n_interfaces[id]++;
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_P2P_DEVICE:
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
break;
|
break;
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
|
static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
|
||||||
{
|
{
|
||||||
u16 rx_chain;
|
u16 rx_chain;
|
||||||
u8 rx_ant = mvm->nvm_data->valid_rx_ant;
|
u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw);
|
||||||
|
|
||||||
rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
|
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_MIMO_SEL_POS;
|
||||||
@ -115,7 +115,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
|
|||||||
u32 tx_ant;
|
u32 tx_ant;
|
||||||
|
|
||||||
mvm->scan_last_antenna_idx =
|
mvm->scan_last_antenna_idx =
|
||||||
iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
|
iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
|
||||||
mvm->scan_last_antenna_idx);
|
mvm->scan_last_antenna_idx);
|
||||||
tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
|
tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
|
||||||
|
|
||||||
|
@ -76,14 +76,12 @@
|
|||||||
#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
|
#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
|
||||||
#define MSEC_TO_TU(_msec) (_msec*1000/1024)
|
#define MSEC_TO_TU(_msec) (_msec*1000/1024)
|
||||||
|
|
||||||
/* For ROC use a TE type which has priority high enough to be scheduled when
|
/*
|
||||||
* there is a concurrent BSS or GO/AP. Currently, use a TE type that has
|
* For the high priority TE use a time event type that has similar priority to
|
||||||
* priority similar to the TE priority used for action scans by the FW.
|
* the FW's action scan priority.
|
||||||
* TODO: This needs to be changed, based on the reason for the ROC, i.e., use
|
|
||||||
* TE_P2P_DEVICE_DISCOVERABLE for remain on channel without mgmt skb, and use
|
|
||||||
* TE_P2P_DEVICE_ACTION_SCAN
|
|
||||||
*/
|
*/
|
||||||
#define IWL_MVM_ROC_TE_TYPE TE_P2P_DEVICE_ACTION_SCAN
|
#define IWL_MVM_ROC_TE_TYPE_NORMAL TE_P2P_DEVICE_DISCOVERABLE
|
||||||
|
#define IWL_MVM_ROC_TE_TYPE_MGMT_TX TE_P2P_CLIENT_ASSOC
|
||||||
|
|
||||||
void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
|
void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
|
||||||
struct iwl_mvm_time_event_data *te_data)
|
struct iwl_mvm_time_event_data *te_data)
|
||||||
@ -116,7 +114,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
|||||||
* issue as it will have to complete before the next command is
|
* issue as it will have to complete before the next command is
|
||||||
* executed, and a new time event means a new command.
|
* executed, and a new time event means a new command.
|
||||||
*/
|
*/
|
||||||
iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false);
|
iwl_mvm_flush_tx_path(mvm, BIT(IWL_MVM_OFFCHANNEL_QUEUE), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
|
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
|
||||||
@ -438,7 +436,7 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
int duration)
|
int duration, enum ieee80211_roc_type type)
|
||||||
{
|
{
|
||||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
||||||
@ -459,21 +457,29 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||||||
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
|
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
|
||||||
time_cmd.id_and_color =
|
time_cmd.id_and_color =
|
||||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
|
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
|
||||||
time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE);
|
|
||||||
|
switch (type) {
|
||||||
|
case IEEE80211_ROC_TYPE_NORMAL:
|
||||||
|
time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_NORMAL);
|
||||||
|
break;
|
||||||
|
case IEEE80211_ROC_TYPE_MGMT_TX:
|
||||||
|
time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_MGMT_TX);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "Got an invalid ROC type\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
time_cmd.apply_time = cpu_to_le32(0);
|
time_cmd.apply_time = cpu_to_le32(0);
|
||||||
time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
|
time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
|
||||||
time_cmd.is_present = cpu_to_le32(1);
|
time_cmd.is_present = cpu_to_le32(1);
|
||||||
|
|
||||||
time_cmd.interval = cpu_to_le32(1);
|
time_cmd.interval = cpu_to_le32(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IWL_MVM_ROC_TE_TYPE can have lower priority than other events
|
* The P2P Device TEs can have lower priority than other events
|
||||||
* that are being scheduled by the driver/fw, and thus it might not be
|
* that are being scheduled by the driver/fw, and thus it might not be
|
||||||
* scheduled. To improve the chances of it being scheduled, allow it to
|
* scheduled. To improve the chances of it being scheduled, allow them
|
||||||
* be fragmented.
|
* to be fragmented, and in addition allow them to be delayed.
|
||||||
* In addition, for the same reasons, allow to delay the scheduling of
|
|
||||||
* the time event.
|
|
||||||
*/
|
*/
|
||||||
time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
|
time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
|
||||||
time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
|
time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
|
||||||
|
@ -162,6 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
|
|||||||
* that the vif type is NL80211_IFTYPE_P2P_DEVICE
|
* that the vif type is NL80211_IFTYPE_P2P_DEVICE
|
||||||
* @duration: the requested duration in millisecond for the fw to be on the
|
* @duration: the requested duration in millisecond for the fw to be on the
|
||||||
* channel that is bound to the vif.
|
* channel that is bound to the vif.
|
||||||
|
* @type: the remain on channel request type
|
||||||
*
|
*
|
||||||
* This function can be used to issue a remain on channel session,
|
* This function can be used to issue a remain on channel session,
|
||||||
* which means that the fw will stay in the channel for the request %duration
|
* which means that the fw will stay in the channel for the request %duration
|
||||||
@ -172,7 +173,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
|
|||||||
* another notification to the driver.
|
* another notification to the driver.
|
||||||
*/
|
*/
|
||||||
int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
int duration);
|
int duration, enum ieee80211_roc_type type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
|
* iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
|
||||||
|
@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
|
|||||||
spin_unlock(&mvmsta->lock);
|
spin_unlock(&mvmsta->lock);
|
||||||
|
|
||||||
if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
|
if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
|
||||||
txq_id < IWL_FIRST_AMPDU_QUEUE)
|
txq_id < IWL_MVM_FIRST_AGG_QUEUE)
|
||||||
atomic_inc(&mvmsta->pending_frames);
|
atomic_inc(&mvmsta->pending_frames);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -606,7 +606,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||||||
info);
|
info);
|
||||||
|
|
||||||
/* Single frame failure in an AMPDU queue => send BAR */
|
/* Single frame failure in an AMPDU queue => send BAR */
|
||||||
if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&
|
if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE &&
|
||||||
!(info->flags & IEEE80211_TX_STAT_ACK))
|
!(info->flags & IEEE80211_TX_STAT_ACK))
|
||||||
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
||||||
|
|
||||||
@ -619,7 +619,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||||||
ieee80211_tx_status_ni(mvm->hw, skb);
|
ieee80211_tx_status_ni(mvm->hw, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txq_id >= IWL_FIRST_AMPDU_QUEUE) {
|
if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) {
|
||||||
/* If this is an aggregation queue, we use the ssn since:
|
/* If this is an aggregation queue, we use the ssn since:
|
||||||
* ssn = wifi seq_num % 256.
|
* ssn = wifi seq_num % 256.
|
||||||
* The seq_ctl is the sequence control of the packet to which
|
* The seq_ctl is the sequence control of the packet to which
|
||||||
@ -681,7 +681,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||||||
* If there are no pending frames for this STA, notify mac80211 that
|
* If there are no pending frames for this STA, notify mac80211 that
|
||||||
* this station can go to sleep in its STA table.
|
* this station can go to sleep in its STA table.
|
||||||
*/
|
*/
|
||||||
if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta &&
|
if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta &&
|
||||||
!WARN_ON(skb_freed > 1) &&
|
!WARN_ON(skb_freed > 1) &&
|
||||||
mvmsta->vif->type == NL80211_IFTYPE_AP &&
|
mvmsta->vif->type == NL80211_IFTYPE_AP &&
|
||||||
atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
|
atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
|
||||||
@ -750,7 +750,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
|
|||||||
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||||
struct ieee80211_sta *sta;
|
struct ieee80211_sta *sta;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE))
|
if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
|
if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
|
||||||
|
@ -1566,8 +1566,11 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
|||||||
if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
|
if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (test_bit(STATUS_RFKILL, &trans_pcie->status))
|
if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
|
||||||
|
IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
|
||||||
|
cmd->id);
|
||||||
return -ERFKILL;
|
return -ERFKILL;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd->flags & CMD_ASYNC)
|
if (cmd->flags & CMD_ASYNC)
|
||||||
return iwl_pcie_send_hcmd_async(trans, cmd);
|
return iwl_pcie_send_hcmd_async(trans, cmd);
|
||||||
|
Loading…
Reference in New Issue
Block a user