diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_common.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.c | 231 |
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 | ||
103 | err_unroll_alloc: | ||
104 | devm_kfree(ice_hw_to_dev(hw), hw->port_info); | ||
75 | err_unroll_cqinit: | 105 | err_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 | */ |
84 | void ice_deinit_hw(struct ice_hw *hw) | 114 | void 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 | */ | ||
552 | static void | ||
553 | ice_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 | */ | ||
668 | static enum ice_status | ||
669 | ice_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 | */ | ||
696 | enum 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 | * |