Skip to content

Commit 9b1aa3e

Browse files
michalQbkuba-moo
authored andcommitted
idpf: add get/set for Ethtool's header split ringparam
idpf supports the header split feature and that feature is always enabled by default. However, for flexibility reasons and to simplify some scenarios, it would be useful to have the support for switching the header split off (and on) from the userspace. Address that need by adding the user config parameter, the functions for disabling (or enabling) the header split feature, and calls to them from the Ethtool ringparam callbacks. It still is enabled by default if supported by the hardware. Reviewed-by: Przemek Kitszel <[email protected]> Signed-off-by: Michal Kubiak <[email protected]> Co-developed-by: Alexander Lobakin <[email protected]> Signed-off-by: Alexander Lobakin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 50d7371 commit 9b1aa3e

File tree

5 files changed

+90
-7
lines changed

5 files changed

+90
-7
lines changed

drivers/net/ethernet/intel/idpf/idpf.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct idpf_vport_max_q;
1515
#include <linux/pci.h>
1616
#include <linux/bitfield.h>
1717
#include <linux/sctp.h>
18-
#include <linux/ethtool.h>
18+
#include <linux/ethtool_netlink.h>
1919
#include <net/gro.h>
2020
#include <linux/dim.h>
2121

@@ -418,11 +418,13 @@ struct idpf_vport {
418418

419419
/**
420420
* enum idpf_user_flags
421+
* @__IDPF_USER_FLAG_HSPLIT: header split state
421422
* @__IDPF_PROMISC_UC: Unicast promiscuous mode
422423
* @__IDPF_PROMISC_MC: Multicast promiscuous mode
423424
* @__IDPF_USER_FLAGS_NBITS: Must be last
424425
*/
425426
enum idpf_user_flags {
427+
__IDPF_USER_FLAG_HSPLIT = 0U,
426428
__IDPF_PROMISC_UC = 32,
427429
__IDPF_PROMISC_MC,
428430

@@ -965,4 +967,7 @@ int idpf_send_map_unmap_queue_vector_msg(struct idpf_vport *vport, bool map);
965967
int idpf_send_set_sriov_vfs_msg(struct idpf_adapter *adapter, u16 num_vfs);
966968
int idpf_sriov_configure(struct pci_dev *pdev, int num_vfs);
967969

970+
u8 idpf_vport_get_hsplit(const struct idpf_vport *vport);
971+
bool idpf_vport_set_hsplit(const struct idpf_vport *vport, u8 val);
972+
968973
#endif /* !_IDPF_H_ */

drivers/net/ethernet/intel/idpf/idpf_ethtool.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ static void idpf_get_ringparam(struct net_device *netdev,
320320
ring->rx_pending = vport->rxq_desc_count;
321321
ring->tx_pending = vport->txq_desc_count;
322322

323+
kring->tcp_data_split = idpf_vport_get_hsplit(vport);
324+
323325
idpf_vport_ctrl_unlock(netdev);
324326
}
325327

@@ -379,6 +381,14 @@ static int idpf_set_ringparam(struct net_device *netdev,
379381
new_rx_count == vport->rxq_desc_count)
380382
goto unlock_mutex;
381383

384+
if (!idpf_vport_set_hsplit(vport, kring->tcp_data_split)) {
385+
NL_SET_ERR_MSG_MOD(ext_ack,
386+
"setting TCP data split is not supported");
387+
err = -EOPNOTSUPP;
388+
389+
goto unlock_mutex;
390+
}
391+
382392
config_data = &vport->adapter->vport_config[idx]->user_config;
383393
config_data->num_req_txq_desc = new_tx_count;
384394
config_data->num_req_rxq_desc = new_rx_count;
@@ -1334,6 +1344,7 @@ static int idpf_get_link_ksettings(struct net_device *netdev,
13341344
static const struct ethtool_ops idpf_ethtool_ops = {
13351345
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
13361346
ETHTOOL_COALESCE_USE_ADAPTIVE,
1347+
.supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT,
13371348
.get_msglevel = idpf_get_msglevel,
13381349
.set_msglevel = idpf_set_msglevel,
13391350
.get_link = ethtool_op_get_link,

drivers/net/ethernet/intel/idpf/idpf_lib.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,71 @@ static void idpf_vport_dealloc(struct idpf_vport *vport)
10571057
adapter->next_vport = idpf_get_free_slot(adapter);
10581058
}
10591059

1060+
/**
1061+
* idpf_is_hsplit_supported - check whether the header split is supported
1062+
* @vport: virtual port to check the capability for
1063+
*
1064+
* Return: true if it's supported by the HW/FW, false if not.
1065+
*/
1066+
static bool idpf_is_hsplit_supported(const struct idpf_vport *vport)
1067+
{
1068+
return idpf_is_queue_model_split(vport->rxq_model) &&
1069+
idpf_is_cap_ena_all(vport->adapter, IDPF_HSPLIT_CAPS,
1070+
IDPF_CAP_HSPLIT);
1071+
}
1072+
1073+
/**
1074+
* idpf_vport_get_hsplit - get the current header split feature state
1075+
* @vport: virtual port to query the state for
1076+
*
1077+
* Return: ``ETHTOOL_TCP_DATA_SPLIT_UNKNOWN`` if not supported,
1078+
* ``ETHTOOL_TCP_DATA_SPLIT_DISABLED`` if disabled,
1079+
* ``ETHTOOL_TCP_DATA_SPLIT_ENABLED`` if active.
1080+
*/
1081+
u8 idpf_vport_get_hsplit(const struct idpf_vport *vport)
1082+
{
1083+
const struct idpf_vport_user_config_data *config;
1084+
1085+
if (!idpf_is_hsplit_supported(vport))
1086+
return ETHTOOL_TCP_DATA_SPLIT_UNKNOWN;
1087+
1088+
config = &vport->adapter->vport_config[vport->idx]->user_config;
1089+
1090+
return test_bit(__IDPF_USER_FLAG_HSPLIT, config->user_flags) ?
1091+
ETHTOOL_TCP_DATA_SPLIT_ENABLED :
1092+
ETHTOOL_TCP_DATA_SPLIT_DISABLED;
1093+
}
1094+
1095+
/**
1096+
* idpf_vport_set_hsplit - enable or disable header split on a given vport
1097+
* @vport: virtual port to configure
1098+
* @val: Ethtool flag controlling the header split state
1099+
*
1100+
* Return: true on success, false if not supported by the HW.
1101+
*/
1102+
bool idpf_vport_set_hsplit(const struct idpf_vport *vport, u8 val)
1103+
{
1104+
struct idpf_vport_user_config_data *config;
1105+
1106+
if (!idpf_is_hsplit_supported(vport))
1107+
return val == ETHTOOL_TCP_DATA_SPLIT_UNKNOWN;
1108+
1109+
config = &vport->adapter->vport_config[vport->idx]->user_config;
1110+
1111+
switch (val) {
1112+
case ETHTOOL_TCP_DATA_SPLIT_UNKNOWN:
1113+
/* Default is to enable */
1114+
case ETHTOOL_TCP_DATA_SPLIT_ENABLED:
1115+
__set_bit(__IDPF_USER_FLAG_HSPLIT, config->user_flags);
1116+
return true;
1117+
case ETHTOOL_TCP_DATA_SPLIT_DISABLED:
1118+
__clear_bit(__IDPF_USER_FLAG_HSPLIT, config->user_flags);
1119+
return true;
1120+
default:
1121+
return false;
1122+
}
1123+
}
1124+
10601125
/**
10611126
* idpf_vport_alloc - Allocates the next available struct vport in the adapter
10621127
* @adapter: board private structure

drivers/net/ethernet/intel/idpf/idpf_txrx.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,12 +1240,15 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, u16 num_rxq)
12401240
struct idpf_adapter *adapter = vport->adapter;
12411241
struct idpf_queue *q;
12421242
int i, k, err = 0;
1243+
bool hs;
12431244

12441245
vport->rxq_grps = kcalloc(vport->num_rxq_grp,
12451246
sizeof(struct idpf_rxq_group), GFP_KERNEL);
12461247
if (!vport->rxq_grps)
12471248
return -ENOMEM;
12481249

1250+
hs = idpf_vport_get_hsplit(vport) == ETHTOOL_TCP_DATA_SPLIT_ENABLED;
1251+
12491252
for (i = 0; i < vport->num_rxq_grp; i++) {
12501253
struct idpf_rxq_group *rx_qgrp = &vport->rxq_grps[i];
12511254
int j;
@@ -1298,9 +1301,8 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, u16 num_rxq)
12981301
q->rx_buf_size = vport->bufq_size[j];
12991302
q->rx_buffer_low_watermark = IDPF_LOW_WATERMARK;
13001303
q->rx_buf_stride = IDPF_RX_BUF_STRIDE;
1301-
if (idpf_is_cap_ena_all(adapter, IDPF_HSPLIT_CAPS,
1302-
IDPF_CAP_HSPLIT) &&
1303-
idpf_is_queue_model_split(vport->rxq_model)) {
1304+
1305+
if (hs) {
13041306
q->rx_hsplit_en = true;
13051307
q->rx_hbuf_size = IDPF_HDR_BUF_SIZE;
13061308
}
@@ -1344,9 +1346,7 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, u16 num_rxq)
13441346
rx_qgrp->splitq.rxq_sets[j]->refillq1 =
13451347
&rx_qgrp->splitq.bufq_sets[1].refillqs[j];
13461348

1347-
if (idpf_is_cap_ena_all(adapter, IDPF_HSPLIT_CAPS,
1348-
IDPF_CAP_HSPLIT) &&
1349-
idpf_is_queue_model_split(vport->rxq_model)) {
1349+
if (hs) {
13501350
q->rx_hsplit_en = true;
13511351
q->rx_hbuf_size = IDPF_HDR_BUF_SIZE;
13521352
}

drivers/net/ethernet/intel/idpf/idpf_virtchnl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,8 @@ void idpf_vport_init(struct idpf_vport *vport, struct idpf_vport_max_q *max_q)
32853285
memcpy(vport->rx_itr_profile, rx_itr, IDPF_DIM_PROFILE_SLOTS);
32863286
memcpy(vport->tx_itr_profile, tx_itr, IDPF_DIM_PROFILE_SLOTS);
32873287

3288+
idpf_vport_set_hsplit(vport, ETHTOOL_TCP_DATA_SPLIT_ENABLED);
3289+
32883290
idpf_vport_init_num_qs(vport, vport_msg);
32893291
idpf_vport_calc_num_q_desc(vport);
32903292
idpf_vport_calc_num_q_groups(vport);

0 commit comments

Comments
 (0)