i40evf: report link speed
authorMitch Williams <mitch.a.williams@intel.com>
Thu, 4 Aug 2016 18:37:02 +0000 (11:37 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 20 Aug 2016 04:22:47 +0000 (21:22 -0700)
The PF driver tells us the link speed, so do something with that
information. Add link speed to log messages, and report speed through
ethtool.

Change-Id: I279dc9540cc5203376406050a3e8d67e128d5882
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40evf/i40evf.h
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index 76ed97db28e2e883f51a7ca5fc9e225a31d8396f..6fa00f36bdc4e9956a85db20a7764764d21bf4c8 100644 (file)
@@ -258,6 +258,7 @@ struct i40evf_adapter {
        struct work_struct watchdog_task;
        bool netdev_registered;
        bool link_up;
+       enum i40e_aq_link_speed link_speed;
        enum i40e_virtchnl_ops current_op;
 #define CLIENT_ENABLED(_a) ((_a)->vf_res ? \
                            (_a)->vf_res->vf_offload_flags & \
index c9c202f6c52172a12dd1fe94d8b6c2acc0ebbcfa..e17a154562660745e5e8871079f2bd0d190f831f 100644 (file)
@@ -74,13 +74,33 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = {
 static int i40evf_get_settings(struct net_device *netdev,
                               struct ethtool_cmd *ecmd)
 {
-       /* In the future the VF will be able to query the PF for
-        * some information - for now use a dummy value
-        */
+       struct i40evf_adapter *adapter = netdev_priv(netdev);
+
        ecmd->supported = 0;
        ecmd->autoneg = AUTONEG_DISABLE;
        ecmd->transceiver = XCVR_DUMMY1;
        ecmd->port = PORT_NONE;
+       /* Set speed and duplex */
+       switch (adapter->link_speed) {
+       case I40E_LINK_SPEED_40GB:
+               ethtool_cmd_speed_set(ecmd, SPEED_40000);
+               break;
+       case I40E_LINK_SPEED_20GB:
+               ethtool_cmd_speed_set(ecmd, SPEED_20000);
+               break;
+       case I40E_LINK_SPEED_10GB:
+               ethtool_cmd_speed_set(ecmd, SPEED_10000);
+               break;
+       case I40E_LINK_SPEED_1GB:
+               ethtool_cmd_speed_set(ecmd, SPEED_1000);
+               break;
+       case I40E_LINK_SPEED_100MB:
+               ethtool_cmd_speed_set(ecmd, SPEED_100);
+               break;
+       default:
+               break;
+       }
+       ecmd->duplex = DUPLEX_FULL;
 
        return 0;
 }
index d76c221d4c8a3ab7f2e5fe386962842b91d8ae2c..cc6cb30c166723659cf390896f5b9bf45f5fdb0b 100644 (file)
@@ -816,6 +816,45 @@ void i40evf_set_rss_lut(struct i40evf_adapter *adapter)
        kfree(vrl);
 }
 
+/**
+ * i40evf_print_link_message - print link up or down
+ * @adapter: adapter structure
+ *
+ * Log a message telling the world of our wonderous link status
+ */
+static void i40evf_print_link_message(struct i40evf_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       char *speed = "Unknown ";
+
+       if (!adapter->link_up) {
+               netdev_info(netdev, "NIC Link is Down\n");
+               return;
+       }
+
+       switch (adapter->link_speed) {
+       case I40E_LINK_SPEED_40GB:
+               speed = "40 G";
+               break;
+       case I40E_LINK_SPEED_20GB:
+               speed = "20 G";
+               break;
+       case I40E_LINK_SPEED_10GB:
+               speed = "10 G";
+               break;
+       case I40E_LINK_SPEED_1GB:
+               speed = "1000 M";
+               break;
+       case I40E_LINK_SPEED_100MB:
+               speed = "100 M";
+               break;
+       default:
+               break;
+       }
+
+       netdev_info(netdev, "NIC Link is Up %sbps Full Duplex\n", speed);
+}
+
 /**
  * i40evf_request_reset
  * @adapter: adapter structure
@@ -853,15 +892,13 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
                        (struct i40e_virtchnl_pf_event *)msg;
                switch (vpe->event) {
                case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
-                       adapter->link_up =
-                               vpe->event_data.link_event.link_status;
-                       if (adapter->link_up && !netif_carrier_ok(netdev)) {
-                               dev_info(&adapter->pdev->dev, "NIC Link is Up\n");
-                               netif_carrier_on(netdev);
-                               netif_tx_wake_all_queues(netdev);
-                       } else if (!adapter->link_up) {
-                               dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
-                               netif_carrier_off(netdev);
+                       adapter->link_speed =
+                               vpe->event_data.link_event.link_speed;
+                       if (adapter->link_up !=
+                           vpe->event_data.link_event.link_status) {
+                               adapter->link_up =
+                                       vpe->event_data.link_event.link_status;
+                               i40evf_print_link_message(adapter);
                                netif_tx_stop_all_queues(netdev);
                        }
                        break;