net/ice/base: add ethertype IPv6 check for dummy packet
[dpdk.git] / drivers / net / ice / base / ice_ptp_hw.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2021 Intel Corporation
3  */
4
5 #include "ice_type.h"
6 #include "ice_common.h"
7 #include "ice_ptp_hw.h"
8 #include "ice_ptp_consts.h"
9
10
11 /* Low level functions for interacting with and managing the device clock used
12  * for the Precision Time Protocol.
13  *
14  * The ice hardware represents the current time using three registers:
15  *
16  *    GLTSYN_TIME_H     GLTSYN_TIME_L     GLTSYN_TIME_R
17  *  +---------------+ +---------------+ +---------------+
18  *  |    32 bits    | |    32 bits    | |    32 bits    |
19  *  +---------------+ +---------------+ +---------------+
20  *
21  * The registers are incremented every clock tick using a 40bit increment
22  * value defined over two registers:
23  *
24  *                     GLTSYN_INCVAL_H   GLTSYN_INCVAL_L
25  *                    +---------------+ +---------------+
26  *                    |    8 bit s    | |    32 bits    |
27  *                    +---------------+ +---------------+
28  *
29  * The increment value is added to the GLSTYN_TIME_R and GLSTYN_TIME_L
30  * registers every clock source tick. Depending on the specific device
31  * configuration, the clock source frequency could be one of a number of
32  * values.
33  *
34  * For E810 devices, the increment frequency is 812.5 MHz
35  *
36  * For E822 devices the clock can be derived from different sources, and the
37  * increment has an effective frequency of one of the following:
38  * - 823.4375 MHz
39  * - 783.36 MHz
40  * - 796.875 MHz
41  * - 816 MHz
42  * - 830.078125 MHz
43  * - 783.36 MHz
44  *
45  * The hardware captures timestamps in the PHY for incoming packets, and for
46  * outgoing packets on request. To support this, the PHY maintains a timer
47  * that matches the lower 64 bits of the global source timer.
48  *
49  * In order to ensure that the PHY timers and the source timer are equivalent,
50  * shadow registers are used to prepare the desired initial values. A special
51  * sync command is issued to trigger copying from the shadow registers into
52  * the appropriate source and PHY registers simultaneously.
53  *
54  * The driver supports devices which have different PHYs with subtly different
55  * mechanisms to program and control the timers. We divide the devices into
56  * families named after the first major device, E810 and similar devices, and
57  * E822 and similar devices.
58  *
59  * - E822 based devices have additional support for fine grained Vernier
60  *   calibration which requires significant setup
61  * - The layout of timestamp data in the PHY register blocks is different
62  * - The way timer synchronization commands are issued is different.
63  *
64  * To support this, very low level functions have an e810 or e822 suffix
65  * indicating what type of device they work on. Higher level abstractions for
66  * tasks that can be done on both devices do not have the suffix and will
67  * correctly look up the appropriate low level function when running.
68  *
69  * Functions which only make sense on a single device family may not have
70  * a suitable generic implementation
71  */
72
73 /**
74  * ice_get_ptp_src_clock_index - determine source clock index
75  * @hw: pointer to HW struct
76  *
77  * Determine the source clock index currently in use, based on device
78  * capabilities reported during initialization.
79  */
80 u8 ice_get_ptp_src_clock_index(struct ice_hw *hw)
81 {
82         return hw->func_caps.ts_func_info.tmr_index_assoc;
83 }
84
85 /**
86  * ice_ptp_read_src_incval - Read source timer increment value
87  * @hw: pointer to HW struct
88  *
89  * Read the increment value of the source timer and return it.
90  */
91 u64 ice_ptp_read_src_incval(struct ice_hw *hw)
92 {
93         u32 lo, hi;
94         u8 tmr_idx;
95
96         tmr_idx = ice_get_ptp_src_clock_index(hw);
97
98         lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
99         hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
100
101         return ((u64)(hi & INCVAL_HIGH_M) << 32) | lo;
102 }
103
104 /**
105  * ice_ptp_exec_tmr_cmd - Execute all prepared timer commands
106  * @hw: pointer to HW struct
107  *
108  * Write the SYNC_EXEC_CMD bit to the GLTSYN_CMD_SYNC register, and flush the
109  * write immediately. This triggers the hardware to begin executing all of the
110  * source and PHY timer commands synchronously.
111  */
112 static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
113 {
114         wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD);
115         ice_flush(hw);
116 }
117
118 /* E822 family functions
119  *
120  * The following functions operate on the E822 family of devices.
121  */
122
123 /**
124  * ice_fill_phy_msg_e822 - Fill message data for a PHY register access
125  * @msg: the PHY message buffer to fill in
126  * @port: the port to access
127  * @offset: the register offset
128  */
129 static void
130 ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
131 {
132         int phy_port, phy, quadtype;
133
134         phy_port = port % ICE_PORTS_PER_PHY;
135         phy = port / ICE_PORTS_PER_PHY;
136         quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_NUM_QUAD_TYPE;
137
138         if (quadtype == 0) {
139                 msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
140                 msg->msg_addr_high = P_Q0_H(P_0_BASE + offset, phy_port);
141         } else {
142                 msg->msg_addr_low = P_Q1_L(P_4_BASE + offset, phy_port);
143                 msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
144         }
145
146         if (phy == 0)
147                 msg->dest_dev = rmn_0;
148         else if (phy == 1)
149                 msg->dest_dev = rmn_1;
150         else
151                 msg->dest_dev = rmn_2;
152 }
153
154 /**
155  * ice_is_64b_phy_reg_e822 - Check if this is a 64bit PHY register
156  * @low_addr: the low address to check
157  * @high_addr: on return, contains the high address of the 64bit register
158  *
159  * Checks if the provided low address is one of the known 64bit PHY values
160  * represented as two 32bit registers. If it is, return the appropriate high
161  * register offset to use.
162  */
163 static bool ice_is_64b_phy_reg_e822(u16 low_addr, u16 *high_addr)
164 {
165         switch (low_addr) {
166         case P_REG_PAR_PCS_TX_OFFSET_L:
167                 *high_addr = P_REG_PAR_PCS_TX_OFFSET_U;
168                 return true;
169         case P_REG_PAR_PCS_RX_OFFSET_L:
170                 *high_addr = P_REG_PAR_PCS_RX_OFFSET_U;
171                 return true;
172         case P_REG_PAR_TX_TIME_L:
173                 *high_addr = P_REG_PAR_TX_TIME_U;
174                 return true;
175         case P_REG_PAR_RX_TIME_L:
176                 *high_addr = P_REG_PAR_RX_TIME_U;
177                 return true;
178         case P_REG_TOTAL_TX_OFFSET_L:
179                 *high_addr = P_REG_TOTAL_TX_OFFSET_U;
180                 return true;
181         case P_REG_TOTAL_RX_OFFSET_L:
182                 *high_addr = P_REG_TOTAL_RX_OFFSET_U;
183                 return true;
184         case P_REG_UIX66_10G_40G_L:
185                 *high_addr = P_REG_UIX66_10G_40G_U;
186                 return true;
187         case P_REG_UIX66_25G_100G_L:
188                 *high_addr = P_REG_UIX66_25G_100G_U;
189                 return true;
190         case P_REG_TX_CAPTURE_L:
191                 *high_addr = P_REG_TX_CAPTURE_U;
192                 return true;
193         case P_REG_RX_CAPTURE_L:
194                 *high_addr = P_REG_RX_CAPTURE_U;
195                 return true;
196         case P_REG_TX_TIMER_INC_PRE_L:
197                 *high_addr = P_REG_TX_TIMER_INC_PRE_U;
198                 return true;
199         case P_REG_RX_TIMER_INC_PRE_L:
200                 *high_addr = P_REG_RX_TIMER_INC_PRE_U;
201                 return true;
202         default:
203                 return false;
204         }
205 }
206
207 /**
208  * ice_is_40b_phy_reg_e822 - Check if this is a 40bit PHY register
209  * @low_addr: the low address to check
210  * @high_addr: on return, contains the high address of the 40bit value
211  *
212  * Checks if the provided low address is one of the known 40bit PHY values
213  * split into two registers with the lower 8 bits in the low register and the
214  * upper 32 bits in the high register. If it is, return the appropriate high
215  * register offset to use.
216  */
217 static bool ice_is_40b_phy_reg_e822(u16 low_addr, u16 *high_addr)
218 {
219         switch (low_addr) {
220         case P_REG_TIMETUS_L:
221                 *high_addr = P_REG_TIMETUS_U;
222                 return true;
223         case P_REG_PAR_RX_TUS_L:
224                 *high_addr = P_REG_PAR_RX_TUS_U;
225                 return true;
226         case P_REG_PAR_TX_TUS_L:
227                 *high_addr = P_REG_PAR_TX_TUS_U;
228                 return true;
229         case P_REG_PCS_RX_TUS_L:
230                 *high_addr = P_REG_PCS_RX_TUS_U;
231                 return true;
232         case P_REG_PCS_TX_TUS_L:
233                 *high_addr = P_REG_PCS_TX_TUS_U;
234                 return true;
235         case P_REG_DESK_PAR_RX_TUS_L:
236                 *high_addr = P_REG_DESK_PAR_RX_TUS_U;
237                 return true;
238         case P_REG_DESK_PAR_TX_TUS_L:
239                 *high_addr = P_REG_DESK_PAR_TX_TUS_U;
240                 return true;
241         case P_REG_DESK_PCS_RX_TUS_L:
242                 *high_addr = P_REG_DESK_PCS_RX_TUS_U;
243                 return true;
244         case P_REG_DESK_PCS_TX_TUS_L:
245                 *high_addr = P_REG_DESK_PCS_TX_TUS_U;
246                 return true;
247         default:
248                 return false;
249         }
250 }
251
252 /**
253  * ice_read_phy_reg_e822_lp - Read a PHY register
254  * @hw: pointer to the HW struct
255  * @port: PHY port to read from
256  * @offset: PHY register offset to read
257  * @val: on return, the contents read from the PHY
258  * @lock_sbq: true if the sideband queue lock must be acquired
259  *
260  * Read a PHY register for the given port over the device sideband queue.
261  */
262 static enum ice_status
263 ice_read_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val,
264                          bool lock_sbq)
265 {
266         struct ice_sbq_msg_input msg = {0};
267         enum ice_status status;
268
269         ice_fill_phy_msg_e822(&msg, port, offset);
270         msg.opcode = ice_sbq_msg_rd;
271
272         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
273         if (status) {
274                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
275                           status);
276                 return status;
277         }
278
279         *val = msg.data;
280
281         return ICE_SUCCESS;
282 }
283
284 enum ice_status
285 ice_read_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
286 {
287         return ice_read_phy_reg_e822_lp(hw, port, offset, val, true);
288 }
289
290 /**
291  * ice_read_40b_phy_reg_e822 - Read a 40bit value from PHY registers
292  * @hw: pointer to the HW struct
293  * @port: PHY port to read from
294  * @low_addr: offset of the lower register to read from
295  * @val: on return, the contents of the 40bit value from the PHY registers
296  *
297  * Reads the two registers associated with a 40bit value and returns it in the
298  * val pointer. The offset always specifies the lower register offset to use.
299  * The high offset is looked up. This function only operates on registers
300  * known to be split into a lower 8 bit chunk and an upper 32 bit chunk.
301  */
302 static enum ice_status
303 ice_read_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
304 {
305         enum ice_status status;
306         u32 low, high;
307         u16 high_addr;
308
309         /* Only operate on registers known to be split into two 32bit
310          * registers.
311          */
312         if (!ice_is_40b_phy_reg_e822(low_addr, &high_addr)) {
313                 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
314                           low_addr);
315                 return ICE_ERR_PARAM;
316         }
317
318         status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
319         if (status) {
320                 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
321                           low_addr, status);
322                 return status;
323         }
324
325         status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
326         if (status) {
327                 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
328                           high_addr, status);
329                 return status;
330         }
331
332         *val = (u64)high << P_REG_40B_HIGH_S | (low & P_REG_40B_LOW_M);
333
334         return ICE_SUCCESS;
335 }
336
337 /**
338  * ice_read_64b_phy_reg_e822 - Read a 64bit value from PHY registers
339  * @hw: pointer to the HW struct
340  * @port: PHY port to read from
341  * @low_addr: offset of the lower register to read from
342  * @val: on return, the contents of the 64bit value from the PHY registers
343  *
344  * Reads the two registers associated with a 64bit value and returns it in the
345  * val pointer. The offset always specifies the lower register offset to use.
346  * The high offset is looked up. This function only operates on registers
347  * known to be two parts of a 64bit value.
348  */
349 static enum ice_status
350 ice_read_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
351 {
352         enum ice_status status;
353         u32 low, high;
354         u16 high_addr;
355
356         /* Only operate on registers known to be split into two 32bit
357          * registers.
358          */
359         if (!ice_is_64b_phy_reg_e822(low_addr, &high_addr)) {
360                 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
361                           low_addr);
362                 return ICE_ERR_PARAM;
363         }
364
365         status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
366         if (status) {
367                 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
368                           low_addr, status);
369                 return status;
370         }
371
372         status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
373         if (status) {
374                 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
375                           high_addr, status);
376                 return status;
377         }
378
379         *val = (u64)high << 32 | low;
380
381         return ICE_SUCCESS;
382 }
383
384 /**
385  * ice_write_phy_reg_e822_lp - Write a PHY register
386  * @hw: pointer to the HW struct
387  * @port: PHY port to write to
388  * @offset: PHY register offset to write
389  * @val: The value to write to the register
390  * @lock_sbq: true if the sideband queue lock must be acquired
391  *
392  * Write a PHY register for the given port over the device sideband queue.
393  */
394 static enum ice_status
395 ice_write_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val,
396                           bool lock_sbq)
397 {
398         struct ice_sbq_msg_input msg = {0};
399         enum ice_status status;
400
401         ice_fill_phy_msg_e822(&msg, port, offset);
402         msg.opcode = ice_sbq_msg_wr;
403         msg.data = val;
404
405         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
406         if (status) {
407                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
408                           status);
409                 return status;
410         }
411
412         return ICE_SUCCESS;
413 }
414
415 enum ice_status
416 ice_write_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 val)
417 {
418         return ice_write_phy_reg_e822_lp(hw, port, offset, val, true);
419 }
420
421 /**
422  * ice_write_40b_phy_reg_e822 - Write a 40b value to the PHY
423  * @hw: pointer to the HW struct
424  * @port: port to write to
425  * @low_addr: offset of the low register
426  * @val: 40b value to write
427  *
428  * Write the provided 40b value to the two associated registers by splitting
429  * it up into two chunks, the lower 8 bits and the upper 32 bits.
430  */
431 static enum ice_status
432 ice_write_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
433 {
434         enum ice_status status;
435         u32 low, high;
436         u16 high_addr;
437
438         /* Only operate on registers known to be split into a lower 8 bit
439          * register and an upper 32 bit register.
440          */
441         if (!ice_is_40b_phy_reg_e822(low_addr, &high_addr)) {
442                 ice_debug(hw, ICE_DBG_PTP, "Invalid 40b register addr 0x%08x\n",
443                           low_addr);
444                 return ICE_ERR_PARAM;
445         }
446
447         low = (u32)(val & P_REG_40B_LOW_M);
448         high = (u32)(val >> P_REG_40B_HIGH_S);
449
450         status = ice_write_phy_reg_e822(hw, port, low_addr, low);
451         if (status) {
452                 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
453                           low_addr, status);
454                 return status;
455         }
456
457         status = ice_write_phy_reg_e822(hw, port, high_addr, high);
458         if (status) {
459                 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
460                           high_addr, status);
461                 return status;
462         }
463
464         return ICE_SUCCESS;
465 }
466
467 /**
468  * ice_write_64b_phy_reg_e822 - Write a 64bit value to PHY registers
469  * @hw: pointer to the HW struct
470  * @port: PHY port to read from
471  * @low_addr: offset of the lower register to read from
472  * @val: the contents of the 64bit value to write to PHY
473  *
474  * Write the 64bit value to the two associated 32bit PHY registers. The offset
475  * is always specified as the lower register, and the high address is looked
476  * up. This function only operates on registers known to be two parts of
477  * a 64bit value.
478  */
479 static enum ice_status
480 ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
481 {
482         enum ice_status status;
483         u32 low, high;
484         u16 high_addr;
485
486         /* Only operate on registers known to be split into two 32bit
487          * registers.
488          */
489         if (!ice_is_64b_phy_reg_e822(low_addr, &high_addr)) {
490                 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
491                           low_addr);
492                 return ICE_ERR_PARAM;
493         }
494
495         low = ICE_LO_DWORD(val);
496         high = ICE_HI_DWORD(val);
497
498         status = ice_write_phy_reg_e822(hw, port, low_addr, low);
499         if (status) {
500                 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
501                           low_addr, status);
502                 return status;
503         }
504
505         status = ice_write_phy_reg_e822(hw, port, high_addr, high);
506         if (status) {
507                 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
508                           high_addr, status);
509                 return status;
510         }
511
512         return ICE_SUCCESS;
513 }
514
515 /**
516  * ice_fill_quad_msg_e822 - Fill message data for quad register access
517  * @msg: the PHY message buffer to fill in
518  * @quad: the quad to access
519  * @offset: the register offset
520  *
521  * Fill a message buffer for accessing a register in a quad shared between
522  * multiple PHYs.
523  */
524 static void
525 ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
526 {
527         u32 addr;
528
529         msg->dest_dev = rmn_0;
530
531         if ((quad % ICE_NUM_QUAD_TYPE) == 0)
532                 addr = Q_0_BASE + offset;
533         else
534                 addr = Q_1_BASE + offset;
535
536         msg->msg_addr_low = ICE_LO_WORD(addr);
537         msg->msg_addr_high = ICE_HI_WORD(addr);
538 }
539
540 /**
541  * ice_read_quad_reg_e822_lp - Read a PHY quad register
542  * @hw: pointer to the HW struct
543  * @quad: quad to read from
544  * @offset: quad register offset to read
545  * @val: on return, the contents read from the quad
546  * @lock_sbq: true if the sideband queue lock must be acquired
547  *
548  * Read a quad register over the device sideband queue. Quad registers are
549  * shared between multiple PHYs.
550  */
551 static enum ice_status
552 ice_read_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 *val,
553                           bool lock_sbq)
554 {
555         struct ice_sbq_msg_input msg = {0};
556         enum ice_status status;
557
558         if (quad >= ICE_MAX_QUAD)
559                 return ICE_ERR_PARAM;
560
561         ice_fill_quad_msg_e822(&msg, quad, offset);
562         msg.opcode = ice_sbq_msg_rd;
563
564         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
565         if (status) {
566                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
567                           status);
568                 return status;
569         }
570
571         *val = msg.data;
572
573         return ICE_SUCCESS;
574 }
575
576 enum ice_status
577 ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
578 {
579         return ice_read_quad_reg_e822_lp(hw, quad, offset, val, true);
580 }
581
582 /**
583  * ice_write_quad_reg_e822_lp - Write a PHY quad register
584  * @hw: pointer to the HW struct
585  * @quad: quad to write to
586  * @offset: quad register offset to write
587  * @val: The value to write to the register
588  * @lock_sbq: true if the sideband queue lock must be acquired
589  *
590  * Write a quad register over the device sideband queue. Quad registers are
591  * shared between multiple PHYs.
592  */
593 static enum ice_status
594 ice_write_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 val,
595                            bool lock_sbq)
596 {
597         struct ice_sbq_msg_input msg = {0};
598         enum ice_status status;
599
600         if (quad >= ICE_MAX_QUAD)
601                 return ICE_ERR_PARAM;
602
603         ice_fill_quad_msg_e822(&msg, quad, offset);
604         msg.opcode = ice_sbq_msg_wr;
605         msg.data = val;
606
607         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
608         if (status) {
609                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
610                           status);
611                 return status;
612         }
613
614         return ICE_SUCCESS;
615 }
616
617 enum ice_status
618 ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
619 {
620         return ice_write_quad_reg_e822_lp(hw, quad, offset, val, true);
621 }
622
623 /**
624  * ice_read_phy_tstamp_e822 - Read a PHY timestamp out of the quad block
625  * @hw: pointer to the HW struct
626  * @quad: the quad to read from
627  * @idx: the timestamp index to read
628  * @tstamp: on return, the 40bit timestamp value
629  *
630  * Read a 40bit timestamp value out of the two associated registers in the
631  * quad memory block that is shared between the internal PHYs of the E822
632  * family of devices.
633  */
634 static enum ice_status
635 ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
636 {
637         enum ice_status status;
638         u16 lo_addr, hi_addr;
639         u32 lo, hi;
640
641         lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
642         hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
643
644         status = ice_read_quad_reg_e822(hw, quad, lo_addr, &lo);
645         if (status) {
646                 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
647                           status);
648                 return status;
649         }
650
651         status = ice_read_quad_reg_e822(hw, quad, hi_addr, &hi);
652         if (status) {
653                 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
654                           status);
655                 return status;
656         }
657
658         /* For E822 based internal PHYs, the timestamp is reported with the
659          * lower 8 bits in the low register, and the upper 32 bits in the high
660          * register.
661          */
662         *tstamp = ((u64)hi) << TS_PHY_HIGH_S | ((u64)lo & TS_PHY_LOW_M);
663
664         return ICE_SUCCESS;
665 }
666
667 /**
668  * ice_clear_phy_tstamp_e822 - Clear a timestamp from the quad block
669  * @hw: pointer to the HW struct
670  * @quad: the quad to read from
671  * @idx: the timestamp index to reset
672  *
673  * Clear a timestamp, resetting its valid bit, from the PHY quad block that is
674  * shared between the internal PHYs on the E822 devices.
675  */
676 static enum ice_status
677 ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
678 {
679         enum ice_status status;
680         u16 lo_addr, hi_addr;
681
682         lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
683         hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
684
685         status = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
686         if (status) {
687                 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
688                           status);
689                 return status;
690         }
691
692         status = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
693         if (status) {
694                 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
695                           status);
696                 return status;
697         }
698
699         return ICE_SUCCESS;
700 }
701
702 /**
703  * ice_ptp_prep_phy_time_e822 - Prepare PHY port with initial time
704  * @hw: pointer to the HW struct
705  * @time: Time to initialize the PHY port clocks to
706  *
707  * Program the PHY port registers with a new initial time value. The port
708  * clock will be initialized once the driver issues an INIT_TIME sync
709  * command. The time value is the upper 32 bits of the PHY timer, usually in
710  * units of nominal nanoseconds.
711  */
712 static enum ice_status
713 ice_ptp_prep_phy_time_e822(struct ice_hw *hw, u32 time)
714 {
715         enum ice_status status;
716         u64 phy_time;
717         u8 port;
718
719         /* The time represents the upper 32 bits of the PHY timer, so we need
720          * to shift to account for this when programming.
721          */
722         phy_time = (u64)time << 32;
723
724         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
725
726                 /* Tx case */
727                 status = ice_write_64b_phy_reg_e822(hw, port,
728                                                     P_REG_TX_TIMER_INC_PRE_L,
729                                                     phy_time);
730                 if (status)
731                         goto exit_err;
732
733                 /* Rx case */
734                 status = ice_write_64b_phy_reg_e822(hw, port,
735                                                     P_REG_RX_TIMER_INC_PRE_L,
736                                                     phy_time);
737                 if (status)
738                         goto exit_err;
739         }
740
741         return ICE_SUCCESS;
742
743 exit_err:
744         ice_debug(hw, ICE_DBG_PTP, "Failed to write init time for port %u, status %d\n",
745                   port, status);
746
747         return status;
748 }
749
750 /**
751  * ice_ptp_prep_port_adj_e822 - Prepare a single port for time adjust
752  * @hw: pointer to HW struct
753  * @port: Port number to be programmed
754  * @time: time in cycles to adjust the port Tx and Rx clocks
755  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
756  *            sq_lock has already been locked at a higher level
757  *
758  * Program the port for an atomic adjustment by writing the Tx and Rx timer
759  * registers. The atomic adjustment won't be completed until the driver issues
760  * an ADJ_TIME command.
761  *
762  * Note that time is not in units of nanoseconds. It is in clock time
763  * including the lower sub-nanosecond portion of the port timer.
764  *
765  * Negative adjustments are supported using 2s complement arithmetic.
766  */
767 enum ice_status
768 ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time,
769                            bool lock_sbq)
770 {
771         enum ice_status status;
772         u32 l_time, u_time;
773
774         l_time = ICE_LO_DWORD(time);
775         u_time = ICE_HI_DWORD(time);
776
777         /* Tx case */
778         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_L,
779                                            l_time, lock_sbq);
780         if (status)
781                 goto exit_err;
782
783         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_U,
784                                            u_time, lock_sbq);
785         if (status)
786                 goto exit_err;
787
788         /* Rx case */
789         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_L,
790                                            l_time, lock_sbq);
791         if (status)
792                 goto exit_err;
793
794         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_U,
795                                            u_time, lock_sbq);
796         if (status)
797                 goto exit_err;
798
799         return ICE_SUCCESS;
800
801 exit_err:
802         ice_debug(hw, ICE_DBG_PTP, "Failed to write time adjust for port %u, status %d\n",
803                   port, status);
804         return status;
805 }
806
807 /**
808  * ice_ptp_prep_phy_adj_e822 - Prep PHY ports for a time adjustment
809  * @hw: pointer to HW struct
810  * @adj: adjustment in nanoseconds
811  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
812  *            sq_lock has already been locked at a higher level
813  *
814  * Prepare the PHY ports for an atomic time adjustment by programming the PHY
815  * Tx and Rx port registers. The actual adjustment is completed by issuing an
816  * ADJ_TIME or ADJ_TIME_AT_TIME sync command.
817  */
818 static enum ice_status
819 ice_ptp_prep_phy_adj_e822(struct ice_hw *hw, s32 adj, bool lock_sbq)
820 {
821         s64 cycles;
822         u8 port;
823
824         /* The port clock supports adjustment of the sub-nanosecond portion of
825          * the clock. We shift the provided adjustment in nanoseconds to
826          * calculate the appropriate adjustment to program into the PHY ports.
827          */
828         if (adj > 0)
829                 cycles = (s64)adj << 32;
830         else
831                 cycles = -(((s64)-adj) << 32);
832
833         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
834                 enum ice_status status;
835
836                 status = ice_ptp_prep_port_adj_e822(hw, port, cycles,
837                                                     lock_sbq);
838                 if (status)
839                         return status;
840         }
841
842         return ICE_SUCCESS;
843 }
844
845 /**
846  * ice_ptp_prep_phy_incval_e822 - Prepare PHY ports for time adjustment
847  * @hw: pointer to HW struct
848  * @incval: new increment value to prepare
849  *
850  * Prepare each of the PHY ports for a new increment value by programming the
851  * port's TIMETUS registers. The new increment value will be updated after
852  * issuing an INIT_INCVAL command.
853  */
854 static enum ice_status
855 ice_ptp_prep_phy_incval_e822(struct ice_hw *hw, u64 incval)
856 {
857         enum ice_status status;
858         u8 port;
859
860         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
861                 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L,
862                                                     incval);
863                 if (status)
864                         goto exit_err;
865         }
866
867         return ICE_SUCCESS;
868
869 exit_err:
870         ice_debug(hw, ICE_DBG_PTP, "Failed to write incval for port %u, status %d\n",
871                   port, status);
872
873         return status;
874 }
875
876 /**
877  * ice_ptp_read_phy_incval_e822 - Read a PHY port's current incval
878  * @hw: pointer to the HW struct
879  * @port: the port to read
880  * @incval: on return, the time_clk_cyc incval for this port
881  *
882  * Read the time_clk_cyc increment value for a given PHY port.
883  */
884 enum ice_status
885 ice_ptp_read_phy_incval_e822(struct ice_hw *hw, u8 port, u64 *incval)
886 {
887         enum ice_status status;
888
889         status = ice_read_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
890         if (status) {
891                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TIMETUS_L, status %d\n",
892                           status);
893                 return status;
894         }
895
896         ice_debug(hw, ICE_DBG_PTP, "read INCVAL = 0x%016llx\n",
897                   (unsigned long long)*incval);
898
899         return ICE_SUCCESS;
900 }
901
902 /**
903  * ice_ptp_prep_phy_adj_target_e822 - Prepare PHY for adjust at target time
904  * @hw: pointer to HW struct
905  * @target_time: target time to program
906  *
907  * Program the PHY port Tx and Rx TIMER_CNT_ADJ registers used for the
908  * ADJ_TIME_AT_TIME command. This should be used in conjunction with
909  * ice_ptp_prep_phy_adj_e822 to program an atomic adjustment that is
910  * delayed until a specified target time.
911  *
912  * Note that a target time adjustment is not currently supported on E810
913  * devices.
914  */
915 static enum ice_status
916 ice_ptp_prep_phy_adj_target_e822(struct ice_hw *hw, u32 target_time)
917 {
918         enum ice_status status;
919         u8 port;
920
921         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
922
923                 /* Tx case */
924                 /* No sub-nanoseconds data */
925                 status = ice_write_phy_reg_e822_lp(hw, port,
926                                                    P_REG_TX_TIMER_CNT_ADJ_L,
927                                                    0, true);
928                 if (status)
929                         goto exit_err;
930
931                 status = ice_write_phy_reg_e822_lp(hw, port,
932                                                    P_REG_TX_TIMER_CNT_ADJ_U,
933                                                    target_time, true);
934                 if (status)
935                         goto exit_err;
936
937                 /* Rx case */
938                 /* No sub-nanoseconds data */
939                 status = ice_write_phy_reg_e822_lp(hw, port,
940                                                    P_REG_RX_TIMER_CNT_ADJ_L,
941                                                    0, true);
942                 if (status)
943                         goto exit_err;
944
945                 status = ice_write_phy_reg_e822_lp(hw, port,
946                                                    P_REG_RX_TIMER_CNT_ADJ_U,
947                                                    target_time, true);
948                 if (status)
949                         goto exit_err;
950         }
951
952         return ICE_SUCCESS;
953
954 exit_err:
955         ice_debug(hw, ICE_DBG_PTP, "Failed to write target time for port %u, status %d\n",
956                   port, status);
957
958         return status;
959 }
960
961 /**
962  * ice_ptp_read_port_capture - Read a port's local time capture
963  * @hw: pointer to HW struct
964  * @port: Port number to read
965  * @tx_ts: on return, the Tx port time capture
966  * @rx_ts: on return, the Rx port time capture
967  *
968  * Read the port's Tx and Rx local time capture values.
969  *
970  * Note this has no equivalent for the E810 devices.
971  */
972 enum ice_status
973 ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts)
974 {
975         enum ice_status status;
976
977         /* Tx case */
978         status = ice_read_64b_phy_reg_e822(hw, port, P_REG_TX_CAPTURE_L, tx_ts);
979         if (status) {
980                 ice_debug(hw, ICE_DBG_PTP, "Failed to read REG_TX_CAPTURE, status %d\n",
981                           status);
982                 return status;
983         }
984
985         ice_debug(hw, ICE_DBG_PTP, "tx_init = 0x%016llx\n",
986                   (unsigned long long)*tx_ts);
987
988         /* Rx case */
989         status = ice_read_64b_phy_reg_e822(hw, port, P_REG_RX_CAPTURE_L, rx_ts);
990         if (status) {
991                 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_CAPTURE, status %d\n",
992                           status);
993                 return status;
994         }
995
996         ice_debug(hw, ICE_DBG_PTP, "rx_init = 0x%016llx\n",
997                   (unsigned long long)*rx_ts);
998
999         return ICE_SUCCESS;
1000 }
1001
1002 /**
1003  * ice_ptp_one_port_cmd - Prepare a single PHY port for a timer command
1004  * @hw: pointer to HW struct
1005  * @port: Port to which cmd has to be sent
1006  * @cmd: Command to be sent to the port
1007  * @lock_sbq: true if the sideband queue lock must be acquired
1008  *
1009  * Prepare the requested port for an upcoming timer sync command.
1010  *
1011  * Note there is no equivalent of this operation on E810, as that device
1012  * always handles all external PHYs internally.
1013  */
1014 enum ice_status
1015 ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd,
1016                      bool lock_sbq)
1017 {
1018         enum ice_status status;
1019         u32 cmd_val, val;
1020         u8 tmr_idx;
1021
1022         tmr_idx = ice_get_ptp_src_clock_index(hw);
1023         cmd_val = tmr_idx << SEL_PHY_SRC;
1024         switch (cmd) {
1025         case INIT_TIME:
1026                 cmd_val |= PHY_CMD_INIT_TIME;
1027                 break;
1028         case INIT_INCVAL:
1029                 cmd_val |= PHY_CMD_INIT_INCVAL;
1030                 break;
1031         case ADJ_TIME:
1032                 cmd_val |= PHY_CMD_ADJ_TIME;
1033                 break;
1034         case ADJ_TIME_AT_TIME:
1035                 cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
1036                 break;
1037         case READ_TIME:
1038                 cmd_val |= PHY_CMD_READ_TIME;
1039                 break;
1040         default:
1041                 ice_warn(hw, "Unknown timer command %u\n", cmd);
1042                 return ICE_ERR_PARAM;
1043         }
1044
1045         /* Tx case */
1046         /* Read, modify, write */
1047         status = ice_read_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, &val,
1048                                           lock_sbq);
1049         if (status) {
1050                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_TMR_CMD, status %d\n",
1051                           status);
1052                 return status;
1053         }
1054
1055         /* Modify necessary bits only and perform write */
1056         val &= ~TS_CMD_MASK;
1057         val |= cmd_val;
1058
1059         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, val,
1060                                            lock_sbq);
1061         if (status) {
1062                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_TMR_CMD, status %d\n",
1063                           status);
1064                 return status;
1065         }
1066
1067         /* Rx case */
1068         /* Read, modify, write */
1069         status = ice_read_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, &val,
1070                                           lock_sbq);
1071         if (status) {
1072                 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_TMR_CMD, status %d\n",
1073                           status);
1074                 return status;
1075         }
1076
1077         /* Modify necessary bits only and perform write */
1078         val &= ~TS_CMD_MASK;
1079         val |= cmd_val;
1080
1081         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, val,
1082                                            lock_sbq);
1083         if (status) {
1084                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back RX_TMR_CMD, status %d\n",
1085                           status);
1086                 return status;
1087         }
1088
1089         return ICE_SUCCESS;
1090 }
1091
1092 /**
1093  * ice_ptp_port_cmd_e822 - Prepare all ports for a timer command
1094  * @hw: pointer to the HW struct
1095  * @cmd: timer command to prepare
1096  * @lock_sbq: true if the sideband queue lock must  be acquired
1097  *
1098  * Prepare all ports connected to this device for an upcoming timer sync
1099  * command.
1100  */
1101 static enum ice_status
1102 ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1103                       bool lock_sbq)
1104 {
1105         u8 port;
1106
1107         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1108                 enum ice_status status;
1109
1110                 status = ice_ptp_one_port_cmd(hw, port, cmd, lock_sbq);
1111                 if (status)
1112                         return status;
1113         }
1114
1115         return ICE_SUCCESS;
1116 }
1117
1118 /* E822 Vernier calibration functions
1119  *
1120  * The following functions are used as part of the vernier calibration of
1121  * a port. This calibration increases the precision of the timestamps on the
1122  * port.
1123  */
1124
1125 /**
1126  * ice_ptp_set_vernier_wl - Set the window length for vernier calibration
1127  * @hw: pointer to the HW struct
1128  *
1129  * Set the window length used for the vernier port calibration process.
1130  */
1131 enum ice_status ice_ptp_set_vernier_wl(struct ice_hw *hw)
1132 {
1133         u8 port;
1134
1135         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1136                 enum ice_status status;
1137
1138                 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_WL,
1139                                                    PTP_VERNIER_WL, true);
1140                 if (status) {
1141                         ice_debug(hw, ICE_DBG_PTP, "Failed to set vernier window length for port %u, status %d\n",
1142                                   port, status);
1143                         return status;
1144                 }
1145         }
1146
1147         return ICE_SUCCESS;
1148 }
1149
1150 /**
1151  * ice_phy_get_speed_and_fec_e822 - Get link speed and FEC based on serdes mode
1152  * @hw: pointer to HW struct
1153  * @port: the port to read from
1154  * @link_out: if non-NULL, holds link speed on success
1155  * @fec_out: if non-NULL, holds FEC algorithm on success
1156  *
1157  * Read the serdes data for the PHY port and extract the link speed and FEC
1158  * algorithm.
1159  */
1160 enum ice_status
1161 ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
1162                                enum ice_ptp_link_spd *link_out,
1163                                enum ice_ptp_fec_mode *fec_out)
1164 {
1165         enum ice_ptp_link_spd link;
1166         enum ice_ptp_fec_mode fec;
1167         enum ice_status status;
1168         u32 serdes;
1169
1170         status = ice_read_phy_reg_e822(hw, port, P_REG_LINK_SPEED, &serdes);
1171         if (status) {
1172                 ice_debug(hw, ICE_DBG_PTP, "Failed to read serdes info\n");
1173                 return status;
1174         }
1175
1176         /* Determine the FEC algorithm */
1177         fec = (enum ice_ptp_fec_mode)P_REG_LINK_SPEED_FEC_MODE(serdes);
1178
1179         serdes &= P_REG_LINK_SPEED_SERDES_M;
1180
1181         /* Determine the link speed */
1182         if (fec == ICE_PTP_FEC_MODE_RS_FEC) {
1183                 switch (serdes) {
1184                 case ICE_PTP_SERDES_25G:
1185                         link = ICE_PTP_LNK_SPD_25G_RS;
1186                         break;
1187                 case ICE_PTP_SERDES_50G:
1188                         link = ICE_PTP_LNK_SPD_50G_RS;
1189                         break;
1190                 case ICE_PTP_SERDES_100G:
1191                         link = ICE_PTP_LNK_SPD_100G_RS;
1192                         break;
1193                 default:
1194                         return ICE_ERR_OUT_OF_RANGE;
1195                 }
1196         } else {
1197                 switch (serdes) {
1198                 case ICE_PTP_SERDES_1G:
1199                         link = ICE_PTP_LNK_SPD_1G;
1200                         break;
1201                 case ICE_PTP_SERDES_10G:
1202                         link = ICE_PTP_LNK_SPD_10G;
1203                         break;
1204                 case ICE_PTP_SERDES_25G:
1205                         link = ICE_PTP_LNK_SPD_25G;
1206                         break;
1207                 case ICE_PTP_SERDES_40G:
1208                         link = ICE_PTP_LNK_SPD_40G;
1209                         break;
1210                 case ICE_PTP_SERDES_50G:
1211                         link = ICE_PTP_LNK_SPD_50G;
1212                         break;
1213                 default:
1214                         return ICE_ERR_OUT_OF_RANGE;
1215                 }
1216         }
1217
1218         if (link_out)
1219                 *link_out = link;
1220         if (fec_out)
1221                 *fec_out = fec;
1222
1223         return ICE_SUCCESS;
1224 }
1225
1226 /**
1227  * ice_phy_cfg_lane_e822 - Configure PHY quad for single/multi-lane timestamp
1228  * @hw: pointer to HW struct
1229  * @port: to configure the quad for
1230  */
1231 void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port)
1232 {
1233         enum ice_ptp_link_spd link_spd;
1234         enum ice_status status;
1235         u32 val;
1236         u8 quad;
1237
1238         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, NULL);
1239         if (status) {
1240                 ice_debug(hw, ICE_DBG_PTP, "Failed to get PHY link speed, status %d\n",
1241                           status);
1242                 return;
1243         }
1244
1245         quad = port / ICE_PORTS_PER_QUAD;
1246
1247         status = ice_read_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
1248         if (status) {
1249                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_MEM_GLB_CFG, status %d\n",
1250                           status);
1251                 return;
1252         }
1253
1254         if (link_spd >= ICE_PTP_LNK_SPD_40G)
1255                 val &= ~Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1256         else
1257                 val |= Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1258
1259         status = ice_write_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, val);
1260         if (status) {
1261                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_MEM_GBL_CFG, status %d\n",
1262                           status);
1263                 return;
1264         }
1265 }
1266
1267 /* E810 functions
1268  *
1269  * The following functions operate on the E810 series devices which use
1270  * a separate external PHY.
1271  */
1272
1273 /**
1274  * ice_read_phy_reg_e810_lp - Read register from external PHY on E810
1275  * @hw: pointer to the HW struct
1276  * @addr: the address to read from
1277  * @val: On return, the value read from the PHY
1278  * @lock_sbq: true if the sideband queue lock must be acquired
1279  *
1280  * Read a register from the external PHY on the E810 device.
1281  */
1282 static enum ice_status
1283 ice_read_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 *val, bool lock_sbq)
1284 {
1285         struct ice_sbq_msg_input msg = {0};
1286         enum ice_status status;
1287
1288         msg.msg_addr_low = ICE_LO_WORD(addr);
1289         msg.msg_addr_high = ICE_HI_WORD(addr);
1290         msg.opcode = ice_sbq_msg_rd;
1291         msg.dest_dev = rmn_0;
1292
1293         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
1294         if (status) {
1295                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
1296                           status);
1297                 return status;
1298         }
1299
1300         *val = msg.data;
1301
1302         return ICE_SUCCESS;
1303 }
1304
1305 static enum ice_status
1306 ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
1307 {
1308         return ice_read_phy_reg_e810_lp(hw, addr, val, true);
1309 }
1310
1311 /**
1312  * ice_write_phy_reg_e810_lp - Write register on external PHY on E810
1313  * @hw: pointer to the HW struct
1314  * @addr: the address to writem to
1315  * @val: the value to write to the PHY
1316  * @lock_sbq: true if the sideband queue lock must be acquired
1317  *
1318  * Write a value to a register of the external PHY on the E810 device.
1319  */
1320 static enum ice_status
1321 ice_write_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 val, bool lock_sbq)
1322 {
1323         struct ice_sbq_msg_input msg = {0};
1324         enum ice_status status;
1325
1326         msg.msg_addr_low = ICE_LO_WORD(addr);
1327         msg.msg_addr_high = ICE_HI_WORD(addr);
1328         msg.opcode = ice_sbq_msg_wr;
1329         msg.dest_dev = rmn_0;
1330         msg.data = val;
1331
1332         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
1333         if (status) {
1334                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
1335                           status);
1336                 return status;
1337         }
1338
1339         return ICE_SUCCESS;
1340 }
1341
1342 static enum ice_status
1343 ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
1344 {
1345         return ice_write_phy_reg_e810_lp(hw, addr, val, true);
1346 }
1347
1348 /**
1349  * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY
1350  * @hw: pointer to the HW struct
1351  * @lport: the lport to read from
1352  * @idx: the timestamp index to read
1353  * @tstamp: on return, the 40bit timestamp value
1354  *
1355  * Read a 40bit timestamp value out of the timestamp block of the external PHY
1356  * on the E810 device.
1357  */
1358 static enum ice_status
1359 ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
1360 {
1361         enum ice_status status;
1362         u32 lo_addr, hi_addr, lo, hi;
1363
1364         lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
1365         hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
1366
1367         status = ice_read_phy_reg_e810(hw, lo_addr, &lo);
1368         if (status) {
1369                 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
1370                           status);
1371                 return status;
1372         }
1373
1374         status = ice_read_phy_reg_e810(hw, hi_addr, &hi);
1375         if (status) {
1376                 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
1377                           status);
1378                 return status;
1379         }
1380
1381         /* For E810 devices, the timestamp is reported with the lower 32 bits
1382          * in the low register, and the upper 8 bits in the high register.
1383          */
1384         *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
1385
1386         return ICE_SUCCESS;
1387 }
1388
1389 /**
1390  * ice_clear_phy_tstamp_e810 - Clear a timestamp from the external PHY
1391  * @hw: pointer to the HW struct
1392  * @lport: the lport to read from
1393  * @idx: the timestamp index to reset
1394  *
1395  * Clear a timestamp, resetting its valid bit, from the timestamp block of the
1396  * external PHY on the E810 device.
1397  */
1398 static enum ice_status
1399 ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
1400 {
1401         enum ice_status status;
1402         u32 lo_addr, hi_addr;
1403
1404         lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
1405         hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
1406
1407         status = ice_write_phy_reg_e810(hw, lo_addr, 0);
1408         if (status) {
1409                 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
1410                           status);
1411                 return status;
1412         }
1413
1414         status = ice_write_phy_reg_e810(hw, hi_addr, 0);
1415         if (status) {
1416                 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
1417                           status);
1418                 return status;
1419         }
1420
1421         return ICE_SUCCESS;
1422 }
1423
1424 /**
1425  * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
1426  * @hw: pointer to HW struct
1427  *
1428  * Enable the timesync PTP functionality for the external PHY connected to
1429  * this function.
1430  *
1431  * Note there is no equivalent function needed on E822 based devices.
1432  */
1433 enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw)
1434 {
1435         enum ice_status status;
1436         u8 tmr_idx;
1437
1438         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1439         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
1440                                         GLTSYN_ENA_TSYN_ENA_M);
1441         if (status)
1442                 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
1443                           status);
1444
1445         return status;
1446 }
1447
1448 /**
1449  * ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
1450  * @hw: Board private structure
1451  * @time: Time to initialize the PHY port clock to
1452  *
1453  * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the
1454  * initial clock time. The time will not actually be programmed until the
1455  * driver issues an INIT_TIME command.
1456  *
1457  * The time value is the upper 32 bits of the PHY timer, usually in units of
1458  * nominal nanoseconds.
1459  */
1460 static enum ice_status ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
1461 {
1462         enum ice_status status;
1463         u8 tmr_idx;
1464
1465         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1466         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
1467         if (status) {
1468                 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
1469                           status);
1470                 return status;
1471         }
1472
1473         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
1474         if (status) {
1475                 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
1476                           status);
1477                 return status;
1478         }
1479
1480         return ICE_SUCCESS;
1481 }
1482
1483 /**
1484  * ice_ptp_prep_phy_adj_e810 - Prep PHY port for a time adjustment
1485  * @hw: pointer to HW struct
1486  * @adj: adjustment value to program
1487  * @lock_sbq: true if the sideband queue luck must be acquired
1488  *
1489  * Prepare the PHY port for an atomic adjustment by programming the PHY
1490  * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual adjustment
1491  * is completed by issuing an ADJ_TIME sync command.
1492  *
1493  * The adjustment value only contains the portion used for the upper 32bits of
1494  * the PHY timer, usually in units of nominal nanoseconds. Negative
1495  * adjustments are supported using 2s complement arithmetic.
1496  */
1497 static enum ice_status
1498 ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj, bool lock_sbq)
1499 {
1500         enum ice_status status;
1501         u8 tmr_idx;
1502
1503         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1504
1505         /* Adjustments are represented as signed 2's complement values in
1506          * nanoseconds. Sub-nanosecond adjustment is not supported.
1507          */
1508         status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_L(tmr_idx),
1509                                            0, lock_sbq);
1510         if (status) {
1511                 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
1512                           status);
1513                 return status;
1514         }
1515
1516         status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_H(tmr_idx),
1517                                            adj, lock_sbq);
1518         if (status) {
1519                 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
1520                           status);
1521                 return status;
1522         }
1523
1524         return ICE_SUCCESS;
1525 }
1526
1527 /**
1528  * ice_ptp_prep_phy_incval_e810 - Prep PHY port increment value change
1529  * @hw: pointer to HW struct
1530  * @incval: The new 40bit increment value to prepare
1531  *
1532  * Prepare the PHY port for a new increment value by programming the PHY
1533  * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual change is
1534  * completed by issuing an INIT_INCVAL command.
1535  */
1536 static enum ice_status
1537 ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
1538 {
1539         enum ice_status status;
1540         u32 high, low;
1541         u8 tmr_idx;
1542
1543         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1544         low = ICE_LO_DWORD(incval);
1545         high = ICE_HI_DWORD(incval);
1546
1547         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
1548         if (status) {
1549                 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
1550                           status);
1551                 return status;
1552         }
1553
1554         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
1555         if (status) {
1556                 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
1557                           status);
1558                 return status;
1559         }
1560
1561         return ICE_SUCCESS;
1562 }
1563
1564 /**
1565  * ice_ptp_prep_phy_adj_target_e810 - Prepare PHY port with adjust target
1566  * @hw: Board private structure
1567  * @target_time: Time to trigger the clock adjustment at
1568  *
1569  * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation for
1570  * a target time adjust, which will trigger an adjustment of the clock in the
1571  * future. The actual adjustment will occur the next time the PHY port timer
1572  * crosses over the provided value after the driver issues an ADJ_TIME_AT_TIME
1573  * command.
1574  *
1575  * The time value is the upper 32 bits of the PHY timer, usually in units of
1576  * nominal nanoseconds.
1577  */
1578 static enum ice_status
1579 ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time)
1580 {
1581         enum ice_status status;
1582         u8 tmr_idx;
1583
1584         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1585         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
1586         if (status) {
1587                 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_0, status %d\n",
1588                           status);
1589                 return status;
1590         }
1591
1592         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx),
1593                                         target_time);
1594         if (status) {
1595                 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_L, status %d\n",
1596                           status);
1597                 return status;
1598         }
1599
1600         return ICE_SUCCESS;
1601 }
1602
1603 /**
1604  * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command
1605  * @hw: pointer to HW struct
1606  * @cmd: Command to be sent to the port
1607  * @lock_sbq: true if the sideband queue lock must be acquired
1608  *
1609  * Prepare the external PHYs connected to this device for a timer sync
1610  * command.
1611  */
1612 static enum ice_status
1613 ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1614                       bool lock_sbq)
1615 {
1616         enum ice_status status;
1617         u32 cmd_val, val;
1618
1619         switch (cmd) {
1620         case INIT_TIME:
1621                 cmd_val = GLTSYN_CMD_INIT_TIME;
1622                 break;
1623         case INIT_INCVAL:
1624                 cmd_val = GLTSYN_CMD_INIT_INCVAL;
1625                 break;
1626         case ADJ_TIME:
1627                 cmd_val = GLTSYN_CMD_ADJ_TIME;
1628                 break;
1629         case ADJ_TIME_AT_TIME:
1630                 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
1631                 break;
1632         case READ_TIME:
1633                 cmd_val = GLTSYN_CMD_READ_TIME;
1634                 break;
1635         default:
1636                 ice_warn(hw, "Unknown timer command %u\n", cmd);
1637                 return ICE_ERR_PARAM;
1638         }
1639
1640         /* Read, modify, write */
1641         status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq);
1642         if (status) {
1643                 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n",
1644                           status);
1645                 return status;
1646         }
1647
1648         /* Modify necessary bits only and perform write */
1649         val &= ~TS_CMD_MASK_E810;
1650         val |= cmd_val;
1651
1652         status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq);
1653         if (status) {
1654                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n",
1655                           status);
1656                 return status;
1657         }
1658
1659         return ICE_SUCCESS;
1660 }
1661
1662 /* Device agnostic functions
1663  *
1664  * The following functions implement shared behavior common to both E822 and
1665  * E810 devices, possibly calling a device specific implementation where
1666  * necessary.
1667  */
1668
1669 /**
1670  * ice_ptp_lock - Acquire PTP global semaphore register lock
1671  * @hw: pointer to the HW struct
1672  *
1673  * Acquire the global PTP hardware semaphore lock. Returns true if the lock
1674  * was acquired, false otherwise.
1675  *
1676  * The PFTSYN_SEM register sets the busy bit on read, returning the previous
1677  * value. If software sees the busy bit cleared, this means that this function
1678  * acquired the lock (and the busy bit is now set). If software sees the busy
1679  * bit set, it means that another function acquired the lock.
1680  *
1681  * Software must clear the busy bit with a write to release the lock for other
1682  * functions when done.
1683  */
1684 bool ice_ptp_lock(struct ice_hw *hw)
1685 {
1686         u32 hw_lock;
1687         int i;
1688
1689 #define MAX_TRIES 5
1690
1691         for (i = 0; i < MAX_TRIES; i++) {
1692                 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
1693                 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
1694                 if (hw_lock) {
1695                         /* Somebody is holding the lock */
1696                         ice_msec_delay(10, true);
1697                         continue;
1698                 } else {
1699                         break;
1700                 }
1701         }
1702
1703         return !hw_lock;
1704 }
1705
1706 /**
1707  * ice_ptp_unlock - Release PTP global semaphore register lock
1708  * @hw: pointer to the HW struct
1709  *
1710  * Release the global PTP hardware semaphore lock. This is done by writing to
1711  * the PFTSYN_SEM register.
1712  */
1713 void ice_ptp_unlock(struct ice_hw *hw)
1714 {
1715         wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
1716 }
1717
1718 /**
1719  * ice_ptp_src_cmd - Prepare source timer for a timer command
1720  * @hw: pointer to HW structure
1721  * @cmd: Timer command
1722  *
1723  * Prepare the source timer for an upcoming timer sync command.
1724  */
1725 void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
1726 {
1727         u32 cmd_val;
1728         u8 tmr_idx;
1729
1730         tmr_idx = ice_get_ptp_src_clock_index(hw);
1731         cmd_val = tmr_idx << SEL_CPK_SRC;
1732
1733         switch (cmd) {
1734         case INIT_TIME:
1735                 cmd_val |= GLTSYN_CMD_INIT_TIME;
1736                 break;
1737         case INIT_INCVAL:
1738                 cmd_val |= GLTSYN_CMD_INIT_INCVAL;
1739                 break;
1740         case ADJ_TIME:
1741                 cmd_val |= GLTSYN_CMD_ADJ_TIME;
1742                 break;
1743         case ADJ_TIME_AT_TIME:
1744                 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
1745                 break;
1746         case READ_TIME:
1747                 cmd_val |= GLTSYN_CMD_READ_TIME;
1748                 break;
1749         default:
1750                 ice_warn(hw, "Unknown timer command %u\n", cmd);
1751                 return;
1752         }
1753
1754         wr32(hw, GLTSYN_CMD, cmd_val);
1755 }
1756
1757 /**
1758  * ice_ptp_tmr_cmd - Prepare and trigger a timer sync command
1759  * @hw: pointer to HW struct
1760  * @cmd: the command to issue
1761  * @lock_sbq: true if the sideband queue lock must be acquired
1762  *
1763  * Prepare the source timer and PHY timers and then trigger the requested
1764  * command. This causes the shadow registers previously written in preparation
1765  * for the command to be synchronously applied to both the source and PHY
1766  * timers.
1767  */
1768 static enum ice_status
1769 ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
1770 {
1771         enum ice_status status;
1772
1773         /* First, prepare the source timer */
1774         ice_ptp_src_cmd(hw, cmd);
1775
1776         /* Next, prepare the ports */
1777         if (ice_is_e810(hw))
1778                 status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq);
1779         else
1780                 status = ice_ptp_port_cmd_e822(hw, cmd, lock_sbq);
1781         if (status) {
1782                 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
1783                           cmd, status);
1784                 return status;
1785         }
1786
1787         /* Write the sync command register to drive both source and PHY timer
1788          * commands synchronously
1789          */
1790         ice_ptp_exec_tmr_cmd(hw);
1791
1792         return ICE_SUCCESS;
1793 }
1794
1795 /**
1796  * ice_ptp_init_time - Initialize device time to provided value
1797  * @hw: pointer to HW struct
1798  * @time: 64bits of time (GLTSYN_TIME_L and GLTSYN_TIME_H)
1799  *
1800  * Initialize the device to the specified time provided. This requires a three
1801  * step process:
1802  *
1803  * 1) write the new init time to the source timer shadow registers
1804  * 2) write the new init time to the phy timer shadow registers
1805  * 3) issue an init_time timer command to synchronously switch both the source
1806  *    and port timers to the new init time value at the next clock cycle.
1807  */
1808 enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time)
1809 {
1810         enum ice_status status;
1811         u8 tmr_idx;
1812
1813         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1814
1815         /* Source timers */
1816         wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time));
1817         wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time));
1818         wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
1819
1820         /* PHY Clks */
1821         /* Fill Rx and Tx ports and send msg to PHY */
1822         if (ice_is_e810(hw))
1823                 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
1824         else
1825                 status = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
1826         if (status)
1827                 return status;
1828
1829         return ice_ptp_tmr_cmd(hw, INIT_TIME, true);
1830 }
1831
1832 /**
1833  * ice_ptp_write_incval - Program PHC with new increment value
1834  * @hw: pointer to HW struct
1835  * @incval: Source timer increment value per clock cycle
1836  *
1837  * Program the PHC with a new increment value. This requires a three-step
1838  * process:
1839  *
1840  * 1) Write the increment value to the source timer shadow registers
1841  * 2) Write the increment value to the PHY timer shadow registers
1842  * 3) Issue an INIT_INCVAL timer command to synchronously switch both the
1843  *    source and port timers to the new increment value at the next clock
1844  *    cycle.
1845  */
1846 enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
1847 {
1848         enum ice_status status;
1849         u8 tmr_idx;
1850
1851         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1852
1853         /* Shadow Adjust */
1854         wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval));
1855         wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval));
1856
1857         if (ice_is_e810(hw))
1858                 status = ice_ptp_prep_phy_incval_e810(hw, incval);
1859         else
1860                 status = ice_ptp_prep_phy_incval_e822(hw, incval);
1861         if (status)
1862                 return status;
1863
1864         return ice_ptp_tmr_cmd(hw, INIT_INCVAL, true);
1865 }
1866
1867 /**
1868  * ice_ptp_write_incval_locked - Program new incval while holding semaphore
1869  * @hw: pointer to HW struct
1870  * @incval: Source timer increment value per clock cycle
1871  *
1872  * Program a new PHC incval while holding the PTP semaphore.
1873  */
1874 enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
1875 {
1876         enum ice_status status;
1877
1878         if (!ice_ptp_lock(hw))
1879                 return ICE_ERR_NOT_READY;
1880
1881         status = ice_ptp_write_incval(hw, incval);
1882
1883         ice_ptp_unlock(hw);
1884
1885         return status;
1886 }
1887
1888 /**
1889  * ice_ptp_adj_clock - Adjust PHC clock time atomically
1890  * @hw: pointer to HW struct
1891  * @adj: Adjustment in nanoseconds
1892  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
1893  *            sq_lock has already been locked at a higher level
1894  *
1895  * Perform an atomic adjustment of the PHC time by the specified number of
1896  * nanoseconds. This requires a three-step process:
1897  *
1898  * 1) Write the adjustment to the source timer shadow registers
1899  * 2) Write the adjustment to the PHY timer shadow registers
1900  * 3) Issue an ADJ_TIME timer command to synchronously apply the adjustment to
1901  *    both the source and port timers at the next clock cycle.
1902  */
1903 enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq)
1904 {
1905         enum ice_status status;
1906         u8 tmr_idx;
1907
1908         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1909
1910         /* Write the desired clock adjustment into the GLTSYN_SHADJ register.
1911          * For an ADJ_TIME command, this set of registers represents the value
1912          * to add to the clock time. It supports subtraction by interpreting
1913          * the value as a 2's complement integer.
1914          */
1915         wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
1916         wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
1917
1918         if (ice_is_e810(hw))
1919                 status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq);
1920         else
1921                 status = ice_ptp_prep_phy_adj_e822(hw, adj, lock_sbq);
1922         if (status)
1923                 return status;
1924
1925         return ice_ptp_tmr_cmd(hw, ADJ_TIME, lock_sbq);
1926 }
1927
1928 /**
1929  * ice_ptp_adj_clock_at_time - Adjust PHC atomically at specified time
1930  * @hw: pointer to HW struct
1931  * @at_time: Time in nanoseconds at which to perform the adjustment
1932  * @adj: Adjustment in nanoseconds
1933  *
1934  * Perform an atomic adjustment to the PHC clock at the specified time. This
1935  * requires a five-step process:
1936  *
1937  * 1) Write the adjustment to the source timer shadow adjust registers
1938  * 2) Write the target time to the source timer shadow time registers
1939  * 3) Write the adjustment to the PHY timers shadow adjust registers
1940  * 4) Write the target time to the PHY timers shadow adjust registers
1941  * 5) Issue an ADJ_TIME_AT_TIME command to initiate the atomic adjustment.
1942  */
1943 enum ice_status
1944 ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
1945 {
1946         enum ice_status status;
1947         u32 time_lo, time_hi;
1948         u8 tmr_idx;
1949
1950         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1951         time_lo = ICE_LO_DWORD(at_time);
1952         time_hi = ICE_HI_DWORD(at_time);
1953
1954         /* Write the desired clock adjustment into the GLTSYN_SHADJ register.
1955          * For an ADJ_TIME_AT_TIME command, this set of registers represents
1956          * the value to add to the clock time. It supports subtraction by
1957          * interpreting the value as a 2's complement integer.
1958          */
1959         wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
1960         wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
1961
1962         /* Write the target time to trigger the adjustment for source clock */
1963         wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
1964         wr32(hw, GLTSYN_SHTIME_L(tmr_idx), time_lo);
1965         wr32(hw, GLTSYN_SHTIME_H(tmr_idx), time_hi);
1966
1967         /* Prepare PHY port adjustments */
1968         if (ice_is_e810(hw))
1969                 status = ice_ptp_prep_phy_adj_e810(hw, adj, true);
1970         else
1971                 status = ice_ptp_prep_phy_adj_e822(hw, adj, true);
1972         if (status)
1973                 return status;
1974
1975         /* Set target time for each PHY port */
1976         if (ice_is_e810(hw))
1977                 status = ice_ptp_prep_phy_adj_target_e810(hw, time_lo);
1978         else
1979                 status = ice_ptp_prep_phy_adj_target_e822(hw, time_lo);
1980         if (status)
1981                 return status;
1982
1983         return ice_ptp_tmr_cmd(hw, ADJ_TIME_AT_TIME, true);
1984 }
1985
1986 /**
1987  * ice_read_phy_tstamp - Read a PHY timestamp from the timestamo block
1988  * @hw: pointer to the HW struct
1989  * @block: the block to read from
1990  * @idx: the timestamp index to read
1991  * @tstamp: on return, the 40bit timestamp value
1992  *
1993  * Read a 40bit timestamp value out of the timestamp block. For E822 devices,
1994  * the block is the quad to read from. For E810 devices, the block is the
1995  * logical port to read from.
1996  */
1997 enum ice_status
1998 ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
1999 {
2000         if (ice_is_e810(hw))
2001                 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
2002         else
2003                 return ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
2004 }
2005
2006 /**
2007  * ice_clear_phy_tstamp - Clear a timestamp from the timestamp block
2008  * @hw: pointer to the HW struct
2009  * @block: the block to read from
2010  * @idx: the timestamp index to reset
2011  *
2012  * Clear a timestamp, resetting its valid bit, from the timestamp block. For
2013  * E822 devices, the block is the quad to clear from. For E810 devices, the
2014  * block is the logical port to clear from.
2015  */
2016 enum ice_status
2017 ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
2018 {
2019         if (ice_is_e810(hw))
2020                 return ice_clear_phy_tstamp_e810(hw, block, idx);
2021         else
2022                 return ice_clear_phy_tstamp_e822(hw, block, idx);
2023 }