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

rgmii.c (7561B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * drivers/net/ethernet/ibm/emac/rgmii.c
      4 *
      5 * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
      6 *
      7 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
      8 *                <benh@kernel.crashing.org>
      9 *
     10 * Based on the arch/ppc version of the driver:
     11 *
     12 * Copyright (c) 2004, 2005 Zultys Technologies.
     13 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
     14 *
     15 * Based on original work by
     16 * 	Matt Porter <mporter@kernel.crashing.org>
     17 * 	Copyright 2004 MontaVista Software, Inc.
     18 */
     19#include <linux/slab.h>
     20#include <linux/kernel.h>
     21#include <linux/ethtool.h>
     22#include <linux/of_address.h>
     23#include <asm/io.h>
     24
     25#include "emac.h"
     26#include "debug.h"
     27
     28// XXX FIXME: Axon seems to support a subset of the RGMII, we
     29// thus need to take that into account and possibly change some
     30// of the bit settings below that don't seem to quite match the
     31// AXON spec
     32
     33/* RGMIIx_FER */
     34#define RGMII_FER_MASK(idx)	(0x7 << ((idx) * 4))
     35#define RGMII_FER_RTBI(idx)	(0x4 << ((idx) * 4))
     36#define RGMII_FER_RGMII(idx)	(0x5 << ((idx) * 4))
     37#define RGMII_FER_TBI(idx)	(0x6 << ((idx) * 4))
     38#define RGMII_FER_GMII(idx)	(0x7 << ((idx) * 4))
     39#define RGMII_FER_MII(idx)	RGMII_FER_GMII(idx)
     40
     41/* RGMIIx_SSR */
     42#define RGMII_SSR_MASK(idx)	(0x7 << ((idx) * 8))
     43#define RGMII_SSR_10(idx)	(0x1 << ((idx) * 8))
     44#define RGMII_SSR_100(idx)	(0x2 << ((idx) * 8))
     45#define RGMII_SSR_1000(idx)	(0x4 << ((idx) * 8))
     46
     47/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
     48static inline int rgmii_valid_mode(int phy_mode)
     49{
     50	return  phy_interface_mode_is_rgmii(phy_mode) ||
     51		phy_mode == PHY_INTERFACE_MODE_GMII ||
     52		phy_mode == PHY_INTERFACE_MODE_MII ||
     53		phy_mode == PHY_INTERFACE_MODE_TBI ||
     54		phy_mode == PHY_INTERFACE_MODE_RTBI;
     55}
     56
     57static inline u32 rgmii_mode_mask(int mode, int input)
     58{
     59	switch (mode) {
     60	case PHY_INTERFACE_MODE_RGMII:
     61	case PHY_INTERFACE_MODE_RGMII_ID:
     62	case PHY_INTERFACE_MODE_RGMII_RXID:
     63	case PHY_INTERFACE_MODE_RGMII_TXID:
     64		return RGMII_FER_RGMII(input);
     65	case PHY_INTERFACE_MODE_TBI:
     66		return RGMII_FER_TBI(input);
     67	case PHY_INTERFACE_MODE_GMII:
     68		return RGMII_FER_GMII(input);
     69	case PHY_INTERFACE_MODE_MII:
     70		return RGMII_FER_MII(input);
     71	case PHY_INTERFACE_MODE_RTBI:
     72		return RGMII_FER_RTBI(input);
     73	default:
     74		BUG();
     75	}
     76}
     77
     78int rgmii_attach(struct platform_device *ofdev, int input, int mode)
     79{
     80	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
     81	struct rgmii_regs __iomem *p = dev->base;
     82
     83	RGMII_DBG(dev, "attach(%d)" NL, input);
     84
     85	/* Check if we need to attach to a RGMII */
     86	if (input < 0 || !rgmii_valid_mode(mode)) {
     87		printk(KERN_ERR "%pOF: unsupported settings !\n",
     88		       ofdev->dev.of_node);
     89		return -ENODEV;
     90	}
     91
     92	mutex_lock(&dev->lock);
     93
     94	/* Enable this input */
     95	out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
     96
     97	printk(KERN_NOTICE "%pOF: input %d in %s mode\n",
     98	       ofdev->dev.of_node, input, phy_modes(mode));
     99
    100	++dev->users;
    101
    102	mutex_unlock(&dev->lock);
    103
    104	return 0;
    105}
    106
    107void rgmii_set_speed(struct platform_device *ofdev, int input, int speed)
    108{
    109	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
    110	struct rgmii_regs __iomem *p = dev->base;
    111	u32 ssr;
    112
    113	mutex_lock(&dev->lock);
    114
    115	ssr = in_be32(&p->ssr) & ~RGMII_SSR_MASK(input);
    116
    117	RGMII_DBG(dev, "speed(%d, %d)" NL, input, speed);
    118
    119	if (speed == SPEED_1000)
    120		ssr |= RGMII_SSR_1000(input);
    121	else if (speed == SPEED_100)
    122		ssr |= RGMII_SSR_100(input);
    123	else if (speed == SPEED_10)
    124		ssr |= RGMII_SSR_10(input);
    125
    126	out_be32(&p->ssr, ssr);
    127
    128	mutex_unlock(&dev->lock);
    129}
    130
    131void rgmii_get_mdio(struct platform_device *ofdev, int input)
    132{
    133	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
    134	struct rgmii_regs __iomem *p = dev->base;
    135	u32 fer;
    136
    137	RGMII_DBG2(dev, "get_mdio(%d)" NL, input);
    138
    139	if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
    140		return;
    141
    142	mutex_lock(&dev->lock);
    143
    144	fer = in_be32(&p->fer);
    145	fer |= 0x00080000u >> input;
    146	out_be32(&p->fer, fer);
    147	(void)in_be32(&p->fer);
    148
    149	DBG2(dev, " fer = 0x%08x\n", fer);
    150}
    151
    152void rgmii_put_mdio(struct platform_device *ofdev, int input)
    153{
    154	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
    155	struct rgmii_regs __iomem *p = dev->base;
    156	u32 fer;
    157
    158	RGMII_DBG2(dev, "put_mdio(%d)" NL, input);
    159
    160	if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
    161		return;
    162
    163	fer = in_be32(&p->fer);
    164	fer &= ~(0x00080000u >> input);
    165	out_be32(&p->fer, fer);
    166	(void)in_be32(&p->fer);
    167
    168	DBG2(dev, " fer = 0x%08x\n", fer);
    169
    170	mutex_unlock(&dev->lock);
    171}
    172
    173void rgmii_detach(struct platform_device *ofdev, int input)
    174{
    175	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
    176	struct rgmii_regs __iomem *p;
    177
    178	BUG_ON(!dev || dev->users == 0);
    179	p = dev->base;
    180
    181	mutex_lock(&dev->lock);
    182
    183	RGMII_DBG(dev, "detach(%d)" NL, input);
    184
    185	/* Disable this input */
    186	out_be32(&p->fer, in_be32(&p->fer) & ~RGMII_FER_MASK(input));
    187
    188	--dev->users;
    189
    190	mutex_unlock(&dev->lock);
    191}
    192
    193int rgmii_get_regs_len(struct platform_device *ofdev)
    194{
    195	return sizeof(struct emac_ethtool_regs_subhdr) +
    196		sizeof(struct rgmii_regs);
    197}
    198
    199void *rgmii_dump_regs(struct platform_device *ofdev, void *buf)
    200{
    201	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
    202	struct emac_ethtool_regs_subhdr *hdr = buf;
    203	struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
    204
    205	hdr->version = 0;
    206	hdr->index = 0; /* for now, are there chips with more than one
    207			 * rgmii ? if yes, then we'll add a cell_index
    208			 * like we do for emac
    209			 */
    210	memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
    211	return regs + 1;
    212}
    213
    214
    215static int rgmii_probe(struct platform_device *ofdev)
    216{
    217	struct device_node *np = ofdev->dev.of_node;
    218	struct rgmii_instance *dev;
    219	struct resource regs;
    220	int rc;
    221
    222	rc = -ENOMEM;
    223	dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL);
    224	if (dev == NULL)
    225		goto err_gone;
    226
    227	mutex_init(&dev->lock);
    228	dev->ofdev = ofdev;
    229
    230	rc = -ENXIO;
    231	if (of_address_to_resource(np, 0, &regs)) {
    232		printk(KERN_ERR "%pOF: Can't get registers address\n", np);
    233		goto err_free;
    234	}
    235
    236	rc = -ENOMEM;
    237	dev->base = (struct rgmii_regs __iomem *)ioremap(regs.start,
    238						 sizeof(struct rgmii_regs));
    239	if (dev->base == NULL) {
    240		printk(KERN_ERR "%pOF: Can't map device registers!\n", np);
    241		goto err_free;
    242	}
    243
    244	/* Check for RGMII flags */
    245	if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL))
    246		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
    247
    248	/* CAB lacks the right properties, fix this up */
    249	if (of_device_is_compatible(ofdev->dev.of_node, "ibm,rgmii-axon"))
    250		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
    251
    252	DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n",
    253	     in_be32(&dev->base->fer), in_be32(&dev->base->ssr));
    254
    255	/* Disable all inputs by default */
    256	out_be32(&dev->base->fer, 0);
    257
    258	printk(KERN_INFO
    259	       "RGMII %pOF initialized with%s MDIO support\n",
    260	       ofdev->dev.of_node,
    261	       (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
    262
    263	wmb();
    264	platform_set_drvdata(ofdev, dev);
    265
    266	return 0;
    267
    268 err_free:
    269	kfree(dev);
    270 err_gone:
    271	return rc;
    272}
    273
    274static int rgmii_remove(struct platform_device *ofdev)
    275{
    276	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
    277
    278	WARN_ON(dev->users != 0);
    279
    280	iounmap(dev->base);
    281	kfree(dev);
    282
    283	return 0;
    284}
    285
    286static const struct of_device_id rgmii_match[] =
    287{
    288	{
    289		.compatible	= "ibm,rgmii",
    290	},
    291	{
    292		.type		= "emac-rgmii",
    293	},
    294	{},
    295};
    296
    297static struct platform_driver rgmii_driver = {
    298	.driver = {
    299		.name = "emac-rgmii",
    300		.of_match_table = rgmii_match,
    301	},
    302	.probe = rgmii_probe,
    303	.remove = rgmii_remove,
    304};
    305
    306int __init rgmii_init(void)
    307{
    308	return platform_driver_register(&rgmii_driver);
    309}
    310
    311void rgmii_exit(void)
    312{
    313	platform_driver_unregister(&rgmii_driver);
    314}