Netdev List
 help / color / mirror / Atom feed
* [patch net-next 4/7] bonding: remove bond_ioctl_change_active()
From: Jiri Pirko @ 2013-10-18 15:43 UTC (permalink / raw)
  To: netdev; +Cc: davem, fubar, vfalico, andy, stephen, vyasevic
In-Reply-To: <1382111019-1102-1-git-send-email-jiri@resnulli.us>

no longer needed since bond_option_active_slave_set() can be used
instead.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 drivers/net/bonding/bond_main.c | 59 ++---------------------------------------
 1 file changed, 2 insertions(+), 57 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a113e42..d90734f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1910,61 +1910,6 @@ static int  bond_release_and_destroy(struct net_device *bond_dev,
 	return ret;
 }
 
-/*
- * This function changes the active slave to slave <slave_dev>.
- * It returns -EINVAL in the following cases.
- *  - <slave_dev> is not found in the list.
- *  - There is not active slave now.
- *  - <slave_dev> is already active.
- *  - The link state of <slave_dev> is not BOND_LINK_UP.
- *  - <slave_dev> is not running.
- * In these cases, this function does nothing.
- * In the other cases, current_slave pointer is changed and 0 is returned.
- */
-static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
-{
-	struct bonding *bond = netdev_priv(bond_dev);
-	struct slave *old_active = NULL;
-	struct slave *new_active = NULL;
-	int res = 0;
-
-	if (!USES_PRIMARY(bond->params.mode))
-		return -EINVAL;
-
-	/* Verify that bond_dev is indeed the master of slave_dev */
-	if (!(slave_dev->flags & IFF_SLAVE) ||
-	    !netdev_has_upper_dev(slave_dev, bond_dev))
-		return -EINVAL;
-
-	read_lock(&bond->lock);
-
-	old_active = bond->curr_active_slave;
-	new_active = bond_get_slave_by_dev(bond, slave_dev);
-	/*
-	 * Changing to the current active: do nothing; return success.
-	 */
-	if (new_active && new_active == old_active) {
-		read_unlock(&bond->lock);
-		return 0;
-	}
-
-	if (new_active &&
-	    old_active &&
-	    new_active->link == BOND_LINK_UP &&
-	    IS_UP(new_active->dev)) {
-		block_netpoll_tx();
-		write_lock_bh(&bond->curr_slave_lock);
-		bond_change_active_slave(bond, new_active);
-		write_unlock_bh(&bond->curr_slave_lock);
-		unblock_netpoll_tx();
-	} else
-		res = -EINVAL;
-
-	read_unlock(&bond->lock);
-
-	return res;
-}
-
 static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
