/* * Copyright (c) 2012 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include <linux/mlx4/device.h> #include <linux/clocksource.h> #include "mlx4_en.h" /* mlx4_en_read_clock - read raw cycle counter (to be used by time counter) */ static u64 mlx4_en_read_clock(const struct cyclecounter *tc) { … } u64 mlx4_en_get_cqe_ts(struct mlx4_cqe *cqe) { … } u64 mlx4_en_get_hwtstamp(struct mlx4_en_dev *mdev, u64 timestamp) { … } void mlx4_en_fill_hwtstamps(struct mlx4_en_dev *mdev, struct skb_shared_hwtstamps *hwts, u64 timestamp) { … } /** * mlx4_en_remove_timestamp - disable PTP device * @mdev: board private structure * * Stop the PTP support. **/ void mlx4_en_remove_timestamp(struct mlx4_en_dev *mdev) { … } #define MLX4_EN_WRAP_AROUND_SEC … /* By scheduling the overflow check every 5 seconds, we have a reasonably * good chance we won't miss a wrap around. * TODO: Use a timer instead of a work queue to increase the guarantee. */ #define MLX4_EN_OVERFLOW_PERIOD … void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev) { … } /** * mlx4_en_phc_adjfine - adjust the frequency of the hardware clock * @ptp: ptp clock structure * @scaled_ppm: Desired frequency change in scaled parts per million * * Adjust the frequency of the PHC cycle counter by the indicated scaled_ppm * from the base frequency. * * Scaled parts per million is ppm with a 16-bit binary fractional field. **/ static int mlx4_en_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) { … } /** * mlx4_en_phc_adjtime - Shift the time of the hardware clock * @ptp: ptp clock structure * @delta: Desired change in nanoseconds * * Adjust the timer by resetting the timecounter structure. **/ static int mlx4_en_phc_adjtime(struct ptp_clock_info *ptp, s64 delta) { … } /** * mlx4_en_phc_gettime - Reads the current time from the hardware clock * @ptp: ptp clock structure * @ts: timespec structure to hold the current time value * * Read the timecounter and return the correct value in ns after converting * it into a struct timespec. **/ static int mlx4_en_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { … } /** * mlx4_en_phc_settime - Set the current time on the hardware clock * @ptp: ptp clock structure * @ts: timespec containing the new time for the cycle counter * * Reset the timecounter to use a new base value instead of the kernel * wall timer value. **/ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts) { … } /** * mlx4_en_phc_enable - enable or disable an ancillary feature * @ptp: ptp clock structure * @request: Desired resource to enable or disable * @on: Caller passes one to enable or zero to disable * * Enable (or disable) ancillary features of the PHC subsystem. * Currently, no ancillary features are supported. **/ static int mlx4_en_phc_enable(struct ptp_clock_info __always_unused *ptp, struct ptp_clock_request __always_unused *request, int __always_unused on) { … } static const struct ptp_clock_info mlx4_en_ptp_clock_info = …; /* This function calculates the max shift that enables the user range * of MLX4_EN_WRAP_AROUND_SEC values in the cycles register. */ static u32 freq_to_shift(u16 freq) { … } void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) { … }