aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
diff options
context:
space:
mode:
authorHadar Hen Zion <hadarh@mellanox.com>2013-04-10 21:56:41 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-11 16:12:40 -0400
commitfab1e24ab84a0ca2f12599b5d4349576d9a3664f (patch)
tree60ba617a70e5cf23f15159125794f26b81d00b8d /drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
parentfd91c49fb047a4a28c694982548aee7bea9c365b (diff)
net/mlx4_core: Translate guest B0 steering rules to DMFS
The different steering modes are global to the device, with DMFS being introduced after SRIOV was merged. Hence, SRIOV guests running legacy / older Linux kernels or non-Linux drivers may provide B0 steering directives when the hypervisor is using DMFS and fail. Under B0 only L2 steering rules are allowed, hence B0 is a subset of DMFS. Use this fact to enable such legacy guests to run by modifying the SRIOV B0 steering wrapper to translate guest B0 directives to DMFS ones when the device uses DMFS. The translated B0 rule has to be kept in the resource tracker as a B0 object to allow for lookup in case of detach. Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/resource_tracker.c')
-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 }