]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/mellanox/mlx4/eq.c
mlx4: 64-byte CQE/EQE support
[karo-tx-linux.git] / drivers / net / ethernet / mellanox / mlx4 / eq.c
index 51c764901ad257bce17199496d895f788a647f8b..c509a86db61012c38692dade72acd17e54fb3384 100644 (file)
@@ -101,15 +101,21 @@ static void eq_set_ci(struct mlx4_eq *eq, int req_not)
        mb();
 }
 
-static struct mlx4_eqe *get_eqe(struct mlx4_eq *eq, u32 entry)
+static struct mlx4_eqe *get_eqe(struct mlx4_eq *eq, u32 entry, u8 eqe_factor)
 {
-       unsigned long off = (entry & (eq->nent - 1)) * MLX4_EQ_ENTRY_SIZE;
-       return eq->page_list[off / PAGE_SIZE].buf + off % PAGE_SIZE;
+       /* (entry & (eq->nent - 1)) gives us a cyclic array */
+       unsigned long offset = (entry & (eq->nent - 1)) * (MLX4_EQ_ENTRY_SIZE << eqe_factor);
+       /* CX3 is capable of extending the EQE from 32 to 64 bytes.
+        * When this feature is enabled, the first (in the lower addresses)
+        * 32 bytes in the 64 byte EQE are reserved and the next 32 bytes
+        * contain the legacy EQE information.
+        */
+       return eq->page_list[offset / PAGE_SIZE].buf + (offset + (eqe_factor ? MLX4_EQ_ENTRY_SIZE : 0)) % PAGE_SIZE;
 }
 
-static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq)
+static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq, u8 eqe_factor)
 {
-       struct mlx4_eqe *eqe = get_eqe(eq, eq->cons_index);
+       struct mlx4_eqe *eqe = get_eqe(eq, eq->cons_index, eqe_factor);
        return !!(eqe->owner & 0x80) ^ !!(eq->cons_index & eq->nent) ? NULL : eqe;
 }
 
@@ -177,7 +183,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe)
                return;
        }
 
-       memcpy(s_eqe, eqe, sizeof(struct mlx4_eqe) - 1);
+       memcpy(s_eqe, eqe, dev->caps.eqe_size - 1);
        s_eqe->slave_id = slave;
        /* ensure all information is written before setting the ownersip bit */
        wmb();
@@ -329,9 +335,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave,
        ctx = &priv->mfunc.master.slave_state[slave];
        spin_lock_irqsave(&ctx->lock, flags);
 
-       mlx4_dbg(dev, "%s: slave: %d, current state: %d new event :%d\n",
-                __func__, slave, cur_state, event);
-
        switch (cur_state) {
        case SLAVE_PORT_DOWN:
                if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event)
@@ -366,9 +369,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave,
                        goto out;
        }
        ret = mlx4_get_slave_port_state(dev, slave, port);
-       mlx4_dbg(dev, "%s: slave: %d, current state: %d new event"
-                " :%d gen_event: %d\n",
-                __func__, slave, cur_state, event, *gen_event);
 
 out:
        spin_unlock_irqrestore(&ctx->lock, flags);
@@ -447,7 +447,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
        int i;
        enum slave_port_gen_event gen_event;
 
-       while ((eqe = next_eqe_sw(eq))) {
+       while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) {
                /*
                 * Make sure we read EQ entry contents after we've
                 * checked the ownership bit.
@@ -843,6 +843,18 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq)
        return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4);
 }
 
+static void mlx4_unmap_uar(struct mlx4_dev *dev)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       int i;
+
+       for (i = 0; i < mlx4_num_eq_uar(dev); ++i)
+               if (priv->eq_table.uar_map[i]) {
+                       iounmap(priv->eq_table.uar_map[i]);
+                       priv->eq_table.uar_map[i] = NULL;
+               }
+}
+
 static int mlx4_create_eq(struct mlx4_dev *dev, int nent,
                          u8 intr, struct mlx4_eq *eq)
 {
@@ -858,7 +870,8 @@ static int mlx4_create_eq(struct mlx4_dev *dev, int nent,
 
        eq->dev   = dev;
        eq->nent  = roundup_pow_of_two(max(nent, 2));
-       npages = PAGE_ALIGN(eq->nent * MLX4_EQ_ENTRY_SIZE) / PAGE_SIZE;
+       /* CX3 is capable of extending the CQE/EQE from 32 to 64 bytes */
+       npages = PAGE_ALIGN(eq->nent * (MLX4_EQ_ENTRY_SIZE << dev->caps.eqe_factor)) / PAGE_SIZE;
 
        eq->page_list = kmalloc(npages * sizeof *eq->page_list,
                                GFP_KERNEL);
@@ -960,8 +973,9 @@ static void mlx4_free_eq(struct mlx4_dev *dev,
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_cmd_mailbox *mailbox;
        int err;
-       int npages = PAGE_ALIGN(MLX4_EQ_ENTRY_SIZE * eq->nent) / PAGE_SIZE;
        int i;
+       /* CX3 is capable of extending the CQE/EQE from 32 to 64 bytes */
+       int npages = PAGE_ALIGN((MLX4_EQ_ENTRY_SIZE << dev->caps.eqe_factor) * eq->nent) / PAGE_SIZE;
 
        mailbox = mlx4_alloc_cmd_mailbox(dev);
        if (IS_ERR(mailbox))
@@ -1207,6 +1221,7 @@ err_out_unmap:
        mlx4_free_irqs(dev);
 
 err_out_bitmap:
+       mlx4_unmap_uar(dev);
        mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
 
 err_out_free:
@@ -1231,10 +1246,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
        if (!mlx4_is_slave(dev))
                mlx4_unmap_clr_int(dev);
 
-       for (i = 0; i < mlx4_num_eq_uar(dev); ++i)
-               if (priv->eq_table.uar_map[i])
-                       iounmap(priv->eq_table.uar_map[i]);
-
+       mlx4_unmap_uar(dev);
        mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
 
        kfree(priv->eq_table.uar_map);