@@ -1214,59 +1214,42 @@ static int _mv88e6xxx_atu_mac_read(struct dsa_switch *ds, u8 addr[ETH_ALEN])
12141214 return 0 ;
12151215}
12161216
1217- static int __mv88e6xxx_port_fdb_cmd (struct dsa_switch * ds , int port ,
1218- const unsigned char * addr , int state )
1217+ static int _mv88e6xxx_atu_load (struct dsa_switch * ds ,
1218+ struct mv88e6xxx_atu_entry * entry )
12191219{
1220- struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1221- u8 fid = ps -> fid [port ];
1220+ u16 reg = 0 ;
12221221 int ret ;
12231222
12241223 ret = _mv88e6xxx_atu_wait (ds );
12251224 if (ret < 0 )
12261225 return ret ;
12271226
1228- ret = _mv88e6xxx_atu_mac_write (ds , addr );
1227+ ret = _mv88e6xxx_atu_mac_write (ds , entry -> mac );
12291228 if (ret < 0 )
12301229 return ret ;
12311230
1232- ret = _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_ATU_DATA ,
1233- (0x10 << port ) | state );
1234- if (ret )
1235- return ret ;
1231+ if (entry -> state != GLOBAL_ATU_DATA_STATE_UNUSED ) {
1232+ unsigned int mask , shift ;
12361233
1237- ret = _mv88e6xxx_atu_cmd (ds , fid , GLOBAL_ATU_OP_LOAD_DB );
1234+ if (entry -> trunk ) {
1235+ reg |= GLOBAL_ATU_DATA_TRUNK ;
1236+ mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK ;
1237+ shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT ;
1238+ } else {
1239+ mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK ;
1240+ shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT ;
1241+ }
12381242
1239- return ret ;
1240- }
1243+ reg |= ( entry -> portv_trunkid << shift ) & mask ;
1244+ }
12411245
1242- int mv88e6xxx_port_fdb_add (struct dsa_switch * ds , int port ,
1243- const unsigned char * addr , u16 vid )
1244- {
1245- int state = is_multicast_ether_addr (addr ) ?
1246- GLOBAL_ATU_DATA_STATE_MC_STATIC :
1247- GLOBAL_ATU_DATA_STATE_UC_STATIC ;
1248- struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1249- int ret ;
1246+ reg |= entry -> state & GLOBAL_ATU_DATA_STATE_MASK ;
12501247
1251- mutex_lock ( & ps -> smi_mutex );
1252- ret = __mv88e6xxx_port_fdb_cmd ( ds , port , addr , state );
1253- mutex_unlock ( & ps -> smi_mutex ) ;
1248+ ret = _mv88e6xxx_reg_write ( ds , REG_GLOBAL , GLOBAL_ATU_DATA , reg );
1249+ if ( ret < 0 )
1250+ return ret ;
12541251
1255- return ret ;
1256- }
1257-
1258- int mv88e6xxx_port_fdb_del (struct dsa_switch * ds , int port ,
1259- const unsigned char * addr , u16 vid )
1260- {
1261- struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1262- int ret ;
1263-
1264- mutex_lock (& ps -> smi_mutex );
1265- ret = __mv88e6xxx_port_fdb_cmd (ds , port , addr ,
1266- GLOBAL_ATU_DATA_STATE_UNUSED );
1267- mutex_unlock (& ps -> smi_mutex );
1268-
1269- return ret ;
1252+ return _mv88e6xxx_atu_cmd (ds , entry -> fid , GLOBAL_ATU_OP_LOAD_DB );
12701253}
12711254
12721255static int _mv88e6xxx_atu_getnext (struct dsa_switch * ds , u16 fid ,
@@ -1329,6 +1312,57 @@ static int _mv88e6xxx_port_vid_to_fid(struct dsa_switch *ds, int port, u16 vid)
13291312 return - ENOENT ;
13301313}
13311314
1315+ static int _mv88e6xxx_port_fdb_load (struct dsa_switch * ds , int port , u16 vid ,
1316+ const u8 addr [ETH_ALEN ], u8 state )
1317+ {
1318+ struct mv88e6xxx_atu_entry entry = { 0 };
1319+ int ret ;
1320+
1321+ ret = _mv88e6xxx_port_vid_to_fid (ds , port , vid );
1322+ if (ret < 0 )
1323+ return ret ;
1324+
1325+ entry .fid = ret ;
1326+ entry .state = state ;
1327+ ether_addr_copy (entry .mac , addr );
1328+ if (state != GLOBAL_ATU_DATA_STATE_UNUSED ) {
1329+ entry .trunk = false;
1330+ entry .portv_trunkid = BIT (port );
1331+ }
1332+
1333+ return _mv88e6xxx_atu_load (ds , & entry );
1334+ }
1335+
1336+ int mv88e6xxx_port_fdb_add (struct dsa_switch * ds , int port , u16 vid ,
1337+ const u8 addr [ETH_ALEN ])
1338+ {
1339+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1340+ u8 state = is_multicast_ether_addr (addr ) ?
1341+ GLOBAL_ATU_DATA_STATE_MC_STATIC :
1342+ GLOBAL_ATU_DATA_STATE_UC_STATIC ;
1343+ int ret ;
1344+
1345+ mutex_lock (& ps -> smi_mutex );
1346+ ret = _mv88e6xxx_port_fdb_load (ds , port , vid , addr , state );
1347+ mutex_unlock (& ps -> smi_mutex );
1348+
1349+ return ret ;
1350+ }
1351+
1352+ int mv88e6xxx_port_fdb_del (struct dsa_switch * ds , int port , u16 vid ,
1353+ const u8 addr [ETH_ALEN ])
1354+ {
1355+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1356+ u8 state = GLOBAL_ATU_DATA_STATE_UNUSED ;
1357+ int ret ;
1358+
1359+ mutex_lock (& ps -> smi_mutex );
1360+ ret = _mv88e6xxx_port_fdb_load (ds , port , vid , addr , state );
1361+ mutex_unlock (& ps -> smi_mutex );
1362+
1363+ return ret ;
1364+ }
1365+
13321366int mv88e6xxx_port_fdb_getnext (struct dsa_switch * ds , int port , u16 * vid ,
13331367 u8 addr [ETH_ALEN ], bool * is_static )
13341368{
0 commit comments