Skip to content

Commit 925f3ec

Browse files
committed
Merge branch 'mv88e6xxx-serdes-on-mv88e6321'
Fidan Aliyeva says: ==================== mv88e6xxx: SERDES on mv88e6321 This patch series add code support to be able to use SERDES feature of mv88e6321 version of Marvel mv88e6xxx series. mv88e6321 has 2 ports to support high speed SERDES but the support is lacking in the driver. mv88e6321 version has a similar architecture to mv88e6352 version making it possible to reuse its pcs functions. That's why the patch series consist of 2 parts: 1. Refactor the serdes functions and pcs_init of mv88e6352 to be more generic (patches 1-2). 2. Add the SERDES support for mv88e6321 reusing 6352's pcs functions The final code has been tested on mv88e6321 ethernet device directly by ip ping tests, performance tests and also verifying the switch's expected register values. Referred document: 88E6321/88E6320 Functional Specification ==================== Link: https://patch.msgid.link/20260528210310.1365858-1-fidan.aliyeva.ext@ericsson.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 046c89c + f456c9b commit 925f3ec

4 files changed

Lines changed: 74 additions & 30 deletions

File tree

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4672,6 +4672,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
46724672
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
46734673
.stu_getnext = mv88e6352_g1_stu_getnext,
46744674
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4675+
.serdes_get_lane = mv88e6352_serdes_get_lane,
46754676
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
46764677
.serdes_get_regs = mv88e6352_serdes_get_regs,
46774678
.gpio_ops = &mv88e6352_gpio_ops,
@@ -4775,6 +4776,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
47754776
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
47764777
.stu_getnext = mv88e6352_g1_stu_getnext,
47774778
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4779+
.serdes_get_lane = mv88e6352_serdes_get_lane,
47784780
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
47794781
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
47804782
.serdes_get_regs = mv88e6352_serdes_get_regs,
@@ -5047,6 +5049,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
50475049
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
50485050
.stu_getnext = mv88e6352_g1_stu_getnext,
50495051
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5052+
.serdes_get_lane = mv88e6352_serdes_get_lane,
50505053
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
50515054
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
50525055
.serdes_get_regs = mv88e6352_serdes_get_regs,
@@ -5269,10 +5272,14 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
52695272
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
52705273
.stu_getnext = mv88e6352_g1_stu_getnext,
52715274
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5275+
.serdes_get_lane = mv88e6321_serdes_get_lane,
5276+
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
5277+
.serdes_get_regs = mv88e6352_serdes_get_regs,
52725278
.gpio_ops = &mv88e6352_gpio_ops,
52735279
.avb_ops = &mv88e6352_avb_ops,
52745280
.ptp_ops = &mv88e6352_ptp_ops,
52755281
.phylink_get_caps = mv88e632x_phylink_get_caps,
5282+
.pcs_ops = &mv88e6352_pcs_ops,
52765283
};
52775284

52785285
static const struct mv88e6xxx_ops mv88e6341_ops = {
@@ -5487,6 +5494,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
54875494
.gpio_ops = &mv88e6352_gpio_ops,
54885495
.avb_ops = &mv88e6352_avb_ops,
54895496
.ptp_ops = &mv88e6352_ptp_ops,
5497+
.serdes_get_lane = mv88e6352_serdes_get_lane,
54905498
.serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
54915499
.serdes_get_strings = mv88e6352_serdes_get_strings,
54925500
.serdes_get_stats = mv88e6352_serdes_get_stats,

drivers/net/dsa/mv88e6xxx/pcs-6352.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,17 +324,17 @@ static int mv88e6352_pcs_init(struct mv88e6xxx_chip *chip, int port)
324324
struct mii_bus *bus;
325325
struct device *dev;
326326
unsigned int irq;
327-
int err;
327+
int lane, err;
328328

329-
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
330-
if (err <= 0)
331-
return err;
329+
lane = mv88e6xxx_serdes_get_lane(chip, port);
330+
if (lane < 0)
331+
return 0;
332332

333333
irq = mv88e6xxx_serdes_irq_mapping(chip, port);
334334
bus = mv88e6xxx_default_mdio_bus(chip);
335335
dev = chip->dev;
336336

337-
mpcs = marvell_c22_pcs_alloc(dev, bus, MV88E6352_ADDR_SERDES);
337+
mpcs = marvell_c22_pcs_alloc(dev, bus, lane);
338338
if (!mpcs)
339339
return -ENOMEM;
340340

drivers/net/dsa/mv88e6xxx/serdes.c

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
#include "port.h"
1818
#include "serdes.h"
1919

20-
static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
21-
u16 *val)
20+
static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int lane,
21+
int reg, u16 *val)
2222
{
23-
return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
23+
return mv88e6xxx_phy_page_read(chip, lane,
2424
MV88E6352_SERDES_PAGE_FIBER,
2525
reg, val);
2626
}
@@ -102,6 +102,17 @@ int mv88e6xxx_pcs_decode_state(struct device *dev, u16 bmsr, u16 lpa,
102102
return 0;
103103
}
104104

105+
int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
106+
{
107+
int has_serdes;
108+
109+
has_serdes = mv88e6352_g2_scratch_port_has_serdes(chip, port);
110+
if (has_serdes == 0)
111+
return -ENODEV;
112+
113+
return MV88E6352_ADDR_SERDES;
114+
}
115+
105116
struct mv88e6352_serdes_hw_stat {
106117
char string[ETH_GSTRING_LEN];
107118
int sizeof_stat;
@@ -115,11 +126,11 @@ static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
115126

116127
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
117128
{
118-
int err;
129+
int lane = -ENODEV;
119130

120-
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
121-
if (err <= 0)
122-
return err;
131+
lane = mv88e6xxx_serdes_get_lane(chip, port);
132+
if (lane < 0)
133+
return 0;
123134

124135
return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
125136
}
@@ -128,11 +139,12 @@ int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port,
128139
uint8_t **data)
129140
{
130141
struct mv88e6352_serdes_hw_stat *stat;
131-
int err, i;
142+
int lane = -ENODEV;
143+
int i;
132144

133-
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
134-
if (err <= 0)
135-
return err;
145+
lane = mv88e6xxx_serdes_get_lane(chip, port);
146+
if (lane < 0)
147+
return 0;
136148

137149
for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
138150
stat = &mv88e6352_serdes_hw_stats[i];
@@ -141,14 +153,14 @@ int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port,
141153
return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
142154
}
143155

144-
static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
156+
static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
145157
struct mv88e6352_serdes_hw_stat *stat)
146158
{
147159
u64 val = 0;
148160
u16 reg;
149161
int err;
150162

151-
err = mv88e6352_serdes_read(chip, stat->reg, &reg);
163+
err = mv88e6352_serdes_read(chip, lane, stat->reg, &reg);
152164
if (err) {
153165
dev_err(chip->dev, "failed to read statistic\n");
154166
return 0;
@@ -157,7 +169,7 @@ static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
157169
val = reg;
158170

159171
if (stat->sizeof_stat == 32) {
160-
err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
172+
err = mv88e6352_serdes_read(chip, lane, stat->reg + 1, &reg);
161173
if (err) {
162174
dev_err(chip->dev, "failed to read statistic\n");
163175
return 0;
@@ -173,19 +185,20 @@ size_t mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
173185
{
174186
struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
175187
struct mv88e6352_serdes_hw_stat *stat;
176-
int i, err;
188+
int lane = -ENODEV;
177189
u64 value;
190+
int i;
178191

179-
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
180-
if (err <= 0)
192+
lane = mv88e6xxx_serdes_get_lane(chip, port);
193+
if (lane < 0)
181194
return 0;
182195

183196
BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
184197
ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
185198

186199
for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
187200
stat = &mv88e6352_serdes_hw_stats[i];
188-
value = mv88e6352_serdes_get_stat(chip, stat);
201+
value = mv88e6352_serdes_get_stat(chip, lane, stat);
189202
mv88e6xxx_port->serdes_stats[i] += value;
190203
data[i] = mv88e6xxx_port->serdes_stats[i];
191204
}
@@ -200,33 +213,52 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
200213

201214
int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
202215
{
203-
int err;
216+
int lane = -ENODEV;
204217

205-
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
206-
if (err <= 0)
207-
return err;
218+
lane = mv88e6xxx_serdes_get_lane(chip, port);
219+
if (lane < 0)
220+
return 0;
208221

209222
return 32 * sizeof(u16);
210223
}
211224

212225
void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
213226
{
227+
int lane = -ENODEV;
214228
u16 *p = _p;
215229
u16 reg;
216230
int err;
217231
int i;
218232

219-
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
220-
if (err <= 0)
233+
lane = mv88e6xxx_serdes_get_lane(chip, port);
234+
if (lane < 0)
221235
return;
222236

223237
for (i = 0 ; i < 32; i++) {
224-
err = mv88e6352_serdes_read(chip, i, &reg);
238+
err = mv88e6352_serdes_read(chip, lane, i, &reg);
225239
if (!err)
226240
p[i] = reg;
227241
}
228242
}
229243

244+
int mv88e6321_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
245+
{
246+
int lane = -ENODEV;
247+
u8 cmode;
248+
249+
if (port != 0 && port != 1)
250+
return lane;
251+
252+
cmode = chip->ports[port].cmode;
253+
254+
if (cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX ||
255+
cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
256+
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)
257+
lane = port + MV88E6321_PORT0_LANE;
258+
259+
return lane;
260+
}
261+
230262
int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
231263
{
232264
u8 cmode = chip->ports[port].cmode;

drivers/net/dsa/mv88e6xxx/serdes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
struct phylink_link_state;
1616

17+
#define MV88E6321_PORT0_LANE 0x0c
18+
1719
#define MV88E6352_ADDR_SERDES 0x0f
1820
#define MV88E6352_SERDES_PAGE_FIBER 0x01
1921
#define MV88E6352_SERDES_IRQ 0x0b
@@ -114,7 +116,9 @@ struct phylink_link_state;
114116
int mv88e6xxx_pcs_decode_state(struct device *dev, u16 bmsr, u16 lpa,
115117
u16 status, struct phylink_link_state *state);
116118

119+
int mv88e6321_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
117120
int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
121+
int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
118122
int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
119123
int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
120124
int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);

0 commit comments

Comments
 (0)