Skip to content

Commit a77dcb8

Browse files
Ajit Khapardedavem330
authored andcommitted
be2net: set and query VEB/VEPA mode of the PF interface
SkyHawk-R can support VEB or VEPA mode. This patch will allow the user to set/query this switch setting. Signed-off-by: Ajit Khaparde <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bc6fc9f commit a77dcb8

File tree

3 files changed

+108
-13
lines changed

3 files changed

+108
-13
lines changed

drivers/net/ethernet/emulex/benet/be_cmds.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,7 +2876,7 @@ int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
28762876
}
28772877

28782878
int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
2879-
u32 domain, u16 intf_id)
2879+
u32 domain, u16 intf_id, u16 hsw_mode)
28802880
{
28812881
struct be_mcc_wrb *wrb;
28822882
struct be_cmd_req_set_hsw_config *req;
@@ -2903,6 +2903,13 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
29032903
AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
29042904
AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
29052905
}
2906+
if (!BEx_chip(adapter) && hsw_mode) {
2907+
AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
2908+
ctxt, adapter->hba_port_num);
2909+
AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
2910+
AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
2911+
ctxt, hsw_mode);
2912+
}
29062913

29072914
be_dws_cpu_to_le(req->context, sizeof(req->context));
29082915
status = be_mcc_notify_wait(adapter);
@@ -2914,7 +2921,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
29142921

29152922
/* Get Hyper switch config */
29162923
int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
2917-
u32 domain, u16 intf_id)
2924+
u32 domain, u16 intf_id, u8 *mode)
29182925
{
29192926
struct be_mcc_wrb *wrb;
29202927
struct be_cmd_req_get_hsw_config *req;
@@ -2937,9 +2944,15 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
29372944
OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL);
29382945

29392946
req->hdr.domain = domain;
2940-
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt,
2941-
intf_id);
2947+
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
2948+
ctxt, intf_id);
29422949
AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
2950+
2951+
if (!BEx_chip(adapter)) {
2952+
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
2953+
ctxt, adapter->hba_port_num);
2954+
AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
2955+
}
29432956
be_dws_cpu_to_le(req->context, sizeof(req->context));
29442957

29452958
status = be_mcc_notify_wait(adapter);
@@ -2950,7 +2963,11 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
29502963
sizeof(resp->context));
29512964
vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
29522965
pvid, &resp->context);
2953-
*pvid = le16_to_cpu(vid);
2966+
if (pvid)
2967+
*pvid = le16_to_cpu(vid);
2968+
if (mode)
2969+
*mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
2970+
port_fwd_type, &resp->context);
29542971
}
29552972

29562973
err:

drivers/net/ethernet/emulex/benet/be_cmds.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,12 +1533,17 @@ struct be_cmd_req_set_mac_list {
15331533
} __packed;
15341534

15351535
/*********************** HSW Config ***********************/
1536+
#define PORT_FWD_TYPE_VEPA 0x3
1537+
#define PORT_FWD_TYPE_VEB 0x2
1538+
15361539
struct amap_set_hsw_context {
15371540
u8 interface_id[16];
15381541
u8 rsvd0[14];
15391542
u8 pvid_valid;
1540-
u8 rsvd1;
1541-
u8 rsvd2[16];
1543+
u8 pport;
1544+
u8 rsvd1[6];
1545+
u8 port_fwd_type[3];
1546+
u8 rsvd2[7];
15421547
u8 pvid[16];
15431548
u8 rsvd3[32];
15441549
u8 rsvd4[32];
@@ -1563,7 +1568,9 @@ struct amap_get_hsw_req_context {
15631568
} __packed;
15641569

15651570
struct amap_get_hsw_resp_context {
1566-
u8 rsvd1[16];
1571+
u8 rsvd0[6];
1572+
u8 port_fwd_type[3];
1573+
u8 rsvd1[7];
15671574
u8 pvid[16];
15681575
u8 rsvd2[32];
15691576
u8 rsvd3[32];
@@ -1965,9 +1972,9 @@ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
19651972
extern int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id,
19661973
u32 dom);
19671974
extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
1968-
u32 domain, u16 intf_id);
1975+
u32 domain, u16 intf_id, u16 hsw_mode);
19691976
extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
1970-
u32 domain, u16 intf_id);
1977+
u32 domain, u16 intf_id, u8 *mode);
19711978
extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
19721979
extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
19731980
struct be_dma_mem *cmd);

drivers/net/ethernet/emulex/benet/be_main.c

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "be_cmds.h"
2222
#include <asm/div64.h>
2323
#include <linux/aer.h>
24+
#include <linux/if_bridge.h>
2425

2526
MODULE_VERSION(DRV_VER);
2627
MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -1212,14 +1213,14 @@ static int be_set_vf_vlan(struct net_device *netdev,
12121213
adapter->vf_cfg[vf].vlan_tag = vlan;
12131214

12141215
status = be_cmd_set_hsw_config(adapter, vlan,
1215-
vf + 1, adapter->vf_cfg[vf].if_handle);
1216+
vf + 1, adapter->vf_cfg[vf].if_handle, 0);
12161217
}
12171218
} else {
12181219
/* Reset Transparent Vlan Tagging. */
12191220
adapter->vf_cfg[vf].vlan_tag = 0;
12201221
vlan = adapter->vf_cfg[vf].def_vid;
12211222
status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
1222-
adapter->vf_cfg[vf].if_handle);
1223+
adapter->vf_cfg[vf].if_handle, 0);
12231224
}
12241225

12251226

@@ -2917,7 +2918,7 @@ static int be_vf_setup(struct be_adapter *adapter)
29172918
vf_cfg->tx_rate = lnk_speed;
29182919

29192920
status = be_cmd_get_hsw_config(adapter, &def_vlan,
2920-
vf + 1, vf_cfg->if_handle);
2921+
vf + 1, vf_cfg->if_handle, NULL);
29212922
if (status)
29222923
goto err;
29232924
vf_cfg->def_vid = def_vlan;
@@ -3795,6 +3796,74 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
37953796
return status;
37963797
}
37973798

3799+
static int be_ndo_bridge_setlink(struct net_device *dev,
3800+
struct nlmsghdr *nlh)
3801+
{
3802+
struct be_adapter *adapter = netdev_priv(dev);
3803+
struct nlattr *attr, *br_spec;
3804+
int rem;
3805+
int status = 0;
3806+
u16 mode = 0;
3807+
3808+
if (!sriov_enabled(adapter))
3809+
return -EOPNOTSUPP;
3810+
3811+
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
3812+
3813+
nla_for_each_nested(attr, br_spec, rem) {
3814+
if (nla_type(attr) != IFLA_BRIDGE_MODE)
3815+
continue;
3816+
3817+
mode = nla_get_u16(attr);
3818+
if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
3819+
return -EINVAL;
3820+
3821+
status = be_cmd_set_hsw_config(adapter, 0, 0,
3822+
adapter->if_handle,
3823+
mode == BRIDGE_MODE_VEPA ?
3824+
PORT_FWD_TYPE_VEPA :
3825+
PORT_FWD_TYPE_VEB);
3826+
if (status)
3827+
goto err;
3828+
3829+
dev_info(&adapter->pdev->dev, "enabled switch mode: %s\n",
3830+
mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
3831+
3832+
return status;
3833+
}
3834+
err:
3835+
dev_err(&adapter->pdev->dev, "Failed to set switch mode %s\n",
3836+
mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
3837+
3838+
return status;
3839+
}
3840+
3841+
static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
3842+
struct net_device *dev,
3843+
u32 filter_mask)
3844+
{
3845+
struct be_adapter *adapter = netdev_priv(dev);
3846+
int status = 0;
3847+
u8 hsw_mode;
3848+
3849+
if (!sriov_enabled(adapter))
3850+
return 0;
3851+
3852+
/* BE and Lancer chips support VEB mode only */
3853+
if (BEx_chip(adapter) || lancer_chip(adapter)) {
3854+
hsw_mode = PORT_FWD_TYPE_VEB;
3855+
} else {
3856+
status = be_cmd_get_hsw_config(adapter, NULL, 0,
3857+
adapter->if_handle, &hsw_mode);
3858+
if (status)
3859+
return 0;
3860+
}
3861+
3862+
return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
3863+
hsw_mode == PORT_FWD_TYPE_VEPA ?
3864+
BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB);
3865+
}
3866+
37983867
static const struct net_device_ops be_netdev_ops = {
37993868
.ndo_open = be_open,
38003869
.ndo_stop = be_close,
@@ -3813,6 +3882,8 @@ static const struct net_device_ops be_netdev_ops = {
38133882
#ifdef CONFIG_NET_POLL_CONTROLLER
38143883
.ndo_poll_controller = be_netpoll,
38153884
#endif
3885+
.ndo_bridge_setlink = be_ndo_bridge_setlink,
3886+
.ndo_bridge_getlink = be_ndo_bridge_getlink,
38163887
};
38173888

38183889
static void be_netdev_init(struct net_device *netdev)

0 commit comments

Comments
 (0)