Skip to content

Commit

Permalink
net: sparx5: add port module support
Browse files Browse the repository at this point in the history
This add configuration of the Sparx5 port module instances.

Sparx5 has in total 65 logical ports (denoted D0 to D64) and 33
physical SerDes connections (S0 to S32).  The 65th port (D64) is fixed
allocated to SerDes0 (S0). The remaining 64 ports can in various
multiplexing scenarios be connected to the remaining 32 SerDes using
QSGMII, or USGMII or USXGMII extenders. 32 of the ports can have a 1:1
mapping to the 32 SerDes.

Some additional ports (D65 to D69) are internal to the device and do not
connect to port modules or SerDes macros. For example, internal ports are
used for frame injection and extraction to the CPU queues.

The 65 logical ports are split up into the following blocks.

- 13 x 5G ports (D0-D11, D64)
- 32 x 2G5 ports (D16-D47)
- 12 x 10G ports (D12-D15, D48-D55)
- 8 x 25G ports (D56-D63)

Each logical port supports different line speeds, and depending on the
speeds supported, different port modules (MAC+PCS) are needed. A port
supporting 5 Gbps, 10 Gbps, or 25 Gbps as maximum line speed, will have a
DEV5G, DEV10G, or DEV25G module to support the 5 Gbps, 10 Gbps (incl 5
Gbps), or 25 Gbps (including 10 Gbps and 5 Gbps) speeds. As well as, it
will have a shadow DEV2G5 port module to support the lower speeds
(10/100/1000/2500Mbps). When a port needs to operate at lower speed and the
shadow DEV2G5 needs to be connected to its corresponding SerDes

Not all interface modes are supported in this series, but will be added at
a later stage.

Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Steen Hegelund authored and David S. Miller committed Jun 24, 2021
1 parent f3cad26 commit 946e7fd
Show file tree
Hide file tree
Showing 6 changed files with 1,279 additions and 12 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/microchip/sparx5/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o

sparx5-switch-objs := sparx5_main.o sparx5_packet.o \
sparx5_netdev.o sparx5_phylink.o
sparx5_netdev.o sparx5_phylink.o sparx5_port.o
9 changes: 8 additions & 1 deletion drivers/net/ethernet/microchip/sparx5/sparx5_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "sparx5_main_regs.h"
#include "sparx5_main.h"
#include "sparx5_port.h"

#define QLIM_WM(fraction) \
((SPX5_BUFFER_MEMORY / SPX5_BUFFER_CELL_SZ - 100) * (fraction) / 100)
Expand Down Expand Up @@ -252,6 +253,7 @@ static int sparx5_create_port(struct sparx5 *sparx5,
struct sparx5_port *spx5_port;
struct net_device *ndev;
struct phylink *phylink;
int err;

ndev = sparx5_create_netdev(sparx5, config->portno);
if (IS_ERR(ndev)) {
Expand All @@ -273,9 +275,14 @@ static int sparx5_create_port(struct sparx5 *sparx5,
spx5_port->phylink_pcs.ops = &sparx5_phylink_pcs_ops;
sparx5->ports[config->portno] = spx5_port;

err = sparx5_port_init(sparx5, spx5_port, &config->conf);
if (err) {
dev_err(sparx5->dev, "port init failed\n");
return err;
}
spx5_port->conf = config->conf;

/* VLAN setup to be added in later patches */
/* VLAN support to be added in later patches */

/* Create a phylink for PHY management. Also handles SFPs */
spx5_port->phylink_config.dev = &spx5_port->ndev->dev;
Expand Down
14 changes: 12 additions & 2 deletions drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "sparx5_main_regs.h"
#include "sparx5_main.h"
#include "sparx5_port.h"

/* The IFH bit position of the first VSTAX bit. This is because the
* VSTAX bit positions in Data sheet is starting from zero.
Expand Down Expand Up @@ -71,6 +72,7 @@ static int sparx5_port_open(struct net_device *ndev)
struct sparx5_port *port = netdev_priv(ndev);
int err = 0;

sparx5_port_enable(port, true);
err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
if (err) {
netdev_err(ndev, "Could not attach to PHY\n");
Expand All @@ -82,7 +84,10 @@ static int sparx5_port_open(struct net_device *ndev)
if (!ndev->phydev) {
/* power up serdes */
port->conf.power_down = false;
err = phy_power_on(port->serdes);
if (port->conf.serdes_reset)
err = sparx5_serdes_set(port->sparx5, port, &port->conf);
else
err = phy_power_on(port->serdes);
if (err)
netdev_err(ndev, "%s failed\n", __func__);
}
Expand All @@ -95,12 +100,17 @@ static int sparx5_port_stop(struct net_device *ndev)
struct sparx5_port *port = netdev_priv(ndev);
int err = 0;

sparx5_port_enable(port, false);
phylink_stop(port->phylink);
phylink_disconnect_phy(port->phylink);

if (!ndev->phydev) {
/* power down serdes */
port->conf.power_down = true;
err = phy_power_off(port->serdes);
if (port->conf.serdes_reset)
err = sparx5_serdes_set(port->sparx5, port, &port->conf);
else
err = phy_power_off(port->serdes);
if (err)
netdev_err(ndev, "%s failed\n", __func__);
}
Expand Down
27 changes: 19 additions & 8 deletions drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "sparx5_main_regs.h"
#include "sparx5_main.h"
#include "sparx5_port.h"

static bool port_conf_has_changed(struct sparx5_port_config *a, struct sparx5_port_config *b)
{
Expand Down Expand Up @@ -115,14 +116,18 @@ static void sparx5_phylink_mac_link_up(struct phylink_config *config,
{
struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
struct sparx5_port_config conf;
int err;

conf = port->conf;
conf.duplex = duplex;
conf.pause = 0;
conf.pause |= tx_pause ? MLO_PAUSE_TX : 0;
conf.pause |= rx_pause ? MLO_PAUSE_RX : 0;
conf.speed = speed;
/* Port configuration to be added later */
/* Configure the port to speed/duplex/pause */
err = sparx5_port_config(port->sparx5, port, &conf);
if (err)
netdev_err(port->ndev, "port config failed: %d\n", err);
}

static void sparx5_phylink_mac_link_down(struct phylink_config *config,
Expand All @@ -140,12 +145,15 @@ static struct sparx5_port *sparx5_pcs_to_port(struct phylink_pcs *pcs)
static void sparx5_pcs_get_state(struct phylink_pcs *pcs,
struct phylink_link_state *state)
{
/* Getting port status to be added later, just defaults now */
state->link = true;
state->an_complete = true;
state->speed = SPEED_1000;
state->duplex = true;
state->pause = MLO_PAUSE_AN;
struct sparx5_port *port = sparx5_pcs_to_port(pcs);
struct sparx5_port_status status;

sparx5_get_port_status(port->sparx5, port, &status);
state->link = status.link && !status.link_down;
state->an_complete = status.an_complete;
state->speed = status.speed;
state->duplex = status.duplex;
state->pause = status.pause;
}

static int sparx5_pcs_config(struct phylink_pcs *pcs,
Expand Down Expand Up @@ -176,7 +184,10 @@ static int sparx5_pcs_config(struct phylink_pcs *pcs,
}
if (!port_conf_has_changed(&port->conf, &conf))
return ret;
/* PCS configuration added later */
/* Enable the PCS matching this interface type */
ret = sparx5_port_pcs_set(port->sparx5, port, &conf);
if (ret)
netdev_err(port->ndev, "port PCS config failed: %d\n", ret);
return ret;
}

Expand Down
Loading

0 comments on commit 946e7fd

Please sign in to comment.