ksz_common.h 5.2 KB
Newer Older
1 2 3
/* SPDX-License-Identifier: GPL-2.0
 * Microchip switch driver common header
 *
4
 * Copyright (C) 2017-2019 Microchip Technology Inc.
5 6 7 8 9
 */

#ifndef __KSZ_COMMON_H
#define __KSZ_COMMON_H

10 11
#include <linux/regmap.h>

12
void ksz_update_port_member(struct ksz_device *dev, int port);
13
void ksz_init_mib_timer(struct ksz_device *dev);
14 15 16 17 18

/* Common DSA access functions */

int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
19 20
void ksz_adjust_link(struct dsa_switch *ds, int port,
		     struct phy_device *phydev);
21
int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
22
void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
int ksz_port_bridge_join(struct dsa_switch *ds, int port,
			 struct net_device *br);
void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
			   struct net_device *br);
void ksz_port_fast_age(struct dsa_switch *ds, int port);
int ksz_port_vlan_prepare(struct dsa_switch *ds, int port,
			  const struct switchdev_obj_port_vlan *vlan);
int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
		      void *data);
int ksz_port_mdb_prepare(struct dsa_switch *ds, int port,
			 const struct switchdev_obj_port_mdb *mdb);
void ksz_port_mdb_add(struct dsa_switch *ds, int port,
		      const struct switchdev_obj_port_mdb *mdb);
int ksz_port_mdb_del(struct dsa_switch *ds, int port,
		     const struct switchdev_obj_port_mdb *mdb);
int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
39
void ksz_disable_port(struct dsa_switch *ds, int port);
40 41 42 43 44

/* Common register access functions */

static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val)
{
45 46
	unsigned int value;
	int ret = regmap_read(dev->regmap[0], reg, &value);
47

48
	*val = value;
49 50 51 52 53
	return ret;
}

static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val)
{
54 55
	unsigned int value;
	int ret = regmap_read(dev->regmap[1], reg, &value);
56

57
	*val = value;
58 59 60 61 62
	return ret;
}

static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val)
{
63 64
	unsigned int value;
	int ret = regmap_read(dev->regmap[2], reg, &value);
65

66
	*val = value;
67 68 69
	return ret;
}

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val)
{
	u32 value[2];
	int ret;

	ret = regmap_bulk_read(dev->regmap[2], reg, value, 2);
	if (!ret) {
		/* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
		value[0] = swab32(value[0]);
		value[1] = swab32(value[1]);
		*val = swab64((u64)*value);
	}

	return ret;
}

86 87
static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value)
{
88
	return regmap_write(dev->regmap[0], reg, value);
89 90 91 92
}

static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value)
{
93
	return regmap_write(dev->regmap[1], reg, value);
94 95 96 97
}

static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value)
{
98
	return regmap_write(dev->regmap[2], reg, value);
99 100
}

101 102 103 104 105 106 107 108 109 110 111 112
static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value)
{
	u32 val[2];

	/* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
	value = swab64(value);
	val[0] = swab32(value & 0xffffffffULL);
	val[1] = swab32(value >> 32ULL);

	return regmap_bulk_write(dev->regmap[2], reg, val, 2);
}

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
static inline void ksz_pread8(struct ksz_device *dev, int port, int offset,
			      u8 *data)
{
	ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data);
}

static inline void ksz_pread16(struct ksz_device *dev, int port, int offset,
			       u16 *data)
{
	ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data);
}

static inline void ksz_pread32(struct ksz_device *dev, int port, int offset,
			       u32 *data)
{
	ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data);
}

static inline void ksz_pwrite8(struct ksz_device *dev, int port, int offset,
			       u8 data)
{
	ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data);
}

static inline void ksz_pwrite16(struct ksz_device *dev, int port, int offset,
				u16 data)
{
	ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), data);
}

static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset,
				u32 data)
{
	ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data);
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
/* Regmap tables generation */
#define KSZ_SPI_OP_RD		3
#define KSZ_SPI_OP_WR		2

#define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad)		\
	swab##swp((opcode) << ((regbits) + (regpad)))

#define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign)		\
	{								\
		.val_bits = (width),					\
		.reg_stride = (width) / 8,				\
		.reg_bits = (regbits) + (regalign),			\
		.pad_bits = (regpad),					\
		.max_register = BIT(regbits) - 1,			\
		.cache_type = REGCACHE_NONE,				\
		.read_flag_mask =					\
			KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp,	\
					     regbits, regpad),		\
		.write_flag_mask =					\
			KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp,	\
					     regbits, regpad),		\
		.reg_format_endian = REGMAP_ENDIAN_BIG,			\
		.val_format_endian = REGMAP_ENDIAN_BIG			\
	}

#define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign)		\
	static const struct regmap_config ksz##_regmap_config[] = {	\
		KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \
		KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \
		KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \
	}

181
#endif