From 4aa5d3e60d6007809a4b7fac9959645ef1600cf9 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 29 Sep 2016 12:16:51 +0200 Subject: mvebu: add support for SFP Add patches for SFP support and package it for ClearFog. Tested with a Juniper SFP module. Signed-off-by: Jonas Gorski Acked-by: Felix Fietkau --- ...-swphy-register-generation-to-tabular-for.patch | 203 +++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch (limited to 'target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch') diff --git a/target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch b/target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch new file mode 100644 index 0000000000..0d689f39a3 --- /dev/null +++ b/target/linux/mvebu/patches-4.4/121-phy-convert-swphy-register-generation-to-tabular-for.patch @@ -0,0 +1,203 @@ +From cd834fe430f030a63bfa9277bba194e8eef4dbd0 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Sun, 20 Sep 2015 10:18:59 +0100 +Subject: [PATCH 710/744] phy: convert swphy register generation to tabular + form + +Convert the swphy register generation to tabular form which allows us +to eliminate multiple switch() statements. This results in a smaller +object code size, more efficient, and easier to add support for faster +speeds. + +Before: + +Idx Name Size VMA LMA File off Algn + 0 .text 00000164 00000000 00000000 00000034 2**2 + + text data bss dec hex filename + 388 0 0 388 184 swphy.o + +After: + +Idx Name Size VMA LMA File off Algn + 0 .text 000000fc 00000000 00000000 00000034 2**2 + 5 .rodata 00000028 00000000 00000000 00000138 2**2 + + text data bss dec hex filename + 324 0 0 324 144 swphy.o + +Reviewed-by: Florian Fainelli +Signed-off-by: Russell King +--- + drivers/net/phy/swphy.c | 143 ++++++++++++++++++++++++++---------------------- + 1 file changed, 78 insertions(+), 65 deletions(-) + +--- a/drivers/net/phy/swphy.c ++++ b/drivers/net/phy/swphy.c +@@ -20,6 +20,72 @@ + + #include "swphy.h" + ++struct swmii_regs { ++ u16 bmcr; ++ u16 bmsr; ++ u16 lpa; ++ u16 lpagb; ++}; ++ ++enum { ++ SWMII_SPEED_10 = 0, ++ SWMII_SPEED_100, ++ SWMII_SPEED_1000, ++ SWMII_DUPLEX_HALF = 0, ++ SWMII_DUPLEX_FULL, ++}; ++ ++/* ++ * These two tables get bitwise-anded together to produce the final result. ++ * This means the speed table must contain both duplex settings, and the ++ * duplex table must contain all speed settings. ++ */ ++static const struct swmii_regs speed[] = { ++ [SWMII_SPEED_10] = { ++ .bmcr = BMCR_FULLDPLX, ++ .lpa = LPA_10FULL | LPA_10HALF, ++ }, ++ [SWMII_SPEED_100] = { ++ .bmcr = BMCR_FULLDPLX | BMCR_SPEED100, ++ .bmsr = BMSR_100FULL | BMSR_100HALF, ++ .lpa = LPA_100FULL | LPA_100HALF, ++ }, ++ [SWMII_SPEED_1000] = { ++ .bmcr = BMCR_FULLDPLX | BMCR_SPEED1000, ++ .bmsr = BMSR_ESTATEN, ++ .lpagb = LPA_1000FULL | LPA_1000HALF, ++ }, ++}; ++ ++static const struct swmii_regs duplex[] = { ++ [SWMII_DUPLEX_HALF] = { ++ .bmcr = ~BMCR_FULLDPLX, ++ .bmsr = BMSR_ESTATEN | BMSR_100HALF, ++ .lpa = LPA_10HALF | LPA_100HALF, ++ .lpagb = LPA_1000HALF, ++ }, ++ [SWMII_DUPLEX_FULL] = { ++ .bmcr = ~0, ++ .bmsr = BMSR_ESTATEN | BMSR_100FULL, ++ .lpa = LPA_10FULL | LPA_100FULL, ++ .lpagb = LPA_1000FULL, ++ }, ++}; ++ ++static int swphy_decode_speed(int speed) ++{ ++ switch (speed) { ++ case 1000: ++ return SWMII_SPEED_1000; ++ case 100: ++ return SWMII_SPEED_100; ++ case 10: ++ return SWMII_SPEED_10; ++ default: ++ return -EINVAL; ++ } ++} ++ + /** + * swphy_update_regs - update MII register array with fixed phy state + * @regs: array of 32 registers to update +@@ -30,81 +96,28 @@ + */ + int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) + { ++ int speed_index, duplex_index; + u16 bmsr = BMSR_ANEGCAPABLE; + u16 bmcr = 0; + u16 lpagb = 0; + u16 lpa = 0; + +- if (state->duplex) { +- switch (state->speed) { +- case 1000: +- bmsr |= BMSR_ESTATEN; +- break; +- case 100: +- bmsr |= BMSR_100FULL; +- break; +- case 10: +- bmsr |= BMSR_10FULL; +- break; +- default: +- break; +- } +- } else { +- switch (state->speed) { +- case 1000: +- bmsr |= BMSR_ESTATEN; +- break; +- case 100: +- bmsr |= BMSR_100HALF; +- break; +- case 10: +- bmsr |= BMSR_10HALF; +- break; +- default: +- break; +- } ++ speed_index = swphy_decode_speed(state->speed); ++ if (speed_index < 0) { ++ pr_warn("swphy: unknown speed\n"); ++ return -EINVAL; + } + ++ duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF; ++ ++ bmsr |= speed[speed_index].bmsr & duplex[duplex_index].bmsr; ++ + if (state->link) { + bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; + +- if (state->duplex) { +- bmcr |= BMCR_FULLDPLX; +- +- switch (state->speed) { +- case 1000: +- bmcr |= BMCR_SPEED1000; +- lpagb |= LPA_1000FULL; +- break; +- case 100: +- bmcr |= BMCR_SPEED100; +- lpa |= LPA_100FULL; +- break; +- case 10: +- lpa |= LPA_10FULL; +- break; +- default: +- pr_warn("swphy: unknown speed\n"); +- return -EINVAL; +- } +- } else { +- switch (state->speed) { +- case 1000: +- bmcr |= BMCR_SPEED1000; +- lpagb |= LPA_1000HALF; +- break; +- case 100: +- bmcr |= BMCR_SPEED100; +- lpa |= LPA_100HALF; +- break; +- case 10: +- lpa |= LPA_10HALF; +- break; +- default: +- pr_warn("swphy: unknown speed\n"); +- return -EINVAL; +- } +- } ++ bmcr |= speed[speed_index].bmcr & duplex[duplex_index].bmcr; ++ lpa |= speed[speed_index].lpa & duplex[duplex_index].lpa; ++ lpagb |= speed[speed_index].lpagb & duplex[duplex_index].lpagb; + + if (state->pause) + lpa |= LPA_PAUSE_CAP; -- cgit v1.2.3