@@ -3257,6 +3202,7 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
 
 static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
 {
+	struct bonding *bond = netdev_priv(bond_dev);
 	struct net_device *slave_dev = NULL;
 	struct ifbond k_binfo;
 	struct ifbond __user *u_binfo = NULL;
@@ -3287,7 +3233,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
 
 
 		if (mii->reg_num == 1) {
-			struct bonding *bond = netdev_priv(bond_dev);
 			mii->val_out = 0;
 			read_lock(&bond->lock);
 			read_lock(&bond->curr_slave_lock);
@@ -3359,7 +3304,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
 			break;
 		case BOND_CHANGE_ACTIVE_OLD:
 		case SIOCBONDCHANGEACTIVE:
-			res = bond_ioctl_change_active(bond_dev, slave_dev);
+			res = bond_option_active_slave_set(bond, slave_dev);
 			break;
 		default:
 			res = -EOPNOTSUPP;
-- 
1.8.3.1

^ permalink raw reply related

* [patch net-next 5/7] bonding: move active_slave getting into separate function
From: Jiri Pirko @ 2013-10-18 15:43 UTC (permalink / raw)
  To: netdev; +Cc: davem, fubar, vfalico, andy, stephen, vyasevic
In-Reply-To: <1382111019-1102-1-git-send-email-jiri@resnulli.us>

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 drivers/net/bonding/bond_options.c | 18 ++++++++++++++++++
 drivers/net/bonding/bond_sysfs.c   |  8 ++++----
 drivers/net/bonding/bonding.h      |  2 ++
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 09af5d1..9a5223c 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -57,6 +57,24 @@ int bond_option_mode_set(struct bonding *bond, int mode)
 	return 0;
 }
 
+static struct net_device *__bond_option_active_slave_get(struct bonding *bond,
+							 struct slave *slave)
+{
+	return USES_PRIMARY(bond->params.mode) && slave ? slave->dev : NULL;
+}
+
+struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
+{
+	struct slave *slave = rcu_dereference(bond->curr_active_slave);
+
+	return __bond_option_active_slave_get(bond, slave);
+}
+
+struct net_device *bond_option_active_slave_get(struct bonding *bond)
+{
+	return __bond_option_active_slave_get(bond, bond->curr_active_slave);
+}
+
 int bond_option_active_slave_set(struct bonding *bond,
 				 struct net_device *slave_dev)
 {
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index abd2600..47749c9 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1219,13 +1219,13 @@ static ssize_t bonding_show_active_slave(struct device *d,
 					 char *buf)
 {
 	struct bonding *bond = to_bond(d);
-	struct slave *curr;
+	struct net_device *slave_dev;
 	int count = 0;
 
 	rcu_read_lock();
-	curr = rcu_dereference(bond->curr_active_slave);
-	if (USES_PRIMARY(bond->params.mode) && curr)
-		count = sprintf(buf, "%s\n", curr->dev->name);
+	slave_dev = bond_option_active_slave_get_rcu(bond);
+	if (slave_dev)
+		count = sprintf(buf, "%s\n", slave_dev->name);
 	rcu_read_unlock();
 
 	return count;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 686759d..046a605 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -428,6 +428,8 @@ int bond_netlink_init(void);
 void bond_netlink_fini(void);
 int bond_option_mode_set(struct bonding *bond, int mode);
 int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev);
+struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
+struct net_device *bond_option_active_slave_get(struct bonding *bond);
 
 struct bond_net {
 	struct net *		net;	/* Associated network namespace */
-- 
1.8.3.1

^ permalink raw reply related

* [patch net-next 6/7] bonding: add Netlink support mode option
From: Jiri Pirko @ 2013-10-18 15:43 UTC (permalink / raw)
  To: netdev; +Cc: davem, fubar, vfalico, andy, stephen, vyasevic
In-Reply-To: <1382111019-1102-1-git-send-email-jiri@resnulli.us>

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 drivers/net/bonding/bond_netlink.c | 56 ++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/if_link.h       | 10 +++++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index 3e5c5f8..a94f870 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -20,6 +20,10 @@
 #include <net/rtnetlink.h>
 #include "bonding.h"
 
+static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
+	[IFLA_BOND_MODE]		= { .type = NLA_U8 },
+};
+
 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
 {
 	if (tb[IFLA_ADDRESS]) {
@@ -31,11 +35,63 @@ static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
 	return 0;
 }
 
+static int bond_changelink(struct net_device *bond_dev,
+			   struct nlattr *tb[], struct nlattr *data[])
+{
+	struct bonding *bond = netdev_priv(bond_dev);
+	int err;
+
+	if (data && data[IFLA_BOND_MODE]) {
+		int mode = nla_get_u8(data[IFLA_BOND_MODE]);
+
+		err = bond_option_mode_set(bond, mode);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
+			struct nlattr *tb[], struct nlattr *data[])
+{
+	int err;
+
+	err = bond_changelink(bond_dev, tb, data);
+	if (err < 0)
+		return err;
+
+	return register_netdevice(bond_dev);
+}
+
+static size_t bond_get_size(const struct net_device *bond_dev)
+{
+	return nla_total_size(sizeof(u8));	/* IFLA_BOND_MODE */
+}
+
+static int bond_fill_info(struct sk_buff *skb,
+			  const struct net_device *bond_dev)
+{
+	struct bonding *bond = netdev_priv(bond_dev);
+
+	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
+		goto nla_put_failure;
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+
 struct rtnl_link_ops bond_link_ops __read_mostly = {
 	.kind			= "bond",
 	.priv_size		= sizeof(struct bonding),
 	.setup			= bond_setup,
+	.maxtype		= IFLA_BOND_MAX,
+	.policy			= bond_policy,
 	.validate		= bond_validate,
+	.newlink		= bond_newlink,
+	.changelink		= bond_changelink,
+	.get_size		= bond_get_size,
+	.fill_info		= bond_fill_info,
 	.get_num_tx_queues	= bond_get_num_tx_queues,
 	.get_num_rx_queues	= bond_get_num_tx_queues, /* Use the same number
 							     as for TX queues */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 80394e8..06fd3fe 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -325,6 +325,16 @@ struct ifla_vxlan_port_range {
 	__be16	high;
 };
 
+/* Bonding section */
+
+enum {
+	IFLA_BOND_UNSPEC,
+	IFLA_BOND_MODE,
+	__IFLA_BOND_MAX,
+};
+
+#define IFLA_BOND_MAX	(__IFLA_BOND_MAX - 1)
+
 /* SR-IOV virtual function management section */
 
 enum {
-- 
1.8.3.1

^ permalink raw reply related

* [patch net-next 7/7] bonding: add Netlink support active_slave option
From: Jiri Pirko @ 2013-10-18 15:43 UTC (permalink / raw)
  To: netdev; +Cc: davem, fubar, vfalico, andy, stephen, vyasevic
In-Reply-To: <1382111019-1102-1-git-send-email-jiri@resnulli.us>

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 drivers/net/bonding/bond_netlink.c | 23 ++++++++++++++++++++++-
 include/uapi/linux/if_link.h       |  1 +
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index a94f870..fe3500b 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -22,6 +22,7 @@
 
 static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
 	[IFLA_BOND_MODE]		= { .type = NLA_U8 },
+	[IFLA_BOND_ACTIVE_SLAVE]	= { .type = NLA_U32 },
 };
 
 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -48,6 +49,22 @@ static int bond_changelink(struct net_device *bond_dev,
 		if (err)
 			return err;
 	}
+	if (data && data[IFLA_BOND_ACTIVE_SLAVE]) {
+		int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
+		struct net_device *slave_dev;
+
+		if (ifindex == 0) {
+			slave_dev = NULL;
+		} else {
+			slave_dev = __dev_get_by_index(dev_net(bond_dev),
+						       ifindex);
+			if (!slave_dev)
+				return -ENODEV;
+		}
+		err = bond_option_active_slave_set(bond, slave_dev);
+		if (err)
+			return err;
+	}
 	return 0;
 }
 
@@ -66,14 +83,18 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
 static size_t bond_get_size(const struct net_device *bond_dev)
 {
 	return nla_total_size(sizeof(u8));	/* IFLA_BOND_MODE */
+		+ nla_total_size(sizeof(u32));	/* IFLA_BOND_ACTIVE_SLAVE */
 }
 
 static int bond_fill_info(struct sk_buff *skb,
 			  const struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
+	struct net_device *slave_dev = bond_option_active_slave_get(bond);
 
-	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
+	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode) ||
+	    (slave_dev &&
+	     nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex)))
 		goto nla_put_failure;
 	return 0;
 
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 06fd3fe..8a1e346 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -330,6 +330,7 @@ struct ifla_vxlan_port_range {
 enum {
 	IFLA_BOND_UNSPEC,
 	IFLA_BOND_MODE,
+	IFLA_BOND_ACTIVE_SLAVE,
 	__IFLA_BOND_MAX,
 };
 
-- 
1.8.3.1

^ permalink raw reply related

* Re: transmit lockup using smsc95xx ethernet on usb3
From: Greg KH @ 2013-10-18 15:50 UTC (permalink / raw)
  To: David Laight; +Cc: Sarah Sharp, netdev, linux-usb, Xenia Ragiadakou
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B7397@saturn3.aculab.com>

On Fri, Oct 18, 2013 at 04:22:02PM +0100, David Laight wrote:
> > It's not too hard.  Here's some directions:
> > http://kernelnewbies.org/KernelBuild
> 
> I can build it easily enough but ...
> 
> Is there a .config file with a sane list of modules anywhere?
> (and builtin drivers for disk boot)
> 
> The defconfig one doesn't seem to contain enough to be useful,
> and the allmodconfig gives me 800MB+ to copy from the build
> system to the test one (I can't seem to see an obvious way of
> doing this either - apart from installing them to the 'wrong'
> place on the build system and then copying everything over).

The easiest thing to do is take a working .config file (like created by
your distro, for the kernel it is booting), and creating a smaller
config for just the hardware plugged into the machine at that moment in
time.

You usually do this automatically by running:
	make localmodconfig
which knows how to root around in /proc/config.gz or /boot/ to try to
find the current config file and go from there.

But remember to go back and enable anything specific for any devices you
don't have plugged in at the moment.

Hope this helps,

greg k-h

^ permalink raw reply

* [patch iproute2] iplink: add support for bonding netlink
From: Jiri Pirko @ 2013-10-18 15:50 UTC (permalink / raw)
  To: netdev; +Cc: davem, fubar, vfalico, andy, stephen, vyasevic
In-Reply-To: <1382111019-1102-1-git-send-email-jiri@resnulli.us>

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 include/linux/if_link.h | 11 ++++++
 ip/Makefile             |  2 +-
 ip/iplink.c             |  4 +--
 ip/iplink_bond.c        | 92 +++++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/ip-link.8.in   |  4 +++
 5 files changed, 110 insertions(+), 3 deletions(-)
 create mode 100644 ip/iplink_bond.c

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index ee4f2ba..3f7b343 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -318,6 +318,17 @@ enum {
 };
 #define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
 
+/* Bonding section */
+
+enum {
+	IFLA_BOND_UNSPEC,
+	IFLA_BOND_MODE,
+	IFLA_BOND_ACTIVE_SLAVE,
+	__IFLA_BOND_MAX,
+};
+
+#define IFLA_BOND_MAX	(__IFLA_BOND_MAX - 1)
+
 struct ifla_vxlan_port_range {
 	__be16	low;
 	__be16	high;
diff --git a/ip/Makefile b/ip/Makefile
index f10d22f..89a7a36 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -5,7 +5,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
     iplink_vlan.o link_veth.o link_gre.o iplink_can.o \
     iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o \
     iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
-    link_iptnl.o link_gre6.o
+    link_iptnl.o link_gre6.o iplink_bond.o
 
 RTMONOBJ=rtmon.o
 
diff --git a/ip/iplink.c b/ip/iplink.c
index 6cde731..58b6c20 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -85,8 +85,8 @@ void iplink_usage(void)
 	if (iplink_have_newlink()) {
 		fprintf(stderr, "\n");
 		fprintf(stderr, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |\n");
-		fprintf(stderr, "          can | bridge | ipoib | ip6tnl | ipip | sit | vxlan |\n");
-		fprintf(stderr, "          gre | gretap | ip6gre | ip6gretap | vti }\n");
+		fprintf(stderr, "          can | bridge | bond | ipoib | ip6tnl | ipip | sit |\n");
+		fprintf(stderr, "          vxlan | gre | gretap | ip6gre | ip6gretap | vti }\n");
 	}
 	exit(-1);
 }
diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c
new file mode 100644
index 0000000..3fb7f4f
--- /dev/null
+++ b/ip/iplink_bond.c
@@ -0,0 +1,92 @@
+/*
+ * iplink_bond.c	Bonding device support
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Jiri Pirko <jiri@resnulli.us>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <linux/if_link.h>
+#include <net/if.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+
+static void explain(void)
+{
+	fprintf(stderr,
+		"Usage: ... bond [ mode BONDMODE ] [ active_slave SLAVE_DEV ]\n"
+		"                [ clear_active_slave ]\n"
+		"\n"
+		"BONDMODE := 0-6\n"
+	);
+}
+
+static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
+			  struct nlmsghdr *n)
+{
+	__u8 mode;
+	unsigned ifindex;
+
+	while (argc > 0) {
+		if (matches(*argv, "mode") == 0) {
+			NEXT_ARG();
+			if (get_u8(&mode, *argv, 0)) {
+				invarg("mode %s is invalid", *argv);
+				return -1;
+			}
+			addattr8(n, 1024, IFLA_BOND_MODE, mode);
+		} else if (matches(*argv, "active_slave") == 0) {
+			NEXT_ARG();
+			ifindex = if_nametoindex(*argv);
+			if (!ifindex)
+				return -1;
+			addattr32(n, 1024, IFLA_BOND_ACTIVE_SLAVE, ifindex);
+		} else if (matches(*argv, "clear_active_slave") == 0) {
+			addattr32(n, 1024, IFLA_BOND_ACTIVE_SLAVE, 0);
+		} else {
+			fprintf(stderr, "bond: unknown command \"%s\"?\n", *argv);
+			explain();
+			return -1;
+		}
+		argc--, argv++;
+	}
+
+	return 0;
+}
+
+static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
+{
+	unsigned ifindex;
+
+	if (!tb)
+		return;
+
+	if (tb[IFLA_BOND_MODE])
+		fprintf(f, "mode %u ", rta_getattr_u8(tb[IFLA_BOND_MODE]));
+
+	if (tb[IFLA_BOND_ACTIVE_SLAVE] &&
+	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_ACTIVE_SLAVE]))) {
+		char buf[IFNAMSIZ];
+		const char *n = if_indextoname(ifindex, buf);
+
+		if (n)
+			fprintf(f, "active_slave %s ", n);
+		else
+			fprintf(f, "active_slave %u ", ifindex);
+	}
+}
+
+struct link_util bond_link_util = {
+	.id		= "bond",
+	.maxattr	= IFLA_BOND_MAX,
+	.parse_opt	= bond_parse_opt,
+	.print_opt	= bond_print_opt,
+};
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 8b68c78..1825dc5 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -51,6 +51,7 @@ ip-link \- network device configuration
 .ti -8
 .IR TYPE " := [ "
 .BR bridge " | "
+.BR bond " ]"
 .BR can " | "
 .BR dummy " | "
 .BR ifb " | "
@@ -155,6 +156,9 @@ Link types:
 .B bridge
 - Ethernet Bridge device
 .sp
+.B bond
+- Bonding device
+.sp
 .B can
 - Controller Area Network interface
 .sp
-- 
1.8.3.1

^ permalink raw reply related

* RE: [PATCH 15/15] net: enic: remove unnecessary pci_set_drvdata()
From: Neel Patel (neepatel) @ 2013-10-18 16:00 UTC (permalink / raw)
  To: Jingoo Han, 'David S. Miller'
  Cc: netdev@vger.kernel.org, Christian Benvenuti (benve),
	Sujith Sankar (ssujith), 'Govindarajulu Varadarajan',
	Nishank Trivedi (nistrive)
In-Reply-To: <00be01cecb98$8cabcd20$a6036760$%han@samsung.com>

Looks good.

-----Original Message-----
From: Jingoo Han [mailto:jg1.han@samsung.com] 
Sent: Thursday, October 17, 2013 5:25 PM
To: 'David S. Miller'
Cc: netdev@vger.kernel.org; 'Jingoo Han'; Christian Benvenuti (benve); Sujith Sankar (ssujith); 'Govindarajulu Varadarajan'; Neel Patel (neepatel); Nishank Trivedi (nistrive)
Subject: [PATCH 15/15] net: enic: remove unnecessary pci_set_drvdata()

The driver core clears the driver data to NULL after device_release or on probe failure. Thus, it is not needed to manually clear the device driver data to NULL.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/net/ethernet/cisco/enic/enic_main.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 7b756cf9..ff78dfa 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -2309,7 +2309,6 @@ err_out_release_regions:
 err_out_disable_device:
 	pci_disable_device(pdev);
 err_out_free_netdev:
-	pci_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
 
 	return err;
@@ -2338,7 +2337,6 @@ static void enic_remove(struct pci_dev *pdev)
 		enic_iounmap(enic);
 		pci_release_regions(pdev);
 		pci_disable_device(pdev);
-		pci_set_drvdata(pdev, NULL);
 		free_netdev(netdev);
 	}
 }
--
1.7.10.4

^ permalink raw reply related

* Re: [PATCH RFC 0/5] net:stmmac: fix jumbo frames handling and optimisation
From: Jimmy PERCHET @ 2013-10-18 16:24 UTC (permalink / raw)
  To: Giuseppe CAVALLARO; +Cc: netdev, Jimmy Perchet
In-Reply-To: <525EF8FF.2010206@st.com>

Hello Peppe,

Thanks for your concern,

I add some details :

> I tested jumbo on chips w/o enhanced some time ago, so welcome further
> tests as you did (maybe on new chips).

I'm working with 3.71a version, in 2KiB + 2KiB configuration.

>> *(1/5) Threshold dma mode is needed on rx path if jumbo frames are expected.
> 
> hmm, this depends on the HW. In the past I used HW with a Fifo that is
> 16KiB for rx buffers and 8KiB for tx.

I used rxfifo_over_2048 flag in order to guess if threshold mode is necessary.


>> *(3/5) On low speed link (10MBit/s), some TX descriptors can remain dirty
>> if the tx coalescence timer expires before they were treated. Re-arm timer
>> in this case.
> 
> hmm not clear to me, let me look at the patch. I hope the link should
> not impact... never seen on my side.
> 
Tx coalescence default parameters are : one interrupt every 64 descriptors
and 40ms timer.
Let say, one is transferring 63 jumbo frames(9KiB) over 10Mb/s link:
* 63<64 there is no interrupt.
* when the timer expires, only 5 descriptors have to be cleaned.(40ms@10Mb/s)
* at the end, 58 dirty descriptors remain.
Normally, they will be cleaned at the next transfer. The real problem appears
if the socket's "wmem" is too small. The transfer stall :
*Socket is waiting for buffer's cleanup before performing a new transfer.
*Driver is waiting for new transfer before performing cleanup.
Re-arming the timer allows to continue cleanup, thus the socket's
wake-up threshold will be reach.


Best Regards,
Jimmy

^ permalink raw reply

* Re: [RFC net-next] ipv6: Use destination address determined by IPVS
From: Hannes Frederic Sowa @ 2013-10-18 16:33 UTC (permalink / raw)
  To: Julian Anastasov
  Cc: Simon Horman,
	YOSHIFUJI Hideaki / 吉藤英明, lvs-devel,
	netdev, Mark Brooks, Phil Oester
In-Reply-To: <alpine.LFD.2.03.1310180921200.1581@ssi.bg>

On Fri, Oct 18, 2013 at 09:33:13AM +0300, Julian Anastasov wrote:
> 
> 	Hello,
> 
> On Fri, 18 Oct 2013, Hannes Frederic Sowa wrote:
> 
> > I played around with your patch and tested xt_TEE. I added a TEE rule to
> > mangle/OUTPUT and pinged. This happend, I have not yet analyzed it:
> 
> 	May be a side effect of using some multicast address?
> Can you test it with such address check?:

I don't think that is the reason.

> 
> 	if (rt->rt6i_flags & RTF_GATEWAY ||
> 	    ipv6_addr_type(&rt->rt6i_gateway) & IPV6_ADDR_UNICAST)

Just checked, I had the same panic.

Greetings,

  Hannes


^ permalink raw reply

* [PATCH net-next v4 0/8] qlcnic: ethtool enhancements and code cleanup.
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

This patch series contains

o updates to ethtool for pause settings and enhance
  register dump to display mask and ring indices.
o cleanup in DCB code and remove redundant eSwitch enablement command.
o fixed firmware dump collection logic to skip unknown entries.

Changes from v3 -> v4
o Dropped patch for Tx queue validation to be submitted in net.

Changes from v2 -> v3

o Updated patch to print informational messages as per Joe Perches's comment.

Changes from v1 -> v2

o Dropped patch to register device if adapter is in FAILED state for more rework.
o Updated patch to display ring indices via ethtool per Ben Hutchings's comment.
o Update patch for DCB cleanup per Stephen Hemminger's comment.

Please apply to net-next.

Thanks,
Himanshu

Himanshu Madhani (1):
  qlcnic: update version to 5.3.51

Jitendra Kalsaria (1):
  qlcnic: Update ethtool standard pause settings.

Pratik Pujar (2):
  qlcnic: Enhance ethtool to display ring indices and interrupt mask
  qlcnic: Firmware dump collection when auto recovery is disabled.

Shahed Shaikh (1):
  qlcnic: Skip unknown entry type while collecting firmware dump

Sony Chacko (1):
  qlcnic: Remove redundant eSwitch enable commands

Sucheta Chakraborty (2):
  qlcnic: Print informational messages only once during driver load.
  qlcnic: dcb code cleanup and refactoring.

 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        | 101 +----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  40 ++---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |   5 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |  20 ++-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  |  47 +++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c    | 184 ++++++++++-----------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h    | 109 ++++++++++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |  54 ++++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  45 +++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c   |  41 +++--
 .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c   |   9 +-
 12 files changed, 341 insertions(+), 316 deletions(-)

-- 
1.8.1.4

^ permalink raw reply

* [PATCH net-next v4 1/8] qlcnic: Print informational messages only once during driver load.
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
	himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |  1 +
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    | 12 -----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  | 24 ++++++++++++++++++----
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  1 +
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 81bf836..a3c4379 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1199,6 +1199,7 @@ struct qlcnic_npar_info {
 	u8	promisc_mode;
 	u8	offload_flags;
 	u8      pci_func;
+	u8      mac[ETH_ALEN];
 };
 
 struct qlcnic_eswitch {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 3ca00e0..66e94dc 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2321,19 +2321,7 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
 			i++;
 			memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
 			i = i + 3;
-			if (ahw->op_mode == QLCNIC_MGMT_FUNC)
-				dev_info(dev, "id = %d active = %d type = %d\n"
-					 "\tport = %d min bw = %d max bw = %d\n"
-					 "\tmac_addr =  %pM\n", pci_info->id,
-					 pci_info->active, pci_info->type,
-					 pci_info->default_port,
-					 pci_info->tx_min_bw,
-					 pci_info->tx_max_bw, pci_info->mac);
 		}
-		if (ahw->op_mode == QLCNIC_MGMT_FUNC)
-			dev_info(dev, "Max functions = %d, active functions = %d\n",
-				 ahw->max_pci_func, ahw->act_pci_func);
-
 	} else {
 		dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
 		err = -EIO;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index 0248a4c..60a477f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -94,13 +94,29 @@ qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
  **/
 static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
 {
-	int err = -EIO;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct device *dev = &adapter->pdev->dev;
+	struct qlcnic_npar_info *npar;
+	int i, err = -EIO;
 
 	qlcnic_83xx_get_minidump_template(adapter);
+
 	if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
 		if (qlcnic_init_pci_info(adapter))
 			return err;
 
+		npar = adapter->npars;
+
+		for (i = 0; i < ahw->act_pci_func; i++, npar++) {
+			dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n",
+				 npar->pci_func, npar->active, npar->type,
+				 npar->phy_port, npar->min_bw, npar->max_bw,
+				 npar->mac);
+		}
+
+		dev_info(dev, "Max functions = %d, active functions = %d\n",
+			 ahw->max_pci_func, ahw->act_pci_func);
+
 		if (qlcnic_83xx_set_vnic_opmode(adapter))
 			return err;
 
@@ -115,12 +131,12 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
 		return err;
 
 	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
-	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
+	ahw->msix_supported = qlcnic_use_msi_x ? 1 : 0;
 	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
 	qlcnic_83xx_enable_vnic_mode(adapter, 1);
 
-	dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
-		 adapter->ahw->fw_hal_version);
+	dev_info(dev, "HAL Version: %d, Management function\n",
+		 ahw->fw_hal_version);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index f07f2b0..55e8b23 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -875,6 +875,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 		adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
 		adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
 
+		memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN);
 		j++;
 	}
 
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 3/8] qlcnic: Firmware dump collection when auto recovery is disabled.
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Pratik Pujar, himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Pratik Pujar <pratik.pujar@qlogic.com>

o Allow collecting the firmware dump of halted firmware when auto
  recovery is disabled.

Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 11 +++++++++++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c      |  7 ++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index f09e787..d303fab 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -818,6 +818,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct qlcnic_mailbox *mbx = ahw->mailbox;
 	int ret = 0;
+	u32 owner;
 	u32 val;
 
 	/* Perform NIC configuration based ready state entry actions */
@@ -846,6 +847,10 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
 			clear_bit(QLC_83XX_MBX_READY, &mbx->status);
 			set_bit(__QLCNIC_RESETTING, &adapter->state);
 			qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
+		}  else {
+			owner = qlcnic_83xx_idc_find_reset_owner_id(adapter);
+			if (ahw->pci_func == owner)
+				qlcnic_dump_fw(adapter);
 		}
 		return -EIO;
 	}
