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 struct phy_device
*phydev
;
189 mii_bus
= bcma_mdio_mii_register(bgmac
);
190 if (IS_ERR(mii_bus
)) {
191 err
= PTR_ERR(mii_bus
);
194 bgmac
->mii_bus
= mii_bus
;
196 phydev
= mdiobus_get_phy(bgmac
->mii_bus
, bgmac
->phyaddr
);
197 if (ci
->id
== BCMA_CHIP_ID_BCM53573
&& phydev
&&
198 (phydev
->drv
->phy_id
& phydev
->drv
->phy_id_mask
) == PHY_ID_BCM54210E
)
199 phydev
->dev_flags
|= PHY_BRCM_EN_MASTER_MODE
;
202 if (core
->bus
->hosttype
== BCMA_HOSTTYPE_PCI
) {
203 dev_err(bgmac
->dev
, "PCI setup not implemented\n");
208 bgmac
->has_robosw
= !!(sprom
->boardflags_lo
& BGMAC_BFL_ENETROBO
);
209 if (bgmac
->has_robosw
)
210 dev_warn(bgmac
->dev
, "Support for Roboswitch not implemented\n");
212 if (sprom
->boardflags_lo
& BGMAC_BFL_ENETADM
)
213 dev_warn(bgmac
->dev
, "Support for ADMtek ethernet switch not implemented\n");
217 /* BCM 471X/535X family */
218 case BCMA_CHIP_ID_BCM4716
:
219 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
221 case BCMA_CHIP_ID_BCM47162
:
222 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL2
;
223 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
225 case BCMA_CHIP_ID_BCM5357
:
226 case BCMA_CHIP_ID_BCM53572
:
227 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
228 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
229 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL1
;
230 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_PHY
;
231 if (ci
->pkg
== BCMA_PKG_ID_BCM47188
||
232 ci
->pkg
== BCMA_PKG_ID_BCM47186
) {
233 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_RGMII
;
234 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
236 if (ci
->pkg
== BCMA_PKG_ID_BCM5358
)
237 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_EPHYRMII
;
239 case BCMA_CHIP_ID_BCM53573
:
240 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
241 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
242 if (ci
->pkg
== BCMA_PKG_ID_BCM47189
)
243 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
244 if (core
->core_unit
== 0) {
245 bgmac
->feature_flags
|= BGMAC_FEAT_CC4_IF_SW_TYPE
;
246 if (ci
->pkg
== BCMA_PKG_ID_BCM47189
)
247 bgmac
->feature_flags
|=
248 BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII
;
249 } else if (core
->core_unit
== 1) {
250 bgmac
->feature_flags
|= BGMAC_FEAT_IRQ_ID_OOB_6
;
251 bgmac
->feature_flags
|= BGMAC_FEAT_CC7_IF_TYPE_RGMII
;
254 case BCMA_CHIP_ID_BCM4749
:
255 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
256 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
257 bgmac
->feature_flags
|= BGMAC_FEAT_FLW_CTRL1
;
258 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_PHY
;
260 bgmac
->feature_flags
|= BGMAC_FEAT_SW_TYPE_RGMII
;
261 bgmac
->feature_flags
|= BGMAC_FEAT_IOST_ATTACHED
;
265 case BCMA_CHIP_ID_BCM4707
:
266 case BCMA_CHIP_ID_BCM47094
:
267 case BCMA_CHIP_ID_BCM53018
:
268 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
269 bgmac
->feature_flags
|= BGMAC_FEAT_NO_RESET
;
270 bgmac
->feature_flags
|= BGMAC_FEAT_FORCE_SPEED_2500
;
273 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
274 bgmac
->feature_flags
|= BGMAC_FEAT_SET_RXQ_CLK
;
277 if (!bgmac_is_bcm4707_family(core
) && core
->id
.rev
> 2)
278 bgmac
->feature_flags
|= BGMAC_FEAT_MISC_PLL_REQ
;
280 if (core
->id
.id
== BCMA_CORE_4706_MAC_GBIT
) {
281 bgmac
->feature_flags
|= BGMAC_FEAT_CMN_PHY_CTL
;
282 bgmac
->feature_flags
|= BGMAC_FEAT_NO_CLR_MIB
;
285 if (core
->id
.rev
>= 4) {
286 bgmac
->feature_flags
|= BGMAC_FEAT_CMDCFG_SR_REV4
;
287 bgmac
->feature_flags
|= BGMAC_FEAT_TX_MASK_SETUP
;
288 bgmac
->feature_flags
|= BGMAC_FEAT_RX_MASK_SETUP
;
291 bgmac
->read
= bcma_bgmac_read
;
292 bgmac
->write
= bcma_bgmac_write
;
293 bgmac
->idm_read
= bcma_bgmac_idm_read
;
294 bgmac
->idm_write
= bcma_bgmac_idm_write
;
295 bgmac
->clk_enabled
= bcma_bgmac_clk_enabled
;
296 bgmac
->clk_enable
= bcma_bgmac_clk_enable
;
297 bgmac
->cco_ctl_maskset
= bcma_bgmac_cco_ctl_maskset
;
298 bgmac
->get_bus_clock
= bcma_bgmac_get_bus_clock
;
299 bgmac
->cmn_maskset32
= bcma_bgmac_cmn_maskset32
;
301 bgmac
->phy_connect
= bcma_phy_connect
;
303 bgmac
->phy_connect
= bgmac_phy_connect_direct
;
305 err
= bgmac_enet_probe(bgmac
);
312 bcma_mdio_mii_unregister(bgmac
->mii_bus
);
314 bcma_set_drvdata(core
, NULL
);
319 static void bgmac_remove(struct bcma_device
*core
)
321 struct bgmac
*bgmac
= bcma_get_drvdata(core
);
323 bcma_mdio_mii_unregister(bgmac
->mii_bus
);
324 bgmac_enet_remove(bgmac
);
325 bcma_set_drvdata(core
, NULL
);
329 static struct bcma_driver bgmac_bcma_driver
= {
330 .name
= KBUILD_MODNAME
,
331 .id_table
= bgmac_bcma_tbl
,
332 .probe
= bgmac_probe
,
333 .remove
= bgmac_remove
,
336 static int __init
bgmac_init(void)
340 err
= bcma_driver_register(&bgmac_bcma_driver
);
343 pr_info("Broadcom 47xx GBit MAC driver loaded\n");
348 static void __exit
bgmac_exit(void)
350 bcma_driver_unregister(&bgmac_bcma_driver
);
353 module_init(bgmac_init
)
354 module_exit(bgmac_exit
)
356 MODULE_AUTHOR("Rafał Miłecki");
357 MODULE_LICENSE("GPL");