@@ -2093,9 +2093,9 @@ static int _mv88e6xxx_atu_load(struct mv88e6xxx_chip *chip,
2093
2093
return _mv88e6xxx_atu_cmd (chip , entry -> fid , GLOBAL_ATU_OP_LOAD_DB );
2094
2094
}
2095
2095
2096
- static int _mv88e6xxx_port_fdb_load (struct mv88e6xxx_chip * chip , int port ,
2097
- const unsigned char * addr , u16 vid ,
2098
- u8 state )
2096
+ static int mv88e6xxx_port_db_load_purge (struct mv88e6xxx_chip * chip , int port ,
2097
+ const unsigned char * addr , u16 vid ,
2098
+ u8 state )
2099
2099
{
2100
2100
struct mv88e6xxx_atu_entry entry = { 0 };
2101
2101
struct mv88e6xxx_vtu_stu_entry vlan ;
@@ -2134,30 +2134,27 @@ static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
2134
2134
const struct switchdev_obj_port_fdb * fdb ,
2135
2135
struct switchdev_trans * trans )
2136
2136
{
2137
- int state = is_multicast_ether_addr (fdb -> addr ) ?
2138
- GLOBAL_ATU_DATA_STATE_MC_STATIC :
2139
- GLOBAL_ATU_DATA_STATE_UC_STATIC ;
2140
2137
struct mv88e6xxx_chip * chip = ds_to_priv (ds );
2141
2138
2142
2139
mutex_lock (& chip -> reg_lock );
2143
- if (_mv88e6xxx_port_fdb_load (chip , port , fdb -> addr , fdb -> vid , state ))
2144
- netdev_err ( ds -> ports [ port ]. netdev ,
2145
- "failed to load MAC address\n" );
2140
+ if (mv88e6xxx_port_db_load_purge (chip , port , fdb -> addr , fdb -> vid ,
2141
+ GLOBAL_ATU_DATA_STATE_UC_STATIC ))
2142
+ netdev_err ( ds -> ports [ port ]. netdev , "failed to load unicast MAC address\n" );
2146
2143
mutex_unlock (& chip -> reg_lock );
2147
2144
}
2148
2145
2149
2146
static int mv88e6xxx_port_fdb_del (struct dsa_switch * ds , int port ,
2150
2147
const struct switchdev_obj_port_fdb * fdb )
2151
2148
{
2152
2149
struct mv88e6xxx_chip * chip = ds_to_priv (ds );
2153
- int ret ;
2150
+ int err ;
2154
2151
2155
2152
mutex_lock (& chip -> reg_lock );
2156
- ret = _mv88e6xxx_port_fdb_load (chip , port , fdb -> addr , fdb -> vid ,
2157
- GLOBAL_ATU_DATA_STATE_UNUSED );
2153
+ err = mv88e6xxx_port_db_load_purge (chip , port , fdb -> addr , fdb -> vid ,
2154
+ GLOBAL_ATU_DATA_STATE_UNUSED );
2158
2155
mutex_unlock (& chip -> reg_lock );
2159
2156
2160
- return ret ;
2157
+ return err ;
2161
2158
}
2162
2159
2163
2160
static int _mv88e6xxx_atu_getnext (struct mv88e6xxx_chip * chip , u16 fid ,
@@ -2205,10 +2202,10 @@ static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
2205
2202
return 0 ;
2206
2203
}
2207
2204
2208
- static int _mv88e6xxx_port_fdb_dump_one (struct mv88e6xxx_chip * chip ,
2209
- u16 fid , u16 vid , int port ,
2210
- struct switchdev_obj_port_fdb * fdb ,
2211
- int (* cb )(struct switchdev_obj * obj ))
2205
+ static int mv88e6xxx_port_db_dump_fid (struct mv88e6xxx_chip * chip ,
2206
+ u16 fid , u16 vid , int port ,
2207
+ struct switchdev_obj * obj ,
2208
+ int (* cb )(struct switchdev_obj * obj ))
2212
2209
{
2213
2210
struct mv88e6xxx_atu_entry addr = {
2214
2211
.mac = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff },
@@ -2222,72 +2219,98 @@ static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_chip *chip,
2222
2219
do {
2223
2220
err = _mv88e6xxx_atu_getnext (chip , fid , & addr );
2224
2221
if (err )
2225
- break ;
2222
+ return err ;
2226
2223
2227
2224
if (addr .state == GLOBAL_ATU_DATA_STATE_UNUSED )
2228
2225
break ;
2229
2226
2230
- if (!addr .trunk && addr .portv_trunkid & BIT (port )) {
2231
- bool is_static = addr .state ==
2232
- (is_multicast_ether_addr (addr .mac ) ?
2233
- GLOBAL_ATU_DATA_STATE_MC_STATIC :
2234
- GLOBAL_ATU_DATA_STATE_UC_STATIC );
2227
+ if (addr .trunk || (addr .portv_trunkid & BIT (port )) == 0 )
2228
+ continue ;
2229
+
2230
+ if (obj -> id == SWITCHDEV_OBJ_ID_PORT_FDB ) {
2231
+ struct switchdev_obj_port_fdb * fdb ;
2232
+
2233
+ if (!is_unicast_ether_addr (addr .mac ))
2234
+ continue ;
2235
2235
2236
+ fdb = SWITCHDEV_OBJ_PORT_FDB (obj );
2236
2237
fdb -> vid = vid ;
2237
2238
ether_addr_copy (fdb -> addr , addr .mac );
2238
- fdb -> ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE ;
2239
+ if (addr .state == GLOBAL_ATU_DATA_STATE_UC_STATIC )
2240
+ fdb -> ndm_state = NUD_NOARP ;
2241
+ else
2242
+ fdb -> ndm_state = NUD_REACHABLE ;
2243
+ } else if (obj -> id == SWITCHDEV_OBJ_ID_PORT_MDB ) {
2244
+ struct switchdev_obj_port_mdb * mdb ;
2239
2245
2240
- err = cb (& fdb -> obj );
2241
- if (err )
2242
- break ;
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 );
2252
+ } else {
2253
+ return - EOPNOTSUPP ;
2243
2254
}
2255
+
2256
+ err = cb (obj );
2257
+ if (err )
2258
+ return err ;
2244
2259
} while (!is_broadcast_ether_addr (addr .mac ));
2245
2260
2246
2261
return err ;
2247
2262
}
2248
2263
2249
- static int mv88e6xxx_port_fdb_dump (struct dsa_switch * ds , int port ,
2250
- struct switchdev_obj_port_fdb * fdb ,
2251
- int (* cb )(struct switchdev_obj * obj ))
2264
+ static int mv88e6xxx_port_db_dump (struct mv88e6xxx_chip * chip , int port ,
2265
+ struct switchdev_obj * obj ,
2266
+ int (* cb )(struct switchdev_obj * obj ))
2252
2267
{
2253
- struct mv88e6xxx_chip * chip = ds_to_priv (ds );
2254
2268
struct mv88e6xxx_vtu_stu_entry vlan = {
2255
2269
.vid = GLOBAL_VTU_VID_MASK , /* all ones */
2256
2270
};
2257
2271
u16 fid ;
2258
2272
int err ;
2259
2273
2260
- mutex_lock (& chip -> reg_lock );
2261
-
2262
2274
/* Dump port's default Filtering Information Database (VLAN ID 0) */
2263
2275
err = _mv88e6xxx_port_fid_get (chip , port , & fid );
2264
2276
if (err )
2265
- goto unlock ;
2277
+ return err ;
2266
2278
2267
- err = _mv88e6xxx_port_fdb_dump_one (chip , fid , 0 , port , fdb , cb );
2279
+ err = mv88e6xxx_port_db_dump_fid (chip , fid , 0 , port , obj , cb );
2268
2280
if (err )
2269
- goto unlock ;
2281
+ return err ;
2270
2282
2271
2283
/* Dump VLANs' Filtering Information Databases */
2272
2284
err = _mv88e6xxx_vtu_vid_write (chip , vlan .vid );
2273
2285
if (err )
2274
- goto unlock ;
2286
+ return err ;
2275
2287
2276
2288
do {
2277
2289
err = _mv88e6xxx_vtu_getnext (chip , & vlan );
2278
2290
if (err )
2279
- break ;
2291
+ return err ;
2280
2292
2281
2293
if (!vlan .valid )
2282
2294
break ;
2283
2295
2284
- err = _mv88e6xxx_port_fdb_dump_one (chip , vlan .fid , vlan .vid ,
2285
- port , fdb , cb );
2296
+ err = mv88e6xxx_port_db_dump_fid (chip , vlan .fid , vlan .vid , port ,
2297
+ obj , cb );
2286
2298
if (err )
2287
- break ;
2299
+ return err ;
2288
2300
} while (vlan .vid < GLOBAL_VTU_VID_MASK );
2289
2301
2290
- unlock :
2302
+ return err ;
2303
+ }
2304
+
2305
+ static int mv88e6xxx_port_fdb_dump (struct dsa_switch * ds , int port ,
2306
+ struct switchdev_obj_port_fdb * fdb ,
2307
+ int (* cb )(struct switchdev_obj * obj ))
2308
+ {
2309
+ struct mv88e6xxx_chip * chip = ds_to_priv (ds );
2310
+ int err ;
2311
+
2312
+ mutex_lock (& chip -> reg_lock );
2313
+ err = mv88e6xxx_port_db_dump (chip , port , & fdb -> obj , cb );
2291
2314
mutex_unlock (& chip -> reg_lock );
2292
2315
2293
2316
return err ;
@@ -3980,6 +4003,58 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
3980
4003
return NULL ;
3981
4004
}
3982
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
+
3983
4058
static struct dsa_switch_ops mv88e6xxx_switch_ops = {
3984
4059
.probe = mv88e6xxx_drv_probe ,
3985
4060
.get_tag_protocol = mv88e6xxx_get_tag_protocol ,
@@ -4015,6 +4090,10 @@ static struct dsa_switch_ops mv88e6xxx_switch_ops = {
4015
4090
.port_fdb_add = mv88e6xxx_port_fdb_add ,
4016
4091
.port_fdb_del = mv88e6xxx_port_fdb_del ,
4017
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 ,
4018
4097
};
4019
4098
4020
4099
static int mv88e6xxx_register_switch (struct mv88e6xxx_chip * chip ,
0 commit comments