net: dsa: microchip: add port_cleanup function
Add port_cleanup function to reset some device variables when the port is disabled. Add a mutex to make sure changing those variables is thread-safe. Signed-off-by: Tristram Ha <Tristram.Ha@microchip.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									6ca5081526
								
							
						
					
					
						commit
						7049f9b5d0
					
				| @ -450,12 +450,14 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, | ||||
| 			break; | ||||
| 
 | ||||
| 		member = dev->host_mask | p->vid_member; | ||||
| 		mutex_lock(&dev->dev_mutex); | ||||
| 
 | ||||
| 		/* Port is a member of a bridge. */ | ||||
| 		if (dev->br_member & (1 << port)) { | ||||
| 			dev->member |= (1 << port); | ||||
| 			member = dev->member; | ||||
| 		} | ||||
| 		mutex_unlock(&dev->dev_mutex); | ||||
| 		break; | ||||
| 	case BR_STATE_BLOCKING: | ||||
| 		data |= PORT_LEARN_DISABLE; | ||||
| @ -470,6 +472,7 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, | ||||
| 
 | ||||
| 	ksz_pwrite8(dev, port, P_STP_CTRL, data); | ||||
| 	p->stp_state = state; | ||||
| 	mutex_lock(&dev->dev_mutex); | ||||
| 	if (data & PORT_RX_ENABLE) | ||||
| 		dev->rx_ports |= (1 << port); | ||||
| 	else | ||||
| @ -494,6 +497,7 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, | ||||
| 	 */ | ||||
| 	if (forward != dev->member) | ||||
| 		ksz_update_port_member(dev, port); | ||||
| 	mutex_unlock(&dev->dev_mutex); | ||||
| } | ||||
| 
 | ||||
| static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) | ||||
| @ -1080,6 +1084,7 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) | ||||
| 		ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8); | ||||
| 		p->phydev.duplex = 1; | ||||
| 	} | ||||
| 	mutex_lock(&dev->dev_mutex); | ||||
| 	if (cpu_port) { | ||||
| 		member = dev->port_mask; | ||||
| 		dev->on_ports = dev->host_mask; | ||||
| @ -1092,6 +1097,7 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) | ||||
| 		if (p->phydev.link) | ||||
| 			dev->live_ports |= (1 << port); | ||||
| 	} | ||||
| 	mutex_unlock(&dev->dev_mutex); | ||||
| 	ksz9477_cfg_port_member(dev, port, member); | ||||
| 
 | ||||
| 	/* clear pending interrupts */ | ||||
|  | ||||
| @ -20,6 +20,16 @@ | ||||
| 
 | ||||
| #include "ksz_priv.h" | ||||
| 
 | ||||
| void ksz_port_cleanup(struct ksz_device *dev, int port) | ||||
| { | ||||
| 	/* Common code for port cleanup. */ | ||||
| 	mutex_lock(&dev->dev_mutex); | ||||
| 	dev->on_ports &= ~(1 << port); | ||||
| 	dev->live_ports &= ~(1 << port); | ||||
| 	mutex_unlock(&dev->dev_mutex); | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(ksz_port_cleanup); | ||||
| 
 | ||||
| void ksz_update_port_member(struct ksz_device *dev, int port) | ||||
| { | ||||
| 	struct ksz_port *p; | ||||
| @ -151,6 +161,13 @@ void ksz_adjust_link(struct dsa_switch *ds, int port, | ||||
| 		p->read = true; | ||||
| 		schedule_work(&dev->mib_read); | ||||
| 	} | ||||
| 	mutex_lock(&dev->dev_mutex); | ||||
| 	if (!phydev->link) | ||||
| 		dev->live_ports &= ~(1 << port); | ||||
| 	else | ||||
| 		/* Remember which port is connected and active. */ | ||||
| 		dev->live_ports |= (1 << port) & dev->on_ports; | ||||
| 	mutex_unlock(&dev->dev_mutex); | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(ksz_adjust_link); | ||||
| 
 | ||||
| @ -188,7 +205,9 @@ int ksz_port_bridge_join(struct dsa_switch *ds, int port, | ||||
| { | ||||
| 	struct ksz_device *dev = ds->priv; | ||||
| 
 | ||||
| 	mutex_lock(&dev->dev_mutex); | ||||
| 	dev->br_member |= (1 << port); | ||||
| 	mutex_unlock(&dev->dev_mutex); | ||||
| 
 | ||||
| 	/* port_stp_state_set() will be called after to put the port in
 | ||||
| 	 * appropriate state so there is no need to do anything. | ||||
| @ -203,8 +222,10 @@ void ksz_port_bridge_leave(struct dsa_switch *ds, int port, | ||||
| { | ||||
| 	struct ksz_device *dev = ds->priv; | ||||
| 
 | ||||
| 	mutex_lock(&dev->dev_mutex); | ||||
| 	dev->br_member &= ~(1 << port); | ||||
| 	dev->member &= ~(1 << port); | ||||
| 	mutex_unlock(&dev->dev_mutex); | ||||
| 
 | ||||
| 	/* port_stp_state_set() will be called after to put the port in
 | ||||
| 	 * forwarding state so there is no need to do anything. | ||||
| @ -417,6 +438,7 @@ int ksz_switch_register(struct ksz_device *dev, | ||||
| 		gpiod_set_value(dev->reset_gpio, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	mutex_init(&dev->dev_mutex); | ||||
| 	mutex_init(&dev->reg_mutex); | ||||
| 	mutex_init(&dev->stats_mutex); | ||||
| 	mutex_init(&dev->alu_mutex); | ||||
|  | ||||
| @ -7,6 +7,7 @@ | ||||
| #ifndef __KSZ_COMMON_H | ||||
| #define __KSZ_COMMON_H | ||||
| 
 | ||||
| void ksz_port_cleanup(struct ksz_device *dev, int port); | ||||
| void ksz_update_port_member(struct ksz_device *dev, int port); | ||||
| void ksz_init_mib_timer(struct ksz_device *dev); | ||||
| 
 | ||||
|  | ||||
| @ -48,6 +48,7 @@ struct ksz_device { | ||||
| 	struct ksz_platform_data *pdata; | ||||
| 	const char *name; | ||||
| 
 | ||||
| 	struct mutex dev_mutex;		/* device access */ | ||||
| 	struct mutex reg_mutex;		/* register access */ | ||||
| 	struct mutex stats_mutex;	/* status access */ | ||||
| 	struct mutex alu_mutex;		/* ALU access */ | ||||
| @ -137,6 +138,7 @@ struct ksz_dev_ops { | ||||
| 	void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); | ||||
| 	void (*phy_setup)(struct ksz_device *dev, int port, | ||||
| 			  struct phy_device *phy); | ||||
| 	void (*port_cleanup)(struct ksz_device *dev, int port); | ||||
| 	void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); | ||||
| 	void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); | ||||
| 	void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user