brintos

brintos / linux-shallow public Read only

0
0
Text · 54.5 KiB · 415445c Raw
1949 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2020, Intel Corporation. */3 4#include <linux/vmalloc.h>5 6#include "ice.h"7#include "ice_lib.h"8#include "devlink.h"9#include "devlink_port.h"10#include "ice_eswitch.h"11#include "ice_fw_update.h"12#include "ice_dcb_lib.h"13#include "ice_sf_eth.h"14 15/* context for devlink info version reporting */16struct ice_info_ctx {17	char buf[128];18	struct ice_orom_info pending_orom;19	struct ice_nvm_info pending_nvm;20	struct ice_netlist_info pending_netlist;21	struct ice_hw_dev_caps dev_caps;22};23 24/* The following functions are used to format specific strings for various25 * devlink info versions. The ctx parameter is used to provide the storage26 * buffer, as well as any ancillary information calculated when the info27 * request was made.28 *29 * If a version does not exist, for example when attempting to get the30 * inactive version of flash when there is no pending update, the function31 * should leave the buffer in the ctx structure empty.32 */33 34static void ice_info_get_dsn(struct ice_pf *pf, struct ice_info_ctx *ctx)35{36	u8 dsn[8];37 38	/* Copy the DSN into an array in Big Endian format */39	put_unaligned_be64(pci_get_dsn(pf->pdev), dsn);40 41	snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);42}43 44static void ice_info_pba(struct ice_pf *pf, struct ice_info_ctx *ctx)45{46	struct ice_hw *hw = &pf->hw;47	int status;48 49	status = ice_read_pba_string(hw, (u8 *)ctx->buf, sizeof(ctx->buf));50	if (status)51		/* We failed to locate the PBA, so just skip this entry */52		dev_dbg(ice_pf_to_dev(pf), "Failed to read Product Board Assembly string, status %d\n",53			status);54}55 56static void ice_info_fw_mgmt(struct ice_pf *pf, struct ice_info_ctx *ctx)57{58	struct ice_hw *hw = &pf->hw;59 60	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",61		 hw->fw_maj_ver, hw->fw_min_ver, hw->fw_patch);62}63 64static void ice_info_fw_api(struct ice_pf *pf, struct ice_info_ctx *ctx)65{66	struct ice_hw *hw = &pf->hw;67 68	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", hw->api_maj_ver,69		 hw->api_min_ver, hw->api_patch);70}71 72static void ice_info_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx)73{74	struct ice_hw *hw = &pf->hw;75 76	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);77}78 79static void ice_info_orom_ver(struct ice_pf *pf, struct ice_info_ctx *ctx)80{81	struct ice_orom_info *orom = &pf->hw.flash.orom;82 83	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",84		 orom->major, orom->build, orom->patch);85}86 87static void88ice_info_pending_orom_ver(struct ice_pf __always_unused *pf,89			  struct ice_info_ctx *ctx)90{91	struct ice_orom_info *orom = &ctx->pending_orom;92 93	if (ctx->dev_caps.common_cap.nvm_update_pending_orom)94		snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",95			 orom->major, orom->build, orom->patch);96}97 98static void ice_info_nvm_ver(struct ice_pf *pf, struct ice_info_ctx *ctx)99{100	struct ice_nvm_info *nvm = &pf->hw.flash.nvm;101 102	snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);103}104 105static void106ice_info_pending_nvm_ver(struct ice_pf __always_unused *pf,107			 struct ice_info_ctx *ctx)108{109	struct ice_nvm_info *nvm = &ctx->pending_nvm;110 111	if (ctx->dev_caps.common_cap.nvm_update_pending_nvm)112		snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x",113			 nvm->major, nvm->minor);114}115 116static void ice_info_eetrack(struct ice_pf *pf, struct ice_info_ctx *ctx)117{118	struct ice_nvm_info *nvm = &pf->hw.flash.nvm;119 120	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack);121}122 123static void124ice_info_pending_eetrack(struct ice_pf *pf, struct ice_info_ctx *ctx)125{126	struct ice_nvm_info *nvm = &ctx->pending_nvm;127 128	if (ctx->dev_caps.common_cap.nvm_update_pending_nvm)129		snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack);130}131 132static void ice_info_ddp_pkg_name(struct ice_pf *pf, struct ice_info_ctx *ctx)133{134	struct ice_hw *hw = &pf->hw;135 136	snprintf(ctx->buf, sizeof(ctx->buf), "%s", hw->active_pkg_name);137}138 139static void140ice_info_ddp_pkg_version(struct ice_pf *pf, struct ice_info_ctx *ctx)141{142	struct ice_pkg_ver *pkg = &pf->hw.active_pkg_ver;143 144	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u.%u",145		 pkg->major, pkg->minor, pkg->update, pkg->draft);146}147 148static void149ice_info_ddp_pkg_bundle_id(struct ice_pf *pf, struct ice_info_ctx *ctx)150{151	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", pf->hw.active_track_id);152}153 154static void ice_info_netlist_ver(struct ice_pf *pf, struct ice_info_ctx *ctx)155{156	struct ice_netlist_info *netlist = &pf->hw.flash.netlist;157 158	/* The netlist version fields are BCD formatted */159	snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x",160		 netlist->major, netlist->minor,161		 netlist->type >> 16, netlist->type & 0xFFFF,162		 netlist->rev, netlist->cust_ver);163}164 165static void ice_info_netlist_build(struct ice_pf *pf, struct ice_info_ctx *ctx)166{167	struct ice_netlist_info *netlist = &pf->hw.flash.netlist;168 169	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);170}171 172static void173ice_info_pending_netlist_ver(struct ice_pf __always_unused *pf,174			     struct ice_info_ctx *ctx)175{176	struct ice_netlist_info *netlist = &ctx->pending_netlist;177 178	/* The netlist version fields are BCD formatted */179	if (ctx->dev_caps.common_cap.nvm_update_pending_netlist)180		snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x",181			 netlist->major, netlist->minor,182			 netlist->type >> 16, netlist->type & 0xFFFF,183			 netlist->rev, netlist->cust_ver);184}185 186static void187ice_info_pending_netlist_build(struct ice_pf __always_unused *pf,188			       struct ice_info_ctx *ctx)189{190	struct ice_netlist_info *netlist = &ctx->pending_netlist;191 192	if (ctx->dev_caps.common_cap.nvm_update_pending_netlist)193		snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);194}195 196static void ice_info_cgu_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx)197{198	u32 id, cfg_ver, fw_ver;199 200	if (!ice_is_feature_supported(pf, ICE_F_CGU))201		return;202	if (ice_aq_get_cgu_info(&pf->hw, &id, &cfg_ver, &fw_ver))203		return;204	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", id, cfg_ver, fw_ver);205}206 207static void ice_info_cgu_id(struct ice_pf *pf, struct ice_info_ctx *ctx)208{209	if (!ice_is_feature_supported(pf, ICE_F_CGU))210		return;211	snprintf(ctx->buf, sizeof(ctx->buf), "%u", pf->hw.cgu_part_number);212}213 214#define fixed(key, getter) { ICE_VERSION_FIXED, key, getter, NULL }215#define running(key, getter) { ICE_VERSION_RUNNING, key, getter, NULL }216#define stored(key, getter, fallback) { ICE_VERSION_STORED, key, getter, fallback }217 218/* The combined() macro inserts both the running entry as well as a stored219 * entry. The running entry will always report the version from the active220 * handler. The stored entry will first try the pending handler, and fallback221 * to the active handler if the pending function does not report a version.222 * The pending handler should check the status of a pending update for the223 * relevant flash component. It should only fill in the buffer in the case224 * where a valid pending version is available. This ensures that the related225 * stored and running versions remain in sync, and that stored versions are226 * correctly reported as expected.227 */228#define combined(key, active, pending) \229	running(key, active), \230	stored(key, pending, active)231 232enum ice_version_type {233	ICE_VERSION_FIXED,234	ICE_VERSION_RUNNING,235	ICE_VERSION_STORED,236};237 238static const struct ice_devlink_version {239	enum ice_version_type type;240	const char *key;241	void (*getter)(struct ice_pf *pf, struct ice_info_ctx *ctx);242	void (*fallback)(struct ice_pf *pf, struct ice_info_ctx *ctx);243} ice_devlink_versions[] = {244	fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, ice_info_pba),245	running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, ice_info_fw_mgmt),246	running("fw.mgmt.api", ice_info_fw_api),247	running("fw.mgmt.build", ice_info_fw_build),248	combined(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ice_info_orom_ver, ice_info_pending_orom_ver),249	combined("fw.psid.api", ice_info_nvm_ver, ice_info_pending_nvm_ver),250	combined(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ice_info_eetrack, ice_info_pending_eetrack),251	running("fw.app.name", ice_info_ddp_pkg_name),252	running(DEVLINK_INFO_VERSION_GENERIC_FW_APP, ice_info_ddp_pkg_version),253	running("fw.app.bundle_id", ice_info_ddp_pkg_bundle_id),254	combined("fw.netlist", ice_info_netlist_ver, ice_info_pending_netlist_ver),255	combined("fw.netlist.build", ice_info_netlist_build, ice_info_pending_netlist_build),256	fixed("cgu.id", ice_info_cgu_id),257	running("fw.cgu", ice_info_cgu_fw_build),258};259 260/**261 * ice_devlink_info_get - .info_get devlink handler262 * @devlink: devlink instance structure263 * @req: the devlink info request264 * @extack: extended netdev ack structure265 *266 * Callback for the devlink .info_get operation. Reports information about the267 * device.268 *269 * Return: zero on success or an error code on failure.270 */271static int ice_devlink_info_get(struct devlink *devlink,272				struct devlink_info_req *req,273				struct netlink_ext_ack *extack)274{275	struct ice_pf *pf = devlink_priv(devlink);276	struct device *dev = ice_pf_to_dev(pf);277	struct ice_hw *hw = &pf->hw;278	struct ice_info_ctx *ctx;279	size_t i;280	int err;281 282	err = ice_wait_for_reset(pf, 10 * HZ);283	if (err) {284		NL_SET_ERR_MSG_MOD(extack, "Device is busy resetting");285		return err;286	}287 288	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);289	if (!ctx)290		return -ENOMEM;291 292	/* discover capabilities first */293	err = ice_discover_dev_caps(hw, &ctx->dev_caps);294	if (err) {295		dev_dbg(dev, "Failed to discover device capabilities, status %d aq_err %s\n",296			err, ice_aq_str(hw->adminq.sq_last_status));297		NL_SET_ERR_MSG_MOD(extack, "Unable to discover device capabilities");298		goto out_free_ctx;299	}300 301	if (ctx->dev_caps.common_cap.nvm_update_pending_orom) {302		err = ice_get_inactive_orom_ver(hw, &ctx->pending_orom);303		if (err) {304			dev_dbg(dev, "Unable to read inactive Option ROM version data, status %d aq_err %s\n",305				err, ice_aq_str(hw->adminq.sq_last_status));306 307			/* disable display of pending Option ROM */308			ctx->dev_caps.common_cap.nvm_update_pending_orom = false;309		}310	}311 312	if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) {313		err = ice_get_inactive_nvm_ver(hw, &ctx->pending_nvm);314		if (err) {315			dev_dbg(dev, "Unable to read inactive NVM version data, status %d aq_err %s\n",316				err, ice_aq_str(hw->adminq.sq_last_status));317 318			/* disable display of pending Option ROM */319			ctx->dev_caps.common_cap.nvm_update_pending_nvm = false;320		}321	}322 323	if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) {324		err = ice_get_inactive_netlist_ver(hw, &ctx->pending_netlist);325		if (err) {326			dev_dbg(dev, "Unable to read inactive Netlist version data, status %d aq_err %s\n",327				err, ice_aq_str(hw->adminq.sq_last_status));328 329			/* disable display of pending Option ROM */330			ctx->dev_caps.common_cap.nvm_update_pending_netlist = false;331		}332	}333 334	ice_info_get_dsn(pf, ctx);335 336	err = devlink_info_serial_number_put(req, ctx->buf);337	if (err) {338		NL_SET_ERR_MSG_MOD(extack, "Unable to set serial number");339		goto out_free_ctx;340	}341 342	for (i = 0; i < ARRAY_SIZE(ice_devlink_versions); i++) {343		enum ice_version_type type = ice_devlink_versions[i].type;344		const char *key = ice_devlink_versions[i].key;345 346		memset(ctx->buf, 0, sizeof(ctx->buf));347 348		ice_devlink_versions[i].getter(pf, ctx);349 350		/* If the default getter doesn't report a version, use the351		 * fallback function. This is primarily useful in the case of352		 * "stored" versions that want to report the same value as the353		 * running version in the normal case of no pending update.354		 */355		if (ctx->buf[0] == '\0' && ice_devlink_versions[i].fallback)356			ice_devlink_versions[i].fallback(pf, ctx);357 358		/* Do not report missing versions */359		if (ctx->buf[0] == '\0')360			continue;361 362		switch (type) {363		case ICE_VERSION_FIXED:364			err = devlink_info_version_fixed_put(req, key, ctx->buf);365			if (err) {366				NL_SET_ERR_MSG_MOD(extack, "Unable to set fixed version");367				goto out_free_ctx;368			}369			break;370		case ICE_VERSION_RUNNING:371			err = devlink_info_version_running_put(req, key, ctx->buf);372			if (err) {373				NL_SET_ERR_MSG_MOD(extack, "Unable to set running version");374				goto out_free_ctx;375			}376			break;377		case ICE_VERSION_STORED:378			err = devlink_info_version_stored_put(req, key, ctx->buf);379			if (err) {380				NL_SET_ERR_MSG_MOD(extack, "Unable to set stored version");381				goto out_free_ctx;382			}383			break;384		}385	}386 387out_free_ctx:388	kfree(ctx);389	return err;390}391 392/**393 * ice_devlink_reload_empr_start - Start EMP reset to activate new firmware394 * @pf: pointer to the pf instance395 * @extack: netlink extended ACK structure396 *397 * Allow user to activate new Embedded Management Processor firmware by398 * issuing device specific EMP reset. Called in response to399 * a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE.400 *401 * Note that teardown and rebuild of the driver state happens automatically as402 * part of an interrupt and watchdog task. This is because all physical403 * functions on the device must be able to reset when an EMP reset occurs from404 * any source.405 */406static int407ice_devlink_reload_empr_start(struct ice_pf *pf,408			      struct netlink_ext_ack *extack)409{410	struct device *dev = ice_pf_to_dev(pf);411	struct ice_hw *hw = &pf->hw;412	u8 pending;413	int err;414 415	err = ice_get_pending_updates(pf, &pending, extack);416	if (err)417		return err;418 419	/* pending is a bitmask of which flash banks have a pending update,420	 * including the main NVM bank, the Option ROM bank, and the netlist421	 * bank. If any of these bits are set, then there is a pending update422	 * waiting to be activated.423	 */424	if (!pending) {425		NL_SET_ERR_MSG_MOD(extack, "No pending firmware update");426		return -ECANCELED;427	}428 429	if (pf->fw_emp_reset_disabled) {430		NL_SET_ERR_MSG_MOD(extack, "EMP reset is not available. To activate firmware, a reboot or power cycle is needed");431		return -ECANCELED;432	}433 434	dev_dbg(dev, "Issuing device EMP reset to activate firmware\n");435 436	err = ice_aq_nvm_update_empr(hw);437	if (err) {438		dev_err(dev, "Failed to trigger EMP device reset to reload firmware, err %d aq_err %s\n",439			err, ice_aq_str(hw->adminq.sq_last_status));440		NL_SET_ERR_MSG_MOD(extack, "Failed to trigger EMP device reset to reload firmware");441		return err;442	}443 444	return 0;445}446 447/**448 * ice_devlink_reinit_down - unload given PF449 * @pf: pointer to the PF struct450 */451static void ice_devlink_reinit_down(struct ice_pf *pf)452{453	/* No need to take devl_lock, it's already taken by devlink API */454	ice_unload(pf);455	rtnl_lock();456	ice_vsi_decfg(ice_get_main_vsi(pf));457	rtnl_unlock();458	ice_deinit_dev(pf);459}460 461/**462 * ice_devlink_reload_down - prepare for reload463 * @devlink: pointer to the devlink instance to reload464 * @netns_change: if true, the network namespace is changing465 * @action: the action to perform466 * @limit: limits on what reload should do, such as not resetting467 * @extack: netlink extended ACK structure468 */469static int470ice_devlink_reload_down(struct devlink *devlink, bool netns_change,471			enum devlink_reload_action action,472			enum devlink_reload_limit limit,473			struct netlink_ext_ack *extack)474{475	struct ice_pf *pf = devlink_priv(devlink);476 477	switch (action) {478	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:479		if (ice_is_eswitch_mode_switchdev(pf)) {480			NL_SET_ERR_MSG_MOD(extack,481					   "Go to legacy mode before doing reinit");482			return -EOPNOTSUPP;483		}484		if (ice_is_adq_active(pf)) {485			NL_SET_ERR_MSG_MOD(extack,486					   "Turn off ADQ before doing reinit");487			return -EOPNOTSUPP;488		}489		if (ice_has_vfs(pf)) {490			NL_SET_ERR_MSG_MOD(extack,491					   "Remove all VFs before doing reinit");492			return -EOPNOTSUPP;493		}494		ice_devlink_reinit_down(pf);495		return 0;496	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:497		return ice_devlink_reload_empr_start(pf, extack);498	default:499		WARN_ON(1);500		return -EOPNOTSUPP;501	}502}503 504/**505 * ice_devlink_reload_empr_finish - Wait for EMP reset to finish506 * @pf: pointer to the pf instance507 * @extack: netlink extended ACK structure508 *509 * Wait for driver to finish rebuilding after EMP reset is completed. This510 * includes time to wait for both the actual device reset as well as the time511 * for the driver's rebuild to complete.512 */513static int514ice_devlink_reload_empr_finish(struct ice_pf *pf,515			       struct netlink_ext_ack *extack)516{517	int err;518 519	err = ice_wait_for_reset(pf, 60 * HZ);520	if (err) {521		NL_SET_ERR_MSG_MOD(extack, "Device still resetting after 1 minute");522		return err;523	}524 525	return 0;526}527 528/**529 * ice_get_tx_topo_user_sel - Read user's choice from flash530 * @pf: pointer to pf structure531 * @layers: value read from flash will be saved here532 *533 * Reads user's preference for Tx Scheduler Topology Tree from PFA TLV.534 *535 * Return: zero when read was successful, negative values otherwise.536 */537static int ice_get_tx_topo_user_sel(struct ice_pf *pf, uint8_t *layers)538{539	struct ice_aqc_nvm_tx_topo_user_sel usr_sel = {};540	struct ice_hw *hw = &pf->hw;541	int err;542 543	err = ice_acquire_nvm(hw, ICE_RES_READ);544	if (err)545		return err;546 547	err = ice_aq_read_nvm(hw, ICE_AQC_NVM_TX_TOPO_MOD_ID, 0,548			      sizeof(usr_sel), &usr_sel, true, true, NULL);549	if (err)550		goto exit_release_res;551 552	if (usr_sel.data & ICE_AQC_NVM_TX_TOPO_USER_SEL)553		*layers = ICE_SCHED_5_LAYERS;554	else555		*layers = ICE_SCHED_9_LAYERS;556 557exit_release_res:558	ice_release_nvm(hw);559 560	return err;561}562 563/**564 * ice_update_tx_topo_user_sel - Save user's preference in flash565 * @pf: pointer to pf structure566 * @layers: value to be saved in flash567 *568 * Variable "layers" defines user's preference about number of layers in Tx569 * Scheduler Topology Tree. This choice should be stored in PFA TLV field570 * and be picked up by driver, next time during init.571 *572 * Return: zero when save was successful, negative values otherwise.573 */574static int ice_update_tx_topo_user_sel(struct ice_pf *pf, int layers)575{576	struct ice_aqc_nvm_tx_topo_user_sel usr_sel = {};577	struct ice_hw *hw = &pf->hw;578	int err;579 580	err = ice_acquire_nvm(hw, ICE_RES_WRITE);581	if (err)582		return err;583 584	err = ice_aq_read_nvm(hw, ICE_AQC_NVM_TX_TOPO_MOD_ID, 0,585			      sizeof(usr_sel), &usr_sel, true, true, NULL);586	if (err)587		goto exit_release_res;588 589	if (layers == ICE_SCHED_5_LAYERS)590		usr_sel.data |= ICE_AQC_NVM_TX_TOPO_USER_SEL;591	else592		usr_sel.data &= ~ICE_AQC_NVM_TX_TOPO_USER_SEL;593 594	err = ice_write_one_nvm_block(pf, ICE_AQC_NVM_TX_TOPO_MOD_ID, 2,595				      sizeof(usr_sel.data), &usr_sel.data,596				      true, NULL, NULL);597exit_release_res:598	ice_release_nvm(hw);599 600	return err;601}602 603/**604 * ice_devlink_tx_sched_layers_get - Get tx_scheduling_layers parameter605 * @devlink: pointer to the devlink instance606 * @id: the parameter ID to set607 * @ctx: context to store the parameter value608 *609 * Return: zero on success and negative value on failure.610 */611static int ice_devlink_tx_sched_layers_get(struct devlink *devlink, u32 id,612					   struct devlink_param_gset_ctx *ctx)613{614	struct ice_pf *pf = devlink_priv(devlink);615	int err;616 617	err = ice_get_tx_topo_user_sel(pf, &ctx->val.vu8);618	if (err)619		return err;620 621	return 0;622}623 624/**625 * ice_devlink_tx_sched_layers_set - Set tx_scheduling_layers parameter626 * @devlink: pointer to the devlink instance627 * @id: the parameter ID to set628 * @ctx: context to get the parameter value629 * @extack: netlink extended ACK structure630 *631 * Return: zero on success and negative value on failure.632 */633static int ice_devlink_tx_sched_layers_set(struct devlink *devlink, u32 id,634					   struct devlink_param_gset_ctx *ctx,635					   struct netlink_ext_ack *extack)636{637	struct ice_pf *pf = devlink_priv(devlink);638	int err;639 640	err = ice_update_tx_topo_user_sel(pf, ctx->val.vu8);641	if (err)642		return err;643 644	NL_SET_ERR_MSG_MOD(extack,645			   "Tx scheduling layers have been changed on this device. You must do the PCI slot powercycle for the change to take effect.");646 647	return 0;648}649 650/**651 * ice_devlink_tx_sched_layers_validate - Validate passed tx_scheduling_layers652 *                                        parameter value653 * @devlink: unused pointer to devlink instance654 * @id: the parameter ID to validate655 * @val: value to validate656 * @extack: netlink extended ACK structure657 *658 * Supported values are:659 * - 5 - five layers Tx Scheduler Topology Tree660 * - 9 - nine layers Tx Scheduler Topology Tree661 *662 * Return: zero when passed parameter value is supported. Negative value on663 * error.664 */665static int ice_devlink_tx_sched_layers_validate(struct devlink *devlink, u32 id,666						union devlink_param_value val,667						struct netlink_ext_ack *extack)668{669	if (val.vu8 != ICE_SCHED_5_LAYERS && val.vu8 != ICE_SCHED_9_LAYERS) {670		NL_SET_ERR_MSG_MOD(extack,671				   "Wrong number of tx scheduler layers provided.");672		return -EINVAL;673	}674 675	return 0;676}677 678/**679 * ice_tear_down_devlink_rate_tree - removes devlink-rate exported tree680 * @pf: pf struct681 *682 * This function tears down tree exported during VF's creation.683 */684void ice_tear_down_devlink_rate_tree(struct ice_pf *pf)685{686	struct devlink *devlink;687	struct ice_vf *vf;688	unsigned int bkt;689 690	devlink = priv_to_devlink(pf);691 692	devl_lock(devlink);693	mutex_lock(&pf->vfs.table_lock);694	ice_for_each_vf(pf, bkt, vf) {695		if (vf->devlink_port.devlink_rate)696			devl_rate_leaf_destroy(&vf->devlink_port);697	}698	mutex_unlock(&pf->vfs.table_lock);699 700	devl_rate_nodes_destroy(devlink);701	devl_unlock(devlink);702}703 704/**705 * ice_enable_custom_tx - try to enable custom Tx feature706 * @pf: pf struct707 *708 * This function tries to enable custom Tx feature,709 * it's not possible to enable it, if DCB or ADQ is active.710 */711static bool ice_enable_custom_tx(struct ice_pf *pf)712{713	struct ice_port_info *pi = ice_get_main_vsi(pf)->port_info;714	struct device *dev = ice_pf_to_dev(pf);715 716	if (pi->is_custom_tx_enabled)717		/* already enabled, return true */718		return true;719 720	if (ice_is_adq_active(pf)) {721		dev_err(dev, "ADQ active, can't modify Tx scheduler tree\n");722		return false;723	}724 725	if (ice_is_dcb_active(pf)) {726		dev_err(dev, "DCB active, can't modify Tx scheduler tree\n");727		return false;728	}729 730	pi->is_custom_tx_enabled = true;731 732	return true;733}734 735/**736 * ice_traverse_tx_tree - traverse Tx scheduler tree737 * @devlink: devlink struct738 * @node: current node, used for recursion739 * @tc_node: tc_node struct, that is treated as a root740 * @pf: pf struct741 *742 * This function traverses Tx scheduler tree and exports743 * entire structure to the devlink-rate.744 */745static void ice_traverse_tx_tree(struct devlink *devlink, struct ice_sched_node *node,746				 struct ice_sched_node *tc_node, struct ice_pf *pf)747{748	struct devlink_rate *rate_node = NULL;749	struct ice_dynamic_port *sf;750	struct ice_vf *vf;751	int i;752 753	if (node->rate_node)754		/* already added, skip to the next */755		goto traverse_children;756 757	if (node->parent == tc_node) {758		/* create root node */759		rate_node = devl_rate_node_create(devlink, node, node->name, NULL);760	} else if (node->vsi_handle &&761		   pf->vsi[node->vsi_handle]->type == ICE_VSI_VF &&762		   pf->vsi[node->vsi_handle]->vf) {763		vf = pf->vsi[node->vsi_handle]->vf;764		if (!vf->devlink_port.devlink_rate)765			/* leaf nodes doesn't have children766			 * so we don't set rate_node767			 */768			devl_rate_leaf_create(&vf->devlink_port, node,769					      node->parent->rate_node);770	} else if (node->vsi_handle &&771		   pf->vsi[node->vsi_handle]->type == ICE_VSI_SF &&772		   pf->vsi[node->vsi_handle]->sf) {773		sf = pf->vsi[node->vsi_handle]->sf;774		if (!sf->devlink_port.devlink_rate)775			/* leaf nodes doesn't have children776			 * so we don't set rate_node777			 */778			devl_rate_leaf_create(&sf->devlink_port, node,779					      node->parent->rate_node);780	} else if (node->info.data.elem_type != ICE_AQC_ELEM_TYPE_LEAF &&781		   node->parent->rate_node) {782		rate_node = devl_rate_node_create(devlink, node, node->name,783						  node->parent->rate_node);784	}785 786	if (rate_node && !IS_ERR(rate_node))787		node->rate_node = rate_node;788 789traverse_children:790	for (i = 0; i < node->num_children; i++)791		ice_traverse_tx_tree(devlink, node->children[i], tc_node, pf);792}793 794/**795 * ice_devlink_rate_init_tx_topology - export Tx scheduler tree to devlink rate796 * @devlink: devlink struct797 * @vsi: main vsi struct798 *799 * This function finds a root node, then calls ice_traverse_tx tree, which800 * traverses the tree and exports it's contents to devlink rate.801 */802int ice_devlink_rate_init_tx_topology(struct devlink *devlink, struct ice_vsi *vsi)803{804	struct ice_port_info *pi = vsi->port_info;805	struct ice_sched_node *tc_node;806	struct ice_pf *pf = vsi->back;807	int i;808 809	tc_node = pi->root->children[0];810	mutex_lock(&pi->sched_lock);811	for (i = 0; i < tc_node->num_children; i++)812		ice_traverse_tx_tree(devlink, tc_node->children[i], tc_node, pf);813	mutex_unlock(&pi->sched_lock);814 815	return 0;816}817 818static void ice_clear_rate_nodes(struct ice_sched_node *node)819{820	node->rate_node = NULL;821 822	for (int i = 0; i < node->num_children; i++)823		ice_clear_rate_nodes(node->children[i]);824}825 826/**827 * ice_devlink_rate_clear_tx_topology - clear node->rate_node828 * @vsi: main vsi struct829 *830 * Clear rate_node to cleanup creation of Tx topology.831 *832 */833void ice_devlink_rate_clear_tx_topology(struct ice_vsi *vsi)834{835	struct ice_port_info *pi = vsi->port_info;836 837	mutex_lock(&pi->sched_lock);838	ice_clear_rate_nodes(pi->root->children[0]);839	mutex_unlock(&pi->sched_lock);840}841 842/**843 * ice_set_object_tx_share - sets node scheduling parameter844 * @pi: devlink struct instance845 * @node: node struct instance846 * @bw: bandwidth in bytes per second847 * @extack: extended netdev ack structure848 *849 * This function sets ICE_MIN_BW scheduling BW limit.850 */851static int ice_set_object_tx_share(struct ice_port_info *pi, struct ice_sched_node *node,852				   u64 bw, struct netlink_ext_ack *extack)853{854	int status;855 856	mutex_lock(&pi->sched_lock);857	/* converts bytes per second to kilo bits per second */858	node->tx_share = div_u64(bw, 125);859	status = ice_sched_set_node_bw_lmt(pi, node, ICE_MIN_BW, node->tx_share);860	mutex_unlock(&pi->sched_lock);861 862	if (status)863		NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_share");864 865	return status;866}867 868/**869 * ice_set_object_tx_max - sets node scheduling parameter870 * @pi: devlink struct instance871 * @node: node struct instance872 * @bw: bandwidth in bytes per second873 * @extack: extended netdev ack structure874 *875 * This function sets ICE_MAX_BW scheduling BW limit.876 */877static int ice_set_object_tx_max(struct ice_port_info *pi, struct ice_sched_node *node,878				 u64 bw, struct netlink_ext_ack *extack)879{880	int status;881 882	mutex_lock(&pi->sched_lock);883	/* converts bytes per second value to kilo bits per second */884	node->tx_max = div_u64(bw, 125);885	status = ice_sched_set_node_bw_lmt(pi, node, ICE_MAX_BW, node->tx_max);886	mutex_unlock(&pi->sched_lock);887 888	if (status)889		NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_max");890 891	return status;892}893 894/**895 * ice_set_object_tx_priority - sets node scheduling parameter896 * @pi: devlink struct instance897 * @node: node struct instance898 * @priority: value representing priority for strict priority arbitration899 * @extack: extended netdev ack structure900 *901 * This function sets priority of node among siblings.902 */903static int ice_set_object_tx_priority(struct ice_port_info *pi, struct ice_sched_node *node,904				      u32 priority, struct netlink_ext_ack *extack)905{906	int status;907 908	if (priority >= 8) {909		NL_SET_ERR_MSG_MOD(extack, "Priority should be less than 8");910		return -EINVAL;911	}912 913	mutex_lock(&pi->sched_lock);914	node->tx_priority = priority;915	status = ice_sched_set_node_priority(pi, node, node->tx_priority);916	mutex_unlock(&pi->sched_lock);917 918	if (status)919		NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_priority");920 921	return status;922}923 924/**925 * ice_set_object_tx_weight - sets node scheduling parameter926 * @pi: devlink struct instance927 * @node: node struct instance928 * @weight: value represeting relative weight for WFQ arbitration929 * @extack: extended netdev ack structure930 *931 * This function sets node weight for WFQ algorithm.932 */933static int ice_set_object_tx_weight(struct ice_port_info *pi, struct ice_sched_node *node,934				    u32 weight, struct netlink_ext_ack *extack)935{936	int status;937 938	if (weight > 200 || weight < 1) {939		NL_SET_ERR_MSG_MOD(extack, "Weight must be between 1 and 200");940		return -EINVAL;941	}942 943	mutex_lock(&pi->sched_lock);944	node->tx_weight = weight;945	status = ice_sched_set_node_weight(pi, node, node->tx_weight);946	mutex_unlock(&pi->sched_lock);947 948	if (status)949		NL_SET_ERR_MSG_MOD(extack, "Can't set scheduling node tx_weight");950 951	return status;952}953 954/**955 * ice_get_pi_from_dev_rate - get port info from devlink_rate956 * @rate_node: devlink struct instance957 *958 * This function returns corresponding port_info struct of devlink_rate959 */960static struct ice_port_info *ice_get_pi_from_dev_rate(struct devlink_rate *rate_node)961{962	struct ice_pf *pf = devlink_priv(rate_node->devlink);963 964	return ice_get_main_vsi(pf)->port_info;965}966 967static int ice_devlink_rate_node_new(struct devlink_rate *rate_node, void **priv,968				     struct netlink_ext_ack *extack)969{970	struct ice_sched_node *node;971	struct ice_port_info *pi;972 973	pi = ice_get_pi_from_dev_rate(rate_node);974 975	if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink)))976		return -EBUSY;977 978	/* preallocate memory for ice_sched_node */979	node = devm_kzalloc(ice_hw_to_dev(pi->hw), sizeof(*node), GFP_KERNEL);980	*priv = node;981 982	return 0;983}984 985static int ice_devlink_rate_node_del(struct devlink_rate *rate_node, void *priv,986				     struct netlink_ext_ack *extack)987{988	struct ice_sched_node *node, *tc_node;989	struct ice_port_info *pi;990 991	pi = ice_get_pi_from_dev_rate(rate_node);992	tc_node = pi->root->children[0];993	node = priv;994 995	if (!rate_node->parent || !node || tc_node == node || !extack)996		return 0;997 998	if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink)))999		return -EBUSY;1000 1001	/* can't allow to delete a node with children */1002	if (node->num_children)1003		return -EINVAL;1004 1005	mutex_lock(&pi->sched_lock);1006	ice_free_sched_node(pi, node);1007	mutex_unlock(&pi->sched_lock);1008 1009	return 0;1010}1011 1012static int ice_devlink_rate_leaf_tx_max_set(struct devlink_rate *rate_leaf, void *priv,1013					    u64 tx_max, struct netlink_ext_ack *extack)1014{1015	struct ice_sched_node *node = priv;1016 1017	if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink)))1018		return -EBUSY;1019 1020	if (!node)1021		return 0;1022 1023	return ice_set_object_tx_max(ice_get_pi_from_dev_rate(rate_leaf),1024				     node, tx_max, extack);1025}1026 1027static int ice_devlink_rate_leaf_tx_share_set(struct devlink_rate *rate_leaf, void *priv,1028					      u64 tx_share, struct netlink_ext_ack *extack)1029{1030	struct ice_sched_node *node = priv;1031 1032	if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink)))1033		return -EBUSY;1034 1035	if (!node)1036		return 0;1037 1038	return ice_set_object_tx_share(ice_get_pi_from_dev_rate(rate_leaf), node,1039				       tx_share, extack);1040}1041 1042static int ice_devlink_rate_leaf_tx_priority_set(struct devlink_rate *rate_leaf, void *priv,1043						 u32 tx_priority, struct netlink_ext_ack *extack)1044{1045	struct ice_sched_node *node = priv;1046 1047	if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink)))1048		return -EBUSY;1049 1050	if (!node)1051		return 0;1052 1053	return ice_set_object_tx_priority(ice_get_pi_from_dev_rate(rate_leaf), node,1054					  tx_priority, extack);1055}1056 1057static int ice_devlink_rate_leaf_tx_weight_set(struct devlink_rate *rate_leaf, void *priv,1058					       u32 tx_weight, struct netlink_ext_ack *extack)1059{1060	struct ice_sched_node *node = priv;1061 1062	if (!ice_enable_custom_tx(devlink_priv(rate_leaf->devlink)))1063		return -EBUSY;1064 1065	if (!node)1066		return 0;1067 1068	return ice_set_object_tx_weight(ice_get_pi_from_dev_rate(rate_leaf), node,1069					tx_weight, extack);1070}1071 1072static int ice_devlink_rate_node_tx_max_set(struct devlink_rate *rate_node, void *priv,1073					    u64 tx_max, struct netlink_ext_ack *extack)1074{1075	struct ice_sched_node *node = priv;1076 1077	if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink)))1078		return -EBUSY;1079 1080	if (!node)1081		return 0;1082 1083	return ice_set_object_tx_max(ice_get_pi_from_dev_rate(rate_node),1084				     node, tx_max, extack);1085}1086 1087static int ice_devlink_rate_node_tx_share_set(struct devlink_rate *rate_node, void *priv,1088					      u64 tx_share, struct netlink_ext_ack *extack)1089{1090	struct ice_sched_node *node = priv;1091 1092	if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink)))1093		return -EBUSY;1094 1095	if (!node)1096		return 0;1097 1098	return ice_set_object_tx_share(ice_get_pi_from_dev_rate(rate_node),1099				       node, tx_share, extack);1100}1101 1102static int ice_devlink_rate_node_tx_priority_set(struct devlink_rate *rate_node, void *priv,1103						 u32 tx_priority, struct netlink_ext_ack *extack)1104{1105	struct ice_sched_node *node = priv;1106 1107	if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink)))1108		return -EBUSY;1109 1110	if (!node)1111		return 0;1112 1113	return ice_set_object_tx_priority(ice_get_pi_from_dev_rate(rate_node),1114					  node, tx_priority, extack);1115}1116 1117static int ice_devlink_rate_node_tx_weight_set(struct devlink_rate *rate_node, void *priv,1118					       u32 tx_weight, struct netlink_ext_ack *extack)1119{1120	struct ice_sched_node *node = priv;1121 1122	if (!ice_enable_custom_tx(devlink_priv(rate_node->devlink)))1123		return -EBUSY;1124 1125	if (!node)1126		return 0;1127 1128	return ice_set_object_tx_weight(ice_get_pi_from_dev_rate(rate_node),1129					node, tx_weight, extack);1130}1131 1132static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,1133				  struct devlink_rate *parent,1134				  void *priv, void *parent_priv,1135				  struct netlink_ext_ack *extack)1136{1137	struct ice_port_info *pi = ice_get_pi_from_dev_rate(devlink_rate);1138	struct ice_sched_node *tc_node, *node, *parent_node;1139	u16 num_nodes_added;1140	u32 first_node_teid;1141	u32 node_teid;1142	int status;1143 1144	tc_node = pi->root->children[0];1145	node = priv;1146 1147	if (!extack)1148		return 0;1149 1150	if (!ice_enable_custom_tx(devlink_priv(devlink_rate->devlink)))1151		return -EBUSY;1152 1153	if (!parent) {1154		if (!node || tc_node == node || node->num_children)1155			return -EINVAL;1156 1157		mutex_lock(&pi->sched_lock);1158		ice_free_sched_node(pi, node);1159		mutex_unlock(&pi->sched_lock);1160 1161		return 0;1162	}1163 1164	parent_node = parent_priv;1165 1166	/* if the node doesn't exist, create it */1167	if (!node->parent) {1168		mutex_lock(&pi->sched_lock);1169		status = ice_sched_add_elems(pi, tc_node, parent_node,1170					     parent_node->tx_sched_layer + 1,1171					     1, &num_nodes_added, &first_node_teid,1172					     &node);1173		mutex_unlock(&pi->sched_lock);1174 1175		if (status) {1176			NL_SET_ERR_MSG_MOD(extack, "Can't add a new node");1177			return status;1178		}1179 1180		if (devlink_rate->tx_share)1181			ice_set_object_tx_share(pi, node, devlink_rate->tx_share, extack);1182		if (devlink_rate->tx_max)1183			ice_set_object_tx_max(pi, node, devlink_rate->tx_max, extack);1184		if (devlink_rate->tx_priority)1185			ice_set_object_tx_priority(pi, node, devlink_rate->tx_priority, extack);1186		if (devlink_rate->tx_weight)1187			ice_set_object_tx_weight(pi, node, devlink_rate->tx_weight, extack);1188	} else {1189		node_teid = le32_to_cpu(node->info.node_teid);1190		mutex_lock(&pi->sched_lock);1191		status = ice_sched_move_nodes(pi, parent_node, 1, &node_teid);1192		mutex_unlock(&pi->sched_lock);1193 1194		if (status)1195			NL_SET_ERR_MSG_MOD(extack, "Can't move existing node to a new parent");1196	}1197 1198	return status;1199}1200 1201/**1202 * ice_devlink_reinit_up - do reinit of the given PF1203 * @pf: pointer to the PF struct1204 */1205static int ice_devlink_reinit_up(struct ice_pf *pf)1206{1207	struct ice_vsi *vsi = ice_get_main_vsi(pf);1208	int err;1209 1210	err = ice_init_dev(pf);1211	if (err)1212		return err;1213 1214	vsi->flags = ICE_VSI_FLAG_INIT;1215 1216	rtnl_lock();1217	err = ice_vsi_cfg(vsi);1218	rtnl_unlock();1219	if (err)1220		goto err_vsi_cfg;1221 1222	/* No need to take devl_lock, it's already taken by devlink API */1223	err = ice_load(pf);1224	if (err)1225		goto err_load;1226 1227	return 0;1228 1229err_load:1230	rtnl_lock();1231	ice_vsi_decfg(vsi);1232	rtnl_unlock();1233err_vsi_cfg:1234	ice_deinit_dev(pf);1235	return err;1236}1237 1238/**1239 * ice_devlink_reload_up - do reload up after reinit1240 * @devlink: pointer to the devlink instance reloading1241 * @action: the action requested1242 * @limit: limits imposed by userspace, such as not resetting1243 * @actions_performed: on return, indicate what actions actually performed1244 * @extack: netlink extended ACK structure1245 */1246static int1247ice_devlink_reload_up(struct devlink *devlink,1248		      enum devlink_reload_action action,1249		      enum devlink_reload_limit limit,1250		      u32 *actions_performed,1251		      struct netlink_ext_ack *extack)1252{1253	struct ice_pf *pf = devlink_priv(devlink);1254 1255	switch (action) {1256	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:1257		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);1258		return ice_devlink_reinit_up(pf);1259	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:1260		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);1261		return ice_devlink_reload_empr_finish(pf, extack);1262	default:1263		WARN_ON(1);1264		return -EOPNOTSUPP;1265	}1266}1267 1268static const struct devlink_ops ice_devlink_ops = {1269	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,1270	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |1271			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),1272	.reload_down = ice_devlink_reload_down,1273	.reload_up = ice_devlink_reload_up,1274	.eswitch_mode_get = ice_eswitch_mode_get,1275	.eswitch_mode_set = ice_eswitch_mode_set,1276	.info_get = ice_devlink_info_get,1277	.flash_update = ice_devlink_flash_update,1278 1279	.rate_node_new = ice_devlink_rate_node_new,1280	.rate_node_del = ice_devlink_rate_node_del,1281 1282	.rate_leaf_tx_max_set = ice_devlink_rate_leaf_tx_max_set,1283	.rate_leaf_tx_share_set = ice_devlink_rate_leaf_tx_share_set,1284	.rate_leaf_tx_priority_set = ice_devlink_rate_leaf_tx_priority_set,1285	.rate_leaf_tx_weight_set = ice_devlink_rate_leaf_tx_weight_set,1286 1287	.rate_node_tx_max_set = ice_devlink_rate_node_tx_max_set,1288	.rate_node_tx_share_set = ice_devlink_rate_node_tx_share_set,1289	.rate_node_tx_priority_set = ice_devlink_rate_node_tx_priority_set,1290	.rate_node_tx_weight_set = ice_devlink_rate_node_tx_weight_set,1291 1292	.rate_leaf_parent_set = ice_devlink_set_parent,1293	.rate_node_parent_set = ice_devlink_set_parent,1294 1295	.port_new = ice_devlink_port_new,1296};1297 1298static const struct devlink_ops ice_sf_devlink_ops;1299 1300static int1301ice_devlink_enable_roce_get(struct devlink *devlink, u32 id,1302			    struct devlink_param_gset_ctx *ctx)1303{1304	struct ice_pf *pf = devlink_priv(devlink);1305 1306	ctx->val.vbool = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? true : false;1307 1308	return 0;1309}1310 1311static int ice_devlink_enable_roce_set(struct devlink *devlink, u32 id,1312				       struct devlink_param_gset_ctx *ctx,1313				       struct netlink_ext_ack *extack)1314{1315	struct ice_pf *pf = devlink_priv(devlink);1316	bool roce_ena = ctx->val.vbool;1317	int ret;1318 1319	if (!roce_ena) {1320		ice_unplug_aux_dev(pf);1321		pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_ROCEV2;1322		return 0;1323	}1324 1325	pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;1326	ret = ice_plug_aux_dev(pf);1327	if (ret)1328		pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_ROCEV2;1329 1330	return ret;1331}1332 1333static int1334ice_devlink_enable_roce_validate(struct devlink *devlink, u32 id,1335				 union devlink_param_value val,1336				 struct netlink_ext_ack *extack)1337{1338	struct ice_pf *pf = devlink_priv(devlink);1339 1340	if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags))1341		return -EOPNOTSUPP;1342 1343	if (pf->rdma_mode & IIDC_RDMA_PROTOCOL_IWARP) {1344		NL_SET_ERR_MSG_MOD(extack, "iWARP is currently enabled. This device cannot enable iWARP and RoCEv2 simultaneously");1345		return -EOPNOTSUPP;1346	}1347 1348	return 0;1349}1350 1351static int1352ice_devlink_enable_iw_get(struct devlink *devlink, u32 id,1353			  struct devlink_param_gset_ctx *ctx)1354{1355	struct ice_pf *pf = devlink_priv(devlink);1356 1357	ctx->val.vbool = pf->rdma_mode & IIDC_RDMA_PROTOCOL_IWARP;1358 1359	return 0;1360}1361 1362static int ice_devlink_enable_iw_set(struct devlink *devlink, u32 id,1363				     struct devlink_param_gset_ctx *ctx,1364				     struct netlink_ext_ack *extack)1365{1366	struct ice_pf *pf = devlink_priv(devlink);1367	bool iw_ena = ctx->val.vbool;1368	int ret;1369 1370	if (!iw_ena) {1371		ice_unplug_aux_dev(pf);1372		pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_IWARP;1373		return 0;1374	}1375 1376	pf->rdma_mode |= IIDC_RDMA_PROTOCOL_IWARP;1377	ret = ice_plug_aux_dev(pf);1378	if (ret)1379		pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_IWARP;1380 1381	return ret;1382}1383 1384static int1385ice_devlink_enable_iw_validate(struct devlink *devlink, u32 id,1386			       union devlink_param_value val,1387			       struct netlink_ext_ack *extack)1388{1389	struct ice_pf *pf = devlink_priv(devlink);1390 1391	if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags))1392		return -EOPNOTSUPP;1393 1394	if (pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2) {1395		NL_SET_ERR_MSG_MOD(extack, "RoCEv2 is currently enabled. This device cannot enable iWARP and RoCEv2 simultaneously");1396		return -EOPNOTSUPP;1397	}1398 1399	return 0;1400}1401 1402#define DEVLINK_LOCAL_FWD_DISABLED_STR "disabled"1403#define DEVLINK_LOCAL_FWD_ENABLED_STR "enabled"1404#define DEVLINK_LOCAL_FWD_PRIORITIZED_STR "prioritized"1405 1406/**1407 * ice_devlink_local_fwd_mode_to_str - Get string for local_fwd mode.1408 * @mode: local forwarding for mode used in port_info struct.1409 *1410 * Return: Mode respective string or "Invalid".1411 */1412static const char *1413ice_devlink_local_fwd_mode_to_str(enum ice_local_fwd_mode mode)1414{1415	switch (mode) {1416	case ICE_LOCAL_FWD_MODE_ENABLED:1417		return DEVLINK_LOCAL_FWD_ENABLED_STR;1418	case ICE_LOCAL_FWD_MODE_PRIORITIZED:1419		return DEVLINK_LOCAL_FWD_PRIORITIZED_STR;1420	case ICE_LOCAL_FWD_MODE_DISABLED:1421		return DEVLINK_LOCAL_FWD_DISABLED_STR;1422	}1423 1424	return "Invalid";1425}1426 1427/**1428 * ice_devlink_local_fwd_str_to_mode - Get local_fwd mode from string name.1429 * @mode_str: local forwarding mode string.1430 *1431 * Return: Mode value or negative number if invalid.1432 */1433static int ice_devlink_local_fwd_str_to_mode(const char *mode_str)1434{1435	if (!strcmp(mode_str, DEVLINK_LOCAL_FWD_ENABLED_STR))1436		return ICE_LOCAL_FWD_MODE_ENABLED;1437	else if (!strcmp(mode_str, DEVLINK_LOCAL_FWD_PRIORITIZED_STR))1438		return ICE_LOCAL_FWD_MODE_PRIORITIZED;1439	else if (!strcmp(mode_str, DEVLINK_LOCAL_FWD_DISABLED_STR))1440		return ICE_LOCAL_FWD_MODE_DISABLED;1441 1442	return -EINVAL;1443}1444 1445/**1446 * ice_devlink_local_fwd_get - Get local_fwd parameter.1447 * @devlink: Pointer to the devlink instance.1448 * @id: The parameter ID to set.1449 * @ctx: Context to store the parameter value.1450 *1451 * Return: Zero.1452 */1453static int ice_devlink_local_fwd_get(struct devlink *devlink, u32 id,1454				     struct devlink_param_gset_ctx *ctx)1455{1456	struct ice_pf *pf = devlink_priv(devlink);1457	struct ice_port_info *pi;1458	const char *mode_str;1459 1460	pi = pf->hw.port_info;1461	mode_str = ice_devlink_local_fwd_mode_to_str(pi->local_fwd_mode);1462	snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s", mode_str);1463 1464	return 0;1465}1466 1467/**1468 * ice_devlink_local_fwd_set - Set local_fwd parameter.1469 * @devlink: Pointer to the devlink instance.1470 * @id: The parameter ID to set.1471 * @ctx: Context to get the parameter value.1472 * @extack: Netlink extended ACK structure.1473 *1474 * Return: Zero.1475 */1476static int ice_devlink_local_fwd_set(struct devlink *devlink, u32 id,1477				     struct devlink_param_gset_ctx *ctx,1478				     struct netlink_ext_ack *extack)1479{1480	int new_local_fwd_mode = ice_devlink_local_fwd_str_to_mode(ctx->val.vstr);1481	struct ice_pf *pf = devlink_priv(devlink);1482	struct device *dev = ice_pf_to_dev(pf);1483	struct ice_port_info *pi;1484 1485	pi = pf->hw.port_info;1486	if (pi->local_fwd_mode != new_local_fwd_mode) {1487		pi->local_fwd_mode = new_local_fwd_mode;1488		dev_info(dev, "Setting local_fwd to %s\n", ctx->val.vstr);1489		ice_schedule_reset(pf, ICE_RESET_CORER);1490	}1491 1492	return 0;1493}1494 1495/**1496 * ice_devlink_local_fwd_validate - Validate passed local_fwd parameter value.1497 * @devlink: Unused pointer to devlink instance.1498 * @id: The parameter ID to validate.1499 * @val: Value to validate.1500 * @extack: Netlink extended ACK structure.1501 *1502 * Supported values are:1503 * "enabled" - local_fwd is enabled, "disabled" - local_fwd is disabled1504 * "prioritized" - local_fwd traffic is prioritized in scheduling.1505 *1506 * Return: Zero when passed parameter value is supported. Negative value on1507 * error.1508 */1509static int ice_devlink_local_fwd_validate(struct devlink *devlink, u32 id,1510					  union devlink_param_value val,1511					  struct netlink_ext_ack *extack)1512{1513	if (ice_devlink_local_fwd_str_to_mode(val.vstr) < 0) {1514		NL_SET_ERR_MSG_MOD(extack, "Error: Requested value is not supported.");1515		return -EINVAL;1516	}1517 1518	return 0;1519}1520 1521enum ice_param_id {1522	ICE_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,1523	ICE_DEVLINK_PARAM_ID_TX_SCHED_LAYERS,1524	ICE_DEVLINK_PARAM_ID_LOCAL_FWD,1525};1526 1527static const struct devlink_param ice_dvl_rdma_params[] = {1528	DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_RUNTIME),1529			      ice_devlink_enable_roce_get,1530			      ice_devlink_enable_roce_set,1531			      ice_devlink_enable_roce_validate),1532	DEVLINK_PARAM_GENERIC(ENABLE_IWARP, BIT(DEVLINK_PARAM_CMODE_RUNTIME),1533			      ice_devlink_enable_iw_get,1534			      ice_devlink_enable_iw_set,1535			      ice_devlink_enable_iw_validate),1536};1537 1538static const struct devlink_param ice_dvl_sched_params[] = {1539	DEVLINK_PARAM_DRIVER(ICE_DEVLINK_PARAM_ID_TX_SCHED_LAYERS,1540			     "tx_scheduling_layers",1541			     DEVLINK_PARAM_TYPE_U8,1542			     BIT(DEVLINK_PARAM_CMODE_PERMANENT),1543			     ice_devlink_tx_sched_layers_get,1544			     ice_devlink_tx_sched_layers_set,1545			     ice_devlink_tx_sched_layers_validate),1546	DEVLINK_PARAM_DRIVER(ICE_DEVLINK_PARAM_ID_LOCAL_FWD,1547			     "local_forwarding", DEVLINK_PARAM_TYPE_STRING,1548			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),1549			     ice_devlink_local_fwd_get,1550			     ice_devlink_local_fwd_set,1551			     ice_devlink_local_fwd_validate),1552};1553 1554static void ice_devlink_free(void *devlink_ptr)1555{1556	devlink_free((struct devlink *)devlink_ptr);1557}1558 1559/**1560 * ice_allocate_pf - Allocate devlink and return PF structure pointer1561 * @dev: the device to allocate for1562 *1563 * Allocate a devlink instance for this device and return the private area as1564 * the PF structure. The devlink memory is kept track of through devres by1565 * adding an action to remove it when unwinding.1566 */1567struct ice_pf *ice_allocate_pf(struct device *dev)1568{1569	struct devlink *devlink;1570 1571	devlink = devlink_alloc(&ice_devlink_ops, sizeof(struct ice_pf), dev);1572	if (!devlink)1573		return NULL;1574 1575	/* Add an action to teardown the devlink when unwinding the driver */1576	if (devm_add_action_or_reset(dev, ice_devlink_free, devlink))1577		return NULL;1578 1579	return devlink_priv(devlink);1580}1581 1582/**1583 * ice_allocate_sf - Allocate devlink and return SF structure pointer1584 * @dev: the device to allocate for1585 * @pf: pointer to the PF structure1586 *1587 * Allocate a devlink instance for SF.1588 *1589 * Return: ice_sf_priv pointer to allocated memory or ERR_PTR in case of error1590 */1591struct ice_sf_priv *ice_allocate_sf(struct device *dev, struct ice_pf *pf)1592{1593	struct devlink *devlink;1594	int err;1595 1596	devlink = devlink_alloc(&ice_sf_devlink_ops, sizeof(struct ice_sf_priv),1597				dev);1598	if (!devlink)1599		return ERR_PTR(-ENOMEM);1600 1601	err = devl_nested_devlink_set(priv_to_devlink(pf), devlink);1602	if (err) {1603		devlink_free(devlink);1604		return ERR_PTR(err);1605	}1606 1607	return devlink_priv(devlink);1608}1609 1610/**1611 * ice_devlink_register - Register devlink interface for this PF1612 * @pf: the PF to register the devlink for.1613 *1614 * Register the devlink instance associated with this physical function.1615 *1616 * Return: zero on success or an error code on failure.1617 */1618void ice_devlink_register(struct ice_pf *pf)1619{1620	struct devlink *devlink = priv_to_devlink(pf);1621 1622	devl_register(devlink);1623}1624 1625/**1626 * ice_devlink_unregister - Unregister devlink resources for this PF.1627 * @pf: the PF structure to cleanup1628 *1629 * Releases resources used by devlink and cleans up associated memory.1630 */1631void ice_devlink_unregister(struct ice_pf *pf)1632{1633	devl_unregister(priv_to_devlink(pf));1634}1635 1636int ice_devlink_register_params(struct ice_pf *pf)1637{1638	struct devlink *devlink = priv_to_devlink(pf);1639	struct ice_hw *hw = &pf->hw;1640	int status;1641 1642	status = devl_params_register(devlink, ice_dvl_rdma_params,1643				      ARRAY_SIZE(ice_dvl_rdma_params));1644	if (status)1645		return status;1646 1647	if (hw->func_caps.common_cap.tx_sched_topo_comp_mode_en)1648		status = devl_params_register(devlink, ice_dvl_sched_params,1649					      ARRAY_SIZE(ice_dvl_sched_params));1650 1651	return status;1652}1653 1654void ice_devlink_unregister_params(struct ice_pf *pf)1655{1656	struct devlink *devlink = priv_to_devlink(pf);1657	struct ice_hw *hw = &pf->hw;1658 1659	devl_params_unregister(devlink, ice_dvl_rdma_params,1660			       ARRAY_SIZE(ice_dvl_rdma_params));1661 1662	if (hw->func_caps.common_cap.tx_sched_topo_comp_mode_en)1663		devl_params_unregister(devlink, ice_dvl_sched_params,1664				       ARRAY_SIZE(ice_dvl_sched_params));1665}1666 1667#define ICE_DEVLINK_READ_BLK_SIZE (1024 * 1024)1668 1669static const struct devlink_region_ops ice_nvm_region_ops;1670static const struct devlink_region_ops ice_sram_region_ops;1671 1672/**1673 * ice_devlink_nvm_snapshot - Capture a snapshot of the NVM flash contents1674 * @devlink: the devlink instance1675 * @ops: the devlink region to snapshot1676 * @extack: extended ACK response structure1677 * @data: on exit points to snapshot data buffer1678 *1679 * This function is called in response to a DEVLINK_CMD_REGION_NEW for either1680 * the nvm-flash or shadow-ram region.1681 *1682 * It captures a snapshot of the NVM or Shadow RAM flash contents. This1683 * snapshot can then later be viewed via the DEVLINK_CMD_REGION_READ netlink1684 * interface.1685 *1686 * @returns zero on success, and updates the data pointer. Returns a non-zero1687 * error code on failure.1688 */1689static int ice_devlink_nvm_snapshot(struct devlink *devlink,1690				    const struct devlink_region_ops *ops,1691				    struct netlink_ext_ack *extack, u8 **data)1692{1693	struct ice_pf *pf = devlink_priv(devlink);1694	struct device *dev = ice_pf_to_dev(pf);1695	struct ice_hw *hw = &pf->hw;1696	bool read_shadow_ram;1697	u8 *nvm_data, *tmp, i;1698	u32 nvm_size, left;1699	s8 num_blks;1700	int status;1701 1702	if (ops == &ice_nvm_region_ops) {1703		read_shadow_ram = false;1704		nvm_size = hw->flash.flash_size;1705	} else if (ops == &ice_sram_region_ops) {1706		read_shadow_ram = true;1707		nvm_size = hw->flash.sr_words * 2u;1708	} else {1709		NL_SET_ERR_MSG_MOD(extack, "Unexpected region in snapshot function");1710		return -EOPNOTSUPP;1711	}1712 1713	nvm_data = vzalloc(nvm_size);1714	if (!nvm_data)1715		return -ENOMEM;1716 1717	num_blks = DIV_ROUND_UP(nvm_size, ICE_DEVLINK_READ_BLK_SIZE);1718	tmp = nvm_data;1719	left = nvm_size;1720 1721	/* Some systems take longer to read the NVM than others which causes the1722	 * FW to reclaim the NVM lock before the entire NVM has been read. Fix1723	 * this by breaking the reads of the NVM into smaller chunks that will1724	 * probably not take as long. This has some overhead since we are1725	 * increasing the number of AQ commands, but it should always work1726	 */1727	for (i = 0; i < num_blks; i++) {1728		u32 read_sz = min_t(u32, ICE_DEVLINK_READ_BLK_SIZE, left);1729 1730		status = ice_acquire_nvm(hw, ICE_RES_READ);1731		if (status) {1732			dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n",1733				status, hw->adminq.sq_last_status);1734			NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore");1735			vfree(nvm_data);1736			return -EIO;1737		}1738 1739		status = ice_read_flat_nvm(hw, i * ICE_DEVLINK_READ_BLK_SIZE,1740					   &read_sz, tmp, read_shadow_ram);1741		if (status) {1742			dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n",1743				read_sz, status, hw->adminq.sq_last_status);1744			NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents");1745			ice_release_nvm(hw);1746			vfree(nvm_data);1747			return -EIO;1748		}1749		ice_release_nvm(hw);1750 1751		tmp += read_sz;1752		left -= read_sz;1753	}1754 1755	*data = nvm_data;1756 1757	return 0;1758}1759 1760/**1761 * ice_devlink_nvm_read - Read a portion of NVM flash contents1762 * @devlink: the devlink instance1763 * @ops: the devlink region to snapshot1764 * @extack: extended ACK response structure1765 * @offset: the offset to start at1766 * @size: the amount to read1767 * @data: the data buffer to read into1768 *1769 * This function is called in response to DEVLINK_CMD_REGION_READ to directly1770 * read a section of the NVM contents.1771 *1772 * It reads from either the nvm-flash or shadow-ram region contents.1773 *1774 * @returns zero on success, and updates the data pointer. Returns a non-zero1775 * error code on failure.1776 */1777static int ice_devlink_nvm_read(struct devlink *devlink,1778				const struct devlink_region_ops *ops,1779				struct netlink_ext_ack *extack,1780				u64 offset, u32 size, u8 *data)1781{1782	struct ice_pf *pf = devlink_priv(devlink);1783	struct device *dev = ice_pf_to_dev(pf);1784	struct ice_hw *hw = &pf->hw;1785	bool read_shadow_ram;1786	u64 nvm_size;1787	int status;1788 1789	if (ops == &ice_nvm_region_ops) {1790		read_shadow_ram = false;1791		nvm_size = hw->flash.flash_size;1792	} else if (ops == &ice_sram_region_ops) {1793		read_shadow_ram = true;1794		nvm_size = hw->flash.sr_words * 2u;1795	} else {1796		NL_SET_ERR_MSG_MOD(extack, "Unexpected region in snapshot function");1797		return -EOPNOTSUPP;1798	}1799 1800	if (offset + size >= nvm_size) {1801		NL_SET_ERR_MSG_MOD(extack, "Cannot read beyond the region size");1802		return -ERANGE;1803	}1804 1805	status = ice_acquire_nvm(hw, ICE_RES_READ);1806	if (status) {1807		dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n",1808			status, hw->adminq.sq_last_status);1809		NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore");1810		return -EIO;1811	}1812 1813	status = ice_read_flat_nvm(hw, (u32)offset, &size, data,1814				   read_shadow_ram);1815	if (status) {1816		dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n",1817			size, status, hw->adminq.sq_last_status);1818		NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents");1819		ice_release_nvm(hw);1820		return -EIO;1821	}1822	ice_release_nvm(hw);1823 1824	return 0;1825}1826 1827/**1828 * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities1829 * @devlink: the devlink instance1830 * @ops: the devlink region being snapshotted1831 * @extack: extended ACK response structure1832 * @data: on exit points to snapshot data buffer1833 *1834 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for1835 * the device-caps devlink region. It captures a snapshot of the device1836 * capabilities reported by firmware.1837 *1838 * @returns zero on success, and updates the data pointer. Returns a non-zero1839 * error code on failure.1840 */1841static int1842ice_devlink_devcaps_snapshot(struct devlink *devlink,1843			     const struct devlink_region_ops *ops,1844			     struct netlink_ext_ack *extack, u8 **data)1845{1846	struct ice_pf *pf = devlink_priv(devlink);1847	struct device *dev = ice_pf_to_dev(pf);1848	struct ice_hw *hw = &pf->hw;1849	void *devcaps;1850	int status;1851 1852	devcaps = vzalloc(ICE_AQ_MAX_BUF_LEN);1853	if (!devcaps)1854		return -ENOMEM;1855 1856	status = ice_aq_list_caps(hw, devcaps, ICE_AQ_MAX_BUF_LEN, NULL,1857				  ice_aqc_opc_list_dev_caps, NULL);1858	if (status) {1859		dev_dbg(dev, "ice_aq_list_caps: failed to read device capabilities, err %d aq_err %d\n",1860			status, hw->adminq.sq_last_status);1861		NL_SET_ERR_MSG_MOD(extack, "Failed to read device capabilities");1862		vfree(devcaps);1863		return status;1864	}1865 1866	*data = (u8 *)devcaps;1867 1868	return 0;1869}1870 1871static const struct devlink_region_ops ice_nvm_region_ops = {1872	.name = "nvm-flash",1873	.destructor = vfree,1874	.snapshot = ice_devlink_nvm_snapshot,1875	.read = ice_devlink_nvm_read,1876};1877 1878static const struct devlink_region_ops ice_sram_region_ops = {1879	.name = "shadow-ram",1880	.destructor = vfree,1881	.snapshot = ice_devlink_nvm_snapshot,1882	.read = ice_devlink_nvm_read,1883};1884 1885static const struct devlink_region_ops ice_devcaps_region_ops = {1886	.name = "device-caps",1887	.destructor = vfree,1888	.snapshot = ice_devlink_devcaps_snapshot,1889};1890 1891/**1892 * ice_devlink_init_regions - Initialize devlink regions1893 * @pf: the PF device structure1894 *1895 * Create devlink regions used to enable access to dump the contents of the1896 * flash memory on the device.1897 */1898void ice_devlink_init_regions(struct ice_pf *pf)1899{1900	struct devlink *devlink = priv_to_devlink(pf);1901	struct device *dev = ice_pf_to_dev(pf);1902	u64 nvm_size, sram_size;1903 1904	nvm_size = pf->hw.flash.flash_size;1905	pf->nvm_region = devl_region_create(devlink, &ice_nvm_region_ops, 1,1906					    nvm_size);1907	if (IS_ERR(pf->nvm_region)) {1908		dev_err(dev, "failed to create NVM devlink region, err %ld\n",1909			PTR_ERR(pf->nvm_region));1910		pf->nvm_region = NULL;1911	}1912 1913	sram_size = pf->hw.flash.sr_words * 2u;1914	pf->sram_region = devl_region_create(devlink, &ice_sram_region_ops,1915					     1, sram_size);1916	if (IS_ERR(pf->sram_region)) {1917		dev_err(dev, "failed to create shadow-ram devlink region, err %ld\n",1918			PTR_ERR(pf->sram_region));1919		pf->sram_region = NULL;1920	}1921 1922	pf->devcaps_region = devl_region_create(devlink,1923						&ice_devcaps_region_ops, 10,1924						ICE_AQ_MAX_BUF_LEN);1925	if (IS_ERR(pf->devcaps_region)) {1926		dev_err(dev, "failed to create device-caps devlink region, err %ld\n",1927			PTR_ERR(pf->devcaps_region));1928		pf->devcaps_region = NULL;1929	}1930}1931 1932/**1933 * ice_devlink_destroy_regions - Destroy devlink regions1934 * @pf: the PF device structure1935 *1936 * Remove previously created regions for this PF.1937 */1938void ice_devlink_destroy_regions(struct ice_pf *pf)1939{1940	if (pf->nvm_region)1941		devl_region_destroy(pf->nvm_region);1942 1943	if (pf->sram_region)1944		devl_region_destroy(pf->sram_region);1945 1946	if (pf->devcaps_region)1947		devl_region_destroy(pf->devcaps_region);1948}1949