aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c85
1 files changed, 63 insertions, 22 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 1391b52f443a..f2d64435d8ef 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -75,6 +75,7 @@ struct res_gid {
75 u8 gid[16]; 75 u8 gid[16];
76 enum mlx4_protocol prot; 76 enum mlx4_protocol prot;
77 enum mlx4_steer_type steer; 77 enum mlx4_steer_type steer;
78 u64 reg_id;
78}; 79};
79 80
80enum res_qp_states { 81enum res_qp_states {
@@ -2934,7 +2935,7 @@ static struct res_gid *find_gid(struct mlx4_dev *dev, int slave,
2934 2935
2935static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, 2936static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2936 u8 *gid, enum mlx4_protocol prot, 2937 u8 *gid, enum mlx4_protocol prot,
2937 enum mlx4_steer_type steer) 2938 enum mlx4_steer_type steer, u64 reg_id)
2938{ 2939{
2939 struct res_gid *res; 2940 struct res_gid *res;
2940 int err; 2941 int err;
@@ -2951,6 +2952,7 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2951 memcpy(res->gid, gid, 16); 2952 memcpy(res->gid, gid, 16);
2952 res->prot = prot; 2953 res->prot = prot;
2953 res->steer = steer; 2954 res->steer = steer;
2955 res->reg_id = reg_id;
2954 list_add_tail(&res->list, &rqp->mcg_list); 2956 list_add_tail(&res->list, &rqp->mcg_list);
2955 err = 0; 2957 err = 0;
2956 } 2958 }
@@ -2961,7 +2963,7 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2961 2963
2962static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, 2964static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2963 u8 *gid, enum mlx4_protocol prot, 2965 u8 *gid, enum mlx4_protocol prot,
2964 enum mlx4_steer_type steer) 2966 enum mlx4_steer_type steer, u64 *reg_id)
2965{ 2967{
2966 struct res_gid *res; 2968 struct res_gid *res;
2967 int err; 2969 int err;
@@ -2971,6 +2973,7 @@ static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2971 if (!res || res->prot != prot || res->steer != steer) 2973 if (!res || res->prot != prot || res->steer != steer)
2972 err = -EINVAL; 2974 err = -EINVAL;
2973 else { 2975 else {
2976 *reg_id = res->reg_id;
2974 list_del(&res->list); 2977 list_del(&res->list);
2975 kfree(res); 2978 kfree(res);
2976 err = 0; 2979 err = 0;
@@ -2980,6 +2983,37 @@ static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
2980 return err; 2983 return err;
2981} 2984}
2982 2985
2986static int qp_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
2987 int block_loopback, enum mlx4_protocol prot,
2988 enum mlx4_steer_type type, u64 *reg_id)
2989{
2990 switch (dev->caps.steering_mode) {
2991 case MLX4_STEERING_MODE_DEVICE_MANAGED:
2992 return mlx4_trans_to_dmfs_attach(dev, qp, gid, gid[5],
2993 block_loopback, prot,
2994 reg_id);
2995 case MLX4_STEERING_MODE_B0:
2996 return mlx4_qp_attach_common(dev, qp, gid,
2997 block_loopback, prot, type);
2998 default:
2999 return -EINVAL;
3000 }
3001}
3002
3003static int qp_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
3004 enum mlx4_protocol prot, enum mlx4_steer_type type,
3005 u64 reg_id)
3006{
3007 switch (dev->caps.steering_mode) {
3008 case MLX4_STEERING_MODE_DEVICE_MANAGED:
3009 return mlx4_flow_detach(dev, reg_id);
3010 case MLX4_STEERING_MODE_B0:
3011 return mlx4_qp_detach_common(dev, qp, gid, prot, type);
3012 default:
3013 return -EINVAL;
3014 }
3015}
3016
2983int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, 3017int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
2984 struct mlx4_vhcr *vhcr, 3018 struct mlx4_vhcr *vhcr,
2985 struct mlx4_cmd_mailbox *inbox, 3019 struct mlx4_cmd_mailbox *inbox,
@@ -2992,14 +3026,12 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
2992 int err; 3026 int err;
2993 int qpn; 3027 int qpn;
2994 struct res_qp *rqp; 3028 struct res_qp *rqp;
3029 u64 reg_id = 0;
2995 int attach = vhcr->op_modifier; 3030 int attach = vhcr->op_modifier;
2996 int block_loopback = vhcr->in_modifier >> 31; 3031 int block_loopback = vhcr->in_modifier >> 31;
2997 u8 steer_type_mask = 2; 3032 u8 steer_type_mask = 2;
2998 enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1; 3033 enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
2999 3034
3000 if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0)
3001 return -EINVAL;
3002
3003 qpn = vhcr->in_modifier & 0xffffff; 3035 qpn = vhcr->in_modifier & 0xffffff;
3004 err = get_res(dev, slave, qpn, RES_QP, &rqp); 3036 err = get_res(dev, slave, qpn, RES_QP, &rqp);
3005 if (err) 3037 if (err)
@@ -3007,30 +3039,32 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
3007 3039
3008 qp.qpn = qpn; 3040 qp.qpn = qpn;
3009 if (attach) { 3041 if (attach) {
3010 err = add_mcg_res(dev, slave, rqp, gid, prot, type); 3042 err = qp_attach(dev, &qp, gid, block_loopback, prot,
3011 if (err) 3043 type, &reg_id);
3044 if (err) {
3045 pr_err("Fail to attach rule to qp 0x%x\n", qpn);
3012 goto ex_put; 3046 goto ex_put;
3013 3047 }
3014 err = mlx4_qp_attach_common(dev, &qp, gid, 3048 err = add_mcg_res(dev, slave, rqp, gid, prot, type, reg_id);
3015 block_loopback, prot, type);
3016 if (err) 3049 if (err)
3017 goto ex_rem; 3050 goto ex_detach;
3018 } else { 3051 } else {
3019 err = rem_mcg_res(dev, slave, rqp, gid, prot, type); 3052 err = rem_mcg_res(dev, slave, rqp, gid, prot, type, &reg_id);
3020 if (err) 3053 if (err)
3021 goto ex_put; 3054 goto ex_put;
3022 err = mlx4_qp_detach_common(dev, &qp, gid, prot, type);
3023 }
3024 3055
3056 err = qp_detach(dev, &qp, gid, prot, type, reg_id);
3057 if (err)
3058 pr_err("Fail to detach rule from qp 0x%x reg_id = 0x%llx\n",
3059 qpn, reg_id);
3060 }
3025 put_res(dev, slave, qpn, RES_QP); 3061 put_res(dev, slave, qpn, RES_QP);
3026 return 0; 3062 return err;
3027 3063
3028ex_rem: 3064ex_detach:
3029 /* ignore error return below, already in error */ 3065 qp_detach(dev, &qp, gid, prot, type, reg_id);
3030 (void) rem_mcg_res(dev, slave, rqp, gid, prot, type);
3031ex_put: 3066ex_put:
3032 put_res(dev, slave, qpn, RES_QP); 3067 put_res(dev, slave, qpn, RES_QP);
3033
3034 return err; 3068 return err;
3035} 3069}
3036 3070
@@ -3266,9 +3300,16 @@ static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
3266 struct mlx4_qp qp; /* dummy for calling attach/detach */ 3300 struct mlx4_qp qp; /* dummy for calling attach/detach */
3267 3301
3268 list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) { 3302 list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
3269 qp.qpn = rqp->local_qpn; 3303 switch (dev->caps.steering_mode) {
3270 (void) mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot, 3304 case MLX4_STEERING_MODE_DEVICE_MANAGED:
3271 rgid->steer); 3305 mlx4_flow_detach(dev, rgid->reg_id);
3306 break;
3307 case MLX4_STEERING_MODE_B0:
3308 qp.qpn = rqp->local_qpn;
3309 (void) mlx4_qp_detach_common(dev, &qp, rgid->gid,
3310 rgid->prot, rgid->steer);
3311 break;
3312 }
3272 list_del(&rgid->list); 3313 list_del(&rgid->list);
3273 kfree(rgid); 3314 kfree(rgid);
3274 } 3315 }