<commit_before>/* SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 2016-2018 Solarflare Communications Inc.
 * All rights reserved.
 *
 * This software was jointly developed between OKTET Labs (under contract
 * for Solarflare) and Solarflare Communications, Inc.
 */

#include <rte_dev.h>
#include <rte_ethdev_driver.h>
#include <rte_ethdev_pci.h>
#include <rte_pci.h>
#include <rte_bus_pci.h>
#include <rte_errno.h>

#include "efx.h"

#include "sfc.h"
#include "sfc_debug.h"
#include "sfc_log.h"
#include "sfc_kvargs.h"
#include "sfc_ev.h"
#include "sfc_rx.h"
#include "sfc_tx.h"
#include "sfc_flow.h"
#include "sfc_dp.h"
#include "sfc_dp_rx.h"

uint32_t sfc_logtype_driver;

static struct sfc_dp_list sfc_dp_head =
	TAILQ_HEAD_INITIALIZER(sfc_dp_head);

static int
sfc_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
{
	struct sfc_adapter *sa = dev->data->dev_private;
	efx_nic_fw_info_t enfi;
	int ret;
	int rc;

	/*
	 * Return value of the callback is likely supposed to be
	 * equal to or greater than 0, nevertheless, if an error
	 * occurs, it will be desirable to pass it to the caller
	 */
	if ((fw_version == NULL) || (fw_size == 0))
		return -EINVAL;

	rc = efx_nic_get_fw_version(sa->nic, &enfi);
	if (rc != 0)
		return -rc;

	ret = snprintf(fw_version, fw_size,
		       "%" PRIu16 ".%" PRIu16 ".%" PRIu16 ".%" PRIu16,
		       enfi.enfi_mc_fw_version[0], enfi.enfi_mc_fw_version[1],
		       enfi.enfi_mc_fw_version[2], enfi.enfi_mc_fw_version[3]);
	if (ret < 0)
		return ret;

	if (enfi.enfi_dpcpu_fw_ids_valid) {
		size_t dpcpu_fw_ids_offset = MIN(fw_size - 1, (size_t)ret);
		int ret_extra;

		ret_extra = snprintf(fw_version + dpcpu_fw_ids_offset,
				     fw_size - dpcpu_fw_ids_offset,
				     " rx%" PRIx16 " tx%" PRIx16,
				     enfi.enfi_rx_dpcpu_fw_id,
				     enfi.enfi_tx_dpcpu_fw_id);
		if (ret_extra < 0)
			return ret_extra;

		ret += ret_extra;
	}

	if (fw_size < (size_t)(++ret))
		return ret;
	else
		return 0;
}

static void
sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
	struct sfc_adapter *sa = dev->data->dev_private;
	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
	struct sfc_rss *rss = &sa->rss;
	uint64_t txq_offloads_def = 0;

	sfc_log_init(sa, "entry");

	dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;

	/* Autonegotiation may be disabled */
	dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_1000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_1G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_10000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_10G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_25000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_25G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_40000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_40G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_50000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_50G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_100000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_100G;

	dev_info->max_rx_queues = sa->rxq_max;
	dev_info->max_tx_queues = sa->txq_max;

	/* By default packets are dropped if no descriptors are available */
	dev_info->default_rxconf.rx_drop_en = 1;

	dev_info->rx_queue_offload_capa = sfc_rx_get_queue_offload_caps(sa);

	/*
	 * rx_offload_capa includes both device and queue offloads since
	 * the latter may be requested on a per device basis which makes
	 * sense when some offloads are needed to be set on all queues.
	 */
	dev_info->rx_offload_capa = sfc_rx_get_dev_offload_caps(sa) |
				    dev_info->rx_queue_offload_capa;

	dev_info->tx_queue_offload_capa = sfc_tx_get_queue_offload_caps(sa);

	/*
	 * tx_offload_capa includes both device and queue offloads since
	 * the latter may be requested on a per device basis which makes
	 * sense when some offloads are needed to be set on all queues.
	 */
	dev_info->tx_offload_capa = sfc_tx_get_dev_offload_caps(sa) |
				    dev_info->tx_queue_offload_capa;

	if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
		txq_offloads_def |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;

	dev_info->default_txconf.offloads |= txq_offloads_def;

	dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP;
	if ((~sa->dp_tx->features & SFC_DP_TX_FEAT_VLAN_INSERT) ||
	    !encp->enc_hw_tx_insert_vlan_enabled)
		dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOVLANOFFL;

	if (~sa->dp_tx->features & SFC_DP_TX_FEAT_MULTI_SEG)
		dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;

	if (~sa->dp_tx->features & SFC_DP_TX_FEAT_MULTI_POOL)
		dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOMULTMEMP;

	if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT)
		dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT;
<commit_msg>net/sfc: rely on ethdev mapping of Tx offloads to TxQ flags<commit_after>/* SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 2016-2018 Solarflare Communications Inc.
 * All rights reserved.
 *
 * This software was jointly developed between OKTET Labs (under contract
 * for Solarflare) and Solarflare Communications, Inc.
 */

#include <rte_dev.h>
#include <rte_ethdev_driver.h>
#include <rte_ethdev_pci.h>
#include <rte_pci.h>
#include <rte_bus_pci.h>
#include <rte_errno.h>

#include "efx.h"

#include "sfc.h"
#include "sfc_debug.h"
#include "sfc_log.h"
#include "sfc_kvargs.h"
#include "sfc_ev.h"
#include "sfc_rx.h"
#include "sfc_tx.h"
#include "sfc_flow.h"
#include "sfc_dp.h"
#include "sfc_dp_rx.h"

uint32_t sfc_logtype_driver;

static struct sfc_dp_list sfc_dp_head =
	TAILQ_HEAD_INITIALIZER(sfc_dp_head);

static int
sfc_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
{
	struct sfc_adapter *sa = dev->data->dev_private;
	efx_nic_fw_info_t enfi;
	int ret;
	int rc;

	/*
	 * Return value of the callback is likely supposed to be
	 * equal to or greater than 0, nevertheless, if an error
	 * occurs, it will be desirable to pass it to the caller
	 */
	if ((fw_version == NULL) || (fw_size == 0))
		return -EINVAL;

	rc = efx_nic_get_fw_version(sa->nic, &enfi);
	if (rc != 0)
		return -rc;

	ret = snprintf(fw_version, fw_size,
		       "%" PRIu16 ".%" PRIu16 ".%" PRIu16 ".%" PRIu16,
		       enfi.enfi_mc_fw_version[0], enfi.enfi_mc_fw_version[1],
		       enfi.enfi_mc_fw_version[2], enfi.enfi_mc_fw_version[3]);
	if (ret < 0)
		return ret;

	if (enfi.enfi_dpcpu_fw_ids_valid) {
		size_t dpcpu_fw_ids_offset = MIN(fw_size - 1, (size_t)ret);
		int ret_extra;

		ret_extra = snprintf(fw_version + dpcpu_fw_ids_offset,
				     fw_size - dpcpu_fw_ids_offset,
				     " rx%" PRIx16 " tx%" PRIx16,
				     enfi.enfi_rx_dpcpu_fw_id,
				     enfi.enfi_tx_dpcpu_fw_id);
		if (ret_extra < 0)
			return ret_extra;

		ret += ret_extra;
	}

	if (fw_size < (size_t)(++ret))
		return ret;
	else
		return 0;
}

static void
sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
	struct sfc_adapter *sa = dev->data->dev_private;
	struct sfc_rss *rss = &sa->rss;
	uint64_t txq_offloads_def = 0;

	sfc_log_init(sa, "entry");

	dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;

	/* Autonegotiation may be disabled */
	dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_1000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_1G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_10000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_10G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_25000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_25G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_40000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_40G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_50000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_50G;
	if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_100000FDX)
		dev_info->speed_capa |= ETH_LINK_SPEED_100G;

	dev_info->max_rx_queues = sa->rxq_max;
	dev_info->max_tx_queues = sa->txq_max;

	/* By default packets are dropped if no descriptors are available */
	dev_info->default_rxconf.rx_drop_en = 1;

	dev_info->rx_queue_offload_capa = sfc_rx_get_queue_offload_caps(sa);

	/*
	 * rx_offload_capa includes both device and queue offloads since
	 * the latter may be requested on a per device basis which makes
	 * sense when some offloads are needed to be set on all queues.
	 */
	dev_info->rx_offload_capa = sfc_rx_get_dev_offload_caps(sa) |
				    dev_info->rx_queue_offload_capa;

	dev_info->tx_queue_offload_capa = sfc_tx_get_queue_offload_caps(sa);

	/*
	 * tx_offload_capa includes both device and queue offloads since
	 * the latter may be requested on a per device basis which makes
	 * sense when some offloads are needed to be set on all queues.
	 */
	dev_info->tx_offload_capa = sfc_tx_get_dev_offload_caps(sa) |
				    dev_info->tx_queue_offload_capa;

	if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
		txq_offloads_def |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;

	dev_info->default_txconf.offloads |= txq_offloads_def;

{'fraction_non_alphanumeric': 0.10593125140417883, 'fraction_numerical': 0.01797348910357223, 'mean_word_length': 4.732775273663877, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2201275', 'n_tokens_mistral': 4049, 'n_tokens_neox': 3753, 'n_words': 719}