On Wed, Aug 16, 2023 at 12:55:56AM +0000, Hawkins, Nick wrote: > Greetings Andrew, > > I have a follow up question below: > > >> +static int umac_mdio_read(struct mii_bus *bus, int phy_id, int reg) > >> +{ > >> + struct umac_mdio_priv *umac_mdio = bus->priv; > >> + unsigned int status; > >> + unsigned int value; > >> + int ret; > >> + > >> + status = __raw_readl(umac_mdio->base + UMAC_MII); > >> + > >> + status &= ~(UMAC_MII_PHY_ADDR_MASK | UMAC_MII_REG_ADDR_MASK); > >> + status |= ((phy_id << UMAC_MII_PHY_ADDR_SHIFT) & > >> + UMAC_MII_PHY_ADDR_MASK); > >> + status |= (reg & UMAC_MII_REG_ADDR_MASK); > >> + status |= UMAC_MII_MRNW; /* set bit for read mode */ > >> + __raw_writel(status, umac_mdio->base + UMAC_MII); > >> + > >> + status |= UMAC_MII_MOWNER; /* set bit to activate mii transfer */ > >> + __raw_writel(status, umac_mdio->base + UMAC_MII); > > > > I assume UMAC_MII_MOWNER must be set in a separate operation? But > > using __raw_writel() i'm not sure there is any barrier between the two > > writes. > > Is there a function you would recommend using instead? writel(). In general, it is best to use writel()/readl() for correctness. In the hot path, dealing with actually Ethernet frames where every uS counts, you can then think about using writel_relaxed()/readl_relaxed(). But for something slow like an MDIO bus driver, i would always avoid the possibility of having hard to find bugs because of missing barriers. Andrew