1 /* SPDX-License-Identifier: GPL-2.0 2 * Microchip switch driver common header 3 * 4 * Copyright (C) 2017-2019 Microchip Technology Inc. 5 */ 6 7 #ifndef __KSZ_COMMON_H 8 #define __KSZ_COMMON_H 9 10 #include <linux/regmap.h> 11 12 void ksz_port_cleanup(struct ksz_device *dev, int port); 13 void ksz_update_port_member(struct ksz_device *dev, int port); 14 void ksz_init_mib_timer(struct ksz_device *dev); 15 16 /* Common DSA access functions */ 17 18 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg); 19 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val); 20 void ksz_adjust_link(struct dsa_switch *ds, int port, 21 struct phy_device *phydev); 22 int ksz_sset_count(struct dsa_switch *ds, int port, int sset); 23 void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf); 24 int ksz_port_bridge_join(struct dsa_switch *ds, int port, 25 struct net_device *br); 26 void ksz_port_bridge_leave(struct dsa_switch *ds, int port, 27 struct net_device *br); 28 void ksz_port_fast_age(struct dsa_switch *ds, int port); 29 int ksz_port_vlan_prepare(struct dsa_switch *ds, int port, 30 const struct switchdev_obj_port_vlan *vlan); 31 int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb, 32 void *data); 33 int ksz_port_mdb_prepare(struct dsa_switch *ds, int port, 34 const struct switchdev_obj_port_mdb *mdb); 35 void ksz_port_mdb_add(struct dsa_switch *ds, int port, 36 const struct switchdev_obj_port_mdb *mdb); 37 int ksz_port_mdb_del(struct dsa_switch *ds, int port, 38 const struct switchdev_obj_port_mdb *mdb); 39 int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy); 40 void ksz_disable_port(struct dsa_switch *ds, int port); 41 42 /* Common register access functions */ 43 44 static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) 45 { 46 unsigned int value; 47 int ret = regmap_read(dev->regmap[0], reg, &value); 48 49 *val = value; 50 return ret; 51 } 52 53 static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) 54 { 55 unsigned int value; 56 int ret = regmap_read(dev->regmap[1], reg, &value); 57 58 *val = value; 59 return ret; 60 } 61 62 static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) 63 { 64 unsigned int value; 65 int ret = regmap_read(dev->regmap[2], reg, &value); 66 67 *val = value; 68 return ret; 69 } 70 71 static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) 72 { 73 return regmap_write(dev->regmap[0], reg, value); 74 } 75 76 static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) 77 { 78 return regmap_write(dev->regmap[1], reg, value); 79 } 80 81 static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) 82 { 83 return regmap_write(dev->regmap[2], reg, value); 84 } 85 86 static inline void ksz_pread8(struct ksz_device *dev, int port, int offset, 87 u8 *data) 88 { 89 ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); 90 } 91 92 static inline void ksz_pread16(struct ksz_device *dev, int port, int offset, 93 u16 *data) 94 { 95 ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); 96 } 97 98 static inline void ksz_pread32(struct ksz_device *dev, int port, int offset, 99 u32 *data) 100 { 101 ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); 102 } 103 104 static inline void ksz_pwrite8(struct ksz_device *dev, int port, int offset, 105 u8 data) 106 { 107 ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); 108 } 109 110 static inline void ksz_pwrite16(struct ksz_device *dev, int port, int offset, 111 u16 data) 112 { 113 ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), data); 114 } 115 116 static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, 117 u32 data) 118 { 119 ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data); 120 } 121 122 /* Regmap tables generation */ 123 #define KSZ_SPI_OP_RD 3 124 #define KSZ_SPI_OP_WR 2 125 126 #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad) \ 127 swab##swp((opcode) << ((regbits) + (regpad))) 128 129 #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign) \ 130 { \ 131 .val_bits = (width), \ 132 .reg_stride = (width) / 8, \ 133 .reg_bits = (regbits) + (regalign), \ 134 .pad_bits = (regpad), \ 135 .max_register = BIT(regbits) - 1, \ 136 .cache_type = REGCACHE_NONE, \ 137 .read_flag_mask = \ 138 KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp, \ 139 regbits, regpad), \ 140 .write_flag_mask = \ 141 KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ 142 regbits, regpad), \ 143 .reg_format_endian = REGMAP_ENDIAN_BIG, \ 144 .val_format_endian = REGMAP_ENDIAN_BIG \ 145 } 146 147 #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \ 148 static const struct regmap_config ksz##_regmap_config[] = { \ 149 KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \ 150 KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \ 151 KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \ 152 } 153 154 #endif 155