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

Commit 64da5852 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'PTP-support-for-DSA-and-mv88e6xxx-driver'



Andrew Lunn says:

====================
PTP support for DSA and mv88e6xxx driver.

This patchset adds support for using the PTP hardware in switches
supported by the mv88e6xxx driver. The code was produces in
collaboration with Brandon Streiff doing the initial implementation,
and then Richard Cochran and Andrew Lunn making further changes and
cleanups.

The code is sufficient to use ptp4l on a single DSA interface, either
as a master or a slave. Due to the use of an MDIO bus to access the
switch, reading hardware timestamps is slower than what ptp4l
expects. Thus it is necessary to use the option
--tx_timestamp_timeout=32. Heavy use of ethtool -S, or bridge fdb show
can also upset ptp4l. Patches to address this will follow.

Further work is requires to support bridges using Boundary Clock or
Transparent Clock mode.

Since the RFC, an overflow bug has been fixed. Brandon Streiff
has also Acked-by: the updates to his initial patchset.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e0f9759f a2e47134
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -18,3 +18,13 @@ config NET_DSA_MV88E6XXX_GLOBAL2

	  It is required on most chips. If the chip you compile the support for
	  doesn't have such registers set, say N here. In doubt, say Y.

config NET_DSA_MV88E6XXX_PTP
	bool "PTP support for Marvell 88E6xxx"
	default n
	depends on NET_DSA_MV88E6XXX_GLOBAL2
	imply NETWORK_PHY_TIMESTAMPING
	imply PTP_1588_CLOCK
	help
	  Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
	  chips that support it.
+4 −0
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@ mv88e6xxx-objs += global1.o
mv88e6xxx-objs += global1_atu.o
mv88e6xxx-objs += global1_vtu.o
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2.o
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2_avb.o
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2_scratch.o
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o
mv88e6xxx-objs += phy.o
mv88e6xxx-objs += port.o
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
mv88e6xxx-objs += serdes.o
+67 −0
Original line number Diff line number Diff line
@@ -36,8 +36,10 @@
#include "chip.h"
#include "global1.h"
#include "global2.h"
#include "hwtstamp.h"
#include "phy.h"
#include "port.h"
#include "ptp.h"
#include "serdes.h"

static void assert_reg_lock(struct mv88e6xxx_chip *chip)
@@ -2092,6 +2094,17 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
	if (err)
		goto unlock;

	/* Setup PTP Hardware Clock and timestamping */
	if (chip->info->ptp_support) {
		err = mv88e6xxx_ptp_setup(chip);
		if (err)
			goto unlock;

		err = mv88e6xxx_hwtstamp_setup(chip);
		if (err)
			goto unlock;
	}

unlock:
	mutex_unlock(&chip->reg_lock);

@@ -2472,6 +2485,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.gpio_ops = &mv88e6352_gpio_ops,
};

static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -2602,6 +2616,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.serdes_power = mv88e6352_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
};

static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -2673,6 +2688,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.serdes_power = mv88e6352_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
};

static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -2736,6 +2752,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
	.vtu_getnext = mv88e6390_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
	.serdes_power = mv88e6390_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
};

static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -2771,6 +2788,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
	.vtu_getnext = mv88e6390_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
	.serdes_power = mv88e6390_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
};

static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -2843,6 +2861,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.serdes_power = mv88e6352_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6352_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -2879,6 +2899,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
	.vtu_getnext = mv88e6390_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
	.serdes_power = mv88e6390_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6390_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -2913,6 +2935,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6185_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6352_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -2945,6 +2969,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6185_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6352_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6341_ops = {
@@ -2981,6 +3007,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6390_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6350_ops = {
@@ -3049,6 +3077,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
	.reset = mv88e6352_g1_reset,
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.avb_ops = &mv88e6352_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3086,6 +3115,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
	.vtu_getnext = mv88e6352_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
	.serdes_power = mv88e6352_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6352_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3124,6 +3155,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
	.vtu_getnext = mv88e6390_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
	.serdes_power = mv88e6390_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6390_avb_ops,
};

static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3162,6 +3195,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
	.vtu_getnext = mv88e6390_g1_vtu_getnext,
	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
	.serdes_power = mv88e6390_serdes_power,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6390_avb_ops,
};

static const struct mv88e6xxx_info mv88e6xxx_table[] = {
@@ -3267,6 +3302,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6341",
		.num_databases = 4096,
		.num_ports = 6,
		.num_gpio = 11,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3346,6 +3382,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6172",
		.num_databases = 4096,
		.num_ports = 7,
		.num_gpio = 15,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3386,6 +3423,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6176",
		.num_databases = 4096,
		.num_ports = 7,
		.num_gpio = 15,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3424,6 +3462,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6190",
		.num_databases = 4096,
		.num_ports = 11,	/* 10 + Z80 */
		.num_gpio = 16,
		.max_vid = 8191,
		.port_base_addr = 0x0,
		.global1_addr = 0x1b,
@@ -3444,6 +3483,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6190X",
		.num_databases = 4096,
		.num_ports = 11,	/* 10 + Z80 */
		.num_gpio = 16,
		.max_vid = 8191,
		.port_base_addr = 0x0,
		.global1_addr = 0x1b,
@@ -3475,6 +3515,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.ptp_support = true,
		.ops = &mv88e6191_ops,
	},

