0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010
0011 #include <linux/bcma/bcma.h>
0012 #include <linux/brcmphy.h>
0013 #include <linux/of_mdio.h>
0014 #include "bgmac.h"
0015
0016 static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
0017 u32 value, int timeout)
0018 {
0019 u32 val;
0020 int i;
0021
0022 for (i = 0; i < timeout / 10; i++) {
0023 val = bcma_read32(core, reg);
0024 if ((val & mask) == value)
0025 return true;
0026 udelay(10);
0027 }
0028 dev_err(&core->dev, "Timeout waiting for reg 0x%X\n", reg);
0029 return false;
0030 }
0031
0032
0033
0034
0035
0036 static u16 bcma_mdio_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
0037 {
0038 struct bcma_device *core;
0039 u16 phy_access_addr;
0040 u16 phy_ctl_addr;
0041 u32 tmp;
0042
0043 BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
0044 BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
0045 BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
0046 BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
0047 BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
0048 BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
0049 BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
0050 BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
0051 BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
0052 BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
0053 BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
0054
0055 if (bgmac->bcma.core->id.id == BCMA_CORE_4706_MAC_GBIT) {
0056 core = bgmac->bcma.core->bus->drv_gmac_cmn.core;
0057 phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
0058 phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
0059 } else {
0060 core = bgmac->bcma.core;
0061 phy_access_addr = BGMAC_PHY_ACCESS;
0062 phy_ctl_addr = BGMAC_PHY_CNTL;
0063 }
0064
0065 tmp = bcma_read32(core, phy_ctl_addr);
0066 tmp &= ~BGMAC_PC_EPA_MASK;
0067 tmp |= phyaddr;
0068 bcma_write32(core, phy_ctl_addr, tmp);
0069
0070 tmp = BGMAC_PA_START;
0071 tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
0072 tmp |= reg << BGMAC_PA_REG_SHIFT;
0073 bcma_write32(core, phy_access_addr, tmp);
0074
0075 if (!bcma_mdio_wait_value(core, phy_access_addr, BGMAC_PA_START, 0,
0076 1000)) {
0077 dev_err(&core->dev, "Reading PHY %d register 0x%X failed\n",
0078 phyaddr, reg);
0079 return 0xffff;
0080 }
0081
0082 return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
0083 }
0084
0085
0086 static int bcma_mdio_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg,
0087 u16 value)
0088 {
0089 struct bcma_device *core;
0090 u16 phy_access_addr;
0091 u16 phy_ctl_addr;
0092 u32 tmp;
0093
0094 if (bgmac->bcma.core->id.id == BCMA_CORE_4706_MAC_GBIT) {
0095 core = bgmac->bcma.core->bus->drv_gmac_cmn.core;
0096 phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
0097 phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
0098 } else {
0099 core = bgmac->bcma.core;
0100 phy_access_addr = BGMAC_PHY_ACCESS;
0101 phy_ctl_addr = BGMAC_PHY_CNTL;
0102 }
0103
0104 tmp = bcma_read32(core, phy_ctl_addr);
0105 tmp &= ~BGMAC_PC_EPA_MASK;
0106 tmp |= phyaddr;
0107 bcma_write32(core, phy_ctl_addr, tmp);
0108
0109 bcma_write32(bgmac->bcma.core, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
0110 if (bcma_read32(bgmac->bcma.core, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
0111 dev_warn(&core->dev, "Error setting MDIO int\n");
0112
0113 tmp = BGMAC_PA_START;
0114 tmp |= BGMAC_PA_WRITE;
0115 tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
0116 tmp |= reg << BGMAC_PA_REG_SHIFT;
0117 tmp |= value;
0118 bcma_write32(core, phy_access_addr, tmp);
0119
0120 if (!bcma_mdio_wait_value(core, phy_access_addr, BGMAC_PA_START, 0,
0121 1000)) {
0122 dev_err(&core->dev, "Writing to PHY %d register 0x%X failed\n",
0123 phyaddr, reg);
0124 return -ETIMEDOUT;
0125 }
0126
0127 return 0;
0128 }
0129
0130
0131 static void bcma_mdio_phy_init(struct bgmac *bgmac)
0132 {
0133 struct bcma_chipinfo *ci = &bgmac->bcma.core->bus->chipinfo;
0134 u8 i;
0135
0136
0137
0138
0139
0140 if (ci->id == BCMA_CHIP_ID_BCM5356) {
0141 for (i = 0; i < 5; i++) {
0142 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x008b);
0143 bcma_mdio_phy_write(bgmac, i, 0x15, 0x0100);
0144 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000f);
0145 bcma_mdio_phy_write(bgmac, i, 0x12, 0x2aaa);
0146 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b);
0147 }
0148 return;
0149 }
0150 if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
0151 (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
0152 (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
0153 struct bcma_drv_cc *cc = &bgmac->bcma.core->bus->drv_cc;
0154
0155 bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
0156 bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
0157 for (i = 0; i < 5; i++) {
0158 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000f);
0159 bcma_mdio_phy_write(bgmac, i, 0x16, 0x5284);
0160 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b);
0161 bcma_mdio_phy_write(bgmac, i, 0x17, 0x0010);
0162 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000f);
0163 bcma_mdio_phy_write(bgmac, i, 0x16, 0x5296);
0164 bcma_mdio_phy_write(bgmac, i, 0x17, 0x1073);
0165 bcma_mdio_phy_write(bgmac, i, 0x17, 0x9073);
0166 bcma_mdio_phy_write(bgmac, i, 0x16, 0x52b6);
0167 bcma_mdio_phy_write(bgmac, i, 0x17, 0x9273);
0168 bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b);
0169 }
0170 return;
0171 }
0172
0173
0174 if (bgmac->net_dev && bgmac->net_dev->phydev)
0175 phy_init_hw(bgmac->net_dev->phydev);
0176 }
0177
0178
0179 static int bcma_mdio_phy_reset(struct mii_bus *bus)
0180 {
0181 struct bgmac *bgmac = bus->priv;
0182 u8 phyaddr = bgmac->phyaddr;
0183
0184 if (phyaddr == BGMAC_PHY_NOREGS)
0185 return 0;
0186
0187 bcma_mdio_phy_write(bgmac, phyaddr, MII_BMCR, BMCR_RESET);
0188 udelay(100);
0189 if (bcma_mdio_phy_read(bgmac, phyaddr, MII_BMCR) & BMCR_RESET)
0190 dev_err(bgmac->dev, "PHY reset failed\n");
0191 bcma_mdio_phy_init(bgmac);
0192
0193 return 0;
0194 }
0195
0196
0197
0198
0199
0200 static int bcma_mdio_mii_read(struct mii_bus *bus, int mii_id, int regnum)
0201 {
0202 return bcma_mdio_phy_read(bus->priv, mii_id, regnum);
0203 }
0204
0205 static int bcma_mdio_mii_write(struct mii_bus *bus, int mii_id, int regnum,
0206 u16 value)
0207 {
0208 return bcma_mdio_phy_write(bus->priv, mii_id, regnum, value);
0209 }
0210
0211 struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac)
0212 {
0213 struct bcma_device *core = bgmac->bcma.core;
0214 struct mii_bus *mii_bus;
0215 struct device_node *np;
0216 int err;
0217
0218 mii_bus = mdiobus_alloc();
0219 if (!mii_bus) {
0220 err = -ENOMEM;
0221 goto err;
0222 }
0223
0224 mii_bus->name = "bcma_mdio mii bus";
0225 sprintf(mii_bus->id, "%s-%d-%d", "bcma_mdio", core->bus->num,
0226 core->core_unit);
0227 mii_bus->priv = bgmac;
0228 mii_bus->read = bcma_mdio_mii_read;
0229 mii_bus->write = bcma_mdio_mii_write;
0230 mii_bus->reset = bcma_mdio_phy_reset;
0231 mii_bus->parent = &core->dev;
0232 mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
0233
0234 np = of_get_child_by_name(core->dev.of_node, "mdio");
0235
0236 err = of_mdiobus_register(mii_bus, np);
0237 of_node_put(np);
0238 if (err) {
0239 dev_err(&core->dev, "Registration of mii bus failed\n");
0240 goto err_free_bus;
0241 }
0242
0243 return mii_bus;
0244
0245 err_free_bus:
0246 mdiobus_free(mii_bus);
0247 err:
0248 return ERR_PTR(err);
0249 }
0250 EXPORT_SYMBOL_GPL(bcma_mdio_mii_register);
0251
0252 void bcma_mdio_mii_unregister(struct mii_bus *mii_bus)
0253 {
0254 if (!mii_bus)
0255 return;
0256
0257 mdiobus_unregister(mii_bus);
0258 mdiobus_free(mii_bus);
0259 }
0260 EXPORT_SYMBOL_GPL(bcma_mdio_mii_unregister);
0261
0262 MODULE_AUTHOR("Rafał Miłecki");
0263 MODULE_LICENSE("GPL");