iwlwifi: mvm: don't read system time when modifying AP/GO MAC
authorJohannes Berg <johannes.berg@intel.com>
Thu, 28 Feb 2013 13:05:14 +0000 (14:05 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 Mar 2013 15:47:54 +0000 (16:47 +0100)
When modifying a MAC, we update its beacon system time which
is taken as a base to calculate TBTT. The firmware doesn't use
the new timestamp because the time is never used after the MAC
and broadcast station were added, but it is safer to not rely
on this and avoids the overhead of reading the register every
time the MAC is updated.

Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mvm.h

index a993f6c7dac02084e6b65567011afa771893c879..2779235daa356457f05a3a5c46c0b2b6fa8fcff9 100644 (file)
@@ -855,10 +855,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
  */
 static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
                                         struct ieee80211_vif *vif,
-                                        struct iwl_mac_data_ap *ctxt_ap)
+                                        struct iwl_mac_data_ap *ctxt_ap,
+                                        bool add)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       u32 curr_dev_time;
 
        ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
        ctxt_ap->bi_reciprocal =
@@ -870,10 +870,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
                                               vif->bss_conf.dtim_period));
 
        ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
-       curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
-       ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);
 
-       ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time);
+       /*
+        * Only read the system time when the MAC is being added, when we
+        * just modify the MAC then we should keep the time -- the firmware
+        * can otherwise have a "jumping" TBTT.
+        */
+       if (add)
+               mvmvif->ap_beacon_time =
+                       iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
+
+       ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
+
+       ctxt_ap->beacon_tsf = 0; /* unused */
 
        /* TODO: Assume that the beacon id == mac context id */
        ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);
@@ -894,7 +903,8 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
        cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
 
        /* Fill the data specific for ap mode */
-       iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap);
+       iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap,
+                                    action == FW_CTXT_ACTION_ADD);
 
        return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
 }
@@ -911,7 +921,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
        iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 
        /* Fill the data specific for GO mode */
-       iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap);
+       iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
+                                    action == FW_CTXT_ACTION_ADD);
 
        cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
        cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
index efe5da992897f0aedb49fa4bf9bb6a8ad9779521..234c5726d196065a2268ca91c412c37845b29d77 100644 (file)
@@ -174,6 +174,8 @@ struct iwl_mvm_vif {
        bool uploaded;
        bool ap_active;
 
+       u32 ap_beacon_time;
+
        enum iwl_tsf_id tsf_id;
 
        /*