Commit 1c87bbad authored by David Spinadel's avatar David Spinadel Committed by Emmanuel Grumbach

iwlwifi: mvm: support extended beacon notification

Use extended beacon notification when supported by FW.
Set last beacon system time to AP or GO interface.
System time of last beacon can be used to avoid TBTT overlapping
between two interfaces, CSA and other uses.
Signed-off-by: default avatarDavid Spinadel <david.spinadel@intel.com>
Signed-off-by: default avatarAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 09b0ce1a
......@@ -119,11 +119,13 @@ enum iwl_ucode_tlv_flag {
/**
* enum iwl_ucode_tlv_api - ucode api
* @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
* @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
* @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
* @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
*/
enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
};
......
......@@ -548,6 +548,20 @@ struct iwl_beacon_notif {
__le32 ibss_mgr_status;
} __packed;
/**
* struct iwl_extended_beacon_notif - notifies about beacon transmission
* @beacon_notify_hdr: tx response command associated with the beacon
* @tsf: last beacon tsf
* @ibss_mgr_status: whether IBSS is manager
* @gp2: last beacon time in gp2
*/
struct iwl_extended_beacon_notif {
struct iwl_mvm_tx_resp beacon_notify_hdr;
__le64 tsf;
__le32 ibss_mgr_status;
__le32 gp2;
} __packed; /* BEACON_NTFY_API_S_VER_5 */
/**
* enum iwl_dump_control - dump (flush) control flags
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
......
......@@ -1205,19 +1205,31 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
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);
struct iwl_mvm_tx_resp *beacon_notify_hdr;
u64 tsf;
lockdep_assert_held(&mvm->mutex);
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);
if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_CAPA_EXTENDED_BEACON) {
struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
beacon_notify_hdr = &beacon->beacon_notify_hdr;
tsf = le64_to_cpu(beacon->tsf);
mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
} else {
struct iwl_beacon_notif *beacon = (void *)pkt->data;
beacon_notify_hdr = &beacon->beacon_notify_hdr;
tsf = le64_to_cpu(beacon->tsf);
}
IWL_DEBUG_RX(mvm,
"beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n",
le16_to_cpu(beacon_notify_hdr->status.status) &
TX_STATUS_MSK,
beacon_notify_hdr->failure_frame, tsf,
mvm->ap_last_beacon_gp2,
le32_to_cpu(beacon_notify_hdr->initial_rate));
if (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) {
if (!ieee80211_csa_is_complete(mvm->csa_vif)) {
......
......@@ -1465,6 +1465,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex);
mvmvif->ap_ibss_active = false;
mvm->ap_last_beacon_gp2 = 0;
iwl_mvm_bt_coex_vif_change(mvm);
......
......@@ -658,6 +658,9 @@ struct iwl_mvm {
bool ps_disabled;
struct ieee80211_vif *csa_vif;
/* system time of last beacon (for AP/GO interface) */
u32 ap_last_beacon_gp2;
};
/* Extract MVM priv from op_mode and _hw */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment