diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/devlink/devlink.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/devlink/devlink.c | 170 |
1 files changed, 154 insertions, 16 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c index a7c39e951c7b..f7bafc1dad2b 100644 --- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c +++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c @@ -6,6 +6,15 @@ struct ixgbe_info_ctx { char buf[128]; + struct ixgbe_orom_info pending_orom; + struct ixgbe_nvm_info pending_nvm; + struct ixgbe_netlist_info pending_netlist; + struct ixgbe_hw_dev_caps dev_caps; +}; + +enum ixgbe_devlink_version_type { + IXGBE_DL_VERSION_RUNNING, + IXGBE_DL_VERSION_STORED }; static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter, @@ -20,7 +29,8 @@ static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter, } static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_nvm_version nvm_ver; @@ -30,6 +40,10 @@ static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter, if (hw->mac.type == ixgbe_mac_e610) { struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_orom) + orom = &ctx->pending_orom; + snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", orom->major, orom->build, orom->patch); return; @@ -51,14 +65,20 @@ static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter, } static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_nvm_version nvm_ver; if (hw->mac.type == ixgbe_mac_e610) { - snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", - hw->flash.nvm.eetrack); + u32 eetrack = hw->flash.nvm.eetrack; + + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_nvm) + eetrack = ctx->pending_nvm.eetrack; + + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", eetrack); return; } @@ -92,34 +112,54 @@ static void ixgbe_info_fw_build(struct ixgbe_adapter *adapter, } static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_nvm) + nvm = &ctx->pending_nvm; + snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev); } static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_orom) + orom = &ctx->pending_orom; + snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev); } static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_nvm) + nvm = &ctx->pending_nvm; + snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor); } static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_netlist) + netlist = &ctx->pending_netlist; + /* The netlist version fields are BCD formatted */ snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", netlist->major, netlist->minor, @@ -128,13 +168,57 @@ static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter, } static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter, - struct ixgbe_info_ctx *ctx) + struct ixgbe_info_ctx *ctx, + enum ixgbe_devlink_version_type type) { struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; + if (type == IXGBE_DL_VERSION_STORED && + ctx->dev_caps.common_cap.nvm_update_pending_netlist) + netlist = &ctx->pending_netlist; + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); } +static int ixgbe_set_ctx_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_info_ctx *ctx, + struct netlink_ext_ack *extack) +{ + bool *pending_orom, *pending_nvm, *pending_netlist; + int err; + + err = ixgbe_discover_dev_caps(hw, &ctx->dev_caps); + if (err) { + NL_SET_ERR_MSG_MOD(extack, + "Unable to discover device capabilities"); + return err; + } + + pending_orom = &ctx->dev_caps.common_cap.nvm_update_pending_orom; + pending_nvm = &ctx->dev_caps.common_cap.nvm_update_pending_nvm; + pending_netlist = &ctx->dev_caps.common_cap.nvm_update_pending_netlist; + + if (*pending_orom) { + err = ixgbe_get_inactive_orom_ver(hw, &ctx->pending_orom); + if (err) + *pending_orom = false; + } + + if (*pending_nvm) { + err = ixgbe_get_inactive_nvm_ver(hw, &ctx->pending_nvm); + if (err) + *pending_nvm = false; + } + + if (*pending_netlist) { + err = ixgbe_get_inactive_netlist_ver(hw, &ctx->pending_netlist); + if (err) + *pending_netlist = false; + } + + return 0; +} + static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter, struct devlink_info_req *req, struct ixgbe_info_ctx *ctx) @@ -153,31 +237,77 @@ static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter, if (err) return err; - ixgbe_info_fw_srev(adapter, ctx); + ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING); err = devlink_info_version_running_put(req, "fw.mgmt.srev", ctx->buf); if (err) return err; - ixgbe_info_orom_srev(adapter, ctx); + ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING); err = devlink_info_version_running_put(req, "fw.undi.srev", ctx->buf); if (err) return err; - ixgbe_info_nvm_ver(adapter, ctx); + ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING); err = devlink_info_version_running_put(req, "fw.psid.api", ctx->buf); if (err) return err; - ixgbe_info_netlist_ver(adapter, ctx); + ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING); err = devlink_info_version_running_put(req, "fw.netlist", ctx->buf); if (err) return err; - ixgbe_info_netlist_build(adapter, ctx); + ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_RUNNING); return devlink_info_version_running_put(req, "fw.netlist.build", ctx->buf); } +static int +ixgbe_devlink_pending_info_get_e610(struct ixgbe_adapter *adapter, + struct devlink_info_req *req, + struct ixgbe_info_ctx *ctx) +{ + int err; + + ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_STORED); + err = devlink_info_version_stored_put(req, + DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, + ctx->buf); + if (err) + return err; + + ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_STORED); + err = devlink_info_version_stored_put(req, + DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, + ctx->buf); + if (err) + return err; + + ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_STORED); + err = devlink_info_version_stored_put(req, "fw.mgmt.srev", ctx->buf); + if (err) + return err; + + ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_STORED); + err = devlink_info_version_stored_put(req, "fw.undi.srev", ctx->buf); + if (err) + return err; + + ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_STORED); + err = devlink_info_version_stored_put(req, "fw.psid.api", ctx->buf); + if (err) + return err; + + ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_STORED); + err = devlink_info_version_stored_put(req, "fw.netlist", ctx->buf); + if (err) + return err; + + ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_STORED); + return devlink_info_version_stored_put(req, "fw.netlist.build", + ctx->buf); +} + static int ixgbe_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, struct netlink_ext_ack *extack) @@ -206,21 +336,29 @@ static int ixgbe_devlink_info_get(struct devlink *devlink, if (err) goto free_ctx; - ixgbe_info_orom_ver(adapter, ctx); + ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING); err = devlink_info_version_running_put(req, DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ctx->buf); if (err) goto free_ctx; - ixgbe_info_eetrack(adapter, ctx); + ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_RUNNING); err = devlink_info_version_running_put(req, DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ctx->buf); if (err || hw->mac.type != ixgbe_mac_e610) goto free_ctx; + err = ixgbe_set_ctx_dev_caps(hw, ctx, extack); + if (err) + goto free_ctx; + err = ixgbe_devlink_info_get_e610(adapter, req, ctx); + if (err) + goto free_ctx; + + err = ixgbe_devlink_pending_info_get_e610(adapter, req, ctx); free_ctx: kfree(ctx); return err; |
