Skip to content

Commit 57aaf63

Browse files
Sunil Gouthamdavem330
authored andcommitted
net: thunderx: Add 81xx support to BGX driver
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> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0bcb7d5 commit 57aaf63

File tree

2 files changed

+113
-10
lines changed

2 files changed

+113
-10
lines changed

drivers/net/ethernet/cavium/thunder/thunder_bgx.c

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct bgx {
5050
int lmac_count;
5151
void __iomem *reg_base;
5252
struct pci_dev *pdev;
53+
bool is_81xx;
5354
};
5455

5556
static struct bgx *bgx_vnic[MAX_BGX_THUNDER];
@@ -803,9 +804,17 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
803804
struct device *dev = &bgx->pdev->dev;
804805
struct lmac *lmac;
805806
char str[20];
807+
u8 dlm;
808+
809+
if (lmacid > MAX_LMAC_PER_BGX)
810+
return;
806811

807812
lmac = &bgx->lmac[lmacid];
808-
sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
813+
dlm = (lmacid / 2) + (bgx->bgx_id * 2);
814+
if (!bgx->is_81xx)
815+
sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
816+
else
817+
sprintf(str, "BGX%d DLM%d mode", bgx->bgx_id, dlm);
809818

810819
switch (lmac->lmac_type) {
811820
case BGX_MODE_SGMII:
@@ -857,34 +866,110 @@ static void lmac_set_lane2sds(struct lmac *lmac)
857866
static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
858867
{
859868
struct lmac *lmac;
869+
struct lmac *olmac;
860870
u64 cmr_cfg;
871+
u8 lmac_type;
872+
u8 lane_to_sds;
861873

862874
lmac = &bgx->lmac[idx];
863-
lmac->lmacid = idx;
864875

865-
/* Read LMAC0 type to figure out QLM mode
866-
* This is configured by low level firmware
876+
if (!bgx->is_81xx) {
877+
/* Read LMAC0 type to figure out QLM mode
878+
* This is configured by low level firmware
879+
*/
880+
cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
881+
lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
882+
lmac->use_training =
883+
bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
884+
SPU_PMD_CRTL_TRAIN_EN;
885+
lmac_set_lane2sds(lmac);
886+
return;
887+
}
888+
889+
/* On 81xx BGX can be split across 2 DLMs
890+
* firmware programs lmac_type of LMAC0 and LMAC2
867891
*/
868-
cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
869-
lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
870-
lmac->use_training =
871-
bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
892+
if ((idx == 0) || (idx == 2)) {
893+
cmr_cfg = bgx_reg_read(bgx, idx, BGX_CMRX_CFG);
894+
lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
895+
lane_to_sds = (u8)(cmr_cfg & 0xFF);
896+
/* Check if config is not reset value */
897+
if ((lmac_type == 0) && (lane_to_sds == 0xE4))
898+
lmac->lmac_type = BGX_MODE_INVALID;
899+
else
900+
lmac->lmac_type = lmac_type;
901+
lmac->use_training =
902+
bgx_reg_read(bgx, idx, BGX_SPUX_BR_PMD_CRTL) &
903+
SPU_PMD_CRTL_TRAIN_EN;
904+
lmac_set_lane2sds(lmac);
905+
906+
/* Set LMAC type of other lmac on same DLM i.e LMAC 1/3 */
907+
olmac = &bgx->lmac[idx + 1];
908+
olmac->lmac_type = lmac->lmac_type;
909+
olmac->use_training =
910+
bgx_reg_read(bgx, idx + 1, BGX_SPUX_BR_PMD_CRTL) &
872911
SPU_PMD_CRTL_TRAIN_EN;
873-
lmac_set_lane2sds(lmac);
912+
lmac_set_lane2sds(olmac);
913+
}
914+
}
915+
916+
static bool is_dlm0_in_bgx_mode(struct bgx *bgx)
917+
{
918+
struct lmac *lmac;
919+
920+
if (!bgx->is_81xx)
921+
return true;
922+
923+
lmac = &bgx->lmac[1];
924+
if (lmac->lmac_type == BGX_MODE_INVALID)
925+
return false;
926+
927+
return true;
874928
}
875929

876930
static void bgx_get_qlm_mode(struct bgx *bgx)
877931
{
932+
struct lmac *lmac;
933+
struct lmac *lmac01;
934+
struct lmac *lmac23;
878935
u8 idx;
879936

937+
/* Init all LMAC's type to invalid */
938+
for (idx = 0; idx < MAX_LMAC_PER_BGX; idx++) {
939+
lmac = &bgx->lmac[idx];
940+
lmac->lmac_type = BGX_MODE_INVALID;
941+
lmac->lmacid = idx;
942+
}
943+
880944
/* It is assumed that low level firmware sets this value */
881945
bgx->lmac_count = bgx_reg_read(bgx, 0, BGX_CMR_RX_LMACS) & 0x7;
882946
if (bgx->lmac_count > MAX_LMAC_PER_BGX)
883947
bgx->lmac_count = MAX_LMAC_PER_BGX;
884948

885949
for (idx = 0; idx < bgx->lmac_count; idx++)
886950
bgx_set_lmac_config(bgx, idx);
887-
bgx_print_qlm_mode(bgx, 0);
951+
952+
if (!bgx->is_81xx) {
953+
bgx_print_qlm_mode(bgx, 0);
954+
return;
955+
}
956+
957+
if (bgx->lmac_count) {
958+
bgx_print_qlm_mode(bgx, 0);
959+
bgx_print_qlm_mode(bgx, 2);
960+
}
961+
962+
/* If DLM0 is not in BGX mode then LMAC0/1 have
963+
* to be configured with serdes lanes of DLM1
964+
*/
965+
if (is_dlm0_in_bgx_mode(bgx) || (bgx->lmac_count > 2))
966+
return;
967+
for (idx = 0; idx < bgx->lmac_count; idx++) {
968+
lmac01 = &bgx->lmac[idx];
969+
lmac23 = &bgx->lmac[idx + 2];
970+
lmac01->lmac_type = lmac23->lmac_type;
971+
lmac01->lane_to_sds = lmac23->lane_to_sds;
972+
}
888973
}
889974

890975
#ifdef CONFIG_ACPI
@@ -1059,6 +1144,7 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
10591144
struct device *dev = &pdev->dev;
10601145
struct bgx *bgx = NULL;
10611146
u8 lmac;
1147+
u16 sdevid;
10621148

10631149
bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
10641150
if (!bgx)
@@ -1080,6 +1166,10 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
10801166
goto err_disable_device;
10811167
}
10821168

1169+
pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdevid);
1170+
if (sdevid == PCI_SUBSYS_DEVID_81XX_BGX)
1171+
bgx->is_81xx = true;
1172+
10831173
/* MAP configuration registers */
10841174
bgx->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
10851175
if (!bgx->reg_base) {
@@ -1105,6 +1195,8 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11051195
if (err) {
11061196
dev_err(dev, "BGX%d failed to enable lmac%d\n",
11071197
bgx->bgx_id, lmac);
1198+
while (lmac)
1199+
bgx_lmac_disable(bgx, --lmac);
11081200
goto err_enable;
11091201
}
11101202
}

drivers/net/ethernet/cavium/thunder/thunder_bgx.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
#ifndef THUNDER_BGX_H
1010
#define THUNDER_BGX_H
1111

12+
/* PCI device ID */
13+
#define PCI_DEVICE_ID_THUNDER_BGX 0xA026
14+
15+
/* Subsystem device IDs */
16+
#define PCI_SUBSYS_DEVID_88XX_BGX 0xA126
17+
#define PCI_SUBSYS_DEVID_81XX_BGX 0xA226
18+
#define PCI_SUBSYS_DEVID_83XX_BGX 0xA326
19+
1220
#define MAX_BGX_THUNDER 8 /* Max 4 nodes, 2 per node */
1321
#define MAX_BGX_PER_CN88XX 2
1422
#define MAX_BGX_PER_CN81XX 2
@@ -215,6 +223,9 @@ enum LMAC_TYPE {
215223
BGX_MODE_XLAUI = 4, /* 4 lanes, 10.3125 Gbaud */
216224
BGX_MODE_10G_KR = 3,/* 1 lane, 10.3125 Gbaud */
217225
BGX_MODE_40G_KR = 4,/* 4 lanes, 10.3125 Gbaud */
226+
BGX_MODE_RGMII = 5,
227+
BGX_MODE_QSGMII = 6,
228+
BGX_MODE_INVALID = 7,
218229
};
219230

220231
#endif /* THUNDER_BGX_H */

0 commit comments

Comments
 (0)