]> git.baikalelectronics.ru Git - kernel.git/commitdiff
qed: FW 8.42.2.0 Additional ll2 type
authorMichal Kalderon <michal.kalderon@marvell.com>
Mon, 27 Jan 2020 13:26:12 +0000 (15:26 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Jan 2020 13:35:32 +0000 (14:35 +0100)
LL2 queues were a limited resource due to FW constraints.
This FW introduced a new resource which is a context based ll2 queue
(memory on host). The additional ll2 queues are required for RDMA SRIOV.
The code refers to the previous ll2 queues as ram-based or legacy, and the
new queues as ctx-based.
This change decreased the "legacy" ram-based queues therefore the first ll2
queue used for iWARP was converted to the ctx-based ll2 queue.
This feature also exposed a bug in the DIRECT_REG_WR64 macro implementation
which didn't have an effect in other use cases.

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.h
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_hsi.h
drivers/net/ethernet/qlogic/qed/qed_iscsi.c
drivers/net/ethernet/qlogic/qed/qed_iwarp.c
drivers/net/ethernet/qlogic/qed/qed_ll2.c
drivers/net/ethernet/qlogic/qed/qed_ll2.h
drivers/net/ethernet/qlogic/qed/qed_mcp.c
include/linux/qed/common_hsi.h
include/linux/qed/qed_if.h
include/linux/qed/qed_ll2_if.h

index 8ec46bf409c2c8c66c402d4412aac821ecf70fb3..cfa45fb9a5a426b400678cce688a81a0f84d64e3 100644 (file)
@@ -253,7 +253,8 @@ enum qed_resources {
        QED_VLAN,
        QED_RDMA_CNQ_RAM,
        QED_ILT,
-       QED_LL2_QUEUE,
+       QED_LL2_RAM_QUEUE,
+       QED_LL2_CTX_QUEUE,
        QED_CMDQS_CQS,
        QED_RDMA_STATS_QUEUE,
        QED_BDQ,
index 479d98e6187ac8e72cf8136f8238e7d43be9a244..898c1f8d1530547ee553340972d89f563daeae22 100644 (file)
@@ -3565,8 +3565,10 @@ const char *qed_hw_get_resc_name(enum qed_resources res_id)
                return "RDMA_CNQ_RAM";
        case QED_ILT:
                return "ILT";
-       case QED_LL2_QUEUE:
-               return "LL2_QUEUE";
+       case QED_LL2_RAM_QUEUE:
+               return "LL2_RAM_QUEUE";
+       case QED_LL2_CTX_QUEUE:
+               return "LL2_CTX_QUEUE";
        case QED_CMDQS_CQS:
                return "CMDQS_CQS";
        case QED_RDMA_STATS_QUEUE:
@@ -3615,8 +3617,11 @@ qed_hw_set_soft_resc_size(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 
        for (res_id = 0; res_id < QED_MAX_RESC; res_id++) {
                switch (res_id) {
-               case QED_LL2_QUEUE:
-                       resc_max_val = MAX_NUM_LL2_RX_QUEUES;
+               case QED_LL2_RAM_QUEUE:
+                       resc_max_val = MAX_NUM_LL2_RX_RAM_QUEUES;
+                       break;
+               case QED_LL2_CTX_QUEUE:
+                       resc_max_val = MAX_NUM_LL2_RX_CTX_QUEUES;
                        break;
                case QED_RDMA_CNQ_RAM:
                        /* No need for a case for QED_CMDQS_CQS since
@@ -3691,8 +3696,11 @@ int qed_hw_get_dflt_resc(struct qed_hwfn *p_hwfn,
                *p_resc_num = (b_ah ? PXP_NUM_ILT_RECORDS_K2 :
                               PXP_NUM_ILT_RECORDS_BB) / num_funcs;
                break;
-       case QED_LL2_QUEUE:
-               *p_resc_num = MAX_NUM_LL2_RX_QUEUES / num_funcs;
+       case QED_LL2_RAM_QUEUE:
+               *p_resc_num = MAX_NUM_LL2_RX_RAM_QUEUES / num_funcs;
+               break;
+       case QED_LL2_CTX_QUEUE:
+               *p_resc_num = MAX_NUM_LL2_RX_CTX_QUEUES / num_funcs;
                break;
        case QED_RDMA_CNQ_RAM:
        case QED_CMDQS_CQS:
index cced2ce365dea5df4d69ed431b9c5f16cb306b9b..f0e5195cae011f9ad9f50e601853e21f1d599fb0 100644 (file)
@@ -98,6 +98,7 @@ enum core_event_opcode {
        CORE_EVENT_RX_QUEUE_STOP,
        CORE_EVENT_RX_QUEUE_FLUSH,
        CORE_EVENT_TX_QUEUE_UPDATE,
+       CORE_EVENT_QUEUE_STATS_QUERY,
        MAX_CORE_EVENT_OPCODE
 };
 
@@ -116,7 +117,7 @@ struct core_ll2_port_stats {
        struct regpair gsi_crcchksm_error;
 };
 
-/* Ethernet TX Per Queue Stats */
+/* LL2 TX Per Queue Stats */
 struct core_ll2_pstorm_per_queue_stat {
        struct regpair sent_ucast_bytes;
        struct regpair sent_mcast_bytes;
@@ -124,13 +125,13 @@ struct core_ll2_pstorm_per_queue_stat {
        struct regpair sent_ucast_pkts;
        struct regpair sent_mcast_pkts;
        struct regpair sent_bcast_pkts;
+       struct regpair error_drop_pkts;
 };
 
 /* Light-L2 RX Producers in Tstorm RAM */
 struct core_ll2_rx_prod {
        __le16 bd_prod;
        __le16 cqe_prod;
-       __le32 reserved;
 };
 
 struct core_ll2_tstorm_per_queue_stat {
@@ -147,6 +148,18 @@ struct core_ll2_ustorm_per_queue_stat {
        struct regpair rcv_bcast_pkts;
 };
 
+/* Structure for doorbell data, in PWM mode, for RX producers update. */
+struct core_pwm_prod_update_data {
+       __le16 icid; /* internal CID */
+       u8 reserved0;
+       u8 params;
+#define CORE_PWM_PROD_UPDATE_DATA_AGG_CMD_MASK   0x3
+#define CORE_PWM_PROD_UPDATE_DATA_AGG_CMD_SHIFT   0
+#define CORE_PWM_PROD_UPDATE_DATA_RESERVED1_MASK  0x3F /* Set 0 */
+#define CORE_PWM_PROD_UPDATE_DATA_RESERVED1_SHIFT 2
+       struct core_ll2_rx_prod prod; /* Producers */
+};
+
 /* Core Ramrod Command IDs (light L2) */
 enum core_ramrod_cmd_id {
        CORE_RAMROD_UNUSED,
@@ -156,6 +169,7 @@ enum core_ramrod_cmd_id {
        CORE_RAMROD_TX_QUEUE_STOP,
        CORE_RAMROD_RX_QUEUE_FLUSH,
        CORE_RAMROD_TX_QUEUE_UPDATE,
+       CORE_RAMROD_QUEUE_STATS_QUERY,
        MAX_CORE_RAMROD_CMD_ID
 };
 
@@ -274,8 +288,11 @@ struct core_rx_start_ramrod_data {
        u8 mf_si_mcast_accept_all;
        struct core_rx_action_on_error action_on_error;
        u8 gsi_offload_flag;
+       u8 vport_id_valid;
+       u8 vport_id;
+       u8 zero_prod_flg;
        u8 wipe_inner_vlan_pri_en;
-       u8 reserved[5];
+       u8 reserved[2];
 };
 
 /* Ramrod data for rx queue stop ramrod */
@@ -352,8 +369,11 @@ struct core_tx_start_ramrod_data {
        __le16 pbl_size;
        __le16 qm_pq_id;
        u8 gsi_offload_flag;
+       u8 ctx_stats_en;
+       u8 vport_id_valid;
        u8 vport_id;
-       u8 resrved[2];
+       u8 enforce_security_flag;
+       u8 reserved[7];
 };
 
 /* Ramrod data for tx queue stop ramrod */
@@ -761,7 +781,7 @@ struct e4_tstorm_core_conn_ag_ctx {
        __le16 word1;
        __le16 word2;
        __le16 word3;
-       __le32 reg9;
+       __le32 ll2_rx_prod;
        __le32 reg10;
 };
 
@@ -844,6 +864,11 @@ struct ustorm_core_conn_st_ctx {
        __le32 reserved[4];
 };
 
+/* The core storm context for the Tstorm */
+struct tstorm_core_conn_st_ctx {
+       __le32 reserved[4];
+};
+
 /* core connection context */
 struct e4_core_conn_context {
        struct ystorm_core_conn_st_ctx ystorm_st_context;
@@ -857,6 +882,8 @@ struct e4_core_conn_context {
        struct mstorm_core_conn_st_ctx mstorm_st_context;
        struct ustorm_core_conn_st_ctx ustorm_st_context;
        struct regpair ustorm_st_padding[2];
+       struct tstorm_core_conn_st_ctx tstorm_st_context;
+       struct regpair tstorm_st_padding[2];
 };
 
 struct eth_mstorm_per_pf_stat {
@@ -12483,6 +12510,11 @@ enum resource_id_enum {
        RESOURCE_LL2_QUEUE_E = 15,
        RESOURCE_RDMA_STATS_QUEUE_E = 16,
        RESOURCE_BDQ_E = 17,
+       RESOURCE_QCN_E = 18,
+       RESOURCE_LLH_FILTER_E = 19,
+       RESOURCE_VF_MAC_ADDR = 20,
+       RESOURCE_LL2_CQS_E = 21,
+       RESOURCE_VF_CNQS = 22,
        RESOURCE_MAX_NUM,
        RESOURCE_NUM_INVALID = 0xFFFFFFFF
 };
index 5585c18053ec482a7c0787e7f62bf135bd206cb3..8ee668d66b4bb1cd614bbf78ea9768dfb8891baa 100644 (file)
@@ -213,8 +213,9 @@ qed_sp_iscsi_func_start(struct qed_hwfn *p_hwfn,
        p_init->num_sq_pages_in_ring = p_params->num_sq_pages_in_ring;
        p_init->num_r2tq_pages_in_ring = p_params->num_r2tq_pages_in_ring;
        p_init->num_uhq_pages_in_ring = p_params->num_uhq_pages_in_ring;
-       p_init->ll2_rx_queue_id = p_hwfn->hw_info.resc_start[QED_LL2_QUEUE] +
-                                 p_params->ll2_ooo_queue_id;
+       p_init->ll2_rx_queue_id =
+           p_hwfn->hw_info.resc_start[QED_LL2_RAM_QUEUE] +
+           p_params->ll2_ooo_queue_id;
 
        p_init->func_params.log_page_size = p_params->log_page_size;
        val = p_params->num_tasks;
index 65ec16a3165844aa29876dcaf19bf240ec783310..d2fe61a5cf567a58ebc4b7ec2bc7d72b78e623c9 100644 (file)
@@ -137,8 +137,8 @@ qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
                         struct iwarp_init_func_ramrod_data *p_ramrod)
 {
        p_ramrod->iwarp.ll2_ooo_q_index =
-               RESC_START(p_hwfn, QED_LL2_QUEUE) +
-               p_hwfn->p_rdma_info->iwarp.ll2_ooo_handle;
+           RESC_START(p_hwfn, QED_LL2_RAM_QUEUE) +
+           p_hwfn->p_rdma_info->iwarp.ll2_ooo_handle;
 
        p_ramrod->tcp.max_fin_rt = QED_IWARP_MAX_FIN_RT_DEFAULT;
 
@@ -2651,6 +2651,8 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
 
        memset(&data, 0, sizeof(data));
        data.input.conn_type = QED_LL2_TYPE_IWARP;
+       /* SYN will use ctx based queues */
+       data.input.rx_conn_type = QED_LL2_RX_TYPE_CTX;
        data.input.mtu = params->max_mtu;
        data.input.rx_num_desc = QED_IWARP_LL2_SYN_RX_SIZE;
        data.input.tx_num_desc = QED_IWARP_LL2_SYN_TX_SIZE;
@@ -2683,6 +2685,8 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
 
        /* Start OOO connection */
        data.input.conn_type = QED_LL2_TYPE_OOO;
+       /* OOO/unaligned will use legacy ll2 queues (ram based) */
+       data.input.rx_conn_type = QED_LL2_RX_TYPE_LEGACY;
        data.input.mtu = params->max_mtu;
 
        n_ooo_bufs = (QED_IWARP_MAX_OOO * rcv_wnd_size) /
index 19a1a58d60f89d6ffc6cab8f84971a9f7fdc1c39..037e5978787e554af3d1289f77ecadf4524a386a 100644 (file)
@@ -962,7 +962,7 @@ static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn,
                return rc;
 
        p_ramrod = &p_ent->ramrod.core_rx_queue_start;
-
+       memset(p_ramrod, 0, sizeof(*p_ramrod));
        p_ramrod->sb_id = cpu_to_le16(qed_int_get_sp_sb_id(p_hwfn));
        p_ramrod->sb_index = p_rx->rx_sb_index;
        p_ramrod->complete_event_flg = 1;
@@ -996,6 +996,8 @@ static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn,
 
        p_ramrod->action_on_error.error_type = action_on_error;
        p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
+       p_ramrod->zero_prod_flg = 1;
+
        return qed_spq_post(p_hwfn, p_ent, NULL);
 }
 
@@ -1317,6 +1319,25 @@ qed_ll2_set_cbs(struct qed_ll2_info *p_ll2_info, const struct qed_ll2_cbs *cbs)
        return 0;
 }
 
+static void _qed_ll2_calc_allowed_conns(struct qed_hwfn *p_hwfn,
+                                       struct qed_ll2_acquire_data *data,
+                                       u8 *start_idx, u8 *last_idx)
+{
+       /* LL2 queues handles will be split as follows:
+        * First will be the legacy queues, and then the ctx based.
+        */
+       if (data->input.rx_conn_type == QED_LL2_RX_TYPE_LEGACY) {
+               *start_idx = QED_LL2_LEGACY_CONN_BASE_PF;
+               *last_idx = *start_idx +
+                       QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF;
+       } else {
+               /* QED_LL2_RX_TYPE_CTX */
+               *start_idx = QED_LL2_CTX_CONN_BASE_PF;
+               *last_idx = *start_idx +
+                       QED_MAX_NUM_OF_CTX_LL2_CONNS_PF;
+       }
+}
+
 static enum core_error_handle
 qed_ll2_get_error_choice(enum qed_ll2_error_handle err)
 {
@@ -1337,14 +1358,16 @@ int qed_ll2_acquire_connection(void *cxt, struct qed_ll2_acquire_data *data)
        struct qed_hwfn *p_hwfn = cxt;
        qed_int_comp_cb_t comp_rx_cb, comp_tx_cb;
        struct qed_ll2_info *p_ll2_info = NULL;
-       u8 i, *p_tx_max;
+       u8 i, first_idx, last_idx, *p_tx_max;
        int rc;
 
        if (!data->p_connection_handle || !p_hwfn->p_ll2_info)
                return -EINVAL;
 
+       _qed_ll2_calc_allowed_conns(p_hwfn, data, &first_idx, &last_idx);
+
        /* Find a free connection to be used */
-       for (i = 0; (i < QED_MAX_NUM_OF_LL2_CONNECTIONS); i++) {
+       for (i = first_idx; i < last_idx; i++) {
                mutex_lock(&p_hwfn->p_ll2_info[i].mutex);
                if (p_hwfn->p_ll2_info[i].b_active) {
                        mutex_unlock(&p_hwfn->p_ll2_info[i].mutex);
@@ -1448,6 +1471,7 @@ static int qed_ll2_establish_connection_rx(struct qed_hwfn *p_hwfn,
        enum qed_ll2_error_handle error_input;
        enum core_error_handle error_mode;
        u8 action_on_error = 0;
+       int rc;
 
        if (!QED_LL2_RX_REGISTERED(p_ll2_conn))
                return 0;
@@ -1461,7 +1485,18 @@ static int qed_ll2_establish_connection_rx(struct qed_hwfn *p_hwfn,
        error_mode = qed_ll2_get_error_choice(error_input);
        SET_FIELD(action_on_error, CORE_RX_ACTION_ON_ERROR_NO_BUFF, error_mode);
 
-       return qed_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
+       rc = qed_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
+       if (rc)
+               return rc;
+
+       if (p_ll2_conn->rx_queue.ctx_based) {
+               rc = qed_db_recovery_add(p_hwfn->cdev,
+                                        p_ll2_conn->rx_queue.set_prod_addr,
+                                        &p_ll2_conn->rx_queue.db_data,
+                                        DB_REC_WIDTH_64B, DB_REC_KERNEL);
+       }
+
+       return rc;
 }
 
 static void
@@ -1475,13 +1510,41 @@ qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
        qed_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
 }
 
+static inline u8 qed_ll2_handle_to_queue_id(struct qed_hwfn *p_hwfn,
+                                           u8 handle,
+                                           u8 ll2_queue_type)
+{
+       u8 qid;
+
+       if (ll2_queue_type == QED_LL2_RX_TYPE_LEGACY)
+               return p_hwfn->hw_info.resc_start[QED_LL2_RAM_QUEUE] + handle;
+
+       /* QED_LL2_RX_TYPE_CTX
+        * FW distinguishes between the legacy queues (ram based) and the
+        * ctx based queues by the queue_id.
+        * The first MAX_NUM_LL2_RX_RAM_QUEUES queues are legacy
+        * and the queue ids above that are ctx base.
+        */
+       qid = p_hwfn->hw_info.resc_start[QED_LL2_CTX_QUEUE] +
+             MAX_NUM_LL2_RX_RAM_QUEUES;
+
+       /* See comment on the acquire connection for how the ll2
+        * queues handles are divided.
+        */
+       qid += (handle - QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF);
+
+       return qid;
+}
+
 int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
 {
-       struct qed_hwfn *p_hwfn = cxt;
-       struct qed_ll2_info *p_ll2_conn;
+       struct e4_core_conn_context *p_cxt;
        struct qed_ll2_tx_packet *p_pkt;
+       struct qed_ll2_info *p_ll2_conn;
+       struct qed_hwfn *p_hwfn = cxt;
        struct qed_ll2_rx_queue *p_rx;
        struct qed_ll2_tx_queue *p_tx;
+       struct qed_cxt_info cxt_info;
        struct qed_ptt *p_ptt;
        int rc = -EINVAL;
        u32 i, capacity;
@@ -1539,13 +1602,46 @@ int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
        rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_CORE, &p_ll2_conn->cid);
        if (rc)
                goto out;
+       cxt_info.iid = p_ll2_conn->cid;
+       rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info);
+       if (rc) {
+               DP_NOTICE(p_hwfn, "Cannot find context info for cid=%d\n",
+                         p_ll2_conn->cid);
+               goto out;
+       }
+
+       p_cxt = cxt_info.p_cxt;
+
+       memset(p_cxt, 0, sizeof(*p_cxt));
 
-       qid = p_hwfn->hw_info.resc_start[QED_LL2_QUEUE] + connection_handle;
+       qid = qed_ll2_handle_to_queue_id(p_hwfn, connection_handle,
+                                        p_ll2_conn->input.rx_conn_type);
        p_ll2_conn->queue_id = qid;
        p_ll2_conn->tx_stats_id = qid;
-       p_rx->set_prod_addr = (u8 __iomem *)p_hwfn->regview +
-                                           GTT_BAR0_MAP_REG_TSDM_RAM +
-                                           TSTORM_LL2_RX_PRODS_OFFSET(qid);
+
+       DP_VERBOSE(p_hwfn, QED_MSG_LL2,
+                  "Establishing ll2 queue. PF %d ctx_based=%d abs qid=%d\n",
+                  p_hwfn->rel_pf_id, p_ll2_conn->input.rx_conn_type, qid);
+
+       if (p_ll2_conn->input.rx_conn_type == QED_LL2_RX_TYPE_LEGACY) {
+               p_rx->set_prod_addr = p_hwfn->regview +
+                   GTT_BAR0_MAP_REG_TSDM_RAM + TSTORM_LL2_RX_PRODS_OFFSET(qid);
+       } else {
+               /* QED_LL2_RX_TYPE_CTX - using doorbell */
+               p_rx->ctx_based = 1;
+
+               p_rx->set_prod_addr = p_hwfn->doorbells +
+                       p_hwfn->dpi_start_offset +
+                       DB_ADDR_SHIFT(DQ_PWM_OFFSET_TCM_LL2_PROD_UPDATE);
+
+               /* prepare db data */
+               p_rx->db_data.icid = cpu_to_le16((u16)p_ll2_conn->cid);
+               SET_FIELD(p_rx->db_data.params,
+                         CORE_PWM_PROD_UPDATE_DATA_AGG_CMD, DB_AGG_CMD_SET);
+               SET_FIELD(p_rx->db_data.params,
+                         CORE_PWM_PROD_UPDATE_DATA_RESERVED1, 0);
+       }
+
        p_tx->doorbell_addr = (u8 __iomem *)p_hwfn->doorbells +
                                            qed_db_addr(p_ll2_conn->cid,
                                                        DQ_DEMS_LEGACY);
@@ -1556,7 +1652,6 @@ int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
                  DQ_XCM_CORE_TX_BD_PROD_CMD);
        p_tx->db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
 
-
        rc = qed_ll2_establish_connection_rx(p_hwfn, p_ll2_conn);
        if (rc)
                goto out;
@@ -1590,7 +1685,7 @@ static void qed_ll2_post_rx_buffer_notify_fw(struct qed_hwfn *p_hwfn,
                                             struct qed_ll2_rx_packet *p_curp)
 {
        struct qed_ll2_rx_packet *p_posting_packet = NULL;
-       struct core_ll2_rx_prod rx_prod = { 0, 0, 0 };
+       struct core_ll2_rx_prod rx_prod = { 0, 0 };
        bool b_notify_fw = false;
        u16 bd_prod, cq_prod;
 
@@ -1615,13 +1710,27 @@ static void qed_ll2_post_rx_buffer_notify_fw(struct qed_hwfn *p_hwfn,
 
        bd_prod = qed_chain_get_prod_idx(&p_rx->rxq_chain);
        cq_prod = qed_chain_get_prod_idx(&p_rx->rcq_chain);
-       rx_prod.bd_prod = cpu_to_le16(bd_prod);
-       rx_prod.cqe_prod = cpu_to_le16(cq_prod);
+       if (p_rx->ctx_based) {
+               /* update producer by giving a doorbell */
+               p_rx->db_data.prod.bd_prod = cpu_to_le16(bd_prod);
+               p_rx->db_data.prod.cqe_prod = cpu_to_le16(cq_prod);
+               /* Make sure chain element is updated before ringing the
+                * doorbell
+                */
+               dma_wmb();
+               DIRECT_REG_WR64(p_rx->set_prod_addr,
+                               *((u64 *)&p_rx->db_data));
+       } else {
+               rx_prod.bd_prod = cpu_to_le16(bd_prod);
+               rx_prod.cqe_prod = cpu_to_le16(cq_prod);
 
-       /* Make sure chain element is updated before ringing the doorbell */
-       dma_wmb();
+               /* Make sure chain element is updated before ringing the
+                * doorbell
+                */
+               dma_wmb();
 
-       DIRECT_REG_WR(p_rx->set_prod_addr, *((u32 *)&rx_prod));
+               DIRECT_REG_WR(p_rx->set_prod_addr, *((u32 *)&rx_prod));
+       }
 }
 
 int qed_ll2_post_rx_buffer(void *cxt,
@@ -1965,6 +2074,12 @@ int qed_ll2_terminate_connection(void *cxt, u8 connection_handle)
        if (QED_LL2_RX_REGISTERED(p_ll2_conn)) {
                p_ll2_conn->rx_queue.b_cb_registered = false;
                smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */
+
+               if (p_ll2_conn->rx_queue.ctx_based)
+                       qed_db_recovery_del(p_hwfn->cdev,
+                                           p_ll2_conn->rx_queue.set_prod_addr,
+                                           &p_ll2_conn->rx_queue.db_data);
+
                rc = qed_sp_ll2_rx_queue_stop(p_hwfn, p_ll2_conn);
                if (rc)
                        goto out;
index 5f01fbd3c0735a53b7575fb0a7ae0b22665417f8..288642d526b73c080528b5217fb09ef3420e24e6 100644 (file)
 #include "qed_sp.h"
 
 #define QED_MAX_NUM_OF_LL2_CONNECTIONS                    (4)
+/* LL2 queues handles will be split as follows:
+ * first will be legacy queues, and then the ctx based queues.
+ */
+#define QED_MAX_NUM_OF_LL2_CONNS_PF            (4)
+#define QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF   (3)
+
+#define QED_MAX_NUM_OF_CTX_LL2_CONNS_PF        \
+       (QED_MAX_NUM_OF_LL2_CONNS_PF - QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF)
+
+#define QED_LL2_LEGACY_CONN_BASE_PF     0
+#define QED_LL2_CTX_CONN_BASE_PF        QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF
+
 
 struct qed_ll2_rx_packet {
        struct list_head list_entry;
@@ -79,6 +91,7 @@ struct qed_ll2_rx_queue {
        struct qed_chain rxq_chain;
        struct qed_chain rcq_chain;
        u8 rx_sb_index;
+       u8 ctx_based;
        bool b_cb_registered;
        __le16 *p_fw_cons;
        struct list_head active_descq;
@@ -86,6 +99,7 @@ struct qed_ll2_rx_queue {
        struct list_head posting_descq;
        struct qed_ll2_rx_packet *descq_array;
        void __iomem *set_prod_addr;
+       struct core_pwm_prod_update_data db_data;
 };
 
 struct qed_ll2_tx_queue {
index 36ddb89856a869cce7087c086888d71206f6e9bd..aeac359941de04ea56de01957960acb196be324d 100644 (file)
@@ -3261,9 +3261,12 @@ static enum resource_id_enum qed_mcp_get_mfw_res_id(enum qed_resources res_id)
        case QED_ILT:
                mfw_res_id = RESOURCE_ILT_E;
                break;
-       case QED_LL2_QUEUE:
+       case QED_LL2_RAM_QUEUE:
                mfw_res_id = RESOURCE_LL2_QUEUE_E;
                break;
+       case QED_LL2_CTX_QUEUE:
+               mfw_res_id = RESOURCE_LL2_CQS_E;
+               break;
        case QED_RDMA_CNQ_RAM:
        case QED_CMDQS_CQS:
                /* CNQ/CMDQS are the same resource */
index 3f437e826a4c9faea063a227c1944ac4bf0dc94a..a2b7826b36f0259a51f2837c59b1875fe26789ff 100644 (file)
 
 #define CORE_SPQE_PAGE_SIZE_BYTES      4096
 
-#define MAX_NUM_LL2_RX_QUEUES          48
-#define MAX_NUM_LL2_TX_STATS_COUNTERS  48
+/* Number of LL2 RAM based queues */
+#define MAX_NUM_LL2_RX_RAM_QUEUES 32
+
+/* Number of LL2 context based queues */
+#define MAX_NUM_LL2_RX_CTX_QUEUES 208
+#define MAX_NUM_LL2_RX_QUEUES \
+       (MAX_NUM_LL2_RX_RAM_QUEUES + MAX_NUM_LL2_RX_CTX_QUEUES)
+
+#define MAX_NUM_LL2_TX_STATS_COUNTERS  48
 
 #define FW_MAJOR_VERSION       8
 #define FW_MINOR_VERSION       42
 #define DQ_PWM_OFFSET_TCM_ROCE_RQ_PROD         (DQ_PWM_OFFSET_TCM16_BASE + 1)
 #define DQ_PWM_OFFSET_TCM_IWARP_RQ_PROD                (DQ_PWM_OFFSET_TCM16_BASE + 3)
 
+/* DQ_DEMS_AGG_VAL_BASE */
+#define DQ_PWM_OFFSET_TCM_LL2_PROD_UPDATE \
+       (DQ_PWM_OFFSET_TCM32_BASE + DQ_TCM_AGG_VAL_SEL_REG9 - 4)
+
 #define        DQ_REGION_SHIFT                 (12)
 
 /* DPM */
index b5db1ee96d789a9d71688c00d389c90c32604b27..9bcb2f41900442b06aefc2b66581a45dc1912381 100644 (file)
@@ -463,7 +463,7 @@ enum qed_db_rec_space {
 
 #define DIRECT_REG_RD(reg_addr) readl((void __iomem *)(reg_addr))
 
-#define DIRECT_REG_WR64(reg_addr, val) writeq((u32)val,        \
+#define DIRECT_REG_WR64(reg_addr, val) writeq((u64)val,        \
                                              (void __iomem *)(reg_addr))
 
 #define QED_COALESCE_MAX 0x1FF
@@ -1177,6 +1177,8 @@ struct qed_common_ops {
 #define GET_FIELD(value, name) \
        (((value) >> (name ## _SHIFT)) & name ## _MASK)
 
+#define DB_ADDR_SHIFT(addr) ((addr) << DB_PWM_ADDR_OFFSET_SHIFT)
+
 /* Debug print definitions */
 #define DP_ERR(cdev, fmt, ...)                                 \
        do {                                                    \
index 5eb022953acadd7f8c6c2297901bf0e5c566ce3f..1313c34d9a68195bc5b9a5ffe8cd9a0c0fb47a7d 100644 (file)
@@ -52,6 +52,12 @@ enum qed_ll2_conn_type {
        QED_LL2_TYPE_ROCE,
        QED_LL2_TYPE_IWARP,
        QED_LL2_TYPE_RESERVED3,
+       MAX_QED_LL2_CONN_TYPE
+};
+
+enum qed_ll2_rx_conn_type {
+       QED_LL2_RX_TYPE_LEGACY,
+       QED_LL2_RX_TYPE_CTX,
        MAX_QED_LL2_RX_CONN_TYPE
 };
 
@@ -165,6 +171,7 @@ struct qed_ll2_cbs {
 };
 
 struct qed_ll2_acquire_data_inputs {
+       enum qed_ll2_rx_conn_type rx_conn_type;
        enum qed_ll2_conn_type conn_type;
        u16 mtu;
        u16 rx_num_desc;