Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71509614 authored by Hubert Feurstein's avatar Hubert Feurstein Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: add PTP support for MV88E6250 family



This adds PTP support for the MV88E6250 family.

Signed-off-by: default avatarHubert Feurstein <h.feurstein@gmail.com>
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8858ccc8
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -3538,6 +3538,8 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
	.reset = mv88e6250_g1_reset,
	.reset = mv88e6250_g1_reset,
	.vtu_getnext = mv88e6250_g1_vtu_getnext,
	.vtu_getnext = mv88e6250_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
	.vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
	.avb_ops = &mv88e6352_avb_ops,
	.ptp_ops = &mv88e6250_ptp_ops,
	.phylink_validate = mv88e6065_phylink_validate,
	.phylink_validate = mv88e6065_phylink_validate,
};
};


@@ -4334,6 +4336,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.atu_move_port_mask = 0xf,
		.atu_move_port_mask = 0xf,
		.dual_chip = true,
		.dual_chip = true,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.ptp_support = true,
		.ops = &mv88e6250_ops,
		.ops = &mv88e6250_ops,
	},
	},


@@ -4379,6 +4382,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.atu_move_port_mask = 0xf,
		.atu_move_port_mask = 0xf,
		.dual_chip = true,
		.dual_chip = true,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.ptp_support = true,
		.ops = &mv88e6250_ops,
		.ops = &mv88e6250_ops,
	},
	},


+4 −0
Original line number Original line Diff line number Diff line
@@ -539,6 +539,10 @@ struct mv88e6xxx_ptp_ops {
	int arr1_sts_reg;
	int arr1_sts_reg;
	int dep_sts_reg;
	int dep_sts_reg;
	u32 rx_filters;
	u32 rx_filters;
	u32 cc_shift;
	u32 cc_mult;
	u32 cc_mult_num;
	u32 cc_mult_dem;
};
};


#define STATS_TYPE_PORT		BIT(0)
#define STATS_TYPE_PORT		BIT(0)
+68 −11
Original line number Original line Diff line number Diff line
@@ -15,11 +15,31 @@
#include "hwtstamp.h"
#include "hwtstamp.h"
#include "ptp.h"
#include "ptp.h"


/* Raw timestamps are in units of 8-ns clock periods. */
#define MV88E6XXX_MAX_ADJ_PPB	1000000
#define CC_SHIFT	28

#define CC_MULT		(8 << CC_SHIFT)
/* Family MV88E6250:
#define CC_MULT_NUM	(1 << 9)
 * Raw timestamps are in units of 10-ns clock periods.
#define CC_MULT_DEM	15625ULL
 *
 * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
 * simplifies to
 * clkadj = scaled_ppm * 2^7 / 5^5
 */
#define MV88E6250_CC_SHIFT	28
#define MV88E6250_CC_MULT	(10 << MV88E6250_CC_SHIFT)
#define MV88E6250_CC_MULT_NUM	(1 << 7)
#define MV88E6250_CC_MULT_DEM	3125ULL

/* Other families:
 * Raw timestamps are in units of 8-ns clock periods.
 *
 * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
 * simplifies to
 * clkadj = scaled_ppm * 2^9 / 5^6
 */
#define MV88E6XXX_CC_SHIFT	28
#define MV88E6XXX_CC_MULT	(8 << MV88E6XXX_CC_SHIFT)
#define MV88E6XXX_CC_MULT_NUM	(1 << 9)
#define MV88E6XXX_CC_MULT_DEM	15625ULL


#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)


@@ -179,6 +199,7 @@ static void mv88e6352_tai_event_work(struct work_struct *ugly)
static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
{
	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
	const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
	int neg_adj = 0;
	int neg_adj = 0;
	u32 diff, mult;
	u32 diff, mult;
	u64 adj;
	u64 adj;
@@ -187,10 +208,11 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
		neg_adj = 1;
		neg_adj = 1;
		scaled_ppm = -scaled_ppm;
		scaled_ppm = -scaled_ppm;
	}
	}
	mult = CC_MULT;

	adj = CC_MULT_NUM;
	mult = ptp_ops->cc_mult;
	adj = ptp_ops->cc_mult_num;
	adj *= scaled_ppm;
	adj *= scaled_ppm;
	diff = div_u64(adj, CC_MULT_DEM);
	diff = div_u64(adj, ptp_ops->cc_mult_dem);


	mv88e6xxx_reg_lock(chip);
	mv88e6xxx_reg_lock(chip);


