Skip to content

Commit

Permalink
be2net: set and query VEB/VEPA mode of the PF interface
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Ajit Khaparde authored and davem330 committed Sep 4, 2013
1 parent bc6fc9f commit a77dcb8
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 13 deletions.
27 changes: 22 additions & 5 deletions drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
u32 domain, u16 intf_id)
u32 domain, u16 intf_id, u16 hsw_mode)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_set_hsw_config *req;
Expand All @@ -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, 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));
status = be_mcc_notify_wait(adapter);
Expand All @@ -2914,7 +2921,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,

/* Get Hyper switch config */
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_cmd_req_get_hsw_config *req;
Expand All @@ -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);

req->hdr.domain = domain;
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt,
intf_id);
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
ctxt, intf_id);
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));

status = be_mcc_notify_wait(adapter);
Expand All @@ -2950,7 +2963,11 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
sizeof(resp->context));
vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
pvid, &resp->context);
*pvid = le16_to_cpu(vid);
if (pvid)
*pvid = le16_to_cpu(vid);
if (mode)
*mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
port_fwd_type, &resp->context);
}

err:
Expand Down
17 changes: 12 additions & 5 deletions drivers/net/ethernet/emulex/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1533,12 +1533,17 @@ struct be_cmd_req_set_mac_list {
} __packed;

/*********************** HSW Config ***********************/
#define PORT_FWD_TYPE_VEPA 0x3
#define PORT_FWD_TYPE_VEB 0x2

struct amap_set_hsw_context {
u8 interface_id[16];
u8 rsvd0[14];
u8 pvid_valid;
u8 rsvd1;
u8 rsvd2[16];
u8 pport;
u8 rsvd1[6];
u8 port_fwd_type[3];
u8 rsvd2[7];
u8 pvid[16];
u8 rsvd3[32];
u8 rsvd4[32];
Expand All @@ -1563,7 +1568,9 @@ struct amap_get_hsw_req_context {
} __packed;

struct amap_get_hsw_resp_context {
u8 rsvd1[16];
u8 rsvd0[6];
u8 port_fwd_type[3];
u8 rsvd1[7];
u8 pvid[16];
u8 rsvd2[32];
u8 rsvd3[32];
Expand Down Expand Up @@ -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,
u32 dom);
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,
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_ext_fat_capabilites(struct be_adapter *adapter,
struct be_dma_mem *cmd);
Expand Down
77 changes: 74 additions & 3 deletions drivers/net/ethernet/emulex/benet/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "be_cmds.h"
#include <asm/div64.h>
#include <linux/aer.h>
#include <linux/if_bridge.h>

MODULE_VERSION(DRV_VER);
MODULE_DEVICE_TABLE(pci, be_dev_ids);
Expand Down Expand Up @@ -1212,14 +1213,14 @@ static int be_set_vf_vlan(struct net_device *netdev,
adapter->vf_cfg[vf].vlan_tag = 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 {
/* Reset Transparent Vlan Tagging. */
adapter->vf_cfg[vf].vlan_tag = 0;
vlan = adapter->vf_cfg[vf].def_vid;
status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
adapter->vf_cfg[vf].if_handle);
adapter->vf_cfg[vf].if_handle, 0);
}


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

status = be_cmd_get_hsw_config(adapter, &def_vlan,
vf + 1, vf_cfg->if_handle);
vf + 1, vf_cfg->if_handle, NULL);
if (status)
goto err;
vf_cfg->def_vid = def_vlan;
Expand Down Expand Up @@ -3795,6 +3796,74 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
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 = {
.ndo_open = be_open,
.ndo_stop = be_close,
Expand All @@ -3813,6 +3882,8 @@ static const struct net_device_ops be_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = be_netpoll,
#endif
.ndo_bridge_setlink = be_ndo_bridge_setlink,
.ndo_bridge_getlink = be_ndo_bridge_getlink,
};

static void be_netdev_init(struct net_device *netdev)
Expand Down

0 comments on commit a77dcb8

Please sign in to comment.