src/dpdk/drivers/net/ice/base/ice_acl_ctrl.c
enum ice_status
ice_acl_create_scen(struct ice_hw *hw, u16 match_width, u16 num_entries,
		    u16 *scen_id)
{
	u8 cascade_cnt, first_tcam, last_tcam, i, k;
	struct ice_aqc_acl_scen scen_buf;
	struct ice_acl_scen *scen;
	enum ice_status status;

	if (!hw->acl_tbl)
		return ICE_ERR_DOES_NOT_EXIST;

	scen = (struct ice_acl_scen *)ice_malloc(hw, sizeof(*scen));
	if (!scen)
		return ICE_ERR_NO_MEMORY;

	scen->start = hw->acl_tbl->first_entry;
	scen->width = ICE_AQC_ACL_KEY_WIDTH_BYTES *
		DIVIDE_AND_ROUND_UP(match_width, ICE_AQC_ACL_KEY_WIDTH_BYTES);
	scen->num_entry = num_entries;

	status = ice_acl_alloc_partition(hw, scen);
	if (status)
		goto out;

	ice_memset(&scen_buf, 0, sizeof(scen_buf), ICE_NONDMA_MEM);

	/* Determine the number of cascade TCAMs, given the scenario's width */
	cascade_cnt = DIVIDE_AND_ROUND_UP(scen->width,
					  ICE_AQC_ACL_KEY_WIDTH_BYTES);
	first_tcam = ICE_ACL_TBL_TCAM_IDX(scen->start);
	last_tcam = ICE_ACL_TBL_TCAM_IDX(scen->end);

	/* For each scenario, we reserved last three bytes of scenario width for
	 * packet direction flag, profile ID and range checker. Thus, we want to
	 * return back to the caller the eff_width, pkt_dir_idx, rng_chk_idx and
	 * pid_idx.
	 */
	scen->eff_width = cascade_cnt * ICE_AQC_ACL_KEY_WIDTH_BYTES -
		ICE_ACL_SCEN_MIN_WIDTH;
	scen->rng_chk_idx = (cascade_cnt - 1) * ICE_AQC_ACL_KEY_WIDTH_BYTES +
		ICE_ACL_SCEN_RNG_CHK_IDX_IN_TCAM;
	scen->pid_idx = (cascade_cnt - 1) * ICE_AQC_ACL_KEY_WIDTH_BYTES +
		ICE_ACL_SCEN_PID_IDX_IN_TCAM;
	scen->pkt_dir_idx = (cascade_cnt - 1) * ICE_AQC_ACL_KEY_WIDTH_BYTES +
		ICE_ACL_SCEN_PKT_DIR_IDX_IN_TCAM;

	/* set the chunk mask for the tcams */
	ice_acl_set_scen_chnk_msk(&scen_buf, scen);

	/* set the TCAM select and start_cmp and start_set bits */
	k = first_tcam;
	/* set the START_SET bit at the beginning of the stack */
	scen_buf.tcam_cfg[k].start_cmp_set |= ICE_AQC_ACL_ALLOC_SCE_START_SET;
	while (k <= last_tcam) {
		u8 last_tcam_idx_cascade = cascade_cnt + k - 1;

		/* set start_cmp for the first cascaded TCAM */
		scen_buf.tcam_cfg[k].start_cmp_set |=
			ICE_AQC_ACL_ALLOC_SCE_START_CMP;

		/* cascade TCAMs up to the width of the scenario */
		for (i = k; i < cascade_cnt + k; i++) {
			ice_acl_fill_tcam_select(&scen_buf, scen, i, i - k);
			ice_acl_assign_act_mem_for_scen(hw->acl_tbl, scen,
							&scen_buf,
							i,
							last_tcam_idx_cascade);
		}

		k = i;
	}

	/* We need to set the start_cmp bit for the unused TCAMs. */
	i = 0;
	while (i < first_tcam)
		scen_buf.tcam_cfg[i++].start_cmp_set =
					ICE_AQC_ACL_ALLOC_SCE_START_CMP;

	i = last_tcam + 1;
	while (i < ICE_AQC_ACL_SLICES)
		scen_buf.tcam_cfg[i++].start_cmp_set =
					ICE_AQC_ACL_ALLOC_SCE_START_CMP;

	status = ice_aq_alloc_acl_scen(hw, scen_id, &scen_buf, NULL);
	if (status) {
		ice_debug(hw, ICE_DBG_ACL, "AQ allocation of ACL scenario failed. status: %d\n",
			  status);
		goto out;
	}

	scen->id = *scen_id;
	ice_acl_commit_partition(hw, scen, false);
	ice_acl_init_entry(scen);
	LIST_ADD(&scen->list_entry, &hw->acl_tbl->scens);

out:
	if (status)
		ice_free(hw, scen);

	return status;
}
/**
 * ice_acl_create_scen
 * @hw: pointer to the hardware structure
 * @match_width: number of bytes to be matched in this scenario
 * @num_entries: number of entries to be allocated for the scenario
 * @scen_id: holds returned scenario ID if successful
 */
ice_acl_create_scen
@hw: pointer to the hardware structure
@match_width: number of bytes to be matched in this scenario
@num_entries: number of entries to be allocated for the scenario
@scen_id: holds returned scenario ID if successful
ice_acl_create_scen @hw : pointer to the hardware structure @match_width : number of bytes to be matched in this scenario @num_entries : number of entries to be allocated for the scenario @scen_id : holds returned scenario ID if successful
enum ice_status
ice_acl_create_scen(struct ice_hw *hw, u16 match_width, u16 num_entries,
		    u16 *scen_id)
{
	u8 cascade_cnt, first_tcam, last_tcam, i, k;
	struct ice_aqc_acl_scen scen_buf;
	struct ice_acl_scen *scen;
	enum ice_status status;
	if (!hw->acl_tbl)
		return ICE_ERR_DOES_NOT_EXIST;
	scen = (struct ice_acl_scen *)ice_malloc(hw, sizeof(*scen));
	if (!scen)
		return ICE_ERR_NO_MEMORY;
	scen->start = hw->acl_tbl->first_entry;
	scen->width = ICE_AQC_ACL_KEY_WIDTH_BYTES *
		DIVIDE_AND_ROUND_UP(match_width, ICE_AQC_ACL_KEY_WIDTH_BYTES);
	scen->num_entry = num_entries;
	status = ice_acl_alloc_partition(hw, scen);
	if (status)
		goto out;
	ice_memset(&scen_buf, 0, sizeof(scen_buf), ICE_NONDMA_MEM);
	cascade_cnt = DIVIDE_AND_ROUND_UP(scen->width,
					  ICE_AQC_ACL_KEY_WIDTH_BYTES);
	first_tcam = ICE_ACL_TBL_TCAM_IDX(scen->start);
	last_tcam = ICE_ACL_TBL_TCAM_IDX(scen->end);
	scen->eff_width = cascade_cnt * ICE_AQC_ACL_KEY_WIDTH_BYTES -
		ICE_ACL_SCEN_MIN_WIDTH;
	scen->rng_chk_idx = (cascade_cnt - 1) * ICE_AQC_ACL_KEY_WIDTH_BYTES +
		ICE_ACL_SCEN_RNG_CHK_IDX_IN_TCAM;
	scen->pid_idx = (cascade_cnt - 1) * ICE_AQC_ACL_KEY_WIDTH_BYTES +
		ICE_ACL_SCEN_PID_IDX_IN_TCAM;
	scen->pkt_dir_idx = (cascade_cnt - 1) * ICE_AQC_ACL_KEY_WIDTH_BYTES +
		ICE_ACL_SCEN_PKT_DIR_IDX_IN_TCAM;
	ice_acl_set_scen_chnk_msk(&scen_buf, scen);
	k = first_tcam;
	scen_buf.tcam_cfg[k].start_cmp_set |= ICE_AQC_ACL_ALLOC_SCE_START_SET;
	while (k <= last_tcam) {
		u8 last_tcam_idx_cascade = cascade_cnt + k - 1;
		scen_buf.tcam_cfg[k].start_cmp_set |=
			ICE_AQC_ACL_ALLOC_SCE_START_CMP;
		for (i = k; i < cascade_cnt + k; i++) {
			ice_acl_fill_tcam_select(&scen_buf, scen, i, i - k);
			ice_acl_assign_act_mem_for_scen(hw->acl_tbl, scen,
							&scen_buf,
							i,
							last_tcam_idx_cascade);
		}
		k = i;
	}
	i = 0;
	while (i < first_tcam)
		scen_buf.tcam_cfg[i++].start_cmp_set =
					ICE_AQC_ACL_ALLOC_SCE_START_CMP;
	i = last_tcam + 1;
	while (i < ICE_AQC_ACL_SLICES)
		scen_buf.tcam_cfg[i++].start_cmp_set =
					ICE_AQC_ACL_ALLOC_SCE_START_CMP;
	status = ice_aq_alloc_acl_scen(hw, scen_id, &scen_buf, NULL);
	if (status) {
		ice_debug(hw, ICE_DBG_ACL, "AQ allocation of ACL scenario failed. status: %d\n",
			  status);
		goto out;
	}
	scen->id = *scen_id;
	ice_acl_commit_partition(hw, scen, false);
	ice_acl_init_entry(scen);
	LIST_ADD(&scen->list_entry, &hw->acl_tbl->scens);
out:
	if (status)
		ice_free(hw, scen);
	return status;
}
enum ice_status ice_acl_create_scen ( struct ice_hw * hw , u16 match_width , u16 num_entries , u16 * scen_id ) { u8 cascade_cnt , first_tcam , last_tcam , i , k ; struct ice_aqc_acl_scen scen_buf ; struct ice_acl_scen * scen ; enum ice_status status ; if ( ! hw -> acl_tbl ) return ICE_ERR_DOES_NOT_EXIST ; scen = ( struct ice_acl_scen * ) ice_malloc ( hw , sizeof ( * scen ) ) ; if ( ! scen ) return ICE_ERR_NO_MEMORY ; scen -> start = hw -> acl_tbl -> first_entry ; scen -> width = ICE_AQC_ACL_KEY_WIDTH_BYTES * DIVIDE_AND_ROUND_UP ( match_width , ICE_AQC_ACL_KEY_WIDTH_BYTES ) ; scen -> num_entry = num_entries ; status = ice_acl_alloc_partition ( hw , scen ) ; if ( status ) goto out ; ice_memset ( & scen_buf , 0 , sizeof ( scen_buf ) , ICE_NONDMA_MEM ) ; cascade_cnt = DIVIDE_AND_ROUND_UP ( scen -> width , ICE_AQC_ACL_KEY_WIDTH_BYTES ) ; first_tcam = ICE_ACL_TBL_TCAM_IDX ( scen -> start ) ; last_tcam = ICE_ACL_TBL_TCAM_IDX ( scen -> end ) ; scen -> eff_width = cascade_cnt * ICE_AQC_ACL_KEY_WIDTH_BYTES - ICE_ACL_SCEN_MIN_WIDTH ; scen -> rng_chk_idx = ( cascade_cnt - 1 ) * ICE_AQC_ACL_KEY_WIDTH_BYTES + ICE_ACL_SCEN_RNG_CHK_IDX_IN_TCAM ; scen -> pid_idx = ( cascade_cnt - 1 ) * ICE_AQC_ACL_KEY_WIDTH_BYTES + ICE_ACL_SCEN_PID_IDX_IN_TCAM ; scen -> pkt_dir_idx = ( cascade_cnt - 1 ) * ICE_AQC_ACL_KEY_WIDTH_BYTES + ICE_ACL_SCEN_PKT_DIR_IDX_IN_TCAM ; ice_acl_set_scen_chnk_msk ( & scen_buf , scen ) ; k = first_tcam ; scen_buf . tcam_cfg [ k ] . start_cmp_set |= ICE_AQC_ACL_ALLOC_SCE_START_SET ; while ( k <= last_tcam ) { u8 last_tcam_idx_cascade = cascade_cnt + k - 1 ; scen_buf . tcam_cfg [ k ] . start_cmp_set |= ICE_AQC_ACL_ALLOC_SCE_START_CMP ; for ( i = k ; i < cascade_cnt + k ; i ++ ) { ice_acl_fill_tcam_select ( & scen_buf , scen , i , i - k ) ; ice_acl_assign_act_mem_for_scen ( hw -> acl_tbl , scen , & scen_buf , i , last_tcam_idx_cascade ) ; } k = i ; } i = 0 ; while ( i < first_tcam ) scen_buf . tcam_cfg [ i ++ ] . start_cmp_set = ICE_AQC_ACL_ALLOC_SCE_START_CMP ; i = last_tcam + 1 ; while ( i < ICE_AQC_ACL_SLICES ) scen_buf . tcam_cfg [ i ++ ] . start_cmp_set = ICE_AQC_ACL_ALLOC_SCE_START_CMP ; status = ice_aq_alloc_acl_scen ( hw , scen_id , & scen_buf , NULL ) ; if ( status ) { ice_debug ( hw , ICE_DBG_ACL , " \n " , status ) ; goto out ; } scen -> id = * scen_id ; ice_acl_commit_partition ( hw , scen , false ) ; ice_acl_init_entry ( scen ) ; LIST_ADD ( & scen -> list_entry , & hw -> acl_tbl -> scens ) ; out : if ( status ) ice_free ( hw , scen ) ; return status ; }
ice_acl_create_scen
 @hw: pointer to the hardware structure
 @match_width: number of bytes to be matched in this scenario
 @num_entries: number of entries to be allocated for the scenario
 @scen_id: holds returned scenario ID if successful
ice_acl_create_scen @hw : pointer to the hardware structure @match_width : number of bytes to be matched in this scenario @num_entries : number of entries to be allocated for the scenario @scen_id : holds returned scenario ID if successful
/* Determine the number of cascade TCAMs, given the scenario's width */ /* For each scenario, we reserved last three bytes of scenario width for
	 * packet direction flag, profile ID and range checker. Thus, we want to
	 * return back to the caller the eff_width, pkt_dir_idx, rng_chk_idx and
	 * pid_idx.
	 */ /* set the chunk mask for the tcams */ /* set the TCAM select and start_cmp and start_set bits */ /* set the START_SET bit at the beginning of the stack */ /* set start_cmp for the first cascaded TCAM */ /* cascade TCAMs up to the width of the scenario */ /* We need to set the start_cmp bit for the unused TCAMs. */