Message ID | 1477510561-17035-5-git-send-email-jon.mason@broadcom.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 10/26/2016 12:36 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, the bgmac_chip_reset() was intentionally removed to prevent the > resetting of the chip to the default values on open. Finally, clearing > of the pending interrupts on init is required due to observed issues on > some platforms. > > Signed-off-by: Jon Mason <jon.mason@broadcom.com> > --- > +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); > + > + usleep_range(10, 100); Does not seem like a good idea, do you need that sleep? > + > + 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; > } > > + if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP) > + phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP; > + > return 0; > } > > @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, bgmac); > > + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) > + bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP; > + > /* Set the features of the 4707 family */ > bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; > bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; > @@ -182,6 +233,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(&pdev->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 +272,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 38876ec..1796208 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 */ > bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); > > @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev) > struct bgmac *bgmac = netdev_priv(net_dev); > int err = 0; > > - bgmac_chip_reset(bgmac); > - Is this removal intentional? Maybe it should be special cased with checking for a NS2 BGMAC instance and not do it in that case?
On Wed, Oct 26, 2016 at 02:50:39PM -0700, Florian Fainelli wrote: > On 10/26/2016 12:36 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, the bgmac_chip_reset() was intentionally removed to prevent the > > resetting of the chip to the default values on open. Finally, clearing > > of the pending interrupts on init is required due to observed issues on > > some platforms. > > > > Signed-off-by: Jon Mason <jon.mason@broadcom.com> > > --- > > > +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); > > + > > + usleep_range(10, 100); > > Does not seem like a good idea, do you need that sleep? Oops, that's not supposed to be there. Removed. > > + > > + 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; > > } > > > > + if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP) > > + phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP; > > + > > return 0; > > } > > > > @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev) > > > > platform_set_drvdata(pdev, bgmac); > > > > + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) > > + bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP; > > + > > /* Set the features of the 4707 family */ > > bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; > > bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; > > @@ -182,6 +233,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(&pdev->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 +272,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 38876ec..1796208 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 */ > > bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); > > > > @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev) > > struct bgmac *bgmac = netdev_priv(net_dev); > > int err = 0; > > > > - bgmac_chip_reset(bgmac); > > - > > Is this removal intentional? Maybe it should be special cased with > checking for a NS2 BGMAC instance and not do it in that case? The reset seems completely unnecessary. There is already 2 resets in the probe routine, another reset serves no purpose. I can add it back, as it does not seem to have the negative effect I was seeing before. Of course, if I remove this one I should remove the reset in the close too (which seems even more unnecessary, but I didn't remove it). Thanks, Jon > -- > Florian
On 10/27/2016 1:51 PM, Jon Mason wrote: > On Wed, Oct 26, 2016 at 02:50:39PM -0700, Florian Fainelli wrote: >> On 10/26/2016 12:36 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, the bgmac_chip_reset() was intentionally removed to prevent the >>> resetting of the chip to the default values on open. Finally, clearing >>> of the pending interrupts on init is required due to observed issues on >>> some platforms. >>> >>> Signed-off-by: Jon Mason <jon.mason@broadcom.com> >>> --- >> >>> +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); >>> + >>> + usleep_range(10, 100); >> >> Does not seem like a good idea, do you need that sleep? > > Oops, that's not supposed to be there. Removed. > > >>> + >>> + 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; >>> } >>> >>> + if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP) >>> + phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP; >>> + >>> return 0; >>> } >>> >>> @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev) >>> >>> platform_set_drvdata(pdev, bgmac); >>> >>> + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) >>> + bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP; >>> + >>> /* Set the features of the 4707 family */ >>> bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; >>> bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; >>> @@ -182,6 +233,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(&pdev->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 +272,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 38876ec..1796208 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 */ >>> bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); >>> >>> @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev) >>> struct bgmac *bgmac = netdev_priv(net_dev); >>> int err = 0; >>> >>> - bgmac_chip_reset(bgmac); >>> - >> >> Is this removal intentional? Maybe it should be special cased with >> checking for a NS2 BGMAC instance and not do it in that case? > > The reset seems completely unnecessary. There is already 2 resets in > the probe routine, another reset serves no purpose. I can add it > back, as it does not seem to have the negative effect I was seeing > before. After repeated ifconfig down/up, does Ethernet still work with this reset removed? Thanks. > > Of course, if I remove this one I should remove the reset in the close > too (which seems even more unnecessary, but I didn't remove it). > > Thanks, > Jon > >> -- >> Florian
On 10/27/2016 3:21 PM, Ray Jui wrote: > > > On 10/27/2016 1:51 PM, Jon Mason wrote: >> On Wed, Oct 26, 2016 at 02:50:39PM -0700, Florian Fainelli wrote: >>> On 10/26/2016 12:36 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, the bgmac_chip_reset() was intentionally removed to prevent the >>>> resetting of the chip to the default values on open. Finally, clearing >>>> of the pending interrupts on init is required due to observed issues on >>>> some platforms. >>>> >>>> Signed-off-by: Jon Mason <jon.mason@broadcom.com> >>>> --- >>> >>>> +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); >>>> + >>>> + usleep_range(10, 100); >>> >>> Does not seem like a good idea, do you need that sleep? >> >> Oops, that's not supposed to be there. Removed. >> >> >>>> + >>>> + 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; >>>> } >>>> >>>> + if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP) >>>> + phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP; >>>> + >>>> return 0; >>>> } >>>> >>>> @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev) >>>> >>>> platform_set_drvdata(pdev, bgmac); >>>> >>>> + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) >>>> + bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP; >>>> + >>>> /* Set the features of the 4707 family */ >>>> bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; >>>> bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; >>>> @@ -182,6 +233,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(&pdev->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 +272,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 38876ec..1796208 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 */ >>>> bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); >>>> >>>> @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev) >>>> struct bgmac *bgmac = netdev_priv(net_dev); >>>> int err = 0; >>>> >>>> - bgmac_chip_reset(bgmac); >>>> - >>> >>> Is this removal intentional? Maybe it should be special cased with >>> checking for a NS2 BGMAC instance and not do it in that case? >> >> The reset seems completely unnecessary. There is already 2 resets in >> the probe routine, another reset serves no purpose. I can add it >> back, as it does not seem to have the negative effect I was seeing >> before. > > After repeated ifconfig down/up, does Ethernet still work with this > reset removed? > > Thanks. > Sorry, I meant to say, after removing both reset calls in the open and close functions, does Ethernet still work after repeated ifconfig down/up with data traffic in the background? I would guess this reset is required, to flush out and clean up the internal memories and state machine of the AMAC core each time before you bring up the interface. It might also be required in the close function, such that after the interface bring down, there's no staled data coming out of the AMAC core. But I cannot say for sure since I do not try this out myself. Thanks. >> >> Of course, if I remove this one I should remove the reset in the close >> too (which seems even more unnecessary, but I didn't remove it). >> >> Thanks, >> Jon >> >>> -- >>> Florian
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c index aed5dc5..49fcff4 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 <linux/bcma/bcma.h> +#include <linux/brcmphy.h> #include <linux/etherdevice.h> #include <linux/of_address.h> #include <linux/of_mdio.h> #include <linux/of_net.h> #include "bgmac.h" +#define NICPM_IOMUX_CTRL 0x00000008 + +#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,17 +96,56 @@ 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); + + usleep_range(10, 100); + + 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; } + if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP) + phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP; + return 0; } @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bgmac); + if (of_property_read_bool(np, "brcm,enet-phy-lane-swap")) + bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP; + /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; @@ -182,6 +233,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(&pdev->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 +272,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 38876ec..1796208 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 */ bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev) struct bgmac *bgmac = netdev_priv(net_dev); int err = 0; - bgmac_chip_reset(bgmac); - err = bgmac_dma_init(bgmac); if (err) return err; diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index ea52ac3..677e685 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -409,6 +409,7 @@ #define BGMAC_FEAT_CC4_IF_SW_TYPE BIT(17) #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18) #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19) +#define BGMAC_FEAT_LANE_SWAP BIT(20) struct bgmac_slot_info { union { @@ -463,6 +464,7 @@ struct bgmac { struct { void *base; void *idm_base; + void *nicpm_base; } plat; struct { struct bcma_device *core;
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, the bgmac_chip_reset() was intentionally removed to prevent the resetting of the chip to the default values on open. Finally, clearing of the pending interrupts on init is required due to observed issues on some platforms. Signed-off-by: Jon Mason <jon.mason@broadcom.com> --- drivers/net/ethernet/broadcom/bgmac-platform.c | 64 +++++++++++++++++++++++++- drivers/net/ethernet/broadcom/bgmac.c | 5 +- drivers/net/ethernet/broadcom/bgmac.h | 2 + 3 files changed, 67 insertions(+), 4 deletions(-)