ath10k: add a support of set_tsf on vdev interface
authorPeter Oh <poh@qca.qualcomm.com>
Mon, 4 Apr 2016 23:19:14 +0000 (16:19 -0700)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 12 Apr 2016 18:26:24 +0000 (21:26 +0300)
10.2.4.70.24 firmware introduces new feature to set TSF
via vdev parameter, hence implement relevant function.
set_tsf function can be used to shift TBTT that will
help avoid its clockdrift which happens when beacons
are collided.

Signed-off-by: Peter Oh <poh@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/wmi-tlv.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.h

index b0e613bc10a5000f8249a388fc0174d5f82b5371..c30a3944b612686916ddb83a0afac3f222ad62bd 100644 (file)
@@ -6796,6 +6796,32 @@ static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        return 0;
 }
 
+static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                   u64 tsf)
+{
+       struct ath10k *ar = hw->priv;
+       struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+       u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
+       int ret;
+
+       /* Workaround:
+        *
+        * Given tsf argument is entire TSF value, but firmware accepts
+        * only TSF offset to current TSF.
+        *
+        * get_tsf function is used to get offset value, however since
+        * ath10k_get_tsf is not implemented properly, it will return 0 always.
+        * Luckily all the caller functions to set_tsf, as of now, also rely on
+        * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
+        * final tsf offset value to firmware will be arithmetically correct.
+        */
+       tsf_offset = tsf - ath10k_get_tsf(hw, vif);
+       ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+                                       vdev_param, tsf_offset);
+       if (ret && ret != -EOPNOTSUPP)
+               ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
+}
+
 static int ath10k_ampdu_action(struct ieee80211_hw *hw,
                               struct ieee80211_vif *vif,
                               struct ieee80211_ampdu_params *params)
@@ -7252,6 +7278,7 @@ static const struct ieee80211_ops ath10k_ops = {
        .set_bitrate_mask               = ath10k_mac_op_set_bitrate_mask,
        .sta_rc_update                  = ath10k_sta_rc_update,
        .get_tsf                        = ath10k_get_tsf,
+       .set_tsf                        = ath10k_set_tsf,
        .ampdu_action                   = ath10k_ampdu_action,
        .get_et_sset_count              = ath10k_debug_get_et_sset_count,
        .get_et_stats                   = ath10k_debug_get_et_stats,
index 108593202052fb86fe43060ec6f19ef113417d0f..e09337ee7c9664cccb3368faf59dc460845f5f80 100644 (file)
@@ -3409,6 +3409,7 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
        .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
        .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
        .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
+       .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
 };
 
 static const struct wmi_ops wmi_tlv_ops = {
index f7ec65f263a0e13a291fe4fbbaa7999d5c854ea6..db3e9a4be564784a0a0dc2d53d172afeda43a80a 100644 (file)
@@ -781,6 +781,7 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = {
        .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
        .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
        .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
+       .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
 };
 
 /* 10.X WMI VDEV param map */
@@ -856,6 +857,7 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
        .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
        .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
        .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
+       .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
 };
 
 static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
@@ -930,6 +932,7 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
        .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
        .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
        .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
+       .set_tsf = WMI_10X_VDEV_PARAM_TSF_INCREMENT,
 };
 
 static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
@@ -1005,6 +1008,7 @@ static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
        .meru_vc = WMI_10_4_VDEV_PARAM_MERU_VC,
        .rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE,
        .bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK,
+       .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
 };
 
 static struct wmi_pdev_param_map wmi_pdev_param_map = {
index 0fae0daa9215460c380feb6cc9ce01eaab3aa3fa..137edb4d451d95a4d2f6b35dbc7c793f4326aa23 100644 (file)
@@ -4635,6 +4635,7 @@ struct wmi_vdev_param_map {
        u32 meru_vc;
        u32 rx_decap_type;
        u32 bw_nss_ratemask;
+       u32 set_tsf;
 };
 
 #define WMI_VDEV_PARAM_UNSUPPORTED 0
@@ -4891,6 +4892,7 @@ enum wmi_10x_vdev_param {
        WMI_10X_VDEV_PARAM_RTS_FIXED_RATE,
        WMI_10X_VDEV_PARAM_VHT_SGIMASK,
        WMI_10X_VDEV_PARAM_VHT80_RATEMASK,
+       WMI_10X_VDEV_PARAM_TSF_INCREMENT,
 };
 
 enum wmi_10_4_vdev_param {