@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.4.1.7"
+#define DRV_VERSION "1.4.1.7nl"
#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
@@ -1223,24 +1223,14 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac)
return 0;
}
-static int enic_set_vf_port(struct net_device *netdev, int vf,
+static void enic_set_vf_port_parse_global_attr(struct enic *enic,
struct nlattr *port[])
{
- struct enic *enic = netdev_priv(netdev);
-
- memset(&enic->pp, 0, sizeof(enic->pp));
-
if (port[IFLA_PORT_REQUEST]) {
enic->pp.set |= ENIC_SET_REQUEST;
enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
}
- if (port[IFLA_PORT_PROFILE]) {
- enic->pp.set |= ENIC_SET_NAME;
- memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
- PORT_PROFILE_MAX);
- }
-
if (port[IFLA_PORT_INSTANCE_UUID]) {
enic->pp.set |= ENIC_SET_INSTANCE;
memcpy(enic->pp.instance_uuid,
@@ -1252,6 +1242,57 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
memcpy(enic->pp.host_uuid,
nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
}
+}
+
+static void enic_set_vf_port_parse_legacy_attr(struct enic *enic,
+ struct nlattr *port[])
+{
+ if (port[IFLA_PORT_PROFILE]) {
+ enic->pp.set |= ENIC_SET_NAME;
+ memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+ PORT_PROFILE_MAX);
+ }
+}
+
+static int enic_set_vf_port_parse_proto_attr(struct enic *enic,
+ struct nlattr *port[])
+{
+ struct nlattr *tb_8021qbh[IFLA_PORT_8021QBH_MAX+1];
+ int err = 0;
+
+ if (!port[IFLA_PORT_PROTO_8021QBH])
+ return -1;
+
+ err = rtnl_link_parse_port_proto(PORT_PROTO_8021QBH,
+ port[IFLA_PORT_PROTO_8021QBH],
+ tb_8021qbh);
+ if (err < 0)
+ goto errout;
+
+ if (tb_8021qbh[IFLA_PORT_8021QBH_PROFILE]) {
+ enic->pp.set |= ENIC_SET_NAME;
+ memcpy(enic->pp.name,
+ nla_data(tb_8021qbh[IFLA_PORT_8021QBH_PROFILE]),
+ PORT_PROFILE_MAX);
+ }
+
+errout:
+ return err;
+}
+
+static int enic_set_vf_port(struct net_device *netdev, int vf,
+ struct nlattr *port[])
+{
+ struct enic *enic = netdev_priv(netdev);
+ int err = 0;
+
+ memset(&enic->pp, 0, sizeof(enic->pp));
+
+ enic_set_vf_port_parse_global_attr(enic, port);
+
+ err = enic_set_vf_port_parse_proto_attr(enic, port);
+ if (err < 0)
+ enic_set_vf_port_parse_legacy_attr(enic, port);
/* don't support VFs, yet */
if (vf != PORT_SELF_VF)
@@ -1280,6 +1321,7 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
struct enic *enic = netdev_priv(netdev);
int err, error, done;
u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
+ struct nlattr *proto;
if (!(enic->pp.set & ENIC_SET_APPLIED))
return -ENODATA;
@@ -1309,7 +1351,7 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
- if (enic->pp.set & ENIC_SET_NAME)
+ if (enic->pp.set & ENIC_SET_NAME) /* Deprecated */
NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
enic->pp.name);
if (enic->pp.set & ENIC_SET_INSTANCE)
@@ -1319,6 +1361,13 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
enic->pp.host_uuid);
+ proto = nla_nest_start(skb, IFLA_PORT_PROTO_8021QBH);
+ if (proto == NULL)
+ goto nla_put_failure;
+ NLA_PUT(skb, IFLA_PORT_8021QBH_PROFILE, PORT_PROFILE_MAX,
+ enic->pp.name);
+ nla_nest_end(skb, proto);
+
return 0;
nla_put_failure: