diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index f814855c187..a3b75071ba4 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -215,6 +215,11 @@ TUNABLE_INT("hw.ixl.tx_itr", &ixl_tx_itr); SYSCTL_INT(_hw_ixl, OID_AUTO, tx_itr, CTLFLAG_RDTUN, &ixl_tx_itr, 0, "TX Interrupt Rate"); +static int ixl_hw_lldp = 1; +TUNABLE_INT("hw.ixl.hw_lldp", &ixl_hw_lldp); +SYSCTL_INT(_hw_ixl, OID_AUTO, hw_lldp, CTLFLAG_RDTUN, + &ixl_hw_lldp, 0, "Handle LLDP by NIC"); + #ifdef IXL_IW int ixl_enable_iwarp = 0; TUNABLE_INT("hw.ixl.enable_iwarp", &ixl_enable_iwarp); @@ -315,6 +320,7 @@ ixl_save_pf_tunables(struct ixl_pf *pf) pf->dynamic_tx_itr = ixl_dynamic_tx_itr; pf->dbg_mask = ixl_core_debug_mask; pf->hw.debug_mask = ixl_shared_debug_mask; + pf->hw_lldp = ixl_hw_lldp; if (ixl_ring_size < IXL_MIN_RING || ixl_ring_size > IXL_MAX_RING diff --git a/sys/dev/ixl/ixl_pf.h b/sys/dev/ixl/ixl_pf.h index 54083007c51..47801cf5391 100644 --- a/sys/dev/ixl/ixl_pf.h +++ b/sys/dev/ixl/ixl_pf.h @@ -100,6 +100,7 @@ struct ixl_pf { int dynamic_tx_itr; int tx_itr; int rx_itr; + int hw_lldp; struct mtx pf_mtx; diff --git a/sys/dev/ixl/ixl_pf_main.c b/sys/dev/ixl/ixl_pf_main.c index 37c2745aae2..11bc6dfd887 100644 --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -62,6 +62,7 @@ static int ixl_sysctl_show_fw(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_unallocated_queues(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_pf_tx_itr(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_pf_rx_itr(SYSCTL_HANDLER_ARGS); +static int ixl_sysctl_pf_lldp(SYSCTL_HANDLER_ARGS); /* Debug Sysctls */ static int ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS); @@ -2714,6 +2715,41 @@ ixl_sysctl_pf_rx_itr(SYSCTL_HANDLER_ARGS) return (error); } +/* + * Used to set the Rx ITR value for all of the PF LAN VSI's queues. + * Writes to the ITR registers immediately. + */ +static int +ixl_sysctl_pf_lldp(SYSCTL_HANDLER_ARGS) +{ + struct ixl_pf *pf = (struct ixl_pf *)arg1; + struct i40e_hw *hw = &pf->hw; + device_t dev = pf->dev; + int error = 0; + int requested_lldp_status; + + requested_lldp_status = pf->hw_lldp; + error = sysctl_handle_int(oidp, &requested_lldp_status, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + if (requested_lldp_status < 0 || requested_lldp_status > 1 ) { + device_printf(dev, "Invalid lldp value; value must be 0 or 1\n"); + return (EINVAL); + } + + if (pf->hw_lldp == requested_lldp_status) + return (error); + + if (!requested_lldp_status) { + i40e_aq_stop_lldp(hw, FALSE, NULL); + } else { + i40e_aq_start_lldp(hw, NULL); + } + + pf->hw_lldp = requested_lldp_status; + return (error); +} + void ixl_add_hw_stats(struct ixl_pf *pf) { @@ -4292,6 +4328,11 @@ ixl_add_device_sysctls(struct ixl_pf *pf) OID_AUTO, "dynamic_tx_itr", CTLFLAG_RW, &pf->dynamic_tx_itr, 0, "Enable dynamic TX ITR"); + SYSCTL_ADD_PROC(ctx, ctx_list, + OID_AUTO, "hw_lldp", CTLTYPE_INT | CTLFLAG_RW, + pf, 0, ixl_sysctl_pf_lldp, "I", + "Handle LLDP by the NIC"); + /* Add FEC sysctls for 25G adapters */ /* * XXX: These settings can be changed, but that isn't supported,