Commit 4fefbc66 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'mdio-support-updates'

Nikita Yushchenko says:

====================
rswitch: mdio support updates

This series cleans up rswitch mdio support, and adds C22 operations.
====================

Link: https://patch.msgid.link/20241216071957.2587354-1-nikita.yoush@cogentembedded.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 44d49629 db48fe90
Loading
Loading
Loading
Loading
+52 −32
Original line number Diff line number Diff line
@@ -1164,9 +1164,9 @@ static void rswitch_rmac_setting(struct rswitch_etha *etha, const u8 *mac)

static void rswitch_etha_enable_mii(struct rswitch_etha *etha)
{
	rswitch_modify(etha->addr, MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK,
		       MPIC_PSMCS(etha->psmcs) | MPIC_PSMHT(0x06));
	rswitch_modify(etha->addr, MPSM, 0, MPSM_MFF_C45);
	rswitch_modify(etha->addr, MPIC, MPIC_PSMCS | MPIC_PSMHT,
		       FIELD_PREP(MPIC_PSMCS, etha->psmcs) |
		       FIELD_PREP(MPIC_PSMHT, 0x06));
}

static int rswitch_etha_hw_init(struct rswitch_etha *etha, const u8 *mac)
@@ -1195,61 +1195,79 @@ static int rswitch_etha_hw_init(struct rswitch_etha *etha, const u8 *mac)
	return rswitch_etha_change_mode(etha, EAMC_OPC_OPERATION);
}

static int rswitch_etha_set_access(struct rswitch_etha *etha, bool read,
				   int phyad, int devad, int regad, int data)
static int rswitch_etha_mpsm_op(struct rswitch_etha *etha, bool read,
				unsigned int mmf, unsigned int pda,
				unsigned int pra, unsigned int pop,
				unsigned int prd)
{
	int pop = read ? MDIO_READ_C45 : MDIO_WRITE_C45;
	u32 val;
	int ret;

	if (devad == 0xffffffff)
		return -ENODEV;

	writel(MMIS1_CLEAR_FLAGS, etha->addr + MMIS1);
	val = MPSM_PSME |
	      FIELD_PREP(MPSM_MFF, mmf) |
	      FIELD_PREP(MPSM_PDA, pda) |
	      FIELD_PREP(MPSM_PRA, pra) |
	      FIELD_PREP(MPSM_POP, pop) |
	      FIELD_PREP(MPSM_PRD, prd);
	iowrite32(val, etha->addr + MPSM);

	val = MPSM_PSME | MPSM_MFF_C45;
	iowrite32((regad << 16) | (devad << 8) | (phyad << 3) | val, etha->addr + MPSM);

	ret = rswitch_reg_wait(etha->addr, MMIS1, MMIS1_PAACS, MMIS1_PAACS);
	ret = rswitch_reg_wait(etha->addr, MPSM, MPSM_PSME, 0);
	if (ret)
		return ret;

	rswitch_modify(etha->addr, MMIS1, MMIS1_PAACS, MMIS1_PAACS);

	if (read) {
		writel((pop << 13) | (devad << 8) | (phyad << 3) | val, etha->addr + MPSM);
		val = ioread32(etha->addr + MPSM);
		ret = FIELD_GET(MPSM_PRD, val);
	}

		ret = rswitch_reg_wait(etha->addr, MMIS1, MMIS1_PRACS, MMIS1_PRACS);
		if (ret)
	return ret;
}

		ret = (ioread32(etha->addr + MPSM) & MPSM_PRD_MASK) >> 16;
static int rswitch_etha_mii_read_c45(struct mii_bus *bus, int addr, int devad,
				     int regad)
{
	struct rswitch_etha *etha = bus->priv;
	int ret;

		rswitch_modify(etha->addr, MMIS1, MMIS1_PRACS, MMIS1_PRACS);
	} else {
		iowrite32((data << 16) | (pop << 13) | (devad << 8) | (phyad << 3) | val,
			  etha->addr + MPSM);
	ret = rswitch_etha_mpsm_op(etha, false, MPSM_MMF_C45, addr, devad,
				   MPSM_POP_ADDRESS, regad);
	if (ret)
		return ret;

		ret = rswitch_reg_wait(etha->addr, MMIS1, MMIS1_PWACS, MMIS1_PWACS);
	return rswitch_etha_mpsm_op(etha, true, MPSM_MMF_C45, addr, devad,
				    MPSM_POP_READ_C45, 0);
}

static int rswitch_etha_mii_write_c45(struct mii_bus *bus, int addr, int devad,
				      int regad, u16 val)
{
	struct rswitch_etha *etha = bus->priv;
	int ret;

	ret = rswitch_etha_mpsm_op(etha, false, MPSM_MMF_C45, addr, devad,
				   MPSM_POP_ADDRESS, regad);
	if (ret)
		return ret;

	return rswitch_etha_mpsm_op(etha, false, MPSM_MMF_C45, addr, devad,
				    MPSM_POP_WRITE, val);
}

static int rswitch_etha_mii_read_c45(struct mii_bus *bus, int addr, int devad,
				     int regad)
static int rswitch_etha_mii_read_c22(struct mii_bus *bus, int phyad, int regad)
{
	struct rswitch_etha *etha = bus->priv;

	return rswitch_etha_set_access(etha, true, addr, devad, regad, 0);
	return rswitch_etha_mpsm_op(etha, true, MPSM_MMF_C22, phyad, regad,
				    MPSM_POP_READ_C22, 0);
}

static int rswitch_etha_mii_write_c45(struct mii_bus *bus, int addr, int devad,
static int rswitch_etha_mii_write_c22(struct mii_bus *bus, int phyad,
				      int regad, u16 val)
{
	struct rswitch_etha *etha = bus->priv;

	return rswitch_etha_set_access(etha, false, addr, devad, regad, val);
	return rswitch_etha_mpsm_op(etha, false, MPSM_MMF_C22, phyad, regad,
				    MPSM_POP_WRITE, val);
}

/* Call of_node_put(port) after done */
@@ -1334,6 +1352,8 @@ static int rswitch_mii_register(struct rswitch_device *rdev)
	mii_bus->priv = rdev->etha;
	mii_bus->read_c45 = rswitch_etha_mii_read_c45;
	mii_bus->write_c45 = rswitch_etha_mii_write_c45;
	mii_bus->read = rswitch_etha_mii_read_c22;
	mii_bus->write = rswitch_etha_mii_write_c22;
	mii_bus->parent = &rdev->priv->pdev->dev;

	mdio_np = of_get_child_by_name(rdev->np_port, "mdio");
+13 −20
Original line number Diff line number Diff line
@@ -732,28 +732,21 @@ enum rswitch_etha_mode {
#define MPIC_LSC_100M		1
#define MPIC_LSC_1G		2
#define MPIC_LSC_2_5G		3

#define MDIO_READ_C45		0x03
#define MDIO_WRITE_C45		0x01
#define MPIC_PSMCS		GENMASK(22, 16)
#define MPIC_PSMHT		GENMASK(26, 24)

#define MPSM_PSME		BIT(0)
#define MPSM_MFF_C45		BIT(2)
#define MPSM_PRD_SHIFT		16
#define MPSM_PRD_MASK		GENMASK(31, MPSM_PRD_SHIFT)

/* Completion flags */
#define MMIS1_PAACS             BIT(2) /* Address */
#define MMIS1_PWACS             BIT(1) /* Write */
#define MMIS1_PRACS             BIT(0) /* Read */
#define MMIS1_CLEAR_FLAGS       0xf

#define MPIC_PSMCS_SHIFT	16
#define MPIC_PSMCS_MASK		GENMASK(22, MPIC_PSMCS_SHIFT)
#define MPIC_PSMCS(val)		((val) << MPIC_PSMCS_SHIFT)

#define MPIC_PSMHT_SHIFT	24
#define MPIC_PSMHT_MASK		GENMASK(26, MPIC_PSMHT_SHIFT)
#define MPIC_PSMHT(val)		((val) << MPIC_PSMHT_SHIFT)
#define MPSM_MFF		BIT(2)
#define MPSM_MMF_C22		0
#define MPSM_MMF_C45		1
#define MPSM_PDA		GENMASK(7, 3)
#define MPSM_PRA		GENMASK(12, 8)
#define MPSM_POP		GENMASK(14, 13)
#define MPSM_POP_ADDRESS	0
#define MPSM_POP_WRITE		1
#define MPSM_POP_READ_C22	2
#define MPSM_POP_READ_C45	3
#define MPSM_PRD		GENMASK(31, 16)

#define MLVC_PLV		BIT(16)