From 2d17993b2c382784fa2cd81544d3eb47cfbf9442 Mon Sep 17 00:00:00 2001
From: Bruno Veiga <Bruno.VeigadeAlmeida@windriver.com>
Date: Thu, 13 Feb 2025 12:06:52 -0300
Subject: [PATCH] Add ptp-interface-parameters-add support in ptpinstance.pp

Adding support for new parameters that will be configured in
StarlingX PTP. Also we reestructured a part of the puppet manifest
to be easier to read, and so that there is no more duplicaded
code. We changed the nic_clock_reset parameters to come from
clock_conf.conf file instead of hieradata, because upon deletion
the parameters don't show on hieradata anymore.

Test plan:
PASS: SMA1 input writen correctly into file
PASS: SMA2 input writen correctly into file
PASS: SMA1 output writen correctly into file
PASS: SMA2 output writen correctly into file
PASS: U.FL1 output writen correctly into file
PASS: U.FL2 input writen correctly into file
PASS: synce_rclka enabled checked in dmesg
PASS: synce_rclkb enabled checked in dmesg

Story: 2011345
Task: 51704

Change-Id: Ie864f376b2244e8d49af0e4bc357e600d12229be
Signed-off-by: Bruno Veiga <Bruno.VeigadeAlmeida@windriver.com>
---
 .../lib/puppet/functions/read_clock_conf.rb   |  46 +++
 .../modules/platform/manifests/ptpinstance.pp | 319 ++++++++++++------
 2 files changed, 260 insertions(+), 105 deletions(-)
 create mode 100644 puppet-manifests/src/modules/platform/lib/puppet/functions/read_clock_conf.rb

diff --git a/puppet-manifests/src/modules/platform/lib/puppet/functions/read_clock_conf.rb b/puppet-manifests/src/modules/platform/lib/puppet/functions/read_clock_conf.rb
new file mode 100644
index 000000000..aefa889b7
--- /dev/null
+++ b/puppet-manifests/src/modules/platform/lib/puppet/functions/read_clock_conf.rb
@@ -0,0 +1,46 @@
+Puppet::Functions.create_function(:'read_clock_conf') do
+    dispatch :read_config do
+      param 'String', :path
+    end
+
+    def read_config(path)
+      config_hash = {}
+      current_name = nil
+      step = 0
+
+      config_file = File.read(path)
+      config_file.each_line do |line|
+        if md = line.match(/^ifname \[(\S*)\]/)
+          if !config_hash.has_key?(md[1])
+            current_name = md[1]
+            config_hash[current_name] = {
+              'base_port' => nil,
+              'ifname' => nil,
+              'parameters' => {},
+              'port_names' => [],
+              'uuid' => nil
+            }
+            step = 1
+          else
+            next
+          end
+        elsif md = line.match(/^base_port \[(\S*)\]/)
+          if step == 1
+            config_hash[current_name]['base_port'] = md[1]
+            step = 2
+          else
+            next
+          end
+        else md = line.match(/^(\S*) (\S*)$/)
+          if step == 2 or step == 3
+            config_hash[current_name]['parameters'][md[1]] = md[2]
+            step = 3
+          else
+            next
+          end
+        end
+      end
+
+      return config_hash
+    end
+  end
\ No newline at end of file
diff --git a/puppet-manifests/src/modules/platform/manifests/ptpinstance.pp b/puppet-manifests/src/modules/platform/manifests/ptpinstance.pp
index 6eae6d2fa..b0ecb26f6 100644
--- a/puppet-manifests/src/modules/platform/manifests/ptpinstance.pp
+++ b/puppet-manifests/src/modules/platform/manifests/ptpinstance.pp
@@ -20,7 +20,7 @@ define platform::ptpinstance::ptp_config_files(
     path    => "${ptp_conf_dir}/ptpinstance/${service}-${_name}.conf",
     mode    => '0644',
     content => template('platform/ptpinstance.conf.erb'),
-    require => File["${ptp_conf_dir}/ptpinstance"]
+    require => File["${ptp_conf_dir}/ptpinstance"],
   }
   -> file { "${_name}-sysconfig":
     ensure  => file,
@@ -28,7 +28,7 @@ define platform::ptpinstance::ptp_config_files(
     path    => "${ptp_options_dir}/ptpinstance/${service}-instance-${_name}",
     mode    => '0644',
     content => template("platform/${service}-instance.erb"),
-    require => File["${ptp_options_dir}/ptpinstance"]
+    require => File["${ptp_options_dir}/ptpinstance"],
   }
   -> service { "instance-${_name}":
     ensure     => $ensure,
@@ -91,58 +91,26 @@ define platform::ptpinstance::nic_clock_handler (
   $uuid,
   $base_port,
   $ptp_conf_dir,
-  $wpc_commands = {
-    'sma1' => {
-        'input' => "1 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA1",
-        'output' => "2 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA1"
-    },
-    'sma2' => {
-        'input' => "1 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA2",
-        'output' => "2 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA2"
-    },
-    'u.fl1' => {
-        'output' => "2 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL1"
-    },
-    'u.fl2' => {
-        'input' => "1 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL2"
-    },
-    'synce_rclka' => {
-        'enabled' => "1 \$channel > /sys/class/net/${name}/device/phy/synce"
-    },
-    'synce_rclkb' => {
-        'enabled' => "1 \$channel > /sys/class/net/${name}/device/phy/synce"
-    }
-  },
-  $wpc_channels = {
-    'sma1' => "cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA1 | awk '{print \$2}'",
-    'sma2' => "cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA2 | awk '{print \$2}'",
-    'u.fl1' => "cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL1 | awk '{print \$2}'",
-    'u.fl2' => "cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL2 | awk '{print \$2}'",
-    'synce_rclka' => 'echo 0',
-    'synce_rclkb' => 'echo 1'
-  }
 ) {
   exec { "${ifname}_heading":
-    command => "echo ifname [${name}] >> ${ptp_conf_dir}/ptpinstance/clock-conf.conf",
-    require => File['ensure_clock_conf_present']
+    command  => "echo ifname [${name}] >> ${ptp_conf_dir}/ptpinstance/clock-conf.conf",
+    require  => File['ensure_clock_conf_present'],
+    provider => shell,
   }
   -> exec { "${ifname}_${base_port}_heading":
     command  => "echo base_port [${base_port}] >> ${ptp_conf_dir}/ptpinstance/clock-conf.conf",
+    provider => shell,
   }
   $parameters.each |String $parm, String $value| {
-    if $wpc_commands[$parm] {
-      exec { "${ifname}_${parm}":
-        command  => "PTP=$(basename /sys/class/net/${base_port}/device/ptp/ptp*);\
-          channel=$(${wpc_channels[$parm]});\
-          echo ${wpc_commands[$parm][$value]}",
-        provider => shell,
-        require  => [ Exec["${ifname}_heading"], Exec["${ifname}_${base_port}_heading"] ]
-      }
-      -> exec { "${ifname}_${parm}_to_file":
-        command  => "echo ${parm} ${value} >> ${ptp_conf_dir}/ptpinstance/clock-conf.conf"
-      }
-    } else {
-      notice("Skipped invalid clock parameter ${parm}.")
+    platform::ptpinstance::config_param { "${name}_${parm}_${value}":
+      iface   => $name,
+      param   => $parm,
+      value   => $value,
+      require => [Exec["${ifname}_heading"], Exec["${ifname}_${base_port}_heading"]],
+    }
+    -> exec { "${ifname}_${parm}_to_file":
+      command  => "echo ${parm} ${value} >> ${ptp_conf_dir}/ptpinstance/clock-conf.conf",
+      provider => shell,
     }
   }
 }
@@ -154,46 +122,11 @@ define platform::ptpinstance::nic_clock_reset (
   $uuid,
   $base_port,
 ) {
-  if $parameters['u.fl1'] {
-    exec { "${ifname}_clear_UFL1":
-      command  => "PTP=$(basename /sys/class/net/${base_port}/device/ptp/ptp*);\
-        channel=$(cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL1 | awk '{print \$2}');\
-        echo 0 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL1",
-      provider => shell,
-    }
-  }
-  if $parameters['u.fl2'] {
-    exec { "${ifname}_clear_UFL2":
-      command  => "PTP=$(basename /sys/class/net/${base_port}/device/ptp/ptp*);\
-        channel=$(cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL2 | awk '{print \$2}');\
-        echo 0 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/U.FL2",
-      provider => shell,
-    }
-  }
-  if $parameters['sma1'] {
-    exec { "${ifname}_clear_SMA1":
-      command  => "PTP=$(basename /sys/class/net/${base_port}/device/ptp/ptp*);\
-        channel=$(cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA1 | awk '{print \$2}');\
-        echo 0 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA1",
-      provider => shell,
-    }
-  }
-  if $parameters['sma2'] {
-    exec { "${ifname}_clear_SMA2":
-      command  => "PTP=$(basename /sys/class/net/${base_port}/device/ptp/ptp*);\
-        channel=$(cat /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA2 | awk '{print \$2}');\
-        echo 0 \$channel > /sys/class/net/${base_port}/device/ptp/\$PTP/pins/SMA2",
-      provider => shell,
-    }
-  }
-  if $parameters['synce_rclka'] {
-    exec { "${ifname}_clear_rclka":
-      command => "echo 0 0 > /sys/class/net/${name}/device/phy/synce",
-    }
-  }
-  if $parameters['synce_rclkb'] {
-    exec { "${ifname}_clear_rclkb":
-      command => "echo 0 1 > /sys/class/net/${name}/device/phy/synce",
+  $parameters.each |String $parm, String $value| {
+    platform::ptpinstance::config_param { "${name}_${parm}_default":
+      iface => $name,
+      param => $parm,
+      value => 'default',
     }
   }
 }
@@ -219,24 +152,31 @@ class platform::ptpinstance::nic_clock (
 
   require ::platform::ptpinstance::nic_clock::nic_reset
 
-  file {"${ptp_conf_dir}/ptpinstance":
-    ensure =>  directory,
-    mode   =>  '0755',
+  file { "${ptp_conf_dir}/ptpinstance":
+    ensure => directory,
+    mode   => '0755',
   }
   -> tidy { 'purge_conf':
     path    => "${ptp_conf_dir}/ptpinstance",
-    matches => [ '[^clock]*.conf' ],
+    matches => ['[^clock]*.conf'],
     recurse => true,
-    rmdirs  => false
+    rmdirs  => false,
   }
   -> file { 'ensure_clock_conf_present':
     ensure  => present,
     path    => "${ptp_conf_dir}/ptpinstance/clock-conf.conf",
     mode    => '0644',
-    require => File["${ptp_conf_dir}/ptpinstance"]
+    require => File["${ptp_conf_dir}/ptpinstance"],
   }
   if $nic_clock_enabled {
-    create_resources('platform::ptpinstance::nic_clock_handler', $nic_clock_config, {'ptp_conf_dir' => $ptp_conf_dir})
+    create_resources('platform::ptpinstance::nic_clock_handler', $nic_clock_config, { 'ptp_conf_dir' => $ptp_conf_dir })
+    $iface_keys = keys($nic_clock_config)
+    $iface_keys.each|Integer $index, String $iface_cfg| {
+      if $index > 0 {
+        # Defining an order for the instances that will be created with create_resources
+        Platform::Ptpinstance::Nic_clock_handler[$iface_keys[$index - 1]] -> Platform::Ptpinstance::Nic_clock_handler[$iface_cfg]
+      }
+    }
   }
 }
 
@@ -244,15 +184,22 @@ class platform::ptpinstance::nic_clock::nic_reset (
   $nic_clock_config = $platform::ptpinstance::nic_clock::nic_clock_config,
   $nic_clock_enabled = $platform::ptpinstance::nic_clock::nic_clock_enabled
 ) {
-  include ::platform::ptpinstance::params
   $ptp_conf_dir = $::platform::ptpinstance::params::ptp_conf_dir
+  $clock_conf_values = read_clock_conf("${ptp_conf_dir}/ptpinstance/clock-conf.conf")
 
   if $nic_clock_enabled {
-    create_resources('platform::ptpinstance::nic_clock_reset', $nic_clock_config)
+    create_resources('platform::ptpinstance::nic_clock_reset', $clock_conf_values)
+    $iface_keys = keys($clock_conf_values)
+    $iface_keys.each|Integer $index, String $iface_cfg| {
+      if $index > 0 {
+        # Defining an order for the instances that will be created with create_resources
+        Platform::Ptpinstance::Nic_clock_reset[$iface_keys[$index - 1]] -> Platform::Ptpinstance::Nic_clock_reset[$iface_cfg]
+      }
+    }
   }
   exec { 'clear_clock_conf_file':
     command => "echo \"\" > ${ptp_conf_dir}/ptpinstance/clock-conf.conf",
-    onlyif  => "stat ${ptp_conf_dir}/ptpinstance/clock-conf.conf"
+    onlyif  => "stat ${ptp_conf_dir}/ptpinstance/clock-conf.conf",
   }
 }
 
@@ -268,7 +215,6 @@ define platform::ptpinstance::disable_e810_gnss_uart_interfaces (
   $pmc_gm_settings = '',
   $external_source = '',
 ) {
-
   $gnss_device = $global_parameters['ts2phc.nmea_serialport']
 
   if empty($gnss_device) {
@@ -281,12 +227,12 @@ define platform::ptpinstance::disable_e810_gnss_uart_interfaces (
 
     notice("Trying to disable UART devices for serial port ${gnss_device}")
 
-    exec {"${_name}_disable_gnss_uart1":
+    exec { "${_name}_disable_gnss_uart1":
       command => "echo -ne \"${uart1_cmd}\" > ${gnss_device}",
       timeout => 3,
       onlyif  => "/usr/bin/test -c ${gnss_device}",
     }
-    exec {"${_name}_disable_gnss_uart2":
+    exec { "${_name}_disable_gnss_uart2":
       command => "echo -ne \"${uart2_cmd}\" > ${gnss_device}",
       timeout => 3,
       onlyif  => "/usr/bin/test -c ${gnss_device}",
@@ -326,13 +272,13 @@ class platform::ptpinstance (
     }
   }
 
-  file{"${ptp_options_dir}/ptpinstance":
-    ensure =>  directory,
-    mode   =>  '0755',
+  file { "${ptp_options_dir}/ptpinstance":
+    ensure => directory,
+    mode   => '0755',
   }
   -> tidy { 'purge_sysconf':
     path    => "${ptp_options_dir}/ptpinstance/",
-    matches => [ '*-instance-*' ],
+    matches => ['*-instance-*'],
     recurse => true,
     rmdirs  => false
   }
@@ -428,7 +374,170 @@ class platform::ptpinstance (
 class platform::ptpinstance::runtime {
   class { 'platform::ptpinstance::nic_clock': }
   -> class { 'platform::ptpinstance': runtime => true }
-  -> exec {'Ensure collectd is restarted':
+  -> exec { 'Ensure collectd is restarted':
     command => '/usr/local/sbin/pmon-restart collectd'
   }
 }
+
+define platform::ptpinstance::net_tspll_cfg (
+  $iface,
+  $tspll_freq,
+  $clk_src,
+  $src_tmr_mode,
+) {
+  exec { "${iface}_tspll_cfg_${tspll_freq}_${clk_src}_${src_tmr_mode}":
+    command  => "echo ${tspll_freq} ${clk_src} ${src_tmr_mode} > /sys/class/net/${iface}/device/tspll_cfg",
+    provider => shell,
+  }
+}
+
+define platform::ptpinstance::phy_synce (
+  $iface,
+  $enable,
+  $pin,
+) {
+  exec { "${iface}_synce_${enable}_${pin}":
+    command  => "echo ${enable} ${pin} > /sys/class/net/${iface}/device/phy/synce",
+    provider => shell,
+  }
+}
+
+define platform::ptpinstance::phy_tx_clk (
+  $iface,
+  $ref_clk,
+) {
+  exec { "${iface}_tx_clk_${ref_clk}":
+    command  => "echo ${ref_clk} > /sys/class/net/${iface}/device/phy/tx_clk",
+    provider => shell,
+  }
+}
+
+define platform::ptpinstance::ptp_extts_enable (
+  $iface,
+  $enable,
+) {
+  exec { "${iface}_extts_enable_${enable}":
+    command  => "PTPNAME=$(basename /sys/class/net/${iface}/device/ptp/ptp*);\
+      CHANNEL=$(cat /sys/class/net/${iface}/device/ptp/\$PTP/pins/${pin} | awk '{print \$2}');\
+      echo \$CHANNEL ${enable} > /sys/class/net/${iface}/device/ptp/\$PTP/extts_enable",
+    provider => shell,
+  }
+}
+
+define platform::ptpinstance::ptp_period (
+  $iface,
+  $start_time_s = 0,
+  $start_time_ns = 0,
+  $period_s = 0,
+  $period_ns = 0,
+) {
+  exec { "${iface}_period_${start_time_s}_${start_time_ns}_${period_s}_${period_ns}}":
+    command  => "PTP=$(basename /sys/class/net/${iface}/device/ptp/ptp*);\
+      CHANNEL=$(cat /sys/class/net/${iface}/device/ptp/\$PTP/pins/${pin} | awk '{print \$2}');\
+      echo \$CHANNEL ${start_time_s} ${start_time_ns} ${period_s} ${period_ns} > /sys/class/net/${iface}/device/ptp/\$PTP/period",
+    provider => shell,
+  }
+}
+
+define platform::ptpinstance::ptp_pin (
+  $iface,
+  $pin,
+  $function,
+) {
+  exec { "${iface}_${pin}_${function}":
+    command  => "PTP=$(basename /sys/class/net/${iface}/device/ptp/ptp*);\
+      CHANNEL=$(cat /sys/class/net/${iface}/device/ptp/\$PTP/pins/${pin} | awk '{print \$2}');\
+      echo ${function} \$CHANNEL > /sys/class/net/${iface}/device/ptp/\$PTP/pins/${pin}",
+    provider => shell,
+  }
+}
+
+define platform::ptpinstance::config_param (
+  $iface,
+  $param,
+  $value,
+) {
+  $cmds = {
+    'tspll_cfg' => {
+      'resource' => 'platform::ptpinstance::net_tspll_cfg',
+      'default'        => { 'iface' => $iface, 'tspll_freq' => 4, 'clk_src' => 0, 'src_tmr_mode' => 0 },
+      'timeref_25'     => { 'iface' => $iface, 'tspll_freq' => 0, 'clk_src' => 1, 'src_tmr_mode' => 0 },
+      'timeref_156.25' => { 'iface' => $iface, 'tspll_freq' => 4, 'clk_src' => 1, 'src_tmr_mode' => 0 },
+    },
+    'synce_rclka' => {
+      'resource' => 'platform::ptpinstance::phy_synce',
+      'default' => { 'iface' => $iface, 'enable' => 0, 'pin' => 0 },
+      'enabled' => { 'iface' => $iface, 'enable' => 1, 'pin' => 0 },
+    },
+    'synce_rclkb' => {
+      'resource' => 'platform::ptpinstance::phy_synce',
+      'default' => { 'iface' => $iface, 'enable' => 0, 'pin' => 1 },
+      'enabled' => { 'iface' => $iface, 'enable' => 1, 'pin' => 1 },
+    },
+    'tx_clk' => {
+      'resource' => 'platform::ptpinstance::phy_tx_clk',
+      'default' => { 'iface' => $iface, 'ref_clk' => 0 },
+      'enabled' => { 'iface' => $iface, 'ref_clk' => 1 },
+    },
+    'extts_enable' => {
+      'resource' => 'platform::ptpinstance::ptp_extts_enable',
+      'default' => { 'iface' => $iface, 'enable' => 0 },
+      'enabled' => { 'iface' => $iface, 'enable' => 1 },
+    },
+    'period' => {
+      'resource' => 'platform::ptpinstance::ptp_period',
+      'default'  => { 'iface' => $iface, 'start_time_s' => 0, 'start_time_ns' => 0, 'period_s' => 0, 'period_ns' => 0 },
+      'out_1pps' => { 'iface' => $iface, 'start_time_s' => 0, 'start_time_ns' => 0, 'period_s' => 1, 'period_ns' => 0 },
+    },
+    'sdp0' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'SDP0', 'function' => 0 },
+      'output'  => { 'iface' => $iface, 'pin' => 'SDP0', 'function' => 2 },
+    },
+    'sdp1' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'SDP1', 'function' => 0 },
+      'input'   => { 'iface' => $iface, 'pin' => 'SDP1', 'function' => 1 },
+    },
+    'sdp2' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'SDP2', 'function' => 0 },
+      'output'  => { 'iface' => $iface, 'pin' => 'SDP2', 'function' => 2 },
+    },
+    'sdp3' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'SDP3', 'function' => 0 },
+      'input'   => { 'iface' => $iface, 'pin' => 'SDP3', 'function' => 1 },
+    },
+    'sma1' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'SMA1', 'function' => 0 },
+      'input'   => { 'iface' => $iface, 'pin' => 'SMA1', 'function' => 1 },
+      'output'  => { 'iface' => $iface, 'pin' => 'SMA1', 'function' => 2 },
+    },
+    'sma2' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'SMA2', 'function' => 0 },
+      'input'   => { 'iface' => $iface, 'pin' => 'SMA2', 'function' => 1 },
+      'output'  => { 'iface' => $iface, 'pin' => 'SMA2', 'function' => 2 },
+    },
+    'u.fl1' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'U.FL1', 'function' => 0 },
+      'output'  => { 'iface' => $iface, 'pin' => 'U.FL1', 'function' => 2 },
+    },
+    'u.fl2' => {
+      'resource' => 'platform::ptpinstance::ptp_pin',
+      'default' => { 'iface' => $iface, 'pin' => 'U.FL2', 'function' => 0 },
+      'input'   => { 'iface' => $iface, 'pin' => 'U.FL2', 'function' => 1 },
+    },
+  }
+
+  if !$cmds[$param] {
+    notice("Skipped invalid clock parameter: ${param}.")
+  } elsif !$cmds[$param][$value] {
+    notice("Skipped invalid clock parameter value: ${param}: ${value}.")
+  } else {
+    create_resources($cmds[$param]['resource'], { "${iface}_${param}_${value}" => $cmds[$param][$value] })
+  }
+}