diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 85 |
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 | ||
80 | enum res_qp_states { | 81 | enum res_qp_states { |
@@ -2934,7 +2935,7 @@ static struct res_gid *find_gid(struct mlx4_dev *dev, int slave, | |||
2934 | 2935 | ||
2935 | static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, | 2936 | static 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 | ||
2962 | static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, | 2964 | static 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 | ||
2986 | static 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 | |||
3003 | static 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 | |||
2983 | int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 3017 | int 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, ®_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, ®_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 | ||
3028 | ex_rem: | 3064 | ex_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); | ||
3031 | ex_put: | 3066 | ex_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 | } |