diff options
-rw-r--r-- | sys/dev/cxgbe/adapter.h | 1 | ||||
-rw-r--r-- | sys/dev/cxgbe/t4_filter.c | 42 | ||||
-rw-r--r-- | sys/dev/cxgbe/t4_ioctl.h | 2 | ||||
-rw-r--r-- | sys/dev/cxgbe/t4_main.c | 3 |
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; |