ice: Get MAC/PHY/link info and scheduler topology
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tue, 20 Mar 2018 14:58:09 +0000 (07:58 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 26 Mar 2018 17:24:54 +0000 (10:24 -0700)
This patch adds code to continue the initialization flow as follows:

1) Get PHY/link information and store it
2) Get default scheduler tree topology and store it
3) Get the MAC address associated with the port and store it

Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_common.h
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/ice/ice_sched.h
drivers/net/ethernet/intel/ice/ice_status.h
drivers/net/ethernet/intel/ice/ice_type.h

index 716c555..1a1776a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/compiler.h>
+#include <linux/etherdevice.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
 #include <linux/delay.h>
index d1b70f0..5061240 100644 (file)
@@ -104,6 +104,35 @@ struct ice_aqc_list_caps_elem {
        __le64 rsvd2;
 };
 
+/* Manage MAC address, read command - indirect (0x0107)
+ * This struct is also used for the response
+ */
+struct ice_aqc_manage_mac_read {
+       __le16 flags; /* Zeroed by device driver */
+#define ICE_AQC_MAN_MAC_LAN_ADDR_VALID         BIT(4)
+#define ICE_AQC_MAN_MAC_SAN_ADDR_VALID         BIT(5)
+#define ICE_AQC_MAN_MAC_PORT_ADDR_VALID                BIT(6)
+#define ICE_AQC_MAN_MAC_WOL_ADDR_VALID         BIT(7)
+#define ICE_AQC_MAN_MAC_READ_S                 4
+#define ICE_AQC_MAN_MAC_READ_M                 (0xF << ICE_AQC_MAN_MAC_READ_S)
+       u8 lport_num;
+       u8 lport_num_valid;
+#define ICE_AQC_MAN_MAC_PORT_NUM_IS_VALID      BIT(0)
+       u8 num_addr; /* Used in response */
+       u8 reserved[3];
+       __le32 addr_high;
+       __le32 addr_low;
+};
+
+/* Response buffer format for manage MAC read command */
+struct ice_aqc_manage_mac_read_resp {
+       u8 lport_num;
+       u8 addr_type;
+#define ICE_AQC_MAN_MAC_ADDR_TYPE_LAN          0
+#define ICE_AQC_MAN_MAC_ADDR_TYPE_WOL          1
+       u8 mac_addr[ETH_ALEN];
+};
+
 /* Clear PXE Command and response (direct 0x0110) */
 struct ice_aqc_clear_pxe {
        u8 rx_cnt;
@@ -161,6 +190,16 @@ struct ice_aqc_get_sw_cfg_resp {
        struct ice_aqc_get_sw_cfg_resp_elem elements[1];
 };
 
+/* Get Default Topology (indirect 0x0400) */
+struct ice_aqc_get_topo {
+       u8 port_num;
+       u8 num_branches;
+       __le16 reserved1;
+       __le32 reserved2;
+       __le32 addr_high;
+       __le32 addr_low;
+};
+
 /* Add TSE (indirect 0x0401)
  * Delete TSE (indirect 0x040F)
  * Move TSE (indirect 0x0408)
@@ -221,6 +260,12 @@ struct ice_aqc_txsched_topo_grp_info_hdr {
        __le16 reserved2;
 };
 
+struct ice_aqc_get_topo_elem {
+       struct ice_aqc_txsched_topo_grp_info_hdr hdr;
+       struct ice_aqc_txsched_elem_data
+               generic[ICE_AQC_TOPO_MAX_LEVEL_NUM];
+};
+
 struct ice_aqc_delete_elem {
        struct ice_aqc_txsched_topo_grp_info_hdr hdr;
        __le32 teid[1];
@@ -266,6 +311,210 @@ struct ice_aqc_query_txsched_res_resp {
        struct ice_aqc_layer_props layer_props[ICE_AQC_TOPO_MAX_LEVEL_NUM];
 };
 
+/* Get PHY capabilities (indirect 0x0600) */
+struct ice_aqc_get_phy_caps {
+       u8 lport_num;
+       u8 reserved;
+       __le16 param0;
+       /* 18.0 - Report qualified modules */
+#define ICE_AQC_GET_PHY_RQM            BIT(0)
+       /* 18.1 - 18.2 : Report mode
+        * 00b - Report NVM capabilities
+        * 01b - Report topology capabilities
+        * 10b - Report SW configured
+        */
+#define ICE_AQC_REPORT_MODE_S          1
+#define ICE_AQC_REPORT_MODE_M          (3 << ICE_AQC_REPORT_MODE_S)
+#define ICE_AQC_REPORT_NVM_CAP         0
+#define ICE_AQC_REPORT_TOPO_CAP                BIT(1)
+#define ICE_AQC_REPORT_SW_CFG          BIT(2)
+       __le32 reserved1;
+       __le32 addr_high;
+       __le32 addr_low;
+};
+
+/* This is #define of PHY type (Extended):
+ * The first set of defines is for phy_type_low.
+ */
+#define ICE_PHY_TYPE_LOW_100BASE_TX            BIT_ULL(0)
+#define ICE_PHY_TYPE_LOW_100M_SGMII            BIT_ULL(1)
+#define ICE_PHY_TYPE_LOW_1000BASE_T            BIT_ULL(2)
+#define ICE_PHY_TYPE_LOW_1000BASE_SX           BIT_ULL(3)
+#define ICE_PHY_TYPE_LOW_1000BASE_LX           BIT_ULL(4)
+#define ICE_PHY_TYPE_LOW_1000BASE_KX           BIT_ULL(5)
+#define ICE_PHY_TYPE_LOW_1G_SGMII              BIT_ULL(6)
+#define ICE_PHY_TYPE_LOW_2500BASE_T            BIT_ULL(7)
+#define ICE_PHY_TYPE_LOW_2500BASE_X            BIT_ULL(8)
+#define ICE_PHY_TYPE_LOW_2500BASE_KX           BIT_ULL(9)
+#define ICE_PHY_TYPE_LOW_5GBASE_T              BIT_ULL(10)
+#define ICE_PHY_TYPE_LOW_5GBASE_KR             BIT_ULL(11)
+#define ICE_PHY_TYPE_LOW_10GBASE_T             BIT_ULL(12)
+#define ICE_PHY_TYPE_LOW_10G_SFI_DA            BIT_ULL(13)
+#define ICE_PHY_TYPE_LOW_10GBASE_SR            BIT_ULL(14)
+#define ICE_PHY_TYPE_LOW_10GBASE_LR            BIT_ULL(15)
+#define ICE_PHY_TYPE_LOW_10GBASE_KR_CR1                BIT_ULL(16)
+#define ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC       BIT_ULL(17)
+#define ICE_PHY_TYPE_LOW_10G_SFI_C2C           BIT_ULL(18)
+#define ICE_PHY_TYPE_LOW_25GBASE_T             BIT_ULL(19)
+#define ICE_PHY_TYPE_LOW_25GBASE_CR            BIT_ULL(20)
+#define ICE_PHY_TYPE_LOW_25GBASE_CR_S          BIT_ULL(21)
+#define ICE_PHY_TYPE_LOW_25GBASE_CR1           BIT_ULL(22)
+#define ICE_PHY_TYPE_LOW_25GBASE_SR            BIT_ULL(23)
+#define ICE_PHY_TYPE_LOW_25GBASE_LR            BIT_ULL(24)
+#define ICE_PHY_TYPE_LOW_25GBASE_KR            BIT_ULL(25)
+#define ICE_PHY_TYPE_LOW_25GBASE_KR_S          BIT_ULL(26)
+#define ICE_PHY_TYPE_LOW_25GBASE_KR1           BIT_ULL(27)
+#define ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC       BIT_ULL(28)
+#define ICE_PHY_TYPE_LOW_25G_AUI_C2C           BIT_ULL(29)
+#define ICE_PHY_TYPE_LOW_40GBASE_CR4           BIT_ULL(30)
+#define ICE_PHY_TYPE_LOW_40GBASE_SR4           BIT_ULL(31)
+#define ICE_PHY_TYPE_LOW_40GBASE_LR4           BIT_ULL(32)
+#define ICE_PHY_TYPE_LOW_40GBASE_KR4           BIT_ULL(33)
+#define ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC     BIT_ULL(34)
+#define ICE_PHY_TYPE_LOW_40G_XLAUI             BIT_ULL(35)
+#define ICE_PHY_TYPE_LOW_MAX_INDEX             63
+
+struct ice_aqc_get_phy_caps_data {
+       __le64 phy_type_low; /* Use values from ICE_PHY_TYPE_LOW_* */
+       __le64 reserved;
+       u8 caps;
+#define ICE_AQC_PHY_EN_TX_LINK_PAUSE                   BIT(0)
+#define ICE_AQC_PHY_EN_RX_LINK_PAUSE                   BIT(1)
+#define ICE_AQC_PHY_LOW_POWER_MODE                     BIT(2)
+#define ICE_AQC_PHY_EN_LINK                            BIT(3)
+#define ICE_AQC_PHY_AN_MODE                            BIT(4)
+#define ICE_AQC_GET_PHY_EN_MOD_QUAL                    BIT(5)
+       u8 low_power_ctrl;
+#define ICE_AQC_PHY_EN_D3COLD_LOW_POWER_AUTONEG                BIT(0)
+       __le16 eee_cap;
+#define ICE_AQC_PHY_EEE_EN_100BASE_TX                  BIT(0)
+#define ICE_AQC_PHY_EEE_EN_1000BASE_T                  BIT(1)
+#define ICE_AQC_PHY_EEE_EN_10GBASE_T                   BIT(2)
+#define ICE_AQC_PHY_EEE_EN_1000BASE_KX                 BIT(3)
+#define ICE_AQC_PHY_EEE_EN_10GBASE_KR                  BIT(4)
+#define ICE_AQC_PHY_EEE_EN_25GBASE_KR                  BIT(5)
+#define ICE_AQC_PHY_EEE_EN_40GBASE_KR4                 BIT(6)
+       __le16 eeer_value;
+       u8 phy_id_oui[4]; /* PHY/Module ID connected on the port */
+       u8 link_fec_options;
+#define ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN              BIT(0)
+#define ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ             BIT(1)
+#define ICE_AQC_PHY_FEC_25G_RS_528_REQ                 BIT(2)
+#define ICE_AQC_PHY_FEC_25G_KR_REQ                     BIT(3)
+#define ICE_AQC_PHY_FEC_25G_RS_544_REQ                 BIT(4)
+#define ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN             BIT(6)
+#define ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN             BIT(7)
+       u8 extended_compliance_code;
+#define ICE_MODULE_TYPE_TOTAL_BYTE                     3
+       u8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];
+#define ICE_AQC_MOD_TYPE_BYTE0_SFP_PLUS                        0xA0
+#define ICE_AQC_MOD_TYPE_BYTE0_QSFP_PLUS               0x80
+#define ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE     BIT(0)
+#define ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE      BIT(1)
+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_SR             BIT(4)
+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_LR             BIT(5)
+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_LRM            BIT(6)
+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_ER             BIT(7)
+#define ICE_AQC_MOD_TYPE_BYTE2_SFP_PLUS                        0xA0
+#define ICE_AQC_MOD_TYPE_BYTE2_QSFP_PLUS               0x86
+       u8 qualified_module_count;
+#define ICE_AQC_QUAL_MOD_COUNT_MAX                     16
+       struct {
+               u8 v_oui[3];
+               u8 rsvd1;
+               u8 v_part[16];
+               __le32 v_rev;
+               __le64 rsvd8;
+       } qual_modules[ICE_AQC_QUAL_MOD_COUNT_MAX];
+};
+
+/* Get link status (indirect 0x0607), also used for Link Status Event */
+struct ice_aqc_get_link_status {
+       u8 lport_num;
+       u8 reserved;
+       __le16 cmd_flags;
+#define ICE_AQ_LSE_M                   0x3
+#define ICE_AQ_LSE_NOP                 0x0
+#define ICE_AQ_LSE_DIS                 0x2
+#define ICE_AQ_LSE_ENA                 0x3
+       /* only response uses this flag */
+#define ICE_AQ_LSE_IS_ENABLED          0x1
+       __le32 reserved2;
+       __le32 addr_high;
+       __le32 addr_low;
+};
+
+/* Get link status response data structure, also used for Link Status Event */
+struct ice_aqc_get_link_status_data {
+       u8 topo_media_conflict;
+#define ICE_AQ_LINK_TOPO_CONFLICT      BIT(0)
+#define ICE_AQ_LINK_MEDIA_CONFLICT     BIT(1)
+#define ICE_AQ_LINK_TOPO_CORRUPT       BIT(2)
+       u8 reserved1;
+       u8 link_info;
+#define ICE_AQ_LINK_UP                 BIT(0)  /* Link Status */
+#define ICE_AQ_LINK_FAULT              BIT(1)
+#define ICE_AQ_LINK_FAULT_TX           BIT(2)
+#define ICE_AQ_LINK_FAULT_RX           BIT(3)
+#define ICE_AQ_LINK_FAULT_REMOTE       BIT(4)
+#define ICE_AQ_LINK_UP_PORT            BIT(5)  /* External Port Link Status */
+#define ICE_AQ_MEDIA_AVAILABLE         BIT(6)
+#define ICE_AQ_SIGNAL_DETECT           BIT(7)
+       u8 an_info;
+#define ICE_AQ_AN_COMPLETED            BIT(0)
+#define ICE_AQ_LP_AN_ABILITY           BIT(1)
+#define ICE_AQ_PD_FAULT                        BIT(2)  /* Parallel Detection Fault */
+#define ICE_AQ_FEC_EN                  BIT(3)
+#define ICE_AQ_PHY_LOW_POWER           BIT(4)  /* Low Power State */
+#define ICE_AQ_LINK_PAUSE_TX           BIT(5)
+#define ICE_AQ_LINK_PAUSE_RX           BIT(6)
+#define ICE_AQ_QUALIFIED_MODULE                BIT(7)
+       u8 ext_info;
+#define ICE_AQ_LINK_PHY_TEMP_ALARM     BIT(0)
+#define ICE_AQ_LINK_EXCESSIVE_ERRORS   BIT(1)  /* Excessive Link Errors */
+       /* Port TX Suspended */
+#define ICE_AQ_LINK_TX_S               2
+#define ICE_AQ_LINK_TX_M               (0x03 << ICE_AQ_LINK_TX_S)
+#define ICE_AQ_LINK_TX_ACTIVE          0
+#define ICE_AQ_LINK_TX_DRAINED         1
+#define ICE_AQ_LINK_TX_FLUSHED         3
+       u8 reserved2;
+       __le16 max_frame_size;
+       u8 cfg;
+#define ICE_AQ_LINK_25G_KR_FEC_EN      BIT(0)
+#define ICE_AQ_LINK_25G_RS_528_FEC_EN  BIT(1)
+#define ICE_AQ_LINK_25G_RS_544_FEC_EN  BIT(2)
+       /* Pacing Config */
+#define ICE_AQ_CFG_PACING_S            3
+#define ICE_AQ_CFG_PACING_M            (0xF << ICE_AQ_CFG_PACING_S)
+#define ICE_AQ_CFG_PACING_TYPE_M       BIT(7)
+#define ICE_AQ_CFG_PACING_TYPE_AVG     0
+#define ICE_AQ_CFG_PACING_TYPE_FIXED   ICE_AQ_CFG_PACING_TYPE_M
+       /* External Device Power Ability */
+       u8 power_desc;
+#define ICE_AQ_PWR_CLASS_M             0x3
+#define ICE_AQ_LINK_PWR_BASET_LOW_HIGH 0
+#define ICE_AQ_LINK_PWR_BASET_HIGH     1
+#define ICE_AQ_LINK_PWR_QSFP_CLASS_1   0
+#define ICE_AQ_LINK_PWR_QSFP_CLASS_2   1
+#define ICE_AQ_LINK_PWR_QSFP_CLASS_3   2
+#define ICE_AQ_LINK_PWR_QSFP_CLASS_4   3
+       __le16 link_speed;
+#define ICE_AQ_LINK_SPEED_10MB         BIT(0)
+#define ICE_AQ_LINK_SPEED_100MB                BIT(1)
+#define ICE_AQ_LINK_SPEED_1000MB       BIT(2)
+#define ICE_AQ_LINK_SPEED_2500MB       BIT(3)
+#define ICE_AQ_LINK_SPEED_5GB          BIT(4)
+#define ICE_AQ_LINK_SPEED_10GB         BIT(5)
+#define ICE_AQ_LINK_SPEED_20GB         BIT(6)
+#define ICE_AQ_LINK_SPEED_25GB         BIT(7)
+#define ICE_AQ_LINK_SPEED_40GB         BIT(8)
+#define ICE_AQ_LINK_SPEED_UNKNOWN      BIT(15)
+       __le32 reserved3; /* Aligns next field to 8-byte boundary */
+       __le64 phy_type_low; /* Use values from ICE_PHY_TYPE_LOW_* */
+       __le64 reserved4;
+};
+
 /* NVM Read command (indirect 0x0701)
  * NVM Erase commands (direct 0x0702)
  * NVM Update commands (indirect 0x0703)
@@ -318,12 +567,16 @@ struct ice_aq_desc {
                struct ice_aqc_get_ver get_ver;
                struct ice_aqc_q_shutdown q_shutdown;
                struct ice_aqc_req_res res_owner;
+               struct ice_aqc_manage_mac_read mac_read;
                struct ice_aqc_clear_pxe clear_pxe;
                struct ice_aqc_list_caps get_cap;
+               struct ice_aqc_get_phy_caps get_phy;
                struct ice_aqc_get_sw_cfg get_sw_conf;
+               struct ice_aqc_get_topo get_topo;
                struct ice_aqc_query_txsched_res query_sched_res;
                struct ice_aqc_add_move_delete_elem add_move_delete_elem;
                struct ice_aqc_nvm nvm;
+               struct ice_aqc_get_link_status get_link_status;
        } params;
 };
 
@@ -362,6 +615,9 @@ enum ice_adminq_opc {
        ice_aqc_opc_list_func_caps                      = 0x000A,
        ice_aqc_opc_list_dev_caps                       = 0x000B,
 
+       /* manage MAC address */
+       ice_aqc_opc_manage_mac_read                     = 0x0107,
+
        /* PXE */
        ice_aqc_opc_clear_pxe_mode                      = 0x0110,
 
@@ -371,9 +627,14 @@ enum ice_adminq_opc {
        ice_aqc_opc_clear_pf_cfg                        = 0x02A4,
 
        /* transmit scheduler commands */
+       ice_aqc_opc_get_dflt_topo                       = 0x0400,
        ice_aqc_opc_delete_sched_elems                  = 0x040F,
        ice_aqc_opc_query_sched_res                     = 0x0412,
 
+       /* PHY commands */
+       ice_aqc_opc_get_phy_caps                        = 0x0600,
+       ice_aqc_opc_get_link_status                     = 0x0607,
+
        /* NVM commands */
        ice_aqc_opc_nvm_read                            = 0x0701,
 
index f9567dc..ef5bab2 100644 (file)
@@ -37,12 +37,237 @@ enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)
 }
 
 /**
+ * ice_aq_manage_mac_read - manage MAC address read command
+ * @hw: pointer to the hw struct
+ * @buf: a virtual buffer to hold the manage MAC read response
+ * @buf_size: Size of the virtual buffer
+ * @cd: pointer to command details structure or NULL
+ *
+ * This function is used to return per PF station MAC address (0x0107).
+ * NOTE: Upon successful completion of this command, MAC address information
+ * is returned in user specified buffer. Please interpret user specified
+ * buffer as "manage_mac_read" response.
+ * Response such as various MAC addresses are stored in HW struct (port.mac)
+ * ice_aq_discover_caps is expected to be called before this function is called.
+ */
+static enum ice_status
+ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
+                      struct ice_sq_cd *cd)
+{
+       struct ice_aqc_manage_mac_read_resp *resp;
+       struct ice_aqc_manage_mac_read *cmd;
+       struct ice_aq_desc desc;
+       enum ice_status status;
+       u16 flags;
+
+       cmd = &desc.params.mac_read;
+
+       if (buf_size < sizeof(*resp))
+               return ICE_ERR_BUF_TOO_SHORT;
+
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read);
+
+       status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
+       if (status)
+               return status;
+
+       resp = (struct ice_aqc_manage_mac_read_resp *)buf;
+       flags = le16_to_cpu(cmd->flags) & ICE_AQC_MAN_MAC_READ_M;
+
+       if (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) {
+               ice_debug(hw, ICE_DBG_LAN, "got invalid MAC address\n");
+               return ICE_ERR_CFG;
+       }
+
+       ether_addr_copy(hw->port_info->mac.lan_addr, resp->mac_addr);
+       ether_addr_copy(hw->port_info->mac.perm_addr, resp->mac_addr);
+       return 0;
+}
+
+/**
+ * ice_aq_get_phy_caps - returns PHY capabilities
+ * @pi: port information structure
+ * @qual_mods: report qualified modules
+ * @report_mode: report mode capabilities
+ * @pcaps: structure for PHY capabilities to be filled
+ * @cd: pointer to command details structure or NULL
+ *
+ * Returns the various PHY capabilities supported on the Port (0x0600)
+ */
+static enum ice_status
+ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
+                   struct ice_aqc_get_phy_caps_data *pcaps,
+                   struct ice_sq_cd *cd)
+{
+       struct ice_aqc_get_phy_caps *cmd;
+       u16 pcaps_size = sizeof(*pcaps);
+       struct ice_aq_desc desc;
+       enum ice_status status;
+
+       cmd = &desc.params.get_phy;
+
+       if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)
+               return ICE_ERR_PARAM;
+
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);
+
+       if (qual_mods)
+               cmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM);
+
+       cmd->param0 |= cpu_to_le16(report_mode);
+       status = ice_aq_send_cmd(pi->hw, &desc, pcaps, pcaps_size, cd);
+
+       if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP)
+               pi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low);
+
+       return status;
+}
+
+/**
+ * ice_get_media_type - Gets media type
+ * @pi: port information structure
+ */
+static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
+{
+       struct ice_link_status *hw_link_info;
+
+       if (!pi)
+               return ICE_MEDIA_UNKNOWN;
+
+       hw_link_info = &pi->phy.link_info;
+
+       if (hw_link_info->phy_type_low) {
+               switch (hw_link_info->phy_type_low) {
+               case ICE_PHY_TYPE_LOW_1000BASE_SX:
+               case ICE_PHY_TYPE_LOW_1000BASE_LX:
+               case ICE_PHY_TYPE_LOW_10GBASE_SR:
+               case ICE_PHY_TYPE_LOW_10GBASE_LR:
+               case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
+               case ICE_PHY_TYPE_LOW_25GBASE_SR:
+               case ICE_PHY_TYPE_LOW_25GBASE_LR:
+               case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
+               case ICE_PHY_TYPE_LOW_40GBASE_SR4:
+               case ICE_PHY_TYPE_LOW_40GBASE_LR4:
+                       return ICE_MEDIA_FIBER;
+               case ICE_PHY_TYPE_LOW_100BASE_TX:
+               case ICE_PHY_TYPE_LOW_1000BASE_T:
+               case ICE_PHY_TYPE_LOW_2500BASE_T:
+               case ICE_PHY_TYPE_LOW_5GBASE_T:
+               case ICE_PHY_TYPE_LOW_10GBASE_T:
+               case ICE_PHY_TYPE_LOW_25GBASE_T:
+                       return ICE_MEDIA_BASET;
+               case ICE_PHY_TYPE_LOW_10G_SFI_DA:
+               case ICE_PHY_TYPE_LOW_25GBASE_CR:
+               case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
+               case ICE_PHY_TYPE_LOW_25GBASE_CR1:
+               case ICE_PHY_TYPE_LOW_40GBASE_CR4:
+                       return ICE_MEDIA_DA;
+               case ICE_PHY_TYPE_LOW_1000BASE_KX:
+               case ICE_PHY_TYPE_LOW_2500BASE_KX:
+               case ICE_PHY_TYPE_LOW_2500BASE_X:
+               case ICE_PHY_TYPE_LOW_5GBASE_KR:
+               case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
+               case ICE_PHY_TYPE_LOW_25GBASE_KR:
+               case ICE_PHY_TYPE_LOW_25GBASE_KR1:
+               case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
+               case ICE_PHY_TYPE_LOW_40GBASE_KR4:
+                       return ICE_MEDIA_BACKPLANE;
+               }
+       }
+
+       return ICE_MEDIA_UNKNOWN;
+}
+
+/**
+ * ice_aq_get_link_info
+ * @pi: port information structure
+ * @ena_lse: enable/disable LinkStatusEvent reporting
+ * @link: pointer to link status structure - optional
+ * @cd: pointer to command details structure or NULL
+ *
+ * Get Link Status (0x607). Returns the link status of the adapter.
+ */
+enum ice_status
+ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
+                    struct ice_link_status *link, struct ice_sq_cd *cd)
+{
+       struct ice_link_status *hw_link_info_old, *hw_link_info;
+       struct ice_aqc_get_link_status_data link_data = { 0 };
+       struct ice_aqc_get_link_status *resp;
+       enum ice_media_type *hw_media_type;
+       struct ice_fc_info *hw_fc_info;
+       bool tx_pause, rx_pause;
+       struct ice_aq_desc desc;
+       enum ice_status status;
+       u16 cmd_flags;
+
+       if (!pi)
+               return ICE_ERR_PARAM;
+       hw_link_info_old = &pi->phy.link_info_old;
+       hw_media_type = &pi->phy.media_type;
+       hw_link_info = &pi->phy.link_info;
+       hw_fc_info = &pi->fc;
+
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
+       cmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS;
+       resp = &desc.params.get_link_status;
+       resp->cmd_flags = cpu_to_le16(cmd_flags);
+       resp->lport_num = pi->lport;
+
+       status = ice_aq_send_cmd(pi->hw, &desc, &link_data, sizeof(link_data),
+                                cd);
+
+       if (status)
+               return status;
+
+       /* save off old link status information */
+       *hw_link_info_old = *hw_link_info;
+
+       /* update current link status information */
+       hw_link_info->link_speed = le16_to_cpu(link_data.link_speed);
+       hw_link_info->phy_type_low = le64_to_cpu(link_data.phy_type_low);
+       *hw_media_type = ice_get_media_type(pi);
+       hw_link_info->link_info = link_data.link_info;
+       hw_link_info->an_info = link_data.an_info;
+       hw_link_info->ext_info = link_data.ext_info;
+       hw_link_info->max_frame_size = le16_to_cpu(link_data.max_frame_size);
+       hw_link_info->pacing = link_data.cfg & ICE_AQ_CFG_PACING_M;
+
+       /* update fc info */
+       tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);
+       rx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX);
+       if (tx_pause && rx_pause)
+               hw_fc_info->current_mode = ICE_FC_FULL;
+       else if (tx_pause)
+               hw_fc_info->current_mode = ICE_FC_TX_PAUSE;
+       else if (rx_pause)
+               hw_fc_info->current_mode = ICE_FC_RX_PAUSE;
+       else
+               hw_fc_info->current_mode = ICE_FC_NONE;
+
+       hw_link_info->lse_ena =
+               !!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED));
+
+       /* save link status information */
+       if (link)
+               *link = *hw_link_info;
+
+       /* flag cleared so calling functions don't call AQ again */
+       pi->phy.get_link_info = false;
+
+       return status;
+}
+
+/**
  * ice_init_hw - main hardware initialization routine
  * @hw: pointer to the hardware structure
  */
 enum ice_status ice_init_hw(struct ice_hw *hw)
 {
+       struct ice_aqc_get_phy_caps_data *pcaps;
        enum ice_status status;
+       u16 mac_buf_len;
+       void *mac_buf;
 
        /* Set MAC type based on DeviceID */
        status = ice_set_mac_type(hw);
@@ -98,8 +323,46 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
                goto err_unroll_alloc;
        }
 
+       /* Initialize port_info struct with scheduler data */
+       status = ice_sched_init_port(hw->port_info);
+       if (status)
+               goto err_unroll_sched;
+
+       pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
+       if (!pcaps) {
+               status = ICE_ERR_NO_MEMORY;
+               goto err_unroll_sched;
+       }
+
+       /* Initialize port_info struct with PHY capabilities */
+       status = ice_aq_get_phy_caps(hw->port_info, false,
+                                    ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL);
+       devm_kfree(ice_hw_to_dev(hw), pcaps);
+       if (status)
+               goto err_unroll_sched;
+
+       /* Initialize port_info struct with link information */
+       status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
+       if (status)
+               goto err_unroll_sched;
+
+       /* Get port MAC information */
+       mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp);
+       mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL);
+
+       if (!mac_buf)
+               goto err_unroll_sched;
+
+       status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
+       devm_kfree(ice_hw_to_dev(hw), mac_buf);
+
+       if (status)
+               goto err_unroll_sched;
+
        return 0;
 
+err_unroll_sched:
+       ice_sched_cleanup_all(hw);
 err_unroll_alloc:
        devm_kfree(ice_hw_to_dev(hw), hw->port_info);
 err_unroll_cqinit:
@@ -115,6 +378,7 @@ void ice_deinit_hw(struct ice_hw *hw)
 {
        ice_sched_cleanup_all(hw);
        ice_shutdown_all_ctrlq(hw);
+
        if (hw->port_info) {
                devm_kfree(ice_hw_to_dev(hw), hw->port_info);
                hw->port_info = NULL;
index 87d8734..e0a7aa1 100644 (file)
@@ -35,4 +35,7 @@ ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc,
                void *buf, u16 buf_size, struct ice_sq_cd *cd);
 enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd);
 enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);
+enum ice_status
+ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
+                    struct ice_link_status *link, struct ice_sq_cd *cd);
 #endif /* _ICE_COMMON_H_ */
index ce4edf6..22039f9 100644 (file)
@@ -4,6 +4,141 @@
 #include "ice_sched.h"
 
 /**
+ * ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB
+ * @pi: port information structure
+ * @info: Scheduler element information from firmware
+ *
+ * This function inserts the root node of the scheduling tree topology
+ * to the SW DB.
+ */
+static enum ice_status
+ice_sched_add_root_node(struct ice_port_info *pi,
+                       struct ice_aqc_txsched_elem_data *info)
+{
+       struct ice_sched_node *root;
+       struct ice_hw *hw;
+       u16 max_children;
+
+       if (!pi)
+               return ICE_ERR_PARAM;
+
+       hw = pi->hw;
+
+       root = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL);
+       if (!root)
+               return ICE_ERR_NO_MEMORY;
+
+       max_children = le16_to_cpu(hw->layer_info[0].max_children);
+       root->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,
+                                     sizeof(*root), GFP_KERNEL);
+       if (!root->children) {
+               devm_kfree(ice_hw_to_dev(hw), root);
+               return ICE_ERR_NO_MEMORY;
+       }
+
+       memcpy(&root->info, info, sizeof(*info));
+       pi->root = root;
+       return 0;
+}
+
+/**
+ * ice_sched_find_node_by_teid - Find the Tx scheduler node in SW DB
+ * @start_node: pointer to the starting ice_sched_node struct in a sub-tree
+ * @teid: node teid to search
+ *
+ * This function searches for a node matching the teid in the scheduling tree
+ * from the SW DB. The search is recursive and is restricted by the number of
+ * layers it has searched through; stopping at the max supported layer.
+ *
+ * This function needs to be called when holding the port_info->sched_lock
+ */
+struct ice_sched_node *
+ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
+{
+       u16 i;
+
+       /* The TEID is same as that of the start_node */
+       if (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)
+               return start_node;
+
+       /* The node has no children or is at the max layer */
+       if (!start_node->num_children ||
+           start_node->tx_sched_layer >= ICE_AQC_TOPO_MAX_LEVEL_NUM ||
+           start_node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF)
+               return NULL;
+
+       /* Check if teid matches to any of the children nodes */
+       for (i = 0; i < start_node->num_children; i++)
+               if (ICE_TXSCHED_GET_NODE_TEID(start_node->children[i]) == teid)
+                       return start_node->children[i];
+
+       /* Search within each child's sub-tree */
+       for (i = 0; i < start_node->num_children; i++) {
+               struct ice_sched_node *tmp;
+
+               tmp = ice_sched_find_node_by_teid(start_node->children[i],
+                                                 teid);
+               if (tmp)
+                       return tmp;
+       }
+
+       return NULL;
+}
+
+/**
+ * ice_sched_add_node - Insert the Tx scheduler node in SW DB
+ * @pi: port information structure
+ * @layer: Scheduler layer of the node
+ * @info: Scheduler element information from firmware
+ *
+ * This function inserts a scheduler node to the SW DB.
+ */
+enum ice_status
+ice_sched_add_node(struct ice_port_info *pi, u8 layer,
+                  struct ice_aqc_txsched_elem_data *info)
+{
+       struct ice_sched_node *parent;
+       struct ice_sched_node *node;
+       struct ice_hw *hw;
+       u16 max_children;
+
+       if (!pi)
+               return ICE_ERR_PARAM;
+
+       hw = pi->hw;
+
+       /* A valid parent node should be there */
+       parent = ice_sched_find_node_by_teid(pi->root,
+                                            le32_to_cpu(info->parent_teid));
+       if (!parent) {
+               ice_debug(hw, ICE_DBG_SCHED,
+                         "Parent Node not found for parent_teid=0x%x\n",
+                         le32_to_cpu(info->parent_teid));
+               return ICE_ERR_PARAM;
+       }
+
+       node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
+       if (!node)
+               return ICE_ERR_NO_MEMORY;
+       max_children = le16_to_cpu(hw->layer_info[layer].max_children);
+       if (max_children) {
+               node->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,
+                                             sizeof(*node), GFP_KERNEL);
+               if (!node->children) {
+                       devm_kfree(ice_hw_to_dev(hw), node);
+                       return ICE_ERR_NO_MEMORY;
+               }
+       }
+
+       node->in_use = true;
+       node->parent = parent;
+       node->tx_sched_layer = layer;
+       parent->children[parent->num_children++] = node;
+       memcpy(&node->info, info, sizeof(*info));
+       return 0;
+}
+
+/**
  * ice_aq_delete_sched_elems - delete scheduler elements
  * @hw: pointer to the hw struct
  * @grps_req: number of groups to delete
@@ -195,6 +330,36 @@ err_exit:
 }
 
 /**
+ * ice_aq_get_dflt_topo - gets default scheduler topology
+ * @hw: pointer to the hw struct
+ * @lport: logical port number
+ * @buf: pointer to buffer
+ * @buf_size: buffer size in bytes
+ * @num_branches: returns total number of queue to port branches
+ * @cd: pointer to command details structure or NULL
+ *
+ * Get default scheduler topology (0x400)
+ */
+static enum ice_status
+ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport,
+                    struct ice_aqc_get_topo_elem *buf, u16 buf_size,
+                    u8 *num_branches, struct ice_sq_cd *cd)
+{
+       struct ice_aqc_get_topo *cmd;
+       struct ice_aq_desc desc;
+       enum ice_status status;
+
+       cmd = &desc.params.get_topo;
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo);
+       cmd->port_num = lport;
+       status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
+       if (!status && num_branches)
+               *num_branches = cmd->num_branches;
+
+       return status;
+}
+
+/**
  * ice_aq_query_sched_res - query scheduler resource
  * @hw: pointer to the hw struct
  * @buf_size: buffer size in bytes
@@ -298,6 +463,169 @@ void ice_sched_cleanup_all(struct ice_hw *hw)
 }
 
 /**
+ * ice_rm_dflt_leaf_node - remove the default leaf node in the tree
+ * @pi: port information structure
+ *
+ * This function removes the leaf node that was created by the FW
+ * during initialization
+ */
+static void
+ice_rm_dflt_leaf_node(struct ice_port_info *pi)
+{
+       struct ice_sched_node *node;
+
+       node = pi->root;
+       while (node) {
+               if (!node->num_children)
+                       break;
+               node = node->children[0];
+       }
+       if (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) {
+               u32 teid = le32_to_cpu(node->info.node_teid);
+               enum ice_status status;
+
+               /* remove the default leaf node */
+               status = ice_sched_remove_elems(pi->hw, node->parent, 1, &teid);
+               if (!status)
+                       ice_free_sched_node(pi, node);
+       }
+}
+
+/**
+ * ice_sched_rm_dflt_nodes - free the default nodes in the tree
+ * @pi: port information structure
+ *
+ * This function frees all the nodes except root and TC that were created by
+ * the FW during initialization
+ */
+static void
+ice_sched_rm_dflt_nodes(struct ice_port_info *pi)
+{
+       struct ice_sched_node *node;
+
+       ice_rm_dflt_leaf_node(pi);
+       /* remove the default nodes except TC and root nodes */
+       node = pi->root;
+       while (node) {
+               if (node->tx_sched_layer >= pi->hw->sw_entry_point_layer &&
+                   node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&
+                   node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) {
+                       ice_free_sched_node(pi, node);
+                       break;
+               }
+               if (!node->num_children)
+                       break;
+               node = node->children[0];
+       }
+}
+
+/**
+ * ice_sched_init_port - Initialize scheduler by querying information from FW
+ * @pi: port info structure for the tree to cleanup
+ *
+ * This function is the initial call to find the total number of Tx scheduler
+ * resources, default topology created by firmware and storing the information
+ * in SW DB.
+ */
+enum ice_status ice_sched_init_port(struct ice_port_info *pi)
+{
+       struct ice_aqc_get_topo_elem *buf;
+       enum ice_status status;
+       struct ice_hw *hw;
+       u8 num_branches;
+       u16 num_elems;
+       u8 i, j;
+
+       if (!pi)
+               return ICE_ERR_PARAM;
+       hw = pi->hw;
+
+       /* Query the Default Topology from FW */
+       buf = devm_kcalloc(ice_hw_to_dev(hw), ICE_TXSCHED_MAX_BRANCHES,
+                          sizeof(*buf), GFP_KERNEL);
+       if (!buf)
+               return ICE_ERR_NO_MEMORY;
+
+       /* Query default scheduling tree topology */
+       status = ice_aq_get_dflt_topo(hw, pi->lport, buf,
+                                     sizeof(*buf) * ICE_TXSCHED_MAX_BRANCHES,
+                                     &num_branches, NULL);
+       if (status)
+               goto err_init_port;
+
+       /* num_branches should be between 1-8 */
+       if (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {
+               ice_debug(hw, ICE_DBG_SCHED, "num_branches unexpected %d\n",
+                         num_branches);
+               status = ICE_ERR_PARAM;
+               goto err_init_port;
+       }
+
+       /* get the number of elements on the default/first branch */
+       num_elems = le16_to_cpu(buf[0].hdr.num_elems);
+
+       /* num_elems should always be between 1-9 */
+       if (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {
+               ice_debug(hw, ICE_DBG_SCHED, "num_elems unexpected %d\n",
+                         num_elems);
+               status = ICE_ERR_PARAM;
+               goto err_init_port;
+       }
+
+       /* If the last node is a leaf node then the index of the Q group
+        * layer is two less than the number of elements.
+        */
+       if (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==
+           ICE_AQC_ELEM_TYPE_LEAF)
+               pi->last_node_teid =
+                       le32_to_cpu(buf[0].generic[num_elems - 2].node_teid);
+       else
+               pi->last_node_teid =
+                       le32_to_cpu(buf[0].generic[num_elems - 1].node_teid);
+
+       /* Insert the Tx Sched root node */
+       status = ice_sched_add_root_node(pi, &buf[0].generic[0]);
+       if (status)
+               goto err_init_port;
+
+       /* Parse the default tree and cache the information */
+       for (i = 0; i < num_branches; i++) {
+               num_elems = le16_to_cpu(buf[i].hdr.num_elems);
+
+               /* Skip root element as already inserted */
+               for (j = 1; j < num_elems; j++) {
+                       /* update the sw entry point */
+                       if (buf[0].generic[j].data.elem_type ==
+                           ICE_AQC_ELEM_TYPE_ENTRY_POINT)
+                               hw->sw_entry_point_layer = j;
+
+                       status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
+                       if (status)
+                               goto err_init_port;
+               }
+       }
+
+       /* Remove the default nodes. */
+       if (pi->root)
+               ice_sched_rm_dflt_nodes(pi);
+
+       /* initialize the port for handling the scheduler tree */
+       pi->port_state = ICE_SCHED_PORT_STATE_READY;
+       mutex_init(&pi->sched_lock);
+       INIT_LIST_HEAD(&pi->agg_list);
+       INIT_LIST_HEAD(&pi->vsi_info_list);
+
+err_init_port:
+       if (status && pi->root) {
+               ice_free_sched_node(pi, pi->root);
+               pi->root = NULL;
+       }
+
+       devm_kfree(ice_hw_to_dev(hw), buf);
+       return status;
+}
+
+/**
  * ice_sched_query_res_alloc - query the FW for num of logical sched layers
  * @hw: pointer to the HW struct
  *
index e329f6e..2926ee9 100644 (file)
@@ -21,8 +21,14 @@ struct ice_sched_agg_info {
 };
 
 /* FW AQ command calls */
+enum ice_status ice_sched_init_port(struct ice_port_info *pi);
 enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw);
 void ice_sched_cleanup_all(struct ice_hw *hw);
+struct ice_sched_node *
+ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid);
+enum ice_status
+ice_sched_add_node(struct ice_port_info *pi, u8 layer,
+                  struct ice_aqc_txsched_elem_data *info);
 void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node);
 struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc);
 #endif /* _ICE_SCHED_H_ */
index 7e8049e..144712d 100644 (file)
@@ -15,6 +15,7 @@ enum ice_status {
        ICE_ERR_NO_MEMORY                       = -11,
        ICE_ERR_CFG                             = -12,
        ICE_ERR_OUT_OF_RANGE                    = -13,
+       ICE_ERR_BUF_TOO_SHORT                   = -52,
        ICE_ERR_NVM_BLANK_MODE                  = -53,
        ICE_ERR_AQ_ERROR                        = -100,
        ICE_ERR_AQ_TIMEOUT                      = -101,
index 0b71634..6024c80 100644 (file)
@@ -12,6 +12,7 @@
 /* debug masks - set these bits in hw->debug_mask to control output */
 #define ICE_DBG_INIT           BIT_ULL(1)
 #define ICE_DBG_NVM            BIT_ULL(7)
+#define ICE_DBG_LAN            BIT_ULL(8)
 #define ICE_DBG_SW             BIT_ULL(13)
 #define ICE_DBG_SCHED          BIT_ULL(14)
 #define ICE_DBG_RES            BIT_ULL(17)
@@ -30,12 +31,56 @@ enum ice_aq_res_access_type {
        ICE_RES_WRITE
 };
 
+enum ice_fc_mode {
+       ICE_FC_NONE = 0,
+       ICE_FC_RX_PAUSE,
+       ICE_FC_TX_PAUSE,
+       ICE_FC_FULL,
+       ICE_FC_PFC,
+       ICE_FC_DFLT
+};
+
 /* Various MAC types */
 enum ice_mac_type {
        ICE_MAC_UNKNOWN = 0,
        ICE_MAC_GENERIC,
 };
 
+/* Media Types */
+enum ice_media_type {
+       ICE_MEDIA_UNKNOWN = 0,
+       ICE_MEDIA_FIBER,
+       ICE_MEDIA_BASET,
+       ICE_MEDIA_BACKPLANE,
+       ICE_MEDIA_DA,
+};
+
+struct ice_link_status {
+       /* Refer to ice_aq_phy_type for bits definition */
+       u64 phy_type_low;
+       u16 max_frame_size;
+       u16 link_speed;
+       bool lse_ena;   /* Link Status Event notification */
+       u8 link_info;
+       u8 an_info;
+       u8 ext_info;
+       u8 pacing;
+       u8 req_speeds;
+       /* Refer to #define from module_type[ICE_MODULE_TYPE_TOTAL_BYTE] of
+        * ice_aqc_get_phy_caps structure
+        */
+       u8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];
+};
+
+/* PHY info such as phy_type, etc... */
+struct ice_phy_info {
+       struct ice_link_status link_info;
+       struct ice_link_status link_info_old;
+       u64 phy_type_low;
+       enum ice_media_type media_type;
+       bool get_link_info;
+};
+
 /* Common HW capabilities for SW use */
 struct ice_hw_common_caps {
        /* TX/RX queues */
@@ -68,6 +113,12 @@ struct ice_hw_dev_caps {
        u32 num_vsi_allocd_to_host;     /* Excluding EMP VSI */
 };
 
+/* MAC info */
+struct ice_mac_info {
+       u8 lan_addr[ETH_ALEN];
+       u8 perm_addr[ETH_ALEN];
+};
+
 /* Various RESET request, These are not tied with HW reset types */
 enum ice_reset_req {
        ICE_RESET_PFR   = 0,
@@ -81,6 +132,12 @@ struct ice_bus_info {
        u8 func;
 };
 
+/* Flow control (FC) parameters */
+struct ice_fc_info {
+       enum ice_fc_mode current_mode;  /* FC mode in effect */
+       enum ice_fc_mode req_mode;      /* FC mode requested by caller */
+};
+
 /* NVM Information */
 struct ice_nvm_info {
        u32 eetrack;              /* NVM data version */
@@ -92,6 +149,7 @@ struct ice_nvm_info {
 
 /* Max number of port to queue branches w.r.t topology */
 #define ICE_MAX_TRAFFIC_CLASS 8
+#define ICE_TXSCHED_MAX_BRANCHES ICE_MAX_TRAFFIC_CLASS
 
 struct ice_sched_node {
        struct ice_sched_node *parent;
@@ -108,6 +166,9 @@ struct ice_sched_node {
 #define ICE_SCHED_NODE_OWNER_LAN       0
 };
 
+/* Access Macros for Tx Sched Elements data */
+#define ICE_TXSCHED_GET_NODE_TEID(x) le32_to_cpu((x)->info.node_teid)
+
 /* The aggregator type determines if identifier is for a VSI group,
  * aggregator group, aggregator of queues, or queue group.
  */
@@ -138,6 +199,7 @@ struct ice_sched_tx_policy {
 struct ice_port_info {
        struct ice_sched_node *root;    /* Root Node per Port */
        struct ice_hw *hw;              /* back pointer to hw instance */
+       u32 last_node_teid;             /* scheduler last node info */
        u16 sw_id;                      /* Initial switch ID belongs to port */
        u16 pf_vf_num;
        u8 port_state;
@@ -145,6 +207,9 @@ struct ice_port_info {
 #define ICE_SCHED_PORT_STATE_READY     0x1
        u16 dflt_tx_vsi_num;
        u16 dflt_rx_vsi_num;
+       struct ice_fc_info fc;
+       struct ice_mac_info mac;
+       struct ice_phy_info phy;
        struct mutex sched_lock;        /* protect access to TXSched tree */
        struct ice_sched_tx_policy sched_policy;
        struct list_head vsi_info_list;