[patch net-next mlxsw 3/4] mlxsw: pci: Allow to use CQEs of version 1 and version 2
Jiri Pirko
jiri at resnulli.us
Tue May 1 00:05:07 AEST 2018
Mon, Apr 30, 2018 at 01:24:17PM CEST, idosch at mellanox.com wrote:
>On Thu, Apr 26, 2018 at 10:28:17AM +0200, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri at mellanox.com>
>>
>> Use previously added resources to query FW support for multiple versions
>> of CQEs. Use the biggest version supported. For SDQs, it has no sense to
>> use version 2 as it does not introduce any new features, but it is
>> twice the size of CQE version 1.
>>
>> Signed-off-by: Jiri Pirko <jiri at mellanox.com>
>> ---
>> drivers/net/ethernet/mellanox/mlxsw/cmd.h | 24 ++++++++--
>> drivers/net/ethernet/mellanox/mlxsw/pci.c | 78 +++++++++++++++++++++++++++----
>> 2 files changed, 91 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h
>> index 479511cf79bc..669226b0759c 100644
>> --- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h
>> +++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h
>> @@ -662,6 +662,12 @@ MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_hash_single_size, 0x0C, 25, 1);
>> */
>> MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_hash_double_size, 0x0C, 26, 1);
>>
>> +/* cmd_mbox_config_set_cqe_version
>> + * Capability bit. Setting a bit to 1 configures the profile
>> + * according to the mailbox contents.
>> + */
>> +MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_version, 0x08, 0, 1);
>> +
>> /* cmd_mbox_config_profile_max_vepa_channels
>> * Maximum number of VEPA channels per port (0 through 16)
>> * 0 - multi-channel VEPA is disabled
>> @@ -841,6 +847,14 @@ MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_type,
>> MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_properties,
>> 0x60, 0, 8, 0x08, 0x00, false);
>>
>> +/* cmd_mbox_config_profile_cqe_version
>> + * CQE version:
>> + * 0: CQE version is 0
>> + * 1: CQE version is either 1 or 2
>> + * CQE ver 1 or 2 is configured by Completion Queue Context field cqe_ver.
>> + */
>> +MLXSW_ITEM32(cmd_mbox, config_profile, cqe_version, 0xB0, 0, 8);
>
>It's correct, but I wonder why it's 8 bits in PRM :)
Yeah
>
>> +
>> /* ACCESS_REG - Access EMAD Supported Register
>> * ----------------------------------
>> * OpMod == 0 (N/A), INMmod == 0 (N/A)
>> @@ -1032,11 +1046,15 @@ static inline int mlxsw_cmd_sw2hw_cq(struct mlxsw_core *mlxsw_core,
>> 0, cq_number, in_mbox, MLXSW_CMD_MBOX_SIZE);
>> }
>>
>> -/* cmd_mbox_sw2hw_cq_cv
>> +enum mlxsw_cmd_mbox_sw2hw_cq_cqe_ver {
>> + MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_1,
>> + MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_2,
>> +};
>> +
>> +/* cmd_mbox_sw2hw_cq_cqe_ver
>> * CQE Version.
>> - * 0 - CQE Version 0, 1 - CQE Version 1
>> */
>> -MLXSW_ITEM32(cmd_mbox, sw2hw_cq, cv, 0x00, 28, 4);
>> +MLXSW_ITEM32(cmd_mbox, sw2hw_cq, cqe_ver, 0x00, 28, 4);
>
>Very weird API... v0 vs. v1/v2 is set in config_profile and v1 vs. v2 is
>set in queue context.
Indeed :)
>
>>
>> /* cmd_mbox_sw2hw_cq_c_eqn
>> * Event Queue this CQ reports completion events to.
>> diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
>> index 99196dbafef2..7308be317032 100644
>> --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
>> +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
>> @@ -156,6 +156,8 @@ struct mlxsw_pci {
>> } cmd;
>> struct mlxsw_bus_info bus_info;
>> const struct pci_device_id *id;
>> + enum mlxsw_pci_cqe_v max_cqe_ver; /* Maximal supported CQE version */
>> + u8 num_sdq_cqs; /* Number of CQs used for SDQs */
>> };
>>
>> static void mlxsw_pci_queue_tasklet_schedule(struct mlxsw_pci_queue *q)
>> @@ -477,6 +479,17 @@ static void mlxsw_pci_rdq_fini(struct mlxsw_pci *mlxsw_pci,
>> }
>> }
>>
>> +static void mlxsw_pci_cq_pre_init(struct mlxsw_pci *mlxsw_pci,
>> + struct mlxsw_pci_queue *q)
>> +{
>> + q->u.cq.v = mlxsw_pci->max_cqe_ver;
>> +
>> + /* For SDQ it is pointless to use CQEv2, so use CQEv1 instead */
>> + if (q->u.cq.v == MLXSW_PCI_CQE_V2 &&
>> + q->num < mlxsw_pci->num_sdq_cqs)
>> + q->u.cq.v = MLXSW_PCI_CQE_V1;
>> +}
>> +
>> static int mlxsw_pci_cq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
>> struct mlxsw_pci_queue *q)
>> {
>> @@ -491,7 +504,13 @@ static int mlxsw_pci_cq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
>> mlxsw_pci_cqe_owner_set(q->u.cq.v, elem, 1);
>> }
>>
>> - mlxsw_cmd_mbox_sw2hw_cq_cv_set(mbox, 0); /* CQE ver 0 */
>> + if (q->u.cq.v == MLXSW_PCI_CQE_V1)
>> + mlxsw_cmd_mbox_sw2hw_cq_cqe_ver_set(mbox,
>> + MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_1);
>> + else if (q->u.cq.v == MLXSW_PCI_CQE_V2)
>> + mlxsw_cmd_mbox_sw2hw_cq_cqe_ver_set(mbox,
>> + MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_2);
>> +
>> mlxsw_cmd_mbox_sw2hw_cq_c_eqn_set(mbox, MLXSW_PCI_EQ_COMP_NUM);
>> mlxsw_cmd_mbox_sw2hw_cq_st_set(mbox, 0);
>> mlxsw_cmd_mbox_sw2hw_cq_log_cq_size_set(mbox, ilog2(q->count));
>> @@ -643,6 +662,18 @@ static void mlxsw_pci_cq_tasklet(unsigned long data)
>> }
>> }
>>
>> +static u16 mlxsw_pci_cq_elem_count(struct mlxsw_pci_queue *q)
>
>const
>
>> +{
>> + return q->u.cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_COUNT :
>> + MLXSW_PCI_CQE01_COUNT;
>> +}
>> +
>> +static u8 mlxsw_pci_cq_elem_size(struct mlxsw_pci_queue *q)
>
>const
Both fixed
>
>> +{
>> + return q->u.cq.v == MLXSW_PCI_CQE_V2 ? MLXSW_PCI_CQE2_SIZE :
>> + MLXSW_PCI_CQE01_SIZE;
>> +}
>> +
>> static int mlxsw_pci_eq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
>> struct mlxsw_pci_queue *q)
>> {
>> @@ -755,11 +786,15 @@ static void mlxsw_pci_eq_tasklet(unsigned long data)
>> struct mlxsw_pci_queue_ops {
>> const char *name;
>> enum mlxsw_pci_queue_type type;
>> + void (*pre_init)(struct mlxsw_pci *mlxsw_pci,
>> + struct mlxsw_pci_queue *q);
>> int (*init)(struct mlxsw_pci *mlxsw_pci, char *mbox,
>> struct mlxsw_pci_queue *q);
>> void (*fini)(struct mlxsw_pci *mlxsw_pci,
>> struct mlxsw_pci_queue *q);
>> void (*tasklet)(unsigned long data);
>> + u16 (*elem_count_f)(struct mlxsw_pci_queue *q);
>> + u8 (*elem_size_f)(struct mlxsw_pci_queue *q);
>> u16 elem_count;
>> u8 elem_size;
>> };
>> @@ -782,11 +817,12 @@ static const struct mlxsw_pci_queue_ops mlxsw_pci_rdq_ops = {
>>
>> static const struct mlxsw_pci_queue_ops mlxsw_pci_cq_ops = {
>> .type = MLXSW_PCI_QUEUE_TYPE_CQ,
>> + .pre_init = mlxsw_pci_cq_pre_init,
>> .init = mlxsw_pci_cq_init,
>> .fini = mlxsw_pci_cq_fini,
>> .tasklet = mlxsw_pci_cq_tasklet,
>> - .elem_count = MLXSW_PCI_CQE01_COUNT,
>> - .elem_size = MLXSW_PCI_CQE01_SIZE
>> + .elem_count_f = mlxsw_pci_cq_elem_count,
>> + .elem_size_f = mlxsw_pci_cq_elem_size
>> };
>>
>> static const struct mlxsw_pci_queue_ops mlxsw_pci_eq_ops = {
>> @@ -806,12 +842,15 @@ static int mlxsw_pci_queue_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
>> int i;
>> int err;
>>
>> - q->u.cq.v = MLXSW_PCI_CQE_V0;
>> + q->num = q_num;
>> + if (q_ops->pre_init)
>> + q_ops->pre_init(mlxsw_pci, q);
>>
>> spin_lock_init(&q->lock);
>> - q->num = q_num;
>> - q->count = q_ops->elem_count;
>> - q->elem_size = q_ops->elem_size;
>> + q->count = q_ops->elem_count_f ? q_ops->elem_count_f(q) :
>> + q_ops->elem_count;
>> + q->elem_size = q_ops->elem_size_f ? q_ops->elem_size_f(q) :
>> + q_ops->elem_size;
>> q->type = q_ops->type;
>> q->pci = mlxsw_pci;
>>
>> @@ -840,7 +879,7 @@ static int mlxsw_pci_queue_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
>>
>> elem_info = mlxsw_pci_queue_elem_info_get(q, i);
>> elem_info->elem =
>> - __mlxsw_pci_queue_elem_get(q, q_ops->elem_size, i);
>> + __mlxsw_pci_queue_elem_get(q, q->elem_size, i);
>> }
>>
>> mlxsw_cmd_mbox_zero(mbox);
>> @@ -952,6 +991,8 @@ static int mlxsw_pci_aqs_init(struct mlxsw_pci *mlxsw_pci, char *mbox)
>> return -EINVAL;
>> }
>>
>> + mlxsw_pci->num_sdq_cqs = num_sdqs;
>> +
>> err = mlxsw_pci_queue_group_init(mlxsw_pci, mbox, &mlxsw_pci_eq_ops,
>> num_eqs);
>> if (err) {
>> @@ -1192,6 +1233,11 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
>> mlxsw_pci_config_profile_swid_config(mlxsw_pci, mbox, i,
>> &profile->swid_config[i]);
>>
>> + if (mlxsw_pci->max_cqe_ver > MLXSW_PCI_CQE_V0) {
>> + mlxsw_cmd_mbox_config_profile_set_cqe_version_set(mbox, 1);
>> + mlxsw_cmd_mbox_config_profile_cqe_version_set(mbox, 1);
>> + }
>> +
>> return mlxsw_cmd_config_profile_set(mlxsw_pci->core, mbox);
>> }
>>
>> @@ -1386,6 +1432,21 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
>> if (err)
>> goto err_query_resources;
>>
>> + if (MLXSW_CORE_RES_VALID(mlxsw_core, CQE_V2) &&
>> + MLXSW_CORE_RES_GET(mlxsw_core, CQE_V2))
>> + mlxsw_pci->max_cqe_ver = MLXSW_PCI_CQE_V2;
>> + else if (MLXSW_CORE_RES_VALID(mlxsw_core, CQE_V1) &&
>> + MLXSW_CORE_RES_GET(mlxsw_core, CQE_V1))
>> + mlxsw_pci->max_cqe_ver = MLXSW_PCI_CQE_V1;
>> + else if ((MLXSW_CORE_RES_VALID(mlxsw_core, CQE_V0) &&
>> + MLXSW_CORE_RES_GET(mlxsw_core, CQE_V0)) ||
>> + !MLXSW_CORE_RES_VALID(mlxsw_core, CQE_V0)) {
>
>This is for SwitchX-2, right?
Yes.
>
>> + mlxsw_pci->max_cqe_ver = MLXSW_PCI_CQE_V0;
>> + } else {
>> + dev_err(&pdev->dev, "Invalid supported CQE version combination reported\n");
>> + goto err_cqe_v_check;
>> + }
>> +
>> err = mlxsw_pci_config_profile(mlxsw_pci, mbox, profile, res);
>> if (err)
>> goto err_config_profile;
>> @@ -1408,6 +1469,7 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
>> mlxsw_pci_aqs_fini(mlxsw_pci);
>> err_aqs_init:
>> err_config_profile:
>> +err_cqe_v_check:
>> err_query_resources:
>> err_boardinfo:
>> mlxsw_pci_fw_area_fini(mlxsw_pci);
>> --
>> 2.14.3
>>
More information about the Linux-mlxsw
mailing list