Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx4 / mcg.c
index 34dffcf..db7dc0b 100644 (file)
@@ -125,9 +125,14 @@ static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,
                                              enum mlx4_steer_type steer,
                                              u32 qpn)
 {
-       struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1];
+       struct mlx4_steer *s_steer;
        struct mlx4_promisc_qp *pqp;
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return NULL;
+
+       s_steer = &mlx4_priv(dev)->steer[port - 1];
+
        list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
                if (pqp->qpn == qpn)
                        return pqp;
@@ -154,6 +159,9 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,
        u32 prot;
        int err;
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
+
        s_steer = &mlx4_priv(dev)->steer[port - 1];
        new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
        if (!new_entry)
@@ -238,6 +246,9 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
        struct mlx4_promisc_qp *pqp;
        struct mlx4_promisc_qp *dqp;
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
+
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        pqp = get_promisc_qp(dev, port, steer, qpn);
@@ -283,6 +294,9 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
        struct mlx4_steer_index *tmp_entry, *entry = NULL;
        struct mlx4_promisc_qp *dqp, *tmp_dqp;
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return NULL;
+
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        /* if qp is not promisc, it cannot be duplicated */
@@ -324,6 +338,9 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
        bool ret = false;
        int i;
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return NULL;
+
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -378,6 +395,9 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
        int err;
        struct mlx4_priv *priv = mlx4_priv(dev);
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
+
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        mutex_lock(&priv->mcg_table.mutex);
@@ -484,6 +504,9 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
        int loc, i;
        int err;
 
+       if (port < 1 || port > dev->caps.num_ports)
+               return -EINVAL;
+
        s_steer = &mlx4_priv(dev)->steer[port - 1];
        mutex_lock(&priv->mcg_table.mutex);
 
@@ -674,7 +697,8 @@ const u16 __sw_id_hw[] = {
        [MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
        [MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
        [MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
-       [MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006
+       [MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006,
+       [MLX4_NET_TRANS_RULE_ID_VXLAN]   = 0xE008
 };
 
 int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
@@ -699,7 +723,9 @@ static const int __rule_hw_sz[] = {
        [MLX4_NET_TRANS_RULE_ID_TCP] =
                sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
        [MLX4_NET_TRANS_RULE_ID_UDP] =
-               sizeof(struct mlx4_net_trans_rule_hw_tcp_udp)
+               sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
+       [MLX4_NET_TRANS_RULE_ID_VXLAN] =
+               sizeof(struct mlx4_net_trans_rule_hw_vxlan)
 };
 
 int mlx4_hw_rule_sz(struct mlx4_dev *dev,
@@ -764,6 +790,13 @@ static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
                rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk;
                break;
 
+       case MLX4_NET_TRANS_RULE_ID_VXLAN:
+               rule_hw->vxlan.vni =
+                       cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8);
+               rule_hw->vxlan.vni_mask =
+                       cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8);
+               break;
+
        default:
                return -EINVAL;
        }
@@ -1013,7 +1046,7 @@ out:
                                  index, dev->caps.num_mgms);
                else
                        mlx4_bitmap_free(&priv->mcg_table.bitmap,
-                                        index - dev->caps.num_mgms);
+                                        index - dev->caps.num_mgms, MLX4_USE_RR);
        }
        mutex_unlock(&priv->mcg_table.mutex);
 
@@ -1104,7 +1137,7 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
                                          index, amgm_index, dev->caps.num_mgms);
                        else
                                mlx4_bitmap_free(&priv->mcg_table.bitmap,
-                                                amgm_index - dev->caps.num_mgms);
+                                                amgm_index - dev->caps.num_mgms, MLX4_USE_RR);
                }
        } else {
                /* Remove entry from AMGM */
@@ -1124,7 +1157,7 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
                                  prev, index, dev->caps.num_mgms);
                else
                        mlx4_bitmap_free(&priv->mcg_table.bitmap,
-                                        index - dev->caps.num_mgms);
+                                        index - dev->caps.num_mgms, MLX4_USE_RR);
        }
 
 out: