2 * Driver for (BCM4706)? GBit MAC core on BCMA bus.
4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
6 * Licensed under the GNU/GPL. See COPYING for details.
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/bcma/bcma.h>
12 #include <linux/brcmphy.h>
13 #include <linux/etherdevice.h>
14 #include <linux/of_mdio.h>
15 #include <linux/of_net.h>
18 static inline bool bgmac_is_bcm4707_family(struct bcma_device
*core
)
20 switch (core
->bus
->chipinfo
.id
) {
21 case BCMA_CHIP_ID_BCM4707
:
22 case BCMA_CHIP_ID_BCM47094
:
23 case BCMA_CHIP_ID_BCM53018
:
30 /**************************************************
32 **************************************************/
34 static u32
bcma_bgmac_read(struct bgmac
*bgmac
, u16 offset
)
36 return bcma_read32(bgmac
->bcma
.core
, offset
);
39 static void bcma_bgmac_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
41 bcma_write32(bgmac
->bcma
.core
, offset
, value
);
44 static u32
bcma_bgmac_idm_read(struct bgmac
*bgmac
, u16 offset
)
46 return bcma_aread32(bgmac
->bcma
.core
, offset
);
49 static void bcma_bgmac_idm_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
51 return bcma_awrite32(bgmac
->bcma
.core
, offset
, value
);
54 static bool bcma_bgmac_clk_enabled(struct bgmac
*bgmac
)
56 return bcma_core_is_enabled(bgmac
->bcma
.core
);
59 static void bcma_bgmac_clk_enable(struct bgmac
*bgmac
, u32 flags
)
61 bcma_core_enable(bgmac
->bcma
.core
, flags
);
64 static void bcma_bgmac_cco_ctl_maskset(struct bgmac
*bgmac
, u32 offset
,
67 struct bcma_drv_cc
*cc
= &bgmac
->bcma
.core
->bus
->drv_cc
;
69 bcma_chipco_chipctl_maskset(cc
, offset
, mask
, set
);
72 static u32
bcma_bgmac_get_bus_clock(struct bgmac
*bgmac
)
74 struct bcma_drv_cc
*cc
= &bgmac
->bcma
.core
->bus
->drv_cc
;
76 return bcma_pmu_get_bus_clock(cc
);
79 static void bcma_bgmac_cmn_maskset32(struct bgmac
*bgmac
, u16 offset
, u32 mask
,
82 bcma_maskset32(bgmac
->bcma
.cmn
, offset
, mask
, set
);
85 static int bcma_phy_connect(struct bgmac
*bgmac
)
87 struct phy_device
*phy_dev
;
88 char bus_id
[MII_BUS_ID_SIZE
+ 3];
90 /* DT info should be the most accurate */
91 phy_dev
= of_phy_get_and_connect(bgmac
->net_dev
, bgmac
->dev
->of_node
,
96 /* Connect to the PHY */
97 if (bgmac
->mii_bus
&& bgmac
->phyaddr
!= BGMAC_PHY_NOREGS
) {
98 snprintf(bus_id
, sizeof(bus_id
), PHY_ID_FMT
, bgmac
->mii_bus
->id
,
100 phy_dev
= phy_connect(bgmac
->net_dev
, bus_id
, bgmac_adjust_link
,
101 PHY_INTERFACE_MODE_MII
);
102 if (IS_ERR(phy_dev
)) {
103 dev_err(bgmac
->dev
, "PHY connection failed\n");
104 return PTR_ERR(phy_dev
);
110 /* Assume a fixed link to the switch port */
111 return bgmac_phy_connect_direct(bgmac
);
114 static const struct bcma_device_id bgmac_bcma_tbl
[] = {
115 BCMA_CORE(BCMA_MANUF_BCM
, BCMA_CORE_4706_MAC_GBIT
,
116 BCMA_ANY_REV
, BCMA_ANY_CLASS
),
117 BCMA_CORE(BCMA_MANUF_BCM
, BCMA_CORE_MAC_GBIT
, BCMA_ANY_REV
,
121 MODULE_DEVICE_TABLE(bcma
, bgmac_bcma_tbl
);
123 /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
124 static int bgmac_probe(struct bcma_device
*core
)
126 struct bcma_chipinfo
*ci
= &core
->bus
->chipinfo
;
127 struct ssb_sprom
*sprom
= &core
->bus
->sprom
;
128 struct mii_bus
*mii_bus
;
133 bgmac
= bgmac_alloc(&core
->dev
);
137 bgmac
->bcma
.core
= core
;
138 bgmac
->dma_dev
= core
->dma_dev
;
139 bgmac
->irq
= core
->irq
;
141 bcma_set_drvdata(core
, bgmac
);
143 err
= of_get_ethdev_address(bgmac
->dev
->of_node
, bgmac
->net_dev
);
144 if (err
== -EPROBE_DEFER
)
147 /* If no MAC address assigned via device tree, check SPROM */
149 switch (core
->core_unit
) {
160 dev_err(bgmac
->dev
, "Unsupported core_unit %d\n",
165 eth_hw_addr_set(bgmac
->net_dev
, mac
);
168 /* On BCM4706 we need common core to access PHY */
169 if (core
->id
.id
== BCMA_CORE_4706_MAC_GBIT
&&
170 !core
->bus
->drv_gmac_cmn
.core
) {
171 dev_err(bgmac
->dev
, "GMAC CMN core not found (required for BCM4706)\n");
175 bgmac
->bcma
.cmn
= core
->bus
->drv_gmac_cmn
.core
;
177 switch (core
->core_unit
) {
179 bgmac
->phyaddr
= sprom
->et0phyaddr
;
182 bgmac
->phyaddr
= sprom
->et1phyaddr
;
185 bgmac
->phyaddr
= sprom
->et2phyaddr
;
188 bgmac
->phyaddr
&= BGMAC_PHY_MASK
;
189 if (bgmac
->phyaddr
== BGMAC_PHY_MASK
) {
190 dev_err(bgmac
->dev
, "No PHY found\n");
194 dev_info(bgmac
->dev
, "Found PHY addr: %d%s\n", bgmac
->phyaddr
,
195 bgmac
->phyaddr
== BGMAC_PHY_NOREGS
? " (NOREGS)" : "");
197 if (!bgmac_is_bcm4707_family(core
) &&
198 !(ci
->id
== BCMA_CHIP_ID_BCM53573
&& core
->core_unit
== 1)) {
199 struct phy_device
*phydev
;
201 mii_bus
= bcma_mdio_mii_register(bgmac
);
202 if (IS_ERR(mii_bus
)) {
203 err
= PTR_ERR(mii_bus
);
206 bgmac
->mii_bus
= mii_bus
;
208 phydev
= mdiobus_get_phy(bgmac
->mii_bus
, bgmac
->phyaddr
);
209 if (ci
->id
== BCMA_CHIP_ID_BCM53573
&& phydev
&&
210 (phydev
->drv
->phy_id
& phydev
->drv
->phy_id_mask
) == PHY_ID_BCM54210E
)
211 phydev
->dev_flags
|= PHY_BRCM_EN_MASTER_MODE
;
214 if (core
->bus
->hosttype
== BCMA_HOSTTYPE_PCI
) {
215 dev_err(bgmac
->dev
, "PCI setup not implemented\n");
220 bgmac
->has_robosw
= !!(sprom
->boardflags_lo
& BGMAC_BFL_ENETROBO
);
221 if (bgmac
->has_robosw
)
222 dev_warn(bgmac
->dev
, "Support for Roboswitch not implemented\n");
224 if (sprom
->boardflags_lo
& BGMAC_BFL_ENETADM
)
225 dev_warn(bgmac
->dev
, "Support for ADMtek ethernet switch not implemented\n");
229 /* BCM 471X/535X family */
230 case BCMA_CHIP_ID_BCM4716
:
231 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
233 case BCMA_CHIP_ID_BCM47162
:
234 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL2
;
235 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
237 case BCMA_CHIP_ID_BCM5357
:
238 case BCMA_CHIP_ID_BCM53572
:
239 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
240 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
241 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL1
;
242 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_PHY
;
243 if ((ci
->id
== BCMA_CHIP_ID_BCM5357
&& ci
->pkg
== BCMA_PKG_ID_BCM47186
) ||
244 (ci
->id
== BCMA_CHIP_ID_BCM53572
&& ci
->pkg
== BCMA_PKG_ID_BCM47188
)) {
245 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_RGMII
;
246 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
248 if (ci
->id
== BCMA_CHIP_ID_BCM5357
&& ci
->pkg
== BCMA_PKG_ID_BCM5358
)
249 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_EPHYRMII
;
251 case BCMA_CHIP_ID_BCM53573
:
252 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
253 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
254 if (ci
->pkg
== BCMA_PKG_ID_BCM47189
)
255 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
256 if (core
->core_unit
== 0) {
257 bgmac
->feature_flags
|= BGMAC_FEAT_CC4_IF_SW_TYPE
;
258 if (ci
->pkg
== BCMA_PKG_ID_BCM47189
)
259 bgmac
->feature_flags
|=
260 BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII
;
261 } else if (core
->core_unit
== 1) {
262 bgmac
->feature_flags
|= BGMAC_FEAT_IRQ_ID_OOB_6
;
263 bgmac
->feature_flags
|= BGMAC_FEAT_CC7_IF_TYPE_RGMII
;
266 case BCMA_CHIP_ID_BCM4749
:
267 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
268 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
269 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL1
;
270 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_PHY
;
272 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_RGMII
;
273 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
277 case BCMA_CHIP_ID_BCM4707
:
278 case BCMA_CHIP_ID_BCM47094
:
279 case BCMA_CHIP_ID_BCM53018
:
280 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
281 bgmac
->feature_flags
|= BGMAC_FEAT_NO_RESET
;
282 bgmac
->feature_flags
|= BGMAC_FEAT_FORCE_SPEED_2500
;
285 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
286 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
289 if (!bgmac_is_bcm4707_family(core
) && core
->id
.rev
> 2)
290 bgmac
->feature_flags
|= BGMAC_FEAT_MISC_PLL_REQ
;
292 if (core
->id
.id
== BCMA_CORE_4706_MAC_GBIT
) {
293 bgmac
->feature_flags
|= BGMAC_FEAT_CMN_PHY_CTL
;
294 bgmac
->feature_flags
|= BGMAC_FEAT_NO_CLR_MIB
;
297 if (core
->id
.rev
>= 4) {
298 bgmac
->feature_flags
|= BGMAC_FEAT_CMDCFG_SR_REV4
;
299 bgmac
->feature_flags
|= BGMAC_FEAT_TX_MASK_SETUP
;
300 bgmac
->feature_flags
|= BGMAC_FEAT_RX_MASK_SETUP
;
303 bgmac
->read
= bcma_bgmac_read
;
304 bgmac
->write
= bcma_bgmac_write
;
305 bgmac
->idm_read
= bcma_bgmac_idm_read
;
306 bgmac
->idm_write
= bcma_bgmac_idm_write
;
307 bgmac
->clk_enabled
= bcma_bgmac_clk_enabled
;
308 bgmac
->clk_enable
= bcma_bgmac_clk_enable
;
309 bgmac
->cco_ctl_maskset
= bcma_bgmac_cco_ctl_maskset
;
310 bgmac
->get_bus_clock
= bcma_bgmac_get_bus_clock
;
311 bgmac
->cmn_maskset32
= bcma_bgmac_cmn_maskset32
;
312 bgmac
->phy_connect
= bcma_phy_connect
;
314 err
= bgmac_enet_probe(bgmac
);
321 bcma_mdio_mii_unregister(bgmac
->mii_bus
);
323 bcma_set_drvdata(core
, NULL
);
328 static void bgmac_remove(struct bcma_device
*core
)
330 struct bgmac
*bgmac
= bcma_get_drvdata(core
);
332 bcma_mdio_mii_unregister(bgmac
->mii_bus
);
333 bgmac_enet_remove(bgmac
);
334 bcma_set_drvdata(core
, NULL
);
337 static struct bcma_driver bgmac_bcma_driver
= {
338 .name
= KBUILD_MODNAME
,
339 .id_table
= bgmac_bcma_tbl
,
340 .probe
= bgmac_probe
,
341 .remove
= bgmac_remove
,
344 static int __init
bgmac_init(void)
348 err
= bcma_driver_register(&bgmac_bcma_driver
);
351 pr_info("Broadcom 47xx GBit MAC driver loaded\n");
356 static void __exit
bgmac_exit(void)
358 bcma_driver_unregister(&bgmac_bcma_driver
);
361 module_init(bgmac_init
)
362 module_exit(bgmac_exit
)
364 MODULE_AUTHOR("Rafał Miłecki");
365 MODULE_DESCRIPTION("Broadcom iProc GBit BCMA interface driver");
366 MODULE_LICENSE("GPL");