Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
[linux-2.6-microblaze.git] / drivers / net / ethernet / intel / iavf / iavf_virtchnl.c
index d58374c..ed08ace 100644 (file)
@@ -139,7 +139,8 @@ int iavf_send_vf_config_msg(struct iavf_adapter *adapter)
               VIRTCHNL_VF_OFFLOAD_ENCAP |
               VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
               VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
-              VIRTCHNL_VF_OFFLOAD_ADQ;
+              VIRTCHNL_VF_OFFLOAD_ADQ |
+              VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
 
        adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES;
        adapter->aq_required &= ~IAVF_FLAG_AQ_GET_CONFIG;
@@ -891,6 +892,8 @@ void iavf_disable_vlan_stripping(struct iavf_adapter *adapter)
        iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, NULL, 0);
 }
 
+#define IAVF_MAX_SPEED_STRLEN  13
+
 /**
  * iavf_print_link_message - print link up or down
  * @adapter: adapter structure
@@ -900,37 +903,105 @@ void iavf_disable_vlan_stripping(struct iavf_adapter *adapter)
 static void iavf_print_link_message(struct iavf_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       char *speed = "Unknown ";
+       int link_speed_mbps;
+       char *speed;
 
        if (!adapter->link_up) {
                netdev_info(netdev, "NIC Link is Down\n");
                return;
        }
 
+       speed = kcalloc(1, IAVF_MAX_SPEED_STRLEN, GFP_KERNEL);
+       if (!speed)
+               return;
+
+       if (ADV_LINK_SUPPORT(adapter)) {
+               link_speed_mbps = adapter->link_speed_mbps;
+               goto print_link_msg;
+       }
+
        switch (adapter->link_speed) {
-       case IAVF_LINK_SPEED_40GB:
-               speed = "40 G";
+       case VIRTCHNL_LINK_SPEED_40GB:
+               link_speed_mbps = SPEED_40000;
+               break;
+       case VIRTCHNL_LINK_SPEED_25GB:
+               link_speed_mbps = SPEED_25000;
+               break;
+       case VIRTCHNL_LINK_SPEED_20GB:
+               link_speed_mbps = SPEED_20000;
                break;
-       case IAVF_LINK_SPEED_25GB:
-               speed = "25 G";
+       case VIRTCHNL_LINK_SPEED_10GB:
+               link_speed_mbps = SPEED_10000;
                break;
-       case IAVF_LINK_SPEED_20GB:
-               speed = "20 G";
+       case VIRTCHNL_LINK_SPEED_5GB:
+               link_speed_mbps = SPEED_5000;
                break;
-       case IAVF_LINK_SPEED_10GB:
-               speed = "10 G";
+       case VIRTCHNL_LINK_SPEED_2_5GB:
+               link_speed_mbps = SPEED_2500;
                break;
-       case IAVF_LINK_SPEED_1GB:
-               speed = "1000 M";
+       case VIRTCHNL_LINK_SPEED_1GB:
+               link_speed_mbps = SPEED_1000;
                break;
-       case IAVF_LINK_SPEED_100MB:
-               speed = "100 M";
+       case VIRTCHNL_LINK_SPEED_100MB:
+               link_speed_mbps = SPEED_100;
                break;
        default:
+               link_speed_mbps = SPEED_UNKNOWN;
                break;
        }
 
-       netdev_info(netdev, "NIC Link is Up %sbps Full Duplex\n", speed);
+print_link_msg:
+       if (link_speed_mbps > SPEED_1000) {
+               if (link_speed_mbps == SPEED_2500)
+                       snprintf(speed, IAVF_MAX_SPEED_STRLEN, "2.5 Gbps");
+               else
+                       /* convert to Gbps inline */
+                       snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%d %s",
+                                link_speed_mbps / 1000, "Gbps");
+       } else if (link_speed_mbps == SPEED_UNKNOWN) {
+               snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%s", "Unknown Mbps");
+       } else {
+               snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%u %s",
+                        link_speed_mbps, "Mbps");
+       }
+
+       netdev_info(netdev, "NIC Link is Up Speed is %s Full Duplex\n", speed);
+       kfree(speed);
+}
+
+/**
+ * iavf_get_vpe_link_status
+ * @adapter: adapter structure
+ * @vpe: virtchnl_pf_event structure
+ *
+ * Helper function for determining the link status
+ **/
+static bool
+iavf_get_vpe_link_status(struct iavf_adapter *adapter,
+                        struct virtchnl_pf_event *vpe)
+{
+       if (ADV_LINK_SUPPORT(adapter))
+               return vpe->event_data.link_event_adv.link_status;
+       else
+               return vpe->event_data.link_event.link_status;
+}
+
+/**
+ * iavf_set_adapter_link_speed_from_vpe
+ * @adapter: adapter structure for which we are setting the link speed
+ * @vpe: virtchnl_pf_event structure that contains the link speed we are setting
+ *
+ * Helper function for setting iavf_adapter link speed
+ **/
+static void
+iavf_set_adapter_link_speed_from_vpe(struct iavf_adapter *adapter,
+                                    struct virtchnl_pf_event *vpe)
+{
+       if (ADV_LINK_SUPPORT(adapter))
+               adapter->link_speed_mbps =
+                       vpe->event_data.link_event_adv.link_speed;
+       else
+               adapter->link_speed = vpe->event_data.link_event.link_speed;
 }
 
 /**
@@ -1160,12 +1231,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
        if (v_opcode == VIRTCHNL_OP_EVENT) {
                struct virtchnl_pf_event *vpe =
                        (struct virtchnl_pf_event *)msg;
-               bool link_up = vpe->event_data.link_event.link_status;
+               bool link_up = iavf_get_vpe_link_status(adapter, vpe);
 
                switch (vpe->event) {
                case VIRTCHNL_EVENT_LINK_CHANGE:
-                       adapter->link_speed =
-                               vpe->event_data.link_event.link_speed;
+                       iavf_set_adapter_link_speed_from_vpe(adapter, vpe);
 
                        /* we've already got the right link status, bail */
                        if (adapter->link_up == link_up)