@@ -1058,6 +1063,12 @@ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work)
 	adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state;
 	qlcnic_83xx_periodic_tasks(adapter);
 
+	/* Do not reschedule if firmaware is in hanged state and auto
+	 * recovery is disabled
+	 */
+	if ((adapter->flags & QLCNIC_FW_HANG) && !qlcnic_auto_fw_reset)
+		return;
+
 	/* Re-schedule the function */
 	if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status))
 		qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 55e8b23..5195972 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -3353,6 +3353,8 @@ done:
 static int
 qlcnic_check_health(struct qlcnic_adapter *adapter)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
 	u32 state = 0, heartbeat;
 	u32 peg_status;
 	int err = 0;
@@ -3377,7 +3379,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		if (adapter->need_fw_reset)
 			goto detach;
 
-		if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
+		if (ahw->reset_context && qlcnic_auto_fw_reset)
 			qlcnic_reset_hw_context(adapter);
 
 		return 0;
@@ -3420,6 +3422,9 @@ detach:
 
 		qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
 		QLCDB(adapter, DRV, "fw recovery scheduled.\n");
+	} else if (!qlcnic_auto_fw_reset && fw_dump->enable &&
+		   adapter->flags & QLCNIC_FW_RESET_OWNER) {
+		qlcnic_dump_fw(adapter);
 	}
 
 	return 1;
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 4/8] qlcnic: Update ethtool standard pause settings.
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria,
	himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Update ethtool standard pause parameter settings and display

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 18 +++++++++++++++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h |  3 +++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index c2df4ce..268fda6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3369,10 +3369,21 @@ void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
 	}
 	config = ahw->port_config;
 	if (config & QLC_83XX_CFG_STD_PAUSE) {
-		if (config & QLC_83XX_CFG_STD_TX_PAUSE)
+		switch (MSW(config)) {
+		case QLC_83XX_TX_PAUSE:
+			pause->tx_pause = 1;
+			break;
+		case QLC_83XX_RX_PAUSE:
+			pause->rx_pause = 1;
+			break;
+		case QLC_83XX_TX_RX_PAUSE:
+		default:
+			/* Backward compatibility for existing
+			 * flash definitions
+			 */
 			pause->tx_pause = 1;
-		if (config & QLC_83XX_CFG_STD_RX_PAUSE)
 			pause->rx_pause = 1;
+		}
 	}
 
 	if (QLC_83XX_AUTONEG(config))
@@ -3415,7 +3426,8 @@ int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
 		ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
 		ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
 	} else if (!pause->rx_pause && !pause->tx_pause) {
-		ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
+		ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
+				      QLC_83XX_CFG_STD_PAUSE);
 	}
 	status = qlcnic_83xx_set_port_config(adapter);
 	if (status) {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 533e150..2883b57 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -363,6 +363,9 @@ enum qlcnic_83xx_states {
 #define QLC_83XX_LINK_EEE(data)		((data) & BIT_13)
 #define QLC_83XX_DCBX(data)			(((data) >> 28) & 7)
 #define QLC_83XX_AUTONEG(data)			((data) & BIT_15)
+#define QLC_83XX_TX_PAUSE			0x10
+#define QLC_83XX_RX_PAUSE			0x20
+#define QLC_83XX_TX_RX_PAUSE			0x30
 #define QLC_83XX_CFG_STD_PAUSE			(1 << 5)
 #define QLC_83XX_CFG_STD_TX_PAUSE		(1 << 20)
 #define QLC_83XX_CFG_STD_RX_PAUSE		(2 << 20)
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 2/8] qlcnic: Enhance ethtool to display ring indices and interrupt mask
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Pratik Pujar, himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Pratik Pujar <pratik.pujar@qlogic.com>

o Updated ethtool -d <ethX> option to display ring indices for Transmit(Tx),
  Receive(Rx), and Status(St) rings.
o Updated ethtool -d <ethX> option to display ring interrupt mask for Transmit(Tx),
  and Status(St) rings.

Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  8 ++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    | 54 ++++++++++++++++------
 2 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 66e94dc..c2df4ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3267,12 +3267,12 @@ int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
 	return 0;
 }
 
-int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
+inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
 {
 	return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
-		sizeof(adapter->ahw->ext_reg_tbl)) +
-		(ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
-		sizeof(adapter->ahw->reg_tbl));
+		sizeof(*adapter->ahw->ext_reg_tbl)) +
+		(ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
+		sizeof(*adapter->ahw->reg_tbl));
 }
 
 int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index ebe4c86..66355b7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -187,8 +187,8 @@ static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
 		return -1;
 }
 
-#define QLCNIC_RING_REGS_COUNT	20
-#define QLCNIC_RING_REGS_LEN	(QLCNIC_RING_REGS_COUNT * sizeof(u32))
+#define	QLCNIC_TX_INTR_NOT_CONFIGURED	0X78563412
+
 #define QLCNIC_MAX_EEPROM_LEN   1024
 
 static const u32 diag_registers[] = {
@@ -219,7 +219,15 @@ static const u32 ext_diag_registers[] = {
 };
 
 #define QLCNIC_MGMT_API_VERSION	2
-#define QLCNIC_ETHTOOL_REGS_VER	3
+#define QLCNIC_ETHTOOL_REGS_VER	4
+
+static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
+{
+	int ring_regs_cnt = (adapter->max_drv_tx_rings * 5) +
+			    (adapter->max_rds_rings * 2) +
+			    (adapter->max_sds_rings * 3) + 5;
+	return ring_regs_cnt * sizeof(u32);
+}
 
 static int qlcnic_get_regs_len(struct net_device *dev)
 {
@@ -231,7 +239,9 @@ static int qlcnic_get_regs_len(struct net_device *dev)
 	else
 		len = sizeof(ext_diag_registers) + sizeof(diag_registers);
 
-	return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
+	len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
+	len += qlcnic_get_ring_regs_len(adapter);
+	return len;
 }
 
 static int qlcnic_get_eeprom_len(struct net_device *dev)
@@ -493,6 +503,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_host_rds_ring *rds_rings;
+	struct qlcnic_host_tx_ring *tx_ring;
 	u32 *regs_buff = p;
 	int ring, i = 0;
 
@@ -512,21 +524,35 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 		return;
 
-	regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
-
-	regs_buff[i++] = 1; /* No. of tx ring */
-	regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
-	regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
-
-	regs_buff[i++] = 2; /* No. of rx ring */
-	regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
-	regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
+	/* Marker btw regs and TX ring count */
+	regs_buff[i++] = 0xFFEFCDAB;
+
+	regs_buff[i++] = adapter->max_drv_tx_rings; /* No. of TX ring */
+	for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
+		tx_ring = &adapter->tx_ring[ring];
+		regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
+		regs_buff[i++] = tx_ring->sw_consumer;
+		regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
+		regs_buff[i++] = tx_ring->producer;
+		if (tx_ring->crb_intr_mask)
+			regs_buff[i++] = readl(tx_ring->crb_intr_mask);
+		else
+			regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
+	}
 
-	regs_buff[i++] = adapter->max_sds_rings;
+	regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_rings = &recv_ctx->rds_rings[ring];
+		regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
+		regs_buff[i++] = rds_rings->producer;
+	}
 
+	regs_buff[i++] = adapter->max_sds_rings; /* No. of SDS ring */
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 		sds_ring = &(recv_ctx->sds_rings[ring]);
 		regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
+		regs_buff[i++] = sds_ring->consumer;
+		regs_buff[i++] = readl(sds_ring->crb_intr_mask);
 	}
 }
 
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 7/8] qlcnic: Skip unknown entry type while collecting firmware dump
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh, himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>

o Driver aborts the minidump collection operation when it finds
  an unknown entry opcode. This patch skips unknown entry type
  and resumes the minidump collection operation.
o Removed a comparision of collected dump size with expected dump size.
  Size may differ when driver decides to skip an entry.

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c   | 41 ++++++++++------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
index 1551360..7763962 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
@@ -1187,41 +1187,38 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
 		}
 
 		if (ops_index == ops_cnt) {
-			dev_info(&adapter->pdev->dev,
-				 "Invalid entry type %d, exiting dump\n",
+			dev_info(dev, "Skipping unknown entry opcode %d\n",
 				 entry->hdr.type);
-			goto error;
+			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
 		}
 
 		/* Collect dump for this entry */
 		dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
-		if (!qlcnic_valid_dump_entry(&adapter->pdev->dev, entry, dump))
+		if (!qlcnic_valid_dump_entry(dev, entry, dump)) {
 			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
+		}
+
 		buf_offset += entry->hdr.cap_size;
 		entry_offset += entry->hdr.offset;
 		buffer = fw_dump->data + buf_offset;
 	}
-	if (dump_size != buf_offset) {
-		dev_info(&adapter->pdev->dev,
-			 "Captured(%d) and expected size(%d) do not match\n",
-			 buf_offset, dump_size);
-		goto error;
-	} else {
-		fw_dump->clr = 1;
-		snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
-			 adapter->netdev->name);
-		dev_info(&adapter->pdev->dev, "%s: Dump data, %d bytes captured\n",
-			 adapter->netdev->name, fw_dump->size);
-		/* Send a udev event to notify availability of FW dump */
-		kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
-		return 0;
-	}
-error:
+
+	fw_dump->clr = 1;
+	snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", adapter->netdev->name);
+	dev_info(dev, "%s: Dump data %d bytes captured, template header size %d bytes\n",
+		 adapter->netdev->name, fw_dump->size, tmpl_hdr->size);
+	/* Send a udev event to notify availability of FW dump */
+	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg);
+
 	if (fw_dump->use_pex_dma)
 		dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE,
 				  fw_dump->dma_buffer, fw_dump->phys_addr);
