Skip to content

Commit 319d9c2

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next
-queue Tony Nguyen says: ==================== Support rx-fcs on/off for VFs Ahmed Zaki says: Allow the user to turn on/off the CRC/FCS stripping through ethtool. We first add the CRC offload capability in the virtchannel, then the feature is enabled in ice and iavf drivers. We make sure that the netdev features are fixed such that CRC stripping cannot be disabled if VLAN rx offload (VLAN strip) is enabled. Also, VLAN stripping cannot be enabled unless CRC stripping is ON. Testing was done using tcpdump to make sure that the CRC is included in the frame after: # ethtool -K <interface> rx-fcs on and is not included when it is back "off". Also, ethtool should return an error for the above command if "rx-vlan-offload" is already on and at least one VLAN interface/filter exists on the VF. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fff755e + 7559d67 commit 319d9c2

File tree

6 files changed

+141
-7
lines changed

6 files changed

+141
-7
lines changed

drivers/net/ethernet/intel/iavf/iavf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ struct iavf_adapter {
406406
VIRTCHNL_VF_OFFLOAD_VLAN)
407407
#define VLAN_V2_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
408408
VIRTCHNL_VF_OFFLOAD_VLAN_V2)
409+
#define CRC_OFFLOAD_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
410+
VIRTCHNL_VF_OFFLOAD_CRC)
409411
#define VLAN_V2_FILTERING_ALLOWED(_a) \
410412
(VLAN_V2_ALLOWED((_a)) && \
411413
((_a)->vlan_v2_caps.filtering.filtering_support.outer || \

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4401,6 +4401,9 @@ static int iavf_set_features(struct net_device *netdev,
44014401
(features & NETIF_VLAN_OFFLOAD_FEATURES))
44024402
iavf_set_vlan_offload_features(adapter, netdev->features,
44034403
features);
4404+
if (CRC_OFFLOAD_ALLOWED(adapter) &&
4405+
((netdev->features & NETIF_F_RXFCS) ^ (features & NETIF_F_RXFCS)))
4406+
iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED);
44044407

44054408
return 0;
44064409
}
@@ -4522,6 +4525,9 @@ iavf_get_netdev_vlan_hw_features(struct iavf_adapter *adapter)
45224525
}
45234526
}
45244527

4528+
if (CRC_OFFLOAD_ALLOWED(adapter))
4529+
hw_features |= NETIF_F_RXFCS;
4530+
45254531
return hw_features;
45264532
}
45274533

@@ -4685,6 +4691,55 @@ iavf_fix_netdev_vlan_features(struct iavf_adapter *adapter,
46854691
return requested_features;
46864692
}
46874693

4694+
/**
4695+
* iavf_fix_strip_features - fix NETDEV CRC and VLAN strip features
4696+
* @adapter: board private structure
4697+
* @requested_features: stack requested NETDEV features
4698+
*
4699+
* Returns fixed-up features bits
4700+
**/
4701+
static netdev_features_t
4702+
iavf_fix_strip_features(struct iavf_adapter *adapter,
4703+
netdev_features_t requested_features)
4704+
{
4705+
struct net_device *netdev = adapter->netdev;
4706+
bool crc_offload_req, is_vlan_strip;
4707+
netdev_features_t vlan_strip;
4708+
int num_non_zero_vlan;
4709+
4710+
crc_offload_req = CRC_OFFLOAD_ALLOWED(adapter) &&
4711+
(requested_features & NETIF_F_RXFCS);
4712+
num_non_zero_vlan = iavf_get_num_vlans_added(adapter);
4713+
vlan_strip = (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX);
4714+
is_vlan_strip = requested_features & vlan_strip;
4715+
4716+
if (!crc_offload_req)
4717+
return requested_features;
4718+
4719+
if (!num_non_zero_vlan && (netdev->features & vlan_strip) &&
4720+
!(netdev->features & NETIF_F_RXFCS) && is_vlan_strip) {
4721+
requested_features &= ~vlan_strip;
4722+
netdev_info(netdev, "Disabling VLAN stripping as FCS/CRC stripping is also disabled and there is no VLAN configured\n");
4723+
return requested_features;
4724+
}
4725+
4726+
if ((netdev->features & NETIF_F_RXFCS) && is_vlan_strip) {
4727+
requested_features &= ~vlan_strip;
4728+
if (!(netdev->features & vlan_strip))
4729+
netdev_info(netdev, "To enable VLAN stripping, first need to enable FCS/CRC stripping");
4730+
4731+
return requested_features;
4732+
}
4733+
4734+
if (num_non_zero_vlan && is_vlan_strip &&
4735+
!(netdev->features & NETIF_F_RXFCS)) {
4736+
requested_features &= ~NETIF_F_RXFCS;
4737+
netdev_info(netdev, "To disable FCS/CRC stripping, first need to disable VLAN stripping");
4738+
}
4739+
4740+
return requested_features;
4741+
}
4742+
46884743
/**
46894744
* iavf_fix_features - fix up the netdev feature bits
46904745
* @netdev: our net device
@@ -4697,7 +4752,9 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev,
46974752
{
46984753
struct iavf_adapter *adapter = netdev_priv(netdev);
46994754

4700-
return iavf_fix_netdev_vlan_features(adapter, features);
4755+
features = iavf_fix_netdev_vlan_features(adapter, features);
4756+
4757+
return iavf_fix_strip_features(adapter, features);
47014758
}
47024759

47034760
static const struct net_device_ops iavf_netdev_ops = {

drivers/net/ethernet/intel/iavf/iavf_virtchnl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ int iavf_send_vf_config_msg(struct iavf_adapter *adapter)
142142
VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 |
143143
VIRTCHNL_VF_OFFLOAD_ENCAP |
144144
VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
145+
VIRTCHNL_VF_OFFLOAD_CRC |
145146
VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
146147
VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
147148
VIRTCHNL_VF_OFFLOAD_ADQ |
@@ -312,6 +313,9 @@ void iavf_configure_queues(struct iavf_adapter *adapter)
312313
vqpi->rxq.databuffer_size =
313314
ALIGN(adapter->rx_rings[i].rx_buf_len,
314315
BIT_ULL(IAVF_RXQ_CTX_DBUFF_SHIFT));
316+
if (CRC_OFFLOAD_ALLOWED(adapter))
317+
vqpi->rxq.crc_disable = !!(adapter->netdev->features &
318+
NETIF_F_RXFCS);
315319
vqpi++;
316320
}
317321

drivers/net/ethernet/intel/ice/ice_vf_lib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ struct ice_vf {
123123
u8 num_req_qs; /* num of queue pairs requested by VF */
124124
u16 num_mac;
125125
u16 num_vf_qs; /* num of queue configured per VF */
126+
u8 vlan_strip_ena; /* Outer and Inner VLAN strip enable */
127+
#define ICE_INNER_VLAN_STRIP_ENA BIT(0)
128+
#define ICE_OUTER_VLAN_STRIP_ENA BIT(1)
126129
struct ice_mdd_vf_events mdd_rx_events;
127130
struct ice_mdd_vf_events mdd_tx_events;
128131
DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);

drivers/net/ethernet/intel/ice/ice_virtchnl.c

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,9 @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
486486
if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)
487487
vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
488488

489+
if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC)
490+
vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_CRC;
491+
489492
if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
490493
vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
491494

@@ -1620,6 +1623,15 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
16201623
goto error_param;
16211624
}
16221625

1626+
for (i = 0; i < qci->num_queue_pairs; i++) {
1627+
if (!qci->qpair[i].rxq.crc_disable)
1628+
continue;
1629+
1630+
if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC) ||
1631+
vf->vlan_strip_ena)
1632+
goto error_param;
1633+
}
1634+
16231635
for (i = 0; i < qci->num_queue_pairs; i++) {
16241636
qpi = &qci->qpair[i];
16251637
if (qpi->txq.vsi_id != qci->vsi_id ||
@@ -1666,6 +1678,13 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
16661678
vsi->rx_rings[i]->dma = qpi->rxq.dma_ring_addr;
16671679
vsi->rx_rings[i]->count = qpi->rxq.ring_len;
16681680

1681+
if (qpi->rxq.crc_disable)
1682+
vsi->rx_rings[q_idx]->flags |=
1683+
ICE_RX_FLAGS_CRC_STRIP_DIS;
1684+
else
1685+
vsi->rx_rings[q_idx]->flags &=
1686+
~ICE_RX_FLAGS_CRC_STRIP_DIS;
1687+
16691688
if (qpi->rxq.databuffer_size != 0 &&
16701689
(qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
16711690
qpi->rxq.databuffer_size < 1024))
@@ -2410,6 +2429,21 @@ static int ice_vc_remove_vlan_msg(struct ice_vf *vf, u8 *msg)
24102429
return ice_vc_process_vlan_msg(vf, msg, false);
24112430
}
24122431

2432+
/**
2433+
* ice_vsi_is_rxq_crc_strip_dis - check if Rx queue CRC strip is disabled or not
2434+
* @vsi: pointer to the VF VSI info
2435+
*/
2436+
static bool ice_vsi_is_rxq_crc_strip_dis(struct ice_vsi *vsi)
2437+
{
2438+
unsigned int i;
2439+
2440+
ice_for_each_alloc_rxq(vsi, i)
2441+
if (vsi->rx_rings[i]->flags & ICE_RX_FLAGS_CRC_STRIP_DIS)
2442+
return true;
2443+
2444+
return false;
2445+
}
2446+
24132447
/**
24142448
* ice_vc_ena_vlan_stripping
24152449
* @vf: pointer to the VF info
@@ -2439,6 +2473,8 @@ static int ice_vc_ena_vlan_stripping(struct ice_vf *vf)
24392473

24402474
if (vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q))
24412475
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2476+
else
2477+
vf->vlan_strip_ena |= ICE_INNER_VLAN_STRIP_ENA;
24422478

24432479
error_param:
24442480
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING,
@@ -2474,6 +2510,8 @@ static int ice_vc_dis_vlan_stripping(struct ice_vf *vf)
24742510

24752511
if (vsi->inner_vlan_ops.dis_stripping(vsi))
24762512
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2513+
else
2514+
vf->vlan_strip_ena &= ~ICE_INNER_VLAN_STRIP_ENA;
24772515

24782516
error_param:
24792517
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING,
@@ -2649,6 +2687,8 @@ static int ice_vf_init_vlan_stripping(struct ice_vf *vf)
26492687
{
26502688
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
26512689

2690+
vf->vlan_strip_ena = 0;
2691+
26522692
if (!vsi)
26532693
return -EINVAL;
26542694

@@ -2658,10 +2698,16 @@ static int ice_vf_init_vlan_stripping(struct ice_vf *vf)
26582698
if (ice_vf_is_port_vlan_ena(vf) && !ice_is_dvm_ena(&vsi->back->hw))
26592699
return 0;
26602700

2661-
if (ice_vf_vlan_offload_ena(vf->driver_caps))
2662-
return vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q);
2663-
else
2664-
return vsi->inner_vlan_ops.dis_stripping(vsi);
2701+
if (ice_vf_vlan_offload_ena(vf->driver_caps)) {
2702+
int err;
2703+
2704+
err = vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q);
2705+
if (!err)
2706+
vf->vlan_strip_ena |= ICE_INNER_VLAN_STRIP_ENA;
2707+
return err;
2708+
}
2709+
2710+
return vsi->inner_vlan_ops.dis_stripping(vsi);
26652711
}
26662712

26672713
static u16 ice_vc_get_max_vlan_fltrs(struct ice_vf *vf)
@@ -3435,6 +3481,11 @@ static int ice_vc_ena_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg)
34353481
goto out;
34363482
}
34373483

3484+
if (ice_vsi_is_rxq_crc_strip_dis(vsi)) {
3485+
v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
3486+
goto out;
3487+
}
3488+
34383489
ethertype_setting = strip_msg->outer_ethertype_setting;
34393490
if (ethertype_setting) {
34403491
if (ice_vc_ena_vlan_offload(vsi,
@@ -3455,6 +3506,8 @@ static int ice_vc_ena_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg)
34553506
* enabled, is extracted in L2TAG1.
34563507
*/
34573508
ice_vsi_update_l2tsel(vsi, l2tsel);
3509+
3510+
vf->vlan_strip_ena |= ICE_OUTER_VLAN_STRIP_ENA;
34583511
}
34593512
}
34603513

@@ -3466,6 +3519,9 @@ static int ice_vc_ena_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg)
34663519
goto out;
34673520
}
34683521

3522+
if (ethertype_setting)
3523+
vf->vlan_strip_ena |= ICE_INNER_VLAN_STRIP_ENA;
3524+
34693525
out:
34703526
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2,
34713527
v_ret, NULL, 0);
@@ -3527,6 +3583,8 @@ static int ice_vc_dis_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg)
35273583
* in L2TAG1.
35283584
*/
35293585
ice_vsi_update_l2tsel(vsi, l2tsel);
3586+
3587+
vf->vlan_strip_ena &= ~ICE_OUTER_VLAN_STRIP_ENA;
35303588
}
35313589
}
35323590

@@ -3536,6 +3594,9 @@ static int ice_vc_dis_vlan_stripping_v2_msg(struct ice_vf *vf, u8 *msg)
35363594
goto out;
35373595
}
35383596

3597+
if (ethertype_setting)
3598+
vf->vlan_strip_ena &= ~ICE_INNER_VLAN_STRIP_ENA;
3599+
35393600
out:
35403601
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2,
35413602
v_ret, NULL, 0);

include/linux/avf/virtchnl.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
240240
#define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES BIT(6)
241241
/* used to negotiate communicating link speeds in Mbps */
242242
#define VIRTCHNL_VF_CAP_ADV_LINK_SPEED BIT(7)
243+
#define VIRTCHNL_VF_OFFLOAD_CRC BIT(10)
243244
#define VIRTCHNL_VF_OFFLOAD_VLAN_V2 BIT(15)
244245
#define VIRTCHNL_VF_OFFLOAD_VLAN BIT(16)
245246
#define VIRTCHNL_VF_OFFLOAD_RX_POLLING BIT(17)
@@ -295,7 +296,13 @@ VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);
295296
/* VIRTCHNL_OP_CONFIG_RX_QUEUE
296297
* VF sends this message to set up parameters for one RX queue.
297298
* External data buffer contains one instance of virtchnl_rxq_info.
298-
* PF configures requested queue and returns a status code.
299+
* PF configures requested queue and returns a status code. The
300+
* crc_disable flag disables CRC stripping on the VF. Setting
301+
* the crc_disable flag to 1 will disable CRC stripping for each
302+
* queue in the VF where the flag is set. The VIRTCHNL_VF_OFFLOAD_CRC
303+
* offload must have been set prior to sending this info or the PF
304+
* will ignore the request. This flag should be set the same for
305+
* all of the queues for a VF.
299306
*/
300307

301308
/* Rx queue config info */
@@ -307,7 +314,7 @@ struct virtchnl_rxq_info {
307314
u16 splithdr_enabled; /* deprecated with AVF 1.0 */
308315
u32 databuffer_size;
309316
u32 max_pkt_size;
310-
u8 pad0;
317+
u8 crc_disable;
311318
u8 rxdid;
312319
u8 pad1[2];
313320
u64 dma_ring_addr;

0 commit comments

Comments
 (0)