RDMA/nes: Fix SFP+ PHY initialization
SFP+ PHY initialization has very long delays, incorrect settings for direct attach copper cables, and inconsistent link detection. Adjust delays to the minimum required by the PHY. Worst case is now less than 4 seconds. Add new register settings for direct attach cables. Change link detection logic to use two new registers for more consistent link state detection. Reorganize code to shorten line length. Signed-off-by: Chien Tung <chien.tin.tung@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Родитель
5962c2c803
Коммит
1b9493248c
|
@ -757,6 +757,10 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
|
||||||
((port_count > 2) &&
|
((port_count > 2) &&
|
||||||
(nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
|
(nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
|
||||||
/* init serdes 1 */
|
/* init serdes 1 */
|
||||||
|
if (nesadapter->phy_type[0] == NES_PHY_TYPE_ARGUS) {
|
||||||
|
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000);
|
||||||
|
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000);
|
||||||
|
}
|
||||||
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
|
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
|
||||||
if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
|
if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
|
||||||
serdes_common_control = nes_read_indexed(nesdev,
|
serdes_common_control = nes_read_indexed(nesdev,
|
||||||
|
@ -1259,203 +1263,155 @@ int nes_init_phy(struct nes_device *nesdev)
|
||||||
{
|
{
|
||||||
struct nes_adapter *nesadapter = nesdev->nesadapter;
|
struct nes_adapter *nesadapter = nesdev->nesadapter;
|
||||||
u32 counter = 0;
|
u32 counter = 0;
|
||||||
u32 sds_common_control0;
|
u32 sds;
|
||||||
u32 mac_index = nesdev->mac_index;
|
u32 mac_index = nesdev->mac_index;
|
||||||
u32 tx_config = 0;
|
u32 tx_config = 0;
|
||||||
u16 phy_data;
|
u16 phy_data;
|
||||||
u32 temp_phy_data = 0;
|
u32 temp_phy_data = 0;
|
||||||
u32 temp_phy_data2 = 0;
|
u32 temp_phy_data2 = 0;
|
||||||
u32 i = 0;
|
u8 phy_type = nesadapter->phy_type[mac_index];
|
||||||
|
u8 phy_index = nesadapter->phy_index[mac_index];
|
||||||
|
|
||||||
if ((nesadapter->OneG_Mode) &&
|
if ((nesadapter->OneG_Mode) &&
|
||||||
(nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
|
(phy_type != NES_PHY_TYPE_PUMA_1G)) {
|
||||||
nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
|
nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
|
||||||
if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
|
if (phy_type == NES_PHY_TYPE_1G) {
|
||||||
printk(PFX "%s: Programming mdc config for 1G\n", __func__);
|
|
||||||
tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
|
tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
|
||||||
tx_config &= 0xFFFFFFE3;
|
tx_config &= 0xFFFFFFE3;
|
||||||
tx_config |= 0x04;
|
tx_config |= 0x04;
|
||||||
nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
|
nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data);
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
|
nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000);
|
||||||
nesadapter->phy_index[mac_index], phy_data);
|
|
||||||
nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
|
|
||||||
|
|
||||||
/* Reset the PHY */
|
/* Reset the PHY */
|
||||||
nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
|
nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000);
|
||||||
udelay(100);
|
udelay(100);
|
||||||
counter = 0;
|
counter = 0;
|
||||||
do {
|
do {
|
||||||
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
|
if (counter++ > 100)
|
||||||
if (counter++ > 100) break;
|
break;
|
||||||
} while (phy_data & 0x8000);
|
} while (phy_data & 0x8000);
|
||||||
|
|
||||||
/* Setting no phy loopback */
|
/* Setting no phy loopback */
|
||||||
phy_data &= 0xbfff;
|
phy_data &= 0xbfff;
|
||||||
phy_data |= 0x1140;
|
phy_data |= 0x1140;
|
||||||
nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data);
|
nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data);
|
||||||
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
|
nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data);
|
||||||
|
nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data);
|
||||||
nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data);
|
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data);
|
|
||||||
|
|
||||||
nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data);
|
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data);
|
|
||||||
|
|
||||||
/* Setting the interrupt mask */
|
/* Setting the interrupt mask */
|
||||||
nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
|
nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee);
|
||||||
nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee);
|
nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
|
||||||
|
|
||||||
nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
|
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
|
|
||||||
|
|
||||||
/* turning on flow control */
|
/* turning on flow control */
|
||||||
nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
|
nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00);
|
||||||
nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
|
nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
|
||||||
(phy_data & ~(0x03E0)) | 0xc00);
|
|
||||||
/* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
|
|
||||||
phy_data | 0xc00); */
|
|
||||||
nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
|
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
|
|
||||||
|
|
||||||
nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
|
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
|
|
||||||
/* Clear Half duplex */
|
/* Clear Half duplex */
|
||||||
nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index],
|
nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
|
||||||
phy_data & ~(0x0100));
|
nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100));
|
||||||
nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
|
||||||
nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
|
|
||||||
|
|
||||||
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
|
nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
|
||||||
nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
|
nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300);
|
||||||
} else {
|
|
||||||
if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
|
|
||||||
(nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
|
|
||||||
/* setup 10G MDIO operation */
|
|
||||||
tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
|
|
||||||
tx_config &= 0xFFFFFFE3;
|
|
||||||
tx_config |= 0x15;
|
|
||||||
nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
|
|
||||||
}
|
|
||||||
if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
|
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
|
|
||||||
|
|
||||||
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
return 0;
|
||||||
mdelay(10);
|
}
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
|
|
||||||
temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
|
||||||
|
|
||||||
/*
|
if ((phy_type == NES_PHY_TYPE_IRIS) ||
|
||||||
* if firmware is already running (like from a
|
(phy_type == NES_PHY_TYPE_ARGUS)) {
|
||||||
* driver un-load/load, don't do anything.
|
/* setup 10G MDIO operation */
|
||||||
*/
|
tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
|
||||||
if (temp_phy_data == temp_phy_data2) {
|
tx_config &= 0xFFFFFFE3;
|
||||||
/* configure QT2505 AMCC PHY */
|
tx_config |= 0x15;
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
|
nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
|
}
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
|
if ((phy_type == NES_PHY_TYPE_ARGUS)) {
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
|
/* Check firmware heartbeat */
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
|
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
|
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
|
udelay(1500);
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0001);
|
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
|
temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
|
|
||||||
/*
|
if (temp_phy_data != temp_phy_data2)
|
||||||
* remove micro from reset; chip boots from ROM,
|
return 0;
|
||||||
* uploads EEPROM f/w image, uC executes f/w
|
|
||||||
*/
|
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
|
|
||||||
|
|
||||||
/*
|
/* no heartbeat, configure the PHY */
|
||||||
* wait for heart beat to start to
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
|
||||||
* know loading is done
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000);
|
||||||
*/
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C);
|
||||||
counter = 0;
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A);
|
||||||
do {
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052);
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008);
|
||||||
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098);
|
||||||
if (counter++ > 1000) {
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00);
|
||||||
nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001);
|
||||||
break;
|
|
||||||
}
|
|
||||||
mdelay(100);
|
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
|
|
||||||
temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
|
||||||
} while ((temp_phy_data2 == temp_phy_data));
|
|
||||||
|
|
||||||
/*
|
/* setup LEDs */
|
||||||
* wait for tracking to start to know
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007);
|
||||||
* f/w is good to go
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A);
|
||||||
*/
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009);
|
||||||
counter = 0;
|
|
||||||
do {
|
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
|
|
||||||
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
|
||||||
if (counter++ > 1000) {
|
|
||||||
nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mdelay(1000);
|
|
||||||
/*
|
|
||||||
* nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
|
|
||||||
* temp_phy_data);
|
|
||||||
*/
|
|
||||||
} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
|
|
||||||
|
|
||||||
/* set LOS Control invert RXLOSB_I_PADINV */
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528);
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
|
|
||||||
/* set LOS Control to mask of RXLOSB_I */
|
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
|
|
||||||
/* set LED1 to input mode (LED1 and LED2 share same LED) */
|
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
|
|
||||||
/* set LED2 to RX link_status and activity */
|
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
|
|
||||||
/* set LED3 to RX link_status */
|
|
||||||
nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
|
|
||||||
|
|
||||||
/*
|
/* Bring PHY out of reset */
|
||||||
* reset the res-calibration on t2
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002);
|
||||||
* serdes; ensures it is stable after
|
|
||||||
* the amcc phy is stable
|
|
||||||
*/
|
|
||||||
|
|
||||||
sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
|
/* Check for heartbeat */
|
||||||
sds_common_control0 |= 0x1;
|
counter = 0;
|
||||||
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
|
mdelay(690);
|
||||||
|
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
|
||||||
/* release the res-calibration reset */
|
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
sds_common_control0 &= 0xfffffffe;
|
do {
|
||||||
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
|
if (counter++ > 150) {
|
||||||
|
nes_debug(NES_DBG_PHY, "No PHY heartbeat\n");
|
||||||
i = 0;
|
break;
|
||||||
while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
|
|
||||||
&& (i++ < 5000)) {
|
|
||||||
/* mdelay(1); */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* wait for link train done before moving on,
|
|
||||||
* or will get an interupt storm
|
|
||||||
*/
|
|
||||||
counter = 0;
|
|
||||||
do {
|
|
||||||
temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
|
|
||||||
(0x200 * (nesdev->mac_index & 1)));
|
|
||||||
if (counter++ > 1000) {
|
|
||||||
nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mdelay(1);
|
|
||||||
} while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
|
|
||||||
}
|
}
|
||||||
}
|
mdelay(1);
|
||||||
|
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
|
||||||
|
temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
|
} while ((temp_phy_data2 == temp_phy_data));
|
||||||
|
|
||||||
|
/* wait for tracking */
|
||||||
|
counter = 0;
|
||||||
|
do {
|
||||||
|
nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
|
||||||
|
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
|
if (counter++ > 300) {
|
||||||
|
nes_debug(NES_DBG_PHY, "PHY did not track\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mdelay(10);
|
||||||
|
} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
|
||||||
|
|
||||||
|
/* setup signal integrity */
|
||||||
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);
|
||||||
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE);
|
||||||
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032);
|
||||||
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002);
|
||||||
|
nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063);
|
||||||
|
|
||||||
|
/* reset serdes */
|
||||||
|
sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
|
||||||
|
mac_index * 0x200);
|
||||||
|
sds |= 0x1;
|
||||||
|
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
|
||||||
|
mac_index * 0x200, sds);
|
||||||
|
sds &= 0xfffffffe;
|
||||||
|
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
|
||||||
|
mac_index * 0x200, sds);
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
|
||||||
|
&& (counter++ < 5000))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2483,19 +2439,18 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
|
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
|
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
|
||||||
/* check link status */
|
/* check link status */
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
|
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
|
||||||
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
u32temp = 100;
|
|
||||||
do {
|
|
||||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
|
|
||||||
|
|
||||||
phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
|
||||||
if ((phy_data == temp_phy_data) || (!(--u32temp)))
|
nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
break;
|
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
|
||||||
temp_phy_data = phy_data;
|
phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||||
} while (1);
|
|
||||||
|
phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
|
||||||
|
|
||||||
nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
|
nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
|
||||||
__func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
|
__func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NES_PHY_TYPE_PUMA_1G:
|
case NES_PHY_TYPE_PUMA_1G:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче