diff options
| author | bings <bings@codeaurora.org> | 2018-12-19 10:18:27 +0800 |
|---|---|---|
| committer | bings <bings@codeaurora.org> | 2018-12-25 10:24:16 +0800 |
| commit | e9be2a2cf3079c4147baaacecd7965a8eb062117 (patch) | |
| tree | 1689da48be78e53d81c051f6a20e6b4737d5d684 | |
| parent | 76cf07f7b64eba74d0c1d74351a14c3ef0512664 (diff) | |
qcacld-2.0: Add gettime of PTP for NON-QC platform
Implement NON-QC platform TSF and TSF PLUS.
Implement gettime of PTP.
Implement TSF PLUS for SAP/GO.
Change-Id: Id4f41a94256a8f035ae408c168c246569185c534
CRs-Fixed: 2356609
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_cfg.h | 10 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 8 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_tsf.h | 17 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 7 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 11 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 7 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_tsf.c | 318 | ||||
| -rw-r--r-- | Kbuild | 9 |
8 files changed, 370 insertions, 17 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index e9961b2decaa..98f2f2be228a 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -4153,6 +4153,13 @@ FG_BTC_BT_INTERVAL_PAGE_P2P_STA_DEFAULT #define TSF_GPIO_PIN_INVALID (255) #define CFG_SET_TSF_GPIO_PIN_DEFAULT (TSF_GPIO_PIN_INVALID) +#ifdef WLAN_FEATURE_TSF +/* GPIO pin to toogle when capture tsf in host side */ +#define CFG_SET_TSF_GPIO_PIN_HOST_NAME "gtsf_gpio_pin_host" +#define CFG_SET_TSF_GPIO_PIN_HOST_MIN (0) +#define CFG_SET_TSF_GPIO_PIN_HOST_MAX (254) +#define CFG_SET_TSF_GPIO_PIN_HOST_DEFAULT (45) + #ifdef WLAN_FEATURE_TSF_PLUS /* PTP options */ #define CFG_SET_TSF_PTP_OPT_NAME "gtsf_ptp_options" @@ -4164,6 +4171,7 @@ FG_BTC_BT_INTERVAL_PAGE_P2P_STA_DEFAULT #define CFG_SET_TSF_DBG_FS (0x8) #define CFG_SET_TSF_PTP_OPT_DEFAULT (0xf) #endif +#endif #define CFG_MULTICAST_HOST_FW_MSGS "gMulticastHostFwMsgs" #define CFG_MULTICAST_HOST_FW_MSGS_MIN (0) @@ -6257,7 +6265,7 @@ struct hdd_config { uint8_t inform_bss_rssi_raw; #ifdef WLAN_FEATURE_TSF uint32_t tsf_gpio_pin; - + uint32_t tsf_gpio_pin_host; #ifdef WLAN_FEATURE_TSF_PLUS uint8_t tsf_ptp_options; #endif /* WLAN_FEATURE_TSF_PLUS */ diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index de6e6cd77ff1..15b1975fecaa 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -51,6 +51,10 @@ #include <wlan_hdd_wmm.h> #include <wlan_hdd_cfg.h> #include <linux/spinlock.h> +#ifdef WLAN_FEATURE_TSF_PTP +#include <linux/ptp_classify.h> +#include <linux/ptp_clock_kernel.h> +#endif #include <wlan_hdd_ftm.h> #ifdef FEATURE_WLAN_TDLS #include "wlan_hdd_tdls.h" @@ -2138,6 +2142,10 @@ struct hdd_context_s /* the context that is capturing tsf */ hdd_adapter_t *cap_tsf_context; #endif +#ifdef WLAN_FEATURE_TSF_PTP + struct ptp_clock_info ptp_cinfo; + struct ptp_clock *ptp_clock; +#endif /* flag to show whether moniotr mode is enabled */ bool is_mon_enable; v_MACADDR_t hw_macaddr; diff --git a/CORE/HDD/inc/wlan_hdd_tsf.h b/CORE/HDD/inc/wlan_hdd_tsf.h index 6cabf3b90245..a1a329b87fc4 100644 --- a/CORE/HDD/inc/wlan_hdd_tsf.h +++ b/CORE/HDD/inc/wlan_hdd_tsf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015,2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015,2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -91,6 +91,15 @@ int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len); * Return: Describe the execute result of this routine */ int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len); + +/** + * wlan_get_ts_info() - return ts info to uplayer + * @dev: pointer to net_device + * @info: pointer to ethtool_ts_info + * + * Return: Describe the execute result of this routine + */ +int wlan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info); #else static inline void wlan_hdd_tsf_init(hdd_context_t *hdd_ctx) @@ -112,6 +121,12 @@ hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) { return -ENOTSUPP; } + +static inline int +wlan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) +{ + return -ENOTSUPP; +} #endif #if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF) diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index ec651ed6804a..6fc2a9472f0f 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -4564,6 +4564,13 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_INFORM_BSS_RSSI_RAW_MIN, CFG_INFORM_BSS_RSSI_RAW_MAX), #ifdef WLAN_FEATURE_TSF + REG_VARIABLE(CFG_SET_TSF_GPIO_PIN_HOST_NAME, WLAN_PARAM_Integer, + hdd_config_t, tsf_gpio_pin_host, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SET_TSF_GPIO_PIN_HOST_DEFAULT, + CFG_SET_TSF_GPIO_PIN_HOST_MIN, + CFG_SET_TSF_GPIO_PIN_HOST_MAX), + REG_VARIABLE(CFG_SET_TSF_GPIO_PIN_NAME, WLAN_PARAM_Integer, hdd_config_t, tsf_gpio_pin, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 59c720332334..eba0907fd06a 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -60,6 +60,7 @@ #include <vos_api.h> #include <vos_sched.h> #include <linux/etherdevice.h> +#include <linux/ethtool.h> #include <wlan_hdd_includes.h> #include <qc_sap_ioctl.h> #include <wlan_hdd_hostapd.h> @@ -2326,6 +2327,7 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa pHddApCtx->operatingChannel); pHostapdState->bssState = BSS_START; + hdd_start_tsf_sync(pHostapdAdapter); /* Set default key index */ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, @@ -3146,7 +3148,7 @@ stopbss : /* Change the BSS state now since, as we are shutting things down, * we don't want interfaces to become re-enabled */ pHostapdState->bssState = BSS_STOP; - + hdd_stop_tsf_sync(pHostapdAdapter); if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) { if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state) @@ -7692,6 +7694,10 @@ const struct iw_handler_def hostapd_handler_def = { .get_wireless_stats = NULL, }; +static const struct ethtool_ops wlan_hostapd_ethtool_ops = { + .get_ts_info = wlan_get_ts_info, +}; + struct net_device_ops net_ops_struct = { .ndo_open = hdd_hostapd_open, .ndo_stop = hdd_hostapd_stop, @@ -7712,7 +7718,8 @@ static int hdd_set_hostapd(hdd_adapter_t *pAdapter) void hdd_set_ap_ops( struct net_device *pWlanHostapdDev ) { - pWlanHostapdDev->netdev_ops = &net_ops_struct; + pWlanHostapdDev->netdev_ops = &net_ops_struct; + pWlanHostapdDev->ethtool_ops = &wlan_hostapd_ethtool_ops; } VOS_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter, bool reinit) diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index c7dae7df518a..c012af8e15a3 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -93,6 +93,7 @@ #include <linux/ctype.h> #include <linux/compat.h> #include <linux/pm_qos.h> +#include <linux/ethtool.h> #ifdef MSM_PLATFORM #ifdef CONFIG_CNSS #include <soc/qcom/subsystem_restart.h> @@ -10851,6 +10852,10 @@ static v_U16_t hdd_select_queue(struct net_device *dev, return hdd_wmm_select_queue(dev, skb); } +static const struct ethtool_ops wlan_ethtool_ops = { + .get_ts_info = wlan_get_ts_info, +}; + static struct net_device_ops wlan_drv_ops = { .ndo_open = hdd_open, .ndo_stop = hdd_stop, @@ -10889,6 +10894,7 @@ void hdd_set_station_ops( struct net_device *pWlanDev ) pWlanDev->netdev_ops = &wlan_mon_drv_ops; else pWlanDev->netdev_ops = &wlan_drv_ops; + pWlanDev->ethtool_ops = &wlan_ethtool_ops; } void hdd_set_monitor_ops(struct net_device *pwlan_dev) @@ -13308,7 +13314,6 @@ void hdd_connect_result(struct net_device *dev, { hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev); struct cfg80211_bss *bss = NULL; - if (WLAN_STATUS_SUCCESS == status) { struct ieee80211_channel *chan; int freq; diff --git a/CORE/HDD/src/wlan_hdd_tsf.c b/CORE/HDD/src/wlan_hdd_tsf.c index 31d902fbb422..6ad7f14af2c6 100644 --- a/CORE/HDD/src/wlan_hdd_tsf.c +++ b/CORE/HDD/src/wlan_hdd_tsf.c @@ -33,7 +33,10 @@ #include "wlan_hdd_tsf.h" #include "wma_api.h" #include <linux/errqueue.h> - +#if defined(CONFIG_NON_QC_PLATFORM) +#include <linux/gpio.h> +int irq_tsf = -1; +#endif /** * enum hdd_tsf_op_result - result of tsf operation * @@ -207,7 +210,6 @@ static enum hdd_tsf_op_result hdd_indicate_tsf_internal( { int ret; hdd_context_t *hddctx; - if (adapter == NULL || buf == NULL) { hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid pointer")); @@ -280,13 +282,21 @@ static enum hdd_tsf_op_result hdd_indicate_tsf_internal( * to distinguish 32-bit overflow case, this inverval should: * equal or less than (1/2 * OVERFLOW_INDICATOR32 us) */ +#if defined(CONFIG_NON_QC_PLATFORM) +#define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 2 +#else #define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 10 +#endif #define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100 #define OVERFLOW_INDICATOR32 (((int64_t)0x1) << 32) #define MAX_UINT64 ((uint64_t)0xffffffffffffffff) #define MASK_UINT32 0xffffffff #define CAP_TSF_TIMER_FIX_SEC 1 +#if defined(CONFIG_NON_QC_PLATFORM) +#define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 1 +#else #define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 9 +#endif /** * TS_STATUS - timestamp status @@ -414,9 +424,13 @@ enum hdd_ts_status hdd_check_timestamp_status( /* the deviation should be smaller than a threshold */ if (delta_ns > MAX_ALLOWED_DEVIATION_NS) { hddLog(VOS_TRACE_LEVEL_ERROR, - FL("Invalid timestamps - delta: %llu ns"), delta_ns); + FL("Invalid timestamps - delta: %llu ns"), delta_ns); return HDD_TS_STATUS_INVALID; + } else { + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("valid timestamps - delta: %llu ns"), delta_ns); } + return HDD_TS_STATUS_READY; } @@ -641,10 +655,12 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, struct device_attribute *attr, char *buf) { hdd_station_ctx_t *hdd_sta_ctx; + hdd_ap_ctx_t *hdd_ap_ctx; hdd_adapter_t *adapter; hdd_context_t *hdd_ctx; ssize_t size; uint64_t host_time, target_time; + uint8_t *bssid; struct net_device *net_dev = container_of(dev, struct net_device, dev); @@ -656,22 +672,32 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "TSF sync is not initialized\n"); - hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - if (eConnectionState_Associated != hdd_sta_ctx->conn_info.connState) - return scnprintf(buf, PAGE_SIZE, "NOT connected\n"); - hdd_ctx = WLAN_HDD_GET_CTX(adapter); if (!hdd_ctx) return scnprintf(buf, PAGE_SIZE, "Invalid HDD context\n"); + if (adapter->device_mode == WLAN_HDD_INFRA_STATION || + adapter->device_mode == WLAN_HDD_P2P_CLIENT) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (eConnectionState_Associated != + hdd_sta_ctx->conn_info.connState) + return scnprintf(buf, PAGE_SIZE, "NOT connected\n"); + bssid = hdd_sta_ctx->conn_info.bssId; + } else if (adapter->device_mode == WLAN_HDD_SOFTAP || + adapter->device_mode == WLAN_HDD_P2P_GO) { + hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); + bssid = hdd_ap_ctx->sapConfig.self_macaddr.bytes; + } else { + return scnprintf(buf, PAGE_SIZE, "Invalid interface\n"); + } + host_time = hdd_get_monotonic_host_time(hdd_ctx); if (hdd_get_targettime_from_hosttime(adapter, host_time, &target_time)) size = scnprintf(buf, PAGE_SIZE, "Invalid timestamp\n"); else size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n", - buf, target_time, host_time, - hdd_sta_ctx->conn_info.bssId); + buf, target_time, host_time, bssid); return size; } @@ -711,6 +737,10 @@ static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg) if (!arg) return IRQ_NONE; +#if defined(CONFIG_NON_QC_PLATFORM) + if (irq != irq_tsf) + return IRQ_NONE; +#endif hdd_ctx = (hdd_context_t *)arg; host_time = hdd_get_monotonic_host_time(hdd_ctx); @@ -1046,6 +1076,99 @@ static inline int __hdd_indicate_tsf(hdd_adapter_t *adapter, return 0; } +#if defined(CONFIG_NON_QC_PLATFORM) +/** + * wlan_hdd_tsf_plus_init() - tsf plus init + * @hdd_ctx: pointer to the hdd_contex. + * + * Return: Describe the execute result of this routine + */ +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx) +{ + int ret; + + if (!HDD_TSF_IS_PTP_ENABLED(hdd_ctx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("To enable TSF_PLUS, set gtsf_ptp_options in ini")); + goto fail; + } + + if (hdd_ctx->cfg_ini->tsf_gpio_pin_host == TSF_GPIO_PIN_INVALID) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("gpio host pin is invalid %d"), + hdd_ctx->cfg_ini->tsf_gpio_pin_host); + goto fail; + } + + ret = gpio_request(hdd_ctx->cfg_ini->tsf_gpio_pin_host, "wlan_tsf"); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("%s: fail to request irq, gpio %d\n"), __func__, + hdd_ctx->cfg_ini->tsf_gpio_pin_host); + goto fail; + } + + ret = gpio_direction_input(hdd_ctx->cfg_ini->tsf_gpio_pin_host); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to set gpio dir %d\n"), ret); + goto fail_free_gpio; + } + + irq_tsf = gpio_to_irq(hdd_ctx->cfg_ini->tsf_gpio_pin_host); + if (irq_tsf < 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("%s: fail to get irq: %d\n"), __func__, irq_tsf); + goto fail_free_gpio; + } + + ret = request_irq(irq_tsf, hdd_tsf_captured_irq_handler, + IRQF_SHARED | IRQF_TRIGGER_RISING, "wlan_tsf", + (void *)hdd_ctx); + + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to register irq handler: %d"), ret); + goto fail_free_gpio; + } + + if (HDD_TSF_IS_TX_SET(hdd_ctx)) + ol_register_timestamp_callback(hdd_tx_timestamp); + + return HDD_TSF_OP_SUCC; + +fail_free_gpio: + gpio_free(hdd_ctx->cfg_ini->tsf_gpio_pin_host); +fail: + irq_tsf = -1; + return HDD_TSF_OP_FAIL; +} + +/** + * wlan_hdd_tsf_plus_deinit() - tsf plus deinit + * @hdd_ctx: pointer to the hdd_contex. + * + * Return: Describe the execute result of this routine + */ +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(hdd_context_t *hdd_ctx) +{ + if (!HDD_TSF_IS_PTP_ENABLED(hdd_ctx)) + return HDD_TSF_OP_SUCC; + + if (HDD_TSF_IS_TX_SET(hdd_ctx)) + ol_deregister_timestamp_callback(); + + if (irq_tsf >= 0) { + free_irq(irq_tsf, (void *)hdd_ctx); + irq_tsf = -1; + gpio_free(hdd_ctx->cfg_ini->tsf_gpio_pin_host); + } + + return HDD_TSF_OP_SUCC; +} +#else static inline enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx) { @@ -1056,7 +1179,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx) FL("To enable TSF_PLUS, set gtsf_ptp_options in ini")); return HDD_TSF_OP_FAIL; } - ret = cnss_common_register_tsf_captured_handler( hdd_ctx->parent_dev, hdd_tsf_captured_irq_handler, @@ -1066,7 +1188,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx) FL("Failed to register irq handler: %d"), ret); return HDD_TSF_OP_FAIL; } - if (HDD_TSF_IS_TX_SET(hdd_ctx)) ol_register_timestamp_callback(hdd_tx_timestamp); @@ -1096,6 +1217,7 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(hdd_context_t *hdd_ctx) return HDD_TSF_OP_SUCC; } +#endif void hdd_tsf_notify_wlan_state_change(hdd_adapter_t *adapter, eConnectionState old_state, @@ -1191,6 +1313,176 @@ int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) return __hdd_indicate_tsf(adapter, buf, len); } +#ifdef WLAN_FEATURE_TSF_PTP +int wlan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) + +{ + hdd_adapter_t *adapter = netdev_priv(dev); + hdd_context_t *hdd_ctx; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid hdd context")); + return -EINVAL; + } + + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + if (hdd_ctx->ptp_clock) + info->phc_index = ptp_clock_index(hdd_ctx->ptp_clock); + else + info->phc_index = -1; + + return 0; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) +/** + * wlan_ptp_gettime() - return fw ts info to uplayer + * @ptp: pointer to ptp_clock_info. + * @ts: pointer to timespec. + * + * Return: Describe the execute result of this routine + */ +static int wlan_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) +{ + uint64_t host_time, target_time = 0; + VosContextType *pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t *adapter = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, + pVosContext); + if (!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid hdd context")); + return -EINVAL; + } + + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO); + if (!adapter) { + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT); + if (!adapter) { + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (!adapter) + adapter = hdd_get_adapter(pHddCtx, + WLAN_HDD_INFRA_STATION); + } + } + + host_time = hdd_get_monotonic_host_time(pHddCtx); + if (hdd_get_targettime_from_hosttime(adapter, host_time, + &target_time)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("get invalid target timestamp")); + return -EINVAL; + } else { + *ts = ns_to_timespec(target_time * NSEC_PER_USEC); + } + + return 0; +} + +/** + * wlan_hdd_phc_init() - phc init + * @hdd_ctx: pointer to the hdd_contex. + * + * Return: NULL + */ +static void wlan_hdd_phc_init(hdd_context_t *hdd_ctx) +{ + hdd_ctx->ptp_cinfo.gettime = wlan_ptp_gettime; + + hdd_ctx->ptp_clock = ptp_clock_register(&hdd_ctx->ptp_cinfo, + hdd_ctx->parent_dev); +} + +/** + * wlan_hdd_phc_deinit() - phc deinit + * @hdd_ctx: pointer to the hdd_contex. + * + * Return: NULL + */ +static void wlan_hdd_phc_deinit(hdd_context_t *hdd_ctx) +{ + hdd_ctx->ptp_cinfo.gettime = NULL; + + if (hdd_ctx->ptp_clock) { + ptp_clock_unregister(hdd_ctx->ptp_clock); + hdd_ctx->ptp_clock = NULL; + } +} +#else +static int wlan_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) +{ + uint64_t host_time, target_time = 0; + VosContextType *pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t *adapter = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, + pVosContext); + if (!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid hdd context")); + return -EINVAL; + } + + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO); + if (!adapter) { + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT); + if (!adapter) { + adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (!adapter) + adapter = hdd_get_adapter(pHddCtx, + WLAN_HDD_INFRA_STATION); + } + } + + host_time = hdd_get_monotonic_host_time(pHddCtx); + if (hdd_get_targettime_from_hosttime(adapter, host_time, + &target_time)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("get invalid target timestamp")); + return -EINVAL; + } else { + *ts = ns_to_timespec64(target_time * NSEC_PER_USEC); + } + + return 0; +} + +static void wlan_hdd_phc_init(hdd_context_t *hdd_ctx) +{ + hdd_ctx->ptp_cinfo.gettime64 = wlan_ptp_gettime; + hdd_ctx->ptp_clock = ptp_clock_register(&hdd_ctx->ptp_cinfo, + hdd_ctx->parent_dev); +} + +static void wlan_hdd_phc_deinit(hdd_context_t *hdd_ctx) +{ + hdd_ctx->ptp_cinfo.gettime64 = NULL; + + if (hdd_ctx->ptp_clock) { + ptp_clock_unregister(hdd_ctx->ptp_clock); + hdd_ctx->ptp_clock = NULL; + } +} +#endif +#else +int wlan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) +{ + return -ENOTSUPP; +} + +static void wlan_hdd_phc_init(hdd_context_t *hdd_ctx) +{ +} + +static void wlan_hdd_phc_deinit(hdd_context_t *hdd_ctx) +{ +} +#endif + /** * hdd_get_tsf_cb() - handle tsf callback * @@ -1210,7 +1502,6 @@ static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) hdd_adapter_t *adapter; int status; VOS_TIMER_STATE capture_req_timer_status; - if (pcb_cxt == NULL || ptsf == NULL) { hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); @@ -1298,6 +1589,8 @@ void wlan_hdd_tsf_init(hdd_context_t *hdd_ctx) if (wlan_hdd_tsf_plus_init(hdd_ctx) != HDD_TSF_OP_SUCC) goto fail; + wlan_hdd_phc_init(hdd_ctx); + return; fail: @@ -1325,6 +1618,7 @@ void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx) hal_status); } + wlan_hdd_phc_deinit(hdd_ctx); wlan_hdd_tsf_plus_deinit(hdd_ctx); vos_status = hdd_get_front_adapter(hdd_ctx, &adapternode_ptr); @@ -477,6 +477,11 @@ ifeq ($(CONFIG_QCOM_TDLS),y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o endif +ifeq ($(CONFIG_NETWORK_PHY_TIMESTAMPING), y) +CONFIG_WLAN_SYNC_TSF_PLUS := y +CONFIG_WLAN_SYNC_TSF_PTP := y +endif + ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y) CONFIG_WLAN_SYNC_TSF := y endif @@ -1618,6 +1623,10 @@ ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y) CDEFINES += -DWLAN_FEATURE_TSF_PLUS endif +ifeq ($(CONFIG_WLAN_SYNC_TSF_PTP), y) +CDEFINES += -DWLAN_FEATURE_TSF_PTP +endif + # Enable target dump for non-qualcomm platform ifeq ($(CONFIG_NON_QC_PLATFORM), y) CDEFINES += -DCONFIG_NON_QC_PLATFORM |
