Yuval Mintz <yuval.mi...@qlogic.com> :
> The Qlogic Everest Driver is the backend module for the 579xx ethernet
> products by Qlogic.
> 
> This module serves two main purposes:
>  1. It's responsible to contain all the common code that will be shared
>     between the various drivers that would be used with said line of
>     products. Flows such as chip initialization and de-initialization
>     fall under this category.
> 
>  2. It would abstract the protocol-specific HW & FW components, allowing
>     the protocol drivers to have a clean APIs which is detached in its
>     slowpath configuration from the actual HSI.
> 
> This adds a very basic module without any protocol-specific bits.
> I.e., this adds a basic implementation that almost entirely falls under
> the first category.

500 ko of a basic something is mildly reviewable for mere mortals.

[...]
> diff --git a/drivers/net/ethernet/qlogic/qed/qed.h 
> b/drivers/net/ethernet/qlogic/qed/qed.h
> new file mode 100644
> index 0000000..f9f01bb
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed.h
[...]
> +/* helpers */
> +static inline u32 DB_ADDR(u32        cid,
> +                       u32   DEMS)

static inline u32 DB_ADDR(u32 cid, u32 DEMS)

[...]
> +/* forward */
> +struct qed_ptt_pool;
> +struct qed_spq;
> +struct qed_sb_info;
> +struct qed_sb_attn_info;
> +struct qed_cxt_mngr;
> +struct qed_sb_sp_info;
> +struct qed_mcp_info;

Many forward. Dependencies hell ?

[...]
> +struct qed_simd_fp_handler {
> +     void    *token;
> +     void    (*func)(void *);
> +};

Use union * ?

[...]
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c 
> b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
> new file mode 100644
> index 0000000..4acc053
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
[...]
> +     qed_ilt_cli_blk_fill(p_cli,
> +                          p_blk,
> +                          curr_line,
> +                          total,
> +                          CONN_CXT_SIZE(p_hwfn));

        qed_ilt_cli_blk_fill(p_cli, p_blk, curr_line, total, 
CONN_CXT_SIZE(p_hwfn));

s/p_// and it fits in 80 cols.

[...]
> +static int qed_ilt_shadow_alloc(struct qed_hwfn *p_hwfn)
> +{
> +     struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
> +     struct qed_ilt_client_cfg *clients = p_mngr->clients;
> +     struct qed_ilt_cli_blk *p_blk;
> +     u32 size, i, j;
> +     int rc;
> +
> +     size = qed_cxt_ilt_shadow_size(clients);
> +     p_mngr->ilt_shadow = kcalloc(size, sizeof(struct qed_dma_mem),
> +                                  GFP_KERNEL);
> +     if (!p_mngr->ilt_shadow) {
> +             DP_NOTICE(p_hwfn, "Failed to allocate ilt shadow table\n");
> +             rc = -ENOMEM;
> +             goto ilt_shadow_fail;
> +     } else {
> +             DP_VERBOSE(p_hwfn, QED_MSG_ILT,
> +                        "Allocated 0x%x bytes for ilt shadow\n",
> +                        (u32)(size * sizeof(struct qed_dma_mem)));
> +     }

The "else" branch after the "goto" isn't idiomatic.

[...]
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c 
> b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> new file mode 100644
> index 0000000..14366af
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
[...]
> +void qed_init_struct(struct qed_dev *cdev)
> +{
> +     u8 i;
> +
> +     for (i = 0; i < MAX_HWFNS_PER_DEVICE; i++) {
> +             struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
> +
> +             p_hwfn->cdev            = cdev;
> +             p_hwfn->my_id           = i;
> +             p_hwfn->b_active        = false;
> +
> +             ;

; ?


[...]
> +static int qed_init_qm_info(struct qed_hwfn *p_hwfn)
> +{
> +     struct qed_qm_info *qm_info = &p_hwfn->qm_info;
> +     struct init_qm_port_params *p_qm_port;
> +     u8 num_vports, i, vport_id, num_ports;
> +     u16 num_pqs, multi_cos_tcs = 1;
> +
> +     memset(qm_info, 0, sizeof(*qm_info));
> +
> +     num_pqs = multi_cos_tcs + 1; /* The '1' is for pure-LB */
> +     num_vports = (u8)RESC_NUM(p_hwfn, QED_VPORT);
> +
> +     /* Sanity checking that setup requires legal number of resources */
> +     if (num_pqs > RESC_NUM(p_hwfn, QED_PQ)) {
> +             DP_ERR(p_hwfn,
> +                    "Need too many Physical queues - 0x%04x when only %04x 
> are available\n",
> +                    num_pqs, RESC_NUM(p_hwfn, QED_PQ));
> +             return -EINVAL;
> +     }
> +
> +     /* PQs will be arranged as follows: First per-TC PQ then pure-LB quete.
> +      */
> +     qm_info->qm_pq_params = kzalloc(sizeof(*qm_info->qm_pq_params) *
> +                                     num_pqs, GFP_ATOMIC);


qed_init_qm_info is only used in qed_resc_alloc. qed_resc_alloc performs
GFP_KERNEL alloc and qed_resc_alloc does not use qed_init_qm_info in
a spinlocked section. I would thus expect both to use the same allocation
flag.

[...]
> +int qed_resc_alloc(struct qed_dev *cdev)
> +{
> +     struct qed_consq *p_consq;
> +     struct qed_eq *p_eq;
> +     int i, rc = 0;
> +
> +     cdev->fw_data = kzalloc(sizeof(*cdev->fw_data), GFP_KERNEL);
> +     if (!cdev->fw_data)
> +             return -ENOMEM;
> +
[...]
> +     cdev->reset_stats = kzalloc(sizeof(*cdev->reset_stats), GFP_ATOMIC);

GFP_{KERNEL / ATOMIC} but the context is the same.

[...]
> +++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h 
> b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
> new file mode 100644
> index 0000000..cbb0c1c
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
> @@ -0,0 +1,5040 @@
> +/* QLogic qed NIC Driver
> + * Copyright (c) 2015 QLogic Corporation
> + *
> + * This software is available under the terms of the GNU General Public 
> License
> + * (GPL) Version 2, available from the file COPYING in the main directory of
> + * this source tree.
> + */
[...]
> +/****************************************************************************
> +* Copyright(c) 2015 Qlogic Corporation, all rights reserved
> +* Proprietary and Confidential Information.
> +*
> +* This source file is the property of Qlogic Corporation, and
> +* may not be copied or distributed in any isomorphic form without
> +* the prior written consent of Qlogic Corporation.

Oops.

[...]
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c 
> b/drivers/net/ethernet/qlogic/qed/qed_hw.c
> new file mode 100644
> index 0000000..1512b72
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c
[...]
> +int qed_dmae_info_alloc(struct qed_hwfn *p_hwfn)
> +{
> +     dma_addr_t *p_addr = &p_hwfn->dmae_info.completion_word_phys_addr;
> +     struct dmae_cmd **p_cmd = &p_hwfn->dmae_info.p_dmae_cmd;
> +     u32 **p_buff = &p_hwfn->dmae_info.p_intermediate_buffer;
> +     u32 **p_comp = &p_hwfn->dmae_info.p_completion_word;
> +
> +     *p_comp = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
> +                                  sizeof(u32),
> +                                  p_addr,
> +                                  GFP_KERNEL);
> +     if (!*p_comp) {
> +             DP_NOTICE(p_hwfn, "Failed to allocate `p_completion_word'\n");
> +             qed_dmae_info_free(p_hwfn);
> +             return -ENOMEM;
> +     }
> +
> +     p_addr = &p_hwfn->dmae_info.dmae_cmd_phys_addr;
> +     *p_cmd = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
> +                                 sizeof(struct dmae_cmd),
> +                                 p_addr, GFP_KERNEL);
> +     if (!*p_cmd) {
> +             DP_NOTICE(p_hwfn, "Failed to allocate `struct dmae_cmd'\n");
> +             qed_dmae_info_free(p_hwfn);
> +             return -ENOMEM;
> +     }
> +
> +     p_addr  = &p_hwfn->dmae_info.intermediate_buffer_phys_addr;
> +     *p_buff = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
> +                                  sizeof(u32) * DMAE_MAX_RW_SIZE,
> +                                  p_addr, GFP_KERNEL);
> +     if (!*p_buff) {
> +             DP_NOTICE(p_hwfn, "Failed to allocate `intermediate_buffer'\n");
> +             qed_dmae_info_free(p_hwfn);
> +             return -ENOMEM;
> +     }

"qed_dmae_info_free(p_hwfn); ... return -ENOMEM;" is repeated three times.

[...]
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c 
> b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
> new file mode 100644
> index 0000000..c622ffb
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
[...]
> +/* Prepare Tx PQ mapping runtime init values for the specified PF */
> +static void qed_tx_pq_map_rt_init(
> +     struct qed_hwfn                 *p_hwfn,
> +     struct qed_ptt                  *p_ptt,
> +     u8                              port_id,
> +     u8                              pf_id,
> +     u8
> +     max_phys_tcs_per_port,
> +     bool                            is_first_pf,
> +     u32                             num_pf_cids,
> +     u32                             num_vf_cids,
> +     u16                             start_pq,
> +     u16                             num_pf_pqs,
> +     u16                             num_vf_pqs,
> +     u8                              start_vport,
> +     u32
> +     base_mem_addr_4kb,
> +     struct init_qm_pq_params        *pq_params,
> +     struct init_qm_vport_params     *vport_params)
> +{
> +     u16     i, pq_id, pq_group;
> +     u16     num_pqs         = num_pf_pqs + num_vf_pqs;
> +     u16     first_pq_group  = start_pq / QM_PF_QUEUE_GROUP_SIZE;
> +     u16     last_pq_group   =
> +             (start_pq + num_pqs - 1) / QM_PF_QUEUE_GROUP_SIZE;
> +     bool    is_bb_a0 = QED_IS_BB_A0(p_hwfn->cdev);
> +
> +     /* a bit per Tx PQ indicating if the PQ is associated with a VF */
> +     u32     tx_pq_vf_mask[MAX_QM_TX_QUEUES /
> +                           QM_PF_QUEUE_GROUP_SIZE] = { 0 };
> +     u32     tx_pq_vf_mask_width
> +             = is_bb_a0 ? 32 : QM_PF_QUEUE_GROUP_SIZE;
> +     u32     num_tx_pq_vf_masks
> +             = MAX_QM_TX_QUEUES / tx_pq_vf_mask_width;
> +     u32     pq_mem_4kb
> +             = QM_PQ_MEM_4KB(num_pf_cids);
> +     u32     vport_pq_mem_4kb
> +             = QM_PQ_MEM_4KB(num_vf_cids);
> +     u32     mem_addr_4kb
> +             = base_mem_addr_4kb;

Broken style.

> +
> +     /* set mapping from PQ group to PF */
> +     for (pq_group = first_pq_group; pq_group <= last_pq_group; pq_group++)
> +             STORE_RT_REG(p_hwfn, QM_REG_PQTX2PF_0_RT_OFFSET + pq_group,
> +                          (u32)(pf_id));
> +     /* set PQ sizes */
> +     STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_0_RT_OFFSET,
> +                  QM_PQ_SIZE_256B(num_pf_cids));
> +     STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_1_RT_OFFSET,
> +                  QM_PQ_SIZE_256B(num_vf_cids));
> +     /* go over all Tx PQs */
> +     for (i = 0, pq_id = start_pq; i < num_pqs; i++, pq_id++) {
> +             struct qm_rf_pq_map     tx_pq_map;
> +             u8                      voq     = VOQ(port_id,
> +                                                   pq_params[i].tc_id,
> +                                                   max_phys_tcs_per_port);
> +             bool    is_vf_pq                = (i >= num_pf_pqs);
> +
> +             /* update first Tx PQ of VPORT/TC */
> +             u8      vport_id_in_pf =
> +                     pq_params[i].vport_id - start_vport;
> +             u16     first_tx_pq_id =
> +                     vport_params[vport_id_in_pf].first_tx_pq_id[pq_params[i]
> +                                                                 .tc_id];
> +             if (first_tx_pq_id == QM_INVALID_PQ_ID) {
> +                     /* create new VP PQ */
> +                     vport_params[vport_id_in_pf].first_tx_pq_id[pq_params[i]
> +                                                                 .tc_id] =
> +                             pq_id;

Imho you won't avoid moving the body of the "for" loop in its own helper.

[...]
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c 
> b/drivers/net/ethernet/qlogic/qed/qed_spq.c
> new file mode 100644
> index 0000000..9dcc02f
> --- /dev/null
> +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
[...]
> +int
> +qed_spq_get_entry(struct qed_hwfn    *p_hwfn,
> +               struct qed_spq_entry  **pp_ent)
> +{
> +     struct qed_spq          *p_spq  = p_hwfn->p_spq;
> +     struct qed_spq_entry    *p_ent  = NULL;
> +
> +     spin_lock_bh(&p_spq->lock);
> +
> +     if (list_empty(&p_spq->free_pool)) {
> +             p_ent = kzalloc(sizeof(*p_ent), GFP_ATOMIC);
> +             if (!p_ent) {
> +                     spin_unlock_bh(&p_spq->lock);
> +                     return -ENOMEM;

Nit:
                        rc = -ENOMEM;
                        goto out_unlock;

-- 
Ueimor
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to