summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/ice/ice_ptp.c
diff options
context:
space:
mode:
authorYochai Hagvi <yochai.hagvi@intel.com>2024-08-30 13:07:22 +0200
committerTony Nguyen <anthony.l.nguyen@intel.com>2024-10-01 11:11:38 -0700
commitebb2693f8fbdb444e01ac6b6b50282aaabc96e77 (patch)
tree877db7e5cb8aae82fe45ea25aeb2e5368b3605b9 /drivers/net/ethernet/intel/ice/ice_ptp.c
parentdf0b394f1ca79e2f589c5f7ae7cb8095c67bf00c (diff)
downloadlwn-ebb2693f8fbdb444e01ac6b6b50282aaabc96e77.tar.gz
lwn-ebb2693f8fbdb444e01ac6b6b50282aaabc96e77.zip
ice: Read SDP section from NVM for pin definitions
PTP pins assignment and their related SDPs (Software Definable Pins) are currently hardcoded. Fix that by reading NVM section instead on products supporting this, which are E810 products. If SDP section is not defined in NVM, the driver continues to use the hardcoded table. Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Signed-off-by: Yochai Hagvi <yochai.hagvi@intel.com> Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com> Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_ptp.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ptp.c138
1 files changed, 112 insertions, 26 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index f733e673bf26..753709ef1ab2 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -39,7 +39,7 @@ static const struct ice_ptp_pin_desc ice_pin_desc_e810[] = {
{ ONE_PPS, { -1, 5 }},
};
-static const char ice_pin_names_e810t[][64] = {
+static const char ice_pin_names_nvm[][64] = {
"GNSS",
"SMA1",
"U.FL1",
@@ -47,7 +47,7 @@ static const char ice_pin_names_e810t[][64] = {
"U.FL2",
};
-static const struct ice_ptp_pin_desc ice_pin_desc_e810t[] = {
+static const struct ice_ptp_pin_desc ice_pin_desc_e810_sma[] = {
/* name, gpio */
{ GNSS, { 1, -1 }},
{ SMA1, { 1, 0 }},
@@ -2385,8 +2385,8 @@ static void ice_ptp_setup_pin_cfg(struct ice_pf *pf)
if (!ice_is_feature_supported(pf, ICE_F_SMA_CTRL))
name = ice_pin_names[desc->name_idx];
- else
- name = ice_pin_names_e810t[desc->name_idx];
+ else if (desc->name_idx != GPIO_NA)
+ name = ice_pin_names_nvm[desc->name_idx];
if (name)
strscpy(pin->name, name, sizeof(pin->name));
@@ -2397,17 +2397,17 @@ static void ice_ptp_setup_pin_cfg(struct ice_pf *pf)
}
/**
- * ice_ptp_disable_sma_pins - Disable SMA pins
+ * ice_ptp_disable_pins - Disable PTP pins
* @pf: pointer to the PF structure
*
* Disable the OS access to the SMA pins. Called to clear out the OS
* indications of pin support when we fail to setup the SMA control register.
*/
-static void ice_ptp_disable_sma_pins(struct ice_pf *pf)
+static void ice_ptp_disable_pins(struct ice_pf *pf)
{
struct ptp_clock_info *info = &pf->ptp.info;
- dev_warn(ice_pf_to_dev(pf), "Failed to configure SMA pin control\n");
+ dev_warn(ice_pf_to_dev(pf), "Failed to configure PTP pin control\n");
info->enable = NULL;
info->verify = NULL;
@@ -2417,23 +2417,75 @@ static void ice_ptp_disable_sma_pins(struct ice_pf *pf)
}
/**
- * ice_ptp_setup_pins_e810t - Setup PTP pins in sysfs
- * @pf: pointer to the PF instance
+ * ice_ptp_parse_sdp_entries - update ice_ptp_pin_desc structure from NVM
+ * @pf: pointer to the PF structure
+ * @entries: SDP connection section from NVM
+ * @num_entries: number of valid entries in sdp_entries
+ * @pins: PTP pins array to update
+ *
+ * Return: 0 on success, negative error code otherwise.
*/
-static void ice_ptp_setup_pins_e810t(struct ice_pf *pf)
+static int ice_ptp_parse_sdp_entries(struct ice_pf *pf, __le16 *entries,
+ unsigned int num_entries,
+ struct ice_ptp_pin_desc *pins)
{
- struct ice_ptp *ptp = &pf->ptp;
- int err;
+ unsigned int n_pins = 0;
+ unsigned int i;
- ptp->ice_pin_desc = ice_pin_desc_e810t;
- ptp->info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810t);
- ptp->info.pin_config = ptp->pin_desc;
- ice_ptp_setup_pin_cfg(pf);
+ /* Setup ice_pin_desc array */
+ for (i = 0; i < ICE_N_PINS_MAX; i++) {
+ pins[i].name_idx = -1;
+ pins[i].gpio[0] = -1;
+ pins[i].gpio[1] = -1;
+ }
+
+ for (i = 0; i < num_entries; i++) {
+ u16 entry = le16_to_cpu(entries[i]);
+ DECLARE_BITMAP(bitmap, GPIO_NA);
+ unsigned int bitmap_idx;
+ bool dir;
+ u16 gpio;
+
+ *bitmap = FIELD_GET(ICE_AQC_NVM_SDP_AC_PIN_M, entry);
+ dir = !!FIELD_GET(ICE_AQC_NVM_SDP_AC_DIR_M, entry);
+ gpio = FIELD_GET(ICE_AQC_NVM_SDP_AC_SDP_NUM_M, entry);
+ for_each_set_bit(bitmap_idx, bitmap, GPIO_NA + 1) {
+ unsigned int idx;
+
+ /* Check if entry's pin bit is valid */
+ if (bitmap_idx >= NUM_PTP_PINS_NVM &&
+ bitmap_idx != GPIO_NA)
+ continue;
- /* Clear SMA status */
- err = ice_ptp_set_sma_cfg(pf);
- if (err)
- ice_ptp_disable_sma_pins(pf);
+ /* Check if pin already exists */
+ for (idx = 0; idx < ICE_N_PINS_MAX; idx++)
+ if (pins[idx].name_idx == bitmap_idx)
+ break;
+
+ if (idx == ICE_N_PINS_MAX) {
+ /* Pin not found, setup its entry and name */
+ idx = n_pins++;
+ pins[idx].name_idx = bitmap_idx;
+ if (bitmap_idx == GPIO_NA)
+ strscpy(pf->ptp.pin_desc[idx].name,
+ ice_pin_names[gpio],
+ sizeof(pf->ptp.pin_desc[idx]
+ .name));
+ }
+
+ /* Setup in/out GPIO number */
+ pins[idx].gpio[dir] = gpio;
+ }
+ }
+
+ for (i = 0; i < n_pins; i++) {
+ dev_dbg(ice_pf_to_dev(pf),
+ "NVM pin entry[%d] : name_idx %d gpio_out %d gpio_in %d\n",
+ i, pins[i].name_idx, pins[i].gpio[1], pins[i].gpio[0]);
+ }
+
+ pf->ptp.info.n_pins = n_pins;
+ return 0;
}
/**
@@ -2474,15 +2526,49 @@ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf)
*/
static void ice_ptp_set_funcs_e810(struct ice_pf *pf)
{
- if (ice_is_e810t(&pf->hw) &&
- ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) {
- ice_ptp_setup_pins_e810t(pf);
- return;
+ __le16 entries[ICE_AQC_NVM_SDP_AC_MAX_SIZE];
+ struct ice_ptp_pin_desc *desc = NULL;
+ struct ice_ptp *ptp = &pf->ptp;
+ unsigned int num_entries;
+ int err;
+
+ err = ice_ptp_read_sdp_ac(&pf->hw, entries, &num_entries);
+ if (err) {
+ /* SDP section does not exist in NVM or is corrupted */
+ if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) {
+ ptp->ice_pin_desc = ice_pin_desc_e810_sma;
+ ptp->info.n_pins =
+ ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810_sma);
+ } else {
+ pf->ptp.ice_pin_desc = ice_pin_desc_e810;
+ pf->ptp.info.n_pins =
+ ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810);
+ err = 0;
+ }
+ } else {
+ desc = devm_kcalloc(ice_pf_to_dev(pf), ICE_N_PINS_MAX,
+ sizeof(struct ice_ptp_pin_desc),
+ GFP_KERNEL);
+ if (!desc)
+ goto err;
+
+ err = ice_ptp_parse_sdp_entries(pf, entries, num_entries, desc);
+ if (err)
+ goto err;
+
+ ptp->ice_pin_desc = (const struct ice_ptp_pin_desc *)desc;
}
- pf->ptp.ice_pin_desc = ice_pin_desc_e810;
- pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810);
+ ptp->info.pin_config = ptp->pin_desc;
ice_ptp_setup_pin_cfg(pf);
+
+ if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL))
+ err = ice_ptp_set_sma_cfg(pf);
+err:
+ if (err) {
+ devm_kfree(ice_pf_to_dev(pf), desc);
+ ice_ptp_disable_pins(pf);
+ }
}
/**