summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIntel <intel.com>2013-06-03 00:00:00 +0000
committerThomas Monjalon <thomas.monjalon@6wind.com>2013-09-17 14:16:07 +0200
commit01a638e15d837da39f351e038570f3ed666c2ddc (patch)
tree30160bbe6c72e9bb9e20a006c845aa311cf80fc1
parenta108ced36401c5ff4d40c7ddf227eb004a0051ff (diff)
downloaddpdk-01a638e15d837da39f351e038570f3ed666c2ddc.zip
dpdk-01a638e15d837da39f351e038570f3ed666c2ddc.tar.gz
dpdk-01a638e15d837da39f351e038570f3ed666c2ddc.tar.xz
ethdev: RSS RETA configuration
Signed-off-by: Intel
-rw-r--r--app/test-pmd/cmdline.c181
-rw-r--r--app/test-pmd/config.c34
-rw-r--r--app/test-pmd/rxonly.c4
-rw-r--r--app/test-pmd/testpmd.h1
-rw-r--r--lib/librte_ether/rte_ethdev.c72
-rw-r--r--lib/librte_ether/rte_ethdev.h56
6 files changed, 347 insertions, 1 deletions
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f909597..9c1bda9 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -405,6 +405,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"port config all rss (ip|udp|none)\n"
" Set the RSS mode.\n\n"
+ "port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
+ " Set the RSS redirection table.\n\n"
+
"port config (port_id) dcb vt (on|off) (traffic_class)"
" pfc (on|off)\n"
" Set the DCB mode.\n\n"
@@ -1079,6 +1082,182 @@ cmdline_parse_inst_t cmd_config_rss = {
},
};
+/* *** Configure RSS RETA *** */
+struct cmd_config_rss_reta {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ uint8_t port_id;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t list_name;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static int
+parse_reta_config(const char *str, struct rte_eth_rss_reta *reta_conf)
+{
+ int i;
+ unsigned size;
+ uint8_t hash_index;
+ uint8_t nb_queue;
+ char s[256];
+ const char *p, *p0 = str;
+ char *end;
+ enum fieldnames {
+ FLD_HASH_INDEX = 0,
+ FLD_QUEUE,
+ _NUM_FLD
+ };
+ unsigned long int_fld[_NUM_FLD];
+ char *str_fld[_NUM_FLD];
+
+ while ((p = strchr(p0,'(')) != NULL) {
+ ++p;
+ if((p0 = strchr(p,')')) == NULL)
+ return -1;
+
+ size = p0 - p;
+ if(size >= sizeof(s))
+ return -1;
+
+ rte_snprintf(s, sizeof(s), "%.*s", size, p);
+ if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
+ return -1;
+ for (i = 0; i < _NUM_FLD; i++) {
+ errno = 0;
+ int_fld[i] = strtoul(str_fld[i], &end, 0);
+ if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+ return -1;
+ }
+
+ hash_index = (uint8_t)int_fld[FLD_HASH_INDEX];
+ nb_queue = (uint8_t)int_fld[FLD_QUEUE];
+
+ if (hash_index >= ETH_RSS_RETA_NUM_ENTRIES) {
+ printf("Invalid RETA hash index=%d",hash_index);
+ return -1;
+ }
+
+ if (hash_index < ETH_RSS_RETA_NUM_ENTRIES/2)
+ reta_conf->mask_lo |= (1ULL << hash_index);
+ else
+ reta_conf->mask_hi |= (1ULL << (hash_index - ETH_RSS_RETA_NUM_ENTRIES/2));
+
+ reta_conf->reta[hash_index] = nb_queue;
+ }
+
+ return 0;
+}
+
+static void
+cmd_set_rss_reta_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret;
+ struct rte_eth_rss_reta reta_conf;
+ struct cmd_config_rss_reta *res = parsed_result;
+
+ memset(&reta_conf,0,sizeof(struct rte_eth_rss_reta));
+ if (!strcmp(res->list_name, "reta")) {
+ if (parse_reta_config(res->list_of_items, &reta_conf)) {
+ printf("Invalid RSS Redirection Table config entered\n");
+ return;
+ }
+ ret = rte_eth_dev_rss_reta_update(res->port_id, &reta_conf);
+ if (ret != 0)
+ printf("Bad redirection table parameter, return code = %d \n",ret);
+ }
+}
+
+cmdline_parse_token_string_t cmd_config_rss_reta_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
+cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_reta_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
+cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
+cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
+ NULL);
+cmdline_parse_inst_t cmd_config_rss_reta = {
+ .f = cmd_set_rss_reta_parsed,
+ .data = NULL,
+ .help_str = "port config X rss reta (hash,queue)[,(hash,queue)]",
+ .tokens = {
+ (void *)&cmd_config_rss_reta_port,
+ (void *)&cmd_config_rss_reta_keyword,
+ (void *)&cmd_config_rss_reta_port_id,
+ (void *)&cmd_config_rss_reta_name,
+ (void *)&cmd_config_rss_reta_list_name,
+ (void *)&cmd_config_rss_reta_list_of_items,
+ NULL,
+ },
+};
+
+/* *** SHOW PORT INFO *** */
+struct cmd_showport_reta {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss;
+ cmdline_fixed_string_t reta;
+ uint64_t mask_lo;
+ uint64_t mask_hi;
+};
+
+static void cmd_showport_reta_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showport_reta *res = parsed_result;
+ struct rte_eth_rss_reta reta_conf;
+
+ if ((res->mask_lo == 0) && (res->mask_hi == 0)) {
+ printf("Invalid RSS Redirection Table config entered\n");
+ return;
+ }
+
+ reta_conf.mask_lo = res->mask_lo;
+ reta_conf.mask_hi = res->mask_hi;
+
+ port_rss_reta_info(res->port_id,&reta_conf);
+}
+
+cmdline_parse_token_string_t cmd_showport_reta_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, show, "show");
+cmdline_parse_token_string_t cmd_showport_reta_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, port, "port");
+cmdline_parse_token_num_t cmd_showport_reta_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, UINT8);
+cmdline_parse_token_string_t cmd_showport_reta_rss =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
+cmdline_parse_token_string_t cmd_showport_reta_reta =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
+cmdline_parse_token_num_t cmd_showport_reta_mask_lo =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta,mask_lo,UINT64);
+cmdline_parse_token_num_t cmd_showport_reta_mask_hi =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta,mask_hi,UINT64);
+
+cmdline_parse_inst_t cmd_showport_reta = {
+ .f = cmd_showport_reta_parsed,
+ .data = NULL,
+ .help_str = "show port X rss reta mask_lo mask_hi (X = port number)\n\
+ (mask_lo and mask_hi is UINT64)",
+ .tokens = {
+ (void *)&cmd_showport_reta_show,
+ (void *)&cmd_showport_reta_port,
+ (void *)&cmd_showport_reta_port_id,
+ (void *)&cmd_showport_reta_rss,
+ (void *)&cmd_showport_reta_reta,
+ (void *)&cmd_showport_reta_mask_lo,
+ (void *)&cmd_showport_reta_mask_hi,
+ NULL,
+ },
+};
+
/* *** Configure DCB *** */
struct cmd_config_dcb {
cmdline_fixed_string_t port;
@@ -3691,6 +3870,8 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_config_max_pkt_len,
(cmdline_parse_inst_t *)&cmd_config_rx_mode_flag,
(cmdline_parse_inst_t *)&cmd_config_rss,
+ (cmdline_parse_inst_t *)&cmd_config_rss_reta,
+ (cmdline_parse_inst_t *)&cmd_showport_reta,
(cmdline_parse_inst_t *)&cmd_config_burst,
(cmdline_parse_inst_t *)&cmd_config_thresh,
(cmdline_parse_inst_t *)&cmd_config_threshold,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 2d18212..aaf8b9e 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -640,6 +640,40 @@ rxtx_config_display(void)
tx_rs_thresh, txq_flags);
}
+void
+port_rss_reta_info(portid_t port_id,struct rte_eth_rss_reta *reta_conf)
+{
+ uint8_t i,j;
+ int ret;
+
+ if (port_id_is_invalid(port_id))
+ return;
+
+ ret = rte_eth_dev_rss_reta_query(port_id, reta_conf);
+ if (ret != 0) {
+ printf("Failed to get RSS RETA info, return code = %d\n", ret);
+ return;
+ }
+
+ if (reta_conf->mask_lo != 0) {
+ for (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {
+ if (reta_conf->mask_lo & (uint64_t)(1ULL << i))
+ printf("RSS RETA configuration: hash index=%d,"
+ "queue=%d\n",i,reta_conf->reta[i]);
+ }
+ }
+
+ if (reta_conf->mask_hi != 0) {
+ for (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {
+ if(reta_conf->mask_hi & (uint64_t)(1ULL << i)) {
+ j = (uint8_t)(i + ETH_RSS_RETA_NUM_ENTRIES/2);
+ printf("RSS RETA configuration: hash index=%d,"
+ "queue=%d\n",j,reta_conf->reta[j]);
+ }
+ }
+ }
+}
+
/*
* Setup forwarding configuration for each logical core.
*/
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index 8154c92..ed0c2db 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -158,8 +158,10 @@ pkt_burst_receive(struct fwd_stream *fs)
printf(" - type=0x%04x - length=%u - nb_segs=%d",
eth_type, (unsigned) mb->pkt.pkt_len,
(int)mb->pkt.nb_segs);
- if (ol_flags & PKT_RX_RSS_HASH)
+ if (ol_flags & PKT_RX_RSS_HASH) {
printf(" - RSS hash=0x%x", (unsigned) mb->pkt.hash.rss);
+ printf(" - RSS queue=0x%x",(unsigned) fs->rx_queue);
+ }
else if (ol_flags & PKT_RX_FDIR)
printf(" - FDIR hash=0x%x - FDIR id=0x%x ",
mb->pkt.hash.fdir.hash, mb->pkt.hash.fdir.id);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 0f05b2d..615a752 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -506,6 +506,7 @@ void fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id,
void fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id,
struct rte_fdir_filter *fdir_filter);
void fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks);
+void port_rss_reta_info(portid_t port_id, struct rte_eth_rss_reta *reta_conf);
/*
* Work-around of a compilation error with ICC on invocations of the
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 2fd8498..06fc251 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1417,6 +1417,78 @@ rte_eth_dev_priority_flow_ctrl_set(uint8_t port_id, struct rte_eth_pfc_conf *pfc
}
int
+rte_eth_dev_rss_reta_update(uint8_t port_id, struct rte_eth_rss_reta *reta_conf)
+{
+ struct rte_eth_dev *dev;
+ uint8_t i,j;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return (-ENODEV);
+ }
+
+ /* Invalid mask bit(s) setting */
+ if ((reta_conf->mask_lo == 0) && (reta_conf->mask_hi == 0)) {
+ PMD_DEBUG_TRACE("Invalid update mask bits for port=%d\n",port_id);
+ return (-EINVAL);
+ }
+
+ if (reta_conf->mask_lo != 0) {
+ for (i = 0; i < ETH_RSS_RETA_NUM_ENTRIES/2; i++) {
+ if ((reta_conf->mask_lo & (1ULL << i)) &&
+ (reta_conf->reta[i] >= ETH_RSS_RETA_MAX_QUEUE)) {
+ PMD_DEBUG_TRACE("RETA hash index output"
+ "configration for port=%d,invalid"
+ "queue=%d\n",port_id,reta_conf->reta[i]);
+
+ return (-EINVAL);
+ }
+ }
+ }
+
+ if (reta_conf->mask_hi != 0) {
+ for (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {
+ j = (uint8_t)(i + ETH_RSS_RETA_NUM_ENTRIES/2);
+
+ /* Check if the max entry >= 128 */
+ if ((reta_conf->mask_hi & (1ULL << i)) &&
+ (reta_conf->reta[j] >= ETH_RSS_RETA_MAX_QUEUE)) {
+ PMD_DEBUG_TRACE("RETA hash index output"
+ "configration for port=%d,invalid"
+ "queue=%d\n",port_id,reta_conf->reta[j]);
+
+ return (-EINVAL);
+ }
+ }
+ }
+
+ dev = &rte_eth_devices[port_id];
+
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP);
+ return (*dev->dev_ops->reta_update)(dev, reta_conf);
+}
+
+int
+rte_eth_dev_rss_reta_query(uint8_t port_id, struct rte_eth_rss_reta *reta_conf)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return (-ENODEV);
+ }
+
+ if((reta_conf->mask_lo == 0) && (reta_conf->mask_hi == 0)) {
+ PMD_DEBUG_TRACE("Invalid update mask bits for the port=%d\n",port_id);
+ return (-EINVAL);
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
+ return (*dev->dev_ops->reta_query)(dev, reta_conf);
+}
+
+int
rte_eth_led_on(uint8_t port_id)
{
struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 6c006d5..74b3a5b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -306,6 +306,9 @@ struct rte_eth_rss_conf {
#define ETH_RSS_IPV4_UDP 0x0040 /**< IPv4/UDP packet. */
#define ETH_RSS_IPV6_UDP 0x0080 /**< IPv6/UDP packet. */
#define ETH_RSS_IPV6_UDP_EX 0x0100 /**< IPv6/UDP with extension headers. */
+/* Definitions used for redirection table entry size */
+#define ETH_RSS_RETA_NUM_ENTRIES 128
+#define ETH_RSS_RETA_MAX_QUEUE 16
/* Definitions used for VMDQ and DCB functionality */
#define ETH_VMDQ_MAX_VLAN_FILTERS 64 /**< Maximum nb. of VMDQ vlan filters. */
@@ -328,6 +331,18 @@ struct rte_eth_rss_conf {
#define ETH_VLAN_EXTEND_MASK 0x0004 /**< VLAN Extend setting mask*/
/**
+ * A structure used to configure Redirection Table of the Receive Side
+ * Scaling (RSS) feature of an Ethernet port.
+ */
+struct rte_eth_rss_reta {
+ /** First 64 mask bits indicate which entry(s) need to updated/queried. */
+ uint64_t mask_lo;
+ /** Second 64 mask bits indicate which entry(s) need to updated/queried. */
+ uint64_t mask_hi;
+ uint8_t reta[ETH_RSS_RETA_NUM_ENTRIES]; /**< 128 RETA entries*/
+};
+
+/**
* This enum indicates the possible number of traffic classes
* in DCB configratioins
*/
@@ -813,6 +828,14 @@ typedef int (*priority_flow_ctrl_set_t)(struct rte_eth_dev *dev,
struct rte_eth_pfc_conf *pfc_conf);
/**< @internal Setup priority flow control parameter on an Ethernet device */
+typedef int (*reta_update_t)(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta *reta_conf);
+/**< @internal Update RSS redirection table on an Ethernet device */
+
+typedef int (*reta_query_t)(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta *reta_conf);
+/**< @internal Query RSS redirection table on an Ethernet device */
+
typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev);
/**< @internal Turn on SW controllable LED on an Ethernet device */
@@ -877,6 +900,10 @@ struct eth_dev_ops {
fdir_remove_perfect_filter_t fdir_remove_perfect_filter;
/** Setup masks for FDIR filtering. */
fdir_set_masks_t fdir_set_masks;
+ /** Update redirection table. */
+ reta_update_t reta_update;
+ /** Query redirection table. */
+ reta_query_t reta_query;
};
/**
@@ -2106,6 +2133,35 @@ int rte_eth_dev_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
*/
int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);
+/**
+ * Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param reta_conf
+ * RETA to update.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_eth_dev_rss_reta_update(uint8_t port,
+ struct rte_eth_rss_reta *reta_conf);
+
+ /**
+ * Query Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param reta_conf
+ * RETA to query.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_eth_dev_rss_reta_query(uint8_t port,
+ struct rte_eth_rss_reta *reta_conf);
#ifdef __cplusplus
}