net: dsa: mv88e6xxx: Provide generic VTU iterator
Move the intricacies of correctly iterating over the VTU to a common implementation. Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									ffcec3f257
								
							
						
					
					
						commit
						d89ef4b8b3
					
				| @ -1511,6 +1511,37 @@ static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip, | ||||
| 	return chip->info->ops->vtu_getnext(chip, entry); | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip, | ||||
| 			      int (*cb)(struct mv88e6xxx_chip *chip, | ||||
| 					const struct mv88e6xxx_vtu_entry *entry, | ||||
| 					void *priv), | ||||
| 			      void *priv) | ||||
| { | ||||
| 	struct mv88e6xxx_vtu_entry entry = { | ||||
| 		.vid = mv88e6xxx_max_vid(chip), | ||||
| 		.valid = false, | ||||
| 	}; | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!chip->info->ops->vtu_getnext) | ||||
| 		return -EOPNOTSUPP; | ||||
| 
 | ||||
| 	do { | ||||
| 		err = chip->info->ops->vtu_getnext(chip, &entry); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 
 | ||||
| 		if (!entry.valid) | ||||
| 			break; | ||||
| 
 | ||||
| 		err = cb(chip, &entry, priv); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 	} while (entry.vid < mv88e6xxx_max_vid(chip)); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, | ||||
| 				   struct mv88e6xxx_vtu_entry *entry) | ||||
| { | ||||
| @ -1520,9 +1551,18 @@ static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, | ||||
| 	return chip->info->ops->vtu_loadpurge(chip, entry); | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip, | ||||
| 				  const struct mv88e6xxx_vtu_entry *entry, | ||||
| 				  void *_fid_bitmap) | ||||
| { | ||||
| 	unsigned long *fid_bitmap = _fid_bitmap; | ||||
| 
 | ||||
| 	set_bit(entry->fid, fid_bitmap); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap) | ||||
| { | ||||
| 	struct mv88e6xxx_vtu_entry vlan; | ||||
| 	int i, err; | ||||
| 	u16 fid; | ||||
| 
 | ||||
| @ -1538,21 +1578,7 @@ int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Set every FID bit used by the VLAN entries */ | ||||
| 	vlan.vid = mv88e6xxx_max_vid(chip); | ||||
| 	vlan.valid = false; | ||||
| 
 | ||||
| 	do { | ||||
| 		err = mv88e6xxx_vtu_getnext(chip, &vlan); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 
 | ||||
| 		if (!vlan.valid) | ||||
| 			break; | ||||
| 
 | ||||
| 		set_bit(vlan.fid, fid_bitmap); | ||||
| 	} while (vlan.vid < mv88e6xxx_max_vid(chip)); | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap); | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid) | ||||
| @ -2198,10 +2224,30 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip, | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| struct mv88e6xxx_port_db_dump_vlan_ctx { | ||||
| 	int port; | ||||
| 	dsa_fdb_dump_cb_t *cb; | ||||
| 	void *data; | ||||
| }; | ||||
| 
 | ||||
| static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip, | ||||
| 				       const struct mv88e6xxx_vtu_entry *entry, | ||||
| 				       void *_data) | ||||
| { | ||||
| 	struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data; | ||||
| 
 | ||||
| 	return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid, | ||||
| 					  ctx->port, ctx->cb, ctx->data); | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, | ||||
| 				  dsa_fdb_dump_cb_t *cb, void *data) | ||||
| { | ||||
| 	struct mv88e6xxx_vtu_entry vlan; | ||||
| 	struct mv88e6xxx_port_db_dump_vlan_ctx ctx = { | ||||
| 		.port = port, | ||||
| 		.cb = cb, | ||||
| 		.data = data, | ||||
| 	}; | ||||
| 	u16 fid; | ||||
| 	int err; | ||||
| 
 | ||||
| @ -2214,25 +2260,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 
 | ||||
| 	/* Dump VLANs' Filtering Information Databases */ | ||||
| 	vlan.vid = mv88e6xxx_max_vid(chip); | ||||
| 	vlan.valid = false; | ||||
| 
 | ||||
| 	do { | ||||
| 		err = mv88e6xxx_vtu_getnext(chip, &vlan); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 
 | ||||
| 		if (!vlan.valid) | ||||
| 			break; | ||||
| 
 | ||||
| 		err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port, | ||||
| 						 cb, data); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 	} while (vlan.vid < mv88e6xxx_max_vid(chip)); | ||||
| 
 | ||||
| 	return err; | ||||
| 	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx); | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user