Skip to content

Commit 0f4dc19

Browse files
jonasjelonekrobimarko
authored andcommitted
realtek: pcs: adjust autoneg to fix RTL931x issue
The autonegotiation setting might not have been working for RTL931x the whole time. While there weren't any reports about issues so far, these issues might just have been hidden behind other circumstances. While all other variants of the Otto family have the corresponding settings in [page 0x2 register 0x0] of a SerDes, RTL931x has a special Front/Background SerDes architecture and actually moved the autonegotiation settings to a digital Background SerDes. Since we use a special mapping to have a consistent view on these Background SerDes, RTL931x needs to write the settings to another page. To fix this, adjust the autonegotiation setting for all variants. The generic implementation is kept but uses per-variant register field definitions. Those are added for all variants here, with the differing page for RTL931x. Another static data definition is renamed since it conflicts with a change introduced here. Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com> Link: openwrt/openwrt#22013 Signed-off-by: Robert Marko <robimarko@gmail.com>
1 parent fb0bc84 commit 0f4dc19

File tree

1 file changed

+51
-27
lines changed

1 file changed

+51
-27
lines changed

target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ static int rtpcs_sds_read_field(struct rtpcs_serdes *sds, const struct rtpcs_sds
334334
return sds->ops->read(sds, field->page, field->reg, field->msb, field->lsb);
335335
}
336336

337-
__maybe_unused
338337
static int rtpcs_sds_write_field(struct rtpcs_serdes *sds, const struct rtpcs_sds_reg_field *field,
339338
u16 value)
340339
{
@@ -362,6 +361,7 @@ static int rtpcs_sds_xsg_write(struct rtpcs_serdes *sds, int page, int regnum, u
362361

363362
/* Other helpers */
364363

364+
__maybe_unused
365365
static int rtpcs_sds_modify(struct rtpcs_serdes *sds, int page, int regnum,
366366
u16 mask, u16 set)
367367
{
@@ -371,15 +371,6 @@ static int rtpcs_sds_modify(struct rtpcs_serdes *sds, int page, int regnum,
371371
mmd_regnum, mask, set);
372372
}
373373

374-
static int rtpcs_sds_modify_changed(struct rtpcs_serdes *sds, int page, int regnum,
375-
u16 mask, u16 set)
376-
{
377-
int mmd_regnum = rtpcs_sds_to_mmd(page, regnum);
378-
379-
return mdiobus_c45_modify_changed(sds->ctrl->bus, sds->id, MDIO_MMD_VEND1,
380-
mmd_regnum, mask, set);
381-
}
382-
383374
static struct rtpcs_serdes *rtpcs_sds_get_even(struct rtpcs_serdes *sds)
384375
{
385376
u32 even_sds = sds->id & ~1;
@@ -478,8 +469,8 @@ static int rtpcs_sds_determine_hw_mode(struct rtpcs_serdes *sds,
478469
static int rtpcs_generic_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode,
479470
const unsigned long *advertising)
480471
{
481-
u16 bmcr, adv;
482-
bool changed = 0;
472+
u16 bmcr, adv, adv_old;
473+
bool changed = false;
483474
int ret;
484475

485476
if ((sds->hw_mode == RTPCS_SDS_MODE_1000BASEX) ||
@@ -492,16 +483,21 @@ static int rtpcs_generic_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int
492483
advertising))
493484
adv |= ADVERTISE_1000XPSE_ASYM;
494485

495-
ret = rtpcs_sds_modify_changed(sds, 0x2, MII_ADVERTISE,
496-
0xffff, adv);
497-
if (ret < 0)
498-
return ret;
499-
changed = ret;
486+
adv_old = rtpcs_sds_read_field(sds, &sds->regs->an_advertise);
487+
if (adv_old < 0)
488+
return adv_old;
489+
490+
if (adv != adv_old) {
491+
changed = true;
492+
ret = rtpcs_sds_write_field(sds, &sds->regs->an_advertise, adv);
493+
if (ret < 0)
494+
return ret;
495+
}
500496
}
501497

502-
bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : 0;
498+
bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? 1 : 0;
503499

504-
ret = rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANENABLE, bmcr);
500+
ret = rtpcs_sds_write_field(sds, &sds->regs->an_enable, bmcr);
505501
if (ret < 0)
506502
return ret;
507503

@@ -510,7 +506,7 @@ static int rtpcs_generic_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int
510506

511507
static void rtpcs_generic_sds_restart_autoneg(struct rtpcs_serdes *sds)
512508
{
513-
rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
509+
rtpcs_sds_write_field(sds, &sds->regs->an_restart, 0x1);
514510
}
515511

516512
/* Variant-specific functions */
@@ -1143,13 +1139,13 @@ static int rtpcs_930x_sds_op_xsg_write(struct rtpcs_serdes *sds, int page, int r
11431139
value);
11441140
}
11451141

1146-
static const u16 rtpcs_930x_sds_regs[] = {
1142+
static const u16 rtpcs_930x_sds_mode_regs[] = {
11471143
0x0194, 0x0194, 0x0194, 0x0194, /* SDS_MODE_SEL_0 */
11481144
0x02a0, 0x02a0, 0x02a0, 0x02a0, /* SDS_MODE_SEL_1 */
11491145
0x02a4, 0x02a4, /* SDS_MODE_SEL_2 */
11501146
0x0198, 0x0198 /* SDS_MODE_SEL_3 */
11511147
};
1152-
static const u8 rtpcs_930x_sds_lsb[] = { 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 0, 6 };
1148+
static const u8 rtpcs_930x_sds_mode_lsb[] = { 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 0, 6 };
11531149

11541150
static const u16 rtpcs_930x_sds_submode_regs[] = {
11551151
0x1cc, 0x1cc, /* SDS_SUBMODE_CTRL0 */
@@ -1163,11 +1159,11 @@ static int __rtpcs_930x_sds_get_mac_mode(struct rtpcs_serdes *sds)
11631159
u8 sds_id = sds->id;
11641160
int mode_val, ret;
11651161

1166-
ret = regmap_read(sds->ctrl->map, rtpcs_930x_sds_regs[sds_id], &mode_val);
1162+
ret = regmap_read(sds->ctrl->map, rtpcs_930x_sds_mode_regs[sds_id], &mode_val);
11671163
if (ret < 0)
11681164
return ret;
11691165

1170-
mode_val >>= rtpcs_930x_sds_lsb[sds_id];
1166+
mode_val >>= rtpcs_930x_sds_mode_lsb[sds_id];
11711167
return mode_val & RTPCS_930X_SDS_MASK;
11721168
}
11731169

@@ -1176,9 +1172,9 @@ static int __rtpcs_930x_sds_set_mac_mode(struct rtpcs_serdes *sds, u32 mode)
11761172
u8 sds_id = sds->id;
11771173
int ret;
11781174

1179-
ret = regmap_write_bits(sds->ctrl->map, rtpcs_930x_sds_regs[sds_id],
1180-
RTPCS_930X_SDS_MASK << rtpcs_930x_sds_lsb[sds_id],
1181-
mode << rtpcs_930x_sds_lsb[sds_id]);
1175+
ret = regmap_write_bits(sds->ctrl->map, rtpcs_930x_sds_mode_regs[sds_id],
1176+
RTPCS_930X_SDS_MASK << rtpcs_930x_sds_mode_lsb[sds_id],
1177+
mode << rtpcs_930x_sds_mode_lsb[sds_id]);
11821178
mdelay(10);
11831179

11841180
return ret;
@@ -4089,6 +4085,12 @@ static const struct rtpcs_serdes_ops rtpcs_838x_sds_ops = {
40894085
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
40904086
};
40914087

4088+
static const struct rtpcs_sds_regs rtpcs_838x_sds_regs = {
4089+
.an_enable = { .page = 0x2, .reg = MII_BMCR, .msb = 12, .lsb = 12 },
4090+
.an_restart = { .page = 0x2, .reg = MII_BMCR, .msb = 9, .lsb = 9 },
4091+
.an_advertise = { .page = 0x2, .reg = MII_ADVERTISE, .msb = 15, .lsb = 0 },
4092+
};
4093+
40924094
static const struct rtpcs_config rtpcs_838x_cfg = {
40934095
.cpu_port = RTPCS_838X_CPU_PORT,
40944096
.mac_link_dup_sts = RTPCS_838X_MAC_LINK_DUP_STS,
@@ -4100,6 +4102,7 @@ static const struct rtpcs_config rtpcs_838x_cfg = {
41004102
.serdes_count = RTPCS_838X_SERDES_CNT,
41014103
.pcs_ops = &rtpcs_838x_pcs_ops,
41024104
.sds_ops = &rtpcs_838x_sds_ops,
4105+
.sds_regs = &rtpcs_838x_sds_regs,
41034106
.init_serdes_common = rtpcs_838x_init_serdes_common,
41044107
.setup_serdes = rtpcs_838x_setup_serdes,
41054108
};
@@ -4117,6 +4120,12 @@ static const struct rtpcs_serdes_ops rtpcs_839x_sds_ops = {
41174120
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
41184121
};
41194122

4123+
static const struct rtpcs_sds_regs rtpcs_839x_sds_regs = {
4124+
.an_enable = { .page = 0x2, .reg = MII_BMCR, .msb = 12, .lsb = 12 },
4125+
.an_restart = { .page = 0x2, .reg = MII_BMCR, .msb = 9, .lsb = 9 },
4126+
.an_advertise = { .page = 0x2, .reg = MII_ADVERTISE, .msb = 15, .lsb = 0 },
4127+
};
4128+
41204129
static const struct rtpcs_config rtpcs_839x_cfg = {
41214130
.cpu_port = RTPCS_839X_CPU_PORT,
41224131
.mac_link_dup_sts = RTPCS_839X_MAC_LINK_DUP_STS,
@@ -4128,6 +4137,7 @@ static const struct rtpcs_config rtpcs_839x_cfg = {
41284137
.serdes_count = RTPCS_839X_SERDES_CNT,
41294138
.pcs_ops = &rtpcs_839x_pcs_ops,
41304139
.sds_ops = &rtpcs_839x_sds_ops,
4140+
.sds_regs = &rtpcs_839x_sds_regs,
41314141
.init_serdes_common = rtpcs_839x_init_serdes_common,
41324142
.setup_serdes = rtpcs_839x_setup_serdes,
41334143
};
@@ -4146,6 +4156,12 @@ static const struct rtpcs_serdes_ops rtpcs_930x_sds_ops = {
41464156
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
41474157
};
41484158

4159+
static const struct rtpcs_sds_regs rtpcs_930x_sds_regs = {
4160+
.an_enable = { .page = 0x2, .reg = MII_BMCR, .msb = 12, .lsb = 12 },
4161+
.an_restart = { .page = 0x2, .reg = MII_BMCR, .msb = 9, .lsb = 9 },
4162+
.an_advertise = { .page = 0x2, .reg = MII_ADVERTISE, .msb = 15, .lsb = 0 },
4163+
};
4164+
41494165
static const struct rtpcs_config rtpcs_930x_cfg = {
41504166
.cpu_port = RTPCS_930X_CPU_PORT,
41514167
.mac_link_dup_sts = RTPCS_930X_MAC_LINK_DUP_STS,
@@ -4157,6 +4173,7 @@ static const struct rtpcs_config rtpcs_930x_cfg = {
41574173
.serdes_count = RTPCS_930X_SERDES_CNT,
41584174
.pcs_ops = &rtpcs_930x_pcs_ops,
41594175
.sds_ops = &rtpcs_930x_sds_ops,
4176+
.sds_regs = &rtpcs_930x_sds_regs,
41604177
.init_serdes_common = rtpcs_93xx_init_serdes_common,
41614178
.setup_serdes = rtpcs_930x_setup_serdes,
41624179
};
@@ -4175,6 +4192,12 @@ static const struct rtpcs_serdes_ops rtpcs_931x_sds_ops = {
41754192
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
41764193
};
41774194

4195+
static const struct rtpcs_sds_regs rtpcs_931x_sds_regs = {
4196+
.an_enable = { .page = 0x42, .reg = MII_BMCR, .msb = 12, .lsb = 12 },
4197+
.an_restart = { .page = 0x42, .reg = MII_BMCR, .msb = 9, .lsb = 9 },
4198+
.an_advertise = { .page = 0x42, .reg = MII_ADVERTISE, .msb = 15, .lsb = 0 },
4199+
};
4200+
41784201
static const struct rtpcs_config rtpcs_931x_cfg = {
41794202
.cpu_port = RTPCS_931X_CPU_PORT,
41804203
.mac_link_dup_sts = RTPCS_931X_MAC_LINK_DUP_STS,
@@ -4186,6 +4209,7 @@ static const struct rtpcs_config rtpcs_931x_cfg = {
41864209
.serdes_count = RTPCS_931X_SERDES_CNT,
41874210
.pcs_ops = &rtpcs_931x_pcs_ops,
41884211
.sds_ops = &rtpcs_931x_sds_ops,
4212+
.sds_regs = &rtpcs_931x_sds_regs,
41894213
.init_serdes_common = rtpcs_93xx_init_serdes_common,
41904214
.setup_serdes = rtpcs_931x_setup_serdes,
41914215
};

0 commit comments

Comments
 (0)