Backport port mirroring support for mv88e6xxx Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
		
			
				
	
	
		
			150 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 5c74c54ce6fff719999ff48f128cf4150ee4ff59 Mon Sep 17 00:00:00 2001
 | |
| From: Iwan R Timmer <irtimmer@gmail.com>
 | |
| Date: Thu, 7 Nov 2019 22:11:13 +0100
 | |
| Subject: [PATCH] net: dsa: mv88e6xxx: Split monitor port configuration
 | |
| 
 | |
| Separate the configuration of the egress and ingress monitor port.
 | |
| This allows the port mirror functionality to do ingress and egress
 | |
| port mirroring to separate ports.
 | |
| 
 | |
| Signed-off-by: Iwan R Timmer <irtimmer@gmail.com>
 | |
| Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | |
| Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| ---
 | |
|  drivers/net/dsa/mv88e6xxx/chip.c    |  9 ++++++-
 | |
|  drivers/net/dsa/mv88e6xxx/chip.h    |  9 ++++++-
 | |
|  drivers/net/dsa/mv88e6xxx/global1.c | 42 ++++++++++++++++++++---------
 | |
|  drivers/net/dsa/mv88e6xxx/global1.h |  8 ++++--
 | |
|  4 files changed, 52 insertions(+), 16 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| +++ b/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| @@ -2378,7 +2378,14 @@ static int mv88e6xxx_setup_upstream_port
 | |
|  
 | |
|  		if (chip->info->ops->set_egress_port) {
 | |
|  			err = chip->info->ops->set_egress_port(chip,
 | |
| -							       upstream_port);
 | |
| +						MV88E6XXX_EGRESS_DIR_INGRESS,
 | |
| +						upstream_port);
 | |
| +			if (err)
 | |
| +				return err;
 | |
| +
 | |
| +			err = chip->info->ops->set_egress_port(chip,
 | |
| +						MV88E6XXX_EGRESS_DIR_EGRESS,
 | |
| +						upstream_port);
 | |
|  			if (err)
 | |
|  				return err;
 | |
|  		}
 | |
| --- a/drivers/net/dsa/mv88e6xxx/chip.h
 | |
| +++ b/drivers/net/dsa/mv88e6xxx/chip.h
 | |
| @@ -33,6 +33,11 @@ enum mv88e6xxx_egress_mode {
 | |
|  	MV88E6XXX_EGRESS_MODE_ETHERTYPE,
 | |
|  };
 | |
|  
 | |
| +enum mv88e6xxx_egress_direction {
 | |
| +        MV88E6XXX_EGRESS_DIR_INGRESS,
 | |
| +        MV88E6XXX_EGRESS_DIR_EGRESS,
 | |
| +};
 | |
| +
 | |
|  enum mv88e6xxx_frame_mode {
 | |
|  	MV88E6XXX_FRAME_MODE_NORMAL,
 | |
|  	MV88E6XXX_FRAME_MODE_DSA,
 | |
| @@ -464,7 +469,9 @@ struct mv88e6xxx_ops {
 | |
|  	int (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
 | |
|  			       uint64_t *data);
 | |
|  	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
 | |
| -	int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
 | |
| +	int (*set_egress_port)(struct mv88e6xxx_chip *chip,
 | |
| +			       enum mv88e6xxx_egress_direction direction,
 | |
| +			       int port);
 | |
|  
 | |
|  #define MV88E6XXX_CASCADE_PORT_NONE		0xe
 | |
|  #define MV88E6XXX_CASCADE_PORT_MULTIPLE		0xf
 | |
| --- a/drivers/net/dsa/mv88e6xxx/global1.c
 | |
| +++ b/drivers/net/dsa/mv88e6xxx/global1.c
 | |
| @@ -263,7 +263,9 @@ int mv88e6250_g1_ieee_pri_map(struct mv8
 | |
|  /* Offset 0x1a: Monitor Control */
 | |
|  /* Offset 0x1a: Monitor & MGMT Control on some devices */
 | |
|  
 | |
| -int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port)
 | |
| +int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip,
 | |
| +				 enum mv88e6xxx_egress_direction direction,
 | |
| +				 int port)
 | |
|  {
 | |
|  	u16 reg;
 | |
|  	int err;
 | |
| @@ -272,11 +274,20 @@ int mv88e6095_g1_set_egress_port(struct
 | |
|  	if (err)
 | |
|  		return err;
 | |
|  
 | |
| -	reg &= ~(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK |
 | |
| -		 MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
 | |
| -
 | |
| -	reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK) |
 | |
| -		port << __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
 | |
| +	switch (direction) {
 | |
| +	case MV88E6XXX_EGRESS_DIR_INGRESS:
 | |
| +		reg &= MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK;
 | |
| +		reg |= port <<
 | |
| +		       __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK);
 | |
| +		break;
 | |
| +	case MV88E6XXX_EGRESS_DIR_EGRESS:
 | |
| +		reg &= MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
 | |
| +		reg |= port <<
 | |
| +		       __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
 | |
| +		break;
 | |
| +	default:
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
|  
 | |
|  	return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
 | |
|  }
 | |
| @@ -310,17 +321,24 @@ static int mv88e6390_g1_monitor_write(st
 | |
|  	return mv88e6xxx_g1_write(chip, MV88E6390_G1_MONITOR_MGMT_CTL, reg);
 | |
|  }
 | |
|  
 | |
| -int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port)
 | |
| +int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip,
 | |
| +				 enum mv88e6xxx_egress_direction direction,
 | |
| +				 int port)
 | |
|  {
 | |
|  	u16 ptr;
 | |
|  	int err;
 | |
|  
 | |
| -	ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
 | |
| -	err = mv88e6390_g1_monitor_write(chip, ptr, port);
 | |
| -	if (err)
 | |
| -		return err;
 | |
| +	switch (direction) {
 | |
| +	case MV88E6XXX_EGRESS_DIR_INGRESS:
 | |
| +		ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
 | |
| +		break;
 | |
| +	case MV88E6XXX_EGRESS_DIR_EGRESS:
 | |
| +		ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
 | |
| +		break;
 | |
| +	default:
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
|  
 | |
| -	ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
 | |
|  	err = mv88e6390_g1_monitor_write(chip, ptr, port);
 | |
|  	if (err)
 | |
|  		return err;
 | |
| --- a/drivers/net/dsa/mv88e6xxx/global1.h
 | |
| +++ b/drivers/net/dsa/mv88e6xxx/global1.h
 | |
| @@ -288,8 +288,12 @@ int mv88e6095_g1_stats_set_histogram(str
 | |
|  int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip);
 | |
|  void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val);
 | |
|  int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip);
 | |
| -int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port);
 | |
| -int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port);
 | |
| +int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip,
 | |
| +				 enum mv88e6xxx_egress_direction direction,
 | |
| +				 int port);
 | |
| +int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip,
 | |
| +				 enum mv88e6xxx_egress_direction direction,
 | |
| +				 int port);
 | |
|  int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 | |
|  int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 | |
|  int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
 |