mlx4_core: Allow choosing flow steering mode
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx4 / mcg.c
index 4ec3835..1ee4db3 100644 (file)
@@ -54,12 +54,7 @@ struct mlx4_mgm {
 
 int mlx4_get_mgm_entry_size(struct mlx4_dev *dev)
 {
-       if (dev->caps.steering_mode ==
-           MLX4_STEERING_MODE_DEVICE_MANAGED)
-               return 1 << MLX4_FS_MGM_LOG_ENTRY_SIZE;
-       else
-               return min((1 << mlx4_log_num_mgm_entry_size),
-                          MLX4_MAX_MGM_ENTRY_SIZE);
+       return 1 << dev->oper_log_mgm_entry_size;
 }
 
 int mlx4_get_qp_per_mgm(struct mlx4_dev *dev)
@@ -137,11 +132,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
        return err;
 }
 
-static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num,
+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[pf_num];
+       struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1];
        struct mlx4_promisc_qp *pqp;
 
        list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
@@ -182,7 +177,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,
        /* If the given qpn is also a promisc qp,
         * it should be inserted to duplicates list
         */
-       pqp = get_promisc_qp(dev, 0, steer, qpn);
+       pqp = get_promisc_qp(dev, port, steer, qpn);
        if (pqp) {
                dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
                if (!dqp) {
@@ -256,7 +251,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
 
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
-       pqp = get_promisc_qp(dev, 0, steer, qpn);
+       pqp = get_promisc_qp(dev, port, steer, qpn);
        if (!pqp)
                return 0; /* nothing to do */
 
@@ -302,7 +297,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        /* if qp is not promisc, it cannot be duplicated */
-       if (!get_promisc_qp(dev, 0, steer, qpn))
+       if (!get_promisc_qp(dev, port, steer, qpn))
                return false;
 
        /* The qp is promisc qp so it is a duplicate on this index
@@ -352,7 +347,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
        members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
        for (i = 0;  i < members_count; i++) {
                qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
-               if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) {
+               if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
                        /* the qp is not promisc, the entry can't be removed */
                        goto out;
                }
@@ -398,7 +393,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
 
        mutex_lock(&priv->mcg_table.mutex);
 
-       if (get_promisc_qp(dev, 0, steer, qpn)) {
+       if (get_promisc_qp(dev, port, steer, qpn)) {
                err = 0;  /* Noting to do, already exists */
                goto out_mutex;
        }
@@ -432,8 +427,10 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
                        if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) {
                                /* Entry already exists, add to duplicates */
                                dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
-                               if (!dqp)
+                               if (!dqp) {
+                                       err = -ENOMEM;
                                        goto out_mailbox;
+                               }
                                dqp->qpn = qpn;
                                list_add_tail(&dqp->list, &entry->duplicates);
                                found = true;
@@ -501,7 +498,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
        s_steer = &mlx4_priv(dev)->steer[port - 1];
        mutex_lock(&priv->mcg_table.mutex);
 
-       pqp = get_promisc_qp(dev, 0, steer, qpn);
+       pqp = get_promisc_qp(dev, port, steer, qpn);
        if (unlikely(!pqp)) {
                mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
                /* nothing to do */
@@ -648,13 +645,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port,
        return err;
 }
 
-struct mlx4_net_trans_rule_hw_ctrl {
-       __be32 ctrl;
-       __be32 vf_vep_port;
-       __be32 qpn;
-       __be32 reserved;
-};
-
 static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
                                  struct mlx4_net_trans_rule_hw_ctrl *hw)
 {
@@ -678,87 +668,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
        hw->qpn = cpu_to_be32(ctrl->qpn);
 }
 
-struct mlx4_net_trans_rule_hw_ib {
-       u8      size;
-       u8      rsvd1;
-       __be16  id;
-       u32     rsvd2;
-       __be32  qpn;
-       __be32  qpn_mask;
-       u8      dst_gid[16];
-       u8      dst_gid_msk[16];
-} __packed;
-
-struct mlx4_net_trans_rule_hw_eth {
-       u8      size;
-       u8      rsvd;
-       __be16  id;
-       u8      rsvd1[6];
-       u8      dst_mac[6];
-       u16     rsvd2;
-       u8      dst_mac_msk[6];
-       u16     rsvd3;
-       u8      src_mac[6];
-       u16     rsvd4;
-       u8      src_mac_msk[6];
-       u8      rsvd5;
-       u8      ether_type_enable;
-       __be16  ether_type;
-       __be16  vlan_id_msk;
-       __be16  vlan_id;
-} __packed;
-
-struct mlx4_net_trans_rule_hw_tcp_udp {
-       u8      size;
-       u8      rsvd;
-       __be16  id;
-       __be16  rsvd1[3];
-       __be16  dst_port;
-       __be16  rsvd2;
-       __be16  dst_port_msk;
-       __be16  rsvd3;
-       __be16  src_port;
-       __be16  rsvd4;
-       __be16  src_port_msk;
-} __packed;
-
-struct mlx4_net_trans_rule_hw_ipv4 {
-       u8      size;
-       u8      rsvd;
-       __be16  id;
-       __be32  rsvd1;
-       __be32  dst_ip;
-       __be32  dst_ip_msk;
-       __be32  src_ip;
-       __be32  src_ip_msk;
-} __packed;
-
-struct _rule_hw {
-       union {
-               struct {
-                       u8 size;
-                       u8 rsvd;
-                       __be16 id;
-               };
-               struct mlx4_net_trans_rule_hw_eth eth;
-               struct mlx4_net_trans_rule_hw_ib ib;
-               struct mlx4_net_trans_rule_hw_ipv4 ipv4;
-               struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp;
-       };
+const u16 __sw_id_hw[] = {
+       [MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
+       [MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
+       [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
 };
 
 static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
                            struct _rule_hw *rule_hw)
 {
-       static const u16 __sw_id_hw[] = {
-               [MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
-               [MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
-               [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
-       };
-
        static const size_t __rule_hw_sz[] = {
                [MLX4_NET_TRANS_RULE_ID_ETH] =
                        sizeof(struct mlx4_net_trans_rule_hw_eth),