// Module included in the following assemblies:
//
// * networking/advanced_networking/ptp/configuring-ptp.adoc

:_mod-docs-content-type: PROCEDURE
[id="ptp-configuring-linuxptp-services-dual-port-bc_{context}"]
= Configuring PTP boundary clock high availability with dual time receiver ports

[role="_abstract"]
You can configure a Precision Time Protocol (PTP) Telecom Boundary Clock (T-BC) with dual time receiver ports for high availability by creating a `PtpConfig` custom resource (CR). The Alternate Best Master Clock Algorithm (A-BMCA) provides automatic failover between upstream timing paths.

The configuration uses two profiles: one for the time receiver (TR) ports that synchronize from an upstream source, and one for the time transmitter (TT) port that distributes time downstream on a separate PTP domain.

.Prerequisites

* You have installed the OpenShift CLI (`oc`).
* You are logged in as a user with `cluster-admin` privileges.
* You have installed the PTP Operator.
* Your node has a supported multi-port NIC where the ports share a single Physical Hardware Clock (PHC), such as the Intel Westport Channel E810-XXVDA4T.
* You have identified the interface names for the two ports on the same NIC that will serve as time receiver ports, as well as the interface that will serve as the leading interface for the NIC PHC.

.Procedure

. Save the following `PtpConfig` CR definition in the `dual-port-tbc-ptp-config.yaml` file:
+
[source,yaml]
----
apiVersion: ptp.openshift.io/v1
kind: PtpConfig
metadata:
  name: t-bc
  namespace: openshift-ptp
  annotations:
    ran.openshift.io/ztp-deploy-wave: "10"
spec:
  profile:
  - name: tbc-tr
    phc2sysOpts: "-r -n 24 -N 8 -R 16 -u 0 -m -s <first_tr_interface>"
    plugins:
      e810:
        enableDefaultConfig: false
        interconnections:
          - gnssInput: false
            id: <leading_interface>
            part: E810-XXVDA4T
            phaseOutputConnectors:
            - SMA1
            upstreamPort: "<first_tr_interface>,<second_tr_interface>"
        settings:
          LocalHoldoverTimeout: 14400
          LocalMaxHoldoverOffSet: 1500
          MaxInSpecOffset: 100
        pins:
          <leading_interface>:
            SMA1: 2 1
            SMA2: 2 2
            U.FL1: 0 1
            U.FL2: 0 2
    ptp4lConf: |
      [<first_tr_interface>]
      masterOnly 0
      [<second_tr_interface>]
      masterOnly 0
      [global]
      #
      # Default Data Set
      #
      twoStepFlag 1
      slaveOnly 1
      priority1 128
      priority2 128
      domainNumber 24
      clockClass 248
      clockAccuracy 0xFE
      offsetScaledLogVariance 0xFFFF
      free_running 0
      freq_est_interval 1
      dscp_event 0
      dscp_general 0
      dataset_comparison G.8275.x
      G.8275.defaultDS.localPriority 128
      #
      # Port Data Set
      #
      logAnnounceInterval -3
      logSyncInterval -4
      logMinDelayReqInterval -4
      logMinPdelayReqInterval -4
      announceReceiptTimeout 3
      syncReceiptTimeout 0
      delayAsymmetry 0
      fault_reset_interval -4
      neighborPropDelayThresh 20000000
      masterOnly 0
      G.8275.portDS.localPriority 128
      #
      # Run time options
      #
      assume_two_step 0
      logging_level 6
      path_trace_enabled 0
      follow_up_info 0
      hybrid_e2e 0
      inhibit_multicast_service 0
      net_sync_monitor 0
      tc_spanning_tree 0
      tx_timestamp_timeout 50
      unicast_listen 0
      unicast_master_table 0
      unicast_req_duration 3600
      use_syslog 1
      verbose 0
      summary_interval 0
      kernel_leap 1
      check_fup_sync 0
      clock_class_threshold 135
      #
      # Servo Options
      #
      pi_proportional_const 0.60
      pi_integral_const 0.0003
      pi_proportional_scale 0.0
      pi_proportional_exponent -0.3
      pi_proportional_norm_max 0.7
      pi_integral_scale 0.0
      pi_integral_exponent 0.4
      pi_integral_norm_max 0.3
      step_threshold 2.0
      first_step_threshold 0.00002
      max_frequency 900000000
      clock_servo pi
      sanity_freq_limit 200000000
      ntpshm_segment 0
      #
      # Transport options
      #
      transportSpecific 0x0
      ptp_dst_mac 01:1B:19:00:00:00
      p2p_dst_mac 01:80:C2:00:00:0E
      udp_ttl 1
      udp6_scope 0x0E
      uds_address /var/run/ptp4l
      #
      # Default interface options
      #
      clock_type OC
      network_transport L2
      delay_mechanism E2E
      time_stamping hardware
      tsproc_mode filter
      delay_filter moving_median
      delay_filter_length 10
      egressLatency 0
      ingressLatency 0
      boundary_clock_jbod 0
    ptp4lOpts: "-2 --summary_interval -4"
    ptpSchedulingPolicy: SCHED_FIFO
    ptpSchedulingPriority: 10
    ptpSettings:
      clockType: "T-BC"
      inSyncConditionThreshold: "10"
      inSyncConditionTimes: "12"
      logReduce: "false"
      leadingInterface: <leading_interface>
      upstreamPort: "<first_tr_interface>,<second_tr_interface>"
    ts2phcConf: |
      [global]
      use_syslog  0
      verbose 1
      logging_level 7
      ts2phc.pulsewidth 100000000
      leapfile  /usr/share/zoneinfo/leap-seconds.list
      domainNumber 24
      uds_address /var/run/ptp4l.0.socket
      [<leading_interface>]
      ts2phc.extts_polarity rising
      ts2phc.pin_index 1
      ts2phc.extts_correction -10
      ts2phc.master 0
    ts2phcOpts: "-s generic -a --ts2phc.rh_external_pps 1"
  - name: tbc-tt
    ptp4lConf: |
      [<tt_interface>]
      masterOnly 1
      [global]
      #
      # Default Data Set
      #
      twoStepFlag 1
      slaveOnly 0
      priority1 128
      priority2 128
      domainNumber 25
      # ... remaining Port Data Set, Run time, Servo, and Transport options
      # are the same as the tbc-tr profile ...
      dataset_comparison G.8275.x
      G.8275.defaultDS.localPriority 128
      #
      # Default interface options
      #
      clock_type OC
      network_transport L2
      delay_mechanism E2E
      time_stamping hardware
      tsproc_mode filter
      delay_filter moving_median
      delay_filter_length 10
      egressLatency 0
      ingressLatency 0
      boundary_clock_jbod 0
    ptp4lOpts: "-2 --summary_interval -4"
    ptpSchedulingPolicy: SCHED_FIFO
    ptpSchedulingPriority: 10
    ptpSettings:
      controllingProfile: tbc-tr
      logReduce: "false"
  recommend:
  - match:
    - nodeLabel: "node-role.kubernetes.io/<mcp>"
    priority: 4
    profile: tbc-tr
  - match:
    - nodeLabel: "node-role.kubernetes.io/<mcp>"
    priority: 4
    profile: tbc-tt
----
+
where:
+
--
`<first_tr_interface>`:: Specifies the first time receiver port interface name on the NIC. For example, `ens2f1`.

`<second_tr_interface>`:: Specifies the second time receiver port interface name on the same NIC. For example, `ens2f3`.

`<leading_interface>`:: Specifies the first port on the NIC, used as the leading interface for the PHC and phase output. For example, `ens2f0`.

`<tt_interface>`:: Specifies the time transmitter port interface that distributes synchronized time downstream. For example, `ens2f2`.

`phc2sysOpts: "-r -n 24 -N 8 -R 16 -u 0 -m -s <first_tr_interface>"`:: Specifies the `phc2sys` options for system clock synchronization. The `-s` flag sets the first time receiver port as the clock source, which also covers the backup port automatically during failover.

`plugins.e810`:: Specifies the Intel E810 hardware plugin configuration, including pin assignments, holdover settings, and the upstream port list for dual time receiver operation.

`ptpSettings.upstreamPort`:: Specifies both time receiver interfaces as a comma-separated list. This tells the PTP Operator which ports participate in the dual time receiver failover.

`ptpSettings.leadingInterface`:: Specifies the leading interface on the NIC for PHC timing coordination.

`domainNumber 25` (TT profile):: Specifies a different PTP domain for the time transmitter profile. The TT profile distributes time on a separate domain from the upstream TR domain.

`controllingProfile: tbc-tr`:: Specifies that the time transmitter profile is controlled by the time receiver profile.

`<mcp>`:: Specifies the machine config pool label that selects the target nodes for this configuration.
--

. Create the `PtpConfig` CR by running the following command:
+
[source,terminal]
----
$ oc create -f dual-port-tbc-ptp-config.yaml
----

. Verify that the PTP Operator has applied the `PtpConfig` profiles by running the following command:
+
[source,terminal]
----
$ oc get ptpconfig -n openshift-ptp
----
+
.Example output
[source,terminal]
----
NAME   AGE
t-bc   10s
----
