Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * drivers/net/ethernet/ibm/emac/rgmii.c
0004  *
0005  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
0006  *
0007  * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
0008  *                <benh@kernel.crashing.org>
0009  *
0010  * Based on the arch/ppc version of the driver:
0011  *
0012  * Copyright (c) 2004, 2005 Zultys Technologies.
0013  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
0014  *
0015  * Based on original work by
0016  *  Matt Porter <mporter@kernel.crashing.org>
0017  *  Copyright 2004 MontaVista Software, Inc.
0018  */
0019 #include <linux/slab.h>
0020 #include <linux/kernel.h>
0021 #include <linux/ethtool.h>
0022 #include <linux/of_address.h>
0023 #include <asm/io.h>
0024 
0025 #include "emac.h"
0026 #include "debug.h"
0027 
0028 // XXX FIXME: Axon seems to support a subset of the RGMII, we
0029 // thus need to take that into account and possibly change some
0030 // of the bit settings below that don't seem to quite match the
0031 // AXON spec
0032 
0033 /* RGMIIx_FER */
0034 #define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4))
0035 #define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4))
0036 #define RGMII_FER_RGMII(idx)    (0x5 << ((idx) * 4))
0037 #define RGMII_FER_TBI(idx)  (0x6 << ((idx) * 4))
0038 #define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4))
0039 #define RGMII_FER_MII(idx)  RGMII_FER_GMII(idx)
0040 
0041 /* RGMIIx_SSR */
0042 #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8))
0043 #define RGMII_SSR_10(idx)   (0x1 << ((idx) * 8))
0044 #define RGMII_SSR_100(idx)  (0x2 << ((idx) * 8))
0045 #define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8))
0046 
0047 /* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
0048 static inline int rgmii_valid_mode(int phy_mode)
0049 {
0050     return  phy_interface_mode_is_rgmii(phy_mode) ||
0051         phy_mode == PHY_INTERFACE_MODE_GMII ||
0052         phy_mode == PHY_INTERFACE_MODE_MII ||
0053         phy_mode == PHY_INTERFACE_MODE_TBI ||
0054         phy_mode == PHY_INTERFACE_MODE_RTBI;
0055 }
0056 
0057 static inline u32 rgmii_mode_mask(int mode, int input)
0058 {
0059     switch (mode) {
0060     case PHY_INTERFACE_MODE_RGMII:
0061     case PHY_INTERFACE_MODE_RGMII_ID:
0062     case PHY_INTERFACE_MODE_RGMII_RXID:
0063     case PHY_INTERFACE_MODE_RGMII_TXID:
0064         return RGMII_FER_RGMII(input);
0065     case PHY_INTERFACE_MODE_TBI:
0066         return RGMII_FER_TBI(input);
0067     case PHY_INTERFACE_MODE_GMII:
0068         return RGMII_FER_GMII(input);
0069     case PHY_INTERFACE_MODE_MII:
0070         return RGMII_FER_MII(input);
0071     case PHY_INTERFACE_MODE_RTBI:
0072         return RGMII_FER_RTBI(input);
0073     default:
0074         BUG();
0075     }
0076 }
0077 
0078 int rgmii_attach(struct platform_device *ofdev, int input, int mode)
0079 {
0080     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0081     struct rgmii_regs __iomem *p = dev->base;
0082 
0083     RGMII_DBG(dev, "attach(%d)" NL, input);
0084 
0085     /* Check if we need to attach to a RGMII */
0086     if (input < 0 || !rgmii_valid_mode(mode)) {
0087         printk(KERN_ERR "%pOF: unsupported settings !\n",
0088                ofdev->dev.of_node);
0089         return -ENODEV;
0090     }
0091 
0092     mutex_lock(&dev->lock);
0093 
0094     /* Enable this input */
0095     out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
0096 
0097     printk(KERN_NOTICE "%pOF: input %d in %s mode\n",
0098            ofdev->dev.of_node, input, phy_modes(mode));
0099 
0100     ++dev->users;
0101 
0102     mutex_unlock(&dev->lock);
0103 
0104     return 0;
0105 }
0106 
0107 void rgmii_set_speed(struct platform_device *ofdev, int input, int speed)
0108 {
0109     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0110     struct rgmii_regs __iomem *p = dev->base;
0111     u32 ssr;
0112 
0113     mutex_lock(&dev->lock);
0114 
0115     ssr = in_be32(&p->ssr) & ~RGMII_SSR_MASK(input);
0116 
0117     RGMII_DBG(dev, "speed(%d, %d)" NL, input, speed);
0118 
0119     if (speed == SPEED_1000)
0120         ssr |= RGMII_SSR_1000(input);
0121     else if (speed == SPEED_100)
0122         ssr |= RGMII_SSR_100(input);
0123     else if (speed == SPEED_10)
0124         ssr |= RGMII_SSR_10(input);
0125 
0126     out_be32(&p->ssr, ssr);
0127 
0128     mutex_unlock(&dev->lock);
0129 }
0130 
0131 void rgmii_get_mdio(struct platform_device *ofdev, int input)
0132 {
0133     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0134     struct rgmii_regs __iomem *p = dev->base;
0135     u32 fer;
0136 
0137     RGMII_DBG2(dev, "get_mdio(%d)" NL, input);
0138 
0139     if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
0140         return;
0141 
0142     mutex_lock(&dev->lock);
0143 
0144     fer = in_be32(&p->fer);
0145     fer |= 0x00080000u >> input;
0146     out_be32(&p->fer, fer);
0147     (void)in_be32(&p->fer);
0148 
0149     DBG2(dev, " fer = 0x%08x\n", fer);
0150 }
0151 
0152 void rgmii_put_mdio(struct platform_device *ofdev, int input)
0153 {
0154     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0155     struct rgmii_regs __iomem *p = dev->base;
0156     u32 fer;
0157 
0158     RGMII_DBG2(dev, "put_mdio(%d)" NL, input);
0159 
0160     if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
0161         return;
0162 
0163     fer = in_be32(&p->fer);
0164     fer &= ~(0x00080000u >> input);
0165     out_be32(&p->fer, fer);
0166     (void)in_be32(&p->fer);
0167 
0168     DBG2(dev, " fer = 0x%08x\n", fer);
0169 
0170     mutex_unlock(&dev->lock);
0171 }
0172 
0173 void rgmii_detach(struct platform_device *ofdev, int input)
0174 {
0175     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0176     struct rgmii_regs __iomem *p;
0177 
0178     BUG_ON(!dev || dev->users == 0);
0179     p = dev->base;
0180 
0181     mutex_lock(&dev->lock);
0182 
0183     RGMII_DBG(dev, "detach(%d)" NL, input);
0184 
0185     /* Disable this input */
0186     out_be32(&p->fer, in_be32(&p->fer) & ~RGMII_FER_MASK(input));
0187 
0188     --dev->users;
0189 
0190     mutex_unlock(&dev->lock);
0191 }
0192 
0193 int rgmii_get_regs_len(struct platform_device *ofdev)
0194 {
0195     return sizeof(struct emac_ethtool_regs_subhdr) +
0196         sizeof(struct rgmii_regs);
0197 }
0198 
0199 void *rgmii_dump_regs(struct platform_device *ofdev, void *buf)
0200 {
0201     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0202     struct emac_ethtool_regs_subhdr *hdr = buf;
0203     struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
0204 
0205     hdr->version = 0;
0206     hdr->index = 0; /* for now, are there chips with more than one
0207              * rgmii ? if yes, then we'll add a cell_index
0208              * like we do for emac
0209              */
0210     memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
0211     return regs + 1;
0212 }
0213 
0214 
0215 static int rgmii_probe(struct platform_device *ofdev)
0216 {
0217     struct device_node *np = ofdev->dev.of_node;
0218     struct rgmii_instance *dev;
0219     struct resource regs;
0220     int rc;
0221 
0222     rc = -ENOMEM;
0223     dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL);
0224     if (dev == NULL)
0225         goto err_gone;
0226 
0227     mutex_init(&dev->lock);
0228     dev->ofdev = ofdev;
0229 
0230     rc = -ENXIO;
0231     if (of_address_to_resource(np, 0, &regs)) {
0232         printk(KERN_ERR "%pOF: Can't get registers address\n", np);
0233         goto err_free;
0234     }
0235 
0236     rc = -ENOMEM;
0237     dev->base = (struct rgmii_regs __iomem *)ioremap(regs.start,
0238                          sizeof(struct rgmii_regs));
0239     if (dev->base == NULL) {
0240         printk(KERN_ERR "%pOF: Can't map device registers!\n", np);
0241         goto err_free;
0242     }
0243 
0244     /* Check for RGMII flags */
0245     if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL))
0246         dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
0247 
0248     /* CAB lacks the right properties, fix this up */
0249     if (of_device_is_compatible(ofdev->dev.of_node, "ibm,rgmii-axon"))
0250         dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
0251 
0252     DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n",
0253          in_be32(&dev->base->fer), in_be32(&dev->base->ssr));
0254 
0255     /* Disable all inputs by default */
0256     out_be32(&dev->base->fer, 0);
0257 
0258     printk(KERN_INFO
0259            "RGMII %pOF initialized with%s MDIO support\n",
0260            ofdev->dev.of_node,
0261            (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
0262 
0263     wmb();
0264     platform_set_drvdata(ofdev, dev);
0265 
0266     return 0;
0267 
0268  err_free:
0269     kfree(dev);
0270  err_gone:
0271     return rc;
0272 }
0273 
0274 static int rgmii_remove(struct platform_device *ofdev)
0275 {
0276     struct rgmii_instance *dev = platform_get_drvdata(ofdev);
0277 
0278     WARN_ON(dev->users != 0);
0279 
0280     iounmap(dev->base);
0281     kfree(dev);
0282 
0283     return 0;
0284 }
0285 
0286 static const struct of_device_id rgmii_match[] =
0287 {
0288     {
0289         .compatible = "ibm,rgmii",
0290     },
0291     {
0292         .type       = "emac-rgmii",
0293     },
0294     {},
0295 };
0296 
0297 static struct platform_driver rgmii_driver = {
0298     .driver = {
0299         .name = "emac-rgmii",
0300         .of_match_table = rgmii_match,
0301     },
0302     .probe = rgmii_probe,
0303     .remove = rgmii_remove,
0304 };
0305 
0306 int __init rgmii_init(void)
0307 {
0308     return platform_driver_register(&rgmii_driver);
0309 }
0310 
0311 void rgmii_exit(void)
0312 {
0313     platform_driver_unregister(&rgmii_driver);
0314 }