Message ID | 20220419083704.48573-3-horatiu.vultur@microchip.com (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: phy: Extend sysfs to adjust PHY latency. | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/subject_prefix | success | Link |
netdev/cover_letter | success | Series has a cover letter |
netdev/patch_count | success | Link |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/cc_maintainers | success | CCed 7 of 7 maintainers |
netdev/build_clang | success | Errors and warnings before: 0 this patch: 0 |
netdev/module_param | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 111 lines checked |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/source_inline | success | Was 0 now: 0 |
On Tue, Apr 19, 2022 at 10:37:04AM +0200, Horatiu Vultur wrote: > The lan8814 driver supports adjustments of the latency in the silicon > based on the speed and direction, therefore implement set/get_adj_latency > to adjust the HW. > > Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> > --- > drivers/net/phy/micrel.c | 87 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 87 insertions(+) > > diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c > index 96840695debd..099d1ecd6dad 100644 > --- a/drivers/net/phy/micrel.c > +++ b/drivers/net/phy/micrel.c > @@ -120,6 +120,15 @@ > #define PTP_TIMESTAMP_EN_PDREQ_ BIT(2) > #define PTP_TIMESTAMP_EN_PDRES_ BIT(3) > > +#define PTP_RX_LATENCY_1000 0x0224 > +#define PTP_TX_LATENCY_1000 0x0225 > + > +#define PTP_RX_LATENCY_100 0x0222 > +#define PTP_TX_LATENCY_100 0x0223 > + > +#define PTP_RX_LATENCY_10 0x0220 > +#define PTP_TX_LATENCY_10 0x0221 > + > #define PTP_TX_PARSE_L2_ADDR_EN 0x0284 > #define PTP_RX_PARSE_L2_ADDR_EN 0x0244 > > @@ -208,6 +217,16 @@ > #define PTP_TSU_INT_STS_PTP_RX_TS_OVRFL_INT_ BIT(1) > #define PTP_TSU_INT_STS_PTP_RX_TS_EN_ BIT(0) > > +/* Represents the reset value of the latency registers, > + * The values are express in ns > + */ > +#define LAN8814_RX_10_LATENCY 8874 > +#define LAN8814_TX_10_LATENCY 11850 > +#define LAN8814_RX_100_LATENCY 2346 > +#define LAN8814_TX_100_LATENCY 705 > +#define LAN8814_RX_1000_LATENCY 429 > +#define LAN8814_TX_1000_LATENCY 201 > + > /* PHY Control 1 */ > #define MII_KSZPHY_CTRL_1 0x1e > #define KSZ8081_CTRL1_MDIX_STAT BIT(4) > @@ -2657,6 +2676,72 @@ static int lan8804_config_init(struct phy_device *phydev) > return 0; > } > > +static int lan8814_set_adj_latency(struct phy_device *phydev, > + enum ethtool_link_mode_bit_indices link_mode, > + s32 rx, s32 tx) > +{ > + switch (link_mode) { > + case ETHTOOL_LINK_MODE_10baseT_Half_BIT: > + case ETHTOOL_LINK_MODE_10baseT_Full_BIT: > + rx += LAN8814_RX_10_LATENCY; > + tx += LAN8814_TX_10_LATENCY; > + lanphy_write_page_reg(phydev, 5, PTP_RX_LATENCY_10, rx); > + lanphy_write_page_reg(phydev, 5, PTP_TX_LATENCY_10, tx); It is not ideal that the user sees an entry for both link modes X and X+1 in your file, and that writing to link mode X magically also changes X+1. I'm not sure there is anything you can do about this in a generic implementation, so you at least need to document it in sysfs. What about range checks? I can pass 32764 as an rx delay, which when added to PTP_RX_LATENCY_10=0x0220 is going to wrap around and be negative. Andrew
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 96840695debd..099d1ecd6dad 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -120,6 +120,15 @@ #define PTP_TIMESTAMP_EN_PDREQ_ BIT(2) #define PTP_TIMESTAMP_EN_PDRES_ BIT(3) +#define PTP_RX_LATENCY_1000 0x0224 +#define PTP_TX_LATENCY_1000 0x0225 + +#define PTP_RX_LATENCY_100 0x0222 +#define PTP_TX_LATENCY_100 0x0223 + +#define PTP_RX_LATENCY_10 0x0220 +#define PTP_TX_LATENCY_10 0x0221 + #define PTP_TX_PARSE_L2_ADDR_EN 0x0284 #define PTP_RX_PARSE_L2_ADDR_EN 0x0244 @@ -208,6 +217,16 @@ #define PTP_TSU_INT_STS_PTP_RX_TS_OVRFL_INT_ BIT(1) #define PTP_TSU_INT_STS_PTP_RX_TS_EN_ BIT(0) +/* Represents the reset value of the latency registers, + * The values are express in ns + */ +#define LAN8814_RX_10_LATENCY 8874 +#define LAN8814_TX_10_LATENCY 11850 +#define LAN8814_RX_100_LATENCY 2346 +#define LAN8814_TX_100_LATENCY 705 +#define LAN8814_RX_1000_LATENCY 429 +#define LAN8814_TX_1000_LATENCY 201 + /* PHY Control 1 */ #define MII_KSZPHY_CTRL_1 0x1e #define KSZ8081_CTRL1_MDIX_STAT BIT(4) @@ -2657,6 +2676,72 @@ static int lan8804_config_init(struct phy_device *phydev) return 0; } +static int lan8814_set_adj_latency(struct phy_device *phydev, + enum ethtool_link_mode_bit_indices link_mode, + s32 rx, s32 tx) +{ + switch (link_mode) { + case ETHTOOL_LINK_MODE_10baseT_Half_BIT: + case ETHTOOL_LINK_MODE_10baseT_Full_BIT: + rx += LAN8814_RX_10_LATENCY; + tx += LAN8814_TX_10_LATENCY; + lanphy_write_page_reg(phydev, 5, PTP_RX_LATENCY_10, rx); + lanphy_write_page_reg(phydev, 5, PTP_TX_LATENCY_10, tx); + return 0; + case ETHTOOL_LINK_MODE_100baseT_Half_BIT: + case ETHTOOL_LINK_MODE_100baseT_Full_BIT: + rx += LAN8814_RX_100_LATENCY; + tx += LAN8814_TX_100_LATENCY; + lanphy_write_page_reg(phydev, 5, PTP_RX_LATENCY_100, rx); + lanphy_write_page_reg(phydev, 5, PTP_TX_LATENCY_100, tx); + return 0; + case ETHTOOL_LINK_MODE_1000baseT_Half_BIT: + case ETHTOOL_LINK_MODE_1000baseT_Full_BIT: + rx += LAN8814_RX_1000_LATENCY; + tx += LAN8814_TX_1000_LATENCY; + lanphy_write_page_reg(phydev, 5, PTP_RX_LATENCY_1000, rx); + lanphy_write_page_reg(phydev, 5, PTP_TX_LATENCY_1000, tx); + return 0; + default: + return -EINVAL; + } + + return 0; +} + +static int lan8814_get_adj_latency(struct phy_device *phydev, + enum ethtool_link_mode_bit_indices link_mode, + s32 *rx, s32 *tx) +{ + switch (link_mode) { + case ETHTOOL_LINK_MODE_10baseT_Half_BIT: + case ETHTOOL_LINK_MODE_10baseT_Full_BIT: + *rx = lanphy_read_page_reg(phydev, 5, PTP_RX_LATENCY_10); + *tx = lanphy_read_page_reg(phydev, 5, PTP_TX_LATENCY_10); + *rx -= LAN8814_RX_10_LATENCY; + *tx -= LAN8814_TX_10_LATENCY; + return 0; + case ETHTOOL_LINK_MODE_100baseT_Half_BIT: + case ETHTOOL_LINK_MODE_100baseT_Full_BIT: + *rx = lanphy_read_page_reg(phydev, 5, PTP_RX_LATENCY_100); + *tx = lanphy_read_page_reg(phydev, 5, PTP_TX_LATENCY_100); + *rx -= LAN8814_RX_100_LATENCY; + *tx -= LAN8814_TX_100_LATENCY; + return 0; + case ETHTOOL_LINK_MODE_1000baseT_Half_BIT: + case ETHTOOL_LINK_MODE_1000baseT_Full_BIT: + *rx = lanphy_read_page_reg(phydev, 5, PTP_RX_LATENCY_1000); + *tx = lanphy_read_page_reg(phydev, 5, PTP_TX_LATENCY_1000); + *rx -= LAN8814_RX_1000_LATENCY; + *tx -= LAN8814_TX_1000_LATENCY; + return 0; + default: + return -EINVAL; + } + + return 0; +} + static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev) { u16 tsu_irq_status; @@ -3052,6 +3137,8 @@ static struct phy_driver ksphy_driver[] = { .resume = kszphy_resume, .config_intr = lan8814_config_intr, .handle_interrupt = lan8814_handle_interrupt, + .set_adj_latency = lan8814_set_adj_latency, + .get_adj_latency = lan8814_get_adj_latency, }, { .phy_id = PHY_ID_LAN8804, .phy_id_mask = MICREL_PHY_ID_MASK,
The lan8814 driver supports adjustments of the latency in the silicon based on the speed and direction, therefore implement set/get_adj_latency to adjust the HW. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> --- drivers/net/phy/micrel.c | 87 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+)