forked from Minki/linux
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: David Spinadel <david.spinadel@intel.com> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
parent
09b0ce1a87
commit
1c87bbad43
@ -119,11 +119,13 @@ enum iwl_ucode_tlv_flag {
|
|||||||
/**
|
/**
|
||||||
* enum iwl_ucode_tlv_api - ucode api
|
* enum iwl_ucode_tlv_api - ucode api
|
||||||
* @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
|
* @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_CSA_FLOW: ucode can do unbind-bind flow for CSA.
|
||||||
* @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
|
* @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
|
||||||
*/
|
*/
|
||||||
enum iwl_ucode_tlv_api {
|
enum iwl_ucode_tlv_api {
|
||||||
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
|
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_CSA_FLOW = BIT(4),
|
||||||
IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
|
IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
|
||||||
};
|
};
|
||||||
|
@ -548,6 +548,20 @@ struct iwl_beacon_notif {
|
|||||||
__le32 ibss_mgr_status;
|
__le32 ibss_mgr_status;
|
||||||
} __packed;
|
} __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
|
* 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
|
||||||
|
@ -1205,19 +1205,31 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
|
|||||||
struct iwl_device_cmd *cmd)
|
struct iwl_device_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
struct iwl_beacon_notif *beacon = (void *)pkt->data;
|
struct iwl_mvm_tx_resp *beacon_notify_hdr;
|
||||||
u16 status __maybe_unused =
|
u64 tsf;
|
||||||
le16_to_cpu(beacon->beacon_notify_hdr.status.status);
|
|
||||||
u32 rate __maybe_unused =
|
|
||||||
le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
|
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
|
if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_CAPA_EXTENDED_BEACON) {
|
||||||
status & TX_STATUS_MSK,
|
struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
|
||||||
beacon->beacon_notify_hdr.failure_frame,
|
|
||||||
le64_to_cpu(beacon->tsf),
|
beacon_notify_hdr = &beacon->beacon_notify_hdr;
|
||||||
rate);
|
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 (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) {
|
||||||
if (!ieee80211_csa_is_complete(mvm->csa_vif)) {
|
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);
|
mutex_lock(&mvm->mutex);
|
||||||
|
|
||||||
mvmvif->ap_ibss_active = false;
|
mvmvif->ap_ibss_active = false;
|
||||||
|
mvm->ap_last_beacon_gp2 = 0;
|
||||||
|
|
||||||
iwl_mvm_bt_coex_vif_change(mvm);
|
iwl_mvm_bt_coex_vif_change(mvm);
|
||||||
|
|
||||||
|
@ -658,6 +658,9 @@ struct iwl_mvm {
|
|||||||
bool ps_disabled;
|
bool ps_disabled;
|
||||||
|
|
||||||
struct ieee80211_vif *csa_vif;
|
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 */
|
/* Extract MVM priv from op_mode and _hw */
|
||||||
|
Loading…
Reference in New Issue
Block a user