Skip to contentSkip to conversation

sungem update

PATCH In review Benjamin Herrenschmidt 2 participants 5 messages Jan 18, 2005 – Feb 9, 2005 Network drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sungem update

Hi David !

This patch updates the sungem driver. I reworked all of the PM stuff, making it less prone to races, probably simpler to read as well, and I no longer shut the PHY down when the interface is down so that things like laptop-net no longer die (the gain in power consumption was minimal, not worth the pain). I also implemented basic WOL support.

There is still something I'm not totally happy with in the locking (explained in the comment at the beginning), basically too much locking and a couple of places with delays in locks. I will try to improve these later on.

If you are happy with this, please forward to Linus/Andrew asap

drivers/net/sungem_phy.c +24 -19
Index: linux-work/drivers/net/sungem_phy.c
===================================================================
@@ -98,25 +98,15 @@
 	data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
 	phy_write(phy, MII_BCM5201_MULTIPHY, data);
 
+	phy_write(phy, MII_BCM5201_INTERRUPT, 0);
+
 	return 0;
 }
 
-static int bcm5201_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5201_suspend(struct mii_phy* phy)
 {
-	if (!wol_options)
-		phy_write(phy, MII_BCM5201_INTERRUPT, 0);
-
-	/* Here's a strange hack used by both MacOS 9 and X */
-	phy_write(phy, MII_LPA, phy_read(phy, MII_LPA));
-	
-	if (!wol_options) {
-#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
-		u16 val = phy_read(phy, MII_BCM5201_AUXMODE2)
-		phy_write(phy, MII_BCM5201_AUXMODE2,
-			  val & ~MII_BCM5201_AUXMODE2_LOWPOWER);
-#endif			
-		phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
-	}
+	phy_write(phy, MII_BCM5201_INTERRUPT, 0);
+	phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
 
 	return 0;
 }
@@ -144,6 +134,21 @@
 	return 0;
 }
 
+static int bcm5221_suspend(struct mii_phy* phy)
+{
+	u16 data;
+
+	data = phy_read(phy, MII_BCM5221_TEST);
+	phy_write(phy, MII_BCM5221_TEST,
+		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
+
+	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
+	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
+		  data | MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE);
+
+	return 0;
+}
+
 static int bcm5400_init(struct mii_phy* phy)
 {
 	u16 data;
@@ -173,7 +178,7 @@
 	return 0;
 }
 
-static int bcm5400_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5400_suspend(struct mii_phy* phy)
 {
 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
 	phy_write(phy, MII_BMCR, BMCR_PDOWN);
@@ -229,7 +234,7 @@
 	return 0;
 }
 
-static int bcm5401_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5401_suspend(struct mii_phy* phy)
 {
 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
 	phy_write(phy, MII_BMCR, BMCR_PDOWN);
@@ -266,7 +271,7 @@
 	return 0;
 }
 
