1 /* 2 * Driver for (BCM4706)? GBit MAC core on BCMA bus. 3 * 4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> 5 * 6 * Licensed under the GNU/GPL. See COPYING for details. 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/bcma/bcma.h> 12 #include <linux/brcmphy.h> 13 #include <linux/etherdevice.h> 14 #include "bgmac.h" 15 16 static inline bool bgmac_is_bcm4707_family(struct bcma_device *core) 17 { 18 switch (core->bus->chipinfo.id) { 19 case BCMA_CHIP_ID_BCM4707: 20 case BCMA_CHIP_ID_BCM47094: 21 case BCMA_CHIP_ID_BCM53018: 22 return true; 23 default: 24 return false; 25 } 26 } 27 28 /************************************************** 29 * BCMA bus ops 30 **************************************************/ 31 32 static u32 bcma_bgmac_read(struct bgmac *bgmac, u16 offset) 33 { 34 return bcma_read32(bgmac->bcma.core, offset); 35 } 36 37 static void bcma_bgmac_write(struct bgmac *bgmac, u16 offset, u32 value) 38 { 39 bcma_write32(bgmac->bcma.core, offset, value); 40 } 41 42 static u32 bcma_bgmac_idm_read(struct bgmac *bgmac, u16 offset) 43 { 44 return bcma_aread32(bgmac->bcma.core, offset); 45 } 46 47 static void bcma_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value) 48 { 49 return bcma_awrite32(bgmac->bcma.core, offset, value); 50 } 51 52 static bool bcma_bgmac_clk_enabled(struct bgmac *bgmac) 53 { 54 return bcma_core_is_enabled(bgmac->bcma.core); 55 } 56 57 static void bcma_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) 58 { 59 bcma_core_enable(bgmac->bcma.core, flags); 60 } 61 62 static void bcma_bgmac_cco_ctl_maskset(struct bgmac *bgmac, u32 offset, 63 u32 mask, u32 set) 64 { 65 struct bcma_drv_cc *cc = &bgmac->bcma.core->bus->drv_cc; 66 67 bcma_chipco_chipctl_maskset(cc, offset, mask, set); 68 } 69 70 static u32 bcma_bgmac_get_bus_clock(struct bgmac *bgmac) 71 { 72 struct bcma_drv_cc *cc = &bgmac->bcma.core->bus->drv_cc; 73 74 return bcma_pmu_get_bus_clock(cc); 75 } 76 77 static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask, 78 u32 set) 79 { 80 bcma_maskset32(bgmac->bcma.cmn, offset, mask, set); 81 } 82 83 static const struct bcma_device_id bgmac_bcma_tbl[] = { 84 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, 85 BCMA_ANY_REV, BCMA_ANY_CLASS), 86 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, 87 BCMA_ANY_CLASS), 88 {}, 89 }; 90 MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl); 91 92 /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */ 93 static int bgmac_probe(struct bcma_device *core) 94 { 95 struct ssb_sprom *sprom = &core->bus->sprom; 96 struct mii_bus *mii_bus; 97 struct bgmac *bgmac; 98 u8 *mac; 99 int err; 100 101 bgmac = kzalloc(sizeof(*bgmac), GFP_KERNEL); 102 if (!bgmac) 103 return -ENOMEM; 104 105 bgmac->bcma.core = core; 106 bgmac->dev = &core->dev; 107 bgmac->dma_dev = core->dma_dev; 108 bgmac->irq = core->irq; 109 110 bcma_set_drvdata(core, bgmac); 111 112 switch (core->core_unit) { 113 case 0: 114 mac = sprom->et0mac; 115 break; 116 case 1: 117 mac = sprom->et1mac; 118 break; 119 case 2: 120 mac = sprom->et2mac; 121 break; 122 default: 123 dev_err(bgmac->dev, "Unsupported core_unit %d\n", 124 core->core_unit); 125 err = -ENOTSUPP; 126 goto err; 127 } 128 129 ether_addr_copy(bgmac->mac_addr, mac); 130 131 /* On BCM4706 we need common core to access PHY */ 132 if (core->id.id == BCMA_CORE_4706_MAC_GBIT && 133 !core->bus->drv_gmac_cmn.core) { 134 dev_err(bgmac->dev, "GMAC CMN core not found (required for BCM4706)\n"); 135 err = -ENODEV; 136 goto err; 137 } 138 bgmac->bcma.cmn = core->bus->drv_gmac_cmn.core; 139 140 switch (core->core_unit) { 141 case 0: 142 bgmac->phyaddr = sprom->et0phyaddr; 143 break; 144 case 1: 145 bgmac->phyaddr = sprom->et1phyaddr; 146 break; 147 case 2: 148 bgmac->phyaddr = sprom->et2phyaddr; 149 break; 150 } 151 bgmac->phyaddr &= BGMAC_PHY_MASK; 152 if (bgmac->phyaddr == BGMAC_PHY_MASK) { 153 dev_err(bgmac->dev, "No PHY found\n"); 154 err = -ENODEV; 155 goto err; 156 } 157 dev_info(bgmac->dev, "Found PHY addr: %d%s\n", bgmac->phyaddr, 158 bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : ""); 159 160 if (!bgmac_is_bcm4707_family(core)) { 161 mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr); 162 if (!IS_ERR(mii_bus)) { 163 err = PTR_ERR(mii_bus); 164 goto err; 165 } 166 167 bgmac->mii_bus = mii_bus; 168 } 169 170 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { 171 dev_err(bgmac->dev, "PCI setup not implemented\n"); 172 err = -ENOTSUPP; 173 goto err1; 174 } 175 176 bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo & 177 BGMAC_BFL_ENETROBO); 178 if (bgmac->has_robosw) 179 dev_warn(bgmac->dev, "Support for Roboswitch not implemented\n"); 180 181 if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) 182 dev_warn(bgmac->dev, "Support for ADMtek ethernet switch not implemented\n"); 183 184 /* Feature Flags */ 185 switch (core->bus->chipinfo.id) { 186 case BCMA_CHIP_ID_BCM5357: 187 bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; 188 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; 189 bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; 190 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; 191 if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47186) { 192 bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; 193 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; 194 } 195 if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM5358) 196 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII; 197 break; 198 case BCMA_CHIP_ID_BCM53572: 199 bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; 200 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; 201 bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; 202 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; 203 if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47188) { 204 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; 205 bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; 206 } 207 break; 208 case BCMA_CHIP_ID_BCM4749: 209 bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; 210 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; 211 bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; 212 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; 213 if (core->bus->chipinfo.pkg == 10) { 214 bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; 215 bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; 216 } 217 break; 218 case BCMA_CHIP_ID_BCM4716: 219 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; 220 /* fallthrough */ 221 case BCMA_CHIP_ID_BCM47162: 222 bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; 223 bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; 224 break; 225 /* bcm4707_family */ 226 case BCMA_CHIP_ID_BCM4707: 227 case BCMA_CHIP_ID_BCM47094: 228 case BCMA_CHIP_ID_BCM53018: 229 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; 230 bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; 231 bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; 232 break; 233 default: 234 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; 235 bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; 236 } 237 238 if (!bgmac_is_bcm4707_family(core) && core->id.rev > 2) 239 bgmac->feature_flags |= BGMAC_FEAT_MISC_PLL_REQ; 240 241 if (core->id.id == BCMA_CORE_4706_MAC_GBIT) { 242 bgmac->feature_flags |= BGMAC_FEAT_CMN_PHY_CTL; 243 bgmac->feature_flags |= BGMAC_FEAT_NO_CLR_MIB; 244 } 245 246 if (core->id.rev >= 4) { 247 bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4; 248 bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP; 249 bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP; 250 } 251 252 bgmac->read = bcma_bgmac_read; 253 bgmac->write = bcma_bgmac_write; 254 bgmac->idm_read = bcma_bgmac_idm_read; 255 bgmac->idm_write = bcma_bgmac_idm_write; 256 bgmac->clk_enabled = bcma_bgmac_clk_enabled; 257 bgmac->clk_enable = bcma_bgmac_clk_enable; 258 bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; 259 bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; 260 bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; 261 262 err = bgmac_enet_probe(bgmac); 263 if (err) 264 goto err1; 265 266 return 0; 267 268 err1: 269 bcma_mdio_mii_unregister(bgmac->mii_bus); 270 err: 271 kfree(bgmac); 272 bcma_set_drvdata(core, NULL); 273 274 return err; 275 } 276 277 static void bgmac_remove(struct bcma_device *core) 278 { 279 struct bgmac *bgmac = bcma_get_drvdata(core); 280 281 bcma_mdio_mii_unregister(bgmac->mii_bus); 282 bgmac_enet_remove(bgmac); 283 bcma_set_drvdata(core, NULL); 284 kfree(bgmac); 285 } 286 287 static struct bcma_driver bgmac_bcma_driver = { 288 .name = KBUILD_MODNAME, 289 .id_table = bgmac_bcma_tbl, 290 .probe = bgmac_probe, 291 .remove = bgmac_remove, 292 }; 293 294 static int __init bgmac_init(void) 295 { 296 int err; 297 298 err = bcma_driver_register(&bgmac_bcma_driver); 299 if (err) 300 return err; 301 pr_info("Broadcom 47xx GBit MAC driver loaded\n"); 302 303 return 0; 304 } 305 306 static void __exit bgmac_exit(void) 307 { 308 bcma_driver_unregister(&bgmac_bcma_driver); 309 } 310 311 module_init(bgmac_init) 312 module_exit(bgmac_exit) 313 314 MODULE_AUTHOR("Rafał Miłecki"); 315 MODULE_LICENSE("GPL"); 316