Changeset View
Standalone View
sys/dev/mlx5/mlx5_en/mlx5_en_main.c
Show All 27 Lines | |||||
#include "opt_kern_tls.h" | #include "opt_kern_tls.h" | ||||
#include "opt_rss.h" | #include "opt_rss.h" | ||||
#include "opt_ratelimit.h" | #include "opt_ratelimit.h" | ||||
#include <dev/mlx5/mlx5_en/en.h> | #include <dev/mlx5/mlx5_en/en.h> | ||||
#include <sys/eventhandler.h> | #include <sys/eventhandler.h> | ||||
#include <sys/nv.h> | |||||
#include <sys/sockio.h> | #include <sys/sockio.h> | ||||
#include <machine/atomic.h> | #include <machine/atomic.h> | ||||
#include <net/debugnet.h> | #include <net/debugnet.h> | ||||
static int mlx5e_get_wqe_sz(struct mlx5e_priv *priv, u32 *wqe_sz, u32 *nsegs); | static int mlx5e_get_wqe_sz(struct mlx5e_priv *priv, u32 *wqe_sz, u32 *nsegs); | ||||
static if_snd_tag_query_t mlx5e_ul_snd_tag_query; | static if_snd_tag_query_t mlx5e_ul_snd_tag_query; | ||||
static if_snd_tag_free_t mlx5e_ul_snd_tag_free; | static if_snd_tag_free_t mlx5e_ul_snd_tag_free; | ||||
▲ Show 20 Lines • Show All 3,377 Lines • ▼ Show 20 Lines | |||||
mlx5e_set_rx_mode(struct ifnet *ifp) | mlx5e_set_rx_mode(struct ifnet *ifp) | ||||
{ | { | ||||
struct mlx5e_priv *priv = ifp->if_softc; | struct mlx5e_priv *priv = ifp->if_softc; | ||||
queue_work(priv->wq, &priv->set_rx_mode_work); | queue_work(priv->wq, &priv->set_rx_mode_work); | ||||
} | } | ||||
static int | static int | ||||
mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data) | mlx5e_set_legacy_caps_locked(struct ifnet *ifp, unsigned mask, unsigned value) | ||||
{ | { | ||||
struct mlx5e_priv *priv; | struct mlx5e_priv *priv = ifp->if_softc; | ||||
struct ifreq *ifr; | |||||
struct ifdownreason *ifdr; | |||||
struct ifi2creq i2c; | |||||
struct ifrsskey *ifrk; | |||||
struct ifrsshash *ifrh; | |||||
int error = 0; | int error = 0; | ||||
int mask = 0; | |||||
int size_read = 0; | |||||
int module_status; | |||||
int module_num; | |||||
int max_mtu; | |||||
uint8_t read_addr; | |||||
priv = ifp->if_softc; | mask &= (value ^ ifp->if_capenable); | ||||
/* check if detaching */ | |||||
if (priv == NULL || priv->gone != 0) | |||||
return (ENXIO); | |||||
switch (command) { | |||||
case SIOCSIFMTU: | |||||
ifr = (struct ifreq *)data; | |||||
PRIV_LOCK(priv); | |||||
mlx5_query_port_max_mtu(priv->mdev, &max_mtu); | |||||
if (ifr->ifr_mtu >= MLX5E_MTU_MIN && | |||||
ifr->ifr_mtu <= MIN(MLX5E_MTU_MAX, max_mtu)) { | |||||
int was_opened; | |||||
was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); | |||||
if (was_opened) | |||||
mlx5e_close_locked(ifp); | |||||
/* set new MTU */ | |||||
mlx5e_set_dev_port_mtu(ifp, ifr->ifr_mtu); | |||||
if (was_opened) | |||||
mlx5e_open_locked(ifp); | |||||
} else { | |||||
error = EINVAL; | |||||
mlx5_en_err(ifp, | |||||
"Invalid MTU value. Min val: %d, Max val: %d\n", | |||||
MLX5E_MTU_MIN, MIN(MLX5E_MTU_MAX, max_mtu)); | |||||
} | |||||
PRIV_UNLOCK(priv); | |||||
break; | |||||
case SIOCSIFFLAGS: | |||||
if ((ifp->if_flags & IFF_UP) && | |||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)) { | |||||
mlx5e_set_rx_mode(ifp); | |||||
break; | |||||
} | |||||
PRIV_LOCK(priv); | |||||
if (ifp->if_flags & IFF_UP) { | |||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { | |||||
if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) | |||||
mlx5e_open_locked(ifp); | |||||
ifp->if_drv_flags |= IFF_DRV_RUNNING; | |||||
mlx5_set_port_status(priv->mdev, MLX5_PORT_UP); | |||||
} | |||||
} else { | |||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) { | |||||
mlx5_set_port_status(priv->mdev, | |||||
MLX5_PORT_DOWN); | |||||
if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0) | |||||
mlx5e_close_locked(ifp); | |||||
mlx5e_update_carrier(priv); | |||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | |||||
} | |||||
} | |||||
PRIV_UNLOCK(priv); | |||||
break; | |||||
case SIOCADDMULTI: | |||||
case SIOCDELMULTI: | |||||
mlx5e_set_rx_mode(ifp); | |||||
break; | |||||
case SIOCSIFMEDIA: | |||||
case SIOCGIFMEDIA: | |||||
case SIOCGIFXMEDIA: | |||||
ifr = (struct ifreq *)data; | |||||
error = ifmedia_ioctl(ifp, ifr, &priv->media, command); | |||||
break; | |||||
case SIOCSIFCAP: | |||||
ifr = (struct ifreq *)data; | |||||
PRIV_LOCK(priv); | |||||
mask = ifr->ifr_reqcap ^ ifp->if_capenable; | |||||
if (mask & IFCAP_TXCSUM) { | if (mask & IFCAP_TXCSUM) { | ||||
ifp->if_capenable ^= IFCAP_TXCSUM; | ifp->if_capenable ^= IFCAP_TXCSUM; | ||||
ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); | ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); | ||||
if (IFCAP_TSO4 & ifp->if_capenable && | if (IFCAP_TSO4 & ifp->if_capenable && | ||||
!(IFCAP_TXCSUM & ifp->if_capenable)) { | !(IFCAP_TXCSUM & ifp->if_capenable)) { | ||||
mask &= ~IFCAP_TSO4; | mask &= ~IFCAP_TSO4; | ||||
ifp->if_capenable &= ~IFCAP_TSO4; | ifp->if_capenable &= ~IFCAP_TSO4; | ||||
ifp->if_hwassist &= ~CSUM_IP_TSO; | ifp->if_hwassist &= ~CSUM_IP_TSO; | ||||
mlx5_en_err(ifp, | mlx5_en_err(ifp, | ||||
"tso4 disabled due to -txcsum.\n"); | "tso4 disabled due to -txcsum.\n"); | ||||
} | } | ||||
} | } | ||||
if (mask & IFCAP_TXCSUM_IPV6) { | if (mask & IFCAP_TXCSUM_IPV6) { | ||||
ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; | ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; | ||||
ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6); | ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6); | ||||
if (IFCAP_TSO6 & ifp->if_capenable && | if (IFCAP_TSO6 & ifp->if_capenable && | ||||
!(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { | !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { | ||||
mask &= ~IFCAP_TSO6; | mask &= ~IFCAP_TSO6; | ||||
ifp->if_capenable &= ~IFCAP_TSO6; | ifp->if_capenable &= ~IFCAP_TSO6; | ||||
ifp->if_hwassist &= ~CSUM_IP6_TSO; | ifp->if_hwassist &= ~CSUM_IP6_TSO; | ||||
mlx5_en_err(ifp, | mlx5_en_err(ifp, | ||||
"tso6 disabled due to -txcsum6.\n"); | "tso6 disabled due to -txcsum6.\n"); | ||||
} | } | ||||
} | } | ||||
if (mask & IFCAP_MEXTPG) | if (mask & IFCAP_MEXTPG) | ||||
ifp->if_capenable ^= IFCAP_MEXTPG; | ifp->if_capenable ^= IFCAP_MEXTPG; | ||||
if (mask & IFCAP_TXTLS4) | if (mask & IFCAP_TXTLS4) | ||||
ifp->if_capenable ^= IFCAP_TXTLS4; | ifp->if_capenable ^= IFCAP_TXTLS4; | ||||
if (mask & IFCAP_TXTLS6) | if (mask & IFCAP_TXTLS6) | ||||
ifp->if_capenable ^= IFCAP_TXTLS6; | ifp->if_capenable ^= IFCAP_TXTLS6; | ||||
#ifdef RATELIMIT | #ifdef RATELIMIT | ||||
if (mask & IFCAP_TXTLS_RTLMT) | if (mask & IFCAP_TXTLS_RTLMT) | ||||
ifp->if_capenable ^= IFCAP_TXTLS_RTLMT; | ifp->if_capenable ^= IFCAP_TXTLS_RTLMT; | ||||
#endif | #endif | ||||
if (mask & IFCAP_RXCSUM) | if (mask & IFCAP_RXCSUM) | ||||
ifp->if_capenable ^= IFCAP_RXCSUM; | ifp->if_capenable ^= IFCAP_RXCSUM; | ||||
if (mask & IFCAP_RXCSUM_IPV6) | if (mask & IFCAP_RXCSUM_IPV6) | ||||
ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; | ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; | ||||
if (mask & IFCAP_TSO4) { | if (mask & IFCAP_TSO4) { | ||||
if (!(IFCAP_TSO4 & ifp->if_capenable) && | if (!(IFCAP_TSO4 & ifp->if_capenable) && | ||||
!(IFCAP_TXCSUM & ifp->if_capenable)) { | !(IFCAP_TXCSUM & ifp->if_capenable)) { | ||||
mlx5_en_err(ifp, "enable txcsum first.\n"); | mlx5_en_err(ifp, "enable txcsum first.\n"); | ||||
error = EAGAIN; | error = EAGAIN; | ||||
goto out; | } else { | ||||
} | |||||
ifp->if_capenable ^= IFCAP_TSO4; | ifp->if_capenable ^= IFCAP_TSO4; | ||||
ifp->if_hwassist ^= CSUM_IP_TSO; | ifp->if_hwassist ^= CSUM_IP_TSO; | ||||
} | } | ||||
} | |||||
if (mask & IFCAP_TSO6) { | if (mask & IFCAP_TSO6) { | ||||
if (!(IFCAP_TSO6 & ifp->if_capenable) && | if (!(IFCAP_TSO6 & ifp->if_capenable) && | ||||
!(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { | !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { | ||||
mlx5_en_err(ifp, "enable txcsum6 first.\n"); | mlx5_en_err(ifp, "enable txcsum6 first.\n"); | ||||
error = EAGAIN; | error = EAGAIN; | ||||
goto out; | } else { | ||||
} | |||||
ifp->if_capenable ^= IFCAP_TSO6; | ifp->if_capenable ^= IFCAP_TSO6; | ||||
ifp->if_hwassist ^= CSUM_IP6_TSO; | ifp->if_hwassist ^= CSUM_IP6_TSO; | ||||
} | } | ||||
} | |||||
if (mask & IFCAP_VLAN_HWTSO) | if (mask & IFCAP_VLAN_HWTSO) | ||||
ifp->if_capenable ^= IFCAP_VLAN_HWTSO; | ifp->if_capenable ^= IFCAP_VLAN_HWTSO; | ||||
if (mask & IFCAP_VLAN_HWFILTER) { | if (mask & IFCAP_VLAN_HWFILTER) { | ||||
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) | if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) | ||||
mlx5e_disable_vlan_filter(priv); | mlx5e_disable_vlan_filter(priv); | ||||
else | else | ||||
mlx5e_enable_vlan_filter(priv); | mlx5e_enable_vlan_filter(priv); | ||||
ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; | ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; | ||||
} | } | ||||
if (mask & IFCAP_VLAN_HWTAGGING) | if (mask & IFCAP_VLAN_HWTAGGING) | ||||
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; | ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; | ||||
if (mask & IFCAP_WOL_MAGIC) | if (mask & IFCAP_WOL_MAGIC) | ||||
ifp->if_capenable ^= IFCAP_WOL_MAGIC; | ifp->if_capenable ^= IFCAP_WOL_MAGIC; | ||||
if (mask & IFCAP_VXLAN_HWCSUM) { | if (mask & IFCAP_VXLAN_HWCSUM) { | ||||
const bool was_enabled = | const bool was_enabled = | ||||
(ifp->if_capenable & IFCAP_VXLAN_HWCSUM) != 0; | (ifp->if_capenable & IFCAP_VXLAN_HWCSUM) != 0; | ||||
if (was_enabled) | if (was_enabled) | ||||
mlx5e_del_all_vxlan_rules(priv); | mlx5e_del_all_vxlan_rules(priv); | ||||
ifp->if_capenable ^= IFCAP_VXLAN_HWCSUM; | ifp->if_capenable ^= IFCAP_VXLAN_HWCSUM; | ||||
ifp->if_hwassist ^= CSUM_INNER_IP | CSUM_INNER_IP_UDP | | ifp->if_hwassist ^= CSUM_INNER_IP | CSUM_INNER_IP_UDP | | ||||
CSUM_INNER_IP_TCP | CSUM_INNER_IP6_UDP | | CSUM_INNER_IP_TCP | CSUM_INNER_IP6_UDP | | ||||
CSUM_INNER_IP6_TCP; | CSUM_INNER_IP6_TCP; | ||||
if (!was_enabled) { | if (!was_enabled) { | ||||
int err = mlx5e_add_all_vxlan_rules(priv); | int err = mlx5e_add_all_vxlan_rules(priv); | ||||
if (err != 0) { | if (err != 0) { | ||||
mlx5_en_err(ifp, | mlx5_en_err(ifp, | ||||
"mlx5e_add_all_vxlan_rules() failed, %d (ignored)\n", err); | "mlx5e_add_all_vxlan_rules() failed, %d (ignored)\n", err); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (mask & IFCAP_VXLAN_HWTSO) { | if (mask & IFCAP_VXLAN_HWTSO) { | ||||
ifp->if_capenable ^= IFCAP_VXLAN_HWTSO; | ifp->if_capenable ^= IFCAP_VXLAN_HWTSO; | ||||
ifp->if_hwassist ^= CSUM_INNER_IP_TSO | | ifp->if_hwassist ^= CSUM_INNER_IP_TSO | | ||||
CSUM_INNER_IP6_TSO; | CSUM_INNER_IP6_TSO; | ||||
} | } | ||||
VLAN_CAPABILITIES(ifp); | VLAN_CAPABILITIES(ifp); | ||||
/* turn off LRO means also turn of HW LRO - if it's on */ | /* turn off LRO means also turn of HW LRO - if it's on */ | ||||
if (mask & IFCAP_LRO) { | if (mask & IFCAP_LRO) { | ||||
int was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); | int was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); | ||||
bool need_restart = false; | bool need_restart = false; | ||||
ifp->if_capenable ^= IFCAP_LRO; | ifp->if_capenable ^= IFCAP_LRO; | ||||
/* figure out if updating HW LRO is needed */ | /* figure out if updating HW LRO is needed */ | ||||
if (!(ifp->if_capenable & IFCAP_LRO)) { | if (!(ifp->if_capenable & IFCAP_LRO)) { | ||||
if (priv->params.hw_lro_en) { | if (priv->params.hw_lro_en) { | ||||
priv->params.hw_lro_en = false; | priv->params.hw_lro_en = false; | ||||
need_restart = true; | need_restart = true; | ||||
} | } | ||||
} else { | } else { | ||||
if (priv->params.hw_lro_en == false && | if (priv->params.hw_lro_en == false && | ||||
priv->params_ethtool.hw_lro != 0) { | priv->params_ethtool.hw_lro != 0) { | ||||
priv->params.hw_lro_en = true; | priv->params.hw_lro_en = true; | ||||
need_restart = true; | need_restart = true; | ||||
} | } | ||||
} | } | ||||
if (was_opened && need_restart) { | if (was_opened && need_restart) { | ||||
mlx5e_close_locked(ifp); | mlx5e_close_locked(ifp); | ||||
mlx5e_open_locked(ifp); | mlx5e_open_locked(ifp); | ||||
} | } | ||||
} | } | ||||
if (mask & IFCAP_HWRXTSTMP) { | if (mask & IFCAP_HWRXTSTMP) { | ||||
ifp->if_capenable ^= IFCAP_HWRXTSTMP; | ifp->if_capenable ^= IFCAP_HWRXTSTMP; | ||||
if (ifp->if_capenable & IFCAP_HWRXTSTMP) { | if (ifp->if_capenable & IFCAP_HWRXTSTMP) { | ||||
if (priv->clbr_done == 0) | if (priv->clbr_done == 0) | ||||
mlx5e_reset_calibration_callout(priv); | mlx5e_reset_calibration_callout(priv); | ||||
} else { | } else { | ||||
callout_drain(&priv->tstmp_clbr); | callout_drain(&priv->tstmp_clbr); | ||||
priv->clbr_done = 0; | priv->clbr_done = 0; | ||||
} | } | ||||
} | } | ||||
out: | return (error); | ||||
} | |||||
static int | |||||
mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data) | |||||
{ | |||||
struct mlx5e_priv *priv; | |||||
struct ifreq *ifr; | |||||
struct ifdownreason *ifdr; | |||||
struct ifi2creq i2c; | |||||
struct ifrsskey *ifrk; | |||||
struct ifrsshash *ifrh; | |||||
nvlist_t *nv; | |||||
hselasky: I think it would be clever to zero-init drv_ioctl_data_d:
```
struct siocsifcapnv_driver_data… | |||||
Done Inline ActionsIt is not needed, in the sense that driver code which fills the structure, uses it as well, but this is not a critical path. kib: It is not needed, in the sense that driver code which fills the structure, uses it as well, but… | |||||
unsigned mask; | |||||
unsigned value; | |||||
int error = 0; | |||||
int size_read = 0; | |||||
int module_status; | |||||
int module_num; | |||||
int max_mtu; | |||||
uint8_t read_addr; | |||||
priv = ifp->if_softc; | |||||
/* check if detaching */ | |||||
if (priv == NULL || priv->gone != 0) | |||||
return (ENXIO); | |||||
switch (command) { | |||||
case SIOCSIFMTU: | |||||
ifr = (struct ifreq *)data; | |||||
PRIV_LOCK(priv); | |||||
mlx5_query_port_max_mtu(priv->mdev, &max_mtu); | |||||
if (ifr->ifr_mtu >= MLX5E_MTU_MIN && | |||||
ifr->ifr_mtu <= MIN(MLX5E_MTU_MAX, max_mtu)) { | |||||
int was_opened; | |||||
was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); | |||||
if (was_opened) | |||||
mlx5e_close_locked(ifp); | |||||
/* set new MTU */ | |||||
mlx5e_set_dev_port_mtu(ifp, ifr->ifr_mtu); | |||||
if (was_opened) | |||||
mlx5e_open_locked(ifp); | |||||
} else { | |||||
error = EINVAL; | |||||
mlx5_en_err(ifp, | |||||
"Invalid MTU value. Min val: %d, Max val: %d\n", | |||||
MLX5E_MTU_MIN, MIN(MLX5E_MTU_MAX, max_mtu)); | |||||
} | |||||
PRIV_UNLOCK(priv); | PRIV_UNLOCK(priv); | ||||
break; | break; | ||||
case SIOCSIFFLAGS: | |||||
if ((ifp->if_flags & IFF_UP) && | |||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)) { | |||||
mlx5e_set_rx_mode(ifp); | |||||
break; | |||||
} | |||||
PRIV_LOCK(priv); | |||||
if (ifp->if_flags & IFF_UP) { | |||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { | |||||
if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) | |||||
mlx5e_open_locked(ifp); | |||||
ifp->if_drv_flags |= IFF_DRV_RUNNING; | |||||
mlx5_set_port_status(priv->mdev, MLX5_PORT_UP); | |||||
} | |||||
} else { | |||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) { | |||||
mlx5_set_port_status(priv->mdev, | |||||
MLX5_PORT_DOWN); | |||||
if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0) | |||||
mlx5e_close_locked(ifp); | |||||
mlx5e_update_carrier(priv); | |||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | |||||
} | |||||
} | |||||
PRIV_UNLOCK(priv); | |||||
break; | |||||
case SIOCADDMULTI: | |||||
case SIOCDELMULTI: | |||||
mlx5e_set_rx_mode(ifp); | |||||
break; | |||||
case SIOCSIFMEDIA: | |||||
case SIOCGIFMEDIA: | |||||
case SIOCGIFXMEDIA: | |||||
ifr = (struct ifreq *)data; | |||||
error = ifmedia_ioctl(ifp, ifr, &priv->media, command); | |||||
break; | |||||
case SIOCGIFCAPNV: | |||||
nv = (nvlist_t *)data; | |||||
if_legacy_to_capnv(nv, ifp->if_capabilities, ifp->if_capenable); | |||||
nvlist_add_bool(nv, IFCAP_RXTLS4_NAME, priv->ifcap_rxtls4); | |||||
nvlist_add_bool(nv, IFCAP_RXTLS6_NAME, priv->ifcap_rxtls6); | |||||
break; | |||||
case SIOCSIFCAPNV: | |||||
nv = (nvlist_t *)data; | |||||
if_capnv_to_legacy(nv, &mask, &value); | |||||
PRIV_LOCK(priv); | |||||
error = mlx5e_set_legacy_caps_locked(ifp, mask, value); | |||||
if (error == 0) { | |||||
if (nvlist_exists_bool(nv, IFCAP_RXTLS4_NAME)) | |||||
priv->ifcap_rxtls4 = nvlist_get_bool(nv, IFCAP_RXTLS4_NAME); | |||||
if (nvlist_exists_bool(nv, IFCAP_RXTLS6_NAME)) | |||||
priv->ifcap_rxtls6 = nvlist_get_bool(nv, IFCAP_RXTLS6_NAME); | |||||
} | |||||
PRIV_UNLOCK(priv); | |||||
break; | |||||
case SIOCSIFCAP: | |||||
ifr = (struct ifreq *)data; | |||||
PRIV_LOCK(priv); | |||||
error = mlx5e_set_legacy_caps_locked(ifp, ifp->if_capabilities, ifr->ifr_reqcap); | |||||
Done Inline ActionsIn netpfil/pf/pf_nv.c there are a couple of 'pf_nv_XXX_opt()' functions, which deal with fetching values from an nvlist that may or may not be present. If the name isn't present in the nvlist they return a configurable default value. Perhaps something similar would be useful here. There's at least some usage examples of that in netpfil/pf/pf_syncookies.c. kp: In netpfil/pf/pf_nv.c there are a couple of 'pf_nv_XXX_opt()' functions, which deal with… | |||||
Done Inline ActionsThey might be useful for something more advanced/different. There the info passed is both the presence of the option, and its value. In other words, if the bool name is present, it means that userspace asked driver to toggle; it the name is not present, driver should keep the setting as is. So it is actually quite naturally structures around nvlist_exists/nvlist_get, and no artificial things like "default or current value" are needed. I tried to explain it in the man page description. kib: They might be useful for something more advanced/different. There the info passed is both the… | |||||
Done Inline ActionsYeah, the primary reason for the _opt() variants in the pf code is to deal with new features. That is, when we need an extra field for something we can't count on userspace always supplying it (rephrased, it's not an error for old userspace to not know about new features). This situation is slightly different, and your implementation makes sense here. kp: Yeah, the primary reason for the _opt() variants in the pf code is to deal with new features. | |||||
Done Inline ActionsDo we need to update "ifp->if_capenable2" here? hselasky: Do we need to update "ifp->if_capenable2" here? | |||||
Done Inline ActionsYes, we do. But this should be done on the cap-by-cap basis, same as it is done for if_capenable. We need to use e.g. mask2 or reuse mask and do similar manipulations. This is why I did not touched this aspect. Or, do you mean something different? kib: Yes, we do. But this should be done on the cap-by-cap basis, same as it is done for… | |||||
PRIV_UNLOCK(priv); | |||||
break; | |||||
case SIOCGI2C: | case SIOCGI2C: | ||||
ifr = (struct ifreq *)data; | ifr = (struct ifreq *)data; | ||||
/* | /* | ||||
* Copy from the user-space address ifr_data to the | * Copy from the user-space address ifr_data to the | ||||
* kernel-space address i2c | * kernel-space address i2c | ||||
*/ | */ | ||||
error = copyin(ifr_data_get_ptr(ifr), &i2c, sizeof(i2c)); | error = copyin(ifr_data_get_ptr(ifr), &i2c, sizeof(i2c)); | ||||
▲ Show 20 Lines • Show All 861 Lines • ▼ Show 20 Lines | mlx5e_create_ifp(struct mlx5_core_dev *mdev) | ||||
ifp->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO; | ifp->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO; | ||||
ifp->if_capabilities |= IFCAP_HWSTATS | IFCAP_HWRXTSTMP; | ifp->if_capabilities |= IFCAP_HWSTATS | IFCAP_HWRXTSTMP; | ||||
ifp->if_capabilities |= IFCAP_MEXTPG; | ifp->if_capabilities |= IFCAP_MEXTPG; | ||||
ifp->if_capabilities |= IFCAP_TXTLS4 | IFCAP_TXTLS6; | ifp->if_capabilities |= IFCAP_TXTLS4 | IFCAP_TXTLS6; | ||||
#ifdef RATELIMIT | #ifdef RATELIMIT | ||||
ifp->if_capabilities |= IFCAP_TXRTLMT | IFCAP_TXTLS_RTLMT; | ifp->if_capabilities |= IFCAP_TXRTLMT | IFCAP_TXTLS_RTLMT; | ||||
#endif | #endif | ||||
ifp->if_capabilities |= IFCAP_VXLAN_HWCSUM | IFCAP_VXLAN_HWTSO; | ifp->if_capabilities |= IFCAP_VXLAN_HWCSUM | IFCAP_VXLAN_HWTSO; | ||||
ifp->if_capabilities |= IFCAP_NV; | |||||
priv->ifcap_rxtls4 = 1; | |||||
priv->ifcap_rxtls6 = 1; | |||||
ifp->if_snd_tag_alloc = mlx5e_snd_tag_alloc; | ifp->if_snd_tag_alloc = mlx5e_snd_tag_alloc; | ||||
#ifdef RATELIMIT | #ifdef RATELIMIT | ||||
ifp->if_ratelimit_query = mlx5e_ratelimit_query; | ifp->if_ratelimit_query = mlx5e_ratelimit_query; | ||||
#endif | #endif | ||||
/* set TSO limits so that we don't have to drop TX packets */ | /* set TSO limits so that we don't have to drop TX packets */ | ||||
ifp->if_hw_tsomax = MLX5E_MAX_TX_PAYLOAD_SIZE - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); | ifp->if_hw_tsomax = MLX5E_MAX_TX_PAYLOAD_SIZE - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); | ||||
ifp->if_hw_tsomaxsegcount = MLX5E_MAX_TX_MBUF_FRAGS - 1 /* hdr */; | ifp->if_hw_tsomaxsegcount = MLX5E_MAX_TX_MBUF_FRAGS - 1 /* hdr */; | ||||
ifp->if_hw_tsomaxsegsize = MLX5E_MAX_TX_MBUF_SIZE; | ifp->if_hw_tsomaxsegsize = MLX5E_MAX_TX_MBUF_SIZE; | ||||
ifp->if_capenable = ifp->if_capabilities; | ifp->if_capenable = ifp->if_capabilities; | ||||
Done Inline ActionsDoes this not need to be behind '#ifdef RATELIMIT` any more? kp: Does this not need to be behind '#ifdef RATELIMIT` any more? | |||||
Done Inline ActionsI wanted to keep the structure layout constant (mlx5e_priv). Ok, the code is ifdef-ed, but the bits are kept in the structure still. kib: I wanted to keep the structure layout constant (mlx5e_priv). Ok, the code is ifdef-ed, but the… | |||||
Done Inline ActionsShould add here: ifp->if_capenable2 = ifp->if_capabilities2; hselasky: Should add here:
```
ifp->if_capenable2 = ifp->if_capabilities2;
```
| |||||
ifp->if_hwassist = 0; | ifp->if_hwassist = 0; | ||||
if (ifp->if_capenable & IFCAP_TSO) | if (ifp->if_capenable & IFCAP_TSO) | ||||
ifp->if_hwassist |= CSUM_TSO; | ifp->if_hwassist |= CSUM_TSO; | ||||
if (ifp->if_capenable & IFCAP_TXCSUM) | if (ifp->if_capenable & IFCAP_TXCSUM) | ||||
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP); | ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP); | ||||
if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) | if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) | ||||
ifp->if_hwassist |= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6); | ifp->if_hwassist |= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6); | ||||
if (ifp->if_capabilities & IFCAP_VXLAN_HWCSUM) | if (ifp->if_capabilities & IFCAP_VXLAN_HWCSUM) | ||||
▲ Show 20 Lines • Show All 486 Lines • Show Last 20 Lines |
I think it would be clever to zero-init drv_ioctl_data_d: