blob: a320916cced3adb4fb855cea81e8832b820d017c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
// SPDX-License-Identifier: GPL-2.0-only
/* Aquantia Corporation Network Driver
* Copyright (C) 2014-2019 Aquantia Corporation. All rights reserved
*/
/* File aq_ptp.c:
* Definition of functions for Linux PTP support.
*/
#include <linux/ptp_clock_kernel.h>
#include <linux/clocksource.h>
#include "aq_nic.h"
#include "aq_ptp.h"
struct aq_ptp_s {
struct aq_nic_s *aq_nic;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_info;
};
static struct ptp_clock_info aq_ptp_clock = {
.owner = THIS_MODULE,
.name = "atlantic ptp",
.n_ext_ts = 0,
.pps = 0,
.n_per_out = 0,
.n_pins = 0,
.pin_config = NULL,
};
int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
{
struct hw_atl_utils_mbox mbox;
struct aq_ptp_s *aq_ptp;
int err = 0;
hw_atl_utils_mpi_read_stats(aq_nic->aq_hw, &mbox);
if (!(mbox.info.caps_ex & BIT(CAPS_EX_PHY_PTP_EN))) {
aq_nic->aq_ptp = NULL;
return 0;
}
aq_ptp = kzalloc(sizeof(*aq_ptp), GFP_KERNEL);
if (!aq_ptp) {
err = -ENOMEM;
goto err_exit;
}
aq_ptp->aq_nic = aq_nic;
aq_ptp->ptp_info = aq_ptp_clock;
aq_nic->aq_ptp = aq_ptp;
return 0;
err_exit:
kfree(aq_ptp);
aq_nic->aq_ptp = NULL;
return err;
}
void aq_ptp_unregister(struct aq_nic_s *aq_nic)
{
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
if (!aq_ptp)
return;
ptp_clock_unregister(aq_ptp->ptp_clock);
}
void aq_ptp_free(struct aq_nic_s *aq_nic)
{
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
if (!aq_ptp)
return;
kfree(aq_ptp);
aq_nic->aq_ptp = NULL;
}
|