-static int bcm5411_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5411_suspend(struct mii_phy* phy)
 {
 	phy_write(phy, MII_BMCR, BMCR_PDOWN);
 
@@ -662,7 +667,7 @@
 
 /* Broadcom BCM 5221 */
 static struct mii_phy_ops bcm5221_phy_ops = {
-	.suspend	= bcm5201_suspend,
+	.suspend	= bcm5221_suspend,
 	.init		= bcm5221_init,
 	.setup_aneg	= genmii_setup_aneg,
 	.setup_forced	= genmii_setup_forced,
drivers/net/sungem_phy.h +2 -1
Index: linux-work/drivers/net/sungem_phy.h
===================================================================
@@ -7,7 +7,7 @@
 struct mii_phy_ops
 {
 	int		(*init)(struct mii_phy *phy);
-	int		(*suspend)(struct mii_phy *phy, int wol_options);
+	int		(*suspend)(struct mii_phy *phy);
 	int		(*setup_aneg)(struct mii_phy *phy, u32 advertise);
 	int		(*setup_forced)(struct mii_phy *phy, int speed, int fd);
 	int		(*poll_link)(struct mii_phy *phy);
@@ -80,6 +80,7 @@
 #define MII_BCM5221_SHDOW_AUX_STAT2		0x1b
 #define MII_BCM5221_SHDOW_AUX_STAT2_APD		0x0020
 #define MII_BCM5221_SHDOW_AUX_MODE4		0x1a
+#define MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE	0x0001
 #define MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR	0x0004
 
 /* MII BCM5400 1000-BASET Control register */
drivers/net/sungem.c +538 -437

1,433 lines not on this page · raw message

drivers/net/sungem.h +26 -4
Index: linux-work/drivers/net/sungem.h
===================================================================
@@ -170,6 +170,27 @@
  * them later. -DaveM
  */
 
+/* WakeOnLan Registers	*/
+#define WOL_MATCH0	0x3000UL
+#define WOL_MATCH1	0x3004UL
+#define WOL_MATCH2	0x3008UL
+#define WOL_MCOUNT	0x300CUL
+#define WOL_WAKECSR	0x3010UL
+
+/* WOL Match count register
+ */
+#define WOL_MCOUNT_N		0x00000010
+#define WOL_MCOUNT_M		0x00000000 /* 0 << 8 */
+
+#define WOL_WAKECSR_ENABLE	0x00000001
+#define WOL_WAKECSR_MII		0x00000002
+#define WOL_WAKECSR_SEEN	0x00000004
+#define WOL_WAKECSR_FILT_UCAST	0x00000008
+#define WOL_WAKECSR_FILT_MCAST	0x00000010
+#define WOL_WAKECSR_FILT_BCAST	0x00000020
+#define WOL_WAKECSR_FILT_SEEN	0x00000040
+
+
 /* Receive DMA Registers */
 #define RXDMA_CFG	0x4000UL	/* RX Configuration Register	*/
 #define RXDMA_DBLOW	0x4004UL	/* RX Descriptor Base Low	*/
@@ -961,11 +982,12 @@
 	/* Set when chip is actually in operational state
 	 * (ie. not power managed)
 	 */
-	int hw_running;
-	int opened;
+	int asleep;		/* chip asleep, protected by pm_sem */
+	int asleep_wol;		/* was asleep with WOL enabled */
+	int cell_enabled;	/* cell enable count, protected by lock */
+	int opened;		/* driver opened, protected by pm_sem */
+	int running;		/* chip running, protected by lock */
 	struct semaphore pm_sem;
-	struct work_struct pm_task;
-	struct timer_list pm_timer;
 
 	struct gem_init_block *init_block;
 
maintainer
#1 lore raw
Quoted 11 lines · On Tue, 18 Jan 2005 17:10:14 +1100 Benjamin Herrenschmidt…

This patch updates the sungem driver. I reworked all of the PM stuff, making it less prone to races, probably simpler to read as well, and I no longer shut the PHY down when the interface is down so that things like laptop-net no longer die (the gain in power consumption was minimal, not worth the pain). I also implemented basic WOL support.

There is still something I'm not totally happy with in the locking (explained in the comment at the beginning), basically too much locking and a couple of places with delays in locks. I will try to improve these later on.

If you are happy with this, please forward to Linus/Andrew asap

Sorry for taking so long. I'll try to quick review and sanity test this on my sparc sungem chips tomorrow Ben.

#2 lore raw
Quoted 5 lines
Quoted 2 lines

If you are happy with this, please forward to Linus/Andrew asap

Sorry for taking so long. I'll try to quick review and sanity test this on my sparc sungem chips tomorrow Ben.

Thanks. There is no real hurry as the bulk of the powermac PM updates won't make it until 2.6.12 anyway, so feel free to comment. I know I still take too much locks for too long, and I do intend to fix that, though the fact that set_multicast is called with a lock doesn't quite help here ... :) Hopefully, this new version makes the whole stuff more simple tho and easier to follow.

Ben.

maintainer
#3 lore raw
In reply to Benjamin Herrenschmidt
Quoted 6 lines · On Tue, 18 Jan 2005 17:10:14 +1100 Benjamin Herrenschmidt…

This patch updates the sungem driver. I reworked all of the PM stuff, making it less prone to races, probably simpler to read as well, and I no longer shut the PHY down when the interface is down so that things like laptop-net no longer die (the gain in power consumption was minimal, not worth the pain). I also implemented basic WOL support.

Quoted 7 lines

There is still something I'm not totally happy with in the locking (explained in the comment at the beginning), basically too much locking and a couple of places with delays in locks. I will try to improve these later on.

If you are happy with this, please forward to Linus/Andrew asap

Sorry for taking so long to review this :-/

This looks fine, except for one thing. The WOL_* registers don't exist in the Sun variants of the GEM chip, so it's not safe to try and program them on all chips blindly like these changes do. Perhaps some bit test like:

	if (pdev->vendor != PCI_VENDOR_ID_SUN)
		gp->flags |= GEM_HAS_WOL;

Then protect all the WOL_* register programming with this new GEM_HAS_WOL flag.

#4 lore raw

Hi !

Quoted 1 line

Sorry for taking so long to review this :-/

No worries.

Quoted 10 lines

This looks fine, except for one thing. The WOL_* registers don't exist in the Sun variants of the GEM chip, so it's not safe to try and program them on all chips blindly like these changes do. Perhaps some bit test like:

	if (pdev->vendor != PCI_VENDOR_ID_SUN)
		gp->flags |= GEM_HAS_WOL;

Then protect all the WOL_* register programming with this new GEM_HAS_WOL flag.

Ok, I'll have a look.

Ben.