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

emac_mdio.c (4604B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
      4 *
      5 * MDIO implementation for ARC EMAC
      6 */
      7
      8#include <linux/delay.h>
      9#include <linux/of_mdio.h>
     10#include <linux/platform_device.h>
     11#include <linux/gpio/consumer.h>
     12
     13#include "emac.h"
     14
     15/* Number of seconds we wait for "MDIO complete" flag to appear */
     16#define ARC_MDIO_COMPLETE_POLL_COUNT	1
     17
     18/**
     19 * arc_mdio_complete_wait - Waits until MDIO transaction is completed.
     20 * @priv:	Pointer to ARC EMAC private data structure.
     21 *
     22 * returns:	0 on success, -ETIMEDOUT on a timeout.
     23 */
     24static int arc_mdio_complete_wait(struct arc_emac_priv *priv)
     25{
     26	unsigned int i;
     27
     28	for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {
     29		unsigned int status = arc_reg_get(priv, R_STATUS);
     30
     31		status &= MDIO_MASK;
     32
     33		if (status) {
     34			/* Reset "MDIO complete" flag */
     35			arc_reg_set(priv, R_STATUS, status);
     36			return 0;
     37		}
     38
     39		msleep(25);
     40	}
     41
     42	return -ETIMEDOUT;
     43}
     44
     45/**
     46 * arc_mdio_read - MDIO interface read function.
     47 * @bus:	Pointer to MII bus structure.
     48 * @phy_addr:	Address of the PHY device.
     49 * @reg_num:	PHY register to read.
     50 *
     51 * returns:	The register contents on success, -ETIMEDOUT on a timeout.
     52 *
     53 * Reads the contents of the requested register from the requested PHY
     54 * address.
     55 */
     56static int arc_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
     57{
     58	struct arc_emac_priv *priv = bus->priv;
     59	unsigned int value;
     60	int error;
     61
     62	arc_reg_set(priv, R_MDIO,
     63		    0x60020000 | (phy_addr << 23) | (reg_num << 18));
     64
     65	error = arc_mdio_complete_wait(priv);
     66	if (error < 0)
     67		return error;
     68
     69	value = arc_reg_get(priv, R_MDIO) & 0xffff;
     70
     71	dev_dbg(priv->dev, "arc_mdio_read(phy_addr=%i, reg_num=%x) = %x\n",
     72		phy_addr, reg_num, value);
     73
     74	return value;
     75}
     76
     77/**
     78 * arc_mdio_write - MDIO interface write function.
     79 * @bus:	Pointer to MII bus structure.
     80 * @phy_addr:	Address of the PHY device.
     81 * @reg_num:	PHY register to write to.
     82 * @value:	Value to be written into the register.
     83 *
     84 * returns:	0 on success, -ETIMEDOUT on a timeout.
     85 *
     86 * Writes the value to the requested register.
     87 */
     88static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
     89			  int reg_num, u16 value)
     90{
     91	struct arc_emac_priv *priv = bus->priv;
     92
     93	dev_dbg(priv->dev,
     94		"arc_mdio_write(phy_addr=%i, reg_num=%x, value=%x)\n",
     95		phy_addr, reg_num, value);
     96
     97	arc_reg_set(priv, R_MDIO,
     98		    0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
     99
    100	return arc_mdio_complete_wait(priv);
    101}
    102
    103/**
    104 * arc_mdio_reset
    105 * @bus: points to the mii_bus structure
    106 * Description: reset the MII bus
    107 */
    108static int arc_mdio_reset(struct mii_bus *bus)
    109{
    110	struct arc_emac_priv *priv = bus->priv;
    111	struct arc_emac_mdio_bus_data *data = &priv->bus_data;
    112
    113	if (data->reset_gpio) {
    114		gpiod_set_value_cansleep(data->reset_gpio, 1);
    115		msleep(data->msec);
    116		gpiod_set_value_cansleep(data->reset_gpio, 0);
    117	}
    118
    119	return 0;
    120}
    121
    122/**
    123 * arc_mdio_probe - MDIO probe function.
    124 * @priv:	Pointer to ARC EMAC private data structure.
    125 *
    126 * returns:	0 on success, -ENOMEM when mdiobus_alloc
    127 * (to allocate memory for MII bus structure) fails.
    128 *
    129 * Sets up and registers the MDIO interface.
    130 */
    131int arc_mdio_probe(struct arc_emac_priv *priv)
    132{
    133	struct arc_emac_mdio_bus_data *data = &priv->bus_data;
    134	struct device_node *np = priv->dev->of_node;
    135	const char *name = "Synopsys MII Bus";
    136	struct mii_bus *bus;
    137	int error;
    138
    139	bus = mdiobus_alloc();
    140	if (!bus)
    141		return -ENOMEM;
    142
    143	priv->bus = bus;
    144	bus->priv = priv;
    145	bus->parent = priv->dev;
    146	bus->name = name;
    147	bus->read = &arc_mdio_read;
    148	bus->write = &arc_mdio_write;
    149	bus->reset = &arc_mdio_reset;
    150
    151	/* optional reset-related properties */
    152	data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",
    153						   GPIOD_OUT_LOW);
    154	if (IS_ERR(data->reset_gpio)) {
    155		mdiobus_free(bus);
    156		return dev_err_probe(priv->dev, PTR_ERR(data->reset_gpio),
    157				     "Failed to request gpio\n");
    158	}
    159
    160	of_property_read_u32(np, "phy-reset-duration", &data->msec);
    161	/* A sane reset duration should not be longer than 1s */
    162	if (data->msec > 1000)
    163		data->msec = 1;
    164
    165	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
    166
    167	error = of_mdiobus_register(bus, priv->dev->of_node);
    168	if (error) {
    169		mdiobus_free(bus);
    170		return dev_err_probe(priv->dev, error,
    171				     "cannot register MDIO bus %s\n", name);
    172	}
    173
    174	return 0;
    175}
    176
    177/**
    178 * arc_mdio_remove - MDIO remove function.
    179 * @priv:	Pointer to ARC EMAC private data structure.
    180 *
    181 * Unregisters the MDIO and frees any associate memory for MII bus.
    182 */
    183int arc_mdio_remove(struct arc_emac_priv *priv)
    184{
    185	mdiobus_unregister(priv->bus);
    186	mdiobus_free(priv->bus);
    187	priv->bus = NULL;
    188
    189	return 0;
    190}