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; } }
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; }
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; }
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; }