On 12/20/18 5:16 AM, Steen Hegelund wrote: > When doing indirect access in the Ocelot chip, a command is setup, > issued and then we need to poll until the result is ready. The polling > timeout is specified in milliseconds in the datasheet and not in > register access attempts. > It is not a bug on the currently supported platform, but we observed > that the code does not work properly on other platforms that we want to > support as the timing requirements there are different.
Minor nit, to be consistent with previous submissions done to that file/directory, I would use "net: mscc: ocelot: " as a prefix for commit messages. > > Signed-off-by: Steen Hegelund <steen.hegel...@microchip.com> > --- > drivers/net/ethernet/mscc/ocelot.c | 55 +++++++++++++++--------------- > 1 file changed, 27 insertions(+), 28 deletions(-) > > diff --git a/drivers/net/ethernet/mscc/ocelot.c > b/drivers/net/ethernet/mscc/ocelot.c > index 3238b9ee42f3..debe74e4a041 100644 > --- a/drivers/net/ethernet/mscc/ocelot.c > +++ b/drivers/net/ethernet/mscc/ocelot.c > @@ -15,6 +15,7 @@ > #include <linux/netdevice.h> > #include <linux/phy.h> > #include <linux/skbuff.h> > +#include <linux/iopoll.h> > #include <net/arp.h> > #include <net/netevent.h> > #include <net/rtnetlink.h> > @@ -22,6 +23,9 @@ > > #include "ocelot.h" > > +#define TABLE_UPDATE_SLEEP_US 10 > +#define TABLE_UPDATE_TIMEOUT_US 100000 > + > /* MAC table entry types. > * ENTRYTYPE_NORMAL is subject to aging. > * ENTRYTYPE_LOCKED is not subject to aging. > @@ -41,23 +45,20 @@ struct ocelot_mact_entry { > enum macaccess_entry_type type; > }; > > -static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot) > +static inline u32 ocelot_mact_read_macaccess(struct ocelot *ocelot) > { > - unsigned int val, timeout = 10; > - > - /* Wait for the issued mac table command to be completed, or timeout. > - * When the command read from ANA_TABLES_MACACCESS is > - * MACACCESS_CMD_IDLE, the issued command completed successfully. > - */ > - do { > - val = ocelot_read(ocelot, ANA_TABLES_MACACCESS); > - val &= ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M; > - } while (val != MACACCESS_CMD_IDLE && timeout--); > + return ocelot_read(ocelot, ANA_TABLES_MACACCESS); > +} > > - if (!timeout) > - return -ETIMEDOUT; > +static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot) > +{ > + u32 val; > > - return 0; > + return readx_poll_timeout(ocelot_mact_read_macaccess, > + ocelot, val, > + (val & ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M) == > + MACACCESS_CMD_IDLE, > + TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US); > } > > static void ocelot_mact_select(struct ocelot *ocelot, > @@ -129,23 +130,21 @@ static void ocelot_mact_init(struct ocelot *ocelot) > ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); > } > > -static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) > +static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) > { > - unsigned int val, timeout = 10; > - > - /* Wait for the issued vlan table command to be completed, or timeout. > - * When the command read from ANA_TABLES_VLANACCESS is > - * VLANACCESS_CMD_IDLE, the issued command completed successfully. > - */ > - do { > - val = ocelot_read(ocelot, ANA_TABLES_VLANACCESS); > - val &= ANA_TABLES_VLANACCESS_VLAN_TBL_CMD_M; > - } while (val != ANA_TABLES_VLANACCESS_CMD_IDLE && timeout--); > + return ocelot_read(ocelot, ANA_TABLES_VLANACCESS); > +} > > - if (!timeout) > - return -ETIMEDOUT; > +static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) > +{ > + u32 val; > > - return 0; > + return readx_poll_timeout(ocelot_vlant_read_vlanaccess, > + ocelot, > + val, > + (val & ANA_TABLES_VLANACCESS_VLAN_TBL_CMD_M) == > + ANA_TABLES_VLANACCESS_CMD_IDLE, > + TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US); > } > > static int ocelot_vlant_set_mask(struct ocelot *ocelot, u16 vid, u32 mask) > -- Florian