in arch/mips/mach-octeon/cvmx-qlm.c [1437:1690]
enum cvmx_qlm_mode __cvmx_qlm_get_mode_cn73xx(int qlm)
{
cvmx_gserx_cfg_t gserx_cfg;
int qlm_mode[7] = { -1, -1, -1, -1, -1, -1, -1 };
if (qlm_mode[qlm] != -1)
return qlm_mode[qlm];
if (qlm > 6) {
debug("Invalid QLM(%d) passed\n", qlm);
return -1;
}
gserx_cfg.u64 = csr_rd(CVMX_GSERX_CFG(qlm));
if (gserx_cfg.s.pcie) {
cvmx_pemx_cfg_t pemx_cfg;
switch (qlm) {
case 0: /* Either PEM0 x4 or PEM0 x8 */
case 1: /* Either PEM0 x8 or PEM1 x4 */
{
pemx_cfg.u64 = csr_rd(CVMX_PEMX_CFG(0));
if (pemx_cfg.cn78xx.lanes8) {
/* PEM0 x8 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X8;
} else {
/* PEM0/PEM1 x4 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
}
break;
}
case 2: /* Either PEM2 x4 or PEM2 x8 */
{
pemx_cfg.u64 = csr_rd(CVMX_PEMX_CFG(2));
if (pemx_cfg.cn78xx.lanes8) {
/* PEM2 x8 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X8;
} else {
/* PEM2 x4 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
}
break;
}
case 5:
case 6: /* PEM3 x2 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X2; /* PEM3 x2 */
break;
case 3: /* Either PEM2 x8 or PEM3 x4 */
{
pemx_cfg.u64 = csr_rd(CVMX_PEMX_CFG(2));
if (pemx_cfg.cn78xx.lanes8) {
/* PEM2 x8 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X8;
} else {
/* PEM3 x4 */
qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
}
break;
}
default:
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
break;
}
} else if (gserx_cfg.s.bgx) {
cvmx_bgxx_cmrx_config_t cmr_config;
cvmx_bgxx_cmr_rx_lmacs_t bgx_cmr_rx_lmacs;
cvmx_bgxx_spux_br_pmd_control_t pmd_control;
int bgx = 0;
int start = 0, end = 4, index;
int lane_mask = 0, train_mask = 0;
int mux = 0; // 0:BGX2 (DLM5/DLM6), 1:BGX2(DLM5), 2:BGX2(DLM6)
if (qlm < 4) {
bgx = qlm - 2;
} else if (qlm == 5 || qlm == 6) {
bgx = 2;
mux = cvmx_qlm_mux_interface(bgx);
if (mux == 0) {
start = 0;
end = 4;
} else if (mux == 1) {
start = 0;
end = 2;
} else if (mux == 2) {
start = 2;
end = 4;
} else {
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
return qlm_mode[qlm];
}
}
for (index = start; index < end; index++) {
cmr_config.u64 = csr_rd(CVMX_BGXX_CMRX_CONFIG(index, bgx));
pmd_control.u64 = csr_rd(CVMX_BGXX_SPUX_BR_PMD_CONTROL(index, bgx));
lane_mask |= (cmr_config.s.lmac_type << (index * 4));
train_mask |= (pmd_control.s.train_en << (index * 4));
}
/* Need to include DLM5 lmacs when only DLM6 DLM is used */
if (mux == 2)
bgx_cmr_rx_lmacs.u64 = csr_rd(CVMX_BGXX_CMR_RX_LMACS(2));
switch (lane_mask) {
case 0:
if (mux == 1) {
qlm_mode[qlm] = CVMX_QLM_MODE_SGMII_2X1;
} else if (mux == 2) {
qlm_mode[qlm] = CVMX_QLM_MODE_SGMII_2X1;
bgx_cmr_rx_lmacs.s.lmacs = 4;
}
qlm_mode[qlm] = CVMX_QLM_MODE_SGMII;
break;
case 0x1:
qlm_mode[qlm] = CVMX_QLM_MODE_XAUI;
break;
case 0x2:
if (mux == 1) {
// NONE+RXAUI
qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
} else if (mux == 0) {
// RXAUI+SGMII
qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
} else {
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
}
break;
case 0x202:
if (mux == 2) {
// RXAUI+RXAUI
qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
bgx_cmr_rx_lmacs.s.lmacs = 4;
} else if (mux == 1) {
// RXAUI+RXAUI
qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
} else if (mux == 0) {
qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI;
} else {
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
}
break;
case 0x22:
qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI;
break;
case 0x3333:
/*
* Use training to determine if we're in 10GBASE-KR
* or XFI
*/
if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR;
else
qlm_mode[qlm] = CVMX_QLM_MODE_XFI;
break;
case 0x4:
/*
* Use training to determine if we're in 40GBASE-KR
* or XLAUI
*/
if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_40G_KR4;
else
qlm_mode[qlm] = CVMX_QLM_MODE_XLAUI;
break;
case 0x0005:
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_SGMII;
break;
case 0x3335:
if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_10G_KR;
else
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XFI;
break;
case 0x45:
if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_40G_KR4;
else
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XLAUI;
break;
case 0x225:
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_RXAUI;
break;
case 0x15:
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XAUI;
break;
case 0x200:
if (mux == 2) {
qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
bgx_cmr_rx_lmacs.s.lmacs = 4;
} else
case 0x205:
case 0x233:
case 0x3302:
case 0x3305:
if (mux == 0)
qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
else
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
break;
case 0x3300:
if (mux == 0) {
qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
} else if (mux == 2) {
if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR_1X2;
else
qlm_mode[qlm] = CVMX_QLM_MODE_XFI_1X2;
bgx_cmr_rx_lmacs.s.lmacs = 4;
} else {
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
}
break;
case 0x33:
if (mux == 1 || mux == 2) {
if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR_1X2;
else
qlm_mode[qlm] = CVMX_QLM_MODE_XFI_1X2;
if (mux == 2)
bgx_cmr_rx_lmacs.s.lmacs = 4;
} else {
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
}
break;
case 0x0035:
if (mux == 0)
qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
else if (train_mask)
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_10G_KR_1X1;
else
qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XFI_1X1;
break;
case 0x235:
if (mux == 0)
qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
else
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
break;
default:
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
break;
}
if (mux == 2) {
csr_wr(CVMX_BGXX_CMR_RX_LMACS(2), bgx_cmr_rx_lmacs.u64);
csr_wr(CVMX_BGXX_CMR_TX_LMACS(2), bgx_cmr_rx_lmacs.u64);
}
} else if (gserx_cfg.s.sata) {
qlm_mode[qlm] = CVMX_QLM_MODE_SATA_2X1;
} else {
qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
}
return qlm_mode[qlm];
}