From patchwork Fri Mar 3 07:26:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xing, Beilei" X-Patchwork-Id: 21233 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id D72CCF95E; Fri, 3 Mar 2017 08:28:05 +0100 (CET) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 6F63F2B93 for ; Fri, 3 Mar 2017 08:27:32 +0100 (CET) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Mar 2017 23:27:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,235,1484035200"; d="scan'208";a="830441998" Received: from unknown (HELO dpdk9.sh.intel.com) ([10.239.129.31]) by FMSMGA003.fm.intel.com with ESMTP; 02 Mar 2017 23:27:31 -0800 From: Beilei Xing To: jingjing.wu@intel.com Cc: helin.zhang@intel.com, dev@dpdk.org Date: Fri, 3 Mar 2017 15:26:13 +0800 Message-Id: <1488525977-15321-9-git-send-email-beilei.xing@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1488525977-15321-1-git-send-email-beilei.xing@intel.com> References: <1488525977-15321-1-git-send-email-beilei.xing@intel.com> Subject: [dpdk-dev] [PATCH 2/6] net/i40e: support pipeline personalization profile X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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)