hsa: custom proto vfts for vcl tests
[vpp.git] / src / plugins / avf / device.c
index 78a211f..70ea446 100644 (file)
@@ -295,6 +295,7 @@ avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 txq_size)
 {
   clib_error_t *err;
   avf_txq_t *txq;
+  u16 n;
   u8 bpi = vlib_buffer_pool_get_default_for_numa (vm,
                                                  ad->numa_node);
 
@@ -313,11 +314,15 @@ avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 txq_size)
   txq->size = txq_size;
   txq->next = 0;
 
-  /* Prepare a placeholder buffer to maintain a 1-1
-     relationship between bufs and descs when a context
-     descriptor is added in descs */
-  if (!vlib_buffer_alloc_from_pool
-      (vm, &txq->ctx_desc_placeholder_bi, 1, bpi))
+  /* Prepare a placeholder buffer(s) to maintain a 1-1 relationship between
+   * bufs and descs when a context descriptor is added in descs. Worst case
+   * every second descriptor is context descriptor and due to b->ref_count
+   * being u8 we need one for each block of 510 descriptors */
+
+  n = (txq->size / 510) + 1;
+  vec_validate_aligned (txq->ph_bufs, n, CLIB_CACHE_LINE_BYTES);
+
+  if (!vlib_buffer_alloc_from_pool (vm, txq->ph_bufs, n, bpi))
     return clib_error_return (0, "buffer allocation error");
 
   txq->descs = vlib_physmem_alloc_aligned_on_numa (vm, txq->size *
@@ -336,6 +341,9 @@ avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 txq_size)
   /* initialize ring of pending RS slots */
   clib_ring_new_aligned (txq->rs_slots, 32, CLIB_CACHE_LINE_BYTES);
 
+  vec_validate_aligned (txq->tmp_descs, txq->size, CLIB_CACHE_LINE_BYTES);
+  vec_validate_aligned (txq->tmp_bufs, txq->size, CLIB_CACHE_LINE_BYTES);
+
   ad->n_tx_queues = clib_min (ad->num_queue_pairs, qid + 1);
   return 0;
 }
@@ -549,11 +557,11 @@ avf_op_get_vf_resources (vlib_main_t * vm, avf_device_t * ad,
                         virtchnl_vf_resource_t * res)
 {
   clib_error_t *err = 0;
-  u32 bitmap =
-    (VIRTCHNL_VF_OFFLOAD_L2 | VIRTCHNL_VF_OFFLOAD_RSS_PF |
-     VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_VLAN |
-     VIRTCHNL_VF_OFFLOAD_RX_POLLING | VIRTCHNL_VF_CAP_ADV_LINK_SPEED |
-     VIRTCHNL_VF_OFFLOAD_FDIR_PF | VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF);
+  u32 bitmap = (VIRTCHNL_VF_OFFLOAD_L2 | VIRTCHNL_VF_OFFLOAD_RSS_PF |
+               VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_VLAN |
+               VIRTCHNL_VF_OFFLOAD_RX_POLLING |
+               VIRTCHNL_VF_CAP_ADV_LINK_SPEED | VIRTCHNL_VF_OFFLOAD_FDIR_PF |
+               VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF | VIRTCHNL_VF_OFFLOAD_VLAN_V2);
 
   avf_log_debug (ad, "get_vf_resources: bitmap 0x%x (%U)", bitmap,
                 format_avf_vf_cap_flags, bitmap);
@@ -815,6 +823,39 @@ avf_op_get_stats (vlib_main_t * vm, avf_device_t * ad,
                         es, sizeof (virtchnl_eth_stats_t));
 }
 
+clib_error_t *
+avf_op_get_offload_vlan_v2_caps (vlib_main_t *vm, avf_device_t *ad,
+                                virtchnl_vlan_caps_t *vc)
+{
+  clib_error_t *err;
+
+  err = avf_send_to_pf (vm, ad, VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS, 0, 0, vc,
+                       sizeof (virtchnl_vlan_caps_t));
+
+  avf_log_debug (ad, "get_offload_vlan_v2_caps:\n%U%U", format_white_space, 16,
+                format_avf_vlan_caps, vc);
+
+  return err;
+}
+
+clib_error_t *
+avf_op_disable_vlan_stripping_v2 (vlib_main_t *vm, avf_device_t *ad, u32 outer,
+                                 u32 inner)
+{
+  virtchnl_vlan_setting_t vs = {
+    .outer_ethertype_setting = outer,
+    .inner_ethertype_setting = inner,
+    .vport_id = ad->vsi_id,
+  };
+
+  avf_log_debug (ad, "disable_vlan_stripping_v2: outer: %U, inner %U",
+                format_avf_vlan_support, outer, format_avf_vlan_support,
+                inner);
+
+  return avf_send_to_pf (vm, ad, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2, &vs,
+                        sizeof (virtchnl_vlan_setting_t), 0, 0);
+}
+
 clib_error_t *
 avf_device_reset (vlib_main_t * vm, avf_device_t * ad)
 {
@@ -960,7 +1001,23 @@ avf_device_init (vlib_main_t * vm, avf_main_t * am, avf_device_t * ad,
   /*
    * Disable VLAN stripping
    */
-  if ((error = avf_op_disable_vlan_stripping (vm, ad)))
+  if (ad->cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
+    {
+      virtchnl_vlan_caps_t vc = {};
+      u32 outer = VIRTCHNL_VLAN_UNSUPPORTED, inner = VIRTCHNL_VLAN_UNSUPPORTED;
+      u32 mask = VIRTCHNL_VLAN_ETHERTYPE_8100;
+
+      if ((error = avf_op_get_offload_vlan_v2_caps (vm, ad, &vc)))
+       return error;
+
+      outer = vc.offloads.stripping_support.outer & mask;
+      inner = vc.offloads.stripping_support.inner & mask;
+
+      if ((outer || inner) &&
+         (error = avf_op_disable_vlan_stripping_v2 (vm, ad, outer, inner)))
+       return error;
+    }
+  else if ((error = avf_op_disable_vlan_stripping (vm, ad)))
     return error;
 
   /*
@@ -1420,6 +1477,7 @@ avf_delete_if (vlib_main_t * vm, avf_device_t * ad, int with_barrier)
   vnet_main_t *vnm = vnet_get_main ();
   avf_main_t *am = &avf_main;
   int i;
+  u32 dev_instance;
 
   ad->flags &= ~AVF_DEVICE_F_ADMIN_UP;
 
@@ -1465,17 +1523,21 @@ avf_delete_if (vlib_main_t * vm, avf_device_t * ad, int with_barrier)
                                      txq->n_enqueued);
        }
       /* Free the placeholder buffer */
-      vlib_buffer_free_one(vm, txq->ctx_desc_placeholder_bi);
+      vlib_buffer_free (vm, txq->ph_bufs, vec_len (txq->ph_bufs));
+      vec_free (txq->ph_bufs);
       vec_free (txq->bufs);
       clib_ring_free (txq->rs_slots);
+      vec_free (txq->tmp_bufs);
+      vec_free (txq->tmp_descs);
     }
   /* *INDENT-ON* */
   vec_free (ad->txqs);
   vec_free (ad->name);
 
   clib_error_free (ad->error);
+  dev_instance = ad->dev_instance;
   clib_memset (ad, 0, sizeof (*ad));
-  pool_put_index (am->devices, ad->dev_instance);
+  pool_put_index (am->devices, dev_instance);
   clib_mem_free (ad);
 }