-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: mdio: Introduce a regmap-based mdio driver
There exists several examples today of devices that embed an ethernet PHY or PCS directly inside an SoC. In this situation, either the device is controlled through a vendor-specific register set, or sometimes exposes the standard 802.3 registers that are typically accessed over MDIO. As phylib and phylink are designed to use mdiodevices, this driver allows creating a virtual MDIO bus, that translates mdiodev register accesses to regmap accesses. The reason we use regmap is because there are at least 3 such devices known today, 2 of them are Altera TSE PCS's, memory-mapped, exposed with a 4-byte stride in stmmac's dwmac-socfpga variant, and a 2-byte stride in altera-tse. The other one (nxp,sja1110-base-tx-mdio) is exposed over SPI. Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Maxime Chevallier
authored and
David S. Miller
committed
Jun 5, 2023
1 parent
f69de8a
commit 642af0f
Showing
5 changed files
with
138 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS | ||
* within the MMIO-mapped area | ||
* | ||
* Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com> | ||
*/ | ||
#include <linux/bitfield.h> | ||
#include <linux/delay.h> | ||
#include <linux/mdio.h> | ||
#include <linux/module.h> | ||
#include <linux/of.h> | ||
#include <linux/of_mdio.h> | ||
#include <linux/phy.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/regmap.h> | ||
#include <linux/mdio/mdio-regmap.h> | ||
|
||
#define DRV_NAME "mdio-regmap" | ||
|
||
struct mdio_regmap_priv { | ||
struct regmap *regmap; | ||
u8 valid_addr; | ||
}; | ||
|
||
static int mdio_regmap_read_c22(struct mii_bus *bus, int addr, int regnum) | ||
{ | ||
struct mdio_regmap_priv *ctx = bus->priv; | ||
unsigned int val; | ||
int ret; | ||
|
||
if (ctx->valid_addr != addr) | ||
return -ENODEV; | ||
|
||
ret = regmap_read(ctx->regmap, regnum, &val); | ||
if (ret < 0) | ||
return ret; | ||
|
||
return val; | ||
} | ||
|
||
static int mdio_regmap_write_c22(struct mii_bus *bus, int addr, int regnum, | ||
u16 val) | ||
{ | ||
struct mdio_regmap_priv *ctx = bus->priv; | ||
|
||
if (ctx->valid_addr != addr) | ||
return -ENODEV; | ||
|
||
return regmap_write(ctx->regmap, regnum, val); | ||
} | ||
|
||
struct mii_bus *devm_mdio_regmap_register(struct device *dev, | ||
const struct mdio_regmap_config *config) | ||
{ | ||
struct mdio_regmap_priv *mr; | ||
struct mii_bus *mii; | ||
int rc; | ||
|
||
if (!config->parent) | ||
return ERR_PTR(-EINVAL); | ||
|
||
mii = devm_mdiobus_alloc_size(config->parent, sizeof(*mr)); | ||
if (!mii) | ||
return ERR_PTR(-ENOMEM); | ||
|
||
mr = mii->priv; | ||
mr->regmap = config->regmap; | ||
mr->valid_addr = config->valid_addr; | ||
|
||
mii->name = DRV_NAME; | ||
strscpy(mii->id, config->name, MII_BUS_ID_SIZE); | ||
mii->parent = config->parent; | ||
mii->read = mdio_regmap_read_c22; | ||
mii->write = mdio_regmap_write_c22; | ||
|
||
if (config->autoscan) | ||
mii->phy_mask = ~BIT(config->valid_addr); | ||
else | ||
mii->phy_mask = ~0; | ||
|
||
rc = devm_mdiobus_register(dev, mii); | ||
if (rc) { | ||
dev_err(config->parent, "Cannot register MDIO bus![%s] (%d)\n", mii->id, rc); | ||
return ERR_PTR(rc); | ||
} | ||
|
||
return mii; | ||
} | ||
EXPORT_SYMBOL_GPL(devm_mdio_regmap_register); | ||
|
||
MODULE_DESCRIPTION("MDIO API over regmap"); | ||
MODULE_AUTHOR("Maxime Chevallier <maxime.chevallier@bootlin.com>"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS | ||
* within the MMIO-mapped area | ||
* | ||
* Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com> | ||
*/ | ||
#ifndef MDIO_REGMAP_H | ||
#define MDIO_REGMAP_H | ||
|
||
#include <linux/phy.h> | ||
|
||
struct device; | ||
struct regmap; | ||
|
||
struct mdio_regmap_config { | ||
struct device *parent; | ||
struct regmap *regmap; | ||
char name[MII_BUS_ID_SIZE]; | ||
u8 valid_addr; | ||
bool autoscan; | ||
}; | ||
|
||
struct mii_bus *devm_mdio_regmap_register(struct device *dev, | ||
const struct mdio_regmap_config *config); | ||
|
||
#endif |