net/ice/base: init marker group table for parser
[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 #include "ice_cgu_regs.h"
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_read_cgu_reg_e822 - Read a CGU register
704  * @hw: pointer to the HW struct
705  * @addr: Register address to read
706  * @val: storage for register value read
707  *
708  * Read the contents of a register of the Clock Generation Unit. Only
709  * applicable to E822 devices.
710  */
711 static enum ice_status
712 ice_read_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 *val)
713 {
714         struct ice_sbq_msg_input cgu_msg;
715         enum ice_status status;
716
717         cgu_msg.opcode = ice_sbq_msg_rd;
718         cgu_msg.dest_dev = cgu;
719         cgu_msg.msg_addr_low = addr;
720         cgu_msg.msg_addr_high = 0x0;
721
722         status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
723         if (status) {
724                 ice_debug(hw, ICE_DBG_PTP, "Failed to read CGU register 0x%04x, status %d\n",
725                           addr, status);
726                 return status;
727         }
728
729         *val = cgu_msg.data;
730
731         return status;
732 }
733
734 /**
735  * ice_write_cgu_reg_e822 - Write a CGU register
736  * @hw: pointer to the HW struct
737  * @addr: Register address to write
738  * @val: value to write into the register
739  *
740  * Write the specified value to a register of the Clock Generation Unit. Only
741  * applicable to E822 devices.
742  */
743 static enum ice_status
744 ice_write_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 val)
745 {
746         struct ice_sbq_msg_input cgu_msg;
747         enum ice_status status;
748
749         cgu_msg.opcode = ice_sbq_msg_wr;
750         cgu_msg.dest_dev = cgu;
751         cgu_msg.msg_addr_low = addr;
752         cgu_msg.msg_addr_high = 0x0;
753         cgu_msg.data = val;
754
755         status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
756         if (status) {
757                 ice_debug(hw, ICE_DBG_PTP, "Failed to write CGU register 0x%04x, status %d\n",
758                           addr, status);
759                 return status;
760         }
761
762         return status;
763 }
764
765 /**
766  * ice_clk_freq_str - Convert time_ref_freq to string
767  * @clk_freq: Clock frequency
768  *
769  * Convert the specified TIME_REF clock frequency to a string.
770  */
771 static const char *ice_clk_freq_str(u8 clk_freq)
772 {
773         switch ((enum ice_time_ref_freq)clk_freq) {
774         case ICE_TIME_REF_FREQ_25_000:
775                 return "25 MHz";
776         case ICE_TIME_REF_FREQ_122_880:
777                 return "122.88 MHz";
778         case ICE_TIME_REF_FREQ_125_000:
779                 return "125 MHz";
780         case ICE_TIME_REF_FREQ_153_600:
781                 return "153.6 MHz";
782         case ICE_TIME_REF_FREQ_156_250:
783                 return "156.25 MHz";
784         case ICE_TIME_REF_FREQ_245_760:
785                 return "245.76 MHz";
786         default:
787                 return "Unknown";
788         }
789 }
790
791 /**
792  * ice_clk_src_str - Convert time_ref_src to string
793  * @clk_src: Clock source
794  *
795  * Convert the specified clock source to its string name.
796  */
797 static const char *ice_clk_src_str(u8 clk_src)
798 {
799         switch ((enum ice_clk_src)clk_src) {
800         case ICE_CLK_SRC_TCX0:
801                 return "TCX0";
802         case ICE_CLK_SRC_TIME_REF:
803                 return "TIME_REF";
804         default:
805                 return "Unknown";
806         }
807 }
808
809 /**
810  * ice_cfg_cgu_pll_e822 - Configure the Clock Generation Unit
811  * @hw: pointer to the HW struct
812  * @clk_freq: Clock frequency to program
813  * @clk_src: Clock source to select (TIME_REF, or TCX0)
814  *
815  * Configure the Clock Generation Unit with the desired clock frequency and
816  * time reference, enabling the PLL which drives the PTP hardware clock.
817  */
818 enum ice_status
819 ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq clk_freq,
820                      enum ice_clk_src clk_src)
821 {
822         union tspll_ro_bwm_lf bwm_lf;
823         union nac_cgu_dword19 dw19;
824         union nac_cgu_dword22 dw22;
825         union nac_cgu_dword24 dw24;
826         union nac_cgu_dword9 dw9;
827         enum ice_status status;
828
829         if (clk_freq >= NUM_ICE_TIME_REF_FREQ) {
830                 ice_warn(hw, "Invalid TIME_REF frequency %u\n", clk_freq);
831                 return ICE_ERR_PARAM;
832         }
833
834         if (clk_src >= NUM_ICE_CLK_SRC) {
835                 ice_warn(hw, "Invalid clock source %u\n", clk_src);
836                 return ICE_ERR_PARAM;
837         }
838
839         if (clk_src == ICE_CLK_SRC_TCX0 &&
840             clk_freq != ICE_TIME_REF_FREQ_25_000) {
841                 ice_warn(hw, "TCX0 only supports 25 MHz frequency\n");
842                 return ICE_ERR_PARAM;
843         }
844
845         status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD9, &dw9.val);
846         if (status)
847                 return status;
848
849         status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD24, &dw24.val);
850         if (status)
851                 return status;
852
853         status = ice_read_cgu_reg_e822(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
854         if (status)
855                 return status;
856
857         /* Log the current clock configuration */
858         ice_debug(hw, ICE_DBG_PTP, "Current CGU configuration -- %s, clk_src %s, clk_freq %s, PLL %s\n",
859                   dw24.field.ts_pll_enable ? "enabled" : "disabled",
860                   ice_clk_src_str(dw24.field.time_ref_sel),
861                   ice_clk_freq_str(dw9.field.time_ref_freq_sel),
862                   bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
863
864         /* Disable the PLL before changing the clock source or frequency */
865         if (dw24.field.ts_pll_enable) {
866                 dw24.field.ts_pll_enable = 0;
867
868                 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
869                 if (status)
870                         return status;
871         }
872
873         /* Set the frequency */
874         dw9.field.time_ref_freq_sel = clk_freq;
875         status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD9, dw9.val);
876         if (status)
877                 return status;
878
879         /* Configure the TS PLL feedback divisor */
880         status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD19, &dw19.val);
881         if (status)
882                 return status;
883
884         dw19.field.tspll_fbdiv_intgr = e822_cgu_params[clk_freq].feedback_div;
885         dw19.field.tspll_ndivratio = 1;
886
887         status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD19, dw19.val);
888         if (status)
889                 return status;
890
891         /* Configure the TS PLL post divisor */
892         status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD22, &dw22.val);
893         if (status)
894                 return status;
895
896         dw22.field.time1588clk_div = e822_cgu_params[clk_freq].post_pll_div;
897         dw22.field.time1588clk_sel_div2 = 0;
898
899         status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD22, dw22.val);
900         if (status)
901                 return status;
902
903         /* Configure the TS PLL pre divisor and clock source */
904         status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD24, &dw24.val);
905         if (status)
906                 return status;
907
908         dw24.field.ref1588_ck_div = e822_cgu_params[clk_freq].refclk_pre_div;
909         dw24.field.tspll_fbdiv_frac = e822_cgu_params[clk_freq].frac_n_div;
910         dw24.field.time_ref_sel = clk_src;
911
912         status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
913         if (status)
914                 return status;
915
916         /* Finally, enable the PLL */
917         dw24.field.ts_pll_enable = 1;
918
919         status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
920         if (status)
921                 return status;
922
923         /* Wait to verify if the PLL locks */
924         ice_msec_delay(1, true);
925
926         status = ice_read_cgu_reg_e822(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
927         if (status)
928                 return status;
929
930         if (!bwm_lf.field.plllock_true_lock_cri) {
931                 ice_warn(hw, "CGU PLL failed to lock\n");
932                 return ICE_ERR_NOT_READY;
933         }
934
935         /* Log the current clock configuration */
936         ice_debug(hw, ICE_DBG_PTP, "New CGU configuration -- %s, clk_src %s, clk_freq %s, PLL %s\n",
937                   dw24.field.ts_pll_enable ? "enabled" : "disabled",
938                   ice_clk_src_str(dw24.field.time_ref_sel),
939                   ice_clk_freq_str(dw9.field.time_ref_freq_sel),
940                   bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
941
942
943         return ICE_SUCCESS;
944 }
945
946 /**
947  * ice_init_cgu_e822 - Initialize CGU with settings from firmware
948  * @hw: pointer to the HW structure
949  *
950  * Initialize the Clock Generation Unit of the E822 device.
951  */
952 static enum ice_status ice_init_cgu_e822(struct ice_hw *hw)
953 {
954         struct ice_ts_func_info *ts_info = &hw->func_caps.ts_func_info;
955         union tspll_cntr_bist_settings cntr_bist;
956         enum ice_status status;
957
958         status = ice_read_cgu_reg_e822(hw, TSPLL_CNTR_BIST_SETTINGS,
959                                        &cntr_bist.val);
960         if (status)
961                 return status;
962
963         /* Disable sticky lock detection so lock status reported is accurate */
964         cntr_bist.field.i_plllock_sel_0 = 0;
965         cntr_bist.field.i_plllock_sel_1 = 0;
966
967         status = ice_write_cgu_reg_e822(hw, TSPLL_CNTR_BIST_SETTINGS,
968                                         cntr_bist.val);
969         if (status)
970                 return status;
971
972         /* Configure the CGU PLL using the parameters from the function
973          * capabilities.
974          */
975         status = ice_cfg_cgu_pll_e822(hw, ts_info->time_ref,
976                                       (enum ice_clk_src)ts_info->clk_src);
977         if (status)
978                 return status;
979
980         return ICE_SUCCESS;
981 }
982
983 /**
984  * ice_ptp_init_phc_e822 - Perform E822 specific PHC initialization
985  * @hw: pointer to HW struct
986  *
987  * Perform PHC initialization steps specific to E822 devices.
988  */
989 static enum ice_status ice_ptp_init_phc_e822(struct ice_hw *hw)
990 {
991         enum ice_status status;
992         u32 regval;
993
994         /* Enable reading switch and PHY registers over the sideband queue */
995 #define PF_SB_REM_DEV_CTL_SWITCH_READ BIT(1)
996 #define PF_SB_REM_DEV_CTL_PHY0 BIT(2)
997         regval = rd32(hw, PF_SB_REM_DEV_CTL);
998         regval |= (PF_SB_REM_DEV_CTL_SWITCH_READ |
999                    PF_SB_REM_DEV_CTL_PHY0);
1000         wr32(hw, PF_SB_REM_DEV_CTL, regval);
1001
1002         /* Initialize the Clock Generation Unit */
1003         status = ice_init_cgu_e822(hw);
1004         if (status)
1005                 return status;
1006
1007         /* Set window length for all the ports */
1008         return ice_ptp_set_vernier_wl(hw);
1009 }
1010
1011 /**
1012  * ice_ptp_prep_phy_time_e822 - Prepare PHY port with initial time
1013  * @hw: pointer to the HW struct
1014  * @time: Time to initialize the PHY port clocks to
1015  *
1016  * Program the PHY port registers with a new initial time value. The port
1017  * clock will be initialized once the driver issues an INIT_TIME sync
1018  * command. The time value is the upper 32 bits of the PHY timer, usually in
1019  * units of nominal nanoseconds.
1020  */
1021 static enum ice_status
1022 ice_ptp_prep_phy_time_e822(struct ice_hw *hw, u32 time)
1023 {
1024         enum ice_status status;
1025         u64 phy_time;
1026         u8 port;
1027
1028         /* The time represents the upper 32 bits of the PHY timer, so we need
1029          * to shift to account for this when programming.
1030          */
1031         phy_time = (u64)time << 32;
1032
1033         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1034
1035                 /* Tx case */
1036                 status = ice_write_64b_phy_reg_e822(hw, port,
1037                                                     P_REG_TX_TIMER_INC_PRE_L,
1038                                                     phy_time);
1039                 if (status)
1040                         goto exit_err;
1041
1042                 /* Rx case */
1043                 status = ice_write_64b_phy_reg_e822(hw, port,
1044                                                     P_REG_RX_TIMER_INC_PRE_L,
1045                                                     phy_time);
1046                 if (status)
1047                         goto exit_err;
1048         }
1049
1050         return ICE_SUCCESS;
1051
1052 exit_err:
1053         ice_debug(hw, ICE_DBG_PTP, "Failed to write init time for port %u, status %d\n",
1054                   port, status);
1055
1056         return status;
1057 }
1058
1059 /**
1060  * ice_ptp_prep_port_adj_e822 - Prepare a single port for time adjust
1061  * @hw: pointer to HW struct
1062  * @port: Port number to be programmed
1063  * @time: time in cycles to adjust the port Tx and Rx clocks
1064  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
1065  *            sq_lock has already been locked at a higher level
1066  *
1067  * Program the port for an atomic adjustment by writing the Tx and Rx timer
1068  * registers. The atomic adjustment won't be completed until the driver issues
1069  * an ADJ_TIME command.
1070  *
1071  * Note that time is not in units of nanoseconds. It is in clock time
1072  * including the lower sub-nanosecond portion of the port timer.
1073  *
1074  * Negative adjustments are supported using 2s complement arithmetic.
1075  */
1076 enum ice_status
1077 ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time,
1078                            bool lock_sbq)
1079 {
1080         enum ice_status status;
1081         u32 l_time, u_time;
1082
1083         l_time = ICE_LO_DWORD(time);
1084         u_time = ICE_HI_DWORD(time);
1085
1086         /* Tx case */
1087         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_L,
1088                                            l_time, lock_sbq);
1089         if (status)
1090                 goto exit_err;
1091
1092         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_U,
1093                                            u_time, lock_sbq);
1094         if (status)
1095                 goto exit_err;
1096
1097         /* Rx case */
1098         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_L,
1099                                            l_time, lock_sbq);
1100         if (status)
1101                 goto exit_err;
1102
1103         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_U,
1104                                            u_time, lock_sbq);
1105         if (status)
1106                 goto exit_err;
1107
1108         return ICE_SUCCESS;
1109
1110 exit_err:
1111         ice_debug(hw, ICE_DBG_PTP, "Failed to write time adjust for port %u, status %d\n",
1112                   port, status);
1113         return status;
1114 }
1115
1116 /**
1117  * ice_ptp_prep_phy_adj_e822 - Prep PHY ports for a time adjustment
1118  * @hw: pointer to HW struct
1119  * @adj: adjustment in nanoseconds
1120  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
1121  *            sq_lock has already been locked at a higher level
1122  *
1123  * Prepare the PHY ports for an atomic time adjustment by programming the PHY
1124  * Tx and Rx port registers. The actual adjustment is completed by issuing an
1125  * ADJ_TIME or ADJ_TIME_AT_TIME sync command.
1126  */
1127 static enum ice_status
1128 ice_ptp_prep_phy_adj_e822(struct ice_hw *hw, s32 adj, bool lock_sbq)
1129 {
1130         s64 cycles;
1131         u8 port;
1132
1133         /* The port clock supports adjustment of the sub-nanosecond portion of
1134          * the clock. We shift the provided adjustment in nanoseconds to
1135          * calculate the appropriate adjustment to program into the PHY ports.
1136          */
1137         if (adj > 0)
1138                 cycles = (s64)adj << 32;
1139         else
1140                 cycles = -(((s64)-adj) << 32);
1141
1142         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1143                 enum ice_status status;
1144
1145                 status = ice_ptp_prep_port_adj_e822(hw, port, cycles,
1146                                                     lock_sbq);
1147                 if (status)
1148                         return status;
1149         }
1150
1151         return ICE_SUCCESS;
1152 }
1153
1154 /**
1155  * ice_ptp_prep_phy_incval_e822 - Prepare PHY ports for time adjustment
1156  * @hw: pointer to HW struct
1157  * @incval: new increment value to prepare
1158  *
1159  * Prepare each of the PHY ports for a new increment value by programming the
1160  * port's TIMETUS registers. The new increment value will be updated after
1161  * issuing an INIT_INCVAL command.
1162  */
1163 static enum ice_status
1164 ice_ptp_prep_phy_incval_e822(struct ice_hw *hw, u64 incval)
1165 {
1166         enum ice_status status;
1167         u8 port;
1168
1169         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1170                 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L,
1171                                                     incval);
1172                 if (status)
1173                         goto exit_err;
1174         }
1175
1176         return ICE_SUCCESS;
1177
1178 exit_err:
1179         ice_debug(hw, ICE_DBG_PTP, "Failed to write incval for port %u, status %d\n",
1180                   port, status);
1181
1182         return status;
1183 }
1184
1185 /**
1186  * ice_ptp_read_phy_incval_e822 - Read a PHY port's current incval
1187  * @hw: pointer to the HW struct
1188  * @port: the port to read
1189  * @incval: on return, the time_clk_cyc incval for this port
1190  *
1191  * Read the time_clk_cyc increment value for a given PHY port.
1192  */
1193 enum ice_status
1194 ice_ptp_read_phy_incval_e822(struct ice_hw *hw, u8 port, u64 *incval)
1195 {
1196         enum ice_status status;
1197
1198         status = ice_read_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
1199         if (status) {
1200                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TIMETUS_L, status %d\n",
1201                           status);
1202                 return status;
1203         }
1204
1205         ice_debug(hw, ICE_DBG_PTP, "read INCVAL = 0x%016llx\n",
1206                   (unsigned long long)*incval);
1207
1208         return ICE_SUCCESS;
1209 }
1210
1211 /**
1212  * ice_ptp_prep_phy_adj_target_e822 - Prepare PHY for adjust at target time
1213  * @hw: pointer to HW struct
1214  * @target_time: target time to program
1215  *
1216  * Program the PHY port Tx and Rx TIMER_CNT_ADJ registers used for the
1217  * ADJ_TIME_AT_TIME command. This should be used in conjunction with
1218  * ice_ptp_prep_phy_adj_e822 to program an atomic adjustment that is
1219  * delayed until a specified target time.
1220  *
1221  * Note that a target time adjustment is not currently supported on E810
1222  * devices.
1223  */
1224 static enum ice_status
1225 ice_ptp_prep_phy_adj_target_e822(struct ice_hw *hw, u32 target_time)
1226 {
1227         enum ice_status status;
1228         u8 port;
1229
1230         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1231
1232                 /* Tx case */
1233                 /* No sub-nanoseconds data */
1234                 status = ice_write_phy_reg_e822_lp(hw, port,
1235                                                    P_REG_TX_TIMER_CNT_ADJ_L,
1236                                                    0, true);
1237                 if (status)
1238                         goto exit_err;
1239
1240                 status = ice_write_phy_reg_e822_lp(hw, port,
1241                                                    P_REG_TX_TIMER_CNT_ADJ_U,
1242                                                    target_time, true);
1243                 if (status)
1244                         goto exit_err;
1245
1246                 /* Rx case */
1247                 /* No sub-nanoseconds data */
1248                 status = ice_write_phy_reg_e822_lp(hw, port,
1249                                                    P_REG_RX_TIMER_CNT_ADJ_L,
1250                                                    0, true);
1251                 if (status)
1252                         goto exit_err;
1253
1254                 status = ice_write_phy_reg_e822_lp(hw, port,
1255                                                    P_REG_RX_TIMER_CNT_ADJ_U,
1256                                                    target_time, true);
1257                 if (status)
1258                         goto exit_err;
1259         }
1260
1261         return ICE_SUCCESS;
1262
1263 exit_err:
1264         ice_debug(hw, ICE_DBG_PTP, "Failed to write target time for port %u, status %d\n",
1265                   port, status);
1266
1267         return status;
1268 }
1269
1270 /**
1271  * ice_ptp_read_port_capture - Read a port's local time capture
1272  * @hw: pointer to HW struct
1273  * @port: Port number to read
1274  * @tx_ts: on return, the Tx port time capture
1275  * @rx_ts: on return, the Rx port time capture
1276  *
1277  * Read the port's Tx and Rx local time capture values.
1278  *
1279  * Note this has no equivalent for the E810 devices.
1280  */
1281 enum ice_status
1282 ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts)
1283 {
1284         enum ice_status status;
1285
1286         /* Tx case */
1287         status = ice_read_64b_phy_reg_e822(hw, port, P_REG_TX_CAPTURE_L, tx_ts);
1288         if (status) {
1289                 ice_debug(hw, ICE_DBG_PTP, "Failed to read REG_TX_CAPTURE, status %d\n",
1290                           status);
1291                 return status;
1292         }
1293
1294         ice_debug(hw, ICE_DBG_PTP, "tx_init = 0x%016llx\n",
1295                   (unsigned long long)*tx_ts);
1296
1297         /* Rx case */
1298         status = ice_read_64b_phy_reg_e822(hw, port, P_REG_RX_CAPTURE_L, rx_ts);
1299         if (status) {
1300                 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_CAPTURE, status %d\n",
1301                           status);
1302                 return status;
1303         }
1304
1305         ice_debug(hw, ICE_DBG_PTP, "rx_init = 0x%016llx\n",
1306                   (unsigned long long)*rx_ts);
1307
1308         return ICE_SUCCESS;
1309 }
1310
1311 /**
1312  * ice_ptp_one_port_cmd - Prepare a single PHY port for a timer command
1313  * @hw: pointer to HW struct
1314  * @port: Port to which cmd has to be sent
1315  * @cmd: Command to be sent to the port
1316  * @lock_sbq: true if the sideband queue lock must be acquired
1317  *
1318  * Prepare the requested port for an upcoming timer sync command.
1319  *
1320  * Note there is no equivalent of this operation on E810, as that device
1321  * always handles all external PHYs internally.
1322  */
1323 enum ice_status
1324 ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd,
1325                      bool lock_sbq)
1326 {
1327         enum ice_status status;
1328         u32 cmd_val, val;
1329         u8 tmr_idx;
1330
1331         tmr_idx = ice_get_ptp_src_clock_index(hw);
1332         cmd_val = tmr_idx << SEL_PHY_SRC;
1333         switch (cmd) {
1334         case INIT_TIME:
1335                 cmd_val |= PHY_CMD_INIT_TIME;
1336                 break;
1337         case INIT_INCVAL:
1338                 cmd_val |= PHY_CMD_INIT_INCVAL;
1339                 break;
1340         case ADJ_TIME:
1341                 cmd_val |= PHY_CMD_ADJ_TIME;
1342                 break;
1343         case ADJ_TIME_AT_TIME:
1344                 cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
1345                 break;
1346         case READ_TIME:
1347                 cmd_val |= PHY_CMD_READ_TIME;
1348                 break;
1349         default:
1350                 ice_warn(hw, "Unknown timer command %u\n", cmd);
1351                 return ICE_ERR_PARAM;
1352         }
1353
1354         /* Tx case */
1355         /* Read, modify, write */
1356         status = ice_read_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, &val,
1357                                           lock_sbq);
1358         if (status) {
1359                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_TMR_CMD, status %d\n",
1360                           status);
1361                 return status;
1362         }
1363
1364         /* Modify necessary bits only and perform write */
1365         val &= ~TS_CMD_MASK;
1366         val |= cmd_val;
1367
1368         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, val,
1369                                            lock_sbq);
1370         if (status) {
1371                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_TMR_CMD, status %d\n",
1372                           status);
1373                 return status;
1374         }
1375
1376         /* Rx case */
1377         /* Read, modify, write */
1378         status = ice_read_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, &val,
1379                                           lock_sbq);
1380         if (status) {
1381                 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_TMR_CMD, status %d\n",
1382                           status);
1383                 return status;
1384         }
1385
1386         /* Modify necessary bits only and perform write */
1387         val &= ~TS_CMD_MASK;
1388         val |= cmd_val;
1389
1390         status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, val,
1391                                            lock_sbq);
1392         if (status) {
1393                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back RX_TMR_CMD, status %d\n",
1394                           status);
1395                 return status;
1396         }
1397
1398         return ICE_SUCCESS;
1399 }
1400
1401 /**
1402  * ice_ptp_port_cmd_e822 - Prepare all ports for a timer command
1403  * @hw: pointer to the HW struct
1404  * @cmd: timer command to prepare
1405  * @lock_sbq: true if the sideband queue lock must  be acquired
1406  *
1407  * Prepare all ports connected to this device for an upcoming timer sync
1408  * command.
1409  */
1410 static enum ice_status
1411 ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1412                       bool lock_sbq)
1413 {
1414         u8 port;
1415
1416         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1417                 enum ice_status status;
1418
1419                 status = ice_ptp_one_port_cmd(hw, port, cmd, lock_sbq);
1420                 if (status)
1421                         return status;
1422         }
1423
1424         return ICE_SUCCESS;
1425 }
1426
1427 /* E822 Vernier calibration functions
1428  *
1429  * The following functions are used as part of the vernier calibration of
1430  * a port. This calibration increases the precision of the timestamps on the
1431  * port.
1432  */
1433
1434 /**
1435  * ice_ptp_set_vernier_wl - Set the window length for vernier calibration
1436  * @hw: pointer to the HW struct
1437  *
1438  * Set the window length used for the vernier port calibration process.
1439  */
1440 enum ice_status ice_ptp_set_vernier_wl(struct ice_hw *hw)
1441 {
1442         u8 port;
1443
1444         for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1445                 enum ice_status status;
1446
1447                 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_WL,
1448                                                    PTP_VERNIER_WL, true);
1449                 if (status) {
1450                         ice_debug(hw, ICE_DBG_PTP, "Failed to set vernier window length for port %u, status %d\n",
1451                                   port, status);
1452                         return status;
1453                 }
1454         }
1455
1456         return ICE_SUCCESS;
1457 }
1458
1459 /**
1460  * ice_phy_get_speed_and_fec_e822 - Get link speed and FEC based on serdes mode
1461  * @hw: pointer to HW struct
1462  * @port: the port to read from
1463  * @link_out: if non-NULL, holds link speed on success
1464  * @fec_out: if non-NULL, holds FEC algorithm on success
1465  *
1466  * Read the serdes data for the PHY port and extract the link speed and FEC
1467  * algorithm.
1468  */
1469 enum ice_status
1470 ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
1471                                enum ice_ptp_link_spd *link_out,
1472                                enum ice_ptp_fec_mode *fec_out)
1473 {
1474         enum ice_ptp_link_spd link;
1475         enum ice_ptp_fec_mode fec;
1476         enum ice_status status;
1477         u32 serdes;
1478
1479         status = ice_read_phy_reg_e822(hw, port, P_REG_LINK_SPEED, &serdes);
1480         if (status) {
1481                 ice_debug(hw, ICE_DBG_PTP, "Failed to read serdes info\n");
1482                 return status;
1483         }
1484
1485         /* Determine the FEC algorithm */
1486         fec = (enum ice_ptp_fec_mode)P_REG_LINK_SPEED_FEC_MODE(serdes);
1487
1488         serdes &= P_REG_LINK_SPEED_SERDES_M;
1489
1490         /* Determine the link speed */
1491         if (fec == ICE_PTP_FEC_MODE_RS_FEC) {
1492                 switch (serdes) {
1493                 case ICE_PTP_SERDES_25G:
1494                         link = ICE_PTP_LNK_SPD_25G_RS;
1495                         break;
1496                 case ICE_PTP_SERDES_50G:
1497                         link = ICE_PTP_LNK_SPD_50G_RS;
1498                         break;
1499                 case ICE_PTP_SERDES_100G:
1500                         link = ICE_PTP_LNK_SPD_100G_RS;
1501                         break;
1502                 default:
1503                         return ICE_ERR_OUT_OF_RANGE;
1504                 }
1505         } else {
1506                 switch (serdes) {
1507                 case ICE_PTP_SERDES_1G:
1508                         link = ICE_PTP_LNK_SPD_1G;
1509                         break;
1510                 case ICE_PTP_SERDES_10G:
1511                         link = ICE_PTP_LNK_SPD_10G;
1512                         break;
1513                 case ICE_PTP_SERDES_25G:
1514                         link = ICE_PTP_LNK_SPD_25G;
1515                         break;
1516                 case ICE_PTP_SERDES_40G:
1517                         link = ICE_PTP_LNK_SPD_40G;
1518                         break;
1519                 case ICE_PTP_SERDES_50G:
1520                         link = ICE_PTP_LNK_SPD_50G;
1521                         break;
1522                 default:
1523                         return ICE_ERR_OUT_OF_RANGE;
1524                 }
1525         }
1526
1527         if (link_out)
1528                 *link_out = link;
1529         if (fec_out)
1530                 *fec_out = fec;
1531
1532         return ICE_SUCCESS;
1533 }
1534
1535 /**
1536  * ice_phy_cfg_lane_e822 - Configure PHY quad for single/multi-lane timestamp
1537  * @hw: pointer to HW struct
1538  * @port: to configure the quad for
1539  */
1540 void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port)
1541 {
1542         enum ice_ptp_link_spd link_spd;
1543         enum ice_status status;
1544         u32 val;
1545         u8 quad;
1546
1547         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, NULL);
1548         if (status) {
1549                 ice_debug(hw, ICE_DBG_PTP, "Failed to get PHY link speed, status %d\n",
1550                           status);
1551                 return;
1552         }
1553
1554         quad = port / ICE_PORTS_PER_QUAD;
1555
1556         status = ice_read_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
1557         if (status) {
1558                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_MEM_GLB_CFG, status %d\n",
1559                           status);
1560                 return;
1561         }
1562
1563         if (link_spd >= ICE_PTP_LNK_SPD_40G)
1564                 val &= ~Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1565         else
1566                 val |= Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1567
1568         status = ice_write_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, val);
1569         if (status) {
1570                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_MEM_GBL_CFG, status %d\n",
1571                           status);
1572                 return;
1573         }
1574 }
1575
1576 /**
1577  * ice_phy_cfg_uix_e822 - Configure Serdes UI to TU conversion for E822
1578  * @hw: pointer to the HW structure
1579  * @port: the port to configure
1580  *
1581  * Program the conversion ration of Serdes clock "unit intervals" (UIs) to PHC
1582  * hardware clock time units (TUs). That is, determine the number of TUs per
1583  * serdes unit interval, and program the UIX registers with this conversion.
1584  *
1585  * This conversion is used as part of the calibration process when determining
1586  * the additional error of a timestamp vs the real time of transmission or
1587  * receipt of the packet.
1588  *
1589  * Hardware uses the number of TUs per 66 UIs, written to the UIX registers
1590  * for the two main serdes clock rates, 10G/40G and 25G/100G serdes clocks.
1591  *
1592  * To calculate the conversion ratio, we use the following facts:
1593  *
1594  * a) the clock frequency in Hz (cycles per second)
1595  * b) the number of TUs per cycle (the increment value of the clock)
1596  * c) 1 second per 1 billion nanoseconds
1597  * d) the duration of 66 UIs in nanoseconds
1598  *
1599  * Given these facts, we can use the following table to work out what ratios
1600  * to multiply in order to get the number of TUs per 66 UIs:
1601  *
1602  * cycles |   1 second   | incval (TUs) | nanoseconds
1603  * -------+--------------+--------------+-------------
1604  * second | 1 billion ns |    cycle     |   66 UIs
1605  *
1606  * To perform the multiplication using integers without too much loss of
1607  * precision, we can take use the following equation:
1608  *
1609  * (freq * incval * 6600 LINE_UI ) / ( 100 * 1 billion)
1610  *
1611  * We scale up to using 6600 UI instead of 66 in order to avoid fractional
1612  * nanosecond UIs (66 UI at 10G/40G is 6.4 ns)
1613  *
1614  * The increment value has a maximum expected range of about 34 bits, while
1615  * the frequency value is about 29 bits. Multiplying these values shouldn't
1616  * overflow the 64 bits. However, we must then further multiply them again by
1617  * the Serdes unit interval duration. To avoid overflow here, we split the
1618  * overall divide by 1e11 into a divide by 256 (shift down by 8 bits) and
1619  * a divide by 390,625,000. This does lose some precision, but avoids
1620  * miscalculation due to arithmetic overflow.
1621  */
1622 static enum ice_status ice_phy_cfg_uix_e822(struct ice_hw *hw, u8 port)
1623 {
1624         u64 cur_freq, clk_incval, tu_per_sec, uix;
1625         enum ice_status status;
1626
1627         cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1628         clk_incval = ice_ptp_read_src_incval(hw);
1629
1630         /* Calculate TUs per second divided by 256 */
1631         tu_per_sec = (cur_freq * clk_incval) >> 8;
1632
1633 #define LINE_UI_10G_40G 640 /* 6600 UIs is 640 nanoseconds at 10Gb/40Gb */
1634 #define LINE_UI_25G_100G 256 /* 6600 UIs is 256 nanoseconds at 25Gb/100Gb */
1635
1636         /* Program the 10Gb/40Gb conversion ratio */
1637         uix = DIV_64BIT(tu_per_sec * LINE_UI_10G_40G, 390625000);
1638
1639         status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_10G_40G_L,
1640                                             uix);
1641         if (status) {
1642                 ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_10G_40G, status %d\n",
1643                           status);
1644                 return status;
1645         }
1646
1647         /* Program the 25Gb/100Gb conversion ratio */
1648         uix = DIV_64BIT(tu_per_sec * LINE_UI_25G_100G, 390625000);
1649
1650         status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_25G_100G_L,
1651                                             uix);
1652         if (status) {
1653                 ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_25G_100G, status %d\n",
1654                           status);
1655                 return status;
1656         }
1657
1658         return ICE_SUCCESS;
1659 }
1660
1661 /**
1662  * ice_phy_cfg_parpcs_e822 - Configure TUs per PAR/PCS clock cycle
1663  * @hw: pointer to the HW struct
1664  * @port: port to configure
1665  *
1666  * Configure the number of TUs for the PAR and PCS clocks used as part of the
1667  * timestamp calibration process. This depends on the link speed, as the PHY
1668  * uses different markers depending on the speed.
1669  *
1670  * 1Gb/10Gb/25Gb:
1671  * - Tx/Rx PAR/PCS markers
1672  *
1673  * 25Gb RS:
1674  * - Tx/Rx Reed Solomon gearbox PAR/PCS markers
1675  *
1676  * 40Gb/50Gb:
1677  * - Tx/Rx PAR/PCS markers
1678  * - Rx Deskew PAR/PCS markers
1679  *
1680  * 50G RS and 100GB RS:
1681  * - Tx/Rx Reed Solomon gearbox PAR/PCS markers
1682  * - Rx Deskew PAR/PCS markers
1683  * - Tx PAR/PCS markers
1684  *
1685  * To calculate the conversion, we use the PHC clock frequency (cycles per
1686  * second), the increment value (TUs per cycle), and the related PHY clock
1687  * frequency to calculate the TUs per unit of the PHY link clock. The
1688  * following table shows how the units convert:
1689  *
1690  * cycles |  TUs  | second
1691  * -------+-------+--------
1692  * second | cycle | cycles
1693  *
1694  * For each conversion register, look up the appropriate frequency from the
1695  * e822 PAR/PCS table and calculate the TUs per unit of that clock. Program
1696  * this to the appropriate register, preparing hardware to perform timestamp
1697  * calibration to calculate the total Tx or Rx offset to adjust the timestamp
1698  * in order to calibrate for the internal PHY delays.
1699  *
1700  * Note that the increment value ranges up to ~34 bits, and the clock
1701  * frequency is ~29 bits, so multiplying them together should fit within the
1702  * 64 bit arithmetic.
1703  */
1704 static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port)
1705 {
1706         u64 cur_freq, clk_incval, tu_per_sec, phy_tus;
1707         enum ice_ptp_link_spd link_spd;
1708         enum ice_ptp_fec_mode fec_mode;
1709         enum ice_status status;
1710
1711         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1712         if (status)
1713                 return status;
1714
1715         cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1716         clk_incval = ice_ptp_read_src_incval(hw);
1717
1718         /* Calculate TUs per cycle of the PHC clock */
1719         tu_per_sec = cur_freq * clk_incval;
1720
1721         /* For each PHY conversion register, look up the appropriate link
1722          * speed frequency and determine the TUs per that clock's cycle time.
1723          * Split this into a high and low value and then program the
1724          * appropriate register. If that link speed does not use the
1725          * associated register, write zeros to clear it instead.
1726          */
1727
1728         /* P_REG_PAR_TX_TUS */
1729         if (e822_vernier[link_spd].tx_par_clk)
1730                 phy_tus = DIV_64BIT(tu_per_sec,
1731                                     e822_vernier[link_spd].tx_par_clk);
1732         else
1733                 phy_tus = 0;
1734
1735         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_TX_TUS_L,
1736                                             phy_tus);
1737         if (status)
1738                 return status;
1739
1740         /* P_REG_PAR_RX_TUS */
1741         if (e822_vernier[link_spd].rx_par_clk)
1742                 phy_tus = DIV_64BIT(tu_per_sec,
1743                                     e822_vernier[link_spd].rx_par_clk);
1744         else
1745                 phy_tus = 0;
1746
1747         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_RX_TUS_L,
1748                                             phy_tus);
1749         if (status)
1750                 return status;
1751
1752         /* P_REG_PCS_TX_TUS */
1753         if (e822_vernier[link_spd].tx_pcs_clk)
1754                 phy_tus = DIV_64BIT(tu_per_sec,
1755                                     e822_vernier[link_spd].tx_pcs_clk);
1756         else
1757                 phy_tus = 0;
1758
1759         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_TX_TUS_L,
1760                                             phy_tus);
1761         if (status)
1762                 return status;
1763
1764         /* P_REG_PCS_RX_TUS */
1765         if (e822_vernier[link_spd].rx_pcs_clk)
1766                 phy_tus = DIV_64BIT(tu_per_sec,
1767                                     e822_vernier[link_spd].rx_pcs_clk);
1768         else
1769                 phy_tus = 0;
1770
1771         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_RX_TUS_L,
1772                                             phy_tus);
1773         if (status)
1774                 return status;
1775
1776         /* P_REG_DESK_PAR_TX_TUS */
1777         if (e822_vernier[link_spd].tx_desk_rsgb_par)
1778                 phy_tus = DIV_64BIT(tu_per_sec,
1779                                     e822_vernier[link_spd].tx_desk_rsgb_par);
1780         else
1781                 phy_tus = 0;
1782
1783         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_TX_TUS_L,
1784                                             phy_tus);
1785         if (status)
1786                 return status;
1787
1788         /* P_REG_DESK_PAR_RX_TUS */
1789         if (e822_vernier[link_spd].rx_desk_rsgb_par)
1790                 phy_tus = DIV_64BIT(tu_per_sec,
1791                                     e822_vernier[link_spd].rx_desk_rsgb_par);
1792         else
1793                 phy_tus = 0;
1794
1795         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_RX_TUS_L,
1796                                             phy_tus);
1797         if (status)
1798                 return status;
1799
1800         /* P_REG_DESK_PCS_TX_TUS */
1801         if (e822_vernier[link_spd].tx_desk_rsgb_pcs)
1802                 phy_tus = DIV_64BIT(tu_per_sec,
1803                                     e822_vernier[link_spd].tx_desk_rsgb_pcs);
1804         else
1805                 phy_tus = 0;
1806
1807         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_TX_TUS_L,
1808                                             phy_tus);
1809         if (status)
1810                 return status;
1811
1812         /* P_REG_DESK_PCS_RX_TUS */
1813         if (e822_vernier[link_spd].rx_desk_rsgb_pcs)
1814                 phy_tus = DIV_64BIT(tu_per_sec,
1815                                     e822_vernier[link_spd].rx_desk_rsgb_pcs);
1816         else
1817                 phy_tus = 0;
1818
1819         return ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_RX_TUS_L,
1820                                           phy_tus);
1821 }
1822
1823 /**
1824  * ice_calc_fixed_tx_offset_e822 - Calculated Fixed Tx offset for a port
1825  * @hw: pointer to the HW struct
1826  * @link_spd: the Link speed to calculate for
1827  *
1828  * Calculate the fixed offset due to known static latency data.
1829  */
1830 static u64
1831 ice_calc_fixed_tx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
1832 {
1833         u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
1834
1835         cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1836         clk_incval = ice_ptp_read_src_incval(hw);
1837
1838         /* Calculate TUs per second */
1839         tu_per_sec = cur_freq * clk_incval;
1840
1841         /* Calculate number of TUs to add for the fixed Tx latency. Since the
1842          * latency measurement is in 1/100th of a nanosecond, we need to
1843          * multiply by tu_per_sec and then divide by 1e11. This calculation
1844          * overflows 64 bit integer arithmetic, so break it up into two
1845          * divisions by 1e4 first then by 1e7.
1846          */
1847         fixed_offset = DIV_64BIT(tu_per_sec, 10000);
1848         fixed_offset *= e822_vernier[link_spd].tx_fixed_delay;
1849         fixed_offset = DIV_64BIT(fixed_offset, 10000000);
1850
1851         return fixed_offset;
1852 }
1853
1854 /**
1855  * ice_phy_cfg_tx_offset_e822 - Configure total Tx timestamp offset
1856  * @hw: pointer to the HW struct
1857  * @port: the PHY port to configure
1858  *
1859  * Program the P_REG_TOTAL_TX_OFFSET register with the total number of TUs to
1860  * adjust Tx timestamps by. This is calculated by combining some known static
1861  * latency along with the Vernier offset computations done by hardware.
1862  *
1863  * This function must be called only after the offset registers are valid,
1864  * i.e. after the Vernier calibration wait has passed, to ensure that the PHY
1865  * has measured the offset.
1866  *
1867  * To avoid overflow, when calculating the offset based on the known static
1868  * latency values, we use measurements in 1/100th of a nanosecond, and divide
1869  * the TUs per second up front. This avoids overflow while allowing
1870  * calculation of the adjustment using integer arithmetic.
1871  */
1872 enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port)
1873 {
1874         enum ice_ptp_link_spd link_spd;
1875         enum ice_ptp_fec_mode fec_mode;
1876         enum ice_status status;
1877         u64 total_offset, val;
1878
1879         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1880         if (status)
1881                 return status;
1882
1883         total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
1884
1885         /* Read the first Vernier offset from the PHY register and add it to
1886          * the total offset.
1887          */
1888         if (link_spd == ICE_PTP_LNK_SPD_1G ||
1889             link_spd == ICE_PTP_LNK_SPD_10G ||
1890             link_spd == ICE_PTP_LNK_SPD_25G ||
1891             link_spd == ICE_PTP_LNK_SPD_25G_RS ||
1892             link_spd == ICE_PTP_LNK_SPD_40G ||
1893             link_spd == ICE_PTP_LNK_SPD_50G) {
1894                 status = ice_read_64b_phy_reg_e822(hw, port,
1895                                                    P_REG_PAR_PCS_TX_OFFSET_L,
1896                                                    &val);
1897                 if (status)
1898                         return status;
1899
1900                 total_offset += val;
1901         }
1902
1903         /* For Tx, we only need to use the second Vernier offset for
1904          * multi-lane link speeds with RS-FEC. The lanes will always be
1905          * aligned.
1906          */
1907         if (link_spd == ICE_PTP_LNK_SPD_50G_RS ||
1908             link_spd == ICE_PTP_LNK_SPD_100G_RS) {
1909                 status = ice_read_64b_phy_reg_e822(hw, port,
1910                                                    P_REG_PAR_TX_TIME_L,
1911                                                    &val);
1912                 if (status)
1913                         return status;
1914
1915                 total_offset += val;
1916         }
1917
1918         /* Now that the total offset has been calculated, program it to the
1919          * PHY and indicate that the Tx offset is ready. After this,
1920          * timestamps will be enabled.
1921          */
1922         status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
1923                                             total_offset);
1924         if (status)
1925                 return status;
1926
1927         status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
1928         if (status)
1929                 return status;
1930
1931         return ICE_SUCCESS;
1932 }
1933
1934 /**
1935  * ice_phy_cfg_fixed_tx_offset_e822 - Configure Tx offset for bypass mode
1936  * @hw: pointer to the HW struct
1937  * @port: the PHY port to configure
1938  *
1939  * Calculate and program the fixed Tx offset, and indicate that the offset is
1940  * ready. This can be used when operating in bypass mode.
1941  */
1942 static enum ice_status
1943 ice_phy_cfg_fixed_tx_offset_e822(struct ice_hw *hw, u8 port)
1944 {
1945         enum ice_ptp_link_spd link_spd;
1946         enum ice_ptp_fec_mode fec_mode;
1947         enum ice_status status;
1948         u64 total_offset;
1949
1950         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1951         if (status)
1952                 return status;
1953
1954         total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
1955
1956         /* Program the fixed Tx offset into the P_REG_TOTAL_TX_OFFSET_L
1957          * register, then indicate that the Tx offset is ready. After this,
1958          * timestamps will be enabled.
1959          *
1960          * Note that this skips including the more precise offsets generated
1961          * by the Vernier calibration.
1962          */
1963         status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
1964                                             total_offset);
1965         if (status)
1966                 return status;
1967
1968         status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
1969         if (status)
1970                 return status;
1971
1972         return ICE_SUCCESS;
1973 }
1974
1975 /**
1976  * ice_phy_calc_pmd_adj_e822 - Calculate PMD adjustment for Rx
1977  * @hw: pointer to the HW struct
1978  * @port: the PHY port to adjust for
1979  * @link_spd: the current link speed of the PHY
1980  * @fec_mode: the current FEC mode of the PHY
1981  * @pmd_adj: on return, the amount to adjust the Rx total offset by
1982  *
1983  * Calculates the adjustment to Rx timestamps due to PMD alignment in the PHY.
1984  * This varies by link speed and FEC mode. The value calculated accounts for
1985  * various delays caused when receiving a packet.
1986  */
1987 static enum ice_status
1988 ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port,
1989                           enum ice_ptp_link_spd link_spd,
1990                           enum ice_ptp_fec_mode fec_mode, u64 *pmd_adj)
1991 {
1992         u64 cur_freq, clk_incval, tu_per_sec, mult, adj;
1993         u32 pmd_adj_divisor, val;
1994         enum ice_status status;
1995         u8 pmd_align;
1996
1997         status = ice_read_phy_reg_e822(hw, port, P_REG_PMD_ALIGNMENT, &val);
1998         if (status) {
1999                 ice_debug(hw, ICE_DBG_PTP, "Failed to read PMD alignment, status %d\n",
2000                           status);
2001                 return status;
2002         }
2003
2004         pmd_align = (u8)val;
2005
2006         cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
2007         clk_incval = ice_ptp_read_src_incval(hw);
2008
2009         /* Calculate TUs per second */
2010         tu_per_sec = cur_freq * clk_incval;
2011
2012         /* Get the link speed dependent PMD adjustment divisor */
2013         pmd_adj_divisor = e822_vernier[link_spd].pmd_adj_divisor;
2014
2015         /* The PMD alignment adjustment measurement depends on the link speed,
2016          * and whether FEC is enabled. For each link speed, the alignment
2017          * adjustment is calculated by dividing a value by the length of
2018          * a Time Unit in nanoseconds.
2019          *
2020          * 1G: align == 4 ? 10 * 0.8 : (align + 6 % 10) * 0.8
2021          * 10G: align == 65 ? 0 : (align * 0.1 * 32/33)
2022          * 10G w/FEC: align * 0.1 * 32/33
2023          * 25G: align == 65 ? 0 : (align * 0.4 * 32/33)
2024          * 25G w/FEC: align * 0.4 * 32/33
2025          * 40G: align == 65 ? 0 : (align * 0.1 * 32/33)
2026          * 40G w/FEC: align * 0.1 * 32/33
2027          * 50G: align == 65 ? 0 : (align * 0.4 * 32/33)
2028          * 50G w/FEC: align * 0.8 * 32/33
2029          *
2030          * For RS-FEC, if align is < 17 then we must also add 1.6 * 32/33.
2031          *
2032          * To allow for calculating this value using integer arithmetic, we
2033          * instead start with the number of TUs per second, (inverse of the
2034          * length of a Time Unit in nanoseconds), multiply by a value based
2035          * on the PMD alignment register, and then divide by the right value
2036          * calculated based on the table above. To avoid integer overflow this
2037          * division is broken up into a step of dividing by 125 first.
2038          */
2039         if (link_spd == ICE_PTP_LNK_SPD_1G) {
2040                 if (pmd_align == 4)
2041                         mult = 10;
2042                 else
2043                         mult = (pmd_align + 6) % 10;
2044         } else if (link_spd == ICE_PTP_LNK_SPD_10G ||
2045                    link_spd == ICE_PTP_LNK_SPD_25G ||
2046                    link_spd == ICE_PTP_LNK_SPD_40G ||
2047                    link_spd == ICE_PTP_LNK_SPD_50G) {
2048                 /* If Clause 74 FEC, always calculate PMD adjust */
2049                 if (pmd_align != 65 || fec_mode == ICE_PTP_FEC_MODE_CLAUSE74)
2050                         mult = pmd_align;
2051                 else
2052                         mult = 0;
2053         } else if (link_spd == ICE_PTP_LNK_SPD_25G_RS ||
2054                    link_spd == ICE_PTP_LNK_SPD_50G_RS ||
2055                    link_spd == ICE_PTP_LNK_SPD_100G_RS) {
2056                 if (pmd_align < 17)
2057                         mult = pmd_align + 40;
2058                 else
2059                         mult = pmd_align;
2060         } else {
2061                 ice_debug(hw, ICE_DBG_PTP, "Unknown link speed %d, skipping PMD adjustment\n",
2062                           link_spd);
2063                 mult = 0;
2064         }
2065
2066         /* In some cases, there's no need to adjust for the PMD alignment */
2067         if (!mult) {
2068                 *pmd_adj = 0;
2069                 return ICE_SUCCESS;
2070         }
2071
2072         /* Calculate the adjustment by multiplying TUs per second by the
2073          * appropriate multiplier and divisor. To avoid overflow, we first
2074          * divide by 125, and then handle remaining divisor based on the link
2075          * speed pmd_adj_divisor value.
2076          */
2077         adj = DIV_64BIT(tu_per_sec, 125);
2078         adj *= mult;
2079         adj = DIV_64BIT(adj, pmd_adj_divisor);
2080
2081         /* Finally, for 25G-RS and 50G-RS, a further adjustment for the Rx
2082          * cycle count is necessary.
2083          */
2084         if (link_spd == ICE_PTP_LNK_SPD_25G_RS) {
2085                 u64 cycle_adj;
2086                 u8 rx_cycle;
2087
2088                 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_40_TO_160_CNT,
2089                                                &val);
2090                 if (status) {
2091                         ice_debug(hw, ICE_DBG_PTP, "Failed to read 25G-RS Rx cycle count, status %d\n",
2092                                   status);
2093                         return status;
2094                 }
2095
2096                 rx_cycle = val & P_REG_RX_40_TO_160_CNT_RXCYC_M;
2097                 if (rx_cycle) {
2098                         mult = (4 - rx_cycle) * 40;
2099
2100                         cycle_adj = DIV_64BIT(tu_per_sec, 125);
2101                         cycle_adj *= mult;
2102                         cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor);
2103
2104                         adj += cycle_adj;
2105                 }
2106         } else if (link_spd == ICE_PTP_LNK_SPD_50G_RS) {
2107                 u64 cycle_adj;
2108                 u8 rx_cycle;
2109
2110                 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_80_TO_160_CNT,
2111                                                &val);
2112                 if (status) {
2113                         ice_debug(hw, ICE_DBG_PTP, "Failed to read 50G-RS Rx cycle count, status %d\n",
2114                                   status);
2115                         return status;
2116                 }
2117
2118                 rx_cycle = val & P_REG_RX_80_TO_160_CNT_RXCYC_M;
2119                 if (rx_cycle) {
2120                         mult = rx_cycle * 40;
2121
2122                         cycle_adj = DIV_64BIT(tu_per_sec, 125);
2123                         cycle_adj *= mult;
2124                         cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor);
2125
2126                         adj += cycle_adj;
2127                 }
2128         }
2129
2130         /* Return the calculated adjustment */
2131         *pmd_adj = adj;
2132
2133         return ICE_SUCCESS;
2134 }
2135
2136 /**
2137  * ice_calc_fixed_rx_offset_e822 - Calculated the fixed Rx offset for a port
2138  * @hw: pointer to HW struct
2139  * @link_spd: The Link speed to calculate for
2140  *
2141  * Determine the fixed Rx latency for a given link speed.
2142  */
2143 static u64
2144 ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
2145 {
2146         u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
2147
2148         cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
2149         clk_incval = ice_ptp_read_src_incval(hw);
2150
2151         /* Calculate TUs per second */
2152         tu_per_sec = cur_freq * clk_incval;
2153
2154         /* Calculate number of TUs to add for the fixed Rx latency. Since the
2155          * latency measurement is in 1/100th of a nanosecond, we need to
2156          * multiply by tu_per_sec and then divide by 1e11. This calculation
2157          * overflows 64 bit integer arithmetic, so break it up into two
2158          * divisions by 1e4 first then by 1e7.
2159          */
2160         fixed_offset = DIV_64BIT(tu_per_sec, 10000);
2161         fixed_offset *= e822_vernier[link_spd].rx_fixed_delay;
2162         fixed_offset = DIV_64BIT(fixed_offset, 10000000);
2163
2164         return fixed_offset;
2165 }
2166
2167 /**
2168  * ice_phy_cfg_rx_offset_e822 - Configure total Rx timestamp offset
2169  * @hw: pointer to the HW struct
2170  * @port: the PHY port to configure
2171  *
2172  * Program the P_REG_TOTAL_RX_OFFSET register with the number of Time Units to
2173  * adjust Rx timestamps by. This combines calculations from the Vernier offset
2174  * measurements taken in hardware with some data about known fixed delay as
2175  * well as adjusting for multi-lane alignment delay.
2176  *
2177  * This function must be called only after the offset registers are valid,
2178  * i.e. after the Vernier calibration wait has passed, to ensure that the PHY
2179  * has measured the offset.
2180  *
2181  * To avoid overflow, when calculating the offset based on the known static
2182  * latency values, we use measurements in 1/100th of a nanosecond, and divide
2183  * the TUs per second up front. This avoids overflow while allowing
2184  * calculation of the adjustment using integer arithmetic.
2185  */
2186 enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port)
2187 {
2188         enum ice_ptp_link_spd link_spd;
2189         enum ice_ptp_fec_mode fec_mode;
2190         u64 total_offset, pmd, val;
2191         enum ice_status status;
2192
2193         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
2194         if (status)
2195                 return status;
2196
2197         total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
2198
2199         /* Read the first Vernier offset from the PHY register and add it to
2200          * the total offset.
2201          */
2202         status = ice_read_64b_phy_reg_e822(hw, port,
2203                                            P_REG_PAR_PCS_RX_OFFSET_L,
2204                                            &val);
2205         if (status)
2206                 return status;
2207
2208         total_offset += val;
2209
2210         /* For Rx, all multi-lane link speeds include a second Vernier
2211          * calibration, because the lanes might not be aligned.
2212          */
2213         if (link_spd == ICE_PTP_LNK_SPD_40G ||
2214             link_spd == ICE_PTP_LNK_SPD_50G ||
2215             link_spd == ICE_PTP_LNK_SPD_50G_RS ||
2216             link_spd == ICE_PTP_LNK_SPD_100G_RS) {
2217                 status = ice_read_64b_phy_reg_e822(hw, port,
2218                                                    P_REG_PAR_RX_TIME_L,
2219                                                    &val);
2220                 if (status)
2221                         return status;
2222
2223                 total_offset += val;
2224         }
2225
2226         /* In addition, Rx must account for the PMD alignment */
2227         status = ice_phy_calc_pmd_adj_e822(hw, port, link_spd, fec_mode, &pmd);
2228         if (status)
2229                 return status;
2230
2231         /* For RS-FEC, this adjustment adds delay, but for other modes, it
2232          * subtracts delay.
2233          */
2234         if (fec_mode == ICE_PTP_FEC_MODE_RS_FEC)
2235                 total_offset += pmd;
2236         else
2237                 total_offset -= pmd;
2238
2239         /* Now that the total offset has been calculated, program it to the
2240          * PHY and indicate that the Rx offset is ready. After this,
2241          * timestamps will be enabled.
2242          */
2243         status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
2244                                             total_offset);
2245         if (status)
2246                 return status;
2247
2248         status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
2249         if (status)
2250                 return status;
2251
2252         return ICE_SUCCESS;
2253 }
2254
2255 /**
2256  * ice_phy_cfg_fixed_rx_offset_e822 - Configure fixed Rx offset for bypass mode
2257  * @hw: pointer to the HW struct
2258  * @port: the PHY port to configure
2259  *
2260  * Calculate and program the fixed Rx offset, and indicate that the offset is
2261  * ready. This can be used when operating in bypass mode.
2262  */
2263 static enum ice_status
2264 ice_phy_cfg_fixed_rx_offset_e822(struct ice_hw *hw, u8 port)
2265 {
2266         enum ice_ptp_link_spd link_spd;
2267         enum ice_ptp_fec_mode fec_mode;
2268         enum ice_status status;
2269         u64 total_offset;
2270
2271         status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
2272         if (status)
2273                 return status;
2274
2275         total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
2276
2277         /* Program the fixed Rx offset into the P_REG_TOTAL_RX_OFFSET_L
2278          * register, then indicate that the Rx offset is ready. After this,
2279          * timestamps will be enabled.
2280          *
2281          * Note that this skips including the more precise offsets generated
2282          * by Vernier calibration.
2283          */
2284         status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
2285                                             total_offset);
2286         if (status)
2287                 return status;
2288
2289         status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
2290         if (status)
2291                 return status;
2292
2293         return ICE_SUCCESS;
2294 }
2295
2296 /**
2297  * ice_read_phy_and_phc_time_e822 - Simultaneously capture PHC and PHY time
2298  * @hw: pointer to the HW struct
2299  * @port: the PHY port to read
2300  * @phy_time: on return, the 64bit PHY timer value
2301  * @phc_time: on return, the lower 64bits of PHC time
2302  *
2303  * Issue a READ_TIME timer command to simultaneously capture the PHY and PHC
2304  * timer values.
2305  */
2306 static enum ice_status
2307 ice_read_phy_and_phc_time_e822(struct ice_hw *hw, u8 port, u64 *phy_time,
2308                                u64 *phc_time)
2309 {
2310         enum ice_status status;
2311         u64 tx_time, rx_time;
2312         u32 zo, lo;
2313         u8 tmr_idx;
2314
2315         tmr_idx = ice_get_ptp_src_clock_index(hw);
2316
2317         /* Prepare the PHC timer for a READ_TIME capture command */
2318         ice_ptp_src_cmd(hw, READ_TIME);
2319
2320         /* Prepare the PHY timer for a READ_TIME capture command */
2321         status = ice_ptp_one_port_cmd(hw, port, READ_TIME, true);
2322         if (status)
2323                 return status;
2324
2325         /* Issue the sync to start the READ_TIME capture */
2326         ice_ptp_exec_tmr_cmd(hw);
2327
2328         /* Read the captured PHC time from the shadow time registers */
2329         zo = rd32(hw, GLTSYN_SHTIME_0(tmr_idx));
2330         lo = rd32(hw, GLTSYN_SHTIME_L(tmr_idx));
2331         *phc_time = (u64)lo << 32 | zo;
2332
2333         /* Read the captured PHY time from the PHY shadow registers */
2334         status = ice_ptp_read_port_capture(hw, port, &tx_time, &rx_time);
2335         if (status)
2336                 return status;
2337
2338         /* If the PHY Tx and Rx timers don't match, log a warning message.
2339          * Note that this should not happen in normal circumstances since the
2340          * driver always programs them together.
2341          */
2342         if (tx_time != rx_time)
2343                 ice_warn(hw, "PHY port %u Tx and Rx timers do not match, tx_time 0x%016llX, rx_time 0x%016llX\n",
2344                          port, (unsigned long long)tx_time,
2345                          (unsigned long long)rx_time);
2346
2347         *phy_time = tx_time;
2348
2349         return ICE_SUCCESS;
2350 }
2351
2352 /**
2353  * ice_sync_phy_timer_e822 - Synchronize the PHY timer with PHC timer
2354  * @hw: pointer to the HW struct
2355  * @port: the PHY port to synchronize
2356  *
2357  * Perform an adjustment to ensure that the PHY and PHC timers are in sync.
2358  * This is done by issuing a READ_TIME command which triggers a simultaneous
2359  * read of the PHY timer and PHC timer. Then we use the difference to
2360  * calculate an appropriate 2s complement addition to add to the PHY timer in
2361  * order to ensure it reads the same value as the primary PHC timer.
2362  */
2363 static enum ice_status ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port)
2364 {
2365         u64 phc_time, phy_time, difference;
2366         enum ice_status status;
2367
2368         if (!ice_ptp_lock(hw)) {
2369                 ice_debug(hw, ICE_DBG_PTP, "Failed to acquire PTP semaphore\n");
2370                 return ICE_ERR_NOT_READY;
2371         }
2372
2373         status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
2374         if (status)
2375                 goto err_unlock;
2376
2377         /* Calculate the amount required to add to the port time in order for
2378          * it to match the PHC time.
2379          *
2380          * Note that the port adjustment is done using 2s complement
2381          * arithmetic. This is convenient since it means that we can simply
2382          * calculate the difference between the PHC time and the port time,
2383          * and it will be interpreted correctly.
2384          */
2385         difference = phc_time - phy_time;
2386
2387         status = ice_ptp_prep_port_adj_e822(hw, port, (s64)difference, true);
2388         if (status)
2389                 goto err_unlock;
2390
2391         status = ice_ptp_one_port_cmd(hw, port, ADJ_TIME, true);
2392         if (status)
2393                 goto err_unlock;
2394
2395         /* Issue the sync to activate the time adjustment */
2396         ice_ptp_exec_tmr_cmd(hw);
2397
2398         /* Re-capture the timer values to flush the command registers and
2399          * verify that the time was properly adjusted.
2400          */
2401         status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
2402         if (status)
2403                 goto err_unlock;
2404
2405         ice_info(hw, "Port %u PHY time synced to PHC: 0x%016llX, 0x%016llX\n",
2406                  port, (unsigned long long)phy_time,
2407                  (unsigned long long)phc_time);
2408
2409         ice_ptp_unlock(hw);
2410
2411         return ICE_SUCCESS;
2412
2413 err_unlock:
2414         ice_ptp_unlock(hw);
2415         return status;
2416 }
2417
2418 /**
2419  * ice_stop_phy_timer_e822 - Stop the PHY clock timer
2420  * @hw: pointer to the HW struct
2421  * @port: the PHY port to stop
2422  * @soft_reset: if true, hold the SOFT_RESET bit of P_REG_PS
2423  *
2424  * Stop the clock of a PHY port. This must be done as part of the flow to
2425  * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
2426  * initialized or when link speed changes.
2427  */
2428 enum ice_status
2429 ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset)
2430 {
2431         enum ice_status status;
2432         u32 val;
2433
2434         status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 0);
2435         if (status)
2436                 return status;
2437
2438         status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 0);
2439         if (status)
2440                 return status;
2441
2442         status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2443         if (status)
2444                 return status;
2445
2446         val &= ~P_REG_PS_START_M;
2447         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2448         if (status)
2449                 return status;
2450
2451         val &= ~P_REG_PS_ENA_CLK_M;
2452         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2453         if (status)
2454                 return status;
2455
2456         if (soft_reset) {
2457                 val |= P_REG_PS_SFT_RESET_M;
2458                 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2459                 if (status)
2460                         return status;
2461         }
2462
2463         ice_debug(hw, ICE_DBG_PTP, "Disabled clock on PHY port %u\n", port);
2464
2465         return ICE_SUCCESS;
2466 }
2467
2468 /**
2469  * ice_start_phy_timer_e822 - Start the PHY clock timer
2470  * @hw: pointer to the HW struct
2471  * @port: the PHY port to start
2472  * @bypass: if true, start the PHY in bypass mode
2473  *
2474  * Start the clock of a PHY port. This must be done as part of the flow to
2475  * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
2476  * initialized or when link speed changes.
2477  *
2478  * Bypass mode enables timestamps immediately without waiting for Vernier
2479  * calibration to complete. Hardware will still continue taking Vernier
2480  * measurements on Tx or Rx of packets, but they will not be applied to
2481  * timestamps. Use ice_phy_exit_bypass_e822 to exit bypass mode once hardware
2482  * has completed offset calculation.
2483  */
2484 enum ice_status
2485 ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass)
2486 {
2487         enum ice_status status;
2488         u32 lo, hi, val;
2489         u64 incval;
2490         u8 tmr_idx;
2491
2492         tmr_idx = ice_get_ptp_src_clock_index(hw);
2493
2494         status = ice_stop_phy_timer_e822(hw, port, false);
2495         if (status)
2496                 return status;
2497
2498         ice_phy_cfg_lane_e822(hw, port);
2499
2500         status = ice_phy_cfg_uix_e822(hw, port);
2501         if (status)
2502                 return status;
2503
2504         status = ice_phy_cfg_parpcs_e822(hw, port);
2505         if (status)
2506                 return status;
2507
2508         lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
2509         hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
2510         incval = (u64)hi << 32 | lo;
2511
2512         status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
2513         if (status)
2514                 return status;
2515
2516         status = ice_ptp_one_port_cmd(hw, port, INIT_INCVAL, true);
2517         if (status)
2518                 return status;
2519
2520         ice_ptp_exec_tmr_cmd(hw);
2521
2522         status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2523         if (status)
2524                 return status;
2525
2526         val |= P_REG_PS_SFT_RESET_M;
2527         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2528         if (status)
2529                 return status;
2530
2531         val |= P_REG_PS_START_M;
2532         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2533         if (status)
2534                 return status;
2535
2536         val &= ~P_REG_PS_SFT_RESET_M;
2537         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2538         if (status)
2539                 return status;
2540
2541         status = ice_ptp_one_port_cmd(hw, port, INIT_INCVAL, true);
2542         if (status)
2543                 return status;
2544
2545         ice_ptp_exec_tmr_cmd(hw);
2546
2547         val |= P_REG_PS_ENA_CLK_M;
2548         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2549         if (status)
2550                 return status;
2551
2552         val |= P_REG_PS_LOAD_OFFSET_M;
2553         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2554         if (status)
2555                 return status;
2556
2557         ice_ptp_exec_tmr_cmd(hw);
2558
2559         status = ice_sync_phy_timer_e822(hw, port);
2560         if (status)
2561                 return status;
2562
2563         if (bypass) {
2564                 val |= P_REG_PS_BYPASS_MODE_M;
2565                 /* Enter BYPASS mode, enabling timestamps immediately. */
2566                 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2567                 if (status)
2568                         return status;
2569
2570                 /* Program the fixed Tx offset */
2571                 status = ice_phy_cfg_fixed_tx_offset_e822(hw, port);
2572                 if (status)
2573                         return status;
2574
2575                 /* Program the fixed Rx offset */
2576                 status = ice_phy_cfg_fixed_rx_offset_e822(hw, port);
2577                 if (status)
2578                         return status;
2579         }
2580
2581         ice_debug(hw, ICE_DBG_PTP, "Enabled clock on PHY port %u\n", port);
2582
2583         return ICE_SUCCESS;
2584 }
2585
2586 /**
2587  * ice_phy_exit_bypass_e822 - Exit bypass mode, after vernier calculations
2588  * @hw: pointer to the HW struct
2589  * @port: the PHY port to configure
2590  *
2591  * After hardware finishes vernier calculations for the Tx and Rx offset, this
2592  * function can be used to exit bypass mode by updating the total Tx and Rx
2593  * offsets, and then disabling bypass. This will enable hardware to include
2594  * the more precise offset calibrations, increasing precision of the generated
2595  * timestamps.
2596  *
2597  * This cannot be done until hardware has measured the offsets, which requires
2598  * waiting until at least one packet has been sent and received by the device.
2599  */
2600 enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port)
2601 {
2602         enum ice_status status;
2603         u32 val;
2604
2605         status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &val);
2606         if (status) {
2607                 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, status %d\n",
2608                           port, status);
2609                 return status;
2610         }
2611
2612         if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
2613                 ice_debug(hw, ICE_DBG_PTP, "Tx offset is not yet valid for port %u\n",
2614                           port);
2615                 return ICE_ERR_NOT_READY;
2616         }
2617
2618         status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &val);
2619         if (status) {
2620                 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, status %d\n",
2621                           port, status);
2622                 return status;
2623         }
2624
2625         if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
2626                 ice_debug(hw, ICE_DBG_PTP, "Rx offset is not yet valid for port %u\n",
2627                           port);
2628                 return ICE_ERR_NOT_READY;
2629         }
2630
2631         status = ice_phy_cfg_tx_offset_e822(hw, port);
2632         if (status) {
2633                 ice_debug(hw, ICE_DBG_PTP, "Failed to program total Tx offset for port %u, status %d\n",
2634                           port, status);
2635                 return status;
2636         }
2637
2638         status = ice_phy_cfg_rx_offset_e822(hw, port);
2639         if (status) {
2640                 ice_debug(hw, ICE_DBG_PTP, "Failed to program total Rx offset for port %u, status %d\n",
2641                           port, status);
2642                 return status;
2643         }
2644
2645         /* Exit bypass mode now that the offset has been updated */
2646         status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2647         if (status) {
2648                 ice_debug(hw, ICE_DBG_PTP, "Failed to read P_REG_PS for port %u, status %d\n",
2649                           port, status);
2650                 return status;
2651         }
2652
2653         if (!(val & P_REG_PS_BYPASS_MODE_M))
2654                 ice_debug(hw, ICE_DBG_PTP, "Port %u not in bypass mode\n",
2655                           port);
2656
2657         val &= ~P_REG_PS_BYPASS_MODE_M;
2658         status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2659         if (status) {
2660                 ice_debug(hw, ICE_DBG_PTP, "Failed to disable bypass for port %u, status %d\n",
2661                           port, status);
2662                 return status;
2663         }
2664
2665         ice_info(hw, "Exiting bypass mode on PHY port %u\n", port);
2666
2667         return ICE_SUCCESS;
2668 }
2669
2670 /* E810 functions
2671  *
2672  * The following functions operate on the E810 series devices which use
2673  * a separate external PHY.
2674  */
2675
2676 /**
2677  * ice_read_phy_reg_e810_lp - Read register from external PHY on E810
2678  * @hw: pointer to the HW struct
2679  * @addr: the address to read from
2680  * @val: On return, the value read from the PHY
2681  * @lock_sbq: true if the sideband queue lock must be acquired
2682  *
2683  * Read a register from the external PHY on the E810 device.
2684  */
2685 static enum ice_status
2686 ice_read_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 *val, bool lock_sbq)
2687 {
2688         struct ice_sbq_msg_input msg = {0};
2689         enum ice_status status;
2690
2691         msg.msg_addr_low = ICE_LO_WORD(addr);
2692         msg.msg_addr_high = ICE_HI_WORD(addr);
2693         msg.opcode = ice_sbq_msg_rd;
2694         msg.dest_dev = rmn_0;
2695
2696         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2697         if (status) {
2698                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2699                           status);
2700                 return status;
2701         }
2702
2703         *val = msg.data;
2704
2705         return ICE_SUCCESS;
2706 }
2707
2708 static enum ice_status
2709 ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
2710 {
2711         return ice_read_phy_reg_e810_lp(hw, addr, val, true);
2712 }
2713
2714 /**
2715  * ice_write_phy_reg_e810_lp - Write register on external PHY on E810
2716  * @hw: pointer to the HW struct
2717  * @addr: the address to writem to
2718  * @val: the value to write to the PHY
2719  * @lock_sbq: true if the sideband queue lock must be acquired
2720  *
2721  * Write a value to a register of the external PHY on the E810 device.
2722  */
2723 static enum ice_status
2724 ice_write_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 val, bool lock_sbq)
2725 {
2726         struct ice_sbq_msg_input msg = {0};
2727         enum ice_status status;
2728
2729         msg.msg_addr_low = ICE_LO_WORD(addr);
2730         msg.msg_addr_high = ICE_HI_WORD(addr);
2731         msg.opcode = ice_sbq_msg_wr;
2732         msg.dest_dev = rmn_0;
2733         msg.data = val;
2734
2735         status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2736         if (status) {
2737                 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2738                           status);
2739                 return status;
2740         }
2741
2742         return ICE_SUCCESS;
2743 }
2744
2745 static enum ice_status
2746 ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
2747 {
2748         return ice_write_phy_reg_e810_lp(hw, addr, val, true);
2749 }
2750
2751 /**
2752  * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY
2753  * @hw: pointer to the HW struct
2754  * @lport: the lport to read from
2755  * @idx: the timestamp index to read
2756  * @tstamp: on return, the 40bit timestamp value
2757  *
2758  * Read a 40bit timestamp value out of the timestamp block of the external PHY
2759  * on the E810 device.
2760  */
2761 static enum ice_status
2762 ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
2763 {
2764         enum ice_status status;
2765         u32 lo_addr, hi_addr, lo, hi;
2766
2767         lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
2768         hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
2769
2770         status = ice_read_phy_reg_e810(hw, lo_addr, &lo);
2771         if (status) {
2772                 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
2773                           status);
2774                 return status;
2775         }
2776
2777         status = ice_read_phy_reg_e810(hw, hi_addr, &hi);
2778         if (status) {
2779                 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
2780                           status);
2781                 return status;
2782         }
2783
2784         /* For E810 devices, the timestamp is reported with the lower 32 bits
2785          * in the low register, and the upper 8 bits in the high register.
2786          */
2787         *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
2788
2789         return ICE_SUCCESS;
2790 }
2791
2792 /**
2793  * ice_clear_phy_tstamp_e810 - Clear a timestamp from the external PHY
2794  * @hw: pointer to the HW struct
2795  * @lport: the lport to read from
2796  * @idx: the timestamp index to reset
2797  *
2798  * Clear a timestamp, resetting its valid bit, from the timestamp block of the
2799  * external PHY on the E810 device.
2800  */
2801 static enum ice_status
2802 ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
2803 {
2804         enum ice_status status;
2805         u32 lo_addr, hi_addr;
2806
2807         lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
2808         hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
2809
2810         status = ice_write_phy_reg_e810(hw, lo_addr, 0);
2811         if (status) {
2812                 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
2813                           status);
2814                 return status;
2815         }
2816
2817         status = ice_write_phy_reg_e810(hw, hi_addr, 0);
2818         if (status) {
2819                 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
2820                           status);
2821                 return status;
2822         }
2823
2824         return ICE_SUCCESS;
2825 }
2826
2827 /**
2828  * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
2829  * @hw: pointer to HW struct
2830  *
2831  * Enable the timesync PTP functionality for the external PHY connected to
2832  * this function.
2833  *
2834  * Note there is no equivalent function needed on E822 based devices.
2835  */
2836 enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw)
2837 {
2838         enum ice_status status;
2839         u8 tmr_idx;
2840
2841         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2842         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
2843                                         GLTSYN_ENA_TSYN_ENA_M);
2844         if (status)
2845                 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
2846                           status);
2847
2848         return status;
2849 }
2850
2851 /**
2852  * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
2853  * @hw: pointer to HW struct
2854  *
2855  * Perform E810-specific PTP hardware clock initialization steps.
2856  */
2857 static enum ice_status ice_ptp_init_phc_e810(struct ice_hw *hw)
2858 {
2859         /* Ensure synchronization delay is zero */
2860         wr32(hw, GLTSYN_SYNC_DLAY, 0);
2861
2862         /* Initialize the PHY */
2863         return ice_ptp_init_phy_e810(hw);
2864 }
2865
2866 /**
2867  * ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
2868  * @hw: Board private structure
2869  * @time: Time to initialize the PHY port clock to
2870  *
2871  * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the
2872  * initial clock time. The time will not actually be programmed until the
2873  * driver issues an INIT_TIME command.
2874  *
2875  * The time value is the upper 32 bits of the PHY timer, usually in units of
2876  * nominal nanoseconds.
2877  */
2878 static enum ice_status ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
2879 {
2880         enum ice_status status;
2881         u8 tmr_idx;
2882
2883         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2884         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
2885         if (status) {
2886                 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
2887                           status);
2888                 return status;
2889         }
2890
2891         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
2892         if (status) {
2893                 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
2894                           status);
2895                 return status;
2896         }
2897
2898         return ICE_SUCCESS;
2899 }
2900
2901 /**
2902  * ice_ptp_prep_phy_adj_e810 - Prep PHY port for a time adjustment
2903  * @hw: pointer to HW struct
2904  * @adj: adjustment value to program
2905  * @lock_sbq: true if the sideband queue luck must be acquired
2906  *
2907  * Prepare the PHY port for an atomic adjustment by programming the PHY
2908  * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual adjustment
2909  * is completed by issuing an ADJ_TIME sync command.
2910  *
2911  * The adjustment value only contains the portion used for the upper 32bits of
2912  * the PHY timer, usually in units of nominal nanoseconds. Negative
2913  * adjustments are supported using 2s complement arithmetic.
2914  */
2915 static enum ice_status
2916 ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj, bool lock_sbq)
2917 {
2918         enum ice_status status;
2919         u8 tmr_idx;
2920
2921         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2922
2923         /* Adjustments are represented as signed 2's complement values in
2924          * nanoseconds. Sub-nanosecond adjustment is not supported.
2925          */
2926         status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_L(tmr_idx),
2927                                            0, lock_sbq);
2928         if (status) {
2929                 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
2930                           status);
2931                 return status;
2932         }
2933
2934         status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_H(tmr_idx),
2935                                            adj, lock_sbq);
2936         if (status) {
2937                 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
2938                           status);
2939                 return status;
2940         }
2941
2942         return ICE_SUCCESS;
2943 }
2944
2945 /**
2946  * ice_ptp_prep_phy_incval_e810 - Prep PHY port increment value change
2947  * @hw: pointer to HW struct
2948  * @incval: The new 40bit increment value to prepare
2949  *
2950  * Prepare the PHY port for a new increment value by programming the PHY
2951  * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual change is
2952  * completed by issuing an INIT_INCVAL command.
2953  */
2954 static enum ice_status
2955 ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
2956 {
2957         enum ice_status status;
2958         u32 high, low;
2959         u8 tmr_idx;
2960
2961         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2962         low = ICE_LO_DWORD(incval);
2963         high = ICE_HI_DWORD(incval);
2964
2965         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
2966         if (status) {
2967                 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
2968                           status);
2969                 return status;
2970         }
2971
2972         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
2973         if (status) {
2974                 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
2975                           status);
2976                 return status;
2977         }
2978
2979         return ICE_SUCCESS;
2980 }
2981
2982 /**
2983  * ice_ptp_prep_phy_adj_target_e810 - Prepare PHY port with adjust target
2984  * @hw: Board private structure
2985  * @target_time: Time to trigger the clock adjustment at
2986  *
2987  * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation for
2988  * a target time adjust, which will trigger an adjustment of the clock in the
2989  * future. The actual adjustment will occur the next time the PHY port timer
2990  * crosses over the provided value after the driver issues an ADJ_TIME_AT_TIME
2991  * command.
2992  *
2993  * The time value is the upper 32 bits of the PHY timer, usually in units of
2994  * nominal nanoseconds.
2995  */
2996 static enum ice_status
2997 ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time)
2998 {
2999         enum ice_status status;
3000         u8 tmr_idx;
3001
3002         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3003         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
3004         if (status) {
3005                 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_0, status %d\n",
3006                           status);
3007                 return status;
3008         }
3009
3010         status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx),
3011                                         target_time);
3012         if (status) {
3013                 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_L, status %d\n",
3014                           status);
3015                 return status;
3016         }
3017
3018         return ICE_SUCCESS;
3019 }
3020
3021 /**
3022  * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command
3023  * @hw: pointer to HW struct
3024  * @cmd: Command to be sent to the port
3025  * @lock_sbq: true if the sideband queue lock must be acquired
3026  *
3027  * Prepare the external PHYs connected to this device for a timer sync
3028  * command.
3029  */
3030 static enum ice_status
3031 ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
3032                       bool lock_sbq)
3033 {
3034         enum ice_status status;
3035         u32 cmd_val, val;
3036
3037         switch (cmd) {
3038         case INIT_TIME:
3039                 cmd_val = GLTSYN_CMD_INIT_TIME;
3040                 break;
3041         case INIT_INCVAL:
3042                 cmd_val = GLTSYN_CMD_INIT_INCVAL;
3043                 break;
3044         case ADJ_TIME:
3045                 cmd_val = GLTSYN_CMD_ADJ_TIME;
3046                 break;
3047         case ADJ_TIME_AT_TIME:
3048                 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
3049                 break;
3050         case READ_TIME:
3051                 cmd_val = GLTSYN_CMD_READ_TIME;
3052                 break;
3053         default:
3054                 ice_warn(hw, "Unknown timer command %u\n", cmd);
3055                 return ICE_ERR_PARAM;
3056         }
3057
3058         /* Read, modify, write */
3059         status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq);
3060         if (status) {
3061                 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n",
3062                           status);
3063                 return status;
3064         }
3065
3066         /* Modify necessary bits only and perform write */
3067         val &= ~TS_CMD_MASK_E810;
3068         val |= cmd_val;
3069
3070         status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq);
3071         if (status) {
3072                 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n",
3073                           status);
3074                 return status;
3075         }
3076
3077         return ICE_SUCCESS;
3078 }
3079
3080 /* E810T SMA functions
3081  *
3082  * The following functions operate specifically on E810T hardware and are used
3083  * to access the extended GPIOs available.
3084  */
3085
3086 /**
3087  * ice_get_pca9575_handle
3088  * @hw: pointer to the hw struct
3089  * @pca9575_handle: GPIO controller's handle
3090  *
3091  * Find and return the GPIO controller's handle in the netlist.
3092  * When found - the value will be cached in the hw structure and following calls
3093  * will return cached value
3094  */
3095 static enum ice_status
3096 ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_handle)
3097 {
3098         struct ice_aqc_get_link_topo *cmd;
3099         struct ice_aq_desc desc;
3100         enum ice_status status;
3101         u8 idx;
3102
3103         if (!hw || !pca9575_handle)
3104                 return ICE_ERR_PARAM;
3105
3106         /* If handle was read previously return cached value */
3107         if (hw->io_expander_handle) {
3108                 *pca9575_handle = hw->io_expander_handle;
3109                 return ICE_SUCCESS;
3110         }
3111
3112         /* If handle was not detected read it from the netlist */
3113         cmd = &desc.params.get_link_topo;
3114         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
3115
3116         /* Set node type to GPIO controller */
3117         cmd->addr.topo_params.node_type_ctx =
3118                 (ICE_AQC_LINK_TOPO_NODE_TYPE_M &
3119                  ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
3120
3121 #define SW_PCA9575_SFP_TOPO_IDX         2
3122 #define SW_PCA9575_QSFP_TOPO_IDX        1
3123
3124         /* Check if the SW IO expander controlling SMA exists in the netlist. */
3125         if (hw->device_id == ICE_DEV_ID_E810C_SFP)
3126                 idx = SW_PCA9575_SFP_TOPO_IDX;
3127         else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
3128                 idx = SW_PCA9575_QSFP_TOPO_IDX;
3129         else
3130                 return ICE_ERR_NOT_SUPPORTED;
3131
3132         cmd->addr.topo_params.index = idx;
3133
3134         status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3135         if (status)
3136                 return ICE_ERR_NOT_SUPPORTED;
3137
3138         /* Verify if we found the right IO expander type */
3139         if (desc.params.get_link_topo.node_part_num !=
3140                 ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575)
3141                 return ICE_ERR_NOT_SUPPORTED;
3142
3143         /* If present save the handle and return it */
3144         hw->io_expander_handle = desc.params.get_link_topo.addr.handle;
3145         *pca9575_handle = hw->io_expander_handle;
3146
3147         return ICE_SUCCESS;
3148 }
3149
3150 /**
3151  * ice_read_e810t_pca9575_reg
3152  * @hw: pointer to the hw struct
3153  * @offset: GPIO controller register offset
3154  * @data: pointer to data to be read from the GPIO controller
3155  *
3156  * Read the register from the GPIO controller
3157  */
3158 enum ice_status
3159 ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data)
3160 {
3161         struct ice_aqc_link_topo_addr link_topo;
3162         enum ice_status status;
3163         __le16 addr;
3164
3165         memset(&link_topo, 0, sizeof(link_topo));
3166
3167         status = ice_get_pca9575_handle(hw, &link_topo.handle);
3168         if (status)
3169                 return status;
3170
3171         link_topo.topo_params.node_type_ctx =
3172                 (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
3173                  ICE_AQC_LINK_TOPO_NODE_CTX_S);
3174
3175         addr = CPU_TO_LE16((u16)offset);
3176
3177         return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
3178 }
3179
3180 /**
3181  * ice_write_e810t_pca9575_reg
3182  * @hw: pointer to the hw struct
3183  * @offset: GPIO controller register offset
3184  * @data: data to be written to the GPIO controller
3185  *
3186  * Write the data to the GPIO controller register
3187  */
3188 enum ice_status
3189 ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data)
3190 {
3191         struct ice_aqc_link_topo_addr link_topo;
3192         enum ice_status status;
3193         __le16 addr;
3194
3195         memset(&link_topo, 0, sizeof(link_topo));
3196
3197         status = ice_get_pca9575_handle(hw, &link_topo.handle);
3198         if (status)
3199                 return status;
3200
3201         link_topo.topo_params.node_type_ctx =
3202                 (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
3203                  ICE_AQC_LINK_TOPO_NODE_CTX_S);
3204
3205         addr = CPU_TO_LE16((u16)offset);
3206
3207         return ice_aq_write_i2c(hw, link_topo, 0, addr, 1, &data, NULL);
3208 }
3209
3210 /**
3211  * ice_read_sma_ctrl_e810t
3212  * @hw: pointer to the hw struct
3213  * @data: pointer to data to be read from the GPIO controller
3214  *
3215  * Read the SMA controller state. Only bits 3-7 in data are valid.
3216  */
3217 enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data)
3218 {
3219         enum ice_status status;
3220         u16 handle;
3221         u8 i;
3222
3223         status = ice_get_pca9575_handle(hw, &handle);
3224         if (status)
3225                 return status;
3226
3227         *data = 0;
3228
3229         for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
3230                 bool pin;
3231
3232                 status = ice_aq_get_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
3233                                          &pin, NULL);
3234                 if (status)
3235                         break;
3236                 *data |= (u8)(!pin) << i;
3237         }
3238
3239         return status;
3240 }
3241
3242 /**
3243  * ice_write_sma_ctrl_e810t
3244  * @hw: pointer to the hw struct
3245  * @data: data to be written to the GPIO controller
3246  *
3247  * Write the data to the SMA controller. Only bits 3-7 in data are valid.
3248  */
3249 enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data)
3250 {
3251         enum ice_status status;
3252         u16 handle;
3253         u8 i;
3254
3255         status = ice_get_pca9575_handle(hw, &handle);
3256         if (status)
3257                 return status;
3258
3259         for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
3260                 bool pin;
3261
3262                 pin = !(data & (1 << i));
3263                 status = ice_aq_set_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
3264                                          pin, NULL);
3265                 if (status)
3266                         break;
3267         }
3268
3269         return status;
3270 }
3271
3272 /**
3273  * ice_e810t_is_pca9575_present
3274  * @hw: pointer to the hw struct
3275  *
3276  * Check if the SW IO expander is present in the netlist
3277  */
3278 bool ice_e810t_is_pca9575_present(struct ice_hw *hw)
3279 {
3280         enum ice_status status;
3281         __le16 handle = 0;
3282
3283         if (!ice_is_e810t(hw))
3284                 return false;
3285
3286         status = ice_get_pca9575_handle(hw, &handle);
3287         if (!status && handle)
3288                 return true;
3289
3290         return false;
3291 }
3292
3293 /* Device agnostic functions
3294  *
3295  * The following functions implement shared behavior common to both E822 and
3296  * E810 devices, possibly calling a device specific implementation where
3297  * necessary.
3298  */
3299
3300 /**
3301  * ice_ptp_lock - Acquire PTP global semaphore register lock
3302  * @hw: pointer to the HW struct
3303  *
3304  * Acquire the global PTP hardware semaphore lock. Returns true if the lock
3305  * was acquired, false otherwise.
3306  *
3307  * The PFTSYN_SEM register sets the busy bit on read, returning the previous
3308  * value. If software sees the busy bit cleared, this means that this function
3309  * acquired the lock (and the busy bit is now set). If software sees the busy
3310  * bit set, it means that another function acquired the lock.
3311  *
3312  * Software must clear the busy bit with a write to release the lock for other
3313  * functions when done.
3314  */
3315 bool ice_ptp_lock(struct ice_hw *hw)
3316 {
3317         u32 hw_lock;
3318         int i;
3319
3320 #define MAX_TRIES 5
3321
3322         for (i = 0; i < MAX_TRIES; i++) {
3323                 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
3324                 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
3325                 if (hw_lock) {
3326                         /* Somebody is holding the lock */
3327                         ice_msec_delay(10, true);
3328                         continue;
3329                 } else {
3330                         break;
3331                 }
3332         }
3333
3334         return !hw_lock;
3335 }
3336
3337 /**
3338  * ice_ptp_unlock - Release PTP global semaphore register lock
3339  * @hw: pointer to the HW struct
3340  *
3341  * Release the global PTP hardware semaphore lock. This is done by writing to
3342  * the PFTSYN_SEM register.
3343  */
3344 void ice_ptp_unlock(struct ice_hw *hw)
3345 {
3346         wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
3347 }
3348
3349 /**
3350  * ice_ptp_src_cmd - Prepare source timer for a timer command
3351  * @hw: pointer to HW structure
3352  * @cmd: Timer command
3353  *
3354  * Prepare the source timer for an upcoming timer sync command.
3355  */
3356 void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
3357 {
3358         u32 cmd_val;
3359         u8 tmr_idx;
3360
3361         tmr_idx = ice_get_ptp_src_clock_index(hw);
3362         cmd_val = tmr_idx << SEL_CPK_SRC;
3363
3364         switch (cmd) {
3365         case INIT_TIME:
3366                 cmd_val |= GLTSYN_CMD_INIT_TIME;
3367                 break;
3368         case INIT_INCVAL:
3369                 cmd_val |= GLTSYN_CMD_INIT_INCVAL;
3370                 break;
3371         case ADJ_TIME:
3372                 cmd_val |= GLTSYN_CMD_ADJ_TIME;
3373                 break;
3374         case ADJ_TIME_AT_TIME:
3375                 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
3376                 break;
3377         case READ_TIME:
3378                 cmd_val |= GLTSYN_CMD_READ_TIME;
3379                 break;
3380         default:
3381                 ice_warn(hw, "Unknown timer command %u\n", cmd);
3382                 return;
3383         }
3384
3385         wr32(hw, GLTSYN_CMD, cmd_val);
3386 }
3387
3388 /**
3389  * ice_ptp_tmr_cmd - Prepare and trigger a timer sync command
3390  * @hw: pointer to HW struct
3391  * @cmd: the command to issue
3392  * @lock_sbq: true if the sideband queue lock must be acquired
3393  *
3394  * Prepare the source timer and PHY timers and then trigger the requested
3395  * command. This causes the shadow registers previously written in preparation
3396  * for the command to be synchronously applied to both the source and PHY
3397  * timers.
3398  */
3399 static enum ice_status
3400 ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
3401 {
3402         enum ice_status status;
3403
3404         /* First, prepare the source timer */
3405         ice_ptp_src_cmd(hw, cmd);
3406
3407         /* Next, prepare the ports */
3408         if (ice_is_e810(hw))
3409                 status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq);
3410         else
3411                 status = ice_ptp_port_cmd_e822(hw, cmd, lock_sbq);
3412         if (status) {
3413                 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
3414                           cmd, status);
3415                 return status;
3416         }
3417
3418         /* Write the sync command register to drive both source and PHY timer
3419          * commands synchronously
3420          */
3421         ice_ptp_exec_tmr_cmd(hw);
3422
3423         return ICE_SUCCESS;
3424 }
3425
3426 /**
3427  * ice_ptp_init_time - Initialize device time to provided value
3428  * @hw: pointer to HW struct
3429  * @time: 64bits of time (GLTSYN_TIME_L and GLTSYN_TIME_H)
3430  *
3431  * Initialize the device to the specified time provided. This requires a three
3432  * step process:
3433  *
3434  * 1) write the new init time to the source timer shadow registers
3435  * 2) write the new init time to the phy timer shadow registers
3436  * 3) issue an init_time timer command to synchronously switch both the source
3437  *    and port timers to the new init time value at the next clock cycle.
3438  */
3439 enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time)
3440 {
3441         enum ice_status status;
3442         u8 tmr_idx;
3443
3444         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3445
3446         /* Source timers */
3447         wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time));
3448         wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time));
3449         wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
3450
3451         /* PHY Clks */
3452         /* Fill Rx and Tx ports and send msg to PHY */
3453         if (ice_is_e810(hw))
3454                 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
3455         else
3456                 status = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
3457         if (status)
3458                 return status;
3459
3460         return ice_ptp_tmr_cmd(hw, INIT_TIME, true);
3461 }
3462
3463 /**
3464  * ice_ptp_write_incval - Program PHC with new increment value
3465  * @hw: pointer to HW struct
3466  * @incval: Source timer increment value per clock cycle
3467  *
3468  * Program the PHC with a new increment value. This requires a three-step
3469  * process:
3470  *
3471  * 1) Write the increment value to the source timer shadow registers
3472  * 2) Write the increment value to the PHY timer shadow registers
3473  * 3) Issue an INIT_INCVAL timer command to synchronously switch both the
3474  *    source and port timers to the new increment value at the next clock
3475  *    cycle.
3476  */
3477 enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
3478 {
3479         enum ice_status status;
3480         u8 tmr_idx;
3481
3482         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3483
3484         /* Shadow Adjust */
3485         wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval));
3486         wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval));
3487
3488         if (ice_is_e810(hw))
3489                 status = ice_ptp_prep_phy_incval_e810(hw, incval);
3490         else
3491                 status = ice_ptp_prep_phy_incval_e822(hw, incval);
3492         if (status)
3493                 return status;
3494
3495         return ice_ptp_tmr_cmd(hw, INIT_INCVAL, true);
3496 }
3497
3498 /**
3499  * ice_ptp_write_incval_locked - Program new incval while holding semaphore
3500  * @hw: pointer to HW struct
3501  * @incval: Source timer increment value per clock cycle
3502  *
3503  * Program a new PHC incval while holding the PTP semaphore.
3504  */
3505 enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
3506 {
3507         enum ice_status status;
3508
3509         if (!ice_ptp_lock(hw))
3510                 return ICE_ERR_NOT_READY;
3511
3512         status = ice_ptp_write_incval(hw, incval);
3513
3514         ice_ptp_unlock(hw);
3515
3516         return status;
3517 }
3518
3519 /**
3520  * ice_ptp_adj_clock - Adjust PHC clock time atomically
3521  * @hw: pointer to HW struct
3522  * @adj: Adjustment in nanoseconds
3523  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
3524  *            sq_lock has already been locked at a higher level
3525  *
3526  * Perform an atomic adjustment of the PHC time by the specified number of
3527  * nanoseconds. This requires a three-step process:
3528  *
3529  * 1) Write the adjustment to the source timer shadow registers
3530  * 2) Write the adjustment to the PHY timer shadow registers
3531  * 3) Issue an ADJ_TIME timer command to synchronously apply the adjustment to
3532  *    both the source and port timers at the next clock cycle.
3533  */
3534 enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq)
3535 {
3536         enum ice_status status;
3537         u8 tmr_idx;
3538
3539         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3540
3541         /* Write the desired clock adjustment into the GLTSYN_SHADJ register.
3542          * For an ADJ_TIME command, this set of registers represents the value
3543          * to add to the clock time. It supports subtraction by interpreting
3544          * the value as a 2's complement integer.
3545          */
3546         wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
3547         wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
3548
3549         if (ice_is_e810(hw))
3550                 status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq);
3551         else
3552                 status = ice_ptp_prep_phy_adj_e822(hw, adj, lock_sbq);
3553         if (status)
3554                 return status;
3555
3556         return ice_ptp_tmr_cmd(hw, ADJ_TIME, lock_sbq);
3557 }
3558
3559 /**
3560  * ice_ptp_adj_clock_at_time - Adjust PHC atomically at specified time
3561  * @hw: pointer to HW struct
3562  * @at_time: Time in nanoseconds at which to perform the adjustment
3563  * @adj: Adjustment in nanoseconds
3564  *
3565  * Perform an atomic adjustment to the PHC clock at the specified time. This
3566  * requires a five-step process:
3567  *
3568  * 1) Write the adjustment to the source timer shadow adjust registers
3569  * 2) Write the target time to the source timer shadow time registers
3570  * 3) Write the adjustment to the PHY timers shadow adjust registers
3571  * 4) Write the target time to the PHY timers shadow adjust registers
3572  * 5) Issue an ADJ_TIME_AT_TIME command to initiate the atomic adjustment.
3573  */
3574 enum ice_status
3575 ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
3576 {
3577         enum ice_status status;
3578         u32 time_lo, time_hi;
3579         u8 tmr_idx;
3580
3581         tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3582         time_lo = ICE_LO_DWORD(at_time);
3583         time_hi = ICE_HI_DWORD(at_time);
3584
3585         /* Write the desired clock adjustment into the GLTSYN_SHADJ register.
3586          * For an ADJ_TIME_AT_TIME command, this set of registers represents
3587          * the value to add to the clock time. It supports subtraction by
3588          * interpreting the value as a 2's complement integer.
3589          */
3590         wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
3591         wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
3592
3593         /* Write the target time to trigger the adjustment for source clock */
3594         wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
3595         wr32(hw, GLTSYN_SHTIME_L(tmr_idx), time_lo);
3596         wr32(hw, GLTSYN_SHTIME_H(tmr_idx), time_hi);
3597
3598         /* Prepare PHY port adjustments */
3599         if (ice_is_e810(hw))
3600                 status = ice_ptp_prep_phy_adj_e810(hw, adj, true);
3601         else
3602                 status = ice_ptp_prep_phy_adj_e822(hw, adj, true);
3603         if (status)
3604                 return status;
3605
3606         /* Set target time for each PHY port */
3607         if (ice_is_e810(hw))
3608                 status = ice_ptp_prep_phy_adj_target_e810(hw, time_lo);
3609         else
3610                 status = ice_ptp_prep_phy_adj_target_e822(hw, time_lo);
3611         if (status)
3612                 return status;
3613
3614         return ice_ptp_tmr_cmd(hw, ADJ_TIME_AT_TIME, true);
3615 }
3616
3617 /**
3618  * ice_read_phy_tstamp - Read a PHY timestamp from the timestamo block
3619  * @hw: pointer to the HW struct
3620  * @block: the block to read from
3621  * @idx: the timestamp index to read
3622  * @tstamp: on return, the 40bit timestamp value
3623  *
3624  * Read a 40bit timestamp value out of the timestamp block. For E822 devices,
3625  * the block is the quad to read from. For E810 devices, the block is the
3626  * logical port to read from.
3627  */
3628 enum ice_status
3629 ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
3630 {
3631         if (ice_is_e810(hw))
3632                 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
3633         else
3634                 return ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
3635 }
3636
3637 /**
3638  * ice_clear_phy_tstamp - Clear a timestamp from the timestamp block
3639  * @hw: pointer to the HW struct
3640  * @block: the block to read from
3641  * @idx: the timestamp index to reset
3642  *
3643  * Clear a timestamp, resetting its valid bit, from the timestamp block. For
3644  * E822 devices, the block is the quad to clear from. For E810 devices, the
3645  * block is the logical port to clear from.
3646  */
3647 enum ice_status
3648 ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
3649 {
3650         if (ice_is_e810(hw))
3651                 return ice_clear_phy_tstamp_e810(hw, block, idx);
3652         else
3653                 return ice_clear_phy_tstamp_e822(hw, block, idx);
3654 }
3655
3656 /**
3657  * ice_ptp_init_phc - Initialize PTP hardware clock
3658  * @hw: pointer to the HW struct
3659  *
3660  * Perform the steps required to initialize the PTP hardware clock.
3661  */
3662 enum ice_status ice_ptp_init_phc(struct ice_hw *hw)
3663 {
3664         u8 src_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3665
3666         /* Enable source clocks */
3667         wr32(hw, GLTSYN_ENA(src_idx), GLTSYN_ENA_TSYN_ENA_M);
3668
3669         /* Clear event status indications for auxiliary pins */
3670         (void)rd32(hw, GLTSYN_STAT(src_idx));
3671
3672         if (ice_is_e810(hw))
3673                 return ice_ptp_init_phc_e810(hw);
3674         else
3675                 return ice_ptp_init_phc_e822(hw);
3676 }