diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_devlink.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_devlink.c | 103 | 
1 files changed, 81 insertions, 22 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index 88497363fc4c..63acb7b96053 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -371,10 +371,7 @@ out_free_ctx:  /**   * ice_devlink_reload_empr_start - Start EMP reset to activate new firmware - * @devlink: pointer to the devlink instance to reload - * @netns_change: if true, the network namespace is changing - * @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE - * @limit: limits on what reload should do, such as not resetting + * @pf: pointer to the pf instance   * @extack: netlink extended ACK structure   *   * Allow user to activate new Embedded Management Processor firmware by @@ -387,12 +384,9 @@ out_free_ctx:   * any source.   */  static int -ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change, -			      enum devlink_reload_action action, -			      enum devlink_reload_limit limit, +ice_devlink_reload_empr_start(struct ice_pf *pf,  			      struct netlink_ext_ack *extack)  { -	struct ice_pf *pf = devlink_priv(devlink);  	struct device *dev = ice_pf_to_dev(pf);  	struct ice_hw *hw = &pf->hw;  	u8 pending; @@ -431,11 +425,51 @@ ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change,  }  /** + * ice_devlink_reload_down - prepare for reload + * @devlink: pointer to the devlink instance to reload + * @netns_change: if true, the network namespace is changing + * @action: the action to perform + * @limit: limits on what reload should do, such as not resetting + * @extack: netlink extended ACK structure + */ +static int +ice_devlink_reload_down(struct devlink *devlink, bool netns_change, +			enum devlink_reload_action action, +			enum devlink_reload_limit limit, +			struct netlink_ext_ack *extack) +{ +	struct ice_pf *pf = devlink_priv(devlink); + +	switch (action) { +	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: +		if (ice_is_eswitch_mode_switchdev(pf)) { +			NL_SET_ERR_MSG_MOD(extack, +					   "Go to legacy mode before doing reinit\n"); +			return -EOPNOTSUPP; +		} +		if (ice_is_adq_active(pf)) { +			NL_SET_ERR_MSG_MOD(extack, +					   "Turn off ADQ before doing reinit\n"); +			return -EOPNOTSUPP; +		} +		if (ice_has_vfs(pf)) { +			NL_SET_ERR_MSG_MOD(extack, +					   "Remove all VFs before doing reinit\n"); +			return -EOPNOTSUPP; +		} +		ice_unload(pf); +		return 0; +	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: +		return ice_devlink_reload_empr_start(pf, extack); +	default: +		WARN_ON(1); +		return -EOPNOTSUPP; +	} +} + +/**   * ice_devlink_reload_empr_finish - Wait for EMP reset to finish - * @devlink: pointer to the devlink instance reloading - * @action: the action requested - * @limit: limits imposed by userspace, such as not resetting - * @actions_performed: on return, indicate what actions actually performed + * @pf: pointer to the pf instance   * @extack: netlink extended ACK structure   *   * Wait for driver to finish rebuilding after EMP reset is completed. This @@ -443,17 +477,11 @@ ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change,   * for the driver's rebuild to complete.   */  static int -ice_devlink_reload_empr_finish(struct devlink *devlink, -			       enum devlink_reload_action action, -			       enum devlink_reload_limit limit, -			       u32 *actions_performed, +ice_devlink_reload_empr_finish(struct ice_pf *pf,  			       struct netlink_ext_ack *extack)  { -	struct ice_pf *pf = devlink_priv(devlink);  	int err; -	*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE); -  	err = ice_wait_for_reset(pf, 60 * HZ);  	if (err) {  		NL_SET_ERR_MSG_MOD(extack, "Device still resetting after 1 minute"); @@ -1192,12 +1220,43 @@ static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,  	return status;  } +/** + * ice_devlink_reload_up - do reload up after reinit + * @devlink: pointer to the devlink instance reloading + * @action: the action requested + * @limit: limits imposed by userspace, such as not resetting + * @actions_performed: on return, indicate what actions actually performed + * @extack: netlink extended ACK structure + */ +static int +ice_devlink_reload_up(struct devlink *devlink, +		      enum devlink_reload_action action, +		      enum devlink_reload_limit limit, +		      u32 *actions_performed, +		      struct netlink_ext_ack *extack) +{ +	struct ice_pf *pf = devlink_priv(devlink); + +	switch (action) { +	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: +		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); +		return ice_load(pf); +	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: +		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE); +		return ice_devlink_reload_empr_finish(pf, extack); +	default: +		WARN_ON(1); +		return -EOPNOTSUPP; +	} +} +  static const struct devlink_ops ice_devlink_ops = {  	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, -	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), +	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | +			  BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),  	/* The ice driver currently does not support driver reinit */ -	.reload_down = ice_devlink_reload_empr_start, -	.reload_up = ice_devlink_reload_empr_finish, +	.reload_down = ice_devlink_reload_down, +	.reload_up = ice_devlink_reload_up,  	.port_split = ice_devlink_port_split,  	.port_unsplit = ice_devlink_port_unsplit,  	.eswitch_mode_get = ice_eswitch_mode_get,  | 
