* [PATCH v2] Parameterize EMAC Multicast Match Handling @ 2008-06-25 0:08 Grant Erickson 2008-07-01 5:26 ` Grant Erickson 0 siblings, 1 reply; 22+ messages in thread From: Grant Erickson @ 2008-06-25 0:08 UTC (permalink / raw) To: linuxppc-dev; +Cc: Stefan Roese 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 460 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 macros and inlines for handling these differences based on three parameters parsed from the device tree: xaht-slots-shift xaht-width-shift xaht-base-offset and reworks the code, where appropriate to use those macros and inlines. EMAC/EMAC4 values are defaulted for these keys if missing, resulting in a driver that works as today's does for all cores. 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 rathaer than sizeof (emac_regs). Finally, the device trees have been updated with the appropriate xaht-* keys and values. 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/bamboo.dts | 6 +++ arch/powerpc/boot/dts/canyonlands.dts | 10 ++++- arch/powerpc/boot/dts/ebony.dts | 6 +++ arch/powerpc/boot/dts/ep405.dts | 3 ++ arch/powerpc/boot/dts/glacier.dts | 20 +++++++++-- arch/powerpc/boot/dts/haleakala.dts | 5 ++- arch/powerpc/boot/dts/katmai.dts | 5 ++- arch/powerpc/boot/dts/kilauea.dts | 10 ++++- arch/powerpc/boot/dts/makalu.dts | 10 ++++- arch/powerpc/boot/dts/rainier.dts | 10 ++++- arch/powerpc/boot/dts/sequoia.dts | 10 ++++- arch/powerpc/boot/dts/taishan.dts | 20 +++++++++-- arch/powerpc/boot/dts/walnut.dts | 3 ++ arch/powerpc/boot/dts/warp.dts | 3 ++ drivers/net/ibm_newemac/core.c | 55 +++++++++++++++++++---------- drivers/net/ibm_newemac/core.h | 61 +++++++++++++++++++++++++++++++++ drivers/net/ibm_newemac/debug.c | 32 +++++++++++------ drivers/net/ibm_newemac/emac.h | 15 +------- 18 files changed, 219 insertions(+), 65 deletions(-) diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts index ba2521b..200a4ec 100644 --- a/arch/powerpc/boot/dts/bamboo.dts +++ b/arch/powerpc/boot/dts/bamboo.dts @@ -221,6 +221,9 @@ phy-map = <00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; EMAC1: ethernet@ef600f00 { @@ -241,6 +244,9 @@ phy-map = <00000000>; zmii-device = <&ZMII0>; zmii-channel = <1>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; usb@ef601000 { diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index 3963412..75ff768 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts @@ -272,7 +272,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>; @@ -287,6 +287,9 @@ rgmii-channel = <0>; tah-device = <&TAH0>; tah-channel = <0>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -301,7 +304,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>; @@ -316,6 +319,9 @@ rgmii-channel = <1>; tah-device = <&TAH1>; tah-channel = <1>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; mdio-device = <&EMAC0>; diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts index 5079dc8..3c68c1e 100644 --- a/arch/powerpc/boot/dts/ebony.dts +++ b/arch/powerpc/boot/dts/ebony.dts @@ -258,6 +258,9 @@ phy-map = <00000001>; zmii-device = <&ZMII0>; zmii-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; EMAC1: ethernet@40000900 { device_type = "network"; @@ -277,6 +280,9 @@ phy-map = <00000001>; zmii-device = <&ZMII0>; zmii-channel = <1>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; diff --git a/arch/powerpc/boot/dts/ep405.dts b/arch/powerpc/boot/dts/ep405.dts index 9293855..730a561 100644 --- a/arch/powerpc/boot/dts/ep405.dts +++ b/arch/powerpc/boot/dts/ep405.dts @@ -143,6 +143,9 @@ tx-fifo-size = <800>; phy-mode = "rmii"; phy-map = <00000000>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; }; diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts index 0f2fc07..c73bea1 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>; @@ -296,6 +296,9 @@ rgmii-channel = <0>; tah-device = <&TAH0>; tah-channel = <0>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -310,7 +313,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>; @@ -325,6 +328,9 @@ rgmii-channel = <1>; tah-device = <&TAH1>; tah-channel = <1>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; mdio-device = <&EMAC0>; @@ -340,7 +346,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>; @@ -353,6 +359,9 @@ phy-map = <00000000>; rgmii-device = <&RGMII1>; rgmii-channel = <0>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; mdio-device = <&EMAC0>; @@ -368,7 +377,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>; @@ -381,6 +390,9 @@ phy-map = <00000000>; rgmii-device = <&RGMII1>; rgmii-channel = <1>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; mdio-device = <&EMAC0>; diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index b5d95ac..7a1243b 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -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>; @@ -225,6 +225,9 @@ phy-map = <00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index cc2873a..cbe23bd 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>; @@ -217,6 +217,9 @@ tx-fifo-size = <800>; phy-mode = "gmii"; phy-map = <00000000>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; has-inverted-stacr-oc; has-new-stacr-staopc; }; diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts index 48c9a6e..2164d6c 100644 --- a/arch/powerpc/boot/dts/kilauea.dts +++ b/arch/powerpc/boot/dts/kilauea.dts @@ -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>; @@ -226,6 +226,9 @@ phy-map = <00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -241,7 +244,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>; @@ -254,6 +257,9 @@ phy-map = <00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts index 84cc5e7..8f97927 100644 --- a/arch/powerpc/boot/dts/makalu.dts +++ b/arch/powerpc/boot/dts/makalu.dts @@ -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>; @@ -226,6 +226,9 @@ phy-map = <0000003f>; /* Start at 6 */ rgmii-device = <&RGMII0>; rgmii-channel = <0>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -241,7 +244,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>; @@ -254,6 +257,9 @@ phy-map = <00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; + xaht-base-offset = <80>; + xaht-slots-shift = <8>; + xaht-width-shift = <5>; has-inverted-stacr-oc; has-new-stacr-staopc; }; diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts index 6a8fa70..422c969 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>; @@ -278,6 +278,9 @@ zmii-channel = <0>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -292,7 +295,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>; @@ -307,6 +310,9 @@ zmii-channel = <1>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; has-inverted-stacr-oc; has-new-stacr-staopc; }; diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts index 72d6756..cb52b3b 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>; @@ -293,6 +293,9 @@ zmii-channel = <0>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -307,7 +310,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>; @@ -322,6 +325,9 @@ zmii-channel = <1>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; has-inverted-stacr-oc; has-new-stacr-staopc; }; diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts index e808e1c..872d7b7 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>; @@ -271,6 +271,9 @@ phy-map = <00000001>; zmii-device = <&ZMII0>; zmii-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; EMAC1: ethernet@40000900 { unused = <1>; @@ -278,7 +281,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>; @@ -291,6 +294,9 @@ phy-map = <00000001>; zmii-device = <&ZMII0>; zmii-channel = <1>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; EMAC2: ethernet@40000c00 { @@ -298,7 +304,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>; @@ -315,6 +321,9 @@ zmii-channel = <2>; tah-device = <&TAH0>; tah-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; EMAC3: ethernet@40000e00 { @@ -322,7 +331,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>; @@ -339,6 +348,9 @@ zmii-channel = <3>; tah-device = <&TAH1>; tah-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; diff --git a/arch/powerpc/boot/dts/walnut.dts b/arch/powerpc/boot/dts/walnut.dts index a328607..eb7e776 100644 --- a/arch/powerpc/boot/dts/walnut.dts +++ b/arch/powerpc/boot/dts/walnut.dts @@ -142,6 +142,9 @@ tx-fifo-size = <800>; phy-mode = "rmii"; phy-map = <00000001>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; }; diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index b04a52e..a4c3dfb 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts @@ -221,6 +221,9 @@ phy-map = <00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; + xaht-base-offset = <30>; + xaht-slots-shift = <6>; + xaht-width-shift = <4>; }; usb@ef601000 { diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 5d2108c..99d582a 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)); } } @@ -2520,6 +2528,14 @@ static int __devinit emac_init_config(struct emac_instance *dev) if (emac_read_uint_prop(np, "mal-burst-size", &dev->mal_burst_size, 0)) dev->mal_burst_size = 256; + /* IAHT and GAHT filter parameterization */ + if (emac_read_uint_prop(np, "xaht-base-offset", &dev->xaht_base_offset, 0)) + dev->xaht_base_offset = EMAC4_XAHT_BASE_OFFSET_DEFAULT; + if (emac_read_uint_prop(np, "xaht-slots-shift", &dev->xaht_slots_shift, 0)) + dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT_DEFAULT; + if (emac_read_uint_prop(np, "xaht-width-shift", &dev->xaht_width_shift, 0)) + dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT_DEFAULT; + /* PHY mode needs some decoding */ dev->phy_mode = PHY_MODE_NA; pm = of_get_property(np, "phy-mode", &plen); @@ -2672,7 +2688,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); diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 1683db9..e4087fb 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -235,6 +235,11 @@ struct emac_instance { u32 fifo_entry_size; u32 mal_burst_size; /* move to MAL ? */ + /* IAHT and GAHT filter parameterization */ + u32 xaht_base_offset; + u32 xaht_slots_shift; + u32 xaht_width_shift; + /* Descriptor management */ struct mal_descriptor *tx_desc; @@ -342,6 +347,55 @@ 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_DEFAULT 6 +#define EMAC4_XAHT_WIDTH_SHIFT_DEFAULT 4 +#define EMAC4_XAHT_BASE_OFFSET_DEFAULT 0x30 + +#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; + + return ((u32 *)((ptrdiff_t)p + dev->xaht_base_offset)); +} + +static inline u32 *emac_gaht_base(struct emac_instance *dev) +{ + /* GAHT registers always follow 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 are always come before 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 +420,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 [flat|nested] 22+ messages in thread
* Re: [PATCH v2] Parameterize EMAC Multicast Match Handling 2008-06-25 0:08 [PATCH v2] Parameterize EMAC Multicast Match Handling Grant Erickson @ 2008-07-01 5:26 ` Grant Erickson 2008-07-01 6:14 ` Benjamin Herrenschmidt 2008-07-05 9:18 ` [PATCH v3] ibm_newemac: " Grant Erickson 0 siblings, 2 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-01 5:26 UTC (permalink / raw) To: Stefan Roese, Benjamin Herrenschmidt; +Cc: linuxppc-dev On 6/24/08 5:08 PM, Grant Erickson wrote: > 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 460 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 macros and inlines for handling these differences based on > three parameters parsed from the device tree: > > xaht-slots-shift > xaht-width-shift > xaht-base-offset > > and reworks the code, where appropriate to use those macros and inlines. > EMAC/EMAC4 values are defaulted for these keys if missing, resulting in > a driver that works as today's does for all cores. > > 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 > > rathaer than sizeof (emac_regs). > > Finally, the device trees have been updated with the appropriate xaht-* > keys and values. > > 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/bamboo.dts | 6 +++ > arch/powerpc/boot/dts/canyonlands.dts | 10 ++++- > arch/powerpc/boot/dts/ebony.dts | 6 +++ > arch/powerpc/boot/dts/ep405.dts | 3 ++ > arch/powerpc/boot/dts/glacier.dts | 20 +++++++++-- > arch/powerpc/boot/dts/haleakala.dts | 5 ++- > arch/powerpc/boot/dts/katmai.dts | 5 ++- > arch/powerpc/boot/dts/kilauea.dts | 10 ++++- > arch/powerpc/boot/dts/makalu.dts | 10 ++++- > arch/powerpc/boot/dts/rainier.dts | 10 ++++- > arch/powerpc/boot/dts/sequoia.dts | 10 ++++- > arch/powerpc/boot/dts/taishan.dts | 20 +++++++++-- > arch/powerpc/boot/dts/walnut.dts | 3 ++ > arch/powerpc/boot/dts/warp.dts | 3 ++ > drivers/net/ibm_newemac/core.c | 55 +++++++++++++++++++---------- > drivers/net/ibm_newemac/core.h | 61 > +++++++++++++++++++++++++++++++++ > drivers/net/ibm_newemac/debug.c | 32 +++++++++++------ > drivers/net/ibm_newemac/emac.h | 15 +------- > 18 files changed, 219 insertions(+), 65 deletions(-) Stefan and/or Ben: Any thoughts on this? Regards, Grant ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] Parameterize EMAC Multicast Match Handling 2008-07-01 5:26 ` Grant Erickson @ 2008-07-01 6:14 ` Benjamin Herrenschmidt 2008-07-01 6:37 ` Stefan Roese 2008-07-05 9:18 ` [PATCH v3] ibm_newemac: " Grant Erickson 1 sibling, 1 reply; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-01 6:14 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev, Stefan Roese > Stefan and/or Ben: > > Any thoughts on this? I was hesitating a bit... do we really need to be -that- flexible ? That is, either that or use some new compatible entry to detect the new reg layout and whack that as a feature bit instead ? The advantage of the later is that we have the possibility of doing conditional compile for kernels that support only a given processor or set of processors (not that we have implemented much of it, but it just becomes Kconfig mumbo jumbo and a little bit of defines in the .h by turning the feature test into a compile-time 0 or 1. But this isn't a hot path and not a lot of code so maybe not worth bothering... however, it does add 3 properties to the DT and I know embedded people (especially Xilinx) are a bit concerned about the size of the DT when they try to fit it in block RAM... Cheers, Ben. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] Parameterize EMAC Multicast Match Handling 2008-07-01 6:14 ` Benjamin Herrenschmidt @ 2008-07-01 6:37 ` Stefan Roese 2008-07-01 18:13 ` Grant Erickson 0 siblings, 1 reply; 22+ messages in thread From: Stefan Roese @ 2008-07-01 6:37 UTC (permalink / raw) To: benh; +Cc: linuxppc-dev, Grant Erickson On Tuesday 01 July 2008, Benjamin Herrenschmidt wrote: > > Stefan and/or Ben: > > > > Any thoughts on this? > > I was hesitating a bit... do we really need to be -that- flexible ? > > That is, either that or use some new compatible entry to detect the new > reg layout and whack that as a feature bit instead ? The advantage > of the later is that we have the possibility of doing conditional > compile for kernels that support only a given processor or set of > processors (not that we have implemented much of it, but it just > becomes Kconfig mumbo jumbo and a little bit of defines in the .h > by turning the feature test into a compile-time 0 or 1. > > But this isn't a hot path and not a lot of code so maybe not worth > bothering... however, it does add 3 properties to the DT and I know > embedded people (especially Xilinx) are a bit concerned about the size > of the DT when they try to fit it in block RAM... Yes, this was my feeling too. Not the size of the dtb but more the increased complexity of the EMAC device node. I would prefer Ben's idea with this new compatible entry too. Best regards, Stefan ===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de ===================================================================== ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] Parameterize EMAC Multicast Match Handling 2008-07-01 6:37 ` Stefan Roese @ 2008-07-01 18:13 ` Grant Erickson 2008-07-01 19:42 ` Stefan Roese 2008-07-01 23:52 ` Benjamin Herrenschmidt 0 siblings, 2 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-01 18:13 UTC (permalink / raw) To: Stefan Roese, benh; +Cc: linuxppc-dev On 6/30/08 11:37 PM, Stefan Roese wrote: > On Tuesday 01 July 2008, Benjamin Herrenschmidt wrote: >>> Stefan and/or Ben: >>> >>> Any thoughts on this? >> >> I was hesitating a bit... do we really need to be -that- flexible ? >> >> That is, either that or use some new compatible entry to detect the new >> reg layout and whack that as a feature bit instead ? The advantage >> of the later is that we have the possibility of doing conditional >> compile for kernels that support only a given processor or set of >> processors (not that we have implemented much of it, but it just >> becomes Kconfig mumbo jumbo and a little bit of defines in the .h >> by turning the feature test into a compile-time 0 or 1. >> >> But this isn't a hot path and not a lot of code so maybe not worth >> bothering... however, it does add 3 properties to the DT and I know >> embedded people (especially Xilinx) are a bit concerned about the size >> of the DT when they try to fit it in block RAM... > > Yes, this was my feeling too. Not the size of the dtb but more the increased > complexity of the EMAC device node. I would prefer Ben's idea with this new > compatible entry too. In terms of the device tree expression, you would both favor something akin to the following? - compatible = "ibm,emac-405exr", "ibm,emac4"; + compatible = "ibm,emac-405exr", "ibm,emac4", "ibm,emac4sync"; Regards, Grant ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] Parameterize EMAC Multicast Match Handling 2008-07-01 18:13 ` Grant Erickson @ 2008-07-01 19:42 ` Stefan Roese 2008-07-01 23:52 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 22+ messages in thread From: Stefan Roese @ 2008-07-01 19:42 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev On Tuesday 01 July 2008, Grant Erickson wrote: > > Yes, this was my feeling too. Not the size of the dtb but more the > > increased complexity of the EMAC device node. I would prefer Ben's idea > > with this new compatible entry too. > > In terms of the device tree expression, you would both favor something akin > to the following? > > - compatible = "ibm,emac-405exr", "ibm,emac4"; > + compatible = "ibm,emac-405exr", "ibm,emac4", > "ibm,emac4sync"; If this is how IBM/AMCC call this "new" EMAC version, then yes. Best regards, Stefan ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] Parameterize EMAC Multicast Match Handling 2008-07-01 18:13 ` Grant Erickson 2008-07-01 19:42 ` Stefan Roese @ 2008-07-01 23:52 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-01 23:52 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev, Stefan Roese On Tue, 2008-07-01 at 11:13 -0700, Grant Erickson wrote: > In terms of the device tree expression, you would both favor something akin > to the following? > > - compatible = "ibm,emac-405exr", "ibm,emac4"; > + compatible = "ibm,emac-405exr", "ibm,emac4", "ibm,emac4sync"; leave ibm,emac4 either at the end or totally out Cheers, Ben. ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-01 5:26 ` Grant Erickson 2008-07-01 6:14 ` Benjamin Herrenschmidt @ 2008-07-05 9:18 ` Grant Erickson 2008-07-05 22:45 ` Benjamin Herrenschmidt 2008-07-06 0:15 ` [PATCH v4] " Grant Erickson 1 sibling, 2 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-05 9:18 UTC (permalink / raw) To: linuxppc-dev; +Cc: sr 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 [flat|nested] 22+ messages in thread
* Re: [PATCH v3] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-05 9:18 ` [PATCH v3] ibm_newemac: " Grant Erickson @ 2008-07-05 22:45 ` Benjamin Herrenschmidt 2008-07-06 0:15 ` [PATCH v4] " Grant Erickson 1 sibling, 0 replies; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-05 22:45 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev, sr 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 [flat|nested] 22+ messages in thread
* [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-05 9:18 ` [PATCH v3] ibm_newemac: " Grant Erickson 2008-07-05 22:45 ` Benjamin Herrenschmidt @ 2008-07-06 0:15 ` Grant Erickson 2008-07-06 0:31 ` Benjamin Herrenschmidt ` (2 more replies) 1 sibling, 3 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-06 0:15 UTC (permalink / raw) To: linuxppc-dev; +Cc: sr 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 [flat|nested] 22+ messages in thread
* Re: [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 0:15 ` [PATCH v4] " Grant Erickson @ 2008-07-06 0:31 ` Benjamin Herrenschmidt 2008-07-06 9:43 ` Stefan Roese 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson 2 siblings, 0 replies; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-06 0:31 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev, sr 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 [flat|nested] 22+ messages in thread
* Re: [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 0:15 ` [PATCH v4] " Grant Erickson 2008-07-06 0:31 ` Benjamin Herrenschmidt @ 2008-07-06 9:43 ` Stefan Roese 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson 2 siblings, 0 replies; 22+ messages in thread From: Stefan Roese @ 2008-07-06 9:43 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev On Sunday 06 July 2008, Grant Erickson wrote: > 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. Thanks Grant. Apart from Ben's comments I only have a few nitpicking comment. Please see below. <snip> > 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]); > } No parentheses on single line statements. > - 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); Indentation above seems incorrect. > 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; Indentation with 4 spaces instead of one tab above "offset =" (twice). Thanks. BTW: You should send those ibm_newemac related patches to the netdev list too. Best regards, Stefan ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 0:15 ` [PATCH v4] " Grant Erickson 2008-07-06 0:31 ` Benjamin Herrenschmidt 2008-07-06 9:43 ` Stefan Roese @ 2008-07-06 23:30 ` Grant Erickson 2008-07-07 5:58 ` Stefan Roese ` (3 more replies) 2 siblings, 4 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-06 23:30 UTC (permalink / raw) To: linuxppc-dev; +Cc: sr 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 | 61 ++++++++++++++------ drivers/net/ibm_newemac/core.h | 83 ++++++++++++++++++++++++++- drivers/net/ibm_newemac/debug.c | 52 +++++++++++++---- drivers/net/ibm_newemac/emac.h | 101 ++++++++++++++++++++++---------- 13 files changed, 259 insertions(+), 92 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..ed24a1d 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -363,25 +363,31 @@ 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; } - out_be32(&p->gaht1, gaht[0]); - out_be32(&p->gaht2, gaht[1]); - out_be32(&p->gaht3, gaht[2]); - out_be32(&p->gaht4, gaht[3]); + + for (i = 0; i < regs; i++) + out_be32(gaht_base + i, gaht_temp[i]); } static inline u32 emac_iff2rmr(struct net_device *ndev) @@ -398,7 +404,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; @@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev) /* Put some arbitrary OUI, Manuf & Rev IDs so we can * identify this GPCS PHY later. */ - out_be32(&p->ipcr, 0xdeadbeef); + out_be32(&p->u1.emac4.ipcr, 0xdeadbeef); } else mr1 |= EMAC_MR1_MF_1000; @@ -2015,10 +2022,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 +2052,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 +2547,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 +2610,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 +2690,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 +2903,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..70794cd 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 structure which are, in turn, + * initialized based on the "compatible" entry in the device tree. + */ + +#define EMAC4_XAHT_SLOTS_SHIFT 6 +#define EMAC4_XAHT_WIDTH_SHIFT 4 + +#define EMAC4SYNC_XAHT_SLOTS_SHIFT 8 +#define EMAC4SYNC_XAHT_WIDTH_SHIFT 5 + +#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; + + /* The first IAHT entry always is the base of the block of + * IAHT and GAHT registers. + */ + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) + offset = offsetof(struct emac_regs, u1.emac4sync.iaht1); + else + offset = offsetof(struct emac_regs, u0.emac4.iaht1); + + 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..775c850 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c @@ -67,29 +67,55 @@ 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 emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC); + 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) + ); + + if (emac4sync) + printk("MAR = %04x%08x MMAR = %04x%08x\n", + in_be32(&p->u0.emac4sync.mahr), + in_be32(&p->u0.emac4sync.malr), + in_be32(&p->u0.emac4sync.mmahr), + in_be32(&p->u0.emac4sync.mmalr) + ); + + 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\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) - ); + in_be32(&p->octx), in_be32(&p->ocrx) + ); + + if (!emac4sync) { + printk("IPCR = 0x%08x\n", + in_be32(&p->u1.emac4.ipcr) + ); + } else { + printk("REVID = 0x%08x TPC = 0x%08x\n", + in_be32(&p->u1.emac4sync.revid), + in_be32(&p->u1.emac4sync.tpc) + ); + } emac_desc_dump(dev); } diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index 91cb096..0afc2cf 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h @@ -27,37 +27,80 @@ #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 */ + /* Common registers across all EMAC implementations. */ + 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 */ + } emac4; + /* 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]; + } emac4sync; + } u0; + /* Common registers across all EMAC implementations. */ u32 lsah; u32 lsal; - u32 ipgvr; /* Reset, T */ - u32 stacr; /* special */ - u32 trtr; /* special */ - u32 rwmr; /* Reset */ + u32 ipgvr; /* Reset, T */ + u32 stacr; /* Special */ + u32 trtr; /* Special */ + u32 rwmr; /* Reset */ u32 octx; u32 ocrx; - u32 ipcr; + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 ipcr; + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 rsvd1; + u32 revid; + u32 rsvd2[2]; + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 iaht5; /* Reset, R */ + u32 iaht6; /* Reset, R */ + u32 iaht7; /* Reset, R */ + u32 iaht8; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + u32 gaht5; /* Reset, R */ + u32 gaht6; /* Reset, R */ + u32 gaht7; /* Reset, R */ + u32 gaht8; /* Reset, R */ + u32 tpc; /* Reset, T */ + } emac4sync; + } u1; }; /* @@ -73,12 +116,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 [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson @ 2008-07-07 5:58 ` Stefan Roese 2008-07-07 6:00 ` Benjamin Herrenschmidt 2008-07-07 6:18 ` Benjamin Herrenschmidt ` (2 subsequent siblings) 3 siblings, 1 reply; 22+ messages in thread From: Stefan Roese @ 2008-07-07 5:58 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev On Monday 07 July 2008, Grant Erickson wrote: > 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. <snip> > Signed-off-by: Grant Erickson <gerickson@nuovations.com> Acked-by: Stefan Roese <sr@denx.de> Best regards, Stefan ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-07 5:58 ` Stefan Roese @ 2008-07-07 6:00 ` Benjamin Herrenschmidt 2008-07-07 6:29 ` Stefan Roese 0 siblings, 1 reply; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-07 6:00 UTC (permalink / raw) To: Stefan Roese; +Cc: linuxppc-dev, Grant Erickson On Mon, 2008-07-07 at 07:58 +0200, Stefan Roese wrote: > On Monday 07 July 2008, Grant Erickson wrote: > > 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. > > <snip> > > > Signed-off-by: Grant Erickson <gerickson@nuovations.com> > > Acked-by: Stefan Roese <sr@denx.de> Did you have a chance to do a bit of regression testing "just in case" ? Appart from that, I'll sort out with Jeff which tree this will go through. Cheers, Ben. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-07 6:00 ` Benjamin Herrenschmidt @ 2008-07-07 6:29 ` Stefan Roese 2008-07-07 6:43 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 22+ messages in thread From: Stefan Roese @ 2008-07-07 6:29 UTC (permalink / raw) To: linuxppc-dev, benh; +Cc: Grant Erickson On Monday 07 July 2008, Benjamin Herrenschmidt wrote: > On Mon, 2008-07-07 at 07:58 +0200, Stefan Roese wrote: > > On Monday 07 July 2008, Grant Erickson wrote: > > > 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. > > > > <snip> > > > > > Signed-off-by: Grant Erickson <gerickson@nuovations.com> > > > > Acked-by: Stefan Roese <sr@denx.de> > > Did you have a chance to do a bit of regression testing "just in case" ? No, not yet. I'll try to do some tests this week. Best regards, Stefan ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-07 6:29 ` Stefan Roese @ 2008-07-07 6:43 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-07 6:43 UTC (permalink / raw) To: Stefan Roese; +Cc: linuxppc-dev, Grant Erickson On Mon, 2008-07-07 at 08:29 +0200, Stefan Roese wrote: > > Did you have a chance to do a bit of regression testing "just in case" ? > > No, not yet. I'll try to do some tests this week. Thanks ! Cheers, Ben. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson 2008-07-07 5:58 ` Stefan Roese @ 2008-07-07 6:18 ` Benjamin Herrenschmidt 2008-07-07 13:59 ` Jeff Garzik 2008-07-07 19:50 ` Valentine Barshak 2008-07-07 22:03 ` [PATCH v6] " Grant Erickson 3 siblings, 1 reply; 22+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-07 6:18 UTC (permalink / raw) To: Jeff Garzik; +Cc: linuxppc-dev, sr, Grant Erickson Hi Jeff ! If you are ok with this patch, I'll take it through the powerpc tree since it changes all those device tree files. Cheers, Ben. On Sun, 2008-07-06 at 16:30 -0700, Grant Erickson wrote: > 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 | 61 ++++++++++++++------ > drivers/net/ibm_newemac/core.h | 83 ++++++++++++++++++++++++++- > drivers/net/ibm_newemac/debug.c | 52 +++++++++++++---- > drivers/net/ibm_newemac/emac.h | 101 ++++++++++++++++++++++---------- > 13 files changed, 259 insertions(+), 92 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..ed24a1d 100644 > --- a/drivers/net/ibm_newemac/core.c > +++ b/drivers/net/ibm_newemac/core.c > @@ -363,25 +363,31 @@ 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; > } > - out_be32(&p->gaht1, gaht[0]); > - out_be32(&p->gaht2, gaht[1]); > - out_be32(&p->gaht3, gaht[2]); > - out_be32(&p->gaht4, gaht[3]); > + > + for (i = 0; i < regs; i++) > + out_be32(gaht_base + i, gaht_temp[i]); > } > > static inline u32 emac_iff2rmr(struct net_device *ndev) > @@ -398,7 +404,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; > @@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev) > /* Put some arbitrary OUI, Manuf & Rev IDs so we can > * identify this GPCS PHY later. > */ > - out_be32(&p->ipcr, 0xdeadbeef); > + out_be32(&p->u1.emac4.ipcr, 0xdeadbeef); > } else > mr1 |= EMAC_MR1_MF_1000; > > @@ -2015,10 +2022,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 +2052,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 +2547,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 +2610,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 +2690,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 +2903,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..70794cd 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 structure which are, in turn, > + * initialized based on the "compatible" entry in the device tree. > + */ > + > +#define EMAC4_XAHT_SLOTS_SHIFT 6 > +#define EMAC4_XAHT_WIDTH_SHIFT 4 > + > +#define EMAC4SYNC_XAHT_SLOTS_SHIFT 8 > +#define EMAC4SYNC_XAHT_WIDTH_SHIFT 5 > + > +#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; > + > + /* The first IAHT entry always is the base of the block of > + * IAHT and GAHT registers. > + */ > + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) > + offset = offsetof(struct emac_regs, u1.emac4sync.iaht1); > + else > + offset = offsetof(struct emac_regs, u0.emac4.iaht1); > + > + 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..775c850 100644 > --- a/drivers/net/ibm_newemac/debug.c > +++ b/drivers/net/ibm_newemac/debug.c > @@ -67,29 +67,55 @@ 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 emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC); > + 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) > + ); > + > + if (emac4sync) > + printk("MAR = %04x%08x MMAR = %04x%08x\n", > + in_be32(&p->u0.emac4sync.mahr), > + in_be32(&p->u0.emac4sync.malr), > + in_be32(&p->u0.emac4sync.mmahr), > + in_be32(&p->u0.emac4sync.mmalr) > + ); > + > + 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\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) > - ); > + in_be32(&p->octx), in_be32(&p->ocrx) > + ); > + > + if (!emac4sync) { > + printk("IPCR = 0x%08x\n", > + in_be32(&p->u1.emac4.ipcr) > + ); > + } else { > + printk("REVID = 0x%08x TPC = 0x%08x\n", > + in_be32(&p->u1.emac4sync.revid), > + in_be32(&p->u1.emac4sync.tpc) > + ); > + } > > emac_desc_dump(dev); > } > diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h > index 91cb096..0afc2cf 100644 > --- a/drivers/net/ibm_newemac/emac.h > +++ b/drivers/net/ibm_newemac/emac.h > @@ -27,37 +27,80 @@ > > #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 */ > + /* Common registers across all EMAC implementations. */ > + 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 */ > + } emac4; > + /* 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]; > + } emac4sync; > + } u0; > + /* Common registers across all EMAC implementations. */ > u32 lsah; > u32 lsal; > - u32 ipgvr; /* Reset, T */ > - u32 stacr; /* special */ > - u32 trtr; /* special */ > - u32 rwmr; /* Reset */ > + u32 ipgvr; /* Reset, T */ > + u32 stacr; /* Special */ > + u32 trtr; /* Special */ > + u32 rwmr; /* Reset */ > u32 octx; > u32 ocrx; > - u32 ipcr; > + union { > + /* Registers unique to EMAC4 implementations */ > + struct { > + u32 ipcr; > + } emac4; > + /* Registers unique to EMAC4SYNC implementations */ > + struct { > + u32 rsvd1; > + u32 revid; > + u32 rsvd2[2]; > + u32 iaht1; /* Reset, R */ > + u32 iaht2; /* Reset, R */ > + u32 iaht3; /* Reset, R */ > + u32 iaht4; /* Reset, R */ > + u32 iaht5; /* Reset, R */ > + u32 iaht6; /* Reset, R */ > + u32 iaht7; /* Reset, R */ > + u32 iaht8; /* Reset, R */ > + u32 gaht1; /* Reset, R */ > + u32 gaht2; /* Reset, R */ > + u32 gaht3; /* Reset, R */ > + u32 gaht4; /* Reset, R */ > + u32 gaht5; /* Reset, R */ > + u32 gaht6; /* Reset, R */ > + u32 gaht7; /* Reset, R */ > + u32 gaht8; /* Reset, R */ > + u32 tpc; /* Reset, T */ > + } emac4sync; > + } u1; > }; > > /* > @@ -73,12 +116,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 [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-07 6:18 ` Benjamin Herrenschmidt @ 2008-07-07 13:59 ` Jeff Garzik 0 siblings, 0 replies; 22+ messages in thread From: Jeff Garzik @ 2008-07-07 13:59 UTC (permalink / raw) To: benh; +Cc: linuxppc-dev, sr, Grant Erickson Benjamin Herrenschmidt wrote: > Hi Jeff ! > > If you are ok with this patch, I'll take it through the powerpc tree > since it changes all those device tree files. ACK ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson 2008-07-07 5:58 ` Stefan Roese 2008-07-07 6:18 ` Benjamin Herrenschmidt @ 2008-07-07 19:50 ` Valentine Barshak 2008-07-07 22:02 ` Grant Erickson 2008-07-07 22:03 ` [PATCH v6] " Grant Erickson 3 siblings, 1 reply; 22+ messages in thread From: Valentine Barshak @ 2008-07-07 19:50 UTC (permalink / raw) To: Grant Erickson; +Cc: linuxppc-dev, sr Grant Erickson wrote: <snip> > 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>; Should be reg = <ef600a00 c4> <snip> > --- 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>; Should be reg = <ef600a00 c4> Thanks, Valentine. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-07 19:50 ` Valentine Barshak @ 2008-07-07 22:02 ` Grant Erickson 0 siblings, 0 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-07 22:02 UTC (permalink / raw) To: Valentine Barshak; +Cc: linuxppc-dev, Stefan Roese On 7/7/08 12:50 PM, Valentine Barshak wrote: > Grant Erickson wrote: > > <snip> > >> - reg = <ef600a00 70>; >> + reg = <ef600900 c4>; > > Should be reg = <ef600a00 c4> > > <snip> > >> - reg = <ef600a00 70>; >> + reg = <ef600900 c4>; > > Should be reg = <ef600a00 c4> Good catch; amended patch forthcoming. Regards, Grant ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v6] ibm_newemac: Parameterize EMAC Multicast Match Handling 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson ` (2 preceding siblings ...) 2008-07-07 19:50 ` Valentine Barshak @ 2008-07-07 22:03 ` Grant Erickson 3 siblings, 0 replies; 22+ messages in thread From: Grant Erickson @ 2008-07-07 22:03 UTC (permalink / raw) To: linuxppc-dev; +Cc: sr 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 | 61 ++++++++++++++------ drivers/net/ibm_newemac/core.h | 83 ++++++++++++++++++++++++++- drivers/net/ibm_newemac/debug.c | 52 +++++++++++++---- drivers/net/ibm_newemac/emac.h | 101 ++++++++++++++++++++++---------- 13 files changed, 259 insertions(+), 92 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..bfae1b2 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 = <ef600a00 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..895381f 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 = <ef600a00 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..ed24a1d 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -363,25 +363,31 @@ 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; } - out_be32(&p->gaht1, gaht[0]); - out_be32(&p->gaht2, gaht[1]); - out_be32(&p->gaht3, gaht[2]); - out_be32(&p->gaht4, gaht[3]); + + for (i = 0; i < regs; i++) + out_be32(gaht_base + i, gaht_temp[i]); } static inline u32 emac_iff2rmr(struct net_device *ndev) @@ -398,7 +404,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; @@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev) /* Put some arbitrary OUI, Manuf & Rev IDs so we can * identify this GPCS PHY later. */ - out_be32(&p->ipcr, 0xdeadbeef); + out_be32(&p->u1.emac4.ipcr, 0xdeadbeef); } else mr1 |= EMAC_MR1_MF_1000; @@ -2015,10 +2022,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 +2052,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 +2547,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 +2610,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 +2690,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 +2903,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..70794cd 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 structure which are, in turn, + * initialized based on the "compatible" entry in the device tree. + */ + +#define EMAC4_XAHT_SLOTS_SHIFT 6 +#define EMAC4_XAHT_WIDTH_SHIFT 4 + +#define EMAC4SYNC_XAHT_SLOTS_SHIFT 8 +#define EMAC4SYNC_XAHT_WIDTH_SHIFT 5 + +#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; + + /* The first IAHT entry always is the base of the block of + * IAHT and GAHT registers. + */ + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) + offset = offsetof(struct emac_regs, u1.emac4sync.iaht1); + else + offset = offsetof(struct emac_regs, u0.emac4.iaht1); + + 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..775c850 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c @@ -67,29 +67,55 @@ 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 emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC); + 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) + ); + + if (emac4sync) + printk("MAR = %04x%08x MMAR = %04x%08x\n", + in_be32(&p->u0.emac4sync.mahr), + in_be32(&p->u0.emac4sync.malr), + in_be32(&p->u0.emac4sync.mmahr), + in_be32(&p->u0.emac4sync.mmalr) + ); + + 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\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) - ); + in_be32(&p->octx), in_be32(&p->ocrx) + ); + + if (!emac4sync) { + printk("IPCR = 0x%08x\n", + in_be32(&p->u1.emac4.ipcr) + ); + } else { + printk("REVID = 0x%08x TPC = 0x%08x\n", + in_be32(&p->u1.emac4sync.revid), + in_be32(&p->u1.emac4sync.tpc) + ); + } emac_desc_dump(dev); } diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index 91cb096..0afc2cf 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h @@ -27,37 +27,80 @@ #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 */ + /* Common registers across all EMAC implementations. */ + 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 */ + } emac4; + /* 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]; + } emac4sync; + } u0; + /* Common registers across all EMAC implementations. */ u32 lsah; u32 lsal; - u32 ipgvr; /* Reset, T */ - u32 stacr; /* special */ - u32 trtr; /* special */ - u32 rwmr; /* Reset */ + u32 ipgvr; /* Reset, T */ + u32 stacr; /* Special */ + u32 trtr; /* Special */ + u32 rwmr; /* Reset */ u32 octx; u32 ocrx; - u32 ipcr; + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 ipcr; + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 rsvd1; + u32 revid; + u32 rsvd2[2]; + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 iaht5; /* Reset, R */ + u32 iaht6; /* Reset, R */ + u32 iaht7; /* Reset, R */ + u32 iaht8; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + u32 gaht5; /* Reset, R */ + u32 gaht6; /* Reset, R */ + u32 gaht7; /* Reset, R */ + u32 gaht8; /* Reset, R */ + u32 tpc; /* Reset, T */ + } emac4sync; + } u1; }; /* @@ -73,12 +116,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 [flat|nested] 22+ messages in thread
end of thread, other threads:[~2008-07-07 22:03 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-06-25 0:08 [PATCH v2] Parameterize EMAC Multicast Match Handling Grant Erickson 2008-07-01 5:26 ` Grant Erickson 2008-07-01 6:14 ` Benjamin Herrenschmidt 2008-07-01 6:37 ` Stefan Roese 2008-07-01 18:13 ` Grant Erickson 2008-07-01 19:42 ` Stefan Roese 2008-07-01 23:52 ` Benjamin Herrenschmidt 2008-07-05 9:18 ` [PATCH v3] ibm_newemac: " Grant Erickson 2008-07-05 22:45 ` Benjamin Herrenschmidt 2008-07-06 0:15 ` [PATCH v4] " Grant Erickson 2008-07-06 0:31 ` Benjamin Herrenschmidt 2008-07-06 9:43 ` Stefan Roese 2008-07-06 23:30 ` [PATCH v5] " Grant Erickson 2008-07-07 5:58 ` Stefan Roese 2008-07-07 6:00 ` Benjamin Herrenschmidt 2008-07-07 6:29 ` Stefan Roese 2008-07-07 6:43 ` Benjamin Herrenschmidt 2008-07-07 6:18 ` Benjamin Herrenschmidt 2008-07-07 13:59 ` Jeff Garzik 2008-07-07 19:50 ` Valentine Barshak 2008-07-07 22:02 ` Grant Erickson 2008-07-07 22:03 ` [PATCH v6] " Grant Erickson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).