LCOV - code coverage report
Current view: top level - drivers/net/ethernet/aquantia/atlantic - aq_ptp.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 40 611 6.5 %
Date: 2022-04-01 13:59:58 Functions: 7 47 14.9 %
Branches: 10 236 4.2 %

           Branch data     Line data    Source code
       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/ptp_classify.h>
      12                 :            : #include <linux/interrupt.h>
      13                 :            : #include <linux/clocksource.h>
      14                 :            : 
      15                 :            : #include "aq_nic.h"
      16                 :            : #include "aq_ptp.h"
      17                 :            : #include "aq_ring.h"
      18                 :            : #include "aq_phy.h"
      19                 :            : #include "aq_filters.h"
      20                 :            : 
      21                 :            : #define AQ_PTP_TX_TIMEOUT        (HZ *  10)
      22                 :            : 
      23                 :            : #define POLL_SYNC_TIMER_MS 15
      24                 :            : 
      25                 :            : enum ptp_speed_offsets {
      26                 :            :         ptp_offset_idx_10 = 0,
      27                 :            :         ptp_offset_idx_100,
      28                 :            :         ptp_offset_idx_1000,
      29                 :            :         ptp_offset_idx_2500,
      30                 :            :         ptp_offset_idx_5000,
      31                 :            :         ptp_offset_idx_10000,
      32                 :            : };
      33                 :            : 
      34                 :            : struct ptp_skb_ring {
      35                 :            :         struct sk_buff **buff;
      36                 :            :         spinlock_t lock;
      37                 :            :         unsigned int size;
      38                 :            :         unsigned int head;
      39                 :            :         unsigned int tail;
      40                 :            : };
      41                 :            : 
      42                 :            : struct ptp_tx_timeout {
      43                 :            :         spinlock_t lock;
      44                 :            :         bool active;
      45                 :            :         unsigned long tx_start;
      46                 :            : };
      47                 :            : 
      48                 :            : struct aq_ptp_s {
      49                 :            :         struct aq_nic_s *aq_nic;
      50                 :            :         struct hwtstamp_config hwtstamp_config;
      51                 :            :         spinlock_t ptp_lock;
      52                 :            :         spinlock_t ptp_ring_lock;
      53                 :            :         struct ptp_clock *ptp_clock;
      54                 :            :         struct ptp_clock_info ptp_info;
      55                 :            : 
      56                 :            :         atomic_t offset_egress;
      57                 :            :         atomic_t offset_ingress;
      58                 :            : 
      59                 :            :         struct aq_ring_param_s ptp_ring_param;
      60                 :            : 
      61                 :            :         struct ptp_tx_timeout ptp_tx_timeout;
      62                 :            : 
      63                 :            :         unsigned int idx_vector;
      64                 :            :         struct napi_struct napi;
      65                 :            : 
      66                 :            :         struct aq_ring_s ptp_tx;
      67                 :            :         struct aq_ring_s ptp_rx;
      68                 :            :         struct aq_ring_s hwts_rx;
      69                 :            : 
      70                 :            :         struct ptp_skb_ring skb_ring;
      71                 :            : 
      72                 :            :         struct aq_rx_filter_l3l4 udp_filter;
      73                 :            :         struct aq_rx_filter_l2 eth_type_filter;
      74                 :            : 
      75                 :            :         struct delayed_work poll_sync;
      76                 :            :         u32 poll_timeout_ms;
      77                 :            : 
      78                 :            :         bool extts_pin_enabled;
      79                 :            :         u64 last_sync1588_ts;
      80                 :            : };
      81                 :            : 
      82                 :            : struct ptp_tm_offset {
      83                 :            :         unsigned int mbps;
      84                 :            :         int egress;
      85                 :            :         int ingress;
      86                 :            : };
      87                 :            : 
      88                 :            : static struct ptp_tm_offset ptp_offset[6];
      89                 :            : 
      90                 :          0 : void aq_ptp_tm_offset_set(struct aq_nic_s *aq_nic, unsigned int mbps)
      91                 :            : {
      92                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
      93                 :          0 :         int i, egress, ingress;
      94                 :            : 
      95         [ #  # ]:          0 :         if (!aq_ptp)
      96                 :            :                 return;
      97                 :            : 
      98                 :            :         egress = 0;
      99                 :            :         ingress = 0;
     100                 :            : 
     101         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ptp_offset); i++) {
     102         [ #  # ]:          0 :                 if (mbps == ptp_offset[i].mbps) {
     103                 :          0 :                         egress = ptp_offset[i].egress;
     104                 :          0 :                         ingress = ptp_offset[i].ingress;
     105                 :          0 :                         break;
     106                 :            :                 }
     107                 :            :         }
     108                 :            : 
     109                 :          0 :         atomic_set(&aq_ptp->offset_egress, egress);
     110                 :          0 :         atomic_set(&aq_ptp->offset_ingress, ingress);
     111                 :            : }
     112                 :            : 
     113                 :          0 : static int __aq_ptp_skb_put(struct ptp_skb_ring *ring, struct sk_buff *skb)
     114                 :            : {
     115                 :          0 :         unsigned int next_head = (ring->head + 1) % ring->size;
     116                 :            : 
     117         [ #  # ]:          0 :         if (next_head == ring->tail)
     118                 :            :                 return -ENOMEM;
     119                 :            : 
     120                 :          0 :         ring->buff[ring->head] = skb_get(skb);
     121                 :          0 :         ring->head = next_head;
     122                 :            : 
     123                 :          0 :         return 0;
     124                 :            : }
     125                 :            : 
     126                 :          0 : static int aq_ptp_skb_put(struct ptp_skb_ring *ring, struct sk_buff *skb)
     127                 :            : {
     128                 :          0 :         unsigned long flags;
     129                 :          0 :         int ret;
     130                 :            : 
     131                 :          0 :         spin_lock_irqsave(&ring->lock, flags);
     132                 :          0 :         ret = __aq_ptp_skb_put(ring, skb);
     133                 :          0 :         spin_unlock_irqrestore(&ring->lock, flags);
     134                 :            : 
     135                 :          0 :         return ret;
     136                 :            : }
     137                 :            : 
     138                 :          0 : static struct sk_buff *__aq_ptp_skb_get(struct ptp_skb_ring *ring)
     139                 :            : {
     140                 :          0 :         struct sk_buff *skb;
     141                 :            : 
     142                 :          0 :         if (ring->tail == ring->head)
     143                 :            :                 return NULL;
     144                 :            : 
     145                 :          0 :         skb = ring->buff[ring->tail];
     146                 :          0 :         ring->tail = (ring->tail + 1) % ring->size;
     147                 :            : 
     148                 :          0 :         return skb;
     149                 :            : }
     150                 :            : 
     151                 :          0 : static struct sk_buff *aq_ptp_skb_get(struct ptp_skb_ring *ring)
     152                 :            : {
     153                 :          0 :         unsigned long flags;
     154                 :          0 :         struct sk_buff *skb;
     155                 :            : 
     156                 :          0 :         spin_lock_irqsave(&ring->lock, flags);
     157         [ #  # ]:          0 :         skb = __aq_ptp_skb_get(ring);
     158                 :          0 :         spin_unlock_irqrestore(&ring->lock, flags);
     159                 :            : 
     160                 :          0 :         return skb;
     161                 :            : }
     162                 :            : 
     163                 :          0 : static unsigned int aq_ptp_skb_buf_len(struct ptp_skb_ring *ring)
     164                 :            : {
     165                 :          0 :         unsigned long flags;
     166                 :          0 :         unsigned int len;
     167                 :            : 
     168                 :          0 :         spin_lock_irqsave(&ring->lock, flags);
     169                 :          0 :         len = (ring->head >= ring->tail) ?
     170         [ #  # ]:          0 :         ring->head - ring->tail :
     171                 :          0 :         ring->size - ring->tail + ring->head;
     172                 :          0 :         spin_unlock_irqrestore(&ring->lock, flags);
     173                 :            : 
     174                 :          0 :         return len;
     175                 :            : }
     176                 :            : 
     177                 :          0 : static int aq_ptp_skb_ring_init(struct ptp_skb_ring *ring, unsigned int size)
     178                 :            : {
     179         [ #  # ]:          0 :         struct sk_buff **buff = kmalloc(sizeof(*buff) * size, GFP_KERNEL);
     180                 :            : 
     181         [ #  # ]:          0 :         if (!buff)
     182                 :            :                 return -ENOMEM;
     183                 :            : 
     184                 :          0 :         spin_lock_init(&ring->lock);
     185                 :            : 
     186                 :          0 :         ring->buff = buff;
     187                 :          0 :         ring->size = size;
     188                 :          0 :         ring->head = 0;
     189                 :          0 :         ring->tail = 0;
     190                 :            : 
     191                 :          0 :         return 0;
     192                 :            : }
     193                 :            : 
     194                 :          0 : static void aq_ptp_skb_ring_clean(struct ptp_skb_ring *ring)
     195                 :            : {
     196                 :          0 :         struct sk_buff *skb;
     197                 :            : 
     198         [ #  # ]:          0 :         while ((skb = aq_ptp_skb_get(ring)) != NULL)
     199                 :          0 :                 dev_kfree_skb_any(skb);
     200                 :          0 : }
     201                 :            : 
     202                 :          0 : static void aq_ptp_skb_ring_release(struct ptp_skb_ring *ring)
     203                 :            : {
     204         [ #  # ]:          0 :         if (ring->buff) {
     205                 :          0 :                 aq_ptp_skb_ring_clean(ring);
     206                 :          0 :                 kfree(ring->buff);
     207                 :          0 :                 ring->buff = NULL;
     208                 :            :         }
     209                 :          0 : }
     210                 :            : 
     211                 :          0 : static void aq_ptp_tx_timeout_init(struct ptp_tx_timeout *timeout)
     212                 :            : {
     213                 :          0 :         spin_lock_init(&timeout->lock);
     214                 :          0 :         timeout->active = false;
     215                 :            : }
     216                 :            : 
     217                 :          0 : static void aq_ptp_tx_timeout_start(struct aq_ptp_s *aq_ptp)
     218                 :            : {
     219                 :          0 :         struct ptp_tx_timeout *timeout = &aq_ptp->ptp_tx_timeout;
     220                 :          0 :         unsigned long flags;
     221                 :            : 
     222                 :          0 :         spin_lock_irqsave(&timeout->lock, flags);
     223                 :          0 :         timeout->active = true;
     224                 :          0 :         timeout->tx_start = jiffies;
     225                 :          0 :         spin_unlock_irqrestore(&timeout->lock, flags);
     226                 :          0 : }
     227                 :            : 
     228                 :          0 : static void aq_ptp_tx_timeout_update(struct aq_ptp_s *aq_ptp)
     229                 :            : {
     230         [ #  # ]:          0 :         if (!aq_ptp_skb_buf_len(&aq_ptp->skb_ring)) {
     231                 :          0 :                 struct ptp_tx_timeout *timeout = &aq_ptp->ptp_tx_timeout;
     232                 :          0 :                 unsigned long flags;
     233                 :            : 
     234                 :          0 :                 spin_lock_irqsave(&timeout->lock, flags);
     235                 :          0 :                 timeout->active = false;
     236                 :          0 :                 spin_unlock_irqrestore(&timeout->lock, flags);
     237                 :            :         }
     238                 :          0 : }
     239                 :            : 
     240                 :          0 : static void aq_ptp_tx_timeout_check(struct aq_ptp_s *aq_ptp)
     241                 :            : {
     242                 :          0 :         struct ptp_tx_timeout *timeout = &aq_ptp->ptp_tx_timeout;
     243                 :          0 :         unsigned long flags;
     244                 :          0 :         bool timeout_flag;
     245                 :            : 
     246                 :          0 :         timeout_flag = false;
     247                 :            : 
     248                 :          0 :         spin_lock_irqsave(&timeout->lock, flags);
     249         [ #  # ]:          0 :         if (timeout->active) {
     250         [ #  # ]:          0 :                 timeout_flag = time_is_before_jiffies(timeout->tx_start +
     251                 :            :                                                       AQ_PTP_TX_TIMEOUT);
     252                 :            :                 /* reset active flag if timeout detected */
     253         [ #  # ]:          0 :                 if (timeout_flag)
     254                 :          0 :                         timeout->active = false;
     255                 :            :         }
     256                 :          0 :         spin_unlock_irqrestore(&timeout->lock, flags);
     257                 :            : 
     258         [ #  # ]:          0 :         if (timeout_flag) {
     259                 :          0 :                 aq_ptp_skb_ring_clean(&aq_ptp->skb_ring);
     260                 :          0 :                 netdev_err(aq_ptp->aq_nic->ndev,
     261                 :            :                            "PTP Timeout. Clearing Tx Timestamp SKBs\n");
     262                 :            :         }
     263                 :          0 : }
     264                 :            : 
     265                 :            : /* aq_ptp_adjfine
     266                 :            :  * @ptp: the ptp clock structure
     267                 :            :  * @ppb: parts per billion adjustment from base
     268                 :            :  *
     269                 :            :  * adjust the frequency of the ptp cycle counter by the
     270                 :            :  * indicated ppb from the base frequency.
     271                 :            :  */
     272                 :          0 : static int aq_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
     273                 :            : {
     274                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     275                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     276                 :            : 
     277                 :          0 :         mutex_lock(&aq_nic->fwreq_mutex);
     278                 :          0 :         aq_nic->aq_hw_ops->hw_adj_clock_freq(aq_nic->aq_hw,
     279                 :            :                                              scaled_ppm_to_ppb(scaled_ppm));
     280                 :          0 :         mutex_unlock(&aq_nic->fwreq_mutex);
     281                 :            : 
     282                 :          0 :         return 0;
     283                 :            : }
     284                 :            : 
     285                 :            : /* aq_ptp_adjtime
     286                 :            :  * @ptp: the ptp clock structure
     287                 :            :  * @delta: offset to adjust the cycle counter by
     288                 :            :  *
     289                 :            :  * adjust the timer by resetting the timecounter structure.
     290                 :            :  */
     291                 :          0 : static int aq_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
     292                 :            : {
     293                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     294                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     295                 :          0 :         unsigned long flags;
     296                 :            : 
     297                 :          0 :         spin_lock_irqsave(&aq_ptp->ptp_lock, flags);
     298                 :          0 :         aq_nic->aq_hw_ops->hw_adj_sys_clock(aq_nic->aq_hw, delta);
     299                 :          0 :         spin_unlock_irqrestore(&aq_ptp->ptp_lock, flags);
     300                 :            : 
     301                 :          0 :         return 0;
     302                 :            : }
     303                 :            : 
     304                 :            : /* aq_ptp_gettime
     305                 :            :  * @ptp: the ptp clock structure
     306                 :            :  * @ts: timespec structure to hold the current time value
     307                 :            :  *
     308                 :            :  * read the timecounter and return the correct value on ns,
     309                 :            :  * after converting it into a struct timespec.
     310                 :            :  */
     311                 :          0 : static int aq_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
     312                 :            : {
     313                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     314                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     315                 :          0 :         unsigned long flags;
     316                 :          0 :         u64 ns;
     317                 :            : 
     318                 :          0 :         spin_lock_irqsave(&aq_ptp->ptp_lock, flags);
     319                 :          0 :         aq_nic->aq_hw_ops->hw_get_ptp_ts(aq_nic->aq_hw, &ns);
     320                 :          0 :         spin_unlock_irqrestore(&aq_ptp->ptp_lock, flags);
     321                 :            : 
     322                 :          0 :         *ts = ns_to_timespec64(ns);
     323                 :            : 
     324                 :          0 :         return 0;
     325                 :            : }
     326                 :            : 
     327                 :            : /* aq_ptp_settime
     328                 :            :  * @ptp: the ptp clock structure
     329                 :            :  * @ts: the timespec containing the new time for the cycle counter
     330                 :            :  *
     331                 :            :  * reset the timecounter to use a new base value instead of the kernel
     332                 :            :  * wall timer value.
     333                 :            :  */
     334                 :          0 : static int aq_ptp_settime(struct ptp_clock_info *ptp,
     335                 :            :                           const struct timespec64 *ts)
     336                 :            : {
     337                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     338                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     339                 :          0 :         unsigned long flags;
     340                 :          0 :         u64 ns = timespec64_to_ns(ts);
     341                 :          0 :         u64 now;
     342                 :            : 
     343                 :          0 :         spin_lock_irqsave(&aq_ptp->ptp_lock, flags);
     344                 :          0 :         aq_nic->aq_hw_ops->hw_get_ptp_ts(aq_nic->aq_hw, &now);
     345                 :          0 :         aq_nic->aq_hw_ops->hw_adj_sys_clock(aq_nic->aq_hw, (s64)ns - (s64)now);
     346                 :            : 
     347                 :          0 :         spin_unlock_irqrestore(&aq_ptp->ptp_lock, flags);
     348                 :            : 
     349                 :          0 :         return 0;
     350                 :            : }
     351                 :            : 
     352                 :          0 : static void aq_ptp_convert_to_hwtstamp(struct aq_ptp_s *aq_ptp,
     353                 :            :                                        struct skb_shared_hwtstamps *hwtstamp,
     354                 :            :                                        u64 timestamp)
     355                 :            : {
     356                 :          0 :         memset(hwtstamp, 0, sizeof(*hwtstamp));
     357                 :          0 :         hwtstamp->hwtstamp = ns_to_ktime(timestamp);
     358                 :            : }
     359                 :            : 
     360                 :          0 : static int aq_ptp_hw_pin_conf(struct aq_nic_s *aq_nic, u32 pin_index, u64 start,
     361                 :            :                               u64 period)
     362                 :            : {
     363                 :          0 :         if (period)
     364                 :            :                 netdev_dbg(aq_nic->ndev,
     365                 :            :                            "Enable GPIO %d pulsing, start time %llu, period %u\n",
     366                 :            :                            pin_index, start, (u32)period);
     367                 :            :         else
     368                 :            :                 netdev_dbg(aq_nic->ndev,
     369                 :            :                            "Disable GPIO %d pulsing, start time %llu, period %u\n",
     370                 :            :                            pin_index, start, (u32)period);
     371                 :            : 
     372                 :            :         /* Notify hardware of request to being sending pulses.
     373                 :            :          * If period is ZERO then pulsen is disabled.
     374                 :            :          */
     375                 :          0 :         mutex_lock(&aq_nic->fwreq_mutex);
     376                 :          0 :         aq_nic->aq_hw_ops->hw_gpio_pulse(aq_nic->aq_hw, pin_index,
     377                 :            :                                          start, (u32)period);
     378                 :          0 :         mutex_unlock(&aq_nic->fwreq_mutex);
     379                 :            : 
     380                 :          0 :         return 0;
     381                 :            : }
     382                 :            : 
     383                 :          0 : static int aq_ptp_perout_pin_configure(struct ptp_clock_info *ptp,
     384                 :            :                                        struct ptp_clock_request *rq, int on)
     385                 :            : {
     386                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     387                 :          0 :         struct ptp_clock_time *t = &rq->perout.period;
     388                 :          0 :         struct ptp_clock_time *s = &rq->perout.start;
     389                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     390                 :          0 :         u64 start, period;
     391                 :          0 :         u32 pin_index = rq->perout.index;
     392                 :            : 
     393                 :            :         /* verify the request channel is there */
     394         [ #  # ]:          0 :         if (pin_index >= ptp->n_per_out)
     395                 :            :                 return -EINVAL;
     396                 :            : 
     397                 :            :         /* we cannot support periods greater
     398                 :            :          * than 4 seconds due to reg limit
     399                 :            :          */
     400         [ #  # ]:          0 :         if (t->sec > 4 || t->sec < 0)
     401                 :            :                 return -ERANGE;
     402                 :            : 
     403                 :            :         /* convert to unsigned 64b ns,
     404                 :            :          * verify we can put it in a 32b register
     405                 :            :          */
     406         [ #  # ]:          0 :         period = on ? t->sec * NSEC_PER_SEC + t->nsec : 0;
     407                 :            : 
     408                 :            :         /* verify the value is in range supported by hardware */
     409         [ #  # ]:          0 :         if (period > U32_MAX)
     410                 :            :                 return -ERANGE;
     411                 :            :         /* convert to unsigned 64b ns */
     412                 :            :         /* TODO convert to AQ time */
     413         [ #  # ]:          0 :         start = on ? s->sec * NSEC_PER_SEC + s->nsec : 0;
     414                 :            : 
     415                 :          0 :         aq_ptp_hw_pin_conf(aq_nic, pin_index, start, period);
     416                 :            : 
     417                 :          0 :         return 0;
     418                 :            : }
     419                 :            : 
     420                 :            : static int aq_ptp_pps_pin_configure(struct ptp_clock_info *ptp,
     421                 :            :                                     struct ptp_clock_request *rq, int on)
     422                 :            : {
     423                 :            :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     424                 :            :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     425                 :            :         u64 start, period;
     426                 :            :         u32 pin_index = 0;
     427                 :            :         u32 rest = 0;
     428                 :            : 
     429                 :            :         /* verify the request channel is there */
     430                 :            :         if (pin_index >= ptp->n_per_out)
     431                 :            :                 return -EINVAL;
     432                 :            : 
     433                 :            :         aq_nic->aq_hw_ops->hw_get_ptp_ts(aq_nic->aq_hw, &start);
     434                 :            :         div_u64_rem(start, NSEC_PER_SEC, &rest);
     435                 :            :         period = on ? NSEC_PER_SEC : 0; /* PPS - pulse per second */
     436                 :            :         start = on ? start - rest + NSEC_PER_SEC *
     437                 :            :                 (rest > 990000000LL ? 2 : 1) : 0;
     438                 :            : 
     439                 :            :         aq_ptp_hw_pin_conf(aq_nic, pin_index, start, period);
     440                 :            : 
     441                 :            :         return 0;
     442                 :            : }
     443                 :            : 
     444                 :            : static void aq_ptp_extts_pin_ctrl(struct aq_ptp_s *aq_ptp)
     445                 :            : {
     446                 :            :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     447                 :            :         u32 enable = aq_ptp->extts_pin_enabled;
     448                 :            : 
     449                 :            :         if (aq_nic->aq_hw_ops->hw_extts_gpio_enable)
     450                 :            :                 aq_nic->aq_hw_ops->hw_extts_gpio_enable(aq_nic->aq_hw, 0,
     451                 :            :                                                         enable);
     452                 :            : }
     453                 :            : 
     454                 :            : static int aq_ptp_extts_pin_configure(struct ptp_clock_info *ptp,
     455                 :            :                                       struct ptp_clock_request *rq, int on)
     456                 :            : {
     457                 :            :         struct aq_ptp_s *aq_ptp = container_of(ptp, struct aq_ptp_s, ptp_info);
     458                 :            : 
     459                 :            :         u32 pin_index = rq->extts.index;
     460                 :            : 
     461                 :            :         if (pin_index >= ptp->n_ext_ts)
     462                 :            :                 return -EINVAL;
     463                 :            : 
     464                 :            :         aq_ptp->extts_pin_enabled = !!on;
     465                 :            :         if (on) {
     466                 :            :                 aq_ptp->poll_timeout_ms = POLL_SYNC_TIMER_MS;
     467                 :            :                 cancel_delayed_work_sync(&aq_ptp->poll_sync);
     468                 :            :                 schedule_delayed_work(&aq_ptp->poll_sync,
     469                 :            :                                       msecs_to_jiffies(aq_ptp->poll_timeout_ms));
     470                 :            :         }
     471                 :            : 
     472                 :            :         aq_ptp_extts_pin_ctrl(aq_ptp);
     473                 :            :         return 0;
     474                 :            : }
     475                 :            : 
     476                 :            : /* aq_ptp_gpio_feature_enable
     477                 :            :  * @ptp: the ptp clock structure
     478                 :            :  * @rq: the requested feature to change
     479                 :            :  * @on: whether to enable or disable the feature
     480                 :            :  */
     481                 :          0 : static int aq_ptp_gpio_feature_enable(struct ptp_clock_info *ptp,
     482                 :            :                                       struct ptp_clock_request *rq, int on)
     483                 :            : {
     484   [ #  #  #  # ]:          0 :         switch (rq->type) {
     485                 :          0 :         case PTP_CLK_REQ_EXTTS:
     486                 :          0 :                 return aq_ptp_extts_pin_configure(ptp, rq, on);
     487                 :          0 :         case PTP_CLK_REQ_PEROUT:
     488                 :          0 :                 return aq_ptp_perout_pin_configure(ptp, rq, on);
     489                 :          0 :         case PTP_CLK_REQ_PPS:
     490                 :          0 :                 return aq_ptp_pps_pin_configure(ptp, rq, on);
     491                 :            :         default:
     492                 :            :                 return -EOPNOTSUPP;
     493                 :            :         }
     494                 :            : 
     495                 :            :         return 0;
     496                 :            : }
     497                 :            : 
     498                 :            : /* aq_ptp_verify
     499                 :            :  * @ptp: the ptp clock structure
     500                 :            :  * @pin: index of the pin in question
     501                 :            :  * @func: the desired function to use
     502                 :            :  * @chan: the function channel index to use
     503                 :            :  */
     504                 :          0 : static int aq_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
     505                 :            :                          enum ptp_pin_function func, unsigned int chan)
     506                 :            : {
     507                 :            :         /* verify the requested pin is there */
     508   [ #  #  #  # ]:          0 :         if (!ptp->pin_config || pin >= ptp->n_pins)
     509                 :            :                 return -EINVAL;
     510                 :            : 
     511                 :            :         /* enforce locked channels, no changing them */
     512         [ #  # ]:          0 :         if (chan != ptp->pin_config[pin].chan)
     513                 :            :                 return -EINVAL;
     514                 :            : 
     515                 :            :         /* we want to keep the functions locked as well */
     516         [ #  # ]:          0 :         if (func != ptp->pin_config[pin].func)
     517                 :          0 :                 return -EINVAL;
     518                 :            : 
     519                 :            :         return 0;
     520                 :            : }
     521                 :            : 
     522                 :            : /* aq_ptp_tx_hwtstamp - utility function which checks for TX time stamp
     523                 :            :  * @adapter: the private adapter struct
     524                 :            :  *
     525                 :            :  * if the timestamp is valid, we convert it into the timecounter ns
     526                 :            :  * value, then store that result into the hwtstamps structure which
     527                 :            :  * is passed up the network stack
     528                 :            :  */
     529                 :          0 : void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp)
     530                 :            : {
     531                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     532                 :          0 :         struct sk_buff *skb = aq_ptp_skb_get(&aq_ptp->skb_ring);
     533                 :          0 :         struct skb_shared_hwtstamps hwtstamp;
     534                 :            : 
     535         [ #  # ]:          0 :         if (!skb) {
     536                 :          0 :                 netdev_err(aq_nic->ndev, "have timestamp but tx_queues empty\n");
     537                 :          0 :                 return;
     538                 :            :         }
     539                 :            : 
     540                 :          0 :         timestamp += atomic_read(&aq_ptp->offset_egress);
     541                 :          0 :         aq_ptp_convert_to_hwtstamp(aq_ptp, &hwtstamp, timestamp);
     542                 :          0 :         skb_tstamp_tx(skb, &hwtstamp);
     543                 :          0 :         dev_kfree_skb_any(skb);
     544                 :            : 
     545                 :          0 :         aq_ptp_tx_timeout_update(aq_ptp);
     546                 :            : }
     547                 :            : 
     548                 :            : /* aq_ptp_rx_hwtstamp - utility function which checks for RX time stamp
     549                 :            :  * @adapter: pointer to adapter struct
     550                 :            :  * @skb: particular skb to send timestamp with
     551                 :            :  *
     552                 :            :  * if the timestamp is valid, we convert it into the timecounter ns
     553                 :            :  * value, then store that result into the hwtstamps structure which
     554                 :            :  * is passed up the network stack
     555                 :            :  */
     556                 :          0 : static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct sk_buff *skb,
     557                 :            :                                u64 timestamp)
     558                 :            : {
     559                 :          0 :         timestamp -= atomic_read(&aq_ptp->offset_ingress);
     560                 :          0 :         aq_ptp_convert_to_hwtstamp(aq_ptp, skb_hwtstamps(skb), timestamp);
     561                 :          0 : }
     562                 :            : 
     563                 :          0 : void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp,
     564                 :            :                                 struct hwtstamp_config *config)
     565                 :            : {
     566                 :          0 :         *config = aq_ptp->hwtstamp_config;
     567                 :          0 : }
     568                 :            : 
     569                 :          0 : static void aq_ptp_prepare_filters(struct aq_ptp_s *aq_ptp)
     570                 :            : {
     571                 :          0 :         aq_ptp->udp_filter.cmd = HW_ATL_RX_ENABLE_FLTR_L3L4 |
     572                 :            :                                HW_ATL_RX_ENABLE_CMP_PROT_L4 |
     573                 :            :                                HW_ATL_RX_UDP |
     574                 :            :                                HW_ATL_RX_ENABLE_CMP_DEST_PORT_L4 |
     575                 :            :                                HW_ATL_RX_HOST << HW_ATL_RX_ACTION_FL3F4_SHIFT |
     576                 :          0 :                                HW_ATL_RX_ENABLE_QUEUE_L3L4 |
     577                 :          0 :                                aq_ptp->ptp_rx.idx << HW_ATL_RX_QUEUE_FL3L4_SHIFT;
     578                 :          0 :         aq_ptp->udp_filter.p_dst = PTP_EV_PORT;
     579                 :            : 
     580                 :          0 :         aq_ptp->eth_type_filter.ethertype = ETH_P_1588;
     581                 :          0 :         aq_ptp->eth_type_filter.queue = aq_ptp->ptp_rx.idx;
     582                 :            : }
     583                 :            : 
     584                 :          0 : int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp,
     585                 :            :                                struct hwtstamp_config *config)
     586                 :            : {
     587                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     588                 :          0 :         const struct aq_hw_ops *hw_ops;
     589                 :          0 :         int err = 0;
     590                 :            : 
     591                 :          0 :         hw_ops = aq_nic->aq_hw_ops;
     592         [ #  # ]:          0 :         if (config->tx_type == HWTSTAMP_TX_ON ||
     593         [ #  # ]:          0 :             config->rx_filter == HWTSTAMP_FILTER_PTP_V2_EVENT) {
     594                 :          0 :                 aq_ptp_prepare_filters(aq_ptp);
     595         [ #  # ]:          0 :                 if (hw_ops->hw_filter_l3l4_set) {
     596                 :          0 :                         err = hw_ops->hw_filter_l3l4_set(aq_nic->aq_hw,
     597                 :            :                                                          &aq_ptp->udp_filter);
     598                 :            :                 }
     599   [ #  #  #  # ]:          0 :                 if (!err && hw_ops->hw_filter_l2_set) {
     600                 :          0 :                         err = hw_ops->hw_filter_l2_set(aq_nic->aq_hw,
     601                 :            :                                                        &aq_ptp->eth_type_filter);
     602                 :            :                 }
     603                 :          0 :                 aq_utils_obj_set(&aq_nic->flags, AQ_NIC_PTP_DPATH_UP);
     604                 :            :         } else {
     605                 :          0 :                 aq_ptp->udp_filter.cmd &= ~HW_ATL_RX_ENABLE_FLTR_L3L4;
     606         [ #  # ]:          0 :                 if (hw_ops->hw_filter_l3l4_set) {
     607                 :          0 :                         err = hw_ops->hw_filter_l3l4_set(aq_nic->aq_hw,
     608                 :            :                                                          &aq_ptp->udp_filter);
     609                 :            :                 }
     610   [ #  #  #  # ]:          0 :                 if (!err && hw_ops->hw_filter_l2_clear) {
     611                 :          0 :                         err = hw_ops->hw_filter_l2_clear(aq_nic->aq_hw,
     612                 :            :                                                         &aq_ptp->eth_type_filter);
     613                 :            :                 }
     614                 :          0 :                 aq_utils_obj_clear(&aq_nic->flags, AQ_NIC_PTP_DPATH_UP);
     615                 :            :         }
     616                 :            : 
     617         [ #  # ]:          0 :         if (err)
     618                 :            :                 return -EREMOTEIO;
     619                 :            : 
     620                 :          0 :         aq_ptp->hwtstamp_config = *config;
     621                 :            : 
     622                 :          0 :         return 0;
     623                 :            : }
     624                 :            : 
     625                 :       4258 : bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring)
     626                 :            : {
     627                 :       4258 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     628                 :            : 
     629         [ -  + ]:       4258 :         if (!aq_ptp)
     630                 :            :                 return false;
     631                 :            : 
     632                 :          0 :         return &aq_ptp->ptp_tx == ring ||
     633   [ #  #  #  #  :          0 :                &aq_ptp->ptp_rx == ring || &aq_ptp->hwts_rx == ring;
                   #  # ]
     634                 :            : }
     635                 :            : 
     636                 :          0 : u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p,
     637                 :            :                       unsigned int len)
     638                 :            : {
     639                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     640                 :          0 :         u64 timestamp = 0;
     641                 :          0 :         u16 ret = aq_nic->aq_hw_ops->rx_extract_ts(aq_nic->aq_hw,
     642                 :            :                                                    p, len, &timestamp);
     643                 :            : 
     644         [ #  # ]:          0 :         if (ret > 0)
     645                 :          0 :                 aq_ptp_rx_hwtstamp(aq_ptp, skb, timestamp);
     646                 :            : 
     647                 :          0 :         return ret;
     648                 :            : }
     649                 :            : 
     650                 :          0 : static int aq_ptp_poll(struct napi_struct *napi, int budget)
     651                 :            : {
     652                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(napi, struct aq_ptp_s, napi);
     653                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
     654                 :          0 :         bool was_cleaned = false;
     655                 :          0 :         int work_done = 0;
     656                 :          0 :         int err;
     657                 :            : 
     658                 :            :         /* Processing PTP TX traffic */
     659                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_tx_head_update(aq_nic->aq_hw,
     660                 :            :                                                         &aq_ptp->ptp_tx);
     661         [ #  # ]:          0 :         if (err < 0)
     662                 :          0 :                 goto err_exit;
     663                 :            : 
     664         [ #  # ]:          0 :         if (aq_ptp->ptp_tx.sw_head != aq_ptp->ptp_tx.hw_head) {
     665                 :          0 :                 aq_ring_tx_clean(&aq_ptp->ptp_tx);
     666                 :            : 
     667                 :          0 :                 was_cleaned = true;
     668                 :            :         }
     669                 :            : 
     670                 :            :         /* Processing HW_TIMESTAMP RX traffic */
     671                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_hwts_rx_receive(aq_nic->aq_hw,
     672                 :            :                                                          &aq_ptp->hwts_rx);
     673         [ #  # ]:          0 :         if (err < 0)
     674                 :          0 :                 goto err_exit;
     675                 :            : 
     676         [ #  # ]:          0 :         if (aq_ptp->hwts_rx.sw_head != aq_ptp->hwts_rx.hw_head) {
     677                 :          0 :                 aq_ring_hwts_rx_clean(&aq_ptp->hwts_rx, aq_nic);
     678                 :            : 
     679                 :          0 :                 err = aq_nic->aq_hw_ops->hw_ring_hwts_rx_fill(aq_nic->aq_hw,
     680                 :            :                                                               &aq_ptp->hwts_rx);
     681         [ #  # ]:          0 :                 if (err < 0)
     682                 :          0 :                         goto err_exit;
     683                 :            : 
     684                 :            :                 was_cleaned = true;
     685                 :            :         }
     686                 :            : 
     687                 :            :         /* Processing PTP RX traffic */
     688                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_rx_receive(aq_nic->aq_hw,
     689                 :            :                                                     &aq_ptp->ptp_rx);
     690         [ #  # ]:          0 :         if (err < 0)
     691                 :          0 :                 goto err_exit;
     692                 :            : 
     693         [ #  # ]:          0 :         if (aq_ptp->ptp_rx.sw_head != aq_ptp->ptp_rx.hw_head) {
     694                 :          0 :                 unsigned int sw_tail_old;
     695                 :            : 
     696                 :          0 :                 err = aq_ring_rx_clean(&aq_ptp->ptp_rx, napi, &work_done, budget);
     697         [ #  # ]:          0 :                 if (err < 0)
     698                 :          0 :                         goto err_exit;
     699                 :            : 
     700                 :          0 :                 sw_tail_old = aq_ptp->ptp_rx.sw_tail;
     701                 :          0 :                 err = aq_ring_rx_fill(&aq_ptp->ptp_rx);
     702         [ #  # ]:          0 :                 if (err < 0)
     703                 :          0 :                         goto err_exit;
     704                 :            : 
     705                 :          0 :                 err = aq_nic->aq_hw_ops->hw_ring_rx_fill(aq_nic->aq_hw,
     706                 :            :                                                          &aq_ptp->ptp_rx,
     707                 :            :                                                          sw_tail_old);
     708         [ #  # ]:          0 :                 if (err < 0)
     709                 :          0 :                         goto err_exit;
     710                 :            :         }
     711                 :            : 
     712         [ #  # ]:          0 :         if (was_cleaned)
     713                 :          0 :                 work_done = budget;
     714                 :            : 
     715         [ #  # ]:          0 :         if (work_done < budget) {
     716                 :          0 :                 napi_complete_done(napi, work_done);
     717                 :          0 :                 aq_nic->aq_hw_ops->hw_irq_enable(aq_nic->aq_hw,
     718                 :          0 :                                         BIT_ULL(aq_ptp->ptp_ring_param.vec_idx));
     719                 :            :         }
     720                 :            : 
     721                 :          0 : err_exit:
     722                 :          0 :         return work_done;
     723                 :            : }
     724                 :            : 
     725                 :          0 : static irqreturn_t aq_ptp_isr(int irq, void *private)
     726                 :            : {
     727                 :          0 :         struct aq_ptp_s *aq_ptp = private;
     728                 :          0 :         int err = 0;
     729                 :            : 
     730         [ #  # ]:          0 :         if (!aq_ptp) {
     731                 :          0 :                 err = -EINVAL;
     732                 :          0 :                 goto err_exit;
     733                 :            :         }
     734                 :          0 :         napi_schedule(&aq_ptp->napi);
     735                 :            : 
     736                 :          0 : err_exit:
     737                 :          0 :         return err >= 0 ? IRQ_HANDLED : IRQ_NONE;
     738                 :            : }
     739                 :            : 
     740                 :          0 : int aq_ptp_xmit(struct aq_nic_s *aq_nic, struct sk_buff *skb)
     741                 :            : {
     742                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     743                 :          0 :         struct aq_ring_s *ring = &aq_ptp->ptp_tx;
     744                 :          0 :         unsigned long irq_flags;
     745                 :          0 :         int err = NETDEV_TX_OK;
     746                 :          0 :         unsigned int frags;
     747                 :            : 
     748         [ #  # ]:          0 :         if (skb->len <= 0) {
     749                 :          0 :                 dev_kfree_skb_any(skb);
     750                 :          0 :                 goto err_exit;
     751                 :            :         }
     752                 :            : 
     753         [ #  # ]:          0 :         frags = skb_shinfo(skb)->nr_frags + 1;
     754                 :            :         /* Frags cannot be bigger 16KB
     755                 :            :          * because PTP usually works
     756                 :            :          * without Jumbo even in a background
     757                 :            :          */
     758   [ #  #  #  # ]:          0 :         if (frags > AQ_CFG_SKB_FRAGS_MAX || frags > aq_ring_avail_dx(ring)) {
     759                 :            :                 /* Drop packet because it doesn't make sence to delay it */
     760                 :          0 :                 dev_kfree_skb_any(skb);
     761                 :          0 :                 goto err_exit;
     762                 :            :         }
     763                 :            : 
     764                 :          0 :         err = aq_ptp_skb_put(&aq_ptp->skb_ring, skb);
     765         [ #  # ]:          0 :         if (err) {
     766                 :          0 :                 netdev_err(aq_nic->ndev, "SKB Ring is overflow (%u)!\n",
     767                 :            :                            ring->size);
     768                 :          0 :                 return NETDEV_TX_BUSY;
     769                 :            :         }
     770                 :          0 :         skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
     771                 :          0 :         aq_ptp_tx_timeout_start(aq_ptp);
     772         [ #  # ]:          0 :         skb_tx_timestamp(skb);
     773                 :            : 
     774                 :          0 :         spin_lock_irqsave(&aq_nic->aq_ptp->ptp_ring_lock, irq_flags);
     775                 :          0 :         frags = aq_nic_map_skb(aq_nic, skb, ring);
     776                 :            : 
     777         [ #  # ]:          0 :         if (likely(frags)) {
     778                 :          0 :                 err = aq_nic->aq_hw_ops->hw_ring_tx_xmit(aq_nic->aq_hw,
     779                 :            :                                                        ring, frags);
     780         [ #  # ]:          0 :                 if (err >= 0) {
     781                 :          0 :                         ++ring->stats.tx.packets;
     782                 :          0 :                         ring->stats.tx.bytes += skb->len;
     783                 :            :                 }
     784                 :            :         } else {
     785                 :            :                 err = NETDEV_TX_BUSY;
     786                 :            :         }
     787                 :          0 :         spin_unlock_irqrestore(&aq_nic->aq_ptp->ptp_ring_lock, irq_flags);
     788                 :            : 
     789                 :            : err_exit:
     790                 :            :         return err;
     791                 :            : }
     792                 :            : 
     793                 :         97 : void aq_ptp_service_task(struct aq_nic_s *aq_nic)
     794                 :            : {
     795                 :         97 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     796                 :            : 
     797         [ -  + ]:         97 :         if (!aq_ptp)
     798                 :            :                 return;
     799                 :            : 
     800                 :          0 :         aq_ptp_tx_timeout_check(aq_ptp);
     801                 :            : }
     802                 :            : 
     803                 :         33 : int aq_ptp_irq_alloc(struct aq_nic_s *aq_nic)
     804                 :            : {
     805                 :         33 :         struct pci_dev *pdev = aq_nic->pdev;
     806                 :         33 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     807                 :         33 :         int err = 0;
     808                 :            : 
     809         [ -  + ]:         33 :         if (!aq_ptp)
     810                 :            :                 return 0;
     811                 :            : 
     812         [ #  # ]:          0 :         if (pdev->msix_enabled || pdev->msi_enabled) {
     813                 :          0 :                 err = request_irq(pci_irq_vector(pdev, aq_ptp->idx_vector),
     814                 :          0 :                                   aq_ptp_isr, 0, aq_nic->ndev->name, aq_ptp);
     815                 :            :         } else {
     816                 :          0 :                 err = -EINVAL;
     817                 :          0 :                 goto err_exit;
     818                 :            :         }
     819                 :            : 
     820                 :            : err_exit:
     821                 :            :         return err;
     822                 :            : }
     823                 :            : 
     824                 :          0 : void aq_ptp_irq_free(struct aq_nic_s *aq_nic)
     825                 :            : {
     826                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     827                 :          0 :         struct pci_dev *pdev = aq_nic->pdev;
     828                 :            : 
     829         [ #  # ]:          0 :         if (!aq_ptp)
     830                 :            :                 return;
     831                 :            : 
     832                 :          0 :         free_irq(pci_irq_vector(pdev, aq_ptp->idx_vector), aq_ptp);
     833                 :            : }
     834                 :            : 
     835                 :         33 : int aq_ptp_ring_init(struct aq_nic_s *aq_nic)
     836                 :            : {
     837                 :         33 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     838                 :         33 :         int err = 0;
     839                 :            : 
     840         [ -  + ]:         33 :         if (!aq_ptp)
     841                 :            :                 return 0;
     842                 :            : 
     843                 :          0 :         err = aq_ring_init(&aq_ptp->ptp_tx);
     844         [ #  # ]:          0 :         if (err < 0)
     845                 :          0 :                 goto err_exit;
     846                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_tx_init(aq_nic->aq_hw,
     847                 :            :                                                  &aq_ptp->ptp_tx,
     848                 :            :                                                  &aq_ptp->ptp_ring_param);
     849         [ #  # ]:          0 :         if (err < 0)
     850                 :          0 :                 goto err_exit;
     851                 :            : 
     852                 :          0 :         err = aq_ring_init(&aq_ptp->ptp_rx);
     853         [ #  # ]:          0 :         if (err < 0)
     854                 :          0 :                 goto err_exit;
     855                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_rx_init(aq_nic->aq_hw,
     856                 :            :                                                  &aq_ptp->ptp_rx,
     857                 :            :                                                  &aq_ptp->ptp_ring_param);
     858         [ #  # ]:          0 :         if (err < 0)
     859                 :          0 :                 goto err_exit;
     860                 :            : 
     861                 :          0 :         err = aq_ring_rx_fill(&aq_ptp->ptp_rx);
     862         [ #  # ]:          0 :         if (err < 0)
     863                 :          0 :                 goto err_rx_free;
     864                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_rx_fill(aq_nic->aq_hw,
     865                 :            :                                                  &aq_ptp->ptp_rx,
     866                 :            :                                                  0U);
     867         [ #  # ]:          0 :         if (err < 0)
     868                 :          0 :                 goto err_rx_free;
     869                 :            : 
     870                 :          0 :         err = aq_ring_init(&aq_ptp->hwts_rx);
     871         [ #  # ]:          0 :         if (err < 0)
     872                 :          0 :                 goto err_rx_free;
     873                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_rx_init(aq_nic->aq_hw,
     874                 :            :                                                  &aq_ptp->hwts_rx,
     875                 :            :                                                  &aq_ptp->ptp_ring_param);
     876         [ #  # ]:          0 :         if (err < 0)
     877                 :          0 :                 goto err_exit;
     878                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_hwts_rx_fill(aq_nic->aq_hw,
     879                 :            :                                                       &aq_ptp->hwts_rx);
     880         [ #  # ]:          0 :         if (err < 0)
     881                 :          0 :                 goto err_exit;
     882                 :            : 
     883                 :            :         return err;
     884                 :            : 
     885                 :          0 : err_rx_free:
     886                 :          0 :         aq_ring_rx_deinit(&aq_ptp->ptp_rx);
     887                 :            : err_exit:
     888                 :            :         return err;
     889                 :            : }
     890                 :            : 
     891                 :         33 : int aq_ptp_ring_start(struct aq_nic_s *aq_nic)
     892                 :            : {
     893                 :         33 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     894                 :         33 :         int err = 0;
     895                 :            : 
     896         [ -  + ]:         33 :         if (!aq_ptp)
     897                 :            :                 return 0;
     898                 :            : 
     899                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_tx_start(aq_nic->aq_hw, &aq_ptp->ptp_tx);
     900         [ #  # ]:          0 :         if (err < 0)
     901                 :          0 :                 goto err_exit;
     902                 :            : 
     903                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_rx_start(aq_nic->aq_hw, &aq_ptp->ptp_rx);
     904         [ #  # ]:          0 :         if (err < 0)
     905                 :          0 :                 goto err_exit;
     906                 :            : 
     907                 :          0 :         err = aq_nic->aq_hw_ops->hw_ring_rx_start(aq_nic->aq_hw,
     908                 :            :                                                   &aq_ptp->hwts_rx);
     909         [ #  # ]:          0 :         if (err < 0)
     910                 :          0 :                 goto err_exit;
     911                 :            : 
     912                 :          0 :         napi_enable(&aq_ptp->napi);
     913                 :            : 
     914                 :            : err_exit:
     915                 :            :         return err;
     916                 :            : }
     917                 :            : 
     918                 :          0 : void aq_ptp_ring_stop(struct aq_nic_s *aq_nic)
     919                 :            : {
     920                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     921                 :            : 
     922         [ #  # ]:          0 :         if (!aq_ptp)
     923                 :            :                 return;
     924                 :            : 
     925                 :          0 :         aq_nic->aq_hw_ops->hw_ring_tx_stop(aq_nic->aq_hw, &aq_ptp->ptp_tx);
     926                 :          0 :         aq_nic->aq_hw_ops->hw_ring_rx_stop(aq_nic->aq_hw, &aq_ptp->ptp_rx);
     927                 :            : 
     928                 :          0 :         aq_nic->aq_hw_ops->hw_ring_rx_stop(aq_nic->aq_hw, &aq_ptp->hwts_rx);
     929                 :            : 
     930                 :          0 :         napi_disable(&aq_ptp->napi);
     931                 :            : }
     932                 :            : 
     933                 :          0 : void aq_ptp_ring_deinit(struct aq_nic_s *aq_nic)
     934                 :            : {
     935                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     936                 :            : 
     937   [ #  #  #  #  :          0 :         if (!aq_ptp || !aq_ptp->ptp_tx.aq_nic || !aq_ptp->ptp_rx.aq_nic)
                   #  # ]
     938                 :            :                 return;
     939                 :            : 
     940                 :          0 :         aq_ring_tx_clean(&aq_ptp->ptp_tx);
     941                 :          0 :         aq_ring_rx_deinit(&aq_ptp->ptp_rx);
     942                 :            : }
     943                 :            : 
     944                 :            : #define PTP_8TC_RING_IDX             8
     945                 :            : #define PTP_4TC_RING_IDX            16
     946                 :            : #define PTP_HWST_RING_IDX           31
     947                 :            : 
     948                 :         33 : int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
     949                 :            : {
     950                 :         33 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
     951                 :         33 :         unsigned int tx_ring_idx, rx_ring_idx;
     952                 :         33 :         struct aq_ring_s *hwts;
     953                 :         33 :         u32 tx_tc_mode, rx_tc_mode;
     954                 :         33 :         struct aq_ring_s *ring;
     955                 :         33 :         int err;
     956                 :            : 
     957         [ -  + ]:         33 :         if (!aq_ptp)
     958                 :            :                 return 0;
     959                 :            : 
     960                 :            :         /* Index must to be 8 (8 TCs) or 16 (4 TCs).
     961                 :            :          * It depends from Traffic Class mode.
     962                 :            :          */
     963                 :          0 :         aq_nic->aq_hw_ops->hw_tx_tc_mode_get(aq_nic->aq_hw, &tx_tc_mode);
     964         [ #  # ]:          0 :         if (tx_tc_mode == 0)
     965                 :            :                 tx_ring_idx = PTP_8TC_RING_IDX;
     966                 :            :         else
     967                 :          0 :                 tx_ring_idx = PTP_4TC_RING_IDX;
     968                 :            : 
     969                 :          0 :         ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
     970                 :            :                                 tx_ring_idx, &aq_nic->aq_nic_cfg);
     971         [ #  # ]:          0 :         if (!ring) {
     972                 :          0 :                 err = -ENOMEM;
     973                 :          0 :                 goto err_exit;
     974                 :            :         }
     975                 :            : 
     976                 :          0 :         aq_nic->aq_hw_ops->hw_rx_tc_mode_get(aq_nic->aq_hw, &rx_tc_mode);
     977         [ #  # ]:          0 :         if (rx_tc_mode == 0)
     978                 :            :                 rx_ring_idx = PTP_8TC_RING_IDX;
     979                 :            :         else
     980                 :          0 :                 rx_ring_idx = PTP_4TC_RING_IDX;
     981                 :            : 
     982                 :          0 :         ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
     983                 :            :                                 rx_ring_idx, &aq_nic->aq_nic_cfg);
     984         [ #  # ]:          0 :         if (!ring) {
     985                 :          0 :                 err = -ENOMEM;
     986                 :          0 :                 goto err_exit_ptp_tx;
     987                 :            :         }
     988                 :            : 
     989                 :          0 :         hwts = aq_ring_hwts_rx_alloc(&aq_ptp->hwts_rx, aq_nic, PTP_HWST_RING_IDX,
     990                 :            :                                      aq_nic->aq_nic_cfg.rxds,
     991                 :          0 :                                      aq_nic->aq_nic_cfg.aq_hw_caps->rxd_size);
     992         [ #  # ]:          0 :         if (!hwts) {
     993                 :          0 :                 err = -ENOMEM;
     994                 :          0 :                 goto err_exit_ptp_rx;
     995                 :            :         }
     996                 :            : 
     997                 :          0 :         err = aq_ptp_skb_ring_init(&aq_ptp->skb_ring, aq_nic->aq_nic_cfg.rxds);
     998         [ #  # ]:          0 :         if (err != 0) {
     999                 :          0 :                 err = -ENOMEM;
    1000                 :          0 :                 goto err_exit_hwts_rx;
    1001                 :            :         }
    1002                 :            : 
    1003                 :          0 :         aq_ptp->ptp_ring_param.vec_idx = aq_ptp->idx_vector;
    1004                 :          0 :         aq_ptp->ptp_ring_param.cpu = aq_ptp->ptp_ring_param.vec_idx +
    1005                 :          0 :                         aq_nic_get_cfg(aq_nic)->aq_rss.base_cpu_number;
    1006                 :          0 :         cpumask_set_cpu(aq_ptp->ptp_ring_param.cpu,
    1007                 :            :                         &aq_ptp->ptp_ring_param.affinity_mask);
    1008                 :            : 
    1009                 :          0 :         return 0;
    1010                 :            : 
    1011                 :            : err_exit_hwts_rx:
    1012                 :          0 :         aq_ring_free(&aq_ptp->hwts_rx);
    1013                 :          0 : err_exit_ptp_rx:
    1014                 :          0 :         aq_ring_free(&aq_ptp->ptp_rx);
    1015                 :          0 : err_exit_ptp_tx:
    1016                 :          0 :         aq_ring_free(&aq_ptp->ptp_tx);
    1017                 :            : err_exit:
    1018                 :            :         return err;
    1019                 :            : }
    1020                 :            : 
    1021                 :          0 : void aq_ptp_ring_free(struct aq_nic_s *aq_nic)
    1022                 :            : {
    1023                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
    1024                 :            : 
    1025         [ #  # ]:          0 :         if (!aq_ptp)
    1026                 :            :                 return;
    1027                 :            : 
    1028                 :          0 :         aq_ring_free(&aq_ptp->ptp_tx);
    1029                 :          0 :         aq_ring_free(&aq_ptp->ptp_rx);
    1030                 :          0 :         aq_ring_free(&aq_ptp->hwts_rx);
    1031                 :            : 
    1032                 :          0 :         aq_ptp_skb_ring_release(&aq_ptp->skb_ring);
    1033                 :            : }
    1034                 :            : 
    1035                 :            : #define MAX_PTP_GPIO_COUNT 4
    1036                 :            : 
    1037                 :            : static struct ptp_clock_info aq_ptp_clock = {
    1038                 :            :         .owner          = THIS_MODULE,
    1039                 :            :         .name           = "atlantic ptp",
    1040                 :            :         .max_adj        = 999999999,
    1041                 :            :         .n_ext_ts       = 0,
    1042                 :            :         .pps            = 0,
    1043                 :            :         .adjfine        = aq_ptp_adjfine,
    1044                 :            :         .adjtime        = aq_ptp_adjtime,
    1045                 :            :         .gettime64      = aq_ptp_gettime,
    1046                 :            :         .settime64      = aq_ptp_settime,
    1047                 :            :         .n_per_out      = 0,
    1048                 :            :         .enable         = aq_ptp_gpio_feature_enable,
    1049                 :            :         .n_pins         = 0,
    1050                 :            :         .verify         = aq_ptp_verify,
    1051                 :            :         .pin_config     = NULL,
    1052                 :            : };
    1053                 :            : 
    1054                 :            : #define ptp_offset_init(__idx, __mbps, __egress, __ingress)   do { \
    1055                 :            :                 ptp_offset[__idx].mbps = (__mbps); \
    1056                 :            :                 ptp_offset[__idx].egress = (__egress); \
    1057                 :            :                 ptp_offset[__idx].ingress = (__ingress); } \
    1058                 :            :                 while (0)
    1059                 :            : 
    1060                 :          0 : static void aq_ptp_offset_init_from_fw(const struct hw_atl_ptp_offset *offsets)
    1061                 :            : {
    1062                 :          0 :         int i;
    1063                 :            : 
    1064                 :            :         /* Load offsets for PTP */
    1065         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ptp_offset); i++) {
    1066   [ #  #  #  #  :          0 :                 switch (i) {
                   #  # ]
    1067                 :            :                 /* 100M */
    1068                 :          0 :                 case ptp_offset_idx_100:
    1069                 :          0 :                         ptp_offset_init(i, 100,
    1070                 :            :                                         offsets->egress_100,
    1071                 :            :                                         offsets->ingress_100);
    1072                 :          0 :                         break;
    1073                 :            :                 /* 1G */
    1074                 :          0 :                 case ptp_offset_idx_1000:
    1075                 :          0 :                         ptp_offset_init(i, 1000,
    1076                 :            :                                         offsets->egress_1000,
    1077                 :            :                                         offsets->ingress_1000);
    1078                 :          0 :                         break;
    1079                 :            :                 /* 2.5G */
    1080                 :          0 :                 case ptp_offset_idx_2500:
    1081                 :          0 :                         ptp_offset_init(i, 2500,
    1082                 :            :                                         offsets->egress_2500,
    1083                 :            :                                         offsets->ingress_2500);
    1084                 :          0 :                         break;
    1085                 :            :                 /* 5G */
    1086                 :          0 :                 case ptp_offset_idx_5000:
    1087                 :          0 :                         ptp_offset_init(i, 5000,
    1088                 :            :                                         offsets->egress_5000,
    1089                 :            :                                         offsets->ingress_5000);
    1090                 :          0 :                         break;
    1091                 :            :                 /* 10G */
    1092                 :          0 :                 case ptp_offset_idx_10000:
    1093                 :          0 :                         ptp_offset_init(i, 10000,
    1094                 :            :                                         offsets->egress_10000,
    1095                 :            :                                         offsets->ingress_10000);
    1096                 :          0 :                         break;
    1097                 :            :                 }
    1098                 :          0 :         }
    1099                 :          0 : }
    1100                 :            : 
    1101                 :          0 : static void aq_ptp_offset_init(const struct hw_atl_ptp_offset *offsets)
    1102                 :            : {
    1103                 :          0 :         memset(ptp_offset, 0, sizeof(ptp_offset));
    1104                 :            : 
    1105                 :          0 :         aq_ptp_offset_init_from_fw(offsets);
    1106                 :            : }
    1107                 :            : 
    1108                 :          0 : static void aq_ptp_gpio_init(struct ptp_clock_info *info,
    1109                 :            :                              struct hw_atl_info *hw_info)
    1110                 :            : {
    1111                 :          0 :         struct ptp_pin_desc pin_desc[MAX_PTP_GPIO_COUNT];
    1112                 :          0 :         u32 extts_pin_cnt = 0;
    1113                 :          0 :         u32 out_pin_cnt = 0;
    1114                 :          0 :         u32 i;
    1115                 :            : 
    1116                 :          0 :         memset(pin_desc, 0, sizeof(pin_desc));
    1117                 :            : 
    1118         [ #  # ]:          0 :         for (i = 0; i < MAX_PTP_GPIO_COUNT - 1; i++) {
    1119                 :          0 :                 if (hw_info->gpio_pin[i] ==
    1120         [ #  # ]:          0 :                     (GPIO_PIN_FUNCTION_PTP0 + out_pin_cnt)) {
    1121                 :          0 :                         snprintf(pin_desc[out_pin_cnt].name,
    1122                 :            :                                  sizeof(pin_desc[out_pin_cnt].name),
    1123                 :            :                                  "AQ_GPIO%d", i);
    1124                 :          0 :                         pin_desc[out_pin_cnt].index = out_pin_cnt;
    1125                 :          0 :                         pin_desc[out_pin_cnt].chan = out_pin_cnt;
    1126                 :          0 :                         pin_desc[out_pin_cnt++].func = PTP_PF_PEROUT;
    1127                 :            :                 }
    1128                 :            :         }
    1129                 :            : 
    1130                 :          0 :         info->n_per_out = out_pin_cnt;
    1131                 :            : 
    1132         [ #  # ]:          0 :         if (hw_info->caps_ex & BIT(CAPS_EX_PHY_CTRL_TS_PIN)) {
    1133                 :          0 :                 extts_pin_cnt += 1;
    1134                 :            : 
    1135                 :          0 :                 snprintf(pin_desc[out_pin_cnt].name,
    1136                 :            :                          sizeof(pin_desc[out_pin_cnt].name),
    1137                 :            :                           "AQ_GPIO%d", out_pin_cnt);
    1138                 :          0 :                 pin_desc[out_pin_cnt].index = out_pin_cnt;
    1139                 :          0 :                 pin_desc[out_pin_cnt].chan = 0;
    1140                 :          0 :                 pin_desc[out_pin_cnt].func = PTP_PF_EXTTS;
    1141                 :            :         }
    1142                 :            : 
    1143                 :          0 :         info->n_pins = out_pin_cnt + extts_pin_cnt;
    1144                 :          0 :         info->n_ext_ts = extts_pin_cnt;
    1145                 :            : 
    1146         [ #  # ]:          0 :         if (!info->n_pins)
    1147                 :          0 :                 return;
    1148                 :            : 
    1149                 :          0 :         info->pin_config = kcalloc(info->n_pins, sizeof(struct ptp_pin_desc),
    1150                 :            :                                    GFP_KERNEL);
    1151                 :            : 
    1152         [ #  # ]:          0 :         if (!info->pin_config)
    1153                 :            :                 return;
    1154                 :            : 
    1155                 :          0 :         memcpy(info->pin_config, &pin_desc,
    1156                 :          0 :                sizeof(struct ptp_pin_desc) * info->n_pins);
    1157                 :            : }
    1158                 :            : 
    1159                 :          0 : void aq_ptp_clock_init(struct aq_nic_s *aq_nic)
    1160                 :            : {
    1161                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
    1162                 :          0 :         struct timespec64 ts;
    1163                 :            : 
    1164                 :          0 :         ktime_get_real_ts64(&ts);
    1165                 :          0 :         aq_ptp_settime(&aq_ptp->ptp_info, &ts);
    1166                 :          0 : }
    1167                 :            : 
    1168                 :            : static void aq_ptp_poll_sync_work_cb(struct work_struct *w);
    1169                 :            : 
    1170                 :         33 : int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
    1171                 :            : {
    1172                 :         33 :         struct hw_atl_utils_mbox mbox;
    1173                 :         33 :         struct ptp_clock *clock;
    1174                 :         33 :         struct aq_ptp_s *aq_ptp;
    1175                 :         33 :         int err = 0;
    1176                 :            : 
    1177         [ -  + ]:         33 :         if (!aq_nic->aq_hw_ops->hw_get_ptp_ts) {
    1178                 :          0 :                 aq_nic->aq_ptp = NULL;
    1179                 :          0 :                 return 0;
    1180                 :            :         }
    1181                 :            : 
    1182         [ +  + ]:         33 :         if (!aq_nic->aq_fw_ops->enable_ptp) {
    1183                 :          5 :                 aq_nic->aq_ptp = NULL;
    1184                 :          5 :                 return 0;
    1185                 :            :         }
    1186                 :            : 
    1187                 :         28 :         hw_atl_utils_mpi_read_stats(aq_nic->aq_hw, &mbox);
    1188                 :            : 
    1189         [ +  - ]:         28 :         if (!(mbox.info.caps_ex & BIT(CAPS_EX_PHY_PTP_EN))) {
    1190                 :         28 :                 aq_nic->aq_ptp = NULL;
    1191                 :         28 :                 return 0;
    1192                 :            :         }
    1193                 :            : 
    1194                 :          0 :         aq_ptp_offset_init(&mbox.info.ptp_offset);
    1195                 :            : 
    1196                 :          0 :         aq_ptp = kzalloc(sizeof(*aq_ptp), GFP_KERNEL);
    1197         [ #  # ]:          0 :         if (!aq_ptp) {
    1198                 :          0 :                 err = -ENOMEM;
    1199                 :          0 :                 goto err_exit;
    1200                 :            :         }
    1201                 :            : 
    1202                 :          0 :         aq_ptp->aq_nic = aq_nic;
    1203                 :            : 
    1204                 :          0 :         spin_lock_init(&aq_ptp->ptp_lock);
    1205                 :          0 :         spin_lock_init(&aq_ptp->ptp_ring_lock);
    1206                 :            : 
    1207                 :          0 :         aq_ptp->ptp_info = aq_ptp_clock;
    1208                 :          0 :         aq_ptp_gpio_init(&aq_ptp->ptp_info, &mbox.info);
    1209                 :          0 :         clock = ptp_clock_register(&aq_ptp->ptp_info, &aq_nic->ndev->dev);
    1210         [ #  # ]:          0 :         if (IS_ERR(clock)) {
    1211                 :          0 :                 netdev_err(aq_nic->ndev, "ptp_clock_register failed\n");
    1212                 :          0 :                 err = PTR_ERR(clock);
    1213                 :          0 :                 goto err_exit;
    1214                 :            :         }
    1215                 :          0 :         aq_ptp->ptp_clock = clock;
    1216                 :          0 :         aq_ptp_tx_timeout_init(&aq_ptp->ptp_tx_timeout);
    1217                 :            : 
    1218                 :          0 :         atomic_set(&aq_ptp->offset_egress, 0);
    1219                 :          0 :         atomic_set(&aq_ptp->offset_ingress, 0);
    1220                 :            : 
    1221                 :          0 :         netif_napi_add(aq_nic_get_ndev(aq_nic), &aq_ptp->napi,
    1222                 :            :                        aq_ptp_poll, AQ_CFG_NAPI_WEIGHT);
    1223                 :            : 
    1224                 :          0 :         aq_ptp->idx_vector = idx_vec;
    1225                 :            : 
    1226                 :          0 :         aq_nic->aq_ptp = aq_ptp;
    1227                 :            : 
    1228                 :            :         /* enable ptp counter */
    1229                 :          0 :         aq_utils_obj_set(&aq_nic->aq_hw->flags, AQ_HW_PTP_AVAILABLE);
    1230                 :          0 :         mutex_lock(&aq_nic->fwreq_mutex);
    1231                 :          0 :         aq_nic->aq_fw_ops->enable_ptp(aq_nic->aq_hw, 1);
    1232                 :          0 :         aq_ptp_clock_init(aq_nic);
    1233                 :          0 :         mutex_unlock(&aq_nic->fwreq_mutex);
    1234                 :            : 
    1235                 :          0 :         INIT_DELAYED_WORK(&aq_ptp->poll_sync, &aq_ptp_poll_sync_work_cb);
    1236                 :          0 :         aq_ptp->eth_type_filter.location =
    1237                 :          0 :                         aq_nic_reserve_filter(aq_nic, aq_rx_filter_ethertype);
    1238                 :          0 :         aq_ptp->udp_filter.location =
    1239                 :          0 :                         aq_nic_reserve_filter(aq_nic, aq_rx_filter_l3l4);
    1240                 :            : 
    1241                 :          0 :         return 0;
    1242                 :            : 
    1243                 :          0 : err_exit:
    1244         [ #  # ]:          0 :         if (aq_ptp)
    1245                 :          0 :                 kfree(aq_ptp->ptp_info.pin_config);
    1246                 :          0 :         kfree(aq_ptp);
    1247                 :          0 :         aq_nic->aq_ptp = NULL;
    1248                 :          0 :         return err;
    1249                 :            : }
    1250                 :            : 
    1251                 :          0 : void aq_ptp_unregister(struct aq_nic_s *aq_nic)
    1252                 :            : {
    1253                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
    1254                 :            : 
    1255         [ #  # ]:          0 :         if (!aq_ptp)
    1256                 :            :                 return;
    1257                 :            : 
    1258                 :          0 :         ptp_clock_unregister(aq_ptp->ptp_clock);
    1259                 :            : }
    1260                 :            : 
    1261                 :          0 : void aq_ptp_free(struct aq_nic_s *aq_nic)
    1262                 :            : {
    1263                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
    1264                 :            : 
    1265         [ #  # ]:          0 :         if (!aq_ptp)
    1266                 :            :                 return;
    1267                 :            : 
    1268                 :          0 :         aq_nic_release_filter(aq_nic, aq_rx_filter_ethertype,
    1269                 :          0 :                               aq_ptp->eth_type_filter.location);
    1270                 :          0 :         aq_nic_release_filter(aq_nic, aq_rx_filter_l3l4,
    1271                 :          0 :                               aq_ptp->udp_filter.location);
    1272                 :          0 :         cancel_delayed_work_sync(&aq_ptp->poll_sync);
    1273                 :            :         /* disable ptp */
    1274                 :          0 :         mutex_lock(&aq_nic->fwreq_mutex);
    1275                 :          0 :         aq_nic->aq_fw_ops->enable_ptp(aq_nic->aq_hw, 0);
    1276                 :          0 :         mutex_unlock(&aq_nic->fwreq_mutex);
    1277                 :            : 
    1278                 :          0 :         kfree(aq_ptp->ptp_info.pin_config);
    1279                 :            : 
    1280                 :          0 :         netif_napi_del(&aq_ptp->napi);
    1281                 :          0 :         kfree(aq_ptp);
    1282                 :          0 :         aq_nic->aq_ptp = NULL;
    1283                 :            : }
    1284                 :            : 
    1285                 :          0 : struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp)
    1286                 :            : {
    1287                 :          0 :         return aq_ptp->ptp_clock;
    1288                 :            : }
    1289                 :            : 
    1290                 :            : /* PTP external GPIO nanoseconds count */
    1291                 :          0 : static uint64_t aq_ptp_get_sync1588_ts(struct aq_nic_s *aq_nic)
    1292                 :            : {
    1293                 :          0 :         u64 ts = 0;
    1294                 :            : 
    1295                 :          0 :         if (aq_nic->aq_hw_ops->hw_get_sync_ts)
    1296                 :          0 :                 aq_nic->aq_hw_ops->hw_get_sync_ts(aq_nic->aq_hw, &ts);
    1297                 :            : 
    1298                 :          0 :         return ts;
    1299                 :            : }
    1300                 :            : 
    1301                 :          0 : static void aq_ptp_start_work(struct aq_ptp_s *aq_ptp)
    1302                 :            : {
    1303         [ #  # ]:          0 :         if (aq_ptp->extts_pin_enabled) {
    1304                 :          0 :                 aq_ptp->poll_timeout_ms = POLL_SYNC_TIMER_MS;
    1305                 :          0 :                 aq_ptp->last_sync1588_ts =
    1306         [ #  # ]:          0 :                                 aq_ptp_get_sync1588_ts(aq_ptp->aq_nic);
    1307         [ #  # ]:          0 :                 schedule_delayed_work(&aq_ptp->poll_sync,
    1308                 :            :                                       msecs_to_jiffies(aq_ptp->poll_timeout_ms));
    1309                 :            :         }
    1310                 :          0 : }
    1311                 :            : 
    1312                 :          0 : int aq_ptp_link_change(struct aq_nic_s *aq_nic)
    1313                 :            : {
    1314                 :          0 :         struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
    1315                 :            : 
    1316         [ #  # ]:          0 :         if (!aq_ptp)
    1317                 :            :                 return 0;
    1318                 :            : 
    1319         [ #  # ]:          0 :         if (aq_nic->aq_hw->aq_link_status.mbps)
    1320                 :          0 :                 aq_ptp_start_work(aq_ptp);
    1321                 :            :         else
    1322                 :          0 :                 cancel_delayed_work_sync(&aq_ptp->poll_sync);
    1323                 :            : 
    1324                 :            :         return 0;
    1325                 :            : }
    1326                 :            : 
    1327                 :            : static bool aq_ptp_sync_ts_updated(struct aq_ptp_s *aq_ptp, u64 *new_ts)
    1328                 :            : {
    1329                 :            :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
    1330                 :            :         u64 sync_ts2;
    1331                 :            :         u64 sync_ts;
    1332                 :            : 
    1333                 :            :         sync_ts = aq_ptp_get_sync1588_ts(aq_nic);
    1334                 :            : 
    1335                 :            :         if (sync_ts != aq_ptp->last_sync1588_ts) {
    1336                 :            :                 sync_ts2 = aq_ptp_get_sync1588_ts(aq_nic);
    1337                 :            :                 if (sync_ts != sync_ts2) {
    1338                 :            :                         sync_ts = sync_ts2;
    1339                 :            :                         sync_ts2 = aq_ptp_get_sync1588_ts(aq_nic);
    1340                 :            :                         if (sync_ts != sync_ts2) {
    1341                 :            :                                 netdev_err(aq_nic->ndev,
    1342                 :            :                                            "%s: Unable to get correct GPIO TS",
    1343                 :            :                                            __func__);
    1344                 :            :                                 sync_ts = 0;
    1345                 :            :                         }
    1346                 :            :                 }
    1347                 :            : 
    1348                 :            :                 *new_ts = sync_ts;
    1349                 :            :                 return true;
    1350                 :            :         }
    1351                 :            :         return false;
    1352                 :            : }
    1353                 :            : 
    1354                 :          0 : static int aq_ptp_check_sync1588(struct aq_ptp_s *aq_ptp)
    1355                 :            : {
    1356                 :          0 :         struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
    1357                 :          0 :         u64 sync_ts;
    1358                 :            : 
    1359                 :            :          /* Sync1588 pin was triggered */
    1360         [ #  # ]:          0 :         if (aq_ptp_sync_ts_updated(aq_ptp, &sync_ts)) {
    1361         [ #  # ]:          0 :                 if (aq_ptp->extts_pin_enabled) {
    1362                 :          0 :                         struct ptp_clock_event ptp_event;
    1363                 :          0 :                         u64 time = 0;
    1364                 :            : 
    1365                 :          0 :                         aq_nic->aq_hw_ops->hw_ts_to_sys_clock(aq_nic->aq_hw,
    1366                 :            :                                                               sync_ts, &time);
    1367                 :          0 :                         ptp_event.index = aq_ptp->ptp_info.n_pins - 1;
    1368                 :          0 :                         ptp_event.timestamp = time;
    1369                 :            : 
    1370                 :          0 :                         ptp_event.type = PTP_CLOCK_EXTTS;
    1371                 :          0 :                         ptp_clock_event(aq_ptp->ptp_clock, &ptp_event);
    1372                 :            :                 }
    1373                 :            : 
    1374                 :          0 :                 aq_ptp->last_sync1588_ts = sync_ts;
    1375                 :            :         }
    1376                 :            : 
    1377                 :          0 :         return 0;
    1378                 :            : }
    1379                 :            : 
    1380                 :          0 : static void aq_ptp_poll_sync_work_cb(struct work_struct *w)
    1381                 :            : {
    1382                 :          0 :         struct delayed_work *dw = to_delayed_work(w);
    1383                 :          0 :         struct aq_ptp_s *aq_ptp = container_of(dw, struct aq_ptp_s, poll_sync);
    1384                 :            : 
    1385                 :          0 :         aq_ptp_check_sync1588(aq_ptp);
    1386                 :            : 
    1387         [ #  # ]:          0 :         if (aq_ptp->extts_pin_enabled) {
    1388         [ #  # ]:          0 :                 unsigned long timeout = msecs_to_jiffies(aq_ptp->poll_timeout_ms);
    1389                 :            : 
    1390                 :          0 :                 schedule_delayed_work(&aq_ptp->poll_sync, timeout);
    1391                 :            :         }
    1392                 :          0 : }

Generated by: LCOV version 1.14