struct rhash_head ht_node;
        struct mlxsw_afa_set_ht_key ht_key;
        u32 kvdl_index;
-       bool shared; /* Inserted in hashtable (doesn't mean that
+       u8 shared:1, /* Inserted in hashtable (doesn't mean that
                      * kvdl_index is valid).
                      */
+          has_trap:1,
+          has_police:1;
        unsigned int ref_count;
        struct mlxsw_afa_set *next; /* Pointer to the next set. */
        struct mlxsw_afa_set *prev; /* Pointer to the previous set,
 #define MLXSW_AFA_ONE_ACTION_LEN 32
 #define MLXSW_AFA_PAYLOAD_OFFSET 4
 
-static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
-                                          u8 action_code, u8 action_size)
+enum mlxsw_afa_action_type {
+       MLXSW_AFA_ACTION_TYPE_TRAP,
+       MLXSW_AFA_ACTION_TYPE_POLICE,
+       MLXSW_AFA_ACTION_TYPE_OTHER,
+};
+
+static bool
+mlxsw_afa_block_need_split(const struct mlxsw_afa_block *block,
+                          enum mlxsw_afa_action_type type)
+{
+       struct mlxsw_afa_set *cur_set = block->cur_set;
+
+       /* Due to a hardware limitation, police action cannot be in the same
+        * action set with MLXSW_AFA_TRAP_CODE or MLXSW_AFA_TRAPWU_CODE
+        * actions. Work around this limitation by creating a new action set
+        * and place the new action there.
+        */
+       return (cur_set->has_trap && type == MLXSW_AFA_ACTION_TYPE_POLICE) ||
+              (cur_set->has_police && type == MLXSW_AFA_ACTION_TYPE_TRAP);
+}
+
+static char *mlxsw_afa_block_append_action_ext(struct mlxsw_afa_block *block,
+                                              u8 action_code, u8 action_size,
+                                              enum mlxsw_afa_action_type type)
 {
        char *oneact;
        char *actions;
 
        if (block->finished)
                return ERR_PTR(-EINVAL);
-       if (block->cur_act_index + action_size >
-           block->afa->max_acts_per_set) {
+       if (block->cur_act_index + action_size > block->afa->max_acts_per_set ||
+           mlxsw_afa_block_need_split(block, type)) {
                struct mlxsw_afa_set *set;
 
                /* The appended action won't fit into the current action set,
                block->cur_set = set;
        }
 
+       switch (type) {
+       case MLXSW_AFA_ACTION_TYPE_TRAP:
+               block->cur_set->has_trap = true;
+               break;
+       case MLXSW_AFA_ACTION_TYPE_POLICE:
+               block->cur_set->has_police = true;
+               break;
+       default:
+               break;
+       }
+
        actions = block->cur_set->ht_key.enc_actions;
        oneact = actions + block->cur_act_index * MLXSW_AFA_ONE_ACTION_LEN;
        block->cur_act_index += action_size;
        return oneact + MLXSW_AFA_PAYLOAD_OFFSET;
 }
 
+static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
+                                          u8 action_code, u8 action_size)
+{
+       return mlxsw_afa_block_append_action_ext(block, action_code,
+                                                action_size,
+                                                MLXSW_AFA_ACTION_TYPE_OTHER);
+}
+
 /* VLAN Action
  * -----------
  * VLAN action is used for manipulating VLANs. It can be used to implement QinQ,
        mlxsw_afa_trap_mirror_agent_set(payload, mirror_agent);
 }
 
+static char *mlxsw_afa_block_append_action_trap(struct mlxsw_afa_block *block,
+                                               u8 action_code, u8 action_size)
+{
+       return mlxsw_afa_block_append_action_ext(block, action_code,
+                                                action_size,
+                                                MLXSW_AFA_ACTION_TYPE_TRAP);
+}
+
 static int mlxsw_afa_block_append_drop_plain(struct mlxsw_afa_block *block,
                                             bool ingress)
 {
-       char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
-                                                 MLXSW_AFA_TRAP_SIZE);
+       char *act = mlxsw_afa_block_append_action_trap(block,
+                                                      MLXSW_AFA_TRAP_CODE,
+                                                      MLXSW_AFA_TRAP_SIZE);
 
        if (IS_ERR(act))
                return PTR_ERR(act);
        }
        cookie_index = cookie_ref->cookie->cookie_index;
 
-       act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAPWU_CODE,
-                                           MLXSW_AFA_TRAPWU_SIZE);
+       act = mlxsw_afa_block_append_action_trap(block, MLXSW_AFA_TRAPWU_CODE,
+                                                MLXSW_AFA_TRAPWU_SIZE);
        if (IS_ERR(act)) {
                NL_SET_ERR_MSG_MOD(extack, "Cannot append drop with cookie action");
                err = PTR_ERR(act);
 
 int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id)
 {
-       char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
-                                                 MLXSW_AFA_TRAP_SIZE);
+       char *act = mlxsw_afa_block_append_action_trap(block,
+                                                      MLXSW_AFA_TRAP_CODE,
+                                                      MLXSW_AFA_TRAP_SIZE);
 
        if (IS_ERR(act))
                return PTR_ERR(act);
 int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
                                            u16 trap_id)
 {
-       char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
-                                                 MLXSW_AFA_TRAP_SIZE);
+       char *act = mlxsw_afa_block_append_action_trap(block,
+                                                      MLXSW_AFA_TRAP_CODE,
+                                                      MLXSW_AFA_TRAP_SIZE);
 
        if (IS_ERR(act))
                return PTR_ERR(act);
 mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
                                        u8 mirror_agent)
 {
-       char *act = mlxsw_afa_block_append_action(block,
-                                                 MLXSW_AFA_TRAP_CODE,
-                                                 MLXSW_AFA_TRAP_SIZE);
+       char *act = mlxsw_afa_block_append_action_trap(block,
+                                                      MLXSW_AFA_TRAP_CODE,
+                                                      MLXSW_AFA_TRAP_SIZE);
+
        if (IS_ERR(act))
                return PTR_ERR(act);
        mlxsw_afa_trap_pack(act, MLXSW_AFA_TRAP_TRAP_ACTION_NOP,