From: Ajit Khaparde <ajit.khaparde@emulex.com>
To: <davem@davemloft.net>
Cc: <netdev@vger.kernel.org>
Subject: [PATCH net-next] be2net: set and query VEB/VEPA mode of the PF interface
Date: Fri, 30 Aug 2013 15:01:16 -0500 [thread overview]
Message-ID: <20130830200116.GA6311@emulex.com> (raw)
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 <ajit.khaparde@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 27 ++++++++--
drivers/net/ethernet/emulex/benet/be_cmds.h | 17 ++++--
drivers/net/ethernet/emulex/benet/be_main.c | 77 +++++++++++++++++++++++++-
3 files changed, 108 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 52c9085..1ab5dab 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -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;
@@ -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);
@@ -2914,7 +2921,7 @@ err:
/* 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;
@@ -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);
@@ -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:
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 52f3d4c..d026226 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -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];
@@ -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];
@@ -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);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 50116f8..61f97dc 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -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);
@@ -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);
}
@@ -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;
@@ -3795,6 +3796,74 @@ fw_exit:
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,
@@ -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)
--
1.7.1
next reply other threads:[~2013-08-30 20:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-30 20:01 Ajit Khaparde [this message]
2013-09-04 2:20 ` [PATCH net-next] be2net: set and query VEB/VEPA mode of the PF interface David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130830200116.GA6311@emulex.com \
--to=ajit.khaparde@emulex.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.