lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <57e60cb1-7f57-48ff-9884-458831e19810@quicinc.com>
Date: Fri, 8 Nov 2024 20:03:21 +0800
From: Lei Wei <quic_leiwei@...cinc.com>
To: "Russell King (Oracle)" <linux@...linux.org.uk>
CC: "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet
	<edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni
	<pabeni@...hat.com>, Rob Herring <robh@...nel.org>,
        Krzysztof Kozlowski
	<krzk+dt@...nel.org>,
        Conor Dooley <conor+dt@...nel.org>, Andrew Lunn
	<andrew@...n.ch>,
        Heiner Kallweit <hkallweit1@...il.com>, <netdev@...r.kernel.org>,
        <devicetree@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <quic_kkumarcs@...cinc.com>, <quic_suruchia@...cinc.com>,
        <quic_pavir@...cinc.com>, <quic_linchen@...cinc.com>,
        <quic_luoj@...cinc.com>, <srinivas.kandagatla@...aro.org>,
        <bartosz.golaszewski@...aro.org>, <vsmuthu@....qualcomm.com>,
        <john@...ozen.org>
Subject: Re: [PATCH net-next 3/5] net: pcs: qcom-ipq: Add PCS create and
 phylink operations for IPQ9574



On 11/8/2024 3:02 AM, Russell King (Oracle) wrote:
> Hi,
> 
> On Fri, Nov 01, 2024 at 06:32:51PM +0800, Lei Wei wrote:
>> +static int ipq_pcs_config_mode(struct ipq_pcs *qpcs,
>> +			       phy_interface_t interface)
>> +{
>> +	unsigned int val;
>> +	int ret;
>> +
>> +	/* Configure PCS interface mode */
>> +	switch (interface) {
>> +	case PHY_INTERFACE_MODE_SGMII:
>> +		/* Select Qualcomm SGMII AN mode */
>> +		ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
>> +					 PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
>> +					 PCS_MODE_SGMII);
>> +		if (ret)
>> +			return ret;
>> +		break;
>> +	case PHY_INTERFACE_MODE_QSGMII:
>> +		ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
>> +					 PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
>> +					 PCS_MODE_QSGMII);
>> +		if (ret)
>> +			return ret;
>> +		break;
>> +	default:
>> +		dev_err(qpcs->dev,
>> +			"Unsupported interface %s\n", phy_modes(interface));
>> +		return -EOPNOTSUPP;
>> +	}
> 
> I think:
> 
> 	unsigned int mode;
> 
> 	switch (interface) {
> 	case PHY_INTERFACE_MODE_SGMII:
> 		/* Select Qualcomm SGMII AN mode */
> 		mode = PCS_MODE_SGMII;
> 		break;
> 
> 	case PHY_INTERFACE_MODE_QSGMII:
> 		mode = PCS_MODE_QSGMII;
> 		break;
> 
> 	default:
> 		...
> 	}
> 
> 	ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL,
> 				 PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE, mode);
> 	if (ret)
> 		return ret;
> 
> might be easier to read? 

Thanks for the suggestion, I will make this change.

I notice that in patch 4, the USXGMII case
> drops PCS_MODE_AN_MODE from the mask, leaving this bit set to whatever
> value it previously was. Is that intentional?
> 

Yes, this bit is used for configuring the SGMII AN mode - Cisco AN or 
Qualcomm AN. The default setting is Cisco SGMII AN mode.

Please note that as per our discussion with Andrew on his comment 
regarding the default mode to use, we would like to change the default 
setting for SGMII/QSGMII to Cisco AN Mode in the next patch update.

>> +static int ipq_pcs_link_up_config_sgmii(struct ipq_pcs *qpcs,
>> +					int index,
>> +					unsigned int neg_mode,
>> +					int speed)
>> +{
>> +	int ret;
>> +
>> +	/* PCS speed need not be configured if in-band autoneg is enabled */
>> +	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
>> +		goto pcs_adapter_reset;
>> +
>> +	/* PCS speed set for force mode */
>> +	switch (speed) {
>> +	case SPEED_1000:
>> +		ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
>> +					 PCS_MII_SPEED_MASK,
>> +					 PCS_MII_SPEED_1000);
>> +		if (ret)
>> +			return ret;
>> +		break;
>> +	case SPEED_100:
>> +		ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
>> +					 PCS_MII_SPEED_MASK, PCS_MII_SPEED_100);
>> +		if (ret)
>> +			return ret;
>> +		break;
>> +	case SPEED_10:
>> +		ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
>> +					 PCS_MII_SPEED_MASK, PCS_MII_SPEED_10);
>> +		if (ret)
>> +			return ret;
>> +		break;
>> +	default:
>> +		dev_err(qpcs->dev, "Invalid SGMII speed %d\n", speed);
>> +		return -EINVAL;
>> +	}
> 
> I think it's worth having the same structure here, and with fewer lines
> (and fewer long lines) maybe:
> 
> 	if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
> 		switch (speed) {
> 		...
> 		}
> 
> 		ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
> 					 PCS_MII_SPEED_MASK, ctrl);
> 		if (ret)
> 			return ret;
> 	}
> 
> means you don't need the pcs_adapter_reset label.
> 

Sure, thanks for the suggestion. I will make this change.

>> +
>> +pcs_adapter_reset:
>> +	/* PCS adapter reset */
>> +	ret = regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
>> +				 PCS_MII_ADPT_RESET, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return regmap_update_bits(qpcs->regmap, PCS_MII_CTRL(index),
>> +				  PCS_MII_ADPT_RESET, PCS_MII_ADPT_RESET);
>> +}
>> +
>> +static void ipq_pcs_get_state(struct phylink_pcs *pcs,
>> +			      struct phylink_link_state *state)
>> +{
>> +	struct ipq_pcs_mii *qpcs_mii = phylink_pcs_to_qpcs_mii(pcs);
>> +	struct ipq_pcs *qpcs = qpcs_mii->qpcs;
>> +	int index = qpcs_mii->index;
>> +
>> +	switch (state->interface) {
>> +	case PHY_INTERFACE_MODE_SGMII:
>> +	case PHY_INTERFACE_MODE_QSGMII:
>> +		ipq_pcs_get_state_sgmii(qpcs, index, state);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +
>> +	dev_dbg(qpcs->dev,
>> +		"mode=%s/%s/%s link=%u\n",
>> +		phy_modes(state->interface),
>> +		phy_speed_to_str(state->speed),
>> +		phy_duplex_to_str(state->duplex),
>> +		state->link);
> 
> This will get very noisy given that in polling mode, phylink will call
> this once a second - and I see you are using polling mode.
> 

Sure, I will use dev_dbg_ratelimited() API instead.

>> +/**
>> + * ipq_pcs_create() - Create an IPQ PCS MII instance
>> + * @np: Device tree node to the PCS MII
>> + *
>> + * Description: Create a phylink PCS instance for the given PCS MII node @np
>> + * and enable the MII clocks. This instance is associated with the specific
>> + * MII of the PCS and the corresponding Ethernet netdevice.
>> + *
>> + * Return: A pointer to the phylink PCS instance or an error-pointer value.
>> + */
>> +struct phylink_pcs *ipq_pcs_create(struct device_node *np)
>> +{
>> +	struct platform_device *pdev;
>> +	struct ipq_pcs_mii *qpcs_mii;
>> +	struct device_node *pcs_np;
>> +	struct ipq_pcs *qpcs;
>> +	int i, ret;
>> +	u32 index;
>> +
>> +	if (!of_device_is_available(np))
>> +		return ERR_PTR(-ENODEV);
>> +
>> +	if (of_property_read_u32(np, "reg", &index))
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	if (index >= PCS_MAX_MII_NRS)
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	pcs_np = of_get_parent(np);
>> +	if (!pcs_np)
>> +		return ERR_PTR(-ENODEV);
>> +
>> +	if (!of_device_is_available(pcs_np)) {
>> +		of_node_put(pcs_np);
>> +		return ERR_PTR(-ENODEV);
>> +	}
>> +
>> +	pdev = of_find_device_by_node(pcs_np);
>> +	of_node_put(pcs_np);
>> +	if (!pdev)
>> +		return ERR_PTR(-ENODEV);
>> +
>> +	qpcs = platform_get_drvdata(pdev);
>> +	put_device(&pdev->dev);
>> +
>> +	/* If probe is not yet completed, return DEFER to
>> +	 * the dependent driver.
>> +	 */
>> +	if (!qpcs)
>> +		return ERR_PTR(-EPROBE_DEFER);
>> +
>> +	qpcs_mii = kzalloc(sizeof(*qpcs_mii), GFP_KERNEL);
>> +	if (!qpcs_mii)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	qpcs_mii->qpcs = qpcs;
>> +	qpcs_mii->index = index;
>> +	qpcs_mii->pcs.ops = &ipq_pcs_phylink_ops;
>> +	qpcs_mii->pcs.neg_mode = true;
>> +	qpcs_mii->pcs.poll = true;
>> +
>> +	for (i = 0; i < PCS_MII_CLK_MAX; i++) {
>> +		qpcs_mii->clk[i] = of_clk_get_by_name(np, pcs_mii_clk_name[i]);
>> +		if (IS_ERR(qpcs_mii->clk[i])) {
>> +			dev_err(qpcs->dev,
>> +				"Failed to get MII %d interface clock %s\n",
>> +				index, pcs_mii_clk_name[i]);
>> +			goto err_clk_get;
>> +		}
>> +
>> +		ret = clk_prepare_enable(qpcs_mii->clk[i]);
>> +		if (ret) {
>> +			dev_err(qpcs->dev,
>> +				"Failed to enable MII %d interface clock %s\n",
>> +				index, pcs_mii_clk_name[i]);
>> +			goto err_clk_en;
>> +		}
> 
> Do you always need the clock prepared and enabled? If not, you could
> do this in the pcs_enable() method, and turn it off in pcs_disable().
> 

Yes, it can be moved to pcs_enable/pcs_disable method. I will make this 
change.

> I think phylink may need a tweak to "unuse" the current PCS when
> phylink_stop() is called to make that more effective at disabling the
> PCS, which is something that should be done - that's a subject for a
> separate patch which I may send.
> 



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