1a0285236SJedrzej Jagielski // SPDX-License-Identifier: GPL-2.0 2a0285236SJedrzej Jagielski /* Copyright (c) 2025, Intel Corporation. */ 3a0285236SJedrzej Jagielski 4a0285236SJedrzej Jagielski #include "ixgbe.h" 5a0285236SJedrzej Jagielski #include "devlink.h" 6a0285236SJedrzej Jagielski 7f6b588afSJedrzej Jagielski struct ixgbe_info_ctx { 8f6b588afSJedrzej Jagielski char buf[128]; 9*6eae2aebSJedrzej Jagielski struct ixgbe_orom_info pending_orom; 10*6eae2aebSJedrzej Jagielski struct ixgbe_nvm_info pending_nvm; 11*6eae2aebSJedrzej Jagielski struct ixgbe_netlist_info pending_netlist; 12*6eae2aebSJedrzej Jagielski struct ixgbe_hw_dev_caps dev_caps; 13*6eae2aebSJedrzej Jagielski }; 14*6eae2aebSJedrzej Jagielski 15*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type { 16*6eae2aebSJedrzej Jagielski IXGBE_DL_VERSION_RUNNING, 17*6eae2aebSJedrzej Jagielski IXGBE_DL_VERSION_STORED 18f6b588afSJedrzej Jagielski }; 19f6b588afSJedrzej Jagielski 20f6b588afSJedrzej Jagielski static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter, 21f6b588afSJedrzej Jagielski struct ixgbe_info_ctx *ctx) 22f6b588afSJedrzej Jagielski { 23f6b588afSJedrzej Jagielski u8 dsn[8]; 24f6b588afSJedrzej Jagielski 25f6b588afSJedrzej Jagielski /* Copy the DSN into an array in Big Endian format */ 26f6b588afSJedrzej Jagielski put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn); 27f6b588afSJedrzej Jagielski 28f6b588afSJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn); 29f6b588afSJedrzej Jagielski } 30f6b588afSJedrzej Jagielski 318210ff73SJedrzej Jagielski static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter, 32*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 33*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 34f6b588afSJedrzej Jagielski { 35f6b588afSJedrzej Jagielski struct ixgbe_hw *hw = &adapter->hw; 36f6b588afSJedrzej Jagielski struct ixgbe_nvm_version nvm_ver; 37f6b588afSJedrzej Jagielski 38f6b588afSJedrzej Jagielski ctx->buf[0] = '\0'; 39f6b588afSJedrzej Jagielski 408210ff73SJedrzej Jagielski if (hw->mac.type == ixgbe_mac_e610) { 418210ff73SJedrzej Jagielski struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; 428210ff73SJedrzej Jagielski 43*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 44*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_orom) 45*6eae2aebSJedrzej Jagielski orom = &ctx->pending_orom; 46*6eae2aebSJedrzej Jagielski 478210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", 488210ff73SJedrzej Jagielski orom->major, orom->build, orom->patch); 498210ff73SJedrzej Jagielski return; 508210ff73SJedrzej Jagielski } 518210ff73SJedrzej Jagielski 52f6b588afSJedrzej Jagielski ixgbe_get_oem_prod_version(hw, &nvm_ver); 53f6b588afSJedrzej Jagielski if (nvm_ver.oem_valid) { 54f6b588afSJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x", 55f6b588afSJedrzej Jagielski nvm_ver.oem_major, nvm_ver.oem_minor, 56f6b588afSJedrzej Jagielski nvm_ver.oem_release); 57f6b588afSJedrzej Jagielski 58f6b588afSJedrzej Jagielski return; 59f6b588afSJedrzej Jagielski } 60f6b588afSJedrzej Jagielski 61f6b588afSJedrzej Jagielski ixgbe_get_orom_version(hw, &nvm_ver); 62f6b588afSJedrzej Jagielski if (nvm_ver.or_valid) 63f6b588afSJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d", 64f6b588afSJedrzej Jagielski nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch); 65f6b588afSJedrzej Jagielski } 66f6b588afSJedrzej Jagielski 67f6b588afSJedrzej Jagielski static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter, 68*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 69*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 70f6b588afSJedrzej Jagielski { 71f6b588afSJedrzej Jagielski struct ixgbe_hw *hw = &adapter->hw; 72f6b588afSJedrzej Jagielski struct ixgbe_nvm_version nvm_ver; 73f6b588afSJedrzej Jagielski 748210ff73SJedrzej Jagielski if (hw->mac.type == ixgbe_mac_e610) { 75*6eae2aebSJedrzej Jagielski u32 eetrack = hw->flash.nvm.eetrack; 76*6eae2aebSJedrzej Jagielski 77*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 78*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_nvm) 79*6eae2aebSJedrzej Jagielski eetrack = ctx->pending_nvm.eetrack; 80*6eae2aebSJedrzej Jagielski 81*6eae2aebSJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", eetrack); 828210ff73SJedrzej Jagielski return; 838210ff73SJedrzej Jagielski } 848210ff73SJedrzej Jagielski 85f6b588afSJedrzej Jagielski ixgbe_get_oem_prod_version(hw, &nvm_ver); 86f6b588afSJedrzej Jagielski 87f6b588afSJedrzej Jagielski /* No ETRACK version for OEM */ 88f6b588afSJedrzej Jagielski if (nvm_ver.oem_valid) { 89f6b588afSJedrzej Jagielski ctx->buf[0] = '\0'; 90f6b588afSJedrzej Jagielski return; 91f6b588afSJedrzej Jagielski } 92f6b588afSJedrzej Jagielski 93f6b588afSJedrzej Jagielski ixgbe_get_etk_id(hw, &nvm_ver); 94f6b588afSJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm_ver.etk_id); 95f6b588afSJedrzej Jagielski } 96f6b588afSJedrzej Jagielski 978210ff73SJedrzej Jagielski static void ixgbe_info_fw_api(struct ixgbe_adapter *adapter, 988210ff73SJedrzej Jagielski struct ixgbe_info_ctx *ctx) 998210ff73SJedrzej Jagielski { 1008210ff73SJedrzej Jagielski struct ixgbe_hw *hw = &adapter->hw; 1018210ff73SJedrzej Jagielski 1028210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", 1038210ff73SJedrzej Jagielski hw->api_maj_ver, hw->api_min_ver, hw->api_patch); 1048210ff73SJedrzej Jagielski } 1058210ff73SJedrzej Jagielski 1068210ff73SJedrzej Jagielski static void ixgbe_info_fw_build(struct ixgbe_adapter *adapter, 1078210ff73SJedrzej Jagielski struct ixgbe_info_ctx *ctx) 1088210ff73SJedrzej Jagielski { 1098210ff73SJedrzej Jagielski struct ixgbe_hw *hw = &adapter->hw; 1108210ff73SJedrzej Jagielski 1118210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build); 1128210ff73SJedrzej Jagielski } 1138210ff73SJedrzej Jagielski 1148210ff73SJedrzej Jagielski static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter, 115*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 116*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 1178210ff73SJedrzej Jagielski { 1188210ff73SJedrzej Jagielski struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; 1198210ff73SJedrzej Jagielski 120*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 121*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_nvm) 122*6eae2aebSJedrzej Jagielski nvm = &ctx->pending_nvm; 123*6eae2aebSJedrzej Jagielski 1248210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev); 1258210ff73SJedrzej Jagielski } 1268210ff73SJedrzej Jagielski 1278210ff73SJedrzej Jagielski static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter, 128*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 129*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 1308210ff73SJedrzej Jagielski { 1318210ff73SJedrzej Jagielski struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; 1328210ff73SJedrzej Jagielski 133*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 134*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_orom) 135*6eae2aebSJedrzej Jagielski orom = &ctx->pending_orom; 136*6eae2aebSJedrzej Jagielski 1378210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev); 1388210ff73SJedrzej Jagielski } 1398210ff73SJedrzej Jagielski 1408210ff73SJedrzej Jagielski static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter, 141*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 142*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 1438210ff73SJedrzej Jagielski { 1448210ff73SJedrzej Jagielski struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; 1458210ff73SJedrzej Jagielski 146*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 147*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_nvm) 148*6eae2aebSJedrzej Jagielski nvm = &ctx->pending_nvm; 149*6eae2aebSJedrzej Jagielski 1508210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor); 1518210ff73SJedrzej Jagielski } 1528210ff73SJedrzej Jagielski 1538210ff73SJedrzej Jagielski static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter, 154*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 155*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 1568210ff73SJedrzej Jagielski { 1578210ff73SJedrzej Jagielski struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; 1588210ff73SJedrzej Jagielski 159*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 160*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_netlist) 161*6eae2aebSJedrzej Jagielski netlist = &ctx->pending_netlist; 162*6eae2aebSJedrzej Jagielski 1638210ff73SJedrzej Jagielski /* The netlist version fields are BCD formatted */ 1648210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", 1658210ff73SJedrzej Jagielski netlist->major, netlist->minor, 1668210ff73SJedrzej Jagielski netlist->type >> 16, netlist->type & 0xFFFF, 1678210ff73SJedrzej Jagielski netlist->rev, netlist->cust_ver); 1688210ff73SJedrzej Jagielski } 1698210ff73SJedrzej Jagielski 1708210ff73SJedrzej Jagielski static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter, 171*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 172*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type type) 1738210ff73SJedrzej Jagielski { 1748210ff73SJedrzej Jagielski struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; 1758210ff73SJedrzej Jagielski 176*6eae2aebSJedrzej Jagielski if (type == IXGBE_DL_VERSION_STORED && 177*6eae2aebSJedrzej Jagielski ctx->dev_caps.common_cap.nvm_update_pending_netlist) 178*6eae2aebSJedrzej Jagielski netlist = &ctx->pending_netlist; 179*6eae2aebSJedrzej Jagielski 1808210ff73SJedrzej Jagielski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); 1818210ff73SJedrzej Jagielski } 1828210ff73SJedrzej Jagielski 183*6eae2aebSJedrzej Jagielski static int ixgbe_set_ctx_dev_caps(struct ixgbe_hw *hw, 184*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx, 185*6eae2aebSJedrzej Jagielski struct netlink_ext_ack *extack) 186*6eae2aebSJedrzej Jagielski { 187*6eae2aebSJedrzej Jagielski bool *pending_orom, *pending_nvm, *pending_netlist; 188*6eae2aebSJedrzej Jagielski int err; 189*6eae2aebSJedrzej Jagielski 190*6eae2aebSJedrzej Jagielski err = ixgbe_discover_dev_caps(hw, &ctx->dev_caps); 191*6eae2aebSJedrzej Jagielski if (err) { 192*6eae2aebSJedrzej Jagielski NL_SET_ERR_MSG_MOD(extack, 193*6eae2aebSJedrzej Jagielski "Unable to discover device capabilities"); 194*6eae2aebSJedrzej Jagielski return err; 195*6eae2aebSJedrzej Jagielski } 196*6eae2aebSJedrzej Jagielski 197*6eae2aebSJedrzej Jagielski pending_orom = &ctx->dev_caps.common_cap.nvm_update_pending_orom; 198*6eae2aebSJedrzej Jagielski pending_nvm = &ctx->dev_caps.common_cap.nvm_update_pending_nvm; 199*6eae2aebSJedrzej Jagielski pending_netlist = &ctx->dev_caps.common_cap.nvm_update_pending_netlist; 200*6eae2aebSJedrzej Jagielski 201*6eae2aebSJedrzej Jagielski if (*pending_orom) { 202*6eae2aebSJedrzej Jagielski err = ixgbe_get_inactive_orom_ver(hw, &ctx->pending_orom); 203*6eae2aebSJedrzej Jagielski if (err) 204*6eae2aebSJedrzej Jagielski *pending_orom = false; 205*6eae2aebSJedrzej Jagielski } 206*6eae2aebSJedrzej Jagielski 207*6eae2aebSJedrzej Jagielski if (*pending_nvm) { 208*6eae2aebSJedrzej Jagielski err = ixgbe_get_inactive_nvm_ver(hw, &ctx->pending_nvm); 209*6eae2aebSJedrzej Jagielski if (err) 210*6eae2aebSJedrzej Jagielski *pending_nvm = false; 211*6eae2aebSJedrzej Jagielski } 212*6eae2aebSJedrzej Jagielski 213*6eae2aebSJedrzej Jagielski if (*pending_netlist) { 214*6eae2aebSJedrzej Jagielski err = ixgbe_get_inactive_netlist_ver(hw, &ctx->pending_netlist); 215*6eae2aebSJedrzej Jagielski if (err) 216*6eae2aebSJedrzej Jagielski *pending_netlist = false; 217*6eae2aebSJedrzej Jagielski } 218*6eae2aebSJedrzej Jagielski 219*6eae2aebSJedrzej Jagielski return 0; 220*6eae2aebSJedrzej Jagielski } 221*6eae2aebSJedrzej Jagielski 2228210ff73SJedrzej Jagielski static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter, 2238210ff73SJedrzej Jagielski struct devlink_info_req *req, 2248210ff73SJedrzej Jagielski struct ixgbe_info_ctx *ctx) 2258210ff73SJedrzej Jagielski { 2268210ff73SJedrzej Jagielski int err; 2278210ff73SJedrzej Jagielski 2288210ff73SJedrzej Jagielski ixgbe_info_fw_api(adapter, ctx); 2298210ff73SJedrzej Jagielski err = devlink_info_version_running_put(req, 2308210ff73SJedrzej Jagielski DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API, 2318210ff73SJedrzej Jagielski ctx->buf); 2328210ff73SJedrzej Jagielski if (err) 2338210ff73SJedrzej Jagielski return err; 2348210ff73SJedrzej Jagielski 2358210ff73SJedrzej Jagielski ixgbe_info_fw_build(adapter, ctx); 2368210ff73SJedrzej Jagielski err = devlink_info_version_running_put(req, "fw.mgmt.build", ctx->buf); 2378210ff73SJedrzej Jagielski if (err) 2388210ff73SJedrzej Jagielski return err; 2398210ff73SJedrzej Jagielski 240*6eae2aebSJedrzej Jagielski ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 2418210ff73SJedrzej Jagielski err = devlink_info_version_running_put(req, "fw.mgmt.srev", ctx->buf); 2428210ff73SJedrzej Jagielski if (err) 2438210ff73SJedrzej Jagielski return err; 2448210ff73SJedrzej Jagielski 245*6eae2aebSJedrzej Jagielski ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 2468210ff73SJedrzej Jagielski err = devlink_info_version_running_put(req, "fw.undi.srev", ctx->buf); 2478210ff73SJedrzej Jagielski if (err) 2488210ff73SJedrzej Jagielski return err; 2498210ff73SJedrzej Jagielski 250*6eae2aebSJedrzej Jagielski ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 2518210ff73SJedrzej Jagielski err = devlink_info_version_running_put(req, "fw.psid.api", ctx->buf); 2528210ff73SJedrzej Jagielski if (err) 2538210ff73SJedrzej Jagielski return err; 2548210ff73SJedrzej Jagielski 255*6eae2aebSJedrzej Jagielski ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 2568210ff73SJedrzej Jagielski err = devlink_info_version_running_put(req, "fw.netlist", ctx->buf); 2578210ff73SJedrzej Jagielski if (err) 2588210ff73SJedrzej Jagielski return err; 2598210ff73SJedrzej Jagielski 260*6eae2aebSJedrzej Jagielski ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 2618210ff73SJedrzej Jagielski return devlink_info_version_running_put(req, "fw.netlist.build", 2628210ff73SJedrzej Jagielski ctx->buf); 2638210ff73SJedrzej Jagielski } 2648210ff73SJedrzej Jagielski 265*6eae2aebSJedrzej Jagielski static int 266*6eae2aebSJedrzej Jagielski ixgbe_devlink_pending_info_get_e610(struct ixgbe_adapter *adapter, 267*6eae2aebSJedrzej Jagielski struct devlink_info_req *req, 268*6eae2aebSJedrzej Jagielski struct ixgbe_info_ctx *ctx) 269*6eae2aebSJedrzej Jagielski { 270*6eae2aebSJedrzej Jagielski int err; 271*6eae2aebSJedrzej Jagielski 272*6eae2aebSJedrzej Jagielski ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_STORED); 273*6eae2aebSJedrzej Jagielski err = devlink_info_version_stored_put(req, 274*6eae2aebSJedrzej Jagielski DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, 275*6eae2aebSJedrzej Jagielski ctx->buf); 276*6eae2aebSJedrzej Jagielski if (err) 277*6eae2aebSJedrzej Jagielski return err; 278*6eae2aebSJedrzej Jagielski 279*6eae2aebSJedrzej Jagielski ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_STORED); 280*6eae2aebSJedrzej Jagielski err = devlink_info_version_stored_put(req, 281*6eae2aebSJedrzej Jagielski DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, 282*6eae2aebSJedrzej Jagielski ctx->buf); 283*6eae2aebSJedrzej Jagielski if (err) 284*6eae2aebSJedrzej Jagielski return err; 285*6eae2aebSJedrzej Jagielski 286*6eae2aebSJedrzej Jagielski ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_STORED); 287*6eae2aebSJedrzej Jagielski err = devlink_info_version_stored_put(req, "fw.mgmt.srev", ctx->buf); 288*6eae2aebSJedrzej Jagielski if (err) 289*6eae2aebSJedrzej Jagielski return err; 290*6eae2aebSJedrzej Jagielski 291*6eae2aebSJedrzej Jagielski ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_STORED); 292*6eae2aebSJedrzej Jagielski err = devlink_info_version_stored_put(req, "fw.undi.srev", ctx->buf); 293*6eae2aebSJedrzej Jagielski if (err) 294*6eae2aebSJedrzej Jagielski return err; 295*6eae2aebSJedrzej Jagielski 296*6eae2aebSJedrzej Jagielski ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_STORED); 297*6eae2aebSJedrzej Jagielski err = devlink_info_version_stored_put(req, "fw.psid.api", ctx->buf); 298*6eae2aebSJedrzej Jagielski if (err) 299*6eae2aebSJedrzej Jagielski return err; 300*6eae2aebSJedrzej Jagielski 301*6eae2aebSJedrzej Jagielski ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_STORED); 302*6eae2aebSJedrzej Jagielski err = devlink_info_version_stored_put(req, "fw.netlist", ctx->buf); 303*6eae2aebSJedrzej Jagielski if (err) 304*6eae2aebSJedrzej Jagielski return err; 305*6eae2aebSJedrzej Jagielski 306*6eae2aebSJedrzej Jagielski ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_STORED); 307*6eae2aebSJedrzej Jagielski return devlink_info_version_stored_put(req, "fw.netlist.build", 308*6eae2aebSJedrzej Jagielski ctx->buf); 309*6eae2aebSJedrzej Jagielski } 310*6eae2aebSJedrzej Jagielski 311f6b588afSJedrzej Jagielski static int ixgbe_devlink_info_get(struct devlink *devlink, 312f6b588afSJedrzej Jagielski struct devlink_info_req *req, 313f6b588afSJedrzej Jagielski struct netlink_ext_ack *extack) 314f6b588afSJedrzej Jagielski { 315f6b588afSJedrzej Jagielski struct ixgbe_adapter *adapter = devlink_priv(devlink); 316f6b588afSJedrzej Jagielski struct ixgbe_hw *hw = &adapter->hw; 317f6b588afSJedrzej Jagielski struct ixgbe_info_ctx *ctx; 318f6b588afSJedrzej Jagielski int err; 319f6b588afSJedrzej Jagielski 320f6b588afSJedrzej Jagielski ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); 321f6b588afSJedrzej Jagielski if (!ctx) 322f6b588afSJedrzej Jagielski return -ENOMEM; 323f6b588afSJedrzej Jagielski 324f6b588afSJedrzej Jagielski ixgbe_info_get_dsn(adapter, ctx); 325f6b588afSJedrzej Jagielski err = devlink_info_serial_number_put(req, ctx->buf); 326f6b588afSJedrzej Jagielski if (err) 327f6b588afSJedrzej Jagielski goto free_ctx; 328f6b588afSJedrzej Jagielski 3294654ec61SJedrzej Jagielski err = hw->eeprom.ops.read_pba_string(hw, ctx->buf, sizeof(ctx->buf)); 330f6b588afSJedrzej Jagielski if (err) 331f6b588afSJedrzej Jagielski goto free_ctx; 332f6b588afSJedrzej Jagielski 333f6b588afSJedrzej Jagielski err = devlink_info_version_fixed_put(req, 334f6b588afSJedrzej Jagielski DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, 335f6b588afSJedrzej Jagielski ctx->buf); 336f6b588afSJedrzej Jagielski if (err) 337f6b588afSJedrzej Jagielski goto free_ctx; 338f6b588afSJedrzej Jagielski 339*6eae2aebSJedrzej Jagielski ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 340f6b588afSJedrzej Jagielski err = devlink_info_version_running_put(req, 341f6b588afSJedrzej Jagielski DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, 342f6b588afSJedrzej Jagielski ctx->buf); 343f6b588afSJedrzej Jagielski if (err) 344f6b588afSJedrzej Jagielski goto free_ctx; 345f6b588afSJedrzej Jagielski 346*6eae2aebSJedrzej Jagielski ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_RUNNING); 347f6b588afSJedrzej Jagielski err = devlink_info_version_running_put(req, 348f6b588afSJedrzej Jagielski DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, 349f6b588afSJedrzej Jagielski ctx->buf); 3508210ff73SJedrzej Jagielski if (err || hw->mac.type != ixgbe_mac_e610) 3518210ff73SJedrzej Jagielski goto free_ctx; 3528210ff73SJedrzej Jagielski 353*6eae2aebSJedrzej Jagielski err = ixgbe_set_ctx_dev_caps(hw, ctx, extack); 354*6eae2aebSJedrzej Jagielski if (err) 355*6eae2aebSJedrzej Jagielski goto free_ctx; 356*6eae2aebSJedrzej Jagielski 3578210ff73SJedrzej Jagielski err = ixgbe_devlink_info_get_e610(adapter, req, ctx); 358*6eae2aebSJedrzej Jagielski if (err) 359*6eae2aebSJedrzej Jagielski goto free_ctx; 360*6eae2aebSJedrzej Jagielski 361*6eae2aebSJedrzej Jagielski err = ixgbe_devlink_pending_info_get_e610(adapter, req, ctx); 362f6b588afSJedrzej Jagielski free_ctx: 363f6b588afSJedrzej Jagielski kfree(ctx); 364f6b588afSJedrzej Jagielski return err; 365f6b588afSJedrzej Jagielski } 366f6b588afSJedrzej Jagielski 367a0285236SJedrzej Jagielski static const struct devlink_ops ixgbe_devlink_ops = { 368f6b588afSJedrzej Jagielski .info_get = ixgbe_devlink_info_get, 369a0285236SJedrzej Jagielski }; 370a0285236SJedrzej Jagielski 371a0285236SJedrzej Jagielski /** 372a0285236SJedrzej Jagielski * ixgbe_allocate_devlink - Allocate devlink instance 373a0285236SJedrzej Jagielski * @dev: device to allocate devlink for 374a0285236SJedrzej Jagielski * 375a0285236SJedrzej Jagielski * Allocate a devlink instance for this physical function. 376a0285236SJedrzej Jagielski * 377a0285236SJedrzej Jagielski * Return: pointer to the device adapter structure on success, 378a0285236SJedrzej Jagielski * ERR_PTR(-ENOMEM) when allocation failed. 379a0285236SJedrzej Jagielski */ 380a0285236SJedrzej Jagielski struct ixgbe_adapter *ixgbe_allocate_devlink(struct device *dev) 381a0285236SJedrzej Jagielski { 382a0285236SJedrzej Jagielski struct ixgbe_adapter *adapter; 383a0285236SJedrzej Jagielski struct devlink *devlink; 384a0285236SJedrzej Jagielski 385a0285236SJedrzej Jagielski devlink = devlink_alloc(&ixgbe_devlink_ops, sizeof(*adapter), dev); 386a0285236SJedrzej Jagielski if (!devlink) 387a0285236SJedrzej Jagielski return ERR_PTR(-ENOMEM); 388a0285236SJedrzej Jagielski 389a0285236SJedrzej Jagielski adapter = devlink_priv(devlink); 390a0285236SJedrzej Jagielski adapter->devlink = devlink; 391a0285236SJedrzej Jagielski 392a0285236SJedrzej Jagielski return adapter; 393a0285236SJedrzej Jagielski } 394a0285236SJedrzej Jagielski 395a0285236SJedrzej Jagielski /** 396a0285236SJedrzej Jagielski * ixgbe_devlink_set_switch_id - Set unique switch ID based on PCI DSN 397a0285236SJedrzej Jagielski * @adapter: pointer to the device adapter structure 398a0285236SJedrzej Jagielski * @ppid: struct with switch id information 399a0285236SJedrzej Jagielski */ 400a0285236SJedrzej Jagielski static void ixgbe_devlink_set_switch_id(struct ixgbe_adapter *adapter, 401a0285236SJedrzej Jagielski struct netdev_phys_item_id *ppid) 402a0285236SJedrzej Jagielski { 403a0285236SJedrzej Jagielski u64 id = pci_get_dsn(adapter->pdev); 404a0285236SJedrzej Jagielski 405a0285236SJedrzej Jagielski ppid->id_len = sizeof(id); 406a0285236SJedrzej Jagielski put_unaligned_be64(id, &ppid->id); 407a0285236SJedrzej Jagielski } 408a0285236SJedrzej Jagielski 409a0285236SJedrzej Jagielski /** 410a0285236SJedrzej Jagielski * ixgbe_devlink_register_port - Register devlink port 411a0285236SJedrzej Jagielski * @adapter: pointer to the device adapter structure 412a0285236SJedrzej Jagielski * 413a0285236SJedrzej Jagielski * Create and register a devlink_port for this physical function. 414a0285236SJedrzej Jagielski * 415a0285236SJedrzej Jagielski * Return: 0 on success, error code on failure. 416a0285236SJedrzej Jagielski */ 417a0285236SJedrzej Jagielski int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter) 418a0285236SJedrzej Jagielski { 419a0285236SJedrzej Jagielski struct devlink_port *devlink_port = &adapter->devlink_port; 420a0285236SJedrzej Jagielski struct devlink *devlink = adapter->devlink; 421a0285236SJedrzej Jagielski struct device *dev = &adapter->pdev->dev; 422a0285236SJedrzej Jagielski struct devlink_port_attrs attrs = {}; 423a0285236SJedrzej Jagielski int err; 424a0285236SJedrzej Jagielski 425a0285236SJedrzej Jagielski attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 426a0285236SJedrzej Jagielski attrs.phys.port_number = adapter->hw.bus.func; 427a0285236SJedrzej Jagielski ixgbe_devlink_set_switch_id(adapter, &attrs.switch_id); 428a0285236SJedrzej Jagielski 429a0285236SJedrzej Jagielski devlink_port_attrs_set(devlink_port, &attrs); 430a0285236SJedrzej Jagielski 431a0285236SJedrzej Jagielski err = devl_port_register(devlink, devlink_port, 0); 432a0285236SJedrzej Jagielski if (err) { 433a0285236SJedrzej Jagielski dev_err(dev, 434a0285236SJedrzej Jagielski "devlink port registration failed, err %d\n", err); 435a0285236SJedrzej Jagielski } 436a0285236SJedrzej Jagielski 437a0285236SJedrzej Jagielski return err; 438a0285236SJedrzej Jagielski } 439