Esempio n. 1
0
static void
be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
{
	struct be_adapter *adapter = netdev_priv(netdev);
	bool link_up;
	u8 mac_speed = 0;
	u16 qos_link_speed = 0;

	memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);

	if (test->flags & ETH_TEST_FL_OFFLINE) {
		if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
						&data[0]) != 0) {
			test->flags |= ETH_TEST_FL_FAILED;
		}
		if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
						&data[1]) != 0) {
			test->flags |= ETH_TEST_FL_FAILED;
		}
		if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
						&data[2]) != 0) {
			test->flags |= ETH_TEST_FL_FAILED;
		}
	}

	if (be_test_ddr_dma(adapter) != 0) {
		data[3] = 1;
		test->flags |= ETH_TEST_FL_FAILED;
	}

	if (be_cmd_link_status_query(adapter, &link_up, &mac_speed,
				&qos_link_speed) != 0) {
		test->flags |= ETH_TEST_FL_FAILED;
		data[4] = -1;
	} else if (mac_speed) {
		data[4] = 1;
	}
}
Esempio n. 2
0
static void be_link_status_update(struct be_adapter *adapter)
{
	struct be_link_info *prev = &adapter->link;
	struct be_link_info now = { 0 };
	struct net_device *netdev = adapter->netdev;

	be_cmd_link_status_query(&adapter->ctrl, &now);

	/* If link came up or went down */
	if (now.speed != prev->speed && (now.speed == PHY_LINK_SPEED_ZERO ||
			prev->speed == PHY_LINK_SPEED_ZERO)) {
		if (now.speed == PHY_LINK_SPEED_ZERO) {
			netif_stop_queue(netdev);
			netif_carrier_off(netdev);
			printk(KERN_INFO "%s: Link down\n", netdev->name);
		} else {
			netif_start_queue(netdev);
			netif_carrier_on(netdev);
			printk(KERN_INFO "%s: Link up\n", netdev->name);
		}
	}
	*prev = now;
}
Esempio n. 3
0
static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
	struct be_adapter *adapter = netdev_priv(netdev);
	struct be_dma_mem phy_cmd;
	struct be_cmd_resp_get_phy_info *resp;
	u8 mac_speed = 0;
	u16 link_speed = 0;
	bool link_up = false;
	int status;
	u16 intf_type;

	if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
		status = be_cmd_link_status_query(adapter, &link_up,
						&mac_speed, &link_speed);

		be_link_status_update(adapter, link_up);
		/* link_speed is in units of 10 Mbps */
		if (link_speed) {
			ecmd->speed = link_speed*10;
		} else {
			switch (mac_speed) {
			case PHY_LINK_SPEED_1GBPS:
				ecmd->speed = SPEED_1000;
				break;
			case PHY_LINK_SPEED_10GBPS:
				ecmd->speed = SPEED_10000;
				break;
			}
		}

		phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info);
		phy_cmd.va = pci_alloc_consistent(adapter->pdev, phy_cmd.size,
					&phy_cmd.dma);
		if (!phy_cmd.va) {
			dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
			return -ENOMEM;
		}
		status = be_cmd_get_phy_info(adapter, &phy_cmd);
		if (!status) {
			resp = (struct be_cmd_resp_get_phy_info *) phy_cmd.va;
			intf_type = le16_to_cpu(resp->interface_type);

			switch (intf_type) {
			case PHY_TYPE_XFP_10GB:
			case PHY_TYPE_SFP_1GB:
			case PHY_TYPE_SFP_PLUS_10GB:
				ecmd->port = PORT_FIBRE;
				break;
			default:
				ecmd->port = PORT_TP;
				break;
			}

			switch (intf_type) {
			case PHY_TYPE_KR_10GB:
			case PHY_TYPE_KX4_10GB:
				ecmd->autoneg = AUTONEG_ENABLE;
			ecmd->transceiver = XCVR_INTERNAL;
				break;
			default:
				ecmd->autoneg = AUTONEG_DISABLE;
				ecmd->transceiver = XCVR_EXTERNAL;
				break;
			}
		}

		/* Save for future use */
		adapter->link_speed = ecmd->speed;
		adapter->port_type = ecmd->port;
		adapter->transceiver = ecmd->transceiver;
		adapter->autoneg = ecmd->autoneg;
		pci_free_consistent(adapter->pdev, phy_cmd.size,
					phy_cmd.va, phy_cmd.dma);
	} else {
		ecmd->speed = adapter->link_speed;
		ecmd->port = adapter->port_type;
		ecmd->transceiver = adapter->transceiver;
		ecmd->autoneg = adapter->autoneg;
	}

	ecmd->duplex = DUPLEX_FULL;
	ecmd->phy_address = adapter->port_num;
	switch (ecmd->port) {
	case PORT_FIBRE:
		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
		break;
	case PORT_TP:
		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
		break;
	case PORT_AUI:
		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI);
		break;
	}

	if (ecmd->autoneg) {
		ecmd->supported |= SUPPORTED_1000baseT_Full;
		ecmd->supported |= SUPPORTED_Autoneg;
		ecmd->advertising |= (ADVERTISED_10000baseT_Full |
				ADVERTISED_1000baseT_Full);
	}

	return 0;
}
Esempio n. 4
0
static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
	struct be_adapter *adapter = netdev_priv(netdev);
	u8 mac_speed = 0, connector = 0;
	u16 link_speed = 0;
	bool link_up = false;
	int status;

	if (adapter->link_speed < 0) {
		status = be_cmd_link_status_query(adapter, &link_up,
						&mac_speed, &link_speed);

		/* link_speed is in units of 10 Mbps */
		if (link_speed) {
			ecmd->speed = link_speed*10;
		} else {
			switch (mac_speed) {
			case PHY_LINK_SPEED_1GBPS:
				ecmd->speed = SPEED_1000;
				break;
			case PHY_LINK_SPEED_10GBPS:
				ecmd->speed = SPEED_10000;
				break;
			}
		}

		status = be_cmd_read_port_type(adapter, adapter->port_num,
						&connector);
		if (!status) {
			switch (connector) {
			case 7:
				ecmd->port = PORT_FIBRE;
				ecmd->transceiver = XCVR_EXTERNAL;
				break;
			case 0:
				ecmd->port = PORT_TP;
				ecmd->transceiver = XCVR_EXTERNAL;
				break;
			default:
				ecmd->port = PORT_TP;
				ecmd->transceiver = XCVR_INTERNAL;
				break;
			}
		} else {
			ecmd->port = PORT_AUI;
			ecmd->transceiver = XCVR_INTERNAL;
		}

		/* Save for future use */
		adapter->link_speed = ecmd->speed;
		adapter->port_type = ecmd->port;
		adapter->transceiver = ecmd->transceiver;
	} else {
		ecmd->speed = adapter->link_speed;
		ecmd->port = adapter->port_type;
		ecmd->transceiver = adapter->transceiver;
	}

	ecmd->duplex = DUPLEX_FULL;
	ecmd->autoneg = AUTONEG_DISABLE;
	ecmd->phy_address = adapter->port_num;
	switch (ecmd->port) {
	case PORT_FIBRE:
		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
		break;
	case PORT_TP:
		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
		break;
	case PORT_AUI:
		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI);
		break;
	}

	return 0;
}