src/dpdk/drivers/net/ice/base/ice_acl_ctrl.c
enum ice_status
ice_acl_add_entry(struct ice_hw *hw, struct ice_acl_scen *scen,
		  enum ice_acl_entry_prio prio, u8 *keys, u8 *inverts,
		  struct ice_acl_act_entry *acts, u8 acts_cnt, u16 *entry_idx)
{
	u8 i, entry_tcam, num_cscd, offset;
	struct ice_aqc_acl_data buf;
	enum ice_status status = ICE_SUCCESS;
	u16 idx;

	if (!scen)
		return ICE_ERR_DOES_NOT_EXIST;

	*entry_idx = ice_acl_scen_assign_entry_idx(scen, prio);
	if (*entry_idx >= scen->num_entry) {
		*entry_idx = 0;
		return ICE_ERR_MAX_LIMIT;
	}

	/* Determine number of cascaded TCAMs */
	num_cscd = DIVIDE_AND_ROUND_UP(scen->width,
				       ICE_AQC_ACL_KEY_WIDTH_BYTES);

	entry_tcam = ICE_ACL_TBL_TCAM_IDX(scen->start);
	idx = ICE_ACL_TBL_TCAM_ENTRY_IDX(scen->start + *entry_idx);

	ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
	for (i = 0; i < num_cscd; i++) {
		/* If the key spans more than one TCAM in the case of cascaded
		 * TCAMs, the key and key inverts need to be properly split
		 * among TCAMs.E.g.bytes 0 - 4 go to an index in the first TCAM
		 * and bytes 5 - 9 go to the same index in the next TCAM, etc.
		 * If the entry spans more than one TCAM in a cascaded TCAM
		 * mode, the programming of the entries in the TCAMs must be in
		 * reversed order - the TCAM entry of the rightmost TCAM should
		 * be programmed first; the TCAM entry of the leftmost TCAM
		 * should be programmed last.
		 */
		offset = num_cscd - i - 1;
		ice_memcpy(&buf.entry_key.val,
			   &keys[offset * sizeof(buf.entry_key.val)],
			   sizeof(buf.entry_key.val), ICE_NONDMA_TO_NONDMA);
		ice_memcpy(&buf.entry_key_invert.val,
			   &inverts[offset * sizeof(buf.entry_key_invert.val)],
			   sizeof(buf.entry_key_invert.val),
			   ICE_NONDMA_TO_NONDMA);
		status = ice_aq_program_acl_entry(hw, entry_tcam + offset, idx,
						  &buf, NULL);
		if (status) {
			ice_debug(hw, ICE_DBG_ACL, "aq program acl entry failed status: %d\n",
				  status);
			goto out;
		}
	}

	/* Program the action memory */
	status = ice_acl_prog_act(hw, scen, acts, acts_cnt, *entry_idx);

out:
	if (status) {
		ice_acl_rem_entry(hw, scen, *entry_idx);
		*entry_idx = 0;
	}

	return status;
}
/**
 * ice_acl_add_entry - Add a flow entry to an ACL scenario
 * @hw: pointer to the HW struct
 * @scen: scenario to add the entry to
 * @prio: priority level of the entry being added
 * @keys: buffer of the value of the key to be programmed to the ACL entry
 * @inverts: buffer of the value of the key inverts to be programmed
 * @acts: pointer to a buffer containing formatted actions
 * @acts_cnt: indicates the number of actions stored in "acts"
 * @entry_idx: returned scenario relative index of the added flow entry
 *
 * Given an ACL table and a scenario, to add the specified key and key invert
 * to an available entry in the specified scenario.
 * The "keys" and "inverts" buffers must be of the size which is the same as
 * the scenario's width
 */


Given an ACL table and a scenario, to add the specified key and key invert
to an available entry in the specified scenario.
The "keys" and "inverts" buffers must be of the size which is the same as
the scenario's width
Given an ACL table and a scenario to add the specified key and key invert to an available entry in the specified scenario . The " keys " and " inverts " buffers must be of the size which is the same as the scenario ' s width
enum ice_status
ice_acl_add_entry(struct ice_hw *hw, struct ice_acl_scen *scen,
		  enum ice_acl_entry_prio prio, u8 *keys, u8 *inverts,
		  struct ice_acl_act_entry *acts, u8 acts_cnt, u16 *entry_idx)
{
	u8 i, entry_tcam, num_cscd, offset;
	struct ice_aqc_acl_data buf;
	enum ice_status status = ICE_SUCCESS;
	u16 idx;
	if (!scen)
		return ICE_ERR_DOES_NOT_EXIST;
	*entry_idx = ice_acl_scen_assign_entry_idx(scen, prio);
	if (*entry_idx >= scen->num_entry) {
		*entry_idx = 0;
		return ICE_ERR_MAX_LIMIT;
	}
	num_cscd = DIVIDE_AND_ROUND_UP(scen->width,
				       ICE_AQC_ACL_KEY_WIDTH_BYTES);
	entry_tcam = ICE_ACL_TBL_TCAM_IDX(scen->start);
	idx = ICE_ACL_TBL_TCAM_ENTRY_IDX(scen->start + *entry_idx);
	ice_memset(&buf, 0, sizeof(buf), ICE_NONDMA_MEM);
	for (i = 0; i < num_cscd; i++) {
		offset = num_cscd - i - 1;
		ice_memcpy(&buf.entry_key.val,
			   &keys[offset * sizeof(buf.entry_key.val)],
			   sizeof(buf.entry_key.val), ICE_NONDMA_TO_NONDMA);
		ice_memcpy(&buf.entry_key_invert.val,
			   &inverts[offset * sizeof(buf.entry_key_invert.val)],
			   sizeof(buf.entry_key_invert.val),
			   ICE_NONDMA_TO_NONDMA);
		status = ice_aq_program_acl_entry(hw, entry_tcam + offset, idx,
						  &buf, NULL);
		if (status) {
			ice_debug(hw, ICE_DBG_ACL, "aq program acl entry failed status: %d\n",
				  status);
			goto out;
		}
	}
	status = ice_acl_prog_act(hw, scen, acts, acts_cnt, *entry_idx);
out:
	if (status) {
		ice_acl_rem_entry(hw, scen, *entry_idx);
		*entry_idx = 0;
	}
	return status;
}
enum ice_status ice_acl_add_entry ( struct ice_hw * hw , struct ice_acl_scen * scen , enum ice_acl_entry_prio prio , u8 * keys , u8 * inverts , struct ice_acl_act_entry * acts , u8 acts_cnt , u16 * entry_idx ) { u8 i , entry_tcam , num_cscd , offset ; struct ice_aqc_acl_data buf ; enum ice_status status = ICE_SUCCESS ; u16 idx ; if ( ! scen ) return ICE_ERR_DOES_NOT_EXIST ; * entry_idx = ice_acl_scen_assign_entry_idx ( scen , prio ) ; if ( * entry_idx >= scen -> num_entry ) { * entry_idx = 0 ; return ICE_ERR_MAX_LIMIT ; } num_cscd = DIVIDE_AND_ROUND_UP ( scen -> width , ICE_AQC_ACL_KEY_WIDTH_BYTES ) ; entry_tcam = ICE_ACL_TBL_TCAM_IDX ( scen -> start ) ; idx = ICE_ACL_TBL_TCAM_ENTRY_IDX ( scen -> start + * entry_idx ) ; ice_memset ( & buf , 0 , sizeof ( buf ) , ICE_NONDMA_MEM ) ; for ( i = 0 ; i < num_cscd ; i ++ ) { offset = num_cscd - i - 1 ; ice_memcpy ( & buf . entry_key . val , & keys [ offset * sizeof ( buf . entry_key . val ) ] , sizeof ( buf . entry_key . val ) , ICE_NONDMA_TO_NONDMA ) ; ice_memcpy ( & buf . entry_key_invert . val , & inverts [ offset * sizeof ( buf . entry_key_invert . val ) ] , sizeof ( buf . entry_key_invert . val ) , ICE_NONDMA_TO_NONDMA ) ; status = ice_aq_program_acl_entry ( hw , entry_tcam + offset , idx , & buf , NULL ) ; if ( status ) { ice_debug ( hw , ICE_DBG_ACL , " \n " , status ) ; goto out ; } } status = ice_acl_prog_act ( hw , scen , acts , acts_cnt , * entry_idx ) ; out : if ( status ) { ice_acl_rem_entry ( hw , scen , * entry_idx ) ; * entry_idx = 0 ; } return status ; }
ice_acl_add_entry - Add a flow entry to an ACL scenario
 @hw: pointer to the HW struct
 @scen: scenario to add the entry to
 @prio: priority level of the entry being added
 @keys: buffer of the value of the key to be programmed to the ACL entry
 @inverts: buffer of the value of the key inverts to be programmed
 @acts: pointer to a buffer containing formatted actions
 @acts_cnt: indicates the number of actions stored in "acts"
 @entry_idx: returned scenario relative index of the added flow entry
ice_acl_add_entry - Add a flow entry to an ACL scenario @hw : pointer to the HW struct @scen : scenario to add the entry to @prio : priority level of the entry being added @keys : buffer of the value of the key to be programmed to the ACL entry @inverts : buffer of the value of the key inverts to be programmed @acts : pointer to a buffer containing formatted actions @acts_cnt : indicates the number of actions stored in " acts " @entry_idx : returned scenario relative index of the added flow entry
/* Determine number of cascaded TCAMs */ /* If the key spans more than one TCAM in the case of cascaded
		 * TCAMs, the key and key inverts need to be properly split
		 * among TCAMs.E.g.bytes 0 - 4 go to an index in the first TCAM
		 * and bytes 5 - 9 go to the same index in the next TCAM, etc.
		 * If the entry spans more than one TCAM in a cascaded TCAM
		 * mode, the programming of the entries in the TCAMs must be in
		 * reversed order - the TCAM entry of the rightmost TCAM should
		 * be programmed first; the TCAM entry of the leftmost TCAM
		 * should be programmed last.
		 */ /* Program the action memory */