1
1

realtek: mdio: checkpatch & documentation cleanup

checkpatch is complaining. Fix that. Additionally adapt the
documentation and move it up to the beginning of the driver.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23411
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Markus Stockhausen 2026-05-17 12:29:18 +02:00 committed by Robert Marko
parent c166c20cf6
commit 57dbfa0a9c

View File

@ -1,5 +1,58 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* On all Realtek switch platforms the hardware periodically reads the link status of all PHYs.
* The result is automatically written into MAC specific registers that can be consumed by a
* DSA driver. This is to some degree programmable, so that one can tell the hardware to read
* specific C22 registers from specific pages, or C45 registers, to determine the current link
* speed, duplex, flow-control, ...
*
* This happens without any need for the driver to do anything at runtime, completely invisible
* and in a parallel hardware thread, independent of the CPU running Linux. All one needs to do
* is to set it up once. Having the MAC link settings automatically follow the PHY link status
* also happens to be the only way to control MAC port status in a meaningful way, or at least
* it's the only way that is fully understood, as this is what every vendor firmware is doing.
*
* The hardware PHY polling unit doesn't care about bus locking. It just assumes that all paged
* PHY operations are also done via the same hardware unit offering this PHY access abstractions.
*
* Additionally the devices are known to have a so called raw mode. Using the special MAX_PAGE-1
* with the MDIO controller found in Realtek SoCs allows to access the PHY in raw mode, i.e.
* bypassing the cache and paging engine of the MDIO controller. E.g. for RTL838x this is 4095.
*
* On the other hand Realtek PHYs usually make use of select register 0x1f to switch pages. There
* is no problem to issue separate page and access bus calls to the PHYs when they are not
* attached to an Realtek SoC. The design should be to keep the PHY code bus independent.
*
* To bring all this together one needs a tricky bus design that intercepts select page calls but
* lets raw page accesses through. And especially knows how to handle raw accesses to the select
* register.
*
* While C45 clause handling is pretty standard the legacy functions basically track the accesses
* and the state of the bus with the rtmd_port attributes of the control structure. The page
* selection works as follows:
*
* phy_write(phydev, RTMD_PAGE_SELECT, 12) : store internal page 12 in driver
* phy_write(phydev, 7, 33) : write page=12, reg=7, val=33
*
* Any Realtek PHY that is connected to this bus must simply provide the standard page functions:
*
* define RTL821X_PAGE_SELECT 0x1f
*
* static int rtl821x_read_page(struct phy_device *phydev)
* {
* return __phy_read(phydev, RTL821X_PAGE_SELECT);
* }
*
* static int rtl821x_write_page(struct phy_device *phydev, int page)
* {
* return __phy_write(phydev, RTL821X_PAGE_SELECT, page);
* }
*
* In case there are non Realtek PHYs attached to the bus the logic might need to be changed.
* For now it should be sufficient.
*/
#include <linux/fwnode.h>
#include <linux/fwnode_mdio.h>
#include <linux/mfd/syscon.h>
@ -150,68 +203,6 @@
#define for_each_sds_port(ctrl, pn) \
for_each_set_bit(pn, (ctrl)->sds_ports, RTMD_MAX_PORTS)
/*
* On all Realtek switch platforms the hardware periodically reads the link status of all
* PHYs. This is to some degree programmable, so that one can tell the hardware to read
* specific C22 registers from specific pages, or C45 registers, to determine the current
* link speed, duplex, flow-control, ...
*
* This happens without any need for the driver to do anything at runtime, completely
* invisible and in a parallel hardware thread, independent of the CPU running Linux.
* All one needs to do is to set it up once. Having the MAC link settings automatically
* follow the PHY link status also happens to be the only way to control MAC port status
* in a meaningful way, or at least it's the only way we fully understand, as this is
* what every vendor firmware is doing.
*
* The hardware PHY polling unit doesn't care about bus locking, it just assumes that all
* paged PHY operations are also done via the same hardware unit offering this PHY access
* abstractions.
*
* Additionally at least the RTL838x and RTL839x devices are known to have a so called
* raw mode. Using the special MAX_PAGE-1 with the MDIO controller found in Realtek
* SoCs allows to access the PHY in raw mode, ie. bypassing the cache and paging engine
* of the MDIO controller. E.g. for RTL838x this is 0xfff.
*
* On the other hand Realtek PHYs usually make use of select register 0x1f to switch
* pages. There is no problem to issue separate page and access bus calls to the PHYs
* when they are not attached to an Realtek SoC. The paradigm should be to keep the PHY
* implementation bus independent.
*
* To bring all this together we need a tricky bus design that intercepts select page
* calls but lets raw page accesses through. And especially knows how to handle raw
* accesses to the select register. Additionally we need the possibility to write to
* all 8 ports of the PHY individually.
*
* While the C45 clause stuff is pretty standard the legacy functions basically track
* the accesses and the state of the bus with the rtmd_port attributes of the control
* structure. The page selection works as follows:
*
* phy_write(phydev, RTMD_PAGE_SELECT, 12) : store internal page 12 in driver
* phy_write(phydev, 7, 33) : write page=12, reg=7, val=33
*
* or simply
*
* phy_write_paged(phydev, 12, 7, 33) : write page=12, reg=7, val=33
*
* Any Realtek PHY that will be connected to this bus must simply provide the standard
* page functions:
*
* define RTL821X_PAGE_SELECT 0x1f
*
* static int rtl821x_read_page(struct phy_device *phydev)
* {
* return __phy_read(phydev, RTL821X_PAGE_SELECT);
* }
*
* static int rtl821x_write_page(struct phy_device *phydev, int page)
* {
* return __phy_write(phydev, RTL821X_PAGE_SELECT, page);
* }
*
* In case there are non Realtek PHYs attached to the bus the logic might need to be
* reimplemented. For now it should be sufficient.
*/
struct rtmd_port {
int page;
bool raw;
@ -225,7 +216,7 @@ struct rtmd_bus {
};
struct rtmd_ctrl {
struct mutex lock;
struct mutex lock; /* protect HW access */
struct regmap *map;
const struct rtmd_config *cfg;
struct rtmd_port port[RTMD_MAX_PORTS];
@ -992,7 +983,8 @@ static int rtmd_map_ports(struct device *dev)
if (test_bit(pn, ctrl->phy_ports) ||
test_bit(pn, ctrl->sds_ports))
return dev_err_probe(dev, -EINVAL, "%pfwP duplicate port number\n", fw_port);
return dev_err_probe(dev, -EINVAL, "%pfwP duplicate port number\n",
fw_port);
struct fwnode_handle *fw_phy __free(fwnode_handle) =
fwnode_find_reference(fw_port, "phy-handle", 0);
@ -1224,22 +1216,10 @@ static const struct rtmd_config rtmd_931x_cfg = {
};
static const struct of_device_id rtmd_ids[] = {
{
.compatible = "realtek,rtl8380-mdio",
.data = &rtmd_838x_cfg,
},
{
.compatible = "realtek,rtl8392-mdio",
.data = &rtmd_839x_cfg,
},
{
.compatible = "realtek,rtl9301-mdio",
.data = &rtmd_930x_cfg,
},
{
.compatible = "realtek,rtl9311-mdio",
.data = &rtmd_931x_cfg,
},
{ .compatible = "realtek,rtl8380-mdio", .data = &rtmd_838x_cfg, },
{ .compatible = "realtek,rtl8392-mdio", .data = &rtmd_839x_cfg, },
{ .compatible = "realtek,rtl9301-mdio", .data = &rtmd_930x_cfg, },
{ .compatible = "realtek,rtl9311-mdio", .data = &rtmd_931x_cfg, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rtmd_ids);
@ -1256,4 +1236,4 @@ module_platform_driver(rtmd_driver);
MODULE_AUTHOR("Markus Stockhausen <markus.stockhausen@gmx.de>");
MODULE_DESCRIPTION("Realtek Otto MDIO driver");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");