break;
        case NL80211_IFTYPE_STATION:
-               apply_time = chsw->timestamp +
-                       (vif->bss_conf.beacon_int * chsw->count * 1024);
+               /* Schedule the time event to a bit before beacon 1,
+                * to make sure we're in the new channel when the
+                * GO/AP arrives.
+                */
+               apply_time = chsw->device_timestamp +
+                       ((vif->bss_conf.beacon_int * (chsw->count - 1) -
+                         IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
 
                if (chsw->block_tx)
                        iwl_mvm_csa_client_absent(mvm, vif);
 
-               iwl_mvm_schedule_csa_period(mvm, vif,
-                                           IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT,
+               iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
                                            apply_time);
                break;
        default:
 
 /* A TimeUnit is 1024 microsecond */
 #define MSEC_TO_TU(_msec)      (_msec*1000/1024)
 
-/* These values represent the number of TUs before CSA "beacon 0" TBTT
- * when the CSA time-event needs to be scheduled to start.  They must
- * be big enough to ensure that we switch in time.
+/* For GO, this value represents the number of TUs before CSA "beacon
+ * 0" TBTT when the CSA time-event needs to be scheduled to start.  It
+ * must be big enough to ensure that we switch in time.
  */
 #define IWL_MVM_CHANNEL_SWITCH_TIME_GO         40
-#define IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT     110
+
+/* For client, this value represents the number of TUs before CSA
+ * "beacon 1" TBTT, instead.  This is because we don't know when the
+ * GO/AP will be in the new channel, so we switch early enough.
+ */
+#define IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT     10
 
 /*
  * This value (in TUs) is used to fine tune the CSA NoA end time which should