+static inline void
+set_default_llq_configurations(struct ena_llq_configurations *llq_config,
+ struct ena_admin_feature_llq_desc *llq,
+ bool use_large_llq_hdr)
+{
+ llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER;
+ llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY;
+ llq_config->llq_num_decs_before_header =
+ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2;
+
+ if (use_large_llq_hdr &&
+ (llq->entry_size_ctrl_supported & ENA_ADMIN_LIST_ENTRY_SIZE_256B)) {
+ llq_config->llq_ring_entry_size =
+ ENA_ADMIN_LIST_ENTRY_SIZE_256B;
+ llq_config->llq_ring_entry_size_value = 256;
+ } else {
+ llq_config->llq_ring_entry_size =
+ ENA_ADMIN_LIST_ENTRY_SIZE_128B;
+ llq_config->llq_ring_entry_size_value = 128;
+ }
+}
+
+static int
+ena_set_queues_placement_policy(struct ena_adapter *adapter,
+ struct ena_com_dev *ena_dev,
+ struct ena_admin_feature_llq_desc *llq,
+ struct ena_llq_configurations *llq_default_configurations)
+{
+ int rc;
+ u32 llq_feature_mask;
+
+ llq_feature_mask = 1 << ENA_ADMIN_LLQ;
+ if (!(ena_dev->supported_features & llq_feature_mask)) {
+ PMD_DRV_LOG(INFO,
+ "LLQ is not supported. Fallback to host mode policy.\n");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ return 0;
+ }
+
+ rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations);
+ if (unlikely(rc)) {
+ PMD_INIT_LOG(WARNING, "Failed to config dev mode. "
+ "Fallback to host mode policy.");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ return 0;
+ }
+
+ /* Nothing to config, exit */
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
+ return 0;
+
+ if (!adapter->dev_mem_base) {
+ PMD_DRV_LOG(ERR, "Unable to access LLQ bar resource. "
+ "Fallback to host mode policy.\n.");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ return 0;
+ }
+
+ ena_dev->mem_bar = adapter->dev_mem_base;
+
+ return 0;
+}
+
+static uint32_t ena_calc_max_io_queue_num(struct ena_com_dev *ena_dev,
+ struct ena_com_dev_get_features_ctx *get_feat_ctx)
+{
+ uint32_t io_tx_sq_num, io_tx_cq_num, io_rx_num, max_num_io_queues;
+
+ /* Regular queues capabilities */
+ if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) {
+ struct ena_admin_queue_ext_feature_fields *max_queue_ext =
+ &get_feat_ctx->max_queue_ext.max_queue_ext;
+ io_rx_num = RTE_MIN(max_queue_ext->max_rx_sq_num,
+ max_queue_ext->max_rx_cq_num);
+ io_tx_sq_num = max_queue_ext->max_tx_sq_num;
+ io_tx_cq_num = max_queue_ext->max_tx_cq_num;
+ } else {
+ struct ena_admin_queue_feature_desc *max_queues =
+ &get_feat_ctx->max_queues;
+ io_tx_sq_num = max_queues->max_sq_num;
+ io_tx_cq_num = max_queues->max_cq_num;
+ io_rx_num = RTE_MIN(io_tx_sq_num, io_tx_cq_num);
+ }
+
+ /* In case of LLQ use the llq number in the get feature cmd */
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+ io_tx_sq_num = get_feat_ctx->llq.max_llq_num;
+
+ max_num_io_queues = RTE_MIN(ENA_MAX_NUM_IO_QUEUES, io_rx_num);
+ max_num_io_queues = RTE_MIN(max_num_io_queues, io_tx_sq_num);
+ max_num_io_queues = RTE_MIN(max_num_io_queues, io_tx_cq_num);
+
+ if (unlikely(max_num_io_queues == 0)) {
+ PMD_DRV_LOG(ERR, "Number of IO queues should not be 0\n");
+ return -EFAULT;
+ }
+
+ return max_num_io_queues;
+}
+