2023-02-22 21:04:06

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 0/7] net: sunhme: Probe/IRQ cleanups

Well, I've had these patches kicking around in my tree since last October, so I
guess I had better get around to posting them. This series is mainly a
cleanup/consolidation of the probe process, with some interrupt changes as well.
Some of these changes are SBUS- (AKA SPARC-) specific, so this should really get
some testing there as well to ensure nothing breaks. I've CC'd a few SPARC
mailing lists in hopes that someone there can try this out. I also have an SBUS
card I ordered by mistake if anyone has a SPARC computer but lacks this card.

I had originally planned on adding phylib support to this driver in the hopes of
being able to use real phy drivers, but I don't think I'm going to end up doing
that. I wanted to be able to use an external (homegrown) phy, but as it turns
out you can't buy MII cables in $CURRENTYEAR for under $250 a pop, and even if
you could get them you can't buy the connectors either. Oh well...

This series is not actually RFC, but I don't want to forget to post this in
another month.


Sean Anderson (7):
net: sunhme: Just restart autonegotiation if we can't bring the link
up
net: sunhme: Remove residual polling code
net: sunhme: Unify IRQ requesting
net: sunhme: Alphabetize includes
net: sunhme: Switch SBUS to devres
net: sunhme: Consolidate mac address initialization
net: sunhme: Consolidate common probe tasks

drivers/net/ethernet/sun/sunhme.c | 891 ++++++++++--------------------
drivers/net/ethernet/sun/sunhme.h | 6 +-
2 files changed, 288 insertions(+), 609 deletions(-)

--
2.37.1



2023-02-22 21:04:10

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 1/7] net: sunhme: Just restart autonegotiation if we can't bring the link up

If we've tried regular autonegotiation and forcing the link mode, just
restart autonegotiation instead of reinitializing the whole NIC.

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index dd14114cbcfb..3eeda8f3fa80 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -589,7 +589,10 @@ static int set_happy_link_modes(struct happy_meal *hp, void __iomem *tregs)
return 1;
}

-static int happy_meal_init(struct happy_meal *hp);
+static void
+happy_meal_begin_auto_negotiation(struct happy_meal *hp,
+ void __iomem *tregs,
+ const struct ethtool_link_ksettings *ep);

static int is_lucent_phy(struct happy_meal *hp)
{
@@ -743,12 +746,7 @@ static void happy_meal_timer(struct timer_list *t)
netdev_notice(hp->dev,
"Link down, cable problem?\n");

- ret = happy_meal_init(hp);
- if (ret) {
- /* ho hum... */
- netdev_err(hp->dev,
- "Error, cannot re-init the Happy Meal.\n");
- }
+ happy_meal_begin_auto_negotiation(hp, tregs, NULL);
goto out;
}
if (!is_lucent_phy(hp)) {
--
2.37.1


2023-02-22 21:04:19

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 2/7] net: sunhme: Remove residual polling code

The sunhme driver never used the hardware MII polling feature. Even the
if-def'd out happy_meal_poll_start was removed by 2002 [1]. Remove the
various places in the driver which needlessly guard against MII interrupts
which will never be enabled.

[1] https://lwn.net/2002/0411/a/2.5.8-pre3.php3

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 134 ++++--------------------------
drivers/net/ethernet/sun/sunhme.h | 6 +-
2 files changed, 18 insertions(+), 122 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 3eeda8f3fa80..8f6a937a23d5 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -872,32 +872,6 @@ static void happy_meal_get_counters(struct happy_meal *hp, void __iomem *bregs)
hme_write32(hp, bregs + BMAC_LTCTR, 0);
}

-/* hp->happy_lock must be held */
-static void happy_meal_poll_stop(struct happy_meal *hp, void __iomem *tregs)
-{
- /* If polling disabled or not polling already, nothing to do. */
- if ((hp->happy_flags & (HFLAG_POLLENABLE | HFLAG_POLL)) !=
- (HFLAG_POLLENABLE | HFLAG_POLL)) {
- ASD("not polling, return\n");
- return;
- }
-
- /* Shut up the MIF. */
- ASD("were polling, mif ints off, polling off\n");
- hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
-
- /* Turn off polling. */
- hme_write32(hp, tregs + TCVR_CFG,
- hme_read32(hp, tregs + TCVR_CFG) & ~(TCV_CFG_PENABLE));
-
- /* We are no longer polling. */
- hp->happy_flags &= ~(HFLAG_POLL);
-
- /* Let the bits set. */
- udelay(200);
- ASD("done\n");
-}
-
/* Only Sun can take such nice parts and fuck up the programming interface
* like this. Good job guys...
*/
@@ -1002,57 +976,26 @@ static int happy_meal_tcvr_reset(struct happy_meal *hp, void __iomem *tregs)
static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tregs)
{
unsigned long tconfig = hme_read32(hp, tregs + TCVR_CFG);
+ u32 reread = hme_read32(hp, tregs + TCVR_CFG);

ASD("tcfg=%08lx\n", tconfig);
- if (hp->happy_flags & HFLAG_POLL) {
- /* If we are polling, we must stop to get the transceiver type. */
- if (hp->tcvr_type == internal) {
- if (tconfig & TCV_CFG_MDIO1) {
- happy_meal_poll_stop(hp, tregs);
- hp->paddr = TCV_PADDR_ETX;
- hp->tcvr_type = external;
- tconfig &= ~(TCV_CFG_PENABLE);
- tconfig |= TCV_CFG_PSELECT;
- hme_write32(hp, tregs + TCVR_CFG, tconfig);
- ASD("poll stop, internal->external\n");
- }
- } else {
- if (hp->tcvr_type == external) {
- if (!(hme_read32(hp, tregs + TCVR_STATUS) >> 16)) {
- happy_meal_poll_stop(hp, tregs);
- hp->paddr = TCV_PADDR_ITX;
- hp->tcvr_type = internal;
- hme_write32(hp, tregs + TCVR_CFG,
- hme_read32(hp, tregs + TCVR_CFG) &
- ~(TCV_CFG_PSELECT));
- ASD("poll stop, external->internal\n");
- }
- } else {
- ASD("polling, none\n");
- }
- }
+ if (reread & TCV_CFG_MDIO1) {
+ hme_write32(hp, tregs + TCVR_CFG, tconfig | TCV_CFG_PSELECT);
+ hp->paddr = TCV_PADDR_ETX;
+ hp->tcvr_type = external;
+ ASD("not polling, external\n");
} else {
- u32 reread = hme_read32(hp, tregs + TCVR_CFG);
-
- /* Else we can just work off of the MDIO bits. */
- if (reread & TCV_CFG_MDIO1) {
- hme_write32(hp, tregs + TCVR_CFG, tconfig | TCV_CFG_PSELECT);
- hp->paddr = TCV_PADDR_ETX;
- hp->tcvr_type = external;
- ASD("not polling, external\n");
+ if (reread & TCV_CFG_MDIO0) {
+ hme_write32(hp, tregs + TCVR_CFG,
+ tconfig & ~(TCV_CFG_PSELECT));
+ hp->paddr = TCV_PADDR_ITX;
+ hp->tcvr_type = internal;
+ ASD("not polling, internal\n");
} else {
- if (reread & TCV_CFG_MDIO0) {
- hme_write32(hp, tregs + TCVR_CFG,
- tconfig & ~(TCV_CFG_PSELECT));
- hp->paddr = TCV_PADDR_ITX;
- hp->tcvr_type = internal;
- ASD("not polling, internal\n");
- } else {
- netdev_err(hp->dev,
- "Transceiver and a coke please.");
- hp->tcvr_type = none; /* Grrr... */
- ASD("not polling, none\n");
- }
+ netdev_err(hp->dev,
+ "Transceiver and a coke please.");
+ hp->tcvr_type = none; /* Grrr... */
+ ASD("not polling, none\n");
}
}
}
@@ -1339,10 +1282,6 @@ static int happy_meal_init(struct happy_meal *hp)
happy_meal_get_counters(hp, bregs);
}

- /* Stop polling. */
- HMD("to happy_meal_poll_stop\n");
- happy_meal_poll_stop(hp, tregs);
-
/* Stop transmitter and receiver. */
HMD("to happy_meal_stop\n");
happy_meal_stop(hp, gregs);
@@ -1351,11 +1290,6 @@ static int happy_meal_init(struct happy_meal *hp)
HMD("to happy_meal_init_rings\n");
happy_meal_init_rings(hp);

- /* Shut up the MIF. */
- HMD("Disable all MIF irqs (old[%08x])\n",
- hme_read32(hp, tregs + TCVR_IMASK));
- hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
-
/* See if we can enable the MIF frame on this card to speak to the DP83840. */
if (hp->happy_flags & HFLAG_FENABLE) {
HMD("use frame old[%08x]\n",
@@ -1610,7 +1544,6 @@ static void happy_meal_set_initial_advertisement(struct happy_meal *hp)
void __iomem *gregs = hp->gregs;

happy_meal_stop(hp, gregs);
- hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
if (hp->happy_flags & HFLAG_FENABLE)
hme_write32(hp, tregs + TCVR_CFG,
hme_read32(hp, tregs + TCVR_CFG) & ~(TCV_CFG_BENABLE));
@@ -1767,34 +1700,6 @@ static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status)
return 0;
}

-/* hp->happy_lock must be held */
-static void happy_meal_mif_interrupt(struct happy_meal *hp)
-{
- void __iomem *tregs = hp->tcvregs;
-
- netdev_info(hp->dev, "Link status change.\n");
- hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
- hp->sw_lpa = happy_meal_tcvr_read(hp, tregs, MII_LPA);
-
- /* Use the fastest transmission protocol possible. */
- if (hp->sw_lpa & LPA_100FULL) {
- netdev_info(hp->dev, "Switching to 100Mbps at full duplex.\n");
- hp->sw_bmcr |= (BMCR_FULLDPLX | BMCR_SPEED100);
- } else if (hp->sw_lpa & LPA_100HALF) {
- netdev_info(hp->dev, "Switching to 100MBps at half duplex.\n");
- hp->sw_bmcr |= BMCR_SPEED100;
- } else if (hp->sw_lpa & LPA_10FULL) {
- netdev_info(hp->dev, "Switching to 10MBps at full duplex.\n");
- hp->sw_bmcr |= BMCR_FULLDPLX;
- } else {
- netdev_info(hp->dev, "Using 10Mbps at half duplex.\n");
- }
- happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
-
- /* Finally stop polling and shut up the MIF. */
- happy_meal_poll_stop(hp, tregs);
-}
-
/* hp->happy_lock must be held */
static void happy_meal_tx(struct happy_meal *hp)
{
@@ -1978,9 +1883,6 @@ static irqreturn_t happy_meal_interrupt(int irq, void *dev_id)
goto out;
}

- if (happy_status & GREG_STAT_MIFIRQ)
- happy_meal_mif_interrupt(hp);
-
if (happy_status & GREG_STAT_TXALL)
happy_meal_tx(hp);

@@ -2008,7 +1910,6 @@ static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
HMD("status=%08x\n", happy_status);

if (!(happy_status & (GREG_STAT_ERRORS |
- GREG_STAT_MIFIRQ |
GREG_STAT_TXALL |
GREG_STAT_RXTOHOST)))
continue;
@@ -2019,9 +1920,6 @@ static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
if (happy_meal_is_not_so_happy(hp, happy_status))
goto next;

- if (happy_status & GREG_STAT_MIFIRQ)
- happy_meal_mif_interrupt(hp);
-
if (happy_status & GREG_STAT_TXALL)
happy_meal_tx(hp);

diff --git a/drivers/net/ethernet/sun/sunhme.h b/drivers/net/ethernet/sun/sunhme.h
index 9118c60c9426..258b4c7fe962 100644
--- a/drivers/net/ethernet/sun/sunhme.h
+++ b/drivers/net/ethernet/sun/sunhme.h
@@ -462,22 +462,20 @@ struct happy_meal {
};

/* Here are the happy flags. */
-#define HFLAG_POLL 0x00000001 /* We are doing MIF polling */
#define HFLAG_FENABLE 0x00000002 /* The MII frame is enabled */
#define HFLAG_LANCE 0x00000004 /* We are using lance-mode */
#define HFLAG_RXENABLE 0x00000008 /* Receiver is enabled */
#define HFLAG_AUTO 0x00000010 /* Using auto-negotiation, 0 = force */
#define HFLAG_FULL 0x00000020 /* Full duplex enable */
#define HFLAG_MACFULL 0x00000040 /* Using full duplex in the MAC */
-#define HFLAG_POLLENABLE 0x00000080 /* Actually try MIF polling */
#define HFLAG_RXCV 0x00000100 /* XXX RXCV ENABLE */
#define HFLAG_INIT 0x00000200 /* Init called at least once */
#define HFLAG_LINKUP 0x00000400 /* 1 = Link is up */
#define HFLAG_PCI 0x00000800 /* PCI based Happy Meal */
#define HFLAG_QUATTRO 0x00001000 /* On QFE/Quattro card */

-#define HFLAG_20_21 (HFLAG_POLLENABLE | HFLAG_FENABLE)
-#define HFLAG_NOT_A0 (HFLAG_POLLENABLE | HFLAG_FENABLE | HFLAG_LANCE | HFLAG_RXCV)
+#define HFLAG_20_21 HFLAG_FENABLE
+#define HFLAG_NOT_A0 (HFLAG_FENABLE | HFLAG_LANCE | HFLAG_RXCV)

/* Support for QFE/Quattro cards. */
struct quattro {
--
2.37.1


2023-02-22 21:04:23

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 3/7] net: sunhme: Unify IRQ requesting

Instead of registering one interrupt handler for all four SBUS Quattro
HMEs, let each HME register its own handler. To make this work, we don't
handle the IRQ if none of the status bits are set. This reduces the
complexity of the driver, and makes it easier to ensure things happen
before/after enabling IRQs.

I'm not really sure why we request IRQs in two different places (and leave
them running after removing the driver!). A lot of things in this driver
seem to just be crusty, and not necessarily intentional. I'm assuming
that's the case here as well.

This really needs to be tested by someone with an SBUS Quattro card.

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 131 +++---------------------------
1 file changed, 10 insertions(+), 121 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 8f6a937a23d5..127253c67c59 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -1875,6 +1875,8 @@ static irqreturn_t happy_meal_interrupt(int irq, void *dev_id)
u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT);

HMD("status=%08x\n", happy_status);
+ if (!happy_status)
+ return IRQ_NONE;

spin_lock(&hp->happy_lock);

@@ -1896,62 +1898,16 @@ static irqreturn_t happy_meal_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}

-#ifdef CONFIG_SBUS
-static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
-{
- struct quattro *qp = (struct quattro *) cookie;
- int i;
-
- for (i = 0; i < 4; i++) {
- struct net_device *dev = qp->happy_meals[i];
- struct happy_meal *hp = netdev_priv(dev);
- u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT);
-
- HMD("status=%08x\n", happy_status);
-
- if (!(happy_status & (GREG_STAT_ERRORS |
- GREG_STAT_TXALL |
- GREG_STAT_RXTOHOST)))
- continue;
-
- spin_lock(&hp->happy_lock);
-
- if (happy_status & GREG_STAT_ERRORS)
- if (happy_meal_is_not_so_happy(hp, happy_status))
- goto next;
-
- if (happy_status & GREG_STAT_TXALL)
- happy_meal_tx(hp);
-
- if (happy_status & GREG_STAT_RXTOHOST)
- happy_meal_rx(hp, dev);
-
- next:
- spin_unlock(&hp->happy_lock);
- }
- HMD("done\n");
-
- return IRQ_HANDLED;
-}
-#endif
-
static int happy_meal_open(struct net_device *dev)
{
struct happy_meal *hp = netdev_priv(dev);
int res;

- /* On SBUS Quattro QFE cards, all hme interrupts are concentrated
- * into a single source which we register handling at probe time.
- */
- if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) {
- res = request_irq(hp->irq, happy_meal_interrupt, IRQF_SHARED,
- dev->name, dev);
- if (res) {
- HMD("EAGAIN\n");
- netdev_err(dev, "Can't order irq %d to go.\n", hp->irq);
-
- return -EAGAIN;
- }
+ res = request_irq(hp->irq, happy_meal_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (res) {
+ netdev_err(dev, "Can't order irq %d to go.\n", hp->irq);
+ return res;
}

HMD("to happy_meal_init\n");
@@ -1960,7 +1916,7 @@ static int happy_meal_open(struct net_device *dev)
res = happy_meal_init(hp);
spin_unlock_irq(&hp->happy_lock);

- if (res && ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO))
+ if (res)
free_irq(hp->irq, dev);
return res;
}
@@ -1978,12 +1934,7 @@ static int happy_meal_close(struct net_device *dev)

spin_unlock_irq(&hp->happy_lock);

- /* On Quattro QFE cards, all hme interrupts are concentrated
- * into a single source which we register handling at probe
- * time and never unregister.
- */
- if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO)
- free_irq(hp->irq, dev);
+ free_irq(hp->irq, dev);

return 0;
}
@@ -2316,59 +2267,6 @@ static struct quattro *quattro_sbus_find(struct platform_device *child)
platform_set_drvdata(op, qp);
return qp;
}
-
-/* After all quattro cards have been probed, we call these functions
- * to register the IRQ handlers for the cards that have been
- * successfully probed and skip the cards that failed to initialize
- */
-static int __init quattro_sbus_register_irqs(void)
-{
- struct quattro *qp;
-
- for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
- struct platform_device *op = qp->quattro_dev;
- int err, qfe_slot, skip = 0;
-
- for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
- if (!qp->happy_meals[qfe_slot])
- skip = 1;
- }
- if (skip)
- continue;
-
- err = request_irq(op->archdata.irqs[0],
- quattro_sbus_interrupt,
- IRQF_SHARED, "Quattro",
- qp);
- if (err != 0) {
- dev_err(&op->dev,
- "Quattro HME: IRQ registration error %d.\n",
- err);
- return err;
- }
- }
-
- return 0;
-}
-
-static void quattro_sbus_free_irqs(void)
-{
- struct quattro *qp;
-
- for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
- struct platform_device *op = qp->quattro_dev;
- int qfe_slot, skip = 0;
-
- for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
- if (!qp->happy_meals[qfe_slot])
- skip = 1;
- }
- if (skip)
- continue;
-
- free_irq(op->archdata.irqs[0], qp);
- }
-}
#endif /* CONFIG_SBUS */

#ifdef CONFIG_PCI
@@ -3011,8 +2909,6 @@ static int hme_sbus_remove(struct platform_device *op)

unregister_netdev(net_dev);

