aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2021-02-19 21:47:18 +0000
committerNavdeep Parhar <np@FreeBSD.org>2021-02-19 22:23:58 +0000
commitc91dda5ad923f24ef2e538b8dc180fa98598b4db (patch)
tree02cd51cb15e0aadc64676e32e835f89eaa0d8676 /sys/dev
parent7ac8040a99319456c3225cd5166390f5bd172fdf (diff)
downloadsrc-c91dda5ad923f24ef2e538b8dc180fa98598b4db.tar.gz
src-c91dda5ad923f24ef2e538b8dc180fa98598b4db.zip
cxgbe(4): Add a driver ioctl to set the filter mask.
Allow the filter mask (aka the hashfilter mode when hashfilters are in use) to be set any time it is safe to do so. The requested mask must be a subset of the filter mode already. The driver will not change the mode or ingress config just to support a new mask. MFC after: 2 weeks Sponsored by: Chelsio Communications
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/cxgbe/adapter.h1
-rw-r--r--sys/dev/cxgbe/t4_filter.c42
-rw-r--r--sys/dev/cxgbe/t4_ioctl.h2
-rw-r--r--sys/dev/cxgbe/t4_main.c3
4 files changed, 48 insertions, 0 deletions
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h
index 8b8e6bf339e8..5fe7b76ccb0d 100644
--- a/sys/dev/cxgbe/adapter.h
+++ b/sys/dev/cxgbe/adapter.h
@@ -1337,6 +1337,7 @@ void cxgbe_ratelimit_query(struct ifnet *, struct if_ratelimit_query_results *);
/* t4_filter.c */
int get_filter_mode(struct adapter *, uint32_t *);
int set_filter_mode(struct adapter *, uint32_t);
+int set_filter_mask(struct adapter *, uint32_t);
int get_filter(struct adapter *, struct t4_filter *);
int set_filter(struct adapter *, struct t4_filter *);
int del_filter(struct adapter *, struct t4_filter *);
diff --git a/sys/dev/cxgbe/t4_filter.c b/sys/dev/cxgbe/t4_filter.c
index 1e0269fcd5c0..3afab0d1d6b9 100644
--- a/sys/dev/cxgbe/t4_filter.c
+++ b/sys/dev/cxgbe/t4_filter.c
@@ -543,6 +543,48 @@ done:
return (rc);
}
+int
+set_filter_mask(struct adapter *sc, uint32_t mode)
+{
+ struct tp_params *tp = &sc->params.tp;
+ int rc, iconf;
+ uint16_t fmask;
+
+ iconf = mode_to_iconf(mode);
+ fmask = mode_to_fconf(mode);
+ if ((iconf == -1 || iconf == tp->vnic_mode) && fmask == tp->filter_mask)
+ return (0); /* Nothing to do */
+
+ /*
+ * We aren't going to change the global filter mode or VNIC mode here.
+ * The given filter mask must conform to them.
+ */
+ if ((fmask | tp->filter_mode) != tp->filter_mode)
+ return (EINVAL);
+ if (iconf != -1 && iconf != tp->vnic_mode)
+ return (EINVAL);
+
+ rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4sethfm");
+ if (rc)
+ return (rc);
+
+ if (sc->tids.tids_in_use > 0) { /* TOE or hashfilters active */
+ rc = EBUSY;
+ goto done;
+ }
+
+#ifdef TCP_OFFLOAD
+ if (uld_active(sc, ULD_TOM)) {
+ rc = EBUSY;
+ goto done;
+ }
+#endif
+ rc = -t4_set_filter_cfg(sc, -1, fmask, -1);
+done:
+ end_synchronized_op(sc, 0);
+ return (rc);
+}
+
static inline uint64_t
get_filter_hits(struct adapter *sc, uint32_t tid)
{
diff --git a/sys/dev/cxgbe/t4_ioctl.h b/sys/dev/cxgbe/t4_ioctl.h
index 4f0a71683ef0..ff2c5ef80a14 100644
--- a/sys/dev/cxgbe/t4_ioctl.h
+++ b/sys/dev/cxgbe/t4_ioctl.h
@@ -63,6 +63,7 @@ enum {
T4_LOAD_BOOT, /* flash boot rom */
T4_LOAD_BOOTCFG, /* flash bootcfg */
T4_CUDBG_DUMP, /* debug dump of chip state */
+ T4_SET_FILTER_MASK, /* set filter mask (hashfilter mode) */
};
struct t4_reg {
@@ -429,4 +430,5 @@ struct t4_offload_policy {
#define CHELSIO_T4_LOAD_BOOTCFG _IOW('f', T4_LOAD_BOOTCFG, struct t4_data)
#define CHELSIO_T4_CUDBG_DUMP _IOWR('f', T4_CUDBG_DUMP, struct t4_cudbg_dump)
#define CHELSIO_T4_SET_OFLD_POLICY _IOW('f', T4_SET_OFLD_POLICY, struct t4_offload_policy)
+#define CHELSIO_T4_SET_FILTER_MASK _IOW('f', T4_SET_FILTER_MASK, uint32_t)
#endif
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index f64d349b46ae..3594db2ea136 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -10970,6 +10970,9 @@ t4_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, int fflag,
case CHELSIO_T4_SET_FILTER_MODE:
rc = set_filter_mode(sc, *(uint32_t *)data);
break;
+ case CHELSIO_T4_SET_FILTER_MASK:
+ rc = set_filter_mask(sc, *(uint32_t *)data);
+ break;
case CHELSIO_T4_GET_FILTER:
rc = get_filter(sc, (struct t4_filter *)data);
break;