Skip to content

Commit e31e67f

Browse files
Hans-Frieder Vogtkuba-moo
authored andcommitted
net: phy: aquantia: add essential functions to aqr105 driver
This patch makes functions that were provided for aqr107 applicable to aqr105, or replaces generic functions with specific ones. Since the aqr105 was introduced before NBASE-T was defined (or 802.3bz), there are a number of vendor specific registers involved in the definition of the advertisement, in auto-negotiation and in the setting of the speed. The functions have been written following the downstream driver for TN4010 cards with aqr105 PHY, and use code from aqr107 functions wherever it seemed to make sense. Signed-off-by: Hans-Frieder Vogt <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5f27092 commit e31e67f

File tree

1 file changed

+237
-2
lines changed

1 file changed

+237
-2
lines changed

drivers/net/phy/aquantia/aquantia_main.c

Lines changed: 237 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)
5151
#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)
5252
#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
53+
#define MDIO_AN_VEND_PROV_EXC_PHYID_INFO BIT(6)
5354
#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
5455
#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
5556
#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
@@ -333,6 +334,238 @@ static int aqr_read_status(struct phy_device *phydev)
333334
return genphy_c45_read_status(phydev);
334335
}
335336

337+
static int aqr105_get_features(struct phy_device *phydev)
338+
{
339+
int ret;
340+
341+
/* Normal feature discovery */
342+
ret = genphy_c45_pma_read_abilities(phydev);
343+
if (ret)
344+
return ret;
345+
346+
/* The AQR105 PHY misses to indicate the 2.5G and 5G modes, so add them
347+
* here
348+
*/
349+
linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
350+
phydev->supported);
351+
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
352+
phydev->supported);
353+
354+
/* The AQR105 PHY suppports both RJ45 and SFP+ interfaces */
355+
linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, phydev->supported);
356+
linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
357+
358+
return 0;
359+
}
360+
361+
static int aqr105_setup_forced(struct phy_device *phydev)
362+
{
363+
int vend = MDIO_AN_VEND_PROV_EXC_PHYID_INFO;
364+
int ctrl10 = 0;
365+
int adv = ADVERTISE_CSMA;
366+
int ret;
367+
368+
switch (phydev->speed) {
369+
case SPEED_100:
370+
adv |= ADVERTISE_100FULL;
371+
break;
372+
case SPEED_1000:
373+
adv |= ADVERTISE_NPAGE;
374+
if (phydev->duplex == DUPLEX_FULL)
375+
vend |= MDIO_AN_VEND_PROV_1000BASET_FULL;
376+
else
377+
vend |= MDIO_AN_VEND_PROV_1000BASET_HALF;
378+
break;
379+
case SPEED_2500:
380+
adv |= (ADVERTISE_NPAGE | ADVERTISE_RESV);
381+
vend |= MDIO_AN_VEND_PROV_2500BASET_FULL;
382+
break;
383+
case SPEED_5000:
384+
adv |= (ADVERTISE_NPAGE | ADVERTISE_RESV);
385+
vend |= MDIO_AN_VEND_PROV_5000BASET_FULL;
386+
break;
387+
case SPEED_10000:
388+
adv |= (ADVERTISE_NPAGE | ADVERTISE_RESV);
389+
ctrl10 |= MDIO_AN_10GBT_CTRL_ADV10G;
390+
break;
391+
default:
392+
return -EINVAL;
393+
}
394+
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, adv);
395+
if (ret < 0)
396+
return ret;
397+
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, vend);
398+
if (ret < 0)
399+
return ret;
400+
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, ctrl10);
401+
if (ret < 0)
402+
return ret;
403+
404+
/* set by vendor driver, but should be on by default */
405+
ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1,
406+
MDIO_AN_CTRL1_XNP);
407+
if (ret < 0)
408+
return ret;
409+
410+
return genphy_c45_an_disable_aneg(phydev);
411+
}
412+
413+
static int aqr105_config_aneg(struct phy_device *phydev)
414+
{
415+
bool changed = false;
416+
u16 reg;
417+
int ret;
418+
419+
ret = aqr_set_mdix(phydev, phydev->mdix_ctrl);
420+
if (ret < 0)
421+
return ret;
422+
if (ret > 0)
423+
changed = true;
424+
425+
if (phydev->autoneg == AUTONEG_DISABLE)
426+
return aqr105_setup_forced(phydev);
427+
428+
ret = genphy_c45_an_config_aneg(phydev);
429+
if (ret < 0)
430+
return ret;
431+
if (ret > 0)
432+
changed = true;
433+
434+
/* Clause 45 has no standardized support for 1000BaseT, therefore
435+
* use vendor registers for this mode.
436+
*/
437+
reg = 0;
438+
if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
439+
phydev->advertising))
440+
reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
441+
442+
if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
443+
phydev->advertising))
444+
reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
445+
446+
/* Handle the case when the 2.5G and 5G speeds are not advertised */
447+
if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
448+
phydev->advertising))
449+
reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;
450+
451+
if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
452+
phydev->advertising))
453+
reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;
454+
455+
ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
456+
MDIO_AN_VEND_PROV_1000BASET_HALF |
457+
MDIO_AN_VEND_PROV_1000BASET_FULL |
458+
MDIO_AN_VEND_PROV_2500BASET_FULL |
459+
MDIO_AN_VEND_PROV_5000BASET_FULL, reg);
460+
if (ret < 0)
461+
return ret;
462+
if (ret > 0)
463+
changed = true;
464+
465+
return genphy_c45_check_and_restart_aneg(phydev, changed);
466+
}
467+
468+
static int aqr105_read_rate(struct phy_device *phydev)
469+
{
470+
int val;
471+
472+
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
473+
if (val < 0)
474+
return val;
475+
476+
if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
477+
phydev->duplex = DUPLEX_FULL;
478+
else
479+
phydev->duplex = DUPLEX_HALF;
480+
481+
switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
482+
case MDIO_AN_TX_VEND_STATUS1_10BASET:
483+
phydev->speed = SPEED_10;
484+
break;
485+
case MDIO_AN_TX_VEND_STATUS1_100BASETX:
486+
phydev->speed = SPEED_100;
487+
break;
488+
case MDIO_AN_TX_VEND_STATUS1_1000BASET:
489+
phydev->speed = SPEED_1000;
490+
break;
491+
case MDIO_AN_TX_VEND_STATUS1_2500BASET:
492+
phydev->speed = SPEED_2500;
493+
break;
494+
case MDIO_AN_TX_VEND_STATUS1_5000BASET:
495+
phydev->speed = SPEED_5000;
496+
break;
497+
case MDIO_AN_TX_VEND_STATUS1_10GBASET:
498+
phydev->speed = SPEED_10000;
499+
break;
500+
default:
501+
phydev->speed = SPEED_UNKNOWN;
502+
}
503+
504+
return 0;
505+
}
506+
507+
static int aqr105_read_status(struct phy_device *phydev)
508+
{
509+
int ret;
510+
int val;
511+
512+
ret = aqr_read_status(phydev);
513+
if (ret)
514+
return ret;
515+
516+
if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
517+
return 0;
518+
519+
/**
520+
* The status register is not immediately correct on line side link up.
521+
* Poll periodically until it reflects the correct ON state.
522+
* Only return fail for read error, timeout defaults to OFF state.
523+
*/
524+
ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PHYXS,
525+
MDIO_PHYXS_VEND_IF_STATUS, val,
526+
(FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val) !=
527+
MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF),
528+
AQR107_OP_IN_PROG_SLEEP,
529+
AQR107_OP_IN_PROG_TIMEOUT, false);
530+
if (ret && ret != -ETIMEDOUT)
531+
return ret;
532+
533+
switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
534+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
535+
phydev->interface = PHY_INTERFACE_MODE_10GKR;
536+
break;
537+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:
538+
phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;
539+
break;
540+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
541+
phydev->interface = PHY_INTERFACE_MODE_10GBASER;
542+
break;
543+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
544+
phydev->interface = PHY_INTERFACE_MODE_USXGMII;
545+
break;
546+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:
547+
phydev->interface = PHY_INTERFACE_MODE_XAUI;
548+
break;
549+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
550+
phydev->interface = PHY_INTERFACE_MODE_SGMII;
551+
break;
552+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:
553+
phydev->interface = PHY_INTERFACE_MODE_RXAUI;
554+
break;
555+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
556+
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
557+
break;
558+
case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF:
559+
default:
560+
phydev->link = false;
561+
phydev->interface = PHY_INTERFACE_MODE_NA;
562+
break;
563+
}
564+
565+
/* Read rate from vendor register */
566+
return aqr105_read_rate(phydev);
567+
}
568+
336569
static int aqr107_read_rate(struct phy_device *phydev)
337570
{
338571
u32 config_reg;
@@ -911,11 +1144,13 @@ static struct phy_driver aqr_driver[] = {
9111144
{
9121145
PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
9131146
.name = "Aquantia AQR105",
914-
.config_aneg = aqr_config_aneg,
1147+
.get_features = aqr105_get_features,
9151148
.probe = aqr107_probe,
1149+
.config_init = aqr107_config_init,
1150+
.config_aneg = aqr105_config_aneg,
9161151
.config_intr = aqr_config_intr,
9171152
.handle_interrupt = aqr_handle_interrupt,
918-
.read_status = aqr_read_status,
1153+
.read_status = aqr105_read_status,
9191154
.suspend = aqr107_suspend,
9201155
.resume = aqr107_resume,
9211156
},

0 commit comments

Comments
 (0)