diff mbox series

[bpf-next,v3,05/10] net: stmmac: Add Tx HWTS support to XDP ZC

Message ID 20231003200522.1914523-6-sdf@google.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series xsk: TX metadata | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1365 this patch: 1365
netdev/cc_maintainers warning 9 maintainers not CCed: joabreu@synopsys.com pabeni@redhat.com mcoquelin.stm32@gmail.com davem@davemloft.net alexandre.torgue@foss.st.com edumazet@google.com richardcochran@gmail.com linux-arm-kernel@lists.infradead.org linux-stm32@st-md-mailman.stormreply.com
netdev/build_clang success Errors and warnings before: 1363 this patch: 1363
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1389 this patch: 1389
netdev/checkpatch warning WARNING: line length of 85 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 94 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-0 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-1 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-6 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-28 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-13 fail Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-7 success Logs for test_maps on s390x with gcc

Commit Message

Stanislav Fomichev Oct. 3, 2023, 8:05 p.m. UTC
From: Song Yoong Siang <yoong.siang.song@intel.com>

This patch enables transmit hardware timestamp support to XDP zero copy
via XDP Tx metadata framework.

This patchset is tested with tools/testing/selftests/bpf/xdp_hw_metadata
on Intel Tiger Lake platform. Below are the test steps and results.

Command on DUT:
  sudo ./xdp_hw_metadata <interface name>
  sudo hwstamp_ctl -i <interface name> -t 1 -r 1

Command on Link Partner:
  echo -n xdp | nc -u -q1 <destination IPv4 addr> 9091

Result:
  xsk_ring_cons__peek: 1
  0x562e3313b6d0: rx_desc[3]->addr=8e100 addr=8e100 comp_addr=8e100
  No rx_hash err=-95
  rx_timestamp:  1677763849292380229 (sec:1677763849.2924)
  XDP RX-time:   1677763849292641940 (sec:1677763849.2926)
                 delta sec:0.0003 (261.711 usec)
  AF_XDP time:   1677763849292666175 (sec:1677763849.2927)
                 delta sec:0.0000 (24.235 usec)
  0x562e3313b6d0: ping-pong with csum=561c (want 08af)
                  csum_start=34 csum_offset=6
  0x562e3313b6d0: complete tx idx=3 addr=3008
  0x562e3313b6d0: tx_timestamp:  1677763849295700005 (sec:1677763849.2957)
  0x562e3313b6d0: complete rx idx=131 addr=8e100

Additionally, to double confirm the rx_timestamp and tx_timestamp are taken
from PTP Hardware Clock (PHC), we set the value of PHC to a specific value
using tools/testing/selftests/ptp/testptp. Below are the test steps and
results.

Command to set PHC to a specific value:
  sudo ./testptp -d /dev/ptp2 -T 123000000

Result:
  xsk_ring_cons__peek: 1
  0x562e3313b6d0: rx_desc[7]->addr=9e100 addr=9e100 comp_addr=9e100
  No rx_hash err=-95
  rx_timestamp:  123000002731730589 (sec:123000002.7317)
  XDP RX-time:   1677763869396644361 (sec:1677763869.3966)
                 delta sec:1554763866.6649 (1554763866664913.750 usec)
  AF_XDP time:   1677763869396671376 (sec:1677763869.3967)
                 delta sec:0.0000 (27.015 usec)
  0x562e3313b6d0: ping-pong with csum=561c (want d1bf)
                  csum_start=34 csum_offset=6
  0x562e3313b6d0: complete tx idx=7 addr=7008
  0x562e3313b6d0: tx_timestamp:  123000002735048790 (sec:123000002.7350)
  0x562e3313b6d0: complete rx idx=135 addr=9e100

Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  | 12 ++++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 63 ++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletion(-)

Comments

kernel test robot Oct. 4, 2023, 11:05 p.m. UTC | #1
Hi Stanislav,

kernel test robot noticed the following build errors:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Stanislav-Fomichev/xsk-Support-tx_metadata_len/20231004-040718
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20231003200522.1914523-6-sdf%40google.com
patch subject: [PATCH bpf-next v3 05/10] net: stmmac: Add Tx HWTS support to XDP ZC
config: riscv-defconfig (https://download.01.org/0day-ci/archive/20231005/202310050607.UQ0bU3ct-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231005/202310050607.UQ0bU3ct-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310050607.UQ0bU3ct-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_xdp_xmit_zc':
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2554:17: error: implicit declaration of function 'xsk_tx_metadata_to_compl'; did you mean 'xsk_tx_metadata_complete'? [-Werror=implicit-function-declaration]
    2554 |                 xsk_tx_metadata_to_compl(meta, &tx_q->tx_skbuff_dma[entry].xsk_meta);
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~
         |                 xsk_tx_metadata_complete
   cc1: some warnings being treated as errors


vim +2554 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

  2464	
  2465	static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
  2466	{
  2467		struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
  2468		struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
  2469		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
  2470		struct xsk_buff_pool *pool = tx_q->xsk_pool;
  2471		unsigned int entry = tx_q->cur_tx;
  2472		struct dma_desc *tx_desc = NULL;
  2473		struct xdp_desc xdp_desc;
  2474		bool work_done = true;
  2475		u32 tx_set_ic_bit = 0;
  2476		unsigned long flags;
  2477	
  2478		/* Avoids TX time-out as we are sharing with slow path */
  2479		txq_trans_cond_update(nq);
  2480	
  2481		budget = min(budget, stmmac_tx_avail(priv, queue));
  2482	
  2483		while (budget-- > 0) {
  2484			struct stmmac_metadata_request meta_req;
  2485			struct xsk_tx_metadata *meta = NULL;
  2486			dma_addr_t dma_addr;
  2487			bool set_ic;
  2488	
  2489			/* We are sharing with slow path and stop XSK TX desc submission when
  2490			 * available TX ring is less than threshold.
  2491			 */
  2492			if (unlikely(stmmac_tx_avail(priv, queue) < STMMAC_TX_XSK_AVAIL) ||
  2493			    !netif_carrier_ok(priv->dev)) {
  2494				work_done = false;
  2495				break;
  2496			}
  2497	
  2498			if (!xsk_tx_peek_desc(pool, &xdp_desc))
  2499				break;
  2500	
  2501			if (likely(priv->extend_desc))
  2502				tx_desc = (struct dma_desc *)(tx_q->dma_etx + entry);
  2503			else if (tx_q->tbs & STMMAC_TBS_AVAIL)
  2504				tx_desc = &tx_q->dma_entx[entry].basic;
  2505			else
  2506				tx_desc = tx_q->dma_tx + entry;
  2507	
  2508			dma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);
  2509			meta = xsk_buff_get_metadata(pool, xdp_desc.addr);
  2510			xsk_buff_raw_dma_sync_for_device(pool, dma_addr, xdp_desc.len);
  2511	
  2512			tx_q->tx_skbuff_dma[entry].buf_type = STMMAC_TXBUF_T_XSK_TX;
  2513	
  2514			/* To return XDP buffer to XSK pool, we simple call
  2515			 * xsk_tx_completed(), so we don't need to fill up
  2516			 * 'buf' and 'xdpf'.
  2517			 */
  2518			tx_q->tx_skbuff_dma[entry].buf = 0;
  2519			tx_q->xdpf[entry] = NULL;
  2520	
  2521			tx_q->tx_skbuff_dma[entry].map_as_page = false;
  2522			tx_q->tx_skbuff_dma[entry].len = xdp_desc.len;
  2523			tx_q->tx_skbuff_dma[entry].last_segment = true;
  2524			tx_q->tx_skbuff_dma[entry].is_jumbo = false;
  2525	
  2526			stmmac_set_desc_addr(priv, tx_desc, dma_addr);
  2527	
  2528			tx_q->tx_count_frames++;
  2529	
  2530			if (!priv->tx_coal_frames[queue])
  2531				set_ic = false;
  2532			else if (tx_q->tx_count_frames % priv->tx_coal_frames[queue] == 0)
  2533				set_ic = true;
  2534			else
  2535				set_ic = false;
  2536	
  2537			meta_req.priv = priv;
  2538			meta_req.tx_desc = tx_desc;
  2539			meta_req.set_ic = &set_ic;
  2540			xsk_tx_metadata_request(meta, &stmmac_xsk_tx_metadata_ops, &meta_req);
  2541	
  2542			if (set_ic) {
  2543				tx_q->tx_count_frames = 0;
  2544				stmmac_set_tx_ic(priv, tx_desc);
  2545				tx_set_ic_bit++;
  2546			}
  2547	
  2548			stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
  2549					       true, priv->mode, true, true,
  2550					       xdp_desc.len);
  2551	
  2552			stmmac_enable_dma_transmission(priv, priv->ioaddr);
  2553	
> 2554			xsk_tx_metadata_to_compl(meta, &tx_q->tx_skbuff_dma[entry].xsk_meta);
  2555	
  2556			tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
  2557			entry = tx_q->cur_tx;
  2558		}
  2559		flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
  2560		txq_stats->tx_set_ic_bit += tx_set_ic_bit;
  2561		u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
  2562	
  2563		if (tx_desc) {
  2564			stmmac_flush_tx_descriptors(priv, queue);
  2565			xsk_tx_release(pool);
  2566		}
  2567	
  2568		/* Return true if all of the 3 conditions are met
  2569		 *  a) TX Budget is still available
  2570		 *  b) work_done = true when XSK TX desc peek is empty (no more
  2571		 *     pending XSK TX for transmission)
  2572		 */
  2573		return !!budget && work_done;
  2574	}
  2575
