diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 29aeb91cba4975eb24b866287cd603805927e5c5..a98b6ab33ed58e7145a50b9ff0c84777ae6210ca 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -87,6 +87,11 @@ static struct be_cmd_priv_map cmd_priv_map[] = { CMD_SUBSYSTEM_LOWLEVEL, BE_PRIV_DEVCFG | BE_PRIV_DEVSEC }, + { + OPCODE_COMMON_SET_HSW_CONFIG, + CMD_SUBSYSTEM_COMMON, + BE_PRIV_DEVCFG | BE_PRIV_VHADM + }, }; static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem) @@ -3850,6 +3855,10 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, void *ctxt; int status; + if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_HSW_CONFIG, + CMD_SUBSYSTEM_COMMON)) + return -EPERM; + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); @@ -3871,7 +3880,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1); AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid); } - if (!BEx_chip(adapter) && hsw_mode) { + if (hsw_mode) { AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, adapter->hba_port_num); AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a654c12e924b2db448b32dda13c7667ef9691f1d..f11a19b75c995366408d66c2c7183787b5443600 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3729,6 +3729,11 @@ static void be_vf_clear(struct be_adapter *adapter) be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1); } + + if (BE3_chip(adapter)) + be_cmd_set_hsw_config(adapter, 0, 0, + adapter->if_handle, + PORT_FWD_TYPE_PASSTHRU, 0); done: kfree(adapter->vf_cfg); adapter->num_vfs = 0; @@ -4019,6 +4024,15 @@ static int be_vf_setup(struct be_adapter *adapter) } } + if (BE3_chip(adapter)) { + /* On BE3, enable VEB only when SRIOV is enabled */ + status = be_cmd_set_hsw_config(adapter, 0, 0, + adapter->if_handle, + PORT_FWD_TYPE_VEB, 0); + if (status) + goto err; + } + adapter->flags |= BE_FLAGS_SRIOV_ENABLED; return 0; err: @@ -4564,6 +4578,15 @@ static int be_setup(struct be_adapter *adapter) be_cmd_set_logical_link_config(adapter, IFLA_VF_LINK_STATE_AUTO, 0); + /* BE3 EVB echoes broadcast/multicast packets back to PF's vport + * confusing a linux bridge or OVS that it might be connected to. + * Set the EVB to PASSTHRU mode which effectively disables the EVB + * when SRIOV is not enabled. + */ + if (BE3_chip(adapter)) + be_cmd_set_hsw_config(adapter, 0, 0, adapter->if_handle, + PORT_FWD_TYPE_PASSTHRU, 0); + if (adapter->num_vfs) be_vf_setup(adapter);