Commit 217b953a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-phy-bcm5481x-add-support-for-broadr-reach-mode'

Kamil Horák says:

====================
net: phy: bcm5481x: add support for BroadR-Reach mode

PATCH 1 - Add the 10baseT1BRR_Full link mode

PATCH 2 - Add the definitions of LRE registers, necessary to use
   BroadR-Reach modes on the BCM5481x PHY

PATCH 3 - Add brr-mode flag to switch between IEEE802.3 and BroadR-Reach

PATCH 4 - Implementation of the BroadR-Reach modes for the Broadcom
   PHYs
====================

Link: https://patch.msgid.link/20240712150709.3134474-1-kamilh@axis.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d944c27a 03ab6c24
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -93,6 +93,14 @@ properties:
      the turn around line low at end of the control phase of the
      MDIO transaction.

  brr-mode:
    $ref: /schemas/types.yaml#/definitions/flag
    description:
      If set, indicates the network cable interface is an alternative one as
      defined in the BroadR-Reach link mode specification under 1BR-100 and
      1BR-10 names. The PHY must be configured to operate in BroadR-Reach mode
      by software.

  clocks:
    maxItems: 1
    description:
+115 −0
Original line number Diff line number Diff line
@@ -794,6 +794,49 @@ static int _bcm_phy_cable_test_get_status(struct phy_device *phydev,
	return ret;
}

static int bcm_setup_lre_forced(struct phy_device *phydev)
{
	u16 ctl = 0;

	phydev->pause = 0;
	phydev->asym_pause = 0;

	if (phydev->speed == SPEED_100)
		ctl |= LRECR_SPEED100;

	if (phydev->duplex != DUPLEX_FULL)
		return -EOPNOTSUPP;

	return phy_modify(phydev, MII_BCM54XX_LRECR, LRECR_SPEED100, ctl);
}

/**
 * bcm_linkmode_adv_to_lre_adv_t - translate linkmode advertisement to LDS
 * @advertising: the linkmode advertisement settings
 * Return: LDS Auto-Negotiation Advertised Ability register value
 *
 * A small helper function that translates linkmode advertisement
 * settings to phy LDS autonegotiation advertisements for the
 * MII_BCM54XX_LREANAA register of Broadcom PHYs capable of LDS
 */
static u32 bcm_linkmode_adv_to_lre_adv_t(unsigned long *advertising)
{
	u32 result = 0;

	if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
			      advertising))
		result |= LREANAA_10_1PAIR;
	if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
			      advertising))
		result |= LREANAA_100_1PAIR;
	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising))
		result |= LRELPA_PAUSE;
	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising))
		result |= LRELPA_PAUSE_ASYM;

	return result;
}

int bcm_phy_cable_test_start(struct phy_device *phydev)
{
	return _bcm_phy_cable_test_start(phydev, false);
@@ -1066,6 +1109,78 @@ int bcm_phy_led_brightness_set(struct phy_device *phydev,
}
EXPORT_SYMBOL_GPL(bcm_phy_led_brightness_set);

int bcm_setup_lre_master_slave(struct phy_device *phydev)
{
	u16 ctl = 0;

	switch (phydev->master_slave_set) {
	case MASTER_SLAVE_CFG_MASTER_PREFERRED:
	case MASTER_SLAVE_CFG_MASTER_FORCE:
		ctl = LRECR_MASTER;
		break;
	case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
	case MASTER_SLAVE_CFG_SLAVE_FORCE:
		break;
	case MASTER_SLAVE_CFG_UNKNOWN:
	case MASTER_SLAVE_CFG_UNSUPPORTED:
		return 0;
	default:
		phydev_warn(phydev, "Unsupported Master/Slave mode\n");
		return -EOPNOTSUPP;
	}

	return phy_modify_changed(phydev, MII_BCM54XX_LRECR, LRECR_MASTER, ctl);
}
EXPORT_SYMBOL_GPL(bcm_setup_lre_master_slave);

int bcm_config_lre_aneg(struct phy_device *phydev, bool changed)
{
	int err;

	if (genphy_config_eee_advert(phydev))
		changed = true;

	err = bcm_setup_lre_master_slave(phydev);
	if (err < 0)
		return err;
	else if (err)
		changed = true;

	if (phydev->autoneg != AUTONEG_ENABLE)
		return bcm_setup_lre_forced(phydev);

	err = bcm_config_lre_advert(phydev);
	if (err < 0)
		return err;
	else if (err)
		changed = true;

	return genphy_check_and_restart_aneg(phydev, changed);
}
EXPORT_SYMBOL_GPL(bcm_config_lre_aneg);

/**
 * bcm_config_lre_advert - sanitize and advertise Long-Distance Signaling
 *  auto-negotiation parameters
 * @phydev: target phy_device struct
 * Return:  0 if the PHY's advertisement hasn't changed, < 0 on error,
 *          > 0 if it has changed
 *
 * Writes MII_BCM54XX_LREANAA with the appropriate values. The values are to be
 *   sanitized before, to make sure we only advertise what is supported.
 *  The sanitization is done already in phy_ethtool_ksettings_set()
 */
int bcm_config_lre_advert(struct phy_device *phydev)
{
	u32 adv = bcm_linkmode_adv_to_lre_adv_t(phydev->advertising);

	/* Setup BroadR-Reach mode advertisement */
	return phy_modify_changed(phydev, MII_BCM54XX_LREANAA,
				 LRE_ADVERTISE_ALL | LREANAA_PAUSE |
				 LREANAA_PAUSE_ASYM, adv);
}
EXPORT_SYMBOL_GPL(bcm_config_lre_advert);

MODULE_DESCRIPTION("Broadcom PHY Library");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Broadcom Corporation");
+4 −0
Original line number Diff line number Diff line
@@ -121,4 +121,8 @@ irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id);
int bcm_phy_led_brightness_set(struct phy_device *phydev,
			       u8 index, enum led_brightness value);

int bcm_setup_lre_master_slave(struct phy_device *phydev);
int bcm_config_lre_aneg(struct phy_device *phydev, bool changed);
int bcm_config_lre_advert(struct phy_device *phydev);

#endif /* _LINUX_BCM_PHY_LIB_H */
+375 −28
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
 *	Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet
 *	transceivers.
 *
 *	Broadcom BCM54810, BCM54811 BroadR-Reach transceivers.
 *
 *	Copyright (c) 2006  Maciej W. Rozycki
 *
 *	Inspired by code written by Amy Fong.
@@ -36,6 +38,29 @@ struct bcm54xx_phy_priv {
	struct bcm_ptp_private *ptp;
	int	wake_irq;
	bool	wake_irq_enabled;
	bool	brr_mode;
};

/* Link modes for BCM58411 PHY */
static const int bcm54811_linkmodes[] = {
	ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
	ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
	ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
	ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
	ETHTOOL_LINK_MODE_100baseT_Full_BIT,
	ETHTOOL_LINK_MODE_100baseT_Half_BIT,
	ETHTOOL_LINK_MODE_10baseT_Full_BIT,
	ETHTOOL_LINK_MODE_10baseT_Half_BIT
};

/* Long-Distance Signaling (BroadR-Reach mode aneg) relevant linkmode bits */
static const int lds_br_bits[] = {
	ETHTOOL_LINK_MODE_Autoneg_BIT,
	ETHTOOL_LINK_MODE_Pause_BIT,
	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
	ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
	ETHTOOL_LINK_MODE_100baseT1_Full_BIT
};

static bool bcm54xx_phy_can_wakeup(struct phy_device *phydev)
@@ -347,6 +372,61 @@ static void bcm54xx_ptp_config_init(struct phy_device *phydev)
		bcm_ptp_config_init(phydev);
}

static int bcm5481x_set_brrmode(struct phy_device *phydev, bool on)
{
	int reg;
	int err;
	u16 val;

	reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);

	if (reg < 0)
		return reg;

	if (on)
		reg |= BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
	else
		reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;

	err = bcm_phy_write_exp(phydev,
				BCM54810_EXP_BROADREACH_LRE_MISC_CTL, reg);
	if (err)
		return err;

	/* Ensure LRE or IEEE register set is accessed according to the brr
	 *  on/off, thus set the override
	 */
	val = BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL_EN;
	if (!on)
		val |= BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL_OVERRIDE_VAL;

	return bcm_phy_write_exp(phydev,
				 BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL, val);
}

static int bcm54811_config_init(struct phy_device *phydev)
{
	struct bcm54xx_phy_priv *priv = phydev->priv;
	int err, reg;

	/* Enable CLK125 MUX on LED4 if ref clock is enabled. */
	if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
		reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
		if (reg < 0)
			return reg;
		err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
					BCM54612E_LED4_CLK125OUT_EN | reg);
		if (err < 0)
			return err;
	}

	/* With BCM54811, BroadR-Reach implies no autoneg */
	if (priv->brr_mode)
		phydev->autoneg = 0;

	return bcm5481x_set_brrmode(phydev, priv->brr_mode);
}

static int bcm54xx_config_init(struct phy_device *phydev)
{
	int reg, err, val;
@@ -399,6 +479,9 @@ static int bcm54xx_config_init(struct phy_device *phydev)
					BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
					val);
		break;
	case PHY_ID_BCM54811:
		err = bcm54811_config_init(phydev);
		break;
	}
	if (err)
		return err;
@@ -553,52 +636,117 @@ static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
	return -EOPNOTSUPP;
}

static int bcm54811_config_init(struct phy_device *phydev)

/**
 * bcm5481x_read_abilities - read PHY abilities from LRESR or Clause 22
 * (BMSR) registers, based on whether the PHY is in BroadR-Reach or IEEE mode
 * @phydev: target phy_device struct
 *
 * Description: Reads the PHY's abilities and populates phydev->supported
 * accordingly. The register to read the abilities from is determined by
 * the brr mode setting of the PHY as read from the device tree.
 * Note that the LRE and IEEE sets of abilities are disjunct, in other words,
 * not only the link modes differ, but also the auto-negotiation and
 * master-slave setup is controlled differently.
 *
 * Returns: 0 on success, < 0 on failure
 */
static int bcm5481x_read_abilities(struct phy_device *phydev)
{
	int err, reg;
	struct device_node *np = phydev->mdio.dev.of_node;
	struct bcm54xx_phy_priv *priv = phydev->priv;
	int i, val, err;

	/* Disable BroadR-Reach function. */
	reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
	reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
	err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
				reg);
	if (err < 0)
		return err;
	for (i = 0; i < ARRAY_SIZE(bcm54811_linkmodes); i++)
		linkmode_clear_bit(bcm54811_linkmodes[i], phydev->supported);

	err = bcm54xx_config_init(phydev);
	priv->brr_mode = of_property_read_bool(np, "brr-mode");

	/* Enable CLK125 MUX on LED4 if ref clock is enabled. */
	if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
		reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
		err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
					BCM54612E_LED4_CLK125OUT_EN | reg);
		if (err < 0)
	/* Set BroadR-Reach mode as configured in the DT. */
	err = bcm5481x_set_brrmode(phydev, priv->brr_mode);
	if (err)
		return err;

	if (priv->brr_mode) {
		linkmode_set_bit_array(phy_basic_ports_array,
				       ARRAY_SIZE(phy_basic_ports_array),
				       phydev->supported);

		val = phy_read(phydev, MII_BCM54XX_LRESR);
		if (val < 0)
			return val;

		linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
				 phydev->supported,
				 val & LRESR_LDSABILITY);
		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
				 phydev->supported,
				 val & LRESR_100_1PAIR);
		linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
				 phydev->supported,
				 val & LRESR_10_1PAIR);
		return 0;
	}

	return err;
	return genphy_read_abilities(phydev);
}

