static int i40e_set_channels(struct net_device *dev,
                              struct ethtool_channels *ch)
 {
+       const u8 drop = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
        struct i40e_netdev_priv *np = netdev_priv(dev);
        unsigned int count = ch->combined_count;
        struct i40e_vsi *vsi = np->vsi;
        struct i40e_pf *pf = vsi->back;
+       struct i40e_fdir_filter *rule;
+       struct hlist_node *node2;
        int new_count;
+       int err = 0;
 
        /* We do not support setting channels for any other VSI at present */
        if (vsi->type != I40E_VSI_MAIN)
        if (count > i40e_max_channels(vsi))
                return -EINVAL;
 
+       /* verify that the number of channels does not invalidate any current
+        * flow director rules
+        */
+       hlist_for_each_entry_safe(rule, node2,
+                                 &pf->fdir_filter_list, fdir_node) {
+               if (rule->dest_ctl != drop && count <= rule->q_index) {
+                       dev_warn(&pf->pdev->dev,
+                                "Existing user defined filter %d assigns flow to queue %d\n",
+                                rule->fd_id, rule->q_index);
+                       err = -EINVAL;
+               }
+       }
+
+       if (err) {
+               dev_err(&pf->pdev->dev,
+                       "Existing filter rules must be deleted to reduce combined channel count to %d\n",
+                       count);
+               return err;
+       }
+
        /* update feature limits from largest to smallest supported values */
        /* TODO: Flow director limit, DCB etc */