root/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xgbe_cc_read
  2. xgbe_adjfreq
  3. xgbe_adjtime
  4. xgbe_gettime
  5. xgbe_settime
  6. xgbe_enable
  7. xgbe_ptp_register
  8. xgbe_ptp_unregister

   1 /*
   2  * AMD 10Gb Ethernet driver
   3  *
   4  * This file is available to you under your choice of the following two
   5  * licenses:
   6  *
   7  * License 1: GPLv2
   8  *
   9  * Copyright (c) 2014 Advanced Micro Devices, Inc.
  10  *
  11  * This file is free software; you may copy, redistribute and/or modify
  12  * it under the terms of the GNU General Public License as published by
  13  * the Free Software Foundation, either version 2 of the License, or (at
  14  * your option) any later version.
  15  *
  16  * This file is distributed in the hope that it will be useful, but
  17  * WITHOUT ANY WARRANTY; without even the implied warranty of
  18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19  * General Public License for more details.
  20  *
  21  * You should have received a copy of the GNU General Public License
  22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23  *
  24  * This file incorporates work covered by the following copyright and
  25  * permission notice:
  26  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  27  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  28  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  29  *     and you.
  30  *
  31  *     The Software IS NOT an item of Licensed Software or Licensed Product
  32  *     under any End User Software License Agreement or Agreement for Licensed
  33  *     Product with Synopsys or any supplement thereto.  Permission is hereby
  34  *     granted, free of charge, to any person obtaining a copy of this software
  35  *     annotated with this license and the Software, to deal in the Software
  36  *     without restriction, including without limitation the rights to use,
  37  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  38  *     of the Software, and to permit persons to whom the Software is furnished
  39  *     to do so, subject to the following conditions:
  40  *
  41  *     The above copyright notice and this permission notice shall be included
  42  *     in all copies or substantial portions of the Software.
  43  *
  44  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  45  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  46  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  47  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  48  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  49  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  50  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  51  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  52  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  54  *     THE POSSIBILITY OF SUCH DAMAGE.
  55  *
  56  *
  57  * License 2: Modified BSD
  58  *
  59  * Copyright (c) 2014 Advanced Micro Devices, Inc.
  60  * All rights reserved.
  61  *
  62  * Redistribution and use in source and binary forms, with or without
  63  * modification, are permitted provided that the following conditions are met:
  64  *     * Redistributions of source code must retain the above copyright
  65  *       notice, this list of conditions and the following disclaimer.
  66  *     * Redistributions in binary form must reproduce the above copyright
  67  *       notice, this list of conditions and the following disclaimer in the
  68  *       documentation and/or other materials provided with the distribution.
  69  *     * Neither the name of Advanced Micro Devices, Inc. nor the
  70  *       names of its contributors may be used to endorse or promote products
  71  *       derived from this software without specific prior written permission.
  72  *
  73  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  74  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  75  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  76  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  77  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  80  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  81  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  82  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  83  *
  84  * This file incorporates work covered by the following copyright and
  85  * permission notice:
  86  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  87  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  88  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  89  *     and you.
  90  *
  91  *     The Software IS NOT an item of Licensed Software or Licensed Product
  92  *     under any End User Software License Agreement or Agreement for Licensed
  93  *     Product with Synopsys or any supplement thereto.  Permission is hereby
  94  *     granted, free of charge, to any person obtaining a copy of this software
  95  *     annotated with this license and the Software, to deal in the Software
  96  *     without restriction, including without limitation the rights to use,
  97  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  98  *     of the Software, and to permit persons to whom the Software is furnished
  99  *     to do so, subject to the following conditions:
 100  *
 101  *     The above copyright notice and this permission notice shall be included
 102  *     in all copies or substantial portions of the Software.
 103  *
 104  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 105  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 106  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 107  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 108  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 109  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 110  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 111  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 112  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 113  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 114  *     THE POSSIBILITY OF SUCH DAMAGE.
 115  */
 116 
 117 #include <linux/clk.h>
 118 #include <linux/clocksource.h>
 119 #include <linux/ptp_clock_kernel.h>
 120 #include <linux/net_tstamp.h>
 121 
 122 #include "xgbe.h"
 123 #include "xgbe-common.h"
 124 
 125 static u64 xgbe_cc_read(const struct cyclecounter *cc)
 126 {
 127         struct xgbe_prv_data *pdata = container_of(cc,
 128                                                    struct xgbe_prv_data,
 129                                                    tstamp_cc);
 130         u64 nsec;
 131 
 132         nsec = pdata->hw_if.get_tstamp_time(pdata);
 133 
 134         return nsec;
 135 }
 136 
 137 static int xgbe_adjfreq(struct ptp_clock_info *info, s32 delta)
 138 {
 139         struct xgbe_prv_data *pdata = container_of(info,
 140                                                    struct xgbe_prv_data,
 141                                                    ptp_clock_info);
 142         unsigned long flags;
 143         u64 adjust;
 144         u32 addend, diff;
 145         unsigned int neg_adjust = 0;
 146 
 147         if (delta < 0) {
 148                 neg_adjust = 1;
 149                 delta = -delta;
 150         }
 151 
 152         adjust = pdata->tstamp_addend;
 153         adjust *= delta;
 154         diff = div_u64(adjust, 1000000000UL);
 155 
 156         addend = (neg_adjust) ? pdata->tstamp_addend - diff :
 157                                 pdata->tstamp_addend + diff;
 158 
 159         spin_lock_irqsave(&pdata->tstamp_lock, flags);
 160 
 161         pdata->hw_if.update_tstamp_addend(pdata, addend);
 162 
 163         spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
 164 
 165         return 0;
 166 }
 167 
 168 static int xgbe_adjtime(struct ptp_clock_info *info, s64 delta)
 169 {
 170         struct xgbe_prv_data *pdata = container_of(info,
 171                                                    struct xgbe_prv_data,
 172                                                    ptp_clock_info);
 173         unsigned long flags;
 174 
 175         spin_lock_irqsave(&pdata->tstamp_lock, flags);
 176         timecounter_adjtime(&pdata->tstamp_tc, delta);
 177         spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
 178 
 179         return 0;
 180 }
 181 
 182 static int xgbe_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
 183 {
 184         struct xgbe_prv_data *pdata = container_of(info,
 185                                                    struct xgbe_prv_data,
 186                                                    ptp_clock_info);
 187         unsigned long flags;
 188         u64 nsec;
 189 
 190         spin_lock_irqsave(&pdata->tstamp_lock, flags);
 191 
 192         nsec = timecounter_read(&pdata->tstamp_tc);
 193 
 194         spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
 195 
 196         *ts = ns_to_timespec64(nsec);
 197 
 198         return 0;
 199 }
 200 
 201 static int xgbe_settime(struct ptp_clock_info *info,
 202                         const struct timespec64 *ts)
 203 {
 204         struct xgbe_prv_data *pdata = container_of(info,
 205                                                    struct xgbe_prv_data,
 206                                                    ptp_clock_info);
 207         unsigned long flags;
 208         u64 nsec;
 209 
 210         nsec = timespec64_to_ns(ts);
 211 
 212         spin_lock_irqsave(&pdata->tstamp_lock, flags);
 213 
 214         timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc, nsec);
 215 
 216         spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
 217 
 218         return 0;
 219 }
 220 
 221 static int xgbe_enable(struct ptp_clock_info *info,
 222                        struct ptp_clock_request *request, int on)
 223 {
 224         return -EOPNOTSUPP;
 225 }
 226 
 227 void xgbe_ptp_register(struct xgbe_prv_data *pdata)
 228 {
 229         struct ptp_clock_info *info = &pdata->ptp_clock_info;
 230         struct ptp_clock *clock;
 231         struct cyclecounter *cc = &pdata->tstamp_cc;
 232         u64 dividend;
 233 
 234         snprintf(info->name, sizeof(info->name), "%s",
 235                  netdev_name(pdata->netdev));
 236         info->owner = THIS_MODULE;
 237         info->max_adj = pdata->ptpclk_rate;
 238         info->adjfreq = xgbe_adjfreq;
 239         info->adjtime = xgbe_adjtime;
 240         info->gettime64 = xgbe_gettime;
 241         info->settime64 = xgbe_settime;
 242         info->enable = xgbe_enable;
 243 
 244         clock = ptp_clock_register(info, pdata->dev);
 245         if (IS_ERR(clock)) {
 246                 dev_err(pdata->dev, "ptp_clock_register failed\n");
 247                 return;
 248         }
 249 
 250         pdata->ptp_clock = clock;
 251 
 252         /* Calculate the addend:
 253          *   addend = 2^32 / (PTP ref clock / 50Mhz)
 254          *          = (2^32 * 50Mhz) / PTP ref clock
 255          */
 256         dividend = 50000000;
 257         dividend <<= 32;
 258         pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
 259 
 260         /* Setup the timecounter */
 261         cc->read = xgbe_cc_read;
 262         cc->mask = CLOCKSOURCE_MASK(64);
 263         cc->mult = 1;
 264         cc->shift = 0;
 265 
 266         timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
 267                          ktime_to_ns(ktime_get_real()));
 268 
 269         /* Disable all timestamping to start */
 270         XGMAC_IOWRITE(pdata, MAC_TSCR, 0);
 271         pdata->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
 272         pdata->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
 273 }
 274 
 275 void xgbe_ptp_unregister(struct xgbe_prv_data *pdata)
 276 {
 277         if (pdata->ptp_clock)
 278                 ptp_clock_unregister(pdata->ptp_clock);
 279 }

/* [<][>][^][v][top][bottom][index][help] */