ethdev: RSS RETA configuration

Signed-off-by: Intel
This commit is contained in:
Intel 2013-06-03 00:00:00 +00:00 committed by Thomas Monjalon
parent a108ced364
commit 01a638e15d
6 changed files with 347 additions and 1 deletions

View File

@ -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,

View File

@ -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.
*/

View File

@ -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);

View File

@ -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

View File

@ -1416,6 +1416,78 @@ rte_eth_dev_priority_flow_ctrl_set(uint8_t port_id, struct rte_eth_pfc_conf *pfc
return (-ENOTSUP);
}
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)
{

View File

@ -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. */
@ -327,6 +330,18 @@ struct rte_eth_rss_conf {
#define ETH_VLAN_FILTER_MASK 0x0002 /**< VLAN Filter setting mask*/
#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
}