-	vfree(fw_dump->data);
-	return -EINVAL;
+
+	return 0;
 }
 
 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter)
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 8/8] qlcnic: update version to 5.3.51
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 728bb88..0c2405d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 50
-#define QLCNIC_LINUX_VERSIONID  "5.3.50"
+#define _QLCNIC_LINUX_SUBVERSION 51
+#define QLCNIC_LINUX_VERSIONID  "5.3.51"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 6/8] qlcnic: dcb code cleanup and refactoring.
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
	himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

o Move dcb specific function definitions to dcb files.
o Move dcb specific variables to qlcnic_dcb structure.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |  96 -----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |   2 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |   9 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c    | 184 ++++++++++-----------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h    | 109 ++++++++++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  24 +--
 .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c   |   9 +-
 8 files changed, 207 insertions(+), 228 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index a3c4379..728bb88 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -961,8 +961,6 @@ struct qlcnic_ipaddr {
 #define __QLCNIC_SRIOV_CAPABLE		11
 #define __QLCNIC_MBX_POLL_ENABLE	12
 #define __QLCNIC_DIAG_MODE		13
-#define __QLCNIC_DCB_STATE		14
-#define __QLCNIC_DCB_IN_AEN		15
 
 #define QLCNIC_INTERRUPT_TEST		1
 #define QLCNIC_LOOPBACK_TEST		2
@@ -2116,98 +2114,4 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter)
 
 	return status;
 }
-
-static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->get_hw_capability)
-		return dcb->ops->get_hw_capability(adapter);
-
-	return 0;
-}
-
-static inline void qlcnic_dcb_free(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->free)
-		dcb->ops->free(adapter);
-}
-
-static inline int qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->attach)
-		return dcb->ops->attach(adapter);
-
-	return 0;
-}
-
-static inline int
-qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter, char *buf)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->query_hw_capability)
-		return dcb->ops->query_hw_capability(adapter, buf);
-
-	return 0;
-}
-
-static inline void qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->get_info)
-		dcb->ops->get_info(adapter);
-}
-
-static inline int
-qlcnic_dcb_query_cee_param(struct qlcnic_adapter *adapter, char *buf, u8 type)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->query_cee_param)
-		return dcb->ops->query_cee_param(adapter, buf, type);
-
-	return 0;
-}
-
-static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->get_cee_cfg)
-		return dcb->ops->get_cee_cfg(adapter);
-
-	return 0;
-}
-
-static inline void
-qlcnic_dcb_register_aen(struct qlcnic_adapter *adapter, u8 flag)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->register_aen)
-		dcb->ops->register_aen(adapter, flag);
-}
-
-static inline void qlcnic_dcb_handle_aen(struct qlcnic_adapter *adapter,
-					 void *msg)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->handle_aen)
-		dcb->ops->handle_aen(adapter, msg);
-}
-
-static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->init_dcbnl_ops)
-		dcb->ops->init_dcbnl_ops(adapter);
-}
 #endif				/* __QLCNIC_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 268fda6..a126bdf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -902,7 +902,7 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 			 QLCNIC_MBX_RSP(event[0]));
 		break;
 	case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
-		qlcnic_dcb_handle_aen(adapter, (void *)&event[1]);
+		qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
 		break;
 	default:
 		dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index d303fab..e2cd484 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -636,7 +636,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
 	if (adapter->portnum == 0)
 		qlcnic_set_drv_version(adapter);
 
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(adapter->dcb);
 	qlcnic_83xx_idc_attach_driver(adapter);
 
 	return 0;
@@ -2174,6 +2174,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
 int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
 {
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_dcb *dcb;
 	int err = 0;
 
 	ahw->msix_supported = !!qlcnic_use_msi_x;
@@ -2231,8 +2232,10 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
 	if (err)
 		goto disable_mbx_intr;
 
-	if (adapter->dcb && qlcnic_dcb_attach(adapter))
-		qlcnic_clear_dcb_ops(adapter);
+	dcb = adapter->dcb;
+
+	if (dcb && qlcnic_dcb_attach(dcb))
+		qlcnic_clear_dcb_ops(dcb);
 
 	/* Periodically monitor device status */
 	qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index d62d5ce..86bca7c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -57,22 +57,22 @@ static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
 static void qlcnic_dcb_aen_work(struct work_struct *);
 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
 
-static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *);
-static void __qlcnic_dcb_free(struct qlcnic_adapter *);
-static int __qlcnic_dcb_attach(struct qlcnic_adapter *);
-static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *, char *);
-static void __qlcnic_dcb_get_info(struct qlcnic_adapter *);
-
-static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *);
-static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
-static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
-static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
-
-static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *);
-static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
-static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
-static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *, bool);
-static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
+static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *);
+static void __qlcnic_dcb_free(struct qlcnic_dcb *);
+static int __qlcnic_dcb_attach(struct qlcnic_dcb *);
+static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *, char *);
+static void __qlcnic_dcb_get_info(struct qlcnic_dcb *);
+
+static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *);
+static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
+static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
+static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
+
+static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *);
+static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
+static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
+static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *, bool);
+static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
 
 struct qlcnic_dcb_capability {
 	bool	tsa_capability;
@@ -180,7 +180,7 @@ static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
 	.query_cee_param	= qlcnic_83xx_dcb_query_cee_param,
 	.get_cee_cfg		= qlcnic_83xx_dcb_get_cee_cfg,
 	.register_aen		= qlcnic_83xx_dcb_register_aen,
-	.handle_aen		= qlcnic_83xx_dcb_handle_aen,
+	.aen_handler		= qlcnic_83xx_dcb_aen_handler,
 };
 
 static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
@@ -193,7 +193,7 @@ static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
 	.get_hw_capability	= qlcnic_82xx_dcb_get_hw_capability,
 	.query_cee_param	= qlcnic_82xx_dcb_query_cee_param,
 	.get_cee_cfg		= qlcnic_82xx_dcb_get_cee_cfg,
-	.handle_aen		= qlcnic_82xx_dcb_handle_aen,
+	.aen_handler		= qlcnic_82xx_dcb_aen_handler,
 };
 
 static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
@@ -242,10 +242,10 @@ static int qlcnic_dcb_prio_count(u8 up_tc_map)
 	return j;
 }
 
-static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *adapter)
+static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *dcb)
 {
-	if (test_bit(__QLCNIC_DCB_STATE, &adapter->state))
-		adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
+	if (test_bit(QLCNIC_DCB_STATE, &dcb->state))
+		dcb->adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
 }
 
 static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
@@ -256,7 +256,7 @@ static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
 		adapter->dcb->ops = &qlcnic_83xx_dcb_ops;
 }
 
-int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
+int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 {
 	struct qlcnic_dcb *dcb;
 
@@ -267,20 +267,22 @@ int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 	adapter->dcb = dcb;
 	dcb->adapter = adapter;
 	qlcnic_set_dcb_ops(adapter);
+	dcb->state = 0;
 
 	return 0;
 }
 
-static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
+static void __qlcnic_dcb_free(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
+	struct qlcnic_adapter *adapter;
 
 	if (!dcb)
 		return;
 
-	qlcnic_dcb_register_aen(adapter, 0);
+	adapter = dcb->adapter;
+	qlcnic_dcb_register_aen(dcb, 0);
 
-	while (test_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+	while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 		usleep_range(10000, 11000);
 
 	cancel_delayed_work_sync(&dcb->aen_work);
@@ -298,23 +300,22 @@ static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
 	adapter->dcb = NULL;
 }
 
-static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
+static void __qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
 {
-	qlcnic_dcb_get_hw_capability(adapter);
-	qlcnic_dcb_get_cee_cfg(adapter);
-	qlcnic_dcb_register_aen(adapter, 1);
+	qlcnic_dcb_get_hw_capability(dcb);
+	qlcnic_dcb_get_cee_cfg(dcb);
+	qlcnic_dcb_register_aen(dcb, 1);
 }
 
-static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
+static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
 	int err = 0;
 
 	INIT_DELAYED_WORK(&dcb->aen_work, qlcnic_dcb_aen_work);
 
 	dcb->wq = create_singlethread_workqueue("qlcnic-dcb");
 	if (!dcb->wq) {
-		dev_err(&adapter->pdev->dev,
+		dev_err(&dcb->adapter->pdev->dev,
 			"DCB workqueue allocation failed. DCB will be disabled\n");
 		return -1;
 	}
@@ -331,7 +332,7 @@ static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
 		goto out_free_cfg;
 	}
 
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(dcb);
 
 	return 0;
 out_free_cfg:
@@ -345,9 +346,9 @@ out_free_wq:
 	return err;
 }
 
-static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
-					    char *buf)
+static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
 {
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_cmd_args cmd;
 	u32 mbx_out;
 	int err;
@@ -371,15 +372,15 @@ static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
 	return err;
 }
 
-static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
+static int __qlcnic_dcb_get_capability(struct qlcnic_dcb *dcb, u32 *val)
 {
-	struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
+	struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
 	u32 mbx_out;
 	int err;
 
 	memset(cap, 0, sizeof(struct qlcnic_dcb_capability));
 
-	err = qlcnic_dcb_query_hw_capability(adapter, (char *)val);
+	err = qlcnic_dcb_query_hw_capability(dcb, (char *)val);
 	if (err)
 		return err;
 
@@ -397,21 +398,21 @@ static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
 	if (cap->max_num_tc > QLC_DCB_MAX_TC ||
 	    cap->max_ets_tc > cap->max_num_tc ||
 	    cap->max_pfc_tc > cap->max_num_tc) {
-		dev_err(&adapter->pdev->dev, "Invalid DCB configuration\n");
+		dev_err(&dcb->adapter->pdev->dev, "Invalid DCB configuration\n");
 		return -EINVAL;
 	}
 
 	return err;
 }
 
