提交 884476be 编写于 作者: S Somnath Kotur 提交者: David S. Miller

be2net: Fix broadcast echoes from EVB in BE3

On SR-IOV profiles, when the user connects a Linux Bridge or OVS to a BE3
vport, they suffer the "broadcast/multicast echo" problem. BE3 EVB echoes
broadcast and multicast packets back to PF's vport confusing the
Linux bridge.  BE3 relies on the src-mac addr being programmed on the
interface to avoid sending back an echo of a broadcast or multicast packet
on a vPort. When a Linux bridge is connected to a BE3, the mac-addr of the
VM behind the bridge doesn't get configured on the vPort and so echo
cancellation doesn't work.
This patch worksaround this problem by disabling the EVB initially
and re-enabling it *only* when SR-IOV is enabled by the user. For the
driver fix to work, the BE3 FW version must be >= 11.1.84.0.
Signed-off-by: NSomnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: NSathya Perla <sathya.perla@broadcom.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 e261768e
...@@ -87,6 +87,11 @@ static struct be_cmd_priv_map cmd_priv_map[] = { ...@@ -87,6 +87,11 @@ static struct be_cmd_priv_map cmd_priv_map[] = {
CMD_SUBSYSTEM_LOWLEVEL, CMD_SUBSYSTEM_LOWLEVEL,
BE_PRIV_DEVCFG | BE_PRIV_DEVSEC 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) 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, ...@@ -3850,6 +3855,10 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
void *ctxt; void *ctxt;
int status; int status;
if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_HSW_CONFIG,
CMD_SUBSYSTEM_COMMON))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -3871,7 +3880,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, ...@@ -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_valid, ctxt, 1);
AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid); 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, AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
ctxt, adapter->hba_port_num); ctxt, adapter->hba_port_num);
AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1); AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
......
...@@ -3729,6 +3729,11 @@ static void be_vf_clear(struct be_adapter *adapter) ...@@ -3729,6 +3729,11 @@ static void be_vf_clear(struct be_adapter *adapter)
be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1); 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: done:
kfree(adapter->vf_cfg); kfree(adapter->vf_cfg);
adapter->num_vfs = 0; adapter->num_vfs = 0;
...@@ -4019,6 +4024,15 @@ static int be_vf_setup(struct be_adapter *adapter) ...@@ -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; adapter->flags |= BE_FLAGS_SRIOV_ENABLED;
return 0; return 0;
err: err:
...@@ -4564,6 +4578,15 @@ static int be_setup(struct be_adapter *adapter) ...@@ -4564,6 +4578,15 @@ static int be_setup(struct be_adapter *adapter)
be_cmd_set_logical_link_config(adapter, be_cmd_set_logical_link_config(adapter,
IFLA_VF_LINK_STATE_AUTO, 0); 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) if (adapter->num_vfs)
be_vf_setup(adapter); be_vf_setup(adapter);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册