Skip to content

Commit 6465859

Browse files
Sunil Gouthamdavem330
authored andcommitted
net: thunderx: Add RGMII interface type support
This patch adds RGX/RGMII interface type support to BGX driver. This type of interface is supported by 81xx SOC. CN81XX VNIC has 8 VFs and max possible LMAC interfaces are 9, hence RGMII interface will not work if all DLMs are in BGX mode and all 8 LMACs are enabled Signed-off-by: Sunil Goutham <sgoutham@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3f8057c commit 6465859

File tree

6 files changed

+332
-33
lines changed

6 files changed

+332
-33
lines changed

drivers/net/ethernet/cavium/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,20 @@ config THUNDER_NIC_BGX
3636
depends on 64BIT
3737
select PHYLIB
3838
select MDIO_THUNDER
39+
select THUNDER_NIC_RGX
3940
---help---
4041
This driver supports programming and controlling of MAC
4142
interface from NIC physical function driver.
4243

44+
config THUNDER_NIC_RGX
45+
tristate "Thunder MAC interface driver (RGX)"
46+
depends on 64BIT
47+
select PHYLIB
48+
select MDIO_THUNDER
49+
---help---
50+
This driver supports configuring XCV block of RGX interface
51+
present on CN81XX chip.
52+
4353
config LIQUIDIO
4454
tristate "Cavium LiquidIO support"
4555
depends on 64BIT

drivers/net/ethernet/cavium/thunder/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Makefile for Cavium's Thunder ethernet device
33
#
44

5+
obj-$(CONFIG_THUNDER_NIC_RGX) += thunder_xcv.o
56
obj-$(CONFIG_THUNDER_NIC_BGX) += thunder_bgx.o
67
obj-$(CONFIG_THUNDER_NIC_PF) += nicpf.o
78
obj-$(CONFIG_THUNDER_NIC_VF) += nicvf.o

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,14 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
325325
nic_reg_write(nic,
326326
NIC_PF_LMAC_0_7_CREDIT + (lmac * 8),
327327
lmac_credit);
328+
329+
/* On CN81XX there are only 8 VFs but max possible no of
330+
* interfaces are 9.
331+
*/
332+
if (nic->num_vf_en >= pci_sriov_get_totalvfs(nic->pdev)) {
333+
nic->num_vf_en = pci_sriov_get_totalvfs(nic->pdev);
334+
break;
335+
}
328336
}
329337
}
330338

@@ -450,10 +458,8 @@ static void nic_config_cpi(struct nicpf *nic, struct cpi_cfg_msg *cfg)
450458
lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
451459

452460
chan = (lmac * hw->chans_per_lmac) + (bgx * hw->chans_per_bgx);
453-
cpi_base = (lmac * NIC_MAX_CPI_PER_LMAC) +
454-
(bgx * (hw->cpi_cnt / hw->bgx_cnt));
455-
rssi_base = (lmac * hw->rss_ind_tbl_size) +
456-
(bgx * (hw->rssi_cnt / hw->bgx_cnt));
461+
cpi_base = vnic * NIC_MAX_CPI_PER_LMAC;
462+
rssi_base = vnic * hw->rss_ind_tbl_size;
457463

458464
/* Rx channel configuration */
459465
nic_reg_write(nic, NIC_PF_CHAN_0_255_RX_BP_CFG | (chan << 3),

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

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ struct bgx {
4848
u8 bgx_id;
4949
struct lmac lmac[MAX_LMAC_PER_BGX];
5050
int lmac_count;
51+
u8 max_lmac;
5152
void __iomem *reg_base;
5253
struct pci_dev *pdev;
5354
bool is_81xx;
55+
bool is_rgx;
5456
};
5557

5658
static struct bgx *bgx_vnic[MAX_BGX_THUNDER];
@@ -61,6 +63,7 @@ static int bgx_xaui_check_link(struct lmac *lmac);
6163
/* Supported devices */
6264
static const struct pci_device_id bgx_id_table[] = {
6365
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDER_BGX) },
66+
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDER_RGX) },
6467
{ 0, } /* end of table */
6568
};
6669

@@ -124,7 +127,7 @@ unsigned bgx_get_map(int node)
124127
int i;
125128
unsigned map = 0;
126129

127-
for (i = 0; i < MAX_BGX_PER_CN88XX; i++) {
130+
for (i = 0; i < MAX_BGX_PER_CN81XX; i++) {
128131
if (bgx_vnic[(node * MAX_BGX_PER_CN88XX) + i])
129132
map |= (1 << i);
130133
}
@@ -189,17 +192,22 @@ EXPORT_SYMBOL(bgx_set_lmac_mac);
189192
void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable)
190193
{
191194
struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx];
195+
struct lmac *lmac;
192196
u64 cfg;
193197

194198
if (!bgx)
195199
return;
200+
lmac = &bgx->lmac[lmacid];
196201

197202
cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
198203
if (enable)
199204
cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN;
200205
else
201206
cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN);
202207
bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
208+
209+
if (bgx->is_rgx)
210+
xcv_setup_link(enable ? lmac->link_up : 0, lmac->last_speed);
203211
}
204212
EXPORT_SYMBOL(bgx_lmac_rx_tx_enable);
205213

@@ -266,9 +274,12 @@ static void bgx_sgmii_change_link_state(struct lmac *lmac)
266274

267275
port_cfg = bgx_reg_read(bgx, lmac->lmacid, BGX_GMP_GMI_PRTX_CFG);
268276

269-
/* renable lmac */
277+
/* Re-enable lmac */
270278
cmr_cfg |= CMR_EN;
271279
bgx_reg_write(bgx, lmac->lmacid, BGX_CMRX_CFG, cmr_cfg);
280+
281+
if (bgx->is_rgx && (cmr_cfg & (CMR_PKT_RX_EN | CMR_PKT_TX_EN)))
282+
xcv_setup_link(lmac->link_up, lmac->last_speed);
272283
}
273284

274285
static void bgx_lmac_handler(struct net_device *netdev)
@@ -418,10 +429,12 @@ static int bgx_lmac_sgmii_init(struct bgx *bgx, struct lmac *lmac)
418429
return 0;
419430
}
420431

421-
if (bgx_poll_reg(bgx, lmacid, BGX_GMP_PCS_MRX_STATUS,
422-
PCS_MRX_STATUS_AN_CPT, false)) {
423-
dev_err(&bgx->pdev->dev, "BGX AN_CPT not completed\n");
424-
return -1;
432+
if (lmac->lmac_type == BGX_MODE_SGMII) {
433+
if (bgx_poll_reg(bgx, lmacid, BGX_GMP_PCS_MRX_STATUS,
434+
PCS_MRX_STATUS_AN_CPT, false)) {
435+
dev_err(&bgx->pdev->dev, "BGX AN_CPT not completed\n");
436+
return -1;
437+
}
425438
}
426439

427440
return 0;
@@ -663,6 +676,8 @@ static int phy_interface_mode(u8 lmac_type)
663676
{
664677
if (lmac_type == BGX_MODE_QSGMII)
665678
return PHY_INTERFACE_MODE_QSGMII;
679+
if (lmac_type == BGX_MODE_RGMII)
680+
return PHY_INTERFACE_MODE_RGMII;
666681

667682
return PHY_INTERFACE_MODE_SGMII;
668683
}
@@ -676,7 +691,8 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
676691
lmac->bgx = bgx;
677692

678693
if ((lmac->lmac_type == BGX_MODE_SGMII) ||
679-
(lmac->lmac_type == BGX_MODE_QSGMII)) {
694+
(lmac->lmac_type == BGX_MODE_QSGMII) ||
695+
(lmac->lmac_type == BGX_MODE_RGMII)) {
680696
lmac->is_sgmii = 1;
681697
if (bgx_lmac_sgmii_init(bgx, lmac))
682698
return -1;
@@ -829,7 +845,7 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
829845
char str[20];
830846
u8 dlm;
831847

832-
if (lmacid > MAX_LMAC_PER_BGX)
848+
if (lmacid > bgx->max_lmac)
833849
return;
834850

835851
lmac = &bgx->lmac[lmacid];
@@ -870,6 +886,9 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
870886
return;
871887
dev_info(dev, "%s: QSGMII\n", (char *)str);
872888
break;
889+
case BGX_MODE_RGMII:
890+
dev_info(dev, "%s: RGMII\n", (char *)str);
891+
break;
873892
case BGX_MODE_INVALID:
874893
/* Nothing to do */
875894
break;
@@ -885,6 +904,7 @@ static void lmac_set_lane2sds(struct bgx *bgx, struct lmac *lmac)
885904
break;
886905
case BGX_MODE_XAUI:
887906
case BGX_MODE_XLAUI:
907+
case BGX_MODE_RGMII:
888908
lmac->lane_to_sds = 0xE4;
889909
break;
890910
case BGX_MODE_RXAUI:
@@ -904,6 +924,18 @@ static void lmac_set_lane2sds(struct bgx *bgx, struct lmac *lmac)
904924
}
905925
}
906926

