1*0545cc86SMichal Swiatkowski // SPDX-License-Identifier: GPL-2.0 2*0545cc86SMichal Swiatkowski /* Copyright (c) 2020, Intel Corporation. */ 3*0545cc86SMichal Swiatkowski 4*0545cc86SMichal Swiatkowski #include <linux/vmalloc.h> 5*0545cc86SMichal Swiatkowski 6*0545cc86SMichal Swiatkowski #include "ice.h" 7*0545cc86SMichal Swiatkowski #include "ice_lib.h" 8*0545cc86SMichal Swiatkowski #include "devlink.h" 9*0545cc86SMichal Swiatkowski #include "ice_eswitch.h" 10*0545cc86SMichal Swiatkowski #include "ice_fw_update.h" 11*0545cc86SMichal Swiatkowski #include "ice_dcb_lib.h" 12*0545cc86SMichal Swiatkowski 13*0545cc86SMichal Swiatkowski static int ice_active_port_option = -1; 14*0545cc86SMichal Swiatkowski 15*0545cc86SMichal Swiatkowski /* context for devlink info version reporting */ 16*0545cc86SMichal Swiatkowski struct ice_info_ctx { 17*0545cc86SMichal Swiatkowski char buf[128]; 18*0545cc86SMichal Swiatkowski struct ice_orom_info pending_orom; 19*0545cc86SMichal Swiatkowski struct ice_nvm_info pending_nvm; 20*0545cc86SMichal Swiatkowski struct ice_netlist_info pending_netlist; 21*0545cc86SMichal Swiatkowski struct ice_hw_dev_caps dev_caps; 22*0545cc86SMichal Swiatkowski }; 23*0545cc86SMichal Swiatkowski 24*0545cc86SMichal Swiatkowski /* The following functions are used to format specific strings for various 25*0545cc86SMichal Swiatkowski * devlink info versions. The ctx parameter is used to provide the storage 26*0545cc86SMichal Swiatkowski * buffer, as well as any ancillary information calculated when the info 27*0545cc86SMichal Swiatkowski * request was made. 28*0545cc86SMichal Swiatkowski * 29*0545cc86SMichal Swiatkowski * If a version does not exist, for example when attempting to get the 30*0545cc86SMichal Swiatkowski * inactive version of flash when there is no pending update, the function 31*0545cc86SMichal Swiatkowski * should leave the buffer in the ctx structure empty. 32*0545cc86SMichal Swiatkowski */ 33*0545cc86SMichal Swiatkowski 34*0545cc86SMichal Swiatkowski static void ice_info_get_dsn(struct ice_pf *pf, struct ice_info_ctx *ctx) 35*0545cc86SMichal Swiatkowski { 36*0545cc86SMichal Swiatkowski u8 dsn[8]; 37*0545cc86SMichal Swiatkowski 38*0545cc86SMichal Swiatkowski /* Copy the DSN into an array in Big Endian format */ 39*0545cc86SMichal Swiatkowski put_unaligned_be64(pci_get_dsn(pf->pdev), dsn); 40*0545cc86SMichal Swiatkowski 41*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn); 42*0545cc86SMichal Swiatkowski } 43*0545cc86SMichal Swiatkowski 44*0545cc86SMichal Swiatkowski static void ice_info_pba(struct ice_pf *pf, struct ice_info_ctx *ctx) 45*0545cc86SMichal Swiatkowski { 46*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 47*0545cc86SMichal Swiatkowski int status; 48*0545cc86SMichal Swiatkowski 49*0545cc86SMichal Swiatkowski status = ice_read_pba_string(hw, (u8 *)ctx->buf, sizeof(ctx->buf)); 50*0545cc86SMichal Swiatkowski if (status) 51*0545cc86SMichal Swiatkowski /* We failed to locate the PBA, so just skip this entry */ 52*0545cc86SMichal Swiatkowski dev_dbg(ice_pf_to_dev(pf), "Failed to read Product Board Assembly string, status %d\n", 53*0545cc86SMichal Swiatkowski status); 54*0545cc86SMichal Swiatkowski } 55*0545cc86SMichal Swiatkowski 56*0545cc86SMichal Swiatkowski static void ice_info_fw_mgmt(struct ice_pf *pf, struct ice_info_ctx *ctx) 57*0545cc86SMichal Swiatkowski { 58*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 59*0545cc86SMichal Swiatkowski 60*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", 61*0545cc86SMichal Swiatkowski hw->fw_maj_ver, hw->fw_min_ver, hw->fw_patch); 62*0545cc86SMichal Swiatkowski } 63*0545cc86SMichal Swiatkowski 64*0545cc86SMichal Swiatkowski static void ice_info_fw_api(struct ice_pf *pf, struct ice_info_ctx *ctx) 65*0545cc86SMichal Swiatkowski { 66*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 67*0545cc86SMichal Swiatkowski 68*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", hw->api_maj_ver, 69*0545cc86SMichal Swiatkowski hw->api_min_ver, hw->api_patch); 70*0545cc86SMichal Swiatkowski } 71*0545cc86SMichal Swiatkowski 72*0545cc86SMichal Swiatkowski static void ice_info_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx) 73*0545cc86SMichal Swiatkowski { 74*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 75*0545cc86SMichal Swiatkowski 76*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build); 77*0545cc86SMichal Swiatkowski } 78*0545cc86SMichal Swiatkowski 79*0545cc86SMichal Swiatkowski static void ice_info_orom_ver(struct ice_pf *pf, struct ice_info_ctx *ctx) 80*0545cc86SMichal Swiatkowski { 81*0545cc86SMichal Swiatkowski struct ice_orom_info *orom = &pf->hw.flash.orom; 82*0545cc86SMichal Swiatkowski 83*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", 84*0545cc86SMichal Swiatkowski orom->major, orom->build, orom->patch); 85*0545cc86SMichal Swiatkowski } 86*0545cc86SMichal Swiatkowski 87*0545cc86SMichal Swiatkowski static void 88*0545cc86SMichal Swiatkowski ice_info_pending_orom_ver(struct ice_pf __always_unused *pf, 89*0545cc86SMichal Swiatkowski struct ice_info_ctx *ctx) 90*0545cc86SMichal Swiatkowski { 91*0545cc86SMichal Swiatkowski struct ice_orom_info *orom = &ctx->pending_orom; 92*0545cc86SMichal Swiatkowski 93*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_orom) 94*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", 95*0545cc86SMichal Swiatkowski orom->major, orom->build, orom->patch); 96*0545cc86SMichal Swiatkowski } 97*0545cc86SMichal Swiatkowski 98*0545cc86SMichal Swiatkowski static void ice_info_nvm_ver(struct ice_pf *pf, struct ice_info_ctx *ctx) 99*0545cc86SMichal Swiatkowski { 100*0545cc86SMichal Swiatkowski struct ice_nvm_info *nvm = &pf->hw.flash.nvm; 101*0545cc86SMichal Swiatkowski 102*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor); 103*0545cc86SMichal Swiatkowski } 104*0545cc86SMichal Swiatkowski 105*0545cc86SMichal Swiatkowski static void 106*0545cc86SMichal Swiatkowski ice_info_pending_nvm_ver(struct ice_pf __always_unused *pf, 107*0545cc86SMichal Swiatkowski struct ice_info_ctx *ctx) 108*0545cc86SMichal Swiatkowski { 109*0545cc86SMichal Swiatkowski struct ice_nvm_info *nvm = &ctx->pending_nvm; 110*0545cc86SMichal Swiatkowski 111*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) 112*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", 113*0545cc86SMichal Swiatkowski nvm->major, nvm->minor); 114*0545cc86SMichal Swiatkowski } 115*0545cc86SMichal Swiatkowski 116*0545cc86SMichal Swiatkowski static void ice_info_eetrack(struct ice_pf *pf, struct ice_info_ctx *ctx) 117*0545cc86SMichal Swiatkowski { 118*0545cc86SMichal Swiatkowski struct ice_nvm_info *nvm = &pf->hw.flash.nvm; 119*0545cc86SMichal Swiatkowski 120*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack); 121*0545cc86SMichal Swiatkowski } 122*0545cc86SMichal Swiatkowski 123*0545cc86SMichal Swiatkowski static void 124*0545cc86SMichal Swiatkowski ice_info_pending_eetrack(struct ice_pf *pf, struct ice_info_ctx *ctx) 125*0545cc86SMichal Swiatkowski { 126*0545cc86SMichal Swiatkowski struct ice_nvm_info *nvm = &ctx->pending_nvm; 127*0545cc86SMichal Swiatkowski 128*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) 129*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack); 130*0545cc86SMichal Swiatkowski } 131*0545cc86SMichal Swiatkowski 132*0545cc86SMichal Swiatkowski static void ice_info_ddp_pkg_name(struct ice_pf *pf, struct ice_info_ctx *ctx) 133*0545cc86SMichal Swiatkowski { 134*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 135*0545cc86SMichal Swiatkowski 136*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%s", hw->active_pkg_name); 137*0545cc86SMichal Swiatkowski } 138*0545cc86SMichal Swiatkowski 139*0545cc86SMichal Swiatkowski static void 140*0545cc86SMichal Swiatkowski ice_info_ddp_pkg_version(struct ice_pf *pf, struct ice_info_ctx *ctx) 141*0545cc86SMichal Swiatkowski { 142*0545cc86SMichal Swiatkowski struct ice_pkg_ver *pkg = &pf->hw.active_pkg_ver; 143*0545cc86SMichal Swiatkowski 144*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u.%u", 145*0545cc86SMichal Swiatkowski pkg->major, pkg->minor, pkg->update, pkg->draft); 146*0545cc86SMichal Swiatkowski } 147*0545cc86SMichal Swiatkowski 148*0545cc86SMichal Swiatkowski static void 149*0545cc86SMichal Swiatkowski ice_info_ddp_pkg_bundle_id(struct ice_pf *pf, struct ice_info_ctx *ctx) 150*0545cc86SMichal Swiatkowski { 151*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", pf->hw.active_track_id); 152*0545cc86SMichal Swiatkowski } 153*0545cc86SMichal Swiatkowski 154*0545cc86SMichal Swiatkowski static void ice_info_netlist_ver(struct ice_pf *pf, struct ice_info_ctx *ctx) 155*0545cc86SMichal Swiatkowski { 156*0545cc86SMichal Swiatkowski struct ice_netlist_info *netlist = &pf->hw.flash.netlist; 157*0545cc86SMichal Swiatkowski 158*0545cc86SMichal Swiatkowski /* The netlist version fields are BCD formatted */ 159*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", 160*0545cc86SMichal Swiatkowski netlist->major, netlist->minor, 161*0545cc86SMichal Swiatkowski netlist->type >> 16, netlist->type & 0xFFFF, 162*0545cc86SMichal Swiatkowski netlist->rev, netlist->cust_ver); 163*0545cc86SMichal Swiatkowski } 164*0545cc86SMichal Swiatkowski 165*0545cc86SMichal Swiatkowski static void ice_info_netlist_build(struct ice_pf *pf, struct ice_info_ctx *ctx) 166*0545cc86SMichal Swiatkowski { 167*0545cc86SMichal Swiatkowski struct ice_netlist_info *netlist = &pf->hw.flash.netlist; 168*0545cc86SMichal Swiatkowski 169*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); 170*0545cc86SMichal Swiatkowski } 171*0545cc86SMichal Swiatkowski 172*0545cc86SMichal Swiatkowski static void 173*0545cc86SMichal Swiatkowski ice_info_pending_netlist_ver(struct ice_pf __always_unused *pf, 174*0545cc86SMichal Swiatkowski struct ice_info_ctx *ctx) 175*0545cc86SMichal Swiatkowski { 176*0545cc86SMichal Swiatkowski struct ice_netlist_info *netlist = &ctx->pending_netlist; 177*0545cc86SMichal Swiatkowski 178*0545cc86SMichal Swiatkowski /* The netlist version fields are BCD formatted */ 179*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) 180*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", 181*0545cc86SMichal Swiatkowski netlist->major, netlist->minor, 182*0545cc86SMichal Swiatkowski netlist->type >> 16, netlist->type & 0xFFFF, 183*0545cc86SMichal Swiatkowski netlist->rev, netlist->cust_ver); 184*0545cc86SMichal Swiatkowski } 185*0545cc86SMichal Swiatkowski 186*0545cc86SMichal Swiatkowski static void 187*0545cc86SMichal Swiatkowski ice_info_pending_netlist_build(struct ice_pf __always_unused *pf, 188*0545cc86SMichal Swiatkowski struct ice_info_ctx *ctx) 189*0545cc86SMichal Swiatkowski { 190*0545cc86SMichal Swiatkowski struct ice_netlist_info *netlist = &ctx->pending_netlist; 191*0545cc86SMichal Swiatkowski 192*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) 193*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); 194*0545cc86SMichal Swiatkowski } 195*0545cc86SMichal Swiatkowski 196*0545cc86SMichal Swiatkowski static void ice_info_cgu_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx) 197*0545cc86SMichal Swiatkowski { 198*0545cc86SMichal Swiatkowski u32 id, cfg_ver, fw_ver; 199*0545cc86SMichal Swiatkowski 200*0545cc86SMichal Swiatkowski if (!ice_is_feature_supported(pf, ICE_F_CGU)) 201*0545cc86SMichal Swiatkowski return; 202*0545cc86SMichal Swiatkowski if (ice_aq_get_cgu_info(&pf->hw, &id, &cfg_ver, &fw_ver)) 203*0545cc86SMichal Swiatkowski return; 204*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", id, cfg_ver, fw_ver); 205*0545cc86SMichal Swiatkowski } 206*0545cc86SMichal Swiatkowski 207*0545cc86SMichal Swiatkowski static void ice_info_cgu_id(struct ice_pf *pf, struct ice_info_ctx *ctx) 208*0545cc86SMichal Swiatkowski { 209*0545cc86SMichal Swiatkowski if (!ice_is_feature_supported(pf, ICE_F_CGU)) 210*0545cc86SMichal Swiatkowski return; 211*0545cc86SMichal Swiatkowski snprintf(ctx->buf, sizeof(ctx->buf), "%u", pf->hw.cgu_part_number); 212*0545cc86SMichal Swiatkowski } 213*0545cc86SMichal Swiatkowski 214*0545cc86SMichal Swiatkowski #define fixed(key, getter) { ICE_VERSION_FIXED, key, getter, NULL } 215*0545cc86SMichal Swiatkowski #define running(key, getter) { ICE_VERSION_RUNNING, key, getter, NULL } 216*0545cc86SMichal Swiatkowski #define stored(key, getter, fallback) { ICE_VERSION_STORED, key, getter, fallback } 217*0545cc86SMichal Swiatkowski 218*0545cc86SMichal Swiatkowski /* The combined() macro inserts both the running entry as well as a stored 219*0545cc86SMichal Swiatkowski * entry. The running entry will always report the version from the active 220*0545cc86SMichal Swiatkowski * handler. The stored entry will first try the pending handler, and fallback 221*0545cc86SMichal Swiatkowski * to the active handler if the pending function does not report a version. 222*0545cc86SMichal Swiatkowski * The pending handler should check the status of a pending update for the 223*0545cc86SMichal Swiatkowski * relevant flash component. It should only fill in the buffer in the case 224*0545cc86SMichal Swiatkowski * where a valid pending version is available. This ensures that the related 225*0545cc86SMichal Swiatkowski * stored and running versions remain in sync, and that stored versions are 226*0545cc86SMichal Swiatkowski * correctly reported as expected. 227*0545cc86SMichal Swiatkowski */ 228*0545cc86SMichal Swiatkowski #define combined(key, active, pending) \ 229*0545cc86SMichal Swiatkowski running(key, active), \ 230*0545cc86SMichal Swiatkowski stored(key, pending, active) 231*0545cc86SMichal Swiatkowski 232*0545cc86SMichal Swiatkowski enum ice_version_type { 233*0545cc86SMichal Swiatkowski ICE_VERSION_FIXED, 234*0545cc86SMichal Swiatkowski ICE_VERSION_RUNNING, 235*0545cc86SMichal Swiatkowski ICE_VERSION_STORED, 236*0545cc86SMichal Swiatkowski }; 237*0545cc86SMichal Swiatkowski 238*0545cc86SMichal Swiatkowski static const struct ice_devlink_version { 239*0545cc86SMichal Swiatkowski enum ice_version_type type; 240*0545cc86SMichal Swiatkowski const char *key; 241*0545cc86SMichal Swiatkowski void (*getter)(struct ice_pf *pf, struct ice_info_ctx *ctx); 242*0545cc86SMichal Swiatkowski void (*fallback)(struct ice_pf *pf, struct ice_info_ctx *ctx); 243*0545cc86SMichal Swiatkowski } ice_devlink_versions[] = { 244*0545cc86SMichal Swiatkowski fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, ice_info_pba), 245*0545cc86SMichal Swiatkowski running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, ice_info_fw_mgmt), 246*0545cc86SMichal Swiatkowski running("fw.mgmt.api", ice_info_fw_api), 247*0545cc86SMichal Swiatkowski running("fw.mgmt.build", ice_info_fw_build), 248*0545cc86SMichal Swiatkowski combined(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ice_info_orom_ver, ice_info_pending_orom_ver), 249*0545cc86SMichal Swiatkowski combined("fw.psid.api", ice_info_nvm_ver, ice_info_pending_nvm_ver), 250*0545cc86SMichal Swiatkowski combined(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ice_info_eetrack, ice_info_pending_eetrack), 251*0545cc86SMichal Swiatkowski running("fw.app.name", ice_info_ddp_pkg_name), 252*0545cc86SMichal Swiatkowski running(DEVLINK_INFO_VERSION_GENERIC_FW_APP, ice_info_ddp_pkg_version), 253*0545cc86SMichal Swiatkowski running("fw.app.bundle_id", ice_info_ddp_pkg_bundle_id), 254*0545cc86SMichal Swiatkowski combined("fw.netlist", ice_info_netlist_ver, ice_info_pending_netlist_ver), 255*0545cc86SMichal Swiatkowski combined("fw.netlist.build", ice_info_netlist_build, ice_info_pending_netlist_build), 256*0545cc86SMichal Swiatkowski fixed("cgu.id", ice_info_cgu_id), 257*0545cc86SMichal Swiatkowski running("fw.cgu", ice_info_cgu_fw_build), 258*0545cc86SMichal Swiatkowski }; 259*0545cc86SMichal Swiatkowski 260*0545cc86SMichal Swiatkowski /** 261*0545cc86SMichal Swiatkowski * ice_devlink_info_get - .info_get devlink handler 262*0545cc86SMichal Swiatkowski * @devlink: devlink instance structure 263*0545cc86SMichal Swiatkowski * @req: the devlink info request 264*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 265*0545cc86SMichal Swiatkowski * 266*0545cc86SMichal Swiatkowski * Callback for the devlink .info_get operation. Reports information about the 267*0545cc86SMichal Swiatkowski * device. 268*0545cc86SMichal Swiatkowski * 269*0545cc86SMichal Swiatkowski * Return: zero on success or an error code on failure. 270*0545cc86SMichal Swiatkowski */ 271*0545cc86SMichal Swiatkowski static int ice_devlink_info_get(struct devlink *devlink, 272*0545cc86SMichal Swiatkowski struct devlink_info_req *req, 273*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 274*0545cc86SMichal Swiatkowski { 275*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 276*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 277*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 278*0545cc86SMichal Swiatkowski struct ice_info_ctx *ctx; 279*0545cc86SMichal Swiatkowski size_t i; 280*0545cc86SMichal Swiatkowski int err; 281*0545cc86SMichal Swiatkowski 282*0545cc86SMichal Swiatkowski err = ice_wait_for_reset(pf, 10 * HZ); 283*0545cc86SMichal Swiatkowski if (err) { 284*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Device is busy resetting"); 285*0545cc86SMichal Swiatkowski return err; 286*0545cc86SMichal Swiatkowski } 287*0545cc86SMichal Swiatkowski 288*0545cc86SMichal Swiatkowski ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 289*0545cc86SMichal Swiatkowski if (!ctx) 290*0545cc86SMichal Swiatkowski return -ENOMEM; 291*0545cc86SMichal Swiatkowski 292*0545cc86SMichal Swiatkowski /* discover capabilities first */ 293*0545cc86SMichal Swiatkowski err = ice_discover_dev_caps(hw, &ctx->dev_caps); 294*0545cc86SMichal Swiatkowski if (err) { 295*0545cc86SMichal Swiatkowski dev_dbg(dev, "Failed to discover device capabilities, status %d aq_err %s\n", 296*0545cc86SMichal Swiatkowski err, ice_aq_str(hw->adminq.sq_last_status)); 297*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unable to discover device capabilities"); 298*0545cc86SMichal Swiatkowski goto out_free_ctx; 299*0545cc86SMichal Swiatkowski } 300*0545cc86SMichal Swiatkowski 301*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_orom) { 302*0545cc86SMichal Swiatkowski err = ice_get_inactive_orom_ver(hw, &ctx->pending_orom); 303*0545cc86SMichal Swiatkowski if (err) { 304*0545cc86SMichal Swiatkowski dev_dbg(dev, "Unable to read inactive Option ROM version data, status %d aq_err %s\n", 305*0545cc86SMichal Swiatkowski err, ice_aq_str(hw->adminq.sq_last_status)); 306*0545cc86SMichal Swiatkowski 307*0545cc86SMichal Swiatkowski /* disable display of pending Option ROM */ 308*0545cc86SMichal Swiatkowski ctx->dev_caps.common_cap.nvm_update_pending_orom = false; 309*0545cc86SMichal Swiatkowski } 310*0545cc86SMichal Swiatkowski } 311*0545cc86SMichal Swiatkowski 312*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) { 313*0545cc86SMichal Swiatkowski err = ice_get_inactive_nvm_ver(hw, &ctx->pending_nvm); 314*0545cc86SMichal Swiatkowski if (err) { 315*0545cc86SMichal Swiatkowski dev_dbg(dev, "Unable to read inactive NVM version data, status %d aq_err %s\n", 316*0545cc86SMichal Swiatkowski err, ice_aq_str(hw->adminq.sq_last_status)); 317*0545cc86SMichal Swiatkowski 318*0545cc86SMichal Swiatkowski /* disable display of pending Option ROM */ 319*0545cc86SMichal Swiatkowski ctx->dev_caps.common_cap.nvm_update_pending_nvm = false; 320*0545cc86SMichal Swiatkowski } 321*0545cc86SMichal Swiatkowski } 322*0545cc86SMichal Swiatkowski 323*0545cc86SMichal Swiatkowski if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) { 324*0545cc86SMichal Swiatkowski err = ice_get_inactive_netlist_ver(hw, &ctx->pending_netlist); 325*0545cc86SMichal Swiatkowski if (err) { 326*0545cc86SMichal Swiatkowski dev_dbg(dev, "Unable to read inactive Netlist version data, status %d aq_err %s\n", 327*0545cc86SMichal Swiatkowski err, ice_aq_str(hw->adminq.sq_last_status)); 328*0545cc86SMichal Swiatkowski 329*0545cc86SMichal Swiatkowski /* disable display of pending Option ROM */ 330*0545cc86SMichal Swiatkowski ctx->dev_caps.common_cap.nvm_update_pending_netlist = false; 331*0545cc86SMichal Swiatkowski } 332*0545cc86SMichal Swiatkowski } 333*0545cc86SMichal Swiatkowski 334*0545cc86SMichal Swiatkowski ice_info_get_dsn(pf, ctx); 335*0545cc86SMichal Swiatkowski 336*0545cc86SMichal Swiatkowski err = devlink_info_serial_number_put(req, ctx->buf); 337*0545cc86SMichal Swiatkowski if (err) { 338*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unable to set serial number"); 339*0545cc86SMichal Swiatkowski goto out_free_ctx; 340*0545cc86SMichal Swiatkowski } 341*0545cc86SMichal Swiatkowski 342*0545cc86SMichal Swiatkowski for (i = 0; i < ARRAY_SIZE(ice_devlink_versions); i++) { 343*0545cc86SMichal Swiatkowski enum ice_version_type type = ice_devlink_versions[i].type; 344*0545cc86SMichal Swiatkowski const char *key = ice_devlink_versions[i].key; 345*0545cc86SMichal Swiatkowski 346*0545cc86SMichal Swiatkowski memset(ctx->buf, 0, sizeof(ctx->buf)); 347*0545cc86SMichal Swiatkowski 348*0545cc86SMichal Swiatkowski ice_devlink_versions[i].getter(pf, ctx); 349*0545cc86SMichal Swiatkowski 350*0545cc86SMichal Swiatkowski /* If the default getter doesn't report a version, use the 351*0545cc86SMichal Swiatkowski * fallback function. This is primarily useful in the case of 352*0545cc86SMichal Swiatkowski * "stored" versions that want to report the same value as the 353*0545cc86SMichal Swiatkowski * running version in the normal case of no pending update. 354*0545cc86SMichal Swiatkowski */ 355*0545cc86SMichal Swiatkowski if (ctx->buf[0] == '\0' && ice_devlink_versions[i].fallback) 356*0545cc86SMichal Swiatkowski ice_devlink_versions[i].fallback(pf, ctx); 357*0545cc86SMichal Swiatkowski 358*0545cc86SMichal Swiatkowski /* Do not report missing versions */ 359*0545cc86SMichal Swiatkowski if (ctx->buf[0] == '\0') 360*0545cc86SMichal Swiatkowski continue; 361*0545cc86SMichal Swiatkowski 362*0545cc86SMichal Swiatkowski switch (type) { 363*0545cc86SMichal Swiatkowski case ICE_VERSION_FIXED: 364*0545cc86SMichal Swiatkowski err = devlink_info_version_fixed_put(req, key, ctx->buf); 365*0545cc86SMichal Swiatkowski if (err) { 366*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unable to set fixed version"); 367*0545cc86SMichal Swiatkowski goto out_free_ctx; 368*0545cc86SMichal Swiatkowski } 369*0545cc86SMichal Swiatkowski break; 370*0545cc86SMichal Swiatkowski case ICE_VERSION_RUNNING: 371*0545cc86SMichal Swiatkowski err = devlink_info_version_running_put(req, key, ctx->buf); 372*0545cc86SMichal Swiatkowski if (err) { 373*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unable to set running version"); 374*0545cc86SMichal Swiatkowski goto out_free_ctx; 375*0545cc86SMichal Swiatkowski } 376*0545cc86SMichal Swiatkowski break; 377*0545cc86SMichal Swiatkowski case ICE_VERSION_STORED: 378*0545cc86SMichal Swiatkowski err = devlink_info_version_stored_put(req, key, ctx->buf); 379*0545cc86SMichal Swiatkowski if (err) { 380*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unable to set stored version"); 381*0545cc86SMichal Swiatkowski goto out_free_ctx; 382*0545cc86SMichal Swiatkowski } 383*0545cc86SMichal Swiatkowski break; 384*0545cc86SMichal Swiatkowski } 385*0545cc86SMichal Swiatkowski } 386*0545cc86SMichal Swiatkowski 387*0545cc86SMichal Swiatkowski out_free_ctx: 388*0545cc86SMichal Swiatkowski kfree(ctx); 389*0545cc86SMichal Swiatkowski return err; 390*0545cc86SMichal Swiatkowski } 391*0545cc86SMichal Swiatkowski 392*0545cc86SMichal Swiatkowski /** 393*0545cc86SMichal Swiatkowski * ice_devlink_reload_empr_start - Start EMP reset to activate new firmware 394*0545cc86SMichal Swiatkowski * @pf: pointer to the pf instance 395*0545cc86SMichal Swiatkowski * @extack: netlink extended ACK structure 396*0545cc86SMichal Swiatkowski * 397*0545cc86SMichal Swiatkowski * Allow user to activate new Embedded Management Processor firmware by 398*0545cc86SMichal Swiatkowski * issuing device specific EMP reset. Called in response to 399*0545cc86SMichal Swiatkowski * a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE. 400*0545cc86SMichal Swiatkowski * 401*0545cc86SMichal Swiatkowski * Note that teardown and rebuild of the driver state happens automatically as 402*0545cc86SMichal Swiatkowski * part of an interrupt and watchdog task. This is because all physical 403*0545cc86SMichal Swiatkowski * functions on the device must be able to reset when an EMP reset occurs from 404*0545cc86SMichal Swiatkowski * any source. 405*0545cc86SMichal Swiatkowski */ 406*0545cc86SMichal Swiatkowski static int 407*0545cc86SMichal Swiatkowski ice_devlink_reload_empr_start(struct ice_pf *pf, 408*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 409*0545cc86SMichal Swiatkowski { 410*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 411*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 412*0545cc86SMichal Swiatkowski u8 pending; 413*0545cc86SMichal Swiatkowski int err; 414*0545cc86SMichal Swiatkowski 415*0545cc86SMichal Swiatkowski err = ice_get_pending_updates(pf, &pending, extack); 416*0545cc86SMichal Swiatkowski if (err) 417*0545cc86SMichal Swiatkowski return err; 418*0545cc86SMichal Swiatkowski 419*0545cc86SMichal Swiatkowski /* pending is a bitmask of which flash banks have a pending update, 420*0545cc86SMichal Swiatkowski * including the main NVM bank, the Option ROM bank, and the netlist 421*0545cc86SMichal Swiatkowski * bank. If any of these bits are set, then there is a pending update 422*0545cc86SMichal Swiatkowski * waiting to be activated. 423*0545cc86SMichal Swiatkowski */ 424*0545cc86SMichal Swiatkowski if (!pending) { 425*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "No pending firmware update"); 426*0545cc86SMichal Swiatkowski return -ECANCELED; 427*0545cc86SMichal Swiatkowski } 428*0545cc86SMichal Swiatkowski 429*0545cc86SMichal Swiatkowski if (pf->fw_emp_reset_disabled) { 430*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "EMP reset is not available. To activate firmware, a reboot or power cycle is needed"); 431*0545cc86SMichal Swiatkowski return -ECANCELED; 432*0545cc86SMichal Swiatkowski } 433*0545cc86SMichal Swiatkowski 434*0545cc86SMichal Swiatkowski dev_dbg(dev, "Issuing device EMP reset to activate firmware\n"); 435*0545cc86SMichal Swiatkowski 436*0545cc86SMichal Swiatkowski err = ice_aq_nvm_update_empr(hw); 437*0545cc86SMichal Swiatkowski if (err) { 438*0545cc86SMichal Swiatkowski dev_err(dev, "Failed to trigger EMP device reset to reload firmware, err %d aq_err %s\n", 439*0545cc86SMichal Swiatkowski err, ice_aq_str(hw->adminq.sq_last_status)); 440*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to trigger EMP device reset to reload firmware"); 441*0545cc86SMichal Swiatkowski return err; 442*0545cc86SMichal Swiatkowski } 443*0545cc86SMichal Swiatkowski 444*0545cc86SMichal Swiatkowski return 0; 445*0545cc86SMichal Swiatkowski } 446*0545cc86SMichal Swiatkowski 447*0545cc86SMichal Swiatkowski /** 448*0545cc86SMichal Swiatkowski * ice_devlink_reinit_down - unload given PF 449*0545cc86SMichal Swiatkowski * @pf: pointer to the PF struct 450*0545cc86SMichal Swiatkowski */ 451*0545cc86SMichal Swiatkowski static void ice_devlink_reinit_down(struct ice_pf *pf) 452*0545cc86SMichal Swiatkowski { 453*0545cc86SMichal Swiatkowski /* No need to take devl_lock, it's already taken by devlink API */ 454*0545cc86SMichal Swiatkowski ice_unload(pf); 455*0545cc86SMichal Swiatkowski rtnl_lock(); 456*0545cc86SMichal Swiatkowski ice_vsi_decfg(ice_get_main_vsi(pf)); 457*0545cc86SMichal Swiatkowski rtnl_unlock(); 458*0545cc86SMichal Swiatkowski ice_deinit_dev(pf); 459*0545cc86SMichal Swiatkowski } 460*0545cc86SMichal Swiatkowski 461*0545cc86SMichal Swiatkowski /** 462*0545cc86SMichal Swiatkowski * ice_devlink_reload_down - prepare for reload 463*0545cc86SMichal Swiatkowski * @devlink: pointer to the devlink instance to reload 464*0545cc86SMichal Swiatkowski * @netns_change: if true, the network namespace is changing 465*0545cc86SMichal Swiatkowski * @action: the action to perform 466*0545cc86SMichal Swiatkowski * @limit: limits on what reload should do, such as not resetting 467*0545cc86SMichal Swiatkowski * @extack: netlink extended ACK structure 468*0545cc86SMichal Swiatkowski */ 469*0545cc86SMichal Swiatkowski static int 470*0545cc86SMichal Swiatkowski ice_devlink_reload_down(struct devlink *devlink, bool netns_change, 471*0545cc86SMichal Swiatkowski enum devlink_reload_action action, 472*0545cc86SMichal Swiatkowski enum devlink_reload_limit limit, 473*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 474*0545cc86SMichal Swiatkowski { 475*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 476*0545cc86SMichal Swiatkowski 477*0545cc86SMichal Swiatkowski switch (action) { 478*0545cc86SMichal Swiatkowski case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 479*0545cc86SMichal Swiatkowski if (ice_is_eswitch_mode_switchdev(pf)) { 480*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, 481*0545cc86SMichal Swiatkowski "Go to legacy mode before doing reinit"); 482*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 483*0545cc86SMichal Swiatkowski } 484*0545cc86SMichal Swiatkowski if (ice_is_adq_active(pf)) { 485*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, 486*0545cc86SMichal Swiatkowski "Turn off ADQ before doing reinit"); 487*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 488*0545cc86SMichal Swiatkowski } 489*0545cc86SMichal Swiatkowski if (ice_has_vfs(pf)) { 490*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, 491*0545cc86SMichal Swiatkowski "Remove all VFs before doing reinit"); 492*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 493*0545cc86SMichal Swiatkowski } 494*0545cc86SMichal Swiatkowski ice_devlink_reinit_down(pf); 495*0545cc86SMichal Swiatkowski return 0; 496*0545cc86SMichal Swiatkowski case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 497*0545cc86SMichal Swiatkowski return ice_devlink_reload_empr_start(pf, extack); 498*0545cc86SMichal Swiatkowski default: 499*0545cc86SMichal Swiatkowski WARN_ON(1); 500*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 501*0545cc86SMichal Swiatkowski } 502*0545cc86SMichal Swiatkowski } 503*0545cc86SMichal Swiatkowski 504*0545cc86SMichal Swiatkowski /** 505*0545cc86SMichal Swiatkowski * ice_devlink_reload_empr_finish - Wait for EMP reset to finish 506*0545cc86SMichal Swiatkowski * @pf: pointer to the pf instance 507*0545cc86SMichal Swiatkowski * @extack: netlink extended ACK structure 508*0545cc86SMichal Swiatkowski * 509*0545cc86SMichal Swiatkowski * Wait for driver to finish rebuilding after EMP reset is completed. This 510*0545cc86SMichal Swiatkowski * includes time to wait for both the actual device reset as well as the time 511*0545cc86SMichal Swiatkowski * for the driver's rebuild to complete. 512*0545cc86SMichal Swiatkowski */ 513*0545cc86SMichal Swiatkowski static int 514*0545cc86SMichal Swiatkowski ice_devlink_reload_empr_finish(struct ice_pf *pf, 515*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 516*0545cc86SMichal Swiatkowski { 517*0545cc86SMichal Swiatkowski int err; 518*0545cc86SMichal Swiatkowski 519*0545cc86SMichal Swiatkowski err = ice_wait_for_reset(pf, 60 * HZ); 520*0545cc86SMichal Swiatkowski if (err) { 521*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Device still resetting after 1 minute"); 522*0545cc86SMichal Swiatkowski return err; 523*0545cc86SMichal Swiatkowski } 524*0545cc86SMichal Swiatkowski 525*0545cc86SMichal Swiatkowski return 0; 526*0545cc86SMichal Swiatkowski } 527*0545cc86SMichal Swiatkowski 528*0545cc86SMichal Swiatkowski /** 529*0545cc86SMichal Swiatkowski * ice_devlink_port_opt_speed_str - convert speed to a string 530*0545cc86SMichal Swiatkowski * @speed: speed value 531*0545cc86SMichal Swiatkowski */ 532*0545cc86SMichal Swiatkowski static const char *ice_devlink_port_opt_speed_str(u8 speed) 533*0545cc86SMichal Swiatkowski { 534*0545cc86SMichal Swiatkowski switch (speed & ICE_AQC_PORT_OPT_MAX_LANE_M) { 535*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_100M: 536*0545cc86SMichal Swiatkowski return "0.1"; 537*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_1G: 538*0545cc86SMichal Swiatkowski return "1"; 539*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_2500M: 540*0545cc86SMichal Swiatkowski return "2.5"; 541*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_5G: 542*0545cc86SMichal Swiatkowski return "5"; 543*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_10G: 544*0545cc86SMichal Swiatkowski return "10"; 545*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_25G: 546*0545cc86SMichal Swiatkowski return "25"; 547*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_50G: 548*0545cc86SMichal Swiatkowski return "50"; 549*0545cc86SMichal Swiatkowski case ICE_AQC_PORT_OPT_MAX_LANE_100G: 550*0545cc86SMichal Swiatkowski return "100"; 551*0545cc86SMichal Swiatkowski } 552*0545cc86SMichal Swiatkowski 553*0545cc86SMichal Swiatkowski return "-"; 554*0545cc86SMichal Swiatkowski } 555*0545cc86SMichal Swiatkowski 556*0545cc86SMichal Swiatkowski #define ICE_PORT_OPT_DESC_LEN 50 557*0545cc86SMichal Swiatkowski /** 558*0545cc86SMichal Swiatkowski * ice_devlink_port_options_print - Print available port split options 559*0545cc86SMichal Swiatkowski * @pf: the PF to print split port options 560*0545cc86SMichal Swiatkowski * 561*0545cc86SMichal Swiatkowski * Prints a table with available port split options and max port speeds 562*0545cc86SMichal Swiatkowski */ 563*0545cc86SMichal Swiatkowski static void ice_devlink_port_options_print(struct ice_pf *pf) 564*0545cc86SMichal Swiatkowski { 565*0545cc86SMichal Swiatkowski u8 i, j, options_count, cnt, speed, pending_idx, active_idx; 566*0545cc86SMichal Swiatkowski struct ice_aqc_get_port_options_elem *options, *opt; 567*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 568*0545cc86SMichal Swiatkowski bool active_valid, pending_valid; 569*0545cc86SMichal Swiatkowski char desc[ICE_PORT_OPT_DESC_LEN]; 570*0545cc86SMichal Swiatkowski const char *str; 571*0545cc86SMichal Swiatkowski int status; 572*0545cc86SMichal Swiatkowski 573*0545cc86SMichal Swiatkowski options = kcalloc(ICE_AQC_PORT_OPT_MAX * ICE_MAX_PORT_PER_PCI_DEV, 574*0545cc86SMichal Swiatkowski sizeof(*options), GFP_KERNEL); 575*0545cc86SMichal Swiatkowski if (!options) 576*0545cc86SMichal Swiatkowski return; 577*0545cc86SMichal Swiatkowski 578*0545cc86SMichal Swiatkowski for (i = 0; i < ICE_MAX_PORT_PER_PCI_DEV; i++) { 579*0545cc86SMichal Swiatkowski opt = options + i * ICE_AQC_PORT_OPT_MAX; 580*0545cc86SMichal Swiatkowski options_count = ICE_AQC_PORT_OPT_MAX; 581*0545cc86SMichal Swiatkowski active_valid = 0; 582*0545cc86SMichal Swiatkowski 583*0545cc86SMichal Swiatkowski status = ice_aq_get_port_options(&pf->hw, opt, &options_count, 584*0545cc86SMichal Swiatkowski i, true, &active_idx, 585*0545cc86SMichal Swiatkowski &active_valid, &pending_idx, 586*0545cc86SMichal Swiatkowski &pending_valid); 587*0545cc86SMichal Swiatkowski if (status) { 588*0545cc86SMichal Swiatkowski dev_dbg(dev, "Couldn't read port option for port %d, err %d\n", 589*0545cc86SMichal Swiatkowski i, status); 590*0545cc86SMichal Swiatkowski goto err; 591*0545cc86SMichal Swiatkowski } 592*0545cc86SMichal Swiatkowski } 593*0545cc86SMichal Swiatkowski 594*0545cc86SMichal Swiatkowski dev_dbg(dev, "Available port split options and max port speeds (Gbps):\n"); 595*0545cc86SMichal Swiatkowski dev_dbg(dev, "Status Split Quad 0 Quad 1\n"); 596*0545cc86SMichal Swiatkowski dev_dbg(dev, " count L0 L1 L2 L3 L4 L5 L6 L7\n"); 597*0545cc86SMichal Swiatkowski 598*0545cc86SMichal Swiatkowski for (i = 0; i < options_count; i++) { 599*0545cc86SMichal Swiatkowski cnt = 0; 600*0545cc86SMichal Swiatkowski 601*0545cc86SMichal Swiatkowski if (i == ice_active_port_option) 602*0545cc86SMichal Swiatkowski str = "Active"; 603*0545cc86SMichal Swiatkowski else if ((i == pending_idx) && pending_valid) 604*0545cc86SMichal Swiatkowski str = "Pending"; 605*0545cc86SMichal Swiatkowski else 606*0545cc86SMichal Swiatkowski str = ""; 607*0545cc86SMichal Swiatkowski 608*0545cc86SMichal Swiatkowski cnt += snprintf(&desc[cnt], ICE_PORT_OPT_DESC_LEN - cnt, 609*0545cc86SMichal Swiatkowski "%-8s", str); 610*0545cc86SMichal Swiatkowski 611*0545cc86SMichal Swiatkowski cnt += snprintf(&desc[cnt], ICE_PORT_OPT_DESC_LEN - cnt, 612*0545cc86SMichal Swiatkowski "%-6u", options[i].pmd); 613*0545cc86SMichal Swiatkowski 614*0545cc86SMichal Swiatkowski for (j = 0; j < ICE_MAX_PORT_PER_PCI_DEV; ++j) { 615*0545cc86SMichal Swiatkowski speed = options[i + j * ICE_AQC_PORT_OPT_MAX].max_lane_speed; 616*0545cc86SMichal Swiatkowski str = ice_devlink_port_opt_speed_str(speed); 617*0545cc86SMichal Swiatkowski cnt += snprintf(&desc[cnt], ICE_PORT_OPT_DESC_LEN - cnt, 618*0545cc86SMichal Swiatkowski "%3s ", str); 619*0545cc86SMichal Swiatkowski } 620*0545cc86SMichal Swiatkowski 621*0545cc86SMichal Swiatkowski dev_dbg(dev, "%s\n", desc); 622*0545cc86SMichal Swiatkowski } 623*0545cc86SMichal Swiatkowski 624*0545cc86SMichal Swiatkowski err: 625*0545cc86SMichal Swiatkowski kfree(options); 626*0545cc86SMichal Swiatkowski } 627*0545cc86SMichal Swiatkowski 628*0545cc86SMichal Swiatkowski /** 629*0545cc86SMichal Swiatkowski * ice_devlink_aq_set_port_option - Send set port option admin queue command 630*0545cc86SMichal Swiatkowski * @pf: the PF to print split port options 631*0545cc86SMichal Swiatkowski * @option_idx: selected port option 632*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 633*0545cc86SMichal Swiatkowski * 634*0545cc86SMichal Swiatkowski * Sends set port option admin queue command with selected port option and 635*0545cc86SMichal Swiatkowski * calls NVM write activate. 636*0545cc86SMichal Swiatkowski */ 637*0545cc86SMichal Swiatkowski static int 638*0545cc86SMichal Swiatkowski ice_devlink_aq_set_port_option(struct ice_pf *pf, u8 option_idx, 639*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 640*0545cc86SMichal Swiatkowski { 641*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 642*0545cc86SMichal Swiatkowski int status; 643*0545cc86SMichal Swiatkowski 644*0545cc86SMichal Swiatkowski status = ice_aq_set_port_option(&pf->hw, 0, true, option_idx); 645*0545cc86SMichal Swiatkowski if (status) { 646*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_aq_set_port_option, err %d aq_err %d\n", 647*0545cc86SMichal Swiatkowski status, pf->hw.adminq.sq_last_status); 648*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Port split request failed"); 649*0545cc86SMichal Swiatkowski return -EIO; 650*0545cc86SMichal Swiatkowski } 651*0545cc86SMichal Swiatkowski 652*0545cc86SMichal Swiatkowski status = ice_acquire_nvm(&pf->hw, ICE_RES_WRITE); 653*0545cc86SMichal Swiatkowski if (status) { 654*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n", 655*0545cc86SMichal Swiatkowski status, pf->hw.adminq.sq_last_status); 656*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore"); 657*0545cc86SMichal Swiatkowski return -EIO; 658*0545cc86SMichal Swiatkowski } 659*0545cc86SMichal Swiatkowski 660*0545cc86SMichal Swiatkowski status = ice_nvm_write_activate(&pf->hw, ICE_AQC_NVM_ACTIV_REQ_EMPR, NULL); 661*0545cc86SMichal Swiatkowski if (status) { 662*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_nvm_write_activate failed, err %d aq_err %d\n", 663*0545cc86SMichal Swiatkowski status, pf->hw.adminq.sq_last_status); 664*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Port split request failed to save data"); 665*0545cc86SMichal Swiatkowski ice_release_nvm(&pf->hw); 666*0545cc86SMichal Swiatkowski return -EIO; 667*0545cc86SMichal Swiatkowski } 668*0545cc86SMichal Swiatkowski 669*0545cc86SMichal Swiatkowski ice_release_nvm(&pf->hw); 670*0545cc86SMichal Swiatkowski 671*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Reboot required to finish port split"); 672*0545cc86SMichal Swiatkowski return 0; 673*0545cc86SMichal Swiatkowski } 674*0545cc86SMichal Swiatkowski 675*0545cc86SMichal Swiatkowski /** 676*0545cc86SMichal Swiatkowski * ice_devlink_port_split - .port_split devlink handler 677*0545cc86SMichal Swiatkowski * @devlink: devlink instance structure 678*0545cc86SMichal Swiatkowski * @port: devlink port structure 679*0545cc86SMichal Swiatkowski * @count: number of ports to split to 680*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 681*0545cc86SMichal Swiatkowski * 682*0545cc86SMichal Swiatkowski * Callback for the devlink .port_split operation. 683*0545cc86SMichal Swiatkowski * 684*0545cc86SMichal Swiatkowski * Unfortunately, the devlink expression of available options is limited 685*0545cc86SMichal Swiatkowski * to just a number, so search for an FW port option which supports 686*0545cc86SMichal Swiatkowski * the specified number. As there could be multiple FW port options with 687*0545cc86SMichal Swiatkowski * the same port split count, allow switching between them. When the same 688*0545cc86SMichal Swiatkowski * port split count request is issued again, switch to the next FW port 689*0545cc86SMichal Swiatkowski * option with the same port split count. 690*0545cc86SMichal Swiatkowski * 691*0545cc86SMichal Swiatkowski * Return: zero on success or an error code on failure. 692*0545cc86SMichal Swiatkowski */ 693*0545cc86SMichal Swiatkowski static int 694*0545cc86SMichal Swiatkowski ice_devlink_port_split(struct devlink *devlink, struct devlink_port *port, 695*0545cc86SMichal Swiatkowski unsigned int count, struct netlink_ext_ack *extack) 696*0545cc86SMichal Swiatkowski { 697*0545cc86SMichal Swiatkowski struct ice_aqc_get_port_options_elem options[ICE_AQC_PORT_OPT_MAX]; 698*0545cc86SMichal Swiatkowski u8 i, j, active_idx, pending_idx, new_option; 699*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 700*0545cc86SMichal Swiatkowski u8 option_count = ICE_AQC_PORT_OPT_MAX; 701*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 702*0545cc86SMichal Swiatkowski bool active_valid, pending_valid; 703*0545cc86SMichal Swiatkowski int status; 704*0545cc86SMichal Swiatkowski 705*0545cc86SMichal Swiatkowski status = ice_aq_get_port_options(&pf->hw, options, &option_count, 706*0545cc86SMichal Swiatkowski 0, true, &active_idx, &active_valid, 707*0545cc86SMichal Swiatkowski &pending_idx, &pending_valid); 708*0545cc86SMichal Swiatkowski if (status) { 709*0545cc86SMichal Swiatkowski dev_dbg(dev, "Couldn't read port split options, err = %d\n", 710*0545cc86SMichal Swiatkowski status); 711*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to get available port split options"); 712*0545cc86SMichal Swiatkowski return -EIO; 713*0545cc86SMichal Swiatkowski } 714*0545cc86SMichal Swiatkowski 715*0545cc86SMichal Swiatkowski new_option = ICE_AQC_PORT_OPT_MAX; 716*0545cc86SMichal Swiatkowski active_idx = pending_valid ? pending_idx : active_idx; 717*0545cc86SMichal Swiatkowski for (i = 1; i <= option_count; i++) { 718*0545cc86SMichal Swiatkowski /* In order to allow switching between FW port options with 719*0545cc86SMichal Swiatkowski * the same port split count, search for a new option starting 720*0545cc86SMichal Swiatkowski * from the active/pending option (with array wrap around). 721*0545cc86SMichal Swiatkowski */ 722*0545cc86SMichal Swiatkowski j = (active_idx + i) % option_count; 723*0545cc86SMichal Swiatkowski 724*0545cc86SMichal Swiatkowski if (count == options[j].pmd) { 725*0545cc86SMichal Swiatkowski new_option = j; 726*0545cc86SMichal Swiatkowski break; 727*0545cc86SMichal Swiatkowski } 728*0545cc86SMichal Swiatkowski } 729*0545cc86SMichal Swiatkowski 730*0545cc86SMichal Swiatkowski if (new_option == active_idx) { 731*0545cc86SMichal Swiatkowski dev_dbg(dev, "request to split: count: %u is already set and there are no other options\n", 732*0545cc86SMichal Swiatkowski count); 733*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Requested split count is already set"); 734*0545cc86SMichal Swiatkowski ice_devlink_port_options_print(pf); 735*0545cc86SMichal Swiatkowski return -EINVAL; 736*0545cc86SMichal Swiatkowski } 737*0545cc86SMichal Swiatkowski 738*0545cc86SMichal Swiatkowski if (new_option == ICE_AQC_PORT_OPT_MAX) { 739*0545cc86SMichal Swiatkowski dev_dbg(dev, "request to split: count: %u not found\n", count); 740*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Port split requested unsupported port config"); 741*0545cc86SMichal Swiatkowski ice_devlink_port_options_print(pf); 742*0545cc86SMichal Swiatkowski return -EINVAL; 743*0545cc86SMichal Swiatkowski } 744*0545cc86SMichal Swiatkowski 745*0545cc86SMichal Swiatkowski status = ice_devlink_aq_set_port_option(pf, new_option, extack); 746*0545cc86SMichal Swiatkowski if (status) 747*0545cc86SMichal Swiatkowski return status; 748*0545cc86SMichal Swiatkowski 749*0545cc86SMichal Swiatkowski ice_devlink_port_options_print(pf); 750*0545cc86SMichal Swiatkowski 751*0545cc86SMichal Swiatkowski return 0; 752*0545cc86SMichal Swiatkowski } 753*0545cc86SMichal Swiatkowski 754*0545cc86SMichal Swiatkowski /** 755*0545cc86SMichal Swiatkowski * ice_devlink_port_unsplit - .port_unsplit devlink handler 756*0545cc86SMichal Swiatkowski * @devlink: devlink instance structure 757*0545cc86SMichal Swiatkowski * @port: devlink port structure 758*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 759*0545cc86SMichal Swiatkowski * 760*0545cc86SMichal Swiatkowski * Callback for the devlink .port_unsplit operation. 761*0545cc86SMichal Swiatkowski * Calls ice_devlink_port_split with split count set to 1. 762*0545cc86SMichal Swiatkowski * There could be no FW option available with split count 1. 763*0545cc86SMichal Swiatkowski * 764*0545cc86SMichal Swiatkowski * Return: zero on success or an error code on failure. 765*0545cc86SMichal Swiatkowski */ 766*0545cc86SMichal Swiatkowski static int 767*0545cc86SMichal Swiatkowski ice_devlink_port_unsplit(struct devlink *devlink, struct devlink_port *port, 768*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 769*0545cc86SMichal Swiatkowski { 770*0545cc86SMichal Swiatkowski return ice_devlink_port_split(devlink, port, 1, extack); 771*0545cc86SMichal Swiatkowski } 772*0545cc86SMichal Swiatkowski 773*0545cc86SMichal Swiatkowski /** 774*0545cc86SMichal Swiatkowski * ice_tear_down_devlink_rate_tree - removes devlink-rate exported tree 775*0545cc86SMichal Swiatkowski * @pf: pf struct 776*0545cc86SMichal Swiatkowski * 777*0545cc86SMichal Swiatkowski * This function tears down tree exported during VF's creation. 778*0545cc86SMichal Swiatkowski */ 779*0545cc86SMichal Swiatkowski void ice_tear_down_devlink_rate_tree(struct ice_pf *pf) 780*0545cc86SMichal Swiatkowski { 781*0545cc86SMichal Swiatkowski struct devlink *devlink; 782*0545cc86SMichal Swiatkowski struct ice_vf *vf; 783*0545cc86SMichal Swiatkowski unsigned int bkt; 784*0545cc86SMichal Swiatkowski 785*0545cc86SMichal Swiatkowski devlink = priv_to_devlink(pf); 786*0545cc86SMichal Swiatkowski 787*0545cc86SMichal Swiatkowski devl_lock(devlink); 788*0545cc86SMichal Swiatkowski mutex_lock(&pf->vfs.table_lock); 789*0545cc86SMichal Swiatkowski ice_for_each_vf(pf, bkt, vf) { 790*0545cc86SMichal Swiatkowski if (vf->devlink_port.devlink_rate) 791*0545cc86SMichal Swiatkowski devl_rate_leaf_destroy(&vf->devlink_port); 792*0545cc86SMichal Swiatkowski } 793*0545cc86SMichal Swiatkowski mutex_unlock(&pf->vfs.table_lock); 794*0545cc86SMichal Swiatkowski 795*0545cc86SMichal Swiatkowski devl_rate_nodes_destroy(devlink); 796*0545cc86SMichal Swiatkowski devl_unlock(devlink); 797*0545cc86SMichal Swiatkowski } 798*0545cc86SMichal Swiatkowski 799*0545cc86SMichal Swiatkowski /** 800*0545cc86SMichal Swiatkowski * ice_enable_custom_tx - try to enable custom Tx feature 801*0545cc86SMichal Swiatkowski * @pf: pf struct 802*0545cc86SMichal Swiatkowski * 803*0545cc86SMichal Swiatkowski * This function tries to enable custom Tx feature, 804*0545cc86SMichal Swiatkowski * it's not possible to enable it, if DCB or ADQ is active. 805*0545cc86SMichal Swiatkowski */ 806*0545cc86SMichal Swiatkowski static bool ice_enable_custom_tx(struct ice_pf *pf) 807*0545cc86SMichal Swiatkowski { 808*0545cc86SMichal Swiatkowski struct ice_port_info *pi = ice_get_main_vsi(pf)->port_info; 809*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 810*0545cc86SMichal Swiatkowski 811*0545cc86SMichal Swiatkowski if (pi->is_custom_tx_enabled) 812*0545cc86SMichal Swiatkowski /* already enabled, return true */ 813*0545cc86SMichal Swiatkowski return true; 814*0545cc86SMichal Swiatkowski 815*0545cc86SMichal Swiatkowski if (ice_is_adq_active(pf)) { 816*0545cc86SMichal Swiatkowski dev_err(dev, "ADQ active, can't modify Tx scheduler tree\n"); 817*0545cc86SMichal Swiatkowski return false; 818*0545cc86SMichal Swiatkowski } 819*0545cc86SMichal Swiatkowski 820*0545cc86SMichal Swiatkowski if (ice_is_dcb_active(pf)) { 821*0545cc86SMichal Swiatkowski dev_err(dev, "DCB active, can't modify Tx scheduler tree\n"); 822*0545cc86SMichal Swiatkowski return false; 823*0545cc86SMichal Swiatkowski } 824*0545cc86SMichal Swiatkowski 825*0545cc86SMichal Swiatkowski pi->is_custom_tx_enabled = true; 826*0545cc86SMichal Swiatkowski 827*0545cc86SMichal Swiatkowski return true; 828*0545cc86SMichal Swiatkowski } 829*0545cc86SMichal Swiatkowski 830*0545cc86SMichal Swiatkowski /** 831*0545cc86SMichal Swiatkowski * ice_traverse_tx_tree - traverse Tx scheduler tree 832*0545cc86SMichal Swiatkowski * @devlink: devlink struct 833*0545cc86SMichal Swiatkowski * @node: current node, used for recursion 834*0545cc86SMichal Swiatkowski * @tc_node: tc_node struct, that is treated as a root 835*0545cc86SMichal Swiatkowski * @pf: pf struct 836*0545cc86SMichal Swiatkowski * 837*0545cc86SMichal Swiatkowski * This function traverses Tx scheduler tree and exports 838*0545cc86SMichal Swiatkowski * entire structure to the devlink-rate. 839*0545cc86SMichal Swiatkowski */ 840*0545cc86SMichal Swiatkowski static void ice_traverse_tx_tree(struct devlink *devlink, struct ice_sched_node *node, 841*0545cc86SMichal Swiatkowski struct ice_sched_node *tc_node, struct ice_pf *pf) 842*0545cc86SMichal Swiatkowski { 843*0545cc86SMichal Swiatkowski struct devlink_rate *rate_node = NULL; 844*0545cc86SMichal Swiatkowski struct ice_vf *vf; 845*0545cc86SMichal Swiatkowski int i; 846*0545cc86SMichal Swiatkowski 847*0545cc86SMichal Swiatkowski if (node->rate_node) 848*0545cc86SMichal Swiatkowski /* already added, skip to the next */ 849*0545cc86SMichal Swiatkowski goto traverse_children; 850*0545cc86SMichal Swiatkowski 851*0545cc86SMichal Swiatkowski if (node->parent == tc_node) { 852*0545cc86SMichal Swiatkowski /* create root node */ 853*0545cc86SMichal Swiatkowski rate_node = devl_rate_node_create(devlink, node, node->name, NULL); 854*0545cc86SMichal Swiatkowski } else if (node->vsi_handle && 855*0545cc86SMichal Swiatkowski pf->vsi[node->vsi_handle]->vf) { 856*0545cc86SMichal Swiatkowski vf = pf->vsi[node->vsi_handle]->vf; 857*0545cc86SMichal Swiatkowski if (!vf->devlink_port.devlink_rate) 858*0545cc86SMichal Swiatkowski /* leaf nodes doesn't have children 859*0545cc86SMichal Swiatkowski * so we don't set rate_node 860*0545cc86SMichal Swiatkowski */ 861*0545cc86SMichal Swiatkowski devl_rate_leaf_create(&vf->devlink_port, node, 862*0545cc86SMichal Swiatkowski node->parent->rate_node); 863*0545cc86SMichal Swiatkowski } else if (node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF && 864*0545cc86SMichal Swiatkowski node->parent->rate_node) { 865*0545cc86SMichal Swiatkowski rate_node = devl_rate_node_create(devlink, node, node->name, 866*0545cc86SMichal Swiatkowski node->parent->rate_node); 867*0545cc86SMichal Swiatkowski } 868*0545cc86SMichal Swiatkowski 869*0545cc86SMichal Swiatkowski if (rate_node && !IS_ERR(rate_node)) 870*0545cc86SMichal Swiatkowski node->rate_node = rate_node; 871*0545cc86SMichal Swiatkowski 872*0545cc86SMichal Swiatkowski traverse_children: 873*0545cc86SMichal Swiatkowski for (i = 0; i < node->num_children; i++) 874*0545cc86SMichal Swiatkowski ice_traverse_tx_tree(devlink, node->children[i], tc_node, pf); 875*0545cc86SMichal Swiatkowski } 876*0545cc86SMichal Swiatkowski 877*0545cc86SMichal Swiatkowski /** 878*0545cc86SMichal Swiatkowski * ice_devlink_rate_init_tx_topology - export Tx scheduler tree to devlink rate 879*0545cc86SMichal Swiatkowski * @devlink: devlink struct 880*0545cc86SMichal Swiatkowski * @vsi: main vsi struct 881*0545cc86SMichal Swiatkowski * 882*0545cc86SMichal Swiatkowski * This function finds a root node, then calls ice_traverse_tx tree, which 883*0545cc86SMichal Swiatkowski * traverses the tree and exports it's contents to devlink rate. 884*0545cc86SMichal Swiatkowski */ 885*0545cc86SMichal Swiatkowski int ice_devlink_rate_init_tx_topology(struct devlink *devlink, struct ice_vsi *vsi) 886*0545cc86SMichal Swiatkowski { 887*0545cc86SMichal Swiatkowski struct ice_port_info *pi = vsi->port_info; 888*0545cc86SMichal Swiatkowski struct ice_sched_node *tc_node; 889*0545cc86SMichal Swiatkowski struct ice_pf *pf = vsi->back; 890*0545cc86SMichal Swiatkowski int i; 891*0545cc86SMichal Swiatkowski 892*0545cc86SMichal Swiatkowski tc_node = pi->root->children[0]; 893*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 894*0545cc86SMichal Swiatkowski devl_lock(devlink); 895*0545cc86SMichal Swiatkowski for (i = 0; i < tc_node->num_children; i++) 896*0545cc86SMichal Swiatkowski ice_traverse_tx_tree(devlink, tc_node->children[i], tc_node, pf); 897*0545cc86SMichal Swiatkowski devl_unlock(devlink); 898*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 899*0545cc86SMichal Swiatkowski 900*0545cc86SMichal Swiatkowski return 0; 901*0545cc86SMichal Swiatkowski } 902*0545cc86SMichal Swiatkowski 903*0545cc86SMichal Swiatkowski static void ice_clear_rate_nodes(struct ice_sched_node *node) 904*0545cc86SMichal Swiatkowski { 905*0545cc86SMichal Swiatkowski node->rate_node = NULL; 906*0545cc86SMichal Swiatkowski 907*0545cc86SMichal Swiatkowski for (int i = 0; i < node->num_children; i++) 908*0545cc86SMichal Swiatkowski ice_clear_rate_nodes(node->children[i]); 909*0545cc86SMichal Swiatkowski } 910*0545cc86SMichal Swiatkowski 911*0545cc86SMichal Swiatkowski /** 912*0545cc86SMichal Swiatkowski * ice_devlink_rate_clear_tx_topology - clear node->rate_node 913*0545cc86SMichal Swiatkowski * @vsi: main vsi struct 914*0545cc86SMichal Swiatkowski * 915*0545cc86SMichal Swiatkowski * Clear rate_node to cleanup creation of Tx topology. 916*0545cc86SMichal Swiatkowski * 917*0545cc86SMichal Swiatkowski */ 918*0545cc86SMichal Swiatkowski void ice_devlink_rate_clear_tx_topology(struct ice_vsi *vsi) 919*0545cc86SMichal Swiatkowski { 920*0545cc86SMichal Swiatkowski struct ice_port_info *pi = vsi->port_info; 921*0545cc86SMichal Swiatkowski 922*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 923*0545cc86SMichal Swiatkowski ice_clear_rate_nodes(pi->root->children[0]); 924*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 925*0545cc86SMichal Swiatkowski } 926*0545cc86SMichal Swiatkowski 927*0545cc86SMichal Swiatkowski /** 928*0545cc86SMichal Swiatkowski * ice_set_object_tx_share - sets node scheduling parameter 929*0545cc86SMichal Swiatkowski * @pi: devlink struct instance 930*0545cc86SMichal Swiatkowski * @node: node struct instance 931*0545cc86SMichal Swiatkowski * @bw: bandwidth in bytes per second 932*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 933*0545cc86SMichal Swiatkowski * 934*0545cc86SMichal Swiatkowski * This function sets ICE_MIN_BW scheduling BW limit. 935*0545cc86SMichal Swiatkowski */ 936*0545cc86SMichal Swiatkowski static int ice_set_object_tx_share(struct ice_port_info *pi, struct ice_sched_node *node, 937*0545cc86SMichal Swiatkowski u64 bw, struct netlink_ext_ack *extack) 938*0545cc86SMichal Swiatkowski { 939*0545cc86SMichal Swiatkowski int status; 940*0545cc86SMichal Swiatkowski 941*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 942*0545cc86SMichal Swiatkowski /* converts bytes per second to kilo bits per second */ 943*0545cc86SMichal Swiatkowski node->tx_share = div_u64(bw, 125); 944*0545cc86SMichal Swiatkowski status = ice_sched_set_node_bw_lmt(pi, node, ICE_MIN_BW, node->tx_share); 945*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 946*0545cc86SMichal Swiatkowski 947*0545cc86SMichal Swiatkowski if (status) 948*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_share"); 949*0545cc86SMichal Swiatkowski 950*0545cc86SMichal Swiatkowski return status; 951*0545cc86SMichal Swiatkowski } 952*0545cc86SMichal Swiatkowski 953*0545cc86SMichal Swiatkowski /** 954*0545cc86SMichal Swiatkowski * ice_set_object_tx_max - sets node scheduling parameter 955*0545cc86SMichal Swiatkowski * @pi: devlink struct instance 956*0545cc86SMichal Swiatkowski * @node: node struct instance 957*0545cc86SMichal Swiatkowski * @bw: bandwidth in bytes per second 958*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 959*0545cc86SMichal Swiatkowski * 960*0545cc86SMichal Swiatkowski * This function sets ICE_MAX_BW scheduling BW limit. 961*0545cc86SMichal Swiatkowski */ 962*0545cc86SMichal Swiatkowski static int ice_set_object_tx_max(struct ice_port_info *pi, struct ice_sched_node *node, 963*0545cc86SMichal Swiatkowski u64 bw, struct netlink_ext_ack *extack) 964*0545cc86SMichal Swiatkowski { 965*0545cc86SMichal Swiatkowski int status; 966*0545cc86SMichal Swiatkowski 967*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 968*0545cc86SMichal Swiatkowski /* converts bytes per second value to kilo bits per second */ 969*0545cc86SMichal Swiatkowski node->tx_max = div_u64(bw, 125); 970*0545cc86SMichal Swiatkowski status = ice_sched_set_node_bw_lmt(pi, node, ICE_MAX_BW, node->tx_max); 971*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 972*0545cc86SMichal Swiatkowski 973*0545cc86SMichal Swiatkowski if (status) 974*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_max"); 975*0545cc86SMichal Swiatkowski 976*0545cc86SMichal Swiatkowski return status; 977*0545cc86SMichal Swiatkowski } 978*0545cc86SMichal Swiatkowski 979*0545cc86SMichal Swiatkowski /** 980*0545cc86SMichal Swiatkowski * ice_set_object_tx_priority - sets node scheduling parameter 981*0545cc86SMichal Swiatkowski * @pi: devlink struct instance 982*0545cc86SMichal Swiatkowski * @node: node struct instance 983*0545cc86SMichal Swiatkowski * @priority: value representing priority for strict priority arbitration 984*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 985*0545cc86SMichal Swiatkowski * 986*0545cc86SMichal Swiatkowski * This function sets priority of node among siblings. 987*0545cc86SMichal Swiatkowski */ 988*0545cc86SMichal Swiatkowski static int ice_set_object_tx_priority(struct ice_port_info *pi, struct ice_sched_node *node, 989*0545cc86SMichal Swiatkowski u32 priority, struct netlink_ext_ack *extack) 990*0545cc86SMichal Swiatkowski { 991*0545cc86SMichal Swiatkowski int status; 992*0545cc86SMichal Swiatkowski 993*0545cc86SMichal Swiatkowski if (priority >= 8) { 994*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Priority should be less than 8"); 995*0545cc86SMichal Swiatkowski return -EINVAL; 996*0545cc86SMichal Swiatkowski } 997*0545cc86SMichal Swiatkowski 998*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 999*0545cc86SMichal Swiatkowski node->tx_priority = priority; 1000*0545cc86SMichal Swiatkowski status = ice_sched_set_node_priority(pi, node, node->tx_priority); 1001*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 1002*0545cc86SMichal Swiatkowski 1003*0545cc86SMichal Swiatkowski if (status) 1004*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_priority"); 1005*0545cc86SMichal Swiatkowski 1006*0545cc86SMichal Swiatkowski return status; 1007*0545cc86SMichal Swiatkowski } 1008*0545cc86SMichal Swiatkowski 1009*0545cc86SMichal Swiatkowski /** 1010*0545cc86SMichal Swiatkowski * ice_set_object_tx_weight - sets node scheduling parameter 1011*0545cc86SMichal Swiatkowski * @pi: devlink struct instance 1012*0545cc86SMichal Swiatkowski * @node: node struct instance 1013*0545cc86SMichal Swiatkowski * @weight: value represeting relative weight for WFQ arbitration 1014*0545cc86SMichal Swiatkowski * @extack: extended netdev ack structure 1015*0545cc86SMichal Swiatkowski * 1016*0545cc86SMichal Swiatkowski * This function sets node weight for WFQ algorithm. 1017*0545cc86SMichal Swiatkowski */ 1018*0545cc86SMichal Swiatkowski static int ice_set_object_tx_weight(struct ice_port_info *pi, struct ice_sched_node *node, 1019*0545cc86SMichal Swiatkowski u32 weight, struct netlink_ext_ack *extack) 1020*0545cc86SMichal Swiatkowski { 1021*0545cc86SMichal Swiatkowski int status; 1022*0545cc86SMichal Swiatkowski 1023*0545cc86SMichal Swiatkowski if (weight > 200 || weight < 1) { 1024*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Weight must be between 1 and 200"); 1025*0545cc86SMichal Swiatkowski return -EINVAL; 1026*0545cc86SMichal Swiatkowski } 1027*0545cc86SMichal Swiatkowski 1028*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 1029*0545cc86SMichal Swiatkowski node->tx_weight = weight; 1030*0545cc86SMichal Swiatkowski status = ice_sched_set_node_weight(pi, node, node->tx_weight); 1031*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 1032*0545cc86SMichal Swiatkowski 1033*0545cc86SMichal Swiatkowski if (status) 1034*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_weight"); 1035*0545cc86SMichal Swiatkowski 1036*0545cc86SMichal Swiatkowski return status; 1037*0545cc86SMichal Swiatkowski } 1038*0545cc86SMichal Swiatkowski 1039*0545cc86SMichal Swiatkowski /** 1040*0545cc86SMichal Swiatkowski * ice_get_pi_from_dev_rate - get port info from devlink_rate 1041*0545cc86SMichal Swiatkowski * @rate_node: devlink struct instance 1042*0545cc86SMichal Swiatkowski * 1043*0545cc86SMichal Swiatkowski * This function returns corresponding port_info struct of devlink_rate 1044*0545cc86SMichal Swiatkowski */ 1045*0545cc86SMichal Swiatkowski static struct ice_port_info *ice_get_pi_from_dev_rate(struct devlink_rate *rate_node) 1046*0545cc86SMichal Swiatkowski { 1047*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(rate_node->devlink); 1048*0545cc86SMichal Swiatkowski 1049*0545cc86SMichal Swiatkowski return ice_get_main_vsi(pf)->port_info; 1050*0545cc86SMichal Swiatkowski } 1051*0545cc86SMichal Swiatkowski 1052*0545cc86SMichal Swiatkowski static int ice_devlink_rate_node_new(struct devlink_rate *rate_node, void **priv, 1053*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 1054*0545cc86SMichal Swiatkowski { 1055*0545cc86SMichal Swiatkowski struct ice_sched_node *node; 1056*0545cc86SMichal Swiatkowski struct ice_port_info *pi; 1057*0545cc86SMichal Swiatkowski 1058*0545cc86SMichal Swiatkowski pi = ice_get_pi_from_dev_rate(rate_node); 1059*0545cc86SMichal Swiatkowski 1060*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink))) 1061*0545cc86SMichal Swiatkowski return -EBUSY; 1062*0545cc86SMichal Swiatkowski 1063*0545cc86SMichal Swiatkowski /* preallocate memory for ice_sched_node */ 1064*0545cc86SMichal Swiatkowski node = devm_kzalloc(ice_hw_to_dev(pi->hw), sizeof(*node), GFP_KERNEL); 1065*0545cc86SMichal Swiatkowski *priv = node; 1066*0545cc86SMichal Swiatkowski 1067*0545cc86SMichal Swiatkowski return 0; 1068*0545cc86SMichal Swiatkowski } 1069*0545cc86SMichal Swiatkowski 1070*0545cc86SMichal Swiatkowski static int ice_devlink_rate_node_del(struct devlink_rate *rate_node, void *priv, 1071*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 1072*0545cc86SMichal Swiatkowski { 1073*0545cc86SMichal Swiatkowski struct ice_sched_node *node, *tc_node; 1074*0545cc86SMichal Swiatkowski struct ice_port_info *pi; 1075*0545cc86SMichal Swiatkowski 1076*0545cc86SMichal Swiatkowski pi = ice_get_pi_from_dev_rate(rate_node); 1077*0545cc86SMichal Swiatkowski tc_node = pi->root->children[0]; 1078*0545cc86SMichal Swiatkowski node = priv; 1079*0545cc86SMichal Swiatkowski 1080*0545cc86SMichal Swiatkowski if (!rate_node->parent || !node || tc_node == node || !extack) 1081*0545cc86SMichal Swiatkowski return 0; 1082*0545cc86SMichal Swiatkowski 1083*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink))) 1084*0545cc86SMichal Swiatkowski return -EBUSY; 1085*0545cc86SMichal Swiatkowski 1086*0545cc86SMichal Swiatkowski /* can't allow to delete a node with children */ 1087*0545cc86SMichal Swiatkowski if (node->num_children) 1088*0545cc86SMichal Swiatkowski return -EINVAL; 1089*0545cc86SMichal Swiatkowski 1090*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 1091*0545cc86SMichal Swiatkowski ice_free_sched_node(pi, node); 1092*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 1093*0545cc86SMichal Swiatkowski 1094*0545cc86SMichal Swiatkowski return 0; 1095*0545cc86SMichal Swiatkowski } 1096*0545cc86SMichal Swiatkowski 1097*0545cc86SMichal Swiatkowski static int ice_devlink_rate_leaf_tx_max_set(struct devlink_rate *rate_leaf, void *priv, 1098*0545cc86SMichal Swiatkowski u64 tx_max, struct netlink_ext_ack *extack) 1099*0545cc86SMichal Swiatkowski { 1100*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1101*0545cc86SMichal Swiatkowski 1102*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink))) 1103*0545cc86SMichal Swiatkowski return -EBUSY; 1104*0545cc86SMichal Swiatkowski 1105*0545cc86SMichal Swiatkowski if (!node) 1106*0545cc86SMichal Swiatkowski return 0; 1107*0545cc86SMichal Swiatkowski 1108*0545cc86SMichal Swiatkowski return ice_set_object_tx_max(ice_get_pi_from_dev_rate(rate_leaf), 1109*0545cc86SMichal Swiatkowski node, tx_max, extack); 1110*0545cc86SMichal Swiatkowski } 1111*0545cc86SMichal Swiatkowski 1112*0545cc86SMichal Swiatkowski static int ice_devlink_rate_leaf_tx_share_set(struct devlink_rate *rate_leaf, void *priv, 1113*0545cc86SMichal Swiatkowski u64 tx_share, struct netlink_ext_ack *extack) 1114*0545cc86SMichal Swiatkowski { 1115*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1116*0545cc86SMichal Swiatkowski 1117*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink))) 1118*0545cc86SMichal Swiatkowski return -EBUSY; 1119*0545cc86SMichal Swiatkowski 1120*0545cc86SMichal Swiatkowski if (!node) 1121*0545cc86SMichal Swiatkowski return 0; 1122*0545cc86SMichal Swiatkowski 1123*0545cc86SMichal Swiatkowski return ice_set_object_tx_share(ice_get_pi_from_dev_rate(rate_leaf), node, 1124*0545cc86SMichal Swiatkowski tx_share, extack); 1125*0545cc86SMichal Swiatkowski } 1126*0545cc86SMichal Swiatkowski 1127*0545cc86SMichal Swiatkowski static int ice_devlink_rate_leaf_tx_priority_set(struct devlink_rate *rate_leaf, void *priv, 1128*0545cc86SMichal Swiatkowski u32 tx_priority, struct netlink_ext_ack *extack) 1129*0545cc86SMichal Swiatkowski { 1130*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1131*0545cc86SMichal Swiatkowski 1132*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink))) 1133*0545cc86SMichal Swiatkowski return -EBUSY; 1134*0545cc86SMichal Swiatkowski 1135*0545cc86SMichal Swiatkowski if (!node) 1136*0545cc86SMichal Swiatkowski return 0; 1137*0545cc86SMichal Swiatkowski 1138*0545cc86SMichal Swiatkowski return ice_set_object_tx_priority(ice_get_pi_from_dev_rate(rate_leaf), node, 1139*0545cc86SMichal Swiatkowski tx_priority, extack); 1140*0545cc86SMichal Swiatkowski } 1141*0545cc86SMichal Swiatkowski 1142*0545cc86SMichal Swiatkowski static int ice_devlink_rate_leaf_tx_weight_set(struct devlink_rate *rate_leaf, void *priv, 1143*0545cc86SMichal Swiatkowski u32 tx_weight, struct netlink_ext_ack *extack) 1144*0545cc86SMichal Swiatkowski { 1145*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1146*0545cc86SMichal Swiatkowski 1147*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink))) 1148*0545cc86SMichal Swiatkowski return -EBUSY; 1149*0545cc86SMichal Swiatkowski 1150*0545cc86SMichal Swiatkowski if (!node) 1151*0545cc86SMichal Swiatkowski return 0; 1152*0545cc86SMichal Swiatkowski 1153*0545cc86SMichal Swiatkowski return ice_set_object_tx_weight(ice_get_pi_from_dev_rate(rate_leaf), node, 1154*0545cc86SMichal Swiatkowski tx_weight, extack); 1155*0545cc86SMichal Swiatkowski } 1156*0545cc86SMichal Swiatkowski 1157*0545cc86SMichal Swiatkowski static int ice_devlink_rate_node_tx_max_set(struct devlink_rate *rate_node, void *priv, 1158*0545cc86SMichal Swiatkowski u64 tx_max, struct netlink_ext_ack *extack) 1159*0545cc86SMichal Swiatkowski { 1160*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1161*0545cc86SMichal Swiatkowski 1162*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink))) 1163*0545cc86SMichal Swiatkowski return -EBUSY; 1164*0545cc86SMichal Swiatkowski 1165*0545cc86SMichal Swiatkowski if (!node) 1166*0545cc86SMichal Swiatkowski return 0; 1167*0545cc86SMichal Swiatkowski 1168*0545cc86SMichal Swiatkowski return ice_set_object_tx_max(ice_get_pi_from_dev_rate(rate_node), 1169*0545cc86SMichal Swiatkowski node, tx_max, extack); 1170*0545cc86SMichal Swiatkowski } 1171*0545cc86SMichal Swiatkowski 1172*0545cc86SMichal Swiatkowski static int ice_devlink_rate_node_tx_share_set(struct devlink_rate *rate_node, void *priv, 1173*0545cc86SMichal Swiatkowski u64 tx_share, struct netlink_ext_ack *extack) 1174*0545cc86SMichal Swiatkowski { 1175*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1176*0545cc86SMichal Swiatkowski 1177*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink))) 1178*0545cc86SMichal Swiatkowski return -EBUSY; 1179*0545cc86SMichal Swiatkowski 1180*0545cc86SMichal Swiatkowski if (!node) 1181*0545cc86SMichal Swiatkowski return 0; 1182*0545cc86SMichal Swiatkowski 1183*0545cc86SMichal Swiatkowski return ice_set_object_tx_share(ice_get_pi_from_dev_rate(rate_node), 1184*0545cc86SMichal Swiatkowski node, tx_share, extack); 1185*0545cc86SMichal Swiatkowski } 1186*0545cc86SMichal Swiatkowski 1187*0545cc86SMichal Swiatkowski static int ice_devlink_rate_node_tx_priority_set(struct devlink_rate *rate_node, void *priv, 1188*0545cc86SMichal Swiatkowski u32 tx_priority, struct netlink_ext_ack *extack) 1189*0545cc86SMichal Swiatkowski { 1190*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1191*0545cc86SMichal Swiatkowski 1192*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink))) 1193*0545cc86SMichal Swiatkowski return -EBUSY; 1194*0545cc86SMichal Swiatkowski 1195*0545cc86SMichal Swiatkowski if (!node) 1196*0545cc86SMichal Swiatkowski return 0; 1197*0545cc86SMichal Swiatkowski 1198*0545cc86SMichal Swiatkowski return ice_set_object_tx_priority(ice_get_pi_from_dev_rate(rate_node), 1199*0545cc86SMichal Swiatkowski node, tx_priority, extack); 1200*0545cc86SMichal Swiatkowski } 1201*0545cc86SMichal Swiatkowski 1202*0545cc86SMichal Swiatkowski static int ice_devlink_rate_node_tx_weight_set(struct devlink_rate *rate_node, void *priv, 1203*0545cc86SMichal Swiatkowski u32 tx_weight, struct netlink_ext_ack *extack) 1204*0545cc86SMichal Swiatkowski { 1205*0545cc86SMichal Swiatkowski struct ice_sched_node *node = priv; 1206*0545cc86SMichal Swiatkowski 1207*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink))) 1208*0545cc86SMichal Swiatkowski return -EBUSY; 1209*0545cc86SMichal Swiatkowski 1210*0545cc86SMichal Swiatkowski if (!node) 1211*0545cc86SMichal Swiatkowski return 0; 1212*0545cc86SMichal Swiatkowski 1213*0545cc86SMichal Swiatkowski return ice_set_object_tx_weight(ice_get_pi_from_dev_rate(rate_node), 1214*0545cc86SMichal Swiatkowski node, tx_weight, extack); 1215*0545cc86SMichal Swiatkowski } 1216*0545cc86SMichal Swiatkowski 1217*0545cc86SMichal Swiatkowski static int ice_devlink_set_parent(struct devlink_rate *devlink_rate, 1218*0545cc86SMichal Swiatkowski struct devlink_rate *parent, 1219*0545cc86SMichal Swiatkowski void *priv, void *parent_priv, 1220*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 1221*0545cc86SMichal Swiatkowski { 1222*0545cc86SMichal Swiatkowski struct ice_port_info *pi = ice_get_pi_from_dev_rate(devlink_rate); 1223*0545cc86SMichal Swiatkowski struct ice_sched_node *tc_node, *node, *parent_node; 1224*0545cc86SMichal Swiatkowski u16 num_nodes_added; 1225*0545cc86SMichal Swiatkowski u32 first_node_teid; 1226*0545cc86SMichal Swiatkowski u32 node_teid; 1227*0545cc86SMichal Swiatkowski int status; 1228*0545cc86SMichal Swiatkowski 1229*0545cc86SMichal Swiatkowski tc_node = pi->root->children[0]; 1230*0545cc86SMichal Swiatkowski node = priv; 1231*0545cc86SMichal Swiatkowski 1232*0545cc86SMichal Swiatkowski if (!extack) 1233*0545cc86SMichal Swiatkowski return 0; 1234*0545cc86SMichal Swiatkowski 1235*0545cc86SMichal Swiatkowski if (!ice_enable_custom_tx(devlink_priv(devlink_rate->devlink))) 1236*0545cc86SMichal Swiatkowski return -EBUSY; 1237*0545cc86SMichal Swiatkowski 1238*0545cc86SMichal Swiatkowski if (!parent) { 1239*0545cc86SMichal Swiatkowski if (!node || tc_node == node || node->num_children) 1240*0545cc86SMichal Swiatkowski return -EINVAL; 1241*0545cc86SMichal Swiatkowski 1242*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 1243*0545cc86SMichal Swiatkowski ice_free_sched_node(pi, node); 1244*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 1245*0545cc86SMichal Swiatkowski 1246*0545cc86SMichal Swiatkowski return 0; 1247*0545cc86SMichal Swiatkowski } 1248*0545cc86SMichal Swiatkowski 1249*0545cc86SMichal Swiatkowski parent_node = parent_priv; 1250*0545cc86SMichal Swiatkowski 1251*0545cc86SMichal Swiatkowski /* if the node doesn't exist, create it */ 1252*0545cc86SMichal Swiatkowski if (!node->parent) { 1253*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 1254*0545cc86SMichal Swiatkowski status = ice_sched_add_elems(pi, tc_node, parent_node, 1255*0545cc86SMichal Swiatkowski parent_node->tx_sched_layer + 1, 1256*0545cc86SMichal Swiatkowski 1, &num_nodes_added, &first_node_teid, 1257*0545cc86SMichal Swiatkowski &node); 1258*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 1259*0545cc86SMichal Swiatkowski 1260*0545cc86SMichal Swiatkowski if (status) { 1261*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Can't add a new node"); 1262*0545cc86SMichal Swiatkowski return status; 1263*0545cc86SMichal Swiatkowski } 1264*0545cc86SMichal Swiatkowski 1265*0545cc86SMichal Swiatkowski if (devlink_rate->tx_share) 1266*0545cc86SMichal Swiatkowski ice_set_object_tx_share(pi, node, devlink_rate->tx_share, extack); 1267*0545cc86SMichal Swiatkowski if (devlink_rate->tx_max) 1268*0545cc86SMichal Swiatkowski ice_set_object_tx_max(pi, node, devlink_rate->tx_max, extack); 1269*0545cc86SMichal Swiatkowski if (devlink_rate->tx_priority) 1270*0545cc86SMichal Swiatkowski ice_set_object_tx_priority(pi, node, devlink_rate->tx_priority, extack); 1271*0545cc86SMichal Swiatkowski if (devlink_rate->tx_weight) 1272*0545cc86SMichal Swiatkowski ice_set_object_tx_weight(pi, node, devlink_rate->tx_weight, extack); 1273*0545cc86SMichal Swiatkowski } else { 1274*0545cc86SMichal Swiatkowski node_teid = le32_to_cpu(node->info.node_teid); 1275*0545cc86SMichal Swiatkowski mutex_lock(&pi->sched_lock); 1276*0545cc86SMichal Swiatkowski status = ice_sched_move_nodes(pi, parent_node, 1, &node_teid); 1277*0545cc86SMichal Swiatkowski mutex_unlock(&pi->sched_lock); 1278*0545cc86SMichal Swiatkowski 1279*0545cc86SMichal Swiatkowski if (status) 1280*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Can't move existing node to a new parent"); 1281*0545cc86SMichal Swiatkowski } 1282*0545cc86SMichal Swiatkowski 1283*0545cc86SMichal Swiatkowski return status; 1284*0545cc86SMichal Swiatkowski } 1285*0545cc86SMichal Swiatkowski 1286*0545cc86SMichal Swiatkowski /** 1287*0545cc86SMichal Swiatkowski * ice_devlink_reinit_up - do reinit of the given PF 1288*0545cc86SMichal Swiatkowski * @pf: pointer to the PF struct 1289*0545cc86SMichal Swiatkowski */ 1290*0545cc86SMichal Swiatkowski static int ice_devlink_reinit_up(struct ice_pf *pf) 1291*0545cc86SMichal Swiatkowski { 1292*0545cc86SMichal Swiatkowski struct ice_vsi *vsi = ice_get_main_vsi(pf); 1293*0545cc86SMichal Swiatkowski struct ice_vsi_cfg_params params; 1294*0545cc86SMichal Swiatkowski int err; 1295*0545cc86SMichal Swiatkowski 1296*0545cc86SMichal Swiatkowski err = ice_init_dev(pf); 1297*0545cc86SMichal Swiatkowski if (err) 1298*0545cc86SMichal Swiatkowski return err; 1299*0545cc86SMichal Swiatkowski 1300*0545cc86SMichal Swiatkowski params = ice_vsi_to_params(vsi); 1301*0545cc86SMichal Swiatkowski params.flags = ICE_VSI_FLAG_INIT; 1302*0545cc86SMichal Swiatkowski 1303*0545cc86SMichal Swiatkowski rtnl_lock(); 1304*0545cc86SMichal Swiatkowski err = ice_vsi_cfg(vsi, ¶ms); 1305*0545cc86SMichal Swiatkowski rtnl_unlock(); 1306*0545cc86SMichal Swiatkowski if (err) 1307*0545cc86SMichal Swiatkowski goto err_vsi_cfg; 1308*0545cc86SMichal Swiatkowski 1309*0545cc86SMichal Swiatkowski /* No need to take devl_lock, it's already taken by devlink API */ 1310*0545cc86SMichal Swiatkowski err = ice_load(pf); 1311*0545cc86SMichal Swiatkowski if (err) 1312*0545cc86SMichal Swiatkowski goto err_load; 1313*0545cc86SMichal Swiatkowski 1314*0545cc86SMichal Swiatkowski return 0; 1315*0545cc86SMichal Swiatkowski 1316*0545cc86SMichal Swiatkowski err_load: 1317*0545cc86SMichal Swiatkowski rtnl_lock(); 1318*0545cc86SMichal Swiatkowski ice_vsi_decfg(vsi); 1319*0545cc86SMichal Swiatkowski rtnl_unlock(); 1320*0545cc86SMichal Swiatkowski err_vsi_cfg: 1321*0545cc86SMichal Swiatkowski ice_deinit_dev(pf); 1322*0545cc86SMichal Swiatkowski return err; 1323*0545cc86SMichal Swiatkowski } 1324*0545cc86SMichal Swiatkowski 1325*0545cc86SMichal Swiatkowski /** 1326*0545cc86SMichal Swiatkowski * ice_devlink_reload_up - do reload up after reinit 1327*0545cc86SMichal Swiatkowski * @devlink: pointer to the devlink instance reloading 1328*0545cc86SMichal Swiatkowski * @action: the action requested 1329*0545cc86SMichal Swiatkowski * @limit: limits imposed by userspace, such as not resetting 1330*0545cc86SMichal Swiatkowski * @actions_performed: on return, indicate what actions actually performed 1331*0545cc86SMichal Swiatkowski * @extack: netlink extended ACK structure 1332*0545cc86SMichal Swiatkowski */ 1333*0545cc86SMichal Swiatkowski static int 1334*0545cc86SMichal Swiatkowski ice_devlink_reload_up(struct devlink *devlink, 1335*0545cc86SMichal Swiatkowski enum devlink_reload_action action, 1336*0545cc86SMichal Swiatkowski enum devlink_reload_limit limit, 1337*0545cc86SMichal Swiatkowski u32 *actions_performed, 1338*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 1339*0545cc86SMichal Swiatkowski { 1340*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1341*0545cc86SMichal Swiatkowski 1342*0545cc86SMichal Swiatkowski switch (action) { 1343*0545cc86SMichal Swiatkowski case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 1344*0545cc86SMichal Swiatkowski *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 1345*0545cc86SMichal Swiatkowski return ice_devlink_reinit_up(pf); 1346*0545cc86SMichal Swiatkowski case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 1347*0545cc86SMichal Swiatkowski *actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE); 1348*0545cc86SMichal Swiatkowski return ice_devlink_reload_empr_finish(pf, extack); 1349*0545cc86SMichal Swiatkowski default: 1350*0545cc86SMichal Swiatkowski WARN_ON(1); 1351*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1352*0545cc86SMichal Swiatkowski } 1353*0545cc86SMichal Swiatkowski } 1354*0545cc86SMichal Swiatkowski 1355*0545cc86SMichal Swiatkowski static const struct devlink_ops ice_devlink_ops = { 1356*0545cc86SMichal Swiatkowski .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, 1357*0545cc86SMichal Swiatkowski .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | 1358*0545cc86SMichal Swiatkowski BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), 1359*0545cc86SMichal Swiatkowski .reload_down = ice_devlink_reload_down, 1360*0545cc86SMichal Swiatkowski .reload_up = ice_devlink_reload_up, 1361*0545cc86SMichal Swiatkowski .eswitch_mode_get = ice_eswitch_mode_get, 1362*0545cc86SMichal Swiatkowski .eswitch_mode_set = ice_eswitch_mode_set, 1363*0545cc86SMichal Swiatkowski .info_get = ice_devlink_info_get, 1364*0545cc86SMichal Swiatkowski .flash_update = ice_devlink_flash_update, 1365*0545cc86SMichal Swiatkowski 1366*0545cc86SMichal Swiatkowski .rate_node_new = ice_devlink_rate_node_new, 1367*0545cc86SMichal Swiatkowski .rate_node_del = ice_devlink_rate_node_del, 1368*0545cc86SMichal Swiatkowski 1369*0545cc86SMichal Swiatkowski .rate_leaf_tx_max_set = ice_devlink_rate_leaf_tx_max_set, 1370*0545cc86SMichal Swiatkowski .rate_leaf_tx_share_set = ice_devlink_rate_leaf_tx_share_set, 1371*0545cc86SMichal Swiatkowski .rate_leaf_tx_priority_set = ice_devlink_rate_leaf_tx_priority_set, 1372*0545cc86SMichal Swiatkowski .rate_leaf_tx_weight_set = ice_devlink_rate_leaf_tx_weight_set, 1373*0545cc86SMichal Swiatkowski 1374*0545cc86SMichal Swiatkowski .rate_node_tx_max_set = ice_devlink_rate_node_tx_max_set, 1375*0545cc86SMichal Swiatkowski .rate_node_tx_share_set = ice_devlink_rate_node_tx_share_set, 1376*0545cc86SMichal Swiatkowski .rate_node_tx_priority_set = ice_devlink_rate_node_tx_priority_set, 1377*0545cc86SMichal Swiatkowski .rate_node_tx_weight_set = ice_devlink_rate_node_tx_weight_set, 1378*0545cc86SMichal Swiatkowski 1379*0545cc86SMichal Swiatkowski .rate_leaf_parent_set = ice_devlink_set_parent, 1380*0545cc86SMichal Swiatkowski .rate_node_parent_set = ice_devlink_set_parent, 1381*0545cc86SMichal Swiatkowski }; 1382*0545cc86SMichal Swiatkowski 1383*0545cc86SMichal Swiatkowski static int 1384*0545cc86SMichal Swiatkowski ice_devlink_enable_roce_get(struct devlink *devlink, u32 id, 1385*0545cc86SMichal Swiatkowski struct devlink_param_gset_ctx *ctx) 1386*0545cc86SMichal Swiatkowski { 1387*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1388*0545cc86SMichal Swiatkowski 1389*0545cc86SMichal Swiatkowski ctx->val.vbool = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? true : false; 1390*0545cc86SMichal Swiatkowski 1391*0545cc86SMichal Swiatkowski return 0; 1392*0545cc86SMichal Swiatkowski } 1393*0545cc86SMichal Swiatkowski 1394*0545cc86SMichal Swiatkowski static int 1395*0545cc86SMichal Swiatkowski ice_devlink_enable_roce_set(struct devlink *devlink, u32 id, 1396*0545cc86SMichal Swiatkowski struct devlink_param_gset_ctx *ctx) 1397*0545cc86SMichal Swiatkowski { 1398*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1399*0545cc86SMichal Swiatkowski bool roce_ena = ctx->val.vbool; 1400*0545cc86SMichal Swiatkowski int ret; 1401*0545cc86SMichal Swiatkowski 1402*0545cc86SMichal Swiatkowski if (!roce_ena) { 1403*0545cc86SMichal Swiatkowski ice_unplug_aux_dev(pf); 1404*0545cc86SMichal Swiatkowski pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_ROCEV2; 1405*0545cc86SMichal Swiatkowski return 0; 1406*0545cc86SMichal Swiatkowski } 1407*0545cc86SMichal Swiatkowski 1408*0545cc86SMichal Swiatkowski pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2; 1409*0545cc86SMichal Swiatkowski ret = ice_plug_aux_dev(pf); 1410*0545cc86SMichal Swiatkowski if (ret) 1411*0545cc86SMichal Swiatkowski pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_ROCEV2; 1412*0545cc86SMichal Swiatkowski 1413*0545cc86SMichal Swiatkowski return ret; 1414*0545cc86SMichal Swiatkowski } 1415*0545cc86SMichal Swiatkowski 1416*0545cc86SMichal Swiatkowski static int 1417*0545cc86SMichal Swiatkowski ice_devlink_enable_roce_validate(struct devlink *devlink, u32 id, 1418*0545cc86SMichal Swiatkowski union devlink_param_value val, 1419*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 1420*0545cc86SMichal Swiatkowski { 1421*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1422*0545cc86SMichal Swiatkowski 1423*0545cc86SMichal Swiatkowski if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags)) 1424*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1425*0545cc86SMichal Swiatkowski 1426*0545cc86SMichal Swiatkowski if (pf->rdma_mode & IIDC_RDMA_PROTOCOL_IWARP) { 1427*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "iWARP is currently enabled. This device cannot enable iWARP and RoCEv2 simultaneously"); 1428*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1429*0545cc86SMichal Swiatkowski } 1430*0545cc86SMichal Swiatkowski 1431*0545cc86SMichal Swiatkowski return 0; 1432*0545cc86SMichal Swiatkowski } 1433*0545cc86SMichal Swiatkowski 1434*0545cc86SMichal Swiatkowski static int 1435*0545cc86SMichal Swiatkowski ice_devlink_enable_iw_get(struct devlink *devlink, u32 id, 1436*0545cc86SMichal Swiatkowski struct devlink_param_gset_ctx *ctx) 1437*0545cc86SMichal Swiatkowski { 1438*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1439*0545cc86SMichal Swiatkowski 1440*0545cc86SMichal Swiatkowski ctx->val.vbool = pf->rdma_mode & IIDC_RDMA_PROTOCOL_IWARP; 1441*0545cc86SMichal Swiatkowski 1442*0545cc86SMichal Swiatkowski return 0; 1443*0545cc86SMichal Swiatkowski } 1444*0545cc86SMichal Swiatkowski 1445*0545cc86SMichal Swiatkowski static int 1446*0545cc86SMichal Swiatkowski ice_devlink_enable_iw_set(struct devlink *devlink, u32 id, 1447*0545cc86SMichal Swiatkowski struct devlink_param_gset_ctx *ctx) 1448*0545cc86SMichal Swiatkowski { 1449*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1450*0545cc86SMichal Swiatkowski bool iw_ena = ctx->val.vbool; 1451*0545cc86SMichal Swiatkowski int ret; 1452*0545cc86SMichal Swiatkowski 1453*0545cc86SMichal Swiatkowski if (!iw_ena) { 1454*0545cc86SMichal Swiatkowski ice_unplug_aux_dev(pf); 1455*0545cc86SMichal Swiatkowski pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_IWARP; 1456*0545cc86SMichal Swiatkowski return 0; 1457*0545cc86SMichal Swiatkowski } 1458*0545cc86SMichal Swiatkowski 1459*0545cc86SMichal Swiatkowski pf->rdma_mode |= IIDC_RDMA_PROTOCOL_IWARP; 1460*0545cc86SMichal Swiatkowski ret = ice_plug_aux_dev(pf); 1461*0545cc86SMichal Swiatkowski if (ret) 1462*0545cc86SMichal Swiatkowski pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_IWARP; 1463*0545cc86SMichal Swiatkowski 1464*0545cc86SMichal Swiatkowski return ret; 1465*0545cc86SMichal Swiatkowski } 1466*0545cc86SMichal Swiatkowski 1467*0545cc86SMichal Swiatkowski static int 1468*0545cc86SMichal Swiatkowski ice_devlink_enable_iw_validate(struct devlink *devlink, u32 id, 1469*0545cc86SMichal Swiatkowski union devlink_param_value val, 1470*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack) 1471*0545cc86SMichal Swiatkowski { 1472*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1473*0545cc86SMichal Swiatkowski 1474*0545cc86SMichal Swiatkowski if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags)) 1475*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1476*0545cc86SMichal Swiatkowski 1477*0545cc86SMichal Swiatkowski if (pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2) { 1478*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "RoCEv2 is currently enabled. This device cannot enable iWARP and RoCEv2 simultaneously"); 1479*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1480*0545cc86SMichal Swiatkowski } 1481*0545cc86SMichal Swiatkowski 1482*0545cc86SMichal Swiatkowski return 0; 1483*0545cc86SMichal Swiatkowski } 1484*0545cc86SMichal Swiatkowski 1485*0545cc86SMichal Swiatkowski static const struct devlink_param ice_devlink_params[] = { 1486*0545cc86SMichal Swiatkowski DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_RUNTIME), 1487*0545cc86SMichal Swiatkowski ice_devlink_enable_roce_get, 1488*0545cc86SMichal Swiatkowski ice_devlink_enable_roce_set, 1489*0545cc86SMichal Swiatkowski ice_devlink_enable_roce_validate), 1490*0545cc86SMichal Swiatkowski DEVLINK_PARAM_GENERIC(ENABLE_IWARP, BIT(DEVLINK_PARAM_CMODE_RUNTIME), 1491*0545cc86SMichal Swiatkowski ice_devlink_enable_iw_get, 1492*0545cc86SMichal Swiatkowski ice_devlink_enable_iw_set, 1493*0545cc86SMichal Swiatkowski ice_devlink_enable_iw_validate), 1494*0545cc86SMichal Swiatkowski 1495*0545cc86SMichal Swiatkowski }; 1496*0545cc86SMichal Swiatkowski 1497*0545cc86SMichal Swiatkowski static void ice_devlink_free(void *devlink_ptr) 1498*0545cc86SMichal Swiatkowski { 1499*0545cc86SMichal Swiatkowski devlink_free((struct devlink *)devlink_ptr); 1500*0545cc86SMichal Swiatkowski } 1501*0545cc86SMichal Swiatkowski 1502*0545cc86SMichal Swiatkowski /** 1503*0545cc86SMichal Swiatkowski * ice_allocate_pf - Allocate devlink and return PF structure pointer 1504*0545cc86SMichal Swiatkowski * @dev: the device to allocate for 1505*0545cc86SMichal Swiatkowski * 1506*0545cc86SMichal Swiatkowski * Allocate a devlink instance for this device and return the private area as 1507*0545cc86SMichal Swiatkowski * the PF structure. The devlink memory is kept track of through devres by 1508*0545cc86SMichal Swiatkowski * adding an action to remove it when unwinding. 1509*0545cc86SMichal Swiatkowski */ 1510*0545cc86SMichal Swiatkowski struct ice_pf *ice_allocate_pf(struct device *dev) 1511*0545cc86SMichal Swiatkowski { 1512*0545cc86SMichal Swiatkowski struct devlink *devlink; 1513*0545cc86SMichal Swiatkowski 1514*0545cc86SMichal Swiatkowski devlink = devlink_alloc(&ice_devlink_ops, sizeof(struct ice_pf), dev); 1515*0545cc86SMichal Swiatkowski if (!devlink) 1516*0545cc86SMichal Swiatkowski return NULL; 1517*0545cc86SMichal Swiatkowski 1518*0545cc86SMichal Swiatkowski /* Add an action to teardown the devlink when unwinding the driver */ 1519*0545cc86SMichal Swiatkowski if (devm_add_action_or_reset(dev, ice_devlink_free, devlink)) 1520*0545cc86SMichal Swiatkowski return NULL; 1521*0545cc86SMichal Swiatkowski 1522*0545cc86SMichal Swiatkowski return devlink_priv(devlink); 1523*0545cc86SMichal Swiatkowski } 1524*0545cc86SMichal Swiatkowski 1525*0545cc86SMichal Swiatkowski /** 1526*0545cc86SMichal Swiatkowski * ice_devlink_register - Register devlink interface for this PF 1527*0545cc86SMichal Swiatkowski * @pf: the PF to register the devlink for. 1528*0545cc86SMichal Swiatkowski * 1529*0545cc86SMichal Swiatkowski * Register the devlink instance associated with this physical function. 1530*0545cc86SMichal Swiatkowski * 1531*0545cc86SMichal Swiatkowski * Return: zero on success or an error code on failure. 1532*0545cc86SMichal Swiatkowski */ 1533*0545cc86SMichal Swiatkowski void ice_devlink_register(struct ice_pf *pf) 1534*0545cc86SMichal Swiatkowski { 1535*0545cc86SMichal Swiatkowski struct devlink *devlink = priv_to_devlink(pf); 1536*0545cc86SMichal Swiatkowski 1537*0545cc86SMichal Swiatkowski devlink_register(devlink); 1538*0545cc86SMichal Swiatkowski } 1539*0545cc86SMichal Swiatkowski 1540*0545cc86SMichal Swiatkowski /** 1541*0545cc86SMichal Swiatkowski * ice_devlink_unregister - Unregister devlink resources for this PF. 1542*0545cc86SMichal Swiatkowski * @pf: the PF structure to cleanup 1543*0545cc86SMichal Swiatkowski * 1544*0545cc86SMichal Swiatkowski * Releases resources used by devlink and cleans up associated memory. 1545*0545cc86SMichal Swiatkowski */ 1546*0545cc86SMichal Swiatkowski void ice_devlink_unregister(struct ice_pf *pf) 1547*0545cc86SMichal Swiatkowski { 1548*0545cc86SMichal Swiatkowski devlink_unregister(priv_to_devlink(pf)); 1549*0545cc86SMichal Swiatkowski } 1550*0545cc86SMichal Swiatkowski 1551*0545cc86SMichal Swiatkowski /** 1552*0545cc86SMichal Swiatkowski * ice_devlink_set_switch_id - Set unique switch id based on pci dsn 1553*0545cc86SMichal Swiatkowski * @pf: the PF to create a devlink port for 1554*0545cc86SMichal Swiatkowski * @ppid: struct with switch id information 1555*0545cc86SMichal Swiatkowski */ 1556*0545cc86SMichal Swiatkowski static void 1557*0545cc86SMichal Swiatkowski ice_devlink_set_switch_id(struct ice_pf *pf, struct netdev_phys_item_id *ppid) 1558*0545cc86SMichal Swiatkowski { 1559*0545cc86SMichal Swiatkowski struct pci_dev *pdev = pf->pdev; 1560*0545cc86SMichal Swiatkowski u64 id; 1561*0545cc86SMichal Swiatkowski 1562*0545cc86SMichal Swiatkowski id = pci_get_dsn(pdev); 1563*0545cc86SMichal Swiatkowski 1564*0545cc86SMichal Swiatkowski ppid->id_len = sizeof(id); 1565*0545cc86SMichal Swiatkowski put_unaligned_be64(id, &ppid->id); 1566*0545cc86SMichal Swiatkowski } 1567*0545cc86SMichal Swiatkowski 1568*0545cc86SMichal Swiatkowski int ice_devlink_register_params(struct ice_pf *pf) 1569*0545cc86SMichal Swiatkowski { 1570*0545cc86SMichal Swiatkowski struct devlink *devlink = priv_to_devlink(pf); 1571*0545cc86SMichal Swiatkowski 1572*0545cc86SMichal Swiatkowski return devlink_params_register(devlink, ice_devlink_params, 1573*0545cc86SMichal Swiatkowski ARRAY_SIZE(ice_devlink_params)); 1574*0545cc86SMichal Swiatkowski } 1575*0545cc86SMichal Swiatkowski 1576*0545cc86SMichal Swiatkowski void ice_devlink_unregister_params(struct ice_pf *pf) 1577*0545cc86SMichal Swiatkowski { 1578*0545cc86SMichal Swiatkowski devlink_params_unregister(priv_to_devlink(pf), ice_devlink_params, 1579*0545cc86SMichal Swiatkowski ARRAY_SIZE(ice_devlink_params)); 1580*0545cc86SMichal Swiatkowski } 1581*0545cc86SMichal Swiatkowski 1582*0545cc86SMichal Swiatkowski /** 1583*0545cc86SMichal Swiatkowski * ice_devlink_set_port_split_options - Set port split options 1584*0545cc86SMichal Swiatkowski * @pf: the PF to set port split options 1585*0545cc86SMichal Swiatkowski * @attrs: devlink attributes 1586*0545cc86SMichal Swiatkowski * 1587*0545cc86SMichal Swiatkowski * Sets devlink port split options based on available FW port options 1588*0545cc86SMichal Swiatkowski */ 1589*0545cc86SMichal Swiatkowski static void 1590*0545cc86SMichal Swiatkowski ice_devlink_set_port_split_options(struct ice_pf *pf, 1591*0545cc86SMichal Swiatkowski struct devlink_port_attrs *attrs) 1592*0545cc86SMichal Swiatkowski { 1593*0545cc86SMichal Swiatkowski struct ice_aqc_get_port_options_elem options[ICE_AQC_PORT_OPT_MAX]; 1594*0545cc86SMichal Swiatkowski u8 i, active_idx, pending_idx, option_count = ICE_AQC_PORT_OPT_MAX; 1595*0545cc86SMichal Swiatkowski bool active_valid, pending_valid; 1596*0545cc86SMichal Swiatkowski int status; 1597*0545cc86SMichal Swiatkowski 1598*0545cc86SMichal Swiatkowski status = ice_aq_get_port_options(&pf->hw, options, &option_count, 1599*0545cc86SMichal Swiatkowski 0, true, &active_idx, &active_valid, 1600*0545cc86SMichal Swiatkowski &pending_idx, &pending_valid); 1601*0545cc86SMichal Swiatkowski if (status) { 1602*0545cc86SMichal Swiatkowski dev_dbg(ice_pf_to_dev(pf), "Couldn't read port split options, err = %d\n", 1603*0545cc86SMichal Swiatkowski status); 1604*0545cc86SMichal Swiatkowski return; 1605*0545cc86SMichal Swiatkowski } 1606*0545cc86SMichal Swiatkowski 1607*0545cc86SMichal Swiatkowski /* find the biggest available port split count */ 1608*0545cc86SMichal Swiatkowski for (i = 0; i < option_count; i++) 1609*0545cc86SMichal Swiatkowski attrs->lanes = max_t(int, attrs->lanes, options[i].pmd); 1610*0545cc86SMichal Swiatkowski 1611*0545cc86SMichal Swiatkowski attrs->splittable = attrs->lanes ? 1 : 0; 1612*0545cc86SMichal Swiatkowski ice_active_port_option = active_idx; 1613*0545cc86SMichal Swiatkowski } 1614*0545cc86SMichal Swiatkowski 1615*0545cc86SMichal Swiatkowski static const struct devlink_port_ops ice_devlink_port_ops = { 1616*0545cc86SMichal Swiatkowski .port_split = ice_devlink_port_split, 1617*0545cc86SMichal Swiatkowski .port_unsplit = ice_devlink_port_unsplit, 1618*0545cc86SMichal Swiatkowski }; 1619*0545cc86SMichal Swiatkowski 1620*0545cc86SMichal Swiatkowski /** 1621*0545cc86SMichal Swiatkowski * ice_devlink_create_pf_port - Create a devlink port for this PF 1622*0545cc86SMichal Swiatkowski * @pf: the PF to create a devlink port for 1623*0545cc86SMichal Swiatkowski * 1624*0545cc86SMichal Swiatkowski * Create and register a devlink_port for this PF. 1625*0545cc86SMichal Swiatkowski * This function has to be called under devl_lock. 1626*0545cc86SMichal Swiatkowski * 1627*0545cc86SMichal Swiatkowski * Return: zero on success or an error code on failure. 1628*0545cc86SMichal Swiatkowski */ 1629*0545cc86SMichal Swiatkowski int ice_devlink_create_pf_port(struct ice_pf *pf) 1630*0545cc86SMichal Swiatkowski { 1631*0545cc86SMichal Swiatkowski struct devlink_port_attrs attrs = {}; 1632*0545cc86SMichal Swiatkowski struct devlink_port *devlink_port; 1633*0545cc86SMichal Swiatkowski struct devlink *devlink; 1634*0545cc86SMichal Swiatkowski struct ice_vsi *vsi; 1635*0545cc86SMichal Swiatkowski struct device *dev; 1636*0545cc86SMichal Swiatkowski int err; 1637*0545cc86SMichal Swiatkowski 1638*0545cc86SMichal Swiatkowski devlink = priv_to_devlink(pf); 1639*0545cc86SMichal Swiatkowski 1640*0545cc86SMichal Swiatkowski dev = ice_pf_to_dev(pf); 1641*0545cc86SMichal Swiatkowski 1642*0545cc86SMichal Swiatkowski devlink_port = &pf->devlink_port; 1643*0545cc86SMichal Swiatkowski 1644*0545cc86SMichal Swiatkowski vsi = ice_get_main_vsi(pf); 1645*0545cc86SMichal Swiatkowski if (!vsi) 1646*0545cc86SMichal Swiatkowski return -EIO; 1647*0545cc86SMichal Swiatkowski 1648*0545cc86SMichal Swiatkowski attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 1649*0545cc86SMichal Swiatkowski attrs.phys.port_number = pf->hw.bus.func; 1650*0545cc86SMichal Swiatkowski 1651*0545cc86SMichal Swiatkowski /* As FW supports only port split options for whole device, 1652*0545cc86SMichal Swiatkowski * set port split options only for first PF. 1653*0545cc86SMichal Swiatkowski */ 1654*0545cc86SMichal Swiatkowski if (pf->hw.pf_id == 0) 1655*0545cc86SMichal Swiatkowski ice_devlink_set_port_split_options(pf, &attrs); 1656*0545cc86SMichal Swiatkowski 1657*0545cc86SMichal Swiatkowski ice_devlink_set_switch_id(pf, &attrs.switch_id); 1658*0545cc86SMichal Swiatkowski 1659*0545cc86SMichal Swiatkowski devlink_port_attrs_set(devlink_port, &attrs); 1660*0545cc86SMichal Swiatkowski 1661*0545cc86SMichal Swiatkowski err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx, 1662*0545cc86SMichal Swiatkowski &ice_devlink_port_ops); 1663*0545cc86SMichal Swiatkowski if (err) { 1664*0545cc86SMichal Swiatkowski dev_err(dev, "Failed to create devlink port for PF %d, error %d\n", 1665*0545cc86SMichal Swiatkowski pf->hw.pf_id, err); 1666*0545cc86SMichal Swiatkowski return err; 1667*0545cc86SMichal Swiatkowski } 1668*0545cc86SMichal Swiatkowski 1669*0545cc86SMichal Swiatkowski return 0; 1670*0545cc86SMichal Swiatkowski } 1671*0545cc86SMichal Swiatkowski 1672*0545cc86SMichal Swiatkowski /** 1673*0545cc86SMichal Swiatkowski * ice_devlink_destroy_pf_port - Destroy the devlink_port for this PF 1674*0545cc86SMichal Swiatkowski * @pf: the PF to cleanup 1675*0545cc86SMichal Swiatkowski * 1676*0545cc86SMichal Swiatkowski * Unregisters the devlink_port structure associated with this PF. 1677*0545cc86SMichal Swiatkowski * This function has to be called under devl_lock. 1678*0545cc86SMichal Swiatkowski */ 1679*0545cc86SMichal Swiatkowski void ice_devlink_destroy_pf_port(struct ice_pf *pf) 1680*0545cc86SMichal Swiatkowski { 1681*0545cc86SMichal Swiatkowski devl_port_unregister(&pf->devlink_port); 1682*0545cc86SMichal Swiatkowski } 1683*0545cc86SMichal Swiatkowski 1684*0545cc86SMichal Swiatkowski /** 1685*0545cc86SMichal Swiatkowski * ice_devlink_create_vf_port - Create a devlink port for this VF 1686*0545cc86SMichal Swiatkowski * @vf: the VF to create a port for 1687*0545cc86SMichal Swiatkowski * 1688*0545cc86SMichal Swiatkowski * Create and register a devlink_port for this VF. 1689*0545cc86SMichal Swiatkowski * 1690*0545cc86SMichal Swiatkowski * Return: zero on success or an error code on failure. 1691*0545cc86SMichal Swiatkowski */ 1692*0545cc86SMichal Swiatkowski int ice_devlink_create_vf_port(struct ice_vf *vf) 1693*0545cc86SMichal Swiatkowski { 1694*0545cc86SMichal Swiatkowski struct devlink_port_attrs attrs = {}; 1695*0545cc86SMichal Swiatkowski struct devlink_port *devlink_port; 1696*0545cc86SMichal Swiatkowski struct devlink *devlink; 1697*0545cc86SMichal Swiatkowski struct ice_vsi *vsi; 1698*0545cc86SMichal Swiatkowski struct device *dev; 1699*0545cc86SMichal Swiatkowski struct ice_pf *pf; 1700*0545cc86SMichal Swiatkowski int err; 1701*0545cc86SMichal Swiatkowski 1702*0545cc86SMichal Swiatkowski pf = vf->pf; 1703*0545cc86SMichal Swiatkowski dev = ice_pf_to_dev(pf); 1704*0545cc86SMichal Swiatkowski devlink_port = &vf->devlink_port; 1705*0545cc86SMichal Swiatkowski 1706*0545cc86SMichal Swiatkowski vsi = ice_get_vf_vsi(vf); 1707*0545cc86SMichal Swiatkowski if (!vsi) 1708*0545cc86SMichal Swiatkowski return -EINVAL; 1709*0545cc86SMichal Swiatkowski 1710*0545cc86SMichal Swiatkowski attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF; 1711*0545cc86SMichal Swiatkowski attrs.pci_vf.pf = pf->hw.bus.func; 1712*0545cc86SMichal Swiatkowski attrs.pci_vf.vf = vf->vf_id; 1713*0545cc86SMichal Swiatkowski 1714*0545cc86SMichal Swiatkowski ice_devlink_set_switch_id(pf, &attrs.switch_id); 1715*0545cc86SMichal Swiatkowski 1716*0545cc86SMichal Swiatkowski devlink_port_attrs_set(devlink_port, &attrs); 1717*0545cc86SMichal Swiatkowski devlink = priv_to_devlink(pf); 1718*0545cc86SMichal Swiatkowski 1719*0545cc86SMichal Swiatkowski err = devlink_port_register(devlink, devlink_port, vsi->idx); 1720*0545cc86SMichal Swiatkowski if (err) { 1721*0545cc86SMichal Swiatkowski dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", 1722*0545cc86SMichal Swiatkowski vf->vf_id, err); 1723*0545cc86SMichal Swiatkowski return err; 1724*0545cc86SMichal Swiatkowski } 1725*0545cc86SMichal Swiatkowski 1726*0545cc86SMichal Swiatkowski return 0; 1727*0545cc86SMichal Swiatkowski } 1728*0545cc86SMichal Swiatkowski 1729*0545cc86SMichal Swiatkowski /** 1730*0545cc86SMichal Swiatkowski * ice_devlink_destroy_vf_port - Destroy the devlink_port for this VF 1731*0545cc86SMichal Swiatkowski * @vf: the VF to cleanup 1732*0545cc86SMichal Swiatkowski * 1733*0545cc86SMichal Swiatkowski * Unregisters the devlink_port structure associated with this VF. 1734*0545cc86SMichal Swiatkowski */ 1735*0545cc86SMichal Swiatkowski void ice_devlink_destroy_vf_port(struct ice_vf *vf) 1736*0545cc86SMichal Swiatkowski { 1737*0545cc86SMichal Swiatkowski devl_rate_leaf_destroy(&vf->devlink_port); 1738*0545cc86SMichal Swiatkowski devlink_port_unregister(&vf->devlink_port); 1739*0545cc86SMichal Swiatkowski } 1740*0545cc86SMichal Swiatkowski 1741*0545cc86SMichal Swiatkowski #define ICE_DEVLINK_READ_BLK_SIZE (1024 * 1024) 1742*0545cc86SMichal Swiatkowski 1743*0545cc86SMichal Swiatkowski static const struct devlink_region_ops ice_nvm_region_ops; 1744*0545cc86SMichal Swiatkowski static const struct devlink_region_ops ice_sram_region_ops; 1745*0545cc86SMichal Swiatkowski 1746*0545cc86SMichal Swiatkowski /** 1747*0545cc86SMichal Swiatkowski * ice_devlink_nvm_snapshot - Capture a snapshot of the NVM flash contents 1748*0545cc86SMichal Swiatkowski * @devlink: the devlink instance 1749*0545cc86SMichal Swiatkowski * @ops: the devlink region to snapshot 1750*0545cc86SMichal Swiatkowski * @extack: extended ACK response structure 1751*0545cc86SMichal Swiatkowski * @data: on exit points to snapshot data buffer 1752*0545cc86SMichal Swiatkowski * 1753*0545cc86SMichal Swiatkowski * This function is called in response to a DEVLINK_CMD_REGION_NEW for either 1754*0545cc86SMichal Swiatkowski * the nvm-flash or shadow-ram region. 1755*0545cc86SMichal Swiatkowski * 1756*0545cc86SMichal Swiatkowski * It captures a snapshot of the NVM or Shadow RAM flash contents. This 1757*0545cc86SMichal Swiatkowski * snapshot can then later be viewed via the DEVLINK_CMD_REGION_READ netlink 1758*0545cc86SMichal Swiatkowski * interface. 1759*0545cc86SMichal Swiatkowski * 1760*0545cc86SMichal Swiatkowski * @returns zero on success, and updates the data pointer. Returns a non-zero 1761*0545cc86SMichal Swiatkowski * error code on failure. 1762*0545cc86SMichal Swiatkowski */ 1763*0545cc86SMichal Swiatkowski static int ice_devlink_nvm_snapshot(struct devlink *devlink, 1764*0545cc86SMichal Swiatkowski const struct devlink_region_ops *ops, 1765*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack, u8 **data) 1766*0545cc86SMichal Swiatkowski { 1767*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1768*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 1769*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 1770*0545cc86SMichal Swiatkowski bool read_shadow_ram; 1771*0545cc86SMichal Swiatkowski u8 *nvm_data, *tmp, i; 1772*0545cc86SMichal Swiatkowski u32 nvm_size, left; 1773*0545cc86SMichal Swiatkowski s8 num_blks; 1774*0545cc86SMichal Swiatkowski int status; 1775*0545cc86SMichal Swiatkowski 1776*0545cc86SMichal Swiatkowski if (ops == &ice_nvm_region_ops) { 1777*0545cc86SMichal Swiatkowski read_shadow_ram = false; 1778*0545cc86SMichal Swiatkowski nvm_size = hw->flash.flash_size; 1779*0545cc86SMichal Swiatkowski } else if (ops == &ice_sram_region_ops) { 1780*0545cc86SMichal Swiatkowski read_shadow_ram = true; 1781*0545cc86SMichal Swiatkowski nvm_size = hw->flash.sr_words * 2u; 1782*0545cc86SMichal Swiatkowski } else { 1783*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unexpected region in snapshot function"); 1784*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1785*0545cc86SMichal Swiatkowski } 1786*0545cc86SMichal Swiatkowski 1787*0545cc86SMichal Swiatkowski nvm_data = vzalloc(nvm_size); 1788*0545cc86SMichal Swiatkowski if (!nvm_data) 1789*0545cc86SMichal Swiatkowski return -ENOMEM; 1790*0545cc86SMichal Swiatkowski 1791*0545cc86SMichal Swiatkowski num_blks = DIV_ROUND_UP(nvm_size, ICE_DEVLINK_READ_BLK_SIZE); 1792*0545cc86SMichal Swiatkowski tmp = nvm_data; 1793*0545cc86SMichal Swiatkowski left = nvm_size; 1794*0545cc86SMichal Swiatkowski 1795*0545cc86SMichal Swiatkowski /* Some systems take longer to read the NVM than others which causes the 1796*0545cc86SMichal Swiatkowski * FW to reclaim the NVM lock before the entire NVM has been read. Fix 1797*0545cc86SMichal Swiatkowski * this by breaking the reads of the NVM into smaller chunks that will 1798*0545cc86SMichal Swiatkowski * probably not take as long. This has some overhead since we are 1799*0545cc86SMichal Swiatkowski * increasing the number of AQ commands, but it should always work 1800*0545cc86SMichal Swiatkowski */ 1801*0545cc86SMichal Swiatkowski for (i = 0; i < num_blks; i++) { 1802*0545cc86SMichal Swiatkowski u32 read_sz = min_t(u32, ICE_DEVLINK_READ_BLK_SIZE, left); 1803*0545cc86SMichal Swiatkowski 1804*0545cc86SMichal Swiatkowski status = ice_acquire_nvm(hw, ICE_RES_READ); 1805*0545cc86SMichal Swiatkowski if (status) { 1806*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n", 1807*0545cc86SMichal Swiatkowski status, hw->adminq.sq_last_status); 1808*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore"); 1809*0545cc86SMichal Swiatkowski vfree(nvm_data); 1810*0545cc86SMichal Swiatkowski return -EIO; 1811*0545cc86SMichal Swiatkowski } 1812*0545cc86SMichal Swiatkowski 1813*0545cc86SMichal Swiatkowski status = ice_read_flat_nvm(hw, i * ICE_DEVLINK_READ_BLK_SIZE, 1814*0545cc86SMichal Swiatkowski &read_sz, tmp, read_shadow_ram); 1815*0545cc86SMichal Swiatkowski if (status) { 1816*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n", 1817*0545cc86SMichal Swiatkowski read_sz, status, hw->adminq.sq_last_status); 1818*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents"); 1819*0545cc86SMichal Swiatkowski ice_release_nvm(hw); 1820*0545cc86SMichal Swiatkowski vfree(nvm_data); 1821*0545cc86SMichal Swiatkowski return -EIO; 1822*0545cc86SMichal Swiatkowski } 1823*0545cc86SMichal Swiatkowski ice_release_nvm(hw); 1824*0545cc86SMichal Swiatkowski 1825*0545cc86SMichal Swiatkowski tmp += read_sz; 1826*0545cc86SMichal Swiatkowski left -= read_sz; 1827*0545cc86SMichal Swiatkowski } 1828*0545cc86SMichal Swiatkowski 1829*0545cc86SMichal Swiatkowski *data = nvm_data; 1830*0545cc86SMichal Swiatkowski 1831*0545cc86SMichal Swiatkowski return 0; 1832*0545cc86SMichal Swiatkowski } 1833*0545cc86SMichal Swiatkowski 1834*0545cc86SMichal Swiatkowski /** 1835*0545cc86SMichal Swiatkowski * ice_devlink_nvm_read - Read a portion of NVM flash contents 1836*0545cc86SMichal Swiatkowski * @devlink: the devlink instance 1837*0545cc86SMichal Swiatkowski * @ops: the devlink region to snapshot 1838*0545cc86SMichal Swiatkowski * @extack: extended ACK response structure 1839*0545cc86SMichal Swiatkowski * @offset: the offset to start at 1840*0545cc86SMichal Swiatkowski * @size: the amount to read 1841*0545cc86SMichal Swiatkowski * @data: the data buffer to read into 1842*0545cc86SMichal Swiatkowski * 1843*0545cc86SMichal Swiatkowski * This function is called in response to DEVLINK_CMD_REGION_READ to directly 1844*0545cc86SMichal Swiatkowski * read a section of the NVM contents. 1845*0545cc86SMichal Swiatkowski * 1846*0545cc86SMichal Swiatkowski * It reads from either the nvm-flash or shadow-ram region contents. 1847*0545cc86SMichal Swiatkowski * 1848*0545cc86SMichal Swiatkowski * @returns zero on success, and updates the data pointer. Returns a non-zero 1849*0545cc86SMichal Swiatkowski * error code on failure. 1850*0545cc86SMichal Swiatkowski */ 1851*0545cc86SMichal Swiatkowski static int ice_devlink_nvm_read(struct devlink *devlink, 1852*0545cc86SMichal Swiatkowski const struct devlink_region_ops *ops, 1853*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack, 1854*0545cc86SMichal Swiatkowski u64 offset, u32 size, u8 *data) 1855*0545cc86SMichal Swiatkowski { 1856*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1857*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 1858*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 1859*0545cc86SMichal Swiatkowski bool read_shadow_ram; 1860*0545cc86SMichal Swiatkowski u64 nvm_size; 1861*0545cc86SMichal Swiatkowski int status; 1862*0545cc86SMichal Swiatkowski 1863*0545cc86SMichal Swiatkowski if (ops == &ice_nvm_region_ops) { 1864*0545cc86SMichal Swiatkowski read_shadow_ram = false; 1865*0545cc86SMichal Swiatkowski nvm_size = hw->flash.flash_size; 1866*0545cc86SMichal Swiatkowski } else if (ops == &ice_sram_region_ops) { 1867*0545cc86SMichal Swiatkowski read_shadow_ram = true; 1868*0545cc86SMichal Swiatkowski nvm_size = hw->flash.sr_words * 2u; 1869*0545cc86SMichal Swiatkowski } else { 1870*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Unexpected region in snapshot function"); 1871*0545cc86SMichal Swiatkowski return -EOPNOTSUPP; 1872*0545cc86SMichal Swiatkowski } 1873*0545cc86SMichal Swiatkowski 1874*0545cc86SMichal Swiatkowski if (offset + size >= nvm_size) { 1875*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Cannot read beyond the region size"); 1876*0545cc86SMichal Swiatkowski return -ERANGE; 1877*0545cc86SMichal Swiatkowski } 1878*0545cc86SMichal Swiatkowski 1879*0545cc86SMichal Swiatkowski status = ice_acquire_nvm(hw, ICE_RES_READ); 1880*0545cc86SMichal Swiatkowski if (status) { 1881*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n", 1882*0545cc86SMichal Swiatkowski status, hw->adminq.sq_last_status); 1883*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore"); 1884*0545cc86SMichal Swiatkowski return -EIO; 1885*0545cc86SMichal Swiatkowski } 1886*0545cc86SMichal Swiatkowski 1887*0545cc86SMichal Swiatkowski status = ice_read_flat_nvm(hw, (u32)offset, &size, data, 1888*0545cc86SMichal Swiatkowski read_shadow_ram); 1889*0545cc86SMichal Swiatkowski if (status) { 1890*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n", 1891*0545cc86SMichal Swiatkowski size, status, hw->adminq.sq_last_status); 1892*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents"); 1893*0545cc86SMichal Swiatkowski ice_release_nvm(hw); 1894*0545cc86SMichal Swiatkowski return -EIO; 1895*0545cc86SMichal Swiatkowski } 1896*0545cc86SMichal Swiatkowski ice_release_nvm(hw); 1897*0545cc86SMichal Swiatkowski 1898*0545cc86SMichal Swiatkowski return 0; 1899*0545cc86SMichal Swiatkowski } 1900*0545cc86SMichal Swiatkowski 1901*0545cc86SMichal Swiatkowski /** 1902*0545cc86SMichal Swiatkowski * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities 1903*0545cc86SMichal Swiatkowski * @devlink: the devlink instance 1904*0545cc86SMichal Swiatkowski * @ops: the devlink region being snapshotted 1905*0545cc86SMichal Swiatkowski * @extack: extended ACK response structure 1906*0545cc86SMichal Swiatkowski * @data: on exit points to snapshot data buffer 1907*0545cc86SMichal Swiatkowski * 1908*0545cc86SMichal Swiatkowski * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for 1909*0545cc86SMichal Swiatkowski * the device-caps devlink region. It captures a snapshot of the device 1910*0545cc86SMichal Swiatkowski * capabilities reported by firmware. 1911*0545cc86SMichal Swiatkowski * 1912*0545cc86SMichal Swiatkowski * @returns zero on success, and updates the data pointer. Returns a non-zero 1913*0545cc86SMichal Swiatkowski * error code on failure. 1914*0545cc86SMichal Swiatkowski */ 1915*0545cc86SMichal Swiatkowski static int 1916*0545cc86SMichal Swiatkowski ice_devlink_devcaps_snapshot(struct devlink *devlink, 1917*0545cc86SMichal Swiatkowski const struct devlink_region_ops *ops, 1918*0545cc86SMichal Swiatkowski struct netlink_ext_ack *extack, u8 **data) 1919*0545cc86SMichal Swiatkowski { 1920*0545cc86SMichal Swiatkowski struct ice_pf *pf = devlink_priv(devlink); 1921*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 1922*0545cc86SMichal Swiatkowski struct ice_hw *hw = &pf->hw; 1923*0545cc86SMichal Swiatkowski void *devcaps; 1924*0545cc86SMichal Swiatkowski int status; 1925*0545cc86SMichal Swiatkowski 1926*0545cc86SMichal Swiatkowski devcaps = vzalloc(ICE_AQ_MAX_BUF_LEN); 1927*0545cc86SMichal Swiatkowski if (!devcaps) 1928*0545cc86SMichal Swiatkowski return -ENOMEM; 1929*0545cc86SMichal Swiatkowski 1930*0545cc86SMichal Swiatkowski status = ice_aq_list_caps(hw, devcaps, ICE_AQ_MAX_BUF_LEN, NULL, 1931*0545cc86SMichal Swiatkowski ice_aqc_opc_list_dev_caps, NULL); 1932*0545cc86SMichal Swiatkowski if (status) { 1933*0545cc86SMichal Swiatkowski dev_dbg(dev, "ice_aq_list_caps: failed to read device capabilities, err %d aq_err %d\n", 1934*0545cc86SMichal Swiatkowski status, hw->adminq.sq_last_status); 1935*0545cc86SMichal Swiatkowski NL_SET_ERR_MSG_MOD(extack, "Failed to read device capabilities"); 1936*0545cc86SMichal Swiatkowski vfree(devcaps); 1937*0545cc86SMichal Swiatkowski return status; 1938*0545cc86SMichal Swiatkowski } 1939*0545cc86SMichal Swiatkowski 1940*0545cc86SMichal Swiatkowski *data = (u8 *)devcaps; 1941*0545cc86SMichal Swiatkowski 1942*0545cc86SMichal Swiatkowski return 0; 1943*0545cc86SMichal Swiatkowski } 1944*0545cc86SMichal Swiatkowski 1945*0545cc86SMichal Swiatkowski static const struct devlink_region_ops ice_nvm_region_ops = { 1946*0545cc86SMichal Swiatkowski .name = "nvm-flash", 1947*0545cc86SMichal Swiatkowski .destructor = vfree, 1948*0545cc86SMichal Swiatkowski .snapshot = ice_devlink_nvm_snapshot, 1949*0545cc86SMichal Swiatkowski .read = ice_devlink_nvm_read, 1950*0545cc86SMichal Swiatkowski }; 1951*0545cc86SMichal Swiatkowski 1952*0545cc86SMichal Swiatkowski static const struct devlink_region_ops ice_sram_region_ops = { 1953*0545cc86SMichal Swiatkowski .name = "shadow-ram", 1954*0545cc86SMichal Swiatkowski .destructor = vfree, 1955*0545cc86SMichal Swiatkowski .snapshot = ice_devlink_nvm_snapshot, 1956*0545cc86SMichal Swiatkowski .read = ice_devlink_nvm_read, 1957*0545cc86SMichal Swiatkowski }; 1958*0545cc86SMichal Swiatkowski 1959*0545cc86SMichal Swiatkowski static const struct devlink_region_ops ice_devcaps_region_ops = { 1960*0545cc86SMichal Swiatkowski .name = "device-caps", 1961*0545cc86SMichal Swiatkowski .destructor = vfree, 1962*0545cc86SMichal Swiatkowski .snapshot = ice_devlink_devcaps_snapshot, 1963*0545cc86SMichal Swiatkowski }; 1964*0545cc86SMichal Swiatkowski 1965*0545cc86SMichal Swiatkowski /** 1966*0545cc86SMichal Swiatkowski * ice_devlink_init_regions - Initialize devlink regions 1967*0545cc86SMichal Swiatkowski * @pf: the PF device structure 1968*0545cc86SMichal Swiatkowski * 1969*0545cc86SMichal Swiatkowski * Create devlink regions used to enable access to dump the contents of the 1970*0545cc86SMichal Swiatkowski * flash memory on the device. 1971*0545cc86SMichal Swiatkowski */ 1972*0545cc86SMichal Swiatkowski void ice_devlink_init_regions(struct ice_pf *pf) 1973*0545cc86SMichal Swiatkowski { 1974*0545cc86SMichal Swiatkowski struct devlink *devlink = priv_to_devlink(pf); 1975*0545cc86SMichal Swiatkowski struct device *dev = ice_pf_to_dev(pf); 1976*0545cc86SMichal Swiatkowski u64 nvm_size, sram_size; 1977*0545cc86SMichal Swiatkowski 1978*0545cc86SMichal Swiatkowski nvm_size = pf->hw.flash.flash_size; 1979*0545cc86SMichal Swiatkowski pf->nvm_region = devlink_region_create(devlink, &ice_nvm_region_ops, 1, 1980*0545cc86SMichal Swiatkowski nvm_size); 1981*0545cc86SMichal Swiatkowski if (IS_ERR(pf->nvm_region)) { 1982*0545cc86SMichal Swiatkowski dev_err(dev, "failed to create NVM devlink region, err %ld\n", 1983*0545cc86SMichal Swiatkowski PTR_ERR(pf->nvm_region)); 1984*0545cc86SMichal Swiatkowski pf->nvm_region = NULL; 1985*0545cc86SMichal Swiatkowski } 1986*0545cc86SMichal Swiatkowski 1987*0545cc86SMichal Swiatkowski sram_size = pf->hw.flash.sr_words * 2u; 1988*0545cc86SMichal Swiatkowski pf->sram_region = devlink_region_create(devlink, &ice_sram_region_ops, 1989*0545cc86SMichal Swiatkowski 1, sram_size); 1990*0545cc86SMichal Swiatkowski if (IS_ERR(pf->sram_region)) { 1991*0545cc86SMichal Swiatkowski dev_err(dev, "failed to create shadow-ram devlink region, err %ld\n", 1992*0545cc86SMichal Swiatkowski PTR_ERR(pf->sram_region)); 1993*0545cc86SMichal Swiatkowski pf->sram_region = NULL; 1994*0545cc86SMichal Swiatkowski } 1995*0545cc86SMichal Swiatkowski 1996*0545cc86SMichal Swiatkowski pf->devcaps_region = devlink_region_create(devlink, 1997*0545cc86SMichal Swiatkowski &ice_devcaps_region_ops, 10, 1998*0545cc86SMichal Swiatkowski ICE_AQ_MAX_BUF_LEN); 1999*0545cc86SMichal Swiatkowski if (IS_ERR(pf->devcaps_region)) { 2000*0545cc86SMichal Swiatkowski dev_err(dev, "failed to create device-caps devlink region, err %ld\n", 2001*0545cc86SMichal Swiatkowski PTR_ERR(pf->devcaps_region)); 2002*0545cc86SMichal Swiatkowski pf->devcaps_region = NULL; 2003*0545cc86SMichal Swiatkowski } 2004*0545cc86SMichal Swiatkowski } 2005*0545cc86SMichal Swiatkowski 2006*0545cc86SMichal Swiatkowski /** 2007*0545cc86SMichal Swiatkowski * ice_devlink_destroy_regions - Destroy devlink regions 2008*0545cc86SMichal Swiatkowski * @pf: the PF device structure 2009*0545cc86SMichal Swiatkowski * 2010*0545cc86SMichal Swiatkowski * Remove previously created regions for this PF. 2011*0545cc86SMichal Swiatkowski */ 2012*0545cc86SMichal Swiatkowski void ice_devlink_destroy_regions(struct ice_pf *pf) 2013*0545cc86SMichal Swiatkowski { 2014*0545cc86SMichal Swiatkowski if (pf->nvm_region) 2015*0545cc86SMichal Swiatkowski devlink_region_destroy(pf->nvm_region); 2016*0545cc86SMichal Swiatkowski 2017*0545cc86SMichal Swiatkowski if (pf->sram_region) 2018*0545cc86SMichal Swiatkowski devlink_region_destroy(pf->sram_region); 2019*0545cc86SMichal Swiatkowski 2020*0545cc86SMichal Swiatkowski if (pf->devcaps_region) 2021*0545cc86SMichal Swiatkowski devlink_region_destroy(pf->devcaps_region); 2022*0545cc86SMichal Swiatkowski } 2023