/* * 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. *
*/
#define MLX4_EN_WRAP_AROUND_SEC 10UL /* 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 (MLX4_EN_WRAP_AROUND_SEC * HZ / 2)
/** * 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.
**/ staticint mlx4_en_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
u32 mult; unsignedlong flags; struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
ptp_clock_info);
mult = (u32)adjust_by_scaled_ppm(mdev->nominal_c_mult, scaled_ppm);
/** * 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.
**/ staticint mlx4_en_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{ struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
ptp_clock_info); unsignedlong flags;
u64 ns;
/** * 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.
**/ staticint mlx4_en_phc_settime(struct ptp_clock_info *ptp, conststruct timespec64 *ts)
{ struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
ptp_clock_info);
u64 ns = timespec64_to_ns(ts); unsignedlong flags;
/** * 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.
**/ staticint mlx4_en_phc_enable(struct ptp_clock_info __always_unused *ptp, struct ptp_clock_request __always_unused *request, int __always_unused on)
{ return -EOPNOTSUPP;
}
/* 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)
{
u32 freq_khz = freq * 1000;
u64 max_val_cycles = freq_khz * 1000ULL * MLX4_EN_WRAP_AROUND_SEC;
u64 max_val_cycles_rounded = 1ULL << fls64(max_val_cycles - 1); /* calculate max possible multiplier in order to fit in 64bit */
u64 max_mul = div64_u64(ULLONG_MAX, max_val_cycles_rounded);
/* This comes from the reverse of clocksource_khz2mult */ return ilog2(div_u64(max_mul * freq_khz, 1000000));
}
/* mlx4_en_init_timestamp is called for each netdev. * mdev->ptp_clock is common for all ports, skip initialization if * was done for other port.
*/ if (mdev->ptp_clock) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.