net/mlx4_en: Use vlan id instead of vlan index for unregistration
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx4 / port.c
index 946e0af..caaa154 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);
@@ -284,7 +303,7 @@ static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
        memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
        in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
-                      MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
+                      MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 
        mlx4_free_cmd_mailbox(dev, mailbox);
 
@@ -370,9 +389,12 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
        u64 out_param = 0;
        int err;
 
+       if (vlan > 4095)
+               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)
@@ -384,23 +406,26 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
 }
 EXPORT_SYMBOL_GPL(mlx4_register_vlan);
 
-void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
+void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan)
 {
        struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
+       int index;
 
-       if (index < MLX4_VLAN_REGULAR) {
-               mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
-               return;
+       mutex_lock(&table->mutex);
+       if (mlx4_find_cached_vlan(dev, port, vlan, &index)) {
+               mlx4_warn(dev, "vlan 0x%x is not in the vlan table\n", vlan);
+               goto out;
        }
 
-       mutex_lock(&table->mutex);
-       if (!table->refs[index]) {
-               mlx4_warn(dev, "No vlan entry for index %d\n", index);
+       if (index < MLX4_VLAN_REGULAR) {
+               mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
                goto out;
        }
+
        if (--table->refs[index]) {
-               mlx4_dbg(dev, "Have more references for index %d,"
-                        "no need to modify vlan table\n", index);
+               mlx4_dbg(dev, "Have %d more references for index %d,"
+                        "no need to modify vlan table\n", table->refs[index],
+                        index);
                goto out;
        }
        table->entries[index] = 0;
@@ -410,23 +435,19 @@ out:
        mutex_unlock(&table->mutex);
 }
 
-void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
+void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan)
 {
-       u64 in_param = 0;
-       int err;
+       u64 out_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
-               set_param_l(&in_param, port);
-               err = mlx4_cmd(dev, in_param, RES_VLAN, RES_OP_RESERVE_AND_MAP,
-                              MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
-                              MLX4_CMD_WRAPPED);
-               if (!err)
-                       mlx4_warn(dev, "Failed freeing vlan at index:%d\n",
-                                       index);
-
+               (void) mlx4_cmd_imm(dev, vlan, &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);
                return;
        }
-       __mlx4_unregister_vlan(dev, port, index);
+       __mlx4_unregister_vlan(dev, port, vlan);
 }
 EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);