* [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
@ 2016-09-19 23:56 Vivien Didelot
2016-09-20 0:19 ` Andrew Lunn
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Vivien Didelot @ 2016-09-19 23:56 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
An address can be loaded in the ATU with multiple ports, for instance
when adding multiple ports to a Multicast group with "bridge mdb".
The current code doesn't allow that. Add an helper to get a single entry
from the ATU, then set or clear the requested port, before loading the
entry back in the ATU.
Note that the required _mv88e6xxx_atu_getnext function is defined below
mv88e6xxx_port_db_load_purge, so forward-declare it for the moment. The
ATU code will be isolated in future patches.
Fixes: 83dabd1fa84c ("net: dsa: mv88e6xxx: make switchdev DB ops generic")
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 56 +++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 7 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 70a812d..1d71802 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2091,12 +2091,48 @@ static int _mv88e6xxx_atu_load(struct mv88e6xxx_chip *chip,
return _mv88e6xxx_atu_cmd(chip, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
}
+static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
+ struct mv88e6xxx_atu_entry *entry);
+
+static int mv88e6xxx_atu_get(struct mv88e6xxx_chip *chip, int fid,
+ const u8 *addr, struct mv88e6xxx_atu_entry *entry)
+{
+ struct mv88e6xxx_atu_entry next;
+ int err;
+
+ eth_broadcast_addr(next.mac);
+
+ err = _mv88e6xxx_atu_mac_write(chip, next.mac);
+ if (err)
+ return err;
+
+ do {
+ err = _mv88e6xxx_atu_getnext(chip, fid, &next);
+ if (err)
+ return err;
+
+ if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
+ break;
+
+ if (ether_addr_equal(next.mac, addr)) {
+ *entry = next;
+ return 0;
+ }
+ } while (!is_broadcast_ether_addr(next.mac));
+
+ memset(entry, 0, sizeof(*entry));
+ entry->fid = fid;
+ ether_addr_copy(entry->mac, addr);
+
+ return 0;
+}
+
static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
const unsigned char *addr, u16 vid,
u8 state)
{
- struct mv88e6xxx_atu_entry entry = { 0 };
struct mv88e6xxx_vtu_stu_entry vlan;
+ struct mv88e6xxx_atu_entry entry;
int err;
/* Null VLAN ID corresponds to the port private database */
@@ -2107,12 +2143,18 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
if (err)
return err;
- entry.fid = vlan.fid;
- entry.state = state;
- ether_addr_copy(entry.mac, addr);
- if (state != GLOBAL_ATU_DATA_STATE_UNUSED) {
- entry.trunk = false;
- entry.portv_trunkid = BIT(port);
+ err = mv88e6xxx_atu_get(chip, vlan.fid, addr, &entry);
+ if (err)
+ return err;
+
+ /* Purge the ATU entry only if no port is using it anymore */
+ if (state == GLOBAL_ATU_DATA_STATE_UNUSED) {
+ entry.portv_trunkid &= ~BIT(port);
+ if (!entry.portv_trunkid)
+ entry.state = GLOBAL_ATU_DATA_STATE_UNUSED;
+ } else {
+ entry.portv_trunkid |= BIT(port);
+ entry.state = state;
}
return _mv88e6xxx_atu_load(chip, &entry);
--
2.10.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-19 23:56 [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU Vivien Didelot
@ 2016-09-20 0:19 ` Andrew Lunn
2016-09-20 0:29 ` Vivien Didelot
2016-09-20 0:41 ` Andrew Lunn
2016-09-21 4:05 ` David Miller
2 siblings, 1 reply; 8+ messages in thread
From: Andrew Lunn @ 2016-09-20 0:19 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
Hi Vivien
> + do {
> + err = _mv88e6xxx_atu_getnext(chip, fid, &next);
> + if (err)
> + return err;
> +
> + if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
> + break;
> +
> + if (ether_addr_equal(next.mac, addr)) {
> + *entry = next;
> + return 0;
> + }
> + } while (!is_broadcast_ether_addr(next.mac));
This is correct, but i wonder how well it scales? When we have a lot
of entries in the ATU, this is going to take time. At some point in
the future, we might want to keep a shadow copy of static entries of
the ATU in RAM. We then don't need to search for them.
But that is for later, once we have some complaints this is too slow.
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-20 0:19 ` Andrew Lunn
@ 2016-09-20 0:29 ` Vivien Didelot
2016-09-20 0:32 ` Andrew Lunn
0 siblings, 1 reply; 8+ messages in thread
From: Vivien Didelot @ 2016-09-20 0:29 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
Hi Andrew,
Andrew Lunn <andrew@lunn.ch> writes:
> Hi Vivien
>
>> + do {
>> + err = _mv88e6xxx_atu_getnext(chip, fid, &next);
>> + if (err)
>> + return err;
>> +
>> + if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
>> + break;
>> +
>> + if (ether_addr_equal(next.mac, addr)) {
>> + *entry = next;
>> + return 0;
>> + }
>> + } while (!is_broadcast_ether_addr(next.mac));
>
> This is correct, but i wonder how well it scales? When we have a lot
> of entries in the ATU, this is going to take time. At some point in
> the future, we might want to keep a shadow copy of static entries of
> the ATU in RAM. We then don't need to search for them.
There won't be any issue about time here, because we are searching a
precise FID. What takes time is dumping the whole 4095 FIDs at once.
> But that is for later, once we have some complaints this is too slow.
Yes, there are severals things we can cache in this driver, but to be
honest I'd prefer not to cache anything for the moment, until the driver
is robust. Caching data must be the very last point IMO.
Thanks,
Vivien
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-20 0:29 ` Vivien Didelot
@ 2016-09-20 0:32 ` Andrew Lunn
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2016-09-20 0:32 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
On Mon, Sep 19, 2016 at 08:29:40PM -0400, Vivien Didelot wrote:
> Hi Andrew,
>
> Andrew Lunn <andrew@lunn.ch> writes:
>
> > Hi Vivien
> >
> >> + do {
> >> + err = _mv88e6xxx_atu_getnext(chip, fid, &next);
> >> + if (err)
> >> + return err;
> >> +
> >> + if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
> >> + break;
> >> +
> >> + if (ether_addr_equal(next.mac, addr)) {
> >> + *entry = next;
> >> + return 0;
> >> + }
> >> + } while (!is_broadcast_ether_addr(next.mac));
> >
> > This is correct, but i wonder how well it scales? When we have a lot
> > of entries in the ATU, this is going to take time. At some point in
> > the future, we might want to keep a shadow copy of static entries of
> > the ATU in RAM. We then don't need to search for them.
>
> There won't be any issue about time here, because we are searching a
> precise FID.
Ah, i didn't realise you can do that. However, it makes sense, the
hardware needs to do it all the time when it receives a frame.
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-19 23:56 [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU Vivien Didelot
2016-09-20 0:19 ` Andrew Lunn
@ 2016-09-20 0:41 ` Andrew Lunn
2016-09-20 1:07 ` Vivien Didelot
2016-09-21 4:05 ` David Miller
2 siblings, 1 reply; 8+ messages in thread
From: Andrew Lunn @ 2016-09-20 0:41 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
On Mon, Sep 19, 2016 at 07:56:11PM -0400, Vivien Didelot wrote:
> An address can be loaded in the ATU with multiple ports, for instance
> when adding multiple ports to a Multicast group with "bridge mdb".
>
> The current code doesn't allow that. Add an helper to get a single entry
> from the ATU, then set or clear the requested port, before loading the
> entry back in the ATU.
>
> Note that the required _mv88e6xxx_atu_getnext function is defined below
> mv88e6xxx_port_db_load_purge, so forward-declare it for the moment. The
> ATU code will be isolated in future patches.
>
> Fixes: 83dabd1fa84c ("net: dsa: mv88e6xxx: make switchdev DB ops generic")
Is this a real fixes? You don't make it clear what goes wrong. I
assume adding the same MAC address for a second time but for a
different port removes the first entry for the old port?
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-20 0:41 ` Andrew Lunn
@ 2016-09-20 1:07 ` Vivien Didelot
2016-09-20 23:42 ` Andrew Lunn
0 siblings, 1 reply; 8+ messages in thread
From: Vivien Didelot @ 2016-09-20 1:07 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
Hi Andrew,
Andrew Lunn <andrew@lunn.ch> writes:
> On Mon, Sep 19, 2016 at 07:56:11PM -0400, Vivien Didelot wrote:
>> An address can be loaded in the ATU with multiple ports, for instance
>> when adding multiple ports to a Multicast group with "bridge mdb".
>>
>> The current code doesn't allow that. Add an helper to get a single entry
>> from the ATU, then set or clear the requested port, before loading the
>> entry back in the ATU.
>>
>> Note that the required _mv88e6xxx_atu_getnext function is defined below
>> mv88e6xxx_port_db_load_purge, so forward-declare it for the moment. The
>> ATU code will be isolated in future patches.
>>
>> Fixes: 83dabd1fa84c ("net: dsa: mv88e6xxx: make switchdev DB ops generic")
>
> Is this a real fixes? You don't make it clear what goes wrong. I
> assume adding the same MAC address for a second time but for a
> different port removes the first entry for the old port?
Yes, this is what happens, sorry for the bad message. Below is an
example with the relevant hardware bits.
Here's the current behavior, without this patch:
# bridge mdb add dev br0 port lan0 grp 238.39.20.86
FID MAC Addr State Trunk? DPV/Trunk ID
0 01:00:5e:27:14:56 MC_STATIC n 0 - - - - - -
# bridge mdb add dev br0 port lan2 grp 238.39.20.86
FID MAC Addr State Trunk? DPV/Trunk ID
0 01:00:5e:27:14:56 MC_STATIC n - - 2 - - - -
Here's the new behavior, with this patch:
# bridge mdb add dev br0 port lan0 grp 238.39.20.86
FID MAC Addr State Trunk? DPV/Trunk ID
0 01:00:5e:27:14:56 MC_STATIC n 0 - - - - - -
# bridge mdb add dev br0 port lan2 grp 238.39.20.86
FID MAC Addr State Trunk? DPV/Trunk ID
0 01:00:5e:27:14:56 MC_STATIC n 0 - 2 - - - -
Thanks!
Vivien
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-20 1:07 ` Vivien Didelot
@ 2016-09-20 23:42 ` Andrew Lunn
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2016-09-20 23:42 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
On Mon, Sep 19, 2016 at 09:07:16PM -0400, Vivien Didelot wrote:
> Hi Andrew,
>
> Andrew Lunn <andrew@lunn.ch> writes:
>
> > On Mon, Sep 19, 2016 at 07:56:11PM -0400, Vivien Didelot wrote:
> >> An address can be loaded in the ATU with multiple ports, for instance
> >> when adding multiple ports to a Multicast group with "bridge mdb".
> >>
> >> The current code doesn't allow that. Add an helper to get a single entry
> >> from the ATU, then set or clear the requested port, before loading the
> >> entry back in the ATU.
> >>
> >> Note that the required _mv88e6xxx_atu_getnext function is defined below
> >> mv88e6xxx_port_db_load_purge, so forward-declare it for the moment. The
> >> ATU code will be isolated in future patches.
> >>
> >> Fixes: 83dabd1fa84c ("net: dsa: mv88e6xxx: make switchdev DB ops generic")
> >
> > Is this a real fixes? You don't make it clear what goes wrong. I
> > assume adding the same MAC address for a second time but for a
> > different port removes the first entry for the old port?
>
> Yes, this is what happens, sorry for the bad message. Below is an
> example with the relevant hardware bits.
>
> Here's the current behavior, without this patch:
>
> # bridge mdb add dev br0 port lan0 grp 238.39.20.86
>
> FID MAC Addr State Trunk? DPV/Trunk ID
> 0 01:00:5e:27:14:56 MC_STATIC n 0 - - - - - -
>
> # bridge mdb add dev br0 port lan2 grp 238.39.20.86
>
> FID MAC Addr State Trunk? DPV/Trunk ID
> 0 01:00:5e:27:14:56 MC_STATIC n - - 2 - - - -
>
> Here's the new behavior, with this patch:
>
> # bridge mdb add dev br0 port lan0 grp 238.39.20.86
>
> FID MAC Addr State Trunk? DPV/Trunk ID
> 0 01:00:5e:27:14:56 MC_STATIC n 0 - - - - - -
>
> # bridge mdb add dev br0 port lan2 grp 238.39.20.86
>
> FID MAC Addr State Trunk? DPV/Trunk ID
> 0 01:00:5e:27:14:56 MC_STATIC n 0 - 2 - - - -
Hi Vivien
it would be nice to update the commit message with this text.
Otherwise
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU
2016-09-19 23:56 [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU Vivien Didelot
2016-09-20 0:19 ` Andrew Lunn
2016-09-20 0:41 ` Andrew Lunn
@ 2016-09-21 4:05 ` David Miller
2 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2016-09-21 4:05 UTC (permalink / raw)
To: vivien.didelot; +Cc: netdev, linux-kernel, kernel, f.fainelli, andrew
From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Date: Mon, 19 Sep 2016 19:56:11 -0400
> An address can be loaded in the ATU with multiple ports, for instance
> when adding multiple ports to a Multicast group with "bridge mdb".
>
> The current code doesn't allow that. Add an helper to get a single entry
> from the ATU, then set or clear the requested port, before loading the
> entry back in the ATU.
>
> Note that the required _mv88e6xxx_atu_getnext function is defined below
> mv88e6xxx_port_db_load_purge, so forward-declare it for the moment. The
> ATU code will be isolated in future patches.
>
> Fixes: 83dabd1fa84c ("net: dsa: mv88e6xxx: make switchdev DB ops generic")
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Applied.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-09-21 4:05 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-19 23:56 [PATCH net-next] net: dsa: mv88e6xxx: handle multiple ports in ATU Vivien Didelot
2016-09-20 0:19 ` Andrew Lunn
2016-09-20 0:29 ` Vivien Didelot
2016-09-20 0:32 ` Andrew Lunn
2016-09-20 0:41 ` Andrew Lunn
2016-09-20 1:07 ` Vivien Didelot
2016-09-20 23:42 ` Andrew Lunn
2016-09-21 4:05 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).