{
clib_error_t *err;
avf_txq_t *txq;
+ u16 n;
u8 bpi = vlib_buffer_pool_get_default_for_numa (vm,
ad->numa_node);
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 *
/* 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;
}
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);
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)
{
/*
* 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;
/*
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;
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);
}