Thread (17 messages) flat view 17 messages, 4 authors, 2018-10-20

Re: [PATCH v2 net-next 7/8] net: dsa: microchip: Prepare PHY for proper advertisement

From: Florian Fainelli <f.fainelli@gmail.com>
Date: 2017-12-06 22:57:03


On 12/06/2017 01:55 PM, Tristram.Ha@microchip.com wrote:
quoted
quoted
+static void ksz9477_phy_setup(struct ksz_device *dev, int port,
+			      struct phy_device *phy)
+{
+	if (port < dev->phy_port_cnt) {
+		/* SUPPORTED_Asym_Pause and SUPPORTED_Pause can be
removed to
quoted
+		 * disable flow control when rate limiting is used.
+		 */
+		phy->advertising = phy->supported;
+	}
This looks a bit odd. phy_probe() does the same:

       /* Start out supporting everything. Eventually,
         * a controller will attach, and may modify one
         * or both of these values
         */
        phydev->supported = phydrv->features;
        of_set_phy_supported(phydev);
        phydev->advertising = phydev->supported;

You don't modify anything here, so i don't see why it is needed.
In my case I always see the value of advertising is 0x02ff, while that of
supported is 0x62ff.  The Cadence MAC I use does not support flow
control, so maybe the advertising value is stripped of that.
Pause is something that is auto-negotiated, if you don't somehow clear
it, then the Ethernet MAC on the other side can start sending you pause
frames, and if you don't respond back, then there are flow control problems.
If I do not do anything flow control will not be enabled for the ports.
Indeed, but likely there are also switch registers that need to be
programmed such that the pseudo Ethernet MAC in the switch properly
manages Pause frames.
A device connected at 1000 Mbit and another connected at 100 Mbit
will have dropped packet issue if the switch does not do anything else
to regulate traffic.

For other switches that do not really support Asymmetric Pause it
has to be explicitly removed.
If Pause or Asym Pause is not meant to be used/supported for particular
switches, then somehow you need to clear those bits and avoid
advertising them, and most likely you should do that in your
ds->ops->port_enable callback to make this work before phy_start() runs.
 
quoted
quoted
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+		     struct phy_device *phydev)
+{
+	struct ksz_device *dev = ds->priv;
+	struct ksz_port *p = &dev->ports[port];
+
+	if (phydev->link) {
+		p->speed = phydev->speed;
+		p->duplex = phydev->duplex;
+		p->flow_ctrl = phydev->pause;
+		p->link_up = 1;
+		dev->live_ports |= (1 << port) & dev->on_ports;
+	} else if (p->link_up) {
+		p->link_up = 0;
+		p->link_down = 1;
+		dev->live_ports &= ~(1 << port);
+	}
The link_down looks odd. If you are setting link_up to 1, should
link_down also be set to 0? Can it be both up and down at the same
time?
These variables are used internally.  link_up is an indication of the link;
link_down means the link is just dropped.  It is used for MIB counter
reading.  When the link is down most of the MIB counters will not be
updated, so it is a waste of time to read them.  They still are read at
least one more time to pick up any updated counters.
I suppose the question is, why is it okay for those not to be
symmetrical (i.e: not set link_down = 0 when UP)? And considering that
you should have either regular or fixed PHYs for each of your ports,
including the CPU port, why not use phydev->link everywhere as an
indication of whether a given port's link is up or down?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help