From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
Cc: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
open list <linux-kernel@vger.kernel.org>,
Yevhen Orlov <yevhen.orlov@plvision.eu>,
Taras Chornyi <taras.chornyi@plvision.eu>
Subject: Re: [PATCH net-next] net: marvell: prestera: add phylink support
Date: Fri, 8 Jul 2022 22:48:40 +0100 [thread overview]
Message-ID: <YsimODfLM3mu/KZM@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220708170635.13190-1-oleksandr.mazur@plvision.eu>
On Fri, Jul 08, 2022 at 08:06:34PM +0300, Oleksandr Mazur wrote:
> For SFP port prestera driver will use kernel
> phylink infrastucture to configure port mode based on
> the module that has beed inserted
>
> Co-developed-by: Yevhen Orlov <yevhen.orlov@plvision.eu>
> Signed-off-by: Yevhen Orlov <yevhen.orlov@plvision.eu>
> Co-developed-by: Taras Chornyi <taras.chornyi@plvision.eu>
> Signed-off-by: Taras Chornyi <taras.chornyi@plvision.eu>
> Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu>
First question which applies to everything in this patch is - why make
phylink conditional for this driver?
> +#ifdef CONFIG_PHYLINK
> +static void
> +prestera_port_mac_state_cache_read(struct prestera_port *port,
> + struct prestera_port_mac_state *state)
> +{
> + read_lock(&port->state_mac_lock);
> + *state = port->state_mac;
> + read_unlock(&port->state_mac_lock);
> +}
> +
> +static void
> +prestera_port_mac_state_cache_write(struct prestera_port *port,
> + struct prestera_port_mac_state *state)
> +{
> + write_lock(&port->state_mac_lock);
> + port->state_mac = *state;
> + write_unlock(&port->state_mac_lock);
> +}
> +
> +static void prestera_mac_pcs_get_state(struct phylink_config *config,
> + struct phylink_link_state *state)
> +{
> + struct net_device *ndev = to_net_dev(config->dev);
> + struct prestera_port *port = netdev_priv(ndev);
> + struct prestera_port_mac_state smac;
> +
> + prestera_port_mac_state_cache_read(port, &smac);
> +
> + if (smac.valid) {
> + state->link = smac.oper;
> + state->pause = 0;
> + /* AN is completed, when port is up */
> + state->an_complete = smac.oper ? port->autoneg : false;
> + state->speed = smac.speed;
> + state->duplex = smac.duplex;
> } else {
> - port->cfg_phy.admin = false;
> - err = prestera_hw_port_phy_mode_set(port, false, port->autoneg,
> - port->cfg_phy.mode,
> - port->adver_link_modes,
> - port->cfg_phy.mdix);
> + state->link = false;
> + state->pause = 0;
> + state->an_complete = false;
> + state->speed = SPEED_UNKNOWN;
> + state->duplex = DUPLEX_UNKNOWN;
> + }
> +}
This function is obsolete, please delete it.
> +
> +static void prestera_mac_config(struct phylink_config *config,
> + unsigned int an_mode,
> + const struct phylink_link_state *state)
> +{
> + struct net_device *ndev = to_net_dev(config->dev);
> + struct prestera_port *port = netdev_priv(ndev);
> + struct prestera_port_mac_config cfg_mac;
> +
> + prestera_port_cfg_mac_read(port, &cfg_mac);
> + cfg_mac.admin = true;
> + cfg_mac.mode = PRESTERA_MAC_MODE_MAX;
> + cfg_mac.inband = false;
> + cfg_mac.speed = 0;
> + cfg_mac.duplex = DUPLEX_UNKNOWN;
> + cfg_mac.fec = PRESTERA_PORT_FEC_OFF;
> +
> + /* See sfp_select_interface... fIt */
> + switch (state->interface) {
> + case PHY_INTERFACE_MODE_10GBASER:
> + cfg_mac.mode = PRESTERA_MAC_MODE_SR_LR;
> + cfg_mac.speed = SPEED_10000;
> + if (state->speed == SPEED_1000) {
> + cfg_mac.mode = PRESTERA_MAC_MODE_1000BASE_X;
> + } else if (state->speed == SPEED_2500) {
> + cfg_mac.mode = PRESTERA_MAC_MODE_SGMII;
> + cfg_mac.inband = true;
> + cfg_mac.speed = SPEED_2500;
> + cfg_mac.duplex = DUPLEX_FULL;
> + }
No no no no no no no. state->speed is _not_ defined here, as is stated
in the documentation. You can not test it here; the results are
meaningless. Also this looks really odd. If the interface is
10000base-R, then why are you switching the MAC mode to 1000base-X
or SGMII?
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + case PHY_INTERFACE_MODE_SGMII:
> + /* But it seems to be not supported in HW */
> + cfg_mac.mode = PRESTERA_MAC_MODE_SGMII;
SGMII mode for 2500base-X ?
> + cfg_mac.inband = true;
> + cfg_mac.speed = SPEED_2500;
> + cfg_mac.duplex = DUPLEX_FULL;
> + break;
> + case PHY_INTERFACE_MODE_1000BASEX:
> + cfg_mac.mode = PRESTERA_MAC_MODE_1000BASE_X;
> + cfg_mac.inband = state->an_enabled;
> + cfg_mac.speed = SPEED_1000;
> + cfg_mac.duplex = DUPLEX_UNKNOWN;
> + break;
> + default:
> + cfg_mac.mode = PRESTERA_MAC_MODE_1000BASE_X;
> + }
> +
> + prestera_port_cfg_mac_write(port, &cfg_mac);
> +}
> +
> +int prestera_mac_finish(struct phylink_config *config, unsigned int mode,
> + phy_interface_t iface)
> +{
> + return 0;
> +}
No need to implement this if its doing nothing.
> +
> +static void prestera_mac_an_restart(struct phylink_config *config)
> +{
> + /* No need to restart autoneg as it is always with the same parameters,
> + * because e.g. as for 1000baseX FC isn't supported. And for 1000baseT
> + * autoneg provided by external tranciever
> + */
> +}
This function is obsolete, please delete it.
> +
> +static void prestera_mac_link_down(struct phylink_config *config,
> + unsigned int mode, phy_interface_t interface)
> +{
> + struct net_device *ndev = to_net_dev(config->dev);
> + struct prestera_port *port = netdev_priv(ndev);
> + struct prestera_port_mac_state state_mac;
> +
> + /* Invalidate. Parameters will update on next link event. */
> + memset(&state_mac, 0, sizeof(state_mac));
> + state_mac.valid = false;
> + prestera_port_mac_state_cache_write(port, &state_mac);
> +}
> +
> +static void prestera_mac_link_up(struct phylink_config *config,
> + struct phy_device *phy,
> + unsigned int mode, phy_interface_t interface,
> + int speed, int duplex,
> + bool tx_pause, bool rx_pause)
> +{
This is the place that you get to learn about the link speed etc.
> +}
> +
> +static struct phylink_pcs *prestera_mac_select_pcs(struct phylink_config *config,
> + phy_interface_t interface)
> +{
> + struct net_device *dev = to_net_dev(config->dev);
> + struct prestera_port *port = netdev_priv(dev);
> +
> + return &port->phylink_pcs;
> +}
> +
> +static void prestera_pcs_get_state(struct phylink_pcs *pcs,
> + struct phylink_link_state *state)
> +{
> + struct prestera_port *port = container_of(pcs, struct prestera_port,
> + phylink_pcs);
> + struct prestera_port_mac_state smac;
> +
> + prestera_port_mac_state_cache_read(port, &smac);
> +
> + if (smac.valid) {
> + state->link = smac.oper;
> + state->pause = 0;
> + /* AN is completed, when port is up */
> + state->an_complete = smac.oper ? port->autoneg : false;
> + state->speed = smac.speed;
> + state->duplex = smac.duplex;
> + } else {
> + state->link = false;
This isn't a boolean, it's a 1-bit field, so "state->link = 0;" is
appropriate here.
> + state->pause = 0;
This will be set by phylink appropriately, there's no need to set
it if there is no link.
> + state->an_complete = false;
an_complete is a 1-bit field as well, and is set to 0.
> + state->speed = SPEED_UNKNOWN;
> + state->duplex = DUPLEX_UNKNOWN;
These will be set to UNKNOWN if AN is disabled, otherwise to the
configured speed. There's no need to set these.
> + }
> +}
> +
> +static int prestera_pcs_config(struct phylink_pcs *pcs,
> + unsigned int mode,
> + phy_interface_t interface,
> + const unsigned long *advertising,
> + bool permit_pause_to_mac)
> +{
> + return 0;
> +}
> +
> +void prestera_pcs_an_restart(struct phylink_pcs *pcs)
> +{
> +}
> +
> +static const struct phylink_mac_ops prestera_mac_ops = {
> + .validate = phylink_generic_validate,
> + .mac_select_pcs = prestera_mac_select_pcs,
> + .mac_pcs_get_state = prestera_mac_pcs_get_state,
Obsolete method.
> + .mac_config = prestera_mac_config,
> + .mac_finish = prestera_mac_finish,
> + .mac_an_restart = prestera_mac_an_restart,
Obsolete method.
> + .mac_link_down = prestera_mac_link_down,
> + .mac_link_up = prestera_mac_link_up,
> +};
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
prev parent reply other threads:[~2022-07-08 21:48 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-08 17:06 [PATCH net-next] net: marvell: prestera: add phylink support Oleksandr Mazur
2022-07-08 21:48 ` Russell King (Oracle) [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YsimODfLM3mu/KZM@shell.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=oleksandr.mazur@plvision.eu \
--cc=pabeni@redhat.com \
--cc=taras.chornyi@plvision.eu \
--cc=yevhen.orlov@plvision.eu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).