summaryrefslogtreecommitdiff
path: root/sys/dev/dpaa2/dpaa2_frame.c
diff options
context:
space:
mode:
authorDmitry Salychev <dsl@FreeBSD.org>2026-04-13 14:46:49 +0200
committerDmitry Salychev <dsl@FreeBSD.org>2026-04-19 20:11:41 +0200
commit4a6d7fc1a00b69925b3edc39acef0391487a8e3e (patch)
tree8e92fe9845a72c63d600df59be95460f6355391b /sys/dev/dpaa2/dpaa2_frame.c
parent9d39213d222395eb40323102db018cbedf773ddf (diff)
dpaa2: Extract checksum statuses on ingressHEADmain
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.c100
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