Commit ffc705de authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller

net: dsa: mv88e6xxx: Abstract HW timestamp setup

The 6165 family does not have per port PTP control registers. Also, it
places the timestamp data in different registers. Abstract the current
implementation of 6352 compatible PTP devices so that 6165 can be
added.
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dfa54348
...@@ -497,7 +497,12 @@ struct mv88e6xxx_ptp_ops { ...@@ -497,7 +497,12 @@ struct mv88e6xxx_ptp_ops {
int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin, int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin,
enum ptp_pin_function func, unsigned int chan); enum ptp_pin_function func, unsigned int chan);
void (*event_work)(struct work_struct *ugly); void (*event_work)(struct work_struct *ugly);
int (*port_enable)(struct mv88e6xxx_chip *chip, int port);
int (*port_disable)(struct mv88e6xxx_chip *chip, int port);
int n_ext_ts; int n_ext_ts;
int arr0_sts_reg;
int arr1_sts_reg;
int dep_sts_reg;
}; };
#define STATS_TYPE_PORT BIT(0) #define STATS_TYPE_PORT BIT(0)
......
...@@ -92,10 +92,9 @@ int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port, ...@@ -92,10 +92,9 @@ int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port, static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port,
struct hwtstamp_config *config) struct hwtstamp_config *config)
{ {
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
bool tstamp_enable = false; bool tstamp_enable = false;
u16 port_config0;
int err;
/* Prevent the TX/RX paths from trying to interact with the /* Prevent the TX/RX paths from trying to interact with the
* timestamp hardware while we reconfigure it. * timestamp hardware while we reconfigure it.
...@@ -141,24 +140,16 @@ static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port, ...@@ -141,24 +140,16 @@ static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port,
return -ERANGE; return -ERANGE;
} }
mutex_lock(&chip->reg_lock);
if (tstamp_enable) { if (tstamp_enable) {
/* Disable transportSpecific value matching, so that packets if (ptp_ops->port_enable)
* with either 1588 (0) and 802.1AS (1) will be timestamped. ptp_ops->port_enable(chip, port);
*/
port_config0 = MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH;
} else { } else {
/* Disable PTP. This disables both RX and TX timestamping. */ if (ptp_ops->port_disable)
port_config0 = MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP; ptp_ops->port_disable(chip, port);
} }
mutex_lock(&chip->reg_lock);
err = mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
port_config0);
mutex_unlock(&chip->reg_lock); mutex_unlock(&chip->reg_lock);
if (err < 0)
return err;
/* Once hardware has been configured, enable timestamp checks /* Once hardware has been configured, enable timestamp checks
* in the RX/TX paths. * in the RX/TX paths.
*/ */
...@@ -338,17 +329,18 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip, ...@@ -338,17 +329,18 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
static void mv88e6xxx_rxtstamp_work(struct mv88e6xxx_chip *chip, static void mv88e6xxx_rxtstamp_work(struct mv88e6xxx_chip *chip,
struct mv88e6xxx_port_hwtstamp *ps) struct mv88e6xxx_port_hwtstamp *ps)
{ {
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
struct sk_buff *skb; struct sk_buff *skb;
skb = skb_dequeue(&ps->rx_queue); skb = skb_dequeue(&ps->rx_queue);
if (skb) if (skb)
mv88e6xxx_get_rxts(chip, ps, skb, MV88E6XXX_PORT_PTP_ARR0_STS, mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr0_sts_reg,
&ps->rx_queue); &ps->rx_queue);
skb = skb_dequeue(&ps->rx_queue2); skb = skb_dequeue(&ps->rx_queue2);
if (skb) if (skb)
mv88e6xxx_get_rxts(chip, ps, skb, MV88E6XXX_PORT_PTP_ARR1_STS, mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr1_sts_reg,
&ps->rx_queue2); &ps->rx_queue2);
} }
...@@ -389,6 +381,7 @@ bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port, ...@@ -389,6 +381,7 @@ bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip, static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip,
struct mv88e6xxx_port_hwtstamp *ps) struct mv88e6xxx_port_hwtstamp *ps)
{ {
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
struct skb_shared_hwtstamps shhwtstamps; struct skb_shared_hwtstamps shhwtstamps;
u16 departure_block[4], status; u16 departure_block[4], status;
struct sk_buff *tmp_skb; struct sk_buff *tmp_skb;
...@@ -401,7 +394,7 @@ static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip, ...@@ -401,7 +394,7 @@ static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip,
mutex_lock(&chip->reg_lock); mutex_lock(&chip->reg_lock);
err = mv88e6xxx_port_ptp_read(chip, ps->port_id, err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
MV88E6XXX_PORT_PTP_DEP_STS, ptp_ops->dep_sts_reg,
departure_block, departure_block,
ARRAY_SIZE(departure_block)); ARRAY_SIZE(departure_block));
mutex_unlock(&chip->reg_lock); mutex_unlock(&chip->reg_lock);
...@@ -425,8 +418,7 @@ static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip, ...@@ -425,8 +418,7 @@ static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip,
/* We have the timestamp; go ahead and clear valid now */ /* We have the timestamp; go ahead and clear valid now */
mutex_lock(&chip->reg_lock); mutex_lock(&chip->reg_lock);
mv88e6xxx_port_ptp_write(chip, ps->port_id, mv88e6xxx_port_ptp_write(chip, ps->port_id, ptp_ops->dep_sts_reg, 0);
MV88E6XXX_PORT_PTP_DEP_STS, 0);
mutex_unlock(&chip->reg_lock); mutex_unlock(&chip->reg_lock);
status = departure_block[0] & MV88E6XXX_PTP_TS_STATUS_MASK; status = departure_block[0] & MV88E6XXX_PTP_TS_STATUS_MASK;
...@@ -522,8 +514,21 @@ bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port, ...@@ -522,8 +514,21 @@ bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
return true; return true;
} }
int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port)
{
return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP);
}
int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port)
{
return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH);
}
static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port) static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port)
{ {
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
ps->port_id = port; ps->port_id = port;
...@@ -531,8 +536,10 @@ static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port) ...@@ -531,8 +536,10 @@ static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port)
skb_queue_head_init(&ps->rx_queue); skb_queue_head_init(&ps->rx_queue);
skb_queue_head_init(&ps->rx_queue2); skb_queue_head_init(&ps->rx_queue2);
return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0, if (ptp_ops->port_disable)
MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP); return ptp_ops->port_disable(chip, port);
return 0;
} }
int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip) int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip)
......
...@@ -123,6 +123,8 @@ int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port, ...@@ -123,6 +123,8 @@ int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip); int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip);
void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip); void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip);
int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port);
#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */ #else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "chip.h" #include "chip.h"
#include "global2.h" #include "global2.h"
#include "hwtstamp.h"
#include "ptp.h" #include "ptp.h"
/* Raw timestamps are in units of 8-ns clock periods. */ /* Raw timestamps are in units of 8-ns clock periods. */
...@@ -318,7 +319,12 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { ...@@ -318,7 +319,12 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
.ptp_enable = mv88e6352_ptp_enable, .ptp_enable = mv88e6352_ptp_enable,
.ptp_verify = mv88e6352_ptp_verify, .ptp_verify = mv88e6352_ptp_verify,
.event_work = mv88e6352_tai_event_work, .event_work = mv88e6352_tai_event_work,
.port_enable = mv88e6352_hwtstamp_port_enable,
.port_disable = mv88e6352_hwtstamp_port_disable,
.n_ext_ts = 1, .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,
}; };
const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = { const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment