summaryrefslogtreecommitdiffstats
path: root/sys/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib')
-rw-r--r--sys/contrib/octeon-sdk/cvmx-app-init.h38
-rw-r--r--sys/contrib/octeon-sdk/cvmx-helper-board.c128
-rw-r--r--sys/contrib/octeon-sdk/cvmx-helper-sgmii.c66
-rw-r--r--sys/contrib/octeon-sdk/cvmx-mgmt-port.c4
-rw-r--r--sys/contrib/octeon-sdk/cvmx-pcie.c233
5 files changed, 457 insertions, 12 deletions
diff --git a/sys/contrib/octeon-sdk/cvmx-app-init.h b/sys/contrib/octeon-sdk/cvmx-app-init.h
index 605f43e..beab38e 100644
--- a/sys/contrib/octeon-sdk/cvmx-app-init.h
+++ b/sys/contrib/octeon-sdk/cvmx-app-init.h
@@ -120,6 +120,9 @@ struct cvmx_bootinfo {
uint32_t dfa_ref_clock_hz; /**< DFA reference clock in hz (if applicable)*/
uint32_t config_flags; /**< flags indicating various configuration options. These flags supercede
** the 'flags' variable and should be used instead if available */
+#if defined(OCTEON_VENDOR_GEFES)
+ uint32_t dfm_size; /**< DFA Size */
+#endif
#endif
#if (CVMX_BOOTINFO_MIN_VER >= 3)
uint64_t fdt_addr; /**< Address of the OF Flattened Device Tree structure describing the board. */
@@ -216,10 +219,17 @@ enum cvmx_board_types_enum {
CVMX_BOARD_TYPE_HIKARI = 10,
CVMX_BOARD_TYPE_CN3010_EVB_HS5 = 11,
CVMX_BOARD_TYPE_CN3005_EVB_HS5 = 12,
+#if defined(OCTEON_VENDOR_GEFES)
+ CVMX_BOARD_TYPE_TNPA3804 = 13,
+ CVMX_BOARD_TYPE_AT5810 = 14,
+ CVMX_BOARD_TYPE_WNPA3850 = 15,
+ CVMX_BOARD_TYPE_W3860 = 16,
+#else
CVMX_BOARD_TYPE_KBP = 13,
CVMX_BOARD_TYPE_CN3020_EVB_HS5 = 14, /* Deprecated, CVMX_BOARD_TYPE_CN3010_EVB_HS5 supports the CN3020 */
CVMX_BOARD_TYPE_EBT5800 = 15,
CVMX_BOARD_TYPE_NICPRO2 = 16,
+#endif
CVMX_BOARD_TYPE_EBH5600 = 17,
CVMX_BOARD_TYPE_EBH5601 = 18,
CVMX_BOARD_TYPE_EBH5200 = 19,
@@ -305,6 +315,16 @@ enum cvmx_board_types_enum {
#if defined(OCTEON_VENDOR_RADISYS)
CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE=20002,
#endif
+#if defined(OCTEON_VENDOR_GEFES)
+ CVMX_BOARD_TYPE_CUST_TNPA5804 = 20005,
+ CVMX_BOARD_TYPE_CUST_W5434 = 20006,
+ CVMX_BOARD_TYPE_CUST_W5650 = 20007,
+ CVMX_BOARD_TYPE_CUST_W5800 = 20008,
+ CVMX_BOARD_TYPE_CUST_W5651X = 20009,
+ CVMX_BOARD_TYPE_CUST_TNPA5651X = 20010,
+ CVMX_BOARD_TYPE_CUST_TNPA56X4 = 20011,
+ CVMX_BOARD_TYPE_CUST_W63XX = 20013,
+#endif
CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
@@ -352,10 +372,17 @@ static inline const char *cvmx_board_type_to_string(enum cvmx_board_types_enum t
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_HIKARI)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3010_EVB_HS5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3005_EVB_HS5)
+#if defined(OCTEON_VENDOR_GEFES)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_TNPA3804)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_AT5810)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_WNPA3850)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_W3860)
+#else
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KBP)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3020_EVB_HS5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5800)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NICPRO2)
+#endif
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5600)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5601)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5200)
@@ -420,7 +447,6 @@ static inline const char *cvmx_board_type_to_string(enum cvmx_board_types_enum t
#else
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_ZINWELL)
#endif
-
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MAX)
/* Customer private range */
@@ -435,6 +461,16 @@ static inline const char *cvmx_board_type_to_string(enum cvmx_board_types_enum t
#if defined(OCTEON_VENDOR_RADISYS)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE)
#endif
+#if defined(OCTEON_VENDOR_GEFES)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_TNPA5804)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_W5434)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_W5650)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_W5800)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_W5651X)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_TNPA5651X)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_TNPA56X4)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_W63XX)
+#endif
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
/* Module range */
diff --git a/sys/contrib/octeon-sdk/cvmx-helper-board.c b/sys/contrib/octeon-sdk/cvmx-helper-board.c
index d97813e..49e52d4 100644
--- a/sys/contrib/octeon-sdk/cvmx-helper-board.c
+++ b/sys/contrib/octeon-sdk/cvmx-helper-board.c
@@ -385,10 +385,12 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
case CVMX_BOARD_TYPE_SIM:
/* Simulator doesn't have MII */
return -1;
- case CVMX_BOARD_TYPE_EBT3000:
+#if !defined(OCTEON_VENDOR_GEFES)
case CVMX_BOARD_TYPE_EBT5800:
- case CVMX_BOARD_TYPE_THUNDER:
case CVMX_BOARD_TYPE_NICPRO2:
+#endif
+ case CVMX_BOARD_TYPE_EBT3000:
+ case CVMX_BOARD_TYPE_THUNDER:
/* Interface 0 is SPI4, interface 1 is RGMII */
if ((ipd_port >= 16) && (ipd_port < 20))
return ipd_port - 16;
@@ -410,7 +412,9 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
case CVMX_BOARD_TYPE_HIKARI:
case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+#if !defined(OCTEON_VENDOR_GEFES)
case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
+#endif
/* Port 0 is WAN connected to a PHY, Port 1 is GMII connected to a
switch */
if (ipd_port == 0)
@@ -603,6 +607,30 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
/* No MII. */
return -1;
#endif
+#if defined(OCTEON_VENDOR_GEFES)
+ case CVMX_BOARD_TYPE_AT5810:
+ return -1;
+ case CVMX_BOARD_TYPE_TNPA3804:
+ case CVMX_BOARD_TYPE_CUST_TNPA5804:
+ case CVMX_BOARD_TYPE_CUST_W5800:
+ case CVMX_BOARD_TYPE_WNPA3850:
+ case CVMX_BOARD_TYPE_W3860:
+ return -1;// RGMII boards should use inbad status
+ case CVMX_BOARD_TYPE_CUST_W5651X:
+ case CVMX_BOARD_TYPE_CUST_W5650:
+ case CVMX_BOARD_TYPE_CUST_TNPA56X4:
+ case CVMX_BOARD_TYPE_CUST_TNPA5651X:
+ case CVMX_BOARD_TYPE_CUST_W63XX:
+ return -1; /* No PHYs are connected to Octeon, PHYs inside of SFPs which is accessed over TWSI */
+ case CVMX_BOARD_TYPE_CUST_W5434:
+ /* Board has 4 SGMII ports. 4 connect out
+ * must return the MII address of the PHY connected to each IPD port
+ */
+ if ((ipd_port >= 16) && (ipd_port < 20))
+ return ipd_port - 16 + 0x40;
+ else
+ return -1;
+#endif
}
/* Some unknown board. Somebody forgot to update this function... */
@@ -991,7 +1019,9 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
case CVMX_BOARD_TYPE_EBH3100:
case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+#if !defined(OCTEON_VENDOR_GEFES)
case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
+#endif
/* Port 1 on these boards is always Gigabit */
if (ipd_port == 1)
{
@@ -1077,6 +1107,15 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
}
break;
#endif
+#if defined(OCTEON_VENDOR_GEFES)
+ case CVMX_BOARD_TYPE_CUST_TNPA5651X:
+ /* Since we don't auto-negotiate... 1Gbps full duplex link */
+ result.s.link_up = 1;
+ result.s.full_duplex = 1;
+ result.s.speed = 1000;
+ return result;
+ break;
+#endif
}
#endif
@@ -1103,6 +1142,44 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
here. Reading broken in-band status tends to do bad things */
result = __get_inband_link_state(ipd_port);
}
+#if defined(OCTEON_VENDOR_GEFES)
+ else if( (OCTEON_IS_MODEL(OCTEON_CN56XX)) || (OCTEON_IS_MODEL(OCTEON_CN63XX)) )
+ {
+ int interface = cvmx_helper_get_interface_num(ipd_port);
+ int index = cvmx_helper_get_interface_index_num(ipd_port);
+ cvmx_pcsx_miscx_ctl_reg_t mode_type;
+ cvmx_pcsx_mrx_status_reg_t mrx_status;
+ cvmx_pcsx_anx_adv_reg_t anxx_adv;
+ cvmx_pcsx_sgmx_lp_adv_reg_t sgmii_inband_status;
+
+ anxx_adv.u64 = cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
+ mrx_status.u64 = cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG(index, interface));
+
+ mode_type.u64 = cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+
+ /* Read Octeon's inband status */
+ sgmii_inband_status.u64 = cvmx_read_csr(CVMX_PCSX_SGMX_LP_ADV_REG(index, interface));
+
+ result.s.link_up = sgmii_inband_status.s.link;
+ result.s.full_duplex = sgmii_inband_status.s.dup;
+ switch (sgmii_inband_status.s.speed)
+ {
+ case 0: /* 10 Mbps */
+ result.s.speed = 10;
+ break;
+ case 1: /* 100 Mbps */
+ result.s.speed = 100;
+ break;
+ case 2: /* 1 Gbps */
+ result.s.speed = 1000;
+ break;
+ case 3: /* Illegal */
+ result.s.speed = 0;
+ result.s.link_up = 0;
+ break;
+ }
+ }
+#endif
else
{
/* We don't have a PHY address and we don't have in-band status. There
@@ -1319,6 +1396,33 @@ int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
return 12;
break;
#endif
+#if defined(OCTEON_VENDOR_GEFES)
+ case CVMX_BOARD_TYPE_CUST_TNPA5651X:
+ if (interface < 2) /* interface can be EITHER 0 or 1 */
+ return 1;//always return 1 for XAUI and SGMII mode.
+ break;
+ case CVMX_BOARD_TYPE_CUST_TNPA56X4:
+ if ((interface == 0) &&
+ (cvmx_helper_interface_get_mode(interface) == CVMX_HELPER_INTERFACE_MODE_SGMII))
+ {
+ cvmx_pcsx_miscx_ctl_reg_t pcsx_miscx_ctl_reg;
+
+ /* For this port we need to set the mode to 1000BaseX */
+ pcsx_miscx_ctl_reg.u64 =
+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(0, interface));
+ pcsx_miscx_ctl_reg.cn56xx.mode = 1;
+ cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(0, interface),
+ pcsx_miscx_ctl_reg.u64);
+ pcsx_miscx_ctl_reg.u64 =
+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(1, interface));
+ pcsx_miscx_ctl_reg.cn56xx.mode = 1;
+ cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(1, interface),
+ pcsx_miscx_ctl_reg.u64);
+
+ return 2;
+ }
+ break;
+#endif
}
#ifdef CVMX_BUILD_FOR_UBOOT
if (CVMX_HELPER_INTERFACE_MODE_SPI == cvmx_helper_interface_get_mode(interface) && getenv("disable_spi"))
@@ -1481,15 +1585,29 @@ cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
case CVMX_BOARD_TYPE_LANAI2_U:
case CVMX_BOARD_TYPE_LANAI2_G:
#if defined(OCTEON_VENDOR_LANNER)
- case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
- case CVMX_BOARD_TYPE_CUST_LANNER_MR321X:
+ case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
+ case CVMX_BOARD_TYPE_CUST_LANNER_MR321X:
#endif
#if defined(OCTEON_VENDOR_UBIQUITI)
- case CVMX_BOARD_TYPE_CUST_UBIQUITI_E100:
+ case CVMX_BOARD_TYPE_CUST_UBIQUITI_E100:
#endif
#if defined(OCTEON_BOARD_CAPK_0100ND)
case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
#endif
+#if defined(OCTEON_VENDOR_GEFES) /* All GEFES' boards use same xtal type */
+ case CVMX_BOARD_TYPE_TNPA3804:
+ case CVMX_BOARD_TYPE_AT5810:
+ case CVMX_BOARD_TYPE_WNPA3850:
+ case CVMX_BOARD_TYPE_W3860:
+ case CVMX_BOARD_TYPE_CUST_TNPA5804:
+ case CVMX_BOARD_TYPE_CUST_W5434:
+ case CVMX_BOARD_TYPE_CUST_W5650:
+ case CVMX_BOARD_TYPE_CUST_W5800:
+ case CVMX_BOARD_TYPE_CUST_W5651X:
+ case CVMX_BOARD_TYPE_CUST_TNPA5651X:
+ case CVMX_BOARD_TYPE_CUST_TNPA56X4:
+ case CVMX_BOARD_TYPE_CUST_W63XX:
+#endif
case CVMX_BOARD_TYPE_NIC10E_66:
return USB_CLOCK_TYPE_CRYSTAL_12;
case CVMX_BOARD_TYPE_NIC10E:
diff --git a/sys/contrib/octeon-sdk/cvmx-helper-sgmii.c b/sys/contrib/octeon-sdk/cvmx-helper-sgmii.c
index 8699548..6cb0973 100644
--- a/sys/contrib/octeon-sdk/cvmx-helper-sgmii.c
+++ b/sys/contrib/octeon-sdk/cvmx-helper-sgmii.c
@@ -116,7 +116,13 @@ static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
interval. */
pcsx_miscx_ctl_reg.u64 = cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
pcsx_linkx_timer_count_reg.u64 = cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface));
- if (pcsx_miscx_ctl_reg.s.mode)
+ if (pcsx_miscx_ctl_reg.s.mode
+#if defined(OCTEON_VENDOR_GEFES)
+ /* GEF Fiber SFP testing on W5650 showed this to cause link issues for 1000BASE-X*/
+ && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_CUST_W5650)
+ && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_CUST_W63XX)
+#endif
+ )
{
/* 1000BASE-X */
pcsx_linkx_timer_count_reg.s.count = (10000ull * clock_mhz) >> 10;
@@ -200,7 +206,15 @@ static int __cvmx_helper_need_g15618(void)
static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
{
cvmx_pcsx_mrx_control_reg_t control_reg;
+ uint64_t link_timeout;
+
+#if defined(OCTEON_VENDOR_GEFES)
+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CUST_TNPA5651X) {
+ return 0; /* no auto-negotiation */
+ }
+#endif
+
/* Take PCS through a reset sequence.
PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero.
Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the value of
@@ -211,9 +225,16 @@ static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
/* Errata G-15618 requires disabling PCS soft reset in CN63XX pass upto 2.1. */
if (!__cvmx_helper_need_g15618())
{
+ link_timeout = 200000;
+#if defined(OCTEON_VENDOR_GEFES)
+ if( (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CUST_TNPA56X4) && (interface == 0) )
+ {
+ link_timeout = 5000000;
+ }
+#endif
control_reg.s.reset = 1;
cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface), control_reg.u64);
- if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_CONTROL_REG(index, interface), cvmx_pcsx_mrx_control_reg_t, reset, ==, 0, 10000))
+ if (CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_CONTROL_REG(index, interface), cvmx_pcsx_mrx_control_reg_t, reset, ==, 0, link_timeout))
{
cvmx_dprintf("SGMII%d: Timeout waiting for port %d to finish reset\n", interface, index);
return -1;
@@ -256,6 +277,11 @@ static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface, int index
cvmx_gmxx_prtx_cfg_t gmxx_prtx_cfg;
cvmx_pcsx_miscx_ctl_reg_t pcsx_miscx_ctl_reg;
+#if defined(OCTEON_VENDOR_GEFES)
+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CUST_TNPA5651X)
+ return 0; /* no auto-negotiation */
+#endif
+
/* Disable GMX before we make any changes. Remember the enable state */
gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
is_enabled = gmxx_prtx_cfg.s.en;
@@ -586,8 +612,42 @@ cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port)
pcsx_miscx_ctl_reg.u64 = cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
if (pcsx_miscx_ctl_reg.s.mode)
{
+#if defined(OCTEON_VENDOR_GEFES)
/* 1000BASE-X */
- // FIXME
+ int interface = cvmx_helper_get_interface_num(ipd_port);
+ int index = cvmx_helper_get_interface_index_num(ipd_port);
+ cvmx_pcsx_miscx_ctl_reg_t mode_type;
+ cvmx_pcsx_anx_results_reg_t inband_status;
+ cvmx_pcsx_mrx_status_reg_t mrx_status;
+ cvmx_pcsx_anx_adv_reg_t anxx_adv;
+
+ anxx_adv.u64 = cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
+ mrx_status.u64 = cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG(index, interface));
+ mode_type.u64 = cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+
+ /* Read Octeon's inband status */
+ inband_status.u64 = cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG(index, interface));
+
+ result.s.link_up = inband_status.s.link_ok;/* this is only accurate for 1000-base x */
+
+ result.s.full_duplex = inband_status.s.dup;
+ switch (inband_status.s.spd)
+ {
+ case 0: /* 10 Mbps */
+ result.s.speed = 10;
+ break;
+ case 1: /* 100 Mbps */
+ result.s.speed = 100;
+ break;
+ case 2: /* 1 Gbps */
+ result.s.speed = 1000;
+ break;
+ case 3: /* Illegal */
+ result.s.speed = 0;
+ result.s.link_up = 0;
+ break;
+ }
+#endif /* Actually not 100% this is GEFES specific */
}
else
{
diff --git a/sys/contrib/octeon-sdk/cvmx-mgmt-port.c b/sys/contrib/octeon-sdk/cvmx-mgmt-port.c
index d6f6c5d..759a8ce 100644
--- a/sys/contrib/octeon-sdk/cvmx-mgmt-port.c
+++ b/sys/contrib/octeon-sdk/cvmx-mgmt-port.c
@@ -116,12 +116,16 @@ CVMX_SHARED cvmx_mgmt_port_state_t *cvmx_mgmt_port_state_ptr = NULL;
*/
static int __cvmx_mgmt_port_num_ports(void)
{
+#if defined(OCTEON_VENDOR_GEFES)
+ return 0; /* none of the GEFES boards have mgmt ports */
+#else
if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX))
return 1;
else if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN6XXX))
return 2;
else
return 0;
+#endif
}
diff --git a/sys/contrib/octeon-sdk/cvmx-pcie.c b/sys/contrib/octeon-sdk/cvmx-pcie.c
index 088efcb..ff8f514 100644
--- a/sys/contrib/octeon-sdk/cvmx-pcie.c
+++ b/sys/contrib/octeon-sdk/cvmx-pcie.c
@@ -422,12 +422,12 @@ static int __cvmx_pcie_rc_initialize_link_gen1(int pcie_port)
start_cycle = cvmx_get_cycle();
do
{
- if (cvmx_get_cycle() - start_cycle > 2*cvmx_clock_get_rate(CVMX_CLOCK_CORE))
+ if (cvmx_get_cycle() - start_cycle > 100*cvmx_clock_get_rate(CVMX_CLOCK_CORE))
{
cvmx_dprintf("PCIe: Port %d link timeout\n", pcie_port);
return -1;
}
- cvmx_wait(10000);
+ cvmx_wait(50000);
pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
} while (pciercx_cfg032.s.dlla == 0);
@@ -518,6 +518,41 @@ retry:
return -1;
}
+#if defined(CONFIG_GEFES_SUPPORT) /* Commented out for now */
+ /* check if we should initialize this port */
+ if ((cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_TNPA56X4) ||
+ (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_TNPA5651X)) {
+ unsigned char fpga_ekeylanes0 = 0;
+ unsigned char fpga_ekeylanes1 = 0;
+
+ cvmx_get_mmc_ekeying(&fpga_ekeylanes0, &fpga_ekeylanes1);
+ /* For pcie_port 0 - QLM0 (& optionally QLM1)
+ x4 PCIe AMC ports 4-7 via QLM0
+ x8 PCIe AMC ports 4-7 via QLM0 and AMC ports 8-11 via QLM1
+ root complex or end point configuration
+ must be root complex via "if (npei_ctl_status.s.host_mode) {"
+ */
+
+ if ((pcie_port == 0) && (fpga_ekeylanes1 == 0)) {
+ return -1;
+ }
+
+ /* For pcie_port 1 - QLM2 in RC only connected to 82571 ethernet */
+ /* always enabled, don't check ekeying lanes */
+ }
+ else /* all other GEFES boards(maybe just WANIC?)*/
+ {
+ cvmx_npei_ctl_status_t npei_ctl_status;
+
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ if ( (pcie_port == 1) && (!npei_ctl_status.s.host_mode) )
+ {
+ cvmx_dprintf("PCIe: Port 1 not used (RC only), skipping.\\n");
+ return -1;
+ }
+ }
+#endif /* CONFIG_GEFES_SUPPORT */
+
/* PCIe switch arbitration mode. '0' == fixed priority NPEI, PCIe0, then PCIe1. '1' == round robin. */
npei_ctl_status.s.arb = 1;
/* Allow up to 0x20 config retries */
@@ -988,6 +1023,27 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port)
return -1;
}
+#ifdef CONFIG_GEFES_SUPPORT /* commented out for now */
+ /* check if we should initialize this port */
+ if ((cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_TNPA56X4) ||
+ (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_TNPA5651X)) {
+ unsigned char fpga_ekeylanes0;
+ unsigned char fpga_ekeylanes1;
+
+ cvmx_get_mmc_ekeying(&fpga_ekeylanes0, &fpga_ekeylanes1);
+ /* For pcie_port 0 - QLM0 (& optionally QLM1)
+ x4 PCIe AMC ports 4-7 via QLM0
+ x8 PCIe AMC ports 4-7 via QLM0 and AMC ports 8-11 via QLM1
+ root complex or end point configuration
+ must be endpoint via "if (npei_ctl_status.s.host_mode) {"
+ */
+ if (( pcie_port == 0) && (fpga_ekeylanes1 == 0)) {
+ return -1;
+ }
+ /* can't get here for pcie_port 1 as is always only root complex configured */
+ }
+#endif /* CONFIG_GEFES_SUPPORT */
+
/* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be programmed */
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0))
{
@@ -1340,7 +1396,46 @@ uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, int re
*/
uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, int reg)
{
- uint64_t address = __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ uint64_t address;
+
+#ifdef CONFIG_GEFES_SUPPORT /* Commented out for now */
+
+ int result;
+
+ /* if U-boot initializes the PCIe ports, then to Linux
+ it looks as if the ports are up, when in fact, the
+ port 0 link could be down because there is no endpoint
+ configured card present. If that is the case, U-boot
+ would not have configured the access to the PCIe config
+ space for that port and Linux would crash when it tries
+ to access that memory space. This code checks to see
+ if root complex mode is configured, and if it is, if
+ the link is up for the port before trying to access
+ the config space.
+ */
+
+ /* root complex ? */
+ result = cvmx_pcie_dogetinfo(pcie_port, 2);
+ if (result == 1) {
+ //cvmx_dprintf("cvmx_pcie_config_read32: pcie_port %d in root complex mode\n", pcie_port);
+ } else {
+ //cvmx_dprintf("cvmx_pcie_config_read32: pcie_port %d in end point mode\n", pcie_port);
+ }
+
+ if (result == 1) {
+ /* link up? */
+ result = cvmx_pcie_dogetinfo(pcie_port, 0);
+
+ if (result == 1) {
+ //cvmx_dprintf("cvmx_pcie_config_read32: pcie_port %d link UP\n", pcie_port);
+ } else {
+ cvmx_dprintf("cvmx_pcie_config_read32: pcie_port %d link DOWN\n", pcie_port);
+ return 0xffffffff;
+ }
+ }
+#endif /* CONFIG_GEFES_SUPPORT */
+
+ address = __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
if (address)
return cvmx_le32_to_cpu(cvmx_read64_uint32(address));
else
@@ -1698,3 +1793,135 @@ void cvmx_pcie_wait_for_pending(int pcie_port)
}
}
}
+
+#ifdef CONFIG_GEFES_SUPPORT
+/* eastestdebug - add ekeying from MMC routine */
+/* support routine for CVMX_BOARD_TYPE_TNPA56X4 ekeying */
+void cvmx_get_mmc_ekeying(unsigned char *fpga_ekeylanes0, unsigned char *fpga_ekeylanes1)
+{
+ switch (cvmx_sysinfo_get()->board_type) {
+ case CVMX_BOARD_TYPE_TNPA56X4:
+ case CVMX_BOARD_TYPE_TNPA5651X:
+ /*TODO: need to check AMC shelf response for 4-7 and 8-11*/
+ /*TODO: get rid of magic numbers for FPGA access*/
+ /* IPMI define = BOARD_FPGA_DPRAM_PORT_EN_0 */
+ /* base ports 0 & 1, fabric xaui 4-7 */
+ *fpga_ekeylanes0 = *(char*)0x8000000016000080;
+ /* IPMI define = BOARD_FPGA_DPRAM_PORT_EN_1 */
+ /* fabric pcie 4-7, fabric pcie 8-11 */
+ *fpga_ekeylanes1 = *(char*)0x8000000016000082;
+ default:
+ /* TBD for other board types */
+ break;
+ }
+}
+
+/* eastestdebug - add cvmx_pcie_getinfo for PCIe /proc/ data */
+/**
+ * Get desired info for a PCIe port on our Octeon.
+ * Note not possible to have multiple devObj from caller.
+ *
+ * @param pcie_port PCIe port to get info for
+ *
+ * @return uint8_t value for desired info
+ */
+int cvmx_pcie_dogetinfo(int pcie_port, int infotype)
+{
+cvmx_pciercx_cfg032_t pciercx_cfg032;
+cvmx_npei_ctl_status_t npei_ctl_status;
+unsigned char fpga_ekeylanes0 = 0;
+unsigned char fpga_ekeylanes1 = 0;
+uint64_t start_cycle;
+
+ switch (cvmx_sysinfo_get()->board_type) {
+ case CVMX_BOARD_TYPE_TNPA56X4:
+ case CVMX_BOARD_TYPE_TNPA5651X:
+ switch (infotype) {
+ case 0: /* link up (1) /down (0) */
+#if 0
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ if (pciercx_cfg032.s.nlw) {
+ /* link up */
+ return(1);
+ }
+ return(0);
+#endif
+ /* Wait for the link to come up */
+ //cvmx_dprintf("PCIe: Waiting for port %d link\n", pcie_port);
+ start_cycle = cvmx_get_cycle();
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ while (pciercx_cfg032.s.dlla == 0) {
+ /* if (cvmx_get_cycle() - start_cycle > 2*cvmx_sysinfo_get()->cpu_clock_hz) */
+ if (cvmx_get_cycle() - start_cycle > 100 * cvmx_sysinfo_get()->cpu_clock_hz)
+ {
+ cvmx_dprintf("PCIe: Port %d link timeout\n", pcie_port);
+ return 0;
+ }
+ /* cvmx_wait(10000); */
+ cvmx_wait(50000);
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ }
+
+ /* Display the link status */
+ //cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port, pciercx_cfg032.s.nlw);
+ return(1);
+
+ case 1: /* link valid (1) / disabled (0) */
+ /* CVMX_BOARD_TYPE_TNPA56X4 specific */
+ if (pcie_port == 1) {
+ /* port 1 - QLM2 RC x4 always enabled */
+ return (1);
+ }
+ cvmx_get_mmc_ekeying(&fpga_ekeylanes0, &fpga_ekeylanes1);
+ if (fpga_ekeylanes1) {
+ /* ekeying on for something - i.e. valid */
+ return(1);
+ }
+ return(0);
+ case 2: /* link type root complex (1) /end point (0) */
+ if (pcie_port == 1) {
+ /* port 1 - QLM2 RC x4 always enabled */
+ return (1);
+ }
+ /* check if port 0 host (rc) or endpoint */
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ if (npei_ctl_status.s.host_mode) {
+ return(1);
+ }
+ return(0);
+ case 3: /* desired link size x8 (8) /x4 (4) */
+ cvmx_get_mmc_ekeying(&fpga_ekeylanes0, &fpga_ekeylanes1);
+ if (fpga_ekeylanes1 & 0xf0) {
+ return (8); /* x8 */
+ } else if (fpga_ekeylanes1 & 0x0f) {
+ return (4); /* x4 */
+ }
+ break; /* disabled */
+ case 4: /* actual configured link size x32 (32)/ x16 (16) /x8 (8) /x4 (4) /x2 (2) x1 (1) */
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ switch (pciercx_cfg032.s.nlw) {
+ case 1: /* 1 lane */
+ return(1);
+ case 2: /* 2 lanes */
+ return(2);
+ case 4: /* 4 lanes */
+ return(4);
+ case 8: /* 8 lanes */
+ return(8);
+ default:
+ break;
+ }
+ /* unknown, return x4 */
+ return(4);
+ default:
+ /* TBD for other info types */
+ return 0;
+ }
+ break;
+ default:
+ /* TBD for other board types */
+ break;
+ }
+ return 0;
+}
+#endif /* CONFIG_GEFES_SUPPORT */
OpenPOWER on IntegriCloud