When CPU transmit directly to port using tag, the LAN9303 does not
learn MAC addresses received on the CPU port into the ALR table.
ALR learning is performed only when transmitting using ALR lookup.
Solution:
If the two external ports are bridged and the packet is not STP BPDU,
then use ALR lookup to allow ALR learning on CPU port.
Otherwise transmit directly to port with STP state override.
The first patch moves struct lan9303 to include/linux/lan9303.h in order
to prepare for the second patch.
Egil Hjelmeland (2):
net: dsa: lan9303: Move struct lan9303 to include/linux/lan9303.h
net: dsa: lan9303: Learn addresses on CPU port when bridged
MAINTAINERS | 1 +
drivers/net/dsa/lan9303.h | 34 +---------------------------------
include/linux/lan9303.h | 35 +++++++++++++++++++++++++++++++++++
net/dsa/tag_lan9303.c | 23 ++++++++++++++++++++++-
4 files changed, 59 insertions(+), 34 deletions(-)
create mode 100644 include/linux/lan9303.h
--
2.11.0
When CPU transmit directly to port using tag, the LAN9303 does not
learn MAC addresses received on the CPU port into the ALR.
ALR learning is performed only when transmitting using ALR lookup.
Solution:
If the two external ports are bridged and the packet is not STP BPDU,
then use ALR lookup to allow ALR learning on CPU port.
Otherwise transmit directly to port with STP state override.
Signed-off-by: Egil Hjelmeland <redacted>
---
net/dsa/tag_lan9303.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
@@ -2,39 +2,7 @@#include<linux/device.h>#include<net/dsa.h>-structlan9303;--structlan9303_phy_ops{-/* PHY 1 and 2 access*/-int(*phy_read)(structlan9303*chip,intport,intregnum);-int(*phy_write)(structlan9303*chip,intport,-intregnum,u16val);-};--#define LAN9303_NUM_ALR_RECORDS 512-structlan9303_alr_cache_entry{-u8mac_addr[ETH_ALEN];-u8port_map;/* Bitmap of ports. Zero if unused entry */-u8stp_override;/* non zero if set ALR_DAT1_AGE_OVERRID */-};--structlan9303{-structdevice*dev;-structregmap*regmap;-structregmap_irq_chip_data*irq_data;-structgpio_desc*reset_gpio;-u32reset_duration;/* in [ms] */-boolphy_addr_sel_strap;-structdsa_switch*ds;-structmutexindirect_mutex;/* protect indexed register access */-conststructlan9303_phy_ops*ops;-boolis_bridged;/* true if port 1 and 2 are bridged */-u32swe_port_state;/* remember SWE_PORT_STATE while not bridged */-/* LAN9303 do not offer reading specific ALR entry. Cache all-*staticentriesinaflattable-**/-structlan9303_alr_cache_entryalr_cache[LAN9303_NUM_ALR_RECORDS];-};+#include<linux/lan9303.h>externconststructregmap_access_tablelan9303_register_set;externconststructlan9303_phy_opslan9303_indirect_phy_ops;
@@ -0,0 +1,35 @@+/* Included by drivers/net/dsa/lan9303.h and net/dsa/tag_lan9303.c */++structlan9303;++structlan9303_phy_ops{+/* PHY 1 and 2 access*/+int(*phy_read)(structlan9303*chip,intport,intregnum);+int(*phy_write)(structlan9303*chip,intport,+intregnum,u16val);+};++#define LAN9303_NUM_ALR_RECORDS 512+structlan9303_alr_cache_entry{+u8mac_addr[ETH_ALEN];+u8port_map;/* Bitmap of ports. Zero if unused entry */+u8stp_override;/* non zero if set ALR_DAT1_AGE_OVERRID */+};++structlan9303{+structdevice*dev;+structregmap*regmap;+structregmap_irq_chip_data*irq_data;+structgpio_desc*reset_gpio;+u32reset_duration;/* in [ms] */+boolphy_addr_sel_strap;+structdsa_switch*ds;+structmutexindirect_mutex;/* protect indexed register access */+conststructlan9303_phy_ops*ops;+boolis_bridged;/* true if port 1 and 2 are bridged */+u32swe_port_state;/* remember SWE_PORT_STATE while not bridged */+/* LAN9303 do not offer reading specific ALR entry. Cache all+*staticentriesinaflattable+**/+structlan9303_alr_cache_entryalr_cache[LAN9303_NUM_ALR_RECORDS];+};
From: Andrew Lunn <andrew@lunn.ch> Date: 2017-10-24 16:32:01
On Tue, Oct 24, 2017 at 11:35:14AM +0200, Egil Hjelmeland wrote:
The next patch require net/dsa/tag_lan9303.c to access struct lan9303.
Therefore move struct lan9303 definitions from drivers/net/dsa/lan9303.h
to new file include/linux/lan9303.h.
Signed-off-by: Egil Hjelmeland <redacted>
O.K, so not too bad.
I am now however wondering if include/linux/dsa/lan9303.h would be
better?
Anyway,
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
From: Andrew Lunn <andrew@lunn.ch> Date: 2017-10-24 16:33:43
On Tue, Oct 24, 2017 at 11:35:15AM +0200, Egil Hjelmeland wrote:
quoted hunk
When CPU transmit directly to port using tag, the LAN9303 does not
learn MAC addresses received on the CPU port into the ALR.
ALR learning is performed only when transmitting using ALR lookup.
Solution:
If the two external ports are bridged and the packet is not STP BPDU,
then use ALR lookup to allow ALR learning on CPU port.
Otherwise transmit directly to port with STP state override.
Signed-off-by: Egil Hjelmeland <redacted>
---
net/dsa/tag_lan9303.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
How about using skb_mac_header(skb) than skb->data?
quoted
+ LAN9303_TAG_TX_USE_ALR :
+ dp->index |
I am not the expert here.
I see that skb_mac_header() is (skb->head + skb->mac_header). So it will
cost a few nano seconds per packet. Not the end of the world though.
But I see that other net/dsa/tag_*.c use skb->data, assuming that
skb->data point to mac header.
Anyway, it may be an idea to decrement skb->mac_header, in case the
master interface driver uses it? What about skb->mac_len?
If to use skb_mac_header() at all, I would replace all use of skb->data,
like this:
---
/* provide 'LAN9303_TAG_LEN' bytes additional space */
skb_push(skb, LAN9303_TAG_LEN);
/* make room between MACs and Ether-Type */
memmove(skb_mac_header(skb) - LAN9303_TAG_LEN, skb_mac_header(skb),
2 * ETH_ALEN);
skb->mac_header -= LAN9303_TAG_LEN;
lan9303_tag = (u16 *)(skb_mac_header(skb) + 2 * ETH_ALEN);
lan9303_tag[0] = htons(ETH_P_8021Q);
lan9303_tag[1] = lan9303_tx_use_arl(dp, skb_mac_header(skb)) ?
LAN9303_TAG_TX_USE_ALR :
dp->index | LAN9303_TAG_TX_STP_OVERRIDE;
lan9303_tag[1] = htons(lan9303_tag[1]);
---
But I will really like to hear the opinion from more people on this
before going down that road. Anyway, I think it would belong to a
separate patch.
On Tue, Oct 24, 2017 at 11:35:14AM +0200, Egil Hjelmeland wrote:
quoted
The next patch require net/dsa/tag_lan9303.c to access struct lan9303.
Therefore move struct lan9303 definitions from drivers/net/dsa/lan9303.h
to new file include/linux/lan9303.h.
Signed-off-by: Egil Hjelmeland <redacted>
O.K, so not too bad.
I am now however wondering if include/linux/dsa/lan9303.h would be
better?
Me too. I can do that.
Anyway,
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
How about using skb_mac_header(skb) than skb->data?
quoted
+ LAN9303_TAG_TX_USE_ALR :
+ dp->index |
I am not the expert here.
I see that skb_mac_header() is (skb->head + skb->mac_header). So it will
cost a few nano seconds per packet. Not the end of the world though.
But I see that other net/dsa/tag_*.c use skb->data, assuming that
skb->data point to mac header.
Revisited skb_mac_header(). It is basically skb->data after math.
Understand that it would be extra steps than referring skb->data directly.
Unless no one comments on this, please keep first patch.
Thanks.
Woojung