aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-07-08 10:49:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-08 16:35:50 -0400
commitbbbb538e337a3eb2166d5a20307b93822bdacc4f (patch)
tree1a263c7062785b539867751dd018780df2f77a8e /drivers
parentab2807efcfd2dd646a2ca8d71585e26cda3fc0c1 (diff)
wl1271: Add TSF handling
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c26
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c27
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c6
4 files changed, 65 insertions, 6 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index e19e2f8f1e52..5cadb9d06c76 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -1266,3 +1266,29 @@ out:
1266 kfree(acx); 1266 kfree(acx);
1267 return ret; 1267 return ret;
1268} 1268}
1269
1270int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
1271{
1272 struct wl1271_acx_fw_tsf_information *tsf_info;
1273 int ret;
1274
1275 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
1276 if (!tsf_info) {
1277 ret = -ENOMEM;
1278 goto out;
1279 }
1280
1281 ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
1282 tsf_info, sizeof(*tsf_info));
1283 if (ret < 0) {
1284 wl1271_warning("acx tsf info interrogate failed");
1285 goto out;
1286 }
1287
1288 *mactime = le32_to_cpu(tsf_info->current_tsf_low) |
1289 ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
1290
1291out:
1292 kfree(tsf_info);
1293 return ret;
1294}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 420e7e2fc021..914b29b92999 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -993,6 +993,17 @@ struct wl1271_acx_rssi_snr_avg_weights {
993 u8 snr_data; 993 u8 snr_data;
994}; 994};
995 995
996struct wl1271_acx_fw_tsf_information {
997 struct acx_header header;
998
999 __le32 current_tsf_high;
1000 __le32 current_tsf_low;
1001 __le32 last_bttt_high;
1002 __le32 last_tbtt_low;
1003 u8 last_dtim_count;
1004 u8 padding[3];
1005} __attribute__ ((packed));
1006
996enum { 1007enum {
997 ACX_WAKE_UP_CONDITIONS = 0x0002, 1008 ACX_WAKE_UP_CONDITIONS = 0x0002,
998 ACX_MEM_CFG = 0x0003, 1009 ACX_MEM_CFG = 0x0003,
@@ -1114,5 +1125,6 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
1114int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, 1125int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1115 s16 thold, u8 hyst); 1126 s16 thold, u8 hyst);
1116int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); 1127int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
1128int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
1117 1129
1118#endif /* __WL1271_ACX_H__ */ 1130#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 7a14da506d78..5970fde49d40 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1966,6 +1966,32 @@ out:
1966 return ret; 1966 return ret;
1967} 1967}
1968 1968
1969static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
1970{
1971
1972 struct wl1271 *wl = hw->priv;
1973 u64 mactime = ULLONG_MAX;
1974 int ret;
1975
1976 wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf");
1977
1978 mutex_lock(&wl->mutex);
1979
1980 ret = wl1271_ps_elp_wakeup(wl, false);
1981 if (ret < 0)
1982 goto out;
1983
1984 ret = wl1271_acx_tsf_info(wl, &mactime);
1985 if (ret < 0)
1986 goto out_sleep;
1987
1988out_sleep:
1989 wl1271_ps_elp_sleep(wl);
1990
1991out:
1992 mutex_unlock(&wl->mutex);
1993 return mactime;
1994}
1969 1995
1970/* can't be const, mac80211 writes to this */ 1996/* can't be const, mac80211 writes to this */
1971static struct ieee80211_rate wl1271_rates[] = { 1997static struct ieee80211_rate wl1271_rates[] = {
@@ -2195,6 +2221,7 @@ static const struct ieee80211_ops wl1271_ops = {
2195 .bss_info_changed = wl1271_op_bss_info_changed, 2221 .bss_info_changed = wl1271_op_bss_info_changed,
2196 .set_rts_threshold = wl1271_op_set_rts_threshold, 2222 .set_rts_threshold = wl1271_op_set_rts_threshold,
2197 .conf_tx = wl1271_op_conf_tx, 2223 .conf_tx = wl1271_op_conf_tx,
2224 .get_tsf = wl1271_op_get_tsf,
2198 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 2225 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
2199}; 2226};
2200 2227
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index b98fb643fab0..e98f22b3c3ba 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -53,12 +53,6 @@ static void wl1271_rx_status(struct wl1271 *wl,
53 status->band = wl->band; 53 status->band = wl->band;
54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); 54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
55 55
56 /*
57 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the
58 * timestamp from the beacon (acx_tsf_info). In BSS mode (infra) we
59 * only need the mactime for monitor mode. For now the mactime is
60 * not valid, so RX_FLAG_TSFT should not be set
61 */
62 status->signal = desc->rssi; 56 status->signal = desc->rssi;
63 57
64 status->freq = ieee80211_channel_to_frequency(desc->channel); 58 status->freq = ieee80211_channel_to_frequency(desc->channel);