drivers/net/ethernet/mellanox/mlx4/en_clock.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx4/en_clock.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/mellanox/mlx4/en_clock.c- Extension
.c- Size
- 9054 bytes
- Lines
- 302
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/mlx4/device.hlinux/clocksource.hmlx4_en.h
Detected Declarations
function Copyrightfunction mlx4_en_get_cqe_tsfunction mlx4_en_get_hwtstampfunction mlx4_en_fill_hwtstampsfunction mlx4_en_remove_timestampfunction mlx4_en_ptp_overflow_checkfunction mlx4_en_phc_adjfinefunction mlx4_en_phc_adjtimefunction mlx4_en_phc_gettimefunction mlx4_en_phc_settimefunction Enablefunction freq_to_shiftfunction mlx4_en_init_timestamp
Annotated Snippet
#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(struct cyclecounter *tc)
{
struct mlx4_en_dev *mdev =
container_of(tc, struct mlx4_en_dev, cycles);
struct mlx4_dev *dev = mdev->dev;
return mlx4_read_clock(dev) & tc->mask;
}
u64 mlx4_en_get_cqe_ts(struct mlx4_cqe *cqe)
{
u64 hi, lo;
struct mlx4_ts_cqe *ts_cqe = (struct mlx4_ts_cqe *)cqe;
lo = (u64)be16_to_cpu(ts_cqe->timestamp_lo);
hi = ((u64)be32_to_cpu(ts_cqe->timestamp_hi) + !lo) << 16;
return hi | lo;
}
u64 mlx4_en_get_hwtstamp(struct mlx4_en_dev *mdev, u64 timestamp)
{
unsigned int seq;
u64 nsec;
do {
seq = read_seqbegin(&mdev->clock_lock);
nsec = timecounter_cyc2time(&mdev->clock, timestamp);
} while (read_seqretry(&mdev->clock_lock, seq));
return ns_to_ktime(nsec);
}
void mlx4_en_fill_hwtstamps(struct mlx4_en_dev *mdev,
struct skb_shared_hwtstamps *hwts,
u64 timestamp)
{
memset(hwts, 0, sizeof(struct skb_shared_hwtstamps));
hwts->hwtstamp = mlx4_en_get_hwtstamp(mdev, 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)
{
if (mdev->ptp_clock) {
ptp_clock_unregister(mdev->ptp_clock);
mdev->ptp_clock = NULL;
mlx4_info(mdev, "removed PHC\n");
}
}
#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)
void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev)
{
bool timeout = time_is_before_jiffies(mdev->last_overflow_check +
MLX4_EN_OVERFLOW_PERIOD);
unsigned long flags;
if (timeout) {
write_seqlock_irqsave(&mdev->clock_lock, flags);
timecounter_read(&mdev->clock);
write_sequnlock_irqrestore(&mdev->clock_lock, flags);
mdev->last_overflow_check = jiffies;
}
}
/**
* 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
Annotation
- Immediate include surface: `linux/mlx4/device.h`, `linux/clocksource.h`, `mlx4_en.h`.
- Detected declarations: `function Copyright`, `function mlx4_en_get_cqe_ts`, `function mlx4_en_get_hwtstamp`, `function mlx4_en_fill_hwtstamps`, `function mlx4_en_remove_timestamp`, `function mlx4_en_ptp_overflow_check`, `function mlx4_en_phc_adjfine`, `function mlx4_en_phc_adjtime`, `function mlx4_en_phc_gettime`, `function mlx4_en_phc_settime`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.