mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
net/funeth: Unify skb/XDP gather list writing.
Extract the Tx gather list writing code that skbs use into a utility function and use it also for XDP. Signed-off-by: Dimitris Michailidis <dmichail@fungible.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
16ead40812
commit
a3b461bbd1
1 changed files with 31 additions and 15 deletions
|
@ -71,6 +71,33 @@ static unsigned int tx_req_ndesc(const struct fun_eth_tx_req *req)
|
||||||
return DIV_ROUND_UP(req->len8, FUNETH_SQE_SIZE / 8);
|
return DIV_ROUND_UP(req->len8, FUNETH_SQE_SIZE / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write a gather list to the Tx descriptor at @req from @ngle address/length
|
||||||
|
* pairs.
|
||||||
|
*/
|
||||||
|
static struct fun_dataop_gl *fun_write_gl(const struct funeth_txq *q,
|
||||||
|
struct fun_eth_tx_req *req,
|
||||||
|
const dma_addr_t *addrs,
|
||||||
|
const unsigned int *lens,
|
||||||
|
unsigned int ngle)
|
||||||
|
{
|
||||||
|
struct fun_dataop_gl *gle;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
req->len8 = (sizeof(*req) + ngle * sizeof(*gle)) / 8;
|
||||||
|
|
||||||
|
for (i = 0, gle = (struct fun_dataop_gl *)req->dataop.imm;
|
||||||
|
i < ngle && txq_to_end(q, gle); i++, gle++)
|
||||||
|
fun_dataop_gl_init(gle, 0, 0, lens[i], addrs[i]);
|
||||||
|
|
||||||
|
if (txq_to_end(q, gle) == 0) {
|
||||||
|
gle = (struct fun_dataop_gl *)q->desc;
|
||||||
|
for ( ; i < ngle; i++, gle++)
|
||||||
|
fun_dataop_gl_init(gle, 0, 0, lens[i], addrs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gle;
|
||||||
|
}
|
||||||
|
|
||||||
static __be16 tcp_hdr_doff_flags(const struct tcphdr *th)
|
static __be16 tcp_hdr_doff_flags(const struct tcphdr *th)
|
||||||
{
|
{
|
||||||
return *(__be16 *)&tcp_flag_word(th);
|
return *(__be16 *)&tcp_flag_word(th);
|
||||||
|
@ -129,8 +156,8 @@ static unsigned int write_pkt_desc(struct sk_buff *skb, struct funeth_txq *q,
|
||||||
struct fun_eth_tx_req *req;
|
struct fun_eth_tx_req *req;
|
||||||
struct fun_dataop_gl *gle;
|
struct fun_dataop_gl *gle;
|
||||||
const struct tcphdr *th;
|
const struct tcphdr *th;
|
||||||
unsigned int ngle, i;
|
|
||||||
unsigned int l4_hlen;
|
unsigned int l4_hlen;
|
||||||
|
unsigned int ngle;
|
||||||
u16 flags;
|
u16 flags;
|
||||||
|
|
||||||
if (unlikely(map_skb(skb, q->dma_dev, addrs, lens))) {
|
if (unlikely(map_skb(skb, q->dma_dev, addrs, lens))) {
|
||||||
|
@ -243,18 +270,9 @@ static unsigned int write_pkt_desc(struct sk_buff *skb, struct funeth_txq *q,
|
||||||
}
|
}
|
||||||
|
|
||||||
ngle = shinfo->nr_frags + 1;
|
ngle = shinfo->nr_frags + 1;
|
||||||
req->len8 = (sizeof(*req) + ngle * sizeof(*gle)) / 8;
|
|
||||||
req->dataop = FUN_DATAOP_HDR_INIT(ngle, 0, ngle, 0, skb->len);
|
req->dataop = FUN_DATAOP_HDR_INIT(ngle, 0, ngle, 0, skb->len);
|
||||||
|
|
||||||
for (i = 0, gle = (struct fun_dataop_gl *)req->dataop.imm;
|
gle = fun_write_gl(q, req, addrs, lens, ngle);
|
||||||
i < ngle && txq_to_end(q, gle); i++, gle++)
|
|
||||||
fun_dataop_gl_init(gle, 0, 0, lens[i], addrs[i]);
|
|
||||||
|
|
||||||
if (txq_to_end(q, gle) == 0) {
|
|
||||||
gle = (struct fun_dataop_gl *)q->desc;
|
|
||||||
for ( ; i < ngle; i++, gle++)
|
|
||||||
fun_dataop_gl_init(gle, 0, 0, lens[i], addrs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_TLS_DEVICE) && unlikely(tls_len)) {
|
if (IS_ENABLED(CONFIG_TLS_DEVICE) && unlikely(tls_len)) {
|
||||||
struct fun_eth_tls *tls = (struct fun_eth_tls *)gle;
|
struct fun_eth_tls *tls = (struct fun_eth_tls *)gle;
|
||||||
|
@ -495,7 +513,6 @@ static unsigned int fun_xdpq_clean(struct funeth_txq *q, unsigned int budget)
|
||||||
bool fun_xdp_tx(struct funeth_txq *q, struct xdp_frame *xdpf)
|
bool fun_xdp_tx(struct funeth_txq *q, struct xdp_frame *xdpf)
|
||||||
{
|
{
|
||||||
struct fun_eth_tx_req *req;
|
struct fun_eth_tx_req *req;
|
||||||
struct fun_dataop_gl *gle;
|
|
||||||
unsigned int idx, len;
|
unsigned int idx, len;
|
||||||
dma_addr_t dma;
|
dma_addr_t dma;
|
||||||
|
|
||||||
|
@ -517,7 +534,7 @@ bool fun_xdp_tx(struct funeth_txq *q, struct xdp_frame *xdpf)
|
||||||
idx = q->prod_cnt & q->mask;
|
idx = q->prod_cnt & q->mask;
|
||||||
req = fun_tx_desc_addr(q, idx);
|
req = fun_tx_desc_addr(q, idx);
|
||||||
req->op = FUN_ETH_OP_TX;
|
req->op = FUN_ETH_OP_TX;
|
||||||
req->len8 = (sizeof(*req) + sizeof(*gle)) / 8;
|
req->len8 = 0;
|
||||||
req->flags = 0;
|
req->flags = 0;
|
||||||
req->suboff8 = offsetof(struct fun_eth_tx_req, dataop);
|
req->suboff8 = offsetof(struct fun_eth_tx_req, dataop);
|
||||||
req->repr_idn = 0;
|
req->repr_idn = 0;
|
||||||
|
@ -525,8 +542,7 @@ bool fun_xdp_tx(struct funeth_txq *q, struct xdp_frame *xdpf)
|
||||||
fun_eth_offload_init(&req->offload, 0, 0, 0, 0, 0, 0, 0, 0);
|
fun_eth_offload_init(&req->offload, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
req->dataop = FUN_DATAOP_HDR_INIT(1, 0, 1, 0, len);
|
req->dataop = FUN_DATAOP_HDR_INIT(1, 0, 1, 0, len);
|
||||||
|
|
||||||
gle = (struct fun_dataop_gl *)req->dataop.imm;
|
fun_write_gl(q, req, &dma, &len, 1);
|
||||||
fun_dataop_gl_init(gle, 0, 0, len, dma);
|
|
||||||
|
|
||||||
q->info[idx].xdpf = xdpf;
|
q->info[idx].xdpf = xdpf;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue