return 0;
 }
 
+/* Checks the validity of predefined bitrate settings */
+static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
+                               const u32 *bitrate_const,
+                               const unsigned int bitrate_const_cnt)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       unsigned int i;
+
+       for (i = 0; i < bitrate_const_cnt; i++) {
+               if (bt->bitrate == bitrate_const[i])
+                       break;
+       }
+
+       if (i >= priv->bitrate_const_cnt)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
-                            const struct can_bittiming_const *btc)
+                            const struct can_bittiming_const *btc,
+                            const u32 *bitrate_const,
+                            const unsigned int bitrate_const_cnt)
 {
        int err;
 
         * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
         * provided directly which are then checked and fixed up.
         */
-       if (!bt->tq && bt->bitrate)
+       if (!bt->tq && bt->bitrate && btc)
                err = can_calc_bittiming(dev, bt, btc);
-       else if (bt->tq && !bt->bitrate)
+       else if (bt->tq && !bt->bitrate && btc)
                err = can_fixup_bittiming(dev, bt, btc);
+       else if (!bt->tq && bt->bitrate && bitrate_const)
+               err = can_validate_bitrate(dev, bt, bitrate_const,
+                                          bitrate_const_cnt);
        else
                err = -EINVAL;
 
                        return -EOPNOTSUPP;
 
                memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
-               if (priv->bittiming_const) {
-                       err = can_get_bittiming(dev, &bt,
-                                               priv->bittiming_const);
-                       if (err)
-                               return err;
-               }
+               err = can_get_bittiming(dev, &bt,
+                                       priv->bittiming_const,
+                                       priv->bitrate_const,
+                                       priv->bitrate_const_cnt);
+               if (err)
+                       return err;
                memcpy(&priv->bittiming, &bt, sizeof(bt));
 
                if (priv->do_set_bittiming) {
 
                memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
                       sizeof(dbt));
-               if (priv->data_bittiming_const) {
-                       err = can_get_bittiming(dev, &dbt,
-                                               priv->data_bittiming_const);
-                       if (err)
-                               return err;
-               }
+               err = can_get_bittiming(dev, &dbt,
+                                       priv->data_bittiming_const,
+                                       priv->data_bitrate_const,
+                                       priv->data_bitrate_const_cnt);
+               if (err)
+                       return err;
                memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
 
                if (priv->do_set_data_bittiming) {
                size += nla_total_size(sizeof(*priv->termination_const) *       /* IFLA_CAN_TERMINATION_CONST */
                                       priv->termination_const_cnt);
        }
+       if (priv->bitrate_const)                                /* IFLA_CAN_BITRATE_CONST */
+               size += nla_total_size(sizeof(*priv->bitrate_const) *
+                                      priv->bitrate_const_cnt);
+       if (priv->data_bitrate_const)                           /* IFLA_CAN_DATA_BITRATE_CONST */
+               size += nla_total_size(sizeof(*priv->data_bitrate_const) *
+                                      priv->data_bitrate_const_cnt);
 
        return size;
 }
              nla_put(skb, IFLA_CAN_TERMINATION_CONST,
                      sizeof(*priv->termination_const) *
                      priv->termination_const_cnt,
-                     priv->termination_const))))
+                     priv->termination_const))) ||
+
+           (priv->bitrate_const &&
+            nla_put(skb, IFLA_CAN_BITRATE_CONST,
+                    sizeof(*priv->bitrate_const) *
+                    priv->bitrate_const_cnt,
+                    priv->bitrate_const)) ||
+
+           (priv->data_bitrate_const &&
+            nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST,
+                    sizeof(*priv->data_bitrate_const) *
+                    priv->data_bitrate_const_cnt,
+                    priv->data_bitrate_const))
+           )
 
                return -EMSGSIZE;
 
            (!priv->termination_const != !priv->do_set_termination))
                return -EINVAL;
 
+       if (!priv->bitrate_const != !priv->bitrate_const_cnt)
+               return -EINVAL;
+
+       if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt)
+               return -EINVAL;
+
        dev->rtnl_link_ops = &can_link_ops;
        return register_netdev(dev);
 }