]> 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 b84a88bc44dc2a5e7391ca7bc7116344dd63a97f..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();
@@ -441,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.
@@ -864,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);
@@ -966,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))