net/ice/base: save user provided PHY config
authorLeyi Rong <leyi.rong@intel.com>
Wed, 19 Jun 2019 15:17:49 +0000 (23:17 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 28 Jun 2019 18:31:48 +0000 (20:31 +0200)
After the transition from cable-unplug to cable-plug events, FW will
clear the set-phy-cfg data, sent by user. Thus, we will need to
cache these info.
1. The submitted data when set-phy-cfg is called. This info will be used
later to check if FW clears out the PHY info, requested by user.
2. The FC, FEC and LinkSpeed, requested by user. This info will be used
later, by device driver, to construct the new input data for the
set-phy-cfg AQ command.

Signed-off-by: Chinh T Cao <chinh.t.cao@intel.com>
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Signed-off-by: Leyi Rong <leyi.rong@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
drivers/net/ice/base/ice_common.c
drivers/net/ice/base/ice_common.h
drivers/net/ice/base/ice_type.h
drivers/net/ice/ice_ethdev.c

index 09296ea..a0ab25a 100644 (file)
@@ -270,21 +270,23 @@ 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;
+       struct ice_link_status *li_old, *li;
        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;
+       struct ice_hw *hw;
        u16 cmd_flags;
 
        if (!pi)
                return ICE_ERR_PARAM;
-       hw_link_info_old = &pi->phy.link_info_old;
+       hw = pi->hw;
+       li_old = &pi->phy.link_info_old;
        hw_media_type = &pi->phy.media_type;
-       hw_link_info = &pi->phy.link_info;
+       li = &pi->phy.link_info;
        hw_fc_info = &pi->fc;
 
        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
@@ -293,27 +295,27 @@ ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
        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);
+       status = ice_aq_send_cmd(hw, &desc, &link_data, sizeof(link_data), cd);
 
        if (status != ICE_SUCCESS)
                return status;
 
        /* save off old link status information */
-       *hw_link_info_old = *hw_link_info;
+       *li_old = *li;
 
        /* 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_link_info->phy_type_high = LE64_TO_CPU(link_data.phy_type_high);
+       li->link_speed = LE16_TO_CPU(link_data.link_speed);
+       li->phy_type_low = LE64_TO_CPU(link_data.phy_type_low);
+       li->phy_type_high = LE64_TO_CPU(link_data.phy_type_high);
        *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->fec_info = link_data.cfg & ICE_AQ_FEC_MASK;
-       hw_link_info->topo_media_conflict = link_data.topo_media_conflict;
-       hw_link_info->pacing = link_data.cfg & ICE_AQ_CFG_PACING_M;
+       li->link_info = link_data.link_info;
+       li->an_info = link_data.an_info;
+       li->ext_info = link_data.ext_info;
+       li->max_frame_size = LE16_TO_CPU(link_data.max_frame_size);
+       li->fec_info = link_data.cfg & ICE_AQ_FEC_MASK;
+       li->topo_media_conflict = link_data.topo_media_conflict;
+       li->pacing = link_data.cfg & (ICE_AQ_CFG_PACING_M |
+                                     ICE_AQ_CFG_PACING_TYPE_M);
 
        /* update fc info */
        tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);
@@ -327,13 +329,24 @@ ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
        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));
-
+       li->lse_ena = !!(resp->cmd_flags & CPU_TO_LE16(ICE_AQ_LSE_IS_ENABLED));
+
+       ice_debug(hw, ICE_DBG_LINK, "link_speed = 0x%x\n", li->link_speed);
+       ice_debug(hw, ICE_DBG_LINK, "phy_type_low = 0x%llx\n",
+                 (unsigned long long)li->phy_type_low);
+       ice_debug(hw, ICE_DBG_LINK, "phy_type_high = 0x%llx\n",
+                 (unsigned long long)li->phy_type_high);
+       ice_debug(hw, ICE_DBG_LINK, "media_type = 0x%x\n", *hw_media_type);
+       ice_debug(hw, ICE_DBG_LINK, "link_info = 0x%x\n", li->link_info);
+       ice_debug(hw, ICE_DBG_LINK, "an_info = 0x%x\n", li->an_info);
+       ice_debug(hw, ICE_DBG_LINK, "ext_info = 0x%x\n", li->ext_info);
+       ice_debug(hw, ICE_DBG_LINK, "lse_ena = 0x%x\n", li->lse_ena);
+       ice_debug(hw, ICE_DBG_LINK, "max_frame = 0x%x\n", li->max_frame_size);
+       ice_debug(hw, ICE_DBG_LINK, "pacing = 0x%x\n", li->pacing);
 
        /* save link status information */
        if (link)
-               *link = *hw_link_info;
+               *link = *li;
 
        /* flag cleared so calling functions don't call AQ again */
        pi->phy.get_link_info = false;
@@ -2412,7 +2425,7 @@ ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
 /**
  * ice_aq_set_phy_cfg
  * @hw: pointer to the HW struct
- * @lport: logical port number
+ * @pi: port info structure of the interested logical port
  * @cfg: structure with PHY configuration data to be set
  * @cd: pointer to command details structure or NULL
  *
@@ -2422,10 +2435,11 @@ ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
  * parameters. This status will be indicated by the command response (0x0601).
  */
 enum ice_status
-ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
+ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
                   struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd)
 {
        struct ice_aq_desc desc;
+       enum ice_status status;
 
        if (!cfg)
                return ICE_ERR_PARAM;
@@ -2440,10 +2454,26 @@ ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
        }
 
        ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_phy_cfg);
-       desc.params.set_phy.lport_num = lport;
+       desc.params.set_phy.lport_num = pi->lport;
        desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
 
-       return ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd);
+       ice_debug(hw, ICE_DBG_LINK, "phy_type_low = 0x%llx\n",
+                 (unsigned long long)LE64_TO_CPU(cfg->phy_type_low));
+       ice_debug(hw, ICE_DBG_LINK, "phy_type_high = 0x%llx\n",
+                 (unsigned long long)LE64_TO_CPU(cfg->phy_type_high));
+       ice_debug(hw, ICE_DBG_LINK, "caps = 0x%x\n", cfg->caps);
+       ice_debug(hw, ICE_DBG_LINK, "low_power_ctrl = 0x%x\n",
+                 cfg->low_power_ctrl);
+       ice_debug(hw, ICE_DBG_LINK, "eee_cap = 0x%x\n", cfg->eee_cap);
+       ice_debug(hw, ICE_DBG_LINK, "eeer_value = 0x%x\n", cfg->eeer_value);
+       ice_debug(hw, ICE_DBG_LINK, "link_fec_opt = 0x%x\n", cfg->link_fec_opt);
+
+       status = ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd);
+
+       if (!status)
+               pi->phy.curr_user_phy_cfg = *cfg;
+
+       return status;
 }
 
 /**
@@ -2487,6 +2517,38 @@ out:
        return status;
 }
 
+/**
+ * ice_cache_phy_user_req
+ * @pi: port information structure
+ * @cache_data: PHY logging data
+ * @cache_mode: PHY logging mode
+ *
+ * Log the user request on (FC, FEC, SPEED) for later user.
+ */
+static void
+ice_cache_phy_user_req(struct ice_port_info *pi,
+                      struct ice_phy_cache_mode_data cache_data,
+                      enum ice_phy_cache_mode cache_mode)
+{
+       if (!pi)
+               return;
+
+       switch (cache_mode) {
+       case ICE_FC_MODE:
+               pi->phy.curr_user_fc_req = cache_data.data.curr_user_fc_req;
+               break;
+       case ICE_SPEED_MODE:
+               pi->phy.curr_user_speed_req =
+                       cache_data.data.curr_user_speed_req;
+               break;
+       case ICE_FEC_MODE:
+               pi->phy.curr_user_fec_req = cache_data.data.curr_user_fec_req;
+               break;
+       default:
+               break;
+       }
+}
+
 /**
  * ice_set_fc
  * @pi: port information structure
@@ -2499,6 +2561,7 @@ enum ice_status
 ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
 {
        struct ice_aqc_set_phy_cfg_data cfg = { 0 };
+       struct ice_phy_cache_mode_data cache_data;
        struct ice_aqc_get_phy_caps_data *pcaps;
        enum ice_status status;
        u8 pause_mask = 0x0;
@@ -2509,6 +2572,10 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
        hw = pi->hw;
        *aq_failures = ICE_SET_FC_AQ_FAIL_NONE;
 
+       /* Cache user FC request */
+       cache_data.data.curr_user_fc_req = pi->fc.req_mode;
+       ice_cache_phy_user_req(pi, cache_data, ICE_FC_MODE);
+
        switch (pi->fc.req_mode) {
        case ICE_FC_FULL:
                pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
@@ -2540,8 +2607,10 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
        /* clear the old pause settings */
        cfg.caps = pcaps->caps & ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE |
                                   ICE_AQC_PHY_EN_RX_LINK_PAUSE);
+
        /* set the new capabilities */
        cfg.caps |= pause_mask;
+
        /* If the capabilities have changed, then set the new config */
        if (cfg.caps != pcaps->caps) {
                int retry_count, retry_max = 10;
@@ -2557,7 +2626,7 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
                cfg.eeer_value = pcaps->eeer_value;
                cfg.link_fec_opt = pcaps->link_fec_options;
 
-               status = ice_aq_set_phy_cfg(hw, pi->lport, &cfg, NULL);
+               status = ice_aq_set_phy_cfg(hw, pi, &cfg, NULL);
                if (status) {
                        *aq_failures = ICE_SET_FC_AQ_FAIL_SET;
                        goto out;
index aee754b..cccb5f0 100644 (file)
@@ -134,7 +134,7 @@ ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
 
 enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);
 enum ice_status
-ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
+ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
                   struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd);
 enum ice_status
 ice_set_fc(struct ice_port_info *pi, u8 *aq_failures,
index 63ef5bb..bc1ba60 100644 (file)
@@ -136,6 +136,12 @@ enum ice_fc_mode {
        ICE_FC_DFLT
 };
 
+enum ice_phy_cache_mode {
+       ICE_FC_MODE = 0,
+       ICE_SPEED_MODE,
+       ICE_FEC_MODE
+};
+
 enum ice_fec_mode {
        ICE_FEC_NONE = 0,
        ICE_FEC_RS,
@@ -143,6 +149,14 @@ enum ice_fec_mode {
        ICE_FEC_AUTO
 };
 
+struct ice_phy_cache_mode_data {
+       union {
+               enum ice_fec_mode curr_user_fec_req;
+               enum ice_fc_mode curr_user_fc_req;
+               u16 curr_user_speed_req;
+       } data;
+};
+
 enum ice_set_fc_aq_failures {
        ICE_SET_FC_AQ_FAIL_NONE = 0,
        ICE_SET_FC_AQ_FAIL_GET,
@@ -220,6 +234,13 @@ struct ice_phy_info {
        u64 phy_type_high;
        enum ice_media_type media_type;
        u8 get_link_info;
+       /* Please refer to struct ice_aqc_get_link_status_data to get
+        * detail of enable bit in curr_user_speed_req
+        */
+       u16 curr_user_speed_req;
+       enum ice_fec_mode curr_user_fec_req;
+       enum ice_fc_mode curr_user_fc_req;
+       struct ice_aqc_set_phy_cfg_data curr_user_phy_cfg;
 };
 
 #define ICE_MAX_NUM_MIRROR_RULES       64
@@ -636,6 +657,8 @@ struct ice_port_info {
        u8 port_state;
 #define ICE_SCHED_PORT_STATE_INIT      0x0
 #define ICE_SCHED_PORT_STATE_READY     0x1
+       u8 lport;
+#define ICE_LPORT_MASK                 0xff
        u16 dflt_tx_vsi_rule_id;
        u16 dflt_tx_vsi_num;
        u16 dflt_rx_vsi_rule_id;
@@ -651,11 +674,9 @@ struct ice_port_info {
        struct ice_dcbx_cfg remote_dcbx_cfg;    /* Peer Cfg */
        struct ice_dcbx_cfg desired_dcbx_cfg;   /* CEE Desired Cfg */
        /* LLDP/DCBX Status */
-       u8 dcbx_status;
-       u8 is_sw_lldp;
-       u8 lport;
-#define ICE_LPORT_MASK         0xff
-       u8 is_vf;
+       u8 dcbx_status:3;               /* see ICE_DCBX_STATUS_DIS */
+       u8 is_sw_lldp:1;
+       u8 is_vf:1;
 };
 
 struct ice_switch_info {
index 713161b..5968604 100644 (file)
@@ -2296,7 +2296,7 @@ ice_force_phys_link_state(struct ice_hw *hw, bool link_up)
        else
                cfg.caps &= ~ICE_AQ_PHY_ENA_LINK;
 
-       status = ice_aq_set_phy_cfg(hw, pi->lport, &cfg, NULL);
+       status = ice_aq_set_phy_cfg(hw, pi, &cfg, NULL);
 
 out:
        ice_free(hw, pcaps);