kfree(acx);
        return ret;
 }
+
+int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
+{
+       struct wl1271_acx_fw_tsf_information *tsf_info;
+       int ret;
+
+       tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
+       if (!tsf_info) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
+                                    tsf_info, sizeof(*tsf_info));
+       if (ret < 0) {
+               wl1271_warning("acx tsf info interrogate failed");
+               goto out;
+       }
+
+       *mactime = le32_to_cpu(tsf_info->current_tsf_low) |
+               ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
+
+out:
+       kfree(tsf_info);
+       return ret;
+}
 
        u8 snr_data;
 };
 
+struct wl1271_acx_fw_tsf_information {
+       struct acx_header header;
+
+       __le32 current_tsf_high;
+       __le32 current_tsf_low;
+       __le32 last_bttt_high;
+       __le32 last_tbtt_low;
+       u8 last_dtim_count;
+       u8 padding[3];
+} __attribute__ ((packed));
+
 enum {
        ACX_WAKE_UP_CONDITIONS      = 0x0002,
        ACX_MEM_CFG                 = 0x0003,
 int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
                                s16 thold, u8 hyst);
 int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
+int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
 
 #endif /* __WL1271_ACX_H__ */
 
        return ret;
 }
 
+static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
+{
+
+       struct wl1271 *wl = hw->priv;
+       u64 mactime = ULLONG_MAX;
+       int ret;
+
+       wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf");
+
+       mutex_lock(&wl->mutex);
+
+       ret = wl1271_ps_elp_wakeup(wl, false);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1271_acx_tsf_info(wl, &mactime);
+       if (ret < 0)
+               goto out_sleep;
+
+out_sleep:
+       wl1271_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+       return mactime;
+}
 
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_rate wl1271_rates[] = {
        .bss_info_changed = wl1271_op_bss_info_changed,
        .set_rts_threshold = wl1271_op_set_rts_threshold,
        .conf_tx = wl1271_op_conf_tx,
+       .get_tsf = wl1271_op_get_tsf,
        CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
 };
 
 
        status->band = wl->band;
        status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
 
-       /*
-        * FIXME: Add mactime handling.  For IBSS (ad-hoc) we need to get the
-        * timestamp from the beacon (acx_tsf_info).  In BSS mode (infra) we
-        * only need the mactime for monitor mode.  For now the mactime is
-        * not valid, so RX_FLAG_TSFT should not be set
-        */
        status->signal = desc->rssi;
 
        status->freq = ieee80211_channel_to_frequency(desc->channel);