- /* XXX qfe parent interrupt... */
-
of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
@@ -3056,19 +2952,12 @@ static struct platform_driver hme_sbus_driver = {

static int __init happy_meal_sbus_init(void)
{
- int err;
-
- err = platform_driver_register(&hme_sbus_driver);
- if (!err)
- err = quattro_sbus_register_irqs();
-
- return err;
+ return platform_driver_register(&hme_sbus_driver);
}

static void happy_meal_sbus_exit(void)
{
platform_driver_unregister(&hme_sbus_driver);
- quattro_sbus_free_irqs();

while (qfe_sbus_list) {
struct quattro *qfe = qfe_sbus_list;
--
2.37.1


2023-02-22 21:04:28

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 4/7] net: sunhme: Alphabetize includes

Alphabetize includes to make it clearer where to add new ones.

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 45 +++++++++++++++----------------
1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 127253c67c59..ab39b555d9f7 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -14,41 +14,40 @@
* argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
*/

-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/dma.h>
+#include <linux/bitops.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/ethtool.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
#include <linux/mii.h>
-#include <linux/crc32.h>
-#include <linux/random.h>
-#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
+#include <linux/random.h>
#include <linux/skbuff.h>
-#include <linux/mm.h>
-#include <linux/bitops.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/byteorder.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>

#ifdef CONFIG_SPARC
-#include <linux/of.h>
-#include <linux/of_device.h>
+#include <asm/auxio.h>
#include <asm/idprom.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/prom.h>
-#include <asm/auxio.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
#endif
#include <linux/uaccess.h>

--
2.37.1


2023-02-22 21:04:34

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 5/7] net: sunhme: Switch SBUS to devres

The PCI half of this driver was converted in commit 914d9b2711dd ("sunhme:
switch to devres"). Do the same for the SBUS half.

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 118 +++++++++---------------------
1 file changed, 35 insertions(+), 83 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index ab39b555d9f7..75993834729a 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -2322,29 +2322,28 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
struct net_device *dev;
int i, qfe_slot = -1;
u8 addr[ETH_ALEN];
- int err = -ENODEV;
+ int err;

sbus_dp = op->dev.parent->of_node;

/* We can match PCI devices too, do not accept those here. */
if (!of_node_name_eq(sbus_dp, "sbus") && !of_node_name_eq(sbus_dp, "sbi"))
- return err;
+ return -ENODEV;

if (is_qfe) {
qp = quattro_sbus_find(op);
if (qp == NULL)
- goto err_out;
+ return -ENODEV;
for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
if (qp->happy_meals[qfe_slot] == NULL)
break;
if (qfe_slot == 4)
- goto err_out;
+ return -ENODEV;
}

- err = -ENOMEM;
- dev = alloc_etherdev(sizeof(struct happy_meal));
+ dev = devm_alloc_etherdev(&op->dev, sizeof(struct happy_meal));
if (!dev)
- goto err_out;
+ return -ENOMEM;
SET_NETDEV_DEV(dev, &op->dev);

/* If user did not specify a MAC address specifically, use
@@ -2378,46 +2377,45 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)

spin_lock_init(&hp->happy_lock);

- err = -ENODEV;
if (qp != NULL) {
hp->qfe_parent = qp;
hp->qfe_ent = qfe_slot;
qp->happy_meals[qfe_slot] = dev;
}

- hp->gregs = of_ioremap(&op->resource[0], 0,
- GREG_REG_SIZE, "HME Global Regs");
- if (!hp->gregs) {
+ hp->gregs = devm_platform_ioremap_resource(op, 0);
+ if (IS_ERR(hp->gregs)) {
dev_err(&op->dev, "Cannot map global registers.\n");
- goto err_out_free_netdev;
+ err = PTR_ERR(hp->gregs);
+ goto err_out_clear_quattro;
}

- hp->etxregs = of_ioremap(&op->resource[1], 0,
- ETX_REG_SIZE, "HME TX Regs");
- if (!hp->etxregs) {
+ hp->etxregs = devm_platform_ioremap_resource(op, 1);
+ if (IS_ERR(hp->etxregs)) {
dev_err(&op->dev, "Cannot map MAC TX registers.\n");
- goto err_out_iounmap;
+ err = PTR_ERR(hp->etxregs);
+ goto err_out_clear_quattro;
}

- hp->erxregs = of_ioremap(&op->resource[2], 0,
- ERX_REG_SIZE, "HME RX Regs");
- if (!hp->erxregs) {
+ hp->erxregs = devm_platform_ioremap_resource(op, 2);
+ if (IS_ERR(hp->erxregs)) {
dev_err(&op->dev, "Cannot map MAC RX registers.\n");
- goto err_out_iounmap;
+ err = PTR_ERR(hp->erxregs);
+ goto err_out_clear_quattro;
}

- hp->bigmacregs = of_ioremap(&op->resource[3], 0,
- BMAC_REG_SIZE, "HME BIGMAC Regs");
- if (!hp->bigmacregs) {
+ hp->bigmacregs = devm_platform_ioremap_resource(op, 3);
+ if (IS_ERR(hp->bigmacregs)) {
dev_err(&op->dev, "Cannot map BIGMAC registers.\n");
- goto err_out_iounmap;
+ err = PTR_ERR(hp->bigmacregs);
+ goto err_out_clear_quattro;
}

- hp->tcvregs = of_ioremap(&op->resource[4], 0,
- TCVR_REG_SIZE, "HME Tranceiver Regs");
- if (!hp->tcvregs) {
+ hp->tcvregs = devm_platform_ioremap_resource(op, 4);
+ if (IS_ERR(hp->tcvregs)) {
dev_err(&op->dev, "Cannot map TCVR registers.\n");
- goto err_out_iounmap;
+ err = PTR_ERR(hp->tcvregs);
+ goto err_out_clear_quattro;
}

hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
@@ -2437,13 +2435,12 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
hp->happy_bursts = of_getintprop_default(sbus_dp,
"burst-sizes", 0x00);

- hp->happy_block = dma_alloc_coherent(hp->dma_dev,
- PAGE_SIZE,
- &hp->hblock_dvma,
- GFP_ATOMIC);
- err = -ENOMEM;
- if (!hp->happy_block)
- goto err_out_iounmap;
+ hp->happy_block = dmam_alloc_coherent(&op->dev, PAGE_SIZE,
+ &hp->hblock_dvma, GFP_KERNEL);
+ if (!hp->happy_block) {
+ err = -ENOMEM;
+ goto err_out_clear_quattro;
+ }

/* Force check of the link first time we are brought up. */
hp->linkcheck = 0;
@@ -2481,10 +2478,10 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
happy_meal_set_initial_advertisement(hp);
spin_unlock_irq(&hp->happy_lock);

- err = register_netdev(hp->dev);
+ err = devm_register_netdev(&op->dev, dev);
if (err) {
dev_err(&op->dev, "Cannot register net device, aborting.\n");
- goto err_out_free_coherent;
+ goto err_out_clear_quattro;
}

platform_set_drvdata(op, hp);
@@ -2499,31 +2496,9 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)

return 0;

-err_out_free_coherent:
- dma_free_coherent(hp->dma_dev,
- PAGE_SIZE,
- hp->happy_block,
- hp->hblock_dvma);
-
-err_out_iounmap:
- if (hp->gregs)
- of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
- if (hp->etxregs)
- of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
- if (hp->erxregs)
- of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
- if (hp->bigmacregs)
- of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
- if (hp->tcvregs)
- of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
-
+err_out_clear_quattro:
if (qp)
qp->happy_meals[qfe_slot] = NULL;
-
-err_out_free_netdev:
- free_netdev(dev);
-
-err_out:
return err;
}
#endif
@@ -2901,28 +2876,6 @@ static int hme_sbus_probe(struct platform_device *op)
return happy_meal_sbus_probe_one(op, is_qfe);
}

-static int hme_sbus_remove(struct platform_device *op)
-{
- struct happy_meal *hp = platform_get_drvdata(op);
- struct net_device *net_dev = hp->dev;
-
- unregister_netdev(net_dev);
-
- of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
- of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
- of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
- of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
- of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
- dma_free_coherent(hp->dma_dev,
- PAGE_SIZE,
- hp->happy_block,
- hp->hblock_dvma);
-
- free_netdev(net_dev);
-
- return 0;
-}
-
static const struct of_device_id hme_sbus_match[] = {
{
.name = "SUNW,hme",
@@ -2946,7 +2899,6 @@ static struct platform_driver hme_sbus_driver = {
.of_match_table = hme_sbus_match,
},
.probe = hme_sbus_probe,
- .remove = hme_sbus_remove,
};

static int __init happy_meal_sbus_init(void)
--
2.37.1


2023-02-22 21:04:54

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 6/7] net: sunhme: Consolidate mac address initialization

The mac address initialization is braodly the same between PCI and SBUS,
and one was clearly copied from the other. Consolidate them. We still have
to have some ifdefs because pci_(un)map_rom is only implemented for PCI,
and idprom is only implemented for SPARC.

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 284 ++++++++++++++----------------
1 file changed, 135 insertions(+), 149 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 75993834729a..9b55adbe61df 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -34,6 +34,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/netdevice.h>
+#include <linux/of.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
@@ -47,7 +48,6 @@
#include <asm/oplib.h>
#include <asm/prom.h>
#include <linux/of_device.h>
-#include <linux/of.h>
#endif
#include <linux/uaccess.h>

@@ -2313,6 +2313,133 @@ static const struct net_device_ops hme_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};

+#ifdef CONFIG_PCI
+static int is_quattro_p(struct pci_dev *pdev)
+{
+ struct pci_dev *busdev = pdev->bus->self;
+ struct pci_dev *this_pdev;
+ int n_hmes;
+
+ if (!busdev || busdev->vendor != PCI_VENDOR_ID_DEC ||
+ busdev->device != PCI_DEVICE_ID_DEC_21153)
+ return 0;
+
+ n_hmes = 0;
+ list_for_each_entry(this_pdev, &pdev->bus->devices, bus_list) {
+ if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
+ this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
+ n_hmes++;
+ }
+
+ if (n_hmes != 4)
+ return 0;
+
+ return 1;
+}
+
+/* Fetch MAC address from vital product data of PCI ROM. */
+static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
+{
+ int this_offset;
+
+ for (this_offset = 0x20; this_offset < len; this_offset++) {
+ void __iomem *p = rom_base + this_offset;
+
+ if (readb(p + 0) != 0x90 ||
+ readb(p + 1) != 0x00 ||
+ readb(p + 2) != 0x09 ||
+ readb(p + 3) != 0x4e ||
+ readb(p + 4) != 0x41 ||
+ readb(p + 5) != 0x06)
+ continue;
+
+ this_offset += 6;
+ p += 6;
+
+ if (index == 0) {
+ int i;
+
+ for (i = 0; i < 6; i++)
+ dev_addr[i] = readb(p + i);
+ return 1;
+ }
+ index--;
+ }
+ return 0;
+}
+
+static void __maybe_unused get_hme_mac_nonsparc(struct pci_dev *pdev,
+ unsigned char *dev_addr)
+{
+ size_t size;
+ void __iomem *p = pci_map_rom(pdev, &size);
+
+ if (p) {
+ int index = 0;
+ int found;
+
+ if (is_quattro_p(pdev))
+ index = PCI_SLOT(pdev->devfn);
+
+ found = readb(p) == 0x55 &&
+ readb(p + 1) == 0xaa &&
+ find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+ pci_unmap_rom(pdev, p);
+ if (found)
+ return;
+ }
+
+ /* Sun MAC prefix then 3 random bytes. */
+ dev_addr[0] = 0x08;
+ dev_addr[1] = 0x00;
+ dev_addr[2] = 0x20;
+ get_random_bytes(&dev_addr[3], 3);
+}
+#endif /* !(CONFIG_SPARC) */
+
+static void happy_meal_addr_init(struct happy_meal *hp,
+ struct device_node *dp, int qfe_slot)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ if (macaddr[i] != 0)
+ break;
+ }
+
+ if (i < 6) { /* a mac address was given */
+ u8 addr[ETH_ALEN];
+
+ for (i = 0; i < 6; i++)
+ addr[i] = macaddr[i];
+ eth_hw_addr_set(hp->dev, addr);
+ macaddr[5]++;
+ } else {
+#ifdef CONFIG_SPARC
+ const unsigned char *addr;
+ int len;
+
+ /* If user did not specify a MAC address specifically, use
+ * the Quattro local-mac-address property...
+ */
+ if (qfe_slot != -1) {
+ addr = of_get_property(dp, "local-mac-address", &len);
+ if (addr && len == 6) {
+ eth_hw_addr_set(hp->dev, addr);
+ return;
+ }
+ }
+
+ eth_hw_addr_set(hp->dev, idprom->id_ethaddr);
+#else
+ u8 addr[ETH_ALEN];
+
+ get_hme_mac_nonsparc(hp->happy_dev, addr);
+ eth_hw_addr_set(hp->dev, addr);
+#endif
+ }
+}
+
#ifdef CONFIG_SBUS
static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
{
@@ -2320,8 +2447,7 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
struct quattro *qp = NULL;
struct happy_meal *hp;
struct net_device *dev;
- int i, qfe_slot = -1;
- u8 addr[ETH_ALEN];
+ int qfe_slot = -1;
int err;

sbus_dp = op->dev.parent->of_node;
@@ -2346,34 +2472,11 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
return -ENOMEM;
SET_NETDEV_DEV(dev, &op->dev);

- /* If user did not specify a MAC address specifically, use
- * the Quattro local-mac-address property...
- */
- for (i = 0; i < 6; i++) {
- if (macaddr[i] != 0)
- break;
- }
- if (i < 6) { /* a mac address was given */
- for (i = 0; i < 6; i++)
- addr[i] = macaddr[i];
- eth_hw_addr_set(dev, addr);
- macaddr[5]++;
- } else {
- const unsigned char *addr;
- int len;
-
- addr = of_get_property(dp, "local-mac-address", &len);
-
- if (qfe_slot != -1 && addr && len == ETH_ALEN)
- eth_hw_addr_set(dev, addr);
- else
- eth_hw_addr_set(dev, idprom->id_ethaddr);
- }
-
hp = netdev_priv(dev);
-
+ hp->dev = dev;
hp->happy_dev = op;
hp->dma_dev = &op->dev;
+ happy_meal_addr_init(hp, dp, qfe_slot);

spin_lock_init(&hp->happy_lock);

@@ -2451,7 +2554,6 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)

timer_setup(&hp->happy_timer, happy_meal_timer, 0);

- hp->dev = dev;
dev->netdev_ops = &hme_netdev_ops;
dev->watchdog_timeo = 5*HZ;
dev->ethtool_ops = &hme_ethtool_ops;
@@ -2504,104 +2606,17 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
#endif

#ifdef CONFIG_PCI
-#ifndef CONFIG_SPARC
-static int is_quattro_p(struct pci_dev *pdev)
-{
- struct pci_dev *busdev = pdev->bus->self;
- struct pci_dev *this_pdev;
- int n_hmes;
-
- if (busdev == NULL ||
- busdev->vendor != PCI_VENDOR_ID_DEC ||
- busdev->device != PCI_DEVICE_ID_DEC_21153)
- return 0;
-
- n_hmes = 0;
- list_for_each_entry(this_pdev, &pdev->bus->devices, bus_list) {
- if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
- this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
- n_hmes++;
- }
-
- if (n_hmes != 4)
- return 0;
-
- return 1;
-}
-
-/* Fetch MAC address from vital product data of PCI ROM. */
-static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
-{
- int this_offset;
-
- for (this_offset = 0x20; this_offset < len; this_offset++) {
- void __iomem *p = rom_base + this_offset;
-
- if (readb(p + 0) != 0x90 ||
- readb(p + 1) != 0x00 ||
- readb(p + 2) != 0x09 ||
- readb(p + 3) != 0x4e ||
- readb(p + 4) != 0x41 ||
- readb(p + 5) != 0x06)
- continue;
-
- this_offset += 6;
- p += 6;
-
- if (index == 0) {
- int i;
-
- for (i = 0; i < 6; i++)
- dev_addr[i] = readb(p + i);
- return 1;
- }
- index--;
- }
- return 0;
-}
-
-static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
-{
- size_t size;
- void __iomem *p = pci_map_rom(pdev, &size);
-
- if (p) {
- int index = 0;
- int found;
-
- if (is_quattro_p(pdev))
- index = PCI_SLOT(pdev->devfn);
-
- found = readb(p) == 0x55 &&
- readb(p + 1) == 0xaa &&
- find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
- pci_unmap_rom(pdev, p);
- if (found)
- return;
- }
-
- /* Sun MAC prefix then 3 random bytes. */
- dev_addr[0] = 0x08;
- dev_addr[1] = 0x00;
- dev_addr[2] = 0x20;
- get_random_bytes(&dev_addr[3], 3);
-}
-#endif /* !(CONFIG_SPARC) */
-
static int happy_meal_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct quattro *qp = NULL;
-#ifdef CONFIG_SPARC
- struct device_node *dp;
-#endif
+ struct device_node *dp = NULL;
struct happy_meal *hp;
struct net_device *dev;
void __iomem *hpreg_base;
struct resource *hpreg_res;
- int i, qfe_slot = -1;
+ int qfe_slot = -1;
char prom_name[64];
- u8 addr[ETH_ALEN];
int err;

/* Now make sure pci_dev cookie is there. */
@@ -2644,7 +2659,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);

hp = netdev_priv(dev);
-
+ hp->dev = dev;
hp->happy_dev = pdev;
hp->dma_dev = &pdev->dev;

@@ -2680,35 +2695,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
goto err_out_clear_quattro;
}

- for (i = 0; i < 6; i++) {
- if (macaddr[i] != 0)
- break;
- }
- if (i < 6) { /* a mac address was given */
- for (i = 0; i < 6; i++)
- addr[i] = macaddr[i];
- eth_hw_addr_set(dev, addr);
- macaddr[5]++;
- } else {
-#ifdef CONFIG_SPARC
- const unsigned char *addr;
- int len;
-
- if (qfe_slot != -1 &&
- (addr = of_get_property(dp, "local-mac-address", &len))
- != NULL &&
- len == 6) {
- eth_hw_addr_set(dev, addr);
- } else {
- eth_hw_addr_set(dev, idprom->id_ethaddr);
- }
-#else
- u8 addr[ETH_ALEN];
-
- get_hme_mac_nonsparc(pdev, addr);
- eth_hw_addr_set(dev, addr);
-#endif
- }
+ happy_meal_addr_init(hp, dp, qfe_slot);

/* Layout registers. */
hp->gregs = (hpreg_base + 0x0000UL);
@@ -2757,7 +2744,6 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
timer_setup(&hp->happy_timer, happy_meal_timer, 0);

hp->irq = pdev->irq;
- hp->dev = dev;
dev->netdev_ops = &hme_netdev_ops;
dev->watchdog_timeo = 5*HZ;
dev->ethtool_ops = &hme_ethtool_ops;
--
2.37.1


2023-02-22 21:04:59

by Sean Anderson

[permalink] [raw]
Subject: [RFC PATCH net-next 7/7] net: sunhme: Consolidate common probe tasks

Most of the second half of the PCI/SBUS probe functions are the same.
Consolidate them into a common function.

Signed-off-by: Sean Anderson <[email protected]>
---

drivers/net/ethernet/sun/sunhme.c | 183 ++++++++++++------------------
1 file changed, 71 insertions(+), 112 deletions(-)

diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 9b55adbe61df..9404dd4b1023 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -2440,6 +2440,71 @@ static void happy_meal_addr_init(struct happy_meal *hp,
}
}

+static int happy_meal_common_probe(struct happy_meal *hp,
+ struct device_node *dp, int minor_rev)
+{
+ struct net_device *dev = hp->dev;
+ int err;
+
+#ifdef CONFIG_SPARC
+ hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
+ if (hp->hm_revision == 0xff)
+ hp->hm_revision = 0xc0 | minor_rev;
+#else
+ /* works with this on non-sparc hosts */
+ hp->hm_revision = 0x20;
+#endif
+
+ /* Now enable the feature flags we can. */
+ if (hp->hm_revision == 0x20 || hp->hm_revision == 0x21)
+ hp->happy_flags |= HFLAG_20_21;
+ else if (hp->hm_revision != 0xa0)
+ hp->happy_flags |= HFLAG_NOT_A0;
+
+ hp->happy_block = dmam_alloc_coherent(hp->dma_dev, PAGE_SIZE,
+ &hp->hblock_dvma, GFP_KERNEL);
+ if (!hp->happy_block)
+ return -ENOMEM;
+
+ /* Force check of the link first time we are brought up. */
+ hp->linkcheck = 0;
+
+ /* Force timer state to 'asleep' with count of zero. */
+ hp->timer_state = asleep;
+ hp->timer_ticks = 0;
+
+ timer_setup(&hp->happy_timer, happy_meal_timer, 0);
+
+ dev->netdev_ops = &hme_netdev_ops;
+ dev->watchdog_timeo = 5 * HZ;
+ dev->ethtool_ops = &hme_ethtool_ops;
+
+ /* Happy Meal can do it all... */
+ dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+ dev->features |= dev->hw_features | NETIF_F_RXCSUM;
+
+#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
+ /* Hook up SBUS register/descriptor accessors. */
+ hp->read_desc32 = sbus_hme_read_desc32;
+ hp->write_txd = sbus_hme_write_txd;
+ hp->write_rxd = sbus_hme_write_rxd;
+ hp->read32 = sbus_hme_read32;
+ hp->write32 = sbus_hme_write32;
+#endif
+
+ /* Grrr, Happy Meal comes up by default not advertising
+ * full duplex 100baseT capabilities, fix this.
+ */
+ spin_lock_irq(&hp->happy_lock);
+ happy_meal_set_initial_advertisement(hp);
+ spin_unlock_irq(&hp->happy_lock);
+
+ err = devm_register_netdev(hp->dma_dev, dev);
+ if (err)
+ dev_err(hp->dma_dev, "Cannot register net device, aborting.\n");
+ return err;
+}
+
#ifdef CONFIG_SBUS
static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
{
@@ -2521,70 +2586,18 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
goto err_out_clear_quattro;
}

- hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
- if (hp->hm_revision == 0xff)
- hp->hm_revision = 0xa0;
-
- /* Now enable the feature flags we can. */
- if (hp->hm_revision == 0x20 || hp->hm_revision == 0x21)
- hp->happy_flags = HFLAG_20_21;
- else if (hp->hm_revision != 0xa0)
- hp->happy_flags = HFLAG_NOT_A0;
-
if (qp != NULL)
hp->happy_flags |= HFLAG_QUATTRO;

+ hp->irq = op->archdata.irqs[0];
+
/* Get the supported DVMA burst sizes from our Happy SBUS. */
hp->happy_bursts = of_getintprop_default(sbus_dp,
"burst-sizes", 0x00);

- hp->happy_block = dmam_alloc_coherent(&op->dev, PAGE_SIZE,
- &hp->hblock_dvma, GFP_KERNEL);
- if (!hp->happy_block) {
- err = -ENOMEM;
+ err = happy_meal_common_probe(hp, dp, 0);
+ if (err)
goto err_out_clear_quattro;
- }
-
- /* Force check of the link first time we are brought up. */
- hp->linkcheck = 0;
-
- /* Force timer state to 'asleep' with count of zero. */
- hp->timer_state = asleep;
- hp->timer_ticks = 0;
-
- timer_setup(&hp->happy_timer, happy_meal_timer, 0);
-
- dev->netdev_ops = &hme_netdev_ops;
- dev->watchdog_timeo = 5*HZ;
- dev->ethtool_ops = &hme_ethtool_ops;
-
- /* Happy Meal can do it all... */
- dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
- dev->features |= dev->hw_features | NETIF_F_RXCSUM;
-
- hp->irq = op->archdata.irqs[0];
-
-#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
- /* Hook up SBUS register/descriptor accessors. */
- hp->read_desc32 = sbus_hme_read_desc32;
- hp->write_txd = sbus_hme_write_txd;
- hp->write_rxd = sbus_hme_write_rxd;
- hp->read32 = sbus_hme_read32;
- hp->write32 = sbus_hme_write32;
-#endif
-
- /* Grrr, Happy Meal comes up by default not advertising
- * full duplex 100baseT capabilities, fix this.
- */
- spin_lock_irq(&hp->happy_lock);
- happy_meal_set_initial_advertisement(hp);
- spin_unlock_irq(&hp->happy_lock);
-
- err = devm_register_netdev(&op->dev, dev);
- if (err) {
- dev_err(&op->dev, "Cannot register net device, aborting.\n");
- goto err_out_clear_quattro;
- }

platform_set_drvdata(op, hp);

@@ -2704,21 +2717,6 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
hp->bigmacregs = (hpreg_base + 0x6000UL);
hp->tcvregs = (hpreg_base + 0x7000UL);

-#ifdef CONFIG_SPARC
- hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
- if (hp->hm_revision == 0xff)
- hp->hm_revision = 0xc0 | (pdev->revision & 0x0f);
-#else
- /* works with this on non-sparc hosts */
- hp->hm_revision = 0x20;
-#endif
-
- /* Now enable the feature flags we can. */
- if (hp->hm_revision == 0x20 || hp->hm_revision == 0x21)
- hp->happy_flags = HFLAG_20_21;
- else if (hp->hm_revision != 0xa0 && hp->hm_revision != 0xc0)
- hp->happy_flags = HFLAG_NOT_A0;
-
if (qp != NULL)
hp->happy_flags |= HFLAG_QUATTRO;

@@ -2729,50 +2727,11 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
/* Assume PCI happy meals can handle all burst sizes. */
hp->happy_bursts = DMA_BURSTBITS;
#endif
-
- hp->happy_block = dmam_alloc_coherent(&pdev->dev, PAGE_SIZE,
- &hp->hblock_dvma, GFP_KERNEL);
- if (!hp->happy_block) {
- err = -ENOMEM;
- goto err_out_clear_quattro;
- }
-
- hp->linkcheck = 0;
- hp->timer_state = asleep;
- hp->timer_ticks = 0;
-
- timer_setup(&hp->happy_timer, happy_meal_timer, 0);
-
hp->irq = pdev->irq;
- dev->netdev_ops = &hme_netdev_ops;
- dev->watchdog_timeo = 5*HZ;
- dev->ethtool_ops = &hme_ethtool_ops;

- /* Happy Meal can do it all... */
- dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
- dev->features |= dev->hw_features | NETIF_F_RXCSUM;
-
-#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
- /* Hook up PCI register/descriptor accessors. */
- hp->read_desc32 = pci_hme_read_desc32;
- hp->write_txd = pci_hme_write_txd;
- hp->write_rxd = pci_hme_write_rxd;
- hp->read32 = pci_hme_read32;
- hp->write32 = pci_hme_write32;
-#endif
-
- /* Grrr, Happy Meal comes up by default not advertising
- * full duplex 100baseT capabilities, fix this.
- */
- spin_lock_irq(&hp->happy_lock);
- happy_meal_set_initial_advertisement(hp);
- spin_unlock_irq(&hp->happy_lock);
-
- err = devm_register_netdev(&pdev->dev, dev);
- if (err) {
- dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
+ err = happy_meal_common_probe(hp, dp, pdev->revision & 0x0f);
+ if (err)
goto err_out_clear_quattro;
- }

pci_set_drvdata(pdev, hp);

--
2.37.1


2023-02-25 16:56:41

by Simon Horman

[permalink] [raw]
Subject: Re: [RFC PATCH net-next 1/7] net: sunhme: Just restart autonegotiation if we can't bring the link up

On Wed, Feb 22, 2023 at 04:03:49PM -0500, Sean Anderson wrote:
> If we've tried regular autonegotiation and forcing the link mode, just
> restart autonegotiation instead of reinitializing the whole NIC.
>
> Signed-off-by: Sean Anderson <[email protected]>
> ---
>
> drivers/net/ethernet/sun/sunhme.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
> index dd14114cbcfb..3eeda8f3fa80 100644
> --- a/drivers/net/ethernet/sun/sunhme.c
> +++ b/drivers/net/ethernet/sun/sunhme.c
> @@ -589,7 +589,10 @@ static int set_happy_link_modes(struct happy_meal *hp, void __iomem *tregs)
> return 1;
> }
>
> -static int happy_meal_init(struct happy_meal *hp);
> +static void
> +happy_meal_begin_auto_negotiation(struct happy_meal *hp,
> + void __iomem *tregs,
> + const struct ethtool_link_ksettings *ep);

I think it is preferable, though far more verbose, to move
happy_meal_begin_auto_negotiation() before happy_meal_timer and avoid the
need for a forward declaration. I did try this locally, and it did
compile.

> static int is_lucent_phy(struct happy_meal *hp)
> {
> @@ -743,12 +746,7 @@ static void happy_meal_timer(struct timer_list *t)
> netdev_notice(hp->dev,
> "Link down, cable problem?\n");
>
> - ret = happy_meal_init(hp);
> - if (ret) {
> - /* ho hum... */
> - netdev_err(hp->dev,
> - "Error, cannot re-init the Happy Meal.\n");
> - }
> + happy_meal_begin_auto_negotiation(hp, tregs, NULL);
> goto out;
> }
> if (!is_lucent_phy(hp)) {
> --
> 2.37.1
>

2023-02-25 18:39:56

by Simon Horman

[permalink] [raw]
Subject: Re: [RFC PATCH net-next 6/7] net: sunhme: Consolidate mac address initialization

On Wed, Feb 22, 2023 at 04:03:54PM -0500, Sean Anderson wrote:
> The mac address initialization is braodly the same between PCI and SBUS,
> and one was clearly copied from the other. Consolidate them. We still have
> to have some ifdefs because pci_(un)map_rom is only implemented for PCI,
> and idprom is only implemented for SPARC.
>
> Signed-off-by: Sean Anderson <[email protected]>

Overall this looks to correctly move code around as suggest.
Some minor nits and questions inline.

> ---
>
> drivers/net/ethernet/sun/sunhme.c | 284 ++++++++++++++----------------
> 1 file changed, 135 insertions(+), 149 deletions(-)
>
> diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
> index 75993834729a..9b55adbe61df 100644
> --- a/drivers/net/ethernet/sun/sunhme.c
> +++ b/drivers/net/ethernet/sun/sunhme.c
> @@ -34,6 +34,7 @@
> #include <linux/mm.h>
> #include <linux/module.h>
> #include <linux/netdevice.h>
> +#include <linux/of.h>
> #include <linux/random.h>
> #include <linux/skbuff.h>
> #include <linux/slab.h>
> @@ -47,7 +48,6 @@
> #include <asm/oplib.h>
> #include <asm/prom.h>
> #include <linux/of_device.h>
> -#include <linux/of.h>
> #endif
> #include <linux/uaccess.h>
>

nit: The above hunks don't seem related to the rest of this patch.

> @@ -2313,6 +2313,133 @@ static const struct net_device_ops hme_netdev_ops = {
> .ndo_validate_addr = eth_validate_addr,
> };
>
> +#ifdef CONFIG_PCI
> +static int is_quattro_p(struct pci_dev *pdev)

nit: I know you are moving code around here,
and likewise for many of my other comments.
But I think bool would be a better return type for this function.

> +{
> + struct pci_dev *busdev = pdev->bus->self;
> + struct pci_dev *this_pdev;
> + int n_hmes;
> +
> + if (!busdev || busdev->vendor != PCI_VENDOR_ID_DEC ||
> + busdev->device != PCI_DEVICE_ID_DEC_21153)
> + return 0;
> +
> + n_hmes = 0;
> + list_for_each_entry(this_pdev, &pdev->bus->devices, bus_list) {
> + if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
> + this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
> + n_hmes++;
> + }
> +
> + if (n_hmes != 4)
> + return 0;
> +
> + return 1;
> +}
> +
> +/* Fetch MAC address from vital product data of PCI ROM. */
> +static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)

nit: At some point it might be better
to update this function to return 0 on success and
an error otherwise.

> +{
> + int this_offset;
> +
> + for (this_offset = 0x20; this_offset < len; this_offset++) {
> + void __iomem *p = rom_base + this_offset;
> +
> + if (readb(p + 0) != 0x90 ||
> + readb(p + 1) != 0x00 ||
> + readb(p + 2) != 0x09 ||
> + readb(p + 3) != 0x4e ||
> + readb(p + 4) != 0x41 ||
> + readb(p + 5) != 0x06)
> + continue;
> +
> + this_offset += 6;
> + p += 6;
> +
> + if (index == 0) {
> + int i;
> +
> + for (i = 0; i < 6; i++)

nit: This could be,

for (int i = 0; i < 6; i++)

> + dev_addr[i] = readb(p + i);
> + return 1;
> + }
> + index--;
> + }

nit: blank line

> + return 0;
> +}
> +
> +static void __maybe_unused get_hme_mac_nonsparc(struct pci_dev *pdev,
> + unsigned char *dev_addr)
> +{
> + size_t size;
> + void __iomem *p = pci_map_rom(pdev, &size);

nit: reverse xmas tree.

> +
> + if (p) {
> + int index = 0;
> + int found;
> +
> + if (is_quattro_p(pdev))
> + index = PCI_SLOT(pdev->devfn);
> +
> + found = readb(p) == 0x55 &&
> + readb(p + 1) == 0xaa &&
> + find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
> + pci_unmap_rom(pdev, p);
> + if (found)
> + return;
> + }
> +
> + /* Sun MAC prefix then 3 random bytes. */
> + dev_addr[0] = 0x08;
> + dev_addr[1] = 0x00;
> + dev_addr[2] = 0x20;
> + get_random_bytes(&dev_addr[3], 3);
> +}
> +#endif /* !(CONFIG_SPARC) */

Should this be CONFIG_PCI ?

...

> @@ -2346,34 +2472,11 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
> return -ENOMEM;
> SET_NETDEV_DEV(dev, &op->dev);
>
> - /* If user did not specify a MAC address specifically, use
> - * the Quattro local-mac-address property...
> - */
> - for (i = 0; i < 6; i++) {
> - if (macaddr[i] != 0)
> - break;
> - }
> - if (i < 6) { /* a mac address was given */
> - for (i = 0; i < 6; i++)
> - addr[i] = macaddr[i];
> - eth_hw_addr_set(dev, addr);
> - macaddr[5]++;
> - } else {
> - const unsigned char *addr;
> - int len;
> -
> - addr = of_get_property(dp, "local-mac-address", &len);
> -
> - if (qfe_slot != -1 && addr && len == ETH_ALEN)
> - eth_hw_addr_set(dev, addr);
> - else
> - eth_hw_addr_set(dev, idprom->id_ethaddr);
> - }
> -
> hp = netdev_priv(dev);
> -
> + hp->dev = dev;

I'm not clear how this change relates to the rest of the patch.

> hp->happy_dev = op;
> hp->dma_dev = &op->dev;
> + happy_meal_addr_init(hp, dp, qfe_slot);
>
> spin_lock_init(&hp->happy_lock);
>
> @@ -2451,7 +2554,6 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
>
> timer_setup(&hp->happy_timer, happy_meal_timer, 0);
>
> - hp->dev = dev;
> dev->netdev_ops = &hme_netdev_ops;
> dev->watchdog_timeo = 5*HZ;
> dev->ethtool_ops = &hme_ethtool_ops;

...

> static int happy_meal_pci_probe(struct pci_dev *pdev,
> const struct pci_device_id *ent)
> {
> struct quattro *qp = NULL;
> -#ifdef CONFIG_SPARC
> - struct device_node *dp;

Was dp not being initialised previously a bug?

> -#endif
> + struct device_node *dp = NULL;

nit: I think it would be good to move towards, rather than away from,
reverse xmas tree here.

> struct happy_meal *hp;
> struct net_device *dev;
> void __iomem *hpreg_base;
> struct resource *hpreg_res;
> - int i, qfe_slot = -1;
> + int qfe_slot = -1;
> char prom_name[64];
> - u8 addr[ETH_ALEN];
> int err;
>
> /* Now make sure pci_dev cookie is there. */

...

> @@ -2680,35 +2695,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
> goto err_out_clear_quattro;
> }
>
> - for (i = 0; i < 6; i++) {
> - if (macaddr[i] != 0)
> - break;
> - }
> - if (i < 6) { /* a mac address was given */
> - for (i = 0; i < 6; i++)
> - addr[i] = macaddr[i];
> - eth_hw_addr_set(dev, addr);
> - macaddr[5]++;
> - } else {
> -#ifdef CONFIG_SPARC
> - const unsigned char *addr;
> - int len;
> -
> - if (qfe_slot != -1 &&
> - (addr = of_get_property(dp, "local-mac-address", &len))
> - != NULL &&
> - len == 6) {
> - eth_hw_addr_set(dev, addr);
> - } else {
> - eth_hw_addr_set(dev, idprom->id_ethaddr);
> - }
> -#else
> - u8 addr[ETH_ALEN];
> -
> - get_hme_mac_nonsparc(pdev, addr);
> - eth_hw_addr_set(dev, addr);
> -#endif
> - }
> + happy_meal_addr_init(hp, dp, qfe_slot);
>
> /* Layout registers. */
> hp->gregs = (hpreg_base + 0x0000UL);
> @@ -2757,7 +2744,6 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
> timer_setup(&hp->happy_timer, happy_meal_timer, 0);
>
> hp->irq = pdev->irq;
> - hp->dev = dev;
> dev->netdev_ops = &hme_netdev_ops;
> dev->watchdog_timeo = 5*HZ;
> dev->ethtool_ops = &hme_ethtool_ops;
> --
> 2.37.1
>

2023-02-25 19:00:45

by Sean Anderson

[permalink] [raw]
Subject: Re: [RFC PATCH net-next 1/7] net: sunhme: Just restart autonegotiation if we can't bring the link up

On 2/25/23 11:56, Simon Horman wrote:
> On Wed, Feb 22, 2023 at 04:03:49PM -0500, Sean Anderson wrote:
>> If we've tried regular autonegotiation and forcing the link mode, just
>> restart autonegotiation instead of reinitializing the whole NIC.
>>
>> Signed-off-by: Sean Anderson <[email protected]>
>> ---
>>
>> drivers/net/ethernet/sun/sunhme.c | 12 +++++-------
>> 1 file changed, 5 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
>> index dd14114cbcfb..3eeda8f3fa80 100644
>> --- a/drivers/net/ethernet/sun/sunhme.c
>> +++ b/drivers/net/ethernet/sun/sunhme.c
>> @@ -589,7 +589,10 @@ static int set_happy_link_modes(struct happy_meal *hp, void __iomem *tregs)
>> return 1;
>> }
>>
>> -static int happy_meal_init(struct happy_meal *hp);
>> +static void
>> +happy_meal_begin_auto_negotiation(struct happy_meal *hp,
>> + void __iomem *tregs,
>> + const struct ethtool_link_ksettings *ep);
>
> I think it is preferable, though far more verbose, to move
> happy_meal_begin_auto_negotiation() before happy_meal_timer and avoid the
> need for a forward declaration. I did try this locally, and it did
> compile.

Fine by me.

--Sean

>> static int is_lucent_phy(struct happy_meal *hp)
>> {
>> @@ -743,12 +746,7 @@ static void happy_meal_timer(struct timer_list *t)
>> netdev_notice(hp->dev,
>> "Link down, cable problem?\n");
>>
>> - ret = happy_meal_init(hp);
>> - if (ret) {
>> - /* ho hum... */
>> - netdev_err(hp->dev,
>> - "Error, cannot re-init the Happy Meal.\n");
>> - }
>> + happy_meal_begin_auto_negotiation(hp, tregs, NULL);
>> goto out;
>> }
>> if (!is_lucent_phy(hp)) {
>> --
>> 2.37.1
>>


2023-02-25 19:00:45

by Sean Anderson

[permalink] [raw]
Subject: Re: [RFC PATCH net-next 6/7] net: sunhme: Consolidate mac address initialization

On 2/25/23 13:39, Simon Horman wrote:
> On Wed, Feb 22, 2023 at 04:03:54PM -0500, Sean Anderson wrote:
>> The mac address initialization is braodly the same between PCI and SBUS,
>> and one was clearly copied from the other. Consolidate them. We still have
>> to have some ifdefs because pci_(un)map_rom is only implemented for PCI,
>> and idprom is only implemented for SPARC.
>>
>> Signed-off-by: Sean Anderson <[email protected]>
>
> Overall this looks to correctly move code around as suggest.
> Some minor nits and questions inline.
>
>> ---
>>
>> drivers/net/ethernet/sun/sunhme.c | 284 ++++++++++++++----------------
>> 1 file changed, 135 insertions(+), 149 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
>> index 75993834729a..9b55adbe61df 100644
>> --- a/drivers/net/ethernet/sun/sunhme.c
>> +++ b/drivers/net/ethernet/sun/sunhme.c
>> @@ -34,6 +34,7 @@
>> #include <linux/mm.h>
>> #include <linux/module.h>
>> #include <linux/netdevice.h>
>> +#include <linux/of.h>
>> #include <linux/random.h>
>> #include <linux/skbuff.h>
>> #include <linux/slab.h>
>> @@ -47,7 +48,6 @@
>> #include <asm/oplib.h>
>> #include <asm/prom.h>
>> #include <linux/of_device.h>
>> -#include <linux/of.h>
>> #endif
>> #include <linux/uaccess.h>
>>
>
> nit: The above hunks don't seem related to the rest of this patch.

I think I originally included this because I referenced some of_ thing from non-sparc
code. But it seems like that got refactored out.

>> @@ -2313,6 +2313,133 @@ static const struct net_device_ops hme_netdev_ops = {
>> .ndo_validate_addr = eth_validate_addr,
>> };
>>
>> +#ifdef CONFIG_PCI
>> +static int is_quattro_p(struct pci_dev *pdev)
>
> nit: I know you are moving code around here,
> and likewise for many of my other comments.
> But I think bool would be a better return type for this function.

I agree. I will address these sorts of things in a separate patch.

>> +{
>> + struct pci_dev *busdev = pdev->bus->self;
>> + struct pci_dev *this_pdev;
>> + int n_hmes;
>> +
>> + if (!busdev || busdev->vendor != PCI_VENDOR_ID_DEC ||
>> + busdev->device != PCI_DEVICE_ID_DEC_21153)
>> + return 0;
>> +
>> + n_hmes = 0;
>> + list_for_each_entry(this_pdev, &pdev->bus->devices, bus_list) {
>> + if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
>> + this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
>> + n_hmes++;
>> + }
>> +
>> + if (n_hmes != 4)
>> + return 0;
>> +
>> + return 1;
>> +}
>> +
>> +/* Fetch MAC address from vital product data of PCI ROM. */
>> +static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
>
> nit: At some point it might be better
> to update this function to return 0 on success and
> an error otherwise.
>
>> +{
>> + int this_offset;
>> +
>> + for (this_offset = 0x20; this_offset < len; this_offset++) {
>> + void __iomem *p = rom_base + this_offset;
>> +
>> + if (readb(p + 0) != 0x90 ||
>> + readb(p + 1) != 0x00 ||
>> + readb(p + 2) != 0x09 ||
>> + readb(p + 3) != 0x4e ||
>> + readb(p + 4) != 0x41 ||
>> + readb(p + 5) != 0x06)
>> + continue;
>> +
>> + this_offset += 6;
>> + p += 6;
>> +
>> + if (index == 0) {
>> + int i;
>> +
>> + for (i = 0; i < 6; i++)
>
> nit: This could be,
>
> for (int i = 0; i < 6; i++)

That's kosher now?

>> + dev_addr[i] = readb(p + i);
>> + return 1;
>> + }
>> + index--;
>> + }
>
> nit: blank line

OK

>> + return 0;
>> +}
>> +
>> +static void __maybe_unused get_hme_mac_nonsparc(struct pci_dev *pdev,
>> + unsigned char *dev_addr)
>> +{
>> + size_t size;
>> + void __iomem *p = pci_map_rom(pdev, &size);
>
> nit: reverse xmas tree.

OK

>> +
>> + if (p) {
>> + int index = 0;
>> + int found;
>> +
>> + if (is_quattro_p(pdev))
>> + index = PCI_SLOT(pdev->devfn);
>> +
>> + found = readb(p) == 0x55 &&
>> + readb(p + 1) == 0xaa &&
>> + find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
>> + pci_unmap_rom(pdev, p);
>> + if (found)
>> + return;
>> + }
>> +
>> + /* Sun MAC prefix then 3 random bytes. */
>> + dev_addr[0] = 0x08;
>> + dev_addr[1] = 0x00;
>> + dev_addr[2] = 0x20;
>> + get_random_bytes(&dev_addr[3], 3);
>> +}
>> +#endif /* !(CONFIG_SPARC) */
>
> Should this be CONFIG_PCI ?

No idea. I think I will just remove it...

>> @@ -2346,34 +2472,11 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
>> return -ENOMEM;
>> SET_NETDEV_DEV(dev, &op->dev);
>>
>> - /* If user did not specify a MAC address specifically, use
>> - * the Quattro local-mac-address property...
>> - */
>> - for (i = 0; i < 6; i++) {
>> - if (macaddr[i] != 0)
>> - break;
>> - }
>> - if (i < 6) { /* a mac address was given */
>> - for (i = 0; i < 6; i++)
>> - addr[i] = macaddr[i];
>> - eth_hw_addr_set(dev, addr);
>> - macaddr[5]++;
>> - } else {
>> - const unsigned char *addr;
>> - int len;
>> -
>> - addr = of_get_property(dp, "local-mac-address", &len);
>> -
>> - if (qfe_slot != -1 && addr && len == ETH_ALEN)
>> - eth_hw_addr_set(dev, addr);
>> - else
>> - eth_hw_addr_set(dev, idprom->id_ethaddr);
>> - }
>> -
>> hp = netdev_priv(dev);
>> -
>> + hp->dev = dev;
>
> I'm not clear how this change relates to the rest of the patch.

This mirrors the initialization on the PCI side. Makes their equivalence
more obvious.

>> hp->happy_dev = op;
>> hp->dma_dev = &op->dev;
>> + happy_meal_addr_init(hp, dp, qfe_slot);
>>
>> spin_lock_init(&hp->happy_lock);
>>
>> @@ -2451,7 +2554,6 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
>>
>> timer_setup(&hp->happy_timer, happy_meal_timer, 0);
>>
>> - hp->dev = dev;
>> dev->netdev_ops = &hme_netdev_ops;
>> dev->watchdog_timeo = 5*HZ;
>> dev->ethtool_ops = &hme_ethtool_ops;
>
> ...
>
>> static int happy_meal_pci_probe(struct pci_dev *pdev,
>> const struct pci_device_id *ent)
>> {
>> struct quattro *qp = NULL;
>> -#ifdef CONFIG_SPARC
>> - struct device_node *dp;
>
> Was dp not being initialised previously a bug?

No. All uses are protected by CONFIG_SPARC. But passing garbage to other
functions is bad form.

>> -#endif
>> + struct device_node *dp = NULL;
>
> nit: I think it would be good to move towards, rather than away from,
> reverse xmas tree here.

Which is why this line comes first ;)

But I am not a fan of introducing churn just to organize line lengths. So the
following will stay as-is until it needs to be reworked further.

>> struct happy_meal *hp;
>> struct net_device *dev;
>> void __iomem *hpreg_base;
>> struct resource *hpreg_res;
>> - int i, qfe_slot = -1;
>> + int qfe_slot = -1;
>> char prom_name[64];
>> - u8 addr[ETH_ALEN];
>> int err;
>>
>> /* Now make sure pci_dev cookie is there. */
>
> ...
>
>> @@ -2680,35 +2695,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
>> goto err_out_clear_quattro;
>> }
>>
>> - for (i = 0; i < 6; i++) {
>> - if (macaddr[i] != 0)
>> - break;
>> - }
>> - if (i < 6) { /* a mac address was given */
>> - for (i = 0; i < 6; i++)
>> - addr[i] = macaddr[i];
>> - eth_hw_addr_set(dev, addr);
>> - macaddr[5]++;
>> - } else {
>> -#ifdef CONFIG_SPARC
>> - const unsigned char *addr;
>> - int len;
>> -
>> - if (qfe_slot != -1 &&
>> - (addr = of_get_property(dp, "local-mac-address", &len))
>> - != NULL &&
>> - len == 6) {
>> - eth_hw_addr_set(dev, addr);
>> - } else {
>> - eth_hw_addr_set(dev, idprom->id_ethaddr);
>> - }
>> -#else
>> - u8 addr[ETH_ALEN];
>> -
>> - get_hme_mac_nonsparc(pdev, addr);
>> - eth_hw_addr_set(dev, addr);
>> -#endif
>> - }
>> + happy_meal_addr_init(hp, dp, qfe_slot);
>>
>> /* Layout registers. */
>> hp->gregs = (hpreg_base + 0x0000UL);
>> @@ -2757,7 +2744,6 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
>> timer_setup(&hp->happy_timer, happy_meal_timer, 0);
>>
>> hp->irq = pdev->irq;
>> - hp->dev = dev;
>> dev->netdev_ops = &hme_netdev_ops;
>> dev->watchdog_timeo = 5*HZ;
>> dev->ethtool_ops = &hme_ethtool_ops;
>> --
>> 2.37.1
>>

--Sean

2023-02-25 20:27:30

by Simon Horman

[permalink] [raw]
Subject: Re: [RFC PATCH net-next 6/7] net: sunhme: Consolidate mac address initialization

