Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: et131x: Fix errors caused by phydev->addr accesses before initialisation

Fix two reported bugs, caused by et131x_adapter->phydev->addr being accessed
before it is initialised, by:

- letting et131x_mii_write() take a phydev address, instead of using the one
stored in adapter by default. This is so et131x_mdio_write() can use it's own
addr value.
- removing implementation of et131x_mdio_reset(), as it's not needed.
- moving a call to et131x_disable_phy_coma() in et131x_pci_setup(), which uses
phydev->addr, until after the mdiobus has been registered.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=80751
Link: https://bugzilla.kernel.org/show_bug.cgi?id=77121
Cc: stable@vger.kernel.org
Signed-off-by: Mark Einon <mark.einon@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mark Einon and committed by
Greg Kroah-Hartman
ec0a38bf e409842a

+27 -41
+27 -41
drivers/staging/et131x/et131x.c
··· 1421 1421 * @reg: the register to read 1422 1422 * @value: 16-bit value to write 1423 1423 */ 1424 - static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) 1424 + static int et131x_mii_write(struct et131x_adapter *adapter, u8 addr, u8 reg, 1425 + u16 value) 1425 1426 { 1426 1427 struct mac_regs __iomem *mac = &adapter->regs->mac; 1427 - struct phy_device *phydev = adapter->phydev; 1428 1428 int status = 0; 1429 - u8 addr; 1430 1429 u32 delay = 0; 1431 1430 u32 mii_addr; 1432 1431 u32 mii_cmd; 1433 1432 u32 mii_indicator; 1434 - 1435 - if (!phydev) 1436 - return -EIO; 1437 - 1438 - addr = phydev->addr; 1439 1433 1440 1434 /* Save a local copy of the registers we are dealing with so we can 1441 1435 * set them back ··· 1625 1631 struct net_device *netdev = bus->priv; 1626 1632 struct et131x_adapter *adapter = netdev_priv(netdev); 1627 1633 1628 - return et131x_mii_write(adapter, reg, value); 1629 - } 1630 - 1631 - static int et131x_mdio_reset(struct mii_bus *bus) 1632 - { 1633 - struct net_device *netdev = bus->priv; 1634 - struct et131x_adapter *adapter = netdev_priv(netdev); 1635 - 1636 - et131x_mii_write(adapter, MII_BMCR, BMCR_RESET); 1637 - 1638 - return 0; 1634 + return et131x_mii_write(adapter, phy_addr, reg, value); 1639 1635 } 1640 1636 1641 1637 /* et1310_phy_power_switch - PHY power control ··· 1640 1656 static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) 1641 1657 { 1642 1658 u16 data; 1659 + struct phy_device *phydev = adapter->phydev; 1643 1660 1644 1661 et131x_mii_read(adapter, MII_BMCR, &data); 1645 1662 data &= ~BMCR_PDOWN; 1646 1663 if (down) 1647 1664 data |= BMCR_PDOWN; 1648 - et131x_mii_write(adapter, MII_BMCR, data); 1665 + et131x_mii_write(adapter, phydev->addr, MII_BMCR, data); 1649 1666 } 1650 1667 1651 1668 /* et131x_xcvr_init - Init the phy if we are setting it into force mode */ 1652 1669 static void et131x_xcvr_init(struct et131x_adapter *adapter) 1653 1670 { 1654 1671 u16 lcr2; 1672 + struct phy_device *phydev = adapter->phydev; 1655 1673 1656 1674 /* Set the LED behavior such that LED 1 indicates speed (off = 1657 1675 * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates ··· 1674 1688 else 1675 1689 lcr2 |= (LED_VAL_LINKON << LED_TXRX_SHIFT); 1676 1690 1677 - et131x_mii_write(adapter, PHY_LED_2, lcr2); 1691 + et131x_mii_write(adapter, phydev->addr, PHY_LED_2, lcr2); 1678 1692 } 1679 1693 } 1680 1694 ··· 3629 3643 3630 3644 et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, 3631 3645 &register18); 3632 - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 3633 - register18 | 0x4); 3634 - et131x_mii_write(adapter, PHY_INDEX_REG, 3646 + et131x_mii_write(adapter, phydev->addr, 3647 + PHY_MPHY_CONTROL_REG, register18 | 0x4); 3648 + et131x_mii_write(adapter, phydev->addr, PHY_INDEX_REG, 3635 3649 register18 | 0x8402); 3636 - et131x_mii_write(adapter, PHY_DATA_REG, 3650 + et131x_mii_write(adapter, phydev->addr, PHY_DATA_REG, 3637 3651 register18 | 511); 3638 - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 3639 - register18); 3652 + et131x_mii_write(adapter, phydev->addr, 3653 + PHY_MPHY_CONTROL_REG, register18); 3640 3654 } 3641 3655 3642 3656 et1310_config_flow_control(adapter); ··· 3648 3662 et131x_mii_read(adapter, PHY_CONFIG, &reg); 3649 3663 reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; 3650 3664 reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; 3651 - et131x_mii_write(adapter, PHY_CONFIG, reg); 3665 + et131x_mii_write(adapter, phydev->addr, PHY_CONFIG, 3666 + reg); 3652 3667 } 3653 3668 3654 3669 et131x_set_rx_dma_timer(adapter); ··· 3662 3675 3663 3676 et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, 3664 3677 &register18); 3665 - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 3666 - register18 | 0x4); 3667 - et131x_mii_write(adapter, PHY_INDEX_REG, 3668 - register18 | 0x8402); 3669 - et131x_mii_write(adapter, PHY_DATA_REG, 3670 - register18 | 511); 3671 - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 3672 - register18); 3678 + et131x_mii_write(adapter, phydev->addr, 3679 + PHY_MPHY_CONTROL_REG, register18 | 0x4); 3680 + et131x_mii_write(adapter, phydev->addr, 3681 + PHY_INDEX_REG, register18 | 0x8402); 3682 + et131x_mii_write(adapter, phydev->addr, 3683 + PHY_DATA_REG, register18 | 511); 3684 + et131x_mii_write(adapter, phydev->addr, 3685 + PHY_MPHY_CONTROL_REG, register18); 3673 3686 } 3674 3687 3675 3688 /* Free the packets being actively sent & stopped */ ··· 4631 4644 /* Copy address into the net_device struct */ 4632 4645 memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); 4633 4646 4634 - /* Init variable for counting how long we do not have link status */ 4635 - adapter->boot_coma = 0; 4636 - et1310_disable_phy_coma(adapter); 4637 - 4638 4647 rc = -ENOMEM; 4639 4648 4640 4649 /* Setup the mii_bus struct */ ··· 4646 4663 adapter->mii_bus->priv = netdev; 4647 4664 adapter->mii_bus->read = et131x_mdio_read; 4648 4665 adapter->mii_bus->write = et131x_mdio_write; 4649 - adapter->mii_bus->reset = et131x_mdio_reset; 4650 4666 adapter->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), 4651 4667 GFP_KERNEL); 4652 4668 if (!adapter->mii_bus->irq) ··· 4668 4686 4669 4687 /* Setup et1310 as per the documentation */ 4670 4688 et131x_adapter_setup(adapter); 4689 + 4690 + /* Init variable for counting how long we do not have link status */ 4691 + adapter->boot_coma = 0; 4692 + et1310_disable_phy_coma(adapter); 4671 4693 4672 4694 /* We can enable interrupts now 4673 4695 *