struct iwl_mac_data_sta *ctxt_sta)
{
/* We need the dtim_period to set the MAC as associated */
- if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
+ if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) {
+ u32 dtim_offs;
+
+ /*
+ * The DTIM count counts down, so when it is N that means N
+ * more beacon intervals happen until the DTIM TBTT. Therefore
+ * add this to the current time. If that ends up being in the
+ * future, the firmware will handle it.
+ *
+ * Also note that the system_timestamp (which we get here as
+ * "sync_device_ts") and TSF timestamp aren't at exactly the
+ * same offset in the frame -- the TSF is at the first symbol
+ * of the TSF, the system timestamp is at signal acquisition
+ * time. This means there's an offset between them of at most
+ * a few hundred microseconds (24 * 8 bits + PLCP time gives
+ * 384us in the longest case), this is currently not relevant
+ * as the firmware wakes up around 2ms before the TBTT.
+ */
+ dtim_offs = vif->bss_conf.sync_dtim_count *
+ vif->bss_conf.beacon_int;
+ /* convert TU to usecs */
+ dtim_offs *= 1024;
+
+ ctxt_sta->dtim_tsf =
+ cpu_to_le64(vif->bss_conf.sync_tsf + dtim_offs);
+ ctxt_sta->dtim_time =
+ cpu_to_le32(vif->bss_conf.sync_device_ts + dtim_offs);
+
+ IWL_DEBUG_INFO(mvm, "DTIM TBTT is 0x%llx/0x%x, offset %d\n",
+ le64_to_cpu(ctxt_sta->dtim_tsf),
+ le32_to_cpu(ctxt_sta->dtim_time),
+ dtim_offs);
+
ctxt_sta->is_assoc = cpu_to_le32(1);
- else
+ } else {
ctxt_sta->is_assoc = cpu_to_le32(0);
+ }
ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
ctxt_sta->bi_reciprocal =
IEEE80211_HW_WANT_MONITOR_VIF |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
- IEEE80211_HW_AMPDU_AGGREGATION;
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_TIMING_BEACON_ONLY;
hw->queues = IWL_FIRST_AMPDU_QUEUE;
hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;