[PATCH net-next v2 11/15] net: pse-pd: Add support for PSE device index
From: Kory Maincent
Date: Thu Jan 09 2025 - 05:22:01 EST
From: Kory Maincent (Dent Project) <kory.maincent@xxxxxxxxxxx>
Add support for a PSE device index to report the PSE controller index to
the user through ethtool. This will be useful for future support of power
domains and port priority management.
Acked-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
Signed-off-by: Kory Maincent <kory.maincent@xxxxxxxxxxx>
---
drivers/net/pse-pd/pse_core.c | 24 +++++++++++++++++++-----
include/linux/pse-pd/pse.h | 4 ++++
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 887a477197a6..830e8d567d4d 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -13,6 +13,7 @@
static DEFINE_MUTEX(pse_list_mutex);
static LIST_HEAD(pse_controller_list);
+static DEFINE_IDA(pse_ida);
/**
* struct pse_control - a PSE control
@@ -448,6 +449,10 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
mutex_init(&pcdev->lock);
INIT_LIST_HEAD(&pcdev->pse_control_head);
+ ret = ida_alloc_max(&pse_ida, INT_MAX, GFP_KERNEL);
+ if (ret < 0)
+ return ret;
+ pcdev->id = ret;
if (!pcdev->nr_lines)
pcdev->nr_lines = 1;
@@ -461,12 +466,12 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
ret = of_load_pse_pis(pcdev);
if (ret)
- return ret;
+ goto free_pse_ida;
if (pcdev->ops->setup_pi_matrix) {
ret = pcdev->ops->setup_pi_matrix(pcdev);
if (ret)
- return ret;
+ goto free_pse_ida;
}
/* Each regulator name len is pcdev dev name + 7 char +
@@ -483,15 +488,17 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
continue;
reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL);
- if (!reg_name)
- return -ENOMEM;
+ if (!reg_name) {
+ ret = -ENOMEM;
+ goto free_pse_ida;
+ }
snprintf(reg_name, reg_name_len, "pse-%s_pi%d",
dev_name(pcdev->dev), i);
ret = devm_pse_pi_regulator_register(pcdev, reg_name, i);
if (ret)
- return ret;
+ goto free_pse_ida;
}
mutex_lock(&pse_list_mutex);
@@ -499,6 +506,10 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
mutex_unlock(&pse_list_mutex);
return 0;
+
+free_pse_ida:
+ ida_free(&pse_ida, pcdev->id);
+ return ret;
}
EXPORT_SYMBOL_GPL(pse_controller_register);
@@ -509,6 +520,7 @@ EXPORT_SYMBOL_GPL(pse_controller_register);
void pse_controller_unregister(struct pse_controller_dev *pcdev)
{
pse_release_pis(pcdev);
+ ida_free(&pse_ida, pcdev->id);
mutex_lock(&pse_list_mutex);
list_del(&pcdev->list);
mutex_unlock(&pse_list_mutex);
@@ -771,6 +783,8 @@ int pse_ethtool_get_status(struct pse_control *psec,
pcdev = psec->pcdev;
ops = pcdev->ops;
+ status->pse_id = pcdev->id;
+
mutex_lock(&pcdev->lock);
ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state);
if (ret)
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index b5ae3dcee550..be877dea6a11 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -78,6 +78,7 @@ struct pse_pw_limit_ranges {
/**
* struct ethtool_pse_control_status - PSE control/channel status.
*
+ * @pse_id: index number of the PSE.
* @podl_admin_state: operational state of the PoDL PSE
* functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
* @podl_pw_status: power detection status of the PoDL PSE.
@@ -99,6 +100,7 @@ struct pse_pw_limit_ranges {
* ranges
*/
struct ethtool_pse_control_status {
+ u32 pse_id;
enum ethtool_podl_pse_admin_state podl_admin_state;
enum ethtool_podl_pse_pw_d_status podl_pw_status;
enum ethtool_c33_pse_admin_state c33_admin_state;
@@ -208,6 +210,7 @@ struct pse_pi {
* @types: types of the PSE controller
* @pi: table of PSE PIs described in this controller device
* @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
+ * @id: Index of the PSE
*/
struct pse_controller_dev {
const struct pse_controller_ops *ops;
@@ -221,6 +224,7 @@ struct pse_controller_dev {
enum ethtool_pse_types types;
struct pse_pi *pi;
bool no_of_pse_pi;
+ u32 id;
};
#if IS_ENABLED(CONFIG_PSE_CONTROLLER)
--
2.34.1