-static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
+static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
+	struct qlcnic_dcb_cfg *cfg = dcb->cfg;
 	struct qlcnic_dcb_capability *cap;
 	u32 mbx_out;
 	int err;
 
-	err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
+	err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
 	if (err)
 		return err;
 
@@ -419,15 +420,16 @@ static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
 	cap->dcb_capability = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_LLD_MANAGED;
 
 	if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
-		set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		set_bit(QLCNIC_DCB_STATE, &dcb->state);
 
 	return err;
 }
 
-static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
+static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
 					   char *buf, u8 type)
 {
 	u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
 	struct device *dev = &adapter->pdev->dev;
 	dma_addr_t cardrsp_phys_addr;
@@ -447,8 +449,7 @@ static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
 		return -EINVAL;
 	}
 
-	addr = dma_alloc_coherent(&adapter->pdev->dev, size, &cardrsp_phys_addr,
-				  GFP_KERNEL);
+	addr = dma_alloc_coherent(dev, size, &cardrsp_phys_addr, GFP_KERNEL);
 	if (addr == NULL)
 		return -ENOMEM;
 
@@ -488,72 +489,67 @@ out:
 	qlcnic_free_mbx_args(&cmd);
 
 out_free_rsp:
-	dma_free_coherent(&adapter->pdev->dev, size, addr, cardrsp_phys_addr);
+	dma_free_coherent(dev, size, addr, cardrsp_phys_addr);
 
 	return err;
 }
 
-static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
+static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
 {
 	struct qlcnic_dcb_mbx_params *mbx;
 	int err;
 
-	mbx = adapter->dcb->param;
+	mbx = dcb->param;
 	if (!mbx)
 		return 0;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[0],
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[0],
 					 QLC_DCB_LOCAL_PARAM_FWID);
 	if (err)
 		return err;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[1],
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[1],
 					 QLC_DCB_OPER_PARAM_FWID);
 	if (err)
 		return err;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[2],
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[2],
 					 QLC_DCB_PEER_PARAM_FWID);
 	if (err)
 		return err;
 
 	mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
 
-	qlcnic_dcb_data_cee_param_map(adapter);
+	qlcnic_dcb_data_cee_param_map(dcb->adapter);
 
 	return err;
 }
 
 static void qlcnic_dcb_aen_work(struct work_struct *work)
 {
-	struct qlcnic_adapter *adapter;
 	struct qlcnic_dcb *dcb;
 
 	dcb = container_of(work, struct qlcnic_dcb, aen_work.work);
-	adapter = dcb->adapter;
 
-	qlcnic_dcb_get_cee_cfg(adapter);
-	clear_bit(__QLCNIC_DCB_IN_AEN, &adapter->state);
+	qlcnic_dcb_get_cee_cfg(dcb);
+	clear_bit(QLCNIC_DCB_AEN_MODE, &dcb->state);
 }
 
-static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
-				       void *data)
+static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+	if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 		return;
 
 	queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
 }
 
-static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
+static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
+	struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
 	u32 mbx_out;
 	int err;
 
-	err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
+	err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
 	if (err)
 		return err;
 
@@ -565,14 +561,15 @@ static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
 		cap->dcb_capability |= DCB_CAP_DCBX_LLD_MANAGED;
 
 	if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
-		set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		set_bit(QLCNIC_DCB_STATE, &dcb->state);
 
 	return err;
 }
 
-static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
+static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
 					   char *buf, u8 idx)
 {
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_dcb_mbx_params mbx_out;
 	int err, i, j, k, max_app, size;
 	struct qlcnic_dcb_param *each;
@@ -632,24 +629,23 @@ out:
 	return err;
 }
 
-static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
+static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
 	int err;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)dcb->param, 0);
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)dcb->param, 0);
 	if (err)
 		return err;
 
-	qlcnic_dcb_data_cee_param_map(adapter);
+	qlcnic_dcb_data_cee_param_map(dcb->adapter);
 
 	return err;
 }
 
-static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
-					bool flag)
+static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *dcb, bool flag)
 {
 	u8 val = (flag ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC);
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_cmd_args cmd;
 	int err;
 
@@ -669,19 +665,17 @@ static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
 	return err;
 }
 
-static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
-				       void *data)
+static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
 	u32 *val = data;
 
-	if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+	if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 		return;
 
 	if (*val & BIT_8)
-		set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		set_bit(QLCNIC_DCB_STATE, &dcb->state);
 	else
-		clear_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		clear_bit(QLCNIC_DCB_STATE, &dcb->state);
 
 	queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
 }
@@ -814,12 +808,12 @@ static u8 qlcnic_dcb_get_state(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	return test_bit(__QLCNIC_DCB_STATE, &adapter->state);
+	return test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state);
 }
 
 static void qlcnic_dcb_get_perm_hw_addr(struct net_device *netdev, u8 *addr)
 {
-	memcpy(addr, netdev->dev_addr, netdev->addr_len);
+	memcpy(addr, netdev->perm_addr, netdev->addr_len);
 }
 
 static void
@@ -834,7 +828,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 	*prio = *pgid = *bw_per = *up_tc_map = 0;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 	    !type->tc_param_valid)
 		return;
 
@@ -870,7 +864,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
 	*bw_pct = 0;
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 	    !type->tc_param_valid)
 		return;
 
@@ -896,7 +890,7 @@ static void qlcnic_dcb_get_pfc_cfg(struct net_device *netdev, int prio,
 	*setting = 0;
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 	    !type->pfc_mode_enable)
 		return;
 
@@ -915,7 +909,7 @@ static u8 qlcnic_dcb_get_capability(struct net_device *netdev, int capid,
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	switch (capid) {
@@ -944,7 +938,7 @@ static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return -EINVAL;
 
 	switch (attr) {
@@ -967,7 +961,7 @@ static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
 				.protocol = id,
 			     };
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	return dcb_getapp(netdev, &app);
@@ -978,7 +972,7 @@ static u8 qlcnic_dcb_get_pfc_state(struct net_device *netdev)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb *dcb = adapter->dcb;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &dcb->state))
 		return 0;
 
 	return dcb->cfg->type[QLC_DCB_OPER_IDX].pfc_mode_enable;
@@ -989,7 +983,7 @@ static u8 qlcnic_dcb_get_dcbx(struct net_device *netdev)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	return cfg->capability.dcb_capability;
@@ -1000,7 +994,7 @@ static u8 qlcnic_dcb_get_feat_cfg(struct net_device *netdev, int fid, u8 *flag)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb_cee *type;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 1;
 
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
@@ -1055,7 +1049,7 @@ static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
 
 	*app_count = 0;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1076,7 +1070,7 @@ static int qlcnic_dcb_peer_app_table(struct net_device *netdev,
 	struct qlcnic_dcb_app *app;
 	int i, j;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1101,7 +1095,7 @@ static int qlcnic_dcb_cee_peer_get_pg(struct net_device *netdev,
 	struct qlcnic_dcb_cee *peer;
 	u8 i, j, k, map;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1136,7 +1130,7 @@ static int qlcnic_dcb_cee_peer_get_pfc(struct net_device *netdev,
 
 	pfc->pfc_en = 0;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &cfg->type[QLC_DCB_PEER_IDX];
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
index b87ce9f..c04ae0c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
@@ -8,26 +8,29 @@
 #ifndef __QLCNIC_DCBX_H
 #define __QLCNIC_DCBX_H
 
-void qlcnic_clear_dcb_ops(struct qlcnic_adapter *);
+#define QLCNIC_DCB_STATE	0
+#define QLCNIC_DCB_AEN_MODE	1
 
 #ifdef CONFIG_QLCNIC_DCB
-int __qlcnic_register_dcb(struct qlcnic_adapter *);
+int qlcnic_register_dcb(struct qlcnic_adapter *);
 #else
-static inline int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
+static inline int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 { return 0; }
 #endif
 
+struct qlcnic_dcb;
+
 struct qlcnic_dcb_ops {
-	void (*init_dcbnl_ops) (struct qlcnic_adapter *);
-	void (*free) (struct qlcnic_adapter *);
-	int (*attach) (struct qlcnic_adapter *);
-	int (*query_hw_capability) (struct qlcnic_adapter *, char *);
-	int (*get_hw_capability) (struct qlcnic_adapter *);
-	void (*get_info) (struct qlcnic_adapter *);
-	int (*query_cee_param) (struct qlcnic_adapter *, char *, u8);
-	int (*get_cee_cfg) (struct qlcnic_adapter *);
-	int (*register_aen) (struct qlcnic_adapter *, bool);
-	void (*handle_aen) (struct qlcnic_adapter *, void *);
+	int (*query_hw_capability) (struct qlcnic_dcb *, char *);
+	int (*get_hw_capability) (struct qlcnic_dcb *);
+	int (*query_cee_param) (struct qlcnic_dcb *, char *, u8);
+	void (*init_dcbnl_ops) (struct qlcnic_dcb *);
+	int (*register_aen) (struct qlcnic_dcb *, bool);
+	void (*aen_handler) (struct qlcnic_dcb *, void *);
+	int (*get_cee_cfg) (struct qlcnic_dcb *);
+	void (*get_info) (struct qlcnic_dcb *);
+	int (*attach) (struct qlcnic_dcb *);
+	void (*free) (struct qlcnic_dcb *);
 };
 
 struct qlcnic_dcb {
@@ -37,5 +40,85 @@ struct qlcnic_dcb {
 	struct workqueue_struct		*wq;
 	struct qlcnic_dcb_ops		*ops;
 	struct qlcnic_dcb_cfg		*cfg;
+	unsigned long			state;
 };
+
+static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
+{
+	kfree(dcb);
+	dcb = NULL;
+}
+
+static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->get_hw_capability)
+		return dcb->ops->get_hw_capability(dcb);
+
+	return 0;
+}
+
+static inline void qlcnic_dcb_free(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->free)
+		dcb->ops->free(dcb);
+}
+
+static inline int qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->attach)
+		return dcb->ops->attach(dcb);
+
+	return 0;
+}
+
+static inline int
+qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
+{
+	if (dcb && dcb->ops->query_hw_capability)
+		return dcb->ops->query_hw_capability(dcb, buf);
+
+	return 0;
+}
+
+static inline void qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->get_info)
+		dcb->ops->get_info(dcb);
+}
+
+static inline int
+qlcnic_dcb_query_cee_param(struct qlcnic_dcb *dcb, char *buf, u8 type)
+{
+	if (dcb && dcb->ops->query_cee_param)
+		return dcb->ops->query_cee_param(dcb, buf, type);
+
+	return 0;
+}
+
+static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->get_cee_cfg)
+		return dcb->ops->get_cee_cfg(dcb);
+
+	return 0;
+}
+
+static inline void
+qlcnic_dcb_register_aen(struct qlcnic_dcb *dcb, u8 flag)
+{
+	if (dcb && dcb->ops->register_aen)
+		dcb->ops->register_aen(dcb, flag);
+}
+
+static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg)
+{
+	if (dcb && dcb->ops->aen_handler)
+		dcb->ops->aen_handler(dcb, msg);
+}
+
+static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->init_dcbnl_ops)
+		dcb->ops->init_dcbnl_ops(dcb);
+}
 #endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 11b4bb8..897627d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -1011,7 +1011,7 @@ static void qlcnic_handle_fw_message(int desc_cnt, int index,
 		}
 		break;
 	case QLCNIC_C2H_OPCODE_GET_DCB_AEN:
