Skip to content

Commit 95af467

Browse files
atbrady-intelanguy11
authored andcommitted
idpf: configure resources for RX queues
Similar to the TX, RX also supports both single and split queue models. In single queue model, the same descriptor queue is used by SW to post buffer descriptors to HW and by HW to post completed descriptors to SW. In split queue model, "RX buffer queues" are used to pass descriptor buffers from SW to HW whereas "RX queues" are used to post the descriptor completions i.e. descriptors that point to completed buffers, from HW to SW. "RX queue group" is a set of RX queues grouped together and will be serviced by a "RX buffer queue group". IDPF supports 2 buffer queues i.e. large buffer (4KB) queue and small buffer (2KB) queue per buffer queue group. HW uses large buffers for 'hardware gro' feature and also if the packet size is more than 2KB, if not 2KB buffers are used. Add all the resources required for the RX queues initialization. Allocate memory for the RX queue and RX buffer queue groups. Initialize the software maintained refill queues for buffer management algorithm. Same like the TX queues, initialize the queue parameters for the RX queues and send the config RX queue virtchnl message to the device Control Plane. Signed-off-by: Alan Brady <[email protected]> Co-developed-by: Alice Michael <[email protected]> Signed-off-by: Alice Michael <[email protected]> Co-developed-by: Joshua Hay <[email protected]> Signed-off-by: Joshua Hay <[email protected]> Co-developed-by: Madhu Chittim <[email protected]> Signed-off-by: Madhu Chittim <[email protected]> Co-developed-by: Phani Burra <[email protected]> Signed-off-by: Phani Burra <[email protected]> Reviewed-by: Sridhar Samudrala <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Co-developed-by: Pavan Kumar Linga <[email protected]> Signed-off-by: Pavan Kumar Linga <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 1c325aa commit 95af467

File tree

8 files changed

+1705
-12
lines changed

8 files changed

+1705
-12
lines changed

