diff options
Diffstat (limited to 'net/ethtool/pse-pd.c')
| -rw-r--r-- | net/ethtool/pse-pd.c | 60 | 
1 files changed, 50 insertions, 10 deletions
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c index cc478af77111..2c981d443f27 100644 --- a/net/ethtool/pse-pd.c +++ b/net/ethtool/pse-pd.c @@ -82,6 +82,10 @@ static int pse_reply_size(const struct ethnl_req_info *req_base,  		len += nla_total_size(sizeof(u32)); /* _PODL_PSE_ADMIN_STATE */  	if (st->podl_pw_status > 0)  		len += nla_total_size(sizeof(u32)); /* _PODL_PSE_PW_D_STATUS */ +	if (st->c33_admin_state > 0) +		len += nla_total_size(sizeof(u32)); /* _C33_PSE_ADMIN_STATE */ +	if (st->c33_pw_status > 0) +		len += nla_total_size(sizeof(u32)); /* _C33_PSE_PW_D_STATUS */  	return len;  } @@ -103,6 +107,16 @@ static int pse_fill_reply(struct sk_buff *skb,  			st->podl_pw_status))  		return -EMSGSIZE; +	if (st->c33_admin_state > 0 && +	    nla_put_u32(skb, ETHTOOL_A_C33_PSE_ADMIN_STATE, +			st->c33_admin_state)) +		return -EMSGSIZE; + +	if (st->c33_pw_status > 0 && +	    nla_put_u32(skb, ETHTOOL_A_C33_PSE_PW_D_STATUS, +			st->c33_pw_status)) +		return -EMSGSIZE; +  	return 0;  } @@ -113,25 +127,18 @@ const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1] = {  	[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] =  		NLA_POLICY_RANGE(NLA_U32, ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED,  				 ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED), +	[ETHTOOL_A_C33_PSE_ADMIN_CONTROL] = +		NLA_POLICY_RANGE(NLA_U32, ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED, +				 ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED),  };  static int  ethnl_set_pse_validate(struct ethnl_req_info *req_info, struct genl_info *info)  { -	return !!info->attrs[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]; -} - -static int -ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info) -{  	struct net_device *dev = req_info->dev; -	struct pse_control_config config = {};  	struct nlattr **tb = info->attrs;  	struct phy_device *phydev; -	/* this values are already validated by the ethnl_pse_set_policy */ -	config.admin_cotrol = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]); -  	phydev = dev->phydev;  	if (!phydev) {  		NL_SET_ERR_MSG(info->extack, "No PHY is attached"); @@ -143,6 +150,39 @@ ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)  		return -EOPNOTSUPP;  	} +	if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] && +	    !pse_has_podl(phydev->psec)) { +		NL_SET_ERR_MSG_ATTR(info->extack, +				    tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL], +				    "setting PoDL PSE admin control not supported"); +		return -EOPNOTSUPP; +	} +	if (tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL] && +	    !pse_has_c33(phydev->psec)) { +		NL_SET_ERR_MSG_ATTR(info->extack, +				    tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL], +				    "setting C33 PSE admin control not supported"); +		return -EOPNOTSUPP; +	} + +	return 1; +} + +static int +ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info) +{ +	struct net_device *dev = req_info->dev; +	struct pse_control_config config = {}; +	struct nlattr **tb = info->attrs; +	struct phy_device *phydev; + +	phydev = dev->phydev; +	/* These values are already validated by the ethnl_pse_set_policy */ +	if (pse_has_podl(phydev->psec)) +		config.podl_admin_control = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]); +	if (pse_has_c33(phydev->psec)) +		config.c33_admin_control = nla_get_u32(tb[ETHTOOL_A_C33_PSE_ADMIN_CONTROL]); +  	/* Return errno directly - PSE has no notification */  	return pse_ethtool_set_config(phydev->psec, info->extack, &config);  }  |