Commit 8720bd95 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'net-dsa-microchip-common-spi-probe-for-the-ksz-series-switches-part-1'



Arun Ramadoss says:

====================
net: dsa: microchip: common spi probe for the ksz series switches - part 1

This patch series aims to refactor the ksz_switch_register routine to have the
common flow for the ksz series switch. At present ksz8795.c & ksz9477.c have
its own dsa_switch_ops and switch detect functionality.
In ksz_switch_register, ksz_dev_ops is assigned based on the function parameter
passed by the individual ksz8/ksz9477 switch register function. And then switch
detect is performed based on the ksz_dev_ops.detect hook.  This patch modifies
the ksz_switch_register such a way that switch detect is performed first, based
on the chip ksz_dev_ops is assigned to ksz_device structure. It ensures the
common flow for the existing as well as LAN937x switches.
In the next series of patch, it will move ksz_dsa_ops and dsa_switch_ops
from ksz8795.c and ksz9477.c to ksz_common.c and have the common spi
probe all the ksz based switches.

Changes in v1
- Splitted the patch series into two.
- Replaced all occurrence of REG_PORT_STATUS_0 and PORT_FIBER_MODE to
  KSZ8_PORT_STATUS_0 and KSZ8_PORT_FIBER_MODE.
- Separated the tag protocol and phy read/write patch into two.
- Assigned the DSA_TAG_PROTO_NONE as the default value for get_tag_protocol hook.
- Reduced the indentation level by using the if(!dev->dev_ops->mirror_add).
- Added the stp_ctrl_reg as a member in ksz_chip_data and removed the member
  in ksz_dev_ops.
- Removed the r_dyn_mac_table, r_sta_mac_table and w_sta_mac_table from the
  ksz_dev_ops since it is used only in the ksz8795.c.

Changes in RFC v2
- Fixed the compilation issue.
- Reduced the patch set to 15.
====================

Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Link: https://lore.kernel.org/r/20220617084255.19376-1-arun.ramadoss@microchip.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 00bb2920 1fe94f54
Loading
Loading
Loading
Loading
+128 −105
Original line number Diff line number Diff line
@@ -898,29 +898,6 @@ static void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val)
	}
}

static enum dsa_tag_protocol ksz8_get_tag_protocol(struct dsa_switch *ds,
						   int port,
						   enum dsa_tag_protocol mp)
{
	struct ksz_device *dev = ds->priv;

	/* ksz88x3 uses the same tag schema as KSZ9893 */
	return ksz_is_ksz88x3(dev) ?
		DSA_TAG_PROTO_KSZ9893 : DSA_TAG_PROTO_KSZ8795;
}

static u32 ksz8_sw_get_phy_flags(struct dsa_switch *ds, int port)
{
	/* Silicon Errata Sheet (DS80000830A):
	 * Port 1 does not work with LinkMD Cable-Testing.
	 * Port 1 does not respond to received PAUSE control frames.
	 */
	if (!port)
		return MICREL_KSZ8_P1_ERRATA;

	return 0;
}

static void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member)
{
	u8 data;
@@ -931,11 +908,6 @@ static void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member)
	ksz_pwrite8(dev, port, P_MIRROR_CTRL, data);
}

static void ksz8_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
{
	ksz_port_stp_state_set(ds, port, state, P_STP_CTRL);
}

static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
{
	u8 learn[DSA_MAX_PORTS];
@@ -969,11 +941,111 @@ static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
	}
}

static int ksz8_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag,
				    struct netlink_ext_ack *extack)
static int ksz8_fdb_dump(struct ksz_device *dev, int port,
			 dsa_fdb_dump_cb_t *cb, void *data)
{
	struct ksz_device *dev = ds->priv;
	int ret = 0;
	u16 i = 0;
	u16 entries = 0;
	u8 timestamp = 0;
	u8 fid;
	u8 member;
	struct alu_struct alu;

	do {
		alu.is_static = false;
		ret = ksz8_r_dyn_mac_table(dev, i, alu.mac, &fid, &member,
					   &timestamp, &entries);
		if (!ret && (member & BIT(port))) {
			ret = cb(alu.mac, alu.fid, alu.is_static, data);
			if (ret)
				break;
		}
		i++;
	} while (i < entries);
	if (i >= entries)
		ret = 0;

	return ret;
}

static int ksz8_mdb_add(struct ksz_device *dev, int port,
			const struct switchdev_obj_port_mdb *mdb,
			struct dsa_db db)
{
	struct alu_struct alu;
	int index;
	int empty = 0;

	alu.port_forward = 0;
	for (index = 0; index < dev->info->num_statics; index++) {
		if (!ksz8_r_sta_mac_table(dev, index, &alu)) {
			/* Found one already in static MAC table. */
			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
			    alu.fid == mdb->vid)
				break;
		/* Remember the first empty entry. */
		} else if (!empty) {
			empty = index + 1;
		}
	}

	/* no available entry */
	if (index == dev->info->num_statics && !empty)
		return -ENOSPC;

	/* add entry */
	if (index == dev->info->num_statics) {
		index = empty - 1;
		memset(&alu, 0, sizeof(alu));
		memcpy(alu.mac, mdb->addr, ETH_ALEN);
		alu.is_static = true;
	}
	alu.port_forward |= BIT(port);
	if (mdb->vid) {
		alu.is_use_fid = true;

		/* Need a way to map VID to FID. */
		alu.fid = mdb->vid;
	}
	ksz8_w_sta_mac_table(dev, index, &alu);

	return 0;
}

static int ksz8_mdb_del(struct ksz_device *dev, int port,
			const struct switchdev_obj_port_mdb *mdb,
			struct dsa_db db)
{
	struct alu_struct alu;
	int index;

	for (index = 0; index < dev->info->num_statics; index++) {
		if (!ksz8_r_sta_mac_table(dev, index, &alu)) {
			/* Found one already in static MAC table. */
			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
			    alu.fid == mdb->vid)
				break;
		}
	}

	/* no available entry */
	if (index == dev->info->num_statics)
		goto exit;

	/* clear port */
	alu.port_forward &= ~BIT(port);
	if (!alu.port_forward)
		alu.is_static = false;
	ksz8_w_sta_mac_table(dev, index, &alu);

exit:
	return 0;
}

static int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag,
				    struct netlink_ext_ack *extack)
{
	if (ksz_is_ksz88x3(dev))
		return -ENOTSUPP;

@@ -998,12 +1070,11 @@ static void ksz8_port_enable_pvid(struct ksz_device *dev, int port, bool state)
	}
}

static int ksz8_port_vlan_add(struct dsa_switch *ds, int port,
static int ksz8_port_vlan_add(struct ksz_device *dev, int port,
			      const struct switchdev_obj_port_vlan *vlan,
			      struct netlink_ext_ack *extack)
{
	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
	struct ksz_device *dev = ds->priv;
	struct ksz_port *p = &dev->ports[port];
	u16 data, new_pvid = 0;
	u8 fid, member, valid;
@@ -1071,10 +1142,9 @@ static int ksz8_port_vlan_add(struct dsa_switch *ds, int port,
	return 0;
}

static int ksz8_port_vlan_del(struct dsa_switch *ds, int port,
static int ksz8_port_vlan_del(struct ksz_device *dev, int port,
			      const struct switchdev_obj_port_vlan *vlan)
{
	struct ksz_device *dev = ds->priv;
	u16 data, pvid;
	u8 fid, member, valid;

@@ -1104,12 +1174,10 @@ static int ksz8_port_vlan_del(struct dsa_switch *ds, int port,
	return 0;
}

static int ksz8_port_mirror_add(struct dsa_switch *ds, int port,
static int ksz8_port_mirror_add(struct ksz_device *dev, int port,
				struct dsa_mall_mirror_tc_entry *mirror,
				bool ingress, struct netlink_ext_ack *extack)
{
	struct ksz_device *dev = ds->priv;

	if (ingress) {
		ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true);
		dev->mirror_rx |= BIT(port);
@@ -1128,10 +1196,9 @@ static int ksz8_port_mirror_add(struct dsa_switch *ds, int port,
	return 0;
}

static void ksz8_port_mirror_del(struct dsa_switch *ds, int port,
static void ksz8_port_mirror_del(struct ksz_device *dev, int port,
				 struct dsa_mall_mirror_tc_entry *mirror)
{
	struct ksz_device *dev = ds->priv;
	u8 data;

	if (mirror->ingress) {
@@ -1258,7 +1325,7 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds)
	for (i = 0; i < dev->phy_port_cnt; i++) {
		p = &dev->ports[i];

		ksz8_port_stp_state_set(ds, i, BR_STATE_DISABLED);
		ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED);

		/* Last port may be disabled. */
		if (i == dev->phy_port_cnt)
@@ -1272,7 +1339,7 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds)
			continue;
		if (!ksz_is_ksz88x3(dev)) {
			ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote);
			if (remote & PORT_FIBER_MODE)
			if (remote & KSZ8_PORT_FIBER_MODE)
				p->fiber = 1;
		}
		if (p->fiber)
@@ -1371,13 +1438,9 @@ static int ksz8_setup(struct dsa_switch *ds)
	return ksz8_handle_global_errata(ds);
}

static void ksz8_get_caps(struct dsa_switch *ds, int port,
static void ksz8_get_caps(struct ksz_device *dev, int port,
			  struct phylink_config *config)
{
	struct ksz_device *dev = ds->priv;

	ksz_phylink_get_caps(ds, port, config);

	config->mac_capabilities = MAC_10 | MAC_100;

	/* Silicon Errata Sheet (DS80000830A):
@@ -1394,12 +1457,12 @@ static void ksz8_get_caps(struct dsa_switch *ds, int port,
}

static const struct dsa_switch_ops ksz8_switch_ops = {
	.get_tag_protocol	= ksz8_get_tag_protocol,
	.get_phy_flags		= ksz8_sw_get_phy_flags,
	.get_tag_protocol	= ksz_get_tag_protocol,
	.get_phy_flags		= ksz_get_phy_flags,
	.setup			= ksz8_setup,
	.phy_read		= ksz_phy_read16,
	.phy_write		= ksz_phy_write16,
	.phylink_get_caps	= ksz8_get_caps,
	.phylink_get_caps	= ksz_phylink_get_caps,
	.phylink_mac_link_down	= ksz_mac_link_down,
	.port_enable		= ksz_enable_port,
	.get_strings		= ksz_get_strings,
@@ -1407,16 +1470,16 @@ static const struct dsa_switch_ops ksz8_switch_ops = {
	.get_sset_count		= ksz_sset_count,
	.port_bridge_join	= ksz_port_bridge_join,
	.port_bridge_leave	= ksz_port_bridge_leave,
	.port_stp_state_set	= ksz8_port_stp_state_set,
	.port_stp_state_set	= ksz_port_stp_state_set,
	.port_fast_age		= ksz_port_fast_age,
	.port_vlan_filtering	= ksz8_port_vlan_filtering,
	.port_vlan_add		= ksz8_port_vlan_add,
	.port_vlan_del		= ksz8_port_vlan_del,
	.port_vlan_filtering	= ksz_port_vlan_filtering,
	.port_vlan_add		= ksz_port_vlan_add,
	.port_vlan_del		= ksz_port_vlan_del,
	.port_fdb_dump		= ksz_port_fdb_dump,
	.port_mdb_add           = ksz_port_mdb_add,
	.port_mdb_del           = ksz_port_mdb_del,
	.port_mirror_add	= ksz8_port_mirror_add,
	.port_mirror_del	= ksz8_port_mirror_del,
	.port_mirror_add	= ksz_port_mirror_add,
	.port_mirror_del	= ksz_port_mirror_del,
};

static u32 ksz8_get_port_addr(int port, int offset)
@@ -1424,51 +1487,6 @@ static u32 ksz8_get_port_addr(int port, int offset)
	return PORT_CTRL_ADDR(port, offset);
}

static int ksz8_switch_detect(struct ksz_device *dev)
{
	u8 id1, id2;
	u16 id16;
	int ret;

	/* read chip id */
	ret = ksz_read16(dev, REG_CHIP_ID0, &id16);
	if (ret)
		return ret;

	id1 = id16 >> 8;
	id2 = id16 & SW_CHIP_ID_M;

	switch (id1) {
	case KSZ87_FAMILY_ID:
		if ((id2 != CHIP_ID_94 && id2 != CHIP_ID_95))
			return -ENODEV;

		if (id2 == CHIP_ID_95) {
			u8 val;

			id2 = 0x95;
			ksz_read8(dev, REG_PORT_STATUS_0, &val);
			if (val & PORT_FIBER_MODE)
				id2 = 0x65;
		} else if (id2 == CHIP_ID_94) {
			id2 = 0x94;
		}
		break;
	case KSZ88_FAMILY_ID:
		if (id2 != CHIP_ID_63)
			return -ENODEV;
		break;
	default:
		dev_err(dev->dev, "invalid family id: %d\n", id1);
		return -ENODEV;
	}
	id16 &= ~0xff;
	id16 |= id2;
	dev->chip_id = id16;

	return 0;
}

static int ksz8_switch_init(struct ksz_device *dev)
{
	struct ksz8 *ksz8 = dev->priv;
@@ -1514,15 +1532,20 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
	.port_setup = ksz8_port_setup,
	.r_phy = ksz8_r_phy,
	.w_phy = ksz8_w_phy,
	.r_dyn_mac_table = ksz8_r_dyn_mac_table,
	.r_sta_mac_table = ksz8_r_sta_mac_table,
	.w_sta_mac_table = ksz8_w_sta_mac_table,
	.r_mib_cnt = ksz8_r_mib_cnt,
	.r_mib_pkt = ksz8_r_mib_pkt,
	.freeze_mib = ksz8_freeze_mib,
	.port_init_cnt = ksz8_port_init_cnt,
	.fdb_dump = ksz8_fdb_dump,
	.mdb_add = ksz8_mdb_add,
	.mdb_del = ksz8_mdb_del,
	.vlan_filtering = ksz8_port_vlan_filtering,
	.vlan_add = ksz8_port_vlan_add,
	.vlan_del = ksz8_port_vlan_del,
	.mirror_add = ksz8_port_mirror_add,
	.mirror_del = ksz8_port_mirror_del,
	.get_caps = ksz8_get_caps,
	.shutdown = ksz8_reset_switch,
	.detect = ksz8_switch_detect,
	.init = ksz8_switch_init,
	.exit = ksz8_switch_exit,
};
+0 −16
Original line number Diff line number Diff line
@@ -14,23 +14,10 @@
#define KS_PRIO_M			0x3
#define KS_PRIO_S			2

#define REG_CHIP_ID0			0x00

#define KSZ87_FAMILY_ID			0x87
#define KSZ88_FAMILY_ID			0x88

#define REG_CHIP_ID1			0x01

#define SW_CHIP_ID_M			0xF0
#define SW_CHIP_ID_S			4
#define SW_REVISION_M			0x0E
#define SW_REVISION_S			1
#define SW_START			0x01

#define CHIP_ID_94			0x60
#define CHIP_ID_95			0x90
#define CHIP_ID_63			0x30

#define KSZ8863_REG_SW_RESET		0x43

#define KSZ8863_GLOBAL_SOFTWARE_RESET	BIT(4)
@@ -217,8 +204,6 @@
#define REG_PORT_4_STATUS_0		0x48

/* For KSZ8765. */
#define PORT_FIBER_MODE			BIT(7)

#define PORT_REMOTE_ASYM_PAUSE		BIT(5)
#define PORT_REMOTE_SYM_PAUSE		BIT(4)
#define PORT_REMOTE_100BTX_FD		BIT(3)
@@ -322,7 +307,6 @@

#define REG_PORT_CTRL_5			0x05

#define REG_PORT_STATUS_0		0x08
#define REG_PORT_STATUS_1		0x09
#define REG_PORT_LINK_MD_CTRL		0x0A
#define REG_PORT_LINK_MD_RESULT		0x0B
+67 −114
Original line number Diff line number Diff line
@@ -47,9 +47,8 @@ static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
			   bits, set ? bits : 0);
}

static int ksz9477_change_mtu(struct dsa_switch *ds, int port, int mtu)
static int ksz9477_change_mtu(struct ksz_device *dev, int port, int mtu)
{
	struct ksz_device *dev = ds->priv;
	u16 frame_size, max_frame = 0;
	int i;

@@ -65,7 +64,7 @@ static int ksz9477_change_mtu(struct dsa_switch *ds, int port, int mtu)
				  REG_SW_MTU_MASK, max_frame);
}

static int ksz9477_max_mtu(struct dsa_switch *ds, int port)
static int ksz9477_max_mtu(struct ksz_device *dev, int port)
{
	return KSZ9477_MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;
}
@@ -276,21 +275,8 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
	mutex_unlock(&mib->cnt_mutex);
}

static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
						      int port,
						      enum dsa_tag_protocol mp)
{
	enum dsa_tag_protocol proto = DSA_TAG_PROTO_KSZ9477;
	struct ksz_device *dev = ds->priv;

	if (dev->features & IS_9893)
		proto = DSA_TAG_PROTO_KSZ9893;
	return proto;
}

static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
static void ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data)
{
	struct ksz_device *dev = ds->priv;
	u16 val = 0xffff;

	/* No real PHY after this. Simulate the PHY.
@@ -335,24 +321,20 @@ static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
		ksz_pread16(dev, addr, 0x100 + (reg << 1), &val);
	}

	return val;
	*data = val;
}

static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
			       u16 val)
static void ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val)
{
	struct ksz_device *dev = ds->priv;

	/* No real PHY after this. */
	if (addr >= dev->phy_port_cnt)
		return 0;
		return;

	/* No gigabit support.  Do not write to this register. */
	if (!(dev->features & GBIT_SUPPORT) && reg == MII_CTRL1000)
		return 0;
	ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val);
		return;

	return 0;
	ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val);
}

static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
@@ -361,12 +343,6 @@ static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
	ksz_pwrite32(dev, port, REG_PORT_VLAN_MEMBERSHIP__4, member);
}

static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
				       u8 state)
{
	ksz_port_stp_state_set(ds, port, state, P_STP_CTRL);
}

static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
{
	u8 data;
@@ -389,12 +365,10 @@ static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
	}
}

static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
static int ksz9477_port_vlan_filtering(struct ksz_device *dev, int port,
				       bool flag,
				       struct netlink_ext_ack *extack)
{
	struct ksz_device *dev = ds->priv;

	if (flag) {
		ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL,
			     PORT_VLAN_LOOKUP_VID_0, true);
@@ -408,11 +382,10 @@ static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
	return 0;
}

static int ksz9477_port_vlan_add(struct dsa_switch *ds, int port,
static int ksz9477_port_vlan_add(struct ksz_device *dev, int port,
				 const struct switchdev_obj_port_vlan *vlan,
				 struct netlink_ext_ack *extack)
{
	struct ksz_device *dev = ds->priv;
	u32 vlan_table[3];
	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
	int err;
@@ -445,10 +418,9 @@ static int ksz9477_port_vlan_add(struct dsa_switch *ds, int port,
	return 0;
}

static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port,
static int ksz9477_port_vlan_del(struct ksz_device *dev, int port,
				 const struct switchdev_obj_port_vlan *vlan)
{
	struct ksz_device *dev = ds->priv;
	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
	u32 vlan_table[3];
	u16 pvid;
@@ -479,11 +451,10 @@ static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port,
	return 0;
}

static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port,
static int ksz9477_fdb_add(struct ksz_device *dev, int port,
			   const unsigned char *addr, u16 vid,
			   struct dsa_db db)
{
	struct ksz_device *dev = ds->priv;
	u32 alu_table[4];
	u32 data;
	int ret = 0;
@@ -537,11 +508,10 @@ static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port,
	return ret;
}

static int ksz9477_port_fdb_del(struct dsa_switch *ds, int port,
static int ksz9477_fdb_del(struct ksz_device *dev, int port,
			   const unsigned char *addr, u16 vid,
			   struct dsa_db db)
{
	struct ksz_device *dev = ds->priv;
	u32 alu_table[4];
	u32 data;
	int ret = 0;
@@ -628,10 +598,9 @@ static void ksz9477_convert_alu(struct alu_struct *alu, u32 *alu_table)
	alu->mac[5] = alu_table[3] & 0xFF;
}

static int ksz9477_port_fdb_dump(struct dsa_switch *ds, int port,
static int ksz9477_fdb_dump(struct ksz_device *dev, int port,
			    dsa_fdb_dump_cb_t *cb, void *data)
{
	struct ksz_device *dev = ds->priv;
	int ret = 0;
	u32 ksz_data;
	u32 alu_table[4];
@@ -680,11 +649,10 @@ static int ksz9477_port_fdb_dump(struct dsa_switch *ds, int port,
	return ret;
}

static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
static int ksz9477_mdb_add(struct ksz_device *dev, int port,
			   const struct switchdev_obj_port_mdb *mdb,
			   struct dsa_db db)
{
	struct ksz_device *dev = ds->priv;
	u32 static_table[4];
	u32 data;
	int index;
@@ -756,11 +724,10 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
	return err;
}

static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
static int ksz9477_mdb_del(struct ksz_device *dev, int port,
			   const struct switchdev_obj_port_mdb *mdb,
			   struct dsa_db db)
{
	struct ksz_device *dev = ds->priv;
	u32 static_table[4];
	u32 data;
	int index;
@@ -832,11 +799,10 @@ static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
	return ret;
}

static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port,
static int ksz9477_port_mirror_add(struct ksz_device *dev, int port,
				   struct dsa_mall_mirror_tc_entry *mirror,
				   bool ingress, struct netlink_ext_ack *extack)
{
	struct ksz_device *dev = ds->priv;
	u8 data;
	int p;

@@ -872,10 +838,9 @@ static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port,
	return 0;
}

static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port,
static void ksz9477_port_mirror_del(struct ksz_device *dev, int port,
				    struct dsa_mall_mirror_tc_entry *mirror)
{
	struct ksz_device *dev = ds->priv;
	bool in_use = false;
	u8 data;
	int p;
@@ -1097,11 +1062,9 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port)
	ksz9477_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee);
}

static void ksz9477_get_caps(struct dsa_switch *ds, int port,
static void ksz9477_get_caps(struct ksz_device *dev, int port,
			     struct phylink_config *config)
{
	ksz_phylink_get_caps(ds, port, config);

	config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000FD |
				   MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
}
@@ -1260,7 +1223,7 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
			continue;
		p = &dev->ports[i];

		ksz9477_port_stp_state_set(ds, i, BR_STATE_DISABLED);
		ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED);
		p->on = 1;
		if (i < dev->phy_port_cnt)
			p->phy = 1;
@@ -1326,33 +1289,33 @@ static int ksz9477_setup(struct dsa_switch *ds)
}

static const struct dsa_switch_ops ksz9477_switch_ops = {
	.get_tag_protocol	= ksz9477_get_tag_protocol,
	.get_tag_protocol	= ksz_get_tag_protocol,
	.setup			= ksz9477_setup,
	.phy_read		= ksz9477_phy_read16,
	.phy_write		= ksz9477_phy_write16,
	.phy_read		= ksz_phy_read16,
	.phy_write		= ksz_phy_write16,
	.phylink_mac_link_down	= ksz_mac_link_down,
	.phylink_get_caps	= ksz9477_get_caps,
	.phylink_get_caps	= ksz_phylink_get_caps,
	.port_enable		= ksz_enable_port,
	.get_strings		= ksz_get_strings,
	.get_ethtool_stats	= ksz_get_ethtool_stats,
	.get_sset_count		= ksz_sset_count,
	.port_bridge_join	= ksz_port_bridge_join,
	.port_bridge_leave	= ksz_port_bridge_leave,
	.port_stp_state_set	= ksz9477_port_stp_state_set,
	.port_stp_state_set	= ksz_port_stp_state_set,
	.port_fast_age		= ksz_port_fast_age,
	.port_vlan_filtering	= ksz9477_port_vlan_filtering,
	.port_vlan_add		= ksz9477_port_vlan_add,
	.port_vlan_del		= ksz9477_port_vlan_del,
	.port_fdb_dump		= ksz9477_port_fdb_dump,
	.port_fdb_add		= ksz9477_port_fdb_add,
	.port_fdb_del		= ksz9477_port_fdb_del,
	.port_mdb_add           = ksz9477_port_mdb_add,
	.port_mdb_del           = ksz9477_port_mdb_del,
	.port_mirror_add	= ksz9477_port_mirror_add,
	.port_mirror_del	= ksz9477_port_mirror_del,
	.port_vlan_filtering	= ksz_port_vlan_filtering,
	.port_vlan_add		= ksz_port_vlan_add,
	.port_vlan_del		= ksz_port_vlan_del,
	.port_fdb_dump		= ksz_port_fdb_dump,
	.port_fdb_add		= ksz_port_fdb_add,
	.port_fdb_del		= ksz_port_fdb_del,
	.port_mdb_add           = ksz_port_mdb_add,
	.port_mdb_del           = ksz_port_mdb_del,
	.port_mirror_add	= ksz_port_mirror_add,
	.port_mirror_del	= ksz_port_mirror_del,
	.get_stats64		= ksz_get_stats64,
	.port_change_mtu	= ksz9477_change_mtu,
	.port_max_mtu		= ksz9477_max_mtu,
	.port_change_mtu	= ksz_change_mtu,
	.port_max_mtu		= ksz_max_mtu,
};

static u32 ksz9477_get_port_addr(int port, int offset)
@@ -1360,14 +1323,15 @@ static u32 ksz9477_get_port_addr(int port, int offset)
	return PORT_CTRL_ADDR(port, offset);
}

static int ksz9477_switch_detect(struct ksz_device *dev)
static int ksz9477_switch_init(struct ksz_device *dev)
{
	u8 data8;
	u8 id_hi;
	u8 id_lo;
	u32 id32;
	int ret;

	dev->ds->ops = &ksz9477_switch_ops;

	dev->port_mask = (1 << dev->info->port_cnt) - 1;

	/* turn off SPI DO Edge select */
	ret = ksz_read8(dev, REG_SW_GLOBAL_SERIAL_CTRL_0, &data8);
	if (ret)
@@ -1378,10 +1342,6 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
	if (ret)
		return ret;

	/* read chip id */
	ret = ksz_read32(dev, REG_CHIP_ID0__1, &id32);
	if (ret)
		return ret;
	ret = ksz_read8(dev, REG_GLOBAL_OPTIONS, &data8);
	if (ret)
		return ret;
@@ -1392,12 +1352,7 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
	/* Default capability is gigabit capable. */
	dev->features = GBIT_SUPPORT;

	dev_dbg(dev->dev, "Switch detect: ID=%08x%02x\n", id32, data8);
	id_hi = (u8)(id32 >> 16);
	id_lo = (u8)(id32 >> 8);
	if ((id_lo & 0xf) == 3) {
		/* Chip is from KSZ9893 design. */
		dev_info(dev->dev, "Found KSZ9893\n");
	if (dev->chip_id == KSZ9893_CHIP_ID) {
		dev->features |= IS_9893;

		/* Chip does not support gigabit. */
@@ -1405,7 +1360,6 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
			dev->features &= ~GBIT_SUPPORT;
		dev->phy_port_cnt = 2;
	} else {
		dev_info(dev->dev, "Found KSZ9477 or compatible\n");
		/* Chip uses new XMII register definitions. */
		dev->features |= NEW_XMII;

@@ -1413,21 +1367,6 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
		if (!(data8 & SW_GIGABIT_ABLE))
			dev->features &= ~GBIT_SUPPORT;
	}

	/* Change chip id to known ones so it can be matched against them. */
	id32 = (id_hi << 16) | (id_lo << 8);

	dev->chip_id = id32;

	return 0;
}

static int ksz9477_switch_init(struct ksz_device *dev)
{
	dev->ds->ops = &ksz9477_switch_ops;

	dev->port_mask = (1 << dev->info->port_cnt) - 1;

	return 0;
}

@@ -1441,13 +1380,27 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
	.cfg_port_member = ksz9477_cfg_port_member,
	.flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,
	.port_setup = ksz9477_port_setup,
	.r_phy = ksz9477_r_phy,
	.w_phy = ksz9477_w_phy,
	.r_mib_cnt = ksz9477_r_mib_cnt,
	.r_mib_pkt = ksz9477_r_mib_pkt,
	.r_mib_stat64 = ksz_r_mib_stats64,
	.freeze_mib = ksz9477_freeze_mib,
	.port_init_cnt = ksz9477_port_init_cnt,
	.vlan_filtering = ksz9477_port_vlan_filtering,
	.vlan_add = ksz9477_port_vlan_add,
	.vlan_del = ksz9477_port_vlan_del,
	.mirror_add = ksz9477_port_mirror_add,
	.mirror_del = ksz9477_port_mirror_del,
	.get_caps = ksz9477_get_caps,
	.fdb_dump = ksz9477_fdb_dump,
	.fdb_add = ksz9477_fdb_add,
	.fdb_del = ksz9477_fdb_del,
	.mdb_add = ksz9477_mdb_add,
	.mdb_del = ksz9477_mdb_del,
	.change_mtu = ksz9477_change_mtu,
	.max_mtu = ksz9477_max_mtu,
	.shutdown = ksz9477_reset_switch,
	.detect = ksz9477_switch_detect,
	.init = ksz9477_switch_init,
	.exit = ksz9477_switch_exit,
};
+0 −1
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@

#define REG_CHIP_ID2__1			0x0002

#define CHIP_ID_63			0x63
#define CHIP_ID_66			0x66
#define CHIP_ID_67			0x67
#define CHIP_ID_77			0x77
+253 −89

File changed.

Preview size limit exceeded, changes collapsed.

Loading