@@ -324,6 +346,37 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
	.cc_shift = MV88E6XXX_CC_SHIFT,
	.cc_mult = MV88E6XXX_CC_MULT,
	.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
	.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
};

const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
	.clock_read = mv88e6352_ptp_clock_read,
	.ptp_enable = mv88e6352_ptp_enable,
	.ptp_verify = mv88e6352_ptp_verify,
	.event_work = mv88e6352_tai_event_work,
	.port_enable = mv88e6352_hwtstamp_port_enable,
	.port_disable = mv88e6352_hwtstamp_port_disable,
	.n_ext_ts = 1,
	.arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
	.arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
	.dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
	.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
	.cc_shift = MV88E6250_CC_SHIFT,
	.cc_mult = MV88E6250_CC_MULT,
	.cc_mult_num = MV88E6250_CC_MULT_NUM,
	.cc_mult_dem = MV88E6250_CC_MULT_DEM,
};
};


const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
@@ -347,6 +400,10 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
	.cc_shift = MV88E6XXX_CC_SHIFT,
	.cc_mult = MV88E6XXX_CC_MULT,
	.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
	.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
};
};


static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
@@ -384,8 +441,8 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
	memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
	memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
	chip->tstamp_cc.read	= mv88e6xxx_ptp_clock_read;
	chip->tstamp_cc.read	= mv88e6xxx_ptp_clock_read;
	chip->tstamp_cc.mask	= CYCLECOUNTER_MASK(32);
	chip->tstamp_cc.mask	= CYCLECOUNTER_MASK(32);
	chip->tstamp_cc.mult	= CC_MULT;
	chip->tstamp_cc.mult	= ptp_ops->cc_mult;
	chip->tstamp_cc.shift	= CC_SHIFT;
	chip->tstamp_cc.shift	= ptp_ops->cc_shift;


	timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
	timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
			 ktime_to_ns(ktime_get_real()));
			 ktime_to_ns(ktime_get_real()));
@@ -397,7 +454,6 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
	chip->ptp_clock_info.owner = THIS_MODULE;
	chip->ptp_clock_info.owner = THIS_MODULE;
	snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
	snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
		 "%s", dev_name(chip->dev));
		 "%s", dev_name(chip->dev));
	chip->ptp_clock_info.max_adj	= 1000000;


	chip->ptp_clock_info.n_ext_ts	= ptp_ops->n_ext_ts;
	chip->ptp_clock_info.n_ext_ts	= ptp_ops->n_ext_ts;
	chip->ptp_clock_info.n_per_out	= 0;
	chip->ptp_clock_info.n_per_out	= 0;
@@ -413,6 +469,7 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
	}
	}
	chip->ptp_clock_info.pin_config = chip->pin_config;
	chip->ptp_clock_info.pin_config = chip->pin_config;


	chip->ptp_clock_info.max_adj    = MV88E6XXX_MAX_ADJ_PPB;
	chip->ptp_clock_info.adjfine	= mv88e6xxx_ptp_adjfine;
	chip->ptp_clock_info.adjfine	= mv88e6xxx_ptp_adjfine;
	chip->ptp_clock_info.adjtime	= mv88e6xxx_ptp_adjtime;
	chip->ptp_clock_info.adjtime	= mv88e6xxx_ptp_adjtime;
	chip->ptp_clock_info.gettime64	= mv88e6xxx_ptp_gettime;
	chip->ptp_clock_info.gettime64	= mv88e6xxx_ptp_gettime;
+2 −0
Original line number Original line Diff line number Diff line
@@ -149,6 +149,7 @@ void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip);
				      ptp_clock_info)
				      ptp_clock_info)


extern const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops;
extern const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops;
extern const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops;
extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;
extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;


#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
@@ -168,6 +169,7 @@ static inline void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
}
}


static const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {};
static const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {};
static const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {};
static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};
static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};


#endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */
#endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */