/* * Copyright (c) 2001-2020 Mellanox Technologies, Ltd. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed 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, or the * BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef CQ_MGR_INL_H #define CQ_MGR_INL_H #include "cq_mgr.h" #include "ring_simple.h" /**/ /** inlining functions can only help if they are implemented before their usage **/ /**/ inline void cq_mgr::process_recv_buffer(mem_buf_desc_t* p_mem_buf_desc, void* pv_fd_ready_array) { // Assume locked!!! // Pass the Rx buffer ib_comm_mgr for further IP processing if (!m_p_ring->rx_process_buffer(p_mem_buf_desc, pv_fd_ready_array)) { // If buffer is dropped by callback - return to RX pool reclaim_recv_buffer_helper(p_mem_buf_desc); } } inline uint32_t cq_mgr::process_recv_queue(void* pv_fd_ready_array) { // Assume locked!!! // If we have packets in the queue, dequeue one and process it // until reaching cq_poll_batch_max or empty queue uint32_t processed = 0; while (!m_rx_queue.empty()) { mem_buf_desc_t* buff = m_rx_queue.get_and_pop_front(); process_recv_buffer(buff, pv_fd_ready_array); if (++processed >= m_n_sysvar_cq_poll_batch_max) break; } m_p_cq_stat->n_rx_sw_queue_len = m_rx_queue.size(); return processed; } inline bool is_eth_tcp_frame(mem_buf_desc_t* buff) { struct ethhdr* p_eth_h = (struct ethhdr*)(buff->p_buffer); uint16_t h_proto = p_eth_h->h_proto; size_t transport_header_len = ETH_HDR_LEN; struct vlanhdr* p_vlan_hdr = NULL; if (h_proto == htons(ETH_P_8021Q)) { p_vlan_hdr = (struct vlanhdr*)((uint8_t*)p_eth_h + transport_header_len); transport_header_len = ETH_VLAN_HDR_LEN; h_proto = p_vlan_hdr->h_vlan_encapsulated_proto; } struct iphdr *p_ip_h = (struct iphdr*)(buff->p_buffer + transport_header_len); if (likely(h_proto == htons(ETH_P_IP)) && (p_ip_h->protocol == IPPROTO_TCP)) { return true; } return false; } inline bool is_ib_tcp_frame(mem_buf_desc_t* buff) { struct ipoibhdr* p_ipoib_h = (struct ipoibhdr*)(buff->p_buffer + GRH_HDR_LEN); // Validate IPoIB header if (unlikely(p_ipoib_h->ipoib_header != htonl(IPOIB_HEADER))) { return false; } size_t transport_header_len = GRH_HDR_LEN + IPOIB_HDR_LEN; struct iphdr * p_ip_h = (struct iphdr*)(buff->p_buffer + transport_header_len); if (likely(p_ip_h->protocol == IPPROTO_TCP)) { return true; } return false; } #endif//CQ_MGR_INL_H