Re: [PATCH 2/3] net: ethernet: bgmac: Make IDM register space optional
On Mon, Jul 17, 2017 at 2:37 PM, Abhishek Shahwrote: > Hi Jon, > >> This also will need to be added to >> drivers/net/ethernet/broadcom/bgmac-bcma.c. Otherwise, the driver >> will no longer work for those platforms. Since this was already >> accepted, please push out a fix ASAP. >> > I do not see how the bcma driver [bgmac-bcma.c] will no longer work. > The whole idea behind introducing this BGMAC_FEAT_IDM_MASK bit > was to keep bcma driver's functionality intact. > > The BGMAC_FEAT_IDM_MASK bit is explicitly set by the bgmac-platform driver > and is unset inside the same if the idm register base is provided. > > For BCMA driver case, I do not touch BGMAC_FEAT_IDM_MASK bit, i.e. it > is *not* set. > And if it is not set, each idm operation done in bgmac.c will take place. > Please explain if I am missing something here. Sorry, I had it flipped in my mind. Please disregard. > > > Regards, > Abhishek
Re: [PATCH 2/3] net: ethernet: bgmac: Make IDM register space optional
On Thu, Jul 13, 2017 at 3:04 PM, Abhishek Shahwrote: > IDM operations are usually one time ops and should be done in > firmware itself. Driver is not supposed to touch IDM registers. > > However, for some SoCs', driver is performing IDM read/writes. > So this patch masks IDM operations in case firmware is taking > care of IDM operations. > > Signed-off-by: Abhishek Shah > Reviewed-by: Oza Oza > Reviewed-by: Ray Jui > Reviewed-by: Scott Branden > --- > drivers/net/ethernet/broadcom/bgmac-platform.c | 19 --- > drivers/net/ethernet/broadcom/bgmac.c | 70 > +++--- > drivers/net/ethernet/broadcom/bgmac.h | 1 + > 3 files changed, 55 insertions(+), 35 deletions(-) > > diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c > b/drivers/net/ethernet/broadcom/bgmac-platform.c > index 1ca75de..d937083d 100644 > --- a/drivers/net/ethernet/broadcom/bgmac-platform.c > +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c > @@ -55,6 +55,9 @@ static void platform_bgmac_idm_write(struct bgmac *bgmac, > u16 offset, u32 value) > > static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) > { > + if (!bgmac->plat.idm_base) > + return true; > + > if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != > BGMAC_CLK_EN) > return false; > if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) > @@ -66,6 +69,9 @@ static void platform_bgmac_clk_enable(struct bgmac *bgmac, > u32 flags) > { > u32 val; > > + if (!bgmac->plat.idm_base) > + return; > + > /* The Reset Control register only contains a single bit to show if > the > * controller is currently in reset. Do a sanity check here, just in > * case the bootloader happened to leave the device in reset. > @@ -180,6 +186,7 @@ static int bgmac_probe(struct platform_device *pdev) > bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4; > bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP; > bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP; > + bgmac->feature_flags |= BGMAC_FEAT_IDM_MASK; > > bgmac->dev = >dev; > bgmac->dma_dev = >dev; > @@ -207,15 +214,13 @@ static int bgmac_probe(struct platform_device *pdev) > return PTR_ERR(bgmac->plat.base); > > regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base"); > - if (!regs) { > - dev_err(>dev, "Unable to obtain idm resource\n"); > - return -EINVAL; > + if (regs) { > + bgmac->plat.idm_base = devm_ioremap_resource(>dev, > regs); > + if (IS_ERR(bgmac->plat.idm_base)) > + return PTR_ERR(bgmac->plat.idm_base); > + bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK; > } > > - bgmac->plat.idm_base = devm_ioremap_resource(>dev, regs); > - if (IS_ERR(bgmac->plat.idm_base)) > - return PTR_ERR(bgmac->plat.idm_base); > - > regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, > "nicpm_base"); > if (regs) { > bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, > diff --git a/drivers/net/ethernet/broadcom/bgmac.c > b/drivers/net/ethernet/broadcom/bgmac.c > index ba4d2e1..48d672b 100644 > --- a/drivers/net/ethernet/broadcom/bgmac.c > +++ b/drivers/net/ethernet/broadcom/bgmac.c > @@ -622,9 +622,11 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) > BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base)); > BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base)); > > - if (!(bgmac_idm_read(bgmac, BCMA_IOST) & BCMA_IOST_DMA64)) { > - dev_err(bgmac->dev, "Core does not report 64-bit DMA\n"); > - return -ENOTSUPP; > + if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) { > + if (!(bgmac_idm_read(bgmac, BCMA_IOST) & BCMA_IOST_DMA64)) { > + dev_err(bgmac->dev, "Core does not report 64-bit > DMA\n"); > + return -ENOTSUPP; > + } > } > > for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) { > @@ -855,9 +857,11 @@ static void bgmac_mac_speed(struct bgmac *bgmac) > static void bgmac_miiconfig(struct bgmac *bgmac) > { > if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500) { > - bgmac_idm_write(bgmac, BCMA_IOCTL, > - bgmac_idm_read(bgmac, BCMA_IOCTL) | 0x40 | > - BGMAC_BCMA_IOCTL_SW_CLKEN); > + if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) { > + bgmac_idm_write(bgmac, BCMA_IOCTL, > + bgmac_idm_read(bgmac, BCMA_IOCTL) | > + 0x40 | BGMAC_BCMA_IOCTL_SW_CLKEN); > + } >
Re: [PATCH net] mdio: mux: fix parsing mux registers outside of the PHY address range
On Mon, Jul 10, 2017 at 8:56 AM, Andrew Lunnwrote: > On Mon, Jul 10, 2017 at 02:35:23PM +0200, Martin Blumenstingl wrote: >> mdio_mux_init parses the child nodes of the MDIO mux. When using >> "mdio-mux-mmioreg" the child nodes are describing the register value >> that is written to switch between the MDIO busses. >> >> The change which makes the error messages more verbose changed the >> parsing of the "reg" property from a simple of_property_read_u32 call >> to of_mdio_parse_addr. On a Khadas VIM (based on the Meson GXL SoC, >> which uses mdio-mux-mmioreg) this prevents registering the MDIO mux >> (because the "reg" values on the MDIO mux child nodes are 0x2009087f >> and 0xe40908ff) and leads to the following errors: >> mdio-mux-mmioreg c883455c.eth-phy-mux: >> /soc/periphs@c8834000/eth-phy-mux/mdio@e40908ff PHY address -469169921 is >> too large >> mdio-mux-mmioreg c883455c.eth-phy-mux: Error: Failed to find reg for child >> /soc/periphs@c8834000/eth-phy-mux/mdio@e40908ff >> mdio-mux-mmioreg c883455c.eth-phy-mux: >> /soc/periphs@c8834000/eth-phy-mux/mdio@2009087f PHY address 537462911 is too >> large >> mdio-mux-mmioreg c883455c.eth-phy-mux: Error: Failed to find reg for child >> /soc/periphs@c8834000/eth-phy-mux/mdio@2009087f >> mdio-mux-mmioreg c883455c.eth-phy-mux: Error: No acceptable child buses >> found >> mdio-mux-mmioreg c883455c.eth-phy-mux: failed to register mdio-mux bus >> /soc/periphs@c8834000/eth-phy-mux >> (as a result of that ethernet is not working, because the PHY which is >> connected through the mux' child MDIO bus, which is not being >> registered). >> >> Fix this by reverting the change from of_mdio_parse_addr to >> of_mdio_parse_addr. > > Reviewed-by: Andrew Lunn > > Yes, validating the reg property needs to be done separately in each > user of the generic mdio-mix code. The reg for the gpio mux must be <= > number of gpios, mmioreg must be somewhere within the address space, > bcm-iproc < 1024? > > Jon, please feel free to add such code. To be clear, are you suggesting that we add an additional property to of_mdio_parse_addr() that specifies the limit to check against, or remove the check and add it to each additional caller? Thanks, Jon > > Andrew
[PATCH net-next] of_mdio: move of_mdio_parse_addr to header file
The of_mdio_parse_addr() helper function is useful to other code, but the module dependency chain causes issues. To work around this, we can move of_mdio_parse_addr() to be an inline function in the header file. This gets rid of the dependencies and still allows for the reuse of code. Reported-by: Liviu Dudau <li...@dudau.co.uk> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 342fa1964439 ("mdio: mux: make child bus walking more permissive and errors more verbose") --- drivers/of/of_mdio.c| 22 -- include/linux/of_mdio.h | 24 +++- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 7e4c80f9b6cd..057963f2b74f 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -119,28 +119,6 @@ static void of_mdiobus_register_device(struct mii_bus *mdio, child->name, addr); } -int of_mdio_parse_addr(struct device *dev, const struct device_node *np) -{ - u32 addr; - int ret; - - ret = of_property_read_u32(np, "reg", ); - if (ret < 0) { - dev_err(dev, "%s has invalid PHY address\n", np->full_name); - return ret; - } - - /* A PHY must have a reg property in the range [0-31] */ - if (addr >= PHY_MAX_ADDR) { - dev_err(dev, "%s PHY address %i is too large\n", - np->full_name, addr); - return -EINVAL; - } - - return addr; -} -EXPORT_SYMBOL(of_mdio_parse_addr); - /* The following is a list of PHY compatible strings which appear in * some DTBs. The compatible string is never matched against a PHY * driver, so is pointless. We only expect devices which are not PHYs diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index ba35ba520487..f5db93bcd069 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -27,11 +27,33 @@ struct phy_device *of_phy_attach(struct net_device *dev, phy_interface_t iface); extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); -extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np); extern int of_phy_register_fixed_link(struct device_node *np); extern void of_phy_deregister_fixed_link(struct device_node *np); extern bool of_phy_is_fixed_link(struct device_node *np); + +static inline int of_mdio_parse_addr(struct device *dev, +const struct device_node *np) +{ + u32 addr; + int ret; + + ret = of_property_read_u32(np, "reg", ); + if (ret < 0) { + dev_err(dev, "%s has invalid PHY address\n", np->full_name); + return ret; + } + + /* A PHY must have a reg property in the range [0-31] */ + if (addr >= PHY_MAX_ADDR) { + dev_err(dev, "%s PHY address %i is too large\n", + np->full_name, addr); + return -EINVAL; + } + + return addr; +} + #else /* CONFIG_OF_MDIO */ static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) { -- 2.7.4
Re: [PATCH net-next] net: phy: use of_mdio_parse_addr
On Wed, Jun 7, 2017 at 12:18 PM, Liviu Dudau <li...@dudau.co.uk> wrote: > On Fri, Jun 02, 2017 at 02:22:51PM -0400, David Miller wrote: >> From: Jon Mason <jon.ma...@broadcom.com> >> Date: Wed, 31 May 2017 15:43:30 -0400 >> >> > use of_mdio_parse_addr() in place of an OF read of reg and a bounds >> > check (which is litterally the exact same thing that >> > of_mdio_parse_addr() does) >> > >> > Signed-off-by: Jon Mason <jon.ma...@broadcom.com> >> >> Applied, thanks Jon. > > This makes linux-next fail the modules_install target as depmod detects 2 > circular > dependencies. Reverting this patch fixes the issue. > > depmod: ERROR: Cycle detected: libphy -> of_mdio -> fixed_phy -> libphy > depmod: ERROR: Cycle detected: libphy -> of_mdio -> libphy > depmod: ERROR: Found 3 modules in dependency cycles! > make[1]: *** [/home/dliviu/devel/kernel/Makefile:1245: _modinst_post] Error 1 I did not test this as modules. Sorry. It would be ugly to duplicate the code in both place, and the code in question does not seem to really need to be in a C file. Perhaps it can be moved to a header file as an inline function, which would solve this dependency. Would this be acceptable? Thanks, Jon > > This is on an ARCH=arm build, build I doubt it makes a difference. Let me > know if > you need some .config values in order to reproduce. > > Best regards, > Liviu >
[PATCH net-next] mdio: mux: make child bus walking more permissive and errors more verbose
If any errors are encountered while walking the device tree structure of the MDIO bus for children, the code may silently continue, silently exit, or throw an error and exit. This make it difficult for device tree writers to know there is an error. Also, it makes any error in a child entry of the MDIO bus be fatal for all entries. Instead, we should provide verbose errors describing the error and then attempt to continue if it all possible. Also, use of_mdio_parse_addr() Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/mdio-mux.c | 24 +--- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 599ce24c514f..47ded3904050 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c @@ -135,27 +135,33 @@ int mdio_mux_init(struct device *dev, for_each_available_child_of_node(dev->of_node, child_bus_node) { u32 v; - r = of_property_read_u32(child_bus_node, "reg", ); - if (r) + v = of_mdio_parse_addr(dev, child_bus_node); + if (v < 0) { + dev_err(dev, + "Error: Failed to find reg for child %s\n", + of_node_full_name(child_bus_node)); continue; + } cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); if (cb == NULL) { dev_err(dev, - "Error: Failed to allocate memory for child\n"); + "Error: Failed to allocate memory for child %s\n", + of_node_full_name(child_bus_node)); ret_val = -ENOMEM; - of_node_put(child_bus_node); - break; + continue; } cb->bus_number = v; cb->parent = pb; cb->mii_bus = mdiobus_alloc(); if (!cb->mii_bus) { + dev_err(dev, + "Error: Failed to allocate MDIO bus for child %s\n", + of_node_full_name(child_bus_node)); ret_val = -ENOMEM; devm_kfree(dev, cb); - of_node_put(child_bus_node); - break; + continue; } cb->mii_bus->priv = cb; @@ -167,6 +173,9 @@ int mdio_mux_init(struct device *dev, cb->mii_bus->write = mdio_mux_write; r = of_mdiobus_register(cb->mii_bus, child_bus_node); if (r) { + dev_err(dev, + "Error: Failed to register MDIO bus for child %s\n", + of_node_full_name(child_bus_node)); mdiobus_free(cb->mii_bus); devm_kfree(dev, cb); } else { @@ -180,6 +189,7 @@ int mdio_mux_init(struct device *dev, return 0; } + dev_err(dev, "Error: No acceptable child buses found\n"); devm_kfree(dev, pb); err_pb_kz: /* balance the reference of_mdio_find_bus() took */ -- 2.7.4
[PATCH net-next] net: phy: use of_mdio_parse_addr
use of_mdio_parse_addr() in place of an OF read of reg and a bounds check (which is litterally the exact same thing that of_mdio_parse_addr() does) Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/mdio_bus.c | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 8e73f5f36e71..d4782e902e2e 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -263,21 +263,10 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus, for_each_available_child_of_node(bus->dev.of_node, child) { int addr; - int ret; - ret = of_property_read_u32(child, "reg", ); - if (ret < 0) { - dev_err(dev, "%s has invalid MDIO address\n", - child->full_name); + addr = of_mdio_parse_addr(dev, child); + if (addr < 0) continue; - } - - /* A MDIO device must have a reg property in the range [0-31] */ - if (addr >= PHY_MAX_ADDR) { - dev_err(dev, "%s MDIO address %i is too large\n", - child->full_name, addr); - continue; - } if (addr == mdiodev->addr) { dev->of_node = child; -- 2.7.4
Re: [PATCH] mdio: mux: fix device_node_continue.cocci warnings
On Fri, May 12, 2017 at 6:52 PM, Florian Fainelliwrote: > On 05/12/2017 09:22 AM, David Miller wrote: >> From: Julia Lawall >> Date: Fri, 12 May 2017 22:54:23 +0800 (SGT) >> >>> Device node iterators put the previous value of the index variable, so an >>> explicit put causes a double put. >> ... >>> @@ -169,7 +169,6 @@ int mdio_mux_init(struct device *dev, >>> if (r) { >>> mdiobus_free(cb->mii_bus); >>> devm_kfree(dev, cb); >>> -of_node_put(child_bus_node); >>> } else { >> >> I think we're instead simply missing a break; statement here. > > It's kind of questionable, if we have an error initializing one of our > child MDIO bus controller (child from the perspective of the MDIO mux, > boy this is getting complicated...), should we keep on going, or should > we abort entirely and rollback what we have successfully registered? > > I don't think Julia's patch makes thing worse, in that if we had to > rollback, we would not be doing this correctly now anyway. > > Jon, what do you think? If every other case is fatal, then it is odd that this one is permissive. I think we should go 100% one way or the other. So, the options here are to: 1. Encounter an error, unroll any mallocs, etc created by this entry, but continue on to the next entry and return success if any are created 2. Encounter an error, unroll any mallocs, etc created by this entry and any others that were created, and return an error 3. Encounter an error, unroll any mallocs, etc created by this entry, exit and return success if any are created #1 would be the most accepting of any errors encountered #2 would identify any poorly written DTs by breaking their currently working functionality (though we should add some error messages to let them know why) #3 matches the suggestion by David Miller, and would be a hybrid of #1 and #2 in outcome I would prefer #1, as I would not want to break something that was currently working. However, I think we should add much error logging here to let people know their DT is hosed (instead of silently working). So, this would mean applying Julia's patch, and I'll do a follow-on to change the breaks to continues and add the error logging (assuming others agree with me). Thanks, Jon
[PATCH] mdio: mux: Correct mdio_mux_init error path issues
There is a potential unnecessary refcount decriment on error path of put_device(>mii_bus->dev), as it is possible to avoid the of_mdio_find_bus() call if mux_bus is specified by the calling function. The same put_device() is not called in the error path if the devm_kzalloc of pb fails. This caused the variable used in the put_device() to be changed, as the pb pointer was obviously not set up. There is an unnecessary of_node_get() on child_bus_node if the of_mdiobus_register() is successful, as the for_each_available_child_of_node() automatically increments this. Thus the refcount on this node will always be +1 more than it should be. There is no of_node_put() on child_bus_node if the of_mdiobus_register() call fails. Finally, it is lacking devm_kfree() of pb in the error path. While this might not be technically necessary, it was present in other parts of the function. So, I am adding it where necessary to make it uniform. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: f20e6657a875 ("mdio: mux: Enhanced MDIO mux framework for integrated multiplexers") Fixes: 0ca2997d1452 ("netdev/of/phy: Add MDIO bus multiplexer support.") --- drivers/net/phy/mdio-mux.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 963838d4fac1..6943c5ece44a 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c @@ -122,10 +122,9 @@ int mdio_mux_init(struct device *dev, pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL); if (pb == NULL) { ret_val = -ENOMEM; - goto err_parent_bus; + goto err_pb_kz; } - pb->switch_data = data; pb->switch_fn = switch_fn; pb->current_child = -1; @@ -154,6 +153,7 @@ int mdio_mux_init(struct device *dev, cb->mii_bus = mdiobus_alloc(); if (!cb->mii_bus) { ret_val = -ENOMEM; + devm_kfree(dev, cb); of_node_put(child_bus_node); break; } @@ -169,8 +169,8 @@ int mdio_mux_init(struct device *dev, if (r) { mdiobus_free(cb->mii_bus); devm_kfree(dev, cb); + of_node_put(child_bus_node); } else { - of_node_get(child_bus_node); cb->next = pb->children; pb->children = cb; } @@ -181,9 +181,11 @@ int mdio_mux_init(struct device *dev, return 0; } + devm_kfree(dev, pb); +err_pb_kz: /* balance the reference of_mdio_find_bus() took */ - put_device(>mii_bus->dev); - + if (!mux_bus) + put_device(_bus->dev); err_parent_bus: of_node_put(parent_bus_node); return ret_val; -- 2.7.4
[PATCH] net: mdio-mux: bcm-iproc: call mdiobus_free() in error path
If an error is encountered in mdio_mux_init(), the error path will call mdiobus_free(). Since mdiobus_register() has been called prior to mdio_mux_init(), the bus->state will not be MDIOBUS_UNREGISTERED. This causes a BUG_ON() in mdiobus_free(). To correct this issue, add an error path for mdio_mux_init() which calls mdiobus_unregister() prior to mdiobus_free(). Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 98bc865a1ec8 ("net: mdio-mux: Add MDIO mux driver for iProc SoCs") --- drivers/net/phy/mdio-mux-bcm-iproc.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/mdio-mux-bcm-iproc.c b/drivers/net/phy/mdio-mux-bcm-iproc.c index 0a0412524cec..0a5f62e0efcc 100644 --- a/drivers/net/phy/mdio-mux-bcm-iproc.c +++ b/drivers/net/phy/mdio-mux-bcm-iproc.c @@ -203,11 +203,14 @@ static int mdio_mux_iproc_probe(struct platform_device *pdev) >mux_handle, md, md->mii_bus); if (rc) { dev_info(md->dev, "mdiomux initialization failed\n"); - goto out; + goto out_register; } dev_info(md->dev, "iProc mdiomux registered\n"); return 0; + +out_register: + mdiobus_unregister(bus); out: mdiobus_free(bus); return rc; -- 2.7.4
Re: [PATCH 2/2] ARM: dts: Add the ethernet and ethernet PHY to the cygnus core DT.
On Tue, Apr 25, 2017 at 11:23 AM, Sergei Shtylyov <sergei.shtyl...@cogentembedded.com> wrote: > Hello! > > On 04/25/2017 06:15 PM, Jon Mason wrote: > >>>> Cygnus has a single amac controller connected to the B53 switch with 2 >>>> PHYs. On the BCM911360_EP platform, those two PHYs are connected to >>>> the external ethernet jacks. > > > [...] > >>>> Signed-off-by: Eric Anholt <e...@anholt.net> >>>> --- >>>> arch/arm/boot/dts/bcm-cygnus.dtsi | 60 >>>> ++ >>>> arch/arm/boot/dts/bcm911360_entphn.dts | 8 + >>>> 2 files changed, 68 insertions(+) >>>> >>>> diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi >>>> b/arch/arm/boot/dts/bcm-cygnus.dtsi >>>> index 009f1346b817..318899df9972 100644 >>>> --- a/arch/arm/boot/dts/bcm-cygnus.dtsi >>>> +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi > > [...] >>>> >>>> @@ -295,6 +345,16 @@ >>>> status = "disabled"; >>>> }; >>>> >>>> + eth0: enet@18042000 { >>>> + compatible = "brcm,amac"; >>>> + reg = <0x18042000 0x1000>, >>>> + <0x1811 0x1000>; >>>> + reg-names = "amac_base", "idm_base"; >>> >>> >>> >>>I don't think "_base" suffixes are necessary here. >> >> >> 100% necessary, per the driver. See >> drivers/net/ethernet/broadcom/bgmac-platform.c > > >I'd recommend to fix the driver/bindings then... They're already in use in other device trees. So, we'd need to support backward compatibility on them, thus removing any real benefit to changing them. > > MBR, Sergei >
Re: [PATCH 2/2] ARM: dts: Add the ethernet and ethernet PHY to the cygnus core DT.
On Tue, Apr 25, 2017 at 5:40 AM, Sergei Shtylyovwrote: > Hello. > > On 4/25/2017 12:50 AM, Eric Anholt wrote: > >> Cygnus has a single amac controller connected to the B53 switch with 2 >> PHYs. On the BCM911360_EP platform, those two PHYs are connected to >> the external ethernet jacks. > > >My spell checker trips on "amac" and "ethernet" -- perhaps they need > capitalization? > >> Signed-off-by: Eric Anholt >> --- >> arch/arm/boot/dts/bcm-cygnus.dtsi | 60 >> ++ >> arch/arm/boot/dts/bcm911360_entphn.dts | 8 + >> 2 files changed, 68 insertions(+) >> >> diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi >> b/arch/arm/boot/dts/bcm-cygnus.dtsi >> index 009f1346b817..318899df9972 100644 >> --- a/arch/arm/boot/dts/bcm-cygnus.dtsi >> +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi >> @@ -142,6 +142,56 @@ >> interrupts = <0>; >> }; >> >> + mdio: mdio@18002000 { >> + compatible = "brcm,iproc-mdio"; >> + reg = <0x18002000 0x8>; >> + #size-cells = <1>; >> + #address-cells = <0>; >> + >> + gphy0: eth-gphy@0 { > > >The node anmes must be generic, the DT spec has standardized > "ethernet-phy" name for this case. > >> + reg = <0>; >> + max-speed = <1000>; >> + }; >> + >> + gphy1: eth-gphy@1 { >> + reg = <1>; >> + max-speed = <1000>; >> + }; >> + }; > > [...] >> >> @@ -295,6 +345,16 @@ >> status = "disabled"; >> }; >> >> + eth0: enet@18042000 { >> + compatible = "brcm,amac"; >> + reg = <0x18042000 0x1000>, >> + <0x1811 0x1000>; >> + reg-names = "amac_base", "idm_base"; > > >I don't think "_base" suffixes are necessary here. 100% necessary, per the driver. See drivers/net/ethernet/broadcom/bgmac-platform.c > > [...] > > MBR, Sergei >
Re: [PATCH] net: ethernet: bgmac: Allow MAC address to be specified in DTB
On Thu, Mar 16, 2017 at 12:39 PM, Florian Fainelli <f.faine...@gmail.com> wrote: > On 03/16/2017 08:48 AM, Steve Lin wrote: >> Allows the BCMA version of the bgmac driver to obtain MAC address >> from the device tree. If no MAC address is specified there, then >> the previous behavior (obtaining MAC address from SPROM) is >> used. >> >> Signed-off-by: Steve Lin <steven.l...@broadcom.com> > > Reviewed-by: Florian Fainelli <f.faine...@gmail.com> > > PS: you might want to specify which tree this applies to by using [PATCH > net-next] or [PATCH net] in the subject, see the netdev-FAQ.txt for > details: > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/netdev-FAQ.txt I believe he wants this in net-next Acked-by: Jon Mason <jon.ma...@broadcom.com> >> --- >> drivers/net/ethernet/broadcom/bgmac-bcma.c | 39 >> ++ >> 1 file changed, 23 insertions(+), 16 deletions(-) >> >> diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c >> b/drivers/net/ethernet/broadcom/bgmac-bcma.c >> index cf15b7e..6322594 100644 >> --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c >> +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c >> @@ -11,6 +11,7 @@ >> #include >> #include >> #include >> +#include >> #include "bgmac.h" >> >> static inline bool bgmac_is_bcm4707_family(struct bcma_device *core) >> @@ -114,7 +115,7 @@ static int bgmac_probe(struct bcma_device *core) >> struct ssb_sprom *sprom = >bus->sprom; >> struct mii_bus *mii_bus; >> struct bgmac *bgmac; >> - u8 *mac; >> + const u8 *mac = NULL; >> int err; >> >> bgmac = bgmac_alloc(>dev); >> @@ -127,21 +128,27 @@ static int bgmac_probe(struct bcma_device *core) >> >> bcma_set_drvdata(core, bgmac); >> >> - switch (core->core_unit) { >> - case 0: >> - mac = sprom->et0mac; >> - break; >> - case 1: >> - mac = sprom->et1mac; >> - break; >> - case 2: >> - mac = sprom->et2mac; >> - break; >> - default: >> - dev_err(bgmac->dev, "Unsupported core_unit %d\n", >> - core->core_unit); >> - err = -ENOTSUPP; >> - goto err; >> + if (bgmac->dev->of_node) >> + mac = of_get_mac_address(bgmac->dev->of_node); >> + >> + /* If no MAC address assigned via device tree, check SPROM */ >> + if (!mac) { >> + switch (core->core_unit) { >> + case 0: >> + mac = sprom->et0mac; >> + break; >> + case 1: >> + mac = sprom->et1mac; >> + break; >> + case 2: >> + mac = sprom->et2mac; >> + break; >> + default: >> + dev_err(bgmac->dev, "Unsupported core_unit %d\n", >> + core->core_unit); >> + err = -ENOTSUPP; >> + goto err; >> + } >> } >> >> ether_addr_copy(bgmac->net_dev->dev_addr, mac); >> > > > -- > Florian
Re: [PATCH net v4 0/2] net: ethernet: bgmac: bug fixes
On Thu, Mar 02, 2017 at 12:56:05PM -0800, David Miller wrote: > From: David Miller <da...@davemloft.net> > Date: Thu, 02 Mar 2017 12:50:15 -0800 (PST) > > > From: Jon Mason <jon.ma...@broadcom.com> > > Date: Tue, 28 Feb 2017 13:41:49 -0500 > > > >> Changes in v4: > >> * Added the udelays from the previous code (per David Miller) > >> > >> Changes in v3: > >> * Reworked the init sequence patch to only remove the device reset if > >> the device is actually in reset. Given that this code doesn't bear > >> much resemblance to the original code, I'm changing the author of the > >> patch. This was tested on NS2 SVK. > >> > >> Changes in v2: > >> * Reworked the first match to make it more obvious what portions of the > >> register were being preserved (Per Rafal Mileki) > >> * Style change to reorder the function variables in patch 2 (per Sergei > >> Shtylyov) > >> > >> Bug fixes for bgmac driver > > > > Series applied. > > Actually, this doesn't even compile. Reverted... > > [davem@kkuri net]$ make -s -j4 > drivers/net/ethernet/broadcom/bgmac.c: In function ‘bgmac_set_mac_address’: > drivers/net/ethernet/broadcom/bgmac.c:1233:23: error: ‘struct bgmac’ has no > member named ‘mac_addr’; did you mean ‘phyaddr’? > ether_addr_copy(bgmac->mac_addr, sa->sa_data); >^~ > drivers/net/ethernet/broadcom/bgmac.c:1234:38: error: ‘struct bgmac’ has no > member named ‘mac_addr’; did you mean ‘phyaddr’? > bgmac_write_mac_address(bgmac, bgmac->mac_addr); > ^~ Well this is embarrassing. I didn't rebase, even though I acked the patch which changed it out from under me. Sorry, I should've known better. Rebased, compiled, and tested patch coming shortly. I appreciate your patience. Thanks, Jon
[PATCH net v5 1/2] net: ethernet: bgmac: init sequence bug
Fix a bug in the 'bgmac' driver init sequence that blind writes for init sequence where it should preserve most bits other than the ones it is deliberately manipulating. The code now checks to see if the adapter needs to be brought out of reset (where as before it was doing an IDM write to bring it out of reset regardless of whether it was in reset or not). Also, removed unnecessary usleeps (as there is already a read present to flush the IDM writes). Signed-off-by: Zac Schroff <zschr...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: f6a95a24957 ("net: ethernet: bgmac: Add platform device support") --- drivers/net/ethernet/broadcom/bgmac-platform.c | 27 +- drivers/net/ethernet/broadcom/bgmac.h | 16 +++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 7b1af95..da1b8b2 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -51,8 +51,7 @@ static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value) static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) { - if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & -(BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK) + if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != BGMAC_CLK_EN) return false; if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) return false; @@ -61,15 +60,25 @@ static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) { - bgmac_idm_write(bgmac, BCMA_IOCTL, - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); - bgmac_idm_read(bgmac, BCMA_IOCTL); + u32 val; - bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); - bgmac_idm_read(bgmac, BCMA_RESET_CTL); - udelay(1); + /* The Reset Control register only contains a single bit to show if the +* controller is currently in reset. Do a sanity check here, just in +* case the bootloader happened to leave the device in reset. +*/ + val = bgmac_idm_read(bgmac, BCMA_RESET_CTL); + if (val) { + bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); + bgmac_idm_read(bgmac, BCMA_RESET_CTL); + udelay(1); + } - bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); + val = bgmac_idm_read(bgmac, BCMA_IOCTL); + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | +BGMAC_ARUSER); + val |= BGMAC_CLK_EN; + bgmac_idm_write(bgmac, BCMA_IOCTL, val); bgmac_idm_read(bgmac, BCMA_IOCTL); udelay(1); } diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 248727d..6d1c6ff 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -213,6 +213,22 @@ /* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */ #define BGMAC_BCMA_IOCTL_SW_CLKEN 0x0004 /* PHY Clock Enable */ #define BGMAC_BCMA_IOCTL_SW_RESET 0x0008 /* PHY Reset */ +/* The IOCTL values appear to be different in NS, NSP, and NS2, and do not match + * the values directly above + */ +#define BGMAC_CLK_EN BIT(0) +#define BGMAC_RESERVED_0 BIT(1) +#define BGMAC_SOURCE_SYNC_MODE_EN BIT(2) +#define BGMAC_DEST_SYNC_MODE_ENBIT(3) +#define BGMAC_TX_CLK_OUT_INVERT_EN BIT(4) +#define BGMAC_DIRECT_GMII_MODE BIT(5) +#define BGMAC_CLK_250_SEL BIT(6) +#define BGMAC_AWCACHE (0xf << 7) +#define BGMAC_RESERVED_1 (0x1f << 11) +#define BGMAC_ARCACHE (0xf << 16) +#define BGMAC_AWUSER (0x3f << 20) +#define BGMAC_ARUSER (0x3f << 26) +#define BGMAC_RESERVED BIT(31) /* BCMA GMAC core specific IO status (BCMA_IOST) flags */ #define BGMAC_BCMA_IOST_ATTACHED 0x0800 -- 2.7.4
[PATCH net v5 2/2] net: ethernet: bgmac: mac address change bug
From: Hari Vyas <ha...@broadcom.com> ndo_set_mac_address() passes struct sockaddr * as 2nd parameter to bgmac_set_mac_address() but code assumed u8 *. This caused two bytes chopping and the wrong mac address was configured. Signed-off-by: Hari Vyas <ha...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 4e209001b86 ("bgmac: write mac address to hardware in ndo_set_mac_address") --- drivers/net/ethernet/broadcom/bgmac.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 4150467..fd66fca 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1223,12 +1223,16 @@ static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb, static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) { struct bgmac *bgmac = netdev_priv(net_dev); + struct sockaddr *sa = addr; int ret; ret = eth_prepare_mac_addr_change(net_dev, addr); if (ret < 0) return ret; - bgmac_write_mac_address(bgmac, (u8 *)addr); + + ether_addr_copy(net_dev->dev_addr, sa->sa_data); + bgmac_write_mac_address(bgmac, net_dev->dev_addr); + eth_commit_mac_addr_change(net_dev, addr); return 0; } -- 2.7.4
[PATCH net v5 0/2] net: ethernet: bgmac: bug fixes
Changes in v5: * Rebased to the latest code and fixed up a compile error due to the mac_addr struct going away (found by David Miller) Changes in v4: * Added the udelays from the previous code (per David Miller) Changes in v3: * Reworked the init sequence patch to only remove the device reset if the device is actually in reset. Given that this code doesn't bear much resemblance to the original code, I'm changing the author of the patch. This was tested on NS2 SVK. Changes in v2: * Reworked the first match to make it more obvious what portions of the register were being preserved (Per Rafal Mileki) * Style change to reorder the function variables in patch 2 (per Sergei Shtylyov) Bug fixes for bgmac driver Hari Vyas (1): net: ethernet: bgmac: mac address change bug Jon Mason (1): net: ethernet: bgmac: init sequence bug drivers/net/ethernet/broadcom/bgmac-platform.c | 27 +- drivers/net/ethernet/broadcom/bgmac.c | 6 +- drivers/net/ethernet/broadcom/bgmac.h | 16 +++ 3 files changed, 39 insertions(+), 10 deletions(-) -- 2.7.4
[PATCH net-next v3 0/3] net: ethernet: bgmac: PM support and clean-ups
Changes in v3: * Corrected a bug Florian found and added his Reviewed-by Changes in v2: * Reworked the PM patch with Florian's suggestions Add code to support Power Management (only tested on NS2), and add some code clean-ups Joey Zhong (1): net: ethernet: bgmac: driver power manangement Jon Mason (2): net: ethernet: bgmac: use #defines for MAX size net: ethernet: bgmac: unify code of the same family drivers/net/ethernet/broadcom/bgmac-bcma.c | 64 +++--- drivers/net/ethernet/broadcom/bgmac-platform.c | 34 ++ drivers/net/ethernet/broadcom/bgmac.c | 51 drivers/net/ethernet/broadcom/bgmac.h | 4 +- 4 files changed, 116 insertions(+), 37 deletions(-) -- 2.7.4
[PATCH net-next v3 1/3] net: ethernet: bgmac: use #defines for MAX size
The maximum frame size is really just the standard ethernet frame size and FCS. So use those existing defines to make the code a little more beautiful. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 6d1c6ff..a75ed35 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -402,7 +402,7 @@ #define BGMAC_WEIGHT 64 -#define ETHER_MAX_LEN 1518 +#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETH_FCS_LEN) /* Feature Flags */ #define BGMAC_FEAT_TX_MASK_SETUP BIT(0) -- 2.7.4
[PATCH net-next v3 3/3] net: ethernet: bgmac: driver power manangement
From: Joey Zhong <zho...@broadcom.com> Implement suspend/resume callbacks in the bgmac driver. This makes sure that we de-initialize and re-initialize the hardware correctly before entering suspend and when resuming. Signed-off-by: Joey Zhong <zho...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 34 + drivers/net/ethernet/broadcom/bgmac.c | 51 ++ drivers/net/ethernet/broadcom/bgmac.h | 2 + 3 files changed, 87 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 5a3d0b7..ce47728 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -21,8 +21,12 @@ #include #include "bgmac.h" +#define NICPM_PADRING_CFG 0x0004 #define NICPM_IOMUX_CTRL 0x0008 +#define NICPM_PADRING_CFG_INIT_VAL 0x7400 +#define NICPM_IOMUX_CTRL_INIT_VAL_AX 0x2188 + #define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 #define NICPM_IOMUX_CTRL_SPD_SHIFT 10 #define NICPM_IOMUX_CTRL_SPD_10M 0 @@ -108,6 +112,10 @@ static void bgmac_nicpm_speed_set(struct net_device *net_dev) if (!bgmac->plat.nicpm_base) return; + /* SET RGMII IO CONFIG */ + writel(NICPM_PADRING_CFG_INIT_VAL, + bgmac->plat.nicpm_base + NICPM_PADRING_CFG); + val = NICPM_IOMUX_CTRL_INIT_VAL; switch (bgmac->net_dev->phydev->speed) { default: @@ -239,6 +247,31 @@ static int bgmac_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int bgmac_suspend(struct device *dev) +{ + struct bgmac *bgmac = dev_get_drvdata(dev); + + return bgmac_enet_suspend(bgmac); +} + +static int bgmac_resume(struct device *dev) +{ + struct bgmac *bgmac = dev_get_drvdata(dev); + + return bgmac_enet_resume(bgmac); +} + +static const struct dev_pm_ops bgmac_pm_ops = { + .suspend = bgmac_suspend, + .resume = bgmac_resume +}; + +#define BGMAC_PM_OPS (_pm_ops) +#else +#define BGMAC_PM_OPS NULL +#endif /* CONFIG_PM */ + static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, @@ -252,6 +285,7 @@ static struct platform_driver bgmac_enet_driver = { .driver = { .name = "bgmac-enet", .of_match_table = bgmac_of_enet_match, + .pm = BGMAC_PM_OPS }, .probe = bgmac_probe, .remove = bgmac_remove, diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 6b7782f..7f516a2 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1480,6 +1480,7 @@ int bgmac_enet_probe(struct bgmac *bgmac) net_dev->irq = bgmac->irq; SET_NETDEV_DEV(net_dev, bgmac->dev); + dev_set_drvdata(bgmac->dev, bgmac); if (!is_valid_ether_addr(net_dev->dev_addr)) { dev_err(bgmac->dev, "Invalid MAC addr: %pM\n", @@ -1552,5 +1553,55 @@ void bgmac_enet_remove(struct bgmac *bgmac) } EXPORT_SYMBOL_GPL(bgmac_enet_remove); +int bgmac_enet_suspend(struct bgmac *bgmac) +{ + if (!netif_running(bgmac->net_dev)) + return 0; + + phy_stop(bgmac->net_dev->phydev); + + netif_stop_queue(bgmac->net_dev); + + napi_disable(>napi); + + netif_tx_lock(bgmac->net_dev); + netif_device_detach(bgmac->net_dev); + netif_tx_unlock(bgmac->net_dev); + + bgmac_chip_intrs_off(bgmac); + bgmac_chip_reset(bgmac); + bgmac_dma_cleanup(bgmac); + + return 0; +} +EXPORT_SYMBOL_GPL(bgmac_enet_suspend); + +int bgmac_enet_resume(struct bgmac *bgmac) +{ + int rc; + + if (!netif_running(bgmac->net_dev)) + return 0; + + rc = bgmac_dma_init(bgmac); + if (rc) + return rc; + + bgmac_chip_init(bgmac); + + napi_enable(>napi); + + netif_tx_lock(bgmac->net_dev); + netif_device_attach(bgmac->net_dev); + netif_tx_unlock(bgmac->net_dev); + + netif_start_queue(bgmac->net_dev); + + phy_start(bgmac->net_dev->phydev); + + return 0; +} +EXPORT_SYMBOL_GPL(bgmac_enet_resume); + MODULE_AUTHOR("Rafał Miłecki"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index a75ed35..c181876 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -537,6 +537,8 @@ int bgmac_enet_probe(struct bgmac *bgmac); void bgmac_enet_remove(struct bgmac *bgmac); void
[PATCH net-next v3 2/3] net: ethernet: bgmac: unify code of the same family
BCM471X and BCM535X are of the same family (from what I can derive from internal documents). Group them into the case statement together, which results in more code reuse. Also, use existing helper variables to make the code a little more readable too. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 64 +- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index d59cfcc4..cf15b7e 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -192,36 +192,50 @@ static int bgmac_probe(struct bcma_device *core) goto err1; } - bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo & - BGMAC_BFL_ENETROBO); + bgmac->has_robosw = !!(sprom->boardflags_lo & BGMAC_BFL_ENETROBO); if (bgmac->has_robosw) dev_warn(bgmac->dev, "Support for Roboswitch not implemented\n"); - if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) + if (sprom->boardflags_lo & BGMAC_BFL_ENETADM) dev_warn(bgmac->dev, "Support for ADMtek ethernet switch not implemented\n"); /* Feature Flags */ - switch (core->bus->chipinfo.id) { + switch (ci->id) { + /* BCM 471X/535X family */ + case BCMA_CHIP_ID_BCM4716: + bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; + /* fallthrough */ + case BCMA_CHIP_ID_BCM47162: + bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; + bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + break; case BCMA_CHIP_ID_BCM5357: + case BCMA_CHIP_ID_BCM53572: bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47186) { - bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; + if (ci->pkg == BCMA_PKG_ID_BCM47188 || + ci->pkg == BCMA_PKG_ID_BCM47186) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; + bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM5358) + if (ci->pkg == BCMA_PKG_ID_BCM5358) bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII; break; - case BCMA_CHIP_ID_BCM53572: - bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + case BCMA_CHIP_ID_BCM53573: bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; - bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47188) { - bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; + bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + if (ci->pkg == BCMA_PKG_ID_BCM47189) bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; + if (core->core_unit == 0) { + bgmac->feature_flags |= BGMAC_FEAT_CC4_IF_SW_TYPE; + if (ci->pkg == BCMA_PKG_ID_BCM47189) + bgmac->feature_flags |= + BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII; + } else if (core->core_unit == 1) { + bgmac->feature_flags |= BGMAC_FEAT_IRQ_ID_OOB_6; + bgmac->feature_flags |= BGMAC_FEAT_CC7_IF_TYPE_RGMII; } break; case BCMA_CHIP_ID_BCM4749: @@ -229,18 +243,11 @@ static int bgmac_probe(struct bcma_device *core) bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == 10) { + if (ci->pkg == 10) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } break; - case BCMA_CHIP_ID_BCM4716: - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - /* fallthrough */ - case BCMA_CHIP_ID_BCM47162: - bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; - bgmac->feature_fl
[PATCH net v4 1/2] net: ethernet: bgmac: init sequence bug
Fix a bug in the 'bgmac' driver init sequence that blind writes for init sequence where it should preserve most bits other than the ones it is deliberately manipulating. The code now checks to see if the adapter needs to be brought out of reset (where as before it was doing an IDM write to bring it out of reset regardless of whether it was in reset or not). Also, removed unnecessary usleeps (as there is already a read present to flush the IDM writes). Signed-off-by: Zac Schroff <zschr...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: f6a95a24957 ("net: ethernet: bgmac: Add platform device support") --- drivers/net/ethernet/broadcom/bgmac-platform.c | 27 +- drivers/net/ethernet/broadcom/bgmac.h | 16 +++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 7b1af95..da1b8b2 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -51,8 +51,7 @@ static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value) static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) { - if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & -(BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK) + if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != BGMAC_CLK_EN) return false; if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) return false; @@ -61,15 +60,25 @@ static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) { - bgmac_idm_write(bgmac, BCMA_IOCTL, - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); - bgmac_idm_read(bgmac, BCMA_IOCTL); + u32 val; - bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); - bgmac_idm_read(bgmac, BCMA_RESET_CTL); - udelay(1); + /* The Reset Control register only contains a single bit to show if the +* controller is currently in reset. Do a sanity check here, just in +* case the bootloader happened to leave the device in reset. +*/ + val = bgmac_idm_read(bgmac, BCMA_RESET_CTL); + if (val) { + bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); + bgmac_idm_read(bgmac, BCMA_RESET_CTL); + udelay(1); + } - bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); + val = bgmac_idm_read(bgmac, BCMA_IOCTL); + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | +BGMAC_ARUSER); + val |= BGMAC_CLK_EN; + bgmac_idm_write(bgmac, BCMA_IOCTL, val); bgmac_idm_read(bgmac, BCMA_IOCTL); udelay(1); } diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 248727d..6d1c6ff 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -213,6 +213,22 @@ /* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */ #define BGMAC_BCMA_IOCTL_SW_CLKEN 0x0004 /* PHY Clock Enable */ #define BGMAC_BCMA_IOCTL_SW_RESET 0x0008 /* PHY Reset */ +/* The IOCTL values appear to be different in NS, NSP, and NS2, and do not match + * the values directly above + */ +#define BGMAC_CLK_EN BIT(0) +#define BGMAC_RESERVED_0 BIT(1) +#define BGMAC_SOURCE_SYNC_MODE_EN BIT(2) +#define BGMAC_DEST_SYNC_MODE_ENBIT(3) +#define BGMAC_TX_CLK_OUT_INVERT_EN BIT(4) +#define BGMAC_DIRECT_GMII_MODE BIT(5) +#define BGMAC_CLK_250_SEL BIT(6) +#define BGMAC_AWCACHE (0xf << 7) +#define BGMAC_RESERVED_1 (0x1f << 11) +#define BGMAC_ARCACHE (0xf << 16) +#define BGMAC_AWUSER (0x3f << 20) +#define BGMAC_ARUSER (0x3f << 26) +#define BGMAC_RESERVED BIT(31) /* BCMA GMAC core specific IO status (BCMA_IOST) flags */ #define BGMAC_BCMA_IOST_ATTACHED 0x0800 -- 2.7.4
[PATCH net v4 0/2] net: ethernet: bgmac: bug fixes
Changes in v4: * Added the udelays from the previous code (per David Miller) Changes in v3: * Reworked the init sequence patch to only remove the device reset if the device is actually in reset. Given that this code doesn't bear much resemblance to the original code, I'm changing the author of the patch. This was tested on NS2 SVK. Changes in v2: * Reworked the first match to make it more obvious what portions of the register were being preserved (Per Rafal Mileki) * Style change to reorder the function variables in patch 2 (per Sergei Shtylyov) Bug fixes for bgmac driver Hari Vyas (1): net: ethernet: bgmac: mac address change bug Jon Mason (1): net: ethernet: bgmac: init sequence bug drivers/net/ethernet/broadcom/bgmac-platform.c | 27 +- drivers/net/ethernet/broadcom/bgmac.c | 6 +- drivers/net/ethernet/broadcom/bgmac.h | 16 +++ 3 files changed, 39 insertions(+), 10 deletions(-) -- 2.7.4
[PATCH net v4 2/2] net: ethernet: bgmac: mac address change bug
From: Hari Vyas <ha...@broadcom.com> ndo_set_mac_address() passes struct sockaddr * as 2nd parameter to bgmac_set_mac_address() but code assumed u8 *. This caused two bytes chopping and the wrong mac address was configured. Signed-off-by: Hari Vyas <ha...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 4e209001b86 ("bgmac: write mac address to hardware in ndo_set_mac_address") --- drivers/net/ethernet/broadcom/bgmac.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 4150467..6b7782f 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1223,12 +1223,16 @@ static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb, static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) { struct bgmac *bgmac = netdev_priv(net_dev); + struct sockaddr *sa = addr; int ret; ret = eth_prepare_mac_addr_change(net_dev, addr); if (ret < 0) return ret; - bgmac_write_mac_address(bgmac, (u8 *)addr); + + ether_addr_copy(bgmac->mac_addr, sa->sa_data); + bgmac_write_mac_address(bgmac, bgmac->mac_addr); + eth_commit_mac_addr_change(net_dev, addr); return 0; } -- 2.7.4
Re: [PATCH] net: bgmac: store MAC address directly in netdev->dev_addr
On Thu, Feb 16, 2017 at 9:11 AM, Tobias Klauser <tklau...@distanz.ch> wrote: > After commit 34a5102c3235 ("net: bgmac: allocate struct bgmac just once > & don't copy it") the mac_addr member of struct bgmac is no longer > necessary to pass the MAC address to bgmac_enet_probe(). Instead it can > directly be stored in netdev->dev_addr. > > Also use eth_hw_addr_random() instead of eth_random_addr() in case a > random MAC is nedded. This will make sure netdev->addr_assign_type will > be properly set. > > Signed-off-by: Tobias Klauser <tklau...@distanz.ch> Looks sane to me Acked-by: Jon Mason <jon.ma...@broadcom.com> > --- > drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 +- > drivers/net/ethernet/broadcom/bgmac-platform.c | 2 +- > drivers/net/ethernet/broadcom/bgmac.c | 9 - > drivers/net/ethernet/broadcom/bgmac.h | 1 - > 4 files changed, 6 insertions(+), 8 deletions(-) > > diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c > b/drivers/net/ethernet/broadcom/bgmac-bcma.c > index 5ef60d4f12b4..d59cfcc4c4d5 100644 > --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c > +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c > @@ -144,7 +144,7 @@ static int bgmac_probe(struct bcma_device *core) > goto err; > } > > - ether_addr_copy(bgmac->mac_addr, mac); > + ether_addr_copy(bgmac->net_dev->dev_addr, mac); > > /* On BCM4706 we need common core to access PHY */ > if (core->id.id == BCMA_CORE_4706_MAC_GBIT && > diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c > b/drivers/net/ethernet/broadcom/bgmac-platform.c > index 805e6ed6c390..7b1af950f312 100644 > --- a/drivers/net/ethernet/broadcom/bgmac-platform.c > +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c > @@ -169,7 +169,7 @@ static int bgmac_probe(struct platform_device *pdev) > > mac_addr = of_get_mac_address(np); > if (mac_addr) > - ether_addr_copy(bgmac->mac_addr, mac_addr); > + ether_addr_copy(bgmac->net_dev->dev_addr, mac_addr); > else > dev_warn(>dev, "MAC address not present in device > tree\n"); > > diff --git a/drivers/net/ethernet/broadcom/bgmac.c > b/drivers/net/ethernet/broadcom/bgmac.c > index 20fe2520da42..415046750bb4 100644 > --- a/drivers/net/ethernet/broadcom/bgmac.c > +++ b/drivers/net/ethernet/broadcom/bgmac.c > @@ -1477,14 +1477,13 @@ int bgmac_enet_probe(struct bgmac *bgmac) > net_dev->irq = bgmac->irq; > SET_NETDEV_DEV(net_dev, bgmac->dev); > > - if (!is_valid_ether_addr(bgmac->mac_addr)) { > + if (!is_valid_ether_addr(net_dev->dev_addr)) { > dev_err(bgmac->dev, "Invalid MAC addr: %pM\n", > - bgmac->mac_addr); > - eth_random_addr(bgmac->mac_addr); > + net_dev->dev_addr); > + eth_hw_addr_random(net_dev); > dev_warn(bgmac->dev, "Using random MAC: %pM\n", > -bgmac->mac_addr); > +net_dev->dev_addr); > } > - ether_addr_copy(net_dev->dev_addr, bgmac->mac_addr); > > /* This (reset &) enable is not preset in specs or reference driver > but > * Broadcom does it in arch PCI code when enabling fake PCI device. > diff --git a/drivers/net/ethernet/broadcom/bgmac.h > b/drivers/net/ethernet/broadcom/bgmac.h > index ab2db76e4fb8..248727dc62f2 100644 > --- a/drivers/net/ethernet/broadcom/bgmac.h > +++ b/drivers/net/ethernet/broadcom/bgmac.h > @@ -474,7 +474,6 @@ struct bgmac { > > struct device *dev; > struct device *dma_dev; > - unsigned char mac_addr[ETH_ALEN]; > u32 feature_flags; > > struct net_device *net_dev; > -- > 2.11.0 > >
[PATCH net] net: phy: Initialize mdio clock at probe function
From: Yendapally Reddy Dhananjaya Reddy <yendapally.re...@broadcom.com> USB PHYs need the MDIO clock divisor enabled earlier to work. Initialize mdio clock divisor in probe function. The ext bus bit available in the same register will be used by mdio mux to enable external mdio. Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.re...@broadcom.com> Fixes: ddc24ae1 ("net: phy: Broadcom iProc MDIO bus driver") Reviewed-by: Florian Fainelli <f.faine...@gmail.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/mdio-bcm-iproc.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/mdio-bcm-iproc.c b/drivers/net/phy/mdio-bcm-iproc.c index c0b4e65..46fe1ae 100644 --- a/drivers/net/phy/mdio-bcm-iproc.c +++ b/drivers/net/phy/mdio-bcm-iproc.c @@ -81,8 +81,6 @@ static int iproc_mdio_read(struct mii_bus *bus, int phy_id, int reg) if (rc) return rc; - iproc_mdio_config_clk(priv->base); - /* Prepare the read operation */ cmd = (MII_DATA_TA_VAL << MII_DATA_TA_SHIFT) | (reg << MII_DATA_RA_SHIFT) | @@ -112,8 +110,6 @@ static int iproc_mdio_write(struct mii_bus *bus, int phy_id, if (rc) return rc; - iproc_mdio_config_clk(priv->base); - /* Prepare the write operation */ cmd = (MII_DATA_TA_VAL << MII_DATA_TA_SHIFT) | (reg << MII_DATA_RA_SHIFT) | @@ -163,6 +159,8 @@ static int iproc_mdio_probe(struct platform_device *pdev) bus->read = iproc_mdio_read; bus->write = iproc_mdio_write; + iproc_mdio_config_clk(priv->base); + rc = of_mdiobus_register(bus, pdev->dev.of_node); if (rc) { dev_err(>dev, "MDIO bus registration failed\n"); -- 2.7.4
[PATCH net v3 0/2] net: ethernet: bgmac: bug fixes
Changes in v3: * Reworked the init sequence patch to only remove the device reset if the device is actually in reset. Given that this code doesn't bear much resemblance to the original code, I'm changing the author of the patch. This was tested on NS2 SVK. Changes in v2: * Reworked the first match to make it more obvious what portions of the register were being preserved (Per Rafal Mileki) * Style change to reorder the function variables in patch 2 (per Sergei Shtylyov) Bug fixes for bgmac driver Hari Vyas (1): net: ethernet: bgmac: mac address change bug Jon Mason (1): net: ethernet: bgmac: init sequence bug drivers/net/ethernet/broadcom/bgmac-platform.c | 27 -- drivers/net/ethernet/broadcom/bgmac.c | 6 +- drivers/net/ethernet/broadcom/bgmac.h | 16 +++ 3 files changed, 38 insertions(+), 11 deletions(-) -- 2.7.4
[PATCH net-next v2 1/3] net: ethernet: bgmac: use #defines for MAX size
The maximum frame size is really just the standard ethernet frame size and FCS. So use those existing defines to make the code a little more beautiful. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 6d0b5b3..5a518fe 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -402,7 +402,7 @@ #define BGMAC_WEIGHT 64 -#define ETHER_MAX_LEN 1518 +#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETH_FCS_LEN) /* Feature Flags */ #define BGMAC_FEAT_TX_MASK_SETUP BIT(0) -- 2.7.4
[PATCH net-next v2 0/3] net: ethernet: bgmac: PM support and clean-ups
Changes in v2: * Reworked the PM patch with Florian's suggestions Add code to support Power Management (only tested on NS2), and add some code clean-ups Joey Zhong (1): net: ethernet: bgmac: driver power manangement Jon Mason (2): net: ethernet: bgmac: use #defines for MAX size net: ethernet: bgmac: unify code of the same family drivers/net/ethernet/broadcom/bgmac-bcma.c | 64 +++--- drivers/net/ethernet/broadcom/bgmac-platform.c | 34 ++ drivers/net/ethernet/broadcom/bgmac.c | 51 drivers/net/ethernet/broadcom/bgmac.h | 4 +- 4 files changed, 116 insertions(+), 37 deletions(-) -- 2.7.4
[PATCH net-next v2 3/3] net: ethernet: bgmac: driver power manangement
From: Joey Zhong <zho...@broadcom.com> Implement suspend/resume callbacks in the bgmac driver. This makes sure that we de-initialize and re-initialize the hardware correctly before entering suspend and when resuming. Signed-off-by: Joey Zhong <zho...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 34 + drivers/net/ethernet/broadcom/bgmac.c | 51 ++ drivers/net/ethernet/broadcom/bgmac.h | 2 + 3 files changed, 87 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 2d153f7..3df91e7 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -21,8 +21,12 @@ #include #include "bgmac.h" +#define NICPM_PADRING_CFG 0x0004 #define NICPM_IOMUX_CTRL 0x0008 +#define NICPM_PADRING_CFG_INIT_VAL 0x7400 +#define NICPM_IOMUX_CTRL_INIT_VAL_AX 0x2188 + #define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 #define NICPM_IOMUX_CTRL_SPD_SHIFT 10 #define NICPM_IOMUX_CTRL_SPD_10M 0 @@ -108,6 +112,10 @@ static void bgmac_nicpm_speed_set(struct net_device *net_dev) if (!bgmac->plat.nicpm_base) return; + /* SET RGMII IO CONFIG */ + writel(NICPM_PADRING_CFG_INIT_VAL, + bgmac->plat.nicpm_base + NICPM_PADRING_CFG); + val = NICPM_IOMUX_CTRL_INIT_VAL; switch (bgmac->net_dev->phydev->speed) { default: @@ -239,6 +247,31 @@ static int bgmac_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int bgmac_suspend(struct device *dev) +{ + struct bgmac *bgmac = dev_get_drvdata(dev); + + return bgmac_enet_suspend(bgmac); +} + +static int bgmac_resume(struct device *dev) +{ + struct bgmac *bgmac = dev_get_drvdata(dev); + + return bgmac_enet_resume(bgmac); +} + +static const struct dev_pm_ops bgmac_pm_ops = { + .suspend = bgmac_suspend, + .resume = bgmac_resume +}; + +#define BGMAC_PM_OPS (_pm_ops) +#else +#define BGMAC_PM_OPS NULL +#endif /* CONFIG_PM */ + static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, @@ -252,6 +285,7 @@ static struct platform_driver bgmac_enet_driver = { .driver = { .name = "bgmac-enet", .of_match_table = bgmac_of_enet_match, + .pm = BGMAC_PM_OPS }, .probe = bgmac_probe, .remove = bgmac_remove, diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index bd549f8..e78c91d 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1478,6 +1478,7 @@ int bgmac_enet_probe(struct bgmac *bgmac) net_dev->irq = bgmac->irq; SET_NETDEV_DEV(net_dev, bgmac->dev); + dev_set_drvdata(bgmac->dev, bgmac); if (!is_valid_ether_addr(bgmac->mac_addr)) { dev_err(bgmac->dev, "Invalid MAC addr: %pM\n", @@ -1551,5 +1552,55 @@ void bgmac_enet_remove(struct bgmac *bgmac) } EXPORT_SYMBOL_GPL(bgmac_enet_remove); +int bgmac_enet_suspend(struct bgmac *bgmac) +{ + if (!netif_running(bgmac->net_dev)) + return 0; + + phy_stop(bgmac->net_dev->phydev); + + netif_stop_queue(bgmac->net_dev); + + napi_disable(>napi); + + netif_tx_lock(bgmac->net_dev); + netif_device_detach(bgmac->net_dev); + netif_tx_unlock(bgmac->net_dev); + + bgmac_chip_intrs_off(bgmac); + bgmac_chip_reset(bgmac); + bgmac_dma_cleanup(bgmac); + + return 0; +} +EXPORT_SYMBOL_GPL(bgmac_enet_suspend); + +int bgmac_enet_resume(struct bgmac *bgmac) +{ + int rc; + + if (netif_running(bgmac->net_dev)) + return 0; + + rc = bgmac_dma_init(bgmac); + if (rc) + return rc; + + bgmac_chip_init(bgmac); + + napi_enable(>napi); + + netif_tx_lock(bgmac->net_dev); + netif_device_attach(bgmac->net_dev); + netif_tx_unlock(bgmac->net_dev); + + netif_start_queue(bgmac->net_dev); + + phy_start(bgmac->net_dev->phydev); + + return 0; +} +EXPORT_SYMBOL_GPL(bgmac_enet_resume); + MODULE_AUTHOR("Rafał Miłecki"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 5a518fe..741ca27 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -538,6 +538,8 @@ int bgmac_enet_probe(struct bgmac *bgmac); void bgmac_enet_remove(struct bgmac *bgmac); void bgmac_adjust_link(struct net_device *net_dev); int bgmac_phy_
[PATCH net-next v2 2/3] net: ethernet: bgmac: unify code of the same family
BCM471X and BCM535X are of the same family (from what I can derive from internal documents). Group them into the case statement together, which results in more code reuse. Also, use existing helper variables to make the code a little more readable too. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 64 +- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index 5ef60d4..f5c27f4 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -192,36 +192,50 @@ static int bgmac_probe(struct bcma_device *core) goto err1; } - bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo & - BGMAC_BFL_ENETROBO); + bgmac->has_robosw = !!(sprom->boardflags_lo & BGMAC_BFL_ENETROBO); if (bgmac->has_robosw) dev_warn(bgmac->dev, "Support for Roboswitch not implemented\n"); - if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) + if (sprom->boardflags_lo & BGMAC_BFL_ENETADM) dev_warn(bgmac->dev, "Support for ADMtek ethernet switch not implemented\n"); /* Feature Flags */ - switch (core->bus->chipinfo.id) { + switch (ci->id) { + /* BCM 471X/535X family */ + case BCMA_CHIP_ID_BCM4716: + bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; + /* fallthrough */ + case BCMA_CHIP_ID_BCM47162: + bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; + bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + break; case BCMA_CHIP_ID_BCM5357: + case BCMA_CHIP_ID_BCM53572: bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47186) { - bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; + if (ci->pkg == BCMA_PKG_ID_BCM47188 || + ci->pkg == BCMA_PKG_ID_BCM47186) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; + bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM5358) + if (ci->pkg == BCMA_PKG_ID_BCM5358) bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII; break; - case BCMA_CHIP_ID_BCM53572: - bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + case BCMA_CHIP_ID_BCM53573: bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; - bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47188) { - bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; + bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + if (ci->pkg == BCMA_PKG_ID_BCM47189) bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; + if (core->core_unit == 0) { + bgmac->feature_flags |= BGMAC_FEAT_CC4_IF_SW_TYPE; + if (ci->pkg == BCMA_PKG_ID_BCM47189) + bgmac->feature_flags |= + BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII; + } else if (core->core_unit == 1) { + bgmac->feature_flags |= BGMAC_FEAT_IRQ_ID_OOB_6; + bgmac->feature_flags |= BGMAC_FEAT_CC7_IF_TYPE_RGMII; } break; case BCMA_CHIP_ID_BCM4749: @@ -229,18 +243,11 @@ static int bgmac_probe(struct bcma_device *core) bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == 10) { + if (ci->pkg == 10) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } break; - case BCMA_CHIP_ID_BCM4716: - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - /* fallthrough */ - case BCMA_CHIP_ID_BCM47162: - bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; - bgmac->feature_fl
[PATCH net v3 2/2] net: ethernet: bgmac: mac address change bug
From: Hari Vyas <ha...@broadcom.com> ndo_set_mac_address() passes struct sockaddr * as 2nd parameter to bgmac_set_mac_address() but code assumed u8 *. This caused two bytes chopping and the wrong mac address was configured. Signed-off-by: Hari Vyas <ha...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 4e209001b86 ("bgmac: write mac address to hardware in ndo_set_mac_address") --- drivers/net/ethernet/broadcom/bgmac.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index fe88126..bd549f8 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1221,12 +1221,16 @@ static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb, static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) { struct bgmac *bgmac = netdev_priv(net_dev); + struct sockaddr *sa = addr; int ret; ret = eth_prepare_mac_addr_change(net_dev, addr); if (ret < 0) return ret; - bgmac_write_mac_address(bgmac, (u8 *)addr); + + ether_addr_copy(bgmac->mac_addr, sa->sa_data); + bgmac_write_mac_address(bgmac, bgmac->mac_addr); + eth_commit_mac_addr_change(net_dev, addr); return 0; } -- 2.7.4
[PATCH net v3 1/2] net: ethernet: bgmac: init sequence bug
Fix a bug in the 'bgmac' driver init sequence that blind writes for init sequence where it should preserve most bits other than the ones it is deliberately manipulating. The code now checks to see if the adapter needs to be brought out of reset (where as before it was doing an IDM write to bring it out of reset regardless of whether it was in reset or not). Also, removed unnecessary usleeps (as there is already a read present to flush the IDM writes). Signed-off-by: Zac Schroff <zschr...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: f6a95a24957 ("net: ethernet: bgmac: Add platform device support") --- drivers/net/ethernet/broadcom/bgmac-platform.c | 27 -- drivers/net/ethernet/broadcom/bgmac.h | 16 +++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 805e6ed..3aba785 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -51,8 +51,7 @@ static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value) static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) { - if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & -(BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK) + if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != BGMAC_CLK_EN) return false; if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) return false; @@ -61,17 +60,25 @@ static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) { - bgmac_idm_write(bgmac, BCMA_IOCTL, - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); - bgmac_idm_read(bgmac, BCMA_IOCTL); + u32 val; - bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); - bgmac_idm_read(bgmac, BCMA_RESET_CTL); - udelay(1); + /* The Reset Control register only contains a single bit to show if the +* controller is currently in reset. Do a sanity check here, just in +* case the bootloader happened to leave the device in reset. +*/ + val = bgmac_idm_read(bgmac, BCMA_RESET_CTL); + if (val) { + bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); + bgmac_idm_read(bgmac, BCMA_RESET_CTL); + } - bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); + val = bgmac_idm_read(bgmac, BCMA_IOCTL); + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | +BGMAC_ARUSER); + val |= BGMAC_CLK_EN; + bgmac_idm_write(bgmac, BCMA_IOCTL, val); bgmac_idm_read(bgmac, BCMA_IOCTL); - udelay(1); } static void platform_bgmac_cco_ctl_maskset(struct bgmac *bgmac, u32 offset, diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index ab2db76..6d0b5b3 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -213,6 +213,22 @@ /* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */ #define BGMAC_BCMA_IOCTL_SW_CLKEN 0x0004 /* PHY Clock Enable */ #define BGMAC_BCMA_IOCTL_SW_RESET 0x0008 /* PHY Reset */ +/* The IOCTL values appear to be different in NS, NSP, and NS2, and do not match + * the values directly above + */ +#define BGMAC_CLK_EN BIT(0) +#define BGMAC_RESERVED_0 BIT(1) +#define BGMAC_SOURCE_SYNC_MODE_EN BIT(2) +#define BGMAC_DEST_SYNC_MODE_ENBIT(3) +#define BGMAC_TX_CLK_OUT_INVERT_EN BIT(4) +#define BGMAC_DIRECT_GMII_MODE BIT(5) +#define BGMAC_CLK_250_SEL BIT(6) +#define BGMAC_AWCACHE (0xf << 7) +#define BGMAC_RESERVED_1 (0x1f << 11) +#define BGMAC_ARCACHE (0xf << 16) +#define BGMAC_AWUSER (0x3f << 20) +#define BGMAC_ARUSER (0x3f << 26) +#define BGMAC_RESERVED BIT(31) /* BCMA GMAC core specific IO status (BCMA_IOST) flags */ #define BGMAC_BCMA_IOST_ATTACHED 0x0800 -- 2.7.4
Re: [PATCH 3/3] net: ethernet: bgmac: driver power manangement
On Fri, Feb 3, 2017 at 9:16 PM, Florian Fainelli <f.faine...@gmail.com> wrote: > On 02/03/2017 01:39 PM, Jon Mason wrote: >> From: Joey Zhong <zho...@broadcom.com> >> >> Implements suspend/resume, external phy 54810 is assumed >> to remain powered up during deep-sleep for wake-on-lane. > > s/wake-on-lane/Wake-on-LAN, are you positive phy_stop() is not > suspending the PHY and issuing BMCR_PWRDOWN write? > > This also seems incomplete in that, if the device is really configured > for Wake-on-LAN (through ethtool) you should call > device_set_wakeup_capable() and then check for device_may_wakeup() > during suspend or resume to know which part of the suspend/resume > portion should be done. You could refer to bcmgenet for an example. After some internal discussion, WOL is not supported by our SVK. So, we have no way of testing it. Given this limitation, I'm removing the WOL comment until such time as we can actually test the logic. >> >> +int bgmac_enet_suspend(struct bgmac *bgmac) >> +{ >> + netdev_info(bgmac->net_dev, "Suspending\n"); > > remove that message > >> + >> + if (netif_running(bgmac->net_dev)) { >> + netif_stop_queue(bgmac->net_dev); >> + >> + napi_disable(>napi); >> + >> + netif_tx_lock(bgmac->net_dev); >> + netif_device_detach(bgmac->net_dev); >> + netif_tx_unlock(bgmac->net_dev); >> + >> + bgmac_chip_intrs_off(bgmac); >> + bgmac_chip_reset(bgmac); >> + bgmac_dma_cleanup(bgmac); >> + } > > Can you change the indentation to test for netiff_running() first and > return 0 in that case? > >> + >> + phy_stop(bgmac->net_dev->phydev); >> + >> + return 0; >> +} >> +EXPORT_SYMBOL_GPL(bgmac_enet_suspend); >> + >> +int bgmac_enet_resume(struct bgmac *bgmac) >> +{ >> + int rc; >> + >> + netdev_info(bgmac->net_dev, "Resuming\n"); > > Same here, this needs to be removed. Will do this and above. Thanks, Jon > >> + >> + phy_start(bgmac->net_dev->phydev); >> + >> + if (netif_running(bgmac->net_dev)) { >> + rc = bgmac_dma_init(bgmac); >> + if (rc) >> + return rc; >> + >> + bgmac_chip_init(bgmac); >> + >> + napi_enable(>napi); >> + >> + netif_tx_lock(bgmac->net_dev); >> + netif_device_attach(bgmac->net_dev); >> + netif_tx_unlock(bgmac->net_dev); >> + >> + netif_start_queue(bgmac->net_dev); >> + } > -- > Florian
Re: [PATCH v2 1/2] net: ethernet: bgmac: init sequence bug
On Fri, Feb 3, 2017 at 4:41 PM, Rafał Miłecki <ra...@milecki.pl> wrote: > On 02/03/2017 10:08 PM, Jon Mason wrote: >> >> @@ -61,15 +60,20 @@ static bool platform_bgmac_clk_enabled(struct bgmac >> *bgmac) >> >> static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) >> { >> - bgmac_idm_write(bgmac, BCMA_IOCTL, >> - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); >> + u32 val; >> + >> + val = bgmac_idm_read(bgmac, BCMA_IOCTL); >> + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ >> + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | >> +BGMAC_ARUSER); >> + val |= BGMAC_CLK_EN; >> bgmac_idm_read(bgmac, BCMA_IOCTL); > > > This read was previously following write op most likely to flush it or > something. I don't think it makes any sense to read after read. Actually, that is sloppy coding on my part. It should have a write prior to the read to match what was there before. I find it odd that it worked when I tested this patch. It makes me wonder if this "modify, reset, modify" series is really necessary after all. The docs indicate that writing a 0 to the reset brings it out of reset. I do not see any code that puts the HW in reset. So, unless the bootloader puts the HW in reset or it is in the reset state by default, this seems like unnecessary code. I can add some CYA logic to read and see if it is in reset, toggle the bit, and then just do the CLK enable. Thoughts? Thanks, Jon
Re: [PATCH 2/3] net: ethernet: bgmac: unify code of the same family
On Fri, Feb 3, 2017 at 4:48 PM, Rafał Miłecki <ra...@milecki.pl> wrote: > On 2017-02-03 22:39, Jon Mason wrote: >> >> BCM471X and BCM535X are of the same family (from what I can derive from >> internal documents). Group them into the case statement together, which >> results in more code reuse. >> >> Also, use existing helper variables to make the code a little more >> readable too. >> >> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > > > I'd like to review it / test it on few devices. Please give me weekend for > that. Yes, please test this as much as you can. The code move was pretty innocuous, and those are always the times when it comes back to bite me. Thanks, Jon
[PATCH net-next 0/3] net: ethernet: bgmac: PM support and clean-ups
Add code to support Power Management (only tested on NS2), and add some code clean-ups Joey Zhong (1): net: ethernet: bgmac: driver power manangement Jon Mason (2): net: ethernet: bgmac: use #defines for MAX size net: ethernet: bgmac: unify code of the same family drivers/net/ethernet/broadcom/bgmac-bcma.c | 64 +++--- drivers/net/ethernet/broadcom/bgmac-platform.c | 34 ++ drivers/net/ethernet/broadcom/bgmac.c | 53 + drivers/net/ethernet/broadcom/bgmac.h | 4 +- 4 files changed, 118 insertions(+), 37 deletions(-) -- 2.7.4
[PATCH 2/3] net: ethernet: bgmac: unify code of the same family
BCM471X and BCM535X are of the same family (from what I can derive from internal documents). Group them into the case statement together, which results in more code reuse. Also, use existing helper variables to make the code a little more readable too. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 64 +- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index 5ef60d4..f5c27f4 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -192,36 +192,50 @@ static int bgmac_probe(struct bcma_device *core) goto err1; } - bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo & - BGMAC_BFL_ENETROBO); + bgmac->has_robosw = !!(sprom->boardflags_lo & BGMAC_BFL_ENETROBO); if (bgmac->has_robosw) dev_warn(bgmac->dev, "Support for Roboswitch not implemented\n"); - if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) + if (sprom->boardflags_lo & BGMAC_BFL_ENETADM) dev_warn(bgmac->dev, "Support for ADMtek ethernet switch not implemented\n"); /* Feature Flags */ - switch (core->bus->chipinfo.id) { + switch (ci->id) { + /* BCM 471X/535X family */ + case BCMA_CHIP_ID_BCM4716: + bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; + /* fallthrough */ + case BCMA_CHIP_ID_BCM47162: + bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; + bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + break; case BCMA_CHIP_ID_BCM5357: + case BCMA_CHIP_ID_BCM53572: bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47186) { - bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; + if (ci->pkg == BCMA_PKG_ID_BCM47188 || + ci->pkg == BCMA_PKG_ID_BCM47186) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; + bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM5358) + if (ci->pkg == BCMA_PKG_ID_BCM5358) bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII; break; - case BCMA_CHIP_ID_BCM53572: - bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + case BCMA_CHIP_ID_BCM53573: bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; - bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47188) { - bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; + bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK; + if (ci->pkg == BCMA_PKG_ID_BCM47189) bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; + if (core->core_unit == 0) { + bgmac->feature_flags |= BGMAC_FEAT_CC4_IF_SW_TYPE; + if (ci->pkg == BCMA_PKG_ID_BCM47189) + bgmac->feature_flags |= + BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII; + } else if (core->core_unit == 1) { + bgmac->feature_flags |= BGMAC_FEAT_IRQ_ID_OOB_6; + bgmac->feature_flags |= BGMAC_FEAT_CC7_IF_TYPE_RGMII; } break; case BCMA_CHIP_ID_BCM4749: @@ -229,18 +243,11 @@ static int bgmac_probe(struct bcma_device *core) bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (core->bus->chipinfo.pkg == 10) { + if (ci->pkg == 10) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } break; - case BCMA_CHIP_ID_BCM4716: - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - /* fallthrough */ - case BCMA_CHIP_ID_BCM47162: - bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2; - bgmac->feature_fl
[PATCH 1/3] net: ethernet: bgmac: use #defines for MAX size
The maximum frame size is really just the standard ethernet frame size and FCS. So use those existing defines to make the code a little more beautiful. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 6d0b5b3..5a518fe 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -402,7 +402,7 @@ #define BGMAC_WEIGHT 64 -#define ETHER_MAX_LEN 1518 +#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETH_FCS_LEN) /* Feature Flags */ #define BGMAC_FEAT_TX_MASK_SETUP BIT(0) -- 2.7.4
[PATCH 3/3] net: ethernet: bgmac: driver power manangement
From: Joey Zhong <zho...@broadcom.com> Implements suspend/resume, external phy 54810 is assumed to remain powered up during deep-sleep for wake-on-lane. Signed-off-by: Joey Zhong <zho...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 34 + drivers/net/ethernet/broadcom/bgmac.c | 53 ++ drivers/net/ethernet/broadcom/bgmac.h | 2 + 3 files changed, 89 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 2d153f7..3df91e7 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -21,8 +21,12 @@ #include #include "bgmac.h" +#define NICPM_PADRING_CFG 0x0004 #define NICPM_IOMUX_CTRL 0x0008 +#define NICPM_PADRING_CFG_INIT_VAL 0x7400 +#define NICPM_IOMUX_CTRL_INIT_VAL_AX 0x2188 + #define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 #define NICPM_IOMUX_CTRL_SPD_SHIFT 10 #define NICPM_IOMUX_CTRL_SPD_10M 0 @@ -108,6 +112,10 @@ static void bgmac_nicpm_speed_set(struct net_device *net_dev) if (!bgmac->plat.nicpm_base) return; + /* SET RGMII IO CONFIG */ + writel(NICPM_PADRING_CFG_INIT_VAL, + bgmac->plat.nicpm_base + NICPM_PADRING_CFG); + val = NICPM_IOMUX_CTRL_INIT_VAL; switch (bgmac->net_dev->phydev->speed) { default: @@ -239,6 +247,31 @@ static int bgmac_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int bgmac_suspend(struct device *dev) +{ + struct bgmac *bgmac = dev_get_drvdata(dev); + + return bgmac_enet_suspend(bgmac); +} + +static int bgmac_resume(struct device *dev) +{ + struct bgmac *bgmac = dev_get_drvdata(dev); + + return bgmac_enet_resume(bgmac); +} + +static const struct dev_pm_ops bgmac_pm_ops = { + .suspend = bgmac_suspend, + .resume = bgmac_resume +}; + +#define BGMAC_PM_OPS (_pm_ops) +#else +#define BGMAC_PM_OPS NULL +#endif /* CONFIG_PM */ + static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, @@ -252,6 +285,7 @@ static struct platform_driver bgmac_enet_driver = { .driver = { .name = "bgmac-enet", .of_match_table = bgmac_of_enet_match, + .pm = BGMAC_PM_OPS }, .probe = bgmac_probe, .remove = bgmac_remove, diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index bd549f8..8d3aada 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1478,6 +1478,7 @@ int bgmac_enet_probe(struct bgmac *bgmac) net_dev->irq = bgmac->irq; SET_NETDEV_DEV(net_dev, bgmac->dev); + dev_set_drvdata(bgmac->dev, bgmac); if (!is_valid_ether_addr(bgmac->mac_addr)) { dev_err(bgmac->dev, "Invalid MAC addr: %pM\n", @@ -1551,5 +1552,57 @@ void bgmac_enet_remove(struct bgmac *bgmac) } EXPORT_SYMBOL_GPL(bgmac_enet_remove); +int bgmac_enet_suspend(struct bgmac *bgmac) +{ + netdev_info(bgmac->net_dev, "Suspending\n"); + + if (netif_running(bgmac->net_dev)) { + netif_stop_queue(bgmac->net_dev); + + napi_disable(>napi); + + netif_tx_lock(bgmac->net_dev); + netif_device_detach(bgmac->net_dev); + netif_tx_unlock(bgmac->net_dev); + + bgmac_chip_intrs_off(bgmac); + bgmac_chip_reset(bgmac); + bgmac_dma_cleanup(bgmac); + } + + phy_stop(bgmac->net_dev->phydev); + + return 0; +} +EXPORT_SYMBOL_GPL(bgmac_enet_suspend); + +int bgmac_enet_resume(struct bgmac *bgmac) +{ + int rc; + + netdev_info(bgmac->net_dev, "Resuming\n"); + + phy_start(bgmac->net_dev->phydev); + + if (netif_running(bgmac->net_dev)) { + rc = bgmac_dma_init(bgmac); + if (rc) + return rc; + + bgmac_chip_init(bgmac); + + napi_enable(>napi); + + netif_tx_lock(bgmac->net_dev); + netif_device_attach(bgmac->net_dev); + netif_tx_unlock(bgmac->net_dev); + + netif_start_queue(bgmac->net_dev); + } + + return 0; +} +EXPORT_SYMBOL_GPL(bgmac_enet_resume); + MODULE_AUTHOR("Rafał Miłecki"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 5a518fe..741ca27 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@
[PATCH v2 1/2] net: ethernet: bgmac: init sequence bug
From: Zac Schroff <zschr...@broadcom.com> Fix a bug in the 'bgmac' driver init sequence that blind writes for init sequence where it should preserve most bits other than the ones it is deliberately manipulating. Signed-off-by: Zac Schroff <zschr...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: f6a95a24957 ("net: ethernet: bgmac: Add platform device support") --- drivers/net/ethernet/broadcom/bgmac-platform.c | 14 +- drivers/net/ethernet/broadcom/bgmac.h | 16 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 6f736c1..a626dce 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -51,8 +51,7 @@ static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value) static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) { - if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & -(BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK) + if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != BGMAC_CLK_EN) return false; if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) return false; @@ -61,15 +60,20 @@ static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) { - bgmac_idm_write(bgmac, BCMA_IOCTL, - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); + u32 val; + + val = bgmac_idm_read(bgmac, BCMA_IOCTL); + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | +BGMAC_ARUSER); + val |= BGMAC_CLK_EN; bgmac_idm_read(bgmac, BCMA_IOCTL); bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); bgmac_idm_read(bgmac, BCMA_RESET_CTL); udelay(1); - bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); + bgmac_idm_write(bgmac, BCMA_IOCTL, val); bgmac_idm_read(bgmac, BCMA_IOCTL); udelay(1); } diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 71f493f..c8d33eb 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -213,6 +213,22 @@ /* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */ #define BGMAC_BCMA_IOCTL_SW_CLKEN 0x0004 /* PHY Clock Enable */ #define BGMAC_BCMA_IOCTL_SW_RESET 0x0008 /* PHY Reset */ +/* The IOCTL values appear to be different in NS, NSP, and NS2, and do not match + * the values directly above + */ +#define BGMAC_CLK_EN BIT(0) +#define BGMAC_RESERVED_0 BIT(1) +#define BGMAC_SOURCE_SYNC_MODE_EN BIT(2) +#define BGMAC_DEST_SYNC_MODE_ENBIT(3) +#define BGMAC_TX_CLK_OUT_INVERT_EN BIT(4) +#define BGMAC_DIRECT_GMII_MODE BIT(5) +#define BGMAC_CLK_250_SEL BIT(6) +#define BGMAC_AWCACHE (0xf << 7) +#define BGMAC_RESERVED_1 (0x1f << 11) +#define BGMAC_ARCACHE (0xf << 16) +#define BGMAC_AWUSER (0x3f << 20) +#define BGMAC_ARUSER (0x3f << 26) +#define BGMAC_RESERVED BIT(31) /* BCMA GMAC core specific IO status (BCMA_IOST) flags */ #define BGMAC_BCMA_IOST_ATTACHED 0x0800 -- 2.7.4
[PATCH v2 2/2] net: ethernet: bgmac: mac address change bug
From: Hari Vyas <ha...@broadcom.com> ndo_set_mac_address() passes struct sockaddr * as 2nd parameter to bgmac_set_mac_address() but code assumed u8 *. This caused two bytes chopping and the wrong mac address was configured. Signed-off-by: Hari Vyas <ha...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 4e209001b86 ("bgmac: write mac address to hardware in ndo_set_mac_address") --- drivers/net/ethernet/broadcom/bgmac.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 0e066dc6..737be50 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1221,12 +1221,16 @@ static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb, static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) { struct bgmac *bgmac = netdev_priv(net_dev); + struct sockaddr *sa = addr; int ret; ret = eth_prepare_mac_addr_change(net_dev, addr); if (ret < 0) return ret; - bgmac_write_mac_address(bgmac, (u8 *)addr); + + ether_addr_copy(bgmac->mac_addr, sa->sa_data); + bgmac_write_mac_address(bgmac, bgmac->mac_addr); + eth_commit_mac_addr_change(net_dev, addr); return 0; } -- 2.7.4
[PATCH v2 0/2] net: ethernet: bgmac: bug fixes
Changes in v2: * Reworked the first match to make it more obvious what portions of the register were being preserved (Per Rafal Mileki) * Style change to reorder the function variables in patch 2 (per Sergei Shtylyov) Bug fixes for bgmac driver Hari Vyas (1): net: ethernet: bgmac: mac address change bug Zac Schroff (1): net: ethernet: bgmac: init sequence bug drivers/net/ethernet/broadcom/bgmac-platform.c | 14 +- drivers/net/ethernet/broadcom/bgmac.c | 6 +- drivers/net/ethernet/broadcom/bgmac.h | 16 3 files changed, 30 insertions(+), 6 deletions(-) -- 2.7.4
Re: [PATCH v2 3/4] phy: Add USB3 PHY support for Broadcom NSP SoC
On Thu, Feb 2, 2017 at 1:48 AM, Rafał Miłecki <zaj...@gmail.com> wrote: > [Resending with fixed/complete Cc-s] > > On Tue, 17 Jan 2017 11:14:29 -0500, Yendapally Reddy Dhananjaya Reddy > <yendapally.re...@broadcom.com> wrote:> This patch adds support for Broadcom > NSP USB3 PHY >> >> Signed-off-by: Yendapally Reddy Dhananjaya Reddy >> <yendapally.re...@broadcom.com> > > Seriously?! I really dislike what you did there. > > NACK. > > You are aware this block is common for both: Northstar and Northstar Plus > and > we already have phy-bcm-ns-usb3.c! In fact Jon told me to rewrite my initial > driver to make is possible to reuse it on NSP and I did that! > > This is old comment from Jon: > > In 30 March 2016 at 23:31, Jon Mason <jon.ma...@broadcom.com> wrote: >> On Mon, Mar 28, 2016 at 9:46 PM, Florian Fainelli <f.faine...@gmail.com> >> wrote: >>> >>> CC: bcm-kernel-feedback-list, Jon >> >> >> This is a common IP block with NSP. I believe with some minor changes it >> can support both. Please allow me 1-2 days to look at these in more >> detail >> and see if I can get these patches working on NSP. > > Please start using existing code instead of inventing everything from the > scratch internally at Broadcom. You did the same thing with (Q)SPI driver. > > > This driver duplicates phy-bcm-ns-usb3.c and should have not been accepted. > I > strongly suggest *reverting* it and adjusting existing driver if needed. I agree that we need to be heading in the same direction with 4708/9 (Northstar) and Northstar+. Duplication of work is a sin (and if not, it should be). So, I apologize for this and let's move forward together. Regarding the SPI duplication of drivers, the QSPI driver covers a much broader array of SoCs across Broadcom, and was a joint effort between multiple teams internally. To resolve this, I believe the best way forward is to add QSPI to the 4708/9 device trees, and remove the BSPI driver from Linux. I'll have someone work on this internally and get it out ASAP. Regarding the duplication of function for the USB PHYs, the MDIO bus for our PHYs is the way we would like to support everything going forward. This MDIO bus supports more than just USB. So, it will be much more extensible in the future. Since there is already a USB PHY driver for NS, I would recommend that we modify that driver to have MDIO support. If we are in agreement, Kishon can drop the current series in his tree and Dhananjay will abandon the unaccepted ones. Thanks, Jon
Re: [PATCH 1/2] net: ethernet: bgmac: init sequence bug
On Thu, Feb 2, 2017 at 3:15 PM, Rafał Miłeckiwrote: > On 2017-02-02 01:31, Zac Schroff wrote: >> >> How about BCMA_IOCTL_PRESERVE_ACROSS_INIT? > > > I think wireless drivers may still set some these bits during init. > > I've a simpler idea: make it bgmac specific. Call it sth like > BGMAC_BCMA_IOCTL_PRESERVE > BGMAC_BCMA_IOCTL_RESERVED > BGMAC_BCMA_IOCTL_DONT_TOUCH Yes, I am listing out all of the fields in that register. We can be intelligent about what we mask off :)
Re: [PATCH 1/2] net: ethernet: bgmac: init sequence bug
On Wed, Feb 1, 2017 at 6:06 PM, Rafał Miłecki <ra...@milecki.pl> wrote: > On 02/01/2017 11:39 PM, Jon Mason wrote: >> >> From: Zac Schroff <zschr...@broadcom.com> >> >> Fix a bug in the 'bgmac' driver init sequence that blind writes for init >> sequence where it should preserve most bits other than the ones it is >> deliberately manipulating. >> >> Signed-off-by: Zac Schroff <zschr...@broadcom.com> >> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> >> Fixes: f6a95a24957 ("net: ethernet: bgmac: Add platform device support") >> --- >> drivers/net/ethernet/broadcom/bgmac-platform.c | 10 +++--- >> include/linux/bcma/bcma_regs.h | 1 + >> 2 files changed, 8 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c >> b/drivers/net/ethernet/broadcom/bgmac-platform.c >> index 6f736c1..9bbe05c 100644 >> --- a/drivers/net/ethernet/broadcom/bgmac-platform.c >> +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c >> @@ -61,15 +61,19 @@ static bool platform_bgmac_clk_enabled(struct bgmac >> *bgmac) >> >> static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) >> { >> - bgmac_idm_write(bgmac, BCMA_IOCTL, >> - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); >> + u32 regval; >> + >> + /* Some bits of BCMA_IOCTL set by HW/ATF & should not change */ >> + regval = bgmac_idm_read(bgmac, BCMA_IOCTL) & >> BCMA_IOCTL_DO_NOT_MODIFY; >> + regval |= ((flags & (~BCMA_IOCTL_DO_NOT_MODIFY)) | >> BCMA_IOCTL_CLK); > > > You don't need these braces around whole calculation. > This should work the same: > (flags & (~BCMA_IOCTL_DO_NOT_MODIFY)) | BCMA_IOCTL_CLK Fair enough > > >> + bgmac_idm_write(bgmac, BCMA_IOCTL, regval | BCMA_IOCTL_FGC); >> bgmac_idm_read(bgmac, BCMA_IOCTL); >> >> bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); >> bgmac_idm_read(bgmac, BCMA_RESET_CTL); >> udelay(1); >> >> - bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); >> + bgmac_idm_write(bgmac, BCMA_IOCTL, regval); >> bgmac_idm_read(bgmac, BCMA_IOCTL); >> udelay(1); >> } >> diff --git a/include/linux/bcma/bcma_regs.h >> b/include/linux/bcma/bcma_regs.h >> index 9986f82..41d7404 100644 >> --- a/include/linux/bcma/bcma_regs.h >> +++ b/include/linux/bcma/bcma_regs.h >> @@ -31,6 +31,7 @@ >> #define BCMA_IOCTL_CORE_BITS 0x3FFC >> #define BCMA_IOCTL_PME_EN 0x4000 >> #define BCMA_IOCTL_BIST_EN0x8000 >> +#define BCMA_IOCTL_DO_NOT_MODIFY 0x7F80 > > > This sounds like a pretty bad name. Name change coming > Take a look at brcmsmac and SICF_*: > http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/brcm80211/brcmsmac/d11.h?v=4.9#L1737 > > Or b43 and B43_BCMA_IOCTL_*: > http://lxr.free-electrons.com/source/drivers/net/wireless/broadcom/b43/b43.h?v=4.9#L494 > > Both drives modify bits you marked as DO_NOT_MODIFY and they are OK. I think the point Zac was trying to make is that this is changing bits that aren't meaning to be modified. We should only be flipping the bits necessary to enable the clocks, etc. Bootloaders, etc might be setting bits (and in our case they are) which are being removed forcing it to a predefined value. Thanks, Jon
Re: [PATCH 2/2] net: ethernet: bgmac: mac address change bug
On Wed, Feb 1, 2017 at 6:12 PM, Rafał Miłecki <ra...@milecki.pl> wrote: > On 02/01/2017 11:39 PM, Jon Mason wrote: >> >> From: Hari Vyas <ha...@broadcom.com> >> >> ndo_set_mac_address() passes struct sockaddr * as 2nd parameter to >> bgmac_set_mac_address() but code assumed u8 *. This caused two bytes >> chopping and the wrong mac address was configured. >> >> Signed-off-by: Hari Vyas <ha...@broadcom.com> >> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> >> Fixes: 4e209001b86 ("bgmac: write mac address to hardware in >> ndo_set_mac_address") > > > Sounds OK, would it make sense to Cc stable? Sure, I'll add Sergei's mods and do a v2 with stable on the Cc list
[PATCH 2/2] net: ethernet: bgmac: mac address change bug
From: Hari Vyas <ha...@broadcom.com> ndo_set_mac_address() passes struct sockaddr * as 2nd parameter to bgmac_set_mac_address() but code assumed u8 *. This caused two bytes chopping and the wrong mac address was configured. Signed-off-by: Hari Vyas <ha...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: 4e209001b86 ("bgmac: write mac address to hardware in ndo_set_mac_address") --- drivers/net/ethernet/broadcom/bgmac.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 0e066dc6..ea24072 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1222,11 +1222,15 @@ static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) { struct bgmac *bgmac = netdev_priv(net_dev); int ret; + struct sockaddr *sa = addr; ret = eth_prepare_mac_addr_change(net_dev, addr); if (ret < 0) return ret; - bgmac_write_mac_address(bgmac, (u8 *)addr); + + ether_addr_copy(bgmac->mac_addr, sa->sa_data); + bgmac_write_mac_address(bgmac, bgmac->mac_addr); + eth_commit_mac_addr_change(net_dev, addr); return 0; } -- 2.7.4
[PATCH 0/2] net: ethernet: bgmac: bug fixes
Bug fixes for bgmac driver Hari Vyas (1): net: ethernet: bgmac: mac address change bug Zac Schroff (1): net: ethernet: bgmac: init sequence bug drivers/net/ethernet/broadcom/bgmac-platform.c | 10 +++--- drivers/net/ethernet/broadcom/bgmac.c | 6 +- include/linux/bcma/bcma_regs.h | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) -- 2.7.4
[PATCH 1/2] net: ethernet: bgmac: init sequence bug
From: Zac Schroff <zschr...@broadcom.com> Fix a bug in the 'bgmac' driver init sequence that blind writes for init sequence where it should preserve most bits other than the ones it is deliberately manipulating. Signed-off-by: Zac Schroff <zschr...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Fixes: f6a95a24957 ("net: ethernet: bgmac: Add platform device support") --- drivers/net/ethernet/broadcom/bgmac-platform.c | 10 +++--- include/linux/bcma/bcma_regs.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 6f736c1..9bbe05c 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -61,15 +61,19 @@ static bool platform_bgmac_clk_enabled(struct bgmac *bgmac) static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags) { - bgmac_idm_write(bgmac, BCMA_IOCTL, - (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); + u32 regval; + + /* Some bits of BCMA_IOCTL set by HW/ATF & should not change */ + regval = bgmac_idm_read(bgmac, BCMA_IOCTL) & BCMA_IOCTL_DO_NOT_MODIFY; + regval |= ((flags & (~BCMA_IOCTL_DO_NOT_MODIFY)) | BCMA_IOCTL_CLK); + bgmac_idm_write(bgmac, BCMA_IOCTL, regval | BCMA_IOCTL_FGC); bgmac_idm_read(bgmac, BCMA_IOCTL); bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0); bgmac_idm_read(bgmac, BCMA_RESET_CTL); udelay(1); - bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); + bgmac_idm_write(bgmac, BCMA_IOCTL, regval); bgmac_idm_read(bgmac, BCMA_IOCTL); udelay(1); } diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index 9986f82..41d7404 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h @@ -31,6 +31,7 @@ #define BCMA_IOCTL_CORE_BITS 0x3FFC #define BCMA_IOCTL_PME_EN 0x4000 #define BCMA_IOCTL_BIST_EN0x8000 +#define BCMA_IOCTL_DO_NOT_MODIFY 0x7F80 #define BCMA_IOST 0x0500 /* IO status */ #define BCMA_IOST_CORE_BITS 0x0FFF #define BCMA_IOST_DMA64 0x1000 -- 2.7.4
Re: [PATCH V2 3/3] net: bgmac: use PHY subsystem for initializing PHY
On Sat, Jan 28, 2017 at 10:08 PM, Florian Fainelliwrote: > > > On 01/28/2017 01:08 PM, Rafał Miłecki wrote: >> From: Rafał Miłecki >> >> This adds support for using bgmac with PHYs supported by standalone PHY >> drivers. Having any PHY initialization in bgmac is hacky and shouldn't >> be extended but rather removed if anyone has hardware to test it. >> >> Signed-off-by: Rafał Miłecki >> --- >> drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 10 ++ >> 1 file changed, 10 insertions(+) >> >> diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c >> b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c >> index 9d9984999dce..6ce80cbcb48e 100644 >> --- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c >> +++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c >> @@ -132,6 +132,10 @@ static void bcma_mdio_phy_init(struct bgmac *bgmac) >> struct bcma_chipinfo *ci = >bcma.core->bus->chipinfo; >> u8 i; >> >> + /* For some legacy hardware we do chipset-based PHY initialization here >> + * without even detecting PHY ID. It's hacky and should be cleaned as >> + * soon as someone can test it. >> + */ >> if (ci->id == BCMA_CHIP_ID_BCM5356) { >> for (i = 0; i < 5; i++) { >> bcma_mdio_phy_write(bgmac, i, 0x1f, 0x008b); >> @@ -140,6 +144,7 @@ static void bcma_mdio_phy_init(struct bgmac *bgmac) >> bcma_mdio_phy_write(bgmac, i, 0x12, 0x2aaa); >> bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b); >> } >> + return; > > That part is clearly initializing the built-in Ethernet switch's PHYs, > and so the natural place for that would be to stick these init values > into the Broadcom PHY driver. When b53-srab/b53_common attaches the > switch, it will scan all of these port's builtin PHYs and bind to an > appropriate PHY driver which could have this initialization as part of > the config_init routine for instance. Right now, we are most likely > using the Generic PHY. > > Here are the different PHY IDs you should read from these models if you > want to make a subsequent patch that moves this initialization down to > the Broadcom PHY driver: > > 5356: 0x03625DA0 > 5357/53572: 0x03625F00 > 4749: could either be 0x600D85F0 or the same as 53010 (0x600D8760), > unclear where that product came from... Jon, would you know by chance? The 4749 I have has a switch chip (bcm53115, according to the datasheet). So, I do not have any idea what PHYs this is referring to. > -- > Florian
Re: [PATCH v6 7/7] arm64: dts: NS2: add AMAC ethernet support
On Fri, Nov 04, 2016 at 04:31:40PM +0300, Sergei Shtylyov wrote: > Hello. > > On 11/4/2016 8:11 AM, Jon Mason wrote: > > >Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device > >tree > > > >Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > >--- > > arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 + > > arch/arm64/boot/dts/broadcom/ns2.dtsi| 12 > > 2 files changed, 17 insertions(+) > > > >diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts > >b/arch/arm64/boot/dts/broadcom/ns2-svk.dts > >index b09f3bc..c4d5442 100644 > >--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts > >+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts > >@@ -56,6 +56,10 @@ > > }; > > }; > > > >+ { > >+status = "ok"; > >The spec dictates it should be "okay" (although "ok" is also recognized). The rest of the file uses "ok". So, the addition above is consistent with the other entries. Perhaps a patch outside this series to convert the entire file from "ok" to "okay" would be acceptable to you. Thanks, Jon > > >+}; > >+ > > _phy0 { > > status = "ok"; > > }; > >@@ -174,6 +178,7 @@ > > _mux_iproc { > > mdio@10 { > > gphy0: eth-phy@10 { > >+enet-phy-lane-swap; > > reg = <0x10>; > > }; > > }; > [...] > > MBR, Sergei >
[PATCH v6 7/7] arm64: dts: NS2: add AMAC ethernet support
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 + arch/arm64/boot/dts/broadcom/ns2.dtsi| 12 2 files changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index b09f3bc..c4d5442 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -56,6 +56,10 @@ }; }; + { + status = "ok"; +}; + _phy0 { status = "ok"; }; @@ -174,6 +178,7 @@ _mux_iproc { mdio@10 { gphy0: eth-phy@10 { + enet-phy-lane-swap; reg = <0x10>; }; }; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index d95dc40..773ed59 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -191,6 +191,18 @@ #include "ns2-clock.dtsi" + enet: ethernet@6100 { + compatible = "brcm,ns2-amac"; + reg = <0x6100 0x1000>, + <0x6109 0x1000>, + <0x6103 0x100>; + reg-names = "amac_base", "idm_base", "nicpm_base"; + interrupts = ; + phy-handle = <>; + phy-mode = "rgmii"; + status = "disabled"; + }; + dma0: dma@6136 { compatible = "arm,pl330", "arm,primecell"; reg = <0x6136 0x1000>; -- 2.7.4
[PATCH v6 3/7] net: phy: broadcom: Add BCM54810 PHY entry
The BCM54810 PHY requires some semi-unique configuration, which results in some additional configuration in addition to the standard config. Also, some users of the BCM54810 require the PHY lanes to be swapped. Since there is no way to detect this, add a device tree query to see if it is applicable. Inspired-by: Vikas Soni <vs...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> Reviewed-by: Andrew Lunn <and...@lunn.ch> --- drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 58 +- include/linux/brcmphy.h| 9 +++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index ff31c10..d3fcfd2 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -217,7 +217,7 @@ config BROADCOM_PHY select BCM_NET_PHYLIB ---help--- Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, - BCM5481 and BCM5482 PHYs. + BCM5481, BCM54810 and BCM5482 PHYs. config CICADA_PHY tristate "Cicada PHYs" diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 3a64b3d..b1e32e9 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -18,7 +18,7 @@ #include #include #include - +#include #define BRCM_PHY_MODEL(phydev) \ ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) @@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); } +static int bcm54810_config(struct phy_device *phydev) +{ + int rc, val; + + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, + val); + if (rc < 0) + return rc; + + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; + val |= MII_BCM54XX_AUXCTL_MISC_WREN; + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, + val); + if (rc < 0) + return rc; + + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); + if (rc < 0) + return rc; + + return 0; +} + /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ static int bcm50610_a0_workaround(struct phy_device *phydev) { @@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev) (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) bcm54xx_adjust_rxrefclk(phydev); + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { + err = bcm54810_config(phydev); + if (err) + return err; + } + bcm54xx_phydsp_config(phydev); return 0; @@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev) static int bcm5481_config_aneg(struct phy_device *phydev) { + struct device_node *np = phydev->mdio.dev.of_node; int ret; /* Aneg firsly. */ @@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev) phy_write(phydev, 0x18, reg); } + if (of_property_read_bool(np, "enet-phy-lane-swap")) { + /* Lane Swap - Undocumented register...magic! */ + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, + 0x11B); + if (ret < 0) + return ret; + } + return ret; } @@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = { .ack_interrupt = bcm_phy_ack_intr, .config_intr= bcm_phy_config_intr, }, { + .phy_id = PHY_ID_BCM54810, + .phy_id_mask= 0xfff0, + .name = "Broadcom BCM54810", + .features = PHY_GBIT_FEATURES | + SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .config_init= bcm54xx_config_init, + .config_aneg= bcm5481_config_aneg, + .read_status= genphy_read_status, + .ack_interrupt = bcm_phy_ack_intr, + .config_intr= bcm_phy_config_intr, +}, { .phy_id = PHY_ID_BCM5482, .phy_id_mask= 0xfff0, .name = "Broadcom BCM5482", @@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
[PATCH v6 2/7] Documentation: devicetree: add PHY lane swap binding
Add the documentation for PHY lane swapping. This is a boolean entry to notify the phy device drivers that the TX/RX lanes need to be swapped. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> Reviewed-by: Andrew Lunn <and...@lunn.ch> --- Documentation/devicetree/bindings/net/phy.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index bc1c3c8..4627da3 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -35,6 +35,10 @@ Optional Properties: - broken-turn-around: If set, indicates the PHY device does not correctly release the turn around line low at the end of a MDIO transaction. +- enet-phy-lane-swap: If set, indicates the PHY will swap the TX/RX lanes to + compensate for the board being designed with the lanes swapped. + + Example: ethernet-phy@0 { -- 2.7.4
[PATCH v6 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
Add a helper function to read the AUXCTL register for the BCM54xx. This mirrors the bcm54xx_auxctl_write function already present in the code. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> --- drivers/net/phy/broadcom.c | 10 ++ include/linux/brcmphy.h| 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 583ef8a..3a64b3d 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver"); MODULE_AUTHOR("Maciej W. Rozycki"); MODULE_LICENSE("GPL"); +static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum) +{ + /* The register must be written to both the Shadow Register Select and +* the Shadow Read Register Selector +*/ + phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | + regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT); + return phy_read(phydev, MII_BCM54XX_AUX_CTL); +} + static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) { return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 60def78..0ed6691 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -110,6 +110,7 @@ #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX0x0200 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC0x0007 +#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK0x0007 -- 2.7.4
[PATCH v6 0/7] add NS2 support to bgmac
Changes in v6: * Use a common bgmac_phy_connect_direct (per Rafal Milecki) * Rebased on latest net-next * Added Reviewed-by to the relevant patches Changes in v5: * Change a pr_err to netdev_err (per Scott Branden) * Reword the lane swap binding documentation (per Andrew Lunn) Changes in v4: * Actually send out the lane swap binding doc patch (Per Scott Branden) * Remove unused #define (Per Andrew Lunn) Changes in v3: * Clean-up the bgmac DT binding doc (per Rob Herring) * Document the lane swap binding and make it generic (Per Andrew Lunn) Changes in v2: * Remove the PHY power-on (per Andrew Lunn) * Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn) This results on none of the original PHY code from Vikas being present. So, I'm removing him as an author and giving him "Inspired-by" credit. * Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian Fainelli) * Remove bgmac sleep (per Florian Fainelli) * Re-add bgmac chip reset (per Florian Fainelli and Ray Jui) * Rebased on latest net-next * Added patch for bcm54xx_auxctl_read, which is used in the BCM54810 Jon Mason (7): net: phy: broadcom: add bcm54xx_auxctl_read Documentation: devicetree: add PHY lane swap binding net: phy: broadcom: Add BCM54810 PHY entry Documentation: devicetree: net: add NS2 bindings to amac net: ethernet: bgmac: device tree phy enablement net: ethernet: bgmac: add NS2 support arm64: dts: NS2: add AMAC ethernet support .../devicetree/bindings/net/brcm,amac.txt | 16 +++-- Documentation/devicetree/bindings/net/phy.txt | 4 ++ arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++ arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 drivers/net/ethernet/broadcom/bgmac-bcma.c | 22 +++ drivers/net/ethernet/broadcom/bgmac-platform.c | 74 +- drivers/net/ethernet/broadcom/bgmac.c | 32 +++--- drivers/net/ethernet/broadcom/bgmac.h | 9 +++ drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 68 +++- include/linux/brcmphy.h| 10 +++ 11 files changed, 222 insertions(+), 32 deletions(-) -- 2.7.4
[PATCH v6 6/7] net: ethernet: bgmac: add NS2 support
Add support for the variant of amac hardware present in the Broadcom Northstar2 based SoCs. Northstar2 requires an additional register to be configured with the port speed/duplexity (NICPM). This can be added to the link callback to hide it from the instances that do not use this. Also, clearing of the pending interrupts on init is required due to observed issues on some platforms. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +- drivers/net/ethernet/broadcom/bgmac.c | 3 ++ drivers/net/ethernet/broadcom/bgmac.h | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index 4642940..6f736c1 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -14,12 +14,21 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include #include #include "bgmac.h" +#define NICPM_IOMUX_CTRL 0x0008 + +#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 +#define NICPM_IOMUX_CTRL_SPD_SHIFT 10 +#define NICPM_IOMUX_CTRL_SPD_10M 0 +#define NICPM_IOMUX_CTRL_SPD_100M 1 +#define NICPM_IOMUX_CTRL_SPD_1000M 2 + static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) { return readl(bgmac->plat.base + offset); @@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static void bgmac_nicpm_speed_set(struct net_device *net_dev) +{ + struct bgmac *bgmac = netdev_priv(net_dev); + u32 val; + + if (!bgmac->plat.nicpm_base) + return; + + val = NICPM_IOMUX_CTRL_INIT_VAL; + switch (bgmac->net_dev->phydev->speed) { + default: + netdev_err(net_dev, "Unsupported speed. Defaulting to 1000Mb\n"); + case SPEED_1000: + val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_100: + val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_10: + val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + } + + writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); + + bgmac_adjust_link(bgmac->net_dev); +} + static int platform_phy_connect(struct bgmac *bgmac) { struct phy_device *phy_dev; - phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, -bgmac_adjust_link); + if (bgmac->plat.nicpm_base) + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_nicpm_speed_set); + else + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_adjust_link); if (!phy_dev) { dev_err(bgmac->dev, "PHY connection failed\n"); return -ENODEV; @@ -156,6 +199,14 @@ static int bgmac_probe(struct platform_device *pdev) if (IS_ERR(bgmac->plat.idm_base)) return PTR_ERR(bgmac->plat.idm_base); + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); + if (regs) { + bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, + regs); + if (IS_ERR(bgmac->plat.nicpm_base)) + return PTR_ERR(bgmac->plat.nicpm_base); + } + bgmac->read = platform_bgmac_read; bgmac->write = platform_bgmac_write; bgmac->idm_read = platform_bgmac_idm_read; @@ -187,6 +238,7 @@ static int bgmac_remove(struct platform_device *pdev) static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, + {.compatible = "brcm,ns2-amac",}, {}, }; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 7f66ea7..a29787f 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac) /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac) { + /* Clear any erroneously pending interrupts */ + bgmac_write(bgmac, BGMAC
[PATCH v6 4/7] Documentation: devicetree: net: add NS2 bindings to amac
Clean-up the documentation to the bgmac-amac driver, per suggestion by Rob Herring, and add details for NS2 support. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> Reviewed-by: Florian Fainelli <f.faine...@gmail.com> --- Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ba5ecc1..2fefa1a 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings - Required properties: - - compatible: "brcm,amac" or "brcm,nsp-amac" - - reg:Address and length of the GMAC registers, - Address and length of the GMAC IDM registers - - reg-names: Names of the registers. Must have both "amac_base" and - "idm_base" + - compatible: "brcm,amac" + "brcm,nsp-amac" + "brcm,ns2-amac" + - reg:Address and length of the register set for the device. It + contains the information of registers in the same order as + described by reg-names + - reg-names: Names of the registers. + "amac_base":Address and length of the GMAC registers + "idm_base": Address and length of the GMAC IDM registers + "nicpm_base": Address and length of the NIC Port Manager + registers (required for Northstar2) - interrupts: Interrupt number Optional properties: -- 2.7.4
[PATCH v6 5/7] net: ethernet: bgmac: device tree phy enablement
Change the bgmac driver to allow for phy's defined by the device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 22 +++ drivers/net/ethernet/broadcom/bgmac-platform.c | 22 ++- drivers/net/ethernet/broadcom/bgmac.c | 29 +- drivers/net/ethernet/broadcom/bgmac.h | 8 +++ 4 files changed, 56 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index c16ec3a..4a4ffc0 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -80,6 +80,24 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask, bcma_maskset32(bgmac->bcma.cmn, offset, mask, set); } +static int bcma_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + char bus_id[MII_BUS_ID_SIZE + 3]; + + /* Connect to the PHY */ + snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, +bgmac->phyaddr); + phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "PHY connection failed\n"); + return PTR_ERR(phy_dev); + } + + return 0; +} + static const struct bcma_device_id bgmac_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), @@ -275,6 +293,10 @@ static int bgmac_probe(struct bcma_device *core) bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; + if (bgmac->mii_bus) + bgmac->phy_connect = bcma_phy_connect; + else + bgmac->phy_connect = bgmac_phy_connect_direct; err = bgmac_enet_probe(bgmac); if (err) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index be52f27..4642940 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "bgmac.h" @@ -86,6 +87,20 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static int platform_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + + phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, +bgmac_adjust_link); + if (!phy_dev) { + dev_err(bgmac->dev, "PHY connection failed\n"); + return -ENODEV; + } + + return 0; +} + static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -102,7 +117,6 @@ static int bgmac_probe(struct platform_device *pdev) /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; - bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4; bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP; bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP; @@ -151,6 +165,12 @@ static int bgmac_probe(struct platform_device *pdev) bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = platform_bgmac_get_bus_clock; bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32; + if (of_parse_phandle(np, "phy-handle", 0)) { + bgmac->phy_connect = platform_phy_connect; + } else { + bgmac->phy_connect = bgmac_phy_connect_direct; + bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; + } return bgmac_enet_probe(bgmac); } diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 31ca204..7f66ea7 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1388,7 +1388,7 @@ static const struct ethtool_ops bgmac_ethtool_ops = { * MII **/ -static void bgmac_adjust_link(struct net_device *net_dev) +void bgmac_adjust_link(struct net_device *net_dev) { struct bgmac *bgmac = netdev_priv(net_dev); struct phy_device *phy_dev = net_dev->phydev; @@ -1411,8 +1411,9 @@ static void bgmac_adjust_link(struct net_device *net_dev) phy_print_status(phy_dev); } } +EXPORT_SYMBOL_GPL(bgmac_adjust_link); -static int bgmac_phy_connect_direct(struct bgmac
Re: [PATCH v5 5/7] net: ethernet: bgmac: device tree phy enablement
On Thu, Nov 03, 2016 at 09:31:21AM +0100, Rafal Milecki wrote: > On 11/02/2016 06:08 PM, Jon Mason wrote: > >Change the bgmac driver to allow for phy's defined by the device tree > > This is a late review, I know, sorry... :( > > > >+static int bcma_phy_direct_connect(struct bgmac *bgmac) > >+{ > >+struct fixed_phy_status fphy_status = { > >+.link = 1, > >+.speed = SPEED_1000, > >+.duplex = DUPLEX_FULL, > >+}; > >+struct phy_device *phy_dev; > >+int err; > >+ > >+phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); > >+if (!phy_dev || IS_ERR(phy_dev)) { > >+dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); > >+return -ENODEV; > >+} > >+ > >+err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, > >+ PHY_INTERFACE_MODE_MII); > >+if (err) { > >+dev_err(bgmac->dev, "Connecting PHY failed\n"); > >+return err; > >+} > >+ > >+return err; > >+} > > This bcma specific function looks exactly the same as... > > > >+static int platform_phy_direct_connect(struct bgmac *bgmac) > >+{ > >+struct fixed_phy_status fphy_status = { > >+.link = 1, > >+.speed = SPEED_1000, > >+.duplex = DUPLEX_FULL, > >+}; > >+struct phy_device *phy_dev; > >+int err; > >+ > >+phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); > >+if (!phy_dev || IS_ERR(phy_dev)) { > >+dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); > >+return -ENODEV; > >+} > >+ > >+err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, > >+ PHY_INTERFACE_MODE_MII); > >+if (err) { > >+dev_err(bgmac->dev, "Connecting PHY failed\n"); > >+return err; > >+} > >+ > >+return err; > >+} > > This one. > > Would that make sense to keep bgmac_phy_connect_direct and just use it in > bcma/platform code? Yes, I was having the same internal debate. I hate the duplication of code, but I really wanted to keep the PHY logic out of the bgmac.c file. Do you think it is acceptable to make this an inline function in bgmac.h? Thanks, Jon
Re: [PATCH v5 4/7] Documentation: devicetree: net: add NS2 bindings to amac
On Wed, Nov 02, 2016 at 08:18:51PM +0300, Sergei Shtylyov wrote: > Hello. > > On 11/02/2016 08:08 PM, Jon Mason wrote: > > >Clean-up the documentation to the bgmac-amac driver, per suggestion by > >Rob Herring, and add details for NS2 support. > > > >Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > >--- > > Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++- > > 1 file changed, 11 insertions(+), 5 deletions(-) > > > >diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt > >b/Documentation/devicetree/bindings/net/brcm,amac.txt > >index ba5ecc1..2fefa1a 100644 > >--- a/Documentation/devicetree/bindings/net/brcm,amac.txt > >+++ b/Documentation/devicetree/bindings/net/brcm,amac.txt > >@@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings > > - > > > > Required properties: > >- - compatible: "brcm,amac" or "brcm,nsp-amac" > >- - reg: Address and length of the GMAC registers, > >-Address and length of the GMAC IDM registers > >- - reg-names: Names of the registers. Must have both "amac_base" and > >-"idm_base" > >+ - compatible: "brcm,amac" > >+"brcm,nsp-amac" > >+"brcm,ns2-amac" > >+ - reg: Address and length of the register set for the device. > >It > >+contains the information of registers in the same order as > >+described by reg-names > >+ - reg-names: Names of the registers. > >+"amac_base":Address and length of the GMAC registers > >+"idm_base": Address and length of the GMAC IDM registers > >+"nicpm_base": Address and length of the NIC Port Manager > >+registers (required for Northstar2) > > Why this "_base" suffix? It looks redundant... Yes. Rob Herring pointed out the same thing. It is ugly, but follows the existing binding. Thanks, Jon > > [...] > > MBR, Sergei >
[PATCH v5 4/7] Documentation: devicetree: net: add NS2 bindings to amac
Clean-up the documentation to the bgmac-amac driver, per suggestion by Rob Herring, and add details for NS2 support. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ba5ecc1..2fefa1a 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings - Required properties: - - compatible: "brcm,amac" or "brcm,nsp-amac" - - reg:Address and length of the GMAC registers, - Address and length of the GMAC IDM registers - - reg-names: Names of the registers. Must have both "amac_base" and - "idm_base" + - compatible: "brcm,amac" + "brcm,nsp-amac" + "brcm,ns2-amac" + - reg:Address and length of the register set for the device. It + contains the information of registers in the same order as + described by reg-names + - reg-names: Names of the registers. + "amac_base":Address and length of the GMAC registers + "idm_base": Address and length of the GMAC IDM registers + "nicpm_base": Address and length of the NIC Port Manager + registers (required for Northstar2) - interrupts: Interrupt number Optional properties: -- 2.7.4
[PATCH v5 0/7] add NS2 support to bgmac
Changes in v5: * Change a pr_err to netdev_err (per Scott Branden) * Reword the lane swap binding documentation (per Andrew Lunn) Changes in v4: * Actually send out the lane swap binding doc patch (Per Scott Branden) * Remove unused #define (Per Andrew Lunn) Changes in v3: * Clean-up the bgmac DT binding doc (per Rob Herring) * Document the lane swap binding and make it generic (Per Andrew Lunn) Changes in v2: * Remove the PHY power-on (per Andrew Lunn) * Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn) This results on none of the original PHY code from Vikas being present. So, I'm removing him as an author and giving him "Inspired-by" credit. * Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian Fainelli) * Remove bgmac sleep (per Florian Fainelli) * Re-add bgmac chip reset (per Florian Fainelli and Ray Jui) * Rebased on latest net-next * Added patch for bcm54xx_auxctl_read, which is used in the BCM54810 Add support for the amac found in the Broadcom Northstar2 SoC to the bgmac driver. This necessitates adding support to connect to an externally defined phy (as described in the device tree) in the driver. These phy changes are in addition to the changes necessary to get NS2 working. Jon Mason (7): net: phy: broadcom: add bcm54xx_auxctl_read Documentation: devicetree: add PHY lane swap binding net: phy: broadcom: Add BCM54810 PHY entry Documentation: devicetree: net: add NS2 bindings to amac net: ethernet: bgmac: device tree phy enablement net: ethernet: bgmac: add NS2 support arm64: dts: NS2: add AMAC ethernet support .../devicetree/bindings/net/brcm,amac.txt | 16 ++-- Documentation/devicetree/bindings/net/phy.txt | 4 + arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++ arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 +++ drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++ drivers/net/ethernet/broadcom/bgmac-platform.c | 100 - drivers/net/ethernet/broadcom/bgmac.c | 55 ++-- drivers/net/ethernet/broadcom/bgmac.h | 8 ++ drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 68 +- include/linux/brcmphy.h| 10 +++ 11 files changed, 271 insertions(+), 57 deletions(-) -- 2.7.4
[PATCH v5 5/7] net: ethernet: bgmac: device tree phy enablement
Change the bgmac driver to allow for phy's defined by the device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 drivers/net/ethernet/broadcom/bgmac-platform.c | 48 +++- drivers/net/ethernet/broadcom/bgmac.c | 52 ++ drivers/net/ethernet/broadcom/bgmac.h | 7 4 files changed, 105 insertions(+), 50 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index c16ec3a..3e3efde 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -80,6 +80,50 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask, bcma_maskset32(bgmac->bcma.cmn, offset, mask, set); } +static int bcma_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + char bus_id[MII_BUS_ID_SIZE + 3]; + + /* Connect to the PHY */ + snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, +bgmac->phyaddr); + phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "PHY connecton failed\n"); + return PTR_ERR(phy_dev); + } + + return 0; +} + +static int bcma_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static const struct bcma_device_id bgmac_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), @@ -275,6 +319,10 @@ static int bgmac_probe(struct bcma_device *core) bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; + if (bgmac->mii_bus) + bgmac->phy_connect = bcma_phy_connect; + else + bgmac->phy_connect = bcma_phy_direct_connect; err = bgmac_enet_probe(bgmac); if (err) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index be52f27..aed5dc5 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "bgmac.h" @@ -86,6 +87,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static int platform_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + + phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, +bgmac_adjust_link); + if (!phy_dev) { + dev_err(bgmac->dev, "Phy connect failed\n"); + return -ENODEV; + } + + return 0; +} + +static int platform_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -102,7 +143,6 @@ static int bgmac_probe(struct platform_device *pdev) /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESE
[PATCH v5 7/7] arm64: dts: NS2: add AMAC ethernet support
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 + arch/arm64/boot/dts/broadcom/ns2.dtsi| 12 2 files changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index 2d7872a..2e4d90d 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -56,6 +56,10 @@ }; }; + { + status = "ok"; +}; + _phy0 { status = "ok"; }; @@ -172,6 +176,7 @@ _mux_iproc { mdio@10 { gphy0: eth-phy@10 { + enet-phy-lane-swap; reg = <0x10>; }; }; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index d95dc40..773ed59 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -191,6 +191,18 @@ #include "ns2-clock.dtsi" + enet: ethernet@6100 { + compatible = "brcm,ns2-amac"; + reg = <0x6100 0x1000>, + <0x6109 0x1000>, + <0x6103 0x100>; + reg-names = "amac_base", "idm_base", "nicpm_base"; + interrupts = ; + phy-handle = <>; + phy-mode = "rgmii"; + status = "disabled"; + }; + dma0: dma@6136 { compatible = "arm,pl330", "arm,primecell"; reg = <0x6136 0x1000>; -- 2.7.4
[PATCH v5 6/7] net: ethernet: bgmac: add NS2 support
Add support for the variant of amac hardware present in the Broadcom Northstar2 based SoCs. Northstar2 requires an additional register to be configured with the port speed/duplexity (NICPM). This can be added to the link callback to hide it from the instances that do not use this. Also, clearing of the pending interrupts on init is required due to observed issues on some platforms. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +- drivers/net/ethernet/broadcom/bgmac.c | 3 ++ drivers/net/ethernet/broadcom/bgmac.h | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index aed5dc5..fce63cf 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -14,12 +14,21 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include #include #include "bgmac.h" +#define NICPM_IOMUX_CTRL 0x0008 + +#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 +#define NICPM_IOMUX_CTRL_SPD_SHIFT 10 +#define NICPM_IOMUX_CTRL_SPD_10M 0 +#define NICPM_IOMUX_CTRL_SPD_100M 1 +#define NICPM_IOMUX_CTRL_SPD_1000M 2 + static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) { return readl(bgmac->plat.base + offset); @@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static void bgmac_nicpm_speed_set(struct net_device *net_dev) +{ + struct bgmac *bgmac = netdev_priv(net_dev); + u32 val; + + if (!bgmac->plat.nicpm_base) + return; + + val = NICPM_IOMUX_CTRL_INIT_VAL; + switch (bgmac->net_dev->phydev->speed) { + default: + netdev_err(net_dev, "Unsupported speed. Defaulting to 1000Mb\n"); + case SPEED_1000: + val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_100: + val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_10: + val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + } + + writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); + + bgmac_adjust_link(bgmac->net_dev); +} + static int platform_phy_connect(struct bgmac *bgmac) { struct phy_device *phy_dev; - phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, -bgmac_adjust_link); + if (bgmac->plat.nicpm_base) + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_nicpm_speed_set); + else + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_adjust_link); if (!phy_dev) { dev_err(bgmac->dev, "Phy connect failed\n"); return -ENODEV; @@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev) if (IS_ERR(bgmac->plat.idm_base)) return PTR_ERR(bgmac->plat.idm_base); + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); + if (regs) { + bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, + regs); + if (IS_ERR(bgmac->plat.nicpm_base)) + return PTR_ERR(bgmac->plat.nicpm_base); + } + bgmac->read = platform_bgmac_read; bgmac->write = platform_bgmac_write; bgmac->idm_read = platform_bgmac_idm_read; @@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev) static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, + {.compatible = "brcm,ns2-amac",}, {}, }; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 4584958..a805cc8 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac) /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac) { + /* Clear any erroneously pending interrupts */ + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); + /* 1 interrupt per received frame
[PATCH v5 2/7] Documentation: devicetree: add PHY lane swap binding
Add the documentation for PHY lane swapping. This is a boolean entry to notify the phy device drivers that the TX/RX lanes need to be swapped. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- Documentation/devicetree/bindings/net/phy.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index bc1c3c8..4627da3 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -35,6 +35,10 @@ Optional Properties: - broken-turn-around: If set, indicates the PHY device does not correctly release the turn around line low at the end of a MDIO transaction. +- enet-phy-lane-swap: If set, indicates the PHY will swap the TX/RX lanes to + compensate for the board being designed with the lanes swapped. + + Example: ethernet-phy@0 { -- 2.7.4
[PATCH v5 3/7] net: phy: broadcom: Add BCM54810 PHY entry
The BCM54810 PHY requires some semi-unique configuration, which results in some additional configuration in addition to the standard config. Also, some users of the BCM54810 require the PHY lanes to be swapped. Since there is no way to detect this, add a device tree query to see if it is applicable. Inspired-by: Vikas Soni <vs...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 58 +- include/linux/brcmphy.h| 9 +++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 45f68ea..31967ca 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -217,7 +217,7 @@ config BROADCOM_PHY select BCM_NET_PHYLIB ---help--- Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, - BCM5481 and BCM5482 PHYs. + BCM5481, BCM54810 and BCM5482 PHYs. config CICADA_PHY tristate "Cicada PHYs" diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 3a64b3d..b1e32e9 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -18,7 +18,7 @@ #include #include #include - +#include #define BRCM_PHY_MODEL(phydev) \ ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) @@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); } +static int bcm54810_config(struct phy_device *phydev) +{ + int rc, val; + + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, + val); + if (rc < 0) + return rc; + + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; + val |= MII_BCM54XX_AUXCTL_MISC_WREN; + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, + val); + if (rc < 0) + return rc; + + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); + if (rc < 0) + return rc; + + return 0; +} + /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ static int bcm50610_a0_workaround(struct phy_device *phydev) { @@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev) (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) bcm54xx_adjust_rxrefclk(phydev); + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { + err = bcm54810_config(phydev); + if (err) + return err; + } + bcm54xx_phydsp_config(phydev); return 0; @@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev) static int bcm5481_config_aneg(struct phy_device *phydev) { + struct device_node *np = phydev->mdio.dev.of_node; int ret; /* Aneg firsly. */ @@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev) phy_write(phydev, 0x18, reg); } + if (of_property_read_bool(np, "enet-phy-lane-swap")) { + /* Lane Swap - Undocumented register...magic! */ + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, + 0x11B); + if (ret < 0) + return ret; + } + return ret; } @@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = { .ack_interrupt = bcm_phy_ack_intr, .config_intr= bcm_phy_config_intr, }, { + .phy_id = PHY_ID_BCM54810, + .phy_id_mask= 0xfff0, + .name = "Broadcom BCM54810", + .features = PHY_GBIT_FEATURES | + SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .config_init= bcm54xx_config_init, + .config_aneg= bcm5481_config_aneg, + .read_status= genphy_read_status, + .ack_interrupt = bcm_phy_ack_intr, + .config_intr= bcm_phy_config_intr, +}, { .phy_id = PHY_ID_BCM5482, .phy_id_mask= 0xfff0, .name = "Broadcom BCM5482", @@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM54616S, 0xfff0 }, { PHY_ID_BCM5464, 0xfff0 }, { PHY_ID_BCM5481, 0xfff0 }, +
[PATCH v5 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
Add a helper function to read the AUXCTL register for the BCM54xx. This mirrors the bcm54xx_auxctl_write function already present in the code. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/broadcom.c | 10 ++ include/linux/brcmphy.h| 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 583ef8a..3a64b3d 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver"); MODULE_AUTHOR("Maciej W. Rozycki"); MODULE_LICENSE("GPL"); +static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum) +{ + /* The register must be written to both the Shadow Register Select and +* the Shadow Read Register Selector +*/ + phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | + regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT); + return phy_read(phydev, MII_BCM54XX_AUX_CTL); +} + static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) { return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 60def78..0ed6691 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -110,6 +110,7 @@ #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX0x0200 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC0x0007 +#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK0x0007 -- 2.7.4
Re: [PATCH v4 6/7] net: ethernet: bgmac: add NS2 support
On Tue, Nov 01, 2016 at 05:05:13PM -0400, Jon Mason wrote: > On Tue, Nov 01, 2016 at 01:34:30PM -0700, Scott Branden wrote: > > One change in this patch > > > > On 16-11-01 01:04 PM, Jon Mason wrote: > > >Add support for the variant of amac hardware present in the Broadcom > > >Northstar2 based SoCs. Northstar2 requires an additional register to be > > >configured with the port speed/duplexity (NICPM). This can be added to > > >the link callback to hide it from the instances that do not use this. > > >Also, clearing of the pending interrupts on init is required due to > > >observed issues on some platforms. > > > > > >Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > > >--- > > > drivers/net/ethernet/broadcom/bgmac-platform.c | 56 > > > +- > > > drivers/net/ethernet/broadcom/bgmac.c | 3 ++ > > > drivers/net/ethernet/broadcom/bgmac.h | 1 + > > > 3 files changed, 58 insertions(+), 2 deletions(-) > > > > > >diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c > > >b/drivers/net/ethernet/broadcom/bgmac-platform.c > > >index aed5dc5..f6d48c7 100644 > > >--- a/drivers/net/ethernet/broadcom/bgmac-platform.c > > >+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c > > >@@ -14,12 +14,21 @@ > > > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > > > > > #include > > >+#include > > > #include > > > #include > > > #include > > > #include > > > #include "bgmac.h" > > > > > >+#define NICPM_IOMUX_CTRL 0x0008 > > >+ > > >+#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 > > >+#define NICPM_IOMUX_CTRL_SPD_SHIFT10 > > >+#define NICPM_IOMUX_CTRL_SPD_10M 0 > > >+#define NICPM_IOMUX_CTRL_SPD_100M 1 > > >+#define NICPM_IOMUX_CTRL_SPD_1000M2 > > >+ > > > static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) > > > { > > > return readl(bgmac->plat.base + offset); > > >@@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac > > >*bgmac, u16 offset, > > > WARN_ON(1); > > > } > > > > > >+static void bgmac_nicpm_speed_set(struct net_device *net_dev) > > >+{ > > >+ struct bgmac *bgmac = netdev_priv(net_dev); > > >+ u32 val; > > >+ > > >+ if (!bgmac->plat.nicpm_base) > > >+ return; > > >+ > > >+ val = NICPM_IOMUX_CTRL_INIT_VAL; > > >+ switch (bgmac->net_dev->phydev->speed) { > > >+ default: > > >+ pr_err("Unsupported speed. Defaulting to 1000Mb\n"); > > This should be dev_err > > It should probably be netdev_err (and there are a few instances below > that should probably be changed to netdev_err as well). Actually, the other instances I referenced above should not be netdev_err, as they are enountered before the netdev is created. So, dev_err is correct for them. That being said, the original pr_err that Scott referenced should be netdev_err (as it is encountered after the netdev is created). v5 will make that change. Thanks, Jon > > Thanks, > Jon > > > >+ case SPEED_1000: > > >+ val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; > > >+ break; > > >+ case SPEED_100: > > >+ val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; > > >+ break; > > >+ case SPEED_10: > > >+ val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; > > >+ break; > > >+ } > > >+ > > >+ writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); > > >+ > > >+ bgmac_adjust_link(bgmac->net_dev); > > >+} > > >+ > > > static int platform_phy_connect(struct bgmac *bgmac) > > > { > > > struct phy_device *phy_dev; > > > > > >- phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, > > >- bgmac_adjust_link); > > >+ if (bgmac->plat.nicpm_base) > > >+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, > > >+ bgmac->dev->of_node, > > >+ bgmac_nicpm_speed_set); > > >+ else > > >+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, > > >+
Re: [PATCH v4 6/7] net: ethernet: bgmac: add NS2 support
On Tue, Nov 01, 2016 at 01:34:30PM -0700, Scott Branden wrote: > One change in this patch > > On 16-11-01 01:04 PM, Jon Mason wrote: > >Add support for the variant of amac hardware present in the Broadcom > >Northstar2 based SoCs. Northstar2 requires an additional register to be > >configured with the port speed/duplexity (NICPM). This can be added to > >the link callback to hide it from the instances that do not use this. > >Also, clearing of the pending interrupts on init is required due to > >observed issues on some platforms. > > > >Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > >--- > > drivers/net/ethernet/broadcom/bgmac-platform.c | 56 > > +- > > drivers/net/ethernet/broadcom/bgmac.c | 3 ++ > > drivers/net/ethernet/broadcom/bgmac.h | 1 + > > 3 files changed, 58 insertions(+), 2 deletions(-) > > > >diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c > >b/drivers/net/ethernet/broadcom/bgmac-platform.c > >index aed5dc5..f6d48c7 100644 > >--- a/drivers/net/ethernet/broadcom/bgmac-platform.c > >+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c > >@@ -14,12 +14,21 @@ > > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > > > #include > >+#include > > #include > > #include > > #include > > #include > > #include "bgmac.h" > > > >+#define NICPM_IOMUX_CTRL0x0008 > >+ > >+#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 > >+#define NICPM_IOMUX_CTRL_SPD_SHIFT 10 > >+#define NICPM_IOMUX_CTRL_SPD_10M0 > >+#define NICPM_IOMUX_CTRL_SPD_100M 1 > >+#define NICPM_IOMUX_CTRL_SPD_1000M 2 > >+ > > static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) > > { > > return readl(bgmac->plat.base + offset); > >@@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac > >*bgmac, u16 offset, > > WARN_ON(1); > > } > > > >+static void bgmac_nicpm_speed_set(struct net_device *net_dev) > >+{ > >+struct bgmac *bgmac = netdev_priv(net_dev); > >+u32 val; > >+ > >+if (!bgmac->plat.nicpm_base) > >+return; > >+ > >+val = NICPM_IOMUX_CTRL_INIT_VAL; > >+switch (bgmac->net_dev->phydev->speed) { > >+default: > >+pr_err("Unsupported speed. Defaulting to 1000Mb\n"); > This should be dev_err It should probably be netdev_err (and there are a few instances below that should probably be changed to netdev_err as well). Thanks, Jon > >+case SPEED_1000: > >+val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; > >+break; > >+case SPEED_100: > >+val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; > >+break; > >+case SPEED_10: > >+val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; > >+break; > >+} > >+ > >+writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); > >+ > >+bgmac_adjust_link(bgmac->net_dev); > >+} > >+ > > static int platform_phy_connect(struct bgmac *bgmac) > > { > > struct phy_device *phy_dev; > > > >-phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, > >- bgmac_adjust_link); > >+if (bgmac->plat.nicpm_base) > >+phy_dev = of_phy_get_and_connect(bgmac->net_dev, > >+ bgmac->dev->of_node, > >+ bgmac_nicpm_speed_set); > >+else > >+phy_dev = of_phy_get_and_connect(bgmac->net_dev, > >+ bgmac->dev->of_node, > >+ bgmac_adjust_link); > > if (!phy_dev) { > > dev_err(bgmac->dev, "Phy connect failed\n"); > > return -ENODEV; > >@@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev) > > if (IS_ERR(bgmac->plat.idm_base)) > > return PTR_ERR(bgmac->plat.idm_base); > > > >+regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); > >+if (regs) { > >+bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, > >+ regs); > >+if (IS_ERR(bgmac->plat.nicpm_base)) > >+
Re: [PATCH v4 2/7] Documentation: devicetree: add PHY lane swap binding
On Tue, Nov 01, 2016 at 09:48:26PM +0100, Andrew Lunn wrote: > > +- enet-phy-lane-swap: If set, indicates the PHY device requires swapping > > the > > + TX/RX lanes to function properly. > > Is 'requires' the right word here? The PHY performs the actual swap of > the Tx/Rx lanes. What I'm trying to say here is that without the lane swapping, the PHY will not function properly. Thus, those PHYs require this parameter to work. I am open to suggestions to reword the sentence to make it clearer. Thanks, Jon > > Andrew
[PATCH v4 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
Add a helper function to read the AUXCTL register for the BCM54xx. This mirrors the bcm54xx_auxctl_write function already present in the code. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/broadcom.c | 10 ++ include/linux/brcmphy.h| 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 583ef8a..3a64b3d 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver"); MODULE_AUTHOR("Maciej W. Rozycki"); MODULE_LICENSE("GPL"); +static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum) +{ + /* The register must be written to both the Shadow Register Select and +* the Shadow Read Register Selector +*/ + phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | + regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT); + return phy_read(phydev, MII_BCM54XX_AUX_CTL); +} + static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) { return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 60def78..0ed6691 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -110,6 +110,7 @@ #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX0x0200 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC0x0007 +#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK0x0007 -- 2.7.4
[PATCH v4 3/7] net: phy: broadcom: Add BCM54810 PHY entry
The BCM54810 PHY requires some semi-unique configuration, which results in some additional configuration in addition to the standard config. Also, some users of the BCM54810 require the PHY lanes to be swapped. Since there is no way to detect this, add a device tree query to see if it is applicable. Inspired-by: Vikas Soni <vs...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 58 +- include/linux/brcmphy.h| 9 +++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 45f68ea..31967ca 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -217,7 +217,7 @@ config BROADCOM_PHY select BCM_NET_PHYLIB ---help--- Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, - BCM5481 and BCM5482 PHYs. + BCM5481, BCM54810 and BCM5482 PHYs. config CICADA_PHY tristate "Cicada PHYs" diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 3a64b3d..b1e32e9 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -18,7 +18,7 @@ #include #include #include - +#include #define BRCM_PHY_MODEL(phydev) \ ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) @@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); } +static int bcm54810_config(struct phy_device *phydev) +{ + int rc, val; + + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, + val); + if (rc < 0) + return rc; + + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; + val |= MII_BCM54XX_AUXCTL_MISC_WREN; + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, + val); + if (rc < 0) + return rc; + + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); + if (rc < 0) + return rc; + + return 0; +} + /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ static int bcm50610_a0_workaround(struct phy_device *phydev) { @@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev) (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) bcm54xx_adjust_rxrefclk(phydev); + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { + err = bcm54810_config(phydev); + if (err) + return err; + } + bcm54xx_phydsp_config(phydev); return 0; @@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev) static int bcm5481_config_aneg(struct phy_device *phydev) { + struct device_node *np = phydev->mdio.dev.of_node; int ret; /* Aneg firsly. */ @@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev) phy_write(phydev, 0x18, reg); } + if (of_property_read_bool(np, "enet-phy-lane-swap")) { + /* Lane Swap - Undocumented register...magic! */ + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, + 0x11B); + if (ret < 0) + return ret; + } + return ret; } @@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = { .ack_interrupt = bcm_phy_ack_intr, .config_intr= bcm_phy_config_intr, }, { + .phy_id = PHY_ID_BCM54810, + .phy_id_mask= 0xfff0, + .name = "Broadcom BCM54810", + .features = PHY_GBIT_FEATURES | + SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .config_init= bcm54xx_config_init, + .config_aneg= bcm5481_config_aneg, + .read_status= genphy_read_status, + .ack_interrupt = bcm_phy_ack_intr, + .config_intr= bcm_phy_config_intr, +}, { .phy_id = PHY_ID_BCM5482, .phy_id_mask= 0xfff0, .name = "Broadcom BCM5482", @@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM54616S, 0xfff0 }, { PHY_ID_BCM5464, 0xfff0 }, { PHY_ID_BCM5481, 0xfff0 }, +
[PATCH v4 5/7] net: ethernet: bgmac: device tree phy enablement
Change the bgmac driver to allow for phy's defined by the device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 drivers/net/ethernet/broadcom/bgmac-platform.c | 48 +++- drivers/net/ethernet/broadcom/bgmac.c | 52 ++ drivers/net/ethernet/broadcom/bgmac.h | 7 4 files changed, 105 insertions(+), 50 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index c16ec3a..3e3efde 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -80,6 +80,50 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask, bcma_maskset32(bgmac->bcma.cmn, offset, mask, set); } +static int bcma_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + char bus_id[MII_BUS_ID_SIZE + 3]; + + /* Connect to the PHY */ + snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, +bgmac->phyaddr); + phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "PHY connecton failed\n"); + return PTR_ERR(phy_dev); + } + + return 0; +} + +static int bcma_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static const struct bcma_device_id bgmac_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), @@ -275,6 +319,10 @@ static int bgmac_probe(struct bcma_device *core) bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; + if (bgmac->mii_bus) + bgmac->phy_connect = bcma_phy_connect; + else + bgmac->phy_connect = bcma_phy_direct_connect; err = bgmac_enet_probe(bgmac); if (err) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index be52f27..aed5dc5 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "bgmac.h" @@ -86,6 +87,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static int platform_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + + phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, +bgmac_adjust_link); + if (!phy_dev) { + dev_err(bgmac->dev, "Phy connect failed\n"); + return -ENODEV; + } + + return 0; +} + +static int platform_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -102,7 +143,6 @@ static int bgmac_probe(struct platform_device *pdev) /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESE
[PATCH v4 6/7] net: ethernet: bgmac: add NS2 support
Add support for the variant of amac hardware present in the Broadcom Northstar2 based SoCs. Northstar2 requires an additional register to be configured with the port speed/duplexity (NICPM). This can be added to the link callback to hide it from the instances that do not use this. Also, clearing of the pending interrupts on init is required due to observed issues on some platforms. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +- drivers/net/ethernet/broadcom/bgmac.c | 3 ++ drivers/net/ethernet/broadcom/bgmac.h | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index aed5dc5..f6d48c7 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -14,12 +14,21 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include #include #include "bgmac.h" +#define NICPM_IOMUX_CTRL 0x0008 + +#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 +#define NICPM_IOMUX_CTRL_SPD_SHIFT 10 +#define NICPM_IOMUX_CTRL_SPD_10M 0 +#define NICPM_IOMUX_CTRL_SPD_100M 1 +#define NICPM_IOMUX_CTRL_SPD_1000M 2 + static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) { return readl(bgmac->plat.base + offset); @@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static void bgmac_nicpm_speed_set(struct net_device *net_dev) +{ + struct bgmac *bgmac = netdev_priv(net_dev); + u32 val; + + if (!bgmac->plat.nicpm_base) + return; + + val = NICPM_IOMUX_CTRL_INIT_VAL; + switch (bgmac->net_dev->phydev->speed) { + default: + pr_err("Unsupported speed. Defaulting to 1000Mb\n"); + case SPEED_1000: + val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_100: + val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_10: + val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + } + + writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); + + bgmac_adjust_link(bgmac->net_dev); +} + static int platform_phy_connect(struct bgmac *bgmac) { struct phy_device *phy_dev; - phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, -bgmac_adjust_link); + if (bgmac->plat.nicpm_base) + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_nicpm_speed_set); + else + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_adjust_link); if (!phy_dev) { dev_err(bgmac->dev, "Phy connect failed\n"); return -ENODEV; @@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev) if (IS_ERR(bgmac->plat.idm_base)) return PTR_ERR(bgmac->plat.idm_base); + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); + if (regs) { + bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, + regs); + if (IS_ERR(bgmac->plat.nicpm_base)) + return PTR_ERR(bgmac->plat.nicpm_base); + } + bgmac->read = platform_bgmac_read; bgmac->write = platform_bgmac_write; bgmac->idm_read = platform_bgmac_idm_read; @@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev) static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, + {.compatible = "brcm,ns2-amac",}, {}, }; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 4584958..a805cc8 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac) /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac) { + /* Clear any erroneously pending interrupts */ + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); + /* 1 interrupt per received frame */
[PATCH v4 7/7] arm64: dts: NS2: add AMAC ethernet support
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 + arch/arm64/boot/dts/broadcom/ns2.dtsi| 12 2 files changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index 2d7872a..2e4d90d 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -56,6 +56,10 @@ }; }; + { + status = "ok"; +}; + _phy0 { status = "ok"; }; @@ -172,6 +176,7 @@ _mux_iproc { mdio@10 { gphy0: eth-phy@10 { + enet-phy-lane-swap; reg = <0x10>; }; }; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index d95dc40..773ed59 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -191,6 +191,18 @@ #include "ns2-clock.dtsi" + enet: ethernet@6100 { + compatible = "brcm,ns2-amac"; + reg = <0x6100 0x1000>, + <0x6109 0x1000>, + <0x6103 0x100>; + reg-names = "amac_base", "idm_base", "nicpm_base"; + interrupts = ; + phy-handle = <>; + phy-mode = "rgmii"; + status = "disabled"; + }; + dma0: dma@6136 { compatible = "arm,pl330", "arm,primecell"; reg = <0x6136 0x1000>; -- 2.7.4
[PATCH v4 4/7] Documentation: devicetree: net: add NS2 bindings to amac
Clean-up the documentation to the bgmac-amac driver, per suggestion by Rob Herring, and add details for NS2 support. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ba5ecc1..2fefa1a 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings - Required properties: - - compatible: "brcm,amac" or "brcm,nsp-amac" - - reg:Address and length of the GMAC registers, - Address and length of the GMAC IDM registers - - reg-names: Names of the registers. Must have both "amac_base" and - "idm_base" + - compatible: "brcm,amac" + "brcm,nsp-amac" + "brcm,ns2-amac" + - reg:Address and length of the register set for the device. It + contains the information of registers in the same order as + described by reg-names + - reg-names: Names of the registers. + "amac_base":Address and length of the GMAC registers + "idm_base": Address and length of the GMAC IDM registers + "nicpm_base": Address and length of the NIC Port Manager + registers (required for Northstar2) - interrupts: Interrupt number Optional properties: -- 2.7.4
[PATCH v4 2/7] Documentation: devicetree: add PHY lane swap binding
Add the documentation for PHY lane swapping. This is a boolean entry to notify the phy device drivers that the TX/RX lanes need to be swapped. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- Documentation/devicetree/bindings/net/phy.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index bc1c3c8..3dce607 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -35,6 +35,9 @@ Optional Properties: - broken-turn-around: If set, indicates the PHY device does not correctly release the turn around line low at the end of a MDIO transaction. +- enet-phy-lane-swap: If set, indicates the PHY device requires swapping the + TX/RX lanes to function properly. + Example: ethernet-phy@0 { -- 2.7.4
[PATCH v4 0/7] add NS2 support to bgmac
Changes in v4: * Actually send out the lane swap binding doc patch (Per Scott Branden) * Remove unused #define (Per Andrew Lunn) Changes in v3: * Clean-up the bgmac DT binding doc (per Rob Herring) * Document the lane swap binding and make it generic (Per Andrew Lunn) Changes in v2: * Remove the PHY power-on (per Andrew Lunn) * Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn) This results on none of the original PHY code from Vikas being present. So, I'm removing him as an author and giving him "Inspired-by" credit. * Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian Fainelli) * Remove bgmac sleep (per Florian Fainelli) * Re-add bgmac chip reset (per Florian Fainelli and Ray Jui) * Rebased on latest net-next * Added patch for bcm54xx_auxctl_read, which is used in the BCM54810 Add support for the amac found in the Broadcom Northstar2 SoC to the bgmac driver. This necessitates adding support to connect to an externally defined phy (as described in the device tree) in the driver. These phy changes are in addition to the changes necessary to get NS2 working. Jon Mason (7): net: phy: broadcom: add bcm54xx_auxctl_read Documentation: devicetree: add PHY lane swap binding net: phy: broadcom: Add BCM54810 PHY entry Documentation: devicetree: net: add NS2 bindings to amac net: ethernet: bgmac: device tree phy enablement net: ethernet: bgmac: add NS2 support arm64: dts: NS2: add AMAC ethernet support .../devicetree/bindings/net/brcm,amac.txt | 16 ++-- Documentation/devicetree/bindings/net/phy.txt | 3 + arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++ arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 +++ drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++ drivers/net/ethernet/broadcom/bgmac-platform.c | 100 - drivers/net/ethernet/broadcom/bgmac.c | 55 ++-- drivers/net/ethernet/broadcom/bgmac.h | 8 ++ drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 68 +- include/linux/brcmphy.h| 10 +++ 11 files changed, 270 insertions(+), 57 deletions(-) -- 2.7.4
Re: [PATCH v3 2/6] net: phy: broadcom: Add BCM54810 PHY entry
On Tue, Nov 01, 2016 at 07:46:39PM +0100, Andrew Lunn wrote: > Hi Jon > > > @@ -56,6 +57,8 @@ > > #define PHY_BRCM_EXT_IBND_TX_ENABLE0x2000 > > #define PHY_BRCM_CLEAR_RGMII_MODE 0x4000 > > #define PHY_BRCM_DIS_TXCRXC_NOENRGY0x8000 > > +#define PHY_BRCM_EXP_LANE_SWAP 0x0001 > > + > > You define this, but don't use it... Good catch. Cruft from the last patch. I'll sendout a quick v4 to address this and the missing Documentation patch. > > Andrew
Re: [PATCH v3 0/6] add NS2 support to bgmac
On Tue, Nov 01, 2016 at 11:01:19AM -0700, Scott Branden wrote: > Hi Jon, > > On 16-11-01 10:51 AM, Jon Mason wrote: > >Changes in v3: > >* Clean-up the bgmac DT binding doc (per Rob Herring) > >* Document the lane swap binding and make it generic (Per Andrew Lunn) > Where is the documentation of the lane swap binding? Sent out the wrong branch :( Sending out v4 shortly with this patch. > > > > > > >Changes in v2: > >* Remove the PHY power-on (per Andrew Lunn) > >* Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn) > > This results on none of the original PHY code from Vikas being > > present. So, I'm removing him as an author and giving him > > "Inspired-by" credit. > >* Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian > > Fainelli) > >* Remove bgmac sleep (per Florian Fainelli) > >* Re-add bgmac chip reset (per Florian Fainelli and Ray Jui) > >* Rebased on latest net-next > >* Added patch for bcm54xx_auxctl_read, which is used in the BCM54810 > > > > > >Add support for the amac found in the Broadcom Northstar2 SoC to the > >bgmac driver. This necessitates adding support to connect to an > >externally defined phy (as described in the device tree) in the driver. > >These phy changes are in addition to the changes necessary to get NS2 > >working. > > > > > >Jon Mason (6): > > net: phy: broadcom: add bcm54xx_auxctl_read > > net: phy: broadcom: Add BCM54810 PHY entry > > Documentation: devicetree: net: add NS2 bindings to amac > > net: ethernet: bgmac: device tree phy enablement > > net: ethernet: bgmac: add NS2 support > > arm64: dts: NS2: add AMAC ethernet support > > > > .../devicetree/bindings/net/brcm,amac.txt | 16 ++-- > > arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++ > > arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 +++ > > drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++ > > drivers/net/ethernet/broadcom/bgmac-platform.c | 100 > > - > > drivers/net/ethernet/broadcom/bgmac.c | 55 ++-- > > drivers/net/ethernet/broadcom/bgmac.h | 8 ++ > > drivers/net/phy/Kconfig| 2 +- > > drivers/net/phy/broadcom.c | 68 +- > > include/linux/brcmphy.h| 11 +++ > > 10 files changed, 268 insertions(+), 57 deletions(-) > >
[PATCH v3 2/6] net: phy: broadcom: Add BCM54810 PHY entry
The BCM54810 PHY requires some semi-unique configuration, which results in some additional configuration in addition to the standard config. Also, some users of the BCM54810 require the PHY lanes to be swapped. Since there is no way to detect this, add a device tree query to see if it is applicable. Inspired-by: Vikas Soni <vs...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 58 +- include/linux/brcmphy.h| 10 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 45f68ea..31967ca 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -217,7 +217,7 @@ config BROADCOM_PHY select BCM_NET_PHYLIB ---help--- Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, - BCM5481 and BCM5482 PHYs. + BCM5481, BCM54810 and BCM5482 PHYs. config CICADA_PHY tristate "Cicada PHYs" diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 3a64b3d..b1e32e9 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -18,7 +18,7 @@ #include #include #include - +#include #define BRCM_PHY_MODEL(phydev) \ ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) @@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); } +static int bcm54810_config(struct phy_device *phydev) +{ + int rc, val; + + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, + val); + if (rc < 0) + return rc; + + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; + val |= MII_BCM54XX_AUXCTL_MISC_WREN; + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, + val); + if (rc < 0) + return rc; + + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); + if (rc < 0) + return rc; + + return 0; +} + /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ static int bcm50610_a0_workaround(struct phy_device *phydev) { @@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev) (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) bcm54xx_adjust_rxrefclk(phydev); + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { + err = bcm54810_config(phydev); + if (err) + return err; + } + bcm54xx_phydsp_config(phydev); return 0; @@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev) static int bcm5481_config_aneg(struct phy_device *phydev) { + struct device_node *np = phydev->mdio.dev.of_node; int ret; /* Aneg firsly. */ @@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev) phy_write(phydev, 0x18, reg); } + if (of_property_read_bool(np, "enet-phy-lane-swap")) { + /* Lane Swap - Undocumented register...magic! */ + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, + 0x11B); + if (ret < 0) + return ret; + } + return ret; } @@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = { .ack_interrupt = bcm_phy_ack_intr, .config_intr= bcm_phy_config_intr, }, { + .phy_id = PHY_ID_BCM54810, + .phy_id_mask= 0xfff0, + .name = "Broadcom BCM54810", + .features = PHY_GBIT_FEATURES | + SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .config_init= bcm54xx_config_init, + .config_aneg= bcm5481_config_aneg, + .read_status= genphy_read_status, + .ack_interrupt = bcm_phy_ack_intr, + .config_intr= bcm_phy_config_intr, +}, { .phy_id = PHY_ID_BCM5482, .phy_id_mask= 0xfff0, .name = "Broadcom BCM5482", @@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM54616S, 0xfff0 }, { PHY_ID_BCM5464, 0xfff0 }, { PHY_ID_BCM5481, 0xfff0 }, +
[PATCH v3 4/6] net: ethernet: bgmac: device tree phy enablement
Change the bgmac driver to allow for phy's defined by the device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 drivers/net/ethernet/broadcom/bgmac-platform.c | 48 +++- drivers/net/ethernet/broadcom/bgmac.c | 52 ++ drivers/net/ethernet/broadcom/bgmac.h | 7 4 files changed, 105 insertions(+), 50 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index c16ec3a..3e3efde 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -80,6 +80,50 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask, bcma_maskset32(bgmac->bcma.cmn, offset, mask, set); } +static int bcma_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + char bus_id[MII_BUS_ID_SIZE + 3]; + + /* Connect to the PHY */ + snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, +bgmac->phyaddr); + phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "PHY connecton failed\n"); + return PTR_ERR(phy_dev); + } + + return 0; +} + +static int bcma_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static const struct bcma_device_id bgmac_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), @@ -275,6 +319,10 @@ static int bgmac_probe(struct bcma_device *core) bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; + if (bgmac->mii_bus) + bgmac->phy_connect = bcma_phy_connect; + else + bgmac->phy_connect = bcma_phy_direct_connect; err = bgmac_enet_probe(bgmac); if (err) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index be52f27..aed5dc5 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "bgmac.h" @@ -86,6 +87,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static int platform_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + + phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, +bgmac_adjust_link); + if (!phy_dev) { + dev_err(bgmac->dev, "Phy connect failed\n"); + return -ENODEV; + } + + return 0; +} + +static int platform_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -102,7 +143,6 @@ static int bgmac_probe(struct platform_device *pdev) /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESE
[PATCH v3 0/6] add NS2 support to bgmac
Changes in v3: * Clean-up the bgmac DT binding doc (per Rob Herring) * Document the lane swap binding and make it generic (Per Andrew Lunn) Changes in v2: * Remove the PHY power-on (per Andrew Lunn) * Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn) This results on none of the original PHY code from Vikas being present. So, I'm removing him as an author and giving him "Inspired-by" credit. * Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian Fainelli) * Remove bgmac sleep (per Florian Fainelli) * Re-add bgmac chip reset (per Florian Fainelli and Ray Jui) * Rebased on latest net-next * Added patch for bcm54xx_auxctl_read, which is used in the BCM54810 Add support for the amac found in the Broadcom Northstar2 SoC to the bgmac driver. This necessitates adding support to connect to an externally defined phy (as described in the device tree) in the driver. These phy changes are in addition to the changes necessary to get NS2 working. Jon Mason (6): net: phy: broadcom: add bcm54xx_auxctl_read net: phy: broadcom: Add BCM54810 PHY entry Documentation: devicetree: net: add NS2 bindings to amac net: ethernet: bgmac: device tree phy enablement net: ethernet: bgmac: add NS2 support arm64: dts: NS2: add AMAC ethernet support .../devicetree/bindings/net/brcm,amac.txt | 16 ++-- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++ arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 +++ drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++ drivers/net/ethernet/broadcom/bgmac-platform.c | 100 - drivers/net/ethernet/broadcom/bgmac.c | 55 ++-- drivers/net/ethernet/broadcom/bgmac.h | 8 ++ drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 68 +- include/linux/brcmphy.h| 11 +++ 10 files changed, 268 insertions(+), 57 deletions(-) -- 2.7.4
[PATCH v3 5/6] net: ethernet: bgmac: add NS2 support
Add support for the variant of amac hardware present in the Broadcom Northstar2 based SoCs. Northstar2 requires an additional register to be configured with the port speed/duplexity (NICPM). This can be added to the link callback to hide it from the instances that do not use this. Also, clearing of the pending interrupts on init is required due to observed issues on some platforms. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +- drivers/net/ethernet/broadcom/bgmac.c | 3 ++ drivers/net/ethernet/broadcom/bgmac.h | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index aed5dc5..f6d48c7 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -14,12 +14,21 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include #include #include "bgmac.h" +#define NICPM_IOMUX_CTRL 0x0008 + +#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 +#define NICPM_IOMUX_CTRL_SPD_SHIFT 10 +#define NICPM_IOMUX_CTRL_SPD_10M 0 +#define NICPM_IOMUX_CTRL_SPD_100M 1 +#define NICPM_IOMUX_CTRL_SPD_1000M 2 + static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) { return readl(bgmac->plat.base + offset); @@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static void bgmac_nicpm_speed_set(struct net_device *net_dev) +{ + struct bgmac *bgmac = netdev_priv(net_dev); + u32 val; + + if (!bgmac->plat.nicpm_base) + return; + + val = NICPM_IOMUX_CTRL_INIT_VAL; + switch (bgmac->net_dev->phydev->speed) { + default: + pr_err("Unsupported speed. Defaulting to 1000Mb\n"); + case SPEED_1000: + val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_100: + val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_10: + val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + } + + writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); + + bgmac_adjust_link(bgmac->net_dev); +} + static int platform_phy_connect(struct bgmac *bgmac) { struct phy_device *phy_dev; - phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, -bgmac_adjust_link); + if (bgmac->plat.nicpm_base) + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_nicpm_speed_set); + else + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_adjust_link); if (!phy_dev) { dev_err(bgmac->dev, "Phy connect failed\n"); return -ENODEV; @@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev) if (IS_ERR(bgmac->plat.idm_base)) return PTR_ERR(bgmac->plat.idm_base); + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); + if (regs) { + bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, + regs); + if (IS_ERR(bgmac->plat.nicpm_base)) + return PTR_ERR(bgmac->plat.nicpm_base); + } + bgmac->read = platform_bgmac_read; bgmac->write = platform_bgmac_write; bgmac->idm_read = platform_bgmac_idm_read; @@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev) static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, + {.compatible = "brcm,ns2-amac",}, {}, }; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 4584958..a805cc8 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac) /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac) { + /* Clear any erroneously pending interrupts */ + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); + /* 1 interrupt per received frame */
[PATCH v3 6/6] arm64: dts: NS2: add AMAC ethernet support
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 + arch/arm64/boot/dts/broadcom/ns2.dtsi| 12 2 files changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index 2d7872a..2e4d90d 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -56,6 +56,10 @@ }; }; + { + status = "ok"; +}; + _phy0 { status = "ok"; }; @@ -172,6 +176,7 @@ _mux_iproc { mdio@10 { gphy0: eth-phy@10 { + enet-phy-lane-swap; reg = <0x10>; }; }; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index d95dc40..773ed59 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -191,6 +191,18 @@ #include "ns2-clock.dtsi" + enet: ethernet@6100 { + compatible = "brcm,ns2-amac"; + reg = <0x6100 0x1000>, + <0x6109 0x1000>, + <0x6103 0x100>; + reg-names = "amac_base", "idm_base", "nicpm_base"; + interrupts = ; + phy-handle = <>; + phy-mode = "rgmii"; + status = "disabled"; + }; + dma0: dma@6136 { compatible = "arm,pl330", "arm,primecell"; reg = <0x6136 0x1000>; -- 2.7.4
[PATCH v3 1/6] net: phy: broadcom: add bcm54xx_auxctl_read
Add a helper function to read the AUXCTL register for the BCM54xx. This mirrors the bcm54xx_auxctl_write function already present in the code. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/broadcom.c | 10 ++ include/linux/brcmphy.h| 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 583ef8a..3a64b3d 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver"); MODULE_AUTHOR("Maciej W. Rozycki"); MODULE_LICENSE("GPL"); +static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum) +{ + /* The register must be written to both the Shadow Register Select and +* the Shadow Read Register Selector +*/ + phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | + regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT); + return phy_read(phydev, MII_BCM54XX_AUX_CTL); +} + static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) { return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 60def78..0ed6691 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -110,6 +110,7 @@ #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX0x0200 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC0x0007 +#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK0x0007 -- 2.7.4
[PATCH v3 3/6] Documentation: devicetree: net: add NS2 bindings to amac
Clean-up the documentation to the bgmac-amac driver, per suggestion by Rob Herring, and add details for NS2 support. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ba5ecc1..2fefa1a 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings - Required properties: - - compatible: "brcm,amac" or "brcm,nsp-amac" - - reg:Address and length of the GMAC registers, - Address and length of the GMAC IDM registers - - reg-names: Names of the registers. Must have both "amac_base" and - "idm_base" + - compatible: "brcm,amac" + "brcm,nsp-amac" + "brcm,ns2-amac" + - reg:Address and length of the register set for the device. It + contains the information of registers in the same order as + described by reg-names + - reg-names: Names of the registers. + "amac_base":Address and length of the GMAC registers + "idm_base": Address and length of the GMAC IDM registers + "nicpm_base": Address and length of the NIC Port Manager + registers (required for Northstar2) - interrupts: Interrupt number Optional properties: -- 2.7.4
Re: [PATCH v2 2/6] net: phy: broadcom: Add BCM54810 PHY entry
On Tue, Nov 01, 2016 at 05:26:48PM +0100, Andrew Lunn wrote: > > > > + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) { > > > > + /* Lane Swap - Undocumented register...magic! */ > > > > + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER > > > > + 0x9, > > > > + 0x11B); > > > > + if (ret < 0) > > > > + return ret; > > > > + } > > > > + > > > > > > I wounder if this property could be made generic? What exactly are you > > > swapping? Rx and Tx lanes? Maybe we should add it to phy.txt? > > > > Are you envisioning adding a DT check (similar to the > > of_property_read_bool above, only with a more generic string) in > > phy_device_create(), which will then set a PHY device flag? This flag > > would then be checked for in the PHY driver and the appropriate action > > taken (in this case the bcm_phy_write_exp above). > > I would keep the parsing of the property in the driver. But if we > think other PHYs could also support this feature, it would be good to > avoid having "brcm,enet-phy-lane-swap", "marvell,enet-phy-lane-swap", > "davicom,enet-phy-lane-swap", etc. It would be better to have one well > defined property documented in phy.txt which any PHY is free to > implement. Okay, I understand what you are saying now. I will assume that if nothing exists today aside from this Broadcom errata, something in the future will happen. So, I agree that making it generic is a good idea. I'll make the generic string be "enet-phy-lane-swap" (without the previous "brcm"), and add the flag to phy.txt to document it. Thanks, Jon > > Andrew
Re: [PATCH v2 2/6] net: phy: broadcom: Add BCM54810 PHY entry
On Sat, Oct 29, 2016 at 10:18:39AM +0200, Andrew Lunn wrote: > On Fri, Oct 28, 2016 at 04:56:55PM -0400, Jon Mason wrote: > > The BCM54810 PHY requires some semi-unique configuration, which results > > in some additional configuration in addition to the standard config. > > Also, some users of the BCM54810 require the PHY lanes to be swapped. > > Since there is no way to detect this, add a device tree query to see if > > it is applicable. > > > > Inspired-by: Vikas Soni <vs...@broadcom.com> > > Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > > --- > > drivers/net/phy/Kconfig| 2 +- > > drivers/net/phy/broadcom.c | 58 > > +- > > include/linux/brcmphy.h| 10 > > Hi Jon > > The binding documentation is missing. > > > + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) { > > + /* Lane Swap - Undocumented register...magic! */ > > + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, > > + 0x11B); > > + if (ret < 0) > > + return ret; > > + } > > + > > I wounder if this property could be made generic? What exactly are you > swapping? Rx and Tx lanes? Maybe we should add it to phy.txt? Are you envisioning adding a DT check (similar to the of_property_read_bool above, only with a more generic string) in phy_device_create(), which will then set a PHY device flag? This flag would then be checked for in the PHY driver and the appropriate action taken (in this case the bcm_phy_write_exp above). If so, I cam completely fine doing this. I think the only caveat would be that this would be creating a generic interface for only 1 user. If you envision this being used by others, then disregard my concern. Thanks, Jon > > Andrew
[PATCH v2 0/6] add NS2 support to bgmac
Changes in v2: * Remove the PHY power-on (per Andrew Lunn) * Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn) This results on none of the original PHY code from Vikas being present. So, I'm removing him as an author and giving him "Inspired-by" credit. * Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian Fainelli) * Remove bgmac sleep (per Florian Fainelli) * Re-add bgmac chip reset (per Florian Fainelli and Ray Jui) * Rebased on latest net-next * Added patch for bcm54xx_auxctl_read, which is used in the BCM54810 Add support for the amac found in the Broadcom Northstar2 SoC to the bgmac driver. This necessitates adding support to connect to an externally defined phy (as described in the device tree) in the driver. These phy changes are in addition to the changes necessary to get NS2 working. Jon Mason (6): net: phy: broadcom: add bcm54xx_auxctl_read net: phy: broadcom: Add BCM54810 PHY entry Documentation: devicetree: net: add NS2 bindings to amac net: ethernet: bgmac: device tree phy enablement net: ethernet: bgmac: add NS2 support arm64: dts: NS2: add AMAC ethernet support .../devicetree/bindings/net/brcm,amac.txt | 5 +- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++ arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 +++ drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++ drivers/net/ethernet/broadcom/bgmac-platform.c | 100 - drivers/net/ethernet/broadcom/bgmac.c | 55 ++-- drivers/net/ethernet/broadcom/bgmac.h | 8 ++ drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 68 +- include/linux/brcmphy.h| 11 +++ 10 files changed, 260 insertions(+), 54 deletions(-) -- 2.7.4
[PATCH v2 5/6] net: ethernet: bgmac: add NS2 support
Add support for the variant of amac hardware present in the Broadcom Northstar2 based SoCs. Northstar2 requires an additional register to be configured with the port speed/duplexity (NICPM). This can be added to the link callback to hide it from the instances that do not use this. Also, clearing of the pending interrupts on init is required due to observed issues on some platforms. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +- drivers/net/ethernet/broadcom/bgmac.c | 3 ++ drivers/net/ethernet/broadcom/bgmac.h | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index aed5dc5..f6d48c7 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -14,12 +14,21 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include #include #include "bgmac.h" +#define NICPM_IOMUX_CTRL 0x0008 + +#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000 +#define NICPM_IOMUX_CTRL_SPD_SHIFT 10 +#define NICPM_IOMUX_CTRL_SPD_10M 0 +#define NICPM_IOMUX_CTRL_SPD_100M 1 +#define NICPM_IOMUX_CTRL_SPD_1000M 2 + static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) { return readl(bgmac->plat.base + offset); @@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static void bgmac_nicpm_speed_set(struct net_device *net_dev) +{ + struct bgmac *bgmac = netdev_priv(net_dev); + u32 val; + + if (!bgmac->plat.nicpm_base) + return; + + val = NICPM_IOMUX_CTRL_INIT_VAL; + switch (bgmac->net_dev->phydev->speed) { + default: + pr_err("Unsupported speed. Defaulting to 1000Mb\n"); + case SPEED_1000: + val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_100: + val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + case SPEED_10: + val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT; + break; + } + + writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL); + + bgmac_adjust_link(bgmac->net_dev); +} + static int platform_phy_connect(struct bgmac *bgmac) { struct phy_device *phy_dev; - phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, -bgmac_adjust_link); + if (bgmac->plat.nicpm_base) + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_nicpm_speed_set); + else + phy_dev = of_phy_get_and_connect(bgmac->net_dev, +bgmac->dev->of_node, +bgmac_adjust_link); if (!phy_dev) { dev_err(bgmac->dev, "Phy connect failed\n"); return -ENODEV; @@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev) if (IS_ERR(bgmac->plat.idm_base)) return PTR_ERR(bgmac->plat.idm_base); + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); + if (regs) { + bgmac->plat.nicpm_base = devm_ioremap_resource(>dev, + regs); + if (IS_ERR(bgmac->plat.nicpm_base)) + return PTR_ERR(bgmac->plat.nicpm_base); + } + bgmac->read = platform_bgmac_read; bgmac->write = platform_bgmac_write; bgmac->idm_read = platform_bgmac_idm_read; @@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev) static const struct of_device_id bgmac_of_enet_match[] = { {.compatible = "brcm,amac",}, {.compatible = "brcm,nsp-amac",}, + {.compatible = "brcm,ns2-amac",}, {}, }; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 4584958..a805cc8 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac) /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac) { + /* Clear any erroneously pending interrupts */ + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); + /* 1 interrupt per received frame */
[PATCH v2 2/6] net: phy: broadcom: Add BCM54810 PHY entry
The BCM54810 PHY requires some semi-unique configuration, which results in some additional configuration in addition to the standard config. Also, some users of the BCM54810 require the PHY lanes to be swapped. Since there is no way to detect this, add a device tree query to see if it is applicable. Inspired-by: Vikas Soni <vs...@broadcom.com> Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/Kconfig| 2 +- drivers/net/phy/broadcom.c | 58 +- include/linux/brcmphy.h| 10 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 45f68ea..31967ca 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -217,7 +217,7 @@ config BROADCOM_PHY select BCM_NET_PHYLIB ---help--- Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, - BCM5481 and BCM5482 PHYs. + BCM5481, BCM54810 and BCM5482 PHYs. config CICADA_PHY tristate "Cicada PHYs" diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 3a64b3d..777ea29 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -18,7 +18,7 @@ #include #include #include - +#include #define BRCM_PHY_MODEL(phydev) \ ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) @@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); } +static int bcm54810_config(struct phy_device *phydev) +{ + int rc, val; + + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, + val); + if (rc < 0) + return rc; + + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; + val |= MII_BCM54XX_AUXCTL_MISC_WREN; + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, + val); + if (rc < 0) + return rc; + + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); + if (rc < 0) + return rc; + + return 0; +} + /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ static int bcm50610_a0_workaround(struct phy_device *phydev) { @@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev) (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) bcm54xx_adjust_rxrefclk(phydev); + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { + err = bcm54810_config(phydev); + if (err) + return err; + } + bcm54xx_phydsp_config(phydev); return 0; @@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev) static int bcm5481_config_aneg(struct phy_device *phydev) { + struct device_node *np = phydev->mdio.dev.of_node; int ret; /* Aneg firsly. */ @@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev) phy_write(phydev, 0x18, reg); } + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) { + /* Lane Swap - Undocumented register...magic! */ + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, + 0x11B); + if (ret < 0) + return ret; + } + return ret; } @@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = { .ack_interrupt = bcm_phy_ack_intr, .config_intr= bcm_phy_config_intr, }, { + .phy_id = PHY_ID_BCM54810, + .phy_id_mask= 0xfff0, + .name = "Broadcom BCM54810", + .features = PHY_GBIT_FEATURES | + SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .config_init= bcm54xx_config_init, + .config_aneg= bcm5481_config_aneg, + .read_status= genphy_read_status, + .ack_interrupt = bcm_phy_ack_intr, + .config_intr= bcm_phy_config_intr, +}, { .phy_id = PHY_ID_BCM5482, .phy_id_mask= 0xfff0, .name = "Broadcom BCM5482", @@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM54616S, 0xfff0 }, { PHY_ID_BCM5464, 0xfff0 }, { PHY_ID_BCM5481, 0xfff0 }, +
[PATCH v2 6/6] arm64: dts: NS2: add AMAC ethernet support
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 + arch/arm64/boot/dts/broadcom/ns2.dtsi| 12 2 files changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index 2d7872a..9e5c3c9 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -56,6 +56,10 @@ }; }; + { + status = "ok"; +}; + _phy0 { status = "ok"; }; @@ -172,6 +176,7 @@ _mux_iproc { mdio@10 { gphy0: eth-phy@10 { + brcm,enet-phy-lane-swap; reg = <0x10>; }; }; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index d95dc40..773ed59 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -191,6 +191,18 @@ #include "ns2-clock.dtsi" + enet: ethernet@6100 { + compatible = "brcm,ns2-amac"; + reg = <0x6100 0x1000>, + <0x6109 0x1000>, + <0x6103 0x100>; + reg-names = "amac_base", "idm_base", "nicpm_base"; + interrupts = ; + phy-handle = <>; + phy-mode = "rgmii"; + status = "disabled"; + }; + dma0: dma@6136 { compatible = "arm,pl330", "arm,primecell"; reg = <0x6136 0x1000>; -- 2.7.4
[PATCH v2 4/6] net: ethernet: bgmac: device tree phy enablement
Change the bgmac driver to allow for phy's defined by the device tree Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 drivers/net/ethernet/broadcom/bgmac-platform.c | 48 +++- drivers/net/ethernet/broadcom/bgmac.c | 52 ++ drivers/net/ethernet/broadcom/bgmac.h | 7 4 files changed, 105 insertions(+), 50 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index c16ec3a..3e3efde 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -80,6 +80,50 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask, bcma_maskset32(bgmac->bcma.cmn, offset, mask, set); } +static int bcma_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + char bus_id[MII_BUS_ID_SIZE + 3]; + + /* Connect to the PHY */ + snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, +bgmac->phyaddr); + phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "PHY connecton failed\n"); + return PTR_ERR(phy_dev); + } + + return 0; +} + +static int bcma_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static const struct bcma_device_id bgmac_bcma_tbl[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS), @@ -275,6 +319,10 @@ static int bgmac_probe(struct bcma_device *core) bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; + if (bgmac->mii_bus) + bgmac->phy_connect = bcma_phy_connect; + else + bgmac->phy_connect = bcma_phy_direct_connect; err = bgmac_enet_probe(bgmac); if (err) diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index be52f27..aed5dc5 100644 --- a/drivers/net/ethernet/broadcom/bgmac-platform.c +++ b/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "bgmac.h" @@ -86,6 +87,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, WARN_ON(1); } +static int platform_phy_connect(struct bgmac *bgmac) +{ + struct phy_device *phy_dev; + + phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, +bgmac_adjust_link); + if (!phy_dev) { + dev_err(bgmac->dev, "Phy connect failed\n"); + return -ENODEV; + } + + return 0; +} + +static int platform_phy_direct_connect(struct bgmac *bgmac) +{ + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + struct phy_device *phy_dev; + int err; + + phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + if (!phy_dev || IS_ERR(phy_dev)) { + dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); + return -ENODEV; + } + + err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link, +PHY_INTERFACE_MODE_MII); + if (err) { + dev_err(bgmac->dev, "Connecting PHY failed\n"); + return err; + } + + return err; +} + static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -102,7 +143,6 @@ static int bgmac_probe(struct platform_device *pdev) /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESE
[PATCH v2 3/6] Documentation: devicetree: net: add NS2 bindings to amac
Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- Documentation/devicetree/bindings/net/brcm,amac.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ba5ecc1..f2b194e 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -2,11 +2,12 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings - Required properties: - - compatible: "brcm,amac" or "brcm,nsp-amac" + - compatible: "brcm,amac", "brcm,nsp-amac", or "brcm,ns2-amac" - reg:Address and length of the GMAC registers, Address and length of the GMAC IDM registers + Address and length of the NIC Port Manager registers (optional) - reg-names: Names of the registers. Must have both "amac_base" and - "idm_base" + "idm_base". "nicpm_base" is optional (required for NS2) - interrupts: Interrupt number Optional properties: -- 2.7.4
[PATCH v2 1/6] net: phy: broadcom: add bcm54xx_auxctl_read
Add a helper function to read the AUXCTL register for the BCM54xx. This mirrors the bcm54xx_auxctl_write function already present in the code. Signed-off-by: Jon Mason <jon.ma...@broadcom.com> --- drivers/net/phy/broadcom.c | 10 ++ include/linux/brcmphy.h| 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 583ef8a..3a64b3d 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver"); MODULE_AUTHOR("Maciej W. Rozycki"); MODULE_LICENSE("GPL"); +static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum) +{ + /* The register must be written to both the Shadow Register Select and +* the Shadow Read Register Selector +*/ + phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | + regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT); + return phy_read(phydev, MII_BCM54XX_AUX_CTL); +} + static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) { return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 60def78..0ed6691 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -110,6 +110,7 @@ #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX0x0200 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC0x0007 +#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK0x0007 -- 2.7.4
Re: [PATCH 1/5] net: phy: broadcom: Add BCM54810 phy entry
On Thu, Oct 27, 2016 at 11:15:05AM +0200, Andrew Lunn wrote: > On Wed, Oct 26, 2016 at 03:35:57PM -0400, Jon Mason wrote: > > From: Vikas Soni <vs...@broadcom.com> > > > > Add BCM54810 phy entry > > Hi Jon, Vikis > > The subject line is a bit misleading. It does more than add a PHY ID > entry. All of the parts are related to adding the BCM54810 Phy, but I agree it could be more verbose about what is happening. > > Signed-off-by: Vikas Soni <vs...@broadcom.com> > > Signed-off-by: Jon Mason <jon.ma...@broadcom.com> > > --- > > drivers/net/phy/Kconfig| 2 +- > > drivers/net/phy/broadcom.c | 65 > > ++ > > include/linux/brcmphy.h| 7 + > > 3 files changed, 73 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig > > index 45f68ea..31967ca 100644 > > --- a/drivers/net/phy/Kconfig > > +++ b/drivers/net/phy/Kconfig > > @@ -217,7 +217,7 @@ config BROADCOM_PHY > > select BCM_NET_PHYLIB > > ---help--- > > Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, > > - BCM5481 and BCM5482 PHYs. > > + BCM5481, BCM54810 and BCM5482 PHYs. > > > > config CICADA_PHY > > tristate "Cicada PHYs" > > diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c > > index 870327e..cdce761 100644 > > --- a/drivers/net/phy/broadcom.c > > +++ b/drivers/net/phy/broadcom.c > > @@ -35,6 +35,35 @@ static int bcm54xx_auxctl_write(struct phy_device > > *phydev, u16 regnum, u16 val) > > return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); > > } > > > > +static int bcm54810_config(struct phy_device *phydev) > > +{ > > + int rc; > > + > > + /* Disable BroadR-Reach */ > > + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, 0); > > + if (rc < 0) > > + return rc; > > + > > + /* SKEW DISABLE */ > > + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, > > + 0xF0E0); > > + if (rc < 0) > > + return rc; > > + > > + /* DELAY DISABLE */ > > + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, > > + 0x7000); > > This driver mostly uses symbolic names, not #defines. Please can you > use #defines here and else were in this patch. Will do. After looking at this, this appears to be setup for a read that doesn't follow. I'll audit this, clean it up and resend. > > + if (rc < 0) > > + return rc; > > + > > + /* DELAY DISABLE */ > > + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, 0); > > + if (rc < 0) > > + return rc; > > Twice the same comment? > > > + > > + return 0; > > +} > > + > > /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ > > static int bcm50610_a0_workaround(struct phy_device *phydev) > > { > > @@ -207,6 +236,20 @@ static int bcm54xx_config_init(struct phy_device > > *phydev) > > (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) > > bcm54xx_adjust_rxrefclk(phydev); > > > > + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { > > + err = bcm54810_config(phydev); > > + if (err) > > + return err; > > + > > + reg = phy_read(phydev, MII_BMCR); > > + if (reg < 0) > > + return reg; > > + > > + err = phy_write(phydev, MII_BMCR, reg & ~BMCR_PDOWN); > > + if (err) > > + return err; > > This seems a bit odd. I would expect the PHY core correctly handles > the PHY being powered down. Can you explain this a bit more, why it is > needed. I believe it was needed in earlier versions of the code, but doesn't seem to be needed anymore. Removing. > > Thanks > Andrew