aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Hu <whu@FreeBSD.org>2023-09-13 10:48:02 +0000
committerWei Hu <whu@FreeBSD.org>2023-09-13 10:59:40 +0000
commitab7dc1ceb6d36fd804bedb818086ae3ff6692bf7 (patch)
tree298767131942247e93550d05944d393358405b44
parent7f5e3b9fa3d159b7f061b4d01a767cbe5d0527f3 (diff)
-rw-r--r--sys/dev/mana/mana_en.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/sys/dev/mana/mana_en.c b/sys/dev/mana/mana_en.c
index 56fa4e51ba26..064b28fa94a4 100644
--- a/sys/dev/mana/mana_en.c
+++ b/sys/dev/mana/mana_en.c
@@ -169,7 +169,7 @@ mana_ioctl(if_t ifp, u_long command, caddr_t data)
struct ifrsshash *ifrh;
struct ifreq *ifr;
uint16_t new_mtu;
- int rc = 0;
+ int rc = 0, mask;
switch (command) {
case SIOCSIFMTU:
@@ -214,6 +214,81 @@ mana_ioctl(if_t ifp, u_long command, caddr_t data)
}
break;
+ case SIOCSIFCAP:
+ MANA_APC_LOCK_LOCK(apc);
+ ifr = (struct ifreq *)data;
+ /*
+ * Fix up requested capabilities w/ supported capabilities,
+ * since the supported capabilities could have been changed.
+ */
+ mask = (ifr->ifr_reqcap & if_getcapabilities(ifp)) ^
+ if_getcapenable(ifp);
+
+ if (mask & IFCAP_TXCSUM) {
+ if_togglecapenable(ifp, IFCAP_TXCSUM);
+ if_togglehwassist(ifp, (CSUM_TCP | CSUM_UDP | CSUM_IP));
+
+ if ((IFCAP_TSO4 & if_getcapenable(ifp)) &&
+ !(IFCAP_TXCSUM & if_getcapenable(ifp))) {
+ mask &= ~IFCAP_TSO4;
+ if_setcapenablebit(ifp, 0, IFCAP_TSO4);
+ if_sethwassistbits(ifp, 0, CSUM_IP_TSO);
+ mana_warn(NULL,
+ "Also disabled tso4 due to -txcsum.\n");
+ }
+ }
+
+ if (mask & IFCAP_TXCSUM_IPV6) {
+ if_togglecapenable(ifp, IFCAP_TXCSUM_IPV6);
+ if_togglehwassist(ifp, (CSUM_UDP_IPV6 | CSUM_TCP_IPV6));
+
+ if ((IFCAP_TSO6 & if_getcapenable(ifp)) &&
+ !(IFCAP_TXCSUM_IPV6 & if_getcapenable(ifp))) {
+ mask &= ~IFCAP_TSO6;
+ if_setcapenablebit(ifp, 0, IFCAP_TSO6);
+ if_sethwassistbits(ifp, 0, CSUM_IP6_TSO);
+ mana_warn(ifp,
+ "Also disabled tso6 due to -txcsum6.\n");
+ }
+ }
+
+ if (mask & IFCAP_RXCSUM)
+ if_togglecapenable(ifp, IFCAP_RXCSUM);
+ /* We can't diff IPv6 packets from IPv4 packets on RX path. */
+ if (mask & IFCAP_RXCSUM_IPV6)
+ if_togglecapenable(ifp, IFCAP_RXCSUM_IPV6);
+
+ if (mask & IFCAP_LRO)
+ if_togglecapenable(ifp, IFCAP_LRO);
+
+ if (mask & IFCAP_TSO4) {
+ if (!(IFCAP_TSO4 & if_getcapenable(ifp)) &&
+ !(IFCAP_TXCSUM & if_getcapenable(ifp))) {
+ MANA_APC_LOCK_UNLOCK(apc);
+ if_printf(ifp, "Enable txcsum first.\n");
+ rc = EAGAIN;
+ goto out;
+ }
+ if_togglecapenable(ifp, IFCAP_TSO4);
+ if_togglehwassist(ifp, CSUM_IP_TSO);
+ }
+
+ if (mask & IFCAP_TSO6) {
+ if (!(IFCAP_TSO6 & if_getcapenable(ifp)) &&
+ !(IFCAP_TXCSUM_IPV6 & if_getcapenable(ifp))) {
+ MANA_APC_LOCK_UNLOCK(apc);
+ if_printf(ifp, "Enable txcsum6 first.\n");
+ rc = EAGAIN;
+ goto out;
+ }
+ if_togglecapenable(ifp, IFCAP_TSO6);
+ if_togglehwassist(ifp, CSUM_IP6_TSO);
+ }
+
+ MANA_APC_LOCK_UNLOCK(apc);
+out:
+ break;
+
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
case SIOCGIFXMEDIA: