/* *WaitforPCS*_MR*_STATUS_REG[AN_CPT]tobeset,indicating *thatsgmiiautonegotiationiscomplete.InMACmodethis *isn'tanethernetlink,butalinkbetweenOcteonandthe *PHY.
*/ if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface), union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1, 10000)) { /* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */ return -1;
} return0;
}
/** *ConfigureanSGMIIlinktothespecifiedspeedaftertheSERTES *linkisup. * *@interface:Interfacetoinit *@index:Indexofprotontheinterface *@link_info:Linkstatetoconfigure * *ReturnsZeroonsuccess,negativeonfailure
*/ staticint __cvmx_helper_sgmii_hardware_init_link_speed(int interface, int index, union cvmx_helper_link_info
link_info)
{ int is_enabled; union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg; union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
/* 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;
gmxx_prtx_cfg.s.en = 0;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
/* Wait for GMX to be idle */ if (CVMX_WAIT_FOR_FIELD64
(CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg,
rx_idle, ==, 1, 10000)
|| CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1, 10000)) {
cvmx_dprintf
("SGMII%d: Timeout waiting for port %d to be idle\n",
interface, index); return -1;
}
/* Read GMX CFG again to make sure the disable completed */
gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
/* Write the new misc control for PCS */
cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
pcsx_miscx_ctl_reg.u64);
/* Write the new GMX settings with the port still disabled */
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
/* Read GMX CFG again to make sure the config completed */
gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
/* Restore the enabled / disabled state */
gmxx_prtx_cfg.s.en = is_enabled;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
return0;
}
/** *BringuptheSGMIIinterfacetobereadyforpacketI/Obut *leaveI/OdisabledusingtheGMXoverride.Thisfunction *followsthebringupdocumentedin10.6.3ofthemanual. * *@interface:Interfacetobringup *@num_ports:Numberofportsontheinterface * *ReturnsZeroonsuccess,negativeonfailure
*/ staticint __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
{ int index;
__cvmx_helper_setup_gmx(interface, num_ports);
for (index = 0; index < num_ports; index++) { int ipd_port = cvmx_helper_get_ipd_port(interface, index);
__cvmx_helper_sgmii_hardware_init_one_time(interface, index); /* Linux kernel driver will call ....link_set with the *properlinkstate.Inthesimulatorthereisno *linkstatepollingandhenceitissetfrom *here.
*/ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
__cvmx_helper_sgmii_link_set(ipd_port,
__cvmx_helper_sgmii_link_get(ipd_port));
}
return0;
}
int __cvmx_helper_sgmii_enumerate(int interface)
{ return4;
} /** *ProbeaSGMIIinterfaceanddeterminethenumberofports *connectedtoit.TheSGMIIinterfaceshouldstillbedownafter *thiscall. * *@interface:Interfacetoprobe * *ReturnsNumberofportsontheinterface.Zerotodisable.
*/ int __cvmx_helper_sgmii_probe(int interface)
{ union cvmx_gmxx_inf_mode mode;
for (index = 0; index < num_ports; index++) { union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
gmxx_prtx_cfg.u64 =
cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmxx_prtx_cfg.s.en = 1;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
gmxx_prtx_cfg.u64);
__cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface);
}
__cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
__cvmx_interrupt_gmxx_enable(interface); return0;
}
/** *ReturnthelinkstateofanIPD/PKOportasreturnedby *autonegotiation.Theresultofthisfunctionmaynotmatch *Octeon'slinkconfigifautonegotiationhaschangedsince *thelastcalltocvmx_helper_link_set(). * *@ipd_port:IPD/PKOporttoquery * *ReturnsLinkstate
*/ union cvmx_helper_link_info __cvmx_helper_sgmii_link_get(int ipd_port)
{ union cvmx_helper_link_info result; union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg; int interface = cvmx_helper_get_interface_num(ipd_port); int index = cvmx_helper_get_interface_index_num(ipd_port); union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
result.u64 = 0;
if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) { /* The simulator gives you a simulated 1Gbps full duplex link */
result.s.link_up = 1;
result.s.full_duplex = 1;
result.s.speed = 1000; return result;
}
pcsx_mrx_control_reg.u64 =
cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface)); if (pcsx_mrx_control_reg.s.loopbck1) { /* Force 1Gbps full duplex link for internal loopback */
result.s.link_up = 1;
result.s.full_duplex = 1;
result.s.speed = 1000; return result;
}
pcs_misc_ctl_reg.u64 =
cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); if (pcs_misc_ctl_reg.s.mode) { /* 1000BASE-X */ /* FIXME */
} else { union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
pcsx_miscx_ctl_reg.u64 =
cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); if (pcsx_miscx_ctl_reg.s.mac_phy) { /* PHY Mode */ union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg; union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.