public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Jens Emil Schulz Ostergaard <jensemil.schulzostergaard@microchip.com>
To: Vladimir Oltean <olteanv@gmail.com>
Cc: <UNGLinuxDriver@microchip.com>, Andrew Lunn <andrew@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Woojung Huh <woojung.huh@microchip.com>,
	Russell King <linux@armlinux.org.uk>,
	"Steen Hegelund" <Steen.Hegelund@microchip.com>,
	Daniel Machon <daniel.machon@microchip.com>,
	<linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>,
	<devicetree@vger.kernel.org>
Subject: Re: [PATCH net-next 7/8] net: dsa: lan9645x: add mac table integration
Date: Wed, 4 Mar 2026 16:23:51 +0100	[thread overview]
Message-ID: <67a34d22b8f59964fd3bfaee99c8418a21526f3e.camel@microchip.com> (raw)
In-Reply-To: <20260303152709.nospd2qq3dju2tev@skbuf>

On Tue, 2026-03-03 at 17:27 +0200, Vladimir Oltean wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, Mar 03, 2026 at 01:22:33PM +0100, Jens Emil Schulz Østergaard wrote:
> > Add MAC table support, and dsa fdb callback integration. The mactable is
> > keyed on (vid,mac) and each bucket has 4 slots. A mac table entry
> > typically points to a PGID index, the first 9 of which represent a front
> > port.
> > 
> > Mac table entries for L2 multicast will use a PGID containing a group
> > port mask. For IP multicast entries in the mac table a trick us used,
> > where the group port mask is packed into the MAC data, exploiting the
> > fact that the top bits are fixed, and that the number of switch ports is
> > small enough to fit in the redundant bits.
> > 
> > Therefore, we can avoid using sparse PGID resources for IP multicast
> > entries in the mac table.
> > 
> > Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
> > Signed-off-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
> > ---
> >  drivers/net/dsa/microchip/lan9645x/Makefile        |   1 +
> >  drivers/net/dsa/microchip/lan9645x/lan9645x_mac.c  | 413 +++++++++++++++++++++
> >  drivers/net/dsa/microchip/lan9645x/lan9645x_main.c | 110 +++++-
> >  drivers/net/dsa/microchip/lan9645x/lan9645x_main.h |  48 +++
> >  4 files changed, 571 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/dsa/microchip/lan9645x/Makefile b/drivers/net/dsa/microchip/lan9645x/Makefile
> > index bb5eec14d225..a90a46f81c72 100644
> > --- a/drivers/net/dsa/microchip/lan9645x/Makefile
> > +++ b/drivers/net/dsa/microchip/lan9645x/Makefile
> > @@ -6,3 +6,4 @@ mchp-lan9645x-objs := lan9645x_main.o \
> >       lan9645x_port.o \
> >       lan9645x_phylink.o \
> >       lan9645x_vlan.o \
> > +     lan9645x_mac.o \
> 
> Is there some particular ordering here? Because it's surely not
> alphabetical.
> 

I just add new files at the end, I thought that made the most sense. Should they be
sorted by name?

> > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_mac.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_mac.c
> > new file mode 100644
> > index 000000000000..3226cff16e8c
> > --- /dev/null
> > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_mac.c
> > @@ -0,0 +1,413 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/* Copyright (C) 2026 Microchip Technology Inc.
> > + */
> > +
> > +#include "lan9645x_main.h"
> > +
> > +#define LAN9645X_MAC_COLUMNS 4
> 
> Doesn't appear used.

I will remove it.