Stanislav Fomichev Oct. 4, 2023, 11:14 p.m. UTC | #2
On 10/05, kernel test robot wrote:
> Hi Stanislav,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on bpf-next/master]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Stanislav-Fomichev/xsk-Support-tx_metadata_len/20231004-040718
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
> patch link:    https://lore.kernel.org/r/20231003200522.1914523-6-sdf%40google.com
> patch subject: [PATCH bpf-next v3 05/10] net: stmmac: Add Tx HWTS support to XDP ZC
> config: riscv-defconfig (https://download.01.org/0day-ci/archive/20231005/202310050607.UQ0bU3ct-lkp@intel.com/config)
> compiler: riscv64-linux-gcc (GCC) 13.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231005/202310050607.UQ0bU3ct-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202310050607.UQ0bU3ct-lkp@intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_xdp_xmit_zc':
> >> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2554:17: error: implicit declaration of function 'xsk_tx_metadata_to_compl'; did you mean 'xsk_tx_metadata_complete'? [-Werror=implicit-function-declaration]
>     2554 |                 xsk_tx_metadata_to_compl(meta, &tx_q->tx_skbuff_dma[entry].xsk_meta);
>          |                 ^~~~~~~~~~~~~~~~~~~~~~~~
>          |                 xsk_tx_metadata_complete
>    cc1: some warnings being treated as errors


Missing "static inline xsk_tx_metadata_to_compl" for !CONFIG_XDP_SOCKETS.
Will fix in the patch where I add xsk_tx_metadata_to_compl...
kernel test robot Oct. 6, 2023, 4:38 a.m. UTC | #3
Hi Stanislav,

kernel test robot noticed the following build errors:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Stanislav-Fomichev/xsk-Support-tx_metadata_len/20231004-040718
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20231003200522.1914523-6-sdf%40google.com
patch subject: [PATCH bpf-next v3 05/10] net: stmmac: Add Tx HWTS support to XDP ZC
config: riscv-rv32_defconfig (https://download.01.org/0day-ci/archive/20231006/202310061208.tATL34LR-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231006/202310061208.tATL34LR-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310061208.tATL34LR-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2554:3: error: call to undeclared function 'xsk_tx_metadata_to_compl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2554 |                 xsk_tx_metadata_to_compl(meta, &tx_q->tx_skbuff_dma[entry].xsk_meta);
         |                 ^
   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2554:3: note: did you mean 'xsk_tx_metadata_complete'?
   include/net/xdp_sock.h:185:20: note: 'xsk_tx_metadata_complete' declared here
     185 | static inline void xsk_tx_metadata_complete(struct xsk_tx_metadata_compl *compl,
         |                    ^
   1 error generated.


vim +/xsk_tx_metadata_to_compl +2554 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

  2464	
  2465	static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
  2466	{
  2467		struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
  2468		struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
  2469		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
  2470		struct xsk_buff_pool *pool = tx_q->xsk_pool;
  2471		unsigned int entry = tx_q->cur_tx;
  2472		struct dma_desc *tx_desc = NULL;
  2473		struct xdp_desc xdp_desc;
  2474		bool work_done = true;
  2475		u32 tx_set_ic_bit = 0;
  2476		unsigned long flags;
  2477	
  2478		/* Avoids TX time-out as we are sharing with slow path */
  2479		txq_trans_cond_update(nq);
  2480	
  2481		budget = min(budget, stmmac_tx_avail(priv, queue));
  2482	
  2483		while (budget-- > 0) {
  2484			struct stmmac_metadata_request meta_req;
  2485			struct xsk_tx_metadata *meta = NULL;
  2486			dma_addr_t dma_addr;
  2487			bool set_ic;
  2488	
  2489			/* We are sharing with slow path and stop XSK TX desc submission when
  2490			 * available TX ring is less than threshold.
  2491			 */
  2492			if (unlikely(stmmac_tx_avail(priv, queue) < STMMAC_TX_XSK_AVAIL) ||
  2493			    !netif_carrier_ok(priv->dev)) {
  2494				work_done = false;
  2495				break;
  2496			}
  2497	
  2498			if (!xsk_tx_peek_desc(pool, &xdp_desc))
  2499				break;
  2500	
  2501			if (likely(priv->extend_desc))
  2502				tx_desc = (struct dma_desc *)(tx_q->dma_etx + entry);
  2503			else if (tx_q->tbs & STMMAC_TBS_AVAIL)
  2504				tx_desc = &tx_q->dma_entx[entry].basic;
  2505			else
  2506				tx_desc = tx_q->dma_tx + entry;
  2507	
  2508			dma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);
  2509			meta = xsk_buff_get_metadata(pool, xdp_desc.addr);
  2510			xsk_buff_raw_dma_sync_for_device(pool, dma_addr, xdp_desc.len);
  2511	
  2512			tx_q->tx_skbuff_dma[entry].buf_type = STMMAC_TXBUF_T_XSK_TX;
  2513	
  2514			/* To return XDP buffer to XSK pool, we simple call
  2515			 * xsk_tx_completed(), so we don't need to fill up
  2516			 * 'buf' and 'xdpf'.
  2517			 */
  2518			tx_q->tx_skbuff_dma[entry].buf = 0;
  2519			tx_q->xdpf[entry] = NULL;
  2520	
  2521			tx_q->tx_skbuff_dma[entry].map_as_page = false;
  2522			tx_q->tx_skbuff_dma[entry].len = xdp_desc.len;
  2523			tx_q->tx_skbuff_dma[entry].last_segment = true;
  2524			tx_q->tx_skbuff_dma[entry].is_jumbo = false;
  2525	
  2526			stmmac_set_desc_addr(priv, tx_desc, dma_addr);
  2527	
  2528			tx_q->tx_count_frames++;
  2529	
  2530			if (!priv->tx_coal_frames[queue])
  2531				set_ic = false;
  2532			else if (tx_q->tx_count_frames % priv->tx_coal_frames[queue] == 0)
  2533				set_ic = true;
  2534			else
  2535				set_ic = false;
  2536	
  2537			meta_req.priv = priv;
  2538			meta_req.tx_desc = tx_desc;
  2539			meta_req.set_ic = &set_ic;
  2540			xsk_tx_metadata_request(meta, &stmmac_xsk_tx_metadata_ops, &meta_req);
  2541	
  2542			if (set_ic) {
  2543				tx_q->tx_count_frames = 0;
  2544				stmmac_set_tx_ic(priv, tx_desc);
  2545				tx_set_ic_bit++;
  2546			}
  2547	
  2548			stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
  2549					       true, priv->mode, true, true,
  2550					       xdp_desc.len);
  2551	
  2552			stmmac_enable_dma_transmission(priv, priv->ioaddr);
  2553	
> 2554			xsk_tx_metadata_to_compl(meta, &tx_q->tx_skbuff_dma[entry].xsk_meta);
  2555	
  2556			tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
  2557			entry = tx_q->cur_tx;
  2558		}
  2559		flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
  2560		txq_stats->tx_set_ic_bit += tx_set_ic_bit;
  2561		u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
  2562	
  2563		if (tx_desc) {
  2564			stmmac_flush_tx_descriptors(priv, queue);
  2565			xsk_tx_release(pool);
  2566		}
  2567	
  2568		/* Return true if all of the 3 conditions are met
  2569		 *  a) TX Budget is still available
  2570		 *  b) work_done = true when XSK TX desc peek is empty (no more
  2571		 *     pending XSK TX for transmission)
  2572		 */
  2573		return !!budget && work_done;
  2574	}
  2575
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index cd7a9768de5f..686c94c2e8a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -51,6 +51,7 @@  struct stmmac_tx_info {
 	bool last_segment;
 	bool is_jumbo;
 	enum stmmac_txbuf_type buf_type;
+	struct xsk_tx_metadata_compl xsk_meta;
 };
 
 #define STMMAC_TBS_AVAIL	BIT(0)
@@ -100,6 +101,17 @@  struct stmmac_xdp_buff {
 	struct dma_desc *ndesc;
 };
 
+struct stmmac_metadata_request {
+	struct stmmac_priv *priv;
+	struct dma_desc *tx_desc;
+	bool *set_ic;
+};
+
+struct stmmac_xsk_tx_complete {
+	struct stmmac_priv *priv;
+	struct dma_desc *desc;
+};
+
 struct stmmac_rx_queue {
 	u32 rx_count_frames;
 	u32 queue_index;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 81b6f3ecdf92..697712dd4024 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2422,6 +2422,46 @@  static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
 	}
 }
 
+static void stmmac_xsk_request_timestamp(void *_priv)
+{
+	struct stmmac_metadata_request *meta_req = _priv;
+
+	stmmac_enable_tx_timestamp(meta_req->priv, meta_req->tx_desc);
+	*meta_req->set_ic = true;
+}
+
+static u64 stmmac_xsk_fill_timestamp(void *_priv)
+{
+	struct stmmac_xsk_tx_complete *tx_compl = _priv;
+	struct stmmac_priv *priv = tx_compl->priv;
+	struct dma_desc *desc = tx_compl->desc;
+	bool found = false;
+	u64 ns = 0;
+
+	if (!priv->hwts_tx_en)
+		return 0;
+
+	/* check tx tstamp status */
+	if (stmmac_get_tx_timestamp_status(priv, desc)) {
+		stmmac_get_timestamp(priv, desc, priv->adv_ts, &ns);
+		found = true;
+	} else if (!stmmac_get_mac_tx_timestamp(priv, priv->hw, &ns)) {
+		found = true;
+	}
+
+	if (found) {
+		ns -= priv->plat->cdc_error_adj;
+		return ns_to_ktime(ns);
+	}
+
+	return 0;
+}
+
+static const struct xsk_tx_metadata_ops stmmac_xsk_tx_metadata_ops = {
+	.tmo_request_timestamp		= stmmac_xsk_request_timestamp,
+	.tmo_fill_timestamp		= stmmac_xsk_fill_timestamp,
+};
+
 static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 {
 	struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
@@ -2441,6 +2481,8 @@  static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 	budget = min(budget, stmmac_tx_avail(priv, queue));
 
 	while (budget-- > 0) {
+		struct stmmac_metadata_request meta_req;
+		struct xsk_tx_metadata *meta = NULL;
 		dma_addr_t dma_addr;
 		bool set_ic;
 
@@ -2464,6 +2506,7 @@  static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 			tx_desc = tx_q->dma_tx + entry;
 
 		dma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);
+		meta = xsk_buff_get_metadata(pool, xdp_desc.addr);
 		xsk_buff_raw_dma_sync_for_device(pool, dma_addr, xdp_desc.len);
 
 		tx_q->tx_skbuff_dma[entry].buf_type = STMMAC_TXBUF_T_XSK_TX;
@@ -2491,6 +2534,11 @@  static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 		else
 			set_ic = false;
 
+		meta_req.priv = priv;
+		meta_req.tx_desc = tx_desc;
+		meta_req.set_ic = &set_ic;
+		xsk_tx_metadata_request(meta, &stmmac_xsk_tx_metadata_ops, &meta_req);
+
 		if (set_ic) {
 			tx_q->tx_count_frames = 0;
 			stmmac_set_tx_ic(priv, tx_desc);
@@ -2503,6 +2551,8 @@  static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 
 		stmmac_enable_dma_transmission(priv, priv->ioaddr);
 
+		xsk_tx_metadata_to_compl(meta, &tx_q->tx_skbuff_dma[entry].xsk_meta);
+
 		tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
 		entry = tx_q->cur_tx;
 	}
@@ -2608,8 +2658,18 @@  static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
 			} else {
 				tx_packets++;
 			}
-			if (skb)
+			if (skb) {
 				stmmac_get_tx_hwtstamp(priv, p, skb);
+			} else {
+				struct stmmac_xsk_tx_complete tx_compl = {
+					.priv = priv,
+					.desc = p,
+				};
+
+				xsk_tx_metadata_complete(&tx_q->tx_skbuff_dma[entry].xsk_meta,
+							 &stmmac_xsk_tx_metadata_ops,
+							 &tx_compl);
+			}
 		}
 
 		if (likely(tx_q->tx_skbuff_dma[entry].buf &&
@@ -7444,6 +7504,7 @@  int stmmac_dvr_probe(struct device *device,
 	ndev->netdev_ops = &stmmac_netdev_ops;
 
 	ndev->xdp_metadata_ops = &stmmac_xdp_metadata_ops;
+	ndev->xsk_tx_metadata_ops = &stmmac_xsk_tx_metadata_ops;
 
 	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			    NETIF_F_RXCSUM;