@@ -5042,3 +5042,215 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
50425042 if (status || use_register )
50435043 wr32 (hw , reg_addr , reg_val );
50445044}
5045+
5046+ /**
5047+ * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
5048+ * @hw: pointer to the hw struct
5049+ * @buff: command buffer (size in bytes = buff_size)
5050+ * @buff_size: buffer size in bytes
5051+ * @track_id: package tracking id
5052+ * @error_offset: returns error offset
5053+ * @error_info: returns error information
5054+ * @cmd_details: pointer to command details structure or NULL
5055+ **/
5056+ enum
5057+ i40e_status_code i40e_aq_write_ppp (struct i40e_hw * hw , void * buff ,
5058+ u16 buff_size , u32 track_id ,
5059+ u32 * error_offset , u32 * error_info ,
5060+ struct i40e_asq_cmd_details * cmd_details )
5061+ {
5062+ struct i40e_aq_desc desc ;
5063+ struct i40e_aqc_write_personalization_profile * cmd =
5064+ (struct i40e_aqc_write_personalization_profile * )
5065+ & desc .params .raw ;
5066+ struct i40e_aqc_write_ppp_resp * resp ;
5067+ i40e_status status ;
5068+
5069+ i40e_fill_default_direct_cmd_desc (& desc ,
5070+ i40e_aqc_opc_write_personalization_profile );
5071+
5072+ desc .flags |= cpu_to_le16 (I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD );
5073+ if (buff_size > I40E_AQ_LARGE_BUF )
5074+ desc .flags |= cpu_to_le16 ((u16 )I40E_AQ_FLAG_LB );
5075+
5076+ desc .datalen = cpu_to_le16 (buff_size );
5077+
5078+ cmd -> profile_track_id = cpu_to_le32 (track_id );
5079+
5080+ status = i40e_asq_send_command (hw , & desc , buff , buff_size , cmd_details );
5081+ if (!status ) {
5082+ resp = (struct i40e_aqc_write_ppp_resp * )& desc .params .raw ;
5083+ if (error_offset )
5084+ * error_offset = le32_to_cpu (resp -> error_offset );
5085+ if (error_info )
5086+ * error_info = le32_to_cpu (resp -> error_info );
5087+ }
5088+
5089+ return status ;
5090+ }
5091+
5092+ /**
5093+ * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
5094+ * @hw: pointer to the hw struct
5095+ * @buff: command buffer (size in bytes = buff_size)
5096+ * @buff_size: buffer size in bytes
5097+ * @cmd_details: pointer to command details structure or NULL
5098+ **/
5099+ enum
5100+ i40e_status_code i40e_aq_get_ppp_list (struct i40e_hw * hw , void * buff ,
5101+ u16 buff_size , u8 flags ,
5102+ struct i40e_asq_cmd_details * cmd_details )
5103+ {
5104+ struct i40e_aq_desc desc ;
5105+ struct i40e_aqc_get_applied_profiles * cmd =
5106+ (struct i40e_aqc_get_applied_profiles * )& desc .params .raw ;
5107+ i40e_status status ;
5108+
5109+ i40e_fill_default_direct_cmd_desc (& desc ,
5110+ i40e_aqc_opc_get_personalization_profile_list );
5111+
5112+ desc .flags |= cpu_to_le16 ((u16 )I40E_AQ_FLAG_BUF );
5113+ if (buff_size > I40E_AQ_LARGE_BUF )
5114+ desc .flags |= cpu_to_le16 ((u16 )I40E_AQ_FLAG_LB );
5115+ desc .datalen = cpu_to_le16 (buff_size );
5116+
5117+ cmd -> flags = flags ;
5118+
5119+ status = i40e_asq_send_command (hw , & desc , buff , buff_size , cmd_details );
5120+
5121+ return status ;
5122+ }
5123+
5124+ /**
5125+ * i40e_find_segment_in_package
5126+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
5127+ * @pkg_hdr: pointer to the package header to be searched
5128+ *
5129+ * This function searches a package file for a particular segment type. On
5130+ * success it returns a pointer to the segment header, otherwise it will
5131+ * return NULL.
5132+ **/
5133+ struct i40e_generic_seg_header *
5134+ i40e_find_segment_in_package (u32 segment_type ,
5135+ struct i40e_package_header * pkg_hdr )
5136+ {
5137+ struct i40e_generic_seg_header * segment ;
5138+ u32 i ;
5139+
5140+ /* Search all package segments for the requested segment type */
5141+ for (i = 0 ; i < pkg_hdr -> segment_count ; i ++ ) {
5142+ segment =
5143+ (struct i40e_generic_seg_header * )((u8 * )pkg_hdr +
5144+ pkg_hdr -> segment_offset [i ]);
5145+
5146+ if (segment -> type == segment_type )
5147+ return segment ;
5148+ }
5149+
5150+ return NULL ;
5151+ }
5152+
5153+ /**
5154+ * i40e_write_profile
5155+ * @hw: pointer to the hardware structure
5156+ * @profile: pointer to the profile segment of the package to be downloaded
5157+ * @track_id: package tracking id
5158+ *
5159+ * Handles the download of a complete package.
5160+ */
5161+ enum i40e_status_code
5162+ i40e_write_profile (struct i40e_hw * hw , struct i40e_profile_segment * profile ,
5163+ u32 track_id )
5164+ {
5165+ i40e_status status = 0 ;
5166+ struct i40e_section_table * sec_tbl ;
5167+ struct i40e_profile_section_header * sec = NULL ;
5168+ u32 dev_cnt ;
5169+ u32 vendor_dev_id ;
5170+ u32 * nvm ;
5171+ u32 section_size = 0 ;
5172+ u32 offset = 0 , info = 0 ;
5173+ u32 i ;
5174+
5175+ if (!track_id ) {
5176+ i40e_debug (hw , I40E_DEBUG_PACKAGE , "Track_id can't be 0." );
5177+ return I40E_NOT_SUPPORTED ;
5178+ }
5179+
5180+ dev_cnt = profile -> device_table_count ;
5181+
5182+ for (i = 0 ; i < dev_cnt ; i ++ ) {
5183+ vendor_dev_id = profile -> device_table [i ].vendor_dev_id ;
5184+ if ((vendor_dev_id >> 16 ) == PCI_VENDOR_ID_INTEL )
5185+ if (hw -> device_id == (vendor_dev_id & 0xFFFF ))
5186+ break ;
5187+ }
5188+ if (i == dev_cnt ) {
5189+ i40e_debug (hw , I40E_DEBUG_PACKAGE , "Device doesn't support PPP" );
5190+ return I40E_ERR_DEVICE_NOT_SUPPORTED ;
5191+ }
5192+
5193+ nvm = (u32 * )& profile -> device_table [dev_cnt ];
5194+ sec_tbl = (struct i40e_section_table * )& nvm [nvm [0 ] + 1 ];
5195+
5196+ for (i = 0 ; i < sec_tbl -> section_count ; i ++ ) {
5197+ sec = (struct i40e_profile_section_header * )((u8 * )profile +
5198+ sec_tbl -> section_offset [i ]);
5199+
5200+ /* Skip 'AQ', 'note' and 'name' sections */
5201+ if (sec -> section .type != SECTION_TYPE_MMIO )
5202+ continue ;
5203+
5204+ section_size = sec -> section .size +
5205+ sizeof (struct i40e_profile_section_header );
5206+
5207+ /* Write profile */
5208+ status = i40e_aq_write_ppp (hw , (void * )sec , (u16 )section_size ,
5209+ track_id , & offset , & info , NULL );
5210+ if (status ) {
5211+ i40e_debug (hw , I40E_DEBUG_PACKAGE ,
5212+ "Failed to write profile: offset %d, info %d" ,
5213+ offset , info );
5214+ break ;
5215+ }
5216+ }
5217+ return status ;
5218+ }
5219+
5220+ /**
5221+ * i40e_add_pinfo_to_list
5222+ * @hw: pointer to the hardware structure
5223+ * @profile: pointer to the profile segment of the package
5224+ * @profile_info_sec: buffer for information section
5225+ * @track_id: package tracking id
5226+ *
5227+ * Register a profile to the list of loaded profiles.
5228+ */
5229+ enum i40e_status_code
5230+ i40e_add_pinfo_to_list (struct i40e_hw * hw ,
5231+ struct i40e_profile_segment * profile ,
5232+ u8 * profile_info_sec , u32 track_id )
5233+ {
5234+ i40e_status status = 0 ;
5235+ struct i40e_profile_section_header * sec = NULL ;
5236+ struct i40e_profile_info * pinfo ;
5237+ u32 offset = 0 , info = 0 ;
5238+
5239+ sec = (struct i40e_profile_section_header * )profile_info_sec ;
5240+ sec -> tbl_size = 1 ;
5241+ sec -> data_end = sizeof (struct i40e_profile_section_header ) +
5242+ sizeof (struct i40e_profile_info );
5243+ sec -> section .type = SECTION_TYPE_INFO ;
5244+ sec -> section .offset = sizeof (struct i40e_profile_section_header );
5245+ sec -> section .size = sizeof (struct i40e_profile_info );
5246+ pinfo = (struct i40e_profile_info * )(profile_info_sec +
5247+ sec -> section .offset );
5248+ pinfo -> track_id = track_id ;
5249+ pinfo -> version = profile -> version ;
5250+ pinfo -> op = I40E_PPP_ADD_TRACKID ;
5251+ memcpy (pinfo -> name , profile -> name , I40E_PPP_NAME_SIZE );
5252+
5253+ status = i40e_aq_write_ppp (hw , (void * )sec , sec -> data_end ,
5254+ track_id , & offset , & info , NULL );
5255+ return status ;
5256+ }
0 commit comments