Commit 55ececab authored by Faizal Rahim's avatar Faizal Rahim Committed by Tony Nguyen
Browse files

igc: add support to set tx-min-frag-size



Add support for setting tx-min-frag-size via the set_mm callback in igc.
If the requested value is unsupported, round it up to the smallest
supported i226 size (64, 128, 192, 256) and send a netlink message to
inform the user.

Co-developed-by: default avatarVinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: default avatarVinicius Costa Gomes <vinicius.gomes@intel.com>
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarFaizal Rahim <faizal.abdul.rahim@linux.intel.com>
Tested-by: default avatarMor Bar-Gabay <morx.bar.gabay@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 5422570c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ void igc_ethtool_set_ops(struct net_device *);

struct igc_fpe_t {
	struct ethtool_mmsv mmsv;
	u32 tx_min_frag_size;
};

enum igc_mac_filter_type {
+1 −0
Original line number Diff line number Diff line
@@ -583,6 +583,7 @@
#define IGC_TQAVCTRL_PREEMPT_ENA	0x00000002
#define IGC_TQAVCTRL_ENHANCED_QAV	0x00000008
#define IGC_TQAVCTRL_FUTSCDDIS		0x00000080
#define IGC_TQAVCTRL_MIN_FRAG_MASK	0x0000C000

#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT	0x00000001
#define IGC_TXQCTL_STRICT_CYCLE		0x00000002
+5 −0
Original line number Diff line number Diff line
@@ -1789,6 +1789,11 @@ static int igc_ethtool_set_mm(struct net_device *netdev,
	struct igc_adapter *adapter = netdev_priv(netdev);
	struct igc_fpe_t *fpe = &adapter->fpe;

	fpe->tx_min_frag_size = igc_fpe_get_supported_frag_size(cmd->tx_min_frag_size);
	if (fpe->tx_min_frag_size != cmd->tx_min_frag_size)
		NL_SET_ERR_MSG_MOD(extack,
				   "tx-min-frag-size value set is unsupported. Rounded up to supported value (64, 128, 192, 256)");

	if (fpe->mmsv.pmac_enabled != cmd->pmac_enabled) {
		if (cmd->pmac_enabled)
			static_branch_inc(&igc_fpe_enabled);
+36 −3
Original line number Diff line number Diff line
@@ -6,6 +6,13 @@
#include "igc_hw.h"
#include "igc_tsn.h"

#define MIN_MULTPLIER_TX_MIN_FRAG	0
#define MAX_MULTPLIER_TX_MIN_FRAG	3
/* Frag size is based on the Section 8.12.2 of the SW User Manual */
#define TX_MIN_FRAG_SIZE		64
#define TX_MAX_FRAG_SIZE	(TX_MIN_FRAG_SIZE * \
				 (MAX_MULTPLIER_TX_MIN_FRAG + 1))

DEFINE_STATIC_KEY_FALSE(igc_fpe_enabled);

static int igc_fpe_init_smd_frame(struct igc_ring *ring,
@@ -128,6 +135,7 @@ static const struct ethtool_mmsv_ops igc_mmsv_ops = {

void igc_fpe_init(struct igc_adapter *adapter)
{
	adapter->fpe.tx_min_frag_size = TX_MIN_FRAG_SIZE;
	ethtool_mmsv_init(&adapter->fpe.mmsv, adapter->netdev, &igc_mmsv_ops);
}

@@ -299,7 +307,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)
	tqavctrl = rd32(IGC_TQAVCTRL);
	tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
		      IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS |
		      IGC_TQAVCTRL_PREEMPT_ENA);
		      IGC_TQAVCTRL_PREEMPT_ENA | IGC_TQAVCTRL_MIN_FRAG_MASK);

	wr32(IGC_TQAVCTRL, tqavctrl);

@@ -345,12 +353,35 @@ static void igc_tsn_set_retx_qbvfullthreshold(struct igc_adapter *adapter)
	wr32(IGC_RETX_CTL, retxctl);
}

static u8 igc_fpe_get_frag_size_mult(const struct igc_fpe_t *fpe)
{
	u8 mult = (fpe->tx_min_frag_size / TX_MIN_FRAG_SIZE) - 1;

	return clamp_t(u8, mult, MIN_MULTPLIER_TX_MIN_FRAG,
		       MAX_MULTPLIER_TX_MIN_FRAG);
}

u32 igc_fpe_get_supported_frag_size(u32 frag_size)
{
	const u32 supported_sizes[] = {64, 128, 192, 256};

	/* Find the smallest supported size that is >= frag_size */
	for (int i = 0; i < ARRAY_SIZE(supported_sizes); i++) {
		if (frag_size <= supported_sizes[i])
			return supported_sizes[i];
	}

	/* Should not happen */
	return TX_MAX_FRAG_SIZE;
}

static int igc_tsn_enable_offload(struct igc_adapter *adapter)
{
	struct igc_hw *hw = &adapter->hw;
	u32 tqavctrl, baset_l, baset_h;
	u32 sec, nsec, cycle;
	ktime_t base_time, systim;
	u32 frag_size_mult;
	int i;

	wr32(IGC_TSAUXC, 0);
@@ -519,13 +550,15 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
	}

	tqavctrl = rd32(IGC_TQAVCTRL) & ~(IGC_TQAVCTRL_FUTSCDDIS |
		   IGC_TQAVCTRL_PREEMPT_ENA);

		   IGC_TQAVCTRL_PREEMPT_ENA | IGC_TQAVCTRL_MIN_FRAG_MASK);
	tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;

	if (adapter->fpe.mmsv.pmac_enabled)
		tqavctrl |= IGC_TQAVCTRL_PREEMPT_ENA;

	frag_size_mult = igc_fpe_get_frag_size_mult(&adapter->fpe);
	tqavctrl |= FIELD_PREP(IGC_TQAVCTRL_MIN_FRAG_MASK, frag_size_mult);

	adapter->qbv_count++;

	cycle = adapter->cycle_time;
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ enum igc_txd_popts_type {
DECLARE_STATIC_KEY_FALSE(igc_fpe_enabled);

void igc_fpe_init(struct igc_adapter *adapter);
u32 igc_fpe_get_supported_frag_size(u32 frag_size);
int igc_tsn_offload_apply(struct igc_adapter *adapter);
int igc_tsn_reset(struct igc_adapter *adapter);
void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter);