Netdev List
 help / color / mirror / Atom feed
* Re: pull request: wireless 2012-09-07
From: David Miller @ 2012-09-07 18:38 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120907182955.GA1854-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Date: Fri, 7 Sep 2012 14:29:55 -0400

> I'll slow it down after this!

I'm going to hold you to it :-)

>   git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

Pulled, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next] scm: Don't use struct ucred in NETLINK_CB and struct scm_cookie.
From: David Miller @ 2012-09-07 18:41 UTC (permalink / raw)
  To: eric.dumazet; +Cc: ebiederm, netdev, serge
In-Reply-To: <1347030446.2484.771.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 07 Sep 2012 17:07:26 +0200

> Seems fine to me, but I am not sure why you kept NETLINK_CREDS()
> defined/used once.

There are two remaining users, kernel/audit.c and scsi netlink.

^ permalink raw reply

* Re: [PATCH net-next] scm: Don't use struct ucred in NETLINK_CB and struct scm_cookie.
From: David Miller @ 2012-09-07 18:42 UTC (permalink / raw)
  To: ebiederm; +Cc: netdev, serge, eric.dumazet
In-Reply-To: <87haralb0u.fsf@xmission.com>

From: ebiederm@xmission.com (Eric W. Biederman)
Date: Thu, 06 Sep 2012 21:20:01 -0700

> 
> Passing uids and gids on NETLINK_CB from a process in one user
> namespace to a process in another user namespace can result in the
> wrong uid or gid being presented to userspace.  Avoid that problem by
> passing kuids and kgids instead.
> 
> - define struct scm_creds for use in scm_cookie and netlink_skb_parms
>   that holds uid and gid information in kuid_t and kgid_t.
> 
> - Modify scm_set_cred to fill out scm_creds by heand instead of using
>   cred_to_ucred to fill out struct ucred.  This conversion ensures
>   userspace does not get incorrect uid or gid values to look at.
> 
> - Modify scm_recv to convert from struct scm_creds to struct ucred
>   before copying credential values to userspace.
> 
> - Modify __scm_send to populate struct scm_creds on in the scm_cookie,
>   instead of just copying struct ucred from userspace.
> 
> - Modify netlink_sendmsg to copy scm_creds instead of struct ucred
>   into the NETLINK_CB.
> 
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

Applied, thanks Eric.

^ permalink raw reply

* Re: [PATCH net-next v2] ipv4/route: arg delay is useless in rt_cache_flush()
From: David Miller @ 2012-09-07 18:44 UTC (permalink / raw)
  To: eric.dumazet; +Cc: nicolas.dichtel, netdev
In-Reply-To: <1347031479.2484.799.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 07 Sep 2012 17:24:39 +0200

> On Fri, 2012-09-07 at 12:45 +0200, Nicolas Dichtel wrote:
>> Since route cache deletion (89aef8921bfbac22f), delay is no
>> more used. Remove it.
>> 
>> v2: remove ctl in ipv4_sysctl_rtcache_flush()
>> 
> 
> Ideally, this v2:....: should be after the --- marker

I took care of this.

>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
...
> Acked-by: Eric Dumazet <edumazet@google.com>

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH 1/2] dst: take into account policy update on check()
From: David Miller @ 2012-09-07 18:48 UTC (permalink / raw)
  To: eric.dumazet; +Cc: nicolas.dichtel, vyasevich, sri, linux-sctp, netdev
In-Reply-To: <1347031312.2484.794.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 07 Sep 2012 17:21:52 +0200

> On Fri, 2012-09-07 at 17:13 +0200, Nicolas Dichtel wrote:
>> Le 07/09/2012 17:09, Eric Dumazet a écrit :
>> > On Fri, 2012-09-07 at 16:47 +0200, Nicolas Dichtel wrote:
>> >> Le 07/09/2012 16:35, Eric Dumazet a écrit :
>> >>>
>> >>> Hmm... cant we reuse rt_genid ?
>> >>>
>> >>> (When changing flow_cache_genid, change &net->ipv4.rt_genid)
>> >>
>> >> And so adding a new field in net->ipv6?
>> >
>> > or move net->ipv4.rt_genid to net->rt_genid
>> >
>> > Having separate field for IPv4/IPv6 is of little interest IMHO
>> >
>> Ok, I will wait feedback from other people and repost a patch after.
> 
> By the way, the get_random_bytes() calls in rt_cache_invalidate() and in
> rt_genid_init() are no longer needed, since we dont use jhash anymore
> (no more route cache)

I like it, please submit this formally for net-next :-)

^ permalink raw reply

* Re: [PATCH 1/2] dst: take into account policy update on check()
From: David Miller @ 2012-09-07 18:48 UTC (permalink / raw)
  To: nicolas.dichtel; +Cc: eric.dumazet, vyasevich, sri, linux-sctp, netdev
In-Reply-To: <504A0F1F.5060504@6wind.com>

From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Date: Fri, 07 Sep 2012 17:13:35 +0200

> Le 07/09/2012 17:09, Eric Dumazet a écrit :
>> On Fri, 2012-09-07 at 16:47 +0200, Nicolas Dichtel wrote:
>>> Le 07/09/2012 16:35, Eric Dumazet a écrit :
>>>>
>>>> Hmm... cant we reuse rt_genid ?
>>>>
>>>> (When changing flow_cache_genid, change &net->ipv4.rt_genid)
>>>
>>> And so adding a new field in net->ipv6?
>>
>> or move net->ipv4.rt_genid to net->rt_genid
>>
>> Having separate field for IPv4/IPv6 is of little interest IMHO
>>
> Ok, I will wait feedback from other people and repost a patch after.

A global net->rt_genid is definitely the way to go.

^ permalink raw reply

* Re: [PATCH net-next 0/2] qmi_wwan changes intended for 3.7
From: David Miller @ 2012-09-07 18:50 UTC (permalink / raw)
  To: bjorn; +Cc: netdev, linux-usb
In-Reply-To: <1347039367-12399-1-git-send-email-bjorn@mork.no>

From: Bjørn Mork <bjorn@mork.no>
Date: Fri,  7 Sep 2012 19:36:05 +0200

> Just a couple of minor improvements for 3.7.  The QMI
> message size issue is not considered important enough for
> stable.  It does not affect the primary device function
> at all, and I consider it more of a feature enhancement
> than a fix.
> 
> 
> Bjørn Mork (2):
>   net: qmi_wwan: increase max QMI message size to 4096
>   net: qmi_wwan: use a single bind function for all device types

Both applied, thanks.

^ permalink raw reply

* Re: linux-next: Tree for Sept 4 (drivers/net/phy/mdio-mux-mmioreg.c)
From: Timur Tabi @ 2012-09-07 19:37 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: Stephen Rothwell, linux-next, LKML, netdev
In-Reply-To: <5046933A.6080400@xenotime.net>

Randy Dunlap wrote:
> drivers/net/phy/mdio-mux-mmioreg.c: In function 'mdio_mux_mmioreg_probe':
> drivers/net/phy/mdio-mux-mmioreg.c:83:2: error: implicit declaration of function 'of_address_to_resource'

I can't reproduce the problem, but I think I have a fix.  I'll post a
patch in a minute.  Can you test it and let me know (e.g. via an ACK)
whether it works?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* [PATCH] netdev/phy: mdio-mux-mmioreg.c should include of_address.h
From: Timur Tabi @ 2012-09-07 20:09 UTC (permalink / raw)
  To: linux-kernel, netdev, linux-next, sfr, rdunlap

mdio-mux-mmioreg.c uses function of_address_to_resource(), which is defined
in linux/of_address.h.  This fixes a compilation error:

drivers/net/phy/mdio-mux-mmioreg.c: In function 'mdio_mux_mmioreg_probe':
drivers/net/phy/mdio-mux-mmioreg.c:83:2: error: implicit declaration of
	function 'of_address_to_resource'

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/net/phy/mdio-mux-mmioreg.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c
index 098239a..9061ba6 100644
--- a/drivers/net/phy/mdio-mux-mmioreg.c
+++ b/drivers/net/phy/mdio-mux-mmioreg.c
@@ -12,6 +12,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/device.h>
+#include <linux/of_address.h>
 #include <linux/of_mdio.h>
 #include <linux/module.h>
 #include <linux/init.h>
-- 
1.7.3.4

^ permalink raw reply related

* [PATCH net-next] net: rt_cache_flush() cleanup
From: Eric Dumazet @ 2012-09-07 20:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

From: Eric Dumazet <edumazet@google.com>

We dont use jhash anymore since route cache removal,
so we can get rid of get_random_bytes() calls for rt_genid
changes.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/route.c |   19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ab1e7c7..d39edf1 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -447,23 +447,9 @@ static inline bool rt_is_expired(const struct rtable *rth)
 	return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
 }
 
-/*
- * Perturbation of rt_genid by a small quantity [1..256]
- * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
- * many times (2^24) without giving recent rt_genid.
- * Jenkins hash is strong enough that litle changes of rt_genid are OK.
- */
-static void rt_cache_invalidate(struct net *net)
-{
-	unsigned char shuffle;
-
-	get_random_bytes(&shuffle, sizeof(shuffle));
-	atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
-}
-
 void rt_cache_flush(struct net *net)
 {
-	rt_cache_invalidate(net);
+	atomic_inc(&net->ipv4.rt_genid);
 }
 
 static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
@@ -2520,8 +2506,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
 
 static __net_init int rt_genid_init(struct net *net)
 {
-	get_random_bytes(&net->ipv4.rt_genid,
-			 sizeof(net->ipv4.rt_genid));
+	atomic_set(&net->ipv4.rt_genid, 0);
 	get_random_bytes(&net->ipv4.dev_addr_genid,
 			 sizeof(net->ipv4.dev_addr_genid));
 	return 0;

^ permalink raw reply related

* Re: [PATCH 1/4] slab: do ClearSlabPfmemalloc() for all pages of slab
From: JoonSoo Kim @ 2012-09-07 21:10 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Andrew Morton, Linux-MM, Linux-Netdev, LKML, David Miller,
	Chuck Lever, Pekka Enberg, David Rientjes, Christoph Lameter
In-Reply-To: <20120907125519.GB11266@suse.de>

2012/9/7 Mel Gorman <mgorman@suse.de>:
> This churns code a lot more than is necessary. How about this as a
> replacement patch?
>
> ---8<---
> From: Joonsoo Kim <js1304@gmail.com>
> Subject: [PATCH] slab: do ClearSlabPfmemalloc() for all pages of slab
>
> Right now, we call ClearSlabPfmemalloc() for first page of slab when we
> clear SlabPfmemalloc flag. This is fine for most swap-over-network use
> cases as it is expected that order-0 pages are in use. Unfortunately it
> is possible that that __ac_put_obj() checks SlabPfmemalloc on a tail page
> and while this is harmless, it is sloppy. This patch ensures that the head
> page is always used.
>
> [mgorman@suse.de: Easier implementation, changelog cleanup]
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> Signed-off-by: Mel Gorman <mgorman@suse.de>
> ---
>  mm/slab.c |   12 +++++-------
>  1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/mm/slab.c b/mm/slab.c
> index 811af03..590d52a 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -1032,7 +1032,7 @@ static void *__ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac,
>  {
>         if (unlikely(pfmemalloc_active)) {
>                 /* Some pfmemalloc slabs exist, check if this is one */
> -               struct page *page = virt_to_page(objp);
> +               struct page *page = virt_to_head_page(objp);
>                 if (PageSlabPfmemalloc(page))
>                         set_obj_pfmemalloc(&objp);
>         }
> @@ -1919,12 +1919,10 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
>         else
>                 add_zone_page_state(page_zone(page),
>                         NR_SLAB_UNRECLAIMABLE, nr_pages);
> -       for (i = 0; i < nr_pages; i++) {
> +       for (i = 0; i < nr_pages; i++)
>                 __SetPageSlab(page + i);
> -
> -               if (page->pfmemalloc)
> -                       SetPageSlabPfmemalloc(page + i);
> -       }
> +       if (page->pfmemalloc)
> +               SetPageSlabPfmemalloc(page);
>
>         if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
>                 kmemcheck_alloc_shadow(page, cachep->gfporder, flags, nodeid);
> @@ -1955,9 +1953,9 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr)
>         else
>                 sub_zone_page_state(page_zone(page),
>                                 NR_SLAB_UNRECLAIMABLE, nr_freed);
> +       __ClearPageSlabPfmemalloc(page);
>         while (i--) {
>                 BUG_ON(!PageSlab(page));
> -               __ClearPageSlabPfmemalloc(page);
>                 __ClearPageSlab(page);
>                 page++;
>         }

Okay.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH net-next] net: rt_cache_flush() cleanup
From: David Miller @ 2012-09-07 21:23 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1347049631.1234.35.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 07 Sep 2012 22:27:11 +0200

> From: Eric Dumazet <edumazet@google.com>
> 
> We dont use jhash anymore since route cache removal,
> so we can get rid of get_random_bytes() calls for rt_genid
> changes.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied, thanks Eric.

^ permalink raw reply

* Re: [PATCH] netdev/phy: mdio-mux-mmioreg.c should include of_address.h
From: David Miller @ 2012-09-07 21:25 UTC (permalink / raw)
  To: timur; +Cc: linux-kernel, netdev, linux-next, sfr, rdunlap
In-Reply-To: <1347048592-22957-1-git-send-email-timur@freescale.com>

From: Timur Tabi <timur@freescale.com>
Date: Fri, 7 Sep 2012 15:09:52 -0500

> mdio-mux-mmioreg.c uses function of_address_to_resource(), which is defined
> in linux/of_address.h.  This fixes a compilation error:
> 
> drivers/net/phy/mdio-mux-mmioreg.c: In function 'mdio_mux_mmioreg_probe':
> drivers/net/phy/mdio-mux-mmioreg.c:83:2: error: implicit declaration of
> 	function 'of_address_to_resource'
> 
> Signed-off-by: Timur Tabi <timur@freescale.com>

Please provide "Reported-by: ..." tags to give credit to the problem
reporter, Randy Dunlap in this case.

^ permalink raw reply

* Re: [PATCH net-next] scm: Don't use struct ucred in NETLINK_CB and struct scm_cookie.
From: Eric W. Biederman @ 2012-09-07 21:25 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev, serge
In-Reply-To: <20120907.144151.1366430170552241987.davem@davemloft.net>

David Miller <davem@davemloft.net> writes:

> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Fri, 07 Sep 2012 17:07:26 +0200
>
>> Seems fine to me, but I am not sure why you kept NETLINK_CREDS()
>> defined/used once.
>
> There are two remaining users, kernel/audit.c and scsi netlink.

Good point.  I have a change to kernel/audit.c that removes the
usage.    I believe the scsi netlink usage is just plain bogus,
and it wants the netlink port identifier instead.

Would anyone mind if we changed the name of the field in netlink from
pid to portid?  It seems to cause a lot of confusion.  We can't change
the user space fields of course but...

Right now because we can now use current using NETLINK_CREDS in the
kernel is unnecessary.

Eric

^ permalink raw reply

* [PATCH][v2] netdev/phy: mdio-mux-mmioreg.c should include of_address.h
From: Timur Tabi @ 2012-09-07 21:30 UTC (permalink / raw)
  To: linux-kernel, netdev, linux-next, sfr, rdunlap

mdio-mux-mmioreg.c uses function of_address_to_resource(), which is defined
in linux/of_address.h.  This fixes a compilation error:

drivers/net/phy/mdio-mux-mmioreg.c: In function 'mdio_mux_mmioreg_probe':
drivers/net/phy/mdio-mux-mmioreg.c:83:2: error: implicit declaration of
	function 'of_address_to_resource'

Reported-by: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Timur Tabi <timur@freescale.com>

---
 drivers/net/phy/mdio-mux-mmioreg.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c
index 098239a..9061ba6 100644
--- a/drivers/net/phy/mdio-mux-mmioreg.c
+++ b/drivers/net/phy/mdio-mux-mmioreg.c
@@ -12,6 +12,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/device.h>
+#include <linux/of_address.h>
 #include <linux/of_mdio.h>
 #include <linux/module.h>
 #include <linux/init.h>
-- 
1.7.3.4

^ permalink raw reply related

* Re: [PATCH net-next] scm: Don't use struct ucred in NETLINK_CB and struct scm_cookie.
From: David Miller @ 2012-09-07 21:32 UTC (permalink / raw)
  To: ebiederm; +Cc: eric.dumazet, netdev, serge
In-Reply-To: <87627ple4q.fsf@xmission.com>

From: ebiederm@xmission.com (Eric W. Biederman)
Date: Fri, 07 Sep 2012 14:25:09 -0700

> Would anyone mind if we changed the name of the field in netlink from
> pid to portid?  It seems to cause a lot of confusion.  We can't change
> the user space fields of course but...

No objections.

^ permalink raw reply

* Re: [PATCH][v2] netdev/phy: mdio-mux-mmioreg.c should include of_address.h
From: David Miller @ 2012-09-07 21:32 UTC (permalink / raw)
  To: timur; +Cc: linux-kernel, netdev, linux-next, sfr, rdunlap
In-Reply-To: <1347053457-24935-1-git-send-email-timur@freescale.com>

From: Timur Tabi <timur@freescale.com>
Date: Fri, 7 Sep 2012 16:30:57 -0500

> mdio-mux-mmioreg.c uses function of_address_to_resource(), which is defined
> in linux/of_address.h.  This fixes a compilation error:
> 
> drivers/net/phy/mdio-mux-mmioreg.c: In function 'mdio_mux_mmioreg_probe':
> drivers/net/phy/mdio-mux-mmioreg.c:83:2: error: implicit declaration of
> 	function 'of_address_to_resource'
> 
> Reported-by: Randy Dunlap <rdunlap@xenotime.net>
> Signed-off-by: Timur Tabi <timur@freescale.com>

Applied, thanks.

^ permalink raw reply

* Endianess bug fix for sierra_net
From: Lennart Sorensen @ 2012-09-07 22:14 UTC (permalink / raw)
  To: linux-kernel; +Cc: Bjørn Mork, Len Sorensen, linux, netdev

I discovered I couldn't get sierra_net to work on a powerpc.  Turns out
the firmware attribute check assumes the system is little endian and
hence fails because the attributes is a 16 bit value.

Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>

diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index 7be49ea..8e22417 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
 		return -EIO;
 	}
 
-	*datap = *attrdata;
+	*datap = le16_to_cpu(*attrdata);
 
 	kfree(attrdata);
 	return result;

^ permalink raw reply related

* Re: Increased multicast packet drops in 3.4
From: Shawn Bohrer @ 2012-09-07 22:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1346998125.2484.220.camel@edumazet-glaptop>

On Fri, Sep 07, 2012 at 08:08:45AM +0200, Eric Dumazet wrote:
> On Thu, 2012-09-06 at 23:00 -0500, Shawn Bohrer wrote:
> > On Thu, Sep 06, 2012 at 03:21:07PM +0200, Eric Dumazet wrote:
> > > kfree_skb() can free a list of skb, and we use a generic function to do
> > > so, without forwarding the drop/notdrop status. So its unfortunate, but
> > > adding extra parameters just for the sake of drop_monitor is not worth
> > > it.  skb_drop_fraglist() doesnt know if the parent skb is dropped or
> > > only freed, so it calls kfree_skb(), not consume_skb() or kfree_skb()
> > 
> > I understand that this means that dropwatch or the skb:kfree_skb
> > tracepoint won't know if the packet was really dropped, but do we
> > know in this case from the context of the stack trace?  I'm assuming
> > since we didn't receive an error that the packet was delivered and
> > these aren't real drops.
> 
> I am starting to believe this is an application error.
> 
> This application uses recvmmsg() to fetch a lot of messages in one
> syscall, and it might well be it throws out a batch of 50+ messages
> because of an application bug. Yes, this starts with 3.4, but it can b
> triggered by a timing difference or something that is not a proper
> kernel bug...

Eric, you are absolutely correct.  There is at least one bug in the
application.  The code that re-orders out of order packets would give
up around the 50+ point and assume the packets in between were
dropped.  I did prove that if we keep reading from the socket we do
receive those packets.  So no packets are being dropped in the kernel.
I also proved I this is happening on 3.1 as well but 3.4 does trigger
it more often.

I'm still debugging the application because it appears I'm getting
very large batches of packets out of order.  It isn't clear to me if
this is another application bug, the kernel, the switch or something
else.

Thanks for all of your help looking into this (non)-issue.  If I have
further questions about the kernel side I'll let you know.

Thanks,
Shawn

-- 

---------------------------------------------------------------
This email, along with any attachments, is confidential. If you 
believe you received this message in error, please contact the 
sender immediately and delete all copies of the message.  
Thank you.

^ permalink raw reply

* [PATCH] scsi_netlink: Remove dead and buggy code
From: Eric W. Biederman @ 2012-09-07 22:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, James Bottomley, James Smart


The scsi netlink code confuses the netlink port id with a process id,
going so far as to read NETLINK_CREDS(skb)->pid instead of the correct
NETLINK_CB(skb).pid.  Fortunately it does not matter because nothing
registers to respond to scsi netlink requests.

The only interesting use of the scsi_netlink interface is
fc_host_post_vendor_event which sends a netlink multicast message.

Since nothing registers to handle scsi netlink messages kill all of the
registration logic, while retaining the same error handling behavior
preserving the userspace visible behavior and removing all of the
confused code that thought a netlink port id was a process id.

This was tested with a kernel allyesconfig build which had no problems.

Cc: James Bottomley <James.Bottomley@parallels.com>
Cc: James Smart <James.Smart@Emulex.Com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 drivers/scsi/scsi_netlink.c |  555 ++-----------------------------------------
 include/scsi/scsi_netlink.h |   24 --
 2 files changed, 15 insertions(+), 564 deletions(-)

diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index 8818dd6..abd43a3 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -33,40 +33,6 @@
 struct sock *scsi_nl_sock = NULL;
 EXPORT_SYMBOL_GPL(scsi_nl_sock);
 
-static DEFINE_SPINLOCK(scsi_nl_lock);
-static struct list_head scsi_nl_drivers;
-
-static u32	scsi_nl_state;
-#define STATE_EHANDLER_BSY		0x00000001
-
-struct scsi_nl_transport {
-	int (*msg_handler)(struct sk_buff *);
-	void (*event_handler)(struct notifier_block *, unsigned long, void *);
-	unsigned int refcnt;
-	int flags;
-};
-
-/* flags values (bit flags) */
-#define HANDLER_DELETING		0x1
-
-static struct scsi_nl_transport transports[SCSI_NL_MAX_TRANSPORTS] =
-	{ {NULL, }, };
-
-
-struct scsi_nl_drvr {
-	struct list_head next;
-	int (*dmsg_handler)(struct Scsi_Host *shost, void *payload,
-				 u32 len, u32 pid);
-	void (*devt_handler)(struct notifier_block *nb,
-				 unsigned long event, void *notify_ptr);
-	struct scsi_host_template *hostt;
-	u64 vendor_id;
-	unsigned int refcnt;
-	int flags;
-};
-
-
-
 /**
  * scsi_nl_rcv_msg - Receive message handler.
  * @skb:		socket receive buffer
@@ -81,7 +47,6 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
 {
 	struct nlmsghdr *nlh;
 	struct scsi_nl_hdr *hdr;
-	unsigned long flags;
 	u32 rlen;
 	int err, tport;
 
@@ -126,22 +91,24 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
 		/*
 		 * Deliver message to the appropriate transport
 		 */
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-
 		tport = hdr->transport;
-		if ((tport < SCSI_NL_MAX_TRANSPORTS) &&
-		    !(transports[tport].flags & HANDLER_DELETING) &&
-		    (transports[tport].msg_handler)) {
-			transports[tport].refcnt++;
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			err = transports[tport].msg_handler(skb);
-			spin_lock_irqsave(&scsi_nl_lock, flags);
-			transports[tport].refcnt--;
-		} else
+		if (tport == SCSI_NL_TRANSPORT) {
+			switch (hdr->msgtype) {
+			case SCSI_NL_SHOST_VENDOR:
+				/* Locate the driver that corresponds to the message */
+				err = -ESRCH;
+				break;
+			default:
+				err = -EBADR;
+				break;
+			}
+			if (err)
+				printk(KERN_WARNING "%s: Msgtype %d failed - err %d\n",
+				       __func__, hdr->msgtype, err);
+		}
+		else
 			err = -ENOENT;
 
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
 next_msg:
 		if ((err) || (nlh->nlmsg_flags & NLM_F_ACK))
 			netlink_ack(skb, nlh, err);
@@ -150,333 +117,6 @@ next_msg:
 	}
 }
 
-
-/**
- * scsi_nl_rcv_event - Event handler for a netlink socket.
- * @this:		event notifier block
- * @event:		event type
- * @ptr:		event payload
- *
- **/
-static int
-scsi_nl_rcv_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct netlink_notify *n = ptr;
-	struct scsi_nl_drvr *driver;
-	unsigned long flags;
-	int tport;
-
-	if (n->protocol != NETLINK_SCSITRANSPORT)
-		return NOTIFY_DONE;
-
-	spin_lock_irqsave(&scsi_nl_lock, flags);
-	scsi_nl_state |= STATE_EHANDLER_BSY;
-
-	/*
-	 * Pass event on to any transports that may be listening
-	 */
-	for (tport = 0; tport < SCSI_NL_MAX_TRANSPORTS; tport++) {
-		if (!(transports[tport].flags & HANDLER_DELETING) &&
-		    (transports[tport].event_handler)) {
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			transports[tport].event_handler(this, event, ptr);
-			spin_lock_irqsave(&scsi_nl_lock, flags);
-		}
-	}
-
-	/*
-	 * Pass event on to any drivers that may be listening
-	 */
-	list_for_each_entry(driver, &scsi_nl_drivers, next) {
-		if (!(driver->flags & HANDLER_DELETING) &&
-		    (driver->devt_handler)) {
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			driver->devt_handler(this, event, ptr);
-			spin_lock_irqsave(&scsi_nl_lock, flags);
-		}
-	}
-
-	scsi_nl_state &= ~STATE_EHANDLER_BSY;
-	spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block scsi_netlink_notifier = {
-	.notifier_call  = scsi_nl_rcv_event,
-};
-
-
-/*
- * GENERIC SCSI transport receive and event handlers
- */
-
-/**
- * scsi_generic_msg_handler - receive message handler for GENERIC transport messages
- * @skb:		socket receive buffer
- **/
-static int
-scsi_generic_msg_handler(struct sk_buff *skb)
-{
-	struct nlmsghdr *nlh = nlmsg_hdr(skb);
-	struct scsi_nl_hdr *snlh = NLMSG_DATA(nlh);
-	struct scsi_nl_drvr *driver;
-	struct Scsi_Host *shost;
-	unsigned long flags;
-	int err = 0, match, pid;
-
-	pid = NETLINK_CREDS(skb)->pid;
-
-	switch (snlh->msgtype) {
-	case SCSI_NL_SHOST_VENDOR:
-		{
-		struct scsi_nl_host_vendor_msg *msg = NLMSG_DATA(nlh);
-
-		/* Locate the driver that corresponds to the message */
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-		match = 0;
-		list_for_each_entry(driver, &scsi_nl_drivers, next) {
-			if (driver->vendor_id == msg->vendor_id) {
-				match = 1;
-				break;
-			}
-		}
-
-		if ((!match) || (!driver->dmsg_handler)) {
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			err = -ESRCH;
-			goto rcv_exit;
-		}
-
-		if (driver->flags & HANDLER_DELETING) {
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			err = -ESHUTDOWN;
-			goto rcv_exit;
-		}
-
-		driver->refcnt++;
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
-
-		/* if successful, scsi_host_lookup takes a shost reference */
-		shost = scsi_host_lookup(msg->host_no);
-		if (!shost) {
-			err = -ENODEV;
-			goto driver_exit;
-		}
-
-		/* is this host owned by the vendor ? */
-		if (shost->hostt != driver->hostt) {
-			err = -EINVAL;
-			goto vendormsg_put;
-		}
-
-		/* pass message on to the driver */
-		err = driver->dmsg_handler(shost, (void *)&msg[1],
-					 msg->vmsg_datalen, pid);
-
-vendormsg_put:
-		/* release reference by scsi_host_lookup */
-		scsi_host_put(shost);
-
-driver_exit:
-		/* release our own reference on the registration object */
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-		driver->refcnt--;
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-		break;
-		}
-
-	default:
-		err = -EBADR;
-		break;
-	}
-
-rcv_exit:
-	if (err)
-		printk(KERN_WARNING "%s: Msgtype %d failed - err %d\n",
-			 __func__, snlh->msgtype, err);
-	return err;
-}
-
-
-/**
- * scsi_nl_add_transport -
- *    Registers message and event handlers for a transport. Enables
- *    receipt of netlink messages and events to a transport.
- *
- * @tport:		transport registering handlers
- * @msg_handler:	receive message handler callback
- * @event_handler:	receive event handler callback
- **/
-int
-scsi_nl_add_transport(u8 tport,
-	int (*msg_handler)(struct sk_buff *),
-	void (*event_handler)(struct notifier_block *, unsigned long, void *))
-{
-	unsigned long flags;
-	int err = 0;
-
-	if (tport >= SCSI_NL_MAX_TRANSPORTS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&scsi_nl_lock, flags);
-
-	if (scsi_nl_state & STATE_EHANDLER_BSY) {
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-		msleep(1);
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-	}
-
-	if (transports[tport].msg_handler || transports[tport].event_handler) {
-		err = -EALREADY;
-		goto register_out;
-	}
-
-	transports[tport].msg_handler = msg_handler;
-	transports[tport].event_handler = event_handler;
-	transports[tport].flags = 0;
-	transports[tport].refcnt = 0;
-
-register_out:
-	spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
-	return err;
-}
-EXPORT_SYMBOL_GPL(scsi_nl_add_transport);
-
-
-/**
- * scsi_nl_remove_transport -
- *    Disable transport receiption of messages and events
- *
- * @tport:		transport deregistering handlers
- *
- **/
-void
-scsi_nl_remove_transport(u8 tport)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&scsi_nl_lock, flags);
-	if (scsi_nl_state & STATE_EHANDLER_BSY) {
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-		msleep(1);
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-	}
-
-	if (tport < SCSI_NL_MAX_TRANSPORTS) {
-		transports[tport].flags |= HANDLER_DELETING;
-
-		while (transports[tport].refcnt != 0) {
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			schedule_timeout_uninterruptible(HZ/4);
-			spin_lock_irqsave(&scsi_nl_lock, flags);
-		}
-		transports[tport].msg_handler = NULL;
-		transports[tport].event_handler = NULL;
-		transports[tport].flags = 0;
-	}
-
-	spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
-	return;
-}
-EXPORT_SYMBOL_GPL(scsi_nl_remove_transport);
-
-
-/**
- * scsi_nl_add_driver -
- *    A driver is registering its interfaces for SCSI netlink messages
- *
- * @vendor_id:          A unique identification value for the driver.
- * @hostt:		address of the driver's host template. Used
- *			to verify an shost is bound to the driver
- * @nlmsg_handler:	receive message handler callback
- * @nlevt_handler:	receive event handler callback
- *
- * Returns:
- *   0 on Success
- *   error result otherwise
- **/
-int
-scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt,
-	int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload,
-				 u32 len, u32 pid),
-	void (*nlevt_handler)(struct notifier_block *nb,
-				 unsigned long event, void *notify_ptr))
-{
-	struct scsi_nl_drvr *driver;
-	unsigned long flags;
-
-	driver = kzalloc(sizeof(*driver), GFP_KERNEL);
-	if (unlikely(!driver)) {
-		printk(KERN_ERR "%s: allocation failure\n", __func__);
-		return -ENOMEM;
-	}
-
-	driver->dmsg_handler = nlmsg_handler;
-	driver->devt_handler = nlevt_handler;
-	driver->hostt = hostt;
-	driver->vendor_id = vendor_id;
-
-	spin_lock_irqsave(&scsi_nl_lock, flags);
-	if (scsi_nl_state & STATE_EHANDLER_BSY) {
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-		msleep(1);
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-	}
-	list_add_tail(&driver->next, &scsi_nl_drivers);
-	spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(scsi_nl_add_driver);
-
-
-/**
- * scsi_nl_remove_driver -
- *    An driver is unregistering with the SCSI netlink messages
- *
- * @vendor_id:          The unique identification value for the driver.
- **/
-void
-scsi_nl_remove_driver(u64 vendor_id)
-{
-	struct scsi_nl_drvr *driver;
-	unsigned long flags;
-
-	spin_lock_irqsave(&scsi_nl_lock, flags);
-	if (scsi_nl_state & STATE_EHANDLER_BSY) {
-		spin_unlock_irqrestore(&scsi_nl_lock, flags);
-		msleep(1);
-		spin_lock_irqsave(&scsi_nl_lock, flags);
-	}
-
-	list_for_each_entry(driver, &scsi_nl_drivers, next) {
-		if (driver->vendor_id == vendor_id) {
-			driver->flags |= HANDLER_DELETING;
-			while (driver->refcnt != 0) {
-				spin_unlock_irqrestore(&scsi_nl_lock, flags);
-				schedule_timeout_uninterruptible(HZ/4);
-				spin_lock_irqsave(&scsi_nl_lock, flags);
-			}
-			list_del(&driver->next);
-			kfree(driver);
-			spin_unlock_irqrestore(&scsi_nl_lock, flags);
-			return;
-		}
-	}
-
-	spin_unlock_irqrestore(&scsi_nl_lock, flags);
-
-	printk(KERN_ERR "%s: removal of driver failed - vendor_id 0x%llx\n",
-	       __func__, (unsigned long long)vendor_id);
-	return;
-}
-EXPORT_SYMBOL_GPL(scsi_nl_remove_driver);
-
-
 /**
  * scsi_netlink_init - Called by SCSI subsystem to initialize
  * 	the SCSI transport netlink interface
@@ -485,36 +125,19 @@ EXPORT_SYMBOL_GPL(scsi_nl_remove_driver);
 void
 scsi_netlink_init(void)
 {
-	int error;
 	struct netlink_kernel_cfg cfg = {
 		.input	= scsi_nl_rcv_msg,
 		.groups	= SCSI_NL_GRP_CNT,
 	};
 
-	INIT_LIST_HEAD(&scsi_nl_drivers);
-
-	error = netlink_register_notifier(&scsi_netlink_notifier);
-	if (error) {
-		printk(KERN_ERR "%s: register of event handler failed - %d\n",
-				__func__, error);
-		return;
-	}
-
 	scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
 					     THIS_MODULE, &cfg);
 	if (!scsi_nl_sock) {
 		printk(KERN_ERR "%s: register of receive handler failed\n",
 				__func__);
-		netlink_unregister_notifier(&scsi_netlink_notifier);
 		return;
 	}
 
-	/* Register the entry points for the generic SCSI transport */
-	error = scsi_nl_add_transport(SCSI_NL_TRANSPORT,
-				scsi_generic_msg_handler, NULL);
-	if (error)
-		printk(KERN_ERR "%s: register of GENERIC transport handler"
-				"  failed - %d\n", __func__, error);
 	return;
 }
 
@@ -526,158 +149,10 @@ scsi_netlink_init(void)
 void
 scsi_netlink_exit(void)
 {
-	scsi_nl_remove_transport(SCSI_NL_TRANSPORT);
-
 	if (scsi_nl_sock) {
 		netlink_kernel_release(scsi_nl_sock);
-		netlink_unregister_notifier(&scsi_netlink_notifier);
 	}
 
 	return;
 }
 
-
-/*
- * Exported Interfaces
- */
-
-/**
- * scsi_nl_send_transport_msg -
- *    Generic function to send a single message from a SCSI transport to
- *    a single process
- *
- * @pid:		receiving pid
- * @hdr:		message payload
- *
- **/
-void
-scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr)
-{
-	struct sk_buff *skb;
-	struct nlmsghdr	*nlh;
-	const char *fn;
-	char *datab;
-	u32 len, skblen;
-	int err;
-
-	if (!scsi_nl_sock) {
-		err = -ENOENT;
-		fn = "netlink socket";
-		goto msg_fail;
-	}
-
-	len = NLMSG_SPACE(hdr->msglen);
-	skblen = NLMSG_SPACE(len);
-
-	skb = alloc_skb(skblen, GFP_KERNEL);
-	if (!skb) {
-		err = -ENOBUFS;
-		fn = "alloc_skb";
-		goto msg_fail;
-	}
-
-	nlh = nlmsg_put(skb, pid, 0, SCSI_TRANSPORT_MSG, len - sizeof(*nlh), 0);
-	if (!nlh) {
-		err = -ENOBUFS;
-		fn = "nlmsg_put";
-		goto msg_fail_skb;
-	}
-	datab = NLMSG_DATA(nlh);
-	memcpy(datab, hdr, hdr->msglen);
-
-	err = nlmsg_unicast(scsi_nl_sock, skb, pid);
-	if (err < 0) {
-		fn = "nlmsg_unicast";
-		/* nlmsg_unicast already kfree_skb'd */
-		goto msg_fail;
-	}
-
-	return;
-
-msg_fail_skb:
-	kfree_skb(skb);
-msg_fail:
-	printk(KERN_WARNING
-		"%s: Dropped Message : pid %d Transport %d, msgtype x%x, "
-		"msglen %d: %s : err %d\n",
-		__func__, pid, hdr->transport, hdr->msgtype, hdr->msglen,
-		fn, err);
-	return;
-}
-EXPORT_SYMBOL_GPL(scsi_nl_send_transport_msg);
-
-
-/**
- * scsi_nl_send_vendor_msg - called to send a shost vendor unique message
- *                      to a specific process id.
- *
- * @pid:		process id of the receiver
- * @host_no:		host # sending the message
- * @vendor_id:		unique identifier for the driver's vendor
- * @data_len:		amount, in bytes, of vendor unique payload data
- * @data_buf:		pointer to vendor unique data buffer
- *
- * Returns:
- *   0 on successful return
- *   otherwise, failing error code
- *
- * Notes:
- *	This routine assumes no locks are held on entry.
- */
-int
-scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id,
-			 char *data_buf, u32 data_len)
-{
-	struct sk_buff *skb;
-	struct nlmsghdr	*nlh;
-	struct scsi_nl_host_vendor_msg *msg;
-	u32 len, skblen;
-	int err;
-
-	if (!scsi_nl_sock) {
-		err = -ENOENT;
-		goto send_vendor_fail;
-	}
-
-	len = SCSI_NL_MSGALIGN(sizeof(*msg) + data_len);
-	skblen = NLMSG_SPACE(len);
-
-	skb = alloc_skb(skblen, GFP_KERNEL);
-	if (!skb) {
-		err = -ENOBUFS;
-		goto send_vendor_fail;
-	}
-
-	nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
-				skblen - sizeof(*nlh), 0);
-	if (!nlh) {
-		err = -ENOBUFS;
-		goto send_vendor_fail_skb;
-	}
-	msg = NLMSG_DATA(nlh);
-
-	INIT_SCSI_NL_HDR(&msg->snlh, SCSI_NL_TRANSPORT,
-				SCSI_NL_SHOST_VENDOR, len);
-	msg->vendor_id = vendor_id;
-	msg->host_no = host_no;
-	msg->vmsg_datalen = data_len;	/* bytes */
-	memcpy(&msg[1], data_buf, data_len);
-
-	err = nlmsg_unicast(scsi_nl_sock, skb, pid);
-	if (err)
-		/* nlmsg_multicast already kfree_skb'd */
-		goto send_vendor_fail;
-
-	return 0;
-
-send_vendor_fail_skb:
-	kfree_skb(skb);
-send_vendor_fail:
-	printk(KERN_WARNING
-		"%s: Dropped SCSI Msg : host %d vendor_unique - err %d\n",
-		__func__, host_no, err);
-	return err;
-}
-EXPORT_SYMBOL(scsi_nl_send_vendor_msg);
-
-
diff --git a/include/scsi/scsi_netlink.h b/include/scsi/scsi_netlink.h
index 5cb20cc..62b4eda 100644
--- a/include/scsi/scsi_netlink.h
+++ b/include/scsi/scsi_netlink.h
@@ -119,29 +119,5 @@ struct scsi_nl_host_vendor_msg {
 	(hdr)->msglen = mlen;					\
 	}
 
-
-#ifdef __KERNEL__
-
-#include <scsi/scsi_host.h>
-
-/* Exported Kernel Interfaces */
-int scsi_nl_add_transport(u8 tport,
-	 int (*msg_handler)(struct sk_buff *),
-	void (*event_handler)(struct notifier_block *, unsigned long, void *));
-void scsi_nl_remove_transport(u8 tport);
-
-int scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt,
-	int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload,
-				 u32 len, u32 pid),
-	void (*nlevt_handler)(struct notifier_block *nb,
-				 unsigned long event, void *notify_ptr));
-void scsi_nl_remove_driver(u64 vendor_id);
-
-void scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr);
-int scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id,
-			 char *data_buf, u32 data_len);
-
-#endif /* __KERNEL__ */
-
 #endif /* SCSI_NETLINK_H */
 
-- 
1.7.5.4

^ permalink raw reply related

* Re: [PATCH 0/4] PCI error handler const
From: Bjorn Helgaas @ 2012-09-07 22:42 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Linas Vepstas, linux-pci, David Miller, netdev, linux-scsi,
	linux-kernel, James Bottomley
In-Reply-To: <20120907163313.614852012@vyatta.com>

On Fri, Sep 7, 2012 at 9:33 AM, Stephen Hemminger <shemminger@vyatta.com> wrote:
> This is a trivial patch to make PCI error handler function
> tables const. Split into pieces so that core changes are first.

I put all four of these on this branch:

http://git.kernel.org/?p=linux/kernel/git/helgaas/pci.git;a=shortlog;h=refs/heads/pci/stephen-const

If the netdev and scsi folks approve, I can handle them all through my PCI tree.

Bjorn

^ permalink raw reply

* [PATCH 04/12] qlcnic: remove 82xx specific register dump utility
From: Sony Chacko @ 2012-09-07 23:01 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sony Chacko
In-Reply-To: <1347058893-30165-1-git-send-email-sony.chacko@qlogic.com>

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

Modify 82xx driver to support new adapter - Qlogic 83XX CNA
Remove 82xx specific register dump utility

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c  |  107 +-----
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c   |  466 ----------------------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c   |   21 -
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |    4 -
 4 files changed, 1 insertions(+), 597 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index 4e57edb..12c45bf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -103,91 +103,6 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd)
 
 }
 
-static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u16 temp_size)
-{
-	uint64_t sum = 0;
-	int count = temp_size / sizeof(uint32_t);
-	while (count-- > 0)
-		sum += *temp_buffer++;
-	while (sum >> 32)
-		sum = (sum & 0xFFFFFFFF) + (sum >> 32);
-	return ~sum;
-}
-
-int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
-{
-	int err, i;
-	u16 temp_size;
-	void *tmp_addr;
-	u32 version, csum, *template, *tmp_buf;
-	struct qlcnic_cmd_args cmd;
-	struct qlcnic_hardware_context *ahw;
-	struct qlcnic_dump_template_hdr *tmpl_hdr, *tmp_tmpl;
-	dma_addr_t tmp_addr_t = 0;
-
-	ahw = adapter->ahw;
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.req.cmd = QLCNIC_CDRP_CMD_TEMP_SIZE;
-	memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd));
-	qlcnic_issue_cmd(adapter, &cmd);
-	if (cmd.rsp.cmd != QLCNIC_RCODE_SUCCESS) {
-		dev_info(&adapter->pdev->dev,
-			"Can't get template size %d\n", cmd.rsp.cmd);
-		err = -EIO;
-		return err;
-	}
-	temp_size = cmd.rsp.arg2;
-	version = cmd.rsp.arg3;
-	if (!temp_size)
-		return -EIO;
-
-	tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, temp_size,
-			&tmp_addr_t, GFP_KERNEL);
-	if (!tmp_addr) {
-		dev_err(&adapter->pdev->dev,
-			"Can't get memory for FW dump template\n");
-		return -ENOMEM;
-	}
-	memset(&cmd.rsp, 0, sizeof(struct _cdrp_cmd));
-	cmd.req.cmd = QLCNIC_CDRP_CMD_GET_TEMP_HDR;
-	cmd.req.arg1 = LSD(tmp_addr_t);
-	cmd.req.arg2 = MSD(tmp_addr_t);
-	cmd.req.arg3 = temp_size;
-	qlcnic_issue_cmd(adapter, &cmd);
-
-	err = cmd.rsp.cmd;
-	if (err != QLCNIC_RCODE_SUCCESS) {
-		dev_err(&adapter->pdev->dev,
-			"Failed to get mini dump template header %d\n", err);
-		err = -EIO;
-		goto error;
-	}
-	tmp_tmpl = tmp_addr;
-	csum = qlcnic_temp_checksum((uint32_t *) tmp_addr, temp_size);
-	if (csum) {
-		dev_err(&adapter->pdev->dev,
-			"Template header checksum validation failed\n");
-		err = -EIO;
-		goto error;
-	}
-	ahw->fw_dump.tmpl_hdr = vzalloc(temp_size);
-	if (!ahw->fw_dump.tmpl_hdr) {
-		err = -EIO;
-		goto error;
-	}
-	tmp_buf = tmp_addr;
-	template = (u32 *) ahw->fw_dump.tmpl_hdr;
-	for (i = 0; i < temp_size/sizeof(u32); i++)
-		*template++ = __le32_to_cpu(*tmp_buf++);
-
-	tmpl_hdr = ahw->fw_dump.tmpl_hdr;
-	tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
-	ahw->fw_dump.enable = 1;
-error:
-	dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t);
-	return err;
-}
-
 int
 qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
 {
@@ -714,27 +629,7 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
 	qlcnic_issue_cmd(adapter, &cmd);
 	err = cmd.rsp.cmd;
 
-	if (err == QLCNIC_RCODE_SUCCESS) {
-		npar_info->pci_func = le16_to_cpu(nic_info->pci_func);
-		npar_info->op_mode = le16_to_cpu(nic_info->op_mode);
-		npar_info->phys_port = le16_to_cpu(nic_info->phys_port);
-		npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode);
-		npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
-		npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
-		npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw);
-		npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw);
-		npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
-		npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
-
-		dev_info(&adapter->pdev->dev,
-			"phy port: %d switch_mode: %d,\n"
-			"\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n"
-			"\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n",
-			npar_info->phys_port, npar_info->switch_mode,
-			npar_info->max_tx_ques, npar_info->max_rx_ques,
-			npar_info->min_tx_bw, npar_info->max_tx_bw,
-			npar_info->max_mtu, npar_info->capabilities);
-	} else {
+	if (err) {
 		dev_err(&adapter->pdev->dev,
 			"Failed to get nic info%d\n", err);
 		err = -EIO;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index f31022a..6ef5e0e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -1366,472 +1366,6 @@ int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
 	return rv;
 }
 
-/* FW dump related functions */
-static u32
-qlcnic_dump_crb(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
-		u32 *buffer)
-{
-	int i;
-	u32 addr, data;
-	struct __crb *crb = &entry->region.crb;
-	void __iomem *base = adapter->ahw->pci_base0;
-
-	addr = crb->addr;
-
-	for (i = 0; i < crb->no_ops; i++) {
-		QLCNIC_RD_DUMP_REG(addr, base, &data);
-		*buffer++ = cpu_to_le32(addr);
-		*buffer++ = cpu_to_le32(data);
-		addr += crb->stride;
-	}
-	return crb->no_ops * 2 * sizeof(u32);
-}
-
-static u32
-qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
-	struct qlcnic_dump_entry *entry, u32 *buffer)
-{
-	int i, k, timeout = 0;
-	void __iomem *base = adapter->ahw->pci_base0;
-	u32 addr, data;
-	u8 opcode, no_ops;
-	struct __ctrl *ctr = &entry->region.ctrl;
-	struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
-
-	addr = ctr->addr;
-	no_ops = ctr->no_ops;
-
-	for (i = 0; i < no_ops; i++) {
-		k = 0;
-		opcode = 0;
-		for (k = 0; k < 8; k++) {
-			if (!(ctr->opcode & (1 << k)))
-				continue;
-			switch (1 << k) {
-			case QLCNIC_DUMP_WCRB:
-				QLCNIC_WR_DUMP_REG(addr, base, ctr->val1);
-				break;
-			case QLCNIC_DUMP_RWCRB:
-				QLCNIC_RD_DUMP_REG(addr, base, &data);
-				QLCNIC_WR_DUMP_REG(addr, base, data);
-				break;
-			case QLCNIC_DUMP_ANDCRB:
-				QLCNIC_RD_DUMP_REG(addr, base, &data);
-				QLCNIC_WR_DUMP_REG(addr, base,
-					(data & ctr->val2));
-				break;
-			case QLCNIC_DUMP_ORCRB:
-				QLCNIC_RD_DUMP_REG(addr, base, &data);
-				QLCNIC_WR_DUMP_REG(addr, base,
-					(data | ctr->val3));
-				break;
-			case QLCNIC_DUMP_POLLCRB:
-				while (timeout <= ctr->timeout) {
-					QLCNIC_RD_DUMP_REG(addr, base, &data);
-					if ((data & ctr->val2) == ctr->val1)
-						break;
-					msleep(1);
-					timeout++;
-				}
-				if (timeout > ctr->timeout) {
-					dev_info(&adapter->pdev->dev,
-					"Timed out, aborting poll CRB\n");
-					return -EINVAL;
-				}
-				break;
-			case QLCNIC_DUMP_RD_SAVE:
-				if (ctr->index_a)
-					addr = t_hdr->saved_state[ctr->index_a];
-				QLCNIC_RD_DUMP_REG(addr, base, &data);
-				t_hdr->saved_state[ctr->index_v] = data;
-				break;
-			case QLCNIC_DUMP_WRT_SAVED:
-				if (ctr->index_v)
-					data = t_hdr->saved_state[ctr->index_v];
-				else
-					data = ctr->val1;
-				if (ctr->index_a)
-					addr = t_hdr->saved_state[ctr->index_a];
-				QLCNIC_WR_DUMP_REG(addr, base, data);
-				break;
-			case QLCNIC_DUMP_MOD_SAVE_ST:
-				data = t_hdr->saved_state[ctr->index_v];
-				data <<= ctr->shl_val;
-				data >>= ctr->shr_val;
-				if (ctr->val2)
-					data &= ctr->val2;
-				data |= ctr->val3;
-				data += ctr->val1;
-				t_hdr->saved_state[ctr->index_v] = data;
-				break;
-			default:
-				dev_info(&adapter->pdev->dev,
-					"Unknown opcode\n");
-				break;
-			}
-		}
-		addr += ctr->stride;
-	}
-	return 0;
-}
-
-static u32
-qlcnic_dump_mux(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
-	u32 *buffer)
-{
-	int loop;
-	u32 val, data = 0;
-	struct __mux *mux = &entry->region.mux;
-	void __iomem *base = adapter->ahw->pci_base0;
-
-	val = mux->val;
-	for (loop = 0; loop < mux->no_ops; loop++) {
-		QLCNIC_WR_DUMP_REG(mux->addr, base, val);
-		QLCNIC_RD_DUMP_REG(mux->read_addr, base, &data);
-		*buffer++ = cpu_to_le32(val);
-		*buffer++ = cpu_to_le32(data);
-		val += mux->val_stride;
-	}
-	return 2 * mux->no_ops * sizeof(u32);
-}
-
-static u32
-qlcnic_dump_que(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
-	u32 *buffer)
-{
-	int i, loop;
-	u32 cnt, addr, data, que_id = 0;
-	void __iomem *base = adapter->ahw->pci_base0;
-	struct __queue *que = &entry->region.que;
-
-	addr = que->read_addr;
-	cnt = que->read_addr_cnt;
-
-	for (loop = 0; loop < que->no_ops; loop++) {
-		QLCNIC_WR_DUMP_REG(que->sel_addr, base, que_id);
-		addr = que->read_addr;
-		for (i = 0; i < cnt; i++) {
-			QLCNIC_RD_DUMP_REG(addr, base, &data);
-			*buffer++ = cpu_to_le32(data);
-			addr += que->read_addr_stride;
-		}
-		que_id += que->stride;
-	}
-	return que->no_ops * cnt * sizeof(u32);
-}
-
-static u32
-qlcnic_dump_ocm(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
-	u32 *buffer)
-{
-	int i;
-	u32 data;
-	void __iomem *addr;
-	struct __ocm *ocm = &entry->region.ocm;
-
-	addr = adapter->ahw->pci_base0 + ocm->read_addr;
-	for (i = 0; i < ocm->no_ops; i++) {
-		data = readl(addr);
-		*buffer++ = cpu_to_le32(data);
-		addr += ocm->read_addr_stride;
-	}
-	return ocm->no_ops * sizeof(u32);
-}
-
-static u32
-qlcnic_read_rom(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
-	u32 *buffer)
-{
-	int i, count = 0;
-	u32 fl_addr, size, val, lck_val, addr;
-	struct __mem *rom = &entry->region.mem;
-	void __iomem *base = adapter->ahw->pci_base0;
-
-	fl_addr = rom->addr;
-	size = rom->size/4;
-lock_try:
-	lck_val = readl(base + QLCNIC_FLASH_SEM2_LK);
-	if (!lck_val && count < MAX_CTL_CHECK) {
-		msleep(10);
-		count++;
-		goto lock_try;
-	}
-	writel(adapter->ahw->pci_func, (base + QLCNIC_FLASH_LOCK_ID));
-	for (i = 0; i < size; i++) {
-		addr = fl_addr & 0xFFFF0000;
-		QLCNIC_WR_DUMP_REG(FLASH_ROM_WINDOW, base, addr);
-		addr = LSW(fl_addr) + FLASH_ROM_DATA;
-		QLCNIC_RD_DUMP_REG(addr, base, &val);
-		fl_addr += 4;
-		*buffer++ = cpu_to_le32(val);
-	}
-	readl(base + QLCNIC_FLASH_SEM2_ULK);
-	return rom->size;
-}
-
-static u32
-qlcnic_dump_l1_cache(struct qlcnic_adapter *adapter,
-	struct qlcnic_dump_entry *entry, u32 *buffer)
-{
-	int i;
-	u32 cnt, val, data, addr;
-	void __iomem *base = adapter->ahw->pci_base0;
-	struct __cache *l1 = &entry->region.cache;
-
-	val = l1->init_tag_val;
-
-	for (i = 0; i < l1->no_ops; i++) {
-		QLCNIC_WR_DUMP_REG(l1->addr, base, val);
-		QLCNIC_WR_DUMP_REG(l1->ctrl_addr, base, LSW(l1->ctrl_val));
-		addr = l1->read_addr;
-		cnt = l1->read_addr_num;
-		while (cnt) {
-			QLCNIC_RD_DUMP_REG(addr, base, &data);
-			*buffer++ = cpu_to_le32(data);
-			addr += l1->read_addr_stride;
-			cnt--;
-		}
-		val += l1->stride;
-	}
-	return l1->no_ops * l1->read_addr_num * sizeof(u32);
-}
-
-static u32
-qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
-	struct qlcnic_dump_entry *entry, u32 *buffer)
-{
-	int i;
-	u32 cnt, val, data, addr;
-	u8 poll_mask, poll_to, time_out = 0;
-	void __iomem *base = adapter->ahw->pci_base0;
-	struct __cache *l2 = &entry->region.cache;
-
-	val = l2->init_tag_val;
-	poll_mask = LSB(MSW(l2->ctrl_val));
-	poll_to = MSB(MSW(l2->ctrl_val));
-
-	for (i = 0; i < l2->no_ops; i++) {
-		QLCNIC_WR_DUMP_REG(l2->addr, base, val);
-		if (LSW(l2->ctrl_val))
-			QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base,
-				LSW(l2->ctrl_val));
-		if (!poll_mask)
-			goto skip_poll;
-		do {
-			QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data);
-			if (!(data & poll_mask))
-				break;
-			msleep(1);
-			time_out++;
-		} while (time_out <= poll_to);
-
-		if (time_out > poll_to) {
-			dev_err(&adapter->pdev->dev,
-				"Timeout exceeded in %s, aborting dump\n",
-				__func__);
-			return -EINVAL;
-		}
-skip_poll:
-		addr = l2->read_addr;
-		cnt = l2->read_addr_num;
-		while (cnt) {
-			QLCNIC_RD_DUMP_REG(addr, base, &data);
-			*buffer++ = cpu_to_le32(data);
-			addr += l2->read_addr_stride;
-			cnt--;
-		}
-		val += l2->stride;
-	}
-	return l2->no_ops * l2->read_addr_num * sizeof(u32);
-}
-
-static u32
-qlcnic_read_memory(struct qlcnic_adapter *adapter,
-	struct qlcnic_dump_entry *entry, u32 *buffer)
-{
-	u32 addr, data, test, ret = 0;
-	int i, reg_read;
-	struct __mem *mem = &entry->region.mem;
-	void __iomem *base = adapter->ahw->pci_base0;
-
-	reg_read = mem->size;
-	addr = mem->addr;
-	/* check for data size of multiple of 16 and 16 byte alignment */
-	if ((addr & 0xf) || (reg_read%16)) {
-		dev_info(&adapter->pdev->dev,
-			"Unaligned memory addr:0x%x size:0x%x\n",
-			addr, reg_read);
-		return -EINVAL;
-	}
-
-	mutex_lock(&adapter->ahw->mem_lock);
-
-	while (reg_read != 0) {
-		QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_LO, base, addr);
-		QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_HI, base, 0);
-		QLCNIC_WR_DUMP_REG(MIU_TEST_CTR, base,
-			TA_CTL_ENABLE | TA_CTL_START);
-
-		for (i = 0; i < MAX_CTL_CHECK; i++) {
-			QLCNIC_RD_DUMP_REG(MIU_TEST_CTR, base, &test);
-			if (!(test & TA_CTL_BUSY))
-				break;
-		}
-		if (i == MAX_CTL_CHECK) {
-			if (printk_ratelimit()) {
-				dev_err(&adapter->pdev->dev,
-					"failed to read through agent\n");
-				ret = -EINVAL;
-				goto out;
-			}
-		}
-		for (i = 0; i < 4; i++) {
-			QLCNIC_RD_DUMP_REG(MIU_TEST_READ_DATA[i], base, &data);
-			*buffer++ = cpu_to_le32(data);
-		}
-		addr += 16;
-		reg_read -= 16;
-		ret += 16;
-	}
-out:
-	mutex_unlock(&adapter->ahw->mem_lock);
-	return mem->size;
-}
-
-static u32
-qlcnic_dump_nop(struct qlcnic_adapter *adapter,
-	struct qlcnic_dump_entry *entry, u32 *buffer)
-{
-	entry->hdr.flags |= QLCNIC_DUMP_SKIP;
-	return 0;
-}
-
-struct qlcnic_dump_operations fw_dump_ops[] = {
-	{ QLCNIC_DUMP_NOP, qlcnic_dump_nop },
-	{ QLCNIC_DUMP_READ_CRB, qlcnic_dump_crb },
-	{ QLCNIC_DUMP_READ_MUX, qlcnic_dump_mux },
-	{ QLCNIC_DUMP_QUEUE, qlcnic_dump_que },
-	{ QLCNIC_DUMP_BRD_CONFIG, qlcnic_read_rom },
-	{ QLCNIC_DUMP_READ_OCM, qlcnic_dump_ocm },
-	{ QLCNIC_DUMP_PEG_REG, qlcnic_dump_ctrl },
-	{ QLCNIC_DUMP_L1_DTAG, qlcnic_dump_l1_cache },
-	{ QLCNIC_DUMP_L1_ITAG, qlcnic_dump_l1_cache },
-	{ QLCNIC_DUMP_L1_DATA, qlcnic_dump_l1_cache },
-	{ QLCNIC_DUMP_L1_INST, qlcnic_dump_l1_cache },
-	{ QLCNIC_DUMP_L2_DTAG, qlcnic_dump_l2_cache },
-	{ QLCNIC_DUMP_L2_ITAG, qlcnic_dump_l2_cache },
-	{ QLCNIC_DUMP_L2_DATA, qlcnic_dump_l2_cache },
-	{ QLCNIC_DUMP_L2_INST, qlcnic_dump_l2_cache },
-	{ QLCNIC_DUMP_READ_ROM, qlcnic_read_rom },
-	{ QLCNIC_DUMP_READ_MEM, qlcnic_read_memory },
-	{ QLCNIC_DUMP_READ_CTRL, qlcnic_dump_ctrl },
-	{ QLCNIC_DUMP_TLHDR, qlcnic_dump_nop },
-	{ QLCNIC_DUMP_RDEND, qlcnic_dump_nop },
-};
-
-/* Walk the template and collect dump for each entry in the dump template */
-static int
-qlcnic_valid_dump_entry(struct device *dev, struct qlcnic_dump_entry *entry,
-	u32 size)
-{
-	int ret = 1;
-	if (size != entry->hdr.cap_size) {
-		dev_info(dev,
-		"Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
-		entry->hdr.type, entry->hdr.mask, size, entry->hdr.cap_size);
-		dev_info(dev, "Aborting further dump capture\n");
-		ret = 0;
-	}
-	return ret;
-}
-
-int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
-{
-	u32 *buffer;
-	char mesg[64];
-	char *msg[] = {mesg, NULL};
-	int i, k, ops_cnt, ops_index, dump_size = 0;
-	u32 entry_offset, dump, no_entries, buf_offset = 0;
-	struct qlcnic_dump_entry *entry;
-	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
-	struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
-
-	if (fw_dump->clr) {
-		dev_info(&adapter->pdev->dev,
-			"Previous dump not cleared, not capturing dump\n");
-		return -EIO;
-	}
-	/* Calculate the size for dump data area only */
-	for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++)
-		if (i & tmpl_hdr->drv_cap_mask)
-			dump_size += tmpl_hdr->cap_sizes[k];
-	if (!dump_size)
-		return -EIO;
-
-	fw_dump->data = vzalloc(dump_size);
-	if (!fw_dump->data) {
-		dev_info(&adapter->pdev->dev,
-			"Unable to allocate (%d KB) for fw dump\n",
-			dump_size/1024);
-		return -ENOMEM;
-	}
-	buffer = fw_dump->data;
-	fw_dump->size = dump_size;
-	no_entries = tmpl_hdr->num_entries;
-	ops_cnt = ARRAY_SIZE(fw_dump_ops);
-	entry_offset = tmpl_hdr->offset;
-	tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION;
-	tmpl_hdr->sys_info[1] = adapter->fw_version;
-
-	for (i = 0; i < no_entries; i++) {
-		entry = (void *)tmpl_hdr + entry_offset;
-		if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) {
-			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
-			entry_offset += entry->hdr.offset;
-			continue;
-		}
-		/* Find the handler for this entry */
-		ops_index = 0;
-		while (ops_index < ops_cnt) {
-			if (entry->hdr.type == fw_dump_ops[ops_index].opcode)
-				break;
-			ops_index++;
-		}
-		if (ops_index == ops_cnt) {
-			dev_info(&adapter->pdev->dev,
-				"Invalid entry type %d, exiting dump\n",
-				entry->hdr.type);
-			goto error;
-		}
-		/* Collect dump for this entry */
-		dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
-		if (dump && !qlcnic_valid_dump_entry(&adapter->pdev->dev, entry,
-			dump))
-			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
-		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, "Dump data, %d bytes captured\n",
-			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:
-	vfree(fw_dump->data);
-	return -EINVAL;
-}
-
 void qlcnic_get_func_no(struct qlcnic_adapter *adapter)
 {
 	void __iomem *msix_base_addr;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 6f39882..96e9088 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -1178,24 +1178,3 @@ qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
 	sds_ring->consumer = consumer;
 	writel(consumer, sds_ring->crb_sts_consumer);
 }
-
-void
-qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2,
-		 u8 alt_mac, u8 *mac)
-{
-	u32 mac_low, mac_high;
-	int i;
-
-	mac_low = off1;
-	mac_high = off2;
-
-	if (alt_mac) {
-		mac_low |= (mac_low >> 16) | (mac_high << 16);
-		mac_high >>= 16;
-	}
-
-	for (i = 0; i < 2; i++)
-		mac[i] = (u8)(mac_high >> ((1 - i) * 8));
-	for (i = 2; i < 6; i++)
-		mac[i] = (u8)(mac_low >> ((5 - i) * 8));
-}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 9cca75e..d59bed0 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -751,9 +751,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 				adapter->fw_version > prev_fw_version) {
 			if (fw_dump->tmpl_hdr)
 				vfree(fw_dump->tmpl_hdr);
-			if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
-				dev_info(&pdev->dev,
-					"Supports FW dump capability\n");
 		}
 	}
 
@@ -2412,7 +2409,6 @@ skip_ack_check:
 		if (ahw->fw_dump.enable &&
 		    (adapter->flags & QLCNIC_FW_RESET_OWNER)) {
 			QLCDB(adapter, DRV, "Take FW dump\n");
-			qlcnic_dump_fw(adapter);
 			adapter->flags |= QLCNIC_FW_HANG;
 		}
 		rtnl_unlock();
-- 
1.7.1

^ permalink raw reply related

* [PATCH 01/12] qlcnic: Refactoring - template based hardware interface
From: Sony Chacko @ 2012-09-07 23:01 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Anirban Chakraborty
In-Reply-To: <1347058893-30165-1-git-send-email-sony.chacko@qlogic.com>

From: Anirban Chakraborty <anirban.chakraborty@qlogic.com>

Modify 82xx driver to support new adapter - Qlogic 83XX CNA
Separate adapter specific hardware accesses routines
Create template based hardware interface

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |   67 ++++-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c    |    4 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |   32 ++-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h    |   55 +---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c     |  125 ++++++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h     |   36 +++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c   |    1 +
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  312 +++++++++-----------
 8 files changed, 361 insertions(+), 271 deletions(-)
 create mode 100644 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index eaa1db9..a4ae965 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -439,6 +439,8 @@ struct qlcnic_fw_dump {
 	struct	qlcnic_dump_template_hdr *tmpl_hdr;
 };
 
+struct qlcnic_hardware_ops;
+
 /*
  * One hardware_context{} per adapter
  * contains interrupt info as well shared hardware info.
@@ -461,6 +463,8 @@ struct qlcnic_hardware_context {
 
 	u8 beacon_state;
 
+	u32 fw_hal_version;
+	struct qlcnic_hardware_ops *hw_ops;
 	struct qlcnic_nic_intr_coalesce coal;
 	struct qlcnic_fw_dump fw_dump;
 };
@@ -552,8 +556,9 @@ struct qlcnic_recv_context {
 /* HW context creation */
 
 #define QLCNIC_OS_CRB_RETRY_COUNT	4000
-#define QLCNIC_CDRP_SIGNATURE_MAKE(pcifn, version) \
-	(((pcifn) & 0xff) | (((version) & 0xff) << 8) | (0xcafe << 16))
+#define QLCNIC_CDRP_SIGNATURE_MAKE(ahw)					\
+	(((ahw->pci_func) & 0xff) | (((ahw->fw_hal_version) &		\
+	0xff) << 8) | (0xcafe << 16))
 
 #define QLCNIC_CDRP_CMD_BIT		0x80000000
 
@@ -573,9 +578,7 @@ struct qlcnic_recv_context {
  * the crb QLCNIC_CDRP_CRB_OFFSET.
  */
 #define QLCNIC_CDRP_FORM_CMD(cmd)	(QLCNIC_CDRP_CMD_BIT | (cmd))
-#define QLCNIC_CDRP_IS_CMD(cmd)	(((cmd) & QLCNIC_CDRP_CMD_BIT) != 0)
 
-#define QLCNIC_CDRP_CMD_SUBMIT_CAPABILITIES     0x00000001
 #define QLCNIC_CDRP_CMD_READ_MAX_RDS_PER_CTX    0x00000002
 #define QLCNIC_CDRP_CMD_READ_MAX_SDS_PER_CTX    0x00000003
 #define QLCNIC_CDRP_CMD_READ_MAX_RULES_PER_CTX  0x00000004
@@ -1022,7 +1025,6 @@ struct qlcnic_adapter {
 	u16 max_mtu;
 	u16 pvid;
 
-	u32 fw_hal_version;
 	u32 capabilities;
 	u32 irq;
 	u32 temp;
@@ -1443,9 +1445,9 @@ void qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *, u64, u64);
 	(((addr) < (high)) && ((addr) >= (low)))
 
 #define QLCRD32(adapter, off) \
-	(qlcnic_hw_read_wx_2M(adapter, off))
+	adapter->ahw->hw_ops->read_reg(adapter, off)
 #define QLCWR32(adapter, off, val) \
-	(qlcnic_hw_write_wx_2M(adapter, off, val))
+	adapter->ahw->hw_ops->write_reg(adapter, off, val)
 
 int qlcnic_pcie_sem_lock(struct qlcnic_adapter *, int, u32);
 void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int);
@@ -1476,10 +1478,10 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int);
 
 int qlcnic_get_board_info(struct qlcnic_adapter *adapter);
 int qlcnic_wol_supported(struct qlcnic_adapter *adapter);
-int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
 void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter);
 void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter);
 int qlcnic_dump_fw(struct qlcnic_adapter *);
+void qlcnic_get_ocm_win(struct qlcnic_hardware_context *);
 
 /* Functions from qlcnic_init.c */
 int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
@@ -1496,7 +1498,7 @@ int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
 int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter);
 void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter);
 
-void __iomem *qlcnic_get_ioaddr(struct qlcnic_adapter *, u32);
+void __iomem *qlcnic_get_ioaddr(struct qlcnic_hardware_context *, u32);
 
 int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter);
 void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter);
@@ -1528,7 +1530,6 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev,
 	netdev_features_t features);
 int qlcnic_set_features(struct net_device *netdev, netdev_features_t features);
 int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
-int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
 int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
 void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
 		struct qlcnic_host_tx_ring *tx_ring);
@@ -1551,6 +1552,8 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data);
 void qlcnic_dev_request_reset(struct qlcnic_adapter *);
 void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
 
+int qlcnic_setup_intr(struct qlcnic_adapter *);
+
 /* Management functions */
 int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
 int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8);
@@ -1626,6 +1629,50 @@ struct qlcnic_nic_template {
 	int (*start_firmware) (struct qlcnic_adapter *);
 };
 
+/* function template for hardware ops based on different chip type */
+struct qlcnic_hardware_ops {
+	void (*read_crb) (struct qlcnic_adapter *, char *, loff_t, size_t);
+	void (*write_crb) (struct qlcnic_adapter *, char *, loff_t, size_t);
+	u32 (*read_reg) (struct qlcnic_adapter *, ulong);
+	int (*write_reg) (struct qlcnic_adapter *, ulong, u32);
+	void (*get_ocm_win) (struct qlcnic_hardware_context *);
+	int (*get_mac_address) (struct qlcnic_adapter *, u8 *);
+	int (*setup_intr) (struct qlcnic_adapter *);
+	void (*mbx_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
+};
+
+static inline void
+qlcnic_read_crb(struct qlcnic_adapter *adapter, char *buf,
+		loff_t offset, size_t size)
+{
+	adapter->ahw->hw_ops->read_crb(adapter, buf, offset, size);
+}
+
+static inline void
+qlcnic_write_crb(struct qlcnic_adapter *adapter, char *buf,
+		 loff_t offset, size_t size)
+{
+	adapter->ahw->hw_ops->write_crb(adapter, buf, offset, size);
+}
+
+static inline int
+qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
+{
+	return adapter->nic_ops->config_bridged_mode(adapter, enable);
+}
+
+static inline int
+qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
+{
+	return adapter->nic_ops->config_led(adapter, state, rate);
+}
+
+static inline int
+qlcnic_start_firmware(struct qlcnic_adapter *adapter)
+{
+	return adapter->nic_ops->start_firmware(adapter);
+}
+
 #define QLCDB(adapter, lvl, _fmt, _args...) do {	\
 	if (NETIF_MSG_##lvl & adapter->msg_enable)	\
 		printk(KERN_INFO "%s: %s: " _fmt,	\
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index b8ead69..77df8c7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -6,6 +6,7 @@
  */
 
 #include "qlcnic.h"
+#include "qlcnic_hw.h"
 
 static u32
 qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
@@ -34,8 +35,7 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd)
 	struct pci_dev *pdev = adapter->pdev;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
-	signature = QLCNIC_CDRP_SIGNATURE_MAKE(ahw->pci_func,
-		adapter->fw_hal_version);
+	signature = QLCNIC_CDRP_SIGNATURE_MAKE(ahw);
 
 	/* Acquire semaphore before accessing CRB */
 	if (qlcnic_api_lock(adapter)) {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 9e9e78a..c81fcf8 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -13,6 +13,7 @@
 #include <linux/ethtool.h>
 
 #include "qlcnic.h"
+#include "qlcnic_hw.h"
 
 struct qlcnic_stats {
 	char stat_string[ETH_GSTRING_LEN];
@@ -192,10 +193,11 @@ static int
 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	int check_sfp_module = 0;
 
 	/* read which mode */
-	if (adapter->ahw->port_type == QLCNIC_GBE) {
+	if (ahw->port_type == QLCNIC_GBE) {
 		ecmd->supported = (SUPPORTED_10baseT_Half |
 				   SUPPORTED_10baseT_Full |
 				   SUPPORTED_100baseT_Half |
@@ -212,7 +214,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		ecmd->duplex = adapter->link_duplex;
 		ecmd->autoneg = adapter->link_autoneg;
 
-	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
+	} else if (ahw->port_type == QLCNIC_XGBE) {
 		u32 val;
 
 		val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
@@ -241,7 +243,7 @@ skip:
 	ecmd->phy_address = adapter->physical_port;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	switch (adapter->ahw->board_type) {
+	switch (ahw->board_type) {
 	case QLCNIC_BRDTYPE_P3P_REF_QG:
 	case QLCNIC_BRDTYPE_P3P_4_GB:
 	case QLCNIC_BRDTYPE_P3P_4_GB_MM:
@@ -278,7 +280,7 @@ skip:
 		ecmd->autoneg = AUTONEG_DISABLE;
 		break;
 	case QLCNIC_BRDTYPE_P3P_10G_TP:
-		if (adapter->ahw->port_type == QLCNIC_XGBE) {
+		if (ahw->port_type == QLCNIC_XGBE) {
 			ecmd->autoneg = AUTONEG_DISABLE;
 			ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 			ecmd->advertising |=
@@ -296,7 +298,7 @@ skip:
 		break;
 	default:
 		dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
-			adapter->ahw->board_type);
+			ahw->board_type);
 		return -EIO;
 	}
 
@@ -376,12 +378,13 @@ 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_hardware_context *ahw = adapter->ahw;
 	u32 *regs_buff = p;
 	int ring, i = 0, j = 0;
 
 	memset(p, 0, qlcnic_get_regs_len(dev));
 	regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
-		(adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
+		(ahw->revision_id << 16) | (adapter->pdev)->device;
 
 	regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
 	regs_buff[1] = QLCNIC_MGMT_API_VERSION;
@@ -543,10 +546,11 @@ qlcnic_get_pauseparam(struct net_device *netdev,
 			  struct ethtool_pauseparam *pause)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	int port = adapter->physical_port;
 	__u32 val;
 
-	if (adapter->ahw->port_type == QLCNIC_GBE) {
+	if (ahw->port_type == QLCNIC_GBE) {
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 			return;
 		/* get flow control settings */
@@ -568,7 +572,7 @@ qlcnic_get_pauseparam(struct net_device *netdev,
 			pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
 			break;
 		}
-	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
+	} else if (ahw->port_type == QLCNIC_XGBE) {
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 			return;
 		pause->rx_pause = 1;
@@ -588,11 +592,12 @@ qlcnic_set_pauseparam(struct net_device *netdev,
 			  struct ethtool_pauseparam *pause)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	int port = adapter->physical_port;
 	__u32 val;
 
 	/* read mode */
-	if (adapter->ahw->port_type == QLCNIC_GBE) {
+	if (ahw->port_type == QLCNIC_GBE) {
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 			return -EIO;
 		/* set flow control */
@@ -603,8 +608,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
 		else
 			qlcnic_gb_unset_rx_flowctl(val);
 
-		QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
-				val);
+		QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
 		/* set autoneg */
 		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
 		switch (port) {
@@ -635,7 +639,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
 			break;
 		}
 		QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
-	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
+	} else if (ahw->port_type == QLCNIC_XGBE) {
 		if (!pause->rx_pause || pause->autoneg)
 			return -EOPNOTSUPP;
 
@@ -1048,7 +1052,7 @@ static int qlcnic_set_led(struct net_device *dev,
 			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
 		}
 
-		if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
+		if (qlcnic_config_led(adapter, 1, 0xf) == 0) {
 			err = 0;
 			break;
 		}
@@ -1069,7 +1073,7 @@ static int qlcnic_set_led(struct net_device *dev,
 			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
 		}
 
-		if (adapter->nic_ops->config_led(adapter, 0, 0xf))
+		if (qlcnic_config_led(adapter, 0, 0xf))
 			dev_err(&adapter->pdev->dev,
 				"Failed to reset LED blink state.\n");
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
index 28a6b28..0bee9f7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
@@ -449,13 +449,10 @@ enum {
 #define ISR_INT_TARGET_STATUS_F7   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F7))
 #define ISR_INT_TARGET_MASK_F7     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F7))
 
-#define QLCNIC_PCI_MN_2M	(0)
-#define QLCNIC_PCI_MS_2M	(0x80000)
 #define QLCNIC_PCI_OCM0_2M	(0x000c0000UL)
 #define QLCNIC_PCI_CRBSPACE	(0x06000000UL)
 #define QLCNIC_PCI_CAMQM	(0x04800000UL)
 #define QLCNIC_PCI_CAMQM_END	(0x04800800UL)
-#define QLCNIC_PCI_2MB_SIZE	(0x00200000UL)
 #define QLCNIC_PCI_CAMQM_2M_BASE	(0x000ff800UL)
 
 #define QLCNIC_CRB_CAM	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_CAM)
@@ -520,23 +517,6 @@ enum {
 #define MIU_TEST_AGT_ADDR_MASK		0xfffffff8
 #define MIU_TEST_AGT_UPPER_ADDR(off)	(0)
 
-/*
- *   Register offsets for MS
- */
-#define SIU_TEST_AGT_BASE		(0x60)
-
-#define SIU_TEST_AGT_ADDR_LO		(0x04)
-#define SIU_TEST_AGT_ADDR_HI		(0x18)
-#define SIU_TEST_AGT_WRDATA_LO		(0x08)
-#define SIU_TEST_AGT_WRDATA_HI		(0x0c)
-#define SIU_TEST_AGT_WRDATA(i)		(0x08+(4*(i)))
-#define SIU_TEST_AGT_RDDATA_LO		(0x10)
-#define SIU_TEST_AGT_RDDATA_HI		(0x14)
-#define SIU_TEST_AGT_RDDATA(i)		(0x10+(4*(i)))
-
-#define SIU_TEST_AGT_ADDR_MASK		0x3ffff8
-#define SIU_TEST_AGT_UPPER_ADDR(off)	((off)>>22)
-
 /* XG Link status */
 #define XG_LINK_UP	0x10
 #define XG_LINK_DOWN	0x20
@@ -579,17 +559,13 @@ enum {
 
 #define CRB_XG_STATE_P3P		(QLCNIC_REG(0x98))
 #define CRB_PF_LINK_SPEED_1		(QLCNIC_REG(0xe8))
-#define CRB_PF_LINK_SPEED_2		(QLCNIC_REG(0xec))
 
 #define CRB_TEMP_STATE			(QLCNIC_REG(0x1b4))
 
-#define CRB_V2P_0			(QLCNIC_REG(0x290))
-#define CRB_V2P(port)			(CRB_V2P_0+((port)*4))
 #define CRB_DRIVER_VERSION		(QLCNIC_REG(0x2a0))
 
 #define CRB_FW_CAPABILITIES_1		(QLCNIC_CAM_RAM(0x128))
 #define CRB_FW_CAPABILITIES_2		(QLCNIC_CAM_RAM(0x12c))
-#define CRB_MAC_BLOCK_START		(QLCNIC_CAM_RAM(0x1c0))
 
 /*
  * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
@@ -616,11 +592,6 @@ enum {
 /* Lock IDs for PHY lock */
 #define PHY_LOCK_DRIVER		0x44524956
 
-/* Used for PS PCI Memory access */
-#define PCIX_PS_OP_ADDR_LO	(0x10000)
-/*   via CRB  (PS side only)     */
-#define PCIX_PS_OP_ADDR_HI	(0x10004)
-
 #define PCIX_INT_VECTOR 	(0x10100)
 #define PCIX_INT_MASK		(0x10104)
 
@@ -763,7 +734,6 @@ struct qlcnic_legacy_intr_set {
 	u32	int_vec_bit;
 	u32	tgt_status_reg;
 	u32	tgt_mask_reg;
-	u32	pci_int_reg;
 };
 
 #define QLCNIC_FW_API		0x1b216c
@@ -837,50 +807,42 @@ enum {
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F0,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS,		\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(0) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK, },		\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F1,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F1,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F1,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(1) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F1, },	\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F2,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F2,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F2,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(2) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F2, },	\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F3,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F3,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F3,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(3) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F3, },	\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F4,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F4,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F4,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(4) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F4, },	\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F5,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F5,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F5,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(5) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F5, },	\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F6,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F6,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F6,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(6) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F6, },	\
 									\
 	{								\
 		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F7,		\
 		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F7,	\
-		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F7,		\
-		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(7) },	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F7, },	\
 }
 
 /* NIU REGS */
@@ -1031,4 +993,5 @@ struct crb_128M_2M_sub_block_map {
 struct crb_128M_2M_block_map{
 	struct crb_128M_2M_sub_block_map sub_block[16];
 };
+
 #endif				/* __QLCNIC_HDR_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index b528e52..ee4cd43 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -6,6 +6,8 @@
  */
 
 #include "qlcnic.h"
+#include "qlcnic_hdr.h"
+#include "qlcnic_hw.h"
 
 #include <linux/slab.h>
 #include <net/ip.h>
@@ -266,6 +268,13 @@ static const unsigned crb_hub_agt[64] = {
 	0,
 };
 
+static const u32 msi_tgt_status[8] = {
+	ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
+	ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
+	ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
+	ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
+};
+
 /*  PCI Windowing for DDR regions.  */
 
 #define QLCNIC_PCIE_SEM_TIMEOUT	10000
@@ -644,7 +653,7 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
 	return rv;
 }
 
-int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
+int qlcnic_82xx_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
 {
 	struct qlcnic_nic_req req;
 	u64 word;
@@ -864,7 +873,7 @@ int qlcnic_set_features(struct net_device *netdev, netdev_features_t features)
  * In: 'off' is offset from base in 128M pci map
  */
 static int
-qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
+qlcnic_pci_get_crb_addr_2M(struct qlcnic_hardware_context *ahw,
 		ulong off, void __iomem **addr)
 {
 	const struct crb_128M_2M_sub_block_map *m;
@@ -880,7 +889,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
 	m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
 
 	if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
-		*addr = adapter->ahw->pci_base0 + m->start_2M +
+		*addr = ahw->pci_base0 + m->start_2M +
 			(off - m->start_128M);
 		return 0;
 	}
@@ -888,7 +897,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
 	/*
 	 * Not in direct map, use crb window
 	 */
-	*addr = adapter->ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
+	*addr = ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
 	return 1;
 }
 
@@ -929,7 +938,7 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data)
 	int rv;
 	void __iomem *addr = NULL;
 
-	rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr);
+	rv = qlcnic_pci_get_crb_addr_2M(adapter->ahw, off, &addr);
 
 	if (rv == 0) {
 		writel(data, addr);
@@ -962,7 +971,7 @@ qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
 	u32 data = -1;
 	void __iomem *addr = NULL;
 
-	rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr);
+	rv = qlcnic_pci_get_crb_addr_2M(adapter->ahw, off, &addr);
 
 	if (rv == 0)
 		return readl(addr);
@@ -986,11 +995,11 @@ qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
 
 
 void __iomem *
-qlcnic_get_ioaddr(struct qlcnic_adapter *adapter, u32 offset)
+qlcnic_get_ioaddr(struct qlcnic_hardware_context *ahw, u32 offset)
 {
 	void __iomem *addr = NULL;
 
-	WARN_ON(qlcnic_pci_get_crb_addr_2M(adapter, offset, &addr));
+	WARN_ON(qlcnic_pci_get_crb_addr_2M(ahw, offset, &addr));
 
 	return addr;
 }
@@ -1077,15 +1086,17 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter,
 
 	/* P3 onward, test agent base for MIU and SIU is same */
 	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
-				QLCNIC_ADDR_QDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter,
-				QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE);
+			  QLCNIC_ADDR_QDR_NET_MAX)) {
+		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
+					    QLCNIC_CRB_QDR_NET +
+					    MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
 	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter,
-				QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
+					    QLCNIC_CRB_DDR_NET +
+					    MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
@@ -1105,7 +1116,7 @@ correct:
 	i = 0;
 	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
 	writel((TA_CTL_START | TA_CTL_ENABLE),
-			(mem_crb + TEST_AGT_CTRL));
+	       (mem_crb + TEST_AGT_CTRL));
 
 	for (j = 0; j < MAX_CTL_CHECK; j++) {
 		temp = readl(mem_crb + TEST_AGT_CTRL);
@@ -1120,19 +1131,19 @@ correct:
 
 	i = (off & 0xf) ? 0 : 2;
 	writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
-			mem_crb + MIU_TEST_AGT_WRDATA(i));
+	       mem_crb + MIU_TEST_AGT_WRDATA(i));
 	writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
-			mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+	       mem_crb + MIU_TEST_AGT_WRDATA(i+1));
 	i = (off & 0xf) ? 2 : 0;
 
 	writel(data & 0xffffffff,
-			mem_crb + MIU_TEST_AGT_WRDATA(i));
+	       mem_crb + MIU_TEST_AGT_WRDATA(i));
 	writel((data >> 32) & 0xffffffff,
-			mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+	       mem_crb + MIU_TEST_AGT_WRDATA(i+1));
 
 	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
 	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
-			(mem_crb + TEST_AGT_CTRL));
+	       (mem_crb + TEST_AGT_CTRL));
 
 	for (j = 0; j < MAX_CTL_CHECK; j++) {
 		temp = readl(mem_crb + TEST_AGT_CTRL);
@@ -1169,15 +1180,17 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter,
 
 	/* P3 onward, test agent base for MIU and SIU is same */
 	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
-				QLCNIC_ADDR_QDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter,
-				QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE);
+			  QLCNIC_ADDR_QDR_NET_MAX)) {
+		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
+					    QLCNIC_CRB_QDR_NET +
+					    MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
 	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter,
-				QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
+					    QLCNIC_CRB_DDR_NET +
+					    MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
@@ -1230,6 +1243,7 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
 {
 	int offset, board_type, magic;
 	struct pci_dev *pdev = adapter->pdev;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	offset = QLCNIC_FW_MAGIC_OFFSET;
 	if (qlcnic_rom_fast_read(adapter, offset, &magic))
@@ -1245,7 +1259,7 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
 	if (qlcnic_rom_fast_read(adapter, offset, &board_type))
 		return -EIO;
 
-	adapter->ahw->board_type = board_type;
+	ahw->board_type = board_type;
 
 	if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
 		u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
@@ -1264,20 +1278,20 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
 	case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
 	case QLCNIC_BRDTYPE_P3P_10G_XFP:
 	case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
-		adapter->ahw->port_type = QLCNIC_XGBE;
+		ahw->port_type = QLCNIC_XGBE;
 		break;
 	case QLCNIC_BRDTYPE_P3P_REF_QG:
 	case QLCNIC_BRDTYPE_P3P_4_GB:
 	case QLCNIC_BRDTYPE_P3P_4_GB_MM:
-		adapter->ahw->port_type = QLCNIC_GBE;
+		ahw->port_type = QLCNIC_GBE;
 		break;
 	case QLCNIC_BRDTYPE_P3P_10G_TP:
-		adapter->ahw->port_type = (adapter->portnum < 2) ?
+		ahw->port_type = (adapter->portnum < 2) ?
 			QLCNIC_XGBE : QLCNIC_GBE;
 		break;
 	default:
 		dev_err(&pdev->dev, "unknown board type %x\n", board_type);
-		adapter->ahw->port_type = QLCNIC_XGBE;
+		ahw->port_type = QLCNIC_XGBE;
 		break;
 	}
 
@@ -1299,7 +1313,7 @@ qlcnic_wol_supported(struct qlcnic_adapter *adapter)
 	return 0;
 }
 
-int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
+int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
 {
 	struct qlcnic_nic_req   req;
 	int rv;
@@ -1786,3 +1800,54 @@ error:
 	vfree(fw_dump->data);
 	return -EINVAL;
 }
+
+void qlcnic_get_func_no(struct qlcnic_adapter *adapter)
+{
+	void __iomem *msix_base_addr;
+	u32 func;
+	u32 msix_base;
+
+	pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func);
+	msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE;
+	msix_base = readl(msix_base_addr);
+	func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
+	adapter->ahw->pci_func = func;
+}
+
+void qlcnic_get_ocm_win(struct qlcnic_hardware_context *ahw)
+{
+	u32 addr;
+
+	addr = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func));
+	ahw->ocm_win_crb = qlcnic_get_ioaddr(ahw, addr);
+}
+
+void qlcnic_82xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
+			   loff_t offset, size_t size)
+{
+	u32 data;
+	u64 qmdata;
+
+	if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
+		qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
+		memcpy(buf, &qmdata, size);
+	} else {
+		data = QLCRD32(adapter, offset);
+		memcpy(buf, &data, size);
+	}
+}
+
+void qlcnic_82xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
+			    loff_t offset, size_t size)
+{
+	u32 data;
+	u64 qmdata;
+
+	if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
+		memcpy(&qmdata, buf, size);
+		qlcnic_pci_camqm_write_2M(adapter, offset, qmdata);
+	} else {
+		memcpy(&data, buf, size);
+		QLCWR32(adapter, offset, data);
+	}
+}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
new file mode 100644
index 0000000..7dab9e2
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -0,0 +1,36 @@
+#ifndef __QLCNIC_HW_H
+#define __QLCNIC_HW_H
+
+#include "qlcnic.h"
+
+/* List of PCI device IDs */
+#define PCI_DEVICE_ID_QLOGIC_QLE824X  0x8020
+#define QLCNIC_P3P_BAR0_LENGTH		0x00200000UL
+
+#define QLCNIC_BAR_LENGTH(dev_id, bar)			\
+do {							\
+	if (dev_id == PCI_DEVICE_ID_QLOGIC_QLE824X)\
+		*bar = QLCNIC_P3P_BAR0_LENGTH;		\
+	else						\
+		*bar = 0;				\
+} while (0)
+
+#define QLCNIC_ENABLE_INTR(adapter, crb) {		\
+	writel(1, crb);					\
+	if (!QLCNIC_IS_MSI_FAMILY(adapter))		\
+		writel(0xfbff, adapter->tgt_mask_reg);	\
+}
+
+#define QLCNIC_DISABLE_INTR(crb) {			\
+	writel(0, crb);					\
+}
+
+
+
+void qlcnic_82xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
+void qlcnic_82xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
+int qlcnic_82xx_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
+int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
+int qlcnic_82xx_start_firmware(struct qlcnic_adapter *);
+
+#endif				/* __QLCNIC_HW_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index 0bcda9c..350bf79 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/if_vlan.h>
 #include "qlcnic.h"
+#include "qlcnic_hw.h"
 
 struct crb_addr_pair {
 	u32 addr;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 212c121..9dc4ffd 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 
 #include "qlcnic.h"
+#include "qlcnic_hw.h"
 
 #include <linux/swab.h>
 #include <linux/dma-mapping.h>
@@ -88,7 +89,6 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data);
 
 static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev);
 static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long);
-static int qlcnic_start_firmware(struct qlcnic_adapter *);
 
 static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter);
 static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
@@ -105,8 +105,6 @@ static int qlcnic_vlan_rx_del(struct net_device *, u16);
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
 	.class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
 
-#define PCI_DEVICE_ID_QLOGIC_QLE824X  0x8020
-
 static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = {
 	ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X),
 	{0,}
@@ -240,35 +238,6 @@ qlcnic_napi_disable(struct qlcnic_adapter *adapter)
 	}
 }
 
-static void qlcnic_clear_stats(struct qlcnic_adapter *adapter)
-{
-	memset(&adapter->stats, 0, sizeof(adapter->stats));
-}
-
-static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable)
-{
-	u32 control;
-	int pos;
-
-	pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
-	if (pos) {
-		pci_read_config_dword(pdev, pos, &control);
-		if (enable)
-			control |= PCI_MSIX_FLAGS_ENABLE;
-		else
-			control = 0;
-		pci_write_config_dword(pdev, pos, control);
-	}
-}
-
-static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count)
-{
-	int i;
-
-	for (i = 0; i < count; i++)
-		adapter->msix_entries[i].entry = i;
-}
-
 static int
 qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
 {
@@ -343,9 +312,9 @@ static const struct net_device_ops qlcnic_netdev_failed_ops = {
 };
 
 static struct qlcnic_nic_template qlcnic_ops = {
-	.config_bridged_mode = qlcnic_config_bridged_mode,
-	.config_led = qlcnic_config_led,
-	.start_firmware = qlcnic_start_firmware
+	.config_bridged_mode = qlcnic_82xx_config_bridged_mode,
+	.config_led = qlcnic_82xx_config_led,
+	.start_firmware = qlcnic_82xx_start_firmware
 };
 
 static struct qlcnic_nic_template qlcnic_vf_ops = {
@@ -354,47 +323,68 @@ static struct qlcnic_nic_template qlcnic_vf_ops = {
 	.start_firmware = qlcnicvf_start_firmware
 };
 
+static struct qlcnic_hardware_ops qlcnic_82xx_ops = {
+	.read_crb = qlcnic_82xx_read_crb,
+	.write_crb = qlcnic_82xx_write_crb,
+	.read_reg = qlcnic_hw_read_wx_2M,
+	.write_reg = qlcnic_hw_write_wx_2M,
+	.get_mac_address = qlcnic_get_mac_address,
+	.setup_intr = qlcnic_setup_intr,
+	.mbx_cmd = qlcnic_issue_cmd,
+};
+
 static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
 {
 	struct pci_dev *pdev = adapter->pdev;
-	int err = -1;
+	int err = -1, i;
+
+	if (!adapter->msix_entries) {
+		adapter->msix_entries = kcalloc(num_msix,
+						sizeof(struct msix_entry),
+						GFP_KERNEL);
+		if (!adapter->msix_entries) {
+			dev_err(&pdev->dev, "failed allocating msix_entries\n");
+			return -ENOMEM;
+		}
+	}
 
 	adapter->max_sds_rings = 1;
 	adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED);
-	qlcnic_set_msix_bit(pdev, 0);
 
 	if (adapter->msix_supported) {
  enable_msix:
-		qlcnic_init_msix_entries(adapter, num_msix);
+		for (i = 0; i < num_msix; i++)
+			adapter->msix_entries[i].entry = i;
+
 		err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
 		if (err == 0) {
 			adapter->flags |= QLCNIC_MSIX_ENABLED;
-			qlcnic_set_msix_bit(pdev, 1);
-
 			adapter->max_sds_rings = num_msix;
 
 			dev_info(&pdev->dev, "using msi-x interrupts\n");
 			return err;
-		}
-		if (err > 0) {
+		} else if (err > 0) {
 			num_msix = rounddown_pow_of_two(err);
-			if (num_msix)
+			if (num_msix) {
+				dev_info(&pdev->dev, "%s, failed", __func__);
 				goto enable_msix;
+			}
 		}
 	}
 	return err;
 }
 
-
 static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
 {
+	u32 offset;
 	const struct qlcnic_legacy_intr_set *legacy_intrp;
 	struct pci_dev *pdev = adapter->pdev;
 
 	if (use_msi && !pci_enable_msi(pdev)) {
 		adapter->flags |= QLCNIC_MSI_ENABLED;
-		adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
-				msi_tgt_status[adapter->ahw->pci_func]);
+		offset = msi_tgt_status[adapter->ahw->pci_func];
+		adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw,
+							    offset);
 		dev_info(&pdev->dev, "using msi interrupts\n");
 		adapter->msix_entries[0].vector = pdev->irq;
 		return;
@@ -403,33 +393,35 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
 	legacy_intrp = &legacy_intr[adapter->ahw->pci_func];
 
 	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
-	adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
-			legacy_intrp->tgt_status_reg);
-	adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter,
-			legacy_intrp->tgt_mask_reg);
-	adapter->isr_int_vec = qlcnic_get_ioaddr(adapter, ISR_INT_VECTOR);
-
-	adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter,
-			ISR_INT_STATE_REG);
+	offset = legacy_intrp->tgt_status_reg;
+	adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw, offset);
+	adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter->ahw,
+						  legacy_intrp->tgt_mask_reg);
+	adapter->isr_int_vec = qlcnic_get_ioaddr(adapter->ahw, ISR_INT_VECTOR);
+
+	adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter->ahw,
+						       ISR_INT_STATE_REG);
 	dev_info(&pdev->dev, "using legacy interrupts\n");
 	adapter->msix_entries[0].vector = pdev->irq;
 }
 
-static void
+int
 qlcnic_setup_intr(struct qlcnic_adapter *adapter)
 {
-	int num_msix;
+	int num_msix, err;
 
-	if (adapter->msix_supported) {
+	if (adapter->msix_supported)
 		num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
-				QLCNIC_DEF_NUM_STS_DESC_RINGS));
-	} else
+						QLCNIC_DEF_NUM_STS_DESC_RINGS));
+	else
 		num_msix = 1;
 
-	if (!qlcnic_enable_msix(adapter, num_msix))
-		return;
+	err = qlcnic_enable_msix(adapter, num_msix);
+	if (err == -ENOMEM || !err)
+		return err;
 
 	qlcnic_enable_msi_legacy(adapter);
+	return 0;
 }
 
 static void
@@ -442,10 +434,10 @@ qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
 }
 
 static void
-qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
+qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw)
 {
-	if (adapter->ahw->pci_base0 != NULL)
-		iounmap(adapter->ahw->pci_base0);
+	if (ahw->pci_base0 != NULL)
+		iounmap(ahw->pci_base0);
 }
 
 static int
@@ -552,50 +544,52 @@ qlcnic_check_vf(struct qlcnic_adapter *adapter)
 	u32 func;
 	u32 msix_base;
 	u32 op_mode, priv_level;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	/* Determine FW API version */
-	adapter->fw_hal_version = readl(adapter->ahw->pci_base0 +
-					QLCNIC_FW_API);
+	ahw->fw_hal_version = readl(adapter->ahw->pci_base0 +
+				    QLCNIC_FW_API);
 
 	/* Find PCI function number */
 	pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func);
 	msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE;
 	msix_base = readl(msix_base_addr);
 	func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
-	adapter->ahw->pci_func = func;
+	ahw->pci_func = func;
 
 	/* Determine function privilege level */
-	priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
+	priv_op = ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
 	op_mode = readl(priv_op);
 	if (op_mode == QLC_DEV_DRV_DEFAULT)
 		priv_level = QLCNIC_MGMT_FUNC;
 	else
-		priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
+		priv_level = QLC_DEV_GET_DRV(op_mode, ahw->pci_func);
 
 	if (priv_level == QLCNIC_NON_PRIV_FUNC) {
 		adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
 		dev_info(&adapter->pdev->dev,
-			"HAL Version: %d Non Privileged function\n",
-			adapter->fw_hal_version);
+			 "HAL Version: %d Non Privileged function\n",
+			 ahw->fw_hal_version);
 		adapter->nic_ops = &qlcnic_vf_ops;
 	} else
 		adapter->nic_ops = &qlcnic_ops;
 }
 
 static int
-qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
+qlcnic_setup_pci_map(struct pci_dev *pdev,
+		     struct qlcnic_hardware_context *ahw)
 {
+	u32 offset;
 	void __iomem *mem_ptr0 = NULL;
 	resource_size_t mem_base;
-	unsigned long mem_len, pci_len0 = 0;
-
-	struct pci_dev *pdev = adapter->pdev;
+	unsigned long mem_len, pci_len0 = 0, bar0_len;
 
 	/* remap phys address */
 	mem_base = pci_resource_start(pdev, 0);	/* 0 is for BAR 0 */
 	mem_len = pci_resource_len(pdev, 0);
 
-	if (mem_len == QLCNIC_PCI_2MB_SIZE) {
+	QLCNIC_BAR_LENGTH(pdev->device, &bar0_len);
+	if (mem_len == bar0_len) {
 
 		mem_ptr0 = pci_ioremap_bar(pdev, 0);
 		if (mem_ptr0 == NULL) {
@@ -609,19 +603,16 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
 
 	dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
 
-	adapter->ahw->pci_base0 = mem_ptr0;
-	adapter->ahw->pci_len0 = pci_len0;
-
-	qlcnic_check_vf(adapter);
+	ahw->pci_base0 = mem_ptr0;
+	ahw->pci_len0 = pci_len0;
 
-	adapter->ahw->ocm_win_crb = qlcnic_get_ioaddr(adapter,
-		QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(
-			adapter->ahw->pci_func)));
+	offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func));
+	qlcnic_get_ioaddr(ahw, offset);
 
 	return 0;
 }
 
-static void get_brd_name(struct qlcnic_adapter *adapter, char *name)
+static void qlcnic_get_brd_name(struct qlcnic_adapter *adapter, char *name)
 {
 	struct pci_dev *pdev = adapter->pdev;
 	int i, found = 0;
@@ -649,7 +640,8 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 {
 	u32 fw_major, fw_minor, fw_build, prev_fw_version;
 	struct pci_dev *pdev = adapter->pdev;
-	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
 
 	prev_fw_version = adapter->fw_version;
 
@@ -672,7 +664,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 
 	dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
 			fw_major, fw_minor, fw_build);
-	if (adapter->ahw->port_type == QLCNIC_XGBE) {
+	if (ahw->port_type == QLCNIC_XGBE) {
 		if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
 			adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
 			adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
@@ -684,7 +676,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
 		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
 
-	} else if (adapter->ahw->port_type == QLCNIC_GBE) {
+	} else if (ahw->port_type == QLCNIC_GBE) {
 		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
 		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
 		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
@@ -832,6 +824,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
 	void __iomem *priv_op;
 	u32 op_mode, priv_level;
 	int err = 0;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	err = qlcnic_initialize_nic(adapter);
 	if (err)
@@ -840,14 +833,14 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
 	if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED)
 		return 0;
 
-	priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
+	priv_op = ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
 	op_mode = readl(priv_op);
-	priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
+	priv_level = QLC_DEV_GET_DRV(op_mode, ahw->pci_func);
 
 	if (op_mode == QLC_DEV_DRV_DEFAULT)
 		priv_level = QLCNIC_MGMT_FUNC;
 	else
-		priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
+		priv_level = QLC_DEV_GET_DRV(op_mode, ahw->pci_func);
 
 	if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
 		if (priv_level == QLCNIC_MGMT_FUNC) {
@@ -858,13 +851,13 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
 			/* Set privilege level for other functions */
 			qlcnic_set_function_modes(adapter);
 			dev_info(&adapter->pdev->dev,
-				"HAL Version: %d, Management function\n",
-				adapter->fw_hal_version);
+				 "HAL Version: %d, Management function\n",
+				 adapter->ahw->fw_hal_version);
 		} else if (priv_level == QLCNIC_PRIV_FUNC) {
 			adapter->op_mode = QLCNIC_PRIV_FUNC;
 			dev_info(&adapter->pdev->dev,
-				"HAL Version: %d, Privileged function\n",
-				adapter->fw_hal_version);
+				 "HAL Version: %d, Privileged function\n",
+				 adapter->ahw->fw_hal_version);
 		}
 	}
 
@@ -1010,8 +1003,8 @@ qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter)
 	return err;
 }
 
-static int
-qlcnic_start_firmware(struct qlcnic_adapter *adapter)
+int
+qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter)
 {
 	int err;
 
@@ -1338,21 +1331,11 @@ out:
 static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
 {
 	int err = 0;
-	adapter->ahw = kzalloc(sizeof(struct qlcnic_hardware_context),
-				GFP_KERNEL);
-	if (!adapter->ahw) {
-		dev_err(&adapter->pdev->dev,
-			"Failed to allocate recv ctx resources for adapter\n");
-		err = -ENOMEM;
-		goto err_out;
-	}
 	adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
 				GFP_KERNEL);
 	if (!adapter->recv_ctx) {
 		dev_err(&adapter->pdev->dev,
 			"Failed to allocate recv ctx resources for adapter\n");
-		kfree(adapter->ahw);
-		adapter->ahw = NULL;
 		err = -ENOMEM;
 		goto err_out;
 	}
@@ -1360,6 +1343,8 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
 	adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
 	adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
 	adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+	/* clear stats */
+	memset(&adapter->stats, 0, sizeof(adapter->stats));
 err_out:
 	return err;
 }
@@ -1373,8 +1358,6 @@ static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter)
 		vfree(adapter->ahw->fw_dump.tmpl_hdr);
 		adapter->ahw->fw_dump.tmpl_hdr = NULL;
 	}
-	kfree(adapter->ahw);
-	adapter->ahw = NULL;
 }
 
 int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
@@ -1546,26 +1529,13 @@ static int qlcnic_set_dma_mask(struct pci_dev *pdev, u8 *pci_using_dac)
 	return 0;
 }
 
-static int
-qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count)
-{
-	adapter->msix_entries = kcalloc(count, sizeof(struct msix_entry),
-					GFP_KERNEL);
-
-	if (adapter->msix_entries)
-		return 0;
-
-	dev_err(&adapter->pdev->dev, "failed allocating msix_entries\n");
-	return -ENOMEM;
-}
-
 static int __devinit
 qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *netdev = NULL;
 	struct qlcnic_adapter *adapter = NULL;
+	struct qlcnic_hardware_context *ahw;
 	int err;
-	uint8_t revision_id;
 	uint8_t pci_using_dac;
 	char brd_name[QLCNIC_MAX_BOARD_NAME_LEN];
 
@@ -1589,10 +1559,23 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_set_master(pdev);
 	pci_enable_pcie_error_reporting(pdev);
 
+	ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL);
+	if (!ahw)
+		goto err_out_free_res;
+
+	if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE824X)
+		ahw->hw_ops = &qlcnic_82xx_ops;
+	else
+		goto err_out_free_hw_res;
+
+	err = qlcnic_setup_pci_map(pdev, ahw);
+	if (err)
+		goto err_out_free_hw_res;
+
 	netdev = alloc_etherdev(sizeof(struct qlcnic_adapter));
 	if (!netdev) {
 		err = -ENOMEM;
-		goto err_out_free_res;
+		goto err_out_iounmap;
 	}
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
@@ -1600,13 +1583,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	adapter = netdev_priv(netdev);
 	adapter->netdev  = netdev;
 	adapter->pdev    = pdev;
+	adapter->ahw = ahw;
 
 	if (qlcnic_alloc_adapter_resources(adapter))
 		goto err_out_free_netdev;
 
 	adapter->dev_rst_time = jiffies;
-	revision_id = pdev->revision;
-	adapter->ahw->revision_id = revision_id;
+	adapter->ahw->revision_id = pdev->revision;
 	adapter->mac_learn = qlcnic_mac_learn;
 
 	rwlock_init(&adapter->ahw->crb_lock);
@@ -1615,9 +1598,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	spin_lock_init(&adapter->tx_clean_lock);
 	INIT_LIST_HEAD(&adapter->mac_list);
 
-	err = qlcnic_setup_pci_map(adapter);
-	if (err)
-		goto err_out_free_hw;
+	qlcnic_check_vf(adapter);
 
 	/* This will be reset for mezz cards  */
 	adapter->portnum = adapter->ahw->pci_func;
@@ -1625,16 +1606,16 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	err = qlcnic_get_board_info(adapter);
 	if (err) {
 		dev_err(&pdev->dev, "Error getting board config info.\n");
-		goto err_out_iounmap;
+		goto err_out_free_hw;
 	}
 
 	err = qlcnic_setup_idc_param(adapter);
 	if (err)
-		goto err_out_iounmap;
+		goto err_out_free_hw;
 
 	adapter->flags |= QLCNIC_NEED_FLR;
 
-	err = adapter->nic_ops->start_firmware(adapter);
+	err = qlcnic_start_firmware(adapter);
 	if (err) {
 		dev_err(&pdev->dev, "Loading fw failed. Please Reboot\n"
 			"\t\tIf reboot doesn't help, try flashing the card\n");
@@ -1645,21 +1626,17 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev_warn(&pdev->dev, "failed to read mac addr\n");
 
 	if (adapter->portnum == 0) {
-		get_brd_name(adapter, brd_name);
+		qlcnic_get_brd_name(adapter, brd_name);
 
 		pr_info("%s: %s Board Chip rev 0x%x\n",
 				module_name(THIS_MODULE),
 				brd_name, adapter->ahw->revision_id);
 	}
 
-	qlcnic_clear_stats(adapter);
-
-	err = qlcnic_alloc_msix_entries(adapter, adapter->max_rx_ques);
-	if (err)
+	err = qlcnic_setup_intr(adapter);
+	if (err == -ENOMEM)
 		goto err_out_decr_ref;
 
-	qlcnic_setup_intr(adapter);
-
 	err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac);
 	if (err)
 		goto err_out_disable_msi;
@@ -1693,15 +1670,18 @@ err_out_disable_msi:
 err_out_decr_ref:
 	qlcnic_clr_all_drv_state(adapter, 0);
 
-err_out_iounmap:
-	qlcnic_cleanup_pci_map(adapter);
-
 err_out_free_hw:
 	qlcnic_free_adapter_resources(adapter);
 
 err_out_free_netdev:
 	free_netdev(netdev);
 
+err_out_iounmap:
+	qlcnic_cleanup_pci_map(ahw);
+
+err_out_free_hw_res:
+	kfree(ahw);
+
 err_out_free_res:
 	pci_release_regions(pdev);
 
@@ -1727,12 +1707,14 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
 {
 	struct qlcnic_adapter *adapter;
 	struct net_device *netdev;
+	struct qlcnic_hardware_context *ahw;
 
 	adapter = pci_get_drvdata(pdev);
 	if (adapter == NULL)
 		return;
 
 	netdev = adapter->netdev;
+	ahw = adapter->ahw;
 
 	qlcnic_cancel_fw_work(adapter);
 
@@ -1756,7 +1738,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
 
 	qlcnic_remove_diag_entries(adapter);
 
-	qlcnic_cleanup_pci_map(adapter);
+	qlcnic_cleanup_pci_map(ahw);
 
 	qlcnic_release_firmware(adapter);
 
@@ -1766,6 +1748,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
 	pci_set_drvdata(pdev, NULL);
 
 	qlcnic_free_adapter_resources(adapter);
+	kfree(ahw);
 	free_netdev(netdev);
 }
 static int __qlcnic_shutdown(struct pci_dev *pdev)
@@ -1834,7 +1817,7 @@ qlcnic_resume(struct pci_dev *pdev)
 	pci_set_master(pdev);
 	pci_restore_state(pdev);
 
-	err = adapter->nic_ops->start_firmware(adapter);
+	err = qlcnic_start_firmware(adapter);
 	if (err) {
 		dev_err(&pdev->dev, "failed to start firmware\n");
 		return err;
@@ -2735,12 +2718,13 @@ static int
 qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
 {
 	int act, state, active_mask;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
 	act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
 
 	if (adapter->flags & QLCNIC_FW_RESET_OWNER) {
-		active_mask = (~(1 << (adapter->ahw->pci_func * 4)));
+		active_mask = (~(1 << (ahw->pci_func * 4)));
 		act = act & active_mask;
 	}
 
@@ -2857,6 +2841,7 @@ qlcnic_fwinit_work(struct work_struct *work)
 			struct qlcnic_adapter, fw_work.work);
 	u32 dev_state = 0xf;
 	u32 val;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	if (qlcnic_api_lock(adapter))
 		goto err_ret;
@@ -2906,7 +2891,7 @@ skip_ack_check:
 		qlcnic_api_unlock(adapter);
 
 		rtnl_lock();
-		if (adapter->ahw->fw_dump.enable &&
+		if (ahw->fw_dump.enable &&
 		    (adapter->flags & QLCNIC_FW_RESET_OWNER)) {
 			QLCDB(adapter, DRV, "Take FW dump\n");
 			qlcnic_dump_fw(adapter);
@@ -2915,7 +2900,7 @@ skip_ack_check:
 		rtnl_unlock();
 
 		adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
-		if (!adapter->nic_ops->start_firmware(adapter)) {
+		if (!qlcnic_start_firmware(adapter)) {
 			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
 			adapter->fw_wait_cnt = 0;
 			return;
@@ -2931,7 +2916,7 @@ wait_npar:
 
 	switch (dev_state) {
 	case QLCNIC_DEV_READY:
-		if (!adapter->nic_ops->start_firmware(adapter)) {
+		if (!qlcnic_start_firmware(adapter)) {
 			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
 			adapter->fw_wait_cnt = 0;
 			return;
@@ -3064,7 +3049,8 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 		qlcnic_idc_debug_info(adapter, 0);
 	}
 
-	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
+		QLCNIC_DEV_NPAR_NON_OPER);
 	qlcnic_api_unlock(adapter);
 }
 
@@ -3290,12 +3276,14 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
 	}
 	qlcnic_api_unlock(adapter);
 
-	err = adapter->nic_ops->start_firmware(adapter);
+	err = qlcnic_start_firmware(adapter);
 	if (err)
 		return err;
 
 	qlcnic_clr_drv_state(adapter);
-	qlcnic_setup_intr(adapter);
+	kfree(adapter->msix_entries);
+	adapter->msix_entries = NULL;
+	err = qlcnic_setup_intr(adapter);
 
 	if (netif_running(netdev)) {
 		err = qlcnic_attach(adapter);
@@ -3423,7 +3411,7 @@ qlcnic_store_bridged_mode(struct device *dev,
 	if (strict_strtoul(buf, 2, &new))
 		goto err_out;
 
-	if (!adapter->nic_ops->config_bridged_mode(adapter, !!new))
+	if (!qlcnic_config_bridged_mode(adapter, !!new))
 		ret = len;
 
 err_out:
@@ -3510,6 +3498,8 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data)
 		__qlcnic_down(adapter, netdev);
 	qlcnic_detach(adapter);
 	qlcnic_teardown_intr(adapter);
+	kfree(adapter->msix_entries);
+	adapter->msix_entries = NULL;
 
 	if (qlcnic_enable_msix(adapter, data)) {
 		netdev_info(netdev, "failed setting max_rss; rss disabled\n");
@@ -3662,21 +3652,13 @@ qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
-	u32 data;
-	u64 qmdata;
 	int ret;
 
 	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
 	if (ret != 0)
 		return ret;
 
-	if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
-		qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
-		memcpy(buf, &qmdata, size);
-	} else {
-		data = QLCRD32(adapter, offset);
-		memcpy(buf, &data, size);
-	}
+	qlcnic_read_crb(adapter, buf, offset, size);
 	return size;
 }
 
@@ -3687,21 +3669,13 @@ qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
-	u32 data;
-	u64 qmdata;
 	int ret;
 
 	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
 	if (ret != 0)
 		return ret;
 
-	if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
-		memcpy(&qmdata, buf, size);
-		qlcnic_pci_camqm_write_2M(adapter, offset, qmdata);
-	} else {
-		memcpy(&data, buf, size);
-		QLCWR32(adapter, offset, data);
-	}
+	qlcnic_write_crb(adapter, buf, offset, size);
 	return size;
 }
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 0/12] qlcnic: patches for new adapter - Qlogic 83XX CNA
From: Sony Chacko @ 2012-09-07 23:01 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sony Chacko

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

Re: [PATCH 11/12] qlcnic: 83xx adpater ethtool
>From: Ben Hutchings [mailto:bhutchings@solarflare.com]

>	#define QLCNIC_ETHTOOL_REGS_VER	2

> I think QLCNIC_ETHTOOL_REGS_VER needs to be changed,
> as you appear to be dumping more registers from the
> existing hardware as well.

> +static int qlcnic_set_channels(struct net_device *dev

> So you removed the body of qlcnic_set_channels() in an
> earlier patch, and now you're moving it and putting the body
> back how it was...  Please clean up the patch series
> so it doesn't have noise like this in it.

Re: [PATCH 10/12] qlcnic: register dump utility
> *dev,  static int qlcnic_set_channels(struct net_device *dev,
>  		struct ethtool_channels *channel)
>  {
> +	return 0;
>  }
[...]

> No, I don't think so. 
> If you're going to remove support for this operation
> then delete the function entirely.
> And don't put it in a patch that's supposed
> to do something unrelated.

Re: [PATCH 06/12] qlcnic: 83xx data path and HW interfaces routines
> +int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
> +			     struct ethtool_cmd *ecmd)
> +		return -EIO;

> Should be -EINVAL.

> +qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,

> +	default:
> +		dev_info(&adapter->pdev->dev, "Unknown get statistics mode\n");

> It seems like this default case can only be reached
> in case of a driver bug, so WARN would be more appropriate.


We have addressed all the issues raised by Ben Hutchings.
Please apply the updated 12 patch series to net-next.

Thanks,
Sony

^ permalink raw reply

* [PATCH 03/12] qlcnic: Refactoring - Moving hw specific data to hardware context
From: Sony Chacko @ 2012-09-07 23:01 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Anirban Chakraborty
In-Reply-To: <1347058893-30165-1-git-send-email-sony.chacko@qlogic.com>

From: Anirban Chakraborty <anirban.chakraborty@qlogic.com>

Modify 82xx driver to support new adapter - Qlogic 83XX CNA
Group all the HW data in a seperate data structure

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |   86 +++-----
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c    |   25 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |   69 +++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h    |   25 ++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c     |  243 +++++++++++---------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h     |  182 ++++++++++++++-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c   |   41 ++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   20 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  169 +++++++++-----
 9 files changed, 557 insertions(+), 303 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 00eb99c..e7bc324 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -35,9 +35,9 @@
 #include "qlcnic_hdr.h"
 
 #define _QLCNIC_LINUX_MAJOR 5
-#define _QLCNIC_LINUX_MINOR 0
+#define _QLCNIC_LINUX_MINOR 1
 #define _QLCNIC_LINUX_SUBVERSION 29
-#define QLCNIC_LINUX_VERSIONID  "5.0.29"
+#define QLCNIC_LINUX_VERSIONID  "5.1.29"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -458,11 +458,36 @@ struct qlcnic_hardware_context {
 	u8 pci_func;
 	u8 linkup;
 	u8 loopback_state;
+	u8 beacon_state;
+	u8 has_link_events;
+	u8 fw_type;
+	u8 physical_port;
+	u8 reset_context;
+	u8 msix_supported;
+	u8 max_mac_filters;
+	u8 mc_enabled;
+	u8 max_mc_count;
+	u8 diag_test;
+	char diag_cnt;
+
 	u16 port_type;
 	u16 board_type;
 
-	u8 beacon_state;
+	u16 link_speed;
+	u16 link_duplex;
+	u16 link_autoneg;
+	u16 module_type;
+
+	u16 op_mode;
+	u16 switch_mode;
+	u16 max_tx_ques;
+	u16 max_rx_ques;
+	u16 max_mtu;
+	u16 msg_enable;
 
+	u32 capabilities;
+	u32 temp;
+	u32 int_vec_bit;
 	u32 fw_hal_version;
 	struct qlcnic_hardware_ops *hw_ops;
 	struct qlcnic_nic_intr_coalesce coal;
@@ -525,6 +550,7 @@ struct qlcnic_host_sds_ring {
 } ____cacheline_internodealigned_in_smp;
 
 struct qlcnic_host_tx_ring {
+	u16 ctx_id;
 	u32 producer;
 	u32 sw_consumer;
 	u32 num_desc;
@@ -997,49 +1023,22 @@ struct qlcnic_adapter {
 
 	u8 max_rds_rings;
 	u8 max_sds_rings;
-	u8 msix_supported;
 	u8 portnum;
-	u8 physical_port;
-	u8 reset_context;
 
-	u8 mc_enabled;
-	u8 max_mc_count;
 	u8 fw_wait_cnt;
 	u8 fw_fail_cnt;
 	u8 tx_timeo_cnt;
 	u8 need_fw_reset;
 
-	u8 has_link_events;
-	u8 fw_type;
-	u16 tx_context_id;
 	u16 is_up;
-
-	u16 link_speed;
-	u16 link_duplex;
-	u16 link_autoneg;
-	u16 module_type;
-
-	u16 op_mode;
-	u16 switch_mode;
-	u16 max_tx_ques;
-	u16 max_rx_ques;
-	u16 max_mtu;
 	u16 pvid;
 
-	u32 capabilities;
 	u32 irq;
-	u32 temp;
-
-	u32 int_vec_bit;
 	u32 heartbeat;
 
-	u8 max_mac_filters;
 	u8 dev_state;
-	u8 diag_test;
-	char diag_cnt;
 	u8 reset_ack_timeo;
 	u8 dev_init_timeo;
-	u16 msg_enable;
 
 	u8 mac_addr[ETH_ALEN];
 
@@ -1063,7 +1062,6 @@ struct qlcnic_adapter {
 
 	struct delayed_work fw_work;
 
-
 	struct qlcnic_filter_hash fhash;
 
 	spinlock_t tx_clean_lock;
@@ -1589,30 +1587,6 @@ struct qlcnic_brdinfo {
 	char short_name[QLCNIC_MAX_BOARD_NAME_LEN];
 };
 
-static const struct qlcnic_brdinfo qlcnic_boards[] = {
-	{0x1077, 0x8020, 0x1077, 0x203,
-		"8200 Series Single Port 10GbE Converged Network Adapter "
-		"(TCP/IP Networking)"},
-	{0x1077, 0x8020, 0x1077, 0x207,
-		"8200 Series Dual Port 10GbE Converged Network Adapter "
-		"(TCP/IP Networking)"},
-	{0x1077, 0x8020, 0x1077, 0x20b,
-		"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
-	{0x1077, 0x8020, 0x1077, 0x20c,
-		"3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"},
-	{0x1077, 0x8020, 0x1077, 0x20f,
-		"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
-	{0x1077, 0x8020, 0x103c, 0x3733,
-		"NC523SFP 10Gb 2-port Server Adapter"},
-	{0x1077, 0x8020, 0x103c, 0x3346,
-		"CN1000Q Dual Port Converged Network Adapter"},
-	{0x1077, 0x8020, 0x1077, 0x210,
-		"QME8242-k 10GbE Dual Port Mezzanine Card"},
-	{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
-};
-
-#define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards)
-
 static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
 {
 	if (likely(tx_ring->producer < tx_ring->sw_consumer))
@@ -1677,7 +1651,7 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
 }
 
 #define QLCDB(adapter, lvl, _fmt, _args...) do {	\
-	if (NETIF_MSG_##lvl & adapter->msg_enable)	\
+	if (NETIF_MSG_##lvl & adapter->ahw->msg_enable) \
 		printk(KERN_INFO "%s: %s: " _fmt,	\
 			 dev_name(&adapter->pdev->dev),	\
 			__func__, ##_args);		\
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index 75b8995..4e57edb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -453,8 +453,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
 		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
 		tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp;
 
-		adapter->tx_context_id =
-			le16_to_cpu(prsp->context_id);
+		tx_ring->ctx_id = le16_to_cpu(prsp->context_id);
 	} else {
 		dev_err(&adapter->pdev->dev,
 			"Failed to create tx ctx in firmware%d\n", err);
@@ -476,7 +475,7 @@ qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
 	struct qlcnic_cmd_args cmd;
 
 	memset(&cmd, 0, sizeof(cmd));
-	cmd.req.arg1 = adapter->tx_context_id;
+	cmd.req.arg1 = adapter->tx_ring->ctx_id;
 	cmd.req.arg2 = QLCNIC_DESTROY_CTX_RESET;
 	cmd.req.arg3 = 0;
 	cmd.req.cmd = QLCNIC_CDRP_CMD_DESTROY_TX_CTX;
@@ -756,7 +755,7 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
 	struct qlcnic_info *nic_info;
 	size_t nic_size = sizeof(struct qlcnic_info);
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return err;
 
 	nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
@@ -856,7 +855,7 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
 	u32 arg1;
 	struct qlcnic_cmd_args cmd;
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC ||
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC ||
 		!(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
 		return err;
 
@@ -896,8 +895,8 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
 	if (esw_stats == NULL)
 		return -ENOMEM;
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
-	    func != adapter->ahw->pci_func) {
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC &&
+		func != adapter->ahw->pci_func) {
 		dev_err(&adapter->pdev->dev,
 			"Not privilege to query stats for func=%d", func);
 		return -EIO;
@@ -1008,7 +1007,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
 
 	if (esw_stats == NULL)
 		return -ENOMEM;
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return -EIO;
 	if (adapter->npars == NULL)
 		return -EIO;
@@ -1059,7 +1058,7 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
 	u32 arg1;
 	struct qlcnic_cmd_args cmd;
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return -EIO;
 
 	if (func_esw == QLCNIC_STATS_PORT) {
@@ -1132,7 +1131,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
 	struct qlcnic_cmd_args cmd;
 	u8 pci_func;
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return err;
 	pci_func = esw_cfg->pci_func;
 	arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
@@ -1147,7 +1146,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
 	case QLCNIC_PORT_DEFAULTS:
 		arg1 |= (BIT_4 | BIT_6 | BIT_7);
 		arg2 |= (BIT_0 | BIT_1);
-		if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+		if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
 			arg2 |= (BIT_2 | BIT_3);
 		if (!(esw_cfg->discard_tagged))
 			arg1 &= ~BIT_4;
@@ -1200,10 +1199,10 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
 {
 	u32 arg1, arg2;
 	u8 phy_port;
-	if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
 		phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
 	else
-		phy_port = adapter->physical_port;
+		phy_port = adapter->ahw->physical_port;
 	arg1 = phy_port;
 	arg1 |= (esw_cfg->pci_func << 8);
 	if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index c81fcf8..130408e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -210,9 +210,9 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 				     ADVERTISED_1000baseT_Half |
 				     ADVERTISED_1000baseT_Full);
 
-		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
-		ecmd->duplex = adapter->link_duplex;
-		ecmd->autoneg = adapter->link_autoneg;
+		ethtool_cmd_speed_set(ecmd, ahw->link_speed);
+		ecmd->duplex = ahw->link_duplex;
+		ecmd->autoneg = ahw->link_autoneg;
 
 	} else if (ahw->port_type == QLCNIC_XGBE) {
 		u32 val;
@@ -226,10 +226,10 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 			ecmd->advertising = ADVERTISED_10000baseT_Full;
 		}
 
-		if (netif_running(dev) && adapter->has_link_events) {
-			ethtool_cmd_speed_set(ecmd, adapter->link_speed);
-			ecmd->autoneg = adapter->link_autoneg;
-			ecmd->duplex = adapter->link_duplex;
+		if (netif_running(dev) && ahw->has_link_events) {
+			ethtool_cmd_speed_set(ecmd, ahw->link_speed);
+			ecmd->autoneg = ahw->link_autoneg;
+			ecmd->duplex = ahw->link_duplex;
 			goto skip;
 		}
 
@@ -240,7 +240,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		return -EIO;
 
 skip:
-	ecmd->phy_address = adapter->physical_port;
+	ecmd->phy_address = adapter->ahw->physical_port;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
 	switch (ahw->board_type) {
@@ -256,7 +256,7 @@ skip:
 		ecmd->supported |= SUPPORTED_TP;
 		ecmd->advertising |= ADVERTISED_TP;
 		ecmd->port = PORT_TP;
-		ecmd->autoneg =  adapter->link_autoneg;
+		ecmd->autoneg =  ahw->link_autoneg;
 		break;
 	case QLCNIC_BRDTYPE_P3P_IMEZ:
 	case QLCNIC_BRDTYPE_P3P_XG_LOM:
@@ -272,7 +272,7 @@ skip:
 		ecmd->advertising |= ADVERTISED_TP;
 		ecmd->supported |= SUPPORTED_TP;
 		check_sfp_module = netif_running(dev) &&
-			adapter->has_link_events;
+			ahw->has_link_events;
 	case QLCNIC_BRDTYPE_P3P_10G_XFP:
 		ecmd->supported |= SUPPORTED_FIBRE;
 		ecmd->advertising |= ADVERTISED_FIBRE;
@@ -287,7 +287,7 @@ skip:
 				(ADVERTISED_FIBRE | ADVERTISED_TP);
 			ecmd->port = PORT_FIBRE;
 			check_sfp_module = netif_running(dev) &&
-				adapter->has_link_events;
+				ahw->has_link_events;
 		} else {
 			ecmd->autoneg = AUTONEG_ENABLE;
 			ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
@@ -303,7 +303,7 @@ skip:
 	}
 
 	if (check_sfp_module) {
-		switch (adapter->module_type) {
+		switch (adapter->ahw->module_type) {
 		case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
 		case LINKEVENT_MODULE_OPTICAL_SRLR:
 		case LINKEVENT_MODULE_OPTICAL_LRM:
@@ -361,9 +361,9 @@ qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	else if (ret)
 		return -EIO;
 
-	adapter->link_speed = ethtool_cmd_speed(ecmd);
-	adapter->link_duplex = ecmd->duplex;
-	adapter->link_autoneg = ecmd->autoneg;
+	adapter->ahw->link_speed = ethtool_cmd_speed(ecmd);
+	adapter->ahw->link_duplex = ecmd->duplex;
+	adapter->ahw->link_autoneg = ecmd->autoneg;
 
 	if (!netif_running(dev))
 		return 0;
@@ -514,11 +514,11 @@ static void qlcnic_get_channels(struct net_device *dev,
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 
 	channel->max_rx = rounddown_pow_of_two(min_t(int,
-			adapter->max_rx_ques, num_online_cpus()));
-	channel->max_tx = adapter->max_tx_ques;
+			adapter->ahw->max_rx_ques, num_online_cpus()));
+	channel->max_tx = adapter->ahw->max_tx_ques;
 
 	channel->rx_count = adapter->max_sds_rings;
-	channel->tx_count = adapter->max_tx_ques;
+	channel->tx_count = adapter->ahw->max_tx_ques;
 }
 
 static int qlcnic_set_channels(struct net_device *dev,
@@ -547,7 +547,7 @@ qlcnic_get_pauseparam(struct net_device *netdev,
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
-	int port = adapter->physical_port;
+	int port = adapter->ahw->physical_port;
 	__u32 val;
 
 	if (ahw->port_type == QLCNIC_GBE) {
@@ -593,7 +593,7 @@ qlcnic_set_pauseparam(struct net_device *netdev,
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
-	int port = adapter->physical_port;
+	int port = adapter->ahw->physical_port;
 	__u32 val;
 
 	/* read mode */
@@ -707,7 +707,7 @@ static int qlcnic_irq_test(struct net_device *netdev)
 	if (ret)
 		goto clear_it;
 
-	adapter->diag_cnt = 0;
+	adapter->ahw->diag_cnt = 0;
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.req.cmd = QLCNIC_CDRP_CMD_INTRPT_TEST;
 	cmd.req.arg1 = adapter->ahw->pci_func;
@@ -719,7 +719,7 @@ static int qlcnic_irq_test(struct net_device *netdev)
 
 	msleep(10);
 
-	ret = !adapter->diag_cnt;
+	ret = !adapter->ahw->diag_cnt;
 
 done:
 	qlcnic_diag_free_res(netdev, max_sds_rings);
@@ -765,7 +765,7 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
 		qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
 		skb_put(skb, QLCNIC_ILB_PKT_SIZE);
 
-		adapter->diag_cnt = 0;
+		adapter->ahw->diag_cnt = 0;
 		qlcnic_xmit_frame(skb, adapter->netdev);
 
 		loop = 0;
@@ -774,11 +774,11 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
 			qlcnic_process_rcv_ring_diag(sds_ring);
 			if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
 				break;
-		} while (!adapter->diag_cnt);
+		} while (!adapter->ahw->diag_cnt);
 
 		dev_kfree_skb_any(skb);
 
-		if (!adapter->diag_cnt)
+		if (!adapter->ahw->diag_cnt)
 			QLCDB(adapter, DRV,
 			"LB Test: packet #%d was not received\n", i + 1);
 		else
@@ -800,18 +800,19 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	int max_sds_rings = adapter->max_sds_rings;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct qlcnic_host_sds_ring *sds_ring;
 	int loop = 0;
 	int ret;
 
-	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
+	if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
 		netdev_info(netdev, "Firmware is not loopback test capable\n");
 		return -EOPNOTSUPP;
 	}
 
 	QLCDB(adapter, DRV, "%s loopback test in progress\n",
 		   mode == QLCNIC_ILB_MODE ? "internal" : "external");
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
+	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
 		netdev_warn(netdev, "Loopback test not supported for non "
 				"privilege function\n");
 		return 0;
@@ -830,7 +831,7 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
 	if (ret)
 		goto free_res;
 
-	adapter->diag_cnt = 0;
+	ahw->diag_cnt = 0;
 	do {
 		msleep(500);
 		qlcnic_process_rcv_ring_diag(sds_ring);
@@ -839,11 +840,11 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
 				" configure request\n");
 			ret = -QLCNIC_FW_NOT_RESPOND;
 			goto free_res;
-		} else if (adapter->diag_cnt) {
-			ret = adapter->diag_cnt;
+		} else if (ahw->diag_cnt) {
+			ret = ahw->diag_cnt;
 			goto free_res;
 		}
-	} while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
+	} while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
 
 	ret = qlcnic_do_lb_test(adapter, mode);
 
@@ -1032,7 +1033,7 @@ static int qlcnic_set_led(struct net_device *dev,
 	int max_sds_rings = adapter->max_sds_rings;
 	int err = -EIO, active = 1;
 
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
+	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
 		netdev_warn(dev, "LED test not supported for non "
 				"privilege function\n");
 		return -EOPNOTSUPP;
@@ -1211,14 +1212,14 @@ static u32 qlcnic_get_msglevel(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	return adapter->msg_enable;
+	return adapter->ahw->msg_enable;
 }
 
 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	adapter->msg_enable = msglvl;
+	adapter->ahw->msg_enable = msglvl;
 }
 
 static int
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
index 0bee9f7..808b445 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
@@ -517,6 +517,28 @@ enum {
 #define MIU_TEST_AGT_ADDR_MASK		0xfffffff8
 #define MIU_TEST_AGT_UPPER_ADDR(off)	(0)
 
+#define QLCNIC_MS_CTRL     0x41000090
+#define QLCNIC_MS_ADDR_LO  0x41000094
+#define QLCNIC_MS_ADDR_HI  0x41000098
+
+#define QLCNIC_MS_WRTDATA_LO       0x410000A0
+#define QLCNIC_MS_WRTDATA_HI       0x410000A4
+#define QLCNIC_MS_WRTDATA_ULO      0x410000B0
+#define QLCNIC_MS_WRTDATA_UHI      0x410000B4
+
+#define QLCNIC_MS_RDDATA_LO        0x410000A8
+#define QLCNIC_MS_RDDATA_HI        0x410000AC
+#define QLCNIC_MS_RDDATA_ULO       0x410000B8
+#define QLCNIC_MS_RDDATA_UHI       0x410000BC
+
+static const u32 QLCNIC_MS_READ_DATA[] = {
+	0x410000A8, 0x410000AC, 0x410000B8, 0x410000BC};
+
+#define QLC_TA_WRITE_ENABLE (TA_CTL_ENABLE | TA_CTL_WRITE)
+#define QLC_TA_WRITE_START (TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE)
+#define QLC_TA_START_ENABLE (TA_CTL_START | TA_CTL_ENABLE)
+
+
 /* XG Link status */
 #define XG_LINK_UP	0x10
 #define XG_LINK_DOWN	0x20
@@ -715,6 +737,9 @@ enum {
 #define QLCNIC_HEARTBEAT_PERIOD_MSECS	200
 #define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT	45
 
+#define QLCNIC_MAX_MC_COUNT		38
+#define QLCNIC_WATCHDOG_TIMEOUTVALUE	5
+
 #define	ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
 #define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index ee4cd43..f31022a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -279,6 +279,35 @@ static const u32 msi_tgt_status[8] = {
 
 #define QLCNIC_PCIE_SEM_TIMEOUT	10000
 
+static void
+qlcnic_read_dump_reg(u32 addr, void __iomem *bar0, u32 *data)
+{
+	u32 dest;
+	void __iomem *val;
+
+	dest = addr & 0xFFFF0000;
+	val = bar0 + QLCNIC_FW_DUMP_REG1;
+	writel(dest, val);
+	readl(val);
+	val = bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr);
+	*data = readl(val);
+}
+
+static void
+qlcnic_write_dump_reg(u32 addr, void __iomem *bar0, u32 data)
+{
+	u32 dest;
+	void __iomem *val;
+
+	dest = addr & 0xFFFF0000;
+	val = bar0 + QLCNIC_FW_DUMP_REG1;
+	writel(dest, val);
+	readl(val);
+	val = bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr);
+	writel(data, val);
+	readl(val);
+}
+
 int
 qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
 {
@@ -309,6 +338,23 @@ qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem)
 	QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
 }
 
+u32 qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
+{
+	u32 data;
+
+	if (QLCNIC_IS_82XX(adapter))
+		qlcnic_read_dump_reg(addr, adapter->ahw->pci_base0, &data);
+	else
+		return -EIO;
+	return data;
+}
+
+void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
+{
+	if (QLCNIC_IS_82XX(adapter))
+		qlcnic_write_dump_reg(addr, adapter->ahw->pci_base0, data);
+}
+
 static int
 qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
 		struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
@@ -443,7 +489,7 @@ void qlcnic_set_multi(struct net_device *netdev)
 	}
 
 	if ((netdev->flags & IFF_ALLMULTI) ||
-	    (netdev_mc_count(netdev) > adapter->max_mc_count)) {
+	    (netdev_mc_count(netdev) > adapter->ahw->max_mc_count)) {
 		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
 		goto send_fw_cmd;
 	}
@@ -1004,36 +1050,19 @@ qlcnic_get_ioaddr(struct qlcnic_hardware_context *ahw, u32 offset)
 	return addr;
 }
 
-
-static int
-qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter,
-		u64 addr, u32 *start)
-{
-	u32 window;
-
-	window = OCM_WIN_P3P(addr);
-
-	writel(window, adapter->ahw->ocm_win_crb);
-	/* read back to flush */
-	readl(adapter->ahw->ocm_win_crb);
-
-	*start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
-	return 0;
-}
-
 static int
-qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
-		u64 *data, int op)
+qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u32 window,
+			     u64 off, u64 *data, int op)
 {
 	void __iomem *addr;
-	int ret;
 	u32 start;
 
 	mutex_lock(&adapter->ahw->mem_lock);
 
-	ret = qlcnic_pci_set_window_2M(adapter, off, &start);
-	if (ret != 0)
-		goto unlock;
+	writel(window, adapter->ahw->ocm_win_crb);
+	/* read back to flush */
+	readl(adapter->ahw->ocm_win_crb);
+	start = QLCNIC_PCI_OCM0_2M + off;
 
 	addr = adapter->ahw->pci_base0 + start;
 
@@ -1042,10 +1071,12 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
 	else		/* write */
 		writeq(*data, addr);
 
-unlock:
-	mutex_unlock(&adapter->ahw->mem_lock);
+	/* Set window to 0 */
+	writel(0, adapter->ahw->ocm_win_crb);
+	readl(adapter->ahw->ocm_win_crb);
 
-	return ret;
+	mutex_unlock(&adapter->ahw->mem_lock);
+	return 0;
 }
 
 void
@@ -1072,54 +1103,75 @@ qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
 
 #define MAX_CTL_CHECK   1000
 
+/* Set MS memory control data for different chip type*/
+static void
+qlcnic_set_ms_controls(struct qlcnic_adapter *adapter, u64 off,
+		       struct qlcnic_ms_reg_ctrl *ms)
+{
+	ms->control = QLCNIC_MS_CTRL;
+	ms->low = QLCNIC_MS_ADDR_LO;
+	ms->hi = QLCNIC_MS_ADDR_HI;
+	if (off & 0xf) {
+		ms->wd[0] = QLCNIC_MS_WRTDATA_LO;
+		ms->rd[0] = QLCNIC_MS_RDDATA_LO;
+		ms->wd[1] = QLCNIC_MS_WRTDATA_HI;
+		ms->rd[1] = QLCNIC_MS_RDDATA_HI;
+		ms->wd[2] = QLCNIC_MS_WRTDATA_ULO;
+		ms->wd[3] = QLCNIC_MS_WRTDATA_UHI;
+		ms->rd[2] = QLCNIC_MS_RDDATA_ULO;
+		ms->rd[3] = QLCNIC_MS_RDDATA_UHI;
+	} else {
+		ms->wd[0] = QLCNIC_MS_WRTDATA_ULO;
+		ms->rd[0] = QLCNIC_MS_RDDATA_ULO;
+		ms->wd[1] = QLCNIC_MS_WRTDATA_UHI;
+		ms->rd[1] = QLCNIC_MS_RDDATA_UHI;
+		ms->wd[2] = QLCNIC_MS_WRTDATA_LO;
+		ms->wd[3] = QLCNIC_MS_WRTDATA_HI;
+		ms->rd[2] = QLCNIC_MS_RDDATA_LO;
+		ms->rd[3] = QLCNIC_MS_RDDATA_HI;
+	}
+
+	ms->ocm_window = OCM_WIN_P3P(off);
+	ms->off = GET_MEM_OFFS_2M(off);
+}
+
 int
 qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter,
-		u64 off, u64 data)
+			u64 off, u64 data)
 {
-	int i, j, ret;
+	int j, ret = 0;
 	u32 temp, off8;
-	void __iomem *mem_crb;
+	struct qlcnic_ms_reg_ctrl ms;
 
 	/* Only 64-bit aligned access */
 	if (off & 7)
 		return -EIO;
 
-	/* P3 onward, test agent base for MIU and SIU is same */
-	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
-			  QLCNIC_ADDR_QDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
-					    QLCNIC_CRB_QDR_NET +
-					    MIU_TEST_AGT_BASE);
-		goto correct;
-	}
+	memset(&ms, 0, sizeof(struct qlcnic_ms_reg_ctrl));
+	if (!((ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
+		QLCNIC_ADDR_QDR_NET_MAX)) ||
+			(ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET,
+				QLCNIC_ADDR_DDR_NET_MAX))))
+		return -EIO;
 
-	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
-					    QLCNIC_CRB_DDR_NET +
-					    MIU_TEST_AGT_BASE);
-		goto correct;
-	}
+	qlcnic_set_ms_controls(adapter, off, &ms);
 
 	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX))
-		return qlcnic_pci_mem_access_direct(adapter, off, &data, 1);
-
-	return -EIO;
+		return qlcnic_pci_mem_access_direct(adapter, ms.ocm_window,
+						    ms.off, &data, 1);
 
-correct:
 	off8 = off & ~0xf;
 
 	mutex_lock(&adapter->ahw->mem_lock);
 
-	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
-	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
+	qlcnic_ind_wr(adapter, ms.low, off8);
+	qlcnic_ind_wr(adapter, ms.hi, 0);
 
-	i = 0;
-	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
-	writel((TA_CTL_START | TA_CTL_ENABLE),
-	       (mem_crb + TEST_AGT_CTRL));
+	qlcnic_ind_wr(adapter, ms.control, TA_CTL_ENABLE);
+	qlcnic_ind_wr(adapter, ms.control, QLC_TA_START_ENABLE);
 
 	for (j = 0; j < MAX_CTL_CHECK; j++) {
-		temp = readl(mem_crb + TEST_AGT_CTRL);
+		temp = qlcnic_ind_rd(adapter, ms.control);
 		if ((temp & TA_CTL_BUSY) == 0)
 			break;
 	}
@@ -1129,24 +1181,18 @@ correct:
 		goto done;
 	}
 
-	i = (off & 0xf) ? 0 : 2;
-	writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
-	       mem_crb + MIU_TEST_AGT_WRDATA(i));
-	writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
-	       mem_crb + MIU_TEST_AGT_WRDATA(i+1));
-	i = (off & 0xf) ? 2 : 0;
-
-	writel(data & 0xffffffff,
-	       mem_crb + MIU_TEST_AGT_WRDATA(i));
-	writel((data >> 32) & 0xffffffff,
-	       mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+	/* This is the modify part of read-modify-write */
+	qlcnic_ind_wr(adapter, ms.wd[0], qlcnic_ind_rd(adapter, ms.rd[0]));
+	qlcnic_ind_wr(adapter, ms.wd[1], qlcnic_ind_rd(adapter, ms.rd[1]));
+	/* This is the write part of read-modify-write */
+	qlcnic_ind_wr(adapter, ms.wd[2], data & 0xffffffff);
+	qlcnic_ind_wr(adapter, ms.wd[3], (data >> 32) & 0xffffffff);
 
-	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
-	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
-	       (mem_crb + TEST_AGT_CTRL));
+	qlcnic_ind_wr(adapter, ms.control, QLC_TA_WRITE_ENABLE);
+	qlcnic_ind_wr(adapter, ms.control, QLC_TA_WRITE_START);
 
 	for (j = 0; j < MAX_CTL_CHECK; j++) {
-		temp = readl(mem_crb + TEST_AGT_CTRL);
+		temp = qlcnic_ind_rd(adapter, ms.control);
 		if ((temp & TA_CTL_BUSY) == 0)
 			break;
 	}
@@ -1154,7 +1200,7 @@ correct:
 	if (j >= MAX_CTL_CHECK) {
 		if (printk_ratelimit())
 			dev_err(&adapter->pdev->dev,
-					"failed to write through agent\n");
+				"failed to write through agent\n");
 		ret = -EIO;
 	} else
 		ret = 0;
@@ -1166,53 +1212,41 @@ done:
 }
 
 int
-qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter,
-		u64 off, u64 *data)
+qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
 {
 	int j, ret;
 	u32 temp, off8;
 	u64 val;
-	void __iomem *mem_crb;
+	struct qlcnic_ms_reg_ctrl ms;
 
 	/* Only 64-bit aligned access */
 	if (off & 7)
 		return -EIO;
+	if (!((ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
+		QLCNIC_ADDR_QDR_NET_MAX)) ||
+			(ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET,
+				QLCNIC_ADDR_DDR_NET_MAX))))
+		return -EIO ;
 
-	/* P3 onward, test agent base for MIU and SIU is same */
-	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
-			  QLCNIC_ADDR_QDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
-					    QLCNIC_CRB_QDR_NET +
-					    MIU_TEST_AGT_BASE);
-		goto correct;
-	}
-
-	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) {
-		mem_crb = qlcnic_get_ioaddr(adapter->ahw,
-					    QLCNIC_CRB_DDR_NET +
-					    MIU_TEST_AGT_BASE);
-		goto correct;
-	}
+	memset(&ms, 0, sizeof(struct qlcnic_ms_reg_ctrl));
+	qlcnic_set_ms_controls(adapter, off, &ms);
 
-	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) {
-		return qlcnic_pci_mem_access_direct(adapter,
-				off, data, 0);
-	}
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX))
+		return qlcnic_pci_mem_access_direct(adapter, ms.ocm_window,
+						    ms.off, data, 0);
 
-	return -EIO;
+	mutex_lock(&adapter->ahw->mem_lock);
 
-correct:
 	off8 = off & ~0xf;
 
-	mutex_lock(&adapter->ahw->mem_lock);
+	qlcnic_ind_wr(adapter, ms.low, off8);
+	qlcnic_ind_wr(adapter, ms.hi, 0);
 
-	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
-	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
-	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
-	writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
+	qlcnic_ind_wr(adapter, ms.control, TA_CTL_ENABLE);
+	qlcnic_ind_wr(adapter, ms.control, QLC_TA_START_ENABLE);
 
 	for (j = 0; j < MAX_CTL_CHECK; j++) {
-		temp = readl(mem_crb + TEST_AGT_CTRL);
+		temp = qlcnic_ind_rd(adapter, ms.control);
 		if ((temp & TA_CTL_BUSY) == 0)
 			break;
 	}
@@ -1223,13 +1257,10 @@ correct:
 					"failed to read through agent\n");
 		ret = -EIO;
 	} else {
-		off8 = MIU_TEST_AGT_RDDATA_LO;
-		if (off & 0xf)
-			off8 = MIU_TEST_AGT_RDDATA_UPPER_LO;
 
-		temp = readl(mem_crb + off8 + 4);
+		temp = qlcnic_ind_rd(adapter, ms.rd[3]);
 		val = (u64)temp << 32;
-		val |= readl(mem_crb + off8);
+		val |= qlcnic_ind_rd(adapter, ms.rd[2]);
 		*data = val;
 		ret = 0;
 	}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index 7dab9e2..8f16098 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -3,18 +3,168 @@
 
 #include "qlcnic.h"
 
+#define MASK(n) ((1ULL<<(n))-1)
+#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
+#define OCM_WIN_83XX(addr)	(addr & 0xFFE0000)
+
+#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
+#define GET_83XX_OCM_OFFSET(addr)	(addr & MASK(17))
+
+#define CRB_BLK(off)	((off >> 20) & 0x3f)
+#define CRB_SUBBLK(off)	((off >> 16) & 0xf)
+#define CRB_WINDOW_2M	(0x130060)
+#define CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
+#define CRB_INDIRECT_2M	(0x1e0000UL)
+
+
+
 /* List of PCI device IDs */
-#define PCI_DEVICE_ID_QLOGIC_QLE824X  0x8020
-#define QLCNIC_P3P_BAR0_LENGTH		0x00200000UL
+#define PCI_DEVICE_ID_QLOGIC_QLE824X	0x8020
+#define PCI_DEVICE_ID_QLOGIC_QLE834X	0x8030
+#define QLCNIC_82XX_BAR0_LENGTH	0x00200000UL
+#define QLCNIC_83XX_BAR0_LENGTH	0x4000
+
+#define QLCNIC_IS_83XX(adapter)	\
+	(((adapter)->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? 1 : 0)
+
+#define QLCNIC_IS_82XX(adapter)	\
+	(((adapter)->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X) ? 1 : 0)
+
+struct qlcnic_ms_reg_ctrl {
+	u32 ocm_window;
+	u32 control;
+	u32 hi;
+	u32 low;
+	u32 rd[4];
+	u32 wd[4];
+	u64 off;
+};
+
+/* Read from an address offset from BAR0, existing registers */
+#define QLCRD(a, addr)			\
+	readl(((a)->ahw->pci_base0) + ((a)->ahw->reg_tbl[addr]))
+/* Write to an address offset from BAR0, existing registers */
+#define QLCWR(a, addr, value)		\
+	writel(value, ((a)->ahw->pci_base0) + ((a)->ahw->reg_tbl[addr]))
+
+/* Read from a direct address offset from BAR0, additional registers */
+#define QLCRDX(ahw, addr)			\
+	readl(((ahw)->pci_base0) + ((ahw)->ext_reg_tbl[addr]))
+/* Write to a direct address offset from BAR0, additional registers */
+#define QLCWRX(ahw, addr, value)		\
+	writel(value, (((ahw)->pci_base0) + ((ahw)->ext_reg_tbl[addr])))
+
+#define QLCNIC_READ_LINK_SPEED(adapter, pcifn, err)\
+	QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn), err)
+
+/* Mailbox ownership */
+#define QLCNIC_GET_OWNER(val)	\
+	((val) & (BIT_0 | BIT_1))
+#define QLCNIC_SET_OWNER	1
+#define QLCNIC_CLR_OWNER	0
+#define QLCNIC_MBX_TIMEOUT	10000
+
+#define QLCNIC_CMD_CONFIGURE_IP_ADDR		0x1
+#define QLCNIC_CMD_CONFIG_INTRPT		0x2
+#define QLCNIC_CMD_CREATE_RX_CTX		0x7
+#define QLCNIC_CMD_DESTROY_RX_CTX		0x8
+#define QLCNIC_CMD_CREATE_TX_CTX		0x9
+#define QLCNIC_CMD_DESTROY_TX_CTX		0xa
+#define QLCNIC_CMD_CONFIGURE_LRO		0xC
+#define QLCNIC_CMD_CONFIGURE_MAC_LEARNING	0xD
+#define QLCNIC_CMD_GET_STATISTICS		0xF
+#define QLCNIC_CMD_INTRPT_TEST			0x11
+#define QLCNIC_CMD_SET_MTU			0x12
+#define QLCNIC_CMD_READ_PHY			0x13
+#define QLCNIC_CMD_WRITE_PHY			0x14
+#define QLCNIC_CMD_READ_HW_REG			0x15
+#define QLCNIC_CMD_GET_FLOW_CTL			0x16
+#define QLCNIC_CMD_SET_FLOW_CTL			0x17
+#define QLCNIC_CMD_READ_MAX_MTU			0x18
+#define QLCNIC_CMD_READ_MAX_LRO			0x19
+#define QLCNIC_CMD_MAC_ADDRESS			0x1f
+#define QLCNIC_CMD_GET_PCI_INFO			0x20
+#define QLCNIC_CMD_GET_NIC_INFO			0x21
+#define QLCNIC_CMD_SET_NIC_INFO			0x22
+#define QLCNIC_CMD_GET_ESWITCH_CAPABILITY	0x24
+#define QLCNIC_CMD_TOGGLE_ESWITCH		0x25
+#define QLCNIC_CMD_GET_ESWITCH_STATUS		0x26
+#define QLCNIC_CMD_SET_PORTMIRRORING		0x27
+#define QLCNIC_CMD_CONFIGURE_ESWITCH		0x28
+#define QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG	0x29
+#define QLCNIC_CMD_GET_ESWITCH_STATS		0x2a
+#define QLCNIC_CMD_CONFIG_PORT			0x2e
+#define QLCNIC_CMD_TEMP_SIZE			0x2f
+#define QLCNIC_CMD_GET_TEMP_HDR			0x30
+#define QLCNIC_CMD_GET_MAC_STATS		0x37
+#define QLCNIC_CMD_CONFIGURE_RSS		0x41
+#define QLCNIC_CMD_CONFIG_INTR_COAL		0x43
+#define QLCNIC_CMD_CONFIGURE_LED		0x44
+#define QLCNIC_CMD_CONFIG_MAC_VLAN		0x45
+#define QLCNIC_CMD_GET_LINK_EVENT		0x48
+#define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE	0x49
+#define QLCNIC_CMD_CONFIGURE_HW_LRO		0x4A
+#define QLCNIC_CMD_INIT_NIC_FUNC		0x60
+#define QLCNIC_CMD_STOP_NIC_FUNC		0x61
+#define QLCNIC_CMD_IDC_ACK			0x63
+#define QLCNIC_CMD_SET_PORT_CONFIG		0x66
+#define QLCNIC_CMD_GET_PORT_CONFIG		0x67
+#define QLCNIC_CMD_GET_LINK_STATUS		0x68
+#define QLCNIC_CMD_SET_LED_CONFIG		0x69
+#define QLCNIC_CMD_GET_LED_CONFIG		0x6A
+
+#define QLC_TCP_HDR_SIZE            20
+#define QLC_TCP_TS_OPTION_SIZE      12
+#define QLC_TCP_TS_HDR_SIZE         (QLC_TCP_HDR_SIZE + QLC_TCP_TS_OPTION_SIZE)
+
+#define QLCNIC_INTRPT_INTX	1
+#define QLCNIC_INTRPT_MSIX	3
+#define QLCNIC_INTRPT_ADD	1
+#define QLCNIC_INTRPT_DEL	2
+
+#define QLCNIC_GET_CURRENT_MAC	1
+#define QLCNIC_SET_STATION_MAC	2
+#define QLCNIC_GET_DEFAULT_MAC	3
+#define QLCNIC_GET_FAC_DEF_MAC	4
+#define QLCNIC_SET_FAC_DEF_MAC	5
+
+#define QLCNIC_MBX_LINK_EVENT		0x8001
+#define QLCNIC_MBX_COMP_EVENT		0x8100
+#define QLCNIC_MBX_REQUEST_EVENT	0x8101
+#define QLCNIC_MBX_TIME_EXTEND_EVENT	0x8102
+#define QLCNIC_MBX_SFP_INSERT_EVENT	0x8130
+#define QLCNIC_MBX_SFP_REMOVE_EVENT	0x8131
+
+struct qlcnic_mailbox_metadata {
+	u32 cmd;
+	u32 in_args;
+	u32 out_args;
+};
 
 #define QLCNIC_BAR_LENGTH(dev_id, bar)			\
 do {							\
-	if (dev_id == PCI_DEVICE_ID_QLOGIC_QLE824X)\
-		*bar = QLCNIC_P3P_BAR0_LENGTH;		\
-	else						\
+	switch (dev_id) {				\
+	case PCI_DEVICE_ID_QLOGIC_QLE824X:		\
+		*bar = QLCNIC_82XX_BAR0_LENGTH;		\
+		break;					\
+	case PCI_DEVICE_ID_QLOGIC_QLE834X:		\
+		*bar = QLCNIC_83XX_BAR0_LENGTH;	\
+		break;					\
+	default:					\
 		*bar = 0;				\
+	}						\
 } while (0)
 
+/* Make a handle with reference handle (0:14) and RDS ring
+ * number (15).
+ */
+#define QLCNIC_MAKE_REF_HANDLE(adapter, handle, ring_id)		\
+	((adapter->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X) ?	\
+	((handle) | ((ring_id) << 15)) : handle)
+
+#define QLCNIC_FETCH_RING_ID(handle)			\
+	((handle) >> 63)
+
 #define QLCNIC_ENABLE_INTR(adapter, crb) {		\
 	writel(1, crb);					\
 	if (!QLCNIC_IS_MSI_FAMILY(adapter))		\
@@ -25,7 +175,29 @@ do {							\
 	writel(0, crb);					\
 }
 
+#define QLCNIC_MBX_RSP_OK	1
+#define QLCNIC_MBX_PORT_RSP_OK	0x1a
+
+#define QLCNIC_MBX_RSP(reg)\
+	LSW(reg)
+#define QLCNIC_MBX_NUM_REGS(reg)\
+	(MSW(reg) & 0x1FF)
+#define QLCNIC_MBX_STATUS(reg)	\
+	(((reg) >> 25) & 0x7F)
+
+/* Mailbox registers*/
+#define QLCNIC_MBX_HOST(ahw, i)	\
+	((ahw)->pci_base0 + ((i) * 4))
+#define QLCNIC_MBX_FW(ahw, i)	\
+	((ahw)->pci_base0 + 0x800 + ((i) * 4))
+
+#define QLCNIC_IS_TSO_CAPABLE(adapter)\
+	((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
 
+#define QLCNIC_IS_VLAN_TX_CAPABLE(adapter) \
+	((QLCNIC_IS_82XX(adapter)) ?\
+	((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX) :\
+	1)
 
 void qlcnic_82xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
 void qlcnic_82xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index 9691df1..2012ce3 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
@@ -200,6 +200,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
 
 	struct qlcnic_cmd_buffer *cmd_buf_arr;
 	struct net_device *netdev = adapter->netdev;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	size = sizeof(struct qlcnic_host_tx_ring);
 	tx_ring = kzalloc(size, GFP_KERNEL);
@@ -243,7 +244,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
 			rds_ring->dma_size =
 				QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN;
 
-			if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+			if (ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
 				rds_ring->dma_size += QLCNIC_LRO_BUFFER_EXTRA;
 
 			rds_ring->skb_size =
@@ -652,7 +653,7 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
 			"Not an Ethernet NIC func=%u\n", val);
 		return -EIO;
 	}
-	adapter->physical_port = (val >> 2);
+	adapter->ahw->physical_port = (val >> 2);
 	if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo))
 		timeo = QLCNIC_INIT_TIMEOUT_SECS;
 
@@ -990,10 +991,10 @@ qlcnic_get_bootld_offs(struct qlcnic_adapter *adapter)
 {
 	u32 offs = QLCNIC_BOOTLD_START;
 
-	if (adapter->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
+	if (adapter->ahw->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
 		offs = cpu_to_le32((qlcnic_get_data_desc(adapter,
-					QLCNIC_UNI_DIR_SECT_BOOTLD,
-					QLCNIC_UNI_BOOTLD_IDX_OFF))->findex);
+				   QLCNIC_UNI_DIR_SECT_BOOTLD,
+				   QLCNIC_UNI_BOOTLD_IDX_OFF))->findex);
 
 	return (u8 *)&adapter->fw->data[offs];
 }
@@ -1003,10 +1004,10 @@ qlcnic_get_fw_offs(struct qlcnic_adapter *adapter)
 {
 	u32 offs = QLCNIC_IMAGE_START;
 
-	if (adapter->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
+	if (adapter->ahw->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
 		offs = cpu_to_le32((qlcnic_get_data_desc(adapter,
-					QLCNIC_UNI_DIR_SECT_FW,
-					QLCNIC_UNI_FIRMWARE_IDX_OFF))->findex);
+				   QLCNIC_UNI_DIR_SECT_FW,
+				   QLCNIC_UNI_FIRMWARE_IDX_OFF))->findex);
 
 	return (u8 *)&adapter->fw->data[offs];
 }
@@ -1014,10 +1015,10 @@ qlcnic_get_fw_offs(struct qlcnic_adapter *adapter)
 static __le32
 qlcnic_get_fw_size(struct qlcnic_adapter *adapter)
 {
-	if (adapter->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
+	if (adapter->ahw->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
 		return cpu_to_le32((qlcnic_get_data_desc(adapter,
-					QLCNIC_UNI_DIR_SECT_FW,
-					QLCNIC_UNI_FIRMWARE_IDX_OFF))->size);
+				   QLCNIC_UNI_DIR_SECT_FW,
+				   QLCNIC_UNI_FIRMWARE_IDX_OFF))->size);
 	else
 		return cpu_to_le32(
 			*(u32 *)&adapter->fw->data[QLCNIC_FW_SIZE_OFFSET]);
@@ -1032,7 +1033,7 @@ qlcnic_get_fw_version(struct qlcnic_adapter *adapter)
 	const u8 *ver_str;
 	int i, ret;
 
-	if (adapter->fw_type != QLCNIC_UNIFIED_ROMIMAGE)
+	if (adapter->ahw->fw_type != QLCNIC_UNIFIED_ROMIMAGE)
 		return cpu_to_le32(*(u32 *)&fw->data[QLCNIC_FW_VERSION_OFFSET]);
 
 	fw_data_desc = qlcnic_get_data_desc(adapter, QLCNIC_UNI_DIR_SECT_FW,
@@ -1060,7 +1061,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
 	const struct firmware *fw = adapter->fw;
 	__le32 bios_ver, prd_off = adapter->file_prd_off;
 
-	if (adapter->fw_type != QLCNIC_UNIFIED_ROMIMAGE)
+	if (adapter->ahw->fw_type != QLCNIC_UNIFIED_ROMIMAGE)
 		return cpu_to_le32(
 			*(u32 *)&fw->data[QLCNIC_BIOS_VERSION_OFFSET]);
 
@@ -1130,7 +1131,7 @@ qlcnic_load_firmware(struct qlcnic_adapter *adapter)
 	struct pci_dev *pdev = adapter->pdev;
 
 	dev_info(&pdev->dev, "loading firmware from %s\n",
-			fw_name[adapter->fw_type]);
+			fw_name[adapter->ahw->fw_type]);
 
 	if (fw) {
 		__le64 data;
@@ -1222,7 +1223,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
 	u32 ver, bios, min_size;
 	struct pci_dev *pdev = adapter->pdev;
 	const struct firmware *fw = adapter->fw;
-	u8 fw_type = adapter->fw_type;
+	u8 fw_type = adapter->ahw->fw_type;
 
 	if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
 		if (qlcnic_validate_unified_romimage(adapter))
@@ -1267,7 +1268,7 @@ qlcnic_get_next_fwtype(struct qlcnic_adapter *adapter)
 {
 	u8 fw_type;
 
-	switch (adapter->fw_type) {
+	switch (adapter->ahw->fw_type) {
 	case QLCNIC_UNKNOWN_ROMIMAGE:
 		fw_type = QLCNIC_UNIFIED_ROMIMAGE;
 		break;
@@ -1278,7 +1279,7 @@ qlcnic_get_next_fwtype(struct qlcnic_adapter *adapter)
 		break;
 	}
 
-	adapter->fw_type = fw_type;
+	adapter->ahw->fw_type = fw_type;
 }
 
 
@@ -1288,16 +1289,16 @@ void qlcnic_request_firmware(struct qlcnic_adapter *adapter)
 	struct pci_dev *pdev = adapter->pdev;
 	int rc;
 
-	adapter->fw_type = QLCNIC_UNKNOWN_ROMIMAGE;
+	adapter->ahw->fw_type = QLCNIC_UNKNOWN_ROMIMAGE;
 
 next:
 	qlcnic_get_next_fwtype(adapter);
 
-	if (adapter->fw_type == QLCNIC_FLASH_ROMIMAGE) {
+	if (adapter->ahw->fw_type == QLCNIC_FLASH_ROMIMAGE) {
 		adapter->fw = NULL;
 	} else {
 		rc = request_firmware(&adapter->fw,
-				fw_name[adapter->fw_type], &pdev->dev);
+				fw_name[adapter->ahw->fw_type], &pdev->dev);
 		if (rc != 0)
 			goto next;
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index bcbb3af..6f39882 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -585,7 +585,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
 	u8 lb_status = 0;
 	struct net_device *netdev = adapter->netdev;
 
-	adapter->has_link_events = 1;
+	adapter->ahw->has_link_events = 1;
 
 	cable_OUI = msg->body[1] & 0xffffffff;
 	cable_len = (msg->body[1] >> 32) & 0xffff;
@@ -612,13 +612,13 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
 	qlcnic_advert_link_change(adapter, link_status);
 
 	if (duplex == LINKEVENT_FULL_DUPLEX)
-		adapter->link_duplex = DUPLEX_FULL;
+		adapter->ahw->link_duplex = DUPLEX_FULL;
 	else
-		adapter->link_duplex = DUPLEX_HALF;
+		adapter->ahw->link_duplex = DUPLEX_HALF;
 
-	adapter->module_type = module;
-	adapter->link_autoneg = autoneg;
-	adapter->link_speed = link_speed;
+	adapter->ahw->module_type = module;
+	adapter->ahw->link_autoneg = autoneg;
+	adapter->ahw->link_speed = link_speed;
 }
 
 static void
@@ -656,17 +656,17 @@ qlcnic_handle_fw_message(int desc_cnt, int index,
 			break;
 		case 1:
 			dev_info(dev, "loopback already in progress\n");
-			adapter->diag_cnt = -QLCNIC_TEST_IN_PROGRESS;
+			adapter->ahw->diag_cnt = -QLCNIC_TEST_IN_PROGRESS;
 			break;
 		case 2:
 			dev_info(dev, "loopback cable is not connected\n");
-			adapter->diag_cnt = -QLCNIC_LB_CABLE_NOT_CONN;
+			adapter->ahw->diag_cnt = -QLCNIC_LB_CABLE_NOT_CONN;
 			break;
 		default:
 			dev_info(dev,
 				 "configure loopback request failed, ret %x\n",
 				 ret);
-			adapter->diag_cnt = -QLCNIC_UNDEFINED_ERROR;
+			adapter->ahw->diag_cnt = -QLCNIC_UNDEFINED_ERROR;
 			break;
 		}
 		break;
@@ -1130,7 +1130,7 @@ void qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
 		skb_pull(skb, pkt_offset);
 
 	if (!qlcnic_check_loopback_buff(skb->data, adapter->mac_addr))
-		adapter->diag_cnt++;
+		adapter->ahw->diag_cnt++;
 	else
 		dump_skb(skb, adapter);
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index ba26467..9cca75e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -125,6 +125,56 @@ static const u32 msi_tgt_status[8] = {
 	ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
 };
 
+static const u32 qlcnic_reg_tbl[] = {
+	0x1B20A8, /* PEG_HALT_STAT1 */
+	0x1B20AC, /* PEG_HALT_STAT2 */
+	0x1B20B0, /* FW_HEARTBEAT */
+	0x1B2100, /* LOCK ID */
+	0x1B2128, /* FW_CAPABILITIES */
+	0x1B2138, /* drv active */
+	0x1B2140, /* dev state */
+	0x1B2144, /* drv state */
+	0x1B2148, /* drv scratch */
+	0x1B214C, /* dev partition info */
+	0x1B2174, /* drv idc ver */
+	0x1B2150, /* fw version major */
+	0x1B2154, /* fw version minor */
+	0x1B2158, /* fw version sub */
+	0x1B019C, /* npar state */
+	0x1B21FC, /* FW_IMG_VALID */
+	0x1B2250, /* CMD_PEG_STATE */
+	0x1B233C, /* RCV_PEG_STATE */
+	0x1B23B4, /* ASIC TEMP */
+	0x1B216C, /* FW api */
+	0x1B2170, /* drv op mode */
+	0x13C010, /* flash lock */
+	0x13C014, /* flash unlock */
+};
+
+static const struct qlcnic_brdinfo qlcnic_boards[] = {
+	{0x1077, 0x8020, 0x1077, 0x203,
+		"8200 Series Single Port 10GbE Converged Network Adapter "
+		"(TCP/IP Networking)"},
+	{0x1077, 0x8020, 0x1077, 0x207,
+		"8200 Series Dual Port 10GbE Converged Network Adapter "
+		"(TCP/IP Networking)"},
+	{0x1077, 0x8020, 0x1077, 0x20b,
+		"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
+	{0x1077, 0x8020, 0x1077, 0x20c,
+		"3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"},
+	{0x1077, 0x8020, 0x1077, 0x20f,
+		"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
+	{0x1077, 0x8020, 0x103c, 0x3733,
+		"NC523SFP 10Gb 2-port Server Adapter"},
+	{0x1077, 0x8020, 0x103c, 0x3346,
+		"CN1000Q Dual Port Converged Network Adapter"},
+	{0x1077, 0x8020, 0x1077, 0x210,
+		"QME8242-k 10GbE Dual Port Mezzanine Card"},
+	{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
+};
+
+#define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards)
+
 static const
 struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG;
 
@@ -403,7 +453,7 @@ static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
 	adapter->max_sds_rings = 1;
 	adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED);
 
-	if (adapter->msix_supported) {
+	if (adapter->ahw->msix_supported) {
  enable_msix:
 		for (i = 0; i < num_msix; i++)
 			adapter->msix_entries[i].entry = i;
@@ -444,7 +494,7 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
 
 	legacy_intrp = &legacy_intr[adapter->ahw->pci_func];
 
-	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
+	adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit;
 	offset = legacy_intrp->tgt_status_reg;
 	adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw, offset);
 	adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter->ahw,
@@ -462,7 +512,7 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter)
 {
 	int num_msix, err;
 
-	if (adapter->msix_supported)
+	if (adapter->ahw->msix_supported)
 		num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
 						QLCNIC_DEF_NUM_STS_DESC_RINGS));
 	else
@@ -611,7 +661,7 @@ qlcnic_check_vf(struct qlcnic_adapter *adapter)
 		priv_level = QLC_DEV_GET_DRV(op_mode, ahw->pci_func);
 
 	if (priv_level == QLCNIC_NON_PRIV_FUNC) {
-		adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
+		ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
 		dev_info(&adapter->pdev->dev,
 			 "HAL Version: %d Non Privileged function\n",
 			 ahw->fw_hal_version);
@@ -696,7 +746,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 
 	adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
 
-	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) {
+	if (ahw->op_mode != QLCNIC_NON_PRIV_FUNC) {
 		if (fw_dump->tmpl_hdr == NULL ||
 				adapter->fw_version > prev_fw_version) {
 			if (fw_dump->tmpl_hdr)
@@ -728,7 +778,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 		adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G;
 	}
 
-	adapter->msix_supported = !!use_msi_x;
+	adapter->ahw->msix_supported = !!use_msi_x;
 
 	adapter->num_txd = MAX_CMD_DESCRIPTORS;
 
@@ -745,15 +795,15 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
 	if (err)
 		return err;
 
-	adapter->physical_port = (u8)nic_info.phys_port;
-	adapter->switch_mode = nic_info.switch_mode;
-	adapter->max_tx_ques = nic_info.max_tx_ques;
-	adapter->max_rx_ques = nic_info.max_rx_ques;
-	adapter->capabilities = nic_info.capabilities;
-	adapter->max_mac_filters = nic_info.max_mac_filters;
-	adapter->max_mtu = nic_info.max_mtu;
+	adapter->ahw->physical_port = (u8)nic_info.phys_port;
+	adapter->ahw->switch_mode = nic_info.switch_mode;
+	adapter->ahw->max_tx_ques = nic_info.max_tx_ques;
+	adapter->ahw->max_rx_ques = nic_info.max_rx_ques;
+	adapter->ahw->capabilities = nic_info.capabilities;
+	adapter->ahw->max_mac_filters = nic_info.max_mac_filters;
+	adapter->ahw->max_mtu = nic_info.max_mtu;
 
-	if (adapter->capabilities & BIT_6)
+	if (adapter->ahw->capabilities & BIT_6)
 		adapter->flags |= QLCNIC_ESWITCH_ENABLED;
 	else
 		adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
@@ -824,7 +874,7 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
 	vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
 			NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER);
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
 		features |= (NETIF_F_TSO | NETIF_F_TSO6);
 		vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
 	}
@@ -871,7 +921,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
 
 	if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
 		if (priv_level == QLCNIC_MGMT_FUNC) {
-			adapter->op_mode = QLCNIC_MGMT_FUNC;
+			adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
 			err = qlcnic_init_pci_info(adapter);
 			if (err)
 				return err;
@@ -881,7 +931,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
 				 "HAL Version: %d, Management function\n",
 				 adapter->ahw->fw_hal_version);
 		} else if (priv_level == QLCNIC_PRIV_FUNC) {
-			adapter->op_mode = QLCNIC_PRIV_FUNC;
+			adapter->ahw->op_mode = QLCNIC_PRIV_FUNC;
 			dev_info(&adapter->pdev->dev,
 				 "HAL Version: %d, Privileged function\n",
 				 adapter->ahw->fw_hal_version);
@@ -911,7 +961,7 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
 		esw_cfg.offload_flags = BIT_0;
 		esw_cfg.mac_override = BIT_0;
 		esw_cfg.promisc_mode = BIT_0;
-		if (adapter->capabilities  & QLCNIC_FW_CAPABILITY_TSO)
+		if (adapter->ahw->capabilities  & QLCNIC_FW_CAPABILITY_TSO)
 			esw_cfg.offload_flags |= (BIT_1 | BIT_2);
 		if (qlcnic_config_switch_port(adapter, &esw_cfg))
 			return -EIO;
@@ -992,7 +1042,7 @@ static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter)
 	u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO;
 	u32 npar_state;
 
-	if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
 		return 0;
 
 	npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
@@ -1014,7 +1064,7 @@ qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter)
 	int err;
 
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
-		    adapter->op_mode != QLCNIC_MGMT_FUNC)
+		    adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return 0;
 
 	err = qlcnic_set_default_offload_settings(adapter);
@@ -1048,7 +1098,7 @@ qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter)
 		if (err)
 			goto err_out;
 
-		adapter->fw_type = QLCNIC_FLASH_ROMIMAGE;
+		adapter->ahw->fw_type = QLCNIC_FLASH_ROMIMAGE;
 	}
 
 	err = qlcnic_need_fw_reset(adapter);
@@ -1109,7 +1159,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter)
 	struct net_device *netdev = adapter->netdev;
 	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
-	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
+	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
 		handler = qlcnic_tmp_intr;
 		if (!QLCNIC_IS_MSI_FAMILY(adapter))
 			flags |= IRQF_SHARED;
@@ -1168,7 +1218,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
 	if (qlcnic_set_eswitch_port_config(adapter))
 		return -EIO;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
 		capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2);
 		if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
 			adapter->flags |= QLCNIC_FW_LRO_MSS_CAP;
@@ -1199,7 +1249,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
 
 	qlcnic_linkevent_request(adapter, 1);
 
-	adapter->reset_context = 0;
+	adapter->ahw->reset_context = 0;
 	set_bit(__QLCNIC_DEV_UP, &adapter->state);
 	return 0;
 }
@@ -1332,7 +1382,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
 	int ring;
 
 	clear_bit(__QLCNIC_DEV_UP, &adapter->state);
-	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
+	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
 		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 			sds_ring = &adapter->recv_ctx->sds_rings[ring];
 			QLCNIC_DISABLE_INTR(sds_ring->crb_intr_mask);
@@ -1343,7 +1393,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
 
 	qlcnic_detach(adapter);
 
-	adapter->diag_test = 0;
+	adapter->ahw->diag_test = 0;
 	adapter->max_sds_rings = max_sds_rings;
 
 	if (qlcnic_attach(adapter))
@@ -1403,7 +1453,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
 	qlcnic_detach(adapter);
 
 	adapter->max_sds_rings = 1;
-	adapter->diag_test = test;
+	adapter->ahw->diag_test = test;
 
 	ret = qlcnic_attach(adapter);
 	if (ret) {
@@ -1423,14 +1473,14 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
 		qlcnic_post_rx_buffers(adapter, rds_ring);
 	}
 
-	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
+	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
 		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 			sds_ring = &adapter->recv_ctx->sds_rings[ring];
 			QLCNIC_ENABLE_INTR(adapter, sds_ring->crb_intr_mask);
 		}
 	}
 
-	if (adapter->diag_test == QLCNIC_LOOPBACK_TEST) {
+	if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
 		adapter->ahw->loopback_state = 0;
 		qlcnic_linkevent_request(adapter, 1);
 	}
@@ -1501,11 +1551,11 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
 	int err;
 	struct pci_dev *pdev = adapter->pdev;
 
-	adapter->mc_enabled = 0;
-	adapter->max_mc_count = 38;
+	adapter->ahw->mc_enabled = 0;
+	adapter->ahw->max_mc_count = QLCNIC_MAX_MC_COUNT;
 
 	netdev->netdev_ops	   = &qlcnic_netdev_ops;
-	netdev->watchdog_timeo     = 5*HZ;
+	netdev->watchdog_timeo     = QLCNIC_WATCHDOG_TIMEOUTVALUE*HZ;
 
 	qlcnic_change_mtu(netdev, netdev->mtu);
 
@@ -1514,16 +1564,16 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
 	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
 		NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
 		netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
 	if (pci_using_dac)
 		netdev->hw_features |= NETIF_F_HIGHDMA;
 
 	netdev->vlan_features = netdev->hw_features;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX)
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX)
 		netdev->hw_features |= NETIF_F_HW_VLAN_TX;
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
 		netdev->hw_features |= NETIF_F_LRO;
 
 	netdev->features |= netdev->hw_features |
@@ -1954,7 +2004,7 @@ static int qlcnic_check_temp(struct qlcnic_adapter *adapter)
 		       temp_val);
 		rv = 1;
 	} else if (temp_state == QLCNIC_TEMP_WARN) {
-		if (adapter->temp == QLCNIC_TEMP_NORMAL) {
+		if (adapter->ahw->temp == QLCNIC_TEMP_NORMAL) {
 			dev_err(&netdev->dev,
 			       "Device temperature %d degrees C "
 			       "exceeds operating range."
@@ -1962,13 +2012,13 @@ static int qlcnic_check_temp(struct qlcnic_adapter *adapter)
 			       temp_val);
 		}
 	} else {
-		if (adapter->temp == QLCNIC_TEMP_WARN) {
+		if (adapter->ahw->temp == QLCNIC_TEMP_WARN) {
 			dev_info(&netdev->dev,
 			       "Device temperature is now %d degrees C"
 			       " in normal range.\n", temp_val);
 		}
 	}
-	adapter->temp = temp_state;
+	adapter->ahw->temp = temp_state;
 	return rv;
 }
 
@@ -1984,7 +2034,7 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
 	if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS)
 		adapter->need_fw_reset = 1;
 	else
-		adapter->reset_context = 1;
+		adapter->ahw->reset_context = 1;
 }
 
 static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
@@ -2008,7 +2058,7 @@ static irqreturn_t qlcnic_clear_legacy_intr(struct qlcnic_adapter *adapter)
 
 	status = readl(adapter->isr_int_vec);
 
-	if (!(status & adapter->int_vec_bit))
+	if (!(status & adapter->ahw->int_vec_bit))
 		return IRQ_NONE;
 
 	/* check interrupt state machine, to be sure */
@@ -2040,7 +2090,7 @@ static irqreturn_t qlcnic_tmp_intr(int irq, void *data)
 		return IRQ_NONE;
 
 done:
-	adapter->diag_cnt++;
+	adapter->ahw->diag_cnt++;
 	QLCNIC_ENABLE_INTR(adapter, sds_ring->crb_intr_mask);
 	return IRQ_HANDLED;
 }
@@ -2323,7 +2373,7 @@ qlcnic_fwinit_work(struct work_struct *work)
 		return;
 	}
 
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
+	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
 		qlcnic_api_unlock(adapter);
 		goto wait_npar;
 	}
@@ -2439,9 +2489,9 @@ qlcnic_detach_work(struct work_struct *work)
 		goto err_ret;
 	}
 
-	if (adapter->temp == QLCNIC_TEMP_PANIC) {
+	if (adapter->ahw->temp == QLCNIC_TEMP_PANIC) {
 		dev_err(&adapter->pdev->dev, "Detaching the device: temp=%d\n",
-			adapter->temp);
+			adapter->ahw->temp);
 		goto err_ret;
 	}
 
@@ -2567,7 +2617,7 @@ qlcnic_attach_work(struct work_struct *work)
 	struct net_device *netdev = adapter->netdev;
 	u32 npar_state;
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC) {
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
 		npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
 		if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO)
 			qlcnic_clr_all_drv_state(adapter, 0);
@@ -2624,7 +2674,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		if (adapter->need_fw_reset)
 			goto detach;
 
-		if (adapter->reset_context && auto_fw_reset) {
+		if (adapter->ahw->reset_context && auto_fw_reset) {
 			qlcnic_reset_hw_context(adapter);
 			adapter->netdev->trans_start = jiffies;
 		}
@@ -2719,6 +2769,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
 {
 	int err, first_func;
 	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct net_device *netdev = adapter->netdev;
 
 	pdev->error_state = pci_channel_io_normal;
@@ -2736,7 +2787,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
 	if (qlcnic_api_lock(adapter))
 		return -EINVAL;
 
-	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) {
+	if (ahw->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) {
 		adapter->need_fw_reset = 1;
 		set_bit(__QLCNIC_START_FW, &adapter->state);
 		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
@@ -2870,7 +2921,7 @@ qlcnic_store_bridged_mode(struct device *dev,
 	unsigned long new;
 	int ret = -EINVAL;
 
-	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG))
+	if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
 		goto err_out;
 
 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
@@ -2893,7 +2944,7 @@ qlcnic_show_bridged_mode(struct device *dev,
 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
 	int bridged_mode = 0;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
 		bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
 
 	return sprintf(buf, "%d\n", bridged_mode);
@@ -3020,7 +3071,7 @@ qlcnic_store_beacon(struct device *dev,
 	u8 b_state, b_rate;
 	int err;
 
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
+	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
 		dev_warn(dev, "LED test not supported for non "
 				"privilege function\n");
 		return -EOPNOTSUPP;
@@ -3329,7 +3380,7 @@ validate_esw_config(struct qlcnic_adapter *adapter,
 		if (pci_func >= QLCNIC_MAX_PCI_FUNC)
 			return QL_STATUS_INVALID_PARAM;
 
-		if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+		if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
 			if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
 				return QL_STATUS_INVALID_PARAM;
 
@@ -3384,7 +3435,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
 		return ret;
 
 	for (i = 0; i < count; i++) {
-		if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+		if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
 			if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
 				return QL_STATUS_INVALID_PARAM;
 
@@ -3410,7 +3461,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
 		}
 	}
 
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		goto out;
 
 	for (i = 0; i < count; i++) {
@@ -3744,7 +3795,7 @@ qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
 		if (device_create_file(dev, &dev_attr_bridged_mode))
 			dev_warn(dev,
 				"failed to create bridged_mode sysfs entry\n");
@@ -3755,7 +3806,7 @@ qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
+	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
 		device_remove_file(dev, &dev_attr_bridged_mode);
 }
 
@@ -3768,7 +3819,7 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 	if (device_create_bin_file(dev, &bin_attr_port_stats))
 		dev_info(dev, "failed to create port stats sysfs entry");
 
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
+	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
 		return;
 	if (device_create_file(dev, &dev_attr_diag_mode))
 		dev_info(dev, "failed to create diag_mode sysfs entry\n");
@@ -3789,7 +3840,7 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 		return;
 	if (device_create_bin_file(dev, &bin_attr_esw_config))
 		dev_info(dev, "failed to create esw config sysfs entry");
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return;
 	if (device_create_bin_file(dev, &bin_attr_npar_config))
 		dev_info(dev, "failed to create npar config sysfs entry");
@@ -3807,7 +3858,7 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 
 	device_remove_bin_file(dev, &bin_attr_port_stats);
 
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
+	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
 		return;
 	device_remove_file(dev, &dev_attr_diag_mode);
 	device_remove_bin_file(dev, &bin_attr_crb);
@@ -3819,7 +3870,7 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
 		return;
 	device_remove_bin_file(dev, &bin_attr_esw_config);
-	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
 		return;
 	device_remove_bin_file(dev, &bin_attr_npar_config);
 	device_remove_bin_file(dev, &bin_attr_pm_config);
-- 
1.7.1

^ permalink raw reply related


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