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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5ae68b0ce1
commit
0629bf17ea
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue