All of lore.kernel.org
 help / color / mirror / Atom feed
From: sunil.kovvuri@gmail.com
To: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Sunil Goutham <sgoutham@cavium.com>
Subject: [PATCH 08/21] net: thunderx: Add 81xx support to BGX driver
Date: Wed, 10 Aug 2016 12:12:40 +0530	[thread overview]
Message-ID: <1470811373-28277-9-git-send-email-sunil.kovvuri@gmail.com> (raw)
In-Reply-To: <1470811373-28277-1-git-send-email-sunil.kovvuri@gmail.com>

From: Sunil Goutham <sgoutham@cavium.com>

This patch adds support for BGX module on 81xx where a BGX
can be split and have different LMACs configured in
different modes.

Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 112 ++++++++++++++++++++--
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  11 +++
 2 files changed, 113 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 4497427..9c3c273 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -50,6 +50,7 @@ struct bgx {
 	int			lmac_count;
 	void __iomem		*reg_base;
 	struct pci_dev		*pdev;
+	bool                    is_81xx;
 };
 
 static struct bgx *bgx_vnic[MAX_BGX_THUNDER];
@@ -803,9 +804,17 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
 	struct device *dev = &bgx->pdev->dev;
 	struct lmac *lmac;
 	char str[20];
+	u8 dlm;
+
+	if (lmacid > MAX_LMAC_PER_BGX)
+		return;
 
 	lmac = &bgx->lmac[lmacid];
-	sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
+	dlm = (lmacid / 2) + (bgx->bgx_id * 2);
+	if (!bgx->is_81xx)
+		sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
+	else
+		sprintf(str, "BGX%d DLM%d mode", bgx->bgx_id, dlm);
 
 	switch (lmac->lmac_type) {
 	case BGX_MODE_SGMII:
@@ -857,26 +866,81 @@ static void lmac_set_lane2sds(struct lmac *lmac)
 static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
 {
 	struct lmac *lmac;
+	struct lmac *olmac;
 	u64 cmr_cfg;
+	u8 lmac_type;
+	u8 lane_to_sds;
 
 	lmac = &bgx->lmac[idx];
-	lmac->lmacid = idx;
 
-	/* Read LMAC0 type to figure out QLM mode
-	 * This is configured by low level firmware
+	if (!bgx->is_81xx) {
+		/* Read LMAC0 type to figure out QLM mode
+		 * This is configured by low level firmware
+		 */
+		cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
+		lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
+		lmac->use_training =
+			bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
+				SPU_PMD_CRTL_TRAIN_EN;
+		lmac_set_lane2sds(lmac);
+		return;
+	}
+
+	/* On 81xx BGX can be split across 2 DLMs
+	 * firmware programs lmac_type of LMAC0 and LMAC2
 	 */
-	cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
-	lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
-	lmac->use_training =
-		bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
+	if ((idx == 0) || (idx == 2)) {
+		cmr_cfg = bgx_reg_read(bgx, idx, BGX_CMRX_CFG);
+		lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
+		lane_to_sds = (u8)(cmr_cfg & 0xFF);
+		/* Check if config is not reset value */
+		if ((lmac_type == 0) && (lane_to_sds == 0xE4))
+			lmac->lmac_type = BGX_MODE_INVALID;
+		else
+			lmac->lmac_type = lmac_type;
+		lmac->use_training =
+			bgx_reg_read(bgx, idx, BGX_SPUX_BR_PMD_CRTL) &
+				SPU_PMD_CRTL_TRAIN_EN;
+		lmac_set_lane2sds(lmac);
+
+		/* Set LMAC type of other lmac on same DLM i.e LMAC 1/3 */
+		olmac = &bgx->lmac[idx + 1];
+		olmac->lmac_type = lmac->lmac_type;
+		olmac->use_training =
+		bgx_reg_read(bgx, idx + 1, BGX_SPUX_BR_PMD_CRTL) &
 			SPU_PMD_CRTL_TRAIN_EN;
-	lmac_set_lane2sds(lmac);
+		lmac_set_lane2sds(olmac);
+	}
+}
+
+static bool is_dlm0_in_bgx_mode(struct bgx *bgx)
+{
+	struct lmac *lmac;
+
+	if (!bgx->is_81xx)
+		return true;
+
+	lmac = &bgx->lmac[1];
+	if (lmac->lmac_type == BGX_MODE_INVALID)
+		return false;
+
+	return true;
 }
 
 static void bgx_get_qlm_mode(struct bgx *bgx)
 {
+	struct lmac *lmac;
+	struct lmac *lmac01;
+	struct lmac *lmac23;
 	u8  idx;
 
+	/* Init all LMAC's type to invalid */
+	for (idx = 0; idx < MAX_LMAC_PER_BGX; idx++) {
+		lmac = &bgx->lmac[idx];
+		lmac->lmac_type = BGX_MODE_INVALID;
+		lmac->lmacid = idx;
+	}
+
 	/* It is assumed that low level firmware sets this value */
 	bgx->lmac_count = bgx_reg_read(bgx, 0, BGX_CMR_RX_LMACS) & 0x7;
 	if (bgx->lmac_count > MAX_LMAC_PER_BGX)
@@ -884,7 +948,28 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 
 	for (idx = 0; idx < bgx->lmac_count; idx++)
 		bgx_set_lmac_config(bgx, idx);
-	bgx_print_qlm_mode(bgx, 0);
+
+	if (!bgx->is_81xx) {
+		bgx_print_qlm_mode(bgx, 0);
+		return;
+	}
+
+	if (bgx->lmac_count) {
+		bgx_print_qlm_mode(bgx, 0);
+		bgx_print_qlm_mode(bgx, 2);
+	}
+
+	/* If DLM0 is not in BGX mode then LMAC0/1 have
+	 * to be configured with serdes lanes of DLM1
+	 */
+	if (is_dlm0_in_bgx_mode(bgx) || (bgx->lmac_count > 2))
+		return;
+	for (idx = 0; idx < bgx->lmac_count; idx++) {
+		lmac01 = &bgx->lmac[idx];
+		lmac23 = &bgx->lmac[idx + 2];
+		lmac01->lmac_type = lmac23->lmac_type;
+		lmac01->lane_to_sds = lmac23->lane_to_sds;
+	}
 }
 
 #ifdef CONFIG_ACPI
@@ -1059,6 +1144,7 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct device *dev = &pdev->dev;
 	struct bgx *bgx = NULL;
 	u8 lmac;
+	u16 sdevid;
 
 	bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
 	if (!bgx)
@@ -1080,6 +1166,10 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_disable_device;
 	}
 
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdevid);
+	if (sdevid == PCI_SUBSYS_DEVID_81XX_BGX)
+		bgx->is_81xx = true;
+
 	/* MAP configuration registers */
 	bgx->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
 	if (!bgx->reg_base) {
@@ -1105,6 +1195,8 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		if (err) {
 			dev_err(dev, "BGX%d failed to enable lmac%d\n",
 				bgx->bgx_id, lmac);
+			while (lmac)
+				bgx_lmac_disable(bgx, --lmac);
 			goto err_enable;
 		}
 	}
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index b7b91c8..38e9fb4 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -9,6 +9,14 @@
 #ifndef THUNDER_BGX_H
 #define THUNDER_BGX_H
 
+/* PCI device ID */
+#define	PCI_DEVICE_ID_THUNDER_BGX		0xA026
+
+/* Subsystem device IDs */
+#define PCI_SUBSYS_DEVID_88XX_BGX		0xA126
+#define PCI_SUBSYS_DEVID_81XX_BGX		0xA226
+#define PCI_SUBSYS_DEVID_83XX_BGX		0xA326
+
 #define    MAX_BGX_THUNDER			8 /* Max 4 nodes, 2 per node */
 #define    MAX_BGX_PER_CN88XX			2
 #define    MAX_BGX_PER_CN81XX			2
@@ -215,6 +223,9 @@ enum LMAC_TYPE {
 	BGX_MODE_XLAUI = 4, /* 4 lanes, 10.3125 Gbaud */
 	BGX_MODE_10G_KR = 3,/* 1 lane, 10.3125 Gbaud */
 	BGX_MODE_40G_KR = 4,/* 4 lanes, 10.3125 Gbaud */
+	BGX_MODE_RGMII = 5,
+	BGX_MODE_QSGMII = 6,
+	BGX_MODE_INVALID = 7,
 };
 
 #endif /* THUNDER_BGX_H */
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: sunil.kovvuri@gmail.com
To: netdev@vger.kernel.org
Cc: Sunil Goutham <sgoutham@cavium.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH 08/21] net: thunderx: Add 81xx support to BGX driver
Date: Wed, 10 Aug 2016 12:12:40 +0530	[thread overview]
Message-ID: <1470811373-28277-9-git-send-email-sunil.kovvuri@gmail.com> (raw)
In-Reply-To: <1470811373-28277-1-git-send-email-sunil.kovvuri@gmail.com>

From: Sunil Goutham <sgoutham@cavium.com>

This patch adds support for BGX module on 81xx where a BGX
can be split and have different LMACs configured in
different modes.

Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 112 ++++++++++++++++++++--
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  11 +++
 2 files changed, 113 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 4497427..9c3c273 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -50,6 +50,7 @@ struct bgx {
 	int			lmac_count;
 	void __iomem		*reg_base;
 	struct pci_dev		*pdev;
+	bool                    is_81xx;
 };
 
 static struct bgx *bgx_vnic[MAX_BGX_THUNDER];
@@ -803,9 +804,17 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
 	struct device *dev = &bgx->pdev->dev;
 	struct lmac *lmac;
 	char str[20];
+	u8 dlm;
+
+	if (lmacid > MAX_LMAC_PER_BGX)
+		return;
 
 	lmac = &bgx->lmac[lmacid];
-	sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
+	dlm = (lmacid / 2) + (bgx->bgx_id * 2);
+	if (!bgx->is_81xx)
+		sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
+	else
+		sprintf(str, "BGX%d DLM%d mode", bgx->bgx_id, dlm);
 
 	switch (lmac->lmac_type) {
 	case BGX_MODE_SGMII:
@@ -857,26 +866,81 @@ static void lmac_set_lane2sds(struct lmac *lmac)
 static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
 {
 	struct lmac *lmac;
+	struct lmac *olmac;
 	u64 cmr_cfg;
+	u8 lmac_type;
+	u8 lane_to_sds;
 
 	lmac = &bgx->lmac[idx];
-	lmac->lmacid = idx;
 
-	/* Read LMAC0 type to figure out QLM mode
-	 * This is configured by low level firmware
+	if (!bgx->is_81xx) {
+		/* Read LMAC0 type to figure out QLM mode
+		 * This is configured by low level firmware
+		 */
+		cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
+		lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
+		lmac->use_training =
+			bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
+				SPU_PMD_CRTL_TRAIN_EN;
+		lmac_set_lane2sds(lmac);
+		return;
+	}
+
+	/* On 81xx BGX can be split across 2 DLMs
+	 * firmware programs lmac_type of LMAC0 and LMAC2
 	 */
-	cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
-	lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
-	lmac->use_training =
-		bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
+	if ((idx == 0) || (idx == 2)) {
+		cmr_cfg = bgx_reg_read(bgx, idx, BGX_CMRX_CFG);
+		lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
+		lane_to_sds = (u8)(cmr_cfg & 0xFF);
+		/* Check if config is not reset value */
+		if ((lmac_type == 0) && (lane_to_sds == 0xE4))
+			lmac->lmac_type = BGX_MODE_INVALID;
+		else
+			lmac->lmac_type = lmac_type;
+		lmac->use_training =
+			bgx_reg_read(bgx, idx, BGX_SPUX_BR_PMD_CRTL) &
+				SPU_PMD_CRTL_TRAIN_EN;
+		lmac_set_lane2sds(lmac);
+
+		/* Set LMAC type of other lmac on same DLM i.e LMAC 1/3 */
+		olmac = &bgx->lmac[idx + 1];
+		olmac->lmac_type = lmac->lmac_type;
+		olmac->use_training =
+		bgx_reg_read(bgx, idx + 1, BGX_SPUX_BR_PMD_CRTL) &
 			SPU_PMD_CRTL_TRAIN_EN;
-	lmac_set_lane2sds(lmac);
+		lmac_set_lane2sds(olmac);
+	}
+}
+
+static bool is_dlm0_in_bgx_mode(struct bgx *bgx)
+{
+	struct lmac *lmac;
+
+	if (!bgx->is_81xx)
+		return true;
+
+	lmac = &bgx->lmac[1];
+	if (lmac->lmac_type == BGX_MODE_INVALID)
+		return false;
+
+	return true;
 }
 
 static void bgx_get_qlm_mode(struct bgx *bgx)
 {
+	struct lmac *lmac;
+	struct lmac *lmac01;
+	struct lmac *lmac23;
 	u8  idx;
 
+	/* Init all LMAC's type to invalid */
+	for (idx = 0; idx < MAX_LMAC_PER_BGX; idx++) {
+		lmac = &bgx->lmac[idx];
+		lmac->lmac_type = BGX_MODE_INVALID;
+		lmac->lmacid = idx;
+	}
+
 	/* It is assumed that low level firmware sets this value */
 	bgx->lmac_count = bgx_reg_read(bgx, 0, BGX_CMR_RX_LMACS) & 0x7;
 	if (bgx->lmac_count > MAX_LMAC_PER_BGX)
@@ -884,7 +948,28 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 
 	for (idx = 0; idx < bgx->lmac_count; idx++)
 		bgx_set_lmac_config(bgx, idx);
-	bgx_print_qlm_mode(bgx, 0);
+
+	if (!bgx->is_81xx) {
+		bgx_print_qlm_mode(bgx, 0);
+		return;
+	}
+
+	if (bgx->lmac_count) {
+		bgx_print_qlm_mode(bgx, 0);
+		bgx_print_qlm_mode(bgx, 2);
+	}
+
+	/* If DLM0 is not in BGX mode then LMAC0/1 have
+	 * to be configured with serdes lanes of DLM1
+	 */
+	if (is_dlm0_in_bgx_mode(bgx) || (bgx->lmac_count > 2))
+		return;
+	for (idx = 0; idx < bgx->lmac_count; idx++) {
+		lmac01 = &bgx->lmac[idx];
+		lmac23 = &bgx->lmac[idx + 2];
+		lmac01->lmac_type = lmac23->lmac_type;
+		lmac01->lane_to_sds = lmac23->lane_to_sds;
+	}
 }
 
 #ifdef CONFIG_ACPI
@@ -1059,6 +1144,7 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct device *dev = &pdev->dev;
 	struct bgx *bgx = NULL;
 	u8 lmac;
+	u16 sdevid;
 
 	bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
 	if (!bgx)
@@ -1080,6 +1166,10 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_disable_device;
 	}
 
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdevid);
+	if (sdevid == PCI_SUBSYS_DEVID_81XX_BGX)
+		bgx->is_81xx = true;
+
 	/* MAP configuration registers */
 	bgx->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
 	if (!bgx->reg_base) {
@@ -1105,6 +1195,8 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		if (err) {
 			dev_err(dev, "BGX%d failed to enable lmac%d\n",
 				bgx->bgx_id, lmac);
+			while (lmac)
+				bgx_lmac_disable(bgx, --lmac);
 			goto err_enable;
 		}
 	}
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index b7b91c8..38e9fb4 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -9,6 +9,14 @@
 #ifndef THUNDER_BGX_H
 #define THUNDER_BGX_H
 
+/* PCI device ID */
+#define	PCI_DEVICE_ID_THUNDER_BGX		0xA026
+
+/* Subsystem device IDs */
+#define PCI_SUBSYS_DEVID_88XX_BGX		0xA126
+#define PCI_SUBSYS_DEVID_81XX_BGX		0xA226
+#define PCI_SUBSYS_DEVID_83XX_BGX		0xA326
+
 #define    MAX_BGX_THUNDER			8 /* Max 4 nodes, 2 per node */
 #define    MAX_BGX_PER_CN88XX			2
 #define    MAX_BGX_PER_CN81XX			2
@@ -215,6 +223,9 @@ enum LMAC_TYPE {
 	BGX_MODE_XLAUI = 4, /* 4 lanes, 10.3125 Gbaud */
 	BGX_MODE_10G_KR = 3,/* 1 lane, 10.3125 Gbaud */
 	BGX_MODE_40G_KR = 4,/* 4 lanes, 10.3125 Gbaud */
+	BGX_MODE_RGMII = 5,
+	BGX_MODE_QSGMII = 6,
+	BGX_MODE_INVALID = 7,
 };
 
 #endif /* THUNDER_BGX_H */
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: sunil.kovvuri@gmail.com (sunil.kovvuri at gmail.com)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 08/21] net: thunderx: Add 81xx support to BGX driver
Date: Wed, 10 Aug 2016 12:12:40 +0530	[thread overview]
Message-ID: <1470811373-28277-9-git-send-email-sunil.kovvuri@gmail.com> (raw)
In-Reply-To: <1470811373-28277-1-git-send-email-sunil.kovvuri@gmail.com>

From: Sunil Goutham <sgoutham@cavium.com>

This patch adds support for BGX module on 81xx where a BGX
can be split and have different LMACs configured in
different modes.

Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 112 ++++++++++++++++++++--
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  11 +++
 2 files changed, 113 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 4497427..9c3c273 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -50,6 +50,7 @@ struct bgx {
 	int			lmac_count;
 	void __iomem		*reg_base;
 	struct pci_dev		*pdev;
+	bool                    is_81xx;
 };
 
 static struct bgx *bgx_vnic[MAX_BGX_THUNDER];
@@ -803,9 +804,17 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
 	struct device *dev = &bgx->pdev->dev;
 	struct lmac *lmac;
 	char str[20];
+	u8 dlm;
+
+	if (lmacid > MAX_LMAC_PER_BGX)
+		return;
 
 	lmac = &bgx->lmac[lmacid];
-	sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
+	dlm = (lmacid / 2) + (bgx->bgx_id * 2);
+	if (!bgx->is_81xx)
+		sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
+	else
+		sprintf(str, "BGX%d DLM%d mode", bgx->bgx_id, dlm);
 
 	switch (lmac->lmac_type) {
 	case BGX_MODE_SGMII:
@@ -857,26 +866,81 @@ static void lmac_set_lane2sds(struct lmac *lmac)
 static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
 {
 	struct lmac *lmac;
+	struct lmac *olmac;
 	u64 cmr_cfg;
+	u8 lmac_type;
+	u8 lane_to_sds;
 
 	lmac = &bgx->lmac[idx];
-	lmac->lmacid = idx;
 
-	/* Read LMAC0 type to figure out QLM mode
-	 * This is configured by low level firmware
+	if (!bgx->is_81xx) {
+		/* Read LMAC0 type to figure out QLM mode
+		 * This is configured by low level firmware
+		 */
+		cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
+		lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
+		lmac->use_training =
+			bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
+				SPU_PMD_CRTL_TRAIN_EN;
+		lmac_set_lane2sds(lmac);
+		return;
+	}
+
+	/* On 81xx BGX can be split across 2 DLMs
+	 * firmware programs lmac_type of LMAC0 and LMAC2
 	 */
-	cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
-	lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
-	lmac->use_training =
-		bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
+	if ((idx == 0) || (idx == 2)) {
+		cmr_cfg = bgx_reg_read(bgx, idx, BGX_CMRX_CFG);
+		lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
+		lane_to_sds = (u8)(cmr_cfg & 0xFF);
+		/* Check if config is not reset value */
+		if ((lmac_type == 0) && (lane_to_sds == 0xE4))
+			lmac->lmac_type = BGX_MODE_INVALID;
+		else
+			lmac->lmac_type = lmac_type;
+		lmac->use_training =
+			bgx_reg_read(bgx, idx, BGX_SPUX_BR_PMD_CRTL) &
+				SPU_PMD_CRTL_TRAIN_EN;
+		lmac_set_lane2sds(lmac);
+
+		/* Set LMAC type of other lmac on same DLM i.e LMAC 1/3 */
+		olmac = &bgx->lmac[idx + 1];
+		olmac->lmac_type = lmac->lmac_type;
+		olmac->use_training =
+		bgx_reg_read(bgx, idx + 1, BGX_SPUX_BR_PMD_CRTL) &
 			SPU_PMD_CRTL_TRAIN_EN;
-	lmac_set_lane2sds(lmac);
+		lmac_set_lane2sds(olmac);
+	}
+}
+
+static bool is_dlm0_in_bgx_mode(struct bgx *bgx)
+{
+	struct lmac *lmac;
+
+	if (!bgx->is_81xx)
+		return true;
+
+	lmac = &bgx->lmac[1];
+	if (lmac->lmac_type == BGX_MODE_INVALID)
+		return false;
+
+	return true;
 }
 
 static void bgx_get_qlm_mode(struct bgx *bgx)
 {
+	struct lmac *lmac;
+	struct lmac *lmac01;
+	struct lmac *lmac23;
 	u8  idx;
 
+	/* Init all LMAC's type to invalid */
+	for (idx = 0; idx < MAX_LMAC_PER_BGX; idx++) {
+		lmac = &bgx->lmac[idx];
+		lmac->lmac_type = BGX_MODE_INVALID;
+		lmac->lmacid = idx;
+	}
+
 	/* It is assumed that low level firmware sets this value */
 	bgx->lmac_count = bgx_reg_read(bgx, 0, BGX_CMR_RX_LMACS) & 0x7;
 	if (bgx->lmac_count > MAX_LMAC_PER_BGX)
@@ -884,7 +948,28 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 
 	for (idx = 0; idx < bgx->lmac_count; idx++)
 		bgx_set_lmac_config(bgx, idx);
-	bgx_print_qlm_mode(bgx, 0);
+
+	if (!bgx->is_81xx) {
+		bgx_print_qlm_mode(bgx, 0);
+		return;
+	}
+
+	if (bgx->lmac_count) {
+		bgx_print_qlm_mode(bgx, 0);
+		bgx_print_qlm_mode(bgx, 2);
+	}
+
+	/* If DLM0 is not in BGX mode then LMAC0/1 have
+	 * to be configured with serdes lanes of DLM1
+	 */
+	if (is_dlm0_in_bgx_mode(bgx) || (bgx->lmac_count > 2))
+		return;
+	for (idx = 0; idx < bgx->lmac_count; idx++) {
+		lmac01 = &bgx->lmac[idx];
+		lmac23 = &bgx->lmac[idx + 2];
+		lmac01->lmac_type = lmac23->lmac_type;
+		lmac01->lane_to_sds = lmac23->lane_to_sds;
+	}
 }
 
 #ifdef CONFIG_ACPI
@@ -1059,6 +1144,7 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct device *dev = &pdev->dev;
 	struct bgx *bgx = NULL;
 	u8 lmac;
+	u16 sdevid;
 
 	bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
 	if (!bgx)
@@ -1080,6 +1166,10 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_disable_device;
 	}
 
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdevid);
+	if (sdevid == PCI_SUBSYS_DEVID_81XX_BGX)
+		bgx->is_81xx = true;
+
 	/* MAP configuration registers */
 	bgx->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
 	if (!bgx->reg_base) {
@@ -1105,6 +1195,8 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		if (err) {
 			dev_err(dev, "BGX%d failed to enable lmac%d\n",
 				bgx->bgx_id, lmac);
+			while (lmac)
+				bgx_lmac_disable(bgx, --lmac);
 			goto err_enable;
 		}
 	}
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index b7b91c8..38e9fb4 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -9,6 +9,14 @@
 #ifndef THUNDER_BGX_H
 #define THUNDER_BGX_H
 
+/* PCI device ID */
+#define	PCI_DEVICE_ID_THUNDER_BGX		0xA026
+
+/* Subsystem device IDs */
+#define PCI_SUBSYS_DEVID_88XX_BGX		0xA126
+#define PCI_SUBSYS_DEVID_81XX_BGX		0xA226
+#define PCI_SUBSYS_DEVID_83XX_BGX		0xA326
+
 #define    MAX_BGX_THUNDER			8 /* Max 4 nodes, 2 per node */
 #define    MAX_BGX_PER_CN88XX			2
 #define    MAX_BGX_PER_CN81XX			2
@@ -215,6 +223,9 @@ enum LMAC_TYPE {
 	BGX_MODE_XLAUI = 4, /* 4 lanes, 10.3125 Gbaud */
 	BGX_MODE_10G_KR = 3,/* 1 lane, 10.3125 Gbaud */
 	BGX_MODE_40G_KR = 4,/* 4 lanes, 10.3125 Gbaud */
+	BGX_MODE_RGMII = 5,
+	BGX_MODE_QSGMII = 6,
+	BGX_MODE_INVALID = 7,
 };
 
 #endif /* THUNDER_BGX_H */
-- 
2.7.4

  parent reply	other threads:[~2016-08-10 18:16 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-10  6:42 [PATCH 00/21] net: thunderx: Support for newer chips and miscellaneous patches sunil.kovvuri
2016-08-10  6:42 ` sunil.kovvuri at gmail.com
2016-08-10  6:42 ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 01/21] net: thunderx: Moved HW capability info from macros to structure sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 02/21] net: thunderx: Add VNIC's PCI devid on future chips sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 03/21] net: thunderx: Add support for 81xx and 83xx chips sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 04/21] net: thunderx: Set queue count based on number of CPUs sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-11  9:36   ` Yuval Mintz
2016-08-11  9:36     ` Yuval Mintz
2016-08-11  9:36     ` Yuval Mintz
2016-08-11  9:57     ` Sunil Kovvuri
2016-08-11  9:57       ` Sunil Kovvuri
2016-08-11  9:57       ` Sunil Kovvuri
2016-08-10  6:42 ` [PATCH 05/21] net: thunderx: Enable CQE_RX desc's extension fields sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 06/21] net: thunderx: Enable mailbox interrupts on 81xx/83xx sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 07/21] net: thunderx: Support for different LMAC types within BGX sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` sunil.kovvuri [this message]
2016-08-10  6:42   ` [PATCH 08/21] net: thunderx: Add 81xx support to BGX driver sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 09/21] net: thunderx: Add QSGMII interface type support sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 10/21] net: thunderx: Add RGMII " sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 11/21] net: thunderx: Add support for 16 LMACs of 83xx sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-11  2:45   ` kbuild test robot
2016-08-11  2:45     ` kbuild test robot
2016-08-11  2:45     ` kbuild test robot
2016-08-10  6:42 ` [PATCH 12/21] net: thunderx: Support for 83xx mixed QLM/DLM config sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 13/21] net: thunderx: Use netdev's name for naming VF's interrupts sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 14/21] net: thunderx: Use skb_add_rx_frag() for split buffer Rx pkts sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 15/21] net: thunderx: Improvement for MBX interface debug messages sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 16/21] net: thunderx: Reset RXQ HW stats when interface is brought down sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 17/21] net: thunderx: Don't set mac address for secondary Qset VFs sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 18/21] net: thunderx: Use napi_consume_skb for bulk free sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 19/21] net: thunderx: Configure tunnelling protocol parsing sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 20/21] net: thunderx: Use netdev_rss_key_fill() helper sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri
2016-08-10  6:42 ` [PATCH 21/21] net: thunderx: Don't set RX_PACKET_DIS while initializing sunil.kovvuri
2016-08-10  6:42   ` sunil.kovvuri at gmail.com
2016-08-10  6:42   ` sunil.kovvuri

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=1470811373-28277-9-git-send-email-sunil.kovvuri@gmail.com \
    --to=sunil.kovvuri@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=sgoutham@cavium.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.