Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e1de5d6 authored by Eric Schneider's avatar Eric Schneider Committed by Roland Dreier
Browse files

RDMA/nes: Add support for SFP+ PHY



This patch enables the iw_nes module for NetEffect RNICs to support
additional PHYs including SFP+ (referred to as ARGUS in the code).

Signed-off-by: default avatarEric Schneider <eric.schneider@neteffect.com>
Signed-off-by: default avatarGlenn Streiff <gstreiff@neteffect.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 37dab411
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -536,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *);
int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *);
int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *);
void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16);
void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16);
void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *);
void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *);
void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16);
void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16);
void nes_read_10G_phy_reg(struct nes_device *, u16, u8);
void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16);
struct nes_cqp_request *nes_get_cqp_request(struct nes_device *);
struct nes_cqp_request *nes_get_cqp_request(struct nes_device *);
void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int);
void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int);
int nes_arp_table(struct nes_device *, u32, u8 *, u32);
int nes_arp_table(struct nes_device *, u32, u8 *, u32);
+202 −29
Original line number Original line Diff line number Diff line
@@ -1208,11 +1208,16 @@ 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 mac_index = nesdev->mac_index;
	u32 mac_index = nesdev->mac_index;
	u32 tx_config;
	u32 tx_config = 0;
	u16 phy_data;
	u16 phy_data;
	u32 temp_phy_data = 0;
	u32 temp_phy_data2 = 0;
	u32 i = 0;


	if (nesadapter->OneG_Mode) {
	if ((nesadapter->OneG_Mode) &&
	    (nesadapter->phy_type[mac_index] != 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 (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
			printk(PFX "%s: Programming mdc config for 1G\n", __func__);
			printk(PFX "%s: Programming mdc config for 1G\n", __func__);
@@ -1278,12 +1283,126 @@ int nes_init_phy(struct nes_device *nesdev)
		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_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, nesadapter->phy_index[mac_index], phy_data | 0x0300);
	} else {
	} else {
		if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) {
		if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
		    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
			/* setup 10G MDIO operation */
			/* setup 10G MDIO operation */
			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
			tx_config |= 0x14;
			tx_config |= 0x14;
			nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
			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);
			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 firmware is already running (like from a
			 * driver un-load/load, don't do anything.
			 */
			if (temp_phy_data == temp_phy_data2) {
				/* configure QT2505 AMCC PHY */
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
				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);
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000);
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);

				/*
				 * remove micro from reset; chip boots from ROM,
				 * uploads EEPROM f/w image, uC executes f/w
				 */
				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);

				/*
				 * wait for heart beat to start to
				 * know loading is done
				 */
				counter = 0;
				do {
					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);
					if (counter++ > 1000) {
						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
						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));

				/*
				 * wait for tracking to start to know
				 * f/w is good to go
				 */
				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, 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);

				/*
				 * reset the res-calibration on t2
				 * serdes; ensures it is stable after
				 * the amcc phy is stable
				 */

				sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
				sds_common_control0 |= 0x1;
				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);

				/* release the res-calibration reset */
				sds_common_control0 &= 0xfffffffe;
				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);

				i = 0;
				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));
			}
		}
	}
	}
	return 0;
	return 0;
}
}
@@ -2107,6 +2226,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
	u32 u32temp;
	u32 u32temp;
	u16 phy_data;
	u16 phy_data;
	u16 temp_phy_data;
	u16 temp_phy_data;
	u32 pcs_val  = 0x0f0f0000;
	u32 pcs_mask = 0x0f1f0000;


	spin_lock_irqsave(&nesadapter->phy_lock, flags);
	spin_lock_irqsave(&nesadapter->phy_lock, flags);
	if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
	if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
@@ -2170,13 +2291,30 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
		nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n",
		nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n",
				nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0),
				nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0),
				nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200));
				nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200));

		if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) {
			switch (mac_index) {
			case 1:
			case 3:
				pcs_control_status = nes_read_indexed(nesdev,
						NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
				break;
			default:
				pcs_control_status = nes_read_indexed(nesdev,
						NES_IDX_PHY_PCS_CONTROL_STATUS0);
				break;
			}
		} else {
			pcs_control_status = nes_read_indexed(nesdev,
			pcs_control_status = nes_read_indexed(nesdev,
					NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
					NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
			pcs_control_status = nes_read_indexed(nesdev,
			pcs_control_status = nes_read_indexed(nesdev,
					NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
					NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
		}

		nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n",
		nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n",
				mac_index, pcs_control_status);
				mac_index, pcs_control_status);
		if (nesadapter->OneG_Mode) {
		if ((nesadapter->OneG_Mode) &&
				(nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
			u32temp = 0x01010000;
			u32temp = 0x01010000;
			if (nesadapter->port_count > 2) {
			if (nesadapter->port_count > 2) {
				u32temp |= 0x02020000;
				u32temp |= 0x02020000;
@@ -2185,24 +2323,59 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
				phy_data = 0;
				phy_data = 0;
				nes_debug(NES_DBG_PHY, "PCS says the link is down\n");
				nes_debug(NES_DBG_PHY, "PCS says the link is down\n");
			}
			}
		} else if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) {
		} else {
			nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]);
			switch (nesadapter->phy_type[mac_index]) {
			temp_phy_data = (u16)nes_read_indexed(nesdev,
			case NES_PHY_TYPE_IRIS:
								NES_IDX_MAC_MDIO_CONTROL);
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
				temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
				u32temp = 20;
				u32temp = 20;
				do {
				do {
				nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]);
					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
				phy_data = (u16)nes_read_indexed(nesdev,
					phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
								NES_IDX_MAC_MDIO_CONTROL);
					if ((phy_data == temp_phy_data) || (!(--u32temp)))
						break;
					temp_phy_data = phy_data;
				} while (1);
				nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
					__func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
				break;

			case NES_PHY_TYPE_ARGUS:
				/* clear the alarms */
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002);
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005);
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006);
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
				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);
				/* check link status */
				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
				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);
					if ((phy_data == temp_phy_data) || (!(--u32temp)))
					if ((phy_data == temp_phy_data) || (!(--u32temp)))
						break;
						break;
					temp_phy_data = phy_data;
					temp_phy_data = phy_data;
				} while (1);
				} while (1);
				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 ? "DOWN" : "UP");
				break;


		} else {
			case NES_PHY_TYPE_PUMA_1G:
			phy_data = (0x0f0f0000 == (pcs_control_status & 0x0f1f0000)) ? 4 : 0;
				if (mac_index < 2)
					pcs_val = pcs_mask = 0x01010000;
				else
					pcs_val = pcs_mask = 0x02020000;
				/* fall through */
			default:
				phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0;
				break;
			}
		}
		}


		if (phy_data & 0x0004) {
		if (phy_data & 0x0004) {
@@ -2211,8 +2384,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
				nes_debug(NES_DBG_PHY, "The Link is UP!!.  linkup was %d\n",
				nes_debug(NES_DBG_PHY, "The Link is UP!!.  linkup was %d\n",
						nesvnic->linkup);
						nesvnic->linkup);
				if (nesvnic->linkup == 0) {
				if (nesvnic->linkup == 0) {
					printk(PFX "The Link is now up for port %u, netdev %p.\n",
					printk(PFX "The Link is now up for port %s, netdev %p.\n",
							mac_index, nesvnic->netdev);
							nesvnic->netdev->name, nesvnic->netdev);
					if (netif_queue_stopped(nesvnic->netdev))
					if (netif_queue_stopped(nesvnic->netdev))
						netif_start_queue(nesvnic->netdev);
						netif_start_queue(nesvnic->netdev);
					nesvnic->linkup = 1;
					nesvnic->linkup = 1;
@@ -2225,8 +2398,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
				nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
				nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
						nesvnic->linkup);
						nesvnic->linkup);
				if (nesvnic->linkup == 1) {
				if (nesvnic->linkup == 1) {
					printk(PFX "The Link is now down for port %u, netdev %p.\n",
					printk(PFX "The Link is now down for port %s, netdev %p.\n",
							mac_index, nesvnic->netdev);
							nesvnic->netdev->name, nesvnic->netdev);
					if (!(netif_queue_stopped(nesvnic->netdev)))
					if (!(netif_queue_stopped(nesvnic->netdev)))
						netif_stop_queue(nesvnic->netdev);
						netif_stop_queue(nesvnic->netdev);
					nesvnic->linkup = 0;
					nesvnic->linkup = 0;
+4 −2
Original line number Original line Diff line number Diff line
@@ -37,6 +37,8 @@


#define NES_PHY_TYPE_1G        2
#define NES_PHY_TYPE_1G        2
#define NES_PHY_TYPE_IRIS      3
#define NES_PHY_TYPE_IRIS      3
#define NES_PHY_TYPE_ARGUS     4
#define NES_PHY_TYPE_PUMA_1G   5
#define NES_PHY_TYPE_PUMA_10G  6
#define NES_PHY_TYPE_PUMA_10G  6


#define NES_MULTICAST_PF_MAX 8
#define NES_MULTICAST_PF_MAX 8
+48 −24
Original line number Original line Diff line number Diff line
@@ -1377,21 +1377,29 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd


	et_cmd->duplex = DUPLEX_FULL;
	et_cmd->duplex = DUPLEX_FULL;
	et_cmd->port = PORT_MII;
	et_cmd->port = PORT_MII;

	if (nesadapter->OneG_Mode) {
	if (nesadapter->OneG_Mode) {
		et_cmd->speed = SPEED_1000;
		if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
			et_cmd->supported   = SUPPORTED_1000baseT_Full;
			et_cmd->advertising = ADVERTISED_1000baseT_Full;
			et_cmd->autoneg     = AUTONEG_DISABLE;
			et_cmd->transceiver = XCVR_INTERNAL;
			et_cmd->phy_address = nesdev->mac_index;
		} else {
			et_cmd->supported   = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
			et_cmd->supported   = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
			et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
			et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
		et_cmd->speed = SPEED_1000;
			nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data);
		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
			if (phy_data & 0x1000)
				&phy_data);
		if (phy_data&0x1000) {
				et_cmd->autoneg = AUTONEG_ENABLE;
				et_cmd->autoneg = AUTONEG_ENABLE;
		} else {
			else
				et_cmd->autoneg = AUTONEG_DISABLE;
				et_cmd->autoneg = AUTONEG_DISABLE;
		}
			et_cmd->transceiver = XCVR_EXTERNAL;
			et_cmd->transceiver = XCVR_EXTERNAL;
			et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
			et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
		}
	} else {
	} else {
		if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) {
		if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) ||
		    (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) {
			et_cmd->transceiver = XCVR_EXTERNAL;
			et_cmd->transceiver = XCVR_EXTERNAL;
			et_cmd->port = PORT_FIBRE;
			et_cmd->port = PORT_FIBRE;
			et_cmd->supported = SUPPORTED_FIBRE;
			et_cmd->supported = SUPPORTED_FIBRE;
@@ -1422,7 +1430,8 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
	struct nes_adapter *nesadapter = nesdev->nesadapter;
	struct nes_adapter *nesadapter = nesdev->nesadapter;
	u16 phy_data;
	u16 phy_data;


	if (nesadapter->OneG_Mode) {
	if ((nesadapter->OneG_Mode) &&
	    (nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G)) {
		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
				&phy_data);
				&phy_data);
		if (et_cmd->autoneg) {
		if (et_cmd->autoneg) {
@@ -1615,27 +1624,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
	list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
	list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);


	if ((nesdev->netdev_count == 0) &&
	if ((nesdev->netdev_count == 0) &&
	    (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
	    ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) ||
		nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
	     ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) &&
				NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1)));
	      (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) ||
	       ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) {
		/*
		 * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
		 *		NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1)));
		 */
		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
				(0x200*(nesvnic->logical_port&1)));
				(0x200 * (nesdev->mac_index & 1)));
		if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) {
			u32temp |= 0x00200000;
			u32temp |= 0x00200000;
			nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
			nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
				(0x200*(nesvnic->logical_port&1)), u32temp);
				(0x200 * (nesdev->mac_index & 1)), u32temp);
		}

		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
				(0x200*(nesvnic->logical_port&1)) );
				(0x200 * (nesdev->mac_index & 1)));

		if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
		if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
			if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) {
			if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) {
				nes_init_phy(nesdev);
				nes_init_phy(nesdev);
				nes_read_10G_phy_reg(nesdev, 1,
				nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
						nesdev->nesadapter->phy_index[nesvnic->logical_port]);
				temp_phy_data = (u16)nes_read_indexed(nesdev,
				temp_phy_data = (u16)nes_read_indexed(nesdev,
									NES_IDX_MAC_MDIO_CONTROL);
									NES_IDX_MAC_MDIO_CONTROL);
				u32temp = 20;
				u32temp = 20;
				do {
				do {
					nes_read_10G_phy_reg(nesdev, 1,
					nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
							nesdev->nesadapter->phy_index[nesvnic->logical_port]);
					phy_data = (u16)nes_read_indexed(nesdev,
					phy_data = (u16)nes_read_indexed(nesdev,
									NES_IDX_MAC_MDIO_CONTROL);
									NES_IDX_MAC_MDIO_CONTROL);
					if ((phy_data == temp_phy_data) || (!(--u32temp)))
					if ((phy_data == temp_phy_data) || (!(--u32temp)))
@@ -1652,6 +1668,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
				nesvnic->linkup = 1;
				nesvnic->linkup = 1;
			}
			}
		} else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
			nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n",
				nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn));
			if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) ||
			    ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000)))  {
				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
				nesvnic->linkup = 1;
			}
		}
		}
		/* clear the MAC interrupt status, assumes direct logical to physical mapping */
		/* clear the MAC interrupt status, assumes direct logical to physical mapping */
		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
+3 −7
Original line number Original line Diff line number Diff line
@@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16
/**
/**
 * nes_write_10G_phy_reg
 * nes_write_10G_phy_reg
 */
 */
void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg,
void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_addr, u8 dev_addr, u16 phy_reg,
		u8 phy_addr, u16 data)
		u16 data)
{
{
	u32 dev_addr;
	u32 port_addr;
	u32 port_addr;
	u32 u32temp;
	u32 u32temp;
	u32 counter;
	u32 counter;


	dev_addr = 1;
	port_addr = phy_addr;
	port_addr = phy_addr;


	/* set address */
	/* set address */
@@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg,
 * This routine only issues the read, the data must be read
 * This routine only issues the read, the data must be read
 * separately.
 * separately.
 */
 */
void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr)
void nes_read_10G_phy_reg(struct nes_device *nesdev, u8 phy_addr, u8 dev_addr, u16 phy_reg)
{
{
	u32 dev_addr;
	u32 port_addr;
	u32 port_addr;
	u32 u32temp;
	u32 u32temp;
	u32 counter;
	u32 counter;


	dev_addr = 1;
	port_addr = phy_addr;
	port_addr = phy_addr;


	/* set address */
	/* set address */