aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJian Shen <shenjian15@huawei.com>2018-10-10 15:05:35 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-11 01:59:08 -0400
commit374ad291762a24b7ed3118129aca7fcfe4f1ba9d (patch)
treef8da56590c958144e2e8baac79e9391c53918d79
parent775501a1aabab99c5fd0864f42c7a48cdc521db7 (diff)
net: hns3: Add RSS general configuration support for VF
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>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h3
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c155
2 files changed, 106 insertions, 52 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
index 19b32860309c..eb8ed11d6964 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
@@ -148,7 +148,8 @@ struct hclgevf_query_res_cmd {
148 __le16 rsv[7]; 148 __le16 rsv[7];
149}; 149};
150 150
151#define HCLGEVF_RSS_HASH_KEY_OFFSET 4 151#define HCLGEVF_RSS_DEFAULT_OUTPORT_B 4
152#define HCLGEVF_RSS_HASH_KEY_OFFSET_B 4
152#define HCLGEVF_RSS_HASH_KEY_NUM 16 153#define HCLGEVF_RSS_HASH_KEY_NUM 16
153struct hclgevf_rss_config_cmd { 154struct hclgevf_rss_config_cmd {
154 u8 hash_config; 155 u8 hash_config;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index ca4a9f790917..f21196b675cb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -386,6 +386,47 @@ static int hclgevf_get_vector_index(struct hclgevf_dev *hdev, int vector)
386 return -EINVAL; 386 return -EINVAL;
387} 387}
388 388
389static int hclgevf_set_rss_algo_key(struct hclgevf_dev *hdev,
390 const u8 hfunc, const u8 *key)
391{
392 struct hclgevf_rss_config_cmd *req;
393 struct hclgevf_desc desc;
394 int key_offset;
395 int key_size;
396 int ret;
397
398 req = (struct hclgevf_rss_config_cmd *)desc.data;
399
400 for (key_offset = 0; key_offset < 3; key_offset++) {
401 hclgevf_cmd_setup_basic_desc(&desc,
402 HCLGEVF_OPC_RSS_GENERIC_CONFIG,
403 false);
404
405 req->hash_config |= (hfunc & HCLGEVF_RSS_HASH_ALGO_MASK);
406 req->hash_config |=
407 (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET_B);
408
409 if (key_offset == 2)
410 key_size =
411 HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2;
412 else
413 key_size = HCLGEVF_RSS_HASH_KEY_NUM;
414
415 memcpy(req->hash_key,
416 key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, key_size);
417
418 ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
419 if (ret) {
420 dev_err(&hdev->pdev->dev,
421 "Configure RSS config fail, status = %d\n",
422 ret);
423 return ret;
424 }
425 }
426
427 return 0;
428}
429
389static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle) 430static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle)
390{ 431{
391 return HCLGEVF_RSS_KEY_SIZE; 432 return HCLGEVF_RSS_KEY_SIZE;
@@ -466,68 +507,40 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size)
466 return status; 507 return status;
467} 508}
468 509
469static int hclgevf_get_rss_hw_cfg(struct hnae3_handle *handle, u8 *hash, 510static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
470 u8 *key) 511 u8 *hfunc)
471{ 512{
472 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 513 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
473 struct hclgevf_rss_config_cmd *req; 514 struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
474 int lkup_times = key ? 3 : 1; 515 int i;
475 struct hclgevf_desc desc;
476 int key_offset;
477 int key_size;
478 int status;
479
480 req = (struct hclgevf_rss_config_cmd *)desc.data;
481 lkup_times = (lkup_times == 3) ? 3 : ((hash) ? 1 : 0);
482
483 for (key_offset = 0; key_offset < lkup_times; key_offset++) {
484 hclgevf_cmd_setup_basic_desc(&desc,
485 HCLGEVF_OPC_RSS_GENERIC_CONFIG,
486 true);
487 req->hash_config |= (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET);
488 516
489 status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 517 if (handle->pdev->revision >= 0x21) {
490 if (status) { 518 /* Get hash algorithm */
491 dev_err(&hdev->pdev->dev, 519 if (hfunc) {
492 "failed to get hardware RSS cfg, status = %d\n", 520 switch (rss_cfg->hash_algo) {
493 status); 521 case HCLGEVF_RSS_HASH_ALGO_TOEPLITZ:
494 return status; 522 *hfunc = ETH_RSS_HASH_TOP;
523 break;
524 case HCLGEVF_RSS_HASH_ALGO_SIMPLE:
525 *hfunc = ETH_RSS_HASH_XOR;
526 break;
527 default:
528 *hfunc = ETH_RSS_HASH_UNKNOWN;
529 break;
530 }
495 } 531 }
496 532
497 if (key_offset == 2) 533 /* Get the RSS Key required by the user */
498 key_size =
499 HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2;
500 else
501 key_size = HCLGEVF_RSS_HASH_KEY_NUM;
502
503 if (key) 534 if (key)
504 memcpy(key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, 535 memcpy(key, rss_cfg->rss_hash_key,
505 req->hash_key, 536 HCLGEVF_RSS_KEY_SIZE);
506 key_size);
507 } 537 }
508 538
509 if (hash) {
510 if ((req->hash_config & 0xf) == HCLGEVF_RSS_HASH_ALGO_TOEPLITZ)
511 *hash = ETH_RSS_HASH_TOP;
512 else
513 *hash = ETH_RSS_HASH_UNKNOWN;
514 }
515
516 return 0;
517}
518
519static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
520 u8 *hfunc)
521{
522 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
523 struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
524 int i;
525
526 if (indir) 539 if (indir)
527 for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 540 for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
528 indir[i] = rss_cfg->rss_indirection_tbl[i]; 541 indir[i] = rss_cfg->rss_indirection_tbl[i];
529 542
530 return hclgevf_get_rss_hw_cfg(handle, hfunc, key); 543 return 0;
531} 544}
532 545
533static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, 546static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir,
@@ -535,7 +548,36 @@ static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir,
535{ 548{
536 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 549 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
537 struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 550 struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
538 int i; 551 int ret, i;
552
553 if (handle->pdev->revision >= 0x21) {
554 /* Set the RSS Hash Key if specififed by the user */
555 if (key) {
556 switch (hfunc) {
557 case ETH_RSS_HASH_TOP:
558 rss_cfg->hash_algo =
559 HCLGEVF_RSS_HASH_ALGO_TOEPLITZ;
560 break;
561 case ETH_RSS_HASH_XOR:
562 rss_cfg->hash_algo =
563 HCLGEVF_RSS_HASH_ALGO_SIMPLE;
564 break;
565 case ETH_RSS_HASH_NO_CHANGE:
566 break;
567 default:
568 return -EINVAL;
569 }
570
571 ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo,
572 key);
573 if (ret)
574 return ret;
575
576 /* Update the shadow RSS key with user specified qids */
577 memcpy(rss_cfg->rss_hash_key, key,
578 HCLGEVF_RSS_KEY_SIZE);
579 }
580 }
539 581
540 /* update the shadow RSS table with user specified qids */ 582 /* update the shadow RSS table with user specified qids */
541 for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 583 for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
@@ -1276,6 +1318,17 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev)
1276 1318
1277 rss_cfg->rss_size = hdev->rss_size_max; 1319 rss_cfg->rss_size = hdev->rss_size_max;
1278 1320
1321 if (hdev->pdev->revision >= 0x21) {
1322 rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ;
1323 netdev_rss_key_fill(rss_cfg->rss_hash_key,
1324 HCLGEVF_RSS_KEY_SIZE);
1325
1326 ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo,
1327 rss_cfg->rss_hash_key);
1328 if (ret)
1329 return ret;
1330 }
1331
1279 /* Initialize RSS indirect table for each vport */ 1332 /* Initialize RSS indirect table for each vport */
1280 for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 1333 for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
1281 rss_cfg->rss_indirection_tbl[i] = i % hdev->rss_size_max; 1334 rss_cfg->rss_indirection_tbl[i] = i % hdev->rss_size_max;