Skip to content

Commit 946e7fd

Browse files
steen-hegelund-mchpdavem330
authored andcommitted
net: sparx5: add port module support
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 <[email protected]> Signed-off-by: Bjarni Jonasson <[email protected]> Signed-off-by: Lars Povlsen <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f3cad26 commit 946e7fd

File tree

6 files changed

+1279
-12
lines changed

6 files changed

+1279
-12
lines changed

drivers/net/ethernet/microchip/sparx5/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o
77

88
sparx5-switch-objs := sparx5_main.o sparx5_packet.o \
9-
sparx5_netdev.o sparx5_phylink.o
9+
sparx5_netdev.o sparx5_phylink.o sparx5_port.o

drivers/net/ethernet/microchip/sparx5/sparx5_main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "sparx5_main_regs.h"
2828
#include "sparx5_main.h"
29+
#include "sparx5_port.h"
2930

3031
#define QLIM_WM(fraction) \
3132
((SPX5_BUFFER_MEMORY / SPX5_BUFFER_CELL_SZ - 100) * (fraction) / 100)
@@ -252,6 +253,7 @@ static int sparx5_create_port(struct sparx5 *sparx5,
252253
struct sparx5_port *spx5_port;
253254
struct net_device *ndev;
254255
struct phylink *phylink;
256+
int err;
255257

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

278+
err = sparx5_port_init(sparx5, spx5_port, &config->conf);
279+
if (err) {
280+
dev_err(sparx5->dev, "port init failed\n");
281+
return err;
282+
}
276283
spx5_port->conf = config->conf;
277284

278-
/* VLAN setup to be added in later patches */
285+
/* VLAN support to be added in later patches */
279286

280287
/* Create a phylink for PHY management. Also handles SFPs */
281288
spx5_port->phylink_config.dev = &spx5_port->ndev->dev;

drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "sparx5_main_regs.h"
88
#include "sparx5_main.h"
9+
#include "sparx5_port.h"
910

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

75+
sparx5_port_enable(port, true);
7476
err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
7577
if (err) {
7678
netdev_err(ndev, "Could not attach to PHY\n");
@@ -82,7 +84,10 @@ static int sparx5_port_open(struct net_device *ndev)
8284
if (!ndev->phydev) {
8385
/* power up serdes */
8486
port->conf.power_down = false;
85-
err = phy_power_on(port->serdes);
87+
if (port->conf.serdes_reset)
88+
err = sparx5_serdes_set(port->sparx5, port, &port->conf);
89+
else
90+
err = phy_power_on(port->serdes);
8691
if (err)
8792
netdev_err(ndev, "%s failed\n", __func__);
8893
}
@@ -95,12 +100,17 @@ static int sparx5_port_stop(struct net_device *ndev)
95100
struct sparx5_port *port = netdev_priv(ndev);
96101
int err = 0;
97102

103+
sparx5_port_enable(port, false);
98104
phylink_stop(port->phylink);
99105
phylink_disconnect_phy(port->phylink);
100106

101107
if (!ndev->phydev) {
108+
/* power down serdes */
102109
port->conf.power_down = true;
103-
err = phy_power_off(port->serdes);
110+
if (port->conf.serdes_reset)
111+
err = sparx5_serdes_set(port->sparx5, port, &port->conf);
112+
else
113+
err = phy_power_off(port->serdes);
104114
if (err)
105115
netdev_err(ndev, "%s failed\n", __func__);
106116
}

drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "sparx5_main_regs.h"
1414
#include "sparx5_main.h"
15+
#include "sparx5_port.h"
1516

1617
static bool port_conf_has_changed(struct sparx5_port_config *a, struct sparx5_port_config *b)
1718
{
@@ -115,14 +116,18 @@ static void sparx5_phylink_mac_link_up(struct phylink_config *config,
115116
{
116117
struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
117118
struct sparx5_port_config conf;
119+
int err;
118120

119121
conf = port->conf;
120122
conf.duplex = duplex;
121123
conf.pause = 0;
122124
conf.pause |= tx_pause ? MLO_PAUSE_TX : 0;
123125
conf.pause |= rx_pause ? MLO_PAUSE_RX : 0;
124126
conf.speed = speed;
125-
/* Port configuration to be added later */
127+
/* Configure the port to speed/duplex/pause */
128+
err = sparx5_port_config(port->sparx5, port, &conf);
129+
if (err)
130+
netdev_err(port->ndev, "port config failed: %d\n", err);
126131
}
127132

128133
static void sparx5_phylink_mac_link_down(struct phylink_config *config,
@@ -140,12 +145,15 @@ static struct sparx5_port *sparx5_pcs_to_port(struct phylink_pcs *pcs)
140145
static void sparx5_pcs_get_state(struct phylink_pcs *pcs,
141146
struct phylink_link_state *state)
142147
{
143-
/* Getting port status to be added later, just defaults now */
144-
state->link = true;
145-
state->an_complete = true;
146-
state->speed = SPEED_1000;
147-
state->duplex = true;
148-
state->pause = MLO_PAUSE_AN;
148+
struct sparx5_port *port = sparx5_pcs_to_port(pcs);
149+
struct sparx5_port_status status;
150+
151+
sparx5_get_port_status(port->sparx5, port, &status);
152+
state->link = status.link && !status.link_down;
153+
state->an_complete = status.an_complete;
154+
state->speed = status.speed;
155+
state->duplex = status.duplex;
156+
state->pause = status.pause;
149157
}
150158

151159
static int sparx5_pcs_config(struct phylink_pcs *pcs,
@@ -176,7 +184,10 @@ static int sparx5_pcs_config(struct phylink_pcs *pcs,
176184
}
177185
if (!port_conf_has_changed(&port->conf, &conf))
178186
return ret;
179-
/* PCS configuration added later */
187+
/* Enable the PCS matching this interface type */
188+
ret = sparx5_port_pcs_set(port->sparx5, port, &conf);
189+
if (ret)
190+
netdev_err(port->ndev, "port PCS config failed: %d\n", ret);
180191
return ret;
181192
}
182193

0 commit comments

Comments
 (0)