wl1271: Add TSF handling
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>
Thu, 8 Jul 2010 14:49:57 +0000 (17:49 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 8 Jul 2010 20:35:50 +0000 (16:35 -0400)
Add functionality to pass the current TSF (mac time) to the mac80211. This is
needed for ad-hoc merging.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/wl12xx/wl1271_acx.c
drivers/net/wireless/wl12xx/wl1271_acx.h
drivers/net/wireless/wl12xx/wl1271_main.c
drivers/net/wireless/wl12xx/wl1271_rx.c

index e19e2f8f1e522d7806fcde6224a35bfa90a4b65a..5cadb9d06c7693fa12273b4541b2fc25dd15bea2 100644 (file)
@@ -1266,3 +1266,29 @@ out:
        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;
+}
index 420e7e2fc021b357032a861b67acd2bb82007eff..914b29b929993b10418beb382333f9cd45757b33 100644 (file)
@@ -993,6 +993,17 @@ struct wl1271_acx_rssi_snr_avg_weights {
        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,
@@ -1114,5 +1125,6 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
 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__ */
index 7a14da506d781c0f5b3373454c021533df5b6c36..5970fde49d40c7c9302d81c4a462822bb031bfac 100644 (file)
@@ -1966,6 +1966,32 @@ out:
        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[] = {
@@ -2195,6 +2221,7 @@ static const struct ieee80211_ops wl1271_ops = {
        .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)
 };
 
index b98fb643fab0cd674fd33e9b3969e95cab4ea0ef..e98f22b3c3ba8d597eb415905d0b78e649fbaff7 100644 (file)
@@ -53,12 +53,6 @@ static void wl1271_rx_status(struct wl1271 *wl,
        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);