Commit b47385bd authored by Divy Le Ray's avatar Divy Le Ray Committed by Jeff Garzik

cxgb3 - Add LRO support

Add LRO support.
Signed-off-by: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 7385ecf3
...@@ -2409,6 +2409,7 @@ config CHELSIO_T3 ...@@ -2409,6 +2409,7 @@ config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support" tristate "Chelsio Communications T3 10Gb Ethernet support"
depends on PCI depends on PCI
select FW_LOADER select FW_LOADER
select INET_LRO
help help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters. adapters.
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/inet_lro.h>
#include "t3cdev.h" #include "t3cdev.h"
#include <asm/io.h> #include <asm/io.h>
...@@ -173,16 +174,29 @@ enum { /* per port SGE statistics */ ...@@ -173,16 +174,29 @@ enum { /* per port SGE statistics */
SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */ SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */
SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */ SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */
SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */ SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */
SGE_PSTAT_LRO_AGGR, /* # of page chunks added to LRO sessions */
SGE_PSTAT_LRO_FLUSHED, /* # of flushed LRO sessions */
SGE_PSTAT_LRO_NO_DESC, /* # of overflown LRO sessions */
SGE_PSTAT_MAX /* must be last */ SGE_PSTAT_MAX /* must be last */
}; };
#define T3_MAX_LRO_SES 8
#define T3_MAX_LRO_MAX_PKTS 64
struct sge_qset { /* an SGE queue set */ struct sge_qset { /* an SGE queue set */
struct adapter *adap; struct adapter *adap;
struct napi_struct napi; struct napi_struct napi;
struct sge_rspq rspq; struct sge_rspq rspq;
struct sge_fl fl[SGE_RXQ_PER_SET]; struct sge_fl fl[SGE_RXQ_PER_SET];
struct sge_txq txq[SGE_TXQ_PER_SET]; struct sge_txq txq[SGE_TXQ_PER_SET];
struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
struct skb_frag_struct *lro_frag_tbl;
int lro_nfrags;
int lro_enabled;
int lro_frag_len;
void *lro_va;
struct net_device *netdev; struct net_device *netdev;
unsigned long txq_stopped; /* which Tx queues are stopped */ unsigned long txq_stopped; /* which Tx queues are stopped */
struct timer_list tx_reclaim_timer; /* reclaims TX buffers */ struct timer_list tx_reclaim_timer; /* reclaims TX buffers */
......
...@@ -351,6 +351,7 @@ struct tp_params { ...@@ -351,6 +351,7 @@ struct tp_params {
struct qset_params { /* SGE queue set parameters */ struct qset_params { /* SGE queue set parameters */
unsigned int polling; /* polling/interrupt service for rspq */ unsigned int polling; /* polling/interrupt service for rspq */
unsigned int lro; /* large receive offload */
unsigned int coalesce_usecs; /* irq coalescing timer */ unsigned int coalesce_usecs; /* irq coalescing timer */
unsigned int rspq_size; /* # of entries in response queue */ unsigned int rspq_size; /* # of entries in response queue */
unsigned int fl_size; /* # of entries in regular free list */ unsigned int fl_size; /* # of entries in regular free list */
......
...@@ -90,6 +90,7 @@ struct ch_qset_params { ...@@ -90,6 +90,7 @@ struct ch_qset_params {
int32_t fl_size[2]; int32_t fl_size[2];
int32_t intr_lat; int32_t intr_lat;
int32_t polling; int32_t polling;
int32_t lro;
int32_t cong_thres; int32_t cong_thres;
}; };
......
...@@ -1212,6 +1212,9 @@ static char stats_strings[][ETH_GSTRING_LEN] = { ...@@ -1212,6 +1212,9 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"VLANinsertions ", "VLANinsertions ",
"TxCsumOffload ", "TxCsumOffload ",
"RxCsumGood ", "RxCsumGood ",
"LroAggregated ",
"LroFlushed ",
"LroNoDesc ",
"RxDrops ", "RxDrops ",
"CheckTXEnToggled ", "CheckTXEnToggled ",
...@@ -1340,6 +1343,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, ...@@ -1340,6 +1343,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS); *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM); *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD); *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
*data++ = s->rx_cong_drops; *data++ = s->rx_cong_drops;
*data++ = s->num_toggled; *data++ = s->num_toggled;
...@@ -1558,6 +1564,13 @@ static int set_rx_csum(struct net_device *dev, u32 data) ...@@ -1558,6 +1564,13 @@ static int set_rx_csum(struct net_device *dev, u32 data)
struct port_info *p = netdev_priv(dev); struct port_info *p = netdev_priv(dev);
p->rx_csum_offload = data; p->rx_csum_offload = data;
if (!data) {
struct adapter *adap = p->adapter;
int i;
for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
adap->sge.qs[i].lro_enabled = 0;
}
return 0; return 0;
} }
...@@ -1830,6 +1843,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) ...@@ -1830,6 +1843,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
} }
} }
} }
if (t.lro >= 0) {
struct sge_qset *qs = &adapter->sge.qs[t.qset_idx];
q->lro = t.lro;
qs->lro_enabled = t.lro;
}
break; break;
} }
case CHELSIO_GET_QSET_PARAMS:{ case CHELSIO_GET_QSET_PARAMS:{
...@@ -1849,6 +1867,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) ...@@ -1849,6 +1867,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
t.fl_size[0] = q->fl_size; t.fl_size[0] = q->fl_size;
t.fl_size[1] = q->jumbo_size; t.fl_size[1] = q->jumbo_size;
t.polling = q->polling; t.polling = q->polling;
t.lro = q->lro;
t.intr_lat = q->coalesce_usecs; t.intr_lat = q->coalesce_usecs;
t.cong_thres = q->cong_thres; t.cong_thres = q->cong_thres;
......
This diff is collapsed.
...@@ -174,6 +174,13 @@ enum { /* TCP congestion control algorithms */ ...@@ -174,6 +174,13 @@ enum { /* TCP congestion control algorithms */
CONG_ALG_HIGHSPEED CONG_ALG_HIGHSPEED
}; };
enum { /* RSS hash type */
RSS_HASH_NONE = 0,
RSS_HASH_2_TUPLE = 1,
RSS_HASH_4_TUPLE = 2,
RSS_HASH_TCPV6 = 3
};
union opcode_tid { union opcode_tid {
__be32 opcode_tid; __be32 opcode_tid;
__u8 opcode; __u8 opcode;
...@@ -184,6 +191,10 @@ union opcode_tid { ...@@ -184,6 +191,10 @@ union opcode_tid {
#define G_OPCODE(x) (((x) >> S_OPCODE) & 0xFF) #define G_OPCODE(x) (((x) >> S_OPCODE) & 0xFF)
#define G_TID(x) ((x) & 0xFFFFFF) #define G_TID(x) ((x) & 0xFFFFFF)
#define S_HASHTYPE 22
#define M_HASHTYPE 0x3
#define G_HASHTYPE(x) (((x) >> S_HASHTYPE) & M_HASHTYPE)
/* tid is assumed to be 24-bits */ /* tid is assumed to be 24-bits */
#define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid)) #define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment