From: Raju Rangoju <Raju.Rangoju@amd.com>
To: <netdev@vger.kernel.org>
Cc: <davem@davemloft.net>, <edumazet@google.com>, <kuba@kernel.org>,
<pabeni@redhat.com>, <Shyam-sundar.S-k@amd.com>,
Raju Rangoju <Raju.Rangoju@amd.com>,
Sudheesh Mavila <sudheesh.mavila@amd.com>
Subject: [PATCH v3 net-next 2/3] amd-xgbe: add support for Crater ethernet device
Date: Tue, 12 Dec 2023 11:07:22 +0530 [thread overview]
Message-ID: <20231212053723.443772-3-Raju.Rangoju@amd.com> (raw)
In-Reply-To: <20231212053723.443772-1-Raju.Rangoju@amd.com>
Add the necessary support to enable Crater ethernet device. Since the
BAR1 address cannot be used to access the XPCS registers on Crater, use
the pci_{read/write}_config_dword calls. Also, include the new pci device
id 0x1641 to register Crater device with PCIe.
Co-developed-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 5 ++
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 93 +++++++++++++++++++++
drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 35 +++++++-
drivers/net/ethernet/amd/xgbe/xgbe.h | 6 ++
4 files changed, 137 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 3b70f6737633..e1f70f0528ef 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -900,6 +900,11 @@
#define PCS_V2_RV_WINDOW_SELECT 0x1064
#define PCS_V2_YC_WINDOW_DEF 0x18060
#define PCS_V2_YC_WINDOW_SELECT 0x18064
+#define PCS_V2_RN_WINDOW_DEF 0xF8078
+#define PCS_V2_RN_WINDOW_SELECT 0xF807c
+
+#define PCS_RN_SMN_BASE_ADDR 0x11E00000
+#define PCS_RN_PORT_ADDR_SIZE 0x100000
/* PCS register entry bit positions and sizes */
#define PCS_V2_WINDOW_DEF_OFFSET_INDEX 6
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 6cd003c24a64..a9eb2ffa9f73 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -120,6 +120,7 @@
#include <linux/bitrev.h>
#include <linux/crc32.h>
#include <linux/crc32poly.h>
+#include <linux/pci.h>
#include "xgbe.h"
#include "xgbe-common.h"
@@ -1165,6 +1166,92 @@ static unsigned int get_index_offset(struct xgbe_prv_data *pdata, unsigned int m
return pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
}
+static int xgbe_read_mmd_regs_v3(struct xgbe_prv_data *pdata, int prtad,
+ int mmd_reg)
+{
+ unsigned int mmd_address, index, offset;
+ struct pci_dev *rdev;
+ unsigned long flags;
+ int mmd_data;
+
+ rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
+ if (!rdev)
+ return 0;
+
+ mmd_address = get_mmd_address(pdata, mmd_reg);
+
+ /* The PCS registers are accessed using mmio. The underlying
+ * management interface uses indirect addressing to access the MMD
+ * register sets. This requires accessing of the PCS register in two
+ * phases, an address phase and a data phase.
+ *
+ * The mmio interface is based on 16-bit offsets and values. All
+ * register offsets must therefore be adjusted by left shifting the
+ * offset 1 bit and reading 16 bits of data.
+ */
+ offset = get_index_offset(pdata, mmd_address, &index);
+
+ spin_lock_irqsave(&pdata->xpcs_lock, flags);
+ pci_write_config_dword(rdev, 0x60, (pdata->xphy_base + pdata->xpcs_window_sel_reg));
+ pci_write_config_dword(rdev, 0x64, index);
+ pci_write_config_dword(rdev, 0x60, pdata->xphy_base + offset);
+ pci_read_config_dword(rdev, 0x64, &mmd_data);
+ mmd_data = (offset % 4) ? FIELD_GET(XGBE_GEN_HI_MASK, mmd_data) :
+ FIELD_GET(XGBE_GEN_LO_MASK, mmd_data);
+ pci_dev_put(rdev);
+
+ spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
+
+ return mmd_data;
+}
+
+static void xgbe_write_mmd_regs_v3(struct xgbe_prv_data *pdata, int prtad,
+ int mmd_reg, int mmd_data)
+{
+ unsigned int mmd_address, index, offset, ctr_mmd_data;
+ struct pci_dev *rdev;
+ unsigned long flags;
+
+ rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
+ if (!rdev)
+ return;
+
+ mmd_address = get_mmd_address(pdata, mmd_reg);
+
+ /* The PCS registers are accessed using mmio. The underlying
+ * management interface uses indirect addressing to access the MMD
+ * register sets. This requires accessing of the PCS register in two
+ * phases, an address phase and a data phase.
+ *
+ * The mmio interface is based on 16-bit offsets and values. All
+ * register offsets must therefore be adjusted by left shifting the
+ * offset 1 bit and writing 16 bits of data.
+ */
+ offset = get_index_offset(pdata, mmd_address, &index);
+
+ spin_lock_irqsave(&pdata->xpcs_lock, flags);
+ pci_write_config_dword(rdev, 0x60, (pdata->xphy_base + pdata->xpcs_window_sel_reg));
+ pci_write_config_dword(rdev, 0x64, index);
+ pci_write_config_dword(rdev, 0x60, pdata->xphy_base + offset);
+ pci_read_config_dword(rdev, 0x64, &ctr_mmd_data);
+ if (offset % 4) {
+ ctr_mmd_data = FIELD_PREP(XGBE_GEN_HI_MASK, mmd_data) |
+ FIELD_GET(XGBE_GEN_LO_MASK, ctr_mmd_data);
+ } else {
+ ctr_mmd_data = FIELD_PREP(XGBE_GEN_HI_MASK,
+ FIELD_GET(XGBE_GEN_HI_MASK, ctr_mmd_data)) |
+ FIELD_GET(XGBE_GEN_LO_MASK, mmd_data);
+ }
+
+ pci_write_config_dword(rdev, 0x60, (pdata->xphy_base + pdata->xpcs_window_sel_reg));
+ pci_write_config_dword(rdev, 0x64, index);
+ pci_write_config_dword(rdev, 0x60, (pdata->xphy_base + offset));
+ pci_write_config_dword(rdev, 0x64, ctr_mmd_data);
+ pci_dev_put(rdev);
+
+ spin_unlock_irqrestore(&pdata->xpcs_lock, flags);
+}
+
static int xgbe_read_mmd_regs_v2(struct xgbe_prv_data *pdata, int prtad,
int mmd_reg)
{
@@ -1274,6 +1361,9 @@ static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
case XGBE_XPCS_ACCESS_V1:
return xgbe_read_mmd_regs_v1(pdata, prtad, mmd_reg);
+ case XGBE_XPCS_ACCESS_V3:
+ return xgbe_read_mmd_regs_v3(pdata, prtad, mmd_reg);
+
case XGBE_XPCS_ACCESS_V2:
default:
return xgbe_read_mmd_regs_v2(pdata, prtad, mmd_reg);
@@ -1287,6 +1377,9 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
case XGBE_XPCS_ACCESS_V1:
return xgbe_write_mmd_regs_v1(pdata, prtad, mmd_reg, mmd_data);
+ case XGBE_XPCS_ACCESS_V3:
+ return xgbe_write_mmd_regs_v3(pdata, prtad, mmd_reg, mmd_data);
+
case XGBE_XPCS_ACCESS_V2:
default:
return xgbe_write_mmd_regs_v2(pdata, prtad, mmd_reg, mmd_data);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
index 8b0c1e450b7e..db3e8aac3339 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
@@ -295,15 +295,28 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Yellow Carp devices do not need rrc */
pdata->vdata->enable_rrc = 0;
break;
+ case 0x1630:
+ pdata->xpcs_window_def_reg = PCS_V2_RN_WINDOW_DEF;
+ pdata->xpcs_window_sel_reg = PCS_V2_RN_WINDOW_SELECT;
+ break;
default:
pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
break;
}
- pci_dev_put(rdev);
/* Configure the PCS indirect addressing support */
- reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
+ if (pdata->vdata->xpcs_access == XGBE_XPCS_ACCESS_V3) {
+ reg = XP_IOREAD(pdata, XP_PROP_0);
+ pdata->xphy_base = PCS_RN_SMN_BASE_ADDR +
+ (PCS_RN_PORT_ADDR_SIZE * XP_GET_BITS(reg, XP_PROP_0, PORT_ID));
+ pci_write_config_dword(rdev, 0x60, pdata->xphy_base + (pdata->xpcs_window_def_reg));
+ pci_read_config_dword(rdev, 0x64, ®);
+ } else {
+ reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
+ }
+ pci_dev_put(rdev);
+
pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
pdata->xpcs_window <<= 6;
pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
@@ -481,6 +494,22 @@ static int __maybe_unused xgbe_pci_resume(struct device *dev)
return ret;
}
+static struct xgbe_version_data xgbe_v3 = {
+ .init_function_ptrs_phy_impl = xgbe_init_function_ptrs_phy_v2,
+ .xpcs_access = XGBE_XPCS_ACCESS_V3,
+ .mmc_64bit = 1,
+ .tx_max_fifo_size = 65536,
+ .rx_max_fifo_size = 65536,
+ .tx_tstamp_workaround = 1,
+ .ecc_support = 1,
+ .i2c_support = 1,
+ .irq_reissue_support = 1,
+ .tx_desc_prefetch = 5,
+ .rx_desc_prefetch = 5,
+ .an_cdr_workaround = 0,
+ .enable_rrc = 0,
+};
+
static struct xgbe_version_data xgbe_v2a = {
.init_function_ptrs_phy_impl = xgbe_init_function_ptrs_phy_v2,
.xpcs_access = XGBE_XPCS_ACCESS_V2,
@@ -518,6 +547,8 @@ static const struct pci_device_id xgbe_pci_table[] = {
.driver_data = (kernel_ulong_t)&xgbe_v2a },
{ PCI_VDEVICE(AMD, 0x1459),
.driver_data = (kernel_ulong_t)&xgbe_v2b },
+ { PCI_VDEVICE(AMD, 0x1641),
+ .driver_data = (kernel_ulong_t)&xgbe_v3 },
/* Last entry must be zero */
{ 0, }
};
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index ad136ed493ed..dbb1faaf6185 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -347,6 +347,10 @@
(_src)->link_modes._sname, \
__ETHTOOL_LINK_MODE_MASK_NBITS)
+/* Generic low and high masks */
+#define XGBE_GEN_HI_MASK GENMASK(31, 16)
+#define XGBE_GEN_LO_MASK GENMASK(15, 0)
+
struct xgbe_prv_data;
struct xgbe_packet_data {
@@ -565,6 +569,7 @@ enum xgbe_speed {
enum xgbe_xpcs_access {
XGBE_XPCS_ACCESS_V1 = 0,
XGBE_XPCS_ACCESS_V2,
+ XGBE_XPCS_ACCESS_V3,
};
enum xgbe_an_mode {
@@ -1056,6 +1061,7 @@ struct xgbe_prv_data {
struct device *dev;
struct platform_device *phy_platdev;
struct device *phy_dev;
+ unsigned int xphy_base;
/* Version related data */
struct xgbe_version_data *vdata;
--
2.34.1
next prev parent reply other threads:[~2023-12-12 5:38 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-12 5:37 [PATCH v3 net-next 0/3] amd-xgbe: add support for AMD Crater Raju Rangoju
2023-12-12 5:37 ` [PATCH v3 net-next 1/3] amd-xgbe: reorganize the code of XPCS access Raju Rangoju
2023-12-12 8:49 ` Kalesh Anakkur Purayil
2023-12-12 14:33 ` Tom Lendacky
2023-12-13 15:35 ` Raju Rangoju
2023-12-13 16:37 ` Tom Lendacky
2023-12-12 5:37 ` Raju Rangoju [this message]
2023-12-12 15:32 ` [PATCH v3 net-next 2/3] amd-xgbe: add support for Crater ethernet device Tom Lendacky
2023-12-13 16:25 ` Raju Rangoju
2023-12-13 16:42 ` Tom Lendacky
2023-12-12 5:37 ` [PATCH v3 net-next 3/3] amd-xgbe: use smn functions to avoid race Raju Rangoju
2023-12-12 15:38 ` Tom Lendacky
2023-12-15 4:35 ` Raju Rangoju
2023-12-15 14:35 ` Tom Lendacky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231212053723.443772-3-Raju.Rangoju@amd.com \
--to=raju.rangoju@amd.com \
--cc=Shyam-sundar.S-k@amd.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sudheesh.mavila@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).