927+
static void lmac_set_training(struct bgx *bgx, struct lmac *lmac, int lmacid)
928+
{
929+
if ((lmac->lmac_type != BGX_MODE_10G_KR) &&
930+
(lmac->lmac_type != BGX_MODE_40G_KR)) {
931+
lmac->use_training = 0;
932+
return;
933+
}
934+
935+
lmac->use_training = bgx_reg_read(bgx, lmacid, BGX_SPUX_BR_PMD_CRTL) &
936+
SPU_PMD_CRTL_TRAIN_EN;
937+
}
938+
907939
static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
908940
{
909941
struct lmac *lmac;
@@ -914,15 +946,15 @@ static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
914946

915947
lmac = &bgx->lmac[idx];
916948

917-
if (!bgx->is_81xx) {
949+
if (!bgx->is_81xx || bgx->is_rgx) {
918950
/* Read LMAC0 type to figure out QLM mode
919951
* This is configured by low level firmware
920952
*/
921953
cmr_cfg = bgx_reg_read(bgx, 0, BGX_CMRX_CFG);
922954
lmac->lmac_type = (cmr_cfg >> 8) & 0x07;
923-
lmac->use_training =
924-
bgx_reg_read(bgx, 0, BGX_SPUX_BR_PMD_CRTL) &
925-
SPU_PMD_CRTL_TRAIN_EN;
955+
if (bgx->is_rgx)
956+
lmac->lmac_type = BGX_MODE_RGMII;
957+
lmac_set_training(bgx, lmac, 0);
926958
lmac_set_lane2sds(bgx, lmac);
927959
return;
928960
}
@@ -939,17 +971,13 @@ static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
939971
lmac->lmac_type = BGX_MODE_INVALID;
940972
else
941973
lmac->lmac_type = lmac_type;
942-
lmac->use_training =
943-
bgx_reg_read(bgx, idx, BGX_SPUX_BR_PMD_CRTL) &
944-
SPU_PMD_CRTL_TRAIN_EN;
974+
lmac_set_training(bgx, lmac, lmac->lmacid);
945975
lmac_set_lane2sds(bgx, lmac);
946976

947977
/* Set LMAC type of other lmac on same DLM i.e LMAC 1/3 */
948978
olmac = &bgx->lmac[idx + 1];
949979
olmac->lmac_type = lmac->lmac_type;
950-
olmac->use_training =
951-
bgx_reg_read(bgx, idx + 1, BGX_SPUX_BR_PMD_CRTL) &
952-
SPU_PMD_CRTL_TRAIN_EN;
980+
lmac_set_training(bgx, olmac, olmac->lmacid);
953981
lmac_set_lane2sds(bgx, olmac);
954982
}
955983
}
@@ -976,21 +1004,22 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
9761004
u8 idx;
9771005

