net/mlx4_core: Fix reg/unreg vlan/mac to conform to the firmware spec
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx4 / port.c
index d3d3106..9433c1f 100644 (file)
@@ -178,13 +178,24 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac);
 int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 {
        u64 out_param = 0;
-       int err;
+       int err = -EINVAL;
 
        if (mlx4_is_mfunc(dev)) {
-               set_param_l(&out_param, port);
-               err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
-                                  RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
-                                  MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+               if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
+                       err = mlx4_cmd_imm(dev, mac, &out_param,
+                                          ((u32) port) << 8 | (u32) RES_MAC,
+                                          RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
+                                          MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+               }
+               if (err && err == -EINVAL && mlx4_is_slave(dev)) {
+                       /* retry using old REG_MAC format */
+                       set_param_l(&out_param, port);
+                       err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
+                                          RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
+                                          MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+                       if (!err)
+                               dev->flags |= MLX4_FLAG_OLD_REG_MAC;
+               }
                if (err)
                        return err;
 
@@ -231,10 +242,18 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
        u64 out_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
-               set_param_l(&out_param, port);
-               (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
-                                   RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
-                                   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+               if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
+                       (void) mlx4_cmd_imm(dev, mac, &out_param,
+                                           ((u32) port) << 8 | (u32) RES_MAC,
+                                           RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
+                                           MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+               } else {
+                       /* use old unregister mac format */
+                       set_param_l(&out_param, port);
+                       (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
+                                           RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
+                                           MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+               }
                return;
        }
        __mlx4_unregister_mac(dev, port, mac);
@@ -374,8 +393,8 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
                return -EINVAL;
 
        if (mlx4_is_mfunc(dev)) {
-               set_param_l(&out_param, port);
-               err = mlx4_cmd_imm(dev, vlan, &out_param, RES_VLAN,
+               err = mlx4_cmd_imm(dev, vlan, &out_param,
+                                  ((u32) port) << 8 | (u32) RES_VLAN,
                                   RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
                                   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
                if (!err)
@@ -418,8 +437,8 @@ void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
        u64 out_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
-               set_param_l(&out_param, port);
-               (void) mlx4_cmd_imm(dev, index, &out_param, RES_VLAN,
+               (void) mlx4_cmd_imm(dev, index, &out_param,
+                                   ((u32) port) << 8 | (u32) RES_VLAN,
                                    RES_OP_RESERVE_AND_MAP,
                                    MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
                                    MLX4_CMD_WRAPPED);