@@ -1420,6 +1420,7 @@ void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn)
14201420 qed_rdma_bmap_free (p_hwfn , & p_hwfn -> p_rdma_info -> tcp_cid_map , 1 );
14211421 kfree (iwarp_info -> mpa_bufs );
14221422 kfree (iwarp_info -> partial_fpdus );
1423+ kfree (iwarp_info -> mpa_intermediate_buf );
14231424}
14241425
14251426int qed_iwarp_accept (void * rdma_cxt , struct qed_iwarp_accept_in * iparams )
@@ -1762,6 +1763,11 @@ char *pkt_type_str[] = {
17621763 "QED_IWARP_MPA_PKT_UNALIGNED"
17631764};
17641765
1766+ static int
1767+ qed_iwarp_recycle_pkt (struct qed_hwfn * p_hwfn ,
1768+ struct qed_iwarp_fpdu * fpdu ,
1769+ struct qed_iwarp_ll2_buff * buf );
1770+
17651771static enum qed_iwarp_mpa_pkt_type
17661772qed_iwarp_mpa_classify (struct qed_hwfn * p_hwfn ,
17671773 struct qed_iwarp_fpdu * fpdu ,
@@ -1822,6 +1828,68 @@ qed_iwarp_init_fpdu(struct qed_iwarp_ll2_buff *buf,
18221828 fpdu -> mpa_frag_len = fpdu -> fpdu_length - fpdu -> incomplete_bytes ;
18231829}
18241830
1831+ static int
1832+ qed_iwarp_cp_pkt (struct qed_hwfn * p_hwfn ,
1833+ struct qed_iwarp_fpdu * fpdu ,
1834+ struct unaligned_opaque_data * pkt_data ,
1835+ struct qed_iwarp_ll2_buff * buf , u16 tcp_payload_size )
1836+ {
1837+ u8 * tmp_buf = p_hwfn -> p_rdma_info -> iwarp .mpa_intermediate_buf ;
1838+ int rc ;
1839+
1840+ /* need to copy the data from the partial packet stored in fpdu
1841+ * to the new buf, for this we also need to move the data currently
1842+ * placed on the buf. The assumption is that the buffer is big enough
1843+ * since fpdu_length <= mss, we use an intermediate buffer since
1844+ * we may need to copy the new data to an overlapping location
1845+ */
1846+ if ((fpdu -> mpa_frag_len + tcp_payload_size ) > (u16 )buf -> buff_size ) {
1847+ DP_ERR (p_hwfn ,
1848+ "MPA ALIGN: Unexpected: buffer is not large enough for split fpdu buff_size = %d mpa_frag_len = %d, tcp_payload_size = %d, incomplete_bytes = %d\n" ,
1849+ buf -> buff_size , fpdu -> mpa_frag_len ,
1850+ tcp_payload_size , fpdu -> incomplete_bytes );
1851+ return - EINVAL ;
1852+ }
1853+
1854+ DP_VERBOSE (p_hwfn , QED_MSG_RDMA ,
1855+ "MPA ALIGN Copying fpdu: [%p, %d] [%p, %d]\n" ,
1856+ fpdu -> mpa_frag_virt , fpdu -> mpa_frag_len ,
1857+ (u8 * )(buf -> data ) + pkt_data -> first_mpa_offset ,
1858+ tcp_payload_size );
1859+
1860+ memcpy (tmp_buf , fpdu -> mpa_frag_virt , fpdu -> mpa_frag_len );
1861+ memcpy (tmp_buf + fpdu -> mpa_frag_len ,
1862+ (u8 * )(buf -> data ) + pkt_data -> first_mpa_offset ,
1863+ tcp_payload_size );
1864+
1865+ rc = qed_iwarp_recycle_pkt (p_hwfn , fpdu , fpdu -> mpa_buf );
1866+ if (rc )
1867+ return rc ;
1868+
1869+ /* If we managed to post the buffer copy the data to the new buffer
1870+ * o/w this will occur in the next round...
1871+ */
1872+ memcpy ((u8 * )(buf -> data ), tmp_buf ,
1873+ fpdu -> mpa_frag_len + tcp_payload_size );
1874+
1875+ fpdu -> mpa_buf = buf ;
1876+ /* fpdu->pkt_hdr remains as is */
1877+ /* fpdu->mpa_frag is overridden with new buf */
1878+ fpdu -> mpa_frag = buf -> data_phys_addr ;
1879+ fpdu -> mpa_frag_virt = buf -> data ;
1880+ fpdu -> mpa_frag_len += tcp_payload_size ;
1881+
1882+ fpdu -> incomplete_bytes -= tcp_payload_size ;
1883+
1884+ DP_VERBOSE (p_hwfn ,
1885+ QED_MSG_RDMA ,
1886+ "MPA ALIGN: split fpdu buff_size = %d mpa_frag_len = %d, tcp_payload_size = %d, incomplete_bytes = %d\n" ,
1887+ buf -> buff_size , fpdu -> mpa_frag_len , tcp_payload_size ,
1888+ fpdu -> incomplete_bytes );
1889+
1890+ return 0 ;
1891+ }
1892+
18251893static void
18261894qed_iwarp_update_fpdu_length (struct qed_hwfn * p_hwfn ,
18271895 struct qed_iwarp_fpdu * fpdu , u8 * mpa_data )
@@ -1843,6 +1911,90 @@ qed_iwarp_update_fpdu_length(struct qed_hwfn *p_hwfn,
18431911 }
18441912}
18451913
1914+ #define QED_IWARP_IS_RIGHT_EDGE (_curr_pkt ) \
1915+ (GET_FIELD((_curr_pkt)->flags, \
1916+ UNALIGNED_OPAQUE_DATA_PKT_REACHED_WIN_RIGHT_EDGE))
1917+
1918+ /* This function is used to recycle a buffer using the ll2 drop option. It
1919+ * uses the mechanism to ensure that all buffers posted to tx before this one
1920+ * were completed. The buffer sent here will be sent as a cookie in the tx
1921+ * completion function and can then be reposted to rx chain when done. The flow
1922+ * that requires this is the flow where a FPDU splits over more than 3 tcp
1923+ * segments. In this case the driver needs to re-post a rx buffer instead of
1924+ * the one received, but driver can't simply repost a buffer it copied from
1925+ * as there is a case where the buffer was originally a packed FPDU, and is
1926+ * partially posted to FW. Driver needs to ensure FW is done with it.
1927+ */
1928+ static int
1929+ qed_iwarp_recycle_pkt (struct qed_hwfn * p_hwfn ,
1930+ struct qed_iwarp_fpdu * fpdu ,
1931+ struct qed_iwarp_ll2_buff * buf )
1932+ {
1933+ struct qed_ll2_tx_pkt_info tx_pkt ;
1934+ u8 ll2_handle ;
1935+ int rc ;
1936+
1937+ memset (& tx_pkt , 0 , sizeof (tx_pkt ));
1938+ tx_pkt .num_of_bds = 1 ;
1939+ tx_pkt .tx_dest = QED_LL2_TX_DEST_DROP ;
1940+ tx_pkt .l4_hdr_offset_w = fpdu -> pkt_hdr_size >> 2 ;
1941+ tx_pkt .first_frag = fpdu -> pkt_hdr ;
1942+ tx_pkt .first_frag_len = fpdu -> pkt_hdr_size ;
1943+ buf -> piggy_buf = NULL ;
1944+ tx_pkt .cookie = buf ;
1945+
1946+ ll2_handle = p_hwfn -> p_rdma_info -> iwarp .ll2_mpa_handle ;
1947+
1948+ rc = qed_ll2_prepare_tx_packet (p_hwfn , ll2_handle , & tx_pkt , true);
1949+ if (rc )
1950+ DP_VERBOSE (p_hwfn , QED_MSG_RDMA ,
1951+ "Can't drop packet rc=%d\n" , rc );
1952+
1953+ DP_VERBOSE (p_hwfn ,
1954+ QED_MSG_RDMA ,
1955+ "MPA_ALIGN: send drop tx packet [%lx, 0x%x], buf=%p, rc=%d\n" ,
1956+ (unsigned long int )tx_pkt .first_frag ,
1957+ tx_pkt .first_frag_len , buf , rc );
1958+
1959+ return rc ;
1960+ }
1961+
1962+ static int
1963+ qed_iwarp_win_right_edge (struct qed_hwfn * p_hwfn , struct qed_iwarp_fpdu * fpdu )
1964+ {
1965+ struct qed_ll2_tx_pkt_info tx_pkt ;
1966+ u8 ll2_handle ;
1967+ int rc ;
1968+
1969+ memset (& tx_pkt , 0 , sizeof (tx_pkt ));
1970+ tx_pkt .num_of_bds = 1 ;
1971+ tx_pkt .tx_dest = QED_LL2_TX_DEST_LB ;
1972+ tx_pkt .l4_hdr_offset_w = fpdu -> pkt_hdr_size >> 2 ;
1973+
1974+ tx_pkt .first_frag = fpdu -> pkt_hdr ;
1975+ tx_pkt .first_frag_len = fpdu -> pkt_hdr_size ;
1976+ tx_pkt .enable_ip_cksum = true;
1977+ tx_pkt .enable_l4_cksum = true;
1978+ tx_pkt .calc_ip_len = true;
1979+ /* vlan overload with enum iwarp_ll2_tx_queues */
1980+ tx_pkt .vlan = IWARP_LL2_ALIGNED_RIGHT_TRIMMED_TX_QUEUE ;
1981+
1982+ ll2_handle = p_hwfn -> p_rdma_info -> iwarp .ll2_mpa_handle ;
1983+
1984+ rc = qed_ll2_prepare_tx_packet (p_hwfn , ll2_handle , & tx_pkt , true);
1985+ if (rc )
1986+ DP_VERBOSE (p_hwfn , QED_MSG_RDMA ,
1987+ "Can't send right edge rc=%d\n" , rc );
1988+ DP_VERBOSE (p_hwfn ,
1989+ QED_MSG_RDMA ,
1990+ "MPA_ALIGN: Sent right edge FPDU num_bds=%d [%lx, 0x%x], rc=%d\n" ,
1991+ tx_pkt .num_of_bds ,
1992+ (unsigned long int )tx_pkt .first_frag ,
1993+ tx_pkt .first_frag_len , rc );
1994+
1995+ return rc ;
1996+ }
1997+
18461998static int
18471999qed_iwarp_send_fpdu (struct qed_hwfn * p_hwfn ,
18482000 struct qed_iwarp_fpdu * fpdu ,
@@ -1971,6 +2123,20 @@ qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn,
19712123 mpa_buf -> tcp_payload_len ,
19722124 mpa_buf -> placement_offset );
19732125
2126+ if (!QED_IWARP_IS_RIGHT_EDGE (curr_pkt )) {
2127+ mpa_buf -> tcp_payload_len = 0 ;
2128+ break ;
2129+ }
2130+
2131+ rc = qed_iwarp_win_right_edge (p_hwfn , fpdu );
2132+
2133+ if (rc ) {
2134+ DP_VERBOSE (p_hwfn , QED_MSG_RDMA ,
2135+ "Can't send FPDU:reset rc=%d\n" , rc );
2136+ memset (fpdu , 0 , sizeof (* fpdu ));
2137+ break ;
2138+ }
2139+
19742140 mpa_buf -> tcp_payload_len = 0 ;
19752141 break ;
19762142 case QED_IWARP_MPA_PKT_PACKED :
@@ -1994,6 +2160,28 @@ qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn,
19942160 break ;
19952161 case QED_IWARP_MPA_PKT_UNALIGNED :
19962162 qed_iwarp_update_fpdu_length (p_hwfn , fpdu , mpa_data );
2163+ if (mpa_buf -> tcp_payload_len < fpdu -> incomplete_bytes ) {
2164+ /* special handling of fpdu split over more
2165+ * than 2 segments
2166+ */
2167+ if (QED_IWARP_IS_RIGHT_EDGE (curr_pkt )) {
2168+ rc = qed_iwarp_win_right_edge (p_hwfn ,
2169+ fpdu );
2170+ /* packet will be re-processed later */
2171+ if (rc )
2172+ return rc ;
2173+ }
2174+
2175+ rc = qed_iwarp_cp_pkt (p_hwfn , fpdu , curr_pkt ,
2176+ buf ,
2177+ mpa_buf -> tcp_payload_len );
2178+ if (rc ) /* packet will be re-processed later */
2179+ return rc ;
2180+
2181+ mpa_buf -> tcp_payload_len = 0 ;
2182+ break ;
2183+ }
2184+
19972185 rc = qed_iwarp_send_fpdu (p_hwfn , fpdu , curr_pkt , buf ,
19982186 mpa_buf -> tcp_payload_len ,
19992187 pkt_type );
@@ -2510,6 +2698,11 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
25102698 goto err ;
25112699
25122700 iwarp_info -> max_num_partial_fpdus = (u16 )p_hwfn -> p_rdma_info -> num_qps ;
2701+
2702+ iwarp_info -> mpa_intermediate_buf = kzalloc (mpa_buff_size , GFP_KERNEL );
2703+ if (!iwarp_info -> mpa_intermediate_buf )
2704+ goto err ;
2705+
25132706 /* The mpa_bufs array serves for pending RX packets received on the
25142707 * mpa ll2 that don't have place on the tx ring and require later
25152708 * processing. We can't fail on allocation of such a struct therefore
0 commit comments