-		qlcnic_dcb_handle_aen(adapter, (void *)&msg);
+		qlcnic_dcb_aen_handler(adapter->dcb, (void *)&msg);
 		break;
 	default:
 		break;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 725d76f..0274832 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2071,7 +2071,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 		return err;
 	}
 
-	qlcnic_dcb_init_dcbnl_ops(adapter);
+	qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
 
 	return 0;
 }
@@ -2166,17 +2166,6 @@ void qlcnic_set_drv_version(struct qlcnic_adapter *adapter)
 		qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
 }
 
-static int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
-{
-	return __qlcnic_register_dcb(adapter);
-}
-
-void qlcnic_clear_dcb_ops(struct qlcnic_adapter *adapter)
-{
-	kfree(adapter->dcb);
-	adapter->dcb = NULL;
-}
-
 static int
 qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -2185,6 +2174,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct qlcnic_hardware_context *ahw;
 	int err, pci_using_dac = -1;
 	char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */
+	struct qlcnic_dcb *dcb;
 
 	if (pdev->is_virtfn)
 		return -ENODEV;
@@ -2305,8 +2295,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 		adapter->flags |= QLCNIC_NEED_FLR;
 
-		if (adapter->dcb && qlcnic_dcb_attach(adapter))
-			qlcnic_clear_dcb_ops(adapter);
+		dcb = adapter->dcb;
+
+		if (dcb && qlcnic_dcb_attach(dcb))
+			qlcnic_clear_dcb_ops(dcb);
 
 	} else if (qlcnic_83xx_check(adapter)) {
 		adapter->max_drv_tx_rings = 1;
@@ -2451,7 +2443,7 @@ static void qlcnic_remove(struct pci_dev *pdev)
 	qlcnic_cancel_idc_work(adapter);
 	ahw = adapter->ahw;
 
-	qlcnic_dcb_free(adapter);
+	qlcnic_dcb_free(adapter->dcb);
 
 	unregister_netdev(netdev);
 	qlcnic_sriov_cleanup(adapter);
@@ -3329,7 +3321,7 @@ qlcnic_attach_work(struct work_struct *work)
 		return;
 	}
 attach:
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(adapter->dcb);
 
 	if (netif_running(netdev)) {
 		if (qlcnic_up(adapter, netdev))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 392b9bd..8b96e29 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -500,6 +500,7 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
 static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
 				 int pci_using_dac)
 {
+	struct qlcnic_dcb *dcb;
 	int err;
 
 	INIT_LIST_HEAD(&adapter->vf_mc_list);
@@ -533,8 +534,10 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
 	if (err)
 		goto err_out_send_channel_term;
 
-	if (adapter->dcb && qlcnic_dcb_attach(adapter))
-		qlcnic_clear_dcb_ops(adapter);
+	dcb = adapter->dcb;
+
+	if (dcb && qlcnic_dcb_attach(dcb))
+		qlcnic_clear_dcb_ops(dcb);
 
 	err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac);
 	if (err)
@@ -1577,7 +1580,7 @@ static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
 	if (err)
 		goto err_out_term_channel;
 
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(adapter->dcb);
 
 	return 0;
 
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next v4 5/8] qlcnic: Remove redundant eSwitch enable commands
From: Himanshu Madhani @ 2013-10-18 16:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sony Chacko, himanshu.madhani
In-Reply-To: <cover.1382090311.git.himanshu.madhani@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

When more than one NIC physical functions are enabled on a port,
eSwitch on that port gets enabled automatically. Driver
need not explicitly enable the eSwitch.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |  2 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  | 23 ++++------------------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   | 13 ++++++------
 3 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 2883b57..9f4e4c4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -629,7 +629,7 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
 int qlcnic_83xx_get_vnic_vport_info(struct qlcnic_adapter *,
 				    struct qlcnic_info *, u8);
 int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
-int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *, int);
+int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *, int, int *);
 
 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
 void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index 60a477f..734d286 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -256,8 +256,8 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
 	return 0;
 }
 
-static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
-					     int func, int *port_id)
+int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *adapter,
+					int func, int *port_id)
 {
 	struct qlcnic_info nic_info;
 	int err = 0;
@@ -273,23 +273,8 @@ static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
 	else
 		err = -EIO;
 
-	return err;
-}
-
-int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *adapter, int func)
-{
-	int id, err = 0;
-
-	err = qlcnic_83xx_get_eswitch_port_info(adapter, func, &id);
-	if (err)
-		return err;
-
-	if (!(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
-		if (!qlcnic_enable_eswitch(adapter, id, 1))
-			adapter->eswitch[id].flags |= QLCNIC_SWITCH_ENABLE;
-		else
-			err = -EIO;
-	}
+	if (!err)
+		adapter->eswitch[*port_id].flags |= QLCNIC_SWITCH_ENABLE;
 
 	return err;
 }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 5195972..725d76f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -819,7 +819,7 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter)
 int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 {
 	struct qlcnic_pci_info *pci_info;
-	int i, ret = 0, j = 0;
+	int i, id = 0, ret = 0, j = 0;
 	u16 act_pci_func;
 	u8 pfn;
 
@@ -860,7 +860,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 			continue;
 
 		if (qlcnic_port_eswitch_cfg_capability(adapter)) {
-			if (!qlcnic_83xx_enable_port_eswitch(adapter, pfn))
+			if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn,
+								 &id))
 				adapter->npars[j].eswitch_status = true;
 			else
 				continue;
@@ -879,12 +880,12 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 		j++;
 	}
 
-	if (qlcnic_82xx_check(adapter)) {
+	/* Update eSwitch status for adapters without per port eSwitch
+	 * configuration capability
+	 */
+	if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
 		for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
 			adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE;
-	} else if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
-		for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
-			qlcnic_enable_eswitch(adapter, i, 1);
 	}
 
 	kfree(pci_info);
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH] packet: Deliver VLAN TPID to userspace
From: Atzm Watanabe @ 2013-10-18 17:08 UTC (permalink / raw)
  To: netdev

After the 802.1AD support, userspace packet receivers
(packet dumper, software switch, and the like) need how to know
VLAN TPID in order to reassemble original tagged frame.

Signed-off-by: Atzm Watanabe <atzm@stratosphere.co.jp>
---
 include/uapi/linux/if_packet.h | 5 +++--
 net/packet/af_packet.c         | 8 ++++++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h
index dbf0666..6e36e0a 100644
--- a/include/uapi/linux/if_packet.h
+++ b/include/uapi/linux/if_packet.h
@@ -83,7 +83,7 @@ struct tpacket_auxdata {
 	__u16		tp_mac;
 	__u16		tp_net;
 	__u16		tp_vlan_tci;
-	__u16		tp_padding;
+	__u16		tp_vlan_tpid;
 };
 
 /* Rx ring - header status */
