* [PATCHv2 RESEND] am33xx: cpsw: default to ethernet hwaddr from efuse if not defined in dt [not found] <1378415306-28821-1-git-send-email-jacmet@sunsite.dk> @ 2013-09-05 21:42 ` Peter Korsgaard 2013-09-05 22:07 ` Olof Johansson 0 siblings, 1 reply; 3+ messages in thread From: Peter Korsgaard @ 2013-09-05 21:42 UTC (permalink / raw) To: linux-omap, devicetree, olof, khilman, tony Cc: mugunthanvnm, mpfj-list, koen, matt.porter, Peter Korsgaard When booting with CONFIG_ARM_APPENDED_DTB (either because of using an old U-Boot, not wanting the hassle of 2 files or when using Falcon fast boot mode in U-Boot), nothing updates the ethernet hwaddr specified for the CPSW slaves, causing the driver to use a random hwaddr, which is some times troublesome. The am33xx has unique ethernet hwaddrs programmed in the efuse, so it makes more sense to default to these rather than random ones. Add a fixup step which adds mac-address dt properties using the efuse addresses if the DTB didn't contain valid ones. Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> Acked-by: Mugunthan V N <mugunthanvnm@ti.com> Tested-by: Mark Jackson <mpfj-list@newflow.co.uk> Tested-by: Koen Kooi <koen@dominion.thruhere.net> Tested-by: Matt Porter <matt.porter@linaro.org> --- Changes since v1: - Use omap_arch_initcall as pointed out by Tony arch/arm/mach-omap2/Makefile | 3 ++ arch/arm/mach-omap2/am33xx-cpsw.c | 94 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/control.h | 4 ++ 3 files changed, 101 insertions(+) create mode 100644 arch/arm/mach-omap2/am33xx-cpsw.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index afb457c..0afee42 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -305,4 +305,7 @@ endif emac-$(CONFIG_TI_DAVINCI_EMAC) := am35xx-emac.o obj-y += $(emac-m) $(emac-y) +cpsw-$(CONFIG_TI_CPSW) := am33xx-cpsw.o +obj-y += $(cpsw-m) $(cpsw-y) + obj-y += common-board-devices.o twl-common.o dss-common.o diff --git a/arch/arm/mach-omap2/am33xx-cpsw.c b/arch/arm/mach-omap2/am33xx-cpsw.c new file mode 100644 index 0000000..eec29a4 --- /dev/null +++ b/arch/arm/mach-omap2/am33xx-cpsw.c @@ -0,0 +1,94 @@ +/* + * am335x specific cpsw dt fixups + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/etherdevice.h> +#include <linux/of.h> +#include <linux/of_net.h> + +#include "soc.h" +#include "control.h" + +/** + * am33xx_dt_cpsw_set_mac_from_efuse - Add mac-address property using + * ethernet hwaddr from efuse + * @np: Pointer to the cpsw slave to set mac address of + * @idx: Mac address index to use from efuse + */ +static void am33xx_dt_cpsw_set_mac_from_efuse(struct device_node *np, int idx) +{ + struct property *prop; + u32 lo, hi; + u8 *mac; + + switch (idx) { + case 0: + lo = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID0_LOW); + hi = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID0_HIGH); + break; + + case 1: + lo = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID1_LOW); + hi = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID1_HIGH); + break; + + default: + pr_err("cpsw.%d: too many slaves found\n", idx); + return; + } + + prop = kzalloc(sizeof(*prop) + ETH_ALEN, GFP_KERNEL); + if (!prop) + return; + + prop->value = prop + 1; + prop->length = ETH_ALEN; + prop->name = kstrdup("mac-address", GFP_KERNEL); + if (!prop->name) { + kfree(prop); + return; + } + + mac = prop->value; + + mac[0] = hi; + mac[1] = hi >> 8; + mac[2] = hi >> 16; + mac[3] = hi >> 24; + mac[4] = lo; + mac[5] = lo >> 8; + + of_update_property(np, prop); + + pr_info("cpsw.%d: No hwaddr in dt. Using %pM from efuse\n", idx, mac); +} + +static int __init am33xx_dt_cpsw_mac_fixup(void) +{ + struct device_node *np, *slave; + int idx = 0; + + if (!soc_is_am33xx()) + return -ENODEV; + + for_each_compatible_node(np, NULL, "ti,cpsw") + for_each_node_by_name(slave, "slave") { + if (!of_get_mac_address(slave)) + am33xx_dt_cpsw_set_mac_from_efuse(slave, idx); + idx++; + } + + return 0; +} +omap_arch_initcall(am33xx_dt_cpsw_mac_fixup); diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index f7d7c2e..5d684b7 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -352,6 +352,10 @@ /* AM33XX CONTROL_STATUS register */ #define AM33XX_CONTROL_STATUS 0x040 #define AM33XX_CONTROL_SEC_CLK_CTRL 0x1bc +#define AM33XX_CONTROL_MAC_ID0_LOW 0x630 +#define AM33XX_CONTROL_MAC_ID0_HIGH 0x634 +#define AM33XX_CONTROL_MAC_ID1_LOW 0x638 +#define AM33XX_CONTROL_MAC_ID1_HIGH 0x63c /* AM33XX CONTROL_STATUS bitfields (partial) */ #define AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT 22 -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCHv2 RESEND] am33xx: cpsw: default to ethernet hwaddr from efuse if not defined in dt 2013-09-05 21:42 ` [PATCHv2 RESEND] am33xx: cpsw: default to ethernet hwaddr from efuse if not defined in dt Peter Korsgaard @ 2013-09-05 22:07 ` Olof Johansson 2013-09-06 8:44 ` Peter Korsgaard 0 siblings, 1 reply; 3+ messages in thread From: Olof Johansson @ 2013-09-05 22:07 UTC (permalink / raw) To: Peter Korsgaard Cc: linux-omap, devicetree, khilman, tony, mugunthanvnm, mpfj-list, koen, matt.porter Hi, On Thu, Sep 05, 2013 at 11:42:02PM +0200, Peter Korsgaard wrote: > When booting with CONFIG_ARM_APPENDED_DTB (either because of using an old > U-Boot, not wanting the hassle of 2 files or when using Falcon fast boot > mode in U-Boot), nothing updates the ethernet hwaddr specified for the > CPSW slaves, causing the driver to use a random hwaddr, which is some times > troublesome. > > The am33xx has unique ethernet hwaddrs programmed in the efuse, so it makes > more sense to default to these rather than random ones. Add a fixup step > which adds mac-address dt properties using the efuse addresses if the DTB > didn't contain valid ones. > > Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> > Acked-by: Mugunthan V N <mugunthanvnm@ti.com> > Tested-by: Mark Jackson <mpfj-list@newflow.co.uk> > Tested-by: Koen Kooi <koen@dominion.thruhere.net> > Tested-by: Matt Porter <matt.porter@linaro.org> > --- > diff --git a/arch/arm/mach-omap2/am33xx-cpsw.c b/arch/arm/mach-omap2/am33xx-cpsw.c > new file mode 100644 > index 0000000..eec29a4 > --- /dev/null > +++ b/arch/arm/mach-omap2/am33xx-cpsw.c > @@ -0,0 +1,94 @@ > +/* > + * am335x specific cpsw dt fixups > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation version 2. > + * > + * This program is distributed "as is" WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/etherdevice.h> > +#include <linux/of.h> > +#include <linux/of_net.h> > + > +#include "soc.h" > +#include "control.h" > + > +/** > + * am33xx_dt_cpsw_set_mac_from_efuse - Add mac-address property using > + * ethernet hwaddr from efuse > + * @np: Pointer to the cpsw slave to set mac address of > + * @idx: Mac address index to use from efuse > + */ > +static void am33xx_dt_cpsw_set_mac_from_efuse(struct device_node *np, int idx) > +{ > + struct property *prop; > + u32 lo, hi; > + u8 *mac; > + > + switch (idx) { > + case 0: > + lo = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID0_LOW); > + hi = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID0_HIGH); > + break; > + > + case 1: > + lo = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID1_LOW); > + hi = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID1_HIGH); > + break; > + > + default: > + pr_err("cpsw.%d: too many slaves found\n", idx); > + return; > + } > + > + prop = kzalloc(sizeof(*prop) + ETH_ALEN, GFP_KERNEL); > + if (!prop) > + return; > + > + prop->value = prop + 1; > + prop->length = ETH_ALEN; > + prop->name = kstrdup("mac-address", GFP_KERNEL); Hmm. Do we want this to be mac-address or local-mac-address? If it's mac-address, then this will override anything set by u-boot (by means of priority in of_net). I don't think that's desireable. So it should probably set local-mac-address instead. > + if (!prop->name) { > + kfree(prop); > + return; > + } > + > + mac = prop->value; > + > + mac[0] = hi; > + mac[1] = hi >> 8; > + mac[2] = hi >> 16; > + mac[3] = hi >> 24; > + mac[4] = lo; > + mac[5] = lo >> 8; > + > + of_update_property(np, prop); mach-mxs does this too, I wonder if it's worth creating a small helper for it. Doesn't have to be done as part of this patch but it's still worth doing. > + > + pr_info("cpsw.%d: No hwaddr in dt. Using %pM from efuse\n", idx, mac); > +} > + > +static int __init am33xx_dt_cpsw_mac_fixup(void) > +{ > + struct device_node *np, *slave; > + int idx = 0; > + > + if (!soc_is_am33xx()) > + return -ENODEV; > + > + for_each_compatible_node(np, NULL, "ti,cpsw") > + for_each_node_by_name(slave, "slave") { The binding doesn't enforce "slave" node names for the subnodes, so you should probably just iterate over children. Right now they are named slave@0 and slave@1, but lack reg properties (and a notion of what said reg property would symbolize). > + if (!of_get_mac_address(slave)) > + am33xx_dt_cpsw_set_mac_from_efuse(slave, idx); > + idx++; You're assuming that you get the children in order here, which is not guaranteed. Maybe best is to adjust the binding, to make "reg" mean something (i.e. the MAC index for this hardware) and use the <reg> property of the childnode to tell which efuse to read. -Olof ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCHv2 RESEND] am33xx: cpsw: default to ethernet hwaddr from efuse if not defined in dt 2013-09-05 22:07 ` Olof Johansson @ 2013-09-06 8:44 ` Peter Korsgaard 0 siblings, 0 replies; 3+ messages in thread From: Peter Korsgaard @ 2013-09-06 8:44 UTC (permalink / raw) To: Olof Johansson Cc: linux-omap, devicetree, khilman, tony, mugunthanvnm, mpfj-list, koen, matt.porter >>>>> "Olof" == Olof Johansson <olof@lixom.net> writes: Hi Olof, Thanks for the review! >> +/** >> + * am33xx_dt_cpsw_set_mac_from_efuse - Add mac-address property using >> + * ethernet hwaddr from efuse >> + * @np: Pointer to the cpsw slave to set mac address of >> + * @idx: Mac address index to use from efuse >> + */ >> +static void am33xx_dt_cpsw_set_mac_from_efuse(struct device_node *np, int idx) >> +{ >> + struct property *prop; >> + u32 lo, hi; >> + u8 *mac; >> + >> + switch (idx) { >> + case 0: >> + lo = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID0_LOW); >> + hi = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID0_HIGH); >> + break; >> + >> + case 1: >> + lo = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID1_LOW); >> + hi = omap_ctrl_readl(AM33XX_CONTROL_MAC_ID1_HIGH); >> + break; >> + >> + default: >> + pr_err("cpsw.%d: too many slaves found\n", idx); >> + return; >> + } >> + >> + prop = kzalloc(sizeof(*prop) + ETH_ALEN, GFP_KERNEL); >> + if (!prop) >> + return; >> + >> + prop->value = prop + 1; >> + prop->length = ETH_ALEN; >> + prop->name = kstrdup("mac-address", GFP_KERNEL); Olof> Hmm. Do we want this to be mac-address or local-mac-address? If it's Olof> mac-address, then this will override anything set by u-boot (by means Olof> of priority in of_net). I don't think that's desireable. So it should Olof> probably set local-mac-address instead. It doesn't really matter as this only gets called if the DTB doesn't contain any valid mac-address / local-mac-address properties (the if (!of_get_mac_address(slave)) check). >> + if (!prop->name) { >> + kfree(prop); >> + return; >> + } >> + >> + mac = prop->value; >> + >> + mac[0] = hi; >> + mac[1] = hi >> 8; >> + mac[2] = hi >> 16; >> + mac[3] = hi >> 24; >> + mac[4] = lo; >> + mac[5] = lo >> 8; >> + >> + of_update_property(np, prop); Olof> mach-mxs does this too, I wonder if it's worth creating a small helper for it. Yeah, guess where I got the inspiration to do this from? ;) Olof> Doesn't have to be done as part of this patch but it's still worth doing. Ok, I'll send a patch adding of_set_mac_address() and change am335x / mxs to use it once this is in. >> + >> + pr_info("cpsw.%d: No hwaddr in dt. Using %pM from efuse\n", idx, mac); >> +} >> + >> +static int __init am33xx_dt_cpsw_mac_fixup(void) >> +{ >> + struct device_node *np, *slave; >> + int idx = 0; >> + >> + if (!soc_is_am33xx()) >> + return -ENODEV; >> + >> + for_each_compatible_node(np, NULL, "ti,cpsw") >> + for_each_node_by_name(slave, "slave") { Olof> The binding doesn't enforce "slave" node names for the subnodes, so you Olof> should probably just iterate over children. Right now they are named Olof> slave@0 and slave@1, but lack reg properties (and a notion of what said Olof> reg property would symbolize). True. This just follows what the cpsw driver does. I would prefer to change the driver, this file, am33xx.dtsi and the bindings documentation in one go rather than doing something else than the driver here. >> + if (!of_get_mac_address(slave)) >> + am33xx_dt_cpsw_set_mac_from_efuse(slave, idx); >> + idx++; Olof> You're assuming that you get the children in order here, which is not Olof> guaranteed. Again, this is in line with cpsw.c. Once we add a reg property we can use that as idx. Olof> Maybe best is to adjust the binding, to make "reg" mean something Olof> (i.e. the MAC index for this hardware) and use the <reg> property Olof> of the childnode to tell which efuse to read. Indeed. -- Bye, Peter Korsgaard ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-09-06 8:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1378415306-28821-1-git-send-email-jacmet@sunsite.dk>
2013-09-05 21:42 ` [PATCHv2 RESEND] am33xx: cpsw: default to ethernet hwaddr from efuse if not defined in dt Peter Korsgaard
2013-09-05 22:07 ` Olof Johansson
2013-09-06 8:44 ` Peter Korsgaard
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).