[dpdk-dev] [PATCH 2/6] net/i40e: support pipeline personalization profile
Beilei Xing
beilei.xing at intel.com
Fri Mar 3 08:26:13 CET 2017
Add admin queue functions for Pipeline Personalization
Profile AQ commands defined in DCR 287:
- Write Recipe Command buffer (Opcode: 0x0270)
- Get Applied Profiles list (Opcode: 0x0271)
This patch will be moved to base driver in future.
Signed-off-by: Beilei Xing <beilei.xing at intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 237 +++++++++++++++++++++++++++++++++++++++++
drivers/net/i40e/i40e_ethdev.h | 127 ++++++++++++++++++++++
2 files changed, 364 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 508fcc8..ca4a87d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11219,3 +11219,240 @@ rte_pmd_i40e_reset_vf_stats(uint8_t port,
return 0;
}
+
+/**
+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @error_offset: returns error offset
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+ uint16_t buff_size, uint32_t track_id,
+ uint32_t *error_offset, uint32_t *error_info,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_write_personalization_profile *cmd =
+ (struct i40e_aqc_write_personalization_profile *)&desc.params.raw;
+ struct i40e_aqc_write_ppp_resp *resp;
+ enum i40e_status_code status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_write_personalization_profile);
+
+ desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
+ if (buff_size > I40E_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((uint16_t)I40E_AQ_FLAG_LB);
+
+ desc.datalen = CPU_TO_LE16(buff_size);
+
+ cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+ status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+ if (!status) {
+ resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
+ if (error_offset)
+ *error_offset = LE32_TO_CPU(resp->error_offset);
+ if (error_info)
+ *error_info = LE32_TO_CPU(resp->error_info);
+ }
+
+ return status;
+}
+
+/**
+ * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+ uint16_t buff_size, uint8_t flags,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_applied_profiles *cmd =
+ (struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
+ enum i40e_status_code status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_personalization_profile_list);
+
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+ if (buff_size > I40E_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((uint16_t)I40E_AQ_FLAG_LB);
+ desc.datalen = CPU_TO_LE16(buff_size);
+
+ cmd->flags = flags;
+
+ status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+ return status;
+}
+
+/**
+ * i40e_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ */
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(uint32_t segment_type,
+ struct i40e_package_header *pkg_hdr)
+{
+ struct i40e_generic_seg_header *segment;
+ uint32_t i;
+
+ PMD_DRV_LOG(INFO, "i40e_find_segment_in_package");
+ PMD_DRV_LOG(INFO, "Package version: %d.%d.%d.%d",
+ pkg_hdr->version.major,
+ pkg_hdr->version.minor,
+ pkg_hdr->version.update,
+ pkg_hdr->version.draft);
+
+ /* Search all package segments for the requested segment type */
+ for (i = 0; i < pkg_hdr->segment_count; i++) {
+ segment =
+ (struct i40e_generic_seg_header *)((uint8_t *)pkg_hdr +
+ pkg_hdr->segment_offset[i]);
+
+ if (segment->type == segment_type)
+ return segment;
+ }
+
+ return NULL;
+}
+
+/**
+ * i40e_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ uint32_t track_id)
+{
+ enum i40e_status_code status = I40E_SUCCESS;
+ struct i40e_section_table *sec_tbl;
+ struct i40e_profile_section_header *sec = NULL;
+ uint32_t dev_cnt;
+ uint32_t vendor_dev_id;
+ uint32_t *nvm;
+ uint32_t section_size = 0;
+ uint32_t offset = 0, info = 0;
+ uint32_t i;
+
+ PMD_DRV_LOG(INFO, "i40e_write_profile");
+ PMD_DRV_LOG(INFO, "Segment version: %d.%d.%d.%d",
+ profile->header.version.major,
+ profile->header.version.minor,
+ profile->header.version.update,
+ profile->header.version.draft);
+ PMD_DRV_LOG(INFO, "Seg: type 0x%X, size %d, name %s",
+ LE32_TO_CPU(profile->header.type),
+ LE32_TO_CPU(profile->header.size),
+ profile->header.name);
+
+ if (!track_id) {
+ PMD_DRV_LOG(ERR, "Track_id can't be 0.");
+ return I40E_NOT_SUPPORTED;
+ }
+
+ dev_cnt = profile->device_table_count;
+
+ for (i = 0; i < dev_cnt; i++) {
+ vendor_dev_id = profile->device_table[i].vendor_dev_id;
+ if ((vendor_dev_id >> 16) == I40E_INTEL_VENDOR_ID)
+ if (hw->device_id == (vendor_dev_id & 0xFFFF))
+ break;
+ }
+ if (i == dev_cnt) {
+ PMD_DRV_LOG(ERR, "Device doesn't support PPP");
+ return I40E_ERR_DEVICE_NOT_SUPPORTED;
+ }
+
+ nvm = (uint32_t *)&profile->device_table[dev_cnt];
+ sec_tbl = (struct i40e_section_table *)&nvm[nvm[0] + 1];
+
+ for (i = 0; i < sec_tbl->section_count; i++) {
+ sec = (struct i40e_profile_section_header *)
+ ((uint8_t *)profile +
+ sec_tbl->section_offset[i]);
+
+ /* Skip 'AQ', 'note' and 'name' sections */
+ if (sec->section.type != SECTION_TYPE_MMIO)
+ continue;
+
+ section_size = sec->section.size +
+ sizeof(struct i40e_profile_section_header);
+
+ /* Write profile */
+ status = i40e_aq_write_ppp(hw, (void *)sec,
+ (uint16_t)section_size,
+ track_id, &offset, &info, NULL);
+ if (status) {
+ PMD_DRV_LOG(ERR, "Failed to write profile: "
+ "offset %d, info %d",
+ offset, info);
+ break;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * i40e_add_pinfo_to_list
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package
+ * @profile_info_sec: buffer for information section
+ * @track_id: package tracking id
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+ struct i40e_profile_segment *profile,
+ uint8_t *profile_info_sec, uint32_t track_id)
+{
+ enum i40e_status_code status = I40E_SUCCESS;
+ struct i40e_profile_section_header *sec = NULL;
+ struct i40e_profile_info *pinfo;
+ uint32_t offset = 0, info = 0;
+
+ sec = (struct i40e_profile_section_header *)profile_info_sec;
+ sec->tbl_size = 1;
+ sec->data_end = sizeof(struct i40e_profile_section_header) +
+ sizeof(struct i40e_profile_info);
+ sec->section.type = SECTION_TYPE_INFO;
+ sec->section.offset = sizeof(struct i40e_profile_section_header);
+ sec->section.size = sizeof(struct i40e_profile_info);
+ pinfo = (struct i40e_profile_info *)(profile_info_sec +
+ sec->section.offset);
+ pinfo->track_id = track_id;
+ pinfo->version = profile->version;
+ pinfo->op = I40E_PPP_ADD_TRACKID;
+ memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
+
+ status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
+ track_id, &offset, &info, NULL);
+ if (status)
+ PMD_DRV_LOG(ERR, "Failed to add to list: "
+ "offset %d, info %d",
+ offset, info);
+
+ return status;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index f545850..e3eb1b9 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -729,6 +729,116 @@ struct i40e_valid_pattern {
parse_filter_t parse_filter;
};
+/* Support Pipeline Personalization Profile */
+#define i40e_aqc_opc_write_personalization_profile 0x0270
+#define i40e_aqc_opc_get_personalization_profile_list 0x0271
+struct i40e_aqc_write_personalization_profile {
+ uint8_t reserved[4];
+ uint32_t profile_track_id;
+ uint32_t addr_high;
+ uint32_t addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_write_personalization_profile);
+
+struct i40e_aqc_write_ppp_resp {
+ uint32_t error_offset;
+ uint32_t error_info;
+ uint32_t addr_high;
+ uint32_t addr_low;
+};
+
+struct i40e_aqc_get_applied_profiles {
+ uint8_t flags;
+ #define I40E_AQC_GET_PPP_GET_CONF 0x1
+ #define I40E_AQC_GET_PPP_GET_RDPU_CONF 0x2
+ uint8_t rsv[3];
+ uint32_t reserved;
+ uint32_t addr_high;
+ uint32_t addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_get_applied_profiles);
+
+/* Version format for PPP */
+struct i40e_ppp_version {
+ uint8_t major;
+ uint8_t minor;
+ uint8_t update;
+ uint8_t draft;
+};
+
+#define I40E_PPP_NAME_SIZE 32
+
+/* Package header */
+struct i40e_package_header {
+ struct i40e_ppp_version version;
+ uint32_t segment_count;
+ uint32_t segment_offset[1];
+};
+
+/* Generic segment header */
+struct i40e_generic_seg_header {
+#define SEGMENT_TYPE_METADATA 0x00000001
+#define SEGMENT_TYPE_NOTES 0x00000002
+#define SEGMENT_TYPE_I40E 0x00000011
+#define SEGMENT_TYPE_X722 0x00000012
+ uint32_t type;
+ struct i40e_ppp_version version;
+ uint32_t size;
+ char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_metadata_segment {
+ struct i40e_generic_seg_header header;
+ struct i40e_ppp_version version;
+ uint32_t track_id;
+ char name[I40E_PPP_NAME_SIZE];
+};
+
+struct i40e_device_id_entry {
+ uint32_t vendor_dev_id;
+ uint32_t sub_vendor_dev_id;
+};
+
+struct i40e_profile_segment {
+ struct i40e_generic_seg_header header;
+ struct i40e_ppp_version version;
+ char name[I40E_PPP_NAME_SIZE];
+ uint32_t device_table_count;
+ struct i40e_device_id_entry device_table[1];
+};
+
+struct i40e_section_table {
+ uint32_t section_count;
+ uint32_t section_offset[1];
+};
+
+struct i40e_profile_section_header {
+ uint16_t tbl_size;
+ uint16_t data_end;
+ struct {
+#define SECTION_TYPE_INFO 0x0000010
+#define SECTION_TYPE_MMIO 0x0000800
+#define SECTION_TYPE_AQ 0x0000801
+#define SECTION_TYPE_NOTE 0x80000000
+#define SECTION_TYPE_NAME 0x80000001
+ uint32_t type;
+ uint32_t offset;
+ uint32_t size;
+ } section;
+};
+
+struct i40e_profile_info {
+ uint32_t track_id;
+ struct i40e_ppp_version version;
+ uint8_t op;
+#define I40E_PPP_ADD_TRACKID 0x01
+#define I40E_PPP_REMOVE_TRACKID 0x02
+ uint8_t reserved[7];
+ uint8_t name[I40E_PPP_NAME_SIZE];
+};
+
int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
int i40e_vsi_release(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
@@ -805,6 +915,23 @@ int i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
struct rte_eth_tunnel_filter_conf *tunnel_filter,
uint8_t add);
int i40e_fdir_flush(struct rte_eth_dev *dev);
+enum i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
+ uint16_t buff_size, uint32_t track_id,
+ uint32_t *error_offset, uint32_t *error_info,
+ struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
+ uint16_t buff_size, uint8_t flags,
+ struct i40e_asq_cmd_details *cmd_details);
+struct i40e_generic_seg_header *
+i40e_find_segment_in_package(uint32_t segment_type,
+ struct i40e_package_header *pkg_header);
+enum i40e_status_code
+i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+ uint32_t track_id);
+enum i40e_status_code
+i40e_add_pinfo_to_list(struct i40e_hw *hw,
+ struct i40e_profile_segment *profile,
+ uint8_t *profile_info_sec, uint32_t track_id);
#define I40E_DEV_TO_PCI(eth_dev) \
RTE_DEV_TO_PCI((eth_dev)->device)
--
2.5.5
More information about the dev
mailing list