@@ -132,12 +132,13 @@ struct tpacket2_hdr {
 	__u32		tp_sec;
 	__u32		tp_nsec;
 	__u16		tp_vlan_tci;
-	__u16		tp_padding;
+	__u16		tp_vlan_tpid;
 };
 
 struct tpacket_hdr_variant1 {
 	__u32	tp_rxhash;
 	__u32	tp_vlan_tci;
+	__u32	tp_vlan_tpid;
 };
 
 struct tpacket3_hdr {
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2e8286b..fbcc882 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -895,9 +895,11 @@ static void prb_fill_vlan_info(struct tpacket_kbdq_core *pkc,
 {
 	if (vlan_tx_tag_present(pkc->skb)) {
 		ppd->hv1.tp_vlan_tci = vlan_tx_tag_get(pkc->skb);
+		ppd->hv1.tp_vlan_tpid = (__force __u32)ntohs(pkc->skb->vlan_proto);
 		ppd->tp_status = TP_STATUS_VLAN_VALID;
 	} else {
 		ppd->hv1.tp_vlan_tci = 0;
+		ppd->hv1.tp_vlan_tpid = 0;
 		ppd->tp_status = TP_STATUS_AVAILABLE;
 	}
 }
@@ -1836,11 +1838,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 		h.h2->tp_nsec = ts.tv_nsec;
 		if (vlan_tx_tag_present(skb)) {
 			h.h2->tp_vlan_tci = vlan_tx_tag_get(skb);
+			h.h2->tp_vlan_tpid = ntohs(skb->vlan_proto);
 			status |= TP_STATUS_VLAN_VALID;
 		} else {
 			h.h2->tp_vlan_tci = 0;
+			h.h2->tp_vlan_tpid = 0;
 		}
-		h.h2->tp_padding = 0;
 		hdrlen = sizeof(*h.h2);
 		break;
 	case TPACKET_V3:
@@ -2788,11 +2791,12 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 		aux.tp_net = skb_network_offset(skb);
 		if (vlan_tx_tag_present(skb)) {
 			aux.tp_vlan_tci = vlan_tx_tag_get(skb);
+			aux.tp_vlan_tpid = ntohs(skb->vlan_proto);
 			aux.tp_status |= TP_STATUS_VLAN_VALID;
 		} else {
 			aux.tp_vlan_tci = 0;
+			aux.tp_vlan_tpid = 0;
 		}
-		aux.tp_padding = 0;
 		put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
 	}
 
-- 
1.8.1.5

^ permalink raw reply related

* [patch net REPOST 0/3] UFO fixes
From: Jiri Pirko @ 2013-10-18 17:13 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, hannes, jdmason, yoshfuji, kuznet, jmorris,
	kaber, herbert

Couple of patches fixing UFO functionality in different situations.

Jiri Pirko (3):
  udp6: respect IPV6_DONTFRAG sockopt in case there are pending frames
  ip6_output: do skb ufo init for peeked non ufo skb as well
  ip_output: do skb ufo init for peeked non ufo skb as well

 net/ipv4/ip_output.c  | 14 +++++++++-----
 net/ipv6/ip6_output.c | 26 ++++++++++++++------------
 net/ipv6/udp.c        |  5 ++---
 3 files changed, 25 insertions(+), 20 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* [patch net REPOST 1/3] udp6: respect IPV6_DONTFRAG sockopt in case there are pending frames
From: Jiri Pirko @ 2013-10-18 17:13 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, hannes, jdmason, yoshfuji, kuznet, jmorris,
	kaber, herbert
In-Reply-To: <1382116431-28758-1-git-send-email-jiri@resnulli.us>

if up->pending != 0 dontfrag is left with default value -1. That
causes that application that do:
sendto len>mtu flag MSG_MORE
sendto len>mtu flag 0
will receive EMSGSIZE errno as the result of the second sendto.

This patch fixes it by respecting IPV6_DONTFRAG socket option.

introduced by:
commit 4b340ae20d0e2366792abe70f46629e576adaf5e "IPv6: Complete IPV6_DONTFRAG support"

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/ipv6/udp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 72b7eaa..1878609 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1225,9 +1225,6 @@ do_udp_sendmsg:
 	if (tclass < 0)
 		tclass = np->tclass;
 
-	if (dontfrag < 0)
-		dontfrag = np->dontfrag;
-
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
 back_from_confirm:
@@ -1246,6 +1243,8 @@ back_from_confirm:
 	up->pending = AF_INET6;
 
 do_append_data:
+	if (dontfrag < 0)
+		dontfrag = np->dontfrag;
 	up->len += ulen;
 	getfrag  =  is_udplite ?  udplite_getfrag : ip_generic_getfrag;
 	err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
-- 
1.8.3.1

^ permalink raw reply related

* [patch net REPOST 2/3] ip6_output: do skb ufo init for peeked non ufo skb as well
From: Jiri Pirko @ 2013-10-18 17:13 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, hannes, jdmason, yoshfuji, kuznet, jmorris,
	kaber, herbert
In-Reply-To: <1382116431-28758-1-git-send-email-jiri@resnulli.us>

Now, if user application does:
sendto len<mtu flag MSG_MORE
sendto len>mtu flag 0
The skb is not treated as fragmented one because it is not initialized
that way. So move the initialization to fix this.

introduced by:
commit e89e9cf539a28df7d0eb1d0a545368e9920b34ac "[IPv4/IPv6]: UFO Scatter-gather approach"

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/ipv6/ip6_output.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a54c45c..c6cfa2f 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1008,6 +1008,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
 
 {
 	struct sk_buff *skb;
+	struct frag_hdr fhdr;
 	int err;
 
 	/* There is support for UDP large send offload by network
@@ -1015,8 +1016,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
 	 * udp datagram
 	 */
 	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
-		struct frag_hdr fhdr;
-
 		skb = sock_alloc_send_skb(sk,
 			hh_len + fragheaderlen + transhdrlen + 20,
 			(flags & MSG_DONTWAIT), &err);
@@ -1036,20 +1035,23 @@ static inline int ip6_ufo_append_data(struct sock *sk,
 		skb->transport_header = skb->network_header + fragheaderlen;
 
 		skb->protocol = htons(ETH_P_IPV6);
-		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum = 0;
 
-		/* Specify the length of each IPv6 datagram fragment.
-		 * It has to be a multiple of 8.
-		 */
-		skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
-					     sizeof(struct frag_hdr)) & ~7;
-		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
-		ipv6_select_ident(&fhdr, rt);
-		skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
 		__skb_queue_tail(&sk->sk_write_queue, skb);
-	}
+	} else if (skb_is_gso(skb))
+		goto append;
+
+	skb->ip_summed = CHECKSUM_PARTIAL;
+	/* Specify the length of each IPv6 datagram fragment.
+	 * It has to be a multiple of 8.
+	 */
+	skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
+				     sizeof(struct frag_hdr)) & ~7;
+	skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+	ipv6_select_ident(&fhdr, rt);
+	skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
 
+append:
 	return skb_append_datato_frags(sk, skb, getfrag, from,
 				       (length - transhdrlen));
 }
-- 
1.8.3.1

^ permalink raw reply related

* [patch net REPOST 3/3] ip_output: do skb ufo init for peeked non ufo skb as well
From: Jiri Pirko @ 2013-10-18 17:13 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, hannes, jdmason, yoshfuji, kuznet, jmorris,
	kaber, herbert
In-Reply-To: <1382116431-28758-1-git-send-email-jiri@resnulli.us>

Now, if user application does:
sendto len<mtu flag MSG_MORE
sendto len>mtu flag 0
The skb is not treated as fragmented one because it is not initialized
that way. So move the initialization to fix this.

introduced by:
commit e89e9cf539a28df7d0eb1d0a545368e9920b34ac "[IPv4/IPv6]: UFO Scatter-gather approach"

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/ipv4/ip_output.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index a04d872..bd21c5d 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -772,15 +772,19 @@ static inline int ip_ufo_append_data(struct sock *sk,
 		/* initialize protocol header pointer */
 		skb->transport_header = skb->network_header + fragheaderlen;
 
-		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum = 0;
 
-		/* specify the length of each IP datagram fragment */
-		skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
-		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+
 		__skb_queue_tail(queue, skb);
-	}
+	} else if (skb_is_gso(skb))
+		goto append;
+
+	skb->ip_summed = CHECKSUM_PARTIAL;
+	/* specify the length of each IP datagram fragment */
+	skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
+	skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 
+append:
 	return skb_append_datato_frags(sk, skb, getfrag, from,
 				       (length - transhdrlen));
 }
-- 
1.8.3.1

^ permalink raw reply related

* Re: [patch net REPOST 0/3] UFO fixes
From: Jiri Pirko @ 2013-10-18 17:15 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, hannes, jdmason, yoshfuji, kuznet, jmorris,
	kaber, herbert
In-Reply-To: <1382116431-28758-1-git-send-email-jiri@resnulli.us>

Hannes, sorry for messed up email address :/

Fri, Oct 18, 2013 at 07:13:48PM CEST, jiri@resnulli.us wrote:
>Couple of patches fixing UFO functionality in different situations.
>
>Jiri Pirko (3):
>  udp6: respect IPV6_DONTFRAG sockopt in case there are pending frames
>  ip6_output: do skb ufo init for peeked non ufo skb as well
>  ip_output: do skb ufo init for peeked non ufo skb as well
>
> net/ipv4/ip_output.c  | 14 +++++++++-----
> net/ipv6/ip6_output.c | 26 ++++++++++++++------------
> net/ipv6/udp.c        |  5 ++---
> 3 files changed, 25 insertions(+), 20 deletions(-)
>
>-- 
>1.8.3.1
>

^ permalink raw reply

* Re: [patch net REPOST 0/3] UFO fixes
From: Hannes Frederic Sowa @ 2013-10-18 17:20 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, eric.dumazet, jdmason, yoshfuji, kuznet, jmorris,
	kaber, herbert
In-Reply-To: <20131018171524.GC1491@minipsycho.orion>

On Fri, Oct 18, 2013 at 07:15:24PM +0200, Jiri Pirko wrote:
> Hannes, sorry for messed up email address :/

No problem, I got them. ;)

I'll review them again this weekend. Also Jon mailed me that he will
look at the neterion driver this weekend, so this gets finally sorted out.

Thanks,

  Hannes

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox