Commit 08f94ccf authored by Jiawen Wu's avatar Jiawen Wu Committed by Duanqiang Wen
Browse files

net: wangxun: move MDIO bus implementation to the library

mainline inclusion
from mainline-v6.7-rc1
commit f557524029458ab7dd1c6077f35fa23fbb744356
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I93QRU
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f557524029458ab7dd1c6077f35fa23fbb744356



---------------------------------------------------------

Move similar code of accessing MDIO bus from txgbe/ngbe to libwx.

Signed-off-by: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20230912031424.721386-1-jiawenwu@trustnetic.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarDuanqiang Wen <duanqiangwen@net-swift.com>
parent ad4b3d5e
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -12,6 +12,98 @@
#include "wx_lib.h"
#include "wx_hw.h"

static int wx_phy_read_reg_mdi(struct mii_bus *bus, int phy_addr, int devnum, int regnum)
{
	struct wx *wx = bus->priv;
	u32 command, val;
	int ret;

	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(devnum);
	wr32(wx, WX_MSCA, command);

	command = WX_MSCC_CMD(WX_MSCA_CMD_READ) | WX_MSCC_BUSY;
	if (wx->mac.type == wx_mac_em)
		command |= WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret) {
		wx_err(wx, "Mdio read c22 command did not complete.\n");
		return ret;
	}

	return (u16)rd32(wx, WX_MSCC);
}

static int wx_phy_write_reg_mdi(struct mii_bus *bus, int phy_addr,
				int devnum, int regnum, u16 value)
{
	struct wx *wx = bus->priv;
	u32 command, val;
	int ret;

	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(devnum);
	wr32(wx, WX_MSCA, command);

	command = value | WX_MSCC_CMD(WX_MSCA_CMD_WRITE) | WX_MSCC_BUSY;
	if (wx->mac.type == wx_mac_em)
		command |= WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret)
		wx_err(wx, "Mdio write c22 command did not complete.\n");

	return ret;
}

int wx_phy_read_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0xF);
	return wx_phy_read_reg_mdi(bus, phy_addr, 0, regnum);
}
EXPORT_SYMBOL(wx_phy_read_reg_mdi_c22);

int wx_phy_write_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0xF);
	return wx_phy_write_reg_mdi(bus, phy_addr, 0, regnum, value);
}
EXPORT_SYMBOL(wx_phy_write_reg_mdi_c22);

int wx_phy_read_reg_mdi_c45(struct mii_bus *bus, int phy_addr, int devnum, int regnum)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0);
	return wx_phy_read_reg_mdi(bus, phy_addr, devnum, regnum);
}
EXPORT_SYMBOL(wx_phy_read_reg_mdi_c45);

int wx_phy_write_reg_mdi_c45(struct mii_bus *bus, int phy_addr,
			     int devnum, int regnum, u16 value)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0);
	return wx_phy_write_reg_mdi(bus, phy_addr, devnum, regnum, value);
}
EXPORT_SYMBOL(wx_phy_write_reg_mdi_c45);

static void wx_intr_disable(struct wx *wx, u64 qmask)
{
	u32 mask;
+7 −0
Original line number Diff line number Diff line
@@ -4,6 +4,13 @@
#ifndef _WX_HW_H_
#define _WX_HW_H_

#include <linux/phy.h>

int wx_phy_read_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum);
int wx_phy_write_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum, u16 value);
int wx_phy_read_reg_mdi_c45(struct mii_bus *bus, int phy_addr, int devnum, int regnum);
int wx_phy_write_reg_mdi_c45(struct mii_bus *bus, int phy_addr,
			     int devnum, int regnum, u16 value);
void wx_intr_enable(struct wx *wx, u64 qmask);
void wx_irq_disable(struct wx *wx);
int wx_check_flash_load(struct wx *wx, u32 check_bit);
+1 −0
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ enum WX_MSCA_CMD_value {
#define WX_MSCC_SADDR                BIT(18)
#define WX_MSCC_BUSY                 BIT(22)
#define WX_MDIO_CLK(v)               FIELD_PREP(GENMASK(21, 19), v)
#define WX_MDIO_CLAUSE_SELECT        0x11220
#define WX_MMC_CONTROL               0x11800
#define WX_MMC_CONTROL_RSTONRD       BIT(2) /* reset on read */

+4 −115
Original line number Diff line number Diff line
@@ -29,117 +29,6 @@ static int ngbe_phy_write_reg_internal(struct mii_bus *bus, int phy_addr, int re
	return 0;
}

static int ngbe_phy_read_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum)
{
	u32 command, val, device_type = 0;
	struct wx *wx = bus->priv;
	int ret;

	wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0xF);
	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(device_type);
	wr32(wx, WX_MSCA, command);
	command = WX_MSCC_CMD(WX_MSCA_CMD_READ) |
		  WX_MSCC_BUSY |
		  WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret) {
		wx_err(wx, "Mdio read c22 command did not complete.\n");
		return ret;
	}

	return (u16)rd32(wx, WX_MSCC);
}

static int ngbe_phy_write_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
{
	u32 command, val, device_type = 0;
	struct wx *wx = bus->priv;
	int ret;

	wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0xF);
	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(device_type);
	wr32(wx, WX_MSCA, command);
	command = value |
		  WX_MSCC_CMD(WX_MSCA_CMD_WRITE) |
		  WX_MSCC_BUSY |
		  WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret)
		wx_err(wx, "Mdio write c22 command did not complete.\n");

	return ret;
}

static int ngbe_phy_read_reg_mdi_c45(struct mii_bus *bus, int phy_addr, int devnum, int regnum)
{
	struct wx *wx = bus->priv;
	u32 val, command;
	int ret;

	wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0x0);
	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(devnum);
	wr32(wx, WX_MSCA, command);
	command = WX_MSCC_CMD(WX_MSCA_CMD_READ) |
		  WX_MSCC_BUSY |
		  WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret) {
		wx_err(wx, "Mdio read c45 command did not complete.\n");
		return ret;
	}

	return (u16)rd32(wx, WX_MSCC);
}

static int ngbe_phy_write_reg_mdi_c45(struct mii_bus *bus, int phy_addr,
				      int devnum, int regnum, u16 value)
{
	struct wx *wx = bus->priv;
	int ret, command;
	u16 val;

	wr32(wx, NGBE_MDIO_CLAUSE_SELECT, 0x0);
	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(devnum);
	wr32(wx, WX_MSCA, command);
	command = value |
		  WX_MSCC_CMD(WX_MSCA_CMD_WRITE) |
		  WX_MSCC_BUSY |
		  WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret)
		wx_err(wx, "Mdio write c45 command did not complete.\n");

	return ret;
}

static int ngbe_phy_read_reg_c22(struct mii_bus *bus, int phy_addr, int regnum)
{
	struct wx *wx = bus->priv;
@@ -148,7 +37,7 @@ static int ngbe_phy_read_reg_c22(struct mii_bus *bus, int phy_addr, int regnum)
	if (wx->mac_type == em_mac_type_mdi)
		phy_data = ngbe_phy_read_reg_internal(bus, phy_addr, regnum);
	else
		phy_data = ngbe_phy_read_reg_mdi_c22(bus, phy_addr, regnum);
		phy_data = wx_phy_read_reg_mdi_c22(bus, phy_addr, regnum);

	return phy_data;
}
@@ -162,7 +51,7 @@ static int ngbe_phy_write_reg_c22(struct mii_bus *bus, int phy_addr,
	if (wx->mac_type == em_mac_type_mdi)
		ret = ngbe_phy_write_reg_internal(bus, phy_addr, regnum, value);
	else
		ret = ngbe_phy_write_reg_mdi_c22(bus, phy_addr, regnum, value);
		ret = wx_phy_write_reg_mdi_c22(bus, phy_addr, regnum, value);

	return ret;
}
@@ -262,8 +151,8 @@ int ngbe_mdio_init(struct wx *wx)
	mii_bus->priv = wx;

	if (wx->mac_type == em_mac_type_rgmii) {
		mii_bus->read_c45 = ngbe_phy_read_reg_mdi_c45;
		mii_bus->write_c45 = ngbe_phy_write_reg_mdi_c45;
		mii_bus->read_c45 = wx_phy_read_reg_mdi_c45;
		mii_bus->write_c45 = wx_phy_write_reg_mdi_c45;
	}

	snprintf(mii_bus->id, MII_BUS_ID_SIZE, "ngbe-%x", pci_dev_id(pdev));
+0 −3
Original line number Diff line number Diff line
@@ -59,9 +59,6 @@
#define NGBE_EEPROM_VERSION_L			0x1D
#define NGBE_EEPROM_VERSION_H			0x1E

/* Media-dependent registers. */
#define NGBE_MDIO_CLAUSE_SELECT			0x11220

/* GPIO Registers */
#define NGBE_GPIO_DR				0x14800
#define NGBE_GPIO_DDR				0x14804
Loading