static int bcm5481_config_aneg(struct phy_device *phydev)
static int bcm5481x_config_delay_swap(struct phy_device *phydev)
{
	struct device_node *np = phydev->mdio.dev.of_node;
	int ret;

	/* Aneg firstly. */
	ret = genphy_config_aneg(phydev);

	/* Then we can set up the delay. */
	/* Set up the delay. */
	bcm54xx_config_clock_delay(phydev);

	if (of_property_read_bool(np, "enet-phy-lane-swap")) {
		/* Lane Swap - Undocumented register...magic! */
		ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
		int ret = bcm_phy_write_exp(phydev,
					    MII_BCM54XX_EXP_SEL_ER + 0x9,
					    0x11B);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int bcm5481_config_aneg(struct phy_device *phydev)
{
	struct bcm54xx_phy_priv *priv = phydev->priv;
	int ret;

	/* Aneg firstly. */
	if (priv->brr_mode)
		ret = bcm_config_lre_aneg(phydev, false);
	else
		ret = genphy_config_aneg(phydev);

	if (ret)
		return ret;

	/* Then we can set up the delay and swap. */
	return bcm5481x_config_delay_swap(phydev);
}

static int bcm54811_config_aneg(struct phy_device *phydev)
{
	struct bcm54xx_phy_priv *priv = phydev->priv;
	int ret;

	/* Aneg firstly. */
	if (priv->brr_mode) {
		/* BCM54811 is only capable of autonegotiation in IEEE mode */
		phydev->autoneg = 0;
		ret = bcm_config_lre_aneg(phydev, false);
	} else {
		ret = genphy_config_aneg(phydev);
	}

	if (ret)
		return ret;

	/* Then we can set up the delay and swap. */
	return bcm5481x_config_delay_swap(phydev);
}

struct bcm54616s_phy_priv {
@@ -1062,6 +1210,203 @@ static void bcm54xx_link_change_notify(struct phy_device *phydev)
	bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret);
}

static int lre_read_master_slave(struct phy_device *phydev)
{
	int cfg = MASTER_SLAVE_CFG_UNKNOWN, state;
	int val;

	/* In BroadR-Reach mode we are always capable of master-slave
	 *  and there is no preferred master or slave configuration
	 */
	phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
	phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;

	val = phy_read(phydev, MII_BCM54XX_LRECR);
	if (val < 0)
		return val;

	if ((val & LRECR_LDSEN) == 0) {
		if (val & LRECR_MASTER)
			cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
		else
			cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
	}

	val = phy_read(phydev, MII_BCM54XX_LRELDSE);
	if (val < 0)
		return val;

	if (val & LDSE_MASTER)
		state = MASTER_SLAVE_STATE_MASTER;
	else
		state = MASTER_SLAVE_STATE_SLAVE;

	phydev->master_slave_get = cfg;
	phydev->master_slave_state = state;

	return 0;
}

/* Read LDS Link Partner Ability in BroadR-Reach mode */
static int lre_read_lpa(struct phy_device *phydev)
{
	int i, lrelpa;

	if (phydev->autoneg != AUTONEG_ENABLE) {
		if (!phydev->autoneg_complete) {
			/* aneg not yet done, reset all relevant bits */
			for (i = 0; i < ARRAY_SIZE(lds_br_bits); i++)
				linkmode_clear_bit(lds_br_bits[i],
						   phydev->lp_advertising);

			return 0;
		}

		/* Long-Distance Signaling Link Partner Ability */
		lrelpa = phy_read(phydev, MII_BCM54XX_LRELPA);
		if (lrelpa < 0)
			return lrelpa;

		linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
				 phydev->lp_advertising,
				 lrelpa & LRELPA_PAUSE_ASYM);
		linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
				 phydev->lp_advertising,
				 lrelpa & LRELPA_PAUSE);
		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
				 phydev->lp_advertising,
				 lrelpa & LRELPA_100_1PAIR);
		linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
				 phydev->lp_advertising,
				 lrelpa & LRELPA_10_1PAIR);
	} else {
		linkmode_zero(phydev->lp_advertising);
	}

	return 0;
}

static int lre_read_status_fixed(struct phy_device *phydev)
{
	int lrecr = phy_read(phydev, MII_BCM54XX_LRECR);

	if (lrecr < 0)
		return lrecr;

	phydev->duplex = DUPLEX_FULL;

	if (lrecr & LRECR_SPEED100)
		phydev->speed = SPEED_100;
	else
		phydev->speed = SPEED_10;

	return 0;
}

/**
 * lre_update_link - update link status in @phydev
 * @phydev: target phy_device struct
 * Return:  0 on success, < 0 on error
 *
 * Description: Update the value in phydev->link to reflect the
 *   current link value.  In order to do this, we need to read
 *   the status register twice, keeping the second value.
 *   This is a genphy_update_link modified to work on LRE registers
 *   of BroadR-Reach PHY
 */
static int lre_update_link(struct phy_device *phydev)
{
	int status = 0, lrecr;

	lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
	if (lrecr < 0)
		return lrecr;

	/* Autoneg is being started, therefore disregard BMSR value and
	 * report link as down.
	 */
	if (lrecr & BMCR_ANRESTART)
		goto done;

	/* The link state is latched low so that momentary link
	 * drops can be detected. Do not double-read the status
	 * in polling mode to detect such short link drops except
	 * the link was already down.
	 */
	if (!phy_polling_mode(phydev) || !phydev->link) {
		status = phy_read(phydev, MII_BCM54XX_LRESR);
		if (status < 0)
			return status;
		else if (status & LRESR_LSTATUS)
			goto done;
	}

	/* Read link and autonegotiation status */
	status = phy_read(phydev, MII_BCM54XX_LRESR);
	if (status < 0)
		return status;
done:
	phydev->link = status & LRESR_LSTATUS ? 1 : 0;
	phydev->autoneg_complete = status & LRESR_LDSCOMPLETE ? 1 : 0;

	/* Consider the case that autoneg was started and "aneg complete"
	 * bit has been reset, but "link up" bit not yet.
	 */
	if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
		phydev->link = 0;

	return 0;
}

/* Get the status in BroadRReach mode just like genphy_read_status does
*   in normal mode
*/
static int bcm54811_lre_read_status(struct phy_device *phydev)
{
	int err, old_link = phydev->link;

	/* Update the link, but return if there was an error */
	err = lre_update_link(phydev);
	if (err)
		return err;

	/* why bother the PHY if nothing can have changed */
	if (phydev->autoneg ==
		AUTONEG_ENABLE && old_link && phydev->link)
		return 0;

	phydev->speed = SPEED_UNKNOWN;
	phydev->duplex = DUPLEX_UNKNOWN;
	phydev->pause = 0;
	phydev->asym_pause = 0;

	err = lre_read_master_slave(phydev);
	if (err < 0)
		return err;

	/* Read LDS Link Partner Ability */
	err = lre_read_lpa(phydev);
	if (err < 0)
		return err;

	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
		phy_resolve_aneg_linkmode(phydev);
	else if (phydev->autoneg == AUTONEG_DISABLE)
		err = lre_read_status_fixed(phydev);

	return err;
}

static int bcm54811_read_status(struct phy_device *phydev)
{
	struct bcm54xx_phy_priv *priv = phydev->priv;

	if (priv->brr_mode)
		return  bcm54811_lre_read_status(phydev);

	return genphy_read_status(phydev);
}

static struct phy_driver broadcom_drivers[] = {
{
	.phy_id		= PHY_ID_BCM5411,
@@ -1211,10 +1556,12 @@ static struct phy_driver broadcom_drivers[] = {
	.get_strings	= bcm_phy_get_strings,
	.get_stats	= bcm54xx_get_stats,
	.probe		= bcm54xx_phy_probe,
	.config_init    = bcm54811_config_init,
	.config_aneg    = bcm5481_config_aneg,
	.config_init    = bcm54xx_config_init,
	.config_aneg    = bcm54811_config_aneg,
	.config_intr    = bcm_phy_config_intr,
	.handle_interrupt = bcm_phy_handle_interrupt,
	.read_status	= bcm54811_read_status,
	.get_features	= bcm5481x_read_abilities,
	.suspend	= bcm54xx_suspend,
	.resume		= bcm54xx_resume,
	.link_change_notify	= bcm54xx_link_change_notify,
+2 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
 */
const char *phy_speed_to_str(int speed)
{
	BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 102,
	BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 103,
		"Enum ethtool_link_mode_bit_indices and phylib are out of sync. "
		"If a speed or mode has been added please update phy_speed_to_str "
		"and the PHY settings array.\n");
@@ -266,6 +266,7 @@ static const struct phy_setting settings[] = {
	PHY_SETTING(     10, FULL,     10baseT1S_Full		),
	PHY_SETTING(     10, HALF,     10baseT1S_Half		),
	PHY_SETTING(     10, HALF,     10baseT1S_P2MP_Half	),
	PHY_SETTING(     10, FULL,     10baseT1BRR_Full		),
};
#undef PHY_SETTING

Loading