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