aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_common.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index d3d420c3ba7b..f9567dc1aefd 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -2,6 +2,7 @@
2/* Copyright (c) 2018, Intel Corporation. */ 2/* Copyright (c) 2018, Intel Corporation. */
3 3
4#include "ice_common.h" 4#include "ice_common.h"
5#include "ice_sched.h"
5#include "ice_adminq_cmd.h" 6#include "ice_adminq_cmd.h"
6 7
7#define ICE_PF_RESET_WAIT_COUNT 200 8#define ICE_PF_RESET_WAIT_COUNT 200
@@ -70,8 +71,37 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
70 if (status) 71 if (status)
71 goto err_unroll_cqinit; 72 goto err_unroll_cqinit;
72 73
74 status = ice_get_caps(hw);
75 if (status)
76 goto err_unroll_cqinit;
77
78 hw->port_info = devm_kzalloc(ice_hw_to_dev(hw),
79 sizeof(*hw->port_info), GFP_KERNEL);
80 if (!hw->port_info) {
81 status = ICE_ERR_NO_MEMORY;
82 goto err_unroll_cqinit;
83 }
84
85 /* set the back pointer to hw */
86 hw->port_info->hw = hw;
87
88 /* Initialize port_info struct with switch configuration data */
89 status = ice_get_initial_sw_cfg(hw);
90 if (status)
91 goto err_unroll_alloc;
92
93 /* Query the allocated resources for tx scheduler */
94 status = ice_sched_query_res_alloc(hw);
95 if (status) {
96 ice_debug(hw, ICE_DBG_SCHED,
97 "Failed to get scheduler allocated resources\n");
98 goto err_unroll_alloc;
99 }
100
73 return 0; 101 return 0;
74 102
103err_unroll_alloc:
104 devm_kfree(ice_hw_to_dev(hw), hw->port_info);
75err_unroll_cqinit: 105err_unroll_cqinit:
76 ice_shutdown_all_ctrlq(hw); 106 ice_shutdown_all_ctrlq(hw);
77 return status; 107 return status;
@@ -83,7 +113,12 @@ err_unroll_cqinit:
83 */ 113 */
84void ice_deinit_hw(struct ice_hw *hw) 114void ice_deinit_hw(struct ice_hw *hw)
85{ 115{
116 ice_sched_cleanup_all(hw);
86 ice_shutdown_all_ctrlq(hw); 117 ice_shutdown_all_ctrlq(hw);
118 if (hw->port_info) {
119 devm_kfree(ice_hw_to_dev(hw), hw->port_info);
120 hw->port_info = NULL;
121 }
87} 122}
88 123
89/** 124/**
@@ -506,6 +541,202 @@ void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
506} 541}
507 542
508/** 543/**
544 * ice_parse_caps - parse function/device capabilities
545 * @hw: pointer to the hw struct
546 * @buf: pointer to a buffer containing function/device capability records
547 * @cap_count: number of capability records in the list
548 * @opc: type of capabilities list to parse
549 *
550 * Helper function to parse function(0x000a)/device(0x000b) capabilities list.
551 */
552static void
553ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count,
554 enum ice_adminq_opc opc)
555{
556 struct ice_aqc_list_caps_elem *cap_resp;
557 struct ice_hw_func_caps *func_p = NULL;
558 struct ice_hw_dev_caps *dev_p = NULL;
559 struct ice_hw_common_caps *caps;
560 u32 i;
561
562 if (!buf)
563 return;
564
565 cap_resp = (struct ice_aqc_list_caps_elem *)buf;
566
567 if (opc == ice_aqc_opc_list_dev_caps) {
568 dev_p = &hw->dev_caps;
569 caps = &dev_p->common_cap;
570 } else if (opc == ice_aqc_opc_list_func_caps) {
571 func_p = &hw->func_caps;
572 caps = &func_p->common_cap;
573 } else {
574 ice_debug(hw, ICE_DBG_INIT, "wrong opcode\n");
575 return;
576 }
577
578 for (i = 0; caps && i < cap_count; i++, cap_resp++) {
579 u32 logical_id = le32_to_cpu(cap_resp->logical_id);
580 u32 phys_id = le32_to_cpu(cap_resp->phys_id);
581 u32 number = le32_to_cpu(cap_resp->number);
582 u16 cap = le16_to_cpu(cap_resp->cap);
583
584 switch (cap) {
585 case ICE_AQC_CAPS_VSI:
586 if (dev_p) {
587 dev_p->num_vsi_allocd_to_host = number;
588 ice_debug(hw, ICE_DBG_INIT,
589 "HW caps: Dev.VSI cnt = %d\n",
590 dev_p->num_vsi_allocd_to_host);
591 } else if (func_p) {
592 func_p->guaranteed_num_vsi = number;
593 ice_debug(hw, ICE_DBG_INIT,
594 "HW caps: Func.VSI cnt = %d\n",
595 func_p->guaranteed_num_vsi);
596 }
597 break;
598 case ICE_AQC_CAPS_RSS:
599 caps->rss_table_size = number;
600 caps->rss_table_entry_width = logical_id;
601 ice_debug(hw, ICE_DBG_INIT,
602 "HW caps: RSS table size = %d\n",
603 caps->rss_table_size);
604 ice_debug(hw, ICE_DBG_INIT,
605 "HW caps: RSS table width = %d\n",
606 caps->rss_table_entry_width);
607 break;
608 case ICE_AQC_CAPS_RXQS:
609 caps->num_rxq = number;
610 caps->rxq_first_id = phys_id;
611 ice_debug(hw, ICE_DBG_INIT,
612 "HW caps: Num Rx Qs = %d\n", caps->num_rxq);
613 ice_debug(hw, ICE_DBG_INIT,
614 "HW caps: Rx first queue ID = %d\n",
615 caps->rxq_first_id);
616 break;
617 case ICE_AQC_CAPS_TXQS:
618 caps->num_txq = number;
619 caps->txq_first_id = phys_id;
620 ice_debug(hw, ICE_DBG_INIT,
621 "HW caps: Num Tx Qs = %d\n", caps->num_txq);
622 ice_debug(hw, ICE_DBG_INIT,
623 "HW caps: Tx first queue ID = %d\n",
624 caps->txq_first_id);
625 break;
626 case ICE_AQC_CAPS_MSIX:
627 caps->num_msix_vectors = number;
628 caps->msix_vector_first_id = phys_id;
629 ice_debug(hw, ICE_DBG_INIT,
630 "HW caps: MSIX vector count = %d\n",
631 caps->num_msix_vectors);
632 ice_debug(hw, ICE_DBG_INIT,
633 "HW caps: MSIX first vector index = %d\n",
634 caps->msix_vector_first_id);
635 break;
636 case ICE_AQC_CAPS_MAX_MTU:
637 caps->max_mtu = number;
638 if (dev_p)
639 ice_debug(hw, ICE_DBG_INIT,
640 "HW caps: Dev.MaxMTU = %d\n",
641 caps->max_mtu);
642 else if (func_p)
643 ice_debug(hw, ICE_DBG_INIT,
644 "HW caps: func.MaxMTU = %d\n",
645 caps->max_mtu);
646 break;
647 default:
648 ice_debug(hw, ICE_DBG_INIT,
649 "HW caps: Unknown capability[%d]: 0x%x\n", i,
650 cap);
651 break;
652 }
653 }
654}
655
656/**
657 * ice_aq_discover_caps - query function/device capabilities
658 * @hw: pointer to the hw struct
659 * @buf: a virtual buffer to hold the capabilities
660 * @buf_size: Size of the virtual buffer
661 * @data_size: Size of the returned data, or buf size needed if AQ err==ENOMEM
662 * @opc: capabilities type to discover - pass in the command opcode
663 * @cd: pointer to command details structure or NULL
664 *
665 * Get the function(0x000a)/device(0x000b) capabilities description from
666 * the firmware.
667 */
668static enum ice_status
669ice_aq_discover_caps(struct ice_hw *hw, void *buf, u16 buf_size, u16 *data_size,
670 enum ice_adminq_opc opc, struct ice_sq_cd *cd)
671{
672 struct ice_aqc_list_caps *cmd;
673 struct ice_aq_desc desc;
674 enum ice_status status;
675
676 cmd = &desc.params.get_cap;
677
678 if (opc != ice_aqc_opc_list_func_caps &&
679 opc != ice_aqc_opc_list_dev_caps)
680 return ICE_ERR_PARAM;
681
682 ice_fill_dflt_direct_cmd_desc(&desc, opc);
683
684 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
685 if (!status)
686 ice_parse_caps(hw, buf, le32_to_cpu(cmd->count), opc);
687 *data_size = le16_to_cpu(desc.datalen);
688
689 return status;
690}
691
692/**
693 * ice_get_caps - get info about the HW
694 * @hw: pointer to the hardware structure
695 */
696enum ice_status ice_get_caps(struct ice_hw *hw)
697{
698 enum ice_status status;
699 u16 data_size = 0;
700 u16 cbuf_len;
701 u8 retries;
702
703 /* The driver doesn't know how many capabilities the device will return
704 * so the buffer size required isn't known ahead of time. The driver
705 * starts with cbuf_len and if this turns out to be insufficient, the
706 * device returns ICE_AQ_RC_ENOMEM and also the buffer size it needs.
707 * The driver then allocates the buffer of this size and retries the
708 * operation. So it follows that the retry count is 2.
709 */
710#define ICE_GET_CAP_BUF_COUNT 40
711#define ICE_GET_CAP_RETRY_COUNT 2
712
713 cbuf_len = ICE_GET_CAP_BUF_COUNT *
714 sizeof(struct ice_aqc_list_caps_elem);
715
716 retries = ICE_GET_CAP_RETRY_COUNT;
717
718 do {
719 void *cbuf;
720
721 cbuf = devm_kzalloc(ice_hw_to_dev(hw), cbuf_len, GFP_KERNEL);
722 if (!cbuf)
723 return ICE_ERR_NO_MEMORY;
724
725 status = ice_aq_discover_caps(hw, cbuf, cbuf_len, &data_size,
726 ice_aqc_opc_list_func_caps, NULL);
727 devm_kfree(ice_hw_to_dev(hw), cbuf);
728
729 if (!status || hw->adminq.sq_last_status != ICE_AQ_RC_ENOMEM)
730 break;
731
732 /* If ENOMEM is returned, try again with bigger buffer */
733 cbuf_len = data_size;
734 } while (--retries);
735
736 return status;
737}
738
739/**
509 * ice_aq_clear_pxe_mode 740 * ice_aq_clear_pxe_mode
510 * @hw: pointer to the hw struct 741 * @hw: pointer to the hw struct
511 * 742 *