Currently FW use MDIO I/F number corresponded with current PF for PHY
access. This code allow to specify used MDIO I/F number.

Signed-off-by: Piotr Azarewicz <piotr.azarew...@intel.com>
Reviewed-by: Galazka Krzysztof <krzysztof.gala...@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktio...@intel.com>
Reviewed-by: Kirsher Jeffrey T <jeffrey.t.kirs...@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong...@intel.com>
---
 drivers/net/i40e/base/i40e_adminq.c     |  5 +++
 drivers/net/i40e/base/i40e_adminq_cmd.h |  6 ++-
 drivers/net/i40e/base/i40e_common.c     | 60 ++++++++++++++++++++-----
 drivers/net/i40e/base/i40e_prototype.h  | 27 +++++++----
 drivers/net/i40e/base/i40e_type.h       |  1 +
 5 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_adminq.c 
b/drivers/net/i40e/base/i40e_adminq.c
index 2cb81ed80..371a04d53 100644
--- a/drivers/net/i40e/base/i40e_adminq.c
+++ b/drivers/net/i40e/base/i40e_adminq.c
@@ -693,6 +693,11 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw)
             aq->api_min_ver >= 8))
                hw->flags |= I40E_HW_FLAG_FW_LLDP_PERSISTENT;
 
+       if (aq->api_maj_ver > 1 ||
+           (aq->api_maj_ver == 1 &&
+            aq->api_min_ver >= 9))
+               hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED;
+
        if (aq->api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
                ret_code = I40E_ERR_FIRMWARE_API_VERSION;
                goto init_adminq_free_arq;
diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h 
b/drivers/net/i40e/base/i40e_adminq_cmd.h
index 7b4703449..79762d528 100644
--- a/drivers/net/i40e/base/i40e_adminq_cmd.h
+++ b/drivers/net/i40e/base/i40e_adminq_cmd.h
@@ -2311,7 +2311,11 @@ struct i40e_aqc_phy_register_access {
 #define I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE 2
        u8      dev_addres;
        u8      cmd_flags;
-#define I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE   1
+#define I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE   0x01
+#define I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER      0x02
+#define I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT    2
+#define I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK     (0x3 << \
+               I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT)
        u8      reserved1;
        __le32  reg_address;
        __le32  reg_value;
diff --git a/drivers/net/i40e/base/i40e_common.c 
b/drivers/net/i40e/base/i40e_common.c
index d080e9340..75bb9148b 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -7376,21 +7376,51 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 
reg_addr, u32 reg_val)
 
 #ifdef PF_DRIVER
 /**
- * i40e_aq_set_phy_register
+ * i40e_mdio_if_number_selection - MDIO I/F number selection
+ * @hw: pointer to the hw struct
+ * @set_mdio: use MDIO I/F number specified by mdio_num
+ * @mdio_num: MDIO I/F number
+ * @cmd: pointer to PHY Register command structure
+ **/
+static void
+i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num,
+                             struct i40e_aqc_phy_register_access *cmd)
+{
+       if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
+               if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
+                       cmd->cmd_flags |=
+                               I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
+                               ((mdio_num <<
+                               I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
+                               I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
+               else
+                       i40e_debug(hw, I40E_DEBUG_PHY,
+                                  "MDIO I/F number selection not supported by 
current FW version.\n");
+       }
+}
+
+/**
+ * i40e_aq_set_phy_register_ext
  * @hw: pointer to the hw struct
  * @phy_select: select which phy should be accessed
  * @dev_addr: PHY device address
  * @page_change: enable auto page change
+ * @set_mdio: use MDIO I/F number specified by mdio_num
+ * @mdio_num: MDIO I/F number
  * @reg_addr: PHY register address
  * @reg_val: new register value
  * @cmd_details: pointer to command details structure or NULL
  *
  * Write the external PHY register.
+ * NOTE: In common cases MDIO I/F number should not be changed, thats why you
+ * may use simple wrapper i40e_aq_set_phy_register.
  **/
-enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr, bool page_change,
-                               u32 reg_addr, u32 reg_val,
-                               struct i40e_asq_cmd_details *cmd_details)
+enum i40e_status_code
+i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
+                            u8 phy_select, u8 dev_addr, bool page_change,
+                            bool set_mdio, u8 mdio_num,
+                            u32 reg_addr, u32 reg_val,
+                            struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
        struct i40e_aqc_phy_register_access *cmd =
@@ -7408,27 +7438,35 @@ enum i40e_status_code i40e_aq_set_phy_register(struct 
i40e_hw *hw,
        if (!page_change)
                cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
 
+       i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
+
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
 }
 
 /**
- * i40e_aq_get_phy_register
+ * i40e_aq_get_phy_register_ext
  * @hw: pointer to the hw struct
  * @phy_select: select which phy should be accessed
  * @dev_addr: PHY device address
  * @page_change: enable auto page change
+ * @set_mdio: use MDIO I/F number specified by mdio_num
+ * @mdio_num: MDIO I/F number
  * @reg_addr: PHY register address
  * @reg_val: read register value
  * @cmd_details: pointer to command details structure or NULL
  *
  * Read the external PHY register.
+ * NOTE: In common cases MDIO I/F number should not be changed, thats why you
+ * may use simple wrapper i40e_aq_get_phy_register.
  **/
-enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr, bool page_change,
-                               u32 reg_addr, u32 *reg_val,
-                               struct i40e_asq_cmd_details *cmd_details)
+enum i40e_status_code
+i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+                            u8 phy_select, u8 dev_addr, bool page_change,
+                            bool set_mdio, u8 mdio_num,
+                            u32 reg_addr, u32 *reg_val,
+                            struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
        struct i40e_aqc_phy_register_access *cmd =
