Commit 62b5b162 authored by David S. Miller's avatar David S. Miller

Merge branch 'dpaa2-eth-sw-TSO'

Ioana Ciornei says:

====================
dpaa2-eth: add support for software TSO

This series adds support for driver level TSO in the dpaa2-eth driver.

The first 5 patches lay the ground work for the actual feature:
rearrange some variable declaration, cleaning up the interraction with
the S/G Table buffer cache etc.

The 6th patch adds the actual driver level software TSO support by using
the usual tso_build_hdr()/tso_build_data() APIs and creates the S/G FDs.

With this patch set we can see the following improvement in a TCP flow
running on a single A72@2.2GHz of the LX2160A SoC:

before: 6.38Gbit/s
after:  8.48Gbit/s
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dc178d31 86ec882f
...@@ -122,6 +122,7 @@ enum dpaa2_eth_swa_type { ...@@ -122,6 +122,7 @@ enum dpaa2_eth_swa_type {
DPAA2_ETH_SWA_SINGLE, DPAA2_ETH_SWA_SINGLE,
DPAA2_ETH_SWA_SG, DPAA2_ETH_SWA_SG,
DPAA2_ETH_SWA_XDP, DPAA2_ETH_SWA_XDP,
DPAA2_ETH_SWA_SW_TSO,
}; };
/* Must keep this struct smaller than DPAA2_ETH_SWA_SIZE */ /* Must keep this struct smaller than DPAA2_ETH_SWA_SIZE */
...@@ -142,6 +143,12 @@ struct dpaa2_eth_swa { ...@@ -142,6 +143,12 @@ struct dpaa2_eth_swa {
int dma_size; int dma_size;
struct xdp_frame *xdpf; struct xdp_frame *xdpf;
} xdp; } xdp;
struct {
struct sk_buff *skb;
int num_sg;
int sgt_size;
int is_last_fd;
} tso;
}; };
}; };
...@@ -354,6 +361,8 @@ struct dpaa2_eth_drv_stats { ...@@ -354,6 +361,8 @@ struct dpaa2_eth_drv_stats {
__u64 tx_conf_bytes; __u64 tx_conf_bytes;
__u64 tx_sg_frames; __u64 tx_sg_frames;
__u64 tx_sg_bytes; __u64 tx_sg_bytes;
__u64 tx_tso_frames;
__u64 tx_tso_bytes;
__u64 rx_sg_frames; __u64 rx_sg_frames;
__u64 rx_sg_bytes; __u64 rx_sg_bytes;
/* Linear skbs sent as a S/G FD due to insufficient headroom */ /* Linear skbs sent as a S/G FD due to insufficient headroom */
...@@ -493,8 +502,15 @@ struct dpaa2_eth_trap_data { ...@@ -493,8 +502,15 @@ struct dpaa2_eth_trap_data {
struct dpaa2_eth_priv *priv; struct dpaa2_eth_priv *priv;
}; };
#define DPAA2_ETH_SG_ENTRIES_MAX (PAGE_SIZE / sizeof(struct scatterlist))
#define DPAA2_ETH_DEFAULT_COPYBREAK 512 #define DPAA2_ETH_DEFAULT_COPYBREAK 512
#define DPAA2_ETH_ENQUEUE_MAX_FDS 200
struct dpaa2_eth_fds {
struct dpaa2_fd array[DPAA2_ETH_ENQUEUE_MAX_FDS];
};
/* Driver private data */ /* Driver private data */
struct dpaa2_eth_priv { struct dpaa2_eth_priv {
struct net_device *net_dev; struct net_device *net_dev;
...@@ -577,6 +593,8 @@ struct dpaa2_eth_priv { ...@@ -577,6 +593,8 @@ struct dpaa2_eth_priv {
struct devlink_port devlink_port; struct devlink_port devlink_port;
u32 rx_copybreak; u32 rx_copybreak;
struct dpaa2_eth_fds __percpu *fd;
}; };
struct dpaa2_eth_devlink_priv { struct dpaa2_eth_devlink_priv {
......
...@@ -44,6 +44,8 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = { ...@@ -44,6 +44,8 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = {
"[drv] tx conf bytes", "[drv] tx conf bytes",
"[drv] tx sg frames", "[drv] tx sg frames",
"[drv] tx sg bytes", "[drv] tx sg bytes",
"[drv] tx tso frames",
"[drv] tx tso bytes",
"[drv] rx sg frames", "[drv] rx sg frames",
"[drv] rx sg bytes", "[drv] rx sg bytes",
"[drv] tx converted sg frames", "[drv] tx converted sg frames",
......
...@@ -743,8 +743,8 @@ int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, ...@@ -743,8 +743,8 @@ int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
full_mask = s->eqcr.pi_ci_mask; full_mask = s->eqcr.pi_ci_mask;
if (!s->eqcr.available) { if (!s->eqcr.available) {
eqcr_ci = s->eqcr.ci; eqcr_ci = s->eqcr.ci;
p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK; s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI);
s->eqcr.ci = *p & full_mask; s->eqcr.ci &= full_mask;
s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
eqcr_ci, s->eqcr.ci); eqcr_ci, s->eqcr.ci);
if (!s->eqcr.available) { if (!s->eqcr.available) {
...@@ -887,8 +887,8 @@ int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, ...@@ -887,8 +887,8 @@ int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
full_mask = s->eqcr.pi_ci_mask; full_mask = s->eqcr.pi_ci_mask;
if (!s->eqcr.available) { if (!s->eqcr.available) {
eqcr_ci = s->eqcr.ci; eqcr_ci = s->eqcr.ci;
p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK; s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI);
s->eqcr.ci = *p & full_mask; s->eqcr.ci &= full_mask;
s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
eqcr_ci, s->eqcr.ci); eqcr_ci, s->eqcr.ci);
if (!s->eqcr.available) if (!s->eqcr.available)
......
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