diff options
Diffstat (limited to 'src/drivers/net/phy/m88e1512')
-rw-r--r-- | src/drivers/net/phy/m88e1512/chip.h | 3 | ||||
-rw-r--r-- | src/drivers/net/phy/m88e1512/m88e1512.c | 22 | ||||
-rw-r--r-- | src/drivers/net/phy/m88e1512/m88e1512.h | 9 |
3 files changed, 34 insertions, 0 deletions
diff --git a/src/drivers/net/phy/m88e1512/chip.h b/src/drivers/net/phy/m88e1512/chip.h index 9a3523d7ee..915001a7a1 100644 --- a/src/drivers/net/phy/m88e1512/chip.h +++ b/src/drivers/net/phy/m88e1512/chip.h @@ -8,4 +8,7 @@ struct drivers_net_phy_m88e1512_config { unsigned char led_1_ctrl; /* LED[1] Control */ unsigned char led_2_ctrl; /* LED[2] Control */ bool enable_int; /* INTn can be routed to LED[2] pin */ + /* 1x, 2x,...8x is the number of times the PHY attempts to establish Gigabit link + before the PHY downshifts to the next highest speed. */ + unsigned char downshift_cnt; }; diff --git a/src/drivers/net/phy/m88e1512/m88e1512.c b/src/drivers/net/phy/m88e1512/m88e1512.c index a8d1c730a1..f32991fcd5 100644 --- a/src/drivers/net/phy/m88e1512/m88e1512.c +++ b/src/drivers/net/phy/m88e1512/m88e1512.c @@ -17,6 +17,28 @@ static void m88e1512_init(struct device *dev) struct drivers_net_phy_m88e1512_config *config = dev->chip_info; uint16_t reg; + /* Enable downshift. */ + if (config->downshift_cnt) { + if (config->downshift_cnt > DOWNSHIFT_CNT_MAX) { + printk(BIOS_INFO, "%s: Downshift counter for %s is too large.\n", + dev_path(dev->bus->dev), dev->chip_ops->name); + } else { + printk(BIOS_DEBUG, "%s: Enable downshift after %d attempts for %s.\n", + dev_path(dev->bus->dev), config->downshift_cnt, + dev->chip_ops->name); + + reg = mdio_read(dev, COPPER_SPEC_CTRL_REG_1); + clrsetbits16(®, DOWNSHIFT_CNT_MASK, + DOWNSHIFT_CNT(config->downshift_cnt) | DOWNSHIFT_EN); + mdio_write(dev, COPPER_SPEC_CTRL_REG_1, reg); + + /* Downshift enable requires a software reset to take effect. */ + reg = mdio_read(dev, COPPER_CTRL_REG); + setbits16(®, SOFTWARE_RESET); + mdio_write(dev, COPPER_CTRL_REG, reg); + } + } + /* Configure LEDs if requested. */ if (config->configure_leds) { printk(BIOS_DEBUG, "%s: Set a customized LED mode for %s.\n", diff --git a/src/drivers/net/phy/m88e1512/m88e1512.h b/src/drivers/net/phy/m88e1512/m88e1512.h index ca0f756693..449cc57531 100644 --- a/src/drivers/net/phy/m88e1512/m88e1512.h +++ b/src/drivers/net/phy/m88e1512/m88e1512.h @@ -5,6 +5,15 @@ /* Register layout */ #define PAGE_REG 0x16 +/* Page 0 registers */ +#define COPPER_CTRL_REG 0 +#define SOFTWARE_RESET (1 << 15) +#define COPPER_SPEC_CTRL_REG_1 0x10 +#define DOWNSHIFT_CNT_MASK 0x7000 +#define DOWNSHIFT_CNT_MAX 8 +#define DOWNSHIFT_CNT(cnt) ((cnt - 1) << 12) +#define DOWNSHIFT_EN (1 << 11) +/* Page 3 registers */ #define LED_FUNC_CTRL_REG 0x10 #define LED_FUNC_CTRL_MASK 0x0FFF #define LED_TIMER_CTRL_REG 0x12 |