aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_common.c
diff options
context:
space:
mode:
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>2018-03-20 10:58:08 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-03-26 13:14:57 -0400
commit9c20346b6309e20f64ee8e7054914ddc92c60baf (patch)
treeefc92292f19570987f9bb4e9c0be518efa98efe6 /drivers/net/ethernet/intel/ice/ice_common.c
parentf31e4b6fe227dfd7ed51c3fc0550878c7d7a8cf2 (diff)
ice: Get switch config, scheduler config and device capabilities
This patch adds to the initialization flow by getting switch configuration, scheduler configuration and device capabilities. Switch configuration: On boot, an L2 switch element is created in the firmware per physical function. Each physical function is also mapped to a port, to which its switch element is connected. In other words, this switch can be visualized as an embedded vSwitch that can connect a physical function's virtual station interfaces (VSIs) to the egress/ingress port. Egress/ingress filters will be eventually created and applied on this switch element. As part of the initialization flow, the driver gets configuration data from this switch element and stores it. Scheduler configuration: The Tx scheduler is a subsystem responsible for setting and enforcing QoS. As part of the initialization flow, the driver queries and stores the default scheduler configuration for the given physical function. Device capabilities: As part of initialization, the driver has to determine what the device is capable of (ex. max queues, VSIs, etc). This information is obtained from the firmware and stored by the driver. CC: Shannon Nelson <shannon.nelson@oracle.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Acked-by: Shannon Nelson <shannon.nelson@oracle.com> Tested-by: Tony Brelinski <tonyx.brelinski@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
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 *