Commit c5bcdd82 authored by David S. Miller's avatar David S. Miller

Merge branch 'lan966x-extend-switchdev-and-mdb-support'

Horatiu Vultur says:

====================
net: lan966x: Extend switchdev with mdb support

This patch series extends lan966x with mdb support by implementing
the switchdev callbacks: SWITCHDEV_OBJ_ID_PORT_MDB and
SWITCHDEV_OBJ_ID_HOST_MDB.
It adds support for both ipv4/ipv6 entries and l2 entries.

v2->v3:
- rename PGID_FIRST and PGID_LAST to PGID_GP_START and PGID_GP_END
- don't forget and relearn an entry for the CPU if there are more
  references to the cpu.

v1->v2:
- rename lan966x_mac_learn_impl to __lan966x_mac_learn
- rename lan966x_mac_cpu_copy to lan966x_mac_ip_learn
- fix grammar and typos in comments and commit messages
- add reference counter for entries that copy frames to CPU
====================
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2a5ab39b 7aacb894
......@@ -7,4 +7,4 @@ obj-$(CONFIG_LAN966X_SWITCH) += lan966x-switch.o
lan966x-switch-objs := lan966x_main.o lan966x_phylink.o lan966x_port.o \
lan966x_mac.o lan966x_ethtool.o lan966x_switchdev.o \
lan966x_vlan.o lan966x_fdb.o
lan966x_vlan.o lan966x_fdb.o lan966x_mdb.o
......@@ -68,17 +68,19 @@ static void lan966x_mac_select(struct lan966x *lan966x,
lan_wr(mach, lan966x, ANA_MACHDATA);
}
int lan966x_mac_learn(struct lan966x *lan966x, int port,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
enum macaccess_entry_type type)
static int __lan966x_mac_learn(struct lan966x *lan966x, int pgid,
bool cpu_copy,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
enum macaccess_entry_type type)
{
lan966x_mac_select(lan966x, mac, vid);
/* Issue a write command */
lan_wr(ANA_MACACCESS_VALID_SET(1) |
ANA_MACACCESS_CHANGE2SW_SET(0) |
ANA_MACACCESS_DEST_IDX_SET(port) |
ANA_MACACCESS_MAC_CPU_COPY_SET(cpu_copy) |
ANA_MACACCESS_DEST_IDX_SET(pgid) |
ANA_MACACCESS_ENTRYTYPE_SET(type) |
ANA_MACACCESS_MAC_TABLE_CMD_SET(MACACCESS_CMD_LEARN),
lan966x, ANA_MACACCESS);
......@@ -86,6 +88,30 @@ int lan966x_mac_learn(struct lan966x *lan966x, int port,
return lan966x_mac_wait_for_completion(lan966x);
}
/* The mask of the front ports is encoded inside the mac parameter via a call
* to lan966x_mdb_encode_mac().
*/
int lan966x_mac_ip_learn(struct lan966x *lan966x,
bool cpu_copy,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
enum macaccess_entry_type type)
{
WARN_ON(type != ENTRYTYPE_MACV4 && type != ENTRYTYPE_MACV6);
return __lan966x_mac_learn(lan966x, 0, cpu_copy, mac, vid, type);
}
int lan966x_mac_learn(struct lan966x *lan966x, int port,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
enum macaccess_entry_type type)
{
WARN_ON(type != ENTRYTYPE_NORMAL && type != ENTRYTYPE_LOCKED);
return __lan966x_mac_learn(lan966x, port, false, mac, vid, type);
}
int lan966x_mac_forget(struct lan966x *lan966x,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
......
......@@ -926,6 +926,7 @@ static int lan966x_probe(struct platform_device *pdev)
lan966x_port_init(lan966x->ports[p]);
}
lan966x_mdb_init(lan966x);
err = lan966x_fdb_init(lan966x);
if (err)
goto cleanup_ports;
......@@ -955,6 +956,7 @@ static int lan966x_remove(struct platform_device *pdev)
mutex_destroy(&lan966x->stats_lock);
lan966x_mac_purge_entries(lan966x);
lan966x_mdb_deinit(lan966x);
lan966x_fdb_deinit(lan966x);
return 0;
......
......@@ -30,6 +30,8 @@
/* Reserved amount for (SRC, PRIO) at index 8*SRC + PRIO */
#define QSYS_Q_RSRV 95
#define CPU_PORT 8
/* Reserved PGIDs */
#define PGID_CPU (PGID_AGGR - 6)
#define PGID_UC (PGID_AGGR - 5)
......@@ -38,14 +40,16 @@
#define PGID_MCIPV4 (PGID_AGGR - 2)
#define PGID_MCIPV6 (PGID_AGGR - 1)
/* Non-reserved PGIDs, used for general purpose */
#define PGID_GP_START (CPU_PORT + 1)
#define PGID_GP_END PGID_CPU
#define LAN966X_SPEED_NONE 0
#define LAN966X_SPEED_2500 1
#define LAN966X_SPEED_1000 1
#define LAN966X_SPEED_100 2
#define LAN966X_SPEED_10 3
#define CPU_PORT 8
/* MAC table entry types.
* ENTRYTYPE_NORMAL is subject to aging.
* ENTRYTYPE_LOCKED is not subject to aging.
......@@ -105,6 +109,10 @@ struct lan966x {
/* worqueue for fdb */
struct workqueue_struct *fdb_work;
struct list_head fdb_entries;
/* mdb */
struct list_head mdb_entries;
struct list_head pgid_entries;
};
struct lan966x_port_config {
......@@ -157,6 +165,11 @@ int lan966x_port_pcs_set(struct lan966x_port *port,
struct lan966x_port_config *config);
void lan966x_port_init(struct lan966x_port *port);
int lan966x_mac_ip_learn(struct lan966x *lan966x,
bool cpu_copy,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
enum macaccess_entry_type type);
int lan966x_mac_learn(struct lan966x *lan966x, int port,
const unsigned char mac[ETH_ALEN],
unsigned int vid,
......@@ -206,6 +219,15 @@ int lan966x_handle_fdb(struct net_device *dev,
unsigned long event, const void *ctx,
const struct switchdev_notifier_fdb_info *fdb_info);
void lan966x_mdb_init(struct lan966x *lan966x);
void lan966x_mdb_deinit(struct lan966x *lan966x);
int lan966x_handle_port_mdb_add(struct lan966x_port *port,
const struct switchdev_obj *obj);
int lan966x_handle_port_mdb_del(struct lan966x_port *port,
const struct switchdev_obj *obj);
void lan966x_mdb_erase_entries(struct lan966x *lan966x, u16 vid);
void lan966x_mdb_write_entries(struct lan966x *lan966x, u16 vid);
static inline void __iomem *lan_addr(void __iomem *base[],
int id, int tinst, int tcnt,
int gbase, int ginst,
......
This diff is collapsed.
......@@ -169,6 +169,12 @@ enum lan966x_target {
#define ANA_MACACCESS_CHANGE2SW_GET(x)\
FIELD_GET(ANA_MACACCESS_CHANGE2SW, x)
#define ANA_MACACCESS_MAC_CPU_COPY BIT(16)
#define ANA_MACACCESS_MAC_CPU_COPY_SET(x)\
FIELD_PREP(ANA_MACACCESS_MAC_CPU_COPY, x)
#define ANA_MACACCESS_MAC_CPU_COPY_GET(x)\
FIELD_GET(ANA_MACACCESS_MAC_CPU_COPY, x)
#define ANA_MACACCESS_VALID BIT(12)
#define ANA_MACACCESS_VALID_SET(x)\
FIELD_PREP(ANA_MACACCESS_VALID, x)
......
......@@ -438,6 +438,10 @@ static int lan966x_handle_port_obj_add(struct net_device *dev, const void *ctx,
case SWITCHDEV_OBJ_ID_PORT_VLAN:
err = lan966x_handle_port_vlan_add(port, obj);
break;
case SWITCHDEV_OBJ_ID_PORT_MDB:
case SWITCHDEV_OBJ_ID_HOST_MDB:
err = lan966x_handle_port_mdb_add(port, obj);
break;
default:
err = -EOPNOTSUPP;
break;
......@@ -473,6 +477,10 @@ static int lan966x_handle_port_obj_del(struct net_device *dev, const void *ctx,
case SWITCHDEV_OBJ_ID_PORT_VLAN:
err = lan966x_handle_port_vlan_del(port, obj);
break;
case SWITCHDEV_OBJ_ID_PORT_MDB:
case SWITCHDEV_OBJ_ID_HOST_MDB:
err = lan966x_handle_port_mdb_del(port, obj);
break;
default:
err = -EOPNOTSUPP;
break;
......
......@@ -219,6 +219,7 @@ void lan966x_vlan_port_add_vlan(struct lan966x_port *port,
if (lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x, vid)) {
lan966x_vlan_cpu_add_vlan_mask(lan966x, vid);
lan966x_fdb_write_entries(lan966x, vid);
lan966x_mdb_write_entries(lan966x, vid);
}
lan966x_vlan_port_set_vid(port, vid, pvid, untagged);
......@@ -241,6 +242,7 @@ void lan966x_vlan_port_del_vlan(struct lan966x_port *port, u16 vid)
if (!lan966x_vlan_port_any_vlan_mask(lan966x, vid)) {
lan966x_vlan_cpu_del_vlan_mask(lan966x, vid);
lan966x_fdb_erase_entries(lan966x, vid);
lan966x_mdb_erase_entries(lan966x, vid);
}
}
......@@ -254,8 +256,10 @@ void lan966x_vlan_cpu_add_vlan(struct lan966x *lan966x, u16 vid)
* information so when a front port is added then it would add also the
* CPU port.
*/
if (lan966x_vlan_port_any_vlan_mask(lan966x, vid))
if (lan966x_vlan_port_any_vlan_mask(lan966x, vid)) {
lan966x_vlan_cpu_add_vlan_mask(lan966x, vid);
lan966x_mdb_write_entries(lan966x, vid);
}
lan966x_vlan_cpu_add_cpu_vlan_mask(lan966x, vid);
lan966x_fdb_write_entries(lan966x, vid);
......@@ -267,6 +271,7 @@ void lan966x_vlan_cpu_del_vlan(struct lan966x *lan966x, u16 vid)
lan966x_vlan_cpu_del_cpu_vlan_mask(lan966x, vid);
lan966x_vlan_cpu_del_vlan_mask(lan966x, vid);
lan966x_fdb_erase_entries(lan966x, vid);
lan966x_mdb_erase_entries(lan966x, vid);
}
void lan966x_vlan_init(struct lan966x *lan966x)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment