cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

stmmac_mdio.c (14626B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*******************************************************************************
      3  STMMAC Ethernet Driver -- MDIO bus implementation
      4  Provides Bus interface for MII registers
      5
      6  Copyright (C) 2007-2009  STMicroelectronics Ltd
      7
      8
      9  Author: Carl Shaw <carl.shaw@st.com>
     10  Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
     11*******************************************************************************/
     12
     13#include <linux/gpio/consumer.h>
     14#include <linux/io.h>
     15#include <linux/iopoll.h>
     16#include <linux/mii.h>
     17#include <linux/of_mdio.h>
     18#include <linux/pm_runtime.h>
     19#include <linux/phy.h>
     20#include <linux/property.h>
     21#include <linux/slab.h>
     22
     23#include "dwxgmac2.h"
     24#include "stmmac.h"
     25
     26#define MII_BUSY 0x00000001
     27#define MII_WRITE 0x00000002
     28#define MII_DATA_MASK GENMASK(15, 0)
     29
     30/* GMAC4 defines */
     31#define MII_GMAC4_GOC_SHIFT		2
     32#define MII_GMAC4_REG_ADDR_SHIFT	16
     33#define MII_GMAC4_WRITE			(1 << MII_GMAC4_GOC_SHIFT)
     34#define MII_GMAC4_READ			(3 << MII_GMAC4_GOC_SHIFT)
     35#define MII_GMAC4_C45E			BIT(1)
     36
     37/* XGMAC defines */
     38#define MII_XGMAC_SADDR			BIT(18)
     39#define MII_XGMAC_CMD_SHIFT		16
     40#define MII_XGMAC_WRITE			(1 << MII_XGMAC_CMD_SHIFT)
     41#define MII_XGMAC_READ			(3 << MII_XGMAC_CMD_SHIFT)
     42#define MII_XGMAC_BUSY			BIT(22)
     43#define MII_XGMAC_MAX_C22ADDR		3
     44#define MII_XGMAC_C22P_MASK		GENMASK(MII_XGMAC_MAX_C22ADDR, 0)
     45#define MII_XGMAC_PA_SHIFT		16
     46#define MII_XGMAC_DA_SHIFT		21
     47
     48static int stmmac_xgmac2_c45_format(struct stmmac_priv *priv, int phyaddr,
     49				    int phyreg, u32 *hw_addr)
     50{
     51	u32 tmp;
     52
     53	/* Set port as Clause 45 */
     54	tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
     55	tmp &= ~BIT(phyaddr);
     56	writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
     57
     58	*hw_addr = (phyaddr << MII_XGMAC_PA_SHIFT) | (phyreg & 0xffff);
     59	*hw_addr |= (phyreg >> MII_DEVADDR_C45_SHIFT) << MII_XGMAC_DA_SHIFT;
     60	return 0;
     61}
     62
     63static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
     64				    int phyreg, u32 *hw_addr)
     65{
     66	u32 tmp;
     67
     68	/* HW does not support C22 addr >= 4 */
     69	if (phyaddr > MII_XGMAC_MAX_C22ADDR)
     70		return -ENODEV;
     71
     72	/* Set port as Clause 22 */
     73	tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
     74	tmp &= ~MII_XGMAC_C22P_MASK;
     75	tmp |= BIT(phyaddr);
     76	writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
     77
     78	*hw_addr = (phyaddr << MII_XGMAC_PA_SHIFT) | (phyreg & 0x1f);
     79	return 0;
     80}
     81
     82static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
     83{
     84	struct net_device *ndev = bus->priv;
     85	struct stmmac_priv *priv = netdev_priv(ndev);
     86	unsigned int mii_address = priv->hw->mii.addr;
     87	unsigned int mii_data = priv->hw->mii.data;
     88	u32 tmp, addr, value = MII_XGMAC_BUSY;
     89	int ret;
     90
     91	ret = pm_runtime_resume_and_get(priv->device);
     92	if (ret < 0)
     93		return ret;
     94
     95	/* Wait until any existing MII operation is complete */
     96	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
     97			       !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
     98		ret = -EBUSY;
     99		goto err_disable_clks;
    100	}
    101
    102	if (phyreg & MII_ADDR_C45) {
    103		phyreg &= ~MII_ADDR_C45;
    104
    105		ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
    106		if (ret)
    107			goto err_disable_clks;
    108	} else {
    109		ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
    110		if (ret)
    111			goto err_disable_clks;
    112
    113		value |= MII_XGMAC_SADDR;
    114	}
    115
    116	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
    117		& priv->hw->mii.clk_csr_mask;
    118	value |= MII_XGMAC_READ;
    119
    120	/* Wait until any existing MII operation is complete */
    121	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
    122			       !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
    123		ret = -EBUSY;
    124		goto err_disable_clks;
    125	}
    126
    127	/* Set the MII address register to read */
    128	writel(addr, priv->ioaddr + mii_address);
    129	writel(value, priv->ioaddr + mii_data);
    130
    131	/* Wait until any existing MII operation is complete */
    132	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
    133			       !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
    134		ret = -EBUSY;
    135		goto err_disable_clks;
    136	}
    137
    138	/* Read the data from the MII data register */
    139	ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
    140
    141err_disable_clks:
    142	pm_runtime_put(priv->device);
    143
    144	return ret;
    145}
    146
    147static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
    148				    int phyreg, u16 phydata)
    149{
    150	struct net_device *ndev = bus->priv;
    151	struct stmmac_priv *priv = netdev_priv(ndev);
    152	unsigned int mii_address = priv->hw->mii.addr;
    153	unsigned int mii_data = priv->hw->mii.data;
    154	u32 addr, tmp, value = MII_XGMAC_BUSY;
    155	int ret;
    156
    157	ret = pm_runtime_resume_and_get(priv->device);
    158	if (ret < 0)
    159		return ret;
    160
    161	/* Wait until any existing MII operation is complete */
    162	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
    163			       !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
    164		ret = -EBUSY;
    165		goto err_disable_clks;
    166	}
    167
    168	if (phyreg & MII_ADDR_C45) {
    169		phyreg &= ~MII_ADDR_C45;
    170
    171		ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
    172		if (ret)
    173			goto err_disable_clks;
    174	} else {
    175		ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
    176		if (ret)
    177			goto err_disable_clks;
    178
    179		value |= MII_XGMAC_SADDR;
    180	}
    181
    182	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
    183		& priv->hw->mii.clk_csr_mask;
    184	value |= phydata;
    185	value |= MII_XGMAC_WRITE;
    186
    187	/* Wait until any existing MII operation is complete */
    188	if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
    189			       !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
    190		ret = -EBUSY;
    191		goto err_disable_clks;
    192	}
    193
    194	/* Set the MII address register to write */
    195	writel(addr, priv->ioaddr + mii_address);
    196	writel(value, priv->ioaddr + mii_data);
    197
    198	/* Wait until any existing MII operation is complete */
    199	ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp,
    200				 !(tmp & MII_XGMAC_BUSY), 100, 10000);
    201
    202err_disable_clks:
    203	pm_runtime_put(priv->device);
    204
    205	return ret;
    206}
    207
    208/**
    209 * stmmac_mdio_read
    210 * @bus: points to the mii_bus structure
    211 * @phyaddr: MII addr
    212 * @phyreg: MII reg
    213 * Description: it reads data from the MII register from within the phy device.
    214 * For the 7111 GMAC, we must set the bit 0 in the MII address register while
    215 * accessing the PHY registers.
    216 * Fortunately, it seems this has no drawback for the 7109 MAC.
    217 */
    218static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
    219{
    220	struct net_device *ndev = bus->priv;
    221	struct stmmac_priv *priv = netdev_priv(ndev);
    222	unsigned int mii_address = priv->hw->mii.addr;
    223	unsigned int mii_data = priv->hw->mii.data;
    224	u32 value = MII_BUSY;
    225	int data = 0;
    226	u32 v;
    227
    228	data = pm_runtime_resume_and_get(priv->device);
    229	if (data < 0)
    230		return data;
    231
    232	value |= (phyaddr << priv->hw->mii.addr_shift)
    233		& priv->hw->mii.addr_mask;
    234	value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
    235	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
    236		& priv->hw->mii.clk_csr_mask;
    237	if (priv->plat->has_gmac4) {
    238		value |= MII_GMAC4_READ;
    239		if (phyreg & MII_ADDR_C45) {
    240			value |= MII_GMAC4_C45E;
    241			value &= ~priv->hw->mii.reg_mask;
    242			value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
    243			       priv->hw->mii.reg_shift) &
    244			       priv->hw->mii.reg_mask;
    245
    246			data |= (phyreg & MII_REGADDR_C45_MASK) <<
    247				MII_GMAC4_REG_ADDR_SHIFT;
    248		}
    249	}
    250
    251	if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
    252			       100, 10000)) {
    253		data = -EBUSY;
    254		goto err_disable_clks;
    255	}
    256
    257	writel(data, priv->ioaddr + mii_data);
    258	writel(value, priv->ioaddr + mii_address);
    259
    260	if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
    261			       100, 10000)) {
    262		data = -EBUSY;
    263		goto err_disable_clks;
    264	}
    265
    266	/* Read the data from the MII data register */
    267	data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
    268
    269err_disable_clks:
    270	pm_runtime_put(priv->device);
    271
    272	return data;
    273}
    274
    275/**
    276 * stmmac_mdio_write
    277 * @bus: points to the mii_bus structure
    278 * @phyaddr: MII addr
    279 * @phyreg: MII reg
    280 * @phydata: phy data
    281 * Description: it writes the data into the MII register from within the device.
    282 */
    283static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
    284			     u16 phydata)
    285{
    286	struct net_device *ndev = bus->priv;
    287	struct stmmac_priv *priv = netdev_priv(ndev);
    288	unsigned int mii_address = priv->hw->mii.addr;
    289	unsigned int mii_data = priv->hw->mii.data;
    290	int ret, data = phydata;
    291	u32 value = MII_BUSY;
    292	u32 v;
    293
    294	ret = pm_runtime_resume_and_get(priv->device);
    295	if (ret < 0)
    296		return ret;
    297
    298	value |= (phyaddr << priv->hw->mii.addr_shift)
    299		& priv->hw->mii.addr_mask;
    300	value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
    301
    302	value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
    303		& priv->hw->mii.clk_csr_mask;
    304	if (priv->plat->has_gmac4) {
    305		value |= MII_GMAC4_WRITE;
    306		if (phyreg & MII_ADDR_C45) {
    307			value |= MII_GMAC4_C45E;
    308			value &= ~priv->hw->mii.reg_mask;
    309			value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
    310			       priv->hw->mii.reg_shift) &
    311			       priv->hw->mii.reg_mask;
    312
    313			data |= (phyreg & MII_REGADDR_C45_MASK) <<
    314				MII_GMAC4_REG_ADDR_SHIFT;
    315		}
    316	} else {
    317		value |= MII_WRITE;
    318	}
    319
    320	/* Wait until any existing MII operation is complete */
    321	if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
    322			       100, 10000)) {
    323		ret = -EBUSY;
    324		goto err_disable_clks;
    325	}
    326
    327	/* Set the MII address register to write */
    328	writel(data, priv->ioaddr + mii_data);
    329	writel(value, priv->ioaddr + mii_address);
    330
    331	/* Wait until any existing MII operation is complete */
    332	ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
    333				 100, 10000);
    334
    335err_disable_clks:
    336	pm_runtime_put(priv->device);
    337
    338	return ret;
    339}
    340
    341/**
    342 * stmmac_mdio_reset
    343 * @bus: points to the mii_bus structure
    344 * Description: reset the MII bus
    345 */
    346int stmmac_mdio_reset(struct mii_bus *bus)
    347{
    348#if IS_ENABLED(CONFIG_STMMAC_PLATFORM)
    349	struct net_device *ndev = bus->priv;
    350	struct stmmac_priv *priv = netdev_priv(ndev);
    351	unsigned int mii_address = priv->hw->mii.addr;
    352
    353#ifdef CONFIG_OF
    354	if (priv->device->of_node) {
    355		struct gpio_desc *reset_gpio;
    356		u32 delays[3] = { 0, 0, 0 };
    357
    358		reset_gpio = devm_gpiod_get_optional(priv->device,
    359						     "snps,reset",
    360						     GPIOD_OUT_LOW);
    361		if (IS_ERR(reset_gpio))
    362			return PTR_ERR(reset_gpio);
    363
    364		device_property_read_u32_array(priv->device,
    365					       "snps,reset-delays-us",
    366					       delays, ARRAY_SIZE(delays));
    367
    368		if (delays[0])
    369			msleep(DIV_ROUND_UP(delays[0], 1000));
    370
    371		gpiod_set_value_cansleep(reset_gpio, 1);
    372		if (delays[1])
    373			msleep(DIV_ROUND_UP(delays[1], 1000));
    374
    375		gpiod_set_value_cansleep(reset_gpio, 0);
    376		if (delays[2])
    377			msleep(DIV_ROUND_UP(delays[2], 1000));
    378	}
    379#endif
    380
    381	/* This is a workaround for problems with the STE101P PHY.
    382	 * It doesn't complete its reset until at least one clock cycle
    383	 * on MDC, so perform a dummy mdio read. To be updated for GMAC4
    384	 * if needed.
    385	 */
    386	if (!priv->plat->has_gmac4)
    387		writel(0, priv->ioaddr + mii_address);
    388#endif
    389	return 0;
    390}
    391
    392int stmmac_xpcs_setup(struct mii_bus *bus)
    393{
    394	struct net_device *ndev = bus->priv;
    395	struct mdio_device *mdiodev;
    396	struct stmmac_priv *priv;
    397	struct dw_xpcs *xpcs;
    398	int mode, addr;
    399
    400	priv = netdev_priv(ndev);
    401	mode = priv->plat->phy_interface;
    402
    403	/* Try to probe the XPCS by scanning all addresses. */
    404	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
    405		mdiodev = mdio_device_create(bus, addr);
    406		if (IS_ERR(mdiodev))
    407			continue;
    408
    409		xpcs = xpcs_create(mdiodev, mode);
    410		if (IS_ERR_OR_NULL(xpcs)) {
    411			mdio_device_free(mdiodev);
    412			continue;
    413		}
    414
    415		priv->hw->xpcs = xpcs;
    416		break;
    417	}
    418
    419	if (!priv->hw->xpcs) {
    420		dev_warn(priv->device, "No xPCS found\n");
    421		return -ENODEV;
    422	}
    423
    424	return 0;
    425}
    426
    427/**
    428 * stmmac_mdio_register
    429 * @ndev: net device structure
    430 * Description: it registers the MII bus
    431 */
    432int stmmac_mdio_register(struct net_device *ndev)
    433{
    434	int err = 0;
    435	struct mii_bus *new_bus;
    436	struct stmmac_priv *priv = netdev_priv(ndev);
    437	struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
    438	struct device_node *mdio_node = priv->plat->mdio_node;
    439	struct device *dev = ndev->dev.parent;
    440	int addr, found, max_addr;
    441
    442	if (!mdio_bus_data)
    443		return 0;
    444
    445	new_bus = mdiobus_alloc();
    446	if (!new_bus)
    447		return -ENOMEM;
    448
    449	if (mdio_bus_data->irqs)
    450		memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
    451
    452	new_bus->name = "stmmac";
    453
    454	if (priv->plat->has_gmac4)
    455		new_bus->probe_capabilities = MDIOBUS_C22_C45;
    456
    457	if (priv->plat->has_xgmac) {
    458		new_bus->read = &stmmac_xgmac2_mdio_read;
    459		new_bus->write = &stmmac_xgmac2_mdio_write;
    460
    461		/* Right now only C22 phys are supported */
    462		max_addr = MII_XGMAC_MAX_C22ADDR + 1;
    463
    464		/* Check if DT specified an unsupported phy addr */
    465		if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)
    466			dev_err(dev, "Unsupported phy_addr (max=%d)\n",
    467					MII_XGMAC_MAX_C22ADDR);
    468	} else {
    469		new_bus->read = &stmmac_mdio_read;
    470		new_bus->write = &stmmac_mdio_write;
    471		max_addr = PHY_MAX_ADDR;
    472	}
    473
    474	if (mdio_bus_data->needs_reset)
    475		new_bus->reset = &stmmac_mdio_reset;
    476
    477	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
    478		 new_bus->name, priv->plat->bus_id);
    479	new_bus->priv = ndev;
    480	new_bus->phy_mask = mdio_bus_data->phy_mask;
    481	new_bus->parent = priv->device;
    482
    483	err = of_mdiobus_register(new_bus, mdio_node);
    484	if (err != 0) {
    485		dev_err_probe(dev, err, "Cannot register the MDIO bus\n");
    486		goto bus_register_fail;
    487	}
    488
    489	/* Looks like we need a dummy read for XGMAC only and C45 PHYs */
    490	if (priv->plat->has_xgmac)
    491		stmmac_xgmac2_mdio_read(new_bus, 0, MII_ADDR_C45);
    492
    493	if (priv->plat->phy_node || mdio_node)
    494		goto bus_register_done;
    495
    496	found = 0;
    497	for (addr = 0; addr < max_addr; addr++) {
    498		struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
    499
    500		if (!phydev)
    501			continue;
    502
    503		/*
    504		 * If an IRQ was provided to be assigned after
    505		 * the bus probe, do it here.
    506		 */
    507		if (!mdio_bus_data->irqs &&
    508		    (mdio_bus_data->probed_phy_irq > 0)) {
    509			new_bus->irq[addr] = mdio_bus_data->probed_phy_irq;
    510			phydev->irq = mdio_bus_data->probed_phy_irq;
    511		}
    512
    513		/*
    514		 * If we're going to bind the MAC to this PHY bus,
    515		 * and no PHY number was provided to the MAC,
    516		 * use the one probed here.
    517		 */
    518		if (priv->plat->phy_addr == -1)
    519			priv->plat->phy_addr = addr;
    520
    521		phy_attached_info(phydev);
    522		found = 1;
    523	}
    524
    525	if (!found && !mdio_node) {
    526		dev_warn(dev, "No PHY found\n");
    527		err = -ENODEV;
    528		goto no_phy_found;
    529	}
    530
    531bus_register_done:
    532	priv->mii = new_bus;
    533
    534	return 0;
    535
    536no_phy_found:
    537	mdiobus_unregister(new_bus);
    538bus_register_fail:
    539	mdiobus_free(new_bus);
    540	return err;
    541}
    542
    543/**
    544 * stmmac_mdio_unregister
    545 * @ndev: net device structure
    546 * Description: it unregisters the MII bus
    547 */
    548int stmmac_mdio_unregister(struct net_device *ndev)
    549{
    550	struct stmmac_priv *priv = netdev_priv(ndev);
    551
    552	if (!priv->mii)
    553		return 0;
    554
    555	if (priv->hw->xpcs) {
    556		mdio_device_free(priv->hw->xpcs->mdiodev);
    557		xpcs_destroy(priv->hw->xpcs);
    558	}
    559
    560	mdiobus_unregister(priv->mii);
    561	priv->mii->priv = NULL;
    562	mdiobus_free(priv->mii);
    563	priv->mii = NULL;
    564
    565	return 0;
    566}