Skip to content

Commit 43a3d9b

Browse files
mawilli1Jeff Kirsher
authored andcommitted
i40evf: Allow PF driver to configure RSS
If the PF driver reports proper support, allow the PF driver to configure RSS on the behalf of the VF driver. This will allow for RSS support on future hardware without changes to the VF driver. Unfortunately, the old RSS code still needs to stay as the driver needs to be compatible with PF drivers that don't support this interface. But this change still simplifies the data structures a bunch and makes this code simpler to read and maintain. Change-ID: I0375aad40788ecdc0cb24d5cfeccf07804e69771 Signed-off-by: Mitch Williams <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent fed2db9 commit 43a3d9b

File tree

4 files changed

+294
-284
lines changed

4 files changed

+294
-284
lines changed

drivers/net/ethernet/intel/i40evf/i40evf.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ struct i40e_vsi {
6767
u16 rx_itr_setting;
6868
u16 tx_itr_setting;
6969
u16 qs_handle;
70-
u8 *rss_hkey_user; /* User configured hash keys */
71-
u8 *rss_lut_user; /* User configured lookup table entries */
7270
};
7371

7472
/* How many Rx Buffers do we bundle into one write to the hardware ? */
@@ -239,8 +237,13 @@ struct i40evf_adapter {
239237
#define I40EVF_FLAG_AQ_CONFIGURE_QUEUES BIT(6)
240238
#define I40EVF_FLAG_AQ_MAP_VECTORS BIT(7)
241239
#define I40EVF_FLAG_AQ_HANDLE_RESET BIT(8)
242-
#define I40EVF_FLAG_AQ_CONFIGURE_RSS BIT(9)
240+
#define I40EVF_FLAG_AQ_CONFIGURE_RSS BIT(9) /* direct AQ config */
243241
#define I40EVF_FLAG_AQ_GET_CONFIG BIT(10)
242+
/* Newer style, RSS done by the PF so we can ignore hardware vagaries. */
243+
#define I40EVF_FLAG_AQ_GET_HENA BIT(11)
244+
#define I40EVF_FLAG_AQ_SET_HENA BIT(12)
245+
#define I40EVF_FLAG_AQ_SET_RSS_KEY BIT(13)
246+
#define I40EVF_FLAG_AQ_SET_RSS_LUT BIT(14)
244247

245248
/* OS defined structs */
246249
struct net_device *netdev;
@@ -260,8 +263,14 @@ struct i40evf_adapter {
260263
(_a)->vf_res->vf_offload_flags & \
261264
I40E_VIRTCHNL_VF_OFFLOAD_IWARP : \
262265
0)
266+
/* RSS by the PF should be preferred over RSS via other methods. */
267+
#define RSS_PF(_a) ((_a)->vf_res->vf_offload_flags & \
268+
I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF)
263269
#define RSS_AQ(_a) ((_a)->vf_res->vf_offload_flags & \
264270
I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ)
271+
#define RSS_REG(_a) (!((_a)->vf_res->vf_offload_flags & \
272+
(I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ | \
273+
I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF)))
265274
#define VLAN_ALLOWED(_a) ((_a)->vf_res->vf_offload_flags & \
266275
I40E_VIRTCHNL_VF_OFFLOAD_VLAN)
267276
struct i40e_virtchnl_vf_resource *vf_res; /* incl. all VSIs */
@@ -273,6 +282,12 @@ struct i40evf_adapter {
273282
struct i40e_eth_stats current_stats;
274283
struct i40e_vsi vsi;
275284
u32 aq_wait_count;
285+
/* RSS stuff */
286+
u64 hena;
287+
u16 rss_key_size;
288+
u16 rss_lut_size;
289+
u8 *rss_key;
290+
u8 *rss_lut;
276291
};
277292

278293

@@ -316,11 +331,12 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter);
316331
void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags);
317332
void i40evf_request_stats(struct i40evf_adapter *adapter);
318333
void i40evf_request_reset(struct i40evf_adapter *adapter);
334+
void i40evf_get_hena(struct i40evf_adapter *adapter);
335+
void i40evf_set_hena(struct i40evf_adapter *adapter);
336+
void i40evf_set_rss_key(struct i40evf_adapter *adapter);
337+
void i40evf_set_rss_lut(struct i40evf_adapter *adapter);
319338
void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
320339
enum i40e_virtchnl_ops v_opcode,
321340
i40e_status v_retval, u8 *msg, u16 msglen);
322-
int i40evf_config_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut,
323-
u16 lut_size);
324-
int i40evf_get_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut,
325-
u16 lut_size);
341+
int i40evf_config_rss(struct i40evf_adapter *adapter);
326342
#endif /* _I40EVF_H_ */

drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -387,20 +387,16 @@ static int i40evf_set_coalesce(struct net_device *netdev,
387387
static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,
388388
struct ethtool_rxnfc *cmd)
389389
{
390-
struct i40e_hw *hw = &adapter->hw;
391-
u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
392-
((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
393-
394390
/* We always hash on IP src and dest addresses */
395391
cmd->data = RXH_IP_SRC | RXH_IP_DST;
396392

397393
switch (cmd->flow_type) {
398394
case TCP_V4_FLOW:
399-
if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
395+
if (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
400396
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
401397
break;
402398
case UDP_V4_FLOW:
403-
if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
399+
if (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
404400
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
405401
break;
406402

@@ -412,11 +408,11 @@ static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,
412408
break;
413409

414410
case TCP_V6_FLOW:
415-
if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
411+
if (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
416412
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
417413
break;
418414
case UDP_V6_FLOW:
419-
if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
415+
if (adapter->hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
420416
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
421417
break;
422418

@@ -476,9 +472,6 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
476472
struct i40e_hw *hw = &adapter->hw;
477473
u32 flags = adapter->vf_res->vf_offload_flags;
478474

479-
u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
480-
((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
481-
482475
/* RSS does not support anything other than hashing
483476
* to queues on src and dst IPs and ports
484477
*/
@@ -495,33 +488,36 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
495488
case TCP_V4_FLOW:
496489
if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
497490
if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
498-
hena |=
491+
adapter->hena |=
499492
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
500493

501-
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
494+
adapter->hena |=
495+
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
502496
} else {
503497
return -EINVAL;
504498
}
505499
break;
506500
case TCP_V6_FLOW:
507501
if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
508502
if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
509-
hena |=
503+
adapter->hena |=
510504
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
511505

512-
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
506+
adapter->hena |=
507+
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
513508
} else {
514509
return -EINVAL;
515510
}
516511
break;
517512
case UDP_V4_FLOW:
518513
if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
519514
if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
520-
hena |=
515+
adapter->hena |=
521516
BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
522517
BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
523518

524-
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
519+
adapter->hena |=
520+
(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
525521
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
526522
} else {
527523
return -EINVAL;
@@ -530,11 +526,12 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
530526
case UDP_V6_FLOW:
531527
if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
532528
if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
533-
hena |=
529+
adapter->hena |=
534530
BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
535531
BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
536532

537-
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
533+
adapter->hena |=
534+
(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
538535
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
539536
} else {
540537
return -EINVAL;
@@ -547,7 +544,7 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
547544
if ((nfc->data & RXH_L4_B_0_1) ||
548545
(nfc->data & RXH_L4_B_2_3))
549546
return -EINVAL;
550-
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
547+
adapter->hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
551548
break;
552549
case AH_ESP_V6_FLOW:
553550
case AH_V6_FLOW:
@@ -556,23 +553,27 @@ static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
556553
if ((nfc->data & RXH_L4_B_0_1) ||
557554
(nfc->data & RXH_L4_B_2_3))
558555
return -EINVAL;
559-
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
556+
adapter->hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
560557
break;
561558
case IPV4_FLOW:
562-
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
563-
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
559+
adapter->hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
560+
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
564561
break;
565562
case IPV6_FLOW:
566-
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
567-
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
563+
adapter->hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
564+
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
568565
break;
569566
default:
570567
return -EINVAL;
571568
}
572569

573-
wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
574-
wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
575-
i40e_flush(hw);
570+
if (RSS_PF(adapter)) {
571+
adapter->aq_required = I40EVF_FLAG_AQ_SET_HENA;
572+
} else {
573+
wr32(hw, I40E_VFQF_HENA(0), (u32)adapter->hena);
574+
wr32(hw, I40E_VFQF_HENA(1), (u32)(adapter->hena >> 32));
575+
i40e_flush(hw);
576+
}
576577

577578
return 0;
578579
}
@@ -623,6 +624,19 @@ static void i40evf_get_channels(struct net_device *netdev,
623624
ch->combined_count = adapter->num_active_queues;
624625
}
625626

627+
/**
628+
* i40evf_get_rxfh_key_size - get the RSS hash key size
629+
* @netdev: network interface device structure
630+
*
631+
* Returns the table size.
632+
**/
633+
static u32 i40evf_get_rxfh_key_size(struct net_device *netdev)
634+
{
635+
struct i40evf_adapter *adapter = netdev_priv(netdev);
636+
637+
return adapter->rss_key_size;
638+
}
639+
626640
/**
627641
* i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
628642
* @netdev: network interface device structure
@@ -631,7 +645,9 @@ static void i40evf_get_channels(struct net_device *netdev,
631645
**/
632646
static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
633647
{
634-
return (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
648+
struct i40evf_adapter *adapter = netdev_priv(netdev);
649+
650+
return adapter->rss_lut_size;
635651
}
636652

637653
/**
@@ -646,34 +662,20 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
646662
u8 *hfunc)
647663
{
648664
struct i40evf_adapter *adapter = netdev_priv(netdev);
649-
struct i40e_vsi *vsi = &adapter->vsi;
650-
u8 *seed = NULL, *lut;
651-
int ret;
652665
u16 i;
653666

654667
if (hfunc)
655668
*hfunc = ETH_RSS_HASH_TOP;
656669
if (!indir)
657670
return 0;
658671

659-
seed = key;
660-
661-
lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
662-
if (!lut)
663-
return -ENOMEM;
664-
665-
ret = i40evf_get_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
666-
if (ret)
667-
goto out;
672+
memcpy(key, adapter->rss_key, adapter->rss_key_size);
668673

669674
/* Each 32 bits pointed by 'indir' is stored with a lut entry */
670-
for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
671-
indir[i] = (u32)lut[i];
675+
for (i = 0; i < adapter->rss_lut_size; i++)
676+
indir[i] = (u32)adapter->rss_lut[i];
672677

673-
out:
674-
kfree(lut);
675-
676-
return ret;
678+
return 0;
677679
}
678680

679681
/**
@@ -689,8 +691,6 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
689691
const u8 *key, const u8 hfunc)
690692
{
691693
struct i40evf_adapter *adapter = netdev_priv(netdev);
692-
struct i40e_vsi *vsi = &adapter->vsi;
693-
u8 *seed = NULL;
694694
u16 i;
695695

696696
/* We do not allow change in unsupported parameters */
@@ -701,28 +701,14 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
701701
return 0;
702702

703703
if (key) {
704-
if (!vsi->rss_hkey_user) {
705-
vsi->rss_hkey_user = kzalloc(I40EVF_HKEY_ARRAY_SIZE,
706-
GFP_KERNEL);
707-
if (!vsi->rss_hkey_user)
708-
return -ENOMEM;
709-
}
710-
memcpy(vsi->rss_hkey_user, key, I40EVF_HKEY_ARRAY_SIZE);
711-
seed = vsi->rss_hkey_user;
712-
}
713-
if (!vsi->rss_lut_user) {
714-
vsi->rss_lut_user = kzalloc(I40EVF_HLUT_ARRAY_SIZE,
715-
GFP_KERNEL);
716-
if (!vsi->rss_lut_user)
717-
return -ENOMEM;
704+
memcpy(adapter->rss_key, key, adapter->rss_key_size);
718705
}
719706

720707
/* Each 32 bits pointed by 'indir' is stored with a lut entry */
721-
for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
722-
vsi->rss_lut_user[i] = (u8)(indir[i]);
708+
for (i = 0; i < adapter->rss_lut_size; i++)
709+
adapter->rss_lut[i] = (u8)(indir[i]);
723710

724-
return i40evf_config_rss(vsi, seed, vsi->rss_lut_user,
725-
I40EVF_HLUT_ARRAY_SIZE);
711+
return i40evf_config_rss(adapter);
726712
}
727713

728714
/**
@@ -794,6 +780,7 @@ static const struct ethtool_ops i40evf_ethtool_ops = {
794780
.get_rxfh = i40evf_get_rxfh,
795781
.set_rxfh = i40evf_set_rxfh,
796782
.get_channels = i40evf_get_channels,
783+
.get_rxfh_key_size = i40evf_get_rxfh_key_size,
797784
};
798785

799786
/**

0 commit comments

Comments
 (0)