123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- From cd834fe430f030a63bfa9277bba194e8eef4dbd0 Mon Sep 17 00:00:00 2001
- From: Russell King <rmk+kernel@arm.linux.org.uk>
- 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 <f.fainelli@gmail.com>
- Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
- ---
- 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;
|