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