net/mlx4_core: Initialize all mailbox buffers to zero before use
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx4 / port.c
index 946e0af..97d342f 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);
 
@@ -448,8 +469,6 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
 
        inbuf = inmailbox->buf;
        outbuf = outmailbox->buf;
-       memset(inbuf, 0, 256);
-       memset(outbuf, 0, 256);
        inbuf[0] = 1;
        inbuf[1] = 1;
        inbuf[2] = 1;
@@ -632,8 +651,6 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz)
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
 
-       memset(mailbox->buf, 0, 256);
-
        ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
 
        if (pkey_tbl_sz >= 0 && mlx4_is_master(dev)) {
@@ -671,8 +688,6 @@ int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
        context = mailbox->buf;
-       memset(context, 0, sizeof *context);
-
        context->flags = SET_PORT_GEN_ALL_VALID;
        context->mtu = cpu_to_be16(mtu);
        context->pptx = (pptx * (!pfctx)) << 7;
@@ -706,8 +721,6 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
        context = mailbox->buf;
-       memset(context, 0, sizeof *context);
-
        context->base_qpn = cpu_to_be32(base_qpn);
        context->n_mac = dev->caps.log_num_macs;
        context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
@@ -740,8 +753,6 @@ int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc)
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
        context = mailbox->buf;
-       memset(context, 0, sizeof *context);
-
        for (i = 0; i < MLX4_NUM_UP; i += 2)
                context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1];
 
@@ -767,7 +778,6 @@ int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
        context = mailbox->buf;
-       memset(context, 0, sizeof *context);
 
        for (i = 0; i < MLX4_NUM_TC; i++) {
                struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i];