9781006
/* Init all LMAC's type to invalid */
979-
for (idx = 0; idx < MAX_LMAC_PER_BGX; idx++) {
1007+
for (idx = 0; idx < bgx->max_lmac; idx++) {
9801008
lmac = &bgx->lmac[idx];
981-
lmac->lmac_type = BGX_MODE_INVALID;
9821009
lmac->lmacid = idx;
1010+
lmac->lmac_type = BGX_MODE_INVALID;
1011+
lmac->use_training = false;
9831012
}
9841013

9851014
/* It is assumed that low level firmware sets this value */
9861015
bgx->lmac_count = bgx_reg_read(bgx, 0, BGX_CMR_RX_LMACS) & 0x7;
987-
if (bgx->lmac_count > MAX_LMAC_PER_BGX)
988-
bgx->lmac_count = MAX_LMAC_PER_BGX;
1016+
if (bgx->lmac_count > bgx->max_lmac)
1017+
bgx->lmac_count = bgx->max_lmac;
9891018

990-
for (idx = 0; idx < MAX_LMAC_PER_BGX; idx++)
1019+
for (idx = 0; idx < bgx->max_lmac; idx++)
9911020
bgx_set_lmac_config(bgx, idx);
9921021

993-
if (!bgx->is_81xx) {
1022+
if (!bgx->is_81xx || bgx->is_rgx) {
9941023
bgx_print_qlm_mode(bgx, 0);
9951024
return;
9961025
}
@@ -1140,7 +1169,7 @@ static int bgx_init_of_phy(struct bgx *bgx)
11401169
}
11411170

11421171
lmac++;
1143-
if (lmac == MAX_LMAC_PER_BGX) {
1172+
if (lmac == bgx->max_lmac) {
11441173
of_node_put(node);
11451174
break;
11461175
}
@@ -1218,10 +1247,22 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
12181247
err = -ENOMEM;
12191248
goto err_release_regions;
12201249
}
1221-
bgx->bgx_id = (pci_resource_start(pdev, PCI_CFG_REG_BAR_NUM) >> 24) & 1;
1222-
bgx->bgx_id += nic_get_node_id(pdev) * MAX_BGX_PER_CN88XX;
12231250

1224-
bgx_vnic[bgx->bgx_id] = bgx;
1251+
pci_read_config_word(pdev, PCI_DEVICE_ID, &sdevid);
1252+
if (sdevid != PCI_DEVICE_ID_THUNDER_RGX) {
1253+
bgx->bgx_id =
1254+
(pci_resource_start(pdev, PCI_CFG_REG_BAR_NUM) >> 24) & 1;
1255+
bgx->bgx_id += nic_get_node_id(pdev) * MAX_BGX_PER_CN88XX;
1256+
bgx->max_lmac = MAX_LMAC_PER_BGX;
1257+
bgx_vnic[bgx->bgx_id] = bgx;
1258+
} else {
1259+
bgx->is_rgx = true;
1260+
bgx->max_lmac = 1;
1261+
bgx->bgx_id = MAX_BGX_PER_CN81XX - 1;
1262+
bgx_vnic[bgx->bgx_id] = bgx;
1263+
xcv_init_hw();
1264+
}
1265+
12251266
bgx_get_qlm_mode(bgx);
12261267

12271268
err = bgx_init_phy(bgx);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
/* PCI device ID */
1313
#define PCI_DEVICE_ID_THUNDER_BGX 0xA026
14+
#define PCI_DEVICE_ID_THUNDER_RGX 0xA054
1415

1516
/* Subsystem device IDs */
1617
#define PCI_SUBSYS_DEVID_88XX_BGX 0xA126
@@ -19,7 +20,7 @@
1920

2021
#define MAX_BGX_THUNDER 8 /* Max 4 nodes, 2 per node */
2122
#define MAX_BGX_PER_CN88XX 2
22-
#define MAX_BGX_PER_CN81XX 2
23+
#define MAX_BGX_PER_CN81XX 3 /* 2 BGXs + 1 RGX */
2324
#define MAX_BGX_PER_CN83XX 4
2425
#define MAX_LMAC_PER_BGX 4
2526
#define MAX_BGX_CHANS_PER_LMAC 16
@@ -205,6 +206,9 @@ void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac);
205206
void bgx_get_lmac_link_state(int node, int bgx_idx, int lmacid, void *status);
206207
void bgx_lmac_internal_loopback(int node, int bgx_idx,
207208
int lmac_idx, bool enable);
209+
void xcv_init_hw(void);
210+
void xcv_setup_link(bool link_up, int link_speed);
211+
208212
u64 bgx_get_rx_stats(int node, int bgx_idx, int lmac, int idx);
209213
u64 bgx_get_tx_stats(int node, int bgx_idx, int lmac, int idx);
210214
#define BGX_RX_STATS_COUNT 11

0 commit comments

Comments
 (0)