@@ -7445,6 +7483,8 @@ enum i40e_status_code i40e_aq_get_phy_register(struct 
i40e_hw *hw,
        if (!page_change)
                cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
 
+       i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
+
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
        if (!status)
                *reg_val = LE32_TO_CPU(cmd->reg_value);
diff --git a/drivers/net/i40e/base/i40e_prototype.h 
b/drivers/net/i40e/base/i40e_prototype.h
index eaaeb5eea..043bfd984 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -561,14 +561,25 @@ enum i40e_status_code 
i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
                                u32 reg_addr, u32 reg_val,
                                struct i40e_asq_cmd_details *cmd_details);
 void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val);
-enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr, bool page_change,
-                               u32 reg_addr, u32 reg_val,
-                               struct i40e_asq_cmd_details *cmd_details);
-enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw,
-                               u8 phy_select, u8 dev_addr, bool page_change,
-                               u32 reg_addr, u32 *reg_val,
-                               struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code
+i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
+                            u8 phy_select, u8 dev_addr, bool page_change,
+                            bool set_mdio, u8 mdio_num,
+                            u32 reg_addr, u32 reg_val,
+                            struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code
+i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+                            u8 phy_select, u8 dev_addr, bool page_change,
+                            bool set_mdio, u8 mdio_num,
+                            u32 reg_addr, u32 *reg_val,
+                            struct i40e_asq_cmd_details *cmd_details);
+
+/* Convenience wrappers for most common use case */
+#define i40e_aq_set_phy_register(hw, ps, da, pc, ra, rv, cd) \
+       i40e_aq_set_phy_register_ext(hw, ps, da, pc, false, 0, ra, rv, cd)
+#define i40e_aq_get_phy_register(hw, ps, da, pc, ra, rv, cd) \
+       i40e_aq_get_phy_register_ext(hw, ps, da, pc, false, 0, ra, rv, cd)
+
 #ifdef PF_DRIVER
 enum i40e_status_code
 i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 opcode,
diff --git a/drivers/net/i40e/base/i40e_type.h 
b/drivers/net/i40e/base/i40e_type.h
index 6a3cf52a2..673469929 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -743,6 +743,7 @@ struct i40e_hw {
 #define I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK BIT_ULL(3)
 #define I40E_HW_FLAG_FW_LLDP_STOPPABLE     BIT_ULL(4)
 #define I40E_HW_FLAG_FW_LLDP_PERSISTENT     BIT_ULL(5)
+#define I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED BIT_ULL(6)
        u64 flags;
 
        /* Used in set switch config AQ command */
-- 
2.17.1

Reply via email to