ixl: Permit 802.1ad frames to pass though the chip

This patch is a quick hack to change the internal Ethertype used
within the chip.  All frames with this type are dropped silently.
This patch allows you to overwrite the factory default 0x88a8, which
is used by IEEE 802.1ad VLAN stacking.

Reviewed by:	kp, philip, brueffer
Approved by:	kp (mentor)
MFC after:	2 weeks
Differential Revision: https://reviews.freebsd.org/D24179
This commit is contained in:
Lutz Donnerhacke 2021-01-19 15:56:16 +01:00
parent 5290493a20
commit fa6662b368
2 changed files with 50 additions and 1 deletions

View File

@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 27, 2020
.Dd January 19, 2021
.Dt IXL 4
.Os
.Sh NAME
@ -227,6 +227,15 @@ contains the speeds that are allowed to be set.
Displays the current speed.
.It Va dev.ixl.#.fw_version
Displays the current firmware and NVM versions of the adapter.
.It Va dev.ixl.#.debug.switch_vlans
Set the Ethertype used by the hardware itself to handle internal
services.
Frames with this Ethertype will be dropped without notice.
Defaults to
.Dv 0x88a8 ,
which is a well known number for IEEE 802.1ad VLAN stacking.
If you need 802.1ad support, set this number to any another Ethertype i.e.
.Dv 0xffff .
.El
.Sh INTERRUPT STORMS
It is important to note that 40G operation can generate high

View File

@ -69,6 +69,7 @@ static int ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_switch_vlans(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_hkey(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_hena(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_hlut(SYSCTL_HANDLER_ARGS);
@ -2329,6 +2330,11 @@ ixl_add_device_sysctls(struct ixl_pf *pf)
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
pf, 0, ixl_sysctl_switch_config, "A", "HW Switch Configuration");
SYSCTL_ADD_PROC(ctx, debug_list,
OID_AUTO, "switch_vlans",
CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
pf, 0, ixl_sysctl_switch_vlans, "I", "HW Switch VLAN Configuration");
SYSCTL_ADD_PROC(ctx, debug_list,
OID_AUTO, "rss_key",
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
@ -3481,6 +3487,40 @@ ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS)
return (error);
}
static int
ixl_sysctl_switch_vlans(SYSCTL_HANDLER_ARGS)
{
struct ixl_pf *pf = (struct ixl_pf *)arg1;
struct i40e_hw *hw = &pf->hw;
device_t dev = pf->dev;
int requested_vlan = -1;
enum i40e_status_code status = 0;
int error = 0;
error = sysctl_handle_int(oidp, &requested_vlan, 0, req);
if ((error) || (req->newptr == NULL))
return (error);
if ((hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) == 0) {
device_printf(dev, "Flags disallow setting of vlans\n");
return (ENODEV);
}
hw->switch_tag = requested_vlan;
device_printf(dev,
"Setting switch config to switch_tag=%04x, first_tag=%04x, second_tag=%04x\n",
hw->switch_tag, hw->first_tag, hw->second_tag);
status = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL);
if (status) {
device_printf(dev,
"%s: aq_set_switch_config() error %s, aq error %s\n",
__func__, i40e_stat_str(hw, status),
i40e_aq_str(hw, hw->aq.asq_last_status));
return (status);
}
return (0);
}
static int
ixl_sysctl_hkey(SYSCTL_HANDLER_ARGS)
{