On Sat, Feb 25, 2023 at 01:59:33PM -0500, Sean Anderson wrote:
> On 2/25/23 13:39, Simon Horman wrote:
> > On Wed, Feb 22, 2023 at 04:03:54PM -0500, Sean Anderson wrote:
> > > The mac address initialization is braodly the same between PCI and SBUS,
> > > and one was clearly copied from the other. Consolidate them. We still have
> > > to have some ifdefs because pci_(un)map_rom is only implemented for PCI,
> > > and idprom is only implemented for SPARC.
> > >
> > > Signed-off-by: Sean Anderson <[email protected]>
> >
> > Overall this looks to correctly move code around as suggest.
> > Some minor nits and questions inline.
> >
> > > ---
> > >
> > > drivers/net/ethernet/sun/sunhme.c | 284 ++++++++++++++----------------
> > > 1 file changed, 135 insertions(+), 149 deletions(-)
> > >
> > > diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
> > > index 75993834729a..9b55adbe61df 100644
> > > --- a/drivers/net/ethernet/sun/sunhme.c
> > > +++ b/drivers/net/ethernet/sun/sunhme.c
> > > @@ -34,6 +34,7 @@
> > > #include <linux/mm.h>
> > > #include <linux/module.h>
> > > #include <linux/netdevice.h>
> > > +#include <linux/of.h>
> > > #include <linux/random.h>
> > > #include <linux/skbuff.h>
> > > #include <linux/slab.h>
> > > @@ -47,7 +48,6 @@
> > > #include <asm/oplib.h>
> > > #include <asm/prom.h>
> > > #include <linux/of_device.h>
> > > -#include <linux/of.h>
> > > #endif
> > > #include <linux/uaccess.h>
> >
> > nit: The above hunks don't seem related to the rest of this patch.
>
> I think I originally included this because I referenced some of_ thing from non-sparc
> code. But it seems like that got refactored out.
>
> > > @@ -2313,6 +2313,133 @@ static const struct net_device_ops hme_netdev_ops = {
> > > .ndo_validate_addr = eth_validate_addr,
> > > };
> > > +#ifdef CONFIG_PCI
> > > +static int is_quattro_p(struct pci_dev *pdev)
> >
> > nit: I know you are moving code around here,
> > and likewise for many of my other comments.
> > But I think bool would be a better return type for this function.
>
> I agree. I will address these sorts of things in a separate patch.

Thanks.

> > > +{
> > > + struct pci_dev *busdev = pdev->bus->self;
> > > + struct pci_dev *this_pdev;
> > > + int n_hmes;
> > > +
> > > + if (!busdev || busdev->vendor != PCI_VENDOR_ID_DEC ||
> > > + busdev->device != PCI_DEVICE_ID_DEC_21153)
> > > + return 0;
> > > +
> > > + n_hmes = 0;
> > > + list_for_each_entry(this_pdev, &pdev->bus->devices, bus_list) {
> > > + if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
> > > + this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
> > > + n_hmes++;
> > > + }
> > > +
> > > + if (n_hmes != 4)
> > > + return 0;
> > > +
> > > + return 1;
> > > +}
> > > +
> > > +/* Fetch MAC address from vital product data of PCI ROM. */
> > > +static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
> >
> > nit: At some point it might be better
> > to update this function to return 0 on success and
> > an error otherwise.
> >
> > > +{
> > > + int this_offset;
> > > +
> > > + for (this_offset = 0x20; this_offset < len; this_offset++) {
> > > + void __iomem *p = rom_base + this_offset;
> > > +
> > > + if (readb(p + 0) != 0x90 ||
> > > + readb(p + 1) != 0x00 ||
> > > + readb(p + 2) != 0x09 ||
> > > + readb(p + 3) != 0x4e ||
> > > + readb(p + 4) != 0x41 ||
> > > + readb(p + 5) != 0x06)
> > > + continue;
> > > +
> > > + this_offset += 6;
> > > + p += 6;
> > > +
> > > + if (index == 0) {
> > > + int i;
> > > +
> > > + for (i = 0; i < 6; i++)
> >
> > nit: This could be,
> >
> > for (int i = 0; i < 6; i++)
>
> That's kosher now?

I can't vouch for all architectures (e.g. sparc).
But in general, yes, I think so.

> > > + /* Sun MAC prefix then 3 random bytes. */
> > > + dev_addr[0] = 0x08;
> > > + dev_addr[1] = 0x00;
> > > + dev_addr[2] = 0x20;
> > > + get_random_bytes(&dev_addr[3], 3);
> > > +}
> > > +#endif /* !(CONFIG_SPARC) */
> >
> > Should this be CONFIG_PCI ?
>
> No idea. I think I will just remove it...

Yes, that would remove the problem quite nicely.

> > > @@ -2346,34 +2472,11 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
> > > return -ENOMEM;
> > > SET_NETDEV_DEV(dev, &op->dev);
> > > - /* If user did not specify a MAC address specifically, use
> > > - * the Quattro local-mac-address property...
> > > - */
> > > - for (i = 0; i < 6; i++) {
> > > - if (macaddr[i] != 0)
> > > - break;
> > > - }
> > > - if (i < 6) { /* a mac address was given */
> > > - for (i = 0; i < 6; i++)
> > > - addr[i] = macaddr[i];
> > > - eth_hw_addr_set(dev, addr);
> > > - macaddr[5]++;
> > > - } else {
> > > - const unsigned char *addr;
> > > - int len;
> > > -
> > > - addr = of_get_property(dp, "local-mac-address", &len);
> > > -
> > > - if (qfe_slot != -1 && addr && len == ETH_ALEN)
> > > - eth_hw_addr_set(dev, addr);
> > > - else
> > > - eth_hw_addr_set(dev, idprom->id_ethaddr);
> > > - }
> > > -
> > > hp = netdev_priv(dev);
> > > -
> > > + hp->dev = dev;
> >
> > I'm not clear how this change relates to the rest of the patch.
>
> This mirrors the initialization on the PCI side. Makes their equivalence
> more obvious.

Thanks, understood.

> > > hp->happy_dev = op;
> > > hp->dma_dev = &op->dev;
> > > + happy_meal_addr_init(hp, dp, qfe_slot);
> > > spin_lock_init(&hp->happy_lock);
> > > @@ -2451,7 +2554,6 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
> > > timer_setup(&hp->happy_timer, happy_meal_timer, 0);
> > > - hp->dev = dev;
> > > dev->netdev_ops = &hme_netdev_ops;
> > > dev->watchdog_timeo = 5*HZ;
> > > dev->ethtool_ops = &hme_ethtool_ops;
> >
> > ...
> >
> > > static int happy_meal_pci_probe(struct pci_dev *pdev,
> > > const struct pci_device_id *ent)
> > > {
> > > struct quattro *qp = NULL;
> > > -#ifdef CONFIG_SPARC
> > > - struct device_node *dp;
> >
> > Was dp not being initialised previously a bug?
>
> No. All uses are protected by CONFIG_SPARC. But passing garbage to other
> functions is bad form.

Thanks, agreed.

> > > -#endif
> > > + struct device_node *dp = NULL;
> >
> > nit: I think it would be good to move towards, rather than away from,
> > reverse xmas tree here.
>
> Which is why this line comes first ;)

Yes, silly me.

> But I am not a fan of introducing churn just to organize line lengths. So the
> following will stay as-is until it needs to be reworked further.
>

Yes, no objections there.
I just misread the diff. Sorry.

...

2023-02-25 21:08:09

by Simon Horman

[permalink] [raw]
Subject: Re: [RFC PATCH net-next 4/7] net: sunhme: Alphabetize includes

On Wed, Feb 22, 2023 at 04:03:52PM -0500, Sean Anderson wrote:
> Alphabetize includes to make it clearer where to add new ones.
>
> Signed-off-by: Sean Anderson <[email protected]>
> ---
>
> drivers/net/ethernet/sun/sunhme.c | 45 +++++++++++++++----------------
> 1 file changed, 22 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
> index 127253c67c59..ab39b555d9f7 100644
> --- a/drivers/net/ethernet/sun/sunhme.c
> +++ b/drivers/net/ethernet/sun/sunhme.c
> @@ -14,41 +14,40 @@
> * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
> */
>
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> +#include <asm/byteorder.h>
> +#include <asm/dma.h>
> +#include <linux/bitops.h>
> +#include <linux/crc32.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/errno.h>
> +#include <linux/etherdevice.h>
> +#include <linux/ethtool.h>
> #include <linux/fcntl.h>
> -#include <linux/interrupt.h>
> -#include <linux/ioport.h>
> #include <linux/in.h>
> -#include <linux/slab.h>
> -#include <linux/string.h>
> -#include <linux/delay.h>
> #include <linux/init.h>
> -#include <linux/ethtool.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/ioport.h>
> +#include <linux/kernel.h>
> #include <linux/mii.h>
> -#include <linux/crc32.h>
> -#include <linux/random.h>
> -#include <linux/errno.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> #include <linux/netdevice.h>
> -#include <linux/etherdevice.h>
> +#include <linux/random.h>
> #include <linux/skbuff.h>
> -#include <linux/mm.h>
> -#include <linux/bitops.h>
> -#include <linux/dma-mapping.h>
> -
> -#include <asm/io.h>
> -#include <asm/dma.h>
> -#include <asm/byteorder.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/types.h>
>
> #ifdef CONFIG_SPARC
> -#include <linux/of.h>
> -#include <linux/of_device.h>
> +#include <asm/auxio.h>
> #include <asm/idprom.h>
> #include <asm/openprom.h>
> #include <asm/oplib.h>
> #include <asm/prom.h>
> -#include <asm/auxio.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>

A nice cleanup, IMHO.
But can linux/ includes also moved out of the ifdefs.

> #endif
> #include <linux/uaccess.h>

And, perhaps it would be nice to further move things around so there are
three groups of includes:

* <asm/*.h>
- non #ifdef CONFIG_SPARC; and
- #ifdef CONFIG_SPARC
* <linux/*>
* "*.h"