iwlwifi: mvm: support extended beacon notification
authorDavid Spinadel <david.spinadel@intel.com>
Thu, 27 Feb 2014 14:41:52 +0000 (16:41 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 24 Jun 2014 18:55:39 +0000 (21:55 +0300)
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>
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h

index c71331034e9bcadfe78a3efc1241f06cabaa9aac..13e5d69845e9e7653b7010a53197a121c1d02e64 100644 (file)
@@ -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),
 };
index 6cc5f52b807f1bc343ea632674e215423c3abb1d..bdd6ff648626a0e8435c60b8287e274098f8fc69 100644 (file)
@@ -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
index 8b530277763258551cf09292298f8f14be074174..3b0390b8639cfe08dde583aeddc006a04c8d74e8 100644 (file)
@@ -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)) {
index f22be88c038740d3d1790f2061ee61ca9f77bc2f..f2fde36491398d6b5a6e045a8400d7b75527dfd3 100644 (file)
@@ -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);
 
index 8419840d4701f187be955d7cf6c0f452de2a0dcc..da692582d502ae06584e7abbdf51e5a11d6545de 100644 (file)
@@ -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 */