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_net.h>
17 static inline bool bgmac_is_bcm4707_family(struct bcma_device
*core
)
19 switch (core
->bus
->chipinfo
.id
) {
20 case BCMA_CHIP_ID_BCM4707
:
21 case BCMA_CHIP_ID_BCM47094
:
22 case BCMA_CHIP_ID_BCM53018
:
29 /**************************************************
31 **************************************************/
33 static u32
bcma_bgmac_read(struct bgmac
*bgmac
, u16 offset
)
35 return bcma_read32(bgmac
->bcma
.core
, offset
);
38 static void bcma_bgmac_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
40 bcma_write32(bgmac
->bcma
.core
, offset
, value
);
43 static u32
bcma_bgmac_idm_read(struct bgmac
*bgmac
, u16 offset
)
45 return bcma_aread32(bgmac
->bcma
.core
, offset
);
48 static void bcma_bgmac_idm_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
50 return bcma_awrite32(bgmac
->bcma
.core
, offset
, value
);
53 static bool bcma_bgmac_clk_enabled(struct bgmac
*bgmac
)
55 return bcma_core_is_enabled(bgmac
->bcma
.core
);
58 static void bcma_bgmac_clk_enable(struct bgmac
*bgmac
, u32 flags
)
60 bcma_core_enable(bgmac
->bcma
.core
, flags
);
63 static void bcma_bgmac_cco_ctl_maskset(struct bgmac
*bgmac
, u32 offset
,
66 struct bcma_drv_cc
*cc
= &bgmac
->bcma
.core
->bus
->drv_cc
;
68 bcma_chipco_chipctl_maskset(cc
, offset
, mask
, set
);
71 static u32
bcma_bgmac_get_bus_clock(struct bgmac
*bgmac
)
73 struct bcma_drv_cc
*cc
= &bgmac
->bcma
.core
->bus
->drv_cc
;
75 return bcma_pmu_get_bus_clock(cc
);
78 static void bcma_bgmac_cmn_maskset32(struct bgmac
*bgmac
, u16 offset
, u32 mask
,
81 bcma_maskset32(bgmac
->bcma
.cmn
, offset
, mask
, set
);
84 static int bcma_phy_connect(struct bgmac
*bgmac
)
86 struct phy_device
*phy_dev
;
87 char bus_id
[MII_BUS_ID_SIZE
+ 3];
89 /* Connect to the PHY */
90 snprintf(bus_id
, sizeof(bus_id
), PHY_ID_FMT
, bgmac
->mii_bus
->id
,
92 phy_dev
= phy_connect(bgmac
->net_dev
, bus_id
, bgmac_adjust_link
,
93 PHY_INTERFACE_MODE_MII
);
94 if (IS_ERR(phy_dev
)) {
95 dev_err(bgmac
->dev
, "PHY connection failed\n");
96 return PTR_ERR(phy_dev
);
102 static const struct bcma_device_id bgmac_bcma_tbl
[] = {
103 BCMA_CORE(BCMA_MANUF_BCM
, BCMA_CORE_4706_MAC_GBIT
,
104 BCMA_ANY_REV
, BCMA_ANY_CLASS
),
105 BCMA_CORE(BCMA_MANUF_BCM
, BCMA_CORE_MAC_GBIT
, BCMA_ANY_REV
,
109 MODULE_DEVICE_TABLE(bcma
, bgmac_bcma_tbl
);
111 /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
112 static int bgmac_probe(struct bcma_device
*core
)
114 struct bcma_chipinfo
*ci
= &core
->bus
->chipinfo
;
115 struct ssb_sprom
*sprom
= &core
->bus
->sprom
;
116 struct mii_bus
*mii_bus
;
118 const u8
*mac
= NULL
;
121 bgmac
= bgmac_alloc(&core
->dev
);
125 bgmac
->bcma
.core
= core
;
126 bgmac
->dma_dev
= core
->dma_dev
;
127 bgmac
->irq
= core
->irq
;
129 bcma_set_drvdata(core
, bgmac
);
131 if (bgmac
->dev
->of_node
)
132 mac
= of_get_mac_address(bgmac
->dev
->of_node
);
134 /* If no MAC address assigned via device tree, check SPROM */
136 switch (core
->core_unit
) {
147 dev_err(bgmac
->dev
, "Unsupported core_unit %d\n",
154 ether_addr_copy(bgmac
->net_dev
->dev_addr
, mac
);
156 /* On BCM4706 we need common core to access PHY */
157 if (core
->id
.id
== BCMA_CORE_4706_MAC_GBIT
&&
158 !core
->bus
->drv_gmac_cmn
.core
) {
159 dev_err(bgmac
->dev
, "GMAC CMN core not found (required for BCM4706)\n");
163 bgmac
->bcma
.cmn
= core
->bus
->drv_gmac_cmn
.core
;
165 switch (core
->core_unit
) {
167 bgmac
->phyaddr
= sprom
->et0phyaddr
;
170 bgmac
->phyaddr
= sprom
->et1phyaddr
;
173 bgmac
->phyaddr
= sprom
->et2phyaddr
;
176 bgmac
->phyaddr
&= BGMAC_PHY_MASK
;
177 if (bgmac
->phyaddr
== BGMAC_PHY_MASK
) {
178 dev_err(bgmac
->dev
, "No PHY found\n");
182 dev_info(bgmac
->dev
, "Found PHY addr: %d%s\n", bgmac
->phyaddr
,
183 bgmac
->phyaddr
== BGMAC_PHY_NOREGS
? " (NOREGS)" : "");
185 if (!bgmac_is_bcm4707_family(core
) &&
186 !(ci
->id
== BCMA_CHIP_ID_BCM53573
&& core
->core_unit
== 1)) {
187 mii_bus
= bcma_mdio_mii_register(bgmac
);
188 if (IS_ERR(mii_bus
)) {
189 err
= PTR_ERR(mii_bus
);
193 bgmac
->mii_bus
= mii_bus
;
196 if (core
->bus
->hosttype
== BCMA_HOSTTYPE_PCI
) {
197 dev_err(bgmac
->dev
, "PCI setup not implemented\n");
202 bgmac
->has_robosw
= !!(sprom
->boardflags_lo
& BGMAC_BFL_ENETROBO
);
203 if (bgmac
->has_robosw
)
204 dev_warn(bgmac
->dev
, "Support for Roboswitch not implemented\n");
206 if (sprom
->boardflags_lo
& BGMAC_BFL_ENETADM
)
207 dev_warn(bgmac
->dev
, "Support for ADMtek ethernet switch not implemented\n");
211 /* BCM 471X/535X family */
212 case BCMA_CHIP_ID_BCM4716
:
213 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
215 case BCMA_CHIP_ID_BCM47162
:
216 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL2
;
217 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
219 case BCMA_CHIP_ID_BCM5357
:
220 case BCMA_CHIP_ID_BCM53572
:
221 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
222 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
223 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL1
;
224 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_PHY
;
225 if (ci
->pkg
== BCMA_PKG_ID_BCM47188
||
226 ci
->pkg
== BCMA_PKG_ID_BCM47186
) {
227 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_RGMII
;
228 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
230 if (ci
->pkg
== BCMA_PKG_ID_BCM5358
)
231 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_EPHYRMII
;
233 case BCMA_CHIP_ID_BCM53573
:
234 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
235 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
236 if (ci
->pkg
== BCMA_PKG_ID_BCM47189
)
237 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
238 if (core
->core_unit
== 0) {
239 bgmac
->feature_flags
|= BGMAC_FEAT_CC4_IF_SW_TYPE
;
240 if (ci
->pkg
== BCMA_PKG_ID_BCM47189
)
241 bgmac
->feature_flags
|=
242 BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII
;
243 } else if (core
->core_unit
== 1) {
244 bgmac
->feature_flags
|= BGMAC_FEAT_IRQ_ID_OOB_6
;
245 bgmac
->feature_flags
|= BGMAC_FEAT_CC7_IF_TYPE_RGMII
;
248 case BCMA_CHIP_ID_BCM4749
:
249 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
250 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
251 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL1
;
252 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_PHY
;
254 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_RGMII
;
255 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
259 case BCMA_CHIP_ID_BCM4707
:
260 case BCMA_CHIP_ID_BCM47094
:
261 case BCMA_CHIP_ID_BCM53018
:
262 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
263 bgmac
->feature_flags
|= BGMAC_FEAT_NO_RESET
;
264 bgmac
->feature_flags
|= BGMAC_FEAT_FORCE_SPEED_2500
;
267 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
268 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
271 if (!bgmac_is_bcm4707_family(core
) && core
->id
.rev
> 2)
272 bgmac
->feature_flags
|= BGMAC_FEAT_MISC_PLL_REQ
;
274 if (core
->id
.id
== BCMA_CORE_4706_MAC_GBIT
) {
275 bgmac
->feature_flags
|= BGMAC_FEAT_CMN_PHY_CTL
;
276 bgmac
->feature_flags
|= BGMAC_FEAT_NO_CLR_MIB
;
279 if (core
->id
.rev
>= 4) {
280 bgmac
->feature_flags
|= BGMAC_FEAT_CMDCFG_SR_REV4
;
281 bgmac
->feature_flags
|= BGMAC_FEAT_TX_MASK_SETUP
;
282 bgmac
->feature_flags
|= BGMAC_FEAT_RX_MASK_SETUP
;
285 bgmac
->read
= bcma_bgmac_read
;
286 bgmac
->write
= bcma_bgmac_write
;
287 bgmac
->idm_read
= bcma_bgmac_idm_read
;
288 bgmac
->idm_write
= bcma_bgmac_idm_write
;
289 bgmac
->clk_enabled
= bcma_bgmac_clk_enabled
;
290 bgmac
->clk_enable
= bcma_bgmac_clk_enable
;
291 bgmac
->cco_ctl_maskset
= bcma_bgmac_cco_ctl_maskset
;
292 bgmac
->get_bus_clock
= bcma_bgmac_get_bus_clock
;
293 bgmac
->cmn_maskset32
= bcma_bgmac_cmn_maskset32
;
295 bgmac
->phy_connect
= bcma_phy_connect
;
297 bgmac
->phy_connect
= bgmac_phy_connect_direct
;
299 err
= bgmac_enet_probe(bgmac
);
306 bcma_mdio_mii_unregister(bgmac
->mii_bus
);
308 bcma_set_drvdata(core
, NULL
);
313 static void bgmac_remove(struct bcma_device
*core
)
315 struct bgmac
*bgmac
= bcma_get_drvdata(core
);
317 bcma_mdio_mii_unregister(bgmac
->mii_bus
);
318 bgmac_enet_remove(bgmac
);
319 bcma_set_drvdata(core
, NULL
);
323 static struct bcma_driver bgmac_bcma_driver
= {
324 .name
= KBUILD_MODNAME
,
325 .id_table
= bgmac_bcma_tbl
,
326 .probe
= bgmac_probe
,
327 .remove
= bgmac_remove
,
330 static int __init
bgmac_init(void)
334 err
= bcma_driver_register(&bgmac_bcma_driver
);
337 pr_info("Broadcom 47xx GBit MAC driver loaded\n");
342 static void __exit
bgmac_exit(void)
344 bcma_driver_unregister(&bgmac_bcma_driver
);
347 module_init(bgmac_init
)
348 module_exit(bgmac_exit
)
350 MODULE_AUTHOR("Rafał Miłecki");
351 MODULE_LICENSE("GPL");