Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37dab411 authored by Faisal Latif's avatar Faisal Latif Committed by Roland Dreier
Browse files

RDMA/nes: Use LRO

parent b4132efa
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -2,6 +2,7 @@ config INFINIBAND_NES
	tristate "NetEffect RNIC Driver"
	tristate "NetEffect RNIC Driver"
	depends on PCI && INET && INFINIBAND
	depends on PCI && INET && INFINIBAND
	select LIBCRC32C
	select LIBCRC32C
	select INET_LRO
	---help---
	---help---
	  This is a low-level driver for NetEffect RDMA enabled
	  This is a low-level driver for NetEffect RDMA enabled
	  Network Interface Cards (RNIC).
	  Network Interface Cards (RNIC).
+4 −0
Original line number Original line Diff line number Diff line
@@ -91,6 +91,10 @@ unsigned int nes_debug_level = 0;
module_param_named(debug_level, nes_debug_level, uint, 0644);
module_param_named(debug_level, nes_debug_level, uint, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug output level");
MODULE_PARM_DESC(debug_level, "Enable debug output level");


unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR);
MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation");

LIST_HEAD(nes_adapter_list);
LIST_HEAD(nes_adapter_list);
static LIST_HEAD(nes_dev_list);
static LIST_HEAD(nes_dev_list);


+1 −0
Original line number Original line Diff line number Diff line
@@ -173,6 +173,7 @@ extern int disable_mpa_crc;
extern unsigned int send_first;
extern unsigned int send_first;
extern unsigned int nes_drv_opt;
extern unsigned int nes_drv_opt;
extern unsigned int nes_debug_level;
extern unsigned int nes_debug_level;
extern unsigned int nes_lro_max_aggr;


extern struct list_head nes_adapter_list;
extern struct list_head nes_adapter_list;


+45 −8
Original line number Original line Diff line number Diff line
@@ -38,6 +38,7 @@
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/tcp.h>
#include <linux/if_vlan.h>
#include <linux/if_vlan.h>
#include <linux/inet_lro.h>


#include "nes.h"
#include "nes.h"


@@ -1375,6 +1376,25 @@ static void nes_rq_wqes_timeout(unsigned long parm)
}
}




static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr,
			       void **tcph, u64 *hdr_flags, void *priv)
{
	unsigned int ip_len;
	struct iphdr *iph;
	skb_reset_network_header(skb);
	iph = ip_hdr(skb);
	if (iph->protocol != IPPROTO_TCP)
		return -1;
	ip_len = ip_hdrlen(skb);
	skb_set_transport_header(skb, ip_len);
	*tcph = tcp_hdr(skb);

	*hdr_flags = LRO_IPV4 | LRO_TCP;
	*iphdr = iph;
	return 0;
}


/**
/**
 * nes_init_nic_qp
 * nes_init_nic_qp
 */
 */
@@ -1592,7 +1612,6 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
	nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout;
	nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout;
	nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic;
	nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic;
	nes_debug(NES_DBG_INIT, "NAPI support Enabled\n");
	nes_debug(NES_DBG_INIT, "NAPI support Enabled\n");

	if (nesdev->nesadapter->et_use_adaptive_rx_coalesce)
	if (nesdev->nesadapter->et_use_adaptive_rx_coalesce)
	{
	{
		nes_nic_init_timer(nesdev);
		nes_nic_init_timer(nesdev);
@@ -1600,7 +1619,14 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
			jumbomode = 1;
			jumbomode = 1;
		nes_nic_init_timer_defaults(nesdev, jumbomode);
		nes_nic_init_timer_defaults(nesdev, jumbomode);
	}
	}

	nesvnic->lro_mgr.max_aggr = NES_LRO_MAX_AGGR;
	nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS;
	nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc;
	nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
	nesvnic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
	nesvnic->lro_mgr.dev = netdev;
	nesvnic->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
	nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
	return 0;
	return 0;
}
}


@@ -2254,10 +2280,13 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
	u16 pkt_type;
	u16 pkt_type;
	u16 rqes_processed = 0;
	u16 rqes_processed = 0;
	u8 sq_cqes = 0;
	u8 sq_cqes = 0;
	u8 nes_use_lro = 0;


	head = cq->cq_head;
	head = cq->cq_head;
	cq_size = cq->cq_size;
	cq_size = cq->cq_size;
	cq->cqes_pending = 1;
	cq->cqes_pending = 1;
	if (nesvnic->netdev->features & NETIF_F_LRO)
		nes_use_lro = 1;
	do {
	do {
		if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
		if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
				NES_NIC_CQE_VALID) {
				NES_NIC_CQE_VALID) {
@@ -2379,8 +2408,15 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
								>> 16);
								>> 16);
						nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
						nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
								nesvnic->netdev->name, vlan_tag);
								nesvnic->netdev->name, vlan_tag);
						if (nes_use_lro)
							lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
									nesvnic->vlan_grp, vlan_tag, NULL);
						else
							nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
							nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
					} else {
					} else {
						if (nes_use_lro)
							lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
						else
							nes_netif_rx(rx_skb);
							nes_netif_rx(rx_skb);
					}
					}
				}
				}
@@ -2413,13 +2449,14 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)


	} while (1);
	} while (1);


	if (nes_use_lro)
		lro_flush_all(&nesvnic->lro_mgr);
	if (sq_cqes) {
	if (sq_cqes) {
		barrier();
		barrier();
		/* restart the queue if it had been stopped */
		/* restart the queue if it had been stopped */
		if (netif_queue_stopped(nesvnic->netdev))
		if (netif_queue_stopped(nesvnic->netdev))
			netif_wake_queue(nesvnic->netdev);
			netif_wake_queue(nesvnic->netdev);
	}
	}

	cq->cq_head = head;
	cq->cq_head = head;
	/* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n",
	/* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n",
			cq->cq_number, cqe_count, cq->cq_head); */
			cq->cq_number, cqe_count, cq->cq_head); */
+9 −2
Original line number Original line Diff line number Diff line
@@ -33,6 +33,8 @@
#ifndef __NES_HW_H
#ifndef __NES_HW_H
#define __NES_HW_H
#define __NES_HW_H


#include <linux/inet_lro.h>

#define NES_PHY_TYPE_1G   2
#define NES_PHY_TYPE_1G   2
#define NES_PHY_TYPE_IRIS 3
#define NES_PHY_TYPE_IRIS 3
#define NES_PHY_TYPE_PUMA_10G  6
#define NES_PHY_TYPE_PUMA_10G  6
@@ -984,6 +986,8 @@ struct nes_hw_tune_timer {
#define NES_TIMER_ENABLE_LIMIT      4
#define NES_TIMER_ENABLE_LIMIT      4
#define NES_MAX_LINK_INTERRUPTS     128
#define NES_MAX_LINK_INTERRUPTS     128
#define NES_MAX_LINK_CHECK          200
#define NES_MAX_LINK_CHECK          200
#define NES_MAX_LRO_DESCRIPTORS     32
#define NES_LRO_MAX_AGGR            64


struct nes_adapter {
struct nes_adapter {
	u64              fw_ver;
	u64              fw_ver;
@@ -1183,6 +1187,9 @@ struct nes_vnic {
	u8  of_device_registered;
	u8  of_device_registered;
	u8  rdma_enabled;
	u8  rdma_enabled;
	u8  rx_checksum_disabled;
	u8  rx_checksum_disabled;
	u32 lro_max_aggr;
	struct net_lro_mgr lro_mgr;
	struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
};
};


struct nes_ib_device {
struct nes_ib_device {
Loading