@@ -2240,6 +2240,15 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
2240
2240
fdb -> ndm_state = NUD_NOARP ;
2241
2241
else
2242
2242
fdb -> ndm_state = NUD_REACHABLE ;
2243
+ } else if (obj -> id == SWITCHDEV_OBJ_ID_PORT_MDB ) {
2244
+ struct switchdev_obj_port_mdb * mdb ;
2245
+
2246
+ if (!is_multicast_ether_addr (addr .mac ))
2247
+ continue ;
2248
+
2249
+ mdb = SWITCHDEV_OBJ_PORT_MDB (obj );
2250
+ mdb -> vid = vid ;
2251
+ ether_addr_copy (mdb -> addr , addr .mac );
2243
2252
} else {
2244
2253
return - EOPNOTSUPP ;
2245
2254
}
@@ -3994,6 +4003,58 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
3994
4003
return NULL ;
3995
4004
}
3996
4005
4006
+ static int mv88e6xxx_port_mdb_prepare (struct dsa_switch * ds , int port ,
4007
+ const struct switchdev_obj_port_mdb * mdb ,
4008
+ struct switchdev_trans * trans )
4009
+ {
4010
+ /* We don't need any dynamic resource from the kernel (yet),
4011
+ * so skip the prepare phase.
4012
+ */
4013
+
4014
+ return 0 ;
4015
+ }
4016
+
4017
+ static void mv88e6xxx_port_mdb_add (struct dsa_switch * ds , int port ,
4018
+ const struct switchdev_obj_port_mdb * mdb ,
4019
+ struct switchdev_trans * trans )
4020
+ {
4021
+ struct mv88e6xxx_chip * chip = ds_to_priv (ds );
4022
+
4023
+ mutex_lock (& chip -> reg_lock );
4024
+ if (mv88e6xxx_port_db_load_purge (chip , port , mdb -> addr , mdb -> vid ,
4025
+ GLOBAL_ATU_DATA_STATE_MC_STATIC ))
4026
+ netdev_err (ds -> ports [port ].netdev , "failed to load multicast MAC address\n" );
4027
+ mutex_unlock (& chip -> reg_lock );
4028
+ }
4029
+
4030
+ static int mv88e6xxx_port_mdb_del (struct dsa_switch * ds , int port ,
4031
+ const struct switchdev_obj_port_mdb * mdb )
4032
+ {
4033
+ struct mv88e6xxx_chip * chip = ds_to_priv (ds );
4034
+ int err ;
4035
+
4036
+ mutex_lock (& chip -> reg_lock );
4037
+ err = mv88e6xxx_port_db_load_purge (chip , port , mdb -> addr , mdb -> vid ,
4038
+ GLOBAL_ATU_DATA_STATE_UNUSED );
4039
+ mutex_unlock (& chip -> reg_lock );
4040
+
4041
+ return err ;
4042
+ }
4043
+
4044
+ static int mv88e6xxx_port_mdb_dump (struct dsa_switch * ds , int port ,
4045
+ struct switchdev_obj_port_mdb * mdb ,
4046
+ int (* cb )(struct switchdev_obj * obj ))
4047
+ {
4048
+ struct mv88e6xxx_chip * chip = ds_to_priv (ds );
4049
+ int err ;
4050
+
4051
+ mutex_lock (& chip -> reg_lock );
4052
+ err = mv88e6xxx_port_db_dump (chip , port , & mdb -> obj , cb );
4053
+ mutex_unlock (& chip -> reg_lock );
4054
+
4055
+ return err ;
4056
+ }
4057
+
3997
4058
static struct dsa_switch_ops mv88e6xxx_switch_ops = {
3998
4059
.probe = mv88e6xxx_drv_probe ,
3999
4060
.get_tag_protocol = mv88e6xxx_get_tag_protocol ,
@@ -4029,6 +4090,10 @@ static struct dsa_switch_ops mv88e6xxx_switch_ops = {
4029
4090
.port_fdb_add = mv88e6xxx_port_fdb_add ,
4030
4091
.port_fdb_del = mv88e6xxx_port_fdb_del ,
4031
4092
.port_fdb_dump = mv88e6xxx_port_fdb_dump ,
4093
+ .port_mdb_prepare = mv88e6xxx_port_mdb_prepare ,
4094
+ .port_mdb_add = mv88e6xxx_port_mdb_add ,
4095
+ .port_mdb_del = mv88e6xxx_port_mdb_del ,
4096
+ .port_mdb_dump = mv88e6xxx_port_mdb_dump ,
4032
4097
};
4033
4098
4034
4099
static int mv88e6xxx_register_switch (struct mv88e6xxx_chip * chip ,
0 commit comments