@@ -3484,6 +3525,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6240",
		.num_databases = 4096,
		.num_ports = 7,
		.num_gpio = 15,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3495,6 +3537,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_EDSA,
		.ptp_support = true,
		.ops = &mv88e6240_ops,
	},

@@ -3504,6 +3547,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6290",
		.num_databases = 4096,
		.num_ports = 11,	/* 10 + Z80 */
		.num_gpio = 16,
		.max_vid = 8191,
		.port_base_addr = 0x0,
		.global1_addr = 0x1b,
@@ -3515,6 +3559,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.ptp_support = true,
		.ops = &mv88e6290_ops,
	},

@@ -3524,6 +3569,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6320",
		.num_databases = 4096,
		.num_ports = 7,
		.num_gpio = 15,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3534,6 +3580,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_EDSA,
		.ptp_support = true,
		.ops = &mv88e6320_ops,
	},

@@ -3543,6 +3590,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6321",
		.num_databases = 4096,
		.num_ports = 7,
		.num_gpio = 15,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3552,6 +3600,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.atu_move_port_mask = 0xf,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_EDSA,
		.ptp_support = true,
		.ops = &mv88e6321_ops,
	},

@@ -3561,6 +3610,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6341",
		.num_databases = 4096,
		.num_ports = 6,
		.num_gpio = 11,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3571,6 +3621,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_EDSA,
		.ptp_support = true,
		.ops = &mv88e6341_ops,
	},

@@ -3620,6 +3671,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6352",
		.num_databases = 4096,
		.num_ports = 7,
		.num_gpio = 15,
		.max_vid = 4095,
		.port_base_addr = 0x10,
		.global1_addr = 0x1b,
@@ -3631,6 +3683,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_EDSA,
		.ptp_support = true,
		.ops = &mv88e6352_ops,
	},
	[MV88E6390] = {
@@ -3639,6 +3692,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6390",
		.num_databases = 4096,
		.num_ports = 11,	/* 10 + Z80 */
		.num_gpio = 16,
		.max_vid = 8191,
		.port_base_addr = 0x0,
		.global1_addr = 0x1b,
@@ -3650,6 +3704,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.ptp_support = true,
		.ops = &mv88e6390_ops,
	},
	[MV88E6390X] = {
@@ -3658,6 +3713,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.name = "Marvell 88E6390X",
		.num_databases = 4096,
		.num_ports = 11,	/* 10 + Z80 */
		.num_gpio = 16,
		.max_vid = 8191,
		.port_base_addr = 0x0,
		.global1_addr = 0x1b,
@@ -3669,6 +3725,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.pvt = true,
		.multi_chip = true,
		.tag_protocol = DSA_TAG_PROTO_DSA,
		.ptp_support = true,
		.ops = &mv88e6390x_ops,
	},
};
@@ -3880,6 +3937,11 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
	.port_mdb_del           = mv88e6xxx_port_mdb_del,
	.crosschip_bridge_join	= mv88e6xxx_crosschip_bridge_join,
	.crosschip_bridge_leave	= mv88e6xxx_crosschip_bridge_leave,
	.port_hwtstamp_set	= mv88e6xxx_port_hwtstamp_set,
	.port_hwtstamp_get	= mv88e6xxx_port_hwtstamp_get,
	.port_txtstamp		= mv88e6xxx_port_txtstamp,
	.port_rxtstamp		= mv88e6xxx_port_rxtstamp,
	.get_ts_info		= mv88e6xxx_get_ts_info,
};

static struct dsa_switch_driver mv88e6xxx_switch_drv = {
@@ -4022,6 +4084,11 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
	struct mv88e6xxx_chip *chip = ds->priv;

	if (chip->info->ptp_support) {
		mv88e6xxx_hwtstamp_free(chip);
		mv88e6xxx_ptp_free(chip);
	}

	mv88e6xxx_phy_destroy(chip);
	mv88e6xxx_unregister_switch(chip);
	mv88e6xxx_mdios_unregister(chip);
+103 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include <linux/irq.h>
#include <linux/gpio/consumer.h>
#include <linux/phy.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <net/dsa.h>

#ifndef UINT64_MAX
@@ -39,6 +41,8 @@
#define MV88E6XXX_MAX_PVT_SWITCHES	32
#define MV88E6XXX_MAX_PVT_PORTS		16

#define MV88E6XXX_MAX_GPIO	16

enum mv88e6xxx_egress_mode {
	MV88E6XXX_EGRESS_MODE_UNMODIFIED,
	MV88E6XXX_EGRESS_MODE_UNTAGGED,
@@ -105,6 +109,7 @@ struct mv88e6xxx_info {
	const char *name;
	unsigned int num_databases;
	unsigned int num_ports;
	unsigned int num_gpio;
	unsigned int max_vid;
	unsigned int port_base_addr;
	unsigned int global1_addr;
@@ -126,6 +131,9 @@ struct mv88e6xxx_info {
	 */
	u8 atu_move_port_mask;
	const struct mv88e6xxx_ops *ops;

	/* Supports PTP */
	bool ptp_support;
};

struct mv88e6xxx_atu_entry {
@@ -146,6 +154,8 @@ struct mv88e6xxx_vtu_entry {

struct mv88e6xxx_bus_ops;
struct mv88e6xxx_irq_ops;
struct mv88e6xxx_gpio_ops;
struct mv88e6xxx_avb_ops;

struct mv88e6xxx_irq {
	u16 masked;
@@ -154,6 +164,32 @@ struct mv88e6xxx_irq {
	unsigned int nirqs;
};

/* state flags for mv88e6xxx_port_hwtstamp::state */
enum {
	MV88E6XXX_HWTSTAMP_ENABLED,
	MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
};

struct mv88e6xxx_port_hwtstamp {
	/* Port index */
	int port_id;

	/* Timestamping state */
	unsigned long state;

	/* Resources for receive timestamping */
	struct sk_buff_head rx_queue;
	struct sk_buff_head rx_queue2;

	/* Resources for transmit timestamping */
	unsigned long tx_tstamp_start;
	struct sk_buff *tx_skb;
	u16 tx_seq_id;

	/* Current timestamp configuration */
	struct hwtstamp_config tstamp_config;
};

struct mv88e6xxx_chip {
	const struct mv88e6xxx_info *info;

@@ -209,6 +245,26 @@ struct mv88e6xxx_chip {
	int watchdog_irq;
	int atu_prob_irq;
	int vtu_prob_irq;

	/* GPIO resources */
	u8 gpio_data[2];

	/* This cyclecounter abstracts the switch PTP time.
	 * reg_lock must be held for any operation that read()s.
	 */
	struct cyclecounter	tstamp_cc;
	struct timecounter	tstamp_tc;
	struct delayed_work	overflow_work;

	struct ptp_clock	*ptp_clock;
	struct ptp_clock_info	ptp_clock_info;
	struct delayed_work	tai_event_work;
	struct ptp_pin_desc	pin_config[MV88E6XXX_MAX_GPIO];
	u16 trig_config;
	u16 evcap_config;

	/* Per-port timestamping resources. */
	struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
};

struct mv88e6xxx_bus_ops {
@@ -344,6 +400,12 @@ struct mv88e6xxx_ops {
			   struct mv88e6xxx_vtu_entry *entry);
	int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
			     struct mv88e6xxx_vtu_entry *entry);

	/* GPIO operations */
	const struct mv88e6xxx_gpio_ops *gpio_ops;

	/* Interface to the AVB/PTP registers */
	const struct mv88e6xxx_avb_ops *avb_ops;
};

struct mv88e6xxx_irq_ops {
@@ -355,6 +417,42 @@ struct mv88e6xxx_irq_ops {
	void (*irq_free)(struct mv88e6xxx_chip *chip);
};

struct mv88e6xxx_gpio_ops {
	/* Get/set data on GPIO pin */
	int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
	int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
			int value);

	/* get/set GPIO direction */
	int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
	int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
		       bool input);

	/* get/set GPIO pin control */
	int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
			int *func);
	int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
			int func);
};

struct mv88e6xxx_avb_ops {
	/* Access port-scoped Precision Time Protocol registers */
	int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
			     u16 *data, int len);
	int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
			      u16 data);

	/* Access global Precision Time Protocol registers */
	int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
			int len);
	int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);

	/* Access global Time Application Interface registers */
	int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
			int len);
	int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
};

#define STATS_TYPE_PORT		BIT(0)
#define STATS_TYPE_BANK0	BIT(1)
#define STATS_TYPE_BANK1	BIT(2)
@@ -386,6 +484,11 @@ static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
	return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
}

static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
{
	return chip->info->num_gpio;
}

int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
+5 −4
Original line number Diff line number Diff line
@@ -20,22 +20,22 @@
#include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
#include "global2.h"

static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
{
	return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
}

static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
{
	return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
}

static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
{
	return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update);
}

static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
{
	return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
}
@@ -798,6 +798,7 @@ int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
						   val);
}

/* Offset 0x1B: Watchdog Control */
static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
{
	u16 reg;
Loading