drivers/net/ethernet/intel/idpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ idpf-y := \
1111
idpf_dev.o \
1212
idpf_lib.o \
1313
idpf_main.o \
14+
idpf_singleq_txrx.o \
1415
idpf_txrx.o \
1516
idpf_virtchnl.o \
1617
idpf_vf_dev.o

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,20 @@ struct idpf_dev_ops {
208208
STATE(IDPF_VC_DESTROY_VPORT_ERR) \
209209
STATE(IDPF_VC_CONFIG_TXQ) \
210210
STATE(IDPF_VC_CONFIG_TXQ_ERR) \
211+
STATE(IDPF_VC_CONFIG_RXQ) \
212+
STATE(IDPF_VC_CONFIG_RXQ_ERR) \
211213
STATE(IDPF_VC_ALLOC_VECTORS) \
212214
STATE(IDPF_VC_ALLOC_VECTORS_ERR) \
213215
STATE(IDPF_VC_DEALLOC_VECTORS) \
214216
STATE(IDPF_VC_DEALLOC_VECTORS_ERR) \
217+
STATE(IDPF_VC_GET_RSS_LUT) \
218+
STATE(IDPF_VC_GET_RSS_LUT_ERR) \
219+
STATE(IDPF_VC_SET_RSS_LUT) \
220+
STATE(IDPF_VC_SET_RSS_LUT_ERR) \
221+
STATE(IDPF_VC_GET_RSS_KEY) \
222+
STATE(IDPF_VC_GET_RSS_KEY_ERR) \
223+
STATE(IDPF_VC_SET_RSS_KEY) \
224+
STATE(IDPF_VC_SET_RSS_KEY_ERR) \
215225
STATE(IDPF_VC_ADD_MAC_ADDR) \
216226
STATE(IDPF_VC_ADD_MAC_ADDR_ERR) \
217227
STATE(IDPF_VC_DEL_MAC_ADDR) \
@@ -248,6 +258,8 @@ extern const char * const idpf_vport_vc_state_str[];
248258
* @bufq_desc_count: Buffer queue descriptor count
249259
* @bufq_size: Size of buffers in ring (e.g. 2K, 4K, etc)
250260
* @num_rxq_grp: Number of RX queues in a group
261+
* @rxq_grps: Total number of RX groups. Number of groups * number of RX per
262+
* group will yield total number of RX queues.
251263
* @rxq_model: Splitq queue or single queue queuing model
252264
* @rx_ptype_lkup: Lookup table for ptypes on RX
253265
* @adapter: back pointer to associated adapter
@@ -284,6 +296,7 @@ struct idpf_vport {
284296
u32 bufq_desc_count[IDPF_MAX_BUFQS_PER_RXQ_GRP];
285297
u32 bufq_size[IDPF_MAX_BUFQS_PER_RXQ_GRP];
286298
u16 num_rxq_grp;
299+
struct idpf_rxq_group *rxq_grps;
287300
u32 rxq_model;
288301
struct idpf_rx_ptype_decoded rx_ptype_lkup[IDPF_RX_MAX_PTYPE];
289302

@@ -307,9 +320,26 @@ struct idpf_vport {
307320
struct mutex vc_buf_lock;
308321
};
309322

323+
/**
324+
* struct idpf_rss_data - Associated RSS data
325+
* @rss_key_size: Size of RSS hash key
326+
* @rss_key: RSS hash key
327+
* @rss_lut_size: Size of RSS lookup table
328+
* @rss_lut: RSS lookup table
329+
* @cached_lut: Used to restore previously init RSS lut
330+
*/
331+
struct idpf_rss_data {
332+
u16 rss_key_size;
333+
u8 *rss_key;
334+
u16 rss_lut_size;
335+
u32 *rss_lut;
336+
u32 *cached_lut;
337+
};
338+
310339
/**
311340
* struct idpf_vport_user_config_data - User defined configuration values for
312341
* each vport.
342+
* @rss_data: See struct idpf_rss_data
313343
* @num_req_tx_qs: Number of user requested TX queues through ethtool
314344
* @num_req_rx_qs: Number of user requested RX queues through ethtool
315345
* @num_req_txq_desc: Number of user requested TX queue descriptors through
@@ -321,6 +351,7 @@ struct idpf_vport {
321351
* Used to restore configuration after a reset as the vport will get wiped.
322352
*/
323353
struct idpf_vport_user_config_data {
354+
struct idpf_rss_data rss_data;
324355
u16 num_req_tx_qs;
325356
u16 num_req_rx_qs;
326357
u32 num_req_txq_desc;
@@ -667,6 +698,19 @@ static inline struct idpf_vport *idpf_netdev_to_vport(struct net_device *netdev)
667698
return np->vport;
668699
}
669700

701+
/**
702+
* idpf_is_feature_ena - Determine if a particular feature is enabled
703+
* @vport: Vport to check
704+
* @feature: Netdev flag to check
705+
*
706+
* Returns true or false if a particular feature is enabled.
707+
*/
708+
static inline bool idpf_is_feature_ena(const struct idpf_vport *vport,
709+
netdev_features_t feature)
710+
{
711+
return vport->netdev->features & feature;
712+
}
713+
670714
/**
671715
* idpf_vport_ctrl_lock - Acquire the vport control lock
672716
* @netdev: Network interface device structure
@@ -706,6 +750,8 @@ int idpf_intr_req(struct idpf_adapter *adapter);
706750
void idpf_intr_rel(struct idpf_adapter *adapter);
707751
int idpf_send_destroy_vport_msg(struct idpf_vport *vport);
708752
int idpf_send_get_rx_ptype_msg(struct idpf_vport *vport);
753+
int idpf_send_get_set_rss_key_msg(struct idpf_vport *vport, bool get);
754+
int idpf_send_get_set_rss_lut_msg(struct idpf_vport *vport, bool get);
709755
int idpf_send_dealloc_vectors_msg(struct idpf_adapter *adapter);
710756
int idpf_send_alloc_vectors_msg(struct idpf_adapter *adapter, u16 num_vectors);
711757
void idpf_deinit_task(struct idpf_adapter *adapter);
@@ -727,7 +773,7 @@ void idpf_vport_init(struct idpf_vport *vport, struct idpf_vport_max_q *max_q);
727773
u32 idpf_get_vport_id(struct idpf_vport *vport);
728774
int idpf_vport_queue_ids_init(struct idpf_vport *vport);
729775
int idpf_queue_reg_init(struct idpf_vport *vport);
730-
int idpf_send_config_tx_queues_msg(struct idpf_vport *vport);
776+
int idpf_send_config_queues_msg(struct idpf_vport *vport);
731777
int idpf_send_create_vport_msg(struct idpf_adapter *adapter,
732778
struct idpf_vport_max_q *max_q);
733779
int idpf_check_supported_desc_ids(struct idpf_vport *vport);

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,58 @@
44
#ifndef _IDPF_LAN_TXRX_H_
55
#define _IDPF_LAN_TXRX_H_
66

7+
enum idpf_rss_hash {
8+
IDPF_HASH_INVALID = 0,
9+
/* Values 1 - 28 are reserved for future use */
10+
IDPF_HASH_NONF_UNICAST_IPV4_UDP = 29,
11+
IDPF_HASH_NONF_MULTICAST_IPV4_UDP,
12+
IDPF_HASH_NONF_IPV4_UDP,
13+
IDPF_HASH_NONF_IPV4_TCP_SYN_NO_ACK,
14+
IDPF_HASH_NONF_IPV4_TCP,
15+
IDPF_HASH_NONF_IPV4_SCTP,
16+
IDPF_HASH_NONF_IPV4_OTHER,
17+
IDPF_HASH_FRAG_IPV4,
18+
/* Values 37-38 are reserved */
19+
IDPF_HASH_NONF_UNICAST_IPV6_UDP = 39,
20+
IDPF_HASH_NONF_MULTICAST_IPV6_UDP,
21+
IDPF_HASH_NONF_IPV6_UDP,
22+
IDPF_HASH_NONF_IPV6_TCP_SYN_NO_ACK,
23+
IDPF_HASH_NONF_IPV6_TCP,
24+
IDPF_HASH_NONF_IPV6_SCTP,
25+
IDPF_HASH_NONF_IPV6_OTHER,
26+
IDPF_HASH_FRAG_IPV6,
27+
IDPF_HASH_NONF_RSVD47,
28+
IDPF_HASH_NONF_FCOE_OX,
29+
IDPF_HASH_NONF_FCOE_RX,
30+
IDPF_HASH_NONF_FCOE_OTHER,
31+
/* Values 51-62 are reserved */
32+
IDPF_HASH_L2_PAYLOAD = 63,
33+
34+
IDPF_HASH_MAX
35+
};
36+
37+
/* Supported RSS offloads */
38+
#define IDPF_DEFAULT_RSS_HASH \
39+
(BIT_ULL(IDPF_HASH_NONF_IPV4_UDP) | \
40+
BIT_ULL(IDPF_HASH_NONF_IPV4_SCTP) | \
41+
BIT_ULL(IDPF_HASH_NONF_IPV4_TCP) | \
42+
BIT_ULL(IDPF_HASH_NONF_IPV4_OTHER) | \
43+
BIT_ULL(IDPF_HASH_FRAG_IPV4) | \
44+
BIT_ULL(IDPF_HASH_NONF_IPV6_UDP) | \
45+
BIT_ULL(IDPF_HASH_NONF_IPV6_TCP) | \
46+
BIT_ULL(IDPF_HASH_NONF_IPV6_SCTP) | \
47+
BIT_ULL(IDPF_HASH_NONF_IPV6_OTHER) | \
48+
BIT_ULL(IDPF_HASH_FRAG_IPV6) | \
49+
BIT_ULL(IDPF_HASH_L2_PAYLOAD))
50+
51+
#define IDPF_DEFAULT_RSS_HASH_EXPANDED (IDPF_DEFAULT_RSS_HASH | \
52+
BIT_ULL(IDPF_HASH_NONF_IPV4_TCP_SYN_NO_ACK) | \
53+
BIT_ULL(IDPF_HASH_NONF_UNICAST_IPV4_UDP) | \
54+
BIT_ULL(IDPF_HASH_NONF_MULTICAST_IPV4_UDP) | \
55+
BIT_ULL(IDPF_HASH_NONF_IPV6_TCP_SYN_NO_ACK) | \
56+
BIT_ULL(IDPF_HASH_NONF_UNICAST_IPV6_UDP) | \
57+
BIT_ULL(IDPF_HASH_NONF_MULTICAST_IPV6_UDP))
58+
759
/* Transmit descriptors */
860
/* splitq tx buf, singleq tx buf and singleq compl desc */
961
struct idpf_base_tx_desc {

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,11 +668,16 @@ static void idpf_vport_rel(struct idpf_vport *vport)
668668
{
669669
struct idpf_adapter *adapter = vport->adapter;
670670
struct idpf_vport_config *vport_config;
671+
struct idpf_rss_data *rss_data;
671672
struct idpf_vport_max_q max_q;
672673
u16 idx = vport->idx;
673674
int i;
674675

675676
vport_config = adapter->vport_config[vport->idx];
677+
idpf_deinit_rss(vport);
678+
rss_data = &vport_config->user_config.rss_data;
679+
kfree(rss_data->rss_key);
680+
rss_data->rss_key = NULL;
676681

677682
idpf_send_destroy_vport_msg(vport);
678683

@@ -743,6 +748,7 @@ static void idpf_vport_dealloc(struct idpf_vport *vport)
743748
static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
744749
struct idpf_vport_max_q *max_q)
745750
{
751+
struct idpf_rss_data *rss_data;
746752
u16 idx = adapter->next_vport;
747753
struct idpf_vport *vport;
748754

@@ -773,6 +779,21 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
773779

774780
idpf_vport_init(vport, max_q);
775781

782+
/* This alloc is done separate from the LUT because it's not strictly
783+
* dependent on how many queues we have. If we change number of queues
784+
* and soft reset we'll need a new LUT but the key can remain the same
785+
* for as long as the vport exists.
786+
*/
787+
rss_data = &adapter->vport_config[idx]->user_config.rss_data;
788+
rss_data->rss_key = kzalloc(rss_data->rss_key_size, GFP_KERNEL);
789+
if (!rss_data->rss_key) {
790+
kfree(vport);
791+
792+
return NULL;
793+
}
794+
/* Initialize default rss key */
795+
netdev_rss_key_fill((void *)rss_data->rss_key, rss_data->rss_key_size);
796+
776797
/* fill vport slot in the adapter struct */
777798
adapter->vports[idx] = vport;
778799
adapter->vport_ids[idx] = idpf_get_vport_id(vport);
@@ -837,6 +858,7 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res)
837858
{
838859
struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
839860
struct idpf_adapter *adapter = vport->adapter;
861+
struct idpf_vport_config *vport_config;
840862
int err;
841863

842864
if (np->state != __IDPF_VPORT_DOWN)
@@ -865,20 +887,38 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res)
865887
goto intr_rel;
866888
}
867889

890+
err = idpf_rx_bufs_init_all(vport);
891+
if (err) {
892+
dev_err(&adapter->pdev->dev, "Failed to initialize RX buffers for vport %u: %d\n",
893+
vport->vport_id, err);
894+
goto intr_rel;
895+
}
896+
868897
err = idpf_queue_reg_init(vport);
869898
if (err) {
870899
dev_err(&adapter->pdev->dev, "Failed to initialize queue registers for vport %u: %d\n",
871900
vport->vport_id, err);
872901
goto intr_rel;
873902
}
874903

875-
err = idpf_send_config_tx_queues_msg(vport);
904+
err = idpf_send_config_queues_msg(vport);
876905
if (err) {
877906
dev_err(&adapter->pdev->dev, "Failed to configure queues for vport %u, %d\n",
878907
vport->vport_id, err);
879908
goto intr_rel;
880909
}
881910

911+
vport_config = adapter->vport_config[vport->idx];
912+
if (vport_config->user_config.rss_data.rss_lut)
913+
err = idpf_config_rss(vport);
914+
else
915+
err = idpf_init_rss(vport);
916+
if (err) {
917+
dev_err(&adapter->pdev->dev, "Failed to initialize RSS for vport %u: %d\n",
918+
vport->vport_id, err);
919+
goto intr_rel;
920+
}
921+
882922
return 0;
883923

884924
intr_rel:
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (C) 2023 Intel Corporation */
3+
4+
#include "idpf.h"
5+
6+
/**
7+
* idpf_rx_singleq_buf_hw_alloc_all - Replace used receive buffers
8+
* @rx_q: queue for which the hw buffers are allocated
9+
* @cleaned_count: number of buffers to replace
10+
*
11+
* Returns false if all allocations were successful, true if any fail
12+
*/
13+
bool idpf_rx_singleq_buf_hw_alloc_all(struct idpf_queue *rx_q,
14+
u16 cleaned_count)
15+
{
16+
struct virtchnl2_singleq_rx_buf_desc *desc;
17+
u16 nta = rx_q->next_to_alloc;
18+
struct idpf_rx_buf *buf;
19+
20+
if (!cleaned_count)
21+
return false;
22+
23+
desc = IDPF_SINGLEQ_RX_BUF_DESC(rx_q, nta);
24+
buf = &rx_q->rx_buf.buf[nta];
25+
26+
do {
27+
dma_addr_t addr;
28+
29+
addr = idpf_alloc_page(rx_q->pp, buf, rx_q->rx_buf_size);
30+
if (unlikely(addr == DMA_MAPPING_ERROR))
31+
break;
32+
33+
/* Refresh the desc even if buffer_addrs didn't change
34+
* because each write-back erases this info.
35+
*/
36+
desc->pkt_addr = cpu_to_le64(addr);
37+
desc->hdr_addr = 0;
38+
desc++;
39+
40+
buf++;
41+
nta++;
42+
if (unlikely(nta == rx_q->desc_count)) {
43+
desc = IDPF_SINGLEQ_RX_BUF_DESC(rx_q, 0);
44+
buf = rx_q->rx_buf.buf;
45+
nta = 0;
46+
}
47+
48+
cleaned_count--;
49+
} while (cleaned_count);
50+
51+
if (rx_q->next_to_alloc != nta) {
52+
idpf_rx_buf_hw_update(rx_q, nta);
53+
rx_q->next_to_alloc = nta;
54+
}
55+
56+
return !!cleaned_count;
57+
}

0 commit comments

Comments
 (0)