virtio: add virtio 1.1 api flags

Type: feature

Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Change-Id: I95d7fc1cc8db5199570c66535f45e867a7cae676
diff --git a/src/vnet/devices/virtio/pci.h b/src/vnet/devices/virtio/pci.h
index f9a5828..47c74ab 100644
--- a/src/vnet/devices/virtio/pci.h
+++ b/src/vnet/devices/virtio/pci.h
@@ -242,6 +242,20 @@
   void (*device_debug_config_space) (vlib_main_t * vm, virtio_if_t * vif);
 } virtio_pci_func_t;
 
+#define foreach_virtio_flags  \
+  _ (GSO, 0)                  \
+  _ (CSUM_OFFLOAD, 1)         \
+  _ (GRO_COALESCE, 2)         \
+  _ (PACKED, 3)               \
+  _ (IN_ORDER, 4)
+
+typedef enum
+{
+#define _(a, b) VIRTIO_FLAG_##a = (1 << b),
+  foreach_virtio_flags
+#undef _
+} virtio_flag_t;
+
 typedef struct
 {
   u32 addr;
@@ -253,6 +267,7 @@
   u64 features;
   u8 gso_enabled;
   u8 checksum_offload_enabled;
+  u32 virtio_flags;
   clib_error_t *error;
 } virtio_pci_create_if_args_t;
 
diff --git a/src/vnet/devices/virtio/virtio.api b/src/vnet/devices/virtio/virtio.api
index 34f00fa..143d25b 100644
--- a/src/vnet/devices/virtio/virtio.api
+++ b/src/vnet/devices/virtio/virtio.api
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-option version = "2.0.0";
+option version = "3.0.0";
 
 import "vnet/interface_types.api";
 import "vnet/ethernet/ethernet_types.api";
@@ -32,6 +32,7 @@
 */
 define virtio_pci_create
 {
+  option deprecated="21.01";
   u32 client_index;
   u32 context;
   vl_api_pci_address_t pci_addr;
@@ -49,6 +50,47 @@
 */
 define virtio_pci_create_reply
 {
+  option deprecated="21.01";
+  u32 context;
+  i32 retval;
+  vl_api_interface_index_t sw_if_index;
+};
+
+enum virtio_flags {
+        VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
+        VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
+        VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
+        VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
+        VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
+};
+
+/** \brief Initialize a new virtio pci interface with the given parameters
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param pci_addr - pci address
+    @param use_random_mac - let the system generate a unique mac address
+    @param mac_address - mac addr to assign to the interface if use_random not set
+    @param virtio_flags - feature flags to enable
+    @param features - the virtio features which driver should negotiate with device
+*/
+define virtio_pci_create_v2
+{
+  u32 client_index;
+  u32 context;
+  vl_api_pci_address_t pci_addr;
+  bool use_random_mac;
+  vl_api_mac_address_t mac_address;
+  vl_api_virtio_flags_t virtio_flags;
+  u64 features;
+};
+
+/** \brief Reply for virtio pci create reply
+    @param context - returned sender context, to match reply w/ request
+    @param retval - return code
+    @param sw_if_index - software index allocated for the new virtio pci interface
+*/
+define virtio_pci_create_v2_reply
+{
   u32 context;
   i32 retval;
   vl_api_interface_index_t sw_if_index;
diff --git a/src/vnet/devices/virtio/virtio_api.c b/src/vnet/devices/virtio/virtio_api.c
index 96ed927..9a145d9 100644
--- a/src/vnet/devices/virtio/virtio_api.c
+++ b/src/vnet/devices/virtio/virtio_api.c
@@ -47,9 +47,11 @@
 
 #define foreach_virtio_pci_api_msg                        \
 _(VIRTIO_PCI_CREATE, virtio_pci_create)                   \
+_(VIRTIO_PCI_CREATE_V2, virtio_pci_create_v2)             \
 _(VIRTIO_PCI_DELETE, virtio_pci_delete)                   \
 _(SW_INTERFACE_VIRTIO_PCI_DUMP, sw_interface_virtio_pci_dump)
 
+/* It will be deprecated in 21.01 */
 static void
 vl_api_virtio_pci_create_t_handler (vl_api_virtio_pci_create_t * mp)
 {
@@ -94,6 +96,65 @@
 }
 
 static void
+vl_api_virtio_pci_create_v2_t_handler (vl_api_virtio_pci_create_v2_t * mp)
+{
+  vlib_main_t *vm = vlib_get_main ();
+  vl_api_virtio_pci_create_v2_reply_t *rmp;
+  vl_api_registration_t *reg;
+  virtio_pci_create_if_args_t _a, *ap = &_a;
+
+  clib_memset (ap, 0, sizeof (*ap));
+
+  pci_address_decode (&mp->pci_addr, (vlib_pci_addr_t *) & ap->addr);
+  if (!mp->use_random_mac)
+    {
+      clib_memcpy (ap->mac_addr, mp->mac_address, 6);
+      ap->mac_addr_set = 1;
+    }
+  ap->sw_if_index = (u32) ~ 0;
+
+  STATIC_ASSERT (((int) VIRTIO_API_FLAG_GSO == (int) VIRTIO_FLAG_GSO),
+		 "virtio gso api flag mismatch");
+  STATIC_ASSERT (((int) VIRTIO_API_FLAG_CSUM_OFFLOAD ==
+		  (int) VIRTIO_FLAG_CSUM_OFFLOAD),
+		 "virtio checksum offload api flag mismatch");
+  STATIC_ASSERT (((int) VIRTIO_API_FLAG_GRO_COALESCE ==
+		  (int) VIRTIO_FLAG_GRO_COALESCE),
+		 "virtio gro coalesce api flag mismatch");
+  STATIC_ASSERT (((int) VIRTIO_API_FLAG_PACKED == (int) VIRTIO_FLAG_PACKED),
+		 "virtio packed api flag mismatch");
+  STATIC_ASSERT (((int) VIRTIO_API_FLAG_IN_ORDER ==
+		  (int) VIRTIO_FLAG_IN_ORDER),
+		 "virtio in-order api flag mismatch");
+
+  ap->virtio_flags = clib_net_to_host_u32 (mp->virtio_flags);
+  ap->features = clib_net_to_host_u64 (mp->features);
+
+  if (ap->virtio_flags & VIRTIO_FLAG_GSO)
+    ap->gso_enabled = 1;
+  else
+    ap->gso_enabled = 0;
+  if (ap->virtio_flags & VIRTIO_FLAG_CSUM_OFFLOAD)
+    ap->checksum_offload_enabled = 1;
+  else
+    ap->checksum_offload_enabled = 0;
+
+  virtio_pci_create_if (vm, ap);
+
+  reg = vl_api_client_index_to_registration (mp->client_index);
+  if (!reg)
+    return;;
+
+  rmp = vl_msg_api_alloc (sizeof (*rmp));
+  rmp->_vl_msg_id = htons (VL_API_VIRTIO_PCI_CREATE_V2_REPLY);
+  rmp->context = mp->context;
+  rmp->retval = htonl (ap->rv);
+  rmp->sw_if_index = htonl (ap->sw_if_index);
+
+  vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
 vl_api_virtio_pci_delete_t_handler (vl_api_virtio_pci_delete_t * mp)
 {
   vnet_main_t *vnm = vnet_get_main ();