@@ -32,6 +32,12 @@ struct ice_dcf {
struct ice_aq_desc aq_desc;
u8 aq_desc_received;
unsigned long aq_desc_expires;
+
+ /* Save the current Device Serial Number when searching the package
+ * path for later query.
+ */
+#define ICE_DSN_NUM_LEN 8
+ u8 dsn[ICE_DSN_NUM_LEN];
};
#ifdef CONFIG_PCI_IOV
@@ -3243,6 +3243,8 @@ static char *ice_get_opt_fw_name(struct ice_pf *pf)
snprintf(opt_fw_filename, NAME_MAX, "%sice-%016llx.pkg",
ICE_DDP_PKG_PATH, dsn);
+ memcpy(pf->dcf.dsn, &dsn, sizeof(pf->dcf.dsn));
+
return opt_fw_filename;
}
@@ -3907,6 +3907,55 @@ static int ice_vc_dcf_get_vsi_map(struct ice_vf *vf)
return ret;
}
+/**
+ * ice_vc_dcf_query_pkg_info - query DDP package info from PF
+ * @vf: pointer to VF info
+ *
+ * Called from VF to query DDP package information loaded in PF,
+ * including track ID, package name, version and device serial
+ * number.
+ */
+static int ice_vc_dcf_query_pkg_info(struct ice_vf *vf)
+{
+ enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
+ struct virtchnl_pkg_info *pkg_info = NULL;
+ struct ice_hw *hw = &vf->pf->hw;
+ struct ice_pf *pf = vf->pf;
+ int len = 0;
+ int ret;
+
+ if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
+ v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+ goto err;
+ }
+
+ if (!ice_is_vf_dcf(vf) || ice_dcf_get_state(pf) != ICE_DCF_STATE_ON) {
+ v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+ goto err;
+ }
+
+ len = sizeof(struct virtchnl_pkg_info);
+ pkg_info = kzalloc(len, GFP_KERNEL);
+ if (!pkg_info) {
+ v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+ len = 0;
+ goto err;
+ }
+
+ pkg_info->track_id = hw->active_track_id;
+ memcpy(&pkg_info->pkg_ver, &hw->active_pkg_ver,
+ sizeof(pkg_info->pkg_ver));
+ memcpy(pkg_info->pkg_name, hw->active_pkg_name,
+ sizeof(pkg_info->pkg_name));
+ memcpy(pkg_info->dsn, pf->dcf.dsn, sizeof(pkg_info->dsn));
+
+err:
+ ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DCF_GET_PKG_INFO,
+ v_ret, (u8 *)pkg_info, len);
+ kfree(pkg_info);
+ return ret;
+}
+
/**
* ice_vc_process_vf_msg - Process request from VF
* @pf: pointer to the PF structure
@@ -4029,6 +4078,9 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
case VIRTCHNL_OP_DCF_GET_VSI_MAP:
err = ice_vc_dcf_get_vsi_map(vf);
break;
+ case VIRTCHNL_OP_DCF_GET_PKG_INFO:
+ err = ice_vc_dcf_query_pkg_info(vf);
+ break;
case VIRTCHNL_OP_UNKNOWN:
default:
dev_err(dev, "Unsupported opcode %d from VF %d\n", v_opcode,
@@ -141,6 +141,7 @@ enum virtchnl_ops {
VIRTCHNL_OP_DCF_CMD_BUFF = 40,
VIRTCHNL_OP_DCF_DISABLE = 41,
VIRTCHNL_OP_DCF_GET_VSI_MAP = 42,
+ VIRTCHNL_OP_DCF_GET_PKG_INFO = 43,
};
/* These macros are used to generate compilation errors if a structure/union
@@ -604,6 +605,27 @@ struct virtchnl_dcf_vsi_map {
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_dcf_vsi_map);
+#define PKG_NAME_SIZE 32
+#define DSN_SIZE 8
+
+struct pkg_version {
+ u8 major;
+ u8 minor;
+ u8 update;
+ u8 draft;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(4, pkg_version);
+
+struct virtchnl_pkg_info {
+ struct pkg_version pkg_ver;
+ u32 track_id;
+ char pkg_name[PKG_NAME_SIZE];
+ u8 dsn[DSN_SIZE];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_pkg_info);
+
/* VIRTCHNL_OP_EVENT
* PF sends this message to inform the VF driver of events that may affect it.
* No direct response is expected from the VF, though it may generate other
@@ -867,6 +889,7 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
break;
case VIRTCHNL_OP_DCF_DISABLE:
case VIRTCHNL_OP_DCF_GET_VSI_MAP:
+ case VIRTCHNL_OP_DCF_GET_PKG_INFO:
break;
/* These are always errors coming from the VF. */
case VIRTCHNL_OP_EVENT: