Skip to content

Commit

Permalink
net: hns3: Add RSS general configuration support for VF
Browse files Browse the repository at this point in the history
This patch adds RSS key, hash algorithm configuration support
for VF in revision 0x21.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
IronShen authored and davem330 committed Oct 11, 2018
1 parent 775501a commit 374ad29
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 52 deletions.
3 changes: 2 additions & 1 deletion drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ struct hclgevf_query_res_cmd {
__le16 rsv[7];
};

#define HCLGEVF_RSS_HASH_KEY_OFFSET 4
#define HCLGEVF_RSS_DEFAULT_OUTPORT_B 4
#define HCLGEVF_RSS_HASH_KEY_OFFSET_B 4
#define HCLGEVF_RSS_HASH_KEY_NUM 16
struct hclgevf_rss_config_cmd {
u8 hash_config;
Expand Down
155 changes: 104 additions & 51 deletions drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,47 @@ static int hclgevf_get_vector_index(struct hclgevf_dev *hdev, int vector)
return -EINVAL;
}

static int hclgevf_set_rss_algo_key(struct hclgevf_dev *hdev,
const u8 hfunc, const u8 *key)
{
struct hclgevf_rss_config_cmd *req;
struct hclgevf_desc desc;
int key_offset;
int key_size;
int ret;

req = (struct hclgevf_rss_config_cmd *)desc.data;

for (key_offset = 0; key_offset < 3; key_offset++) {
hclgevf_cmd_setup_basic_desc(&desc,
HCLGEVF_OPC_RSS_GENERIC_CONFIG,
false);

req->hash_config |= (hfunc & HCLGEVF_RSS_HASH_ALGO_MASK);
req->hash_config |=
(key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET_B);

if (key_offset == 2)
key_size =
HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2;
else
key_size = HCLGEVF_RSS_HASH_KEY_NUM;

memcpy(req->hash_key,
key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, key_size);

ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"Configure RSS config fail, status = %d\n",
ret);
return ret;
}
}

return 0;
}

static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle)
{
return HCLGEVF_RSS_KEY_SIZE;
Expand Down Expand Up @@ -466,76 +507,77 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size)
return status;
}

static int hclgevf_get_rss_hw_cfg(struct hnae3_handle *handle, u8 *hash,
u8 *key)
static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
u8 *hfunc)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct hclgevf_rss_config_cmd *req;
int lkup_times = key ? 3 : 1;
struct hclgevf_desc desc;
int key_offset;
int key_size;
int status;

req = (struct hclgevf_rss_config_cmd *)desc.data;
lkup_times = (lkup_times == 3) ? 3 : ((hash) ? 1 : 0);

for (key_offset = 0; key_offset < lkup_times; key_offset++) {
hclgevf_cmd_setup_basic_desc(&desc,
HCLGEVF_OPC_RSS_GENERIC_CONFIG,
true);
req->hash_config |= (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET);
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
int i;

status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev,
"failed to get hardware RSS cfg, status = %d\n",
status);
return status;
if (handle->pdev->revision >= 0x21) {
/* Get hash algorithm */
if (hfunc) {
switch (rss_cfg->hash_algo) {
case HCLGEVF_RSS_HASH_ALGO_TOEPLITZ:
*hfunc = ETH_RSS_HASH_TOP;
break;
case HCLGEVF_RSS_HASH_ALGO_SIMPLE:
*hfunc = ETH_RSS_HASH_XOR;
break;
default:
*hfunc = ETH_RSS_HASH_UNKNOWN;
break;
}
}

if (key_offset == 2)
key_size =
HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2;
else
key_size = HCLGEVF_RSS_HASH_KEY_NUM;

/* Get the RSS Key required by the user */
if (key)
memcpy(key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM,
req->hash_key,
key_size);
memcpy(key, rss_cfg->rss_hash_key,
HCLGEVF_RSS_KEY_SIZE);
}

if (hash) {
if ((req->hash_config & 0xf) == HCLGEVF_RSS_HASH_ALGO_TOEPLITZ)
*hash = ETH_RSS_HASH_TOP;
else
*hash = ETH_RSS_HASH_UNKNOWN;
}

return 0;
}

static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
u8 *hfunc)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
int i;

if (indir)
for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
indir[i] = rss_cfg->rss_indirection_tbl[i];

return hclgevf_get_rss_hw_cfg(handle, hfunc, key);
return 0;
}

static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir,
const u8 *key, const u8 hfunc)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
int i;
int ret, i;

if (handle->pdev->revision >= 0x21) {
/* Set the RSS Hash Key if specififed by the user */
if (key) {
switch (hfunc) {
case ETH_RSS_HASH_TOP:
rss_cfg->hash_algo =
HCLGEVF_RSS_HASH_ALGO_TOEPLITZ;
break;
case ETH_RSS_HASH_XOR:
rss_cfg->hash_algo =
HCLGEVF_RSS_HASH_ALGO_SIMPLE;
break;
case ETH_RSS_HASH_NO_CHANGE:
break;
default:
return -EINVAL;
}

ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo,
key);
if (ret)
return ret;

/* Update the shadow RSS key with user specified qids */
memcpy(rss_cfg->rss_hash_key, key,
HCLGEVF_RSS_KEY_SIZE);
}
}

/* update the shadow RSS table with user specified qids */
for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
Expand Down Expand Up @@ -1276,6 +1318,17 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev)

rss_cfg->rss_size = hdev->rss_size_max;

if (hdev->pdev->revision >= 0x21) {
rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ;
netdev_rss_key_fill(rss_cfg->rss_hash_key,
HCLGEVF_RSS_KEY_SIZE);

ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo,
rss_cfg->rss_hash_key);
if (ret)
return ret;
}

/* Initialize RSS indirect table for each vport */
for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
rss_cfg->rss_indirection_tbl[i] = i % hdev->rss_size_max;
Expand Down

0 comments on commit 374ad29

Please sign in to comment.