LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Benjamin Herrenschmidt @ 2008-07-06  0:31 UTC (permalink / raw)
  To: Grant Erickson; +Cc: linuxppc-dev, sr
In-Reply-To: <1215303343-26410-1-git-send-email-gerickson@nuovations.com>

On Sat, 2008-07-05 at 17:15 -0700, Grant Erickson wrote:
> +       union {
> +               /* Registers unique to EMAC4 implementations */
> +               struct {
> +                       u32 iaht1;      /* Reset, R     */
> +                       u32 iaht2;      /* Reset, R     */
> +                       u32 iaht3;      /* Reset, R     */
> +                       u32 iaht4;      /* Reset, R     */
> +                       u32 gaht1;      /* Reset, R     */
> +                       u32 gaht2;      /* Reset, R     */
> +                       u32 gaht3;      /* Reset, R     */
> +                       u32 gaht4;      /* Reset, R     */
> +                       u32 lsah;
> +                       u32 lsal;
> +                       u32 ipgvr;      /* Reset,    T  */
> +                       u32 stacr;      /* Special      */
> +                       u32 trtr;       /* Special      */
> +                       u32 rwmr;       /* Reset        */
> +                       u32 octx;
> +                       u32 ocrx;
> +                       u32 ipcr;
> +               };
> +               /* Registers unique to EMAC4SYNC implementations */
> +               struct {
> +                       u32 mahr;       /* Reset, R, T  */
> +                       u32 malr;       /* Reset, R, T  */
> +                       u32 mmahr;      /* Reset, R, T  */
> +                       u32 mmalr;      /* Reset, R, T  */
> +                       u32 rsvd0[4];
> +                       u32 lsah;
> +                       u32 lsal;
> +                       u32 ipgvr;      /* Reset, T     */
> +                       u32 stacr;
> +                       u32 trtr;
> +                       u32 rwmr;       /* Reset        */
> +                       u32 octx;
> +                       u32 ocrx;
> +                       u32 rsvd1;
> +                       u32 revid;
> +                       u32 rsvd2[2];
> +                       u32 iaht[8];    /* Reset, R     */
> +                       u32 gaht[8];    /* Reset, R     */
> +                       u32 tpc;        /* Reset, T     */
> +               };
> +       };

Getting there :-) I note that all your sub-structs are unnamed. How does
the compiler knows which one to use to get to, for example, "lsah" ?

Thanks for working on that btw !

Cheers,
Ben.

^ permalink raw reply

* [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Grant Erickson @ 2008-07-06  0:15 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: sr
In-Reply-To: <1215249512-1974-1-git-send-email-gerickson@nuovations.com>

Various instances of the EMAC core have varying: 1) number of address 
match slots, 2) width of the registers for handling address match slots, 
3) number of registers for handling address match slots and 4) base 
offset for those registers.

As the driver stands today, it assumes that all EMACs have 4 IAHT and 
GAHT 32-bit registers, starting at offset 0x30 from the register base, 
with only 16-bits of each used for a total of 64 match slots.

The 405EX(r) and 460EX now use the EMAC4SYNC core rather than the EMAC4 
core. This core has 8 IAHT and GAHT registers, starting at offset 0x80 
from the register base, with ALL 32-bits of each used for a total of 
256 match slots.

This adds a new compatible device tree entry "emac4sync" and a new,
related feature flag "EMAC_FTR_EMAC4SYNC" along with a series of macros
and inlines which supply the appropriate parameterized value based on
the presence or absence of the EMAC4SYNC feature.

The code has further been reworked where appropriate to use those macros
and inlines.

In addition, the register size passed to ioremap is now taken from the 
device tree:

	c4 for EMAC4SYNC cores
	74 for EMAC4 cores
	70 for EMAC cores

rather than sizeof (emac_regs).

Finally, the device trees have been updated with the appropriate compatible
entries and resource sizes.

This has been tested on an AMCC Haleakala board such that: 1) inbound 
ICMP requests to 'haleakala.local' via MDNS from both Mac OS X 10.4.11 
and Ubuntu 8.04 systems as well as 2) outbound ICMP requests from 
'haleakala.local' to those same systems in the '.local' domain via MDNS 
now work.

Signed-off-by: Grant Erickson <gerickson@nuovations.com>
---
 arch/powerpc/boot/dts/canyonlands.dts |    8 ++--
 arch/powerpc/boot/dts/glacier.dts     |    8 ++--
 arch/powerpc/boot/dts/haleakala.dts   |    4 +-
 arch/powerpc/boot/dts/katmai.dts      |    2 +-
 arch/powerpc/boot/dts/kilauea.dts     |    8 ++--
 arch/powerpc/boot/dts/makalu.dts      |    8 ++--
 arch/powerpc/boot/dts/rainier.dts     |    4 +-
 arch/powerpc/boot/dts/sequoia.dts     |    4 +-
 arch/powerpc/boot/dts/taishan.dts     |    8 ++--
 drivers/net/ibm_newemac/core.c        |   60 ++++++++++++++------
 drivers/net/ibm_newemac/core.h        |   83 ++++++++++++++++++++++++++++-
 drivers/net/ibm_newemac/debug.c       |   30 +++++++----
 drivers/net/ibm_newemac/emac.h        |   96 ++++++++++++++++++++------------
 13 files changed, 230 insertions(+), 93 deletions(-)

diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 3963412..8b82d47 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -264,7 +264,7 @@
 
 			EMAC0: ethernet@ef600e00 {
 				device_type = "network";
-				compatible = "ibm,emac-460ex", "ibm,emac4";
+				compatible = "ibm,emac-460ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -272,7 +272,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 10 4
 						 /*Wake*/   1 &UIC2 14 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -293,7 +293,7 @@
 
 			EMAC1: ethernet@ef600f00 {
 				device_type = "network";
-				compatible = "ibm,emac-460ex", "ibm,emac4";
+				compatible = "ibm,emac-460ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -301,7 +301,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 11 4
 						 /*Wake*/   1 &UIC2 15 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts
index 0f2fc07..8ffde9b 100644
--- a/arch/powerpc/boot/dts/glacier.dts
+++ b/arch/powerpc/boot/dts/glacier.dts
@@ -281,7 +281,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 10 4
 						 /*Wake*/   1 &UIC2 14 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -310,7 +310,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 11 4
 						 /*Wake*/   1 &UIC2 15 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -340,7 +340,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 12 4
 						 /*Wake*/   1 &UIC2 16 4>;
-				reg = <ef601100 70>;
+				reg = <ef601100 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -368,7 +368,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 13 4
 						 /*Wake*/   1 &UIC2 17 4>;
-				reg = <ef601200 70>;
+				reg = <ef601200 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
index b5d95ac..d131c00 100644
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ b/arch/powerpc/boot/dts/haleakala.dts
@@ -204,7 +204,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405exr", "ibm,emac4";
+				compatible = "ibm,emac-405exr", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -212,7 +212,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index cc2873a..c91bb66 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -206,7 +206,7 @@
 				compatible = "ibm,emac-440spe", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1c 4 1d 4>;
-				reg = <10000800 70>;
+				reg = <10000800 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 48c9a6e..799592d 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -205,7 +205,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -213,7 +213,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -233,7 +233,7 @@
 			EMAC1: ethernet@ef600a00 {
 				linux,network-index = <1>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -241,7 +241,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600a00 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts
index 84cc5e7..4295772 100644
--- a/arch/powerpc/boot/dts/makalu.dts
+++ b/arch/powerpc/boot/dts/makalu.dts
@@ -205,7 +205,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -213,7 +213,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -233,7 +233,7 @@
 			EMAC1: ethernet@ef600a00 {
 				linux,network-index = <1>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -241,7 +241,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600a00 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts
index 6a8fa70..026c22c 100644
--- a/arch/powerpc/boot/dts/rainier.dts
+++ b/arch/powerpc/boot/dts/rainier.dts
@@ -263,7 +263,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -292,7 +292,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index 72d6756..8d66c99 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -278,7 +278,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -307,7 +307,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts
index e808e1c..f736d87 100644
--- a/arch/powerpc/boot/dts/taishan.dts
+++ b/arch/powerpc/boot/dts/taishan.dts
@@ -258,7 +258,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1c 4 1d 4>;
-				reg = <40000800 70>;
+				reg = <40000800 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -278,7 +278,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1e 4 1f 4>;
-				reg = <40000900 70>;
+				reg = <40000900 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -298,7 +298,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC2>;
 				interrupts = <0 4 1 4>;
-				reg = <40000c00 70>;
+				reg = <40000c00 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -322,7 +322,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC2>;
 				interrupts = <2 4 3 4>;
-				reg = <40000e00 70>;
+				reg = <40000e00 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 5d2108c..931a061 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -363,25 +363,32 @@ static int emac_reset(struct emac_instance *dev)
 
 static void emac_hash_mc(struct emac_instance *dev)
 {
-	struct emac_regs __iomem *p = dev->emacp;
-	u16 gaht[4] = { 0 };
+	const int regs = EMAC_XAHT_REGS(dev);
+	u32 *gaht_base = emac_gaht_base(dev);
+	u32 gaht_temp[regs];
 	struct dev_mc_list *dmi;
+	int i;
 
 	DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count);
 
+	memset(gaht_temp, 0, sizeof (gaht_temp));
+
 	for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
-		int bit;
+		int slot, reg, mask;
 		DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
 		     dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
 		     dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
 
-		bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
-		gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+		slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
+		reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
+		mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot);
+
+		gaht_temp[reg] |= mask;
+	}
+
+	for (i = 0; i < regs; i++) {
+		out_be32(gaht_base + i, gaht_temp[i]);
 	}
-	out_be32(&p->gaht1, gaht[0]);
-	out_be32(&p->gaht2, gaht[1]);
-	out_be32(&p->gaht3, gaht[2]);
-	out_be32(&p->gaht4, gaht[3]);
 }
 
 static inline u32 emac_iff2rmr(struct net_device *ndev)
@@ -398,7 +405,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev)
 
 	if (ndev->flags & IFF_PROMISC)
 		r |= EMAC_RMR_PME;
-	else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
+	else if (ndev->flags & IFF_ALLMULTI ||
+			 (ndev->mc_count > EMAC_XAHT_SLOTS(dev)))
 		r |= EMAC_RMR_PMME;
 	else if (ndev->mc_count > 0)
 		r |= EMAC_RMR_MAE;
@@ -2015,10 +2023,10 @@ static int emac_get_regs_len(struct emac_instance *dev)
 {
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
 		return sizeof(struct emac_ethtool_regs_subhdr) +
-			EMAC4_ETHTOOL_REGS_SIZE;
+			EMAC4_ETHTOOL_REGS_SIZE(dev);
 	else
 		return sizeof(struct emac_ethtool_regs_subhdr) +
-			EMAC_ETHTOOL_REGS_SIZE;
+			EMAC_ETHTOOL_REGS_SIZE(dev);
 }
 
 static int emac_ethtool_get_regs_len(struct net_device *ndev)
@@ -2045,12 +2053,12 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf)
 	hdr->index = dev->cell_index;
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
 		hdr->version = EMAC4_ETHTOOL_REGS_VER;
-		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE);
-		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE);
+		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
+		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev));
 	} else {
 		hdr->version = EMAC_ETHTOOL_REGS_VER;
-		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
-		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
+		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
+		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev));
 	}
 }
 
@@ -2540,7 +2548,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 
 	/* Check EMAC version */
-	if (of_device_is_compatible(np, "ibm,emac4")) {
+	if (of_device_is_compatible(np, "ibm,emac4sync")) {
+		dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC);
+	} else if (of_device_is_compatible(np, "ibm,emac4")) {
 		dev->features |= EMAC_FTR_EMAC4;
 		if (of_device_is_compatible(np, "ibm,emac-440gx"))
 			dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
@@ -2601,6 +2611,15 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 	memcpy(dev->ndev->dev_addr, p, 6);
 
+	/* IAHT and GAHT filter parameterization */
+	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) {
+		dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT;
+		dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT;
+	} else {
+		dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT;
+		dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT;
+	}
+
 	DBG(dev, "features     : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE);
 	DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige);
 	DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige);
@@ -2672,7 +2691,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
 		goto err_irq_unmap;
 	}
 	// TODO : request_mem_region
-	dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs));
+	dev->emacp = ioremap(dev->rsrc_regs.start,
+						 dev->rsrc_regs.end - dev->rsrc_regs.start + 1);
 	if (dev->emacp == NULL) {
 		printk(KERN_ERR "%s: Can't map device registers!\n",
 		       np->full_name);
@@ -2884,6 +2904,10 @@ static struct of_device_id emac_match[] =
 		.type		= "network",
 		.compatible	= "ibm,emac4",
 	},
+	{
+		.type		= "network",
+		.compatible	= "ibm,emac4sync",
+	},
 	{},
 };
 
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 1683db9..312bfa5 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -235,6 +235,10 @@ struct emac_instance {
 	u32				fifo_entry_size;
 	u32				mal_burst_size; /* move to MAL ? */
 
+	/* IAHT and GAHT filter parameterization */
+	u32				xaht_slots_shift;
+	u32				xaht_width_shift;
+
 	/* Descriptor management
 	 */
 	struct mal_descriptor		*tx_desc;
@@ -309,6 +313,10 @@ struct emac_instance {
  * Set if we need phy clock workaround for 440ep or 440gr
  */
 #define EMAC_FTR_440EP_PHY_CLK_FIX	0x00000100
+/*
+ * The 405EX and 460EX contain the EMAC4SYNC core
+ */
+#define EMAC_FTR_EMAC4SYNC		0x00000200
 
 
 /* Right now, we don't quite handle the always/possible masks on the
@@ -320,7 +328,8 @@ enum {
 
 	EMAC_FTRS_POSSIBLE	=
 #ifdef CONFIG_IBM_NEW_EMAC_EMAC4
-	    EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
+	    EMAC_FTR_EMAC4	| EMAC_FTR_EMAC4SYNC	|
+	    EMAC_FTR_HAS_NEW_STACR	|
 	    EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
 #endif
 #ifdef CONFIG_IBM_NEW_EMAC_TAH
@@ -342,6 +351,71 @@ static inline int emac_has_feature(struct emac_instance *dev,
 	       (EMAC_FTRS_POSSIBLE & dev->features & feature);
 }
 
+/*
+ * Various instances of the EMAC core have varying 1) number of
+ * address match slots, 2) width of the registers for handling address
+ * match slots, 3) number of registers for handling address match
+ * slots and 4) base offset for those registers.
+ *
+ * These macros and inlines handle these differences based on
+ * parameters supplied by the device tree.
+ */
+
+#define	EMAC4_XAHT_SLOTS_SHIFT		6
+#define	EMAC4_XAHT_WIDTH_SHIFT		4
+#define	EMAC4_XAHT_BASE_OFFSET		0x30
+
+#define	EMAC4SYNC_XAHT_SLOTS_SHIFT	8
+#define	EMAC4SYNC_XAHT_WIDTH_SHIFT	5
+#define	EMAC4SYNC_XAHT_BASE_OFFSET	0x80
+
+
+#define	EMAC_XAHT_SLOTS(dev)         	(1 << (dev)->xaht_slots_shift)
+#define	EMAC_XAHT_WIDTH(dev)         	(1 << (dev)->xaht_width_shift)
+#define	EMAC_XAHT_REGS(dev)          	(1 << ((dev)->xaht_slots_shift - \
+					       (dev)->xaht_width_shift))
+
+#define	EMAC_XAHT_CRC_TO_SLOT(dev, crc)			\
+	((EMAC_XAHT_SLOTS(dev) - 1) -			\
+	 ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) -	\
+		    (dev)->xaht_slots_shift)))
+
+#define	EMAC_XAHT_SLOT_TO_REG(dev, slot)		\
+	((slot) >> (dev)->xaht_width_shift)
+
+#define	EMAC_XAHT_SLOT_TO_MASK(dev, slot)		\
+	((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >>	\
+	 ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1)))
+
+static inline u32 *emac_xaht_base(struct emac_instance *dev)
+{
+	struct emac_regs __iomem *p = dev->emacp;
+	int offset;
+
+	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC))
+	    offset = EMAC4SYNC_XAHT_BASE_OFFSET;
+	else
+	    offset = EMAC4_XAHT_BASE_OFFSET;
+
+	return ((u32 *)((ptrdiff_t)p + offset));
+}
+
+static inline u32 *emac_gaht_base(struct emac_instance *dev)
+{
+	/* GAHT registers always come after an identical number of
+	 * IAHT registers.
+	 */
+	return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev));
+}
+
+static inline u32 *emac_iaht_base(struct emac_instance *dev)
+{
+	/* IAHT registers always come before an identical number of
+	 * GAHT registers.
+	 */
+	return (emac_xaht_base(dev));
+}
+
 
 /* Ethtool get_regs complex data.
  * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
@@ -366,4 +440,11 @@ struct emac_ethtool_regs_subhdr {
 	u32 index;
 };
 
+#define EMAC_ETHTOOL_REGS_VER		0
+#define EMAC_ETHTOOL_REGS_SIZE(dev) 	((dev)->rsrc_regs.end - \
+					 (dev)->rsrc_regs.start + 1)
+#define EMAC4_ETHTOOL_REGS_VER      	1
+#define EMAC4_ETHTOOL_REGS_SIZE(dev)	((dev)->rsrc_regs.end -	\
+					 (dev)->rsrc_regs.start + 1)
+
 #endif /* __IBM_NEWEMAC_CORE_H */
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c
index 86b756a..99f9e14 100644
--- a/drivers/net/ibm_newemac/debug.c
+++ b/drivers/net/ibm_newemac/debug.c
@@ -67,25 +67,33 @@ static void emac_desc_dump(struct emac_instance *p)
 static void emac_mac_dump(struct emac_instance *dev)
 {
 	struct emac_regs __iomem *p = dev->emacp;
+	const int xaht_regs = EMAC_XAHT_REGS(dev);
+	u32 *gaht_base = emac_gaht_base(dev);
+	u32 *iaht_base = emac_iaht_base(dev);
+	int n;
 
 	printk("** EMAC %s registers **\n"
 	       "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
 	       "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
-	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
-	       "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
-	       "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
-	       "LSA = %04x%08x IPGVR = 0x%04x\n"
-	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
-	       "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
+	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n",
 	       dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1),
 	       in_be32(&p->tmr0), in_be32(&p->tmr1),
 	       in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
 	       in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
-	       in_be32(&p->vtci),
-	       in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
-	       in_be32(&p->iaht4),
-	       in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
-	       in_be32(&p->gaht4),
+	       in_be32(&p->vtci)
+	    );
+
+	for (n = 0; n < xaht_regs; n++) {
+		printk("IAHT%02d: 0x%08x\n", n + 1, in_be32(iaht_base + n));
+	}
+
+	for (n = 0; n < xaht_regs; n++) {
+		printk("GAHT%02d: 0x%08x\n", n + 1, in_be32(gaht_base + n));
+	}
+
+	printk("LSA = %04x%08x IPGVR = 0x%04x\n"
+	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
+	       "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
 	       in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
 	       in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
 	       in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h
index 91cb096..aa54f5c 100644
--- a/drivers/net/ibm_newemac/emac.h
+++ b/drivers/net/ibm_newemac/emac.h
@@ -27,37 +27,67 @@
 
 #include <linux/types.h>
 
-/* EMAC registers 		Write Access rules */
+/* EMAC registers 			Write Access rules */
 struct emac_regs {
-	u32 mr0;		/* special 	*/
-	u32 mr1;		/* Reset 	*/
-	u32 tmr0;		/* special 	*/
-	u32 tmr1;		/* special 	*/
-	u32 rmr;		/* Reset 	*/
-	u32 isr;		/* Always 	*/
-	u32 iser;		/* Reset 	*/
-	u32 iahr;		/* Reset, R, T 	*/
-	u32 ialr;		/* Reset, R, T 	*/
-	u32 vtpid;		/* Reset, R, T 	*/
-	u32 vtci;		/* Reset, R, T 	*/
-	u32 ptr;		/* Reset,    T 	*/
-	u32 iaht1;		/* Reset, R	*/
-	u32 iaht2;		/* Reset, R	*/
-	u32 iaht3;		/* Reset, R	*/
-	u32 iaht4;		/* Reset, R	*/
-	u32 gaht1;		/* Reset, R	*/
-	u32 gaht2;		/* Reset, R	*/
-	u32 gaht3;		/* Reset, R	*/
-	u32 gaht4;		/* Reset, R	*/
-	u32 lsah;
-	u32 lsal;
-	u32 ipgvr;		/* Reset,    T 	*/
-	u32 stacr;		/* special 	*/
-	u32 trtr;		/* special 	*/
-	u32 rwmr;		/* Reset 	*/
-	u32 octx;
-	u32 ocrx;
-	u32 ipcr;
+	/* Common registers across all EMAC implementations. */
+	struct {
+		u32 mr0;		/* Special 	*/
+		u32 mr1;		/* Reset 	*/
+		u32 tmr0;		/* Special 	*/
+		u32 tmr1;		/* Special 	*/
+		u32 rmr;		/* Reset 	*/
+		u32 isr;		/* Always 	*/
+		u32 iser;		/* Reset 	*/
+		u32 iahr;		/* Reset, R, T 	*/
+		u32 ialr;		/* Reset, R, T 	*/
+		u32 vtpid;		/* Reset, R, T 	*/
+		u32 vtci;		/* Reset, R, T 	*/
+		u32 ptr;		/* Reset,    T 	*/
+	};
+	union {
+		/* Registers unique to EMAC4 implementations */
+		struct {
+			u32 iaht1;	/* Reset, R	*/
+			u32 iaht2;	/* Reset, R	*/
+			u32 iaht3;	/* Reset, R	*/
+			u32 iaht4;	/* Reset, R	*/
+			u32 gaht1;	/* Reset, R	*/
+			u32 gaht2;	/* Reset, R	*/
+			u32 gaht3;	/* Reset, R	*/
+			u32 gaht4;	/* Reset, R	*/
+			u32 lsah;
+			u32 lsal;
+			u32 ipgvr;	/* Reset,    T 	*/
+			u32 stacr;	/* Special 	*/
+			u32 trtr;	/* Special 	*/
+			u32 rwmr;	/* Reset 	*/
+			u32 octx;
+			u32 ocrx;
+			u32 ipcr;
+		};
+		/* Registers unique to EMAC4SYNC implementations */
+		struct {
+			u32 mahr;	/* Reset, R, T  */
+			u32 malr;	/* Reset, R, T  */
+			u32 mmahr;	/* Reset, R, T  */
+			u32 mmalr;	/* Reset, R, T  */
+			u32 rsvd0[4];
+			u32 lsah;
+			u32 lsal;
+			u32 ipgvr;	/* Reset, T     */
+			u32 stacr;
+			u32 trtr;
+			u32 rwmr;	/* Reset        */
+			u32 octx;
+			u32 ocrx;
+			u32 rsvd1;
+			u32 revid;
+			u32 rsvd2[2];
+			u32 iaht[8];	/* Reset, R     */
+			u32 gaht[8];	/* Reset, R     */
+			u32 tpc;	/* Reset, T     */
+		};
+	};
 };
 
 /*
@@ -73,12 +103,6 @@ struct emac_regs {
 #define PHY_MODE_RTBI	7
 #define PHY_MODE_SGMII	8
 
-
-#define EMAC_ETHTOOL_REGS_VER		0
-#define EMAC_ETHTOOL_REGS_SIZE		(sizeof(struct emac_regs) - sizeof(u32))
-#define EMAC4_ETHTOOL_REGS_VER      	1
-#define EMAC4_ETHTOOL_REGS_SIZE		sizeof(struct emac_regs)
-
 /* EMACx_MR0 */
 #define EMAC_MR0_RXI			0x80000000
 #define EMAC_MR0_TXI			0x40000000

^ permalink raw reply related

* Re: the printk problem
From: Pekka Enberg @ 2008-07-06  0:02 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-ia64, Vegard Nossum, linux-kernel, Jan Engelhardt,
	linuxppc-dev, Peter Anvin, Andrew Morton, Linus Torvalds,
	David S. Miller
In-Reply-To: <20080705185253.GQ14894@parisc-linux.org>

On Sat, Jul 05, 2008 at 08:41:39PM +0200, Vegard Nossum wrote:
>> Single letters are bad because it hurts readability and limits the
>> usefulness of the extension.</MHO>

On Sat, Jul 5, 2008 at 9:52 PM, Matthew Wilcox <matthew@wil.cx> wrote:
> I think you need a little warning noise that goes off in your head that
> means "I might be overdesigning this".  Linus' code is elegant and
> solves a problem nicely.

Am I the only one who missed Linus' patch? Did it make it to the list?

^ permalink raw reply

* Re: the printk problem
From: Arjan van de Ven @ 2008-07-05 22:57 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, linuxppc-dev, Peter Anvin, Andrew Morton,
	David S. Miller, parisc-linux
In-Reply-To: <alpine.LFD.1.10.0807051523180.2847@woody.linux-foundation.org>

Linus Torvalds wrote:
> 
> On Fri, 4 Jul 2008, Linus Torvalds wrote:
>> Still all happily untested, of course. And still with no actual users 
>> converted.
> 
> Ok, it's tested, and here's an example usage conversion.
> 
> The diffstat pretty much says it all. It _does_ change the format of the 
> stack trace entry a bit, but I don't think it's for the worse (unless it 
> breaks things like the oops tracker - Arjan?)
> 
> It changes the symbol-in-module format from
> 
> 	:ext3:add_dirent_to_buf+0x6c/0x26c
> 
> to
> 
> 	add_dirent_to_buf+0x6c/0x26c [ext3]
> 
> but quite frankly, the latter was the standard format anyway (it's what 
> "sprint_symbol()" gives you), and traps_64.c was the odd man out.
> 

This won't break anything for me actually; I already deal with either case.

$ cat oopsparse.pl | wc -l
1252

the kernel is so inconsistent with oops formats (over time/across architectures)
that once you deal with what there is today... you pretty much deal with everything.

I also like the improvement; I wished something like this existed several times already
in the last few months so for sure

Acked-by: Arjan van de Ven <arjan@linux.intel.com>

^ permalink raw reply

* Re: [PATCH v3] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Benjamin Herrenschmidt @ 2008-07-05 22:45 UTC (permalink / raw)
  To: Grant Erickson; +Cc: linuxppc-dev, sr
In-Reply-To: <1215249512-1974-1-git-send-email-gerickson@nuovations.com>

On Sat, 2008-07-05 at 02:18 -0700, Grant Erickson wrote:
> --- a/drivers/net/ibm_newemac/emac.h
> +++ b/drivers/net/ibm_newemac/emac.h
> @@ -41,14 +41,7 @@ struct emac_regs {
>         u32 vtpid;              /* Reset, R, T  */
>         u32 vtci;               /* Reset, R, T  */
>         u32 ptr;                /* Reset,    T  */
> -       u32 iaht1;              /* Reset, R     */
> -       u32 iaht2;              /* Reset, R     */
> -       u32 iaht3;              /* Reset, R     */
> -       u32 iaht4;              /* Reset, R     */
> -       u32 gaht1;              /* Reset, R     */
> -       u32 gaht2;              /* Reset, R     */
> -       u32 gaht3;              /* Reset, R     */
> -       u32 gaht4;              /* Reset, R     */
> +       u32 reserved[8];/* Chip-dependent */
>         u32 lsah;
>         u32 lsal;
>         u32 ipgvr;              /* Reset,    T  */

Mostly looks good. I don't like "reserved" here tho...

Are lsah, lsal and ipgvr still meaningful here ?

If not, just remove everything past "ptr"...

Another option would have been to have emac regs be something
like

struct emac_regs {
	all the common regs
	.../...
	union (
		struct emac4_add_regs {
			emac4 additional regs
		};
		struct emac4sync_add_regs {
			emac4sync additional regs
		}
	};
};

Ben.

^ permalink raw reply

* Re: the printk problem
From: Linus Torvalds @ 2008-07-05 22:32 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linux-ia64, linuxppc-dev, Peter Anvin, Andrew Morton,
	Arjan van de Ven, David S. Miller, parisc-linux
In-Reply-To: <alpine.LFD.1.10.0807041622270.2815@woody.linux-foundation.org>



On Fri, 4 Jul 2008, Linus Torvalds wrote:
> 
> Still all happily untested, of course. And still with no actual users 
> converted.

Ok, it's tested, and here's an example usage conversion.

The diffstat pretty much says it all. It _does_ change the format of the 
stack trace entry a bit, but I don't think it's for the worse (unless it 
breaks things like the oops tracker - Arjan?)

It changes the symbol-in-module format from

	:ext3:add_dirent_to_buf+0x6c/0x26c

to

	add_dirent_to_buf+0x6c/0x26c [ext3]

but quite frankly, the latter was the standard format anyway (it's what 
"sprint_symbol()" gives you), and traps_64.c was the odd man out.

In fact, traps_32.c already uses the standard print_symbol() format, so it 
really was an issue of the 64-bit code being odd (and I assume that this 
also means that it cannot break the oops tracker, since it already had to 
be able to handle both formats).

I also removed the KALLSYMS dependency, so if KALLSYMS isn't enabled it 
will now give the same hex format twice, but I doubt we really care (such 
stack traces are unreadable whether it shows up once or twice, and the 
simplicity is worth it).

If people do just a few more conversions like this, then the 52 added 
lines in lib/vsnprintf.c are more than made up for by removed lines 
elsewhere (and more readable source code).

		Linus

---
 arch/x86/kernel/traps_64.c |   25 +------------------------
 1 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index adff76e..f1a95d1 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -104,30 +104,7 @@ int kstack_depth_to_print = 12;
 
 void printk_address(unsigned long address, int reliable)
 {
-#ifdef CONFIG_KALLSYMS
-	unsigned long offset = 0, symsize;
-	const char *symname;
-	char *modname;
-	char *delim = ":";
-	char namebuf[KSYM_NAME_LEN];
-	char reliab[4] = "";
-
-	symname = kallsyms_lookup(address, &symsize, &offset,
-					&modname, namebuf);
-	if (!symname) {
-		printk(" [<%016lx>]\n", address);
-		return;
-	}
-	if (!reliable)
-		strcpy(reliab, "? ");
-
-	if (!modname)
-		modname = delim = "";
-	printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
-		address, reliab, delim, modname, delim, symname, offset, symsize);
-#else
-	printk(" [<%016lx>]\n", address);
-#endif
+	printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address);
 }
 
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,

^ permalink raw reply related

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
From: Benjamin Herrenschmidt @ 2008-07-05 22:20 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev
In-Reply-To: <200807052351.39945.arnd@arndb.de>

On Sat, 2008-07-05 at 23:51 +0200, Arnd Bergmann wrote:
> 
> It turned out that the firmware sets up the south bridge to never set the 'S'
> bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
> existing cell hardware.
> 
> This weak ordering gives the same ordering guarantees as the default ordering
> for DMA on other PowerPC machines. Setting strong ordering on both the host
> bridge *and* the page table will give further ordering guarantees, i.e.
> it will make sure that no DMA requests on the bus can ever overtake each
> other

I need to look closely at what the various bridge settings are. Drivers
do expect DMA requests from one device to stay in order, at least up to
what's defined in the PCI spec, which is pretty much fully ordered
unless those devices set the PCIe (or X) relaxed ordering attribute.
However, AFAIK, Axon doesn't convey that sort of ordering attributes
from incoming transactions between the PCIe segment and the PLB5.

Ben.

^ permalink raw reply

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
From: Arnd Bergmann @ 2008-07-05 21:51 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev
In-Reply-To: <1215239339.8970.10.camel@pasglop>

On Saturday 05 July 2008, Benjamin Herrenschmidt wrote:
> On Sat, 2008-07-05 at 15:43 +1000, Michael Ellerman wrote:
> > > The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
> > > (for both the dynamic and fixed mappings) which enforces strong ordering of
> > > both reads and writes. This patch makes the default behaviour weak ordering
> > > (the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
> > > new DMA_ATTR_STRONG_ORDERING needs to be used.
> > 
> > We're sure that's safe?
> 
> I'd say it's not...

It turned out that the firmware sets up the south bridge to never set the 'S'
bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
existing cell hardware.

This weak ordering gives the same ordering guarantees as the default ordering
for DMA on other PowerPC machines. Setting strong ordering on both the host
bridge *and* the page table will give further ordering guarantees, i.e.
it will make sure that no DMA requests on the bus can ever overtake each
other.

	Arnd <><

^ permalink raw reply

* Re: the printk problem
From: Matthew Wilcox @ 2008-07-05 18:52 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: linux-ia64, linux-kernel, Jan Engelhardt, linuxppc-dev,
	Peter Anvin, Andrew Morton, Linus Torvalds, David S. Miller
In-Reply-To: <19f34abd0807051141h4ccfd0ar28660199f2bbf81f@mail.gmail.com>

On Sat, Jul 05, 2008 at 08:41:39PM +0200, Vegard Nossum wrote:
> Single letters are bad because it hurts readability and limits the
> usefulness of the extension.</MHO>

I think you need a little warning noise that goes off in your head that
means "I might be overdesigning this".  Linus' code is elegant and
solves a problem nicely.

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply

* Re: the printk problem
From: Linus Torvalds @ 2008-07-05 18:44 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: linux-ia64, Matthew Wilcox, Vegard Nossum, linux-kernel,
	linuxppc-dev, Peter Anvin, Andrew Morton, David S. Miller
In-Reply-To: <alpine.LNX.1.10.0807052039520.28765@fbirervta.pbzchgretzou.qr>



On Sat, 5 Jul 2008, Jan Engelhardt wrote:
> 
> So, and what do you do when you run out of alphanumeric characters?

Did you actually look at my patch?

It's not a single alnum character. It's an arbitrary sequence of alnum 
characters. IOW, my patch allows

	%p6N

or something like that for showing a ipv6 "NIP" format string etc. Or you 
could spell them out even more, although I consider it unlikely that you 
really want to see too many of these, since gcc won't actually be able to 
type-check them (so they will always remain _secondary_ formats).

			Linus

^ permalink raw reply

* Re: the printk problem
From: Vegard Nossum @ 2008-07-05 18:41 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, Jan Engelhardt,
	linuxppc-dev, Peter Anvin, Andrew Morton, David S. Miller
In-Reply-To: <alpine.LFD.1.10.0807051045520.2815@woody.linux-foundation.org>

On Sat, Jul 5, 2008 at 7:56 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Sat, 5 Jul 2008, Vegard Nossum wrote:
>> On Sat, Jul 5, 2008 at 1:33 PM, Jan Engelhardt <jengelh@medozas.de> wrote:
>> > How about %p{feature}?
>
> No.
>
> I _expressly_ chose '%p[alphanumeric]*' because it's basically
> totally insane to have that in a *real* printk() string: the end result
> would be totally unreadable.
>
> In contrast, '%p[specialchar]' is not unreadable, and in fact we have lots
> of those already in the kernel. In fact, there are 40 occurrences of '%p{'
> in the kernel, just grep for it (especially the AFS code seems to be very
> happy to use that kind of printout in its debug statements).
>
> So it makes perfect sense to have a _real_ printk string that says
>
>        "BUG: Dentry %p{i=%lx,n=%s}"
>
> where we have that '%p{...' sequence: the end result is easily parseable.
> In contrast, anybody who uses '%pS' or something like that and expects a
> pointer name to be immediately followed by teh letter 'S' is simply
> insane, because the end result is an unreadable mess.

That's really a truly hideous hack :-)

Single letters are bad because it hurts readability and limits the
usefulness of the extension.</MHO>

If it's just the {} that is the problem, use something else. I'm sure
we can find something that isn't used already.

>
>> (It's hard on the stack, yes, I know. We should fix kallsyms.)
>
> Not just that, but it's broken when KALLSYMS is disabled. Look at what
> sprint_symbol() becomes.

Oops. Not hard to mend, though.

> The patch I already sent out is about a million times better, because it
> avoids all these issues, and knows about subtle issues like the difference
> between a direct pointer and a pointer to a function descriptor.

Right, right. I found it now:

http://ozlabs.org/pipermail/linuxppc-dev/2008-July/059257.html

Argh... Some pointer to original thread would be nice when adding new Ccs.


Vegard

PS: Your version has exactly the same stack problem. Will send a patch
for kallsyms later.

-- 
"The animistic metaphor of the bug that maliciously sneaked in while
the programmer was not looking is intellectually dishonest as it
disguises that the error is the programmer's own creation."
	-- E. W. Dijkstra, EWD1036

^ permalink raw reply

* Re: the printk problem
From: Jan Engelhardt @ 2008-07-05 18:40 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, Matthew Wilcox, Vegard Nossum, linux-kernel,
	linuxppc-dev, Peter Anvin, Andrew Morton, David S. Miller
In-Reply-To: <alpine.LFD.1.10.0807051045520.2815@woody.linux-foundation.org>


On Saturday 2008-07-05 19:56, Linus Torvalds wrote:
>> >
>> > How about %p{feature}?
>
>No.
>
>I _expressly_ chose '%p[alphanumeric]*' because it's basically 
>totally insane to have that in a *real* printk() string: the end result 
>would be totally unreadable.

So, and what do you do when you run out of alphanumeric characters?

^ permalink raw reply

* Re: the printk problem
From: Linus Torvalds @ 2008-07-05 17:56 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, Jan Engelhardt,
	linuxppc-dev, Peter Anvin, Andrew Morton, David S. Miller
In-Reply-To: <20080705125230.GA20166@damson.getinternet.no>



On Sat, 5 Jul 2008, Vegard Nossum wrote:

> On Sat, Jul 5, 2008 at 1:33 PM, Jan Engelhardt <jengelh@medozas.de> wrote:
> >
> > On Saturday 2008-07-05 00:01, Andrew Morton wrote:
> >>
> >>We don't know how much interest there would be in churning NIPQUAD from
> >>the net guys.  Interestingly, there's also %C (wint_t) which is a
> >>32-bit quantity.  So we could just go and say "%C prints an ipv4
> >>address" and be done with it.  But there's no way of doing that for
> >>ipv6 addresses so things would become asymmetrical there.
> >
> >        struct in6_addr src;
> >        printk("Source address: %p{ipv6}\n", &src);
> >
> > How about %p{feature}?

No.

I _expressly_ chose '%p[alphanumeric]*' because it's basically 
totally insane to have that in a *real* printk() string: the end result 
would be totally unreadable.

In contrast, '%p[specialchar]' is not unreadable, and in fact we have lots 
of those already in the kernel. In fact, there are 40 occurrences of '%p{' 
in the kernel, just grep for it (especially the AFS code seems to be very 
happy to use that kind of printout in its debug statements).

So it makes perfect sense to have a _real_ printk string that says

	"BUG: Dentry %p{i=%lx,n=%s}"

where we have that '%p{...' sequence: the end result is easily parseable. 
In contrast, anybody who uses '%pS' or something like that and expects a 
pointer name to be immediately followed by teh letter 'S' is simply 
insane, because the end result is an unreadable mess.

> (It's hard on the stack, yes, I know. We should fix kallsyms.)

Not just that, but it's broken when KALLSYMS is disabled. Look at what 
sprint_symbol() becomes.

The patch I already sent out is about a million times better, because it 
avoids all these issues, and knows about subtle issues like the difference 
between a direct pointer and a pointer to a function descriptor. 

		Linus

^ permalink raw reply

* Re: [PATCH 10/16 v3] powerpc: iommu enablement for CMO
From: Olof Johansson @ 2008-07-05 17:51 UTC (permalink / raw)
  To: Robert Jennings; +Cc: Brian King, linuxppc-dev, paulus, David Darrington
In-Reply-To: <20080704125459.GM1310@linux.vnet.ibm.com>

Hi,

On Jul 4, 2008, at 7:54 AM, Robert Jennings wrote:

> To support Cooperative Memory Overcommitment (CMO), we need to check
> for failure from some of the tce hcalls.
>
> These changes for the pseries platform affect the powerpc  
> architecture;
> patches for the other affected platforms are included in this patch.
>
> pSeries platform IOMMU code changes:
> * platform TCE functions must handle H_NOT_ENOUGH_RESOURCES errors and
>   return an error.
>
> Architecture IOMMU code changes:
> * Calls to ppc_md.tce_build need to check return values and return
>   DMA_MAPPING_ERROR for transient errors.
>
> Architecture changes:
> * struct machdep_calls for tce_build*_pSeriesLP functions need to  
> change
>   to indicate failure.
> * all other platforms will need updates to iommu functions to match  
> the new
>   calling semantics; they will return 0 on success.  The other  
> platforms
>   default configs have been built, but no further testing was  
> performed.
>
> Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>

Acked-by: Olof Johansson <olof@lixom.net>

^ permalink raw reply

* Re: [PATCH] Add MPC5200B base board mvBC-P
From: Grant Likely @ 2008-07-05 16:13 UTC (permalink / raw)
  To: André Schwarz; +Cc: linux-ppc list
In-Reply-To: <486F3F98.3060205@matrix-vision.de>

On Sat, Jul 5, 2008 at 3:32 AM, Andr=E9 Schwarz
<Andre.Schwarz@matrix-vision.de> wrote:
> It's a MPC5200B. I thought that the "b"-Option has already out of use aft=
er
> reading about this a few weeks ago ... maybe I misinterpreted.

No, I'm *toying* with the idea, but I haven't decided yet.

> > I think it would be better to just leave out the partition information
> > and modify U-Boot to fill them in (just like memory and clock speed are
> > left out).  Things like flash partitions are less like hardware
> > description and more like configuration data.
>
> never did this. Is it quick'n'easy ?
> Honestly I don't like the bootloader to set up everything.
> If you need any change it will require a bootloader update which is a ver=
y
> fragile operation out in the field.
> There will always be bricked systems afterwards ....
> Failure in updating the (redundant) dtb blob or kernel will do almost alw=
ays
> no harm since the system is still accessible and flashable using ethernet=
 or
> serial.
>
> If it's not against all rule (which I don't think) I'd really like to sti=
ck
> to it, too.
> Is this ok ?

hurumm... okay, leave it in.  I suppose it isn't a risky thing to do.

g.


--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: the printk problem
From: Jan Engelhardt @ 2008-07-05 14:07 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, linuxppc-dev,
	Peter Anvin, Andrew Morton, Linus Torvalds, David S. Miller
In-Reply-To: <19f34abd0807050650y327ca434pfca324fcccc14f06@mail.gmail.com>


On Saturday 2008-07-05 15:50, Vegard Nossum wrote:
>
>I think the most elegant solution would be a macro similar to the
>initcall macros, that adds the custom extensions to a table which is
>defined by a special linker section. This allows complete
>decentralization, but I don't think it's possible to do binary search
>on the names anymore.

With an rbtree, you can still do binary search.

^ permalink raw reply

* Re: the printk problem
From: Vegard Nossum @ 2008-07-05 13:50 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, linuxppc-dev,
	Peter Anvin, Andrew Morton, Linus Torvalds, David S. Miller
In-Reply-To: <alpine.LNX.1.10.0807051518500.28765@fbirervta.pbzchgretzou.qr>

On Sat, Jul 5, 2008 at 3:24 PM, Jan Engelhardt <jengelh@medozas.de> wrote:
>
> On Saturday 2008-07-05 14:52, Vegard Nossum wrote:
>>> On Saturday 2008-07-05 00:01, Andrew Morton wrote:
>>>>
>>>>We don't know how much interest there would be in churning NIPQUAD from
>>>>the net guys.  Interestingly, there's also %C (wint_t) which is a
>>>>32-bit quantity.  So we could just go and say "%C prints an ipv4
>>>>address" and be done with it.  But there's no way of doing that for
>>>>ipv6 addresses so things would become asymmetrical there.
>>>
>>>        struct in6_addr src;
>>>        printk("Source address: %p{ipv6}\n", &src);
>>>
>>> How about %p{feature}?
>>
>>Something like this?
>>
>>+static char *custom_format(char *buf, char *end,
>>+      const char *fmt, unsigned int fmtlen, void *arg)
>
> I'd use const void *arg here, so nobody gets the idea
> that you could modify the argument while printing :)
>

Oops, of course. Thanks.

>>+{
>>+      if (!strncmp(fmt, "sym", fmtlen)) {
...
>>+      }
>
> And I assume it's then as simple as
>
>        } else if (strncmp(fmt, "nip6", fmtlen) == 0) {
>                snprintf(buf, end - buf (+1?), NIP6_FMT in expanded form,
>                         NIP6 in expanded form(arg));
>        }
>
> Hm, that's going to get a big function when everyone adds their
> fmttypes.
>

Yes. Luckily, the entry point is then fixed in a single place and it's
easy to convert it into something more dynamic :-)

A static array wouldn't help much because it still concentrates all
the names. But we could at least do a binary search on that and get
some speed improvements if it grows large.

I think the most elegant solution would be a macro similar to the
initcall macros, that adds the custom extensions to a table which is
defined by a special linker section. This allows complete
decentralization, but I don't think it's possible to do binary search
on the names anymore.

Dynamic registering/unregistering could be done too. Maybe this is a
good thing for modules...

Thoughts?

>>+
>>+      return buf;
>>+}
>>+
>> static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
>> {
>>       /* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
>>@@ -648,6 +673,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
>>                               continue;
>>
>>                       case 'p':
>>+                              if (fmt[1] == '{') {
>>+                                      const char *cfmt;
>>+
>>+                                      /* Skip the '%{' */
>>+                                      ++fmt;
>>+                                      ++fmt;
>>+
>
> Not this?
>
>        /* Skip the '%p{' */
>        fmt += 3;
>

Oops, the comment is wrong. It should say: "Skip the p{". But fmt += 3
is wrong. Since fmt[0] is at this point 'p', and fmt[1] is '{'. The %
and flags, etc. have already been skipped by the common code. So it
should be fmt += 2 :-)

Thanks!


Vegard

-- 
"The animistic metaphor of the bug that maliciously sneaked in while
the programmer was not looking is intellectually dishonest as it
disguises that the error is the programmer's own creation."
	-- E. W. Dijkstra, EWD1036

^ permalink raw reply

* Re: the printk problem
From: Jan Engelhardt @ 2008-07-05 13:24 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, linuxppc-dev,
	Peter Anvin, Andrew Morton, Linus Torvalds, David S. Miller
In-Reply-To: <20080705125230.GA20166@damson.getinternet.no>


On Saturday 2008-07-05 14:52, Vegard Nossum wrote:
>> On Saturday 2008-07-05 00:01, Andrew Morton wrote:
>>>
>>>We don't know how much interest there would be in churning NIPQUAD from
>>>the net guys.  Interestingly, there's also %C (wint_t) which is a
>>>32-bit quantity.  So we could just go and say "%C prints an ipv4
>>>address" and be done with it.  But there's no way of doing that for
>>>ipv6 addresses so things would become asymmetrical there.
>>
>>        struct in6_addr src;
>>        printk("Source address: %p{ipv6}\n", &src);
>>
>> How about %p{feature}?
>
>Something like this?
>
>+static char *custom_format(char *buf, char *end,
>+	const char *fmt, unsigned int fmtlen, void *arg)

I'd use const void *arg here, so nobody gets the idea
that you could modify the argument while printing :)

>+{
>+	if (!strncmp(fmt, "sym", fmtlen)) {
>+		char name[KSYM_SYMBOL_LEN];
>+		int len;
>+		int i;
>+
>+		len = sprint_symbol(name, (unsigned long) arg);
>+		if (len < 0)
>+			return buf;
>+
>+		i = 0;
>+		while (i < len) {
>+			if (buf < end)
>+				*buf = name[i];
>+			++buf;
>+			++i;
>+		}
>+	}

And I assume it's then as simple as

	} else if (strncmp(fmt, "nip6", fmtlen) == 0) {
		snprintf(buf, end - buf (+1?), NIP6_FMT in expanded form,
		         NIP6 in expanded form(arg));
	}

Hm, that's going to get a big function when everyone adds their
fmttypes.

>+
>+	return buf;
>+}
>+
> static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
> {
> 	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
>@@ -648,6 +673,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
> 				continue;
> 
> 			case 'p':
>+				if (fmt[1] == '{') {
>+					const char *cfmt;
>+
>+					/* Skip the '%{' */
>+					++fmt;
>+					++fmt;
>+

Not this?

	/* Skip the '%p{' */
	fmt += 3;

^ permalink raw reply

* Re: the printk problem
From: Vegard Nossum @ 2008-07-05 12:52 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, linuxppc-dev,
	Peter Anvin, Andrew Morton, Linus Torvalds, David S. Miller
In-Reply-To: <alpine.LNX.1.10.0807051332200.28765@fbirervta.pbzchgretzou.qr>

On Sat, Jul 5, 2008 at 1:33 PM, Jan Engelhardt <jengelh@medozas.de> wrote:
>
> On Saturday 2008-07-05 00:01, Andrew Morton wrote:
>>
>>We don't know how much interest there would be in churning NIPQUAD from
>>the net guys.  Interestingly, there's also %C (wint_t) which is a
>>32-bit quantity.  So we could just go and say "%C prints an ipv4
>>address" and be done with it.  But there's no way of doing that for
>>ipv6 addresses so things would become asymmetrical there.
>
>        struct in6_addr src;
>        printk("Source address: %p{ipv6}\n", &src);
>
> How about %p{feature}?

Something like this?

(It's hard on the stack, yes, I know. We should fix kallsyms.)

Vegard


From: Vegard Nossum <vegard.nossum@gmail.com>
Date: Sat, 5 Jul 2008 14:01:00 +0200
Subject: [PATCH] printf: add %p{} extension

Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
---
 lib/vsprintf.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 6021757..011cf3f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdarg.h>
+#include <linux/kallsyms.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -366,6 +367,30 @@ static noinline char* put_dec(char *buf, unsigned long long num)
 #define SMALL	32		/* Must be 32 == 0x20 */
 #define SPECIAL	64		/* 0x */
 
+static char *custom_format(char *buf, char *end,
+	const char *fmt, unsigned int fmtlen, void *arg)
+{
+	if (!strncmp(fmt, "sym", fmtlen)) {
+		char name[KSYM_SYMBOL_LEN];
+		int len;
+		int i;
+
+		len = sprint_symbol(name, (unsigned long) arg);
+		if (len < 0)
+			return buf;
+
+		i = 0;
+		while (i < len) {
+			if (buf < end)
+				*buf = name[i];
+			++buf;
+			++i;
+		}
+	}
+
+	return buf;
+}
+
 static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
 {
 	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
@@ -648,6 +673,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 				continue;
 
 			case 'p':
+				if (fmt[1] == '{') {
+					const char *cfmt;
+
+					/* Skip the '%{' */
+					++fmt;
+					++fmt;
+
+					cfmt = fmt;
+
+					/* Skip everything up to the '}' */
+					while (*fmt && *fmt != '}')
+						++fmt;
+
+					str = custom_format(str, end,
+						cfmt, fmt - cfmt,
+						va_arg(args, void *));
+					continue;
+				}
+
 				flags |= SMALL;
 				if (field_width == -1) {
 					field_width = 2*sizeof(void *);
-- 
1.5.4.1

^ permalink raw reply related

* Re: the printk problem
From: Jan Engelhardt @ 2008-07-05 11:33 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, linuxppc-dev,
	Peter Anvin, Linus Torvalds, David S. Miller
In-Reply-To: <20080704150100.1f7b8a65.akpm@linux-foundation.org>


On Saturday 2008-07-05 00:01, Andrew Morton wrote:
>
>We don't know how much interest there would be in churning NIPQUAD from
>the net guys.  Interestingly, there's also %C (wint_t) which is a
>32-bit quantity.  So we could just go and say "%C prints an ipv4
>address" and be done with it.  But there's no way of doing that for
>ipv6 addresses so things would become asymmetrical there.

	struct in6_addr src;
	printk("Source address: %p{ipv6}\n", &src);

How about %p{feature}?

^ permalink raw reply

* Re: New fsl device bindings file
From: Jochen Friedrich @ 2008-07-05 11:34 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev list
In-Reply-To: <486D1A58.8010403@freescale.com>

Hi Scott,

>> I'm going to move all the Freescale SoC related bindings into this new 
>> file.  One of the aspects of the new file is we will NOT having an 
>> ordinal heading index.
> 
> How about splitting up like this:
> 
> Documentation/powerpc/device-tree/fsl/cpm.txt
> Documentation/powerpc/device-tree/fsl/cpm/uart.txt
> Documentation/powerpc/device-tree/fsl/tsec.txt
> Documentation/powerpc/device-tree/interrupts.txt
> Documentation/powerpc/device-tree/dtb.txt

Sounds reasonable.

Thanks,
Jochen

^ permalink raw reply

* [PATCH] powerpc: Add documentation for CPM GPIO banks
From: Jochen Friedrich @ 2008-07-05 11:29 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev list, Paul Mackerras, Scott Wood

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 Documentation/powerpc/device-tree/fsl/cpm/gpio.txt |   38 ++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/powerpc/device-tree/fsl/cpm/gpio.txt

diff --git a/Documentation/powerpc/device-tree/fsl/cpm/gpio.txt b/Documentation/powerpc/device-tree/fsl/cpm/gpio.txt
new file mode 100644
index 0000000..54644ae
--- /dev/null
+++ b/Documentation/powerpc/device-tree/fsl/cpm/gpio.txt
@@ -0,0 +1,38 @@
+Every GPIO controller node must have #gpio-cells property defined,
+this information will be used to translate gpio-specifiers.
+
+On CPM1 devices, all ports are using slightly different register layouts.
+Ports A, C and D are 16bit ports and Ports B and E are 32bit ports.
+
+On CPM2 devices, all ports are 32bit ports and use a common register layout.
+
+Required properties:
+- compatible : "fsl,cpm1-pario-bank-a", "fsl,cpm1-pario-bank-b", 
+  "fsl,cpm1-pario-bank-c", "fsl,cpm1-pario-bank-d",
+  "fsl,cpm1-pario-bank-e", "fsl,cpm2-pario-bank"
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional paramters (currently unused).
+- gpio-controller : Marks the port as GPIO controller.
+
+Example of three SOC GPIO banks defined as gpio-controller nodes:
+
+	CPM1_PIO_A: gpio-controller@950 {
+		#gpio-cells = <2>;
+		compatible = "fsl,cpm1-pario-bank-a";
+		reg = <0x950 0x10>;
+		gpio-controller;
+	};
+
+	CPM1_PIO_B: gpio-controller@ab8 {
+		#gpio-cells = <2>;
+		compatible = "fsl,cpm1-pario-bank-b";
+		reg = <0xab8 0x10>;
+		gpio-controller;
+	};
+
+	CPM1_PIO_E: gpio-controller@ac8 {
+		#gpio-cells = <2>;
+		compatible = "fsl,cpm1-pario-bank-e";
+		reg = <0xac8 0x18>;
+		gpio-controller;
+	};
-- 
1.5.6

^ permalink raw reply related

* Re: the printk problem
From: Denys Vlasenko @ 2008-07-05 10:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-ia64, Matthew Wilcox, linux-kernel, linuxppc-dev,
	Peter Anvin, Linus Torvalds, David S. Miller
In-Reply-To: <20080704150100.1f7b8a65.akpm@linux-foundation.org>

On Saturday 05 July 2008 00:01, Andrew Morton wrote:
> > > We also jump through hoops to print things like sector_t and
> > > resource_size_t.  They always need to be cast to `unsiged long long',
> > > which generates additional stack space and text in some setups.
> > 
> > The thing is that GCC checks types.  So it's fine to add "print this
> > pointer specially", but you can't in general add new printf arguments
> > without also hacking GCC.  Unless you use -Wno-format, and require
> > sparse to check special kernel types.
> 
> It would be excellent if gcc had an extension system so that you could
> add new printf control chars and maybe even tell gcc how to check them.
> But of course, if that were to happen, we couldn't use it for 4-5 years.
> 
> What I had initially proposed was to abuse %S, which takes a wchar_t*. 
> gcc accepts `unsigned long *' for %S.
> 
> Then, we put the kernel-specific control char after the S, so we can
> print an inode (rofl) with
> 
> 	struct inode *inode;
> 
> 	printk("here is an inode: %Si\n", (unsigned long *)inode);
> 
> Downsides are:
> 
> - there's a cast, so you could accidentally do
> 
> 	printk("here is an inode: %Si\n", (unsigned long *)dentry);
> 
> - there's a cast, and they're ugly
> 
> - gcc cannot of course check that the arg matches the control string
> 
> Unfortunately (and this seems weird), gcc printf checking will not
> accept a void* for %S: it _has_ to be wchar_t*, and the checker won't
> permit void* substitution for that.

Repeating myself here...
We can add an alternative alias to printk:

 asmlinkage int printk(const char * fmt, ...)
         __attribute__ ((format (printf, 1, 2))) __cold;
+asmlinkage int custom_printk(const char * fmt, ...) __cold asm ("printk");

custom_printk() is actually just printk(), that is,
we won't need additional function, we need to teach
*printk* about MAC addresses, NIPQUADs etc;

and then use printk() if you use only standard %fmt (and have it
checked by gcc), or use custom_printk() if you have non-standard
%fmt in the format string.

The only downside that in second case, you lose gcc checking.
No big deal.
--
vda

^ permalink raw reply

* Re: [PATCH] Add MPC5200B base board mvBC-P
From: André Schwarz @ 2008-07-05  9:32 UTC (permalink / raw)
  To: Grant Likely; +Cc: linux-ppc list
In-Reply-To: <20080704170041.GD17062@secretlab.ca>

[-- Attachment #1: Type: text/plain, Size: 6908 bytes --]

Grant,

thanks for the quick feedback - I'll try to improve.
Hopefully monday morning will be on time ....

Comments inline.

regards,
André

Grant Likely wrote:
> On Fri, Jul 04, 2008 at 06:35:39PM +0200, Andre Schwarz wrote:
>   
>> The mvBlueCOUGAR-P is a MPC5200B based camera system with Intel Gigabit ethernet
>> controller (using e1000). It's just another MPC5200_simple board.
>>
>> Signed-off-by: Andre Schwarz <andre.schwarz@matrix-vision.de>
>> ---
>>
>>
>> Grant,
>>
>> I don't know if there are any merge windows ...
>> If the patch should be modified or re-submitted on a later time please let me know.
>>     
>
> The merge window will be opening any day now.  If you address comments
> quickly then I should be able to merge it into 2.6.27
>
>   
great.
>>  arch/powerpc/boot/dts/mvbc-p.dts             |  206 +++++
>>  arch/powerpc/configs/mvbc-p_defconfig        | 1158 ++++++++++++++++++++++++++
>>     
> Rename this to arch/powerpc/config/52xx/mvbc_p_defconfig (use platform
> specific defconfig dir and don't mix '-' and '_' in filenames).
>
>   
ok - no problem.
>> diff --git a/arch/powerpc/boot/dts/mvbc-p.dts b/arch/powerpc/boot/dts/mvbc-p.dts
>> new file mode 100644
>> index 0000000..90a2808
>> --- /dev/null
>> +++ b/arch/powerpc/boot/dts/mvbc-p.dts
>> @@ -0,0 +1,206 @@
>> +/*
>> + * mvBlueCOUGAR-P device tree source
>> + *
>> + * Copyright (C) 2008 Matrix Vision GmbH
>> + * Andre Schwarz <andre.schwarz@matrix-vision.de>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License as published by the
>> + * Free Software Foundation; either version 2 of the License, or (at your
>> + * option) any later version.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +/ {
>> +	model = "matrix-vision,mvbc-p";
>> +	compatible = "matrix-vision,mvbc-p";
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +
>> +	cpus {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		PowerPC,5200@0 {
>> +			device_type = "cpu";
>> +			reg = <0>;
>> +			d-cache-line-size = <32>;
>> +			i-cache-line-size = <32>;
>> +			d-cache-size = <0x4000>;
>> +			i-cache-size = <0x4000>;
>> +			timebase-frequency = <0>;
>> +			bus-frequency = <0>;
>> +			clock-frequency = <0>;
>> +		};
>> +	};
>> +
>> +	memory {
>> +		device_type = "memory";
>> +		reg = <0x00000000 0x00000000>;
>> +	};
>> +
>> +	soc5200@f0000000 {
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		compatible = "fsl,mpc5200-immr";
>>     
>
> Does this board use the original 5200, or the 5200B?  If it uses the
> 5200B, then you should specify both fsl,mpc5200b-immr and
> fsl,mpc5200-immr.  Same goes for all other compatible properties in the
> tree; see lite5200b.dts for an example.
>
> I am toying with the option of eliminating the need for fsl,mpc5200b-*,
> but until then the conservative and safest thing to do is to claim
> compatibility with both.
>
>   
It's a MPC5200B. I thought that the "b"-Option has already out of use 
after reading about this a few weeks ago ... maybe I misinterpreted.
I'll fix this.
>> +	lpb {
>> +		compatible = "fsl,lpb";
>>     
>
> You should also claim compatibility with "simple-bus" here.
>
> ie:  compatible = "fsl,lpb", "simple-bus";
>
>   
ok.
>> +		#address-cells = <2>;
>> +		#size-cells = <1>;
>> +		ranges = <0x0 0x0 0xff800000 0x00800000>;
>> +		flash@0,0 {
>> +			compatible = "cfi-flash";
>>     
>
> For completeness, it is good practice for the first entry in the compatible
> list to be the actual flash chip, followed by "cfi-flash"
>
>   
ok.
>> +			reg = <0 0 0x800000>;
>> +			#address-cells = <1>;
>> +			#size-cells = <1>;
>> +			bank-width = <1>;
>> +			device-width = <1>;
>> +			nor_total@0x0 {
>> +				reg = <0x0 0x800000>;
>> +			};
>>     
>
> I don't know if this is legal; to have overlapping flash sections (but
> I'm not a cfi-flash binding expert).
>
>   
Hopefully this is still possible. Nested mtd partitions have always been 
possible, e.g. embedded environment inside u-boot partition.
It's proven very useful to have access to the whole chip - so it's 
possible to make binary updates even with the partition layout changing ....
I'd really like to stick to it if you don't mind.
>> +			u-boot@0x0 {
>> +				reg = <0x0 0x40000>;
>> +			};
>> +			u-boot_autoscript@0x40000 {
>> +				reg = <0x40000 0x10000>;
>> +			};
>> +			u-boot_autoscript_red@0x50000 {
>> +				reg = <0x50000 0x10000>;
>> +			};
>> +			fpga@0x60000 {
>> +				reg = <0x60000 0x40000>;
>> +			};
>> +			user@0xa0000 {
>> +				reg = <0xa00000 0x60000>;
>> +			};
>> +			rfs@0x100000 {
>> +				reg = <0x100000 0x300000>;
>> +			};
>> +			kernel@0x400000 {
>> +				reg = <0x400000 0x3c0000>;
>> +			};
>> +			dtb@0x7c0000 {
>> +				reg = <0x7c0000 0x10000>;
>> +			};
>> +			dtb@0x7d0000 {
>> +				reg = <0x7d0000 0x10000>;
>> +			};
>> +			ppcboot_env@0x7e0000 {
>> +				reg = <0x7e0000 0x10000>;
>> +			};
>> +			ppcboot_env@0x7f0000 {
>> +				reg = <0x7f0000 0x10000>;
>> +			};
>>     
>
> I think it would be better to just leave out the partition information
> and modify U-Boot to fill them in (just like memory and clock speed are
> left out).  Things like flash partitions are less like hardware
> description and more like configuration data.
>
>   
never did this. Is it quick'n'easy ?
Honestly I don't like the bootloader to set up everything.
If you need any change it will require a bootloader update which is a 
very fragile operation out in the field.
There will always be bricked systems afterwards ....
Failure in updating the (redundant) dtb blob or kernel will do almost 
always no harm since the system is still accessible and flashable using 
ethernet or serial.

If it's not against all rule (which I don't think) I'd really like to 
stick to it, too.
Is this ok ?
>> +		};
>> +	};
>> +
>> +	pci: pci@0xf0000d00 {
>> +		#interrupt-cells = <1>;
>> +		#size-cells = <2>;
>> +		#address-cells = <3>;
>> +		device_type = "pci";
>> +		compatible = "fsl,mpc5200-pci";
>> +		reg = <0xf0000d00 0x100>;
>> +		interrupt-map-mask = <0xf800 0 0 7>;
>> +		interrupt-map = <0x5800 0 0 1 &mpc5200_pic 1 2 3
>> +			0x5000 0 0 1 &mpc5200_pic 1 3 3>;
>> +		clock-frequency = <0>;
>> +		interrupts = <2 8 0 2 9 0 2 10 0>;
>> +		interrupt-parent = <&mpc5200_pic>;
>> +		bus-range = <0 0>;
>> +		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
>> +			0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
>> +			0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
>> +	};
>> +};
>>     



MATRIX VISION GmbH, Talstraße 16, DE-71570 Oppenweiler  - Registergericht: Amtsgericht Stuttgart, HRB 271090
Geschäftsführer: Gerhard Thullner, Werner Armingeon, Uwe Furtner

[-- Attachment #2: Type: text/html, Size: 8586 bytes --]

^ permalink raw reply

* [PATCH v3] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Grant Erickson @ 2008-07-05  9:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: sr
In-Reply-To: <C48F0E18.101F1%gerickson@nuovations.com>

Various instances of the EMAC core have varying: 1) number of address 
match slots, 2) width of the registers for handling address match slots, 
3) number of registers for handling address match slots and 4) base 
offset for those registers.

As the driver stands today, it assumes that all EMACs have 4 IAHT and 
GAHT 32-bit registers, starting at offset 0x30 from the register base, 
with only 16-bits of each used for a total of 64 match slots.

The 405EX(r) and 460EX now use the EMAC4SYNC core rather than the EMAC4 
core. This core has 8 IAHT and GAHT registers, starting at offset 0x80 
from the register base, with ALL 32-bits of each used for a total of 
256 match slots.

This adds a new compatible device tree entry "emac4sync" and a new,
related feature flag "EMAC_FTR_EMAC4SYNC" along with a series of macros
and inlines which supply the appropriate parameterized value based on
the presence or absence of the EMAC4SYNC feature.

The code has further been reworked where appropriate to use those macros
and inlines.

In addition, the register size passed to ioremap is now taken from the 
device tree:

	c0 for EMAC4SYNC cores
	74 for EMAC4 cores
	70 for EMAC cores

rather than sizeof (emac_regs).

Finally, the device trees have been updated with the appropriate compatible
entries and resource sizes.

This has been tested on an AMCC Haleakala board such that: 1) inbound 
ICMP requests to 'haleakala.local' via MDNS from both Mac OS X 10.4.11 
and Ubuntu 8.04 systems as well as 2) outbound ICMP requests from 
'haleakala.local' to those same systems in the '.local' domain via MDNS 
now work.

Signed-off-by: Grant Erickson <gerickson@nuovations.com>
---
 arch/powerpc/boot/dts/canyonlands.dts |    8 ++--
 arch/powerpc/boot/dts/glacier.dts     |    8 ++--
 arch/powerpc/boot/dts/haleakala.dts   |    4 +-
 arch/powerpc/boot/dts/katmai.dts      |    2 +-
 arch/powerpc/boot/dts/kilauea.dts     |    8 ++--
 arch/powerpc/boot/dts/makalu.dts      |    8 ++--
 arch/powerpc/boot/dts/rainier.dts     |    4 +-
 arch/powerpc/boot/dts/sequoia.dts     |    4 +-
 arch/powerpc/boot/dts/taishan.dts     |    8 ++--
 drivers/net/ibm_newemac/core.c        |   60 +++++++++++++++++-------
 drivers/net/ibm_newemac/core.h        |   83 ++++++++++++++++++++++++++++++++-
 drivers/net/ibm_newemac/debug.c       |   32 ++++++++-----
 drivers/net/ibm_newemac/emac.h        |   15 +------
 13 files changed, 172 insertions(+), 72 deletions(-)

diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 3963412..b2811ea 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -264,7 +264,7 @@
 
 			EMAC0: ethernet@ef600e00 {
 				device_type = "network";
-				compatible = "ibm,emac-460ex", "ibm,emac4";
+				compatible = "ibm,emac-460ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -272,7 +272,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 10 4
 						 /*Wake*/   1 &UIC2 14 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -293,7 +293,7 @@
 
 			EMAC1: ethernet@ef600f00 {
 				device_type = "network";
-				compatible = "ibm,emac-460ex", "ibm,emac4";
+				compatible = "ibm,emac-460ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -301,7 +301,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 11 4
 						 /*Wake*/   1 &UIC2 15 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts
index 0f2fc07..8ffde9b 100644
--- a/arch/powerpc/boot/dts/glacier.dts
+++ b/arch/powerpc/boot/dts/glacier.dts
@@ -281,7 +281,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 10 4
 						 /*Wake*/   1 &UIC2 14 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -310,7 +310,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 11 4
 						 /*Wake*/   1 &UIC2 15 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -340,7 +340,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 12 4
 						 /*Wake*/   1 &UIC2 16 4>;
-				reg = <ef601100 70>;
+				reg = <ef601100 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -368,7 +368,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 13 4
 						 /*Wake*/   1 &UIC2 17 4>;
-				reg = <ef601200 70>;
+				reg = <ef601200 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
index b5d95ac..0ae3e07 100644
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ b/arch/powerpc/boot/dts/haleakala.dts
@@ -204,7 +204,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405exr", "ibm,emac4";
+				compatible = "ibm,emac-405exr", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -212,7 +212,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index cc2873a..c91bb66 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -206,7 +206,7 @@
 				compatible = "ibm,emac-440spe", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1c 4 1d 4>;
-				reg = <10000800 70>;
+				reg = <10000800 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 48c9a6e..e6633a0 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -205,7 +205,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -213,7 +213,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -233,7 +233,7 @@
 			EMAC1: ethernet@ef600a00 {
 				linux,network-index = <1>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -241,7 +241,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600a00 70>;
+				reg = <ef600900 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts
index 84cc5e7..659b960 100644
--- a/arch/powerpc/boot/dts/makalu.dts
+++ b/arch/powerpc/boot/dts/makalu.dts
@@ -205,7 +205,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -213,7 +213,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -233,7 +233,7 @@
 			EMAC1: ethernet@ef600a00 {
 				linux,network-index = <1>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -241,7 +241,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600a00 70>;
+				reg = <ef600900 c0>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts
index 6a8fa70..026c22c 100644
--- a/arch/powerpc/boot/dts/rainier.dts
+++ b/arch/powerpc/boot/dts/rainier.dts
@@ -263,7 +263,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -292,7 +292,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index 72d6756..8d66c99 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -278,7 +278,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -307,7 +307,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts
index e808e1c..f736d87 100644
--- a/arch/powerpc/boot/dts/taishan.dts
+++ b/arch/powerpc/boot/dts/taishan.dts
@@ -258,7 +258,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1c 4 1d 4>;
-				reg = <40000800 70>;
+				reg = <40000800 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -278,7 +278,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1e 4 1f 4>;
-				reg = <40000900 70>;
+				reg = <40000900 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -298,7 +298,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC2>;
 				interrupts = <0 4 1 4>;
-				reg = <40000c00 70>;
+				reg = <40000c00 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -322,7 +322,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC2>;
 				interrupts = <2 4 3 4>;
-				reg = <40000e00 70>;
+				reg = <40000e00 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 5d2108c..931a061 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -363,25 +363,32 @@ static int emac_reset(struct emac_instance *dev)
 
 static void emac_hash_mc(struct emac_instance *dev)
 {
-	struct emac_regs __iomem *p = dev->emacp;
-	u16 gaht[4] = { 0 };
+	const int regs = EMAC_XAHT_REGS(dev);
+	u32 *gaht_base = emac_gaht_base(dev);
+	u32 gaht_temp[regs];
 	struct dev_mc_list *dmi;
+	int i;
 
 	DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count);
 
+	memset(gaht_temp, 0, sizeof (gaht_temp));
+
 	for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
-		int bit;
+		int slot, reg, mask;
 		DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
 		     dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
 		     dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
 
-		bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
-		gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+		slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
+		reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
+		mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot);
+
+		gaht_temp[reg] |= mask;
+	}
+
+	for (i = 0; i < regs; i++) {
+		out_be32(gaht_base + i, gaht_temp[i]);
 	}
-	out_be32(&p->gaht1, gaht[0]);
-	out_be32(&p->gaht2, gaht[1]);
-	out_be32(&p->gaht3, gaht[2]);
-	out_be32(&p->gaht4, gaht[3]);
 }
 
 static inline u32 emac_iff2rmr(struct net_device *ndev)
@@ -398,7 +405,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev)
 
 	if (ndev->flags & IFF_PROMISC)
 		r |= EMAC_RMR_PME;
-	else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
+	else if (ndev->flags & IFF_ALLMULTI ||
+			 (ndev->mc_count > EMAC_XAHT_SLOTS(dev)))
 		r |= EMAC_RMR_PMME;
 	else if (ndev->mc_count > 0)
 		r |= EMAC_RMR_MAE;
@@ -2015,10 +2023,10 @@ static int emac_get_regs_len(struct emac_instance *dev)
 {
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
 		return sizeof(struct emac_ethtool_regs_subhdr) +
-			EMAC4_ETHTOOL_REGS_SIZE;
+			EMAC4_ETHTOOL_REGS_SIZE(dev);
 	else
 		return sizeof(struct emac_ethtool_regs_subhdr) +
-			EMAC_ETHTOOL_REGS_SIZE;
+			EMAC_ETHTOOL_REGS_SIZE(dev);
 }
 
 static int emac_ethtool_get_regs_len(struct net_device *ndev)
@@ -2045,12 +2053,12 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf)
 	hdr->index = dev->cell_index;
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
 		hdr->version = EMAC4_ETHTOOL_REGS_VER;
-		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE);
-		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE);
+		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
+		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev));
 	} else {
 		hdr->version = EMAC_ETHTOOL_REGS_VER;
-		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
-		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
+		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
+		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev));
 	}
 }
 
@@ -2540,7 +2548,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 
 	/* Check EMAC version */
-	if (of_device_is_compatible(np, "ibm,emac4")) {
+	if (of_device_is_compatible(np, "ibm,emac4sync")) {
+		dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC);
+	} else if (of_device_is_compatible(np, "ibm,emac4")) {
 		dev->features |= EMAC_FTR_EMAC4;
 		if (of_device_is_compatible(np, "ibm,emac-440gx"))
 			dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
@@ -2601,6 +2611,15 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 	memcpy(dev->ndev->dev_addr, p, 6);
 
+	/* IAHT and GAHT filter parameterization */
+	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) {
+		dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT;
+		dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT;
+	} else {
+		dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT;
+		dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT;
+	}
+
 	DBG(dev, "features     : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE);
 	DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige);
 	DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige);
@@ -2672,7 +2691,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
 		goto err_irq_unmap;
 	}
 	// TODO : request_mem_region
-	dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs));
+	dev->emacp = ioremap(dev->rsrc_regs.start,
+						 dev->rsrc_regs.end - dev->rsrc_regs.start + 1);
 	if (dev->emacp == NULL) {
 		printk(KERN_ERR "%s: Can't map device registers!\n",
 		       np->full_name);
@@ -2884,6 +2904,10 @@ static struct of_device_id emac_match[] =
 		.type		= "network",
 		.compatible	= "ibm,emac4",
 	},
+	{
+		.type		= "network",
+		.compatible	= "ibm,emac4sync",
+	},
 	{},
 };
 
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 1683db9..312bfa5 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -235,6 +235,10 @@ struct emac_instance {
 	u32				fifo_entry_size;
 	u32				mal_burst_size; /* move to MAL ? */
 
+	/* IAHT and GAHT filter parameterization */
+	u32				xaht_slots_shift;
+	u32				xaht_width_shift;
+
 	/* Descriptor management
 	 */
 	struct mal_descriptor		*tx_desc;
@@ -309,6 +313,10 @@ struct emac_instance {
  * Set if we need phy clock workaround for 440ep or 440gr
  */
 #define EMAC_FTR_440EP_PHY_CLK_FIX	0x00000100
+/*
+ * The 405EX and 460EX contain the EMAC4SYNC core
+ */
+#define EMAC_FTR_EMAC4SYNC		0x00000200
 
 
 /* Right now, we don't quite handle the always/possible masks on the
@@ -320,7 +328,8 @@ enum {
 
 	EMAC_FTRS_POSSIBLE	=
 #ifdef CONFIG_IBM_NEW_EMAC_EMAC4
-	    EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
+	    EMAC_FTR_EMAC4	| EMAC_FTR_EMAC4SYNC	|
+	    EMAC_FTR_HAS_NEW_STACR	|
 	    EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
 #endif
 #ifdef CONFIG_IBM_NEW_EMAC_TAH
@@ -342,6 +351,71 @@ static inline int emac_has_feature(struct emac_instance *dev,
 	       (EMAC_FTRS_POSSIBLE & dev->features & feature);
 }
 
+/*
+ * Various instances of the EMAC core have varying 1) number of
+ * address match slots, 2) width of the registers for handling address
+ * match slots, 3) number of registers for handling address match
+ * slots and 4) base offset for those registers.
+ *
+ * These macros and inlines handle these differences based on
+ * parameters supplied by the device tree.
+ */
+
+#define	EMAC4_XAHT_SLOTS_SHIFT		6
+#define	EMAC4_XAHT_WIDTH_SHIFT		4
+#define	EMAC4_XAHT_BASE_OFFSET		0x30
+
+#define	EMAC4SYNC_XAHT_SLOTS_SHIFT	8
+#define	EMAC4SYNC_XAHT_WIDTH_SHIFT	5
+#define	EMAC4SYNC_XAHT_BASE_OFFSET	0x80
+
+
+#define	EMAC_XAHT_SLOTS(dev)         	(1 << (dev)->xaht_slots_shift)
+#define	EMAC_XAHT_WIDTH(dev)         	(1 << (dev)->xaht_width_shift)
+#define	EMAC_XAHT_REGS(dev)          	(1 << ((dev)->xaht_slots_shift - \
+					       (dev)->xaht_width_shift))
+
+#define	EMAC_XAHT_CRC_TO_SLOT(dev, crc)			\
+	((EMAC_XAHT_SLOTS(dev) - 1) -			\
+	 ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) -	\
+		    (dev)->xaht_slots_shift)))
+
+#define	EMAC_XAHT_SLOT_TO_REG(dev, slot)		\
+	((slot) >> (dev)->xaht_width_shift)
+
+#define	EMAC_XAHT_SLOT_TO_MASK(dev, slot)		\
+	((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >>	\
+	 ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1)))
+
+static inline u32 *emac_xaht_base(struct emac_instance *dev)
+{
+	struct emac_regs __iomem *p = dev->emacp;
+	int offset;
+
+	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC))
+	    offset = EMAC4SYNC_XAHT_BASE_OFFSET;
+	else
+	    offset = EMAC4_XAHT_BASE_OFFSET;
+
+	return ((u32 *)((ptrdiff_t)p + offset));
+}
+
+static inline u32 *emac_gaht_base(struct emac_instance *dev)
+{
+	/* GAHT registers always come after an identical number of
+	 * IAHT registers.
+	 */
+	return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev));
+}
+
+static inline u32 *emac_iaht_base(struct emac_instance *dev)
+{
+	/* IAHT registers always come before an identical number of
+	 * GAHT registers.
+	 */
+	return (emac_xaht_base(dev));
+}
+
 
 /* Ethtool get_regs complex data.
  * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
@@ -366,4 +440,11 @@ struct emac_ethtool_regs_subhdr {
 	u32 index;
 };
 
+#define EMAC_ETHTOOL_REGS_VER		0
+#define EMAC_ETHTOOL_REGS_SIZE(dev) 	((dev)->rsrc_regs.end - \
+					 (dev)->rsrc_regs.start + 1)
+#define EMAC4_ETHTOOL_REGS_VER      	1
+#define EMAC4_ETHTOOL_REGS_SIZE(dev)	((dev)->rsrc_regs.end -	\
+					 (dev)->rsrc_regs.start + 1)
+
 #endif /* __IBM_NEWEMAC_CORE_H */
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c
index 86b756a..d9fc0f4 100644
--- a/drivers/net/ibm_newemac/debug.c
+++ b/drivers/net/ibm_newemac/debug.c
@@ -67,29 +67,37 @@ static void emac_desc_dump(struct emac_instance *p)
 static void emac_mac_dump(struct emac_instance *dev)
 {
 	struct emac_regs __iomem *p = dev->emacp;
+	const int xaht_regs = EMAC_XAHT_REGS(dev);
+	u32 *gaht_base = emac_gaht_base(dev);
+	u32 *iaht_base = emac_iaht_base(dev);
+	int n;
 
 	printk("** EMAC %s registers **\n"
 	       "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
 	       "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
-	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
-	       "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
-	       "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
-	       "LSA = %04x%08x IPGVR = 0x%04x\n"
-	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
-	       "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
+	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n",
 	       dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1),
 	       in_be32(&p->tmr0), in_be32(&p->tmr1),
 	       in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
 	       in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
-	       in_be32(&p->vtci),
-	       in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
-	       in_be32(&p->iaht4),
-	       in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
-	       in_be32(&p->gaht4),
+	       in_be32(&p->vtci)
+		  );
+
+	for (n = 0; n < xaht_regs; n++) {
+		printk("IAHT%02d: 0x%08x\n", n + 1, in_be32(iaht_base + n));
+	}
+
+	for (n = 0; n < xaht_regs; n++) {
+		printk("GAHT%02d: 0x%08x\n", n + 1, in_be32(gaht_base + n));
+	}
+
+	printk("LSA = %04x%08x IPGVR = 0x%04x\n"
+	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
+	       "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
 	       in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
 	       in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
 	       in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
-	    );
+		  );
 
 	emac_desc_dump(dev);
 }
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h
index 91cb096..a4b5775 100644
--- a/drivers/net/ibm_newemac/emac.h
+++ b/drivers/net/ibm_newemac/emac.h
@@ -41,14 +41,7 @@ struct emac_regs {
 	u32 vtpid;		/* Reset, R, T 	*/
 	u32 vtci;		/* Reset, R, T 	*/
 	u32 ptr;		/* Reset,    T 	*/
-	u32 iaht1;		/* Reset, R	*/
-	u32 iaht2;		/* Reset, R	*/
-	u32 iaht3;		/* Reset, R	*/
-	u32 iaht4;		/* Reset, R	*/
-	u32 gaht1;		/* Reset, R	*/
-	u32 gaht2;		/* Reset, R	*/
-	u32 gaht3;		/* Reset, R	*/
-	u32 gaht4;		/* Reset, R	*/
+	u32 reserved[8];/* Chip-dependent */
 	u32 lsah;
 	u32 lsal;
 	u32 ipgvr;		/* Reset,    T 	*/
@@ -73,12 +66,6 @@ struct emac_regs {
 #define PHY_MODE_RTBI	7
 #define PHY_MODE_SGMII	8
 
-
-#define EMAC_ETHTOOL_REGS_VER		0
-#define EMAC_ETHTOOL_REGS_SIZE		(sizeof(struct emac_regs) - sizeof(u32))
-#define EMAC4_ETHTOOL_REGS_VER      	1
-#define EMAC4_ETHTOOL_REGS_SIZE		sizeof(struct emac_regs)
-
 /* EMACx_MR0 */
 #define EMAC_MR0_RXI			0x80000000
 #define EMAC_MR0_TXI			0x40000000

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox