qed: Use dmae to write to widebus registers in fw_funcs
authorMichal Kalderon <michal.kalderon@marvell.com>
Mon, 27 Jan 2020 13:26:11 +0000 (15:26 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Jan 2020 13:35:32 +0000 (14:35 +0100)
There are several wide-bus registers written to by the fw_funcs
that require using the dmae for atomicity. Therefore using the dmae
channel functionality was added to the fw_funcs file, since the code
is very similar to the previously used code, the structures used were
moved to qed_hsi. Due to FW conventions, the names of the flags in the
struct changed. Since this required slight modification in the places
that set the flags the code was modified to use GET/SET FIELD macros.

Signed-off-by: Ariel Elior <ariel.elior@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_dev_api.h
drivers/net/ethernet/qlogic/qed/qed_hsi.h
drivers/net/ethernet/qlogic/qed/qed_hw.c
drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
drivers/net/ethernet/qlogic/qed/qed_init_ops.c
drivers/net/ethernet/qlogic/qed/qed_sriov.c

index 249fcc3dc13884193595e08afdb69f216ff7f863..479d98e6187ac8e72cf8136f8238e7d43be9a244 100644 (file)
@@ -907,7 +907,7 @@ qed_llh_access_filter(struct qed_hwfn *p_hwfn,
        /* Filter value */
        addr = NIG_REG_LLH_FUNC_FILTER_VALUE + 2 * filter_idx * 0x4;
 
-       params.flags = QED_DMAE_FLAG_PF_DST;
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_DST_PF_VALID, 0x1);
        params.dst_pfid = pfid;
        rc = qed_dmae_host2grc(p_hwfn,
                               p_ptt,
index 47376d4d071f853cb013873766a99460268ed9cb..eb4808b3bf6793c635f8bcd860245f43e6a69329 100644 (file)
@@ -230,30 +230,6 @@ enum qed_dmae_address_type_t {
        QED_DMAE_ADDRESS_GRC
 };
 
-/* value of flags If QED_DMAE_FLAG_RW_REPL_SRC flag is set and the
- * source is a block of length DMAE_MAX_RW_SIZE and the
- * destination is larger, the source block will be duplicated as
- * many times as required to fill the destination block. This is
- * used mostly to write a zeroed buffer to destination address
- * using DMA
- */
-#define QED_DMAE_FLAG_RW_REPL_SRC      0x00000001
-#define QED_DMAE_FLAG_VF_SRC           0x00000002
-#define QED_DMAE_FLAG_VF_DST           0x00000004
-#define QED_DMAE_FLAG_COMPLETION_DST   0x00000008
-#define QED_DMAE_FLAG_PORT             0x00000010
-#define QED_DMAE_FLAG_PF_SRC           0x00000020
-#define QED_DMAE_FLAG_PF_DST           0x00000040
-
-struct qed_dmae_params {
-       u32 flags; /* consists of QED_DMAE_FLAG_* values */
-       u8 src_vfid;
-       u8 dst_vfid;
-       u8 port_id;
-       u8 src_pfid;
-       u8 dst_pfid;
-};
-
 /**
  * @brief qed_dmae_host2grc - copy data from source addr to
  * dmae registers using the given ptt
index 5ac68ec01a041f70569663a4dd91b92a2c204e8a..cced2ce365dea5df4d69ed431b9c5f16cb306b9b 100644 (file)
@@ -1435,7 +1435,11 @@ struct dmae_cmd {
        __le16 crc16;
        __le16 crc16_c;
        __le16 crc10;
-       __le16 reserved;
+       __le16 error_bit_reserved;
+#define DMAE_CMD_ERROR_BIT_MASK        0x1
+#define DMAE_CMD_ERROR_BIT_SHIFT       0
+#define DMAE_CMD_RESERVED_MASK        0x7FFF
+#define DMAE_CMD_RESERVED_SHIFT        1
        __le16 xsum16;
        __le16 xsum8;
 };
@@ -1566,6 +1570,41 @@ struct e4_ystorm_core_conn_ag_ctx {
        __le32 reg3;
 };
 
+/* DMAE parameters */
+struct qed_dmae_params {
+       u32 flags;
+/* If QED_DMAE_PARAMS_RW_REPL_SRC flag is set and the
+ * source is a block of length DMAE_MAX_RW_SIZE and the
+ * destination is larger, the source block will be duplicated as
+ * many times as required to fill the destination block. This is
+ * used mostly to write a zeroed buffer to destination address
+ * using DMA
+ */
+#define QED_DMAE_PARAMS_RW_REPL_SRC_MASK       0x1
+#define QED_DMAE_PARAMS_RW_REPL_SRC_SHIFT      0
+#define QED_DMAE_PARAMS_SRC_VF_VALID_MASK      0x1
+#define QED_DMAE_PARAMS_SRC_VF_VALID_SHIFT     1
+#define QED_DMAE_PARAMS_DST_VF_VALID_MASK      0x1
+#define QED_DMAE_PARAMS_DST_VF_VALID_SHIFT     2
+#define QED_DMAE_PARAMS_COMPLETION_DST_MASK    0x1
+#define QED_DMAE_PARAMS_COMPLETION_DST_SHIFT   3
+#define QED_DMAE_PARAMS_PORT_VALID_MASK                0x1
+#define QED_DMAE_PARAMS_PORT_VALID_SHIFT       4
+#define QED_DMAE_PARAMS_SRC_PF_VALID_MASK      0x1
+#define QED_DMAE_PARAMS_SRC_PF_VALID_SHIFT     5
+#define QED_DMAE_PARAMS_DST_PF_VALID_MASK      0x1
+#define QED_DMAE_PARAMS_DST_PF_VALID_SHIFT     6
+#define QED_DMAE_PARAMS_RESERVED_MASK          0x1FFFFFF
+#define QED_DMAE_PARAMS_RESERVED_SHIFT         7
+       u8 src_vfid;
+       u8 dst_vfid;
+       u8 port_id;
+       u8 src_pfid;
+       u8 dst_pfid;
+       u8 reserved1;
+       __le16 reserved2;
+};
+
 /* IGU cleanup command */
 struct igu_cleanup {
        __le32 sb_id_and_flags;
index a4de9e3ef72c9f7efa426d6c756a66e24458035e..4ab8cfaf63d16dc03178f1b09c41c0eba855bb68 100644 (file)
@@ -393,7 +393,7 @@ u32 qed_vfid_to_concrete(struct qed_hwfn *p_hwfn, u8 vfid)
 
 /* DMAE */
 #define QED_DMAE_FLAGS_IS_SET(params, flag) \
-       ((params) != NULL && ((params)->flags & QED_DMAE_FLAG_##flag))
+       ((params) != NULL && GET_FIELD((params)->flags, QED_DMAE_PARAMS_##flag))
 
 static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
                            const u8 is_src_type_grc,
@@ -408,62 +408,55 @@ static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
         * 0- The source is the PCIe
         * 1- The source is the GRC.
         */
-       opcode |= (is_src_type_grc ? DMAE_CMD_SRC_MASK_GRC
-                                  : DMAE_CMD_SRC_MASK_PCIE) <<
-                  DMAE_CMD_SRC_SHIFT;
-       src_pfid = QED_DMAE_FLAGS_IS_SET(p_params, PF_SRC) ?
-                  p_params->src_pfid : p_hwfn->rel_pf_id;
-       opcode |= ((src_pfid & DMAE_CMD_SRC_PF_ID_MASK) <<
-                  DMAE_CMD_SRC_PF_ID_SHIFT);
+       SET_FIELD(opcode, DMAE_CMD_SRC,
+                 (is_src_type_grc ? dmae_cmd_src_grc : dmae_cmd_src_pcie));
+       src_pfid = QED_DMAE_FLAGS_IS_SET(p_params, SRC_PF_VALID) ?
+           p_params->src_pfid : p_hwfn->rel_pf_id;
+       SET_FIELD(opcode, DMAE_CMD_SRC_PF_ID, src_pfid);
 
        /* The destination of the DMA can be: 0-None 1-PCIe 2-GRC 3-None */
-       opcode |= (is_dst_type_grc ? DMAE_CMD_DST_MASK_GRC
-                                  : DMAE_CMD_DST_MASK_PCIE) <<
-                  DMAE_CMD_DST_SHIFT;
-       dst_pfid = QED_DMAE_FLAGS_IS_SET(p_params, PF_DST) ?
-                  p_params->dst_pfid : p_hwfn->rel_pf_id;
-       opcode |= ((dst_pfid & DMAE_CMD_DST_PF_ID_MASK) <<
-                  DMAE_CMD_DST_PF_ID_SHIFT);
+       SET_FIELD(opcode, DMAE_CMD_DST,
+                 (is_dst_type_grc ? dmae_cmd_dst_grc : dmae_cmd_dst_pcie));
+       dst_pfid = QED_DMAE_FLAGS_IS_SET(p_params, DST_PF_VALID) ?
+           p_params->dst_pfid : p_hwfn->rel_pf_id;
+       SET_FIELD(opcode, DMAE_CMD_DST_PF_ID, dst_pfid);
+
 
        /* Whether to write a completion word to the completion destination:
         * 0-Do not write a completion word
         * 1-Write the completion word
         */
-       opcode |= (DMAE_CMD_COMP_WORD_EN_MASK << DMAE_CMD_COMP_WORD_EN_SHIFT);
-       opcode |= (DMAE_CMD_SRC_ADDR_RESET_MASK <<
-                  DMAE_CMD_SRC_ADDR_RESET_SHIFT);
+       SET_FIELD(opcode, DMAE_CMD_COMP_WORD_EN, 1);
+       SET_FIELD(opcode, DMAE_CMD_SRC_ADDR_RESET, 1);
 
        if (QED_DMAE_FLAGS_IS_SET(p_params, COMPLETION_DST))
-               opcode |= (1 << DMAE_CMD_COMP_FUNC_SHIFT);
+               SET_FIELD(opcode, DMAE_CMD_COMP_FUNC, 1);
 
-       opcode |= (DMAE_CMD_ENDIANITY << DMAE_CMD_ENDIANITY_MODE_SHIFT);
+       /* swapping mode 3 - big endian */
+       SET_FIELD(opcode, DMAE_CMD_ENDIANITY_MODE, DMAE_CMD_ENDIANITY);
 
-       port_id = (QED_DMAE_FLAGS_IS_SET(p_params, PORT)) ?
-                  p_params->port_id : p_hwfn->port_id;
-       opcode |= (port_id << DMAE_CMD_PORT_ID_SHIFT);
+       port_id = (QED_DMAE_FLAGS_IS_SET(p_params, PORT_VALID)) ?
+           p_params->port_id : p_hwfn->port_id;
+       SET_FIELD(opcode, DMAE_CMD_PORT_ID, port_id);
 
        /* reset source address in next go */
-       opcode |= (DMAE_CMD_SRC_ADDR_RESET_MASK <<
-                  DMAE_CMD_SRC_ADDR_RESET_SHIFT);
+       SET_FIELD(opcode, DMAE_CMD_SRC_ADDR_RESET, 1);
 
        /* reset dest address in next go */
-       opcode |= (DMAE_CMD_DST_ADDR_RESET_MASK <<
-                  DMAE_CMD_DST_ADDR_RESET_SHIFT);
+       SET_FIELD(opcode, DMAE_CMD_DST_ADDR_RESET, 1);
 
        /* SRC/DST VFID: all 1's - pf, otherwise VF id */
-       if (QED_DMAE_FLAGS_IS_SET(p_params, VF_SRC)) {
-               opcode |= 1 << DMAE_CMD_SRC_VF_ID_VALID_SHIFT;
-               opcode_b |= p_params->src_vfid << DMAE_CMD_SRC_VF_ID_SHIFT;
+       if (QED_DMAE_FLAGS_IS_SET(p_params, SRC_VF_VALID)) {
+               SET_FIELD(opcode, DMAE_CMD_SRC_VF_ID_VALID, 1);
+               SET_FIELD(opcode_b, DMAE_CMD_SRC_VF_ID, p_params->src_vfid);
        } else {
-               opcode_b |= DMAE_CMD_SRC_VF_ID_MASK <<
-                           DMAE_CMD_SRC_VF_ID_SHIFT;
+               SET_FIELD(opcode_b, DMAE_CMD_SRC_VF_ID, 0xFF);
        }
-
-       if (QED_DMAE_FLAGS_IS_SET(p_params, VF_DST)) {
-               opcode |= 1 << DMAE_CMD_DST_VF_ID_VALID_SHIFT;
-               opcode_b |= p_params->dst_vfid << DMAE_CMD_DST_VF_ID_SHIFT;
+       if (QED_DMAE_FLAGS_IS_SET(p_params, DST_VF_VALID)) {
+               SET_FIELD(opcode, DMAE_CMD_DST_VF_ID_VALID, 1);
+               SET_FIELD(opcode_b, DMAE_CMD_DST_VF_ID, p_params->dst_vfid);
        } else {
-               opcode_b |= DMAE_CMD_DST_VF_ID_MASK << DMAE_CMD_DST_VF_ID_SHIFT;
+               SET_FIELD(opcode_b, DMAE_CMD_DST_VF_ID, 0xFF);
        }
 
        p_hwfn->dmae_info.p_dmae_cmd->opcode = cpu_to_le32(opcode);
index 40b8a52dbfa3f6da15b791e8a26c132ae30bb403..6fdf9ab98685dfb013911f25b6c1c6ad1837862e 100644 (file)
@@ -1011,6 +1011,56 @@ bool qed_send_qm_stop_cmd(struct qed_hwfn *p_hwfn,
 #define PRS_ETH_TUNN_OUTPUT_FORMAT     0xF4DAB910
 #define PRS_ETH_OUTPUT_FORMAT          0xFFFF4910
 
+#define ARR_REG_WR(dev, ptt, addr, arr,        arr_size) \
+       do { \
+               u32 i; \
+               \
+               for (i = 0; i < (arr_size); i++) \
+                       qed_wr(dev, ptt, \
+                              ((addr) + (4 * i)), \
+                              ((u32 *)&(arr))[i]); \
+       } while (0)
+
+/**
+ * @brief qed_dmae_to_grc - is an internal function - writes from host to
+ * wide-bus registers (split registers are not supported yet)
+ *
+ * @param p_hwfn - HW device data
+ * @param p_ptt - ptt window used for writing the registers.
+ * @param p_data - pointer to source data.
+ * @param addr - Destination register address.
+ * @param len_in_dwords - data length in DWARDS (u32)
+ */
+static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn,
+                          struct qed_ptt *p_ptt,
+                          u32 *p_data, u32 addr, u32 len_in_dwords)
+{
+       struct qed_dmae_params params = {};
+       int rc;
+
+       if (!p_data)
+               return -1;
+
+       /* Set DMAE params */
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
+
+       /* Execute DMAE command */
+       rc = qed_dmae_host2grc(p_hwfn, p_ptt,
+                              (u64)(uintptr_t)(p_data),
+                              addr, len_in_dwords, &params);
+
+       /* If not read using DMAE, read using GRC */
+       if (rc) {
+               DP_VERBOSE(p_hwfn,
+                          QED_MSG_DEBUG,
+                          "Failed writing to chip using DMAE, using GRC instead\n");
+               /* write to registers using GRC */
+               ARR_REG_WR(p_hwfn, p_ptt, addr, p_data, len_in_dwords);
+       }
+
+       return len_in_dwords;
+}
+
 void qed_set_vxlan_dest_port(struct qed_hwfn *p_hwfn,
                             struct qed_ptt *p_ptt, u16 dest_port)
 {
@@ -1195,6 +1245,8 @@ void qed_set_vxlan_no_l2_enable(struct qed_hwfn *p_hwfn,
 
 void qed_gft_disable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u16 pf_id)
 {
+       struct regpair ram_line = { };
+
        /* Disable gft search for PF */
        qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 0);
 
@@ -1204,12 +1256,9 @@ void qed_gft_disable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u16 pf_id)
        qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id, 0);
 
        /* Zero ramline */
-       qed_wr(p_hwfn,
-              p_ptt, PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id, 0);
-       qed_wr(p_hwfn,
-              p_ptt,
-              PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id + REG_SIZE,
-              0);
+       qed_dmae_to_grc(p_hwfn, p_ptt, (u32 *)&ram_line,
+                       PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
+                       sizeof(ram_line) / REG_SIZE);
 }
 
 void qed_gft_config(struct qed_hwfn *p_hwfn,
@@ -1320,24 +1369,17 @@ void qed_gft_config(struct qed_hwfn *p_hwfn,
 
        qed_wr(p_hwfn,
               p_ptt, PRS_REG_SEARCH_NON_IP_AS_GFT, search_non_ip_as_gft);
-       qed_wr(p_hwfn,
-              p_ptt,
-              PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
-              ram_line.lo);
-       qed_wr(p_hwfn,
-              p_ptt,
-              PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id + REG_SIZE,
-              ram_line.hi);
+       qed_dmae_to_grc(p_hwfn, p_ptt, (u32 *)&ram_line,
+                       PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
+                       sizeof(ram_line) / REG_SIZE);
 
        /* Set default profile so that no filter match will happen */
-       qed_wr(p_hwfn,
-              p_ptt,
-              PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
-              PRS_GFT_CAM_LINES_NO_MATCH, 0xffffffff);
-       qed_wr(p_hwfn,
-              p_ptt,
-              PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
-              PRS_GFT_CAM_LINES_NO_MATCH + REG_SIZE, 0x3ff);
+       ram_line.lo = 0xffffffff;
+       ram_line.hi = 0x3ff;
+       qed_dmae_to_grc(p_hwfn, p_ptt, (u32 *)&ram_line,
+                       PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
+                       PRS_GFT_CAM_LINES_NO_MATCH,
+                       sizeof(ram_line) / REG_SIZE);
 
        /* Enable gft search */
        qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 1);
index ef22a35962951d2683fe9dddc39753a54e567f46..31222b3e393664731d3dbc2387b11563381c0bb2 100644 (file)
@@ -215,7 +215,7 @@ static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
         * 3. p_hwfb->temp_data,
         * 4. fill_count
         */
-       params.flags = QED_DMAE_FLAG_RW_REPL_SRC;
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_RW_REPL_SRC, 0x1);
        return qed_dmae_host2grc(p_hwfn, p_ptt,
                                 (uintptr_t)(&zero_buffer[0]),
                                 addr, fill_count, &params);
index fe4b740de14c559ac0ae3e8354975bb9ebde1b03..66876af814c4737e246e231633561b11da76d746 100644 (file)
@@ -352,7 +352,7 @@ static int qed_iov_post_vf_bulletin(struct qed_hwfn *p_hwfn,
 
        /* propagate bulletin board via dmae to vm memory */
        memset(&params, 0, sizeof(params));
-       params.flags = QED_DMAE_FLAG_VF_DST;
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_DST_VF_VALID, 0x1);
        params.dst_vfid = p_vf->abs_vf_id;
        return qed_dmae_host2host(p_hwfn, p_ptt, p_vf->bulletin.phys,
                                  p_vf->vf_bulletin, p_vf->bulletin.size / 4,
@@ -1225,8 +1225,8 @@ static void qed_iov_send_response(struct qed_hwfn *p_hwfn,
 
        eng_vf_id = p_vf->abs_vf_id;
 
-       memset(&params, 0, sizeof(struct qed_dmae_params));
-       params.flags = QED_DMAE_FLAG_VF_DST;
+       memset(&params, 0, sizeof(params));
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_DST_VF_VALID, 0x1);
        params.dst_vfid = eng_vf_id;
 
        qed_dmae_host2host(p_hwfn, p_ptt, mbx->reply_phys + sizeof(u64),
@@ -4103,8 +4103,9 @@ static int qed_iov_copy_vf_msg(struct qed_hwfn *p_hwfn, struct qed_ptt *ptt,
        if (!vf_info)
                return -EINVAL;
 
-       memset(&params, 0, sizeof(struct qed_dmae_params));
-       params.flags = QED_DMAE_FLAG_VF_SRC | QED_DMAE_FLAG_COMPLETION_DST;
+       memset(&params, 0, sizeof(params));
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_SRC_VF_VALID, 0x1);
+       SET_FIELD(params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 0x1);
        params.src_vfid = vf_info->abs_vf_id;
 
        if (qed_dmae_host2host(p_hwfn, ptt,