diff options
| author | Dmitry Salychev <dsl@FreeBSD.org> | 2026-04-13 14:46:49 +0200 |
|---|---|---|
| committer | Dmitry Salychev <dsl@FreeBSD.org> | 2026-04-19 20:11:41 +0200 |
| commit | 4a6d7fc1a00b69925b3edc39acef0391487a8e3e (patch) | |
| tree | 8e92fe9845a72c63d600df59be95460f6355391b /sys/dev/dpaa2/dpaa2_frame.c | |
| parent | 9d39213d222395eb40323102db018cbedf773ddf (diff) | |
In order to enable RX checksum offloading we need to check the
meta-information for the (good) frames to see if the L3/4 checksums
were calculated and if there was an error.
The way the buffere are setup, the needed frame meta-information is
already requested. All we have to do is make sure it is really part
of the RX frame, that it is valid, and if the respective bits are set.
Also do not forget to set the (dummy) csum_data as otherwise upper
layers will just be cranky. An artefact of the past which likely
should disappear.
PR: 292006
Reviewed by: bz, tuexen
Tested by: bz, tuexen
Approved by: tuexen
Obtained from: bz (initial version, D55320)
MFC after: 3 days
Sponsored by: Traverse Technologies (providing Ten64 HW for testing)
Differential Revision: https://reviews.freebsd.org/D56383
Diffstat (limited to 'sys/dev/dpaa2/dpaa2_frame.c')
| -rw-r--r-- | sys/dev/dpaa2/dpaa2_frame.c | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/sys/dev/dpaa2/dpaa2_frame.c b/sys/dev/dpaa2/dpaa2_frame.c index 4a155f7cb32f..005708228058 100644 --- a/sys/dev/dpaa2/dpaa2_frame.c +++ b/sys/dev/dpaa2/dpaa2_frame.c @@ -1,7 +1,8 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright © 2026 Dmitry Salychev + * Copyright (c) 2026 Dmitry Salychev + * Copyright (c) 2026 Bjoern A. Zeeb * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,6 +30,7 @@ #include <sys/param.h> #include <sys/errno.h> +#include <sys/endian.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -138,28 +140,102 @@ dpaa2_fd_offset(struct dpaa2_fd *fd) return (fd->offset_fmt_sl & DPAA2_FD_OFFSET_MASK); } +uint32_t +dpaa2_fd_get_frc(struct dpaa2_fd *fd) +{ + /* TODO: Convert endiannes in the other functions as well. */ + return (le32toh(fd->frame_ctx)); +} + +#ifdef _not_yet_ +void +dpaa2_fd_set_frc(struct dpaa2_fd *fd, uint32_t frc) +{ + /* TODO: Convert endiannes in the other functions as well. */ + fd->frame_ctx = htole32(frc); +} +#endif + int dpaa2_fa_get_swa(struct dpaa2_fd *fd, struct dpaa2_swa **swa) { - int rc; - - if (fd == NULL || swa == NULL) + if (__predict_false(fd == NULL || swa == NULL)) return (EINVAL); - if (((fd->ctrl >> DPAA2_FD_PTAC_SHIFT) & DPAA2_FD_PTAC_MASK) >= 0x4u) { - *swa = (struct dpaa2_swa *)PHYS_TO_DMAP((bus_addr_t)fd->addr); - rc = 0; - } else { + if (((fd->ctrl >> DPAA2_FD_PTAC_SHIFT) & DPAA2_FD_PTAC_PTA_MASK) == 0u) { *swa = NULL; - rc = ENOENT; + return (ENOENT); } - return (rc); + *swa = (struct dpaa2_swa *)PHYS_TO_DMAP((bus_addr_t)fd->addr); + + return (0); } int dpaa2_fa_get_hwa(struct dpaa2_fd *fd, struct dpaa2_hwa **hwa) { - /* TODO: To be implemented next. */ - return (ENOENT); + uint8_t *buf; + uint32_t hwo; /* HW annotation offset */ + + if (__predict_false(fd == NULL || hwa == NULL)) + return (EINVAL); + + /* + * As soon as the ASAL is in the 64-byte units, we don't need to + * calculate the exact length, but make sure that it isn't 0. + */ + if (((fd->ctrl >> DPAA2_FD_ASAL_SHIFT) & DPAA2_FD_ASAL_MASK) == 0u) { + *hwa = NULL; + return (ENOENT); + } + + buf = (uint8_t *)PHYS_TO_DMAP((bus_addr_t)fd->addr); + hwo = ((fd->ctrl >> DPAA2_FD_PTAC_SHIFT) & DPAA2_FD_PTAC_PTA_MASK) > 0u + ? DPAA2_FA_SWA_SIZE : 0u; + *hwa = (struct dpaa2_hwa *)(buf + hwo); + + return (0); +} + +int +dpaa2_fa_get_fas(struct dpaa2_fd *fd, struct dpaa2_hwa_fas *fas) +{ + struct dpaa2_hwa *hwa; + struct dpaa2_hwa_fas *fasp; + int rc; + + if (__predict_false(fd == NULL || fas == NULL)) + return (EINVAL); + + rc = dpaa2_fa_get_hwa(fd, &hwa); + if (__predict_false(rc != 0)) + return (rc); + + fasp = (struct dpaa2_hwa_fas *)&hwa->fas; + *fas = *fasp; + + return (rc); +} + +#ifdef _not_yet_ +int +dpaa2_fa_set_fas(struct dpaa2_fd *fd, struct dpaa2_hwa_fas *fas) +{ + struct dpaa2_hwa *hwa; + uint64_t *valp; + int rc; + + if (__predict_false(fd == NULL || fas == NULL)) + return (EINVAL); + + rc = dpaa2_fa_get_hwa(fd, &hwa); + if (__predict_false(rc != 0)) + return (rc); + + valp = (uint64_t *)fas; + hwa->fas = *valp; + + return (rc); } +#endif |
