Skip to content

Commit 3e9dbfe

Browse files
kmaincentPaolo Abeni
authored andcommitted
net: pse-pd: Split ethtool_get_status into multiple callbacks
The ethtool_get_status callback currently handles all status and PSE information within a single function. This approach has two key drawbacks: 1. If the core requires some information for purposes other than ethtool_get_status, redundant code will be needed to fetch the same data from the driver (like is_enabled). 2. Drivers currently have access to all information passed to ethtool. New variables will soon be added to ethtool status, such as PSE ID, power domain IDs, and budget evaluation strategies, which are meant to be managed solely by the core. Drivers should not have the ability to modify these variables. To resolve these issues, ethtool_get_status has been split into multiple callbacks, with each handling a specific piece of information required by ethtool or the core. Signed-off-by: Kory Maincent <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent e0a5e2b commit 3e9dbfe

File tree

6 files changed

+323
-94
lines changed

6 files changed

+323
-94
lines changed

drivers/net/pse-pd/pd692x0.c

Lines changed: 109 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -517,21 +517,38 @@ pd692x0_pse_ext_state_map[] = {
517517
{ /* sentinel */ }
518518
};
519519

520-
static void
521-
pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info,
522-
u32 status_code)
520+
static int
521+
pd692x0_pi_get_ext_state(struct pse_controller_dev *pcdev, int id,
522+
struct pse_ext_state_info *ext_state_info)
523523
{
524+
struct ethtool_c33_pse_ext_state_info *c33_ext_state_info;
524525
const struct pd692x0_pse_ext_state_mapping *ext_state_map;
526+
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
527+
struct pd692x0_msg msg, buf = {0};
528+
int ret;
529+
530+
ret = pd692x0_fw_unavailable(priv);
531+
if (ret)
532+
return ret;
525533

534+
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
535+
msg.sub[2] = id;
536+
ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
537+
if (ret < 0)
538+
return ret;
539+
540+
c33_ext_state_info = &ext_state_info->c33_ext_state_info;
526541
ext_state_map = pd692x0_pse_ext_state_map;
527542
while (ext_state_map->status_code) {
528-
if (ext_state_map->status_code == status_code) {
543+
if (ext_state_map->status_code == buf.sub[0]) {
529544
c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state;
530545
c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate;
531-
return;
546+
return 0;
532547
}
533548
ext_state_map++;
534549
}
550+
551+
return 0;
535552
}
536553

537554
struct pd692x0_class_pw {
@@ -613,35 +630,36 @@ static int pd692x0_pi_set_pw_from_table(struct device *dev,
613630
}
614631

615632
static int
616-
pd692x0_pi_get_pw_ranges(struct pse_control_status *st)
633+
pd692x0_pi_get_pw_limit_ranges(struct pse_controller_dev *pcdev, int id,
634+
struct pse_pw_limit_ranges *pw_limit_ranges)
617635
{
636+
struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
618637
const struct pd692x0_class_pw *pw_table;
619638
int i;
620639

621640
pw_table = pd692x0_class_pw_table;
622-
st->c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
623-
sizeof(struct ethtool_c33_pse_pw_limit_range),
624-
GFP_KERNEL);
625-
if (!st->c33_pw_limit_ranges)
641+
c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
642+
sizeof(*c33_pw_limit_ranges),
643+
GFP_KERNEL);
644+
if (!c33_pw_limit_ranges)
626645
return -ENOMEM;
627646

628647
for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
629-
st->c33_pw_limit_ranges[i].min = pw_table->class_pw;
630-
st->c33_pw_limit_ranges[i].max = pw_table->class_pw + pw_table->max_added_class_pw;
648+
c33_pw_limit_ranges[i].min = pw_table->class_pw;
649+
c33_pw_limit_ranges[i].max = pw_table->class_pw +
650+
pw_table->max_added_class_pw;
631651
}
632652

633-
st->c33_pw_limit_nb_ranges = i;
634-
return 0;
653+
pw_limit_ranges->c33_pw_limit_ranges = c33_pw_limit_ranges;
654+
return i;
635655
}
636656

637-
static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
638-
unsigned long id,
639-
struct netlink_ext_ack *extack,
640-
struct pse_control_status *status)
657+
static int
658+
pd692x0_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
659+
struct pse_admin_state *admin_state)
641660
{
642661
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
643662
struct pd692x0_msg msg, buf = {0};
644-
u32 class;
645663
int ret;
646664

647665
ret = pd692x0_fw_unavailable(priv);
@@ -654,39 +672,65 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
654672
if (ret < 0)
655673
return ret;
656674

657-
/* Compare Port Status (Communication Protocol Document par. 7.1) */
658-
if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90)
659-
status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
660-
else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22)
661-
status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
662-
else if (buf.sub[0] == 0x12)
663-
status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
664-
else
665-
status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
666-
667675
if (buf.sub[1])
668-
status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
676+
admin_state->c33_admin_state =
677+
ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
669678
else
670-
status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
679+
admin_state->c33_admin_state =
680+
ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
671681

672-
priv->admin_state[id] = status->c33_admin_state;
682+
priv->admin_state[id] = admin_state->c33_admin_state;
673683

674-
pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]);
675-
status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100;
684+
return 0;
685+
}
676686

677-
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
687+
static int
688+
pd692x0_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,
689+
struct pse_pw_status *pw_status)
690+
{
691+
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
692+
struct pd692x0_msg msg, buf = {0};
693+
int ret;
694+
695+
ret = pd692x0_fw_unavailable(priv);
696+
if (ret)
697+
return ret;
698+
699+
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
678700
msg.sub[2] = id;
679-
memset(&buf, 0, sizeof(buf));
680701
ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
681702
if (ret < 0)
682703
return ret;
683704

684-
ret = pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
685-
if (ret < 0)
705+
/* Compare Port Status (Communication Protocol Document par. 7.1) */
706+
if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90)
707+
pw_status->c33_pw_status =
708+
ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
709+
else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22)
710+
pw_status->c33_pw_status =
711+
ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
712+
else if (buf.sub[0] == 0x12)
713+
pw_status->c33_pw_status =
714+
ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
715+
else
716+
pw_status->c33_pw_status =
717+
ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
718+
719+
return 0;
720+
}
721+
722+
static int
723+
pd692x0_pi_get_pw_class(struct pse_controller_dev *pcdev, int id)
724+
{
725+
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
726+
struct pd692x0_msg msg, buf = {0};
727+
u32 class;
728+
int ret;
729+
730+
ret = pd692x0_fw_unavailable(priv);
731+
if (ret)
686732
return ret;
687-
status->c33_avail_pw_limit = ret;
688733

689-
memset(&buf, 0, sizeof(buf));
690734
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
691735
msg.sub[2] = id;
692736
ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
@@ -695,13 +739,29 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
695739

696740
class = buf.data[3] >> 4;
697741
if (class <= 8)
698-
status->c33_pw_class = class;
742+
return class;
743+
744+
return 0;
745+
}
746+
747+
static int
748+
pd692x0_pi_get_actual_pw(struct pse_controller_dev *pcdev, int id)
749+
{
750+
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
751+
struct pd692x0_msg msg, buf = {0};
752+
int ret;
753+
754+
ret = pd692x0_fw_unavailable(priv);
755+
if (ret)
756+
return ret;
699757

700-
ret = pd692x0_pi_get_pw_ranges(status);
758+
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
759+
msg.sub[2] = id;
760+
ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
701761
if (ret < 0)
702762
return ret;
703763

704-
return 0;
764+
return (buf.data[0] << 4 | buf.data[1]) * 100;
705765
}
706766

707767
static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv)
@@ -1038,13 +1098,18 @@ static int pd692x0_pi_set_pw_limit(struct pse_controller_dev *pcdev,
10381098

10391099
static const struct pse_controller_ops pd692x0_ops = {
10401100
.setup_pi_matrix = pd692x0_setup_pi_matrix,
1041-
.ethtool_get_status = pd692x0_ethtool_get_status,
1101+
.pi_get_admin_state = pd692x0_pi_get_admin_state,
1102+
.pi_get_pw_status = pd692x0_pi_get_pw_status,
1103+
.pi_get_ext_state = pd692x0_pi_get_ext_state,
1104+
.pi_get_pw_class = pd692x0_pi_get_pw_class,
1105+
.pi_get_actual_pw = pd692x0_pi_get_actual_pw,
10421106
.pi_enable = pd692x0_pi_enable,
10431107
.pi_disable = pd692x0_pi_disable,
10441108
.pi_is_enabled = pd692x0_pi_is_enabled,
10451109
.pi_get_voltage = pd692x0_pi_get_voltage,
10461110
.pi_get_pw_limit = pd692x0_pi_get_pw_limit,
10471111
.pi_set_pw_limit = pd692x0_pi_set_pw_limit,
1112+
.pi_get_pw_limit_ranges = pd692x0_pi_get_pw_limit_ranges,
10481113
};
10491114

10501115
#define PD692X0_FW_LINE_MAX_SZ 0xff

drivers/net/pse-pd/pse_core.c

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,13 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
443443
if (!pcdev->nr_lines)
444444
pcdev->nr_lines = 1;
445445

446+
if (!pcdev->ops->pi_get_admin_state ||
447+
!pcdev->ops->pi_get_pw_status) {
448+
dev_err(pcdev->dev,
449+
"Mandatory status report callbacks are missing");
450+
return -EINVAL;
451+
}
452+
446453
ret = of_load_pse_pis(pcdev);
447454
if (ret)
448455
return ret;
@@ -745,25 +752,81 @@ EXPORT_SYMBOL_GPL(of_pse_control_get);
745752
*/
746753
int pse_ethtool_get_status(struct pse_control *psec,
747754
struct netlink_ext_ack *extack,
748-
struct pse_control_status *status)
755+
struct ethtool_pse_control_status *status)
749756
{
757+
struct pse_admin_state admin_state = {0};
758+
struct pse_pw_status pw_status = {0};
750759
const struct pse_controller_ops *ops;
751760
struct pse_controller_dev *pcdev;
752-
int err;
761+
int ret;
753762

754763
pcdev = psec->pcdev;
755764
ops = pcdev->ops;
756-
if (!ops->ethtool_get_status) {
757-
NL_SET_ERR_MSG(extack,
758-
"PSE driver does not support status report");
759-
return -EOPNOTSUPP;
765+
mutex_lock(&pcdev->lock);
766+
ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state);
767+
if (ret)
768+
goto out;
769+
status->podl_admin_state = admin_state.podl_admin_state;
770+
status->c33_admin_state = admin_state.c33_admin_state;
771+
772+
ret = ops->pi_get_pw_status(pcdev, psec->id, &pw_status);
773+
if (ret)
774+
goto out;
775+
status->podl_pw_status = pw_status.podl_pw_status;
776+
status->c33_pw_status = pw_status.c33_pw_status;
777+
778+
if (ops->pi_get_ext_state) {
779+
struct pse_ext_state_info ext_state_info = {0};
780+
781+
ret = ops->pi_get_ext_state(pcdev, psec->id,
782+
&ext_state_info);
783+
if (ret)
784+
goto out;
785+
786+
memcpy(&status->c33_ext_state_info,
787+
&ext_state_info.c33_ext_state_info,
788+
sizeof(status->c33_ext_state_info));
760789
}
761790

762-
mutex_lock(&pcdev->lock);
763-
err = ops->ethtool_get_status(pcdev, psec->id, extack, status);
764-
mutex_unlock(&pcdev->lock);
791+
if (ops->pi_get_pw_class) {
792+
ret = ops->pi_get_pw_class(pcdev, psec->id);
793+
if (ret < 0)
794+
goto out;
765795

766-
return err;
796+
status->c33_pw_class = ret;
797+
}
798+
799+
if (ops->pi_get_actual_pw) {
800+
ret = ops->pi_get_actual_pw(pcdev, psec->id);
801+
if (ret < 0)
802+
goto out;
803+
804+
status->c33_actual_pw = ret;
805+
}
806+
807+
if (ops->pi_get_pw_limit) {
808+
ret = ops->pi_get_pw_limit(pcdev, psec->id);
809+
if (ret < 0)
810+
goto out;
811+
812+
status->c33_avail_pw_limit = ret;
813+
}
814+
815+
if (ops->pi_get_pw_limit_ranges) {
816+
struct pse_pw_limit_ranges pw_limit_ranges = {0};
817+
818+
ret = ops->pi_get_pw_limit_ranges(pcdev, psec->id,
819+
&pw_limit_ranges);
820+
if (ret < 0)
821+
goto out;
822+
823+
status->c33_pw_limit_ranges =
824+
pw_limit_ranges.c33_pw_limit_ranges;
825+
status->c33_pw_limit_nb_ranges = ret;
826+
}
827+
out:
828+
mutex_unlock(&psec->pcdev->lock);
829+
return ret;
767830
}
768831
EXPORT_SYMBOL_GPL(pse_ethtool_get_status);
769832

drivers/net/pse-pd/pse_regulator.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,19 @@ pse_reg_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
6060
}
6161

6262
static int
63-
pse_reg_ethtool_get_status(struct pse_controller_dev *pcdev, unsigned long id,
64-
struct netlink_ext_ack *extack,
65-
struct pse_control_status *status)
63+
pse_reg_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
64+
struct pse_admin_state *admin_state)
65+
{
66+
struct pse_reg_priv *priv = to_pse_reg(pcdev);
67+
68+
admin_state->podl_admin_state = priv->admin_state;
69+
70+
return 0;
71+
}
72+
73+
static int
74+
pse_reg_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,
75+
struct pse_pw_status *pw_status)
6676
{
6777
struct pse_reg_priv *priv = to_pse_reg(pcdev);
6878
int ret;
@@ -72,18 +82,18 @@ pse_reg_ethtool_get_status(struct pse_controller_dev *pcdev, unsigned long id,
7282
return ret;
7383

7484
if (!ret)
75-
status->podl_pw_status = ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED;
85+
pw_status->podl_pw_status =
86+
ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED;
7687
else
77-
status->podl_pw_status =
88+
pw_status->podl_pw_status =
7889
ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING;
7990

80-
status->podl_admin_state = priv->admin_state;
81-
8291
return 0;
8392
}
8493

8594
static const struct pse_controller_ops pse_reg_ops = {
86-
.ethtool_get_status = pse_reg_ethtool_get_status,
95+
.pi_get_admin_state = pse_reg_pi_get_admin_state,
96+
.pi_get_pw_status = pse_reg_pi_get_pw_status,
8797
.pi_enable = pse_reg_pi_enable,
8898
.pi_is_enabled = pse_reg_pi_is_enabled,
8999
.pi_disable = pse_reg_pi_disable,

0 commit comments

Comments
 (0)