diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-07-08 10:49:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-08 16:35:50 -0400 |
commit | bbbb538e337a3eb2166d5a20307b93822bdacc4f (patch) | |
tree | 1a263c7062785b539867751dd018780df2f77a8e /drivers | |
parent | ab2807efcfd2dd646a2ca8d71585e26cda3fc0c1 (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.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_rx.c | 6 |
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 | |||
1270 | int 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 | |||
1291 | out: | ||
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 | ||
996 | struct 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 | |||
996 | enum { | 1007 | enum { |
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); | |||
1114 | int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, | 1125 | int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, |
1115 | s16 thold, u8 hyst); | 1126 | s16 thold, u8 hyst); |
1116 | int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); | 1127 | int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); |
1128 | int 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 | ||
1969 | static 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 | |||
1988 | out_sleep: | ||
1989 | wl1271_ps_elp_sleep(wl); | ||
1990 | |||
1991 | out: | ||
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 */ |
1971 | static struct ieee80211_rate wl1271_rates[] = { | 1997 | static 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); |