@@ -3577,6 +3577,19 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig,
35773577 return 0 ;
35783578}
35793579
3580+ /**
3581+ * ice_set_tcam_flags - set TCAM flag don't care mask
3582+ * @mask: mask for flags
3583+ * @dc_mask: pointer to the don't care mask
3584+ */
3585+ static void ice_set_tcam_flags (u16 mask , u8 dc_mask [ICE_TCAM_KEY_VAL_SZ ])
3586+ {
3587+ u16 inverted_mask = ~mask ;
3588+
3589+ /* flags are lowest u16 */
3590+ put_unaligned_le16 (inverted_mask , dc_mask );
3591+ }
3592+
35803593/**
35813594 * ice_rem_chg_tcam_ent - remove a specific TCAM entry from change list
35823595 * @hw: pointer to the HW struct
@@ -3647,6 +3660,9 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
36473660 if (!p )
36483661 return - ENOMEM ;
36493662
3663+ /* set don't care masks for TCAM flags */
3664+ ice_set_tcam_flags (tcam -> attr .mask , dc_msk );
3665+
36503666 status = ice_tcam_write_entry (hw , blk , tcam -> tcam_idx , tcam -> prof_id ,
36513667 tcam -> ptg , vsig , 0 , tcam -> attr .flags ,
36523668 vl_msk , dc_msk , nm_msk );
@@ -3672,6 +3688,34 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
36723688 return status ;
36733689}
36743690
3691+ /**
3692+ * ice_ptg_attr_in_use - determine if PTG and attribute pair is in use
3693+ * @ptg_attr: pointer to the PTG and attribute pair to check
3694+ * @ptgs_used: bitmap that denotes which PTGs are in use
3695+ * @attr_used: array of PTG and attributes pairs already used
3696+ * @attr_cnt: count of entries in the attr_used array
3697+ *
3698+ * Return: true if the PTG and attribute pair is in use, false otherwise.
3699+ */
3700+ static bool
3701+ ice_ptg_attr_in_use (struct ice_tcam_inf * ptg_attr , unsigned long * ptgs_used ,
3702+ struct ice_tcam_inf * attr_used [], u16 attr_cnt )
3703+ {
3704+ u16 i ;
3705+
3706+ if (!test_bit (ptg_attr -> ptg , ptgs_used ))
3707+ return false;
3708+
3709+ /* the PTG is used, so now look for correct attributes */
3710+ for (i = 0 ; i < attr_cnt ; i ++ )
3711+ if (attr_used [i ]-> ptg == ptg_attr -> ptg &&
3712+ attr_used [i ]-> attr .flags == ptg_attr -> attr .flags &&
3713+ attr_used [i ]-> attr .mask == ptg_attr -> attr .mask )
3714+ return true;
3715+
3716+ return false;
3717+ }
3718+
36753719/**
36763720 * ice_adj_prof_priorities - adjust profile based on priorities
36773721 * @hw: pointer to the HW struct
@@ -3684,10 +3728,16 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
36843728 struct list_head * chg )
36853729{
36863730 DECLARE_BITMAP (ptgs_used , ICE_XLT1_CNT );
3731+ struct ice_tcam_inf * * attr_used ;
36873732 struct ice_vsig_prof * t ;
3688- int status ;
3733+ u16 attr_used_cnt = 0 ;
3734+ int status = 0 ;
36893735 u16 idx ;
36903736
3737+ attr_used = kcalloc (ICE_MAX_PTG_ATTRS , sizeof (* attr_used ), GFP_KERNEL );
3738+ if (!attr_used )
3739+ return - ENOMEM ;
3740+
36913741 bitmap_zero (ptgs_used , ICE_XLT1_CNT );
36923742 idx = vsig & ICE_VSIG_IDX_M ;
36933743
@@ -3705,11 +3755,15 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
37053755 u16 i ;
37063756
37073757 for (i = 0 ; i < t -> tcam_count ; i ++ ) {
3758+ bool used ;
3759+
37083760 /* Scan the priorities from newest to oldest.
37093761 * Make sure that the newest profiles take priority.
37103762 */
3711- if (test_bit (t -> tcam [i ].ptg , ptgs_used ) &&
3712- t -> tcam [i ].in_use ) {
3763+ used = ice_ptg_attr_in_use (& t -> tcam [i ], ptgs_used ,
3764+ attr_used , attr_used_cnt );
3765+
3766+ if (used && t -> tcam [i ].in_use ) {
37133767 /* need to mark this PTG as never match, as it
37143768 * was already in use and therefore duplicate
37153769 * (and lower priority)
@@ -3719,9 +3773,8 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
37193773 & t -> tcam [i ],
37203774 chg );
37213775 if (status )
3722- return status ;
3723- } else if (!test_bit (t -> tcam [i ].ptg , ptgs_used ) &&
3724- !t -> tcam [i ].in_use ) {
3776+ goto free_attr_used ;
3777+ } else if (!used && !t -> tcam [i ].in_use ) {
37253778 /* need to enable this PTG, as it in not in use
37263779 * and not enabled (highest priority)
37273780 */
@@ -3730,15 +3783,21 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
37303783 & t -> tcam [i ],
37313784 chg );
37323785 if (status )
3733- return status ;
3786+ goto free_attr_used ;
37343787 }
37353788
37363789 /* keep track of used ptgs */
3737- __set_bit (t -> tcam [i ].ptg , ptgs_used );
3790+ set_bit (t -> tcam [i ].ptg , ptgs_used );
3791+ if (attr_used_cnt < ICE_MAX_PTG_ATTRS )
3792+ attr_used [attr_used_cnt ++ ] = & t -> tcam [i ];
3793+ else
3794+ ice_debug (hw , ICE_DBG_INIT , "Warn: ICE_MAX_PTG_ATTRS exceeded\n" );
37383795 }
37393796 }
37403797
3741- return 0 ;
3798+ free_attr_used :
3799+ kfree (attr_used );
3800+ return status ;
37423801}
37433802
37443803/**
@@ -3821,11 +3880,15 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
38213880 p -> vsig = vsig ;
38223881 p -> tcam_idx = t -> tcam [i ].tcam_idx ;
38233882
3883+ /* set don't care masks for TCAM flags */
3884+ ice_set_tcam_flags (t -> tcam [i ].attr .mask , dc_msk );
3885+
38243886 /* write the TCAM entry */
38253887 status = ice_tcam_write_entry (hw , blk , t -> tcam [i ].tcam_idx ,
38263888 t -> tcam [i ].prof_id ,
3827- t -> tcam [i ].ptg , vsig , 0 , 0 ,
3828- vl_msk , dc_msk , nm_msk );
3889+ t -> tcam [i ].ptg , vsig , 0 ,
3890+ t -> tcam [i ].attr .flags , vl_msk ,
3891+ dc_msk , nm_msk );
38293892 if (status ) {
38303893 devm_kfree (ice_hw_to_dev (hw ), p );
38313894 goto err_ice_add_prof_id_vsig ;
@@ -4139,9 +4202,6 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
41394202 u16 vsi_num ;
41404203 int status ;
41414204
4142- if (blk != ICE_BLK_FD )
4143- return - EINVAL ;
4144-
41454205 vsi_num = ice_get_hw_vsi_num (hw , dest_vsi );
41464206 status = ice_add_prof_id_flow (hw , blk , vsi_num , hdl );
41474207 if (status ) {
@@ -4150,6 +4210,9 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
41504210 return status ;
41514211 }
41524212
4213+ if (blk != ICE_BLK_FD )
4214+ return 0 ;
4215+
41534216 vsi_num = ice_get_hw_vsi_num (hw , fdir_vsi );
41544217 status = ice_add_prof_id_flow (hw , blk , vsi_num , hdl );
41554218 if (status ) {
0 commit comments