> 
> > +
> > +#define CMD_IDLE             0
> > +#define CMD_LEARN            1
> > +#define CMD_FORGET           2
> > +#define CMD_AGE                      3
> > +#define CMD_GET_NEXT         4
> > +#define CMD_INIT             5
> > +#define CMD_READ             6
> > +#define CMD_WRITE            7
> > +#define CMD_SYNC_GET_NEXT    8
> > +
> > +#define LAN9645X_INVALID_ROW (-1)
> > +
> > +static bool lan9645x_mact_entry_equal(struct lan9645x_mact_entry *entry,
> > +                                   const unsigned char *mac, u16 vid)
> > +{
> > +     /* The hardware table is keyed on (vid,mac) */
> > +     return entry->common.key.vid == vid &&
> > +             ether_addr_equal(mac, entry->common.key.mac);
> 
> Can you please align the "entry" with "ether_addr_equal".
> I think there's more coding style inconsistencies of the same type in
> the submission that I went over and omitted to comment on.
> 

I will go over the patches and fix this where applicable.

> > +}
> > +
> > +static struct lan9645x_mact_entry *
> > +lan9645x_mact_entry_find(struct lan9645x *lan9645x, const unsigned char *mac,
> > +                      u16 vid)
> > +{
> > +     struct lan9645x_mact_entry *entry;
> > +
> > +     lockdep_assert_held(&lan9645x->mac_entry_lock);
> > +
> > +     list_for_each_entry(entry, &lan9645x->mac_entries, list)
> > +             if (lan9645x_mact_entry_equal(entry, mac, vid))
> > +                     return entry;
> > +
> > +     return NULL;
> > +}
> > +
> > +static struct lan9645x_mact_entry *
> > +lan9645x_mact_entry_alloc(struct lan9645x *lan9645x, const unsigned char *mac,
> > +                       u16 vid, u8 pgid, enum macaccess_entry_type type)
> > +{
> > +     struct lan9645x_mact_entry *entry;
> > +
> > +     entry = kzalloc_obj(*entry);
> > +     if (!entry)
> > +             return NULL;
> > +
> > +     INIT_LIST_HEAD(&entry->list);
> 
> This isn't needed on individual list elements, only on the head.
> 
> > +     ether_addr_copy(entry->common.key.mac, mac);
> > +     entry->common.key.vid = vid;
> > +     entry->common.pgid = pgid;
> > +     entry->common.row = LAN9645X_INVALID_ROW;
> 
> Do you use the row for anything?
> 

No I will remove it, and the LIST_INIT above.

> > +     entry->common.type = type;
> > +
> > +     dev_dbg(lan9645x->dev,
> > +             "mact_entry_alloc mac=%pM vid=%u pgid=%u type=%d",
> > +             entry->common.key.mac, entry->common.key.vid,
> > +             entry->common.pgid, entry->common.type);
> > +     return entry;
> > +}
> > +
> > +static void lan9645x_mact_entry_dealloc(struct lan9645x *lan9645x,
> > +                                     struct lan9645x_mact_entry *entry)
> > +{
> > +     if (!entry)
> > +             return;
> > +
> > +     dev_dbg(lan9645x->dev,
> > +             "mact_entry_dealloc mac=%pM vid=%u pgid=%u type=%d",
> > +             entry->common.key.mac, entry->common.key.vid,
> > +             entry->common.pgid, entry->common.type);
> > +
> > +     list_del(&entry->list);
> > +     kfree(entry);
> > +}
> > +
> > +static int lan9645x_mac_wait_for_completion(struct lan9645x *lan9645x,
> > +                                         u32 *maca)
> > +{
> > +     u32 val = 0;
> > +     int err;
> > +
> > +     lockdep_assert_held(&lan9645x->mact_lock);
> > +
> > +     err = lan9645x_rd_poll_timeout(lan9645x, ANA_MACACCESS, val,
> > +                                    ANA_MACACCESS_MAC_TABLE_CMD_GET(val) ==
> > +                                    CMD_IDLE);
> > +     if (err)
> > +             return err;
> > +
> > +     if (maca)
> > +             *maca = val;
> > +
> > +     return 0;
> > +}
> > +
> > +static void lan9645x_mact_parse(u32 machi, u32 maclo, u32 maca,
> > +                             struct lan9645x_mact_common *rentry)
> > +{
> > +     u64 addr = ANA_MACHDATA_MACHDATA_GET(machi);
> > +
> > +     addr = addr << 32 | maclo;
> > +     u64_to_ether_addr(addr, rentry->key.mac);
> > +     rentry->key.vid = ANA_MACHDATA_VID_GET(machi);
> > +     rentry->pgid = ANA_MACACCESS_DEST_IDX_GET(maca);
> > +     rentry->type = ANA_MACACCESS_ENTRYTYPE_GET(maca);
> > +}
> > +
> > +static void lan9645x_mac_select(struct lan9645x *lan9645x,
> > +                             const unsigned char *addr, u16 vid)
> > +{
> > +     u64 maddr = ether_addr_to_u64(addr);
> > +
> > +     lockdep_assert_held(&lan9645x->mact_lock);
> > +
> > +     lan_wr(ANA_MACHDATA_VID_SET(vid) |
> > +            ANA_MACHDATA_MACHDATA_SET(maddr >> 32),
> > +            lan9645x,
> > +            ANA_MACHDATA);
> > +
> > +     lan_wr(maddr & GENMASK(31, 0),
> > +            lan9645x,
> > +            ANA_MACLDATA);
> > +}
> > +
> > +static int __lan9645x_mact_forget(struct lan9645x *lan9645x,
> > +                               const unsigned char mac[ETH_ALEN],
> > +                               unsigned int vid,
> > +                               enum macaccess_entry_type type)
> > +{
> > +     lockdep_assert_held(&lan9645x->mact_lock);
> > +
> > +     lan9645x_mac_select(lan9645x, mac, vid);
> > +
> > +     lan_wr(ANA_MACACCESS_ENTRYTYPE_SET(type) |
> > +            ANA_MACACCESS_MAC_TABLE_CMD_SET(CMD_FORGET),
> > +            lan9645x,
> > +            ANA_MACACCESS);
> > +
> > +     return lan9645x_mac_wait_for_completion(lan9645x, NULL);
> > +}
> > +
> > +int lan9645x_mact_forget(struct lan9645x *lan9645x,
> > +                      const unsigned char mac[ETH_ALEN], unsigned int vid,
> > +                      enum macaccess_entry_type type)
> > +{
> > +     int ret;
> 
> Inconsistent use of "err" and "ret" throughout the driver.
> Pick one and stick to it.
> 

I will fix this in the next version.


> > +
> > +     mutex_lock(&lan9645x->mact_lock);
> > +     ret = __lan9645x_mact_forget(lan9645x, mac, vid, type);
> > +     mutex_unlock(&lan9645x->mact_lock);
> > +
> > +     return ret;
> > +}
> > +
> > +static bool lan9645x_mac_ports_use_cpu(const unsigned char *mac,
> > +                                    enum macaccess_entry_type type)
> > +{
> > +     u32 mc_ports;
> > +
> > +     switch (type) {
> > +     case ENTRYTYPE_MACV4:
> > +             mc_ports = (mac[1] << 8) | mac[2];
> > +             break;
> > +     case ENTRYTYPE_MACV6:
> > +             mc_ports = (mac[0] << 8) | mac[1];
> > +             break;
> > +     default:
> > +             return false;
> > +     }
> > +
> > +     return !!(mc_ports & BIT(CPU_PORT));
> > +}
> > +
> > +static int __lan9645x_mact_learn_cpu_copy(struct lan9645x *lan9645x, int port,
> > +                                       const unsigned char *addr, u16 vid,
> > +                                       enum macaccess_entry_type type,
> > +                                       bool cpu_copy)
> > +{
> > +     lockdep_assert_held(&lan9645x->mact_lock);
> > +
> > +     lan9645x_mac_select(lan9645x, addr, vid);
> > +
> > +     lan_wr(ANA_MACACCESS_VALID_SET(1) |
> > +            ANA_MACACCESS_DEST_IDX_SET(port) |
> > +            ANA_MACACCESS_MAC_CPU_COPY_SET(cpu_copy) |
> > +            ANA_MACACCESS_ENTRYTYPE_SET(type) |
> > +            ANA_MACACCESS_MAC_TABLE_CMD_SET(CMD_LEARN),
> > +            lan9645x, ANA_MACACCESS);
> > +
> > +     return lan9645x_mac_wait_for_completion(lan9645x, NULL);
> > +}
> > +
> > +static int __lan9645x_mact_learn(struct lan9645x *lan9645x, int port,
> > +                              const unsigned char *addr, u16 vid,
> > +                              enum macaccess_entry_type type)
> > +{
> > +     bool cpu_copy = lan9645x_mac_ports_use_cpu(addr, type);
> > +
> > +     return __lan9645x_mact_learn_cpu_copy(lan9645x, port, addr, vid, type,
> > +                                           cpu_copy);
> > +}
> > +
> > +int lan9645x_mact_learn(struct lan9645x *lan9645x, int port,
> > +                     const unsigned char *addr, u16 vid,
> > +                     enum macaccess_entry_type type)
> > +{
> > +     int ret;
> > +
> > +     mutex_lock(&lan9645x->mact_lock);
> > +     ret = __lan9645x_mact_learn(lan9645x, port, addr, vid, type);
> > +     mutex_unlock(&lan9645x->mact_lock);
> > +
> > +     return ret;
> > +}
> > +
> > +int lan9645x_mact_flush(struct lan9645x *lan9645x, int port)
> > +{
> > +     int err = 0;
> 
> This is overwritten with the lan9645x_mac_wait_for_completion() result
> and never read. You don't need to zero-initialize it.
> 

I will remove this.

> > +
> > +     mutex_lock(&lan9645x->mact_lock);
> > +     /* MAC table entries with dst index matching port are aged on scan. */
> > +     lan_wr(ANA_ANAGEFIL_PID_EN_SET(1) |
> > +            ANA_ANAGEFIL_PID_VAL_SET(port),
> > +            lan9645x, ANA_ANAGEFIL);
> > +
> > +     /* Flushing requires two scans. First sets AGE_FLAG=1, second removes
> > +      * entries with AGE_FLAG=1.
> > +      */
> > +     lan_wr(ANA_MACACCESS_MAC_TABLE_CMD_SET(CMD_AGE),
> > +            lan9645x,
> > +            ANA_MACACCESS);
> > +
> > +     err = lan9645x_mac_wait_for_completion(lan9645x, NULL);
> > +     if (err)
> > +             goto mact_unlock;
> > +
> > +     lan_wr(ANA_MACACCESS_MAC_TABLE_CMD_SET(CMD_AGE),
> > +            lan9645x,
> > +            ANA_MACACCESS);
> > +
> > +     err = lan9645x_mac_wait_for_completion(lan9645x, NULL);
> > +
> > +mact_unlock:
> > +     lan_wr(0, lan9645x, ANA_ANAGEFIL);
> > +     mutex_unlock(&lan9645x->mact_lock);
> > +     return err;
> > +}
> > +
> > +int lan9645x_mact_entry_add(struct lan9645x *lan9645x, int pgid,
> > +                         const unsigned char *mac, u16 vid)
> > +{
> > +     struct lan9645x_mact_entry *entry;
> > +     int ret = 0;
> > +
> > +     /* Users can not move (vid,mac) to a different port, without removing
> > +      * the original entry first. But we overwrite entry in HW, and update
> > +      * software pgid for good measure.
> > +      */
> > +     mutex_lock(&lan9645x->mac_entry_lock);
> > +     entry = lan9645x_mact_entry_find(lan9645x, mac, vid);
> > +     if (entry) {
> > +             entry->common.pgid = pgid;
> > +             mutex_unlock(&lan9645x->mac_entry_lock);
> > +             goto mac_learn;
> > +     }
> > +
> > +     entry = lan9645x_mact_entry_alloc(lan9645x, mac, vid, pgid,
> > +                                       ENTRYTYPE_LOCKED);
> > +     if (!entry) {
> > +             mutex_unlock(&lan9645x->mac_entry_lock);
> > +             return -ENOMEM;
> > +     }
> > +
> > +     list_add_tail(&entry->list, &lan9645x->mac_entries);
> > +     mutex_unlock(&lan9645x->mac_entry_lock);
> > +
> > +mac_learn:
> > +     WARN_ON(entry->common.pgid != pgid);
> > +     ret = lan9645x_mact_learn(lan9645x, pgid, mac, vid, ENTRYTYPE_LOCKED);
> 
> Same comment about multiple critical sections getting opened and closed.
> It makes you wonder what can happen in between them. Any reason why you
> don't call __lan9645x_mact_learn()?
> 

There is a lock for the mac_entry list (mac_entry_lock) and one for the mac
table (mact_lock) which __lan9645x_mact_learn would not take. But they
are not used independently here, and as you mention not interleaved right.
I will strip this down to 1 lock for both mac_entry list and mac table.

> > +     if (ret) {
> > +             mutex_lock(&lan9645x->mac_entry_lock);
> > +             lan9645x_mact_entry_dealloc(lan9645x, entry);
> > +             mutex_unlock(&lan9645x->mac_entry_lock);
> > +     }
> > +     return ret;
> > +}
> > +
> > +int lan9645x_mact_entry_del(struct lan9645x *lan9645x, int pgid,
> > +                         const unsigned char *mac, u16 vid)
> > +{
> > +     struct lan9645x_mact_entry *entry;
> > +
> > +     mutex_lock(&lan9645x->mac_entry_lock);
> > +     entry = lan9645x_mact_entry_find(lan9645x, mac, vid);
> > +     if (entry) {
> > +             WARN_ON(entry->common.pgid != pgid);
> > +             lan9645x_mact_entry_dealloc(lan9645x, entry);
> > +             mutex_unlock(&lan9645x->mac_entry_lock);
> > +             goto forget;
> > +     }
> > +     mutex_unlock(&lan9645x->mac_entry_lock);
> > +     return -ENOENT;
> > +
> > +forget:
> > +     return lan9645x_mact_forget(lan9645x, mac, vid, ENTRYTYPE_LOCKED);
> 
> I don't understand why you release the mac_entry_lock just for
> lan9645x_mact_forget() to acquire it again. Can't stuff happen in the
> split second where the MAC table is unlocked? It seems at least more
> straightforward to call __lan9645x_mact_forget() under the locked
> section rather than do the jump.
> 
> And it also seems more straightforward to invert the branch where the
> entry is found in the MAC table with the one where it isn't. This allows
> the more complex code to be less indented.
> 

Yes, as mentioned above I think you are right about the gap, but they are
different locks. The idea was you could potentially iterate the list without
locking the mactable. But I will reduce it to 1 lock and use 
__lan9645x_mact_forget.

> > +}
> > +
> > +void lan9645x_mac_init(struct lan9645x *lan9645x)
> > +{
> > +     mutex_init(&lan9645x->mac_entry_lock);
> > +     mutex_init(&lan9645x->mact_lock);
> > +     mutex_init(&lan9645x->fwd_domain_lock);
> > +     INIT_LIST_HEAD(&lan9645x->mac_entries);
> > +
> > +     /* Clear the MAC table */
> > +     mutex_lock(&lan9645x->mact_lock);
> > +     lan_wr(CMD_INIT, lan9645x, ANA_MACACCESS);
> > +     lan9645x_mac_wait_for_completion(lan9645x, NULL);
> > +     mutex_unlock(&lan9645x->mact_lock);
> 
> mutex_init() immediately followed by mutex_lock() is an antipattern.
> mutex_init() is run from a context with no concurrent threads that can
> acquire the lock.
> mutex_lock() is run from a context where concurrent threads are possible.
> The two put together are a logical inconsistency, it means acquiring the
> lock is unnecessary.
> 

Thanks, I was not aware. I will remove the lock here.

> > +}
> > +
> > +void lan9645x_mac_deinit(struct lan9645x *lan9645x)
> > +{
> > +     mutex_destroy(&lan9645x->mac_entry_lock);
> > +     mutex_destroy(&lan9645x->mact_lock);
> > +     mutex_destroy(&lan9645x->fwd_domain_lock);
> > +}
> > +
> > +int lan9645x_mact_dsa_dump(struct lan9645x *lan9645x, int port,
> > +                        dsa_fdb_dump_cb_t *cb, void *data)
> > +{
> > +     struct lan9645x_mact_entry entry = { 0 };
> 
> Just {}.
> https://lore.kernel.org/netdev/20210810091238.GB1343@shell.armlinux.org.uk/
> 

I will change this where applicable.

> > +     u32 mach, macl, maca;
> > +     int err = 0;
> > +     u32 autoage;
> > +
> > +     mach = 0;
> > +     macl = 0;
> 
> You have two choices.
> 
> You can fold these into their declaration: "u32 mach = 0, macl = 0, maca;",
> _if_ you're going to write them as variables:
>         lan_wr(mach, lan9645x, ANA_MACHDATA);
>         lan_wr(macl, lan9645x, ANA_MACLDATA);
> 
> Or you can remove the initializer, which is overwritten by the first
> variable assignment in the while (1) loop, without the variables ever
> being read in the meantime.

> 
> 
> 
> I will just remove the initializers.
> 
> > +     entry.common.type = ENTRYTYPE_NORMAL;
> > +
> > +     mutex_lock(&lan9645x->mact_lock);
> > +
> > +     /* The aging filter works both for aging scans and GET_NEXT table scans.
> > +      * With it, the HW table iteration only stops at entries matching our
> > +      * filter. Since DSA calls us for each port on a table dump, this helps
> > +      * avoid unnecessary work.
> 
> Nice. I think this is the first driver I see which doesn't do duplicated
> work here. I vaguely remember testing this feature on Ocelot too, but it
> didn't work.
> 

With register IO over SPI this is painfully slow without the hardware iteration. Ocelot
is before my time, so I was not aware the age filters were broken there.

> > +      *
> > +      * Disable automatic aging temporarily. First save current state.
> > +      */
> > +     autoage = lan_rd(lan9645x, ANA_AUTOAGE);
> > +
> > +     /* Disable aging */
> > +     lan_rmw(ANA_AUTOAGE_AGE_PERIOD_SET(0),
> > +             ANA_AUTOAGE_AGE_PERIOD,
> > +             lan9645x, ANA_AUTOAGE);
> > +
> > +     /* Setup filter on our port */
> > +     lan_wr(ANA_ANAGEFIL_PID_EN_SET(1) |
> > +            ANA_ANAGEFIL_PID_VAL_SET(port),
> > +            lan9645x, ANA_ANAGEFIL);
> > +
> > +     lan_wr(0, lan9645x, ANA_MACHDATA);
> > +     lan_wr(0, lan9645x, ANA_MACLDATA);
> > +
> > +     while (1) {
> > +             /* NOTE: we rely on mach, macl and type being set correctly in
> > +              * the registers from previous round, vis a vis the GET_NEXT
> > +              * semantics, so locking entire loop is important.
> > +              */
> > +             lan_wr(ANA_MACACCESS_MAC_TABLE_CMD_SET(CMD_GET_NEXT) |
> > +                    ANA_MACACCESS_ENTRYTYPE_SET(entry.common.type),
> > +                    lan9645x, ANA_MACACCESS);
> > +
> > +             if (lan9645x_mac_wait_for_completion(lan9645x, &maca))
> > +                     break;
> > +
> > +             if (ANA_MACACCESS_VALID_GET(maca) == 0)
> > +                     break;
> > +
> > +             mach = lan_rd(lan9645x, ANA_MACHDATA);
> > +             macl = lan_rd(lan9645x, ANA_MACLDATA);
> > +
> > +             lan9645x_mact_parse(mach, macl, maca, &entry.common);
> > +
> > +             if (ANA_MACACCESS_DEST_IDX_GET(maca) == port &&
> > +                 entry.common.type == ENTRYTYPE_NORMAL) {
> > +                     if (entry.common.key.vid > VLAN_MAX)
> > +                             entry.common.key.vid = 0;
> > +
> > +                     err = cb(entry.common.key.mac, entry.common.key.vid,
> > +                              false, data);
> > +                     if (err)
> > +                             break;
> > +             }
> > +     }
> > +
> > +     /* Remove aging filters and restore aging */
> > +     lan_wr(0, lan9645x, ANA_ANAGEFIL);
> > +     lan_rmw(ANA_AUTOAGE_AGE_PERIOD_SET(ANA_AUTOAGE_AGE_PERIOD_GET(autoage)),
> > +             ANA_AUTOAGE_AGE_PERIOD,
> > +             lan9645x, ANA_AUTOAGE);
> > +
> > +     mutex_unlock(&lan9645x->mact_lock);
> > +
> > +     return err;
> > +}
> > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > index 1c8f20452487..ba76279b4414 100644
> > --- a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > @@ -78,6 +78,7 @@ static void lan9645x_teardown(struct dsa_switch *ds)
> > 
> >       debugfs_remove_recursive(lan9645x->debugfs_root);
> >       lan9645x_npi_port_deinit(lan9645x, lan9645x->npi);
> > +     lan9645x_mac_deinit(lan9645x);
> >  }
> > 
> >  static int lan9645x_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
> > @@ -171,8 +172,8 @@ static int lan9645x_setup(struct dsa_switch *ds)
> >               return err;
> >       }
> > 
> > -     mutex_init(&lan9645x->fwd_domain_lock);
> 
> Why did you have to move this to lan9645x_mac_init()? It has changed
> position since the beginning of the series. Also, it isn't related to
> the MAC table.
> 

I was just used to having it there, but I think you are right. I will keep it in
lan9645x_setup.

> 
> >       lan9645x_vlan_init(lan9645x);
> > +     lan9645x_mac_init(lan9645x);
> > 
> >       /* Link Aggregation Mode: NETDEV_LAG_HASH_L2 */
> >       lan_wr(ANA_AGGR_CFG_AC_SMAC_ENA |


  reply	other threads:[~2026-03-04 15:24 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-03 12:22 [PATCH net-next 0/8] net: dsa: add DSA support for the LAN9645x switch chip family Jens Emil Schulz Østergaard
2026-03-03 12:22 ` [PATCH net-next 1/8] net: dsa: add tag driver for LAN9645X Jens Emil Schulz Østergaard
2026-03-03 14:13   ` Andrew Lunn
2026-03-03 15:58     ` Jens Emil Schulz Ostergaard
2026-03-04 15:14       ` Andrew Lunn
2026-03-05 12:59         ` Jens Emil Schulz Ostergaard
2026-03-03 16:11   ` Vladimir Oltean
2026-03-05 13:53     ` Jens Emil Schulz Ostergaard
2026-03-04 15:23   ` Andrew Lunn
2026-03-05 13:01     ` Jens Emil Schulz Ostergaard
2026-03-03 12:22 ` [PATCH net-next 2/8] dt-bindings: net: lan9645x: add LAN9645X switch bindings Jens Emil Schulz Østergaard
2026-03-03 13:22   ` Vladimir Oltean
2026-03-03 16:00     ` Jens Emil Schulz Ostergaard
2026-03-03 14:18   ` Andrew Lunn
2026-03-03 19:04     ` Conor Dooley
2026-03-04 15:57       ` Jens Emil Schulz Ostergaard
2026-03-05 12:57       ` Jens Emil Schulz Ostergaard
2026-03-05 18:31         ` Conor Dooley
2026-03-06 15:08           ` Jens Emil Schulz Ostergaard
2026-03-06 15:20             ` Conor Dooley
2026-03-18 14:19               ` Jens Emil Schulz Ostergaard
2026-03-18 17:18                 ` Conor Dooley
2026-03-18 17:20                   ` Conor Dooley
2026-03-18 17:26                     ` Christian Marangi
2026-03-24 10:31                       ` Jens Emil Schulz Ostergaard
2026-03-04 15:55     ` Jens Emil Schulz Ostergaard
2026-03-03 18:49   ` Conor Dooley
2026-03-04 15:58     ` Jens Emil Schulz Ostergaard
2026-03-03 18:56   ` Conor Dooley
2026-03-04 16:10     ` Jens Emil Schulz Ostergaard
2026-03-04 16:14       ` Vladimir Oltean
2026-03-04 19:06         ` Conor Dooley
2026-03-05 13:08           ` Jens Emil Schulz Ostergaard
2026-03-03 12:22 ` [PATCH net-next 3/8] net: dsa: lan9645x: add autogenerated register macros Jens Emil Schulz Østergaard
2026-03-03 12:22 ` [PATCH net-next 4/8] net: dsa: lan9645x: add basic dsa driver for LAN9645X Jens Emil Schulz Østergaard
2026-03-03 14:15   ` Vladimir Oltean
2026-03-04 14:37     ` Jens Emil Schulz Ostergaard
2026-03-04 15:58   ` Russell King (Oracle)
2026-03-05 14:24     ` Jens Emil Schulz Ostergaard
2026-03-05 14:58       ` Andrew Lunn
2026-03-05 15:10         ` Vladimir Oltean
2026-03-05 16:54         ` Alexander Stein
2026-03-05 17:37           ` Andrew Lunn
2026-03-06 15:03             ` Jens Emil Schulz Ostergaard
2026-03-06 16:33               ` Andrew Lunn
2026-03-09 12:01                 ` Jens Emil Schulz Ostergaard
2026-03-06 14:22         ` Russell King (Oracle)
2026-03-06 21:03           ` Jakub Kicinski
2026-03-03 12:22 ` [PATCH net-next 5/8] net: dsa: lan9645x: add bridge support Jens Emil Schulz Østergaard
2026-03-03 14:20   ` Vladimir Oltean
2026-03-03 16:08     ` Jens Emil Schulz Ostergaard
2026-03-03 16:17       ` Vladimir Oltean
2026-03-05 13:14         ` Jens Emil Schulz Ostergaard
2026-03-03 14:51   ` Vladimir Oltean
2026-03-09 12:09     ` Jens Emil Schulz Ostergaard
2026-03-03 12:22 ` [PATCH net-next 6/8] net: dsa: lan9645x: add vlan support Jens Emil Schulz Østergaard
2026-03-03 14:59   ` Vladimir Oltean
2026-03-04 14:40     ` Jens Emil Schulz Ostergaard
2026-03-04 14:52       ` Vladimir Oltean
2026-03-03 12:22 ` [PATCH net-next 7/8] net: dsa: lan9645x: add mac table integration Jens Emil Schulz Østergaard
2026-03-03 15:27   ` Vladimir Oltean
2026-03-04 15:23     ` Jens Emil Schulz Ostergaard [this message]
2026-03-04 15:34       ` Andrew Lunn
2026-03-05 13:17         ` Jens Emil Schulz Ostergaard
2026-03-03 12:22 ` [PATCH net-next 8/8] net: dsa: lan9645x: add port statistics Jens Emil Schulz Østergaard
2026-03-03 16:01   ` Vladimir Oltean
2026-03-03 20:21     ` Andrew Lunn
2026-03-04 15:51       ` Jens Emil Schulz Ostergaard
2026-03-04 15:50     ` Jens Emil Schulz Ostergaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=67a34d22b8f59964fd3bfaee99c8418a21526f3e.camel@microchip.com \
    --to=jensemil.schulzostergaard@microchip.com \
    --cc=Steen.Hegelund@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=daniel.machon@microchip.com \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    --cc=woojung.huh@microchip.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox