qed: Add ll2 connection for processing unaligned MPA packets
authorMichal Kalderon <Michal.Kalderon@cavium.com>
Mon, 9 Oct 2017 09:37:49 +0000 (12:37 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 Oct 2017 17:21:26 +0000 (10:21 -0700)
This patch adds only the establishment and termination of the
ll2 connection that handles unaligned MPA packets.

Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_iwarp.c
drivers/net/ethernet/qlogic/qed/qed_iwarp.h

index 8fc9c811f6e32db2b022274ef88cf98cefa86b48..f413621a67b0fad90d08ff67cdb76ac68b2a43b9 100644 (file)
@@ -1713,6 +1713,19 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn,
        return 0;
 }
 
+/* fpdu can be fragmented over maximum 3 bds: header, partial mpa, unaligned */
+#define QED_IWARP_MAX_BDS_PER_FPDU 3
+static void
+qed_iwarp_ll2_comp_mpa_pkt(void *cxt, struct qed_ll2_comp_rx_data *data)
+{
+       struct qed_iwarp_info *iwarp_info;
+       struct qed_hwfn *p_hwfn = cxt;
+
+       iwarp_info = &p_hwfn->p_rdma_info->iwarp;
+       qed_iwarp_ll2_post_rx(p_hwfn, data->cookie,
+                             iwarp_info->ll2_mpa_handle);
+}
+
 static void
 qed_iwarp_ll2_comp_syn_pkt(void *cxt, struct qed_ll2_comp_rx_data *data)
 {
@@ -1877,6 +1890,13 @@ static void qed_iwarp_ll2_rel_tx_pkt(void *cxt, u8 connection_handle,
        kfree(buffer);
 }
 
+void
+qed_iwarp_ll2_slowpath(void *cxt,
+                      u8 connection_handle,
+                      u32 opaque_data_0, u32 opaque_data_1)
+{
+}
+
 static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        struct qed_iwarp_info *iwarp_info = &p_hwfn->p_rdma_info->iwarp;
@@ -1902,6 +1922,16 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
        }
 
+       if (iwarp_info->ll2_mpa_handle != QED_IWARP_HANDLE_INVAL) {
+               rc = qed_ll2_terminate_connection(p_hwfn,
+                                                 iwarp_info->ll2_mpa_handle);
+               if (rc)
+                       DP_INFO(p_hwfn, "Failed to terminate mpa connection\n");
+
+               qed_ll2_release_connection(p_hwfn, iwarp_info->ll2_mpa_handle);
+               iwarp_info->ll2_mpa_handle = QED_IWARP_HANDLE_INVAL;
+       }
+
        qed_llh_remove_mac_filter(p_hwfn,
                                  p_ptt, p_hwfn->p_rdma_info->iwarp.mac_addr);
        return rc;
@@ -1953,12 +1983,14 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
        struct qed_iwarp_info *iwarp_info;
        struct qed_ll2_acquire_data data;
        struct qed_ll2_cbs cbs;
+       u32 mpa_buff_size;
        u16 n_ooo_bufs;
        int rc = 0;
 
        iwarp_info = &p_hwfn->p_rdma_info->iwarp;
        iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
        iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
+       iwarp_info->ll2_mpa_handle = QED_IWARP_HANDLE_INVAL;
 
        iwarp_info->max_mtu = params->max_mtu;
 
@@ -2029,6 +2061,39 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
        if (rc)
                goto err;
 
+       /* Start Unaligned MPA connection */
+       cbs.rx_comp_cb = qed_iwarp_ll2_comp_mpa_pkt;
+       cbs.slowpath_cb = qed_iwarp_ll2_slowpath;
+
+       memset(&data, 0, sizeof(data));
+       data.input.conn_type = QED_LL2_TYPE_IWARP;
+       data.input.mtu = params->max_mtu;
+       /* FW requires that once a packet arrives OOO, it must have at
+        * least 2 rx buffers available on the unaligned connection
+        * for handling the case that it is a partial fpdu.
+        */
+       data.input.rx_num_desc = n_ooo_bufs * 2;
+       data.input.tx_num_desc = data.input.rx_num_desc;
+       data.input.tx_max_bds_per_packet = QED_IWARP_MAX_BDS_PER_FPDU;
+       data.p_connection_handle = &iwarp_info->ll2_mpa_handle;
+       data.input.secondary_queue = true;
+       data.cbs = &cbs;
+
+       rc = qed_ll2_acquire_connection(p_hwfn, &data);
+       if (rc)
+               goto err;
+
+       rc = qed_ll2_establish_connection(p_hwfn, iwarp_info->ll2_mpa_handle);
+       if (rc)
+               goto err;
+
+       mpa_buff_size = QED_IWARP_MAX_BUF_SIZE(params->max_mtu);
+       rc = qed_iwarp_ll2_alloc_buffers(p_hwfn,
+                                        data.input.rx_num_desc,
+                                        mpa_buff_size,
+                                        iwarp_info->ll2_mpa_handle);
+       if (rc)
+               goto err;
        return rc;
 err:
        qed_iwarp_ll2_stop(p_hwfn, p_ptt);
index 9e2bfde894df1a0de988a42de539429e2ad459f8..9d33a1fa1758a0c916a8b180120f24d074fb4e20 100644 (file)
@@ -73,6 +73,7 @@ struct qed_iwarp_info {
        u8 tcp_flags;
        u8 ll2_syn_handle;
        u8 ll2_ooo_handle;
+       u8 ll2_mpa_handle;
        u8 peer2peer;
        enum mpa_negotiation_mode mpa_rev;
        enum mpa_rtr_type rtr_type;