From: Tomaszx Wakula <tomaszx.wak...@intel.com>

Add API and definitions related to reading Software Definable Pin section from
NVM, related to PTP pins assignment.

Signed-off-by: Tomaszx Wakula <tomaszx.wak...@intel.com>
Signed-off-by: Ian Stokes <ian.sto...@intel.com>
---
 drivers/net/ice/base/ice_adminq_cmd.h | 23 +++++++
 drivers/net/ice/base/ice_ptp_hw.c     | 87 +++++++++++++++++++++++++++
 drivers/net/ice/base/ice_ptp_hw.h     |  3 +
 3 files changed, 113 insertions(+)

diff --git a/drivers/net/ice/base/ice_adminq_cmd.h 
b/drivers/net/ice/base/ice_adminq_cmd.h
index 4a20a7ac35..d828731a5b 100644
--- a/drivers/net/ice/base/ice_adminq_cmd.h
+++ b/drivers/net/ice/base/ice_adminq_cmd.h
@@ -1976,6 +1976,29 @@ struct ice_aqc_nvm {
 #define ICE_AQC_NVM_LLDP_STATUS_M_LEN          4 /* In Bits */
 #define ICE_AQC_NVM_LLDP_STATUS_RD_LEN         4 /* In Bytes */
 
+#define ICE_AQC_NVM_SDP_CFG_PTR_OFFSET         0xD8
+#define ICE_AQC_NVM_SDP_CFG_PTR_RD_LEN         2 /* In Bytes */
+#define ICE_AQC_NVM_SDP_CFG_PTR_M              MAKEMASK(0x7FFF, 0)
+#define ICE_AQC_NVM_SDP_CFG_PTR_TYPE_M         BIT(15)
+#define ICE_AQC_NVM_SDP_CFG_HEADER_LEN         2 /* In Bytes */
+#define ICE_AQC_NVM_SDP_CFG_SEC_LEN_LEN                2 /* In Bytes */
+#define ICE_AQC_NVM_SDP_CFG_DATA_LEN           14 /* In Bytes */
+#define ICE_AQC_NVM_SDP_CFG_MAX_SECTION_SIZE   7
+#define ICE_AQC_NVM_SDP_CFG_PIN_SIZE           10
+#define ICE_AQC_NVM_SDP_CFG_PIN_OFFSET         6
+#define ICE_AQC_NVM_SDP_CFG_PIN_MASK           MAKEMASK(0x3FF, \
+                                               ICE_AQC_NVM_SDP_CFG_PIN_OFFSET)
+#define ICE_AQC_NVM_SDP_CFG_CHAN_OFFSET                4
+#define ICE_AQC_NVM_SDP_CFG_CHAN_MASK          MAKEMASK(0x3, \
+                                               ICE_AQC_NVM_SDP_CFG_CHAN_OFFSET)
+#define ICE_AQC_NVM_SDP_CFG_DIR_OFFSET         3
+#define ICE_AQC_NVM_SDP_CFG_DIR_MASK           MAKEMASK(0x1, \
+                                               ICE_AQC_NVM_SDP_CFG_DIR_OFFSET)
+#define ICE_AQC_NVM_SDP_CFG_SDP_NUM_OFFSET             0
+#define ICE_AQC_NVM_SDP_CFG_SDP_NUM_MASK       MAKEMASK(0x7, \
+                                            ICE_AQC_NVM_SDP_CFG_SDP_NUM_OFFSET)
+#define ICE_AQC_NVM_SDP_CFG_NA_PIN_MASK                MAKEMASK(0x1, 15)
+
 #define ICE_AQC_NVM_TX_TOPO_MOD_ID             0x14B
 #define ICE_AQC_NVM_CMPO_MOD_ID                        0x153
 
diff --git a/drivers/net/ice/base/ice_ptp_hw.c 
b/drivers/net/ice/base/ice_ptp_hw.c
index 5609145b8d..8ea4e77266 100644
--- a/drivers/net/ice/base/ice_ptp_hw.c
+++ b/drivers/net/ice/base/ice_ptp_hw.c
@@ -5073,6 +5073,93 @@ bool ice_is_pca9575_present(struct ice_hw *hw)
        return false;
 }
 
+/**
+ * ice_ptp_read_sdp_section_from_nvm - reads SDP section from NVM
+ * @hw: pointer to the HW struct
+ * @section_exist: on return, returns true if section exist
+ * @pin_desc_num: on return, returns the number of ice_ptp_pin_desc entries
+ * @pin_config_num: on return, returns the number of pin that should be
+ *                 exposed on pin_config I/F
+ * @sdp_entries: on return, returns the SDP connection section from NVM
+ * @nvm_entries: on return, returns the number of valid entries in sdp_entries
+ *
+ * Reads SDP connection section from NVM
+ * Returns -1 if NVM read failed or section corrupted, otherwise 0
+ */
+int ice_ptp_read_sdp_section_from_nvm(struct ice_hw *hw, bool *section_exist,
+                                     u8 *pin_desc_num, u8 *pin_config_num,
+                                     u16 *sdp_entries, u8 *nvm_entries)
+{
+       __le16 loc_raw_data, raw_nvm_entries;
+       u32 loc_data, i, all_pin_bitmap = 0;
+       int err;
+
+       *section_exist = false;
+       *pin_desc_num = 0;
+       *pin_config_num = 0;
+
+       err = ice_acquire_nvm(hw, ICE_RES_READ);
+       if (err)
+               goto exit;
+
+       /* Read the offset of EMP_SR_PTR */
+       err = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
+                             ICE_AQC_NVM_SDP_CFG_PTR_OFFSET,
+                             ICE_AQC_NVM_SDP_CFG_PTR_RD_LEN,
+                             &loc_raw_data, false, true, NULL);
+       if (err)
+               goto exit;
+
+       /* check if section exist */
+       loc_data = LE16_TO_CPU(loc_raw_data);
+       if ((loc_data & ICE_AQC_NVM_SDP_CFG_PTR_M) == ICE_AQC_NVM_SDP_CFG_PTR_M)
+               goto exit;
+
+       if (loc_data & ICE_AQC_NVM_SDP_CFG_PTR_TYPE_M) {
+               loc_data &= ICE_AQC_NVM_SDP_CFG_PTR_M;
+               loc_data *= ICE_AQC_NVM_SECTOR_UNIT;
+       } else {
+               loc_data *= ICE_AQC_NVM_WORD_UNIT;
+       }
+
+       /* Skip SDP configuration section length (2 bytes) */
+       loc_data += ICE_AQC_NVM_SDP_CFG_HEADER_LEN;
+
+       /* read number of valid entries */
+       err = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT, loc_data,
+                             ICE_AQC_NVM_SDP_CFG_SEC_LEN_LEN, &raw_nvm_entries,
+                             false, true, NULL);
+       if (err)
+               goto exit;
+       *nvm_entries = (u8)LE16_TO_CPU(raw_nvm_entries);
+
+       /* Read entire SDP configuration section */
+       loc_data += ICE_AQC_NVM_SDP_CFG_SEC_LEN_LEN;
+       err = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT, loc_data,
+                             ICE_AQC_NVM_SDP_CFG_DATA_LEN, sdp_entries,
+                             false, true, NULL);
+       if (err)
+               goto exit;
+
+       /* get number of existing pin/connector */
+       for (i = 0; i < *nvm_entries; i++) {
+               all_pin_bitmap |= (sdp_entries[i] &
+                                  ICE_AQC_NVM_SDP_CFG_PIN_MASK) >>
+                                  ICE_AQC_NVM_SDP_CFG_PIN_OFFSET;
+               if (sdp_entries[i] & ICE_AQC_NVM_SDP_CFG_NA_PIN_MASK)
+                       *pin_desc_num += 1;
+       }
+
+       for (i = 0; i < ICE_AQC_NVM_SDP_CFG_PIN_SIZE - 1; i++)
+               *pin_config_num += (all_pin_bitmap & (1 << i)) != 0;
+       *pin_desc_num += *pin_config_num;
+
+       *section_exist = true;
+exit:
+       ice_release_nvm(hw);
+       return err;
+}
+
 /**
  * ice_ptp_write_direct_incval_e830 - Prep PHY port increment value change
  * @hw: pointer to HW struct
diff --git a/drivers/net/ice/base/ice_ptp_hw.h 
b/drivers/net/ice/base/ice_ptp_hw.h
index 7c0c5ae562..4c63bba722 100644
--- a/drivers/net/ice/base/ice_ptp_hw.h
+++ b/drivers/net/ice/base/ice_ptp_hw.h
@@ -261,6 +261,9 @@ ice_write_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, 
u8 data);
 int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
 int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
 bool ice_is_pca9575_present(struct ice_hw *hw);
+int ice_ptp_read_sdp_section_from_nvm(struct ice_hw *hw, bool *section_exist,
+                                     u8 *pin_desc_num, u8 *pin_config_num,
+                                     u16 *sdp_entries, u8 *nvm_entries);
 
 void
 ice_ptp_process_cgu_err(struct ice_hw *hw, struct ice_rq_event_info *event);
-- 
2.43.0

Reply via email to