Commit a77dcb8c authored by Ajit Khaparde's avatar Ajit Khaparde Committed by David S. Miller

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: default avatarAjit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bc6fc9fa
...@@ -2876,7 +2876,7 @@ int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom) ...@@ -2876,7 +2876,7 @@ int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
} }
int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
u32 domain, u16 intf_id) u32 domain, u16 intf_id, u16 hsw_mode)
{ {
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_req_set_hsw_config *req; struct be_cmd_req_set_hsw_config *req;
...@@ -2903,6 +2903,13 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, ...@@ -2903,6 +2903,13 @@ 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) {
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);
AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
ctxt, hsw_mode);
}
be_dws_cpu_to_le(req->context, sizeof(req->context)); be_dws_cpu_to_le(req->context, sizeof(req->context));
status = be_mcc_notify_wait(adapter); status = be_mcc_notify_wait(adapter);
...@@ -2914,7 +2921,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, ...@@ -2914,7 +2921,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
/* Get Hyper switch config */ /* Get Hyper switch config */
int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
u32 domain, u16 intf_id) u32 domain, u16 intf_id, u8 *mode)
{ {
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_req_get_hsw_config *req; struct be_cmd_req_get_hsw_config *req;
...@@ -2937,9 +2944,15 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, ...@@ -2937,9 +2944,15 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL); OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL);
req->hdr.domain = domain; req->hdr.domain = domain;
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt, AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
intf_id); ctxt, intf_id);
AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1); AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
if (!BEx_chip(adapter)) {
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
ctxt, adapter->hba_port_num);
AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
}
be_dws_cpu_to_le(req->context, sizeof(req->context)); be_dws_cpu_to_le(req->context, sizeof(req->context));
status = be_mcc_notify_wait(adapter); status = be_mcc_notify_wait(adapter);
...@@ -2950,7 +2963,11 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, ...@@ -2950,7 +2963,11 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
sizeof(resp->context)); sizeof(resp->context));
vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context, vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
pvid, &resp->context); pvid, &resp->context);
if (pvid)
*pvid = le16_to_cpu(vid); *pvid = le16_to_cpu(vid);
if (mode)
*mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
port_fwd_type, &resp->context);
} }
err: err:
......
...@@ -1533,12 +1533,17 @@ struct be_cmd_req_set_mac_list { ...@@ -1533,12 +1533,17 @@ struct be_cmd_req_set_mac_list {
} __packed; } __packed;
/*********************** HSW Config ***********************/ /*********************** HSW Config ***********************/
#define PORT_FWD_TYPE_VEPA 0x3
#define PORT_FWD_TYPE_VEB 0x2
struct amap_set_hsw_context { struct amap_set_hsw_context {
u8 interface_id[16]; u8 interface_id[16];
u8 rsvd0[14]; u8 rsvd0[14];
u8 pvid_valid; u8 pvid_valid;
u8 rsvd1; u8 pport;
u8 rsvd2[16]; u8 rsvd1[6];
u8 port_fwd_type[3];
u8 rsvd2[7];
u8 pvid[16]; u8 pvid[16];
u8 rsvd3[32]; u8 rsvd3[32];
u8 rsvd4[32]; u8 rsvd4[32];
...@@ -1563,7 +1568,9 @@ struct amap_get_hsw_req_context { ...@@ -1563,7 +1568,9 @@ struct amap_get_hsw_req_context {
} __packed; } __packed;
struct amap_get_hsw_resp_context { struct amap_get_hsw_resp_context {
u8 rsvd1[16]; u8 rsvd0[6];
u8 port_fwd_type[3];
u8 rsvd1[7];
u8 pvid[16]; u8 pvid[16];
u8 rsvd2[32]; u8 rsvd2[32];
u8 rsvd3[32]; u8 rsvd3[32];
...@@ -1965,9 +1972,9 @@ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, ...@@ -1965,9 +1972,9 @@ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
extern int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, extern int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id,
u32 dom); u32 dom);
extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
u32 domain, u16 intf_id); u32 domain, u16 intf_id, u16 hsw_mode);
extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
u32 domain, u16 intf_id); u32 domain, u16 intf_id, u8 *mode);
extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
struct be_dma_mem *cmd); struct be_dma_mem *cmd);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "be_cmds.h" #include "be_cmds.h"
#include <asm/div64.h> #include <asm/div64.h>
#include <linux/aer.h> #include <linux/aer.h>
#include <linux/if_bridge.h>
MODULE_VERSION(DRV_VER); MODULE_VERSION(DRV_VER);
MODULE_DEVICE_TABLE(pci, be_dev_ids); MODULE_DEVICE_TABLE(pci, be_dev_ids);
...@@ -1212,14 +1213,14 @@ static int be_set_vf_vlan(struct net_device *netdev, ...@@ -1212,14 +1213,14 @@ static int be_set_vf_vlan(struct net_device *netdev,
adapter->vf_cfg[vf].vlan_tag = vlan; adapter->vf_cfg[vf].vlan_tag = vlan;
status = be_cmd_set_hsw_config(adapter, vlan, status = be_cmd_set_hsw_config(adapter, vlan,
vf + 1, adapter->vf_cfg[vf].if_handle); vf + 1, adapter->vf_cfg[vf].if_handle, 0);
} }
} else { } else {
/* Reset Transparent Vlan Tagging. */ /* Reset Transparent Vlan Tagging. */
adapter->vf_cfg[vf].vlan_tag = 0; adapter->vf_cfg[vf].vlan_tag = 0;
vlan = adapter->vf_cfg[vf].def_vid; vlan = adapter->vf_cfg[vf].def_vid;
status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
adapter->vf_cfg[vf].if_handle); adapter->vf_cfg[vf].if_handle, 0);
} }
...@@ -2917,7 +2918,7 @@ static int be_vf_setup(struct be_adapter *adapter) ...@@ -2917,7 +2918,7 @@ static int be_vf_setup(struct be_adapter *adapter)
vf_cfg->tx_rate = lnk_speed; vf_cfg->tx_rate = lnk_speed;
status = be_cmd_get_hsw_config(adapter, &def_vlan, status = be_cmd_get_hsw_config(adapter, &def_vlan,
vf + 1, vf_cfg->if_handle); vf + 1, vf_cfg->if_handle, NULL);
if (status) if (status)
goto err; goto err;
vf_cfg->def_vid = def_vlan; vf_cfg->def_vid = def_vlan;
...@@ -3795,6 +3796,74 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file) ...@@ -3795,6 +3796,74 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
return status; return status;
} }
static int be_ndo_bridge_setlink(struct net_device *dev,
struct nlmsghdr *nlh)
{
struct be_adapter *adapter = netdev_priv(dev);
struct nlattr *attr, *br_spec;
int rem;
int status = 0;
u16 mode = 0;
if (!sriov_enabled(adapter))
return -EOPNOTSUPP;
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
nla_for_each_nested(attr, br_spec, rem) {
if (nla_type(attr) != IFLA_BRIDGE_MODE)
continue;
mode = nla_get_u16(attr);
if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
return -EINVAL;
status = be_cmd_set_hsw_config(adapter, 0, 0,
adapter->if_handle,
mode == BRIDGE_MODE_VEPA ?
PORT_FWD_TYPE_VEPA :
PORT_FWD_TYPE_VEB);
if (status)
goto err;
dev_info(&adapter->pdev->dev, "enabled switch mode: %s\n",
mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
return status;
}
err:
dev_err(&adapter->pdev->dev, "Failed to set switch mode %s\n",
mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
return status;
}
static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
struct net_device *dev,
u32 filter_mask)
{
struct be_adapter *adapter = netdev_priv(dev);
int status = 0;
u8 hsw_mode;
if (!sriov_enabled(adapter))
return 0;
/* BE and Lancer chips support VEB mode only */
if (BEx_chip(adapter) || lancer_chip(adapter)) {
hsw_mode = PORT_FWD_TYPE_VEB;
} else {
status = be_cmd_get_hsw_config(adapter, NULL, 0,
adapter->if_handle, &hsw_mode);
if (status)
return 0;
}
return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
hsw_mode == PORT_FWD_TYPE_VEPA ?
BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB);
}
static const struct net_device_ops be_netdev_ops = { static const struct net_device_ops be_netdev_ops = {
.ndo_open = be_open, .ndo_open = be_open,
.ndo_stop = be_close, .ndo_stop = be_close,
...@@ -3813,6 +3882,8 @@ static const struct net_device_ops be_netdev_ops = { ...@@ -3813,6 +3882,8 @@ static const struct net_device_ops be_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = be_netpoll, .ndo_poll_controller = be_netpoll,
#endif #endif
.ndo_bridge_setlink = be_ndo_bridge_setlink,
.ndo_bridge_getlink = be_ndo_bridge_getlink,
}; };
static void be_netdev_init(struct net_device *netdev) static void be_netdev_init(struct net_device *netdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment