* Re: Connection tracking and vlan
From: Eric W. Biederman @ 2009-10-30 23:15 UTC (permalink / raw)
To: Adayadil Thomas; +Cc: Eric Dumazet, Herbert Xu, netdev, Patrick McHardy
In-Reply-To: <fb7befa20910301220y53e43608u3b37de17661feb4e@mail.gmail.com>
Adayadil Thomas <adayadil.thomas@gmail.com> writes:
> On Fri, Oct 30, 2009 at 11:31 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
>> Very strange, this question about vlan looks like discussion we had
>> yesterday (or the day before...) about interfaces (versus packet defragmentation)
>>
>> "IP conntracking" is about IP, and [V]LAN doesnt matter at all at this protocol level.
>>
>> Same thing if you have two interfaces, eth0 & eth1 : IP conntrack tuples dont
>> include interface name/index
>
> I am concerned about the following situation -
>
> The linux device is configured as a bridge and is deployed between the
> trunk ports
> of 2 switches. In this situation the linux device will be seeing 802.1q packets
> with vlan headers specifying the vlanids.
>
> It is valid to have an environment where private IP addresses are duplicated
> on different virtual LANs. i.e. it is valid to have machine A (
> 10.10.10.1) talking to
> machine B (10.10.10.2) on vlan 1,
> and
> at the same time machine C ( 10.10.10.1) talking to machine D
> (10.10.10.2) on vlan 2.
>
> Since they are on different LANs (VLANs), there should not be any issues.
>
> Now when VLANs are shared across switches, the trunk port will sent
> 802.1q tagged
> packets between the switches. Imagine these packets when going through
> the linux bridge.
> The 802.1q header should identify the separate vlans by the vlan id.
>
> If ip_conntrack does not consider vlans, it is possible that all 5
> tuple are the same
> and thus affect the connection tracking.
>
> I hope I have described the scenario well. If not I can explain in a
> more detailed fashion.
Unless you have multiple network namespaces linux assumes all packets are
in the same ip space. And 10.10.10.1 is the same machine no matter
which interface you talk to it on.
Eric
^ permalink raw reply
* Re: Connection tracking and vlan
From: Ben Greear @ 2009-10-30 23:25 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Adayadil Thomas, Eric Dumazet, Herbert Xu, netdev,
Patrick McHardy
In-Reply-To: <m1639wmq1f.fsf@fess.ebiederm.org>
On 10/30/2009 04:15 PM, Eric W. Biederman wrote:
>> If ip_conntrack does not consider vlans, it is possible that all 5
>> tuple are the same
>> and thus affect the connection tracking.
>>
>> I hope I have described the scenario well. If not I can explain in a
>> more detailed fashion.
>
> Unless you have multiple network namespaces linux assumes all packets are
> in the same ip space. And 10.10.10.1 is the same machine no matter
> which interface you talk to it on.
It only takes a relatively small patch that lets conn-track hash on a
skb->foo_mark, and allow that mark to be set on incoming packets
based on netdevice or whatever, (before the conn-track lookup is
done).
This is logically somewhat similar to using multiple routing
tables and has been working well for me for several years....
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] net: allow netdev_wait_allrefs() to run faster
From: Eric W. Biederman @ 2009-10-30 23:25 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: Eric Dumazet, Octavian Purdila, netdev, Cosmin Ratiu
In-Reply-To: <20091030143527.GA3141@kvack.org>
Benjamin LaHaise <bcrl@lhnet.ca> writes:
> On Thu, Oct 29, 2009 at 06:45:32PM -0700, Eric W. Biederman wrote:
>> The reason for the existence of sysfs_dirent is as things grow larger
>> we want to keep the amount of RAM consumed down. So we don't pin
>> everything in the dcache. So we try and keep the amount of memory
>> consumed down.
>
> I'm aware of that, but for users running into this sort of scaling issue,
> the amount of RAM required is a non-issue (30,000 interfaces require about
> 1GB of RAM at present), making the question more one of how to avoid the
> overhead for users who don't require it. I'd prefer a config option. The
> only way I can really see saving memory usage is to somehow tie sysfs dirent
> lookups into the network stack's own tables for looking up device entries.
> The network stack already has to cope with this kind of scaling, and that
> would save the RAM.
There is that. I'm trying to figure out how to add the improvements
without making sysfs_dirent larger. Which I think that is doable.
>> So I would like to see how much we can par down.
>
>> For dealing with seeks in the middle of readdir I expect the best way
>> to do that is to be inspired by htrees in extNfs and return a hash of
>> the filename as our position, and keep the filename list sorted by
>> that hash. Since we are optimizing for size we don't need to store
>> that hash. Then we can turn that list into a some flavor of sorted
>> binary tree.
>
> readdir() generally isn't an issue at present.
Supporting seekdir into the middle of a directory is the entire reason
I keep the entries sorted by inode. If we sort by a hash of the name.
We can use the hash to support directory position in readdir and seekdir.
And we can completely remove the linear list when the rb_tree is introduced.
>> I'm surprised sysfs_count_nlink shows up, as it is not directly on the
>> add or remove path. I think the answer there is to change s_flags
>> into a set of bitfields and make link_count one of them, perhaps
>> 16bits long. If we ever overflow our bitfield we can just set link
>> count to 0, and userspace (aka find) will know it can't optimized
>> based on link count.
>
> It shows up because of the bits of userspace (udev) touching the directory
> from things like the hotplug code path.
I realized after sending the message that s_mode in sysfs_dirent is a
real size offense. It is a 16bit field packed in between two longs.
So in practice it is possible to move the s_mode up next to s_flags
and add a s_nlink after it both unsigned short and get a cheap sysfs_nlink.
>> I was expecting someone to run into problems with the linear directory
>> of sysfs someday.
>
> Alas, sysfs isn't the only offender.
Agreed. Sysfs is probably the easiest to untangle.
Since I'm not quite ready to post my patches. I will briefly
mention what I have in my queue and hopefully get things posted.
I have changes to make it so that sysfs never has to go from
the sysfs_dirent to the sysfs inode.
I have changes to sys_sysctl() so that it becomes a filesystem lookup
under /proc/sys. Which ultimately makes the code easier to maintain
and debug.
Now back to getting things forward ported and ready to post.
Eric
^ permalink raw reply
* Re: [RFC, PATCH] net: suspicious test in dev_change_name()
From: Jarek Poplawski @ 2009-10-30 23:50 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, Linux Netdev List
In-Reply-To: <4AEAAFC4.9050309@gmail.com>
Eric Dumazet wrote, On 10/30/2009 10:20 AM:
> While preparing a patch for net-next-2.6, I noticed following code in dev_change_name()
>
> int err = 0;
> ...
> ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
> ret = notifier_to_errno(ret);
>
> if (ret) {
> << HERE >> if (err) {
> printk(KERN_ERR
> "%s: name change rollback failed: %d.\n",
> dev->name, ret);
> } else {
> err = ret;
> memcpy(dev->name, oldname, IFNAMSIZ);
> goto rollback;
> }
> }
>
>
> It seems intent was to test if notifier_to_errno() was null ?
I don't think so: err stores the previous ret meaning rollback and
is checked for this later. But somebody forgot err can store previous
(positive) value here, so IMHO you're right: there is a bug in this
place ;-)
Jarek P.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index b8f74cf..029cd41 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -939,9 +939,9 @@ rollback:
> write_unlock_bh(&dev_base_lock);
>
> ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
> - ret = notifier_to_errno(ret);
>
> if (ret) {
> + err = notifier_to_errno(ret);
> if (err) {
> printk(KERN_ERR
> "%s: name change rollback failed: %d.\n",
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] net: allow netdev_wait_allrefs() to run faster
From: Benjamin LaHaise @ 2009-10-30 23:53 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Eric Dumazet, Octavian Purdila, netdev, Cosmin Ratiu
In-Reply-To: <m1my38lb0f.fsf@fess.ebiederm.org>
On Fri, Oct 30, 2009 at 04:25:52PM -0700, Eric W. Biederman wrote:
> I realized after sending the message that s_mode in sysfs_dirent is a
> real size offense. It is a 16bit field packed in between two longs.
> So in practice it is possible to move the s_mode up next to s_flags
> and add a s_nlink after it both unsigned short and get a cheap sysfs_nlink.
That doesn't work -- the number of directory entries can easily exceed 65535.
Current mid range hardware is good enough to terminate 100,000 network
interfaces on a single host.
> Since I'm not quite ready to post my patches. I will briefly
> mention what I have in my queue and hopefully get things posted.
>
> I have changes to make it so that sysfs never has to go from
> the sysfs_dirent to the sysfs inode.
Ah, interesting.
> I have changes to sys_sysctl() so that it becomes a filesystem lookup
> under /proc/sys. Which ultimately makes the code easier to maintain
> and debug.
That sounds like a much saner approach, but has the wrinkle that procfs can
be configured out.
> Now back to getting things forward ported and ready to post.
I'm looking forward to those changes. I've been ignoring procfs for the
time being by disabling the per-interface entries in the network stack,
but there is some desire to be able to enable rp_filter on a per-interface
radius config at runtime. rp_filter has to be disabled across the board
on my access routers, as there are several places where assymetric routing
is used for performance reasons.
-ben
^ permalink raw reply
* Re: [PATCH 0/6] Bonding simplifications and netns support
From: Jay Vosburgh @ 2009-10-31 0:10 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: David Miller, netdev
In-Reply-To: <m1639wo5gb.fsf@fess.ebiederm.org>
Eric W. Biederman <ebiederm@xmission.com> wrote:
>Jay Vosburgh <fubar@us.ibm.com> writes:
>
>> David Miller <davem@davemloft.net> wrote:
>>
>>>From: ebiederm@xmission.com (Eric W. Biederman)
>>>Date: Thu, 29 Oct 2009 17:16:54 -0700
>>>
>>>> I recently had it pointed out to me that the bonding driver does not
>>>> work in a network namespace. So I have simplified the bonding driver
>>>> a bit, added support for ip link add and ip link del, and finally made
>>>> the bonding driver work in multiple network namespaces.
>>>>
>>>> The most note worthy change in the patchset is the addition of support
>>>> in the networking core for registering a sysfs group for a device.
>>>>
>>>> Using this in the bonding driver simplifies the code and removes a
>>>> userspace race between actions triggered by the netlink event and the
>>>> bonding sysfs attributes appearing.
>>>
>>>I've tossed patches 1-7 into net-next-2.6, thanks Eric.
>>
>> I put patches 1-7 on a recent net-next-2.6, and from a simple
>> "insmod bonding.ko; rmmod bonding" I'm seeing the following:
>>
>> ------------[ cut here ]------------
>> WARNING: at fs/proc/generic.c:847 remove_proc_entry+0x1a8/0x1c7()
>> Hardware name: IBM eserver xSeries 220 -[8645]-
>> remove_proc_entry: removing non-empty directory 'net/bonding', leaking at least
>> 'bond0'
>> Modules linked in: bonding(-) ipv6 microcode loop ppdev sworks_agp parport_pc tg
>> 3 e100 agpgart parport mii libphy e1000 edd pata_serverworks [last unloaded: spe
>> edstep_lib]
>> Pid: 6216, comm: rmmod Not tainted 2.6.32-rc3-devel #19
>> Call Trace:
>> [<c012ec9d>] warn_slowpath_common+0x60/0x90
>> [<c012ed01>] warn_slowpath_fmt+0x24/0x27
>> [<c01e3e55>] remove_proc_entry+0x1a8/0x1c7
>> [<e0906435>] ? bond_net_exit+0x0/0xa3 [bonding]
>> [<e09064c3>] bond_net_exit+0x8e/0xa3 [bonding]
>> [<c02e6ee8>] unregister_pernet_gen_subsys+0x23/0x3d
>> [<e0910baa>] bonding_exit+0x3a/0x66 [bonding]
>> [<c015ccf3>] sys_delete_module+0x191/0x1f1
>> [<c0147a30>] ? up_read+0x16/0x2a
>> [<c0102a18>] ? restore_all_notrace+0x0/0x18
>> [<c0353357>] ? do_page_fault+0x0/0x393
>> [<c0102904>] sysenter_do_call+0x12/0x32
>> ---[ end trace 8f3eaeee682a572c ]---
>>
>> Any thoughts? I have not as yet investigated further.
>
>Weird.
>
>We have already run:
>rtnl_link_unregister.
> rtnl_kill_links
> dellink(bond0)
> unregister_netdevice(bond0)
> bond_uninit
> bond_remove_proc_entry
>
>
>So the proc entry should no longer be there. I'm a little nervous about
>the new unregister_netdevice_many but I don't see any obvious problems with
>that code.
>
>Were there by any chance any earlier errors that could have prevented the uninit?
>You weren't inserting multiple copies of the bonding driver?
No, to both questions. Also, if I back out the 7 bonding
patches, the same insmod / rmmod does not panic.
I just set it up and did it again. Fresh boot of the system
(which doesn't load bonding); "insmod drivers/net/bonding/bonding.ko;
rmmod bonding" and blammo.
A little bisect action reveals that the problem first appears
after applying the fifth patch (below). Does a basic insmod / rmmod
cycle work ok for you? I'm specifying no options to bonding.
-J
Subject: [PATCH 5/6] bond: Implement a basic set of rtnl link ops
[...]
This implements a basic set of rtnl link ops and takes advantage of
the fact that rtnl_link_unregister kills all of the surviving
devices to all us to kill bond_free_all. A module alias
is added so ip link add can pull in the bonding module.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
---
drivers/net/bonding/bond_main.c | 55 +++++++++++++++++++++-----------------
1 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 7a37ecf..6da2a82 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4612,22 +4612,6 @@ static void bond_uninit(struct net_device *bond_dev)
netif_addr_unlock_bh(bond_dev);
}
-/* Unregister and free all bond devices.
- * Caller must hold rtnl_lock.
- */
-static void bond_free_all(void)
-{
- struct bonding *bond, *nxt;
-
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
- struct net_device *bond_dev = bond->dev;
-
- unregister_netdevice(bond_dev);
- }
-
- bond_destroy_proc_dir();
-}
-
/*------------------------- Module initialization ---------------------------*/
/*
@@ -5065,6 +5049,23 @@ static int bond_init(struct net_device *bond_dev)
return 0;
}
+static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ if (tb[IFLA_ADDRESS]) {
+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+ return -EINVAL;
+ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+ return -EADDRNOTAVAIL;
+ }
+ return 0;
+}
+
+static struct rtnl_link_ops bond_link_ops __read_mostly = {
+ .kind = "bond",
+ .setup = bond_setup,
+ .validate = bond_validate,
+};
+
/* Create a new bond based on the specified name and bonding parameters.
* If name is NULL, obtain a suitable "bond%d" name for us.
* Caller must NOT hold rtnl_lock; we need to release it here before we
@@ -5086,6 +5087,8 @@ int bond_create(const char *name)
goto out;
}
+ bond_dev->rtnl_link_ops = &bond_link_ops;
+
if (!name) {
res = dev_alloc_name(bond_dev, "bond%d");
if (res < 0)
@@ -5115,6 +5118,10 @@ static int __init bonding_init(void)
bond_create_proc_dir();
+ res = rtnl_link_register(&bond_link_ops);
+ if (res)
+ goto err;
+
for (i = 0; i < max_bonds; i++) {
res = bond_create(NULL);
if (res)
@@ -5128,14 +5135,12 @@ static int __init bonding_init(void)
register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);
bond_register_ipv6_notifier();
-
- goto out;
-err:
- rtnl_lock();
- bond_free_all();
- rtnl_unlock();
out:
return res;
+err:
+ rtnl_link_unregister(&bond_link_ops);
+ bond_destroy_proc_dir();
+ goto out;
}
@@ -5147,9 +5152,8 @@ static void __exit bonding_exit(void)
bond_destroy_sysfs();
- rtnl_lock();
- bond_free_all();
- rtnl_unlock();
+ rtnl_link_unregister(&bond_link_ops);
+ bond_destroy_proc_dir();
}
module_init(bonding_init);
@@ -5158,3 +5162,4 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
+MODULE_ALIAS_RTNL_LINK("bond");
--
1.6.3.1.54.g99dd.dirty
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply related
* Re: [PATCH 0/6] Bonding simplifications and netns support
From: Eric W. Biederman @ 2009-10-31 0:27 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: David Miller, netdev
In-Reply-To: <21200.1256937150@death.nxdomain.ibm.com>
Jay Vosburgh <fubar@us.ibm.com> writes:
> I put patches 1-7 on a recent net-next-2.6, and from a simple
> "insmod bonding.ko; rmmod bonding" I'm seeing the following:
>
> Any thoughts? I have not as yet investigated further.
I just tried to reproduce this, without luck. My best guess is that there is
something odd particular to your setup.
A simple while :; modprobe bonding ; rmmod bonding ; done runs without problems
for me.
Eric
^ permalink raw reply
* Re: [PATCH] net: allow netdev_wait_allrefs() to run faster
From: Eric W. Biederman @ 2009-10-31 0:37 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: Eric Dumazet, Octavian Purdila, netdev, Cosmin Ratiu
In-Reply-To: <20091030235314.GH3141@kvack.org>
Benjamin LaHaise <bcrl@lhnet.ca> writes:
> On Fri, Oct 30, 2009 at 04:25:52PM -0700, Eric W. Biederman wrote:
>> I realized after sending the message that s_mode in sysfs_dirent is a
>> real size offense. It is a 16bit field packed in between two longs.
>> So in practice it is possible to move the s_mode up next to s_flags
>> and add a s_nlink after it both unsigned short and get a cheap sysfs_nlink.
>
> That doesn't work -- the number of directory entries can easily exceed 65535.
> Current mid range hardware is good enough to terminate 100,000 network
> interfaces on a single host.
On overflow you nlink becomes zero and you leave it there. That is how
ondisk filesystems handle that case on directories, and find etc
knows how to deal.
>> Since I'm not quite ready to post my patches. I will briefly
>> mention what I have in my queue and hopefully get things posted.
>>
>> I have changes to make it so that sysfs never has to go from
>> the sysfs_dirent to the sysfs inode.
>
> Ah, interesting.
I have to cleanup sysfs before I merge changes for supporting
multiple network namespaces.
>> I have changes to sys_sysctl() so that it becomes a filesystem lookup
>> under /proc/sys. Which ultimately makes the code easier to maintain
>> and debug.
>
> That sounds like a much saner approach, but has the wrinkle that procfs can
> be configured out.
So I will add the dependency. There are very few serious users of sys_sysctl,
and all of them have been getting a deprecated interface warning every
time they use it for the last several years.
>> Now back to getting things forward ported and ready to post.
>
> I'm looking forward to those changes. I've been ignoring procfs for the
> time being by disabling the per-interface entries in the network stack,
> but there is some desire to be able to enable rp_filter on a per-interface
> radius config at runtime. rp_filter has to be disabled across the board
> on my access routers, as there are several places where assymetric routing
> is used for performance reasons.
Just out of curiosity does the loose rp_filter mode work for you?
Eric
^ permalink raw reply
* [PATCH net-next-2.6] veth: Fix unregister_netdevice_queue for veth
From: Eric W. Biederman @ 2009-10-31 0:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, Linux Netdev List, Pavel Emelyanov
In-Reply-To: <m1hbtgmqew.fsf@fess.ebiederm.org>
I tested the recent unregister many changes and got a weird,
nasty and seemingly unrelasted kernel oops. Changing
unregister_netdevice_queue to use list_move_tail fixes
the problem for me.
ip link add type veth
rmmod veth
ls /sys/class/net/
showed one of the veth devices still present.
A subsequent ip link oopsed the box.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
diff --git a/net/core/dev.c b/net/core/dev.c
index 94f42a1..9c0b202 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5227,6 +5227,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
netdev_init_queues(dev);
INIT_LIST_HEAD(&dev->napi_list);
+ INIT_LIST_HEAD(&dev->unreg_list);
dev->priv_flags = IFF_XMIT_DST_RELEASE;
setup(dev);
strcpy(dev->name, name);
@@ -5308,7 +5309,7 @@ void unregister_netdevice_queue(struct net_device *dev, struct list_head *head)
ASSERT_RTNL();
if (head) {
- list_add_tail(&dev->unreg_list, head);
+ list_move_tail(&dev->unreg_list, head);
} else {
rollback_registered(dev);
/* Finish processing unregister after unlock */
^ permalink raw reply related
* Re: [PATCH 0/6] Bonding simplifications and netns support
From: Eric W. Biederman @ 2009-10-31 1:06 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: David Miller, netdev
In-Reply-To: <32609.1256947853@death.nxdomain.ibm.com>
Jay Vosburgh <fubar@us.ibm.com> writes:
> No, to both questions. Also, if I back out the 7 bonding
> patches, the same insmod / rmmod does not panic.
>
> I just set it up and did it again. Fresh boot of the system
> (which doesn't load bonding); "insmod drivers/net/bonding/bonding.ko;
> rmmod bonding" and blammo.
>
> A little bisect action reveals that the problem first appears
> after applying the fifth patch (below). Does a basic insmod / rmmod
> cycle work ok for you? I'm specifying no options to bonding.
It works here. The only issue I found was that veth wasn't quite
working. I am wondering if there was some version of the tree
where rtnl_link_unregister is broken and you applied the patches to that.
I tested the net-next tree with my patches at the top:
There are some other differences like I am running a 64bit kernel but
I don't expect that would make a difference in practice.
Eric
commit 6639104bd826e0b1388c69a6b7564fffc636c8a8
Author: Eric W. Biederman <ebiederm@xmission.com>
Date: Thu Oct 29 23:58:54 2009 +0000
bond: Get the rtnl_link_ops support correct
- Don't call rtnl_link_unregister if rtnl_link_register fails
- Set .priv_size so we aren't stomping on uninitialized memory
when we use netdev_priv, on bond devices created with
ip link add type bond.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 0/6] Bonding simplifications and netns support
From: Jay Vosburgh @ 2009-10-31 1:45 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: David Miller, netdev
In-Reply-To: <m1ljisid8n.fsf@fess.ebiederm.org>
Eric W. Biederman <ebiederm@xmission.com> wrote:
>Jay Vosburgh <fubar@us.ibm.com> writes:
>
>> No, to both questions. Also, if I back out the 7 bonding
>> patches, the same insmod / rmmod does not panic.
>>
>> I just set it up and did it again. Fresh boot of the system
>> (which doesn't load bonding); "insmod drivers/net/bonding/bonding.ko;
>> rmmod bonding" and blammo.
>>
>> A little bisect action reveals that the problem first appears
>> after applying the fifth patch (below). Does a basic insmod / rmmod
>> cycle work ok for you? I'm specifying no options to bonding.
>
>It works here. The only issue I found was that veth wasn't quite
>working. I am wondering if there was some version of the tree
>where rtnl_link_unregister is broken and you applied the patches to that.
Must have been, I did a pull of net-next-2.6 and it seems to
work ok now. Not sure what it was; I was only a day or so behind.
Anyway, it doesn't panic now; I'll give it some further testing next
week.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* Re: WARNING: at net/ipv4/af_inet.c:154 inet_sock_destruct
From: Eric Dumazet @ 2009-10-31 9:20 UTC (permalink / raw)
To: David Miller; +Cc: francis.moro, linux-kernel, netdev
In-Reply-To: <20091030.122640.137286305.davem@davemloft.net>
David Miller a écrit :
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Fri, 30 Oct 2009 16:03:53 +0100
>
>> [PATCH take2] net: fix sk_forward_alloc corruption
>>
>> On UDP sockets, we must call skb_free_datagram() with socket locked,
>> or risk sk_forward_alloc corruption. This requirement is not respected
>> in SUNRPC.
>>
>> Add a convenient helper, skb_free_datagram_locked() and use it in SUNRPC
>>
>> Reported-by: Francis Moreau <francis.moro@gmail.com>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>
> I've tentatively applied this to my net-2.6 tree, I won't
> push it out until we have positive testing results.
I tested nfs/nfsd with fillowing additional debugging patch.
Without the fix (net: fix sk_forward_alloc corruption), I got warnings,
while with fix applied, I got no warnings. Its probably hard to hit
original bug since its a very small race window.
Trace without fix :
[ 226.686788] RPC: Registered udp transport module.
[ 226.686791] RPC: Registered tcp transport module.
[ 226.686792] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 226.851677] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
[ 226.869381] NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory
[ 226.869443] NFSD: unable to find recovery directory /var/lib/nfs/v4recovery
[ 226.869488] NFSD: starting 90-second grace period
[ 226.870564] svc: failed to register lockdv1 RPC service (errno 97).
[ 244.401237] ------------[ cut here ]------------
[ 244.401288] WARNING: at include/net/sock.h:886 sock_rfree+0x54/0x70()
[ 244.401334] Hardware name: ProLiant BL460c G1
[ 244.401379] Modules linked in: nfsd lockd auth_rpcgss sunrpc exportfs bonding ipv6
[ 244.401699] Pid: 5295, comm: nfsd Not tainted 2.6.32-rc3-00920-gbdd6be3-dirty #342
[ 244.401745] Call Trace:
[ 244.401784] [<c055355a>] ? printk+0x1d/0x23
[ 244.401827] [<c023c3f2>] warn_slowpath_common+0x72/0xa0
[ 244.401869] [<c04b0d54>] ? sock_rfree+0x54/0x70
[ 244.401909] [<c04b0d54>] ? sock_rfree+0x54/0x70
[ 244.401950] [<c023c43a>] warn_slowpath_null+0x1a/0x20
[ 244.401991] [<c04b0d54>] sock_rfree+0x54/0x70
[ 244.402033] [<c04b4cf5>] skb_release_head_state+0x45/0xe0
[ 244.402084] [<c04b49f0>] __kfree_skb+0x10/0x90
[ 244.402125] [<c04b4a8c>] consume_skb+0x1c/0x40
[ 244.402166] [<c04b7c62>] skb_free_datagram+0x12/0x70
[ 244.402217] [<fc9fa177>] svc_release_skb+0x37/0x60 [sunrpc]
[ 244.402261] [<c026f452>] ? module_put+0x62/0xf0
[ 244.402308] [<fca05c98>] svc_send+0x28/0xc0 [sunrpc]
[ 244.402356] [<fc9f8acb>] svc_process+0x22b/0x770 [sunrpc]
[ 244.402416] [<fd04895c>] nfsd+0xac/0x140 [nfsd]
[ 244.402484] [<fd0488b0>] ? nfsd+0x0/0x140 [nfsd]
[ 244.402543] [<c0257ab4>] kthread+0x74/0x80
[ 244.402602] [<c0257a40>] ? kthread+0x0/0x80
[ 244.402656] [<c020390f>] kernel_thread_helper+0x7/0x10
[ 244.402711] ---[ end trace e202cdb1b491aa15 ]---
Debugging patch :
Intent is to make sure sock is locked by user or by softirq handler,
unless we are currently dismantling socket (sk_refcnt==0)
To speedup this test, we could use several bits of sk_lock.owned instead
of one for the user case.
(one for lock owned by user, one for lowk owned by softirq, one in dismantle phase)
diff --git a/include/net/sock.h b/include/net/sock.h
index 55de3bd..08ecb0e 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -849,10 +849,15 @@ static inline int sk_rmem_schedule(struct sock *sk, int size)
__sk_mem_schedule(sk, size, SK_MEM_RECV);
}
+#define sock_owned_by_user(sk) ((sk)->sk_lock.owned)
+#define sock_owned(sk) ((sk)->sk_lock.owned || \
+ spin_is_locked(&(sk)->sk_lock.slock))
+
static inline void sk_mem_reclaim(struct sock *sk)
{
if (!sk_has_account(sk))
return;
+ WARN_ON(!(sock_owned(sk) || atomic_read(&sk->sk_refcnt) == 0));
if (sk->sk_forward_alloc >= SK_MEM_QUANTUM)
__sk_mem_reclaim(sk);
}
@@ -861,6 +866,7 @@ static inline void sk_mem_reclaim_partial(struct sock *sk)
{
if (!sk_has_account(sk))
return;
+ WARN_ON(!(sock_owned(sk) || atomic_read(&sk->sk_refcnt) == 0));
if (sk->sk_forward_alloc > SK_MEM_QUANTUM)
__sk_mem_reclaim(sk);
}
@@ -869,6 +875,7 @@ static inline void sk_mem_charge(struct sock *sk, int size)
{
if (!sk_has_account(sk))
return;
+ WARN_ON(!sock_owned(sk));
sk->sk_forward_alloc -= size;
}
@@ -876,6 +883,7 @@ static inline void sk_mem_uncharge(struct sock *sk, int size)
{
if (!sk_has_account(sk))
return;
+ WARN_ON(!sock_owned(sk));
sk->sk_forward_alloc += size;
}
@@ -900,7 +908,6 @@ static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
* Since ~2.3.5 it is also exclusive sleep lock serializing
* accesses from user process context.
*/
-#define sock_owned_by_user(sk) ((sk)->sk_lock.owned)
/*
* Macro so as to not evaluate some arguments when
^ permalink raw reply related
* [PATCH] e1000: the power down when running ifdown command
From: Naohiro Ooiwa @ 2009-10-31 9:39 UTC (permalink / raw)
To: jeffrey.t.kirsher, jesse.brandeburg, peter.p.waskiewicz.jr,
john.ronciak, davem
Cc: Andrew Morton, netdev, svaidy, e1000-devel
Hi All
I resend my patch.
Sorry, my previous mail lacked an explanation.
The e1000 driver doesn't let the power down when running ifdown command.
So, I set to the D3hot state of a PCI device at the end of e1000_close().
With this modification, e1000 driver reduces power by ifdown.
It's about 6 watts when I measured a total power of one server machine
in my environment.
I tested this patch. The result is good enough to me.
Could you please check my patch ?
If I should have other considerations, please tell me.
Thanks you.
Naohiro Ooiwa
Signed-off-by: Naohiro Ooiwa <nooiwa@miraclelinux.com>
---
drivers/net/e1000/e1000_main.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index bcd192c..12e1a42 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -26,6 +26,11 @@
*******************************************************************************/
+/*
+ * define this if you want pci save power while ifdown.
+ */
+#define E1000_PCI_POWER_SAVE
+
#include "e1000.h"
#include <net/ip6_checksum.h>
@@ -1248,6 +1253,23 @@ static int e1000_open(struct net_device *netdev)
struct e1000_hw *hw = &adapter->hw;
int err;
+#ifdef E1000_PCI_POWER_SAVE
+ struct pci_dev *pdev = adapter->pdev;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
+ if (err) {
+ printk(KERN_ERR "e1000: Cannot enable PCI device from power-save\n");
+ return err;
+ }
+ pci_set_master(pdev);
+#endif
+
/* disallow open during test */
if (test_bit(__E1000_TESTING, &adapter->flags))
return -EBUSY;
@@ -1265,6 +1287,7 @@ static int e1000_open(struct net_device *netdev)
goto err_setup_rx;
e1000_power_up_phy(adapter);
+ e1000_reset(adapter);
adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
if ((hw->mng_cookie.status &
@@ -1341,6 +1364,15 @@ static int e1000_close(struct net_device *netdev)
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
}
+#ifdef E1000_PCI_POWER_SAVE
+#ifdef CONFIG_PM
+ pci_save_state(adapter->pdev);
+#endif
+ pci_disable_device(adapter->pdev);
+ pci_wake_from_d3(adapter->pdev, true);
+ pci_set_power_state(adapter->pdev, PCI_D3hot);
+#endif
+
return 0;
}
--
1.5.4.1
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH net-next-2.6] veth: Fix unregister_netdevice_queue for veth
From: Eric Dumazet @ 2009-10-31 9:41 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: David S. Miller, Linux Netdev List, Pavel Emelyanov
In-Reply-To: <m1639wjshq.fsf_-_@fess.ebiederm.org>
Eric W. Biederman a écrit :
> I tested the recent unregister many changes and got a weird,
> nasty and seemingly unrelasted kernel oops. Changing
> unregister_netdevice_queue to use list_move_tail fixes
> the problem for me.
>
> ip link add type veth
> rmmod veth
>
> ls /sys/class/net/
> showed one of the veth devices still present.
>
> A subsequent ip link oopsed the box.
>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>
Yes, problem is __rtnl_kill_links() doesnt anymore restart
its loop and does :
for_each_netdev(net, dev) {
if (dev->rtnl_link_ops == ops)
ops->dellink(dev, &list_kill);
}
unregister_netdevice_many(&list_kill);
As veth wants in its dellink() method to unregister two netdevices,
we really want your fix or corrupt list_kill
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Thanks Eric
^ permalink raw reply
* Re: [PATCH net-next-2.6] veth: Fix veth_dellink method
From: Eric Dumazet @ 2009-10-31 9:43 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: David S. Miller, Linux Netdev List, Pavel Emelyanov
In-Reply-To: <m1hbtgmqew.fsf@fess.ebiederm.org>
Eric W. Biederman a écrit :
> Eric Dumazet <eric.dumazet@gmail.com> writes:
>>
>> diff --git a/drivers/net/veth.c b/drivers/net/veth.c
>> index ffb502d..9bed694 100644
>> --- a/drivers/net/veth.c
>> +++ b/drivers/net/veth.c
>> @@ -450,8 +450,8 @@ static void veth_dellink(struct net_device *dev, struct list_head *head)
>> priv = netdev_priv(dev);
>> peer = priv->peer;
>>
>> - unregister_netdevice(dev);
>> - unregister_netdevice(peer);
>> + unregister_netdevice_queue(dev, head);
>> + unregister_netdevice_queue(peer, head);
>
> Unless I am mistaken you need to change the list_add_tail to
> list_move_tail in unregister_netdevice_queue because we will be
> adding each veth device twice.
>
You are right, and your patch is the solution to this problem
Thanks
^ permalink raw reply
* Net driver module dependencies on PHY driver modules
From: Ben Hutchings @ 2009-10-31 11:42 UTC (permalink / raw)
To: Matt Carlson, Michael Chan, netdev; +Cc: 553024
[-- Attachment #1: Type: text/plain, Size: 686 bytes --]
I'm handling a bug report <http://bugs.debian.org/553024> relating to
tg3 using phylib and missing the broadcom module.
There seem to be two general problems here:
1. PHY drivers are not auto-loaded
2. An initramfs builder cannot statically determine that a net device
requires a PHY driver
It seems to me that PHY drivers should have aliases based on MDIO PHY
ids, and phylib should request_module() if no suitable driver is
registered. This would solve (1) and go some way to solving (2).
Ben.
--
Ben Hutchings
The generation of random numbers is too important to be left to chance.
- Robert Coveyou
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: Net driver module dependencies on PHY driver modules
From: Tim Gardner @ 2009-10-31 15:34 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Matt Carlson, Michael Chan, netdev, 553024
In-Reply-To: <1256989326.3136.284.camel@localhost>
Ben Hutchings wrote:
> I'm handling a bug report <http://bugs.debian.org/553024> relating to
> tg3 using phylib and missing the broadcom module.
>
> There seem to be two general problems here:
> 1. PHY drivers are not auto-loaded
> 2. An initramfs builder cannot statically determine that a net device
> requires a PHY driver
>
> It seems to me that PHY drivers should have aliases based on MDIO PHY
> ids, and phylib should request_module() if no suitable driver is
> registered. This would solve (1) and go some way to solving (2).
>
> Ben.
>
I encountered the same issue with Karmic and worked around it by
building in all of the phylib modules, e.g., CONFIG_BROADCOM_PHY=y. I
agree that its not the best long term solution.
rtg
--
Tim Gardner tim.gardner@canonical.com
^ permalink raw reply
* Re: RFC: netdev: allow ethtool physical id to drop rtnl_lock
From: Michael Chan @ 2009-10-31 16:44 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <20091030104201.6bb03b23@nehalam>
On Fri, 2009-10-30 at 10:42 -0700, Stephen Hemminger wrote:
> The ethtool operation to blink LED can take an indeterminately long time,
> blocking out other operations (via rtnl_lock). This patch is an attempt
> to work around the problem.
>
> It does need more discussion, because it will mean that drivers that formerly
> were protected from changes during blink aren't. For example, user could
> start device blinking, and then plug in cable causing change netlink event
> to change state or pull cable and have device come down.
Yeah, the biggest concern is shutting down the device while it is still
blinking. During shutdown, some devices are brought to low power state
and the chip will no longer respond to I/Os to blink the LEDs. On some
systems, this can cause bus hang or NMI.
>
> The other possibility is to do this on a driver by driver basis
> which is more effort.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
>
> --- a/net/core/ethtool.c 2009-10-30 10:27:23.621917624 -0700
> +++ b/net/core/ethtool.c 2009-10-30 10:35:53.787670774 -0700
> @@ -17,6 +17,7 @@
> #include <linux/errno.h>
> #include <linux/ethtool.h>
> #include <linux/netdevice.h>
> +#include <linux/rtnetlink.h>
> #include <asm/uaccess.h>
>
> /*
> @@ -781,6 +782,8 @@ static int ethtool_get_strings(struct ne
> static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
> {
> struct ethtool_value id;
> + int err;
> + static int busy;
>
> if (!dev->ethtool_ops->phys_id)
> return -EOPNOTSUPP;
> @@ -788,7 +791,21 @@ static int ethtool_phys_id(struct net_de
> if (copy_from_user(&id, useraddr, sizeof(id)))
> return -EFAULT;
>
> - return dev->ethtool_ops->phys_id(dev, id.data);
> + if (busy)
> + return -EBUSY;
> +
> + /* This operation may take a long time, drop lock */
> + busy = 1;
> + dev_hold(dev);
> + rtnl_unlock();
> +
> + err = dev->ethtool_ops->phys_id(dev, id.data);
> +
> + rtnl_lock();
> + dev_put(dev);
> + busy = 0;
> +
> + return err;
> }
>
> static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [RFC] multiqueue changes
From: Michael Chan @ 2009-10-31 17:25 UTC (permalink / raw)
To: Jarek Poplawski
Cc: Patrick McHardy, Eric Dumazet, David S. Miller, Linux Netdev List
In-Reply-To: <20091030100033.GA6150@ff.dom.local>
On Fri, 2009-10-30 at 03:00 -0700, Jarek Poplawski wrote:
> On Thu, Oct 29, 2009 at 11:12:39PM +0100, Patrick McHardy wrote:
> > Jarek Poplawski wrote:
> > > On Thu, Oct 29, 2009 at 05:37:23PM +0100, Patrick McHardy wrote:
> > > ...
> > >> Well, we do need both values for supporting changes to the actually
> > >> used numbers of TX queues. If I understood Dave's explanation correctly,
> > >> this is also what's intended. It also doesn't seem unreasonable
> > >> what bnx2 is doing.
> > >
> > > Exactly. With a growing number of cores, both available and powered
> > > off, these values will be soon treated more carefully than now.
> > >
> > >> But getting back to the problem Eric reported - so you're suggesting
> > >> that bnx2.c should also adjust num_tx_queues in case the hardware
> > >> doesn't support multiqueue? That seems reasonable as well.
> > >
> > > Currently, declaring num_tx_queues with alloc_netdev_mq() looks like
> > > too soon for some drivers. It seems they should be able to do it
> > > separately later during the .probe.
> >
> > The value passed into alloc_netdev_mq() is just used for allocation
> > purposes, from what I can tell there's no downside in reducing it
> > before the dev_activate() call.
>
> Right, but IMHO this reducing (or reallocation) should be done with
> some API. Simple overwriting of num_tx_queues proposed by Eric, even
> if no downside now, seems to be asking for problems in the future.
>
> > > There is a question if .ndo_open should be considered too.
> >
> > I currently can't see any purpose in decreasing num_tx_queues after
> > registration instead of real_num_tx_queues.
>
> I agree, but since Eric's example shows some drivers do it (almost)
> like this, I'd prefer authors/maintainers answer this question.
>
We need the netdev and the private structure at the beginning of
->probe() to store values as we probe the device. Later on in
->probe(), we'll know whether the device supports MSI-X and multiqueue.
If we successfully enable MSI-X in ->ndo_open(), tx multiqueue will be
used.
So if we can separate the allocation of the netdev and the private
structure from the tx queues, we can allocate and set the exact number
of num_tx_queues in ->ndo_open().
^ permalink raw reply
* Re: [PATCH] e1000: the power down when running ifdown command
From: Stephen Hemminger @ 2009-10-31 17:58 UTC (permalink / raw)
To: Naohiro Ooiwa
Cc: e1000-devel, netdev, jesse.brandeburg, john.ronciak,
jeffrey.t.kirsher, Andrew Morton, svaidy, davem
In-Reply-To: <4AEC05E8.40600@miraclelinux.com>
On Sat, 31 Oct 2009 18:39:52 +0900
Naohiro Ooiwa <nooiwa@miraclelinux.com> wrote:
> Hi All
>
> I resend my patch.
> Sorry, my previous mail lacked an explanation.
>
>
> The e1000 driver doesn't let the power down when running ifdown command.
> So, I set to the D3hot state of a PCI device at the end of e1000_close().
>
> With this modification, e1000 driver reduces power by ifdown.
> It's about 6 watts when I measured a total power of one server machine
> in my environment.
>
> I tested this patch. The result is good enough to me.
>
> Could you please check my patch ?
> If I should have other considerations, please tell me.
>
Does this work with Wake On Lan?
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
^ permalink raw reply
* Re: large packet loss take2 2.6.31.x
From: Frans Pop @ 2009-10-31 18:44 UTC (permalink / raw)
To: Caleb Cushing; +Cc: linux-kernel, netdev
In-Reply-To: <81bfc67a0910310721p21046931o9b512cfd0a8a7acb@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1158 bytes --]
Adding netdev in CC. Original message + attachments follow.
=========
so ever since arch rolled out 2.6.31.x I've been having problems with
my network (again) where I've been losing a large amount of packets
(just testing with mtr somewhere between 30/50%). first I figured it
was the same problem as I had in 2.6.30.x (and maybe it is?) but that
appeared to get fixed. when I started bisecting the bug wasn't
apparent in 2.6.31.0 but I knew for sure it was in .5 (I couldn't
remember if I had noticed it again in .3)
I'm attaching the bisection log and a 'good' dmesg output.
c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9 is the first bad commit
I'm not going to pretend to understand why this patch is breaking my
networking but between bisection and testing it appears to be... I've
never bisected before and I'm definitely not a kernel hacker (I can
barely read C).
I should also note that the wireshark dump here
http://bugzilla.kernel.org/show_bug.cgi?id=13835 is related to this.
and if it's not the same bug then possibly a new one should be opened.
P.S. I'm not subscribed to the list please CC me
Caleb Cushing
http://xenoterracide.blogspot.com
[-- Attachment #2: bisect.log --]
[-- Type: text/x-log, Size: 1347 bytes --]
# bad: [e2984cbfddd5c8fac88b24d7e5f28e1cfb6f3838] Linux 2.6.31.5
# good: [74fca6a42863ffacaf7ba6f1936a9f228950f657] Linux 2.6.31
git bisect start 'v2.6.31.5' 'v2.6.31' '--'
# good: [08f30ff9811e59c08d1cee043ce55b2e862efe58] tty: USB hangup is racy
git bisect good 08f30ff9811e59c08d1cee043ce55b2e862efe58
# bad: [ddf2acb72f3df470ce15eb23ee97cd3be23016f8] KVM: fix LAPIC timer period overflow
git bisect bad ddf2acb72f3df470ce15eb23ee97cd3be23016f8
# bad: [03429ffaea91375d8ed80a60fa13c9ffe694539a] Fix idle time field in /proc/uptime
git bisect bad 03429ffaea91375d8ed80a60fa13c9ffe694539a
# bad: [2f670d465897b491da0b82fd8b047b9ec75bf8c8] USB: xhci: Support full speed devices.
git bisect bad 2f670d465897b491da0b82fd8b047b9ec75bf8c8
# bad: [b8580fde3ba44a0f00bf186dc5e4935bbd51be29] usb-serial: fix termios initialization logic
git bisect bad b8580fde3ba44a0f00bf186dc5e4935bbd51be29
# bad: [c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9] usb-serial: change referencing of port and serial structures
git bisect bad c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9
# good: [fa31221e38207cece07a6d96854a0fcf47c75ae5] hwmon: (asus_atk0110) Add maintainer information
git bisect good fa31221e38207cece07a6d96854a0fcf47c75ae5
# good: [17fd426331d1e4611654985dd545a52d200dd9d1] tty: USB serial termios bits
git bisect good 17fd426331d1e4611654985dd545a52d200dd9d1
[-- Attachment #3: dmesg.log --]
[-- Type: text/x-log, Size: 31964 bytes --]
Linux version 2.6.31.1-test-00092-g17fd426 (xenoterracide@slave4) (gcc version 4.4.2 (GCC) ) #15 SMP PREEMPT Sat Oct 31 09:54:39 EDT 2009
Command line: root=/dev/disk/by-uuid/e9367b57-da02-48bf-9cd7-d41ce53520a3 ro
KERNEL supported cpus:
Intel GenuineIntel
AMD AuthenticAMD
Centaur CentaurHauls
BIOS-provided physical RAM map:
BIOS-e820: 0000000000000000 - 0000000000099c00 (usable)
BIOS-e820: 0000000000099c00 - 00000000000a0000 (reserved)
BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
BIOS-e820: 0000000000100000 - 00000000cf590000 (usable)
BIOS-e820: 00000000cf590000 - 00000000cf5e3000 (ACPI NVS)
BIOS-e820: 00000000cf5e3000 - 00000000cf5f0000 (ACPI data)
BIOS-e820: 00000000cf5f0000 - 00000000cf600000 (reserved)
BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)
BIOS-e820: 0000000100000000 - 00000001b0000000 (usable)
DMI 2.5 present.
last_pfn = 0x1b0000 max_arch_pfn = 0x400000000
MTRR default type: uncachable
MTRR fixed ranges enabled:
00000-9FFFF write-back
A0000-BFFFF uncachable
C0000-E7FFF write-protect
E8000-EFFFF uncachable
F0000-FFFFF write-through
MTRR variable ranges enabled:
0 base 100000000 mask F80000000 write-back
1 base 180000000 mask FE0000000 write-back
2 base 1A0000000 mask FF0000000 write-back
3 base 000000000 mask F80000000 write-back
4 base 080000000 mask FC0000000 write-back
5 base 0C0000000 mask FF0000000 write-back
6 base 0CF700000 mask FFFF00000 uncachable
7 base 0CF800000 mask FFF800000 uncachable
x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106
e820 update range: 00000000cf700000 - 0000000100000000 (usable) ==> (reserved)
last_pfn = 0xcf590 max_arch_pfn = 0x400000000
e820 update range: 0000000000001000 - 0000000000006000 (usable) ==> (reserved)
Scanning 1 areas for low memory corruption
modified physical RAM map:
modified: 0000000000000000 - 0000000000001000 (usable)
modified: 0000000000001000 - 0000000000006000 (reserved)
modified: 0000000000006000 - 0000000000099c00 (usable)
modified: 0000000000099c00 - 00000000000a0000 (reserved)
modified: 00000000000f0000 - 0000000000100000 (reserved)
modified: 0000000000100000 - 00000000cf590000 (usable)
modified: 00000000cf590000 - 00000000cf5e3000 (ACPI NVS)
modified: 00000000cf5e3000 - 00000000cf5f0000 (ACPI data)
modified: 00000000cf5f0000 - 00000000cf600000 (reserved)
modified: 00000000e0000000 - 00000000f0000000 (reserved)
modified: 00000000fec00000 - 0000000100000000 (reserved)
modified: 0000000100000000 - 00000001b0000000 (usable)
initial memory mapped : 0 - 20000000
init_memory_mapping: 0000000000000000-00000000cf590000
0000000000 - 00cf400000 page 2M
00cf400000 - 00cf590000 page 4k
kernel direct mapping tables up to cf590000 @ 8000-e000
init_memory_mapping: 0000000100000000-00000001b0000000
0100000000 - 01b0000000 page 2M
kernel direct mapping tables up to 1b0000000 @ c000-14000
RAMDISK: 37ef1000 - 37fef9a7
ACPI: RSDP 00000000000f97a0 00024 (v02 DELL )
ACPI: XSDT 00000000cf5e3080 0005C (v01 DELL FX09 42302E31 AWRD 00000000)
ACPI: FACP 00000000cf5e7200 000F4 (v03 DELL FX09 42302E31 AWRD 00000000)
ACPI: DSDT 00000000cf5e3200 03FFC (v01 DELL AWRDACPI 00001000 MSFT 03000000)
ACPI: FACS 00000000cf590000 00040
ACPI: HPET 00000000cf5e73c0 00038 (v01 DELL FX09 42302E31 AWRD 00000098)
ACPI: MCFG 00000000cf5e7400 0003C (v01 DELL FX09 42302E31 AWRD 00000000)
ACPI: DMY1 00000000cf5e7440 00176 (v01 DELL FX09 42302E31 AWRD 00000000)
ACPI: DMY2 00000000cf5e75c0 00080 (v01 DELL FX09 42302E31 AWRD 00000000)
ACPI: APIC 00000000cf5e7300 00084 (v01 DELL FX09 42302E31 AWRD 00000000)
ACPI: SSDT 00000000cf5e7f60 00380 (v01 PmRef CpuPm 00003000 INTL 20041203)
ACPI: Local APIC address 0xfee00000
(8 early reservations) ==> bootmem [0000000000 - 01b0000000]
#0 [0000000000 - 0000001000] BIOS data page ==> [0000000000 - 0000001000]
#1 [0000006000 - 0000008000] TRAMPOLINE ==> [0000006000 - 0000008000]
#2 [0001000000 - 00016837d0] TEXT DATA BSS ==> [0001000000 - 00016837d0]
#3 [0037ef1000 - 0037fef9a7] RAMDISK ==> [0037ef1000 - 0037fef9a7]
#4 [0000099c00 - 0000100000] BIOS reserved ==> [0000099c00 - 0000100000]
#5 [0001684000 - 00016840f8] BRK ==> [0001684000 - 00016840f8]
#6 [0000008000 - 000000c000] PGTABLE ==> [0000008000 - 000000c000]
#7 [000000c000 - 000000f000] PGTABLE ==> [000000c000 - 000000f000]
found SMP MP-table at [ffff8800000f3f00] f3f00
[ffffea0000000000-ffffea0005ffffff] PMD -> [ffff880028600000-ffff88002dbfffff] on node 0
Zone PFN ranges:
DMA 0x00000000 -> 0x00001000
DMA32 0x00001000 -> 0x00100000
Normal 0x00100000 -> 0x001b0000
Movable zone start PFN for each node
early_node_map[4] active PFN ranges
0: 0x00000000 -> 0x00000001
0: 0x00000006 -> 0x00000099
0: 0x00000100 -> 0x000cf590
0: 0x00100000 -> 0x001b0000
On node 0 totalpages: 1570084
DMA zone: 56 pages used for memmap
DMA zone: 112 pages reserved
DMA zone: 3820 pages, LIFO batch:0
DMA32 zone: 14280 pages used for memmap
DMA32 zone: 830920 pages, LIFO batch:31
Normal zone: 9856 pages used for memmap
Normal zone: 711040 pages, LIFO batch:31
ACPI: PM-Timer IO Port: 0x408
ACPI: Local APIC address 0xfee00000
ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] enabled)
ACPI: LAPIC (acpi_id[0x02] lapic_id[0x03] enabled)
ACPI: LAPIC (acpi_id[0x03] lapic_id[0x02] enabled)
ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
ACPI: LAPIC_NMI (acpi_id[0x02] high edge lint[0x1])
ACPI: LAPIC_NMI (acpi_id[0x03] high edge lint[0x1])
ACPI: IOAPIC (id[0x04] address[0xfec00000] gsi_base[0])
IOAPIC[0]: apic_id 4, version 32, address 0xfec00000, GSI 0-23
ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
ACPI: IRQ0 used by override.
ACPI: IRQ2 used by override.
ACPI: IRQ9 used by override.
Using ACPI (MADT) for SMP configuration information
ACPI: HPET id: 0x8086a201 base: 0xfed00000
SMP: Allowing 4 CPUs, 0 hotplug CPUs
nr_irqs_gsi: 24
PM: Registered nosave memory: 0000000000001000 - 0000000000006000
PM: Registered nosave memory: 0000000000099000 - 000000000009a000
PM: Registered nosave memory: 000000000009a000 - 00000000000a0000
PM: Registered nosave memory: 00000000000a0000 - 00000000000f0000
PM: Registered nosave memory: 00000000000f0000 - 0000000000100000
PM: Registered nosave memory: 00000000cf590000 - 00000000cf5e3000
PM: Registered nosave memory: 00000000cf5e3000 - 00000000cf5f0000
PM: Registered nosave memory: 00000000cf5f0000 - 00000000cf600000
PM: Registered nosave memory: 00000000cf600000 - 00000000e0000000
PM: Registered nosave memory: 00000000e0000000 - 00000000f0000000
PM: Registered nosave memory: 00000000f0000000 - 00000000fec00000
PM: Registered nosave memory: 00000000fec00000 - 0000000100000000
Allocating PCI resources starting at cf600000 (gap: cf600000:10a00000)
NR_CPUS:16 nr_cpumask_bits:16 nr_cpu_ids:4 nr_node_ids:1
PERCPU: Embedded 28 pages at ffff880028034000, static data 82400 bytes
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 1545780
Kernel command line: root=/dev/disk/by-uuid/e9367b57-da02-48bf-9cd7-d41ce53520a3 ro
PID hash table entries: 4096 (order: 12, 32768 bytes)
Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
Initializing CPU#0
Checking aperture...
No AGP bridge found
Calgary: detecting Calgary via BIOS EBDA area
Calgary: Unable to locate Rio Grande table in EBDA - bailing!
PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
Placing 64MB software IO TLB between ffff880020000000 - ffff880024000000
software IO TLB at phys 0x20000000 - 0x24000000
Memory: 6104592k/7077888k available (3629k kernel code, 797552k absent, 174760k reserved, 1500k data, 484k init)
SLUB: Genslabs=13, HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
NR_IRQS:768
Fast TSC calibration using PIT
Detected 2393.837 MHz processor.
Console: colour VGA+ 80x25
console [tty0] enabled
hpet clockevent registered
HPET: 4 timers in total, 0 timers will be used for per-cpu timer
Calibrating delay loop (skipped), value calculated using timer frequency.. 4789.16 BogoMIPS (lpj=7979456)
Security Framework initialized
Mount-cache hash table entries: 256
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 4096K
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 0
mce: CPU supports 6 MCE banks
CPU0: Thermal monitoring enabled (TM2)
using mwait in idle threads.
Performance Counters: Core2 events, Intel PMU driver.
... version: 2
... bit width: 40
... generic counters: 2
... value mask: 000000ffffffffff
... max period: 000000007fffffff
... fixed-purpose counters: 3
... counter mask: 0000000700000003
ACPI: Core revision 20090521
Setting APIC routing to flat
..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
CPU0: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz stepping 0b
Booting processor 1 APIC 0x1 ip 0x6000
Initializing CPU#1
Calibrating delay using timer specific routine.. 4789.48 BogoMIPS (lpj=7979981)
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 4096K
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 1
mce: CPU supports 6 MCE banks
CPU1: Thermal monitoring enabled (TM2)
x86 PAT enabled: cpu 1, old 0x7040600070406, new 0x7010600070106
CPU1: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz stepping 0b
checking TSC synchronization [CPU#0 -> CPU#1]: passed.
Booting processor 2 APIC 0x3 ip 0x6000
Initializing CPU#2
Calibrating delay using timer specific routine.. 4789.51 BogoMIPS (lpj=7980021)
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 4096K
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 3
mce: CPU supports 6 MCE banks
CPU2: Thermal monitoring enabled (TM2)
x86 PAT enabled: cpu 2, old 0x7040600070406, new 0x7010600070106
CPU2: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz stepping 0b
checking TSC synchronization [CPU#0 -> CPU#2]: passed.
Booting processor 3 APIC 0x2 ip 0x6000
Initializing CPU#3
Calibrating delay using timer specific routine.. 4789.56 BogoMIPS (lpj=7980102)
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 4096K
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 2
mce: CPU supports 6 MCE banks
CPU3: Thermal monitoring enabled (TM2)
x86 PAT enabled: cpu 3, old 0x7040600070406, new 0x7010600070106
CPU3: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz stepping 0b
checking TSC synchronization [CPU#0 -> CPU#3]: passed.
Brought up 4 CPUs
Total of 4 processors activated (19159.72 BogoMIPS).
CPU0 attaching sched-domain:
domain 0: span 0-1 level MC
groups: 0 1
domain 1: span 0-3 level CPU
groups: 0-1 2-3
CPU1 attaching sched-domain:
domain 0: span 0-1 level MC
groups: 1 0
domain 1: span 0-3 level CPU
groups: 0-1 2-3
CPU2 attaching sched-domain:
domain 0: span 2-3 level MC
groups: 2 3
domain 1: span 0-3 level CPU
groups: 2-3 0-1
CPU3 attaching sched-domain:
domain 0: span 2-3 level MC
groups: 3 2
domain 1: span 0-3 level CPU
groups: 2-3 0-1
Booting paravirtualized kernel on bare hardware
NET: Registered protocol family 16
ACPI: bus type pci registered
PCI: MCFG configuration 0: base e0000000 segment 0 buses 0 - 255
PCI: MCFG area at e0000000 reserved in E820
PCI: Using MMCONFIG at e0000000 - efffffff
PCI: Using configuration type 1 for base access
mtrr: your CPUs had inconsistent fixed MTRR settings
mtrr: probably your BIOS does not setup all CPUs.
mtrr: corrected configuration.
bio: create slab <bio-0> at 0
ACPI: EC: Look up EC in DSDT
ACPI: Interpreter enabled
ACPI: (supports S0 S3 S4 S5)
ACPI: Using IOAPIC for interrupt routing
ACPI: No dock devices found.
ACPI: PCI Root Bridge [PCI0] (0000:00)
pci 0000:00:01.0: PME# supported from D0 D3hot D3cold
pci 0000:00:01.0: PME# disabled
pci 0000:00:02.0: reg 10 32bit mmio: [0xfdf00000-0xfdf7ffff]
pci 0000:00:02.0: reg 14 io port: [0xff00-0xff07]
pci 0000:00:02.0: reg 18 32bit mmio: [0xd0000000-0xdfffffff]
pci 0000:00:02.0: reg 1c 32bit mmio: [0xfdc00000-0xfdcfffff]
pci 0000:00:19.0: reg 10 32bit mmio: [0xfdfc0000-0xfdfdffff]
pci 0000:00:19.0: reg 14 32bit mmio: [0xfdfff000-0xfdffffff]
pci 0000:00:19.0: reg 18 io port: [0xfe00-0xfe1f]
pci 0000:00:19.0: PME# supported from D0 D3hot D3cold
pci 0000:00:19.0: PME# disabled
pci 0000:00:1a.0: reg 20 io port: [0xfd00-0xfd1f]
pci 0000:00:1a.1: reg 20 io port: [0xfc00-0xfc1f]
pci 0000:00:1a.2: reg 20 io port: [0xfb00-0xfb1f]
pci 0000:00:1a.7: reg 10 32bit mmio: [0xfdffe000-0xfdffe3ff]
pci 0000:00:1a.7: PME# supported from D0 D3hot D3cold
pci 0000:00:1a.7: PME# disabled
pci 0000:00:1d.0: reg 20 io port: [0xfa00-0xfa1f]
pci 0000:00:1d.1: reg 20 io port: [0xf900-0xf91f]
pci 0000:00:1d.2: reg 20 io port: [0xf800-0xf81f]
pci 0000:00:1d.7: reg 10 32bit mmio: [0xfdffd000-0xfdffd3ff]
pci 0000:00:1d.7: PME# supported from D0 D3hot D3cold
pci 0000:00:1d.7: PME# disabled
pci 0000:00:1f.0: quirk: region 0400-047f claimed by ICH6 ACPI/GPIO/TCO
pci 0000:00:1f.0: quirk: region 0480-04bf claimed by ICH6 GPIO
pci 0000:00:1f.0: ICH7 LPC Generic IO decode 1 PIO at 0800 (mask 003f)
pci 0000:00:1f.0: ICH7 LPC Generic IO decode 2 PIO at 0290 (mask 003f)
pci 0000:00:1f.2: reg 10 io port: [0xf700-0xf707]
pci 0000:00:1f.2: reg 14 io port: [0xf600-0xf603]
pci 0000:00:1f.2: reg 18 io port: [0xf500-0xf507]
pci 0000:00:1f.2: reg 1c io port: [0xf400-0xf403]
pci 0000:00:1f.2: reg 20 io port: [0xf300-0xf31f]
pci 0000:00:1f.2: reg 24 32bit mmio: [0xfdffc000-0xfdffc7ff]
pci 0000:00:1f.2: PME# supported from D3hot
pci 0000:00:1f.2: PME# disabled
pci 0000:00:1f.3: reg 10 64bit mmio: [0xfdffb000-0xfdffb0ff]
pci 0000:00:1f.3: reg 20 io port: [0x500-0x51f]
pci 0000:00:01.0: bridge io port: [0xd000-0xdfff]
pci 0000:00:01.0: bridge 32bit mmio: [0xfda00000-0xfdafffff]
pci 0000:00:01.0: bridge 64bit mmio pref: [0xfdb00000-0xfdbfffff]
pci 0000:02:01.0: reg 10 io port: [0xcf00-0xcf3f]
pci 0000:02:01.0: supports D1 D2
pci 0000:02:01.1: reg 10 io port: [0xce00-0xce07]
pci 0000:02:01.1: supports D1 D2
pci 0000:02:01.2: reg 10 32bit mmio: [0xfdeff000-0xfdeff7ff]
pci 0000:02:01.2: reg 14 32bit mmio: [0xfdef8000-0xfdefbfff]
pci 0000:02:01.2: supports D1 D2
pci 0000:02:01.2: PME# supported from D0 D1 D2 D3hot
pci 0000:02:01.2: PME# disabled
pci 0000:00:1e.0: transparent bridge
pci 0000:00:1e.0: bridge io port: [0xc000-0xcfff]
pci 0000:00:1e.0: bridge 32bit mmio: [0xfde00000-0xfdefffff]
pci 0000:00:1e.0: bridge 64bit mmio pref: [0xfdd00000-0xfddfffff]
pci_bus 0000:00: on NUMA node 0
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.HUB0._PRT]
ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 *5 7 9 10 11 12 14 15)
ACPI: PCI Interrupt Link [LNKB] (IRQs 3 *4 5 7 9 10 11 12 14 15)
ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 9 10 *11 12 14 15)
ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 9 10 *11 12 14 15)
ACPI: PCI Interrupt Link [LNKE] (IRQs 3 4 5 7 9 *10 11 12 14 15)
ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 7 9 *10 11 12 14 15)
ACPI: PCI Interrupt Link [LNK0] (IRQs *3 4 5 7 9 10 11 12 14 15)
ACPI: PCI Interrupt Link [LNK1] (IRQs 3 4 5 7 *9 10 11 12 14 15)
PCI: Using ACPI for IRQ routing
NetLabel: Initializing
NetLabel: domain hash size = 128
NetLabel: protocols = UNLABELED CIPSOv4
NetLabel: unlabeled traffic allowed by default
pnp: PnP ACPI init
ACPI: bus type pnp registered
pnp: PnP ACPI: found 12 devices
ACPI: ACPI bus type pnp unregistered
system 00:01: ioport range 0x4d0-0x4d1 has been reserved
system 00:01: ioport range 0x800-0x87f has been reserved
system 00:01: ioport range 0x290-0x297 has been reserved
system 00:01: ioport range 0x880-0x88f has been reserved
system 00:08: ioport range 0x400-0x4bf could not be reserved
system 00:0a: iomem range 0xe0000000-0xefffffff has been reserved
system 00:0b: iomem range 0xf0000-0xfffff could not be reserved
system 00:0b: iomem range 0xcf600000-0xcf6fffff could not be reserved
system 00:0b: iomem range 0xfed00000-0xfed000ff has been reserved
system 00:0b: iomem range 0xcf590000-0xcf5fffff could not be reserved
system 00:0b: iomem range 0x0-0x9ffff could not be reserved
system 00:0b: iomem range 0x100000-0xcf58ffff could not be reserved
system 00:0b: iomem range 0xfec00000-0xfec00fff could not be reserved
system 00:0b: iomem range 0xfed14000-0xfed1dfff has been reserved
system 00:0b: iomem range 0xfed20000-0xfed9ffff has been reserved
system 00:0b: iomem range 0xfee00000-0xfee00fff has been reserved
system 00:0b: iomem range 0xffb00000-0xffb7ffff has been reserved
system 00:0b: iomem range 0xfff00000-0xffffffff has been reserved
system 00:0b: iomem range 0xe0000-0xeffff has been reserved
pci 0000:00:01.0: PCI bridge, secondary bus 0000:01
pci 0000:00:01.0: IO window: 0xd000-0xdfff
pci 0000:00:01.0: MEM window: 0xfda00000-0xfdafffff
pci 0000:00:01.0: PREFETCH window: 0x000000fdb00000-0x000000fdbfffff
pci 0000:00:1e.0: PCI bridge, secondary bus 0000:02
pci 0000:00:1e.0: IO window: 0xc000-0xcfff
pci 0000:00:1e.0: MEM window: 0xfde00000-0xfdefffff
pci 0000:00:1e.0: PREFETCH window: 0x000000fdd00000-0x000000fddfffff
pci 0000:00:01.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
pci 0000:00:01.0: setting latency timer to 64
pci 0000:00:1e.0: setting latency timer to 64
pci_bus 0000:00: resource 0 io: [0x00-0xffff]
pci_bus 0000:00: resource 1 mem: [0x000000-0xffffffffffffffff]
pci_bus 0000:01: resource 0 io: [0xd000-0xdfff]
pci_bus 0000:01: resource 1 mem: [0xfda00000-0xfdafffff]
pci_bus 0000:01: resource 2 pref mem [0xfdb00000-0xfdbfffff]
pci_bus 0000:02: resource 0 io: [0xc000-0xcfff]
pci_bus 0000:02: resource 1 mem: [0xfde00000-0xfdefffff]
pci_bus 0000:02: resource 2 pref mem [0xfdd00000-0xfddfffff]
pci_bus 0000:02: resource 3 io: [0x00-0xffff]
pci_bus 0000:02: resource 4 mem: [0x000000-0xffffffffffffffff]
NET: Registered protocol family 2
IP route cache hash table entries: 262144 (order: 9, 2097152 bytes)
TCP established hash table entries: 262144 (order: 10, 4194304 bytes)
TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
TCP: Hash tables configured (established 262144 bind 65536)
TCP reno registered
NET: Registered protocol family 1
Unpacking initramfs...
Freeing initrd memory: 1018k freed
Scanning for low memory corruption every 60 seconds
audit: initializing netlink socket (disabled)
type=2000 audit(1256998169.436:1): initialized
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
msgmni has been set to 11926
alg: No test for stdrng (krng)
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
pci 0000:00:02.0: Boot video device
pcieport-driver 0000:00:01.0: irq 24 for MSI/MSI-X
pcieport-driver 0000:00:01.0: setting latency timer to 64
Linux agpgart interface v0.103
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
input: Macintosh mouse button emulation as /devices/virtual/input/input0
PNP: No PS/2 controller found. Probing ports directly.
serio: i8042 KBD port at 0x60,0x64 irq 1
serio: i8042 AUX port at 0x60,0x64 irq 12
mice: PS/2 mouse device common for all mice
cpuidle: using governor ladder
cpuidle: using governor menu
TCP cubic registered
NET: Registered protocol family 17
registered taskstats version 1
Initalizing network drop monitor service
Freeing unused kernel memory: 484k freed
agpgart-intel 0000:00:00.0: Intel G33 Chipset
agpgart-intel 0000:00:00.0: detected 7164K stolen memory
agpgart-intel 0000:00:00.0: AGP aperture is 256M @ 0xd0000000
[drm] Initialized drm 1.1.0 20060810
i915 0000:00:02.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
i915 0000:00:02.0: setting latency timer to 64
mtrr: no more MTRRs available
[drm] MTRR allocation failed. Graphics performance may suffer.
i915 0000:00:02.0: irq 25 for MSI/MSI-X
Switched to high resolution mode on CPU 1
Switched to high resolution mode on CPU 3
Switched to high resolution mode on CPU 2
Switched to high resolution mode on CPU 0
[drm] DAC-6: set mode 1920x1080 11
Console: switching to colour frame buffer device 240x67
[drm] fb0: inteldrmfb frame buffer device
[drm] Initialized i915 1.6.0 20080730 for 0000:00:02.0 on minor 0
FDC 0 is a post-1991 82077
SCSI subsystem initialized
libata version 3.00 loaded.
ahci 0000:00:1f.2: version 3.0
ahci 0000:00:1f.2: PCI INT A -> GSI 19 (level, low) -> IRQ 19
ahci 0000:00:1f.2: irq 26 for MSI/MSI-X
ahci 0000:00:1f.2: AHCI 0001.0200 32 slots 6 ports 3 Gbps 0x3f impl RAID mode
ahci 0000:00:1f.2: flags: 64bit ncq sntf led clo pmp pio slum part ems
ahci 0000:00:1f.2: setting latency timer to 64
scsi0 : ahci
scsi1 : ahci
scsi2 : ahci
scsi3 : ahci
scsi4 : ahci
scsi5 : ahci
ata1: SATA max UDMA/133 abar m2048@0xfdffc000 port 0xfdffc100 irq 26
ata2: SATA max UDMA/133 abar m2048@0xfdffc000 port 0xfdffc180 irq 26
ata3: SATA max UDMA/133 abar m2048@0xfdffc000 port 0xfdffc200 irq 26
ata4: SATA max UDMA/133 abar m2048@0xfdffc000 port 0xfdffc280 irq 26
ata5: SATA max UDMA/133 abar m2048@0xfdffc000 port 0xfdffc300 irq 26
ata6: SATA max UDMA/133 abar m2048@0xfdffc000 port 0xfdffc380 irq 26
ata3: SATA link down (SStatus 0 SControl 300)
ata2: SATA link down (SStatus 0 SControl 300)
ata4: SATA link down (SStatus 0 SControl 300)
ata6: SATA link down (SStatus 0 SControl 300)
ata5: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata5.00: ATAPI: PLDS DVD+/-RW DH-16A6S, YD11, max UDMA/100
ata5.00: configured for UDMA/100
ata1.00: ATA-7: SAMSUNG HD322HJ, 1AC01113, max UDMA7
ata1.00: 625142448 sectors, multi 0: LBA48 NCQ (depth 31/32)
ata1.00: configured for UDMA/133
scsi 0:0:0:0: Direct-Access ATA SAMSUNG HD322HJ 1AC0 PQ: 0 ANSI: 5
scsi 4:0:0:0: CD-ROM PLDS DVD+-RW DH-16A6S YD11 PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 625142448 512-byte logical blocks: (320 GB/298 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
sda: sda1 sda2 sda3 sda4 < sda5 sda6 >
sd 0:0:0:0: [sda] Attached SCSI disk
sr0: scsi3-mmc drive: 48x/12x writer dvd-ram cd/rw xa/form2 cdda tray
Uniform CD-ROM driver Revision: 3.20
sr 4:0:0:0: Attached scsi CD-ROM sr0
EXT4-fs (sda2): barriers enabled
kjournald2 starting: pid 557, dev sda2:8, commit interval 5 seconds
EXT4-fs (sda2): delayed allocation enabled
EXT4-fs: file extents enabled
EXT4-fs: mballoc enabled
EXT4-fs (sda2): mounted filesystem with ordered data mode
rtc_cmos 00:04: RTC can wake from S4
rtc_cmos 00:04: rtc core: registered rtc_cmos as rtc0
rtc0: alarms up to one month, 242 bytes nvram, hpet irqs
udev: starting version 146
i801_smbus 0000:00:1f.3: PCI INT B -> GSI 18 (level, low) -> IRQ 18
input: PC Speaker as /devices/platform/pcspkr/input/input1
input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input2
ACPI: Power Button [PWRF]
input: Power Button as /devices/LNXSYSTM:00/device:00/PNP0C0C:00/input/input3
ACPI: Power Button [PWRB]
dcdbas dcdbas: Dell Systems Management Base Driver (version 5.6.0-3.2)
e1000e: Intel(R) PRO/1000 Network Driver - 1.0.2-k2
e1000e: Copyright (c) 1999-2008 Intel Corporation.
e1000e 0000:00:19.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20
e1000e 0000:00:19.0: pci_enable_pcie_error_reporting failed 0xfffffffb
e1000e 0000:00:19.0: setting latency timer to 64
e1000e 0000:00:19.0: irq 27 for MSI/MSI-X
iTCO_vendor_support: vendor-support=0
sd 0:0:0:0: Attached scsi generic sg0 type 0
sr 4:0:0:0: Attached scsi generic sg1 type 5
ACPI: SSDT 00000000cf5e7680 0022A (v01 PmRef Cpu0Ist 00003000 INTL 20041203)
processor LNXCPU:00: registered as cooling_device0
ACPI: SSDT 00000000cf5e7b40 00152 (v01 PmRef Cpu1Ist 00003000 INTL 20041203)
processor LNXCPU:01: registered as cooling_device1
ACPI: SSDT 00000000cf5e7ca0 00152 (v01 PmRef Cpu2Ist 00003000 INTL 20041203)
processor LNXCPU:02: registered as cooling_device2
ACPI: SSDT 00000000cf5e7e00 00152 (v01 PmRef Cpu3Ist 00003000 INTL 20041203)
processor LNXCPU:03: registered as cooling_device3
iTCO_wdt: Intel TCO WatchDog Timer Driver v1.05
iTCO_wdt: Found a ICH9R TCO device (Version=2, TCOBASE=0x0460)
iTCO_wdt: initialized. heartbeat=30 sec (nowayout=0)
gameport: EMU10K1 is pci0000:02:01.1/gameport0, io 0xce00, speed 1007kHz
fan PNP0C0B:00: registered as cooling_device4
ACPI: Fan [FAN] (on)
thermal LNXTHERM:01: registered as thermal_zone0
ACPI: Thermal Zone [THRM] (40 C)
0000:00:19.0: eth0: (PCI Express:2.5GB/s:Width x1) 00:21:9b:06:4c:c9
0000:00:19.0: eth0: Intel(R) PRO/10/100 Network Connection
0000:00:19.0: eth0: MAC: 7, PHY: 7, PBA No: ffffff-0ff
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
ohci1394 0000:02:01.2: PCI INT B -> GSI 17 (level, low) -> IRQ 17
ohci1394 0000:02:01.2: setting latency timer to 64
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci_hcd 0000:00:1a.7: PCI INT C -> GSI 18 (level, low) -> IRQ 18
ehci_hcd 0000:00:1a.7: setting latency timer to 64
ehci_hcd 0000:00:1a.7: EHCI Host Controller
ehci_hcd 0000:00:1a.7: new USB bus registered, assigned bus number 1
ehci_hcd 0000:00:1a.7: debug port 1
ehci_hcd 0000:00:1a.7: cache line size of 32 is not supported
ehci_hcd 0000:00:1a.7: irq 18, io mem 0xfdffe000
ehci_hcd 0000:00:1a.7: USB 2.0 started, EHCI 1.00
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 6 ports detected
ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
ehci_hcd 0000:00:1d.7: setting latency timer to 64
ehci_hcd 0000:00:1d.7: EHCI Host Controller
ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 2
ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[17] MMIO=[fdeff000-fdeff7ff] Max Packet=[2048] IR/IT contexts=[4/8]
ehci_hcd 0000:00:1d.7: debug port 1
ehci_hcd 0000:00:1d.7: cache line size of 32 is not supported
ehci_hcd 0000:00:1d.7: irq 23, io mem 0xfdffd000
ehci_hcd 0000:00:1d.7: USB 2.0 started, EHCI 1.00
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 6 ports detected
uhci_hcd: USB Universal Host Controller Interface driver
uhci_hcd 0000:00:1a.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
uhci_hcd 0000:00:1a.0: setting latency timer to 64
uhci_hcd 0000:00:1a.0: UHCI Host Controller
uhci_hcd 0000:00:1a.0: new USB bus registered, assigned bus number 3
uhci_hcd 0000:00:1a.0: irq 16, io base 0x0000fd00
usb usb3: configuration #1 chosen from 1 choice
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 2 ports detected
uhci_hcd 0000:00:1a.1: PCI INT B -> GSI 21 (level, low) -> IRQ 21
uhci_hcd 0000:00:1a.1: setting latency timer to 64
uhci_hcd 0000:00:1a.1: UHCI Host Controller
uhci_hcd 0000:00:1a.1: new USB bus registered, assigned bus number 4
uhci_hcd 0000:00:1a.1: irq 21, io base 0x0000fc00
usb usb4: configuration #1 chosen from 1 choice
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 2 ports detected
uhci_hcd 0000:00:1a.2: PCI INT D -> GSI 19 (level, low) -> IRQ 19
uhci_hcd 0000:00:1a.2: setting latency timer to 64
uhci_hcd 0000:00:1a.2: UHCI Host Controller
uhci_hcd 0000:00:1a.2: new USB bus registered, assigned bus number 5
uhci_hcd 0000:00:1a.2: irq 19, io base 0x0000fb00
usb usb5: configuration #1 chosen from 1 choice
hub 5-0:1.0: USB hub found
hub 5-0:1.0: 2 ports detected
uhci_hcd 0000:00:1d.0: PCI INT A -> GSI 23 (level, low) -> IRQ 23
uhci_hcd 0000:00:1d.0: setting latency timer to 64
uhci_hcd 0000:00:1d.0: UHCI Host Controller
uhci_hcd 0000:00:1d.0: new USB bus registered, assigned bus number 6
uhci_hcd 0000:00:1d.0: irq 23, io base 0x0000fa00
usb usb6: configuration #1 chosen from 1 choice
hub 6-0:1.0: USB hub found
hub 6-0:1.0: 2 ports detected
uhci_hcd 0000:00:1d.1: PCI INT B -> GSI 19 (level, low) -> IRQ 19
uhci_hcd 0000:00:1d.1: setting latency timer to 64
uhci_hcd 0000:00:1d.1: UHCI Host Controller
uhci_hcd 0000:00:1d.1: new USB bus registered, assigned bus number 7
uhci_hcd 0000:00:1d.1: irq 19, io base 0x0000f900
usb usb7: configuration #1 chosen from 1 choice
hub 7-0:1.0: USB hub found
hub 7-0:1.0: 2 ports detected
uhci_hcd 0000:00:1d.2: PCI INT C -> GSI 18 (level, low) -> IRQ 18
uhci_hcd 0000:00:1d.2: setting latency timer to 64
uhci_hcd 0000:00:1d.2: UHCI Host Controller
uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 8
uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000f800
usb usb8: configuration #1 chosen from 1 choice
hub 8-0:1.0: USB hub found
hub 8-0:1.0: 2 ports detected
EMU10K1_Audigy 0000:02:01.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
EMU10K1_Audigy 0000:02:01.0: setting latency timer to 64
Installing spdif_bug patch: SB Audigy 2 ZS [SB0350]
usb 5-1: new full speed USB device using uhci_hcd and address 2
usb 5-1: configuration #1 chosen from 1 choice
hub 5-1:1.0: USB hub found
hub 5-1:1.0: 4 ports detected
usb 5-1.1: new low speed USB device using uhci_hcd and address 3
usb 5-1.1: configuration #1 chosen from 1 choice
ieee1394: Host added: ID:BUS[0-00:1023] GUID[00023c01510c1ac4]
usb 5-1.3: new low speed USB device using uhci_hcd and address 4
usbcore: registered new interface driver hiddev
input: Logitech Logitech Gaming Keyboard as /devices/pci0000:00/0000:00:1a.2/usb5/5-1/5-1.1/5-1.1:1.0/input/input4
generic-usb 0003:046D:C221.0001: input,hidraw0: USB HID v1.10 Keyboard [Logitech Logitech Gaming Keyboard] on usb-0000:00:1a.2-1.1/input0
input: Logitech Logitech Gaming Keyboard as /devices/pci0000:00/0000:00:1a.2/usb5/5-1/5-1.1/5-1.1:1.1/input/input5
generic-usb 0003:046D:C221.0002: input,hiddev0,hidraw1: USB HID v1.10 Device [Logitech Logitech Gaming Keyboard] on usb-0000:00:1a.2-1.1/input1
usbcore: registered new interface driver usbhid
usbhid: v2.6:USB HID core driver
usb 5-1.3: configuration #1 chosen from 1 choice
input: Logitech USB-PS/2 Optical Mouse as /devices/pci0000:00/0000:00:1a.2/usb5/5-1/5-1.3/5-1.3:1.0/input/input6
generic-usb 0003:046D:C01E.0003: input,hidraw2: USB HID v1.10 Mouse [Logitech USB-PS/2 Optical Mouse] on usb-0000:00:1a.2-1.3/input0
usb 5-1.4: new full speed USB device using uhci_hcd and address 5
usb 5-1.4: configuration #1 chosen from 1 choice
input: G15 Keyboard G15 Keyboard as /devices/pci0000:00/0000:00:1a.2/usb5/5-1/5-1.4/5-1.4:1.0/input/input7
generic-usb 0003:046D:C222.0004: input,hiddev1,hidraw3: USB HID v1.11 Keypad [G15 Keyboard G15 Keyboard] on usb-0000:00:1a.2-1.4/input0
EXT4-fs (sda2): internal journal on sda2:8
EXT4-fs (sda5): barriers enabled
kjournald2 starting: pid 1140, dev sda5:8, commit interval 5 seconds
EXT4-fs (sda5): internal journal on sda5:8
EXT4-fs (sda5): Ignoring delalloc option - requested data journaling mode
EXT4-fs: file extents enabled
EXT4-fs: mballoc enabled
EXT4-fs (sda5): mounted filesystem with journalled data mode
EXT4-fs (sda6): barriers enabled
kjournald2 starting: pid 1143, dev sda6:8, commit interval 5 seconds
EXT4-fs (sda6): internal journal on sda6:8
EXT4-fs (sda6): delayed allocation enabled
EXT4-fs: file extents enabled
EXT4-fs: mballoc enabled
EXT4-fs (sda6): mounted filesystem with ordered data mode
loop: module loaded
Adding 3212992k swap on /dev/sda3. Priority:-1 extents:1 across:3212992k
e1000e 0000:00:19.0: irq 27 for MSI/MSI-X
e1000e 0000:00:19.0: irq 27 for MSI/MSI-X
ip_tables: (C) 2000-2006 Netfilter Core Team
nf_conntrack version 0.5.0 (16384 buckets, 65536 max)
CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Please use
nf_conntrack.acct=1 kernel parameter, acct=1 nf_conntrack module option or
sysctl net.netfilter.nf_conntrack_acct=1 to enable it.
e1000e: eth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: RX/TX
0000:00:19.0: eth0: 10/100 speed: disabling TSO
NET: Registered protocol family 10
lo: Disabled Privacy Extensions
eth0: no IPv6 routers present
^ permalink raw reply
* kerneloops.org report for the week of October 31 2009
From: Arjan van de Ven @ 2009-10-31 23:03 UTC (permalink / raw)
To: linux-kernel, torvalds
Cc: linux-acpi, tytso, netdev, Eric Paris, akpm, Matt Domsch
This week, a total of 18023 oopses and warnings have been reported,
compared to 5816 reports in the previous week. This number and this
report only includes kernel 2.6.31 and later.
This week, the Ubuntu 9.10 distribution got released, which includes
kerneloops.org integration in the quality feedback system. I'd like
to thank the Ubuntu team for their effort in helping to get the quality
feedback about the kernel integrated into kerneloops.org.
One thing to note is that the Ubuntu 9.10 release ships with the kernel
debug option CONFIG_PM_TEST_SUSPEND enabled, causing many warnings to
be submitted. This huge volume triggered me to split these reports, as well
as the check_bios_for_corruption() reports into a per machine entry.
The top 5 machines for which the suspend test fails:
319 | suspend_test_finish(Latitude D830)
231 | suspend_test_finish(XPS M1530)
225 | suspend_test_finish(MacBook2,1)
171 | suspend_test_finish(Compaq Presario CQ60 Notebook PC)
157 | suspend_test_finish(Studio XPS 1340)
and there is also the very elegant
267 | suspend_test_finish(To Be Filled By O.E.M)
The top 5 machines where the BIOS corrupts memory:
80 | check_for_bios_corruption(HP Compaq nx6110)
69 | check_for_bios_corruption(HP Compaq nc6120)
62 | check_for_bios_corruption(HP Pavilion dv6700 Notebook PC)
49 | check_for_bios_corruption(HP Pavilion dv2700 Notebook PC)
32 | check_for_bios_corruption(Compaq Presario F700 Notebook PC)
The report this week looks different from previous reports; the version
cut-off has moved to 2.6.31 so that a lot of older bugs now dropped out of the report.
New this week are some inotify bugs, that have been fixed in Linus' git tree after -rc5.
There's also an ext2 warning for when the user unplugs a USB stick, as well as the
usual binary and external kernel modules.
If you have (better) descriptions for some of these, let me know and I can add them to the
database.
Rank 1: suspend_test_finish(System Product Name) (warning)
Reported 930 times (1510 total reports)
This warning was last seen in version 2.6.31, and first seen in 2.6.27.15.
More info: http://www.kerneloops.org/searchweek.php?search=suspend_test_finish(System Product Name)
Rank 2: acpi_idle_enter_bm (oops)
Reported 783 times (1924 total reports)
This oops was last seen in version 2.6.32, and first seen in 2.6.23.8.
More info: http://www.kerneloops.org/searchweek.php?search=acpi_idle_enter_bm
Rank 3: dev_watchdog(sis900) (warning)
Reported 514 times (19593 total reports)
This warning was last seen in version 2.6.31, and first seen in 2.6.26-rc4-git2.
More info: http://www.kerneloops.org/searchweek.php?search=dev_watchdog(sis900)
Rank 4: suspend_test_finish(Unknown) (oops)
Reported 431 times (5580 total reports)
This oops was last seen in version 2.6.31, and first seen in 2.6.27.15.
More info: http://www.kerneloops.org/searchweek.php?search=suspend_test_finish(Unknown)
Rank 5: tcp_recvmsg (oops)
Reported 372 times (7133 total reports)
This oops was last seen in version 2.6.31.3, and first seen in 2.6.25.
More info: http://www.kerneloops.org/searchweek.php?search=tcp_recvmsg
Rank 6: inotify_remove_from_idr (oops)
Reported 369 times (942 total reports)
Fixed in commit 9f0d793b52eb
This oops was last seen in version 2.6.32, and first seen in 2.6.31-rc8.
More info: http://www.kerneloops.org/searchweek.php?search=inotify_remove_from_idr
Rank 7: ext2_sync_fs (warning)
Reported 265 times (508 total reports)
Caused by the user removing a USB stick while mounted
This warning was last seen in version 2.6.32-rc5, and first seen in 2.6.30.
More info: http://www.kerneloops.org/searchweek.php?search=ext2_sync_fs
Rank 8: ieee80211_scan_completed (oops)
Reported 264 times (1494 total reports)
This oops was last seen in version 2.6.32-rc2, and first seen in 2.6.27.29.
More info: http://www.kerneloops.org/searchweek.php?search=ieee80211_scan_completed
Rank 9: wl_pci_probe (warning)
Reported 216 times (251 total reports)
[Ubuntu] Bug in a binary driver shipped by Ubuntu
warning only shows up in tainted kernels
This warning was last seen in version 2.6.31, and first seen in 2.6.30.8.
More info: http://www.kerneloops.org/searchweek.php?search=wl_pci_probe
Rank 10: apparmor_bprm_set_creds (oops)
Reported 201 times (324 total reports)
NULL pointer dereference in AppArmor
This oops was last seen in version 2.6.31, and first seen in 2.6.31.
More info: http://www.kerneloops.org/searchweek.php?search=apparmor_bprm_set_creds
Rank 11: KCL_MEM_AllocContiguousPageFrames (warning)
Reported 188 times (256 total reports)
[tainted] The AMD binary graphics driver uses GFP_NOWARN on a high order allocation
warning only shows up in tainted kernels
This warning was last seen in version 2.6.31, and first seen in 2.6.31.
More info: http://www.kerneloops.org/searchweek.php?search=KCL_MEM_AllocContiguousPageFrames
Rank 12: idr_callback (warning)
Reported 174 times (638 total reports)
Fixed in commit 9f0d793b52eb before 2.6.32-rc6
This warning was last seen in version 2.6.32, and first seen in 2.6.31-rc4-git2.
More info: http://www.kerneloops.org/searchweek.php?search=idr_callback
--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
^ permalink raw reply
* Re: kerneloops.org report for the week of October 31 2009
From: Rafael J. Wysocki @ 2009-10-31 23:20 UTC (permalink / raw)
To: Arjan van de Ven
Cc: linux-kernel, torvalds, linux-acpi, tytso, netdev, Eric Paris,
akpm, Matt Domsch
In-Reply-To: <20091031160351.26fcc6c5@infradead.org>
On Sunday 01 November 2009, Arjan van de Ven wrote:
>
> This week, a total of 18023 oopses and warnings have been reported,
> compared to 5816 reports in the previous week. This number and this
> report only includes kernel 2.6.31 and later.
>
> This week, the Ubuntu 9.10 distribution got released, which includes
> kerneloops.org integration in the quality feedback system. I'd like
> to thank the Ubuntu team for their effort in helping to get the quality
> feedback about the kernel integrated into kerneloops.org.
>
>
> One thing to note is that the Ubuntu 9.10 release ships with the kernel
> debug option CONFIG_PM_TEST_SUSPEND enabled, causing many warnings to
> be submitted. This huge volume triggered me to split these reports, as well
> as the check_bios_for_corruption() reports into a per machine entry.
>
> The top 5 machines for which the suspend test fails:
> 319 | suspend_test_finish(Latitude D830)
> 231 | suspend_test_finish(XPS M1530)
> 225 | suspend_test_finish(MacBook2,1)
> 171 | suspend_test_finish(Compaq Presario CQ60 Notebook PC)
> 157 | suspend_test_finish(Studio XPS 1340)
>
> and there is also the very elegant
> 267 | suspend_test_finish(To Be Filled By O.E.M)
>
>
> The top 5 machines where the BIOS corrupts memory:
> 80 | check_for_bios_corruption(HP Compaq nx6110)
> 69 | check_for_bios_corruption(HP Compaq nc6120)
> 62 | check_for_bios_corruption(HP Pavilion dv6700 Notebook PC)
> 49 | check_for_bios_corruption(HP Pavilion dv2700 Notebook PC)
> 32 | check_for_bios_corruption(Compaq Presario F700 Notebook PC)
>
>
> The report this week looks different from previous reports; the version
> cut-off has moved to 2.6.31 so that a lot of older bugs now dropped out of the report.
>
> New this week are some inotify bugs, that have been fixed in Linus' git tree after -rc5.
> There's also an ext2 warning for when the user unplugs a USB stick, as well as the
> usual binary and external kernel modules.
>
> If you have (better) descriptions for some of these, let me know and I can add them to the
> database.
>
>
>
>
> Rank 1: suspend_test_finish(System Product Name) (warning)
> Reported 930 times (1510 total reports)
> This warning was last seen in version 2.6.31, and first seen in 2.6.27.15.
> More info: http://www.kerneloops.org/searchweek.php?search=suspend_test_finish(System Product Name)
This should be fixed by commit 04bf7539c08d64184736cdc5e4ad617eda77eb0f
(PM: Make warning in suspend_test_finish() less likely to happen), at least on some
machines that report it.
Thanks,
Rafael
^ permalink raw reply
* Subject: [PATCH 6/6] bna: Brocade 10Gb Ethernet device driver
From: Rasesh Mody @ 2009-11-01 5:03 UTC (permalink / raw)
To: netdev; +Cc: adapter_linux_open_src_team
From: Rasesh Mody <rmody@brocade.com>
This is patch 6/6 which contains linux driver source for
Brocade's BR1010/BR1020 10Gb CEE capable ethernet adapter.
Re-based source against net-next-2.6 and re-submitting the
patch with few fixes.
We wish this patch to be considered for inclusion in net-next-2.6
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
Kconfig | 15 +++++++++++++++
Makefile | 1 +
bna/Makefile | 17 +++++++++++++++++
3 files changed, 33 insertions(+)
diff -ruP net-next-2.6-orig/drivers/net/Kconfig net-next-2.6-mod/drivers/net/Kconfig
--- net-next-2.6-orig/drivers/net/Kconfig 2009-10-31 00:44:29.000000000 -0700
+++ net-next-2.6-mod/drivers/net/Kconfig 2009-10-31 21:40:54.515921000 -0700
@@ -2757,6 +2757,21 @@
To compile this driver as a module, choose M here: the module
will be called qlge.
+config BNA
+ tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
+ depends on PCI
+ ---help---
+ This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
+ cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called bna.
+
+ For general information and support, go to the Brocade support
+ website at:
+
+ <http://support.brocade.com>
+
source "drivers/net/sfc/Kconfig"
source "drivers/net/benet/Kconfig"
diff -ruP net-next-2.6-orig/drivers/net/Makefile net-next-2.6-mod/drivers/net/Makefile
--- net-next-2.6-orig/drivers/net/Makefile 2009-10-31 00:44:29.000000000 -0700
+++ net-next-2.6-mod/drivers/net/Makefile 2009-10-31 21:40:54.533912000 -0700
@@ -31,6 +31,7 @@
obj-$(CONFIG_JME) += jme.o
obj-$(CONFIG_BE2NET) += benet/
obj-$(CONFIG_VMXNET3) += vmxnet3/
+obj-$(CONFIG_BNA) += bna/
gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
diff -ruP net-next-2.6-orig/drivers/net/bna/Makefile net-next-2.6-mod/drivers/net/bna/Makefile
--- net-next-2.6-orig/drivers/net/bna/Makefile 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/Makefile 2009-10-31 21:40:54.561914000 -0700
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2005-2008 Brocade Communications Systems, Inc.
+# All rights reserved.
+#
+
+obj-$(CONFIG_BNA) += bna.o
+
+bna-objs := bnad.o bnad_ethtool.o bna_fn.o bna_if.o bna_queue.o \
+ bfad_fwimg.o bfa_csdebug.o bfa_sm.o \
+ bfa_ioc.o bfa_timer.o \
+ bfa_cee.o
+
+EXTRA_CFLAGS += -Idrivers/net/bna \
+ -Idrivers/net/bna/include \
+ -Idrivers/net/bna/include/cee \
+ -Idrivers/net/bna/include/cna/pstats \
+ -Idrivers/net/bna/include/cs
^ permalink raw reply
* Subject: [PATCH 3/6] bna: Brocade 10Gb Ethernet device driver
From: Rasesh Mody @ 2009-11-01 5:03 UTC (permalink / raw)
To: netdev; +Cc: adapter_linux_open_src_team
From: Rasesh Mody <rmody@brocade.com>
This is patch 3/6 which contains linux driver source for
Brocade's BR1010/BR1020 10Gb CEE capable ethernet adapter.
Re-based source against net-next-2.6 and re-submitting the
patch with few fixes.
We wish this patch to be considered for inclusion in net-next-2.6
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
bfa_cee.c | 463 +++++++++++
bfa_csdebug.c | 62 +
bfa_ioc.c | 2273 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bfa_sm.c | 45 +
bna_if.c | 588 +++++++++++++++
bna_iocll.h | 66 +
bna_os.h | 182 ++++
bna_priv.h | 490 ++++++++++++
bnad_compat.h | 96 ++
bnad_defs.h | 36
cna.h | 32
11 files changed, 4333 insertions(+)
diff -ruP net-next-2.6-orig/drivers/net/bna/bfa_cee.c net-next-2.6-mod/drivers/net/bna/bfa_cee.c
--- net-next-2.6-orig/drivers/net/bna/bfa_cee.c 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bfa_cee.c 2009-10-31 21:34:47.836534000 -0700
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See LICENSE.bna for copyright and licensing details.
+ */
+
+#include <defs/bfa_defs_cee.h>
+#include <cs/bfa_debug.h>
+#include <cee/bfa_cee.h>
+#include <bfi/bfi_cee.h>
+#include <bfi/bfi.h>
+#include <bfa_ioc.h>
+
+
+#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
+#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
+
+static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg);
+static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
+ *dcbcx_stats);
+static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
+ *lldp_stats);
+static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats);
+static void bfa_cee_format_cee_cfg(void *buffer);
+static void bfa_cee_format_cee_stats(void *buffer);
+
+static void
+bfa_cee_format_cee_stats(void *buffer)
+{
+ struct bfa_cee_stats_s *cee_stats = buffer;
+ bfa_cee_format_dcbcx_stats(&cee_stats->dcbx_stats);
+ bfa_cee_format_lldp_stats(&cee_stats->lldp_stats);
+ bfa_cee_format_cfg_stats(&cee_stats->cfg_stats);
+}
+
+static void
+bfa_cee_format_cee_cfg(void *buffer)
+{
+ struct bfa_cee_attr_s *cee_cfg = buffer;
+ bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
+}
+
+static void
+bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s *dcbcx_stats)
+{
+ dcbcx_stats->subtlvs_unrecognized =
+ bfa_os_ntohl(dcbcx_stats->subtlvs_unrecognized);
+ dcbcx_stats->negotiation_failed =
+ bfa_os_ntohl(dcbcx_stats->negotiation_failed);
+ dcbcx_stats->remote_cfg_changed =
+ bfa_os_ntohl(dcbcx_stats->remote_cfg_changed);
+ dcbcx_stats->tlvs_received = bfa_os_ntohl(dcbcx_stats->tlvs_received);
+ dcbcx_stats->tlvs_invalid = bfa_os_ntohl(dcbcx_stats->tlvs_invalid);
+ dcbcx_stats->seqno = bfa_os_ntohl(dcbcx_stats->seqno);
+ dcbcx_stats->ackno = bfa_os_ntohl(dcbcx_stats->ackno);
+ dcbcx_stats->recvd_seqno = bfa_os_ntohl(dcbcx_stats->recvd_seqno);
+ dcbcx_stats->recvd_ackno = bfa_os_ntohl(dcbcx_stats->recvd_ackno);
+}
+
+static void
+bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s *lldp_stats)
+{
+ lldp_stats->frames_transmitted =
+ bfa_os_ntohl(lldp_stats->frames_transmitted);
+ lldp_stats->frames_aged_out = bfa_os_ntohl(lldp_stats->frames_aged_out);
+ lldp_stats->frames_discarded =
+ bfa_os_ntohl(lldp_stats->frames_discarded);
+ lldp_stats->frames_in_error = bfa_os_ntohl(lldp_stats->frames_in_error);
+ lldp_stats->frames_rcvd = bfa_os_ntohl(lldp_stats->frames_rcvd);
+ lldp_stats->tlvs_discarded = bfa_os_ntohl(lldp_stats->tlvs_discarded);
+ lldp_stats->tlvs_unrecognized =
+ bfa_os_ntohl(lldp_stats->tlvs_unrecognized);
+}
+
+static void
+bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats)
+{
+ cfg_stats->cee_status_down = bfa_os_ntohl(cfg_stats->cee_status_down);
+ cfg_stats->cee_status_up = bfa_os_ntohl(cfg_stats->cee_status_up);
+ cfg_stats->cee_hw_cfg_changed =
+ bfa_os_ntohl(cfg_stats->cee_hw_cfg_changed);
+ cfg_stats->recvd_invalid_cfg =
+ bfa_os_ntohl(cfg_stats->recvd_invalid_cfg);
+}
+
+static void
+bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg)
+{
+ lldp_cfg->time_to_interval = bfa_os_ntohs(lldp_cfg->time_to_interval);
+ lldp_cfg->enabled_system_cap =
+ bfa_os_ntohs(lldp_cfg->enabled_system_cap);
+}
+
+/**
+ * bfa_cee_attr_meminfo()
+ *
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+static u32
+bfa_cee_attr_meminfo(void)
+{
+ return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
+}
+
+/**
+ * bfa_cee_stats_meminfo()
+ *
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+static u32
+bfa_cee_stats_meminfo(void)
+{
+ return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
+{
+ cee->get_attr_status = status;
+ if (status == BFA_STATUS_OK) {
+ /*
+ * The requested data has been copied to the DMA area, *process
+ * it.
+ */
+ memcpy(cee->attr, cee->attr_dma.kva,
+ sizeof(struct bfa_cee_attr_s));
+ bfa_cee_format_cee_cfg(cee->attr);
+ }
+ cee->get_attr_pending = BFA_FALSE;
+ if (cee->cbfn.get_attr_cbfn)
+ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
+{
+ cee->get_stats_status = status;
+ if (status == BFA_STATUS_OK) {
+ /*
+ * The requested data has been copied to the DMA area, process
+ * it.
+ */
+ memcpy(cee->stats, cee->stats_dma.kva,
+ sizeof(struct bfa_cee_stats_s));
+ bfa_cee_format_cee_stats(cee->stats);
+ }
+ cee->get_stats_pending = BFA_FALSE;
+ if (cee->cbfn.get_stats_cbfn)
+ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
+{
+ cee->reset_stats_status = status;
+ cee->reset_stats_pending = BFA_FALSE;
+ if (cee->cbfn.reset_stats_cbfn)
+ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
+}
+
+/**
+ * bfa_cee_meminfo()
+ *
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+u32
+bfa_cee_meminfo(void)
+{
+ return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
+}
+
+/**
+ * bfa_cee_mem_claim()
+ *
+ *
+ * @param[in] cee CEE module pointer
+ * dma_kva Kernel Virtual Address of CEE DMA Memory
+ * dma_pa Physical Address of CEE DMA Memory
+ *
+ * @return void
+ */
+void
+bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
+{
+ cee->attr_dma.kva = dma_kva;
+ cee->attr_dma.pa = dma_pa;
+ cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
+ cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
+ cee->attr = (struct bfa_cee_attr_s *)dma_kva;
+ cee->stats =
+ (struct bfa_cee_stats_s *)(dma_kva + bfa_cee_attr_meminfo());
+}
+
+/**
+ * bfa_cee_get_attr()
+ *
+ * Send the request to the f/w to fetch CEE attributes.
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return Status
+ */
+
+bfa_status_t
+bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
+ bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
+{
+ struct bfi_cee_get_req_s *cmd;
+
+ bfa_assert((cee != NULL) && (cee->ioc != NULL));
+ if (!bfa_ioc_is_operational(cee->ioc))
+ return BFA_STATUS_IOC_FAILURE;
+ if (cee->get_attr_pending == BFA_TRUE)
+ return BFA_STATUS_DEVBUSY;
+ cee->get_attr_pending = BFA_TRUE;
+ cmd = (struct bfi_cee_get_req_s *)cee->get_cfg_mb.msg;
+ cee->attr = attr;
+ cee->cbfn.get_attr_cbfn = cbfn;
+ cee->cbfn.get_attr_cbarg = cbarg;
+ bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
+ bfa_ioc_portid(cee->ioc));
+ bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
+ bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * bfa_cee_get_stats()
+ *
+ * Send the request to the f/w to fetch CEE statistics.
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return Status
+ */
+
+bfa_status_t
+bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
+ bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
+{
+ struct bfi_cee_get_req_s *cmd;
+
+ bfa_assert((cee != NULL) && (cee->ioc != NULL));
+
+ if (!bfa_ioc_is_operational(cee->ioc))
+ return BFA_STATUS_IOC_FAILURE;
+ if (cee->get_stats_pending == BFA_TRUE)
+ return BFA_STATUS_DEVBUSY;
+ cee->get_stats_pending = BFA_TRUE;
+ cmd = (struct bfi_cee_get_req_s *)cee->get_stats_mb.msg;
+ cee->stats = stats;
+ cee->cbfn.get_stats_cbfn = cbfn;
+ cee->cbfn.get_stats_cbarg = cbarg;
+ bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
+ bfa_ioc_portid(cee->ioc));
+ bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
+ bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * bfa_cee_reset_stats()
+ *
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return Status
+ */
+
+bfa_status_t
+bfa_cee_reset_stats(struct bfa_cee_s *cee, bfa_cee_reset_stats_cbfn_t cbfn,
+ void *cbarg)
+{
+ struct bfi_cee_reset_stats_s *cmd;
+
+ bfa_assert((cee != NULL) && (cee->ioc != NULL));
+ if (!bfa_ioc_is_operational(cee->ioc))
+ return BFA_STATUS_IOC_FAILURE;
+ if (cee->reset_stats_pending == BFA_TRUE)
+ return BFA_STATUS_DEVBUSY;
+ cee->reset_stats_pending = BFA_TRUE;
+ cmd = (struct bfi_cee_reset_stats_s *)cee->reset_stats_mb.msg;
+ cee->cbfn.reset_stats_cbfn = cbfn;
+ cee->cbfn.reset_stats_cbarg = cbarg;
+ bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
+ bfa_ioc_portid(cee->ioc));
+ bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
+ return BFA_STATUS_OK;
+}
+
+/**
+ * bfa_cee_isrs()
+ *
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return void
+ */
+
+void
+bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
+{
+ union bfi_cee_i2h_msg_u *msg;
+ struct bfi_cee_get_rsp_s *get_rsp;
+ struct bfa_cee_s *cee = (struct bfa_cee_s *)cbarg;
+ msg = (union bfi_cee_i2h_msg_u *)m;
+ get_rsp = (struct bfi_cee_get_rsp_s *)m;
+ switch (msg->mh.msg_id) {
+ case BFI_CEE_I2H_GET_CFG_RSP:
+ bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
+ break;
+ case BFI_CEE_I2H_GET_STATS_RSP:
+ bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
+ break;
+ case BFI_CEE_I2H_RESET_STATS_RSP:
+ bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
+ break;
+ default:
+ bfa_assert(0);
+ }
+}
+
+/**
+ * bfa_cee_hbfail()
+ *
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return void
+ */
+
+void
+bfa_cee_hbfail(void *arg)
+{
+ struct bfa_cee_s *cee;
+ cee = (struct bfa_cee_s *)arg;
+
+ if (cee->get_attr_pending == BFA_TRUE) {
+ cee->get_attr_status = BFA_STATUS_FAILED;
+ cee->get_attr_pending = BFA_FALSE;
+ if (cee->cbfn.get_attr_cbfn)
+ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ if (cee->get_stats_pending == BFA_TRUE) {
+ cee->get_stats_status = BFA_STATUS_FAILED;
+ cee->get_stats_pending = BFA_FALSE;
+ if (cee->cbfn.get_stats_cbfn)
+ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ if (cee->reset_stats_pending == BFA_TRUE) {
+ cee->reset_stats_status = BFA_STATUS_FAILED;
+ cee->reset_stats_pending = BFA_FALSE;
+ if (cee->cbfn.reset_stats_cbfn) {
+ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+}
+
+/**
+ * bfa_cee_attach()
+ *
+ *
+ * @param[in] cee - Pointer to the CEE module data structure
+ * ioc - Pointer to the ioc module data structure
+ * dev - Pointer to the device driver module data structure
+ * The device driver specific mbox ISR functions have
+ * this pointer as one of the parameters.
+ * trcmod -
+ * logmod -
+ *
+ * @return void
+ */
+void
+bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
+ struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
+{
+ bfa_assert(cee != NULL);
+ cee->dev = dev;
+ cee->trcmod = trcmod;
+ cee->logmod = logmod;
+ cee->ioc = ioc;
+
+ bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
+ bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
+ bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail);
+}
+
+/**
+ * bfa_cee_detach()
+ *
+ *
+ * @param[in] cee - Pointer to the CEE module data structure
+ *
+ * @return void
+ */
+void
+bfa_cee_detach(struct bfa_cee_s *cee)
+{
+ /*
+ * For now, just check if there is some ioctl pending and mark that as
+ * failed?
+ */
+ /* bfa_cee_hbfail(cee); */
+}
diff -ruP net-next-2.6-orig/drivers/net/bna/bfa_csdebug.c net-next-2.6-mod/drivers/net/bna/bfa_csdebug.c
--- net-next-2.6-orig/drivers/net/bna/bfa_csdebug.c 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bfa_csdebug.c 2009-10-31 21:34:47.842536000 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See LICENSE.bna for copyright and licensing details.
+ */
+
+#include <cs/bfa_debug.h>
+#include <bfa_os_inc.h>
+#include <cs/bfa_q.h>
+
+/**
+ * cs_debug_api
+ */
+
+
+void
+bfa_panic(int line, char *file, char *panicstr)
+{
+ bfa_os_panic();
+}
+
+void
+bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event)
+{
+ bfa_os_panic();
+}
+
+int
+bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
+{
+ struct list_head *tqe;
+
+ tqe = bfa_q_next(q);
+ while (tqe != q) {
+ if (tqe == qe)
+ return 1;
+ tqe = bfa_q_next(tqe);
+ if (tqe == NULL)
+ break;
+ }
+ return 0;
+}
+
+
diff -ruP net-next-2.6-orig/drivers/net/bna/bfa_ioc.c net-next-2.6-mod/drivers/net/bna/bfa_ioc.c
--- net-next-2.6-orig/drivers/net/bna/bfa_ioc.c 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bfa_ioc.c 2009-10-31 21:34:47.850535000 -0700
@@ -0,0 +1,2273 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See LICENSE.bna for copyright and licensing details.
+ */
+
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_ctreg.h>
+#include <defs/bfa_defs_pci.h>
+#include <cna.h>
+
+
+/**
+ * IOC local definitions
+ */
+#define BFA_IOC_TOV 2000 /* msecs */
+#define BFA_IOC_HB_TOV 1000 /* msecs */
+#define BFA_IOC_HB_FAIL_MAX 4
+#define BFA_IOC_HWINIT_MAX 2
+#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
+#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
+ + BFA_IOC_TOV)
+
+#define bfa_ioc_timer_start(__ioc) \
+ bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
+ bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
+#define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer)
+
+#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS)
+#define BFA_DBG_FWTRC_LEN \
+ (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \
+ (sizeof(struct bfa_trc_mod_s) - \
+ BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
+#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
+#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
+
+#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
+bfa_boolean_t bfa_auto_recover = BFA_FALSE;
+
+/*
+ * forward declarations
+ */
+static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
+static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
+static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
+static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
+static void bfa_ioc_timeout(void *ioc);
+static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
+static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
+static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
+static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
+static void bfa_ioc_hb_stop(struct bfa_ioc_s *ioc);
+static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
+static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
+static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
+static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
+
+/**
+ * bfa_ioc_sm
+ */
+
+/**
+ * IOC state machine events
+ */
+enum ioc_event {
+ IOC_E_ENABLE = 1, /* IOC enable request */
+ IOC_E_DISABLE = 2, /* IOC disable request */
+ IOC_E_TIMEOUT = 3, /* f/w response timeout */
+ IOC_E_FWREADY = 4, /* f/w initialization done */
+ IOC_E_FWRSP_GETATTR = 5, /* IOC get attribute response */
+ IOC_E_FWRSP_ENABLE = 6, /* enable f/w response */
+ IOC_E_FWRSP_DISABLE = 7, /* disable f/w response */
+ IOC_E_HBFAIL = 8, /* heartbeat failure */
+ IOC_E_HWERROR = 9, /* hardware error interrupt */
+ IOC_E_SEMLOCKED = 10, /* h/w semaphore is locked */
+ IOC_E_DETACH = 11, /* driver detach cleanup */
+};
+
+bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
+
+static struct bfa_sm_table_s ioc_sm_table[] = {
+ {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
+ {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
+ {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
+ {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
+ {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
+ {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
+ {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
+ {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
+ {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
+ {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
+};
+
+/**
+ * Reset entry actions -- initialize state machine
+ */
+static void
+bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
+{
+ ioc->retry_count = 0;
+ ioc->auto_recover = bfa_auto_recover;
+}
+
+/**
+ * Beginning state. IOC is in reset state.
+ */
+static void
+bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ break;
+
+ case IOC_E_DETACH:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Semaphore should be acquired for version check.
+ */
+static void
+bfa_ioc_sm_fwcheck_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+/**
+ * Awaiting h/w semaphore to continue with version check.
+ */
+static void
+bfa_ioc_sm_fwcheck(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_SEMLOCKED:
+ if (bfa_ioc_firmware_lock(ioc)) {
+ ioc->retry_count = 0;
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ } else {
+ bfa_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
+ }
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ /*
+ * fall through
+ */
+
+ case IOC_E_DETACH:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Notify enable completion callback and generate mismatch AEN.
+ */
+static void
+bfa_ioc_sm_mismatch_entry(struct bfa_ioc_s *ioc)
+{
+ /**
+ * Provide enable completion callback and AEN notification only once.
+ */
+ if (ioc->retry_count == 0)
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ ioc->retry_count++;
+ bfa_ioc_timer_start(ioc);
+}
+
+/**
+ * Awaiting firmware version match.
+ */
+static void
+bfa_ioc_sm_mismatch(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ /*
+ * fall through
+ */
+
+ case IOC_E_DETACH:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Request for semaphore.
+ */
+static void
+bfa_ioc_sm_semwait_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+/**
+ * Awaiting semaphore for h/w initialzation.
+ */
+static void
+bfa_ioc_sm_semwait(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_SEMLOCKED:
+ ioc->retry_count = 0;
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_hwinit_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_reset(ioc, BFA_FALSE);
+}
+
+/**
+ * Hardware is being initialized. Interrupts are enabled.
+ * Holding hardware semaphore lock.
+ */
+static void
+bfa_ioc_sm_hwinit(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_FWREADY:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /*
+ * fall through
+ */
+
+ case IOC_E_TIMEOUT:
+ ioc->retry_count++;
+ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_reset(ioc, BFA_TRUE);
+ break;
+ }
+
+ bfa_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hw_sem_release(ioc);
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_enable(ioc);
+}
+
+/**
+ * Host IOC function is being enabled, awaiting response from firmware.
+ * Semaphore is acquired.
+ */
+static void
+bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_FWRSP_ENABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /*
+ * fall through
+ */
+
+ case IOC_E_TIMEOUT:
+ ioc->retry_count++;
+ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
+ bfa_reg_write(ioc->ioc_regs.ioc_fwstate,
+ BFI_IOC_UNINIT);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ break;
+ }
+
+ bfa_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_FWREADY:
+ bfa_ioc_send_enable(ioc);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_getattr(ioc);
+}
+
+/**
+ * IOC configuration in progress. Timer is active.
+ */
+static void
+bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_FWRSP_GETATTR:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /*
+ * fall through
+ */
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
+ bfa_ioc_hb_monitor(ioc);
+}
+
+static void
+bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_ENABLE:
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hb_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
+
+ case IOC_E_HWERROR:
+ case IOC_E_FWREADY:
+ /**
+ * Hard error or IOC recovery by other function.
+ * Treat it same as heartbeat failure.
+ */
+ bfa_ioc_hb_stop(ioc);
+ /*
+ * !!! fall through !!!
+ */
+
+ case IOC_E_HBFAIL:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_disable(ioc);
+}
+
+/**
+ * IOC is being disabled
+ */
+static void
+bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_HWERROR:
+ case IOC_E_FWRSP_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ /*
+ * !!! fall through !!!
+ */
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * IOC disable completion entry.
+ */
+static void
+bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_disable_comp(ioc);
+}
+
+static void
+bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ case IOC_E_DISABLE:
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ case IOC_E_DETACH:
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_ioc_timer_start(ioc);
+}
+
+/**
+ * Hardware initialization failed.
+ */
+static void
+bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+static void
+bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify_s *notify;
+
+ /**
+ * Mark IOC as failed in hardware and stop firmware.
+ */
+ bfa_ioc_lpu_stop(ioc);
+ bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
+
+ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
+ bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
+ /*
+ * Wait for halt to take effect
+ */
+ bfa_reg_read(ioc->ioc_regs.ll_halt);
+ }
+
+ /**
+ * Notify driver and common modules registered for notification.
+ */
+ ioc->cbfn->hbfail_cbfn(ioc->bfa);
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify_s *)qe;
+ notify->cbfn(notify->cbarg);
+ }
+
+ /**
+ * Flush any queued up mailbox requests.
+ */
+ bfa_ioc_mbox_hbfail(ioc);
+
+ /**
+ * Trigger auto-recovery after a delay.
+ */
+ if (ioc->auto_recover) {
+ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer,
+ bfa_ioc_timeout, ioc, BFA_IOC_TOV_RECOVER);
+ }
+}
+
+/**
+ * IOC heartbeat failure.
+ */
+static void
+bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
+{
+
+ switch (event) {
+
+ case IOC_E_ENABLE:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ break;
+
+ case IOC_E_DISABLE:
+ if (ioc->auto_recover)
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ case IOC_E_FWREADY:
+ /**
+ * Recovery is already initiated by other function.
+ */
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+
+
+/**
+ * bfa_ioc_pvt BFA IOC private functions
+ */
+
+static void
+bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify_s *notify;
+
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+
+ /**
+ * Notify common modules registered for notification.
+ */
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify_s *)qe;
+ notify->cbfn(notify->cbarg);
+ }
+}
+
+static void
+bfa_ioc_sem_timeout(void *ioc_arg)
+{
+ struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
+
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+static void
+bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
+{
+ u32 r32;
+ int cnt = 0;
+#define BFA_SEM_SPINCNT 1000
+
+ do {
+ r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
+ cnt++;
+ if (cnt > BFA_SEM_SPINCNT)
+ break;
+ } while (r32 != 0);
+ bfa_assert(cnt < BFA_SEM_SPINCNT);
+}
+
+static void
+bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
+{
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
+}
+
+static void
+bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
+{
+ u32 r32;
+
+ /**
+ * First read to the semaphore register will return 0, subsequent reads
+ * will return 1. Semaphore is released by writing 0 to the register
+ */
+ r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+ if (r32 == 0) {
+ bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
+ return;
+ }
+
+ bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
+ ioc, BFA_IOC_TOV);
+}
+
+static void
+bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
+{
+ bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
+}
+
+static void
+bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
+{
+ bfa_timer_stop(&ioc->sem_timer);
+}
+
+/**
+ * Initialize LPU local memory (aka secondary memory / SRAM)
+ */
+static void
+bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
+{
+ u32 pss_ctl;
+ int i;
+#define PSS_LMEM_INIT_TIME 10000
+
+ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl &= ~__PSS_LMEM_RESET;
+ pss_ctl |= __PSS_LMEM_INIT_EN;
+ pss_ctl |= __PSS_I2C_CLK_DIV(3UL); /* i2c workaround 12.5khz clock */
+ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+
+ /**
+ * wait for memory initialization to be complete
+ */
+ i = 0;
+ do {
+ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+ i++;
+ } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
+
+ /**
+ * If memory initialization is not successful, IOC timeout will catch
+ * such failures.
+ */
+ bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE);
+
+ pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
+ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+}
+
+static void
+bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
+{
+ u32 pss_ctl;
+
+ /**
+ * Take processor out of reset.
+ */
+ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl &= ~__PSS_LPU0_RESET;
+
+ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+}
+
+static void
+bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
+{
+ u32 pss_ctl;
+
+ /**
+ * Put processors in reset.
+ */
+ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
+
+ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+}
+
+/**
+ * Get driver and firmware versions.
+ */
+static void
+bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
+{
+ u32 pgnum, pgoff;
+ u32 loff = 0;
+ int i;
+ u32 *fwsig = (u32 *) fwhdr;
+
+ pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+
+ for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
+ i++) {
+ fwsig[i] = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
+ loff += sizeof(u32);
+ }
+}
+
+static u32 *
+bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+ if (ioc->ctdev)
+ return bfi_image_ct_get_chunk(off);
+ return bfi_image_cb_get_chunk(off);
+}
+
+static u32
+bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
+}
+
+/**
+ * Returns TRUE if same.
+ */
+static bfa_boolean_t
+bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
+{
+ struct bfi_ioc_image_hdr_s *drv_fwhdr;
+ int i;
+
+ drv_fwhdr =
+ (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
+
+ for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
+ if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i])
+ return BFA_FALSE;
+ }
+
+ return BFA_TRUE;
+}
+
+/**
+ * Return true if current running version is valid. Firmware signature and
+ * execution context (driver/bios) must match.
+ */
+static bfa_boolean_t
+bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
+{
+ struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
+
+ /**
+ * If bios/efi boot (flash based) -- return true
+ */
+ if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ return BFA_TRUE;
+
+ bfa_ioc_fwver_get(ioc, &fwhdr);
+ drv_fwhdr =
+ (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
+
+ if (fwhdr.signature != drv_fwhdr->signature)
+ return BFA_FALSE;
+
+ if (fwhdr.exec != drv_fwhdr->exec)
+ return BFA_FALSE;
+
+ return bfa_ioc_fwver_cmp(ioc, &fwhdr);
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ u32 usecnt;
+ struct bfi_ioc_image_hdr_s fwhdr;
+
+ /**
+ * Firmware match check is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return BFA_TRUE;
+
+ /**
+ * If bios boot (flash based) -- do not increment usage count
+ */
+ if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ return BFA_TRUE;
+
+ bfa_ioc_usage_sem_get(ioc);
+ usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+
+ /**
+ * If usage count is 0, always return TRUE.
+ */
+ if (usecnt == 0) {
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
+ bfa_ioc_usage_sem_release(ioc);
+ return BFA_TRUE;
+ }
+
+ ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+
+ /**
+ * Use count cannot be non-zero and chip in uninitialized state.
+ */
+ bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
+
+ /**
+ * Check if another driver with a different firmware is active
+ */
+ bfa_ioc_fwver_get(ioc, &fwhdr);
+ if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
+ bfa_ioc_usage_sem_release(ioc);
+ return BFA_FALSE;
+ }
+
+ /**
+ * Same firmware version. Increment the reference count.
+ */
+ usecnt++;
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+ bfa_ioc_usage_sem_release(ioc);
+ return BFA_TRUE;
+}
+
+static void
+bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+ u32 usecnt;
+
+ /**
+ * Firmware lock is relevant only for CNA.
+ * If bios boot (flash based) -- do not decrement usage count
+ */
+ if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
+ return;
+
+ /**
+ * decrement usage count
+ */
+ bfa_ioc_usage_sem_get(ioc);
+ usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+ bfa_assert(usecnt > 0);
+
+ usecnt--;
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+
+ bfa_ioc_usage_sem_release(ioc);
+}
+
+/**
+ * Conditionally flush any pending message from firmware at start.
+ */
+static void
+bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
+{
+ u32 r32;
+
+ r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
+ if (r32)
+ bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
+}
+
+
+static void
+bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ bfa_boolean_t fwvalid;
+
+ ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+
+ if (force)
+ ioc_fwstate = BFI_IOC_UNINIT;
+
+
+ /**
+ * check if firmware is valid
+ */
+ fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
+ BFA_FALSE : bfa_ioc_fwver_valid(ioc);
+
+ if (!fwvalid) {
+ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
+ return;
+ }
+
+ /**
+ * If hardware initialization is in progress (initialized by other IOC),
+ * just wait for an initialization completion interrupt.
+ */
+ if (ioc_fwstate == BFI_IOC_INITING) {
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ return;
+ }
+
+ /**
+ * If IOC function is disabled and firmware version is same,
+ * just re-enable IOC.
+ */
+ if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
+
+ /**
+ * When using MSI-X any pending firmware ready event should
+ * be flushed. Otherwise MSI-X interrupts are not delivered.
+ */
+ bfa_ioc_msgflush(ioc);
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ return;
+ }
+
+ /**
+ * Initialize the h/w for any other states.
+ */
+ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
+}
+
+static void
+bfa_ioc_timeout(void *ioc_arg)
+{
+ struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
+
+ bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
+}
+
+void
+bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
+{
+ u32 *msgp = (u32 *) ioc_msg;
+ u32 i;
+
+
+ bfa_assert(len <= BFI_IOC_MSGLEN_MAX);
+
+ /*
+ * first write msg to mailbox registers
+ */
+ for (i = 0; i < len / sizeof(u32); i++)
+ bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32),
+ bfa_os_wtole(msgp[i]));
+
+ for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
+ bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), 0);
+
+ /*
+ * write 1 to mailbox CMD to trigger LPU event
+ */
+ bfa_reg_write(ioc->ioc_regs.hfn_mbox_cmd, 1);
+ (void)bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
+}
+
+static void
+bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
+{
+ struct bfi_ioc_ctrl_req_s enable_req;
+
+ bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
+ bfa_ioc_portid(ioc));
+ enable_req.ioc_class = ioc->ioc_mc;
+ bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
+}
+
+static void
+bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
+{
+ struct bfi_ioc_ctrl_req_s disable_req;
+
+ bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
+ bfa_ioc_portid(ioc));
+ bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
+}
+
+static void
+bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
+{
+ struct bfi_ioc_getattr_req_s attr_req;
+
+ bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
+ bfa_ioc_portid(ioc));
+ bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
+ bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
+}
+
+static void
+bfa_ioc_hb_check(void *cbarg)
+{
+ struct bfa_ioc_s *ioc = cbarg;
+ u32 hb_count;
+
+ hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
+ if (ioc->hb_count == hb_count) {
+ ioc->hb_fail++;
+ } else {
+ ioc->hb_count = hb_count;
+ ioc->hb_fail = 0;
+ }
+
+ if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
+ ioc->hb_fail = 0;
+ bfa_ioc_recover(ioc);
+ return;
+ }
+
+ bfa_ioc_mbox_poll(ioc);
+ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
+ BFA_IOC_HB_TOV);
+}
+
+static void
+bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
+{
+ ioc->hb_fail = 0;
+ ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
+ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
+ BFA_IOC_HB_TOV);
+}
+
+static void
+bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
+{
+ bfa_timer_stop(&ioc->ioc_timer);
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct {
+ u32 hfn_mbox, lpu_mbox, hfn_pgn;
+} iocreg_fnreg[] = {
+ {
+ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
+ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
+ HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
+ HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct {
+ u32 hfn, lpu;
+} iocreg_mbcmd_p0[] = {
+ {
+ HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
+ HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
+ HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
+ HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct {
+ u32 hfn, lpu;
+} iocreg_mbcmd_p1[] = {
+ {
+ HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
+ HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
+ HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
+ HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
+};
+
+/**
+ * Shared IRQ handling in INTX mode
+ */
+static struct {
+ u32 isr, msk;
+} iocreg_shirq_next[] = {
+ {
+ HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
+ HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
+ HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
+HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
+
+static void
+bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb;
+ int pcifn = bfa_ioc_pcifn(ioc);
+
+ rb = bfa_ioc_bar0(ioc);
+
+ ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+ ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+ ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+ if (ioc->port_id == 0) {
+ ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+ ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+ } else {
+ ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+ ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+ }
+
+ /**
+ * Shared IRQ handling in INTX mode
+ */
+ ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
+ ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
+
+ /*
+ * PSS control registers
+ */
+ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+ ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+ ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+ /*
+ * IOC semaphore registers and serialization
+ */
+ ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+ ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+ ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+ /**
+ * sram memory access
+ */
+ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
+ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
+ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+}
+
+/**
+ * Initiate a full firmware download.
+ */
+static void
+bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
+ u32 boot_param)
+{
+ u32 *fwimg;
+ u32 pgnum, pgoff;
+ u32 loff = 0;
+ u32 chunkno = 0;
+ u32 i;
+
+ /**
+ * Initialize LMEM first before code download
+ */
+ bfa_ioc_lmem_init(ioc);
+
+ /**
+ * Flash based firmware boot
+ */
+ if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ boot_type = BFI_BOOT_TYPE_FLASH;
+ fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
+ fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
+ fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
+ bfa_os_swap32(boot_param);
+
+ pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+
+ for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
+
+ if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
+ chunkno = BFA_FLASH_CHUNK_NO(i);
+ fwimg = bfa_ioc_fwimg_get_chunk(ioc,
+ BFA_FLASH_CHUNK_ADDR(chunkno));
+ }
+
+ /**
+ * write smem
+ */
+ bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
+ fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
+
+ loff += sizeof(u32);
+
+ /**
+ * handle page offset wrap around
+ */
+ loff = PSS_SMEM_PGOFF(loff);
+ if (loff == 0) {
+ pgnum++;
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+ }
+ }
+
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
+ bfa_ioc_smem_pgnum(ioc, 0));
+}
+
+static void
+bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
+{
+ bfa_ioc_hwinit(ioc, force);
+}
+
+/**
+ * Update BFA configuration from firmware configuration.
+ */
+static void
+bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
+{
+ struct bfi_ioc_attr_s *attr = ioc->attr;
+
+ attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop);
+ attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize);
+
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
+}
+
+/**
+ * Attach time initialization of mbox logic.
+ */
+static void
+bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+ int mc;
+
+ INIT_LIST_HEAD(&mod->cmd_q);
+ for (mc = 0; mc < BFI_MC_MAX; mc++) {
+ mod->mbhdlr[mc].cbfn = NULL;
+ mod->mbhdlr[mc].cbarg = ioc->bfa;
+ }
+}
+
+/**
+ * Mbox poll timer -- restarts any pending mailbox requests.
+ */
+static void
+bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+ struct bfa_mbox_cmd_s *cmd;
+ u32 stat;
+
+ /**
+ * If no command pending, do nothing
+ */
+ if (list_empty(&mod->cmd_q))
+ return;
+
+ /**
+ * If previous command is not yet fetched by firmware, do nothing
+ */
+ stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
+ if (stat)
+ return;
+
+ /**
+ * Enqueue command to firmware.
+ */
+ bfa_q_deq(&mod->cmd_q, &cmd);
+ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+}
+
+/**
+ * Cleanup any pending requests.
+ */
+static void
+bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+ struct bfa_mbox_cmd_s *cmd;
+
+ while (!list_empty(&mod->cmd_q))
+ bfa_q_deq(&mod->cmd_q, &cmd);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
+static void
+bfa_ioc_map_port(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 r32;
+
+ /**
+ * For crossbow, port id is same as pci function.
+ */
+ if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
+ ioc->port_id = bfa_ioc_pcifn(ioc);
+ return;
+ }
+
+ /**
+ * For catapult, base port id on personality register and IOC type
+ */
+ r32 = bfa_reg_read(rb + FNC_PERS_REG);
+ r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+ ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+}
+
+
+
+/**
+ * bfa_ioc_public
+ */
+
+/**
+* Set interrupt mode for a function: INTX or MSIX
+ */
+void
+bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 r32, mode;
+
+ r32 = bfa_reg_read(rb + FNC_PERS_REG);
+
+ mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+ __F0_INTX_STATUS;
+
+ /**
+ * If already in desired mode, do not change anything
+ */
+ if (!msix && mode)
+ return;
+
+ if (msix)
+ mode = __F0_INTX_STATUS_MSIX;
+ else
+ mode = __F0_INTX_STATUS_INTA;
+
+ r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+ r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+
+ bfa_reg_write(rb + FNC_PERS_REG, r32);
+}
+
+bfa_status_t
+bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 pll_sclk, pll_fclk, r32;
+
+ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
+ pll_sclk =
+ __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
+ __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
+ __APP_PLL_312_JITLMT0_1(3U) |
+ __APP_PLL_312_CNTLMT0_1(1U);
+ pll_fclk =
+ __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
+ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
+ __APP_PLL_425_JITLMT0_1(3U) |
+ __APP_PLL_425_CNTLMT0_1(1U);
+
+ /**
+ * For catapult, choose operational mode FC/FCoE
+ */
+ if (ioc->fcmode) {
+ bfa_reg_write((rb + OP_MODE), 0);
+ bfa_reg_write((rb + ETH_MAC_SER_REG),
+ __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
+ | __APP_EMS_CHANNEL_SEL);
+ } else {
+ ioc->pllinit = BFA_TRUE;
+ bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
+ bfa_reg_write((rb + ETH_MAC_SER_REG),
+ __APP_EMS_REFCKBUFEN1);
+ }
+ } else {
+ pll_sclk =
+ __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
+ __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
+ __APP_PLL_312_CNTLMT0_1(3U);
+ pll_fclk =
+ __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
+ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+ __APP_PLL_425_JITLMT0_1(3U) |
+ __APP_PLL_425_CNTLMT0_1(3U);
+ }
+
+ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ __APP_PLL_312_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ __APP_PLL_425_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
+ bfa_os_udelay(2);
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ __APP_PLL_312_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ __APP_PLL_425_LOGIC_SOFT_RESET);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
+
+ /**
+ * Wait for PLLs to lock.
+ */
+ bfa_os_udelay(2000);
+ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
+
+ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
+ bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
+ bfa_os_udelay(1000);
+ r32 = bfa_reg_read((rb + MBIST_STAT_REG));
+ }
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Interface used by diag module to do firmware boot with memory test
+ * as the entry vector.
+ */
+void
+bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
+{
+ bfa_os_addr_t rb;
+
+ bfa_ioc_stats(ioc, ioc_boots);
+
+ if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
+ return;
+
+ /**
+ * Initialize IOC state of all functions on a chip reset.
+ */
+ rb = ioc->pcidev.pci_bar_kva;
+ if (boot_param == BFI_BOOT_TYPE_MEMTEST) {
+ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_MEMTEST);
+ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_MEMTEST);
+ } else {
+ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_INITING);
+ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
+ }
+
+ bfa_ioc_download_fw(ioc, boot_type, boot_param);
+
+ /**
+ * Enable interrupts just before starting LPU
+ */
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_ioc_lpu_start(ioc);
+}
+
+/**
+ * Enable/disable IOC failure auto recovery.
+ */
+void
+bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
+{
+ bfa_auto_recover = BFA_FALSE;
+}
+
+
+bfa_boolean_t
+bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
+{
+ return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
+}
+
+void
+bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
+{
+ u32 *msgp = mbmsg;
+ u32 r32;
+ int i;
+
+ /**
+ * read the MBOX msg
+ */
+ for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
+ i++) {
+ r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox +
+ i * sizeof(u32));
+ msgp[i] = bfa_os_htonl(r32);
+ }
+
+ /**
+ * turn off mailbox interrupt by clearing mailbox status
+ */
+ bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
+ bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
+}
+
+void
+bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
+{
+ union bfi_ioc_i2h_msg_u *msg;
+
+ msg = (union bfi_ioc_i2h_msg_u *)m;
+
+ bfa_ioc_stats(ioc, ioc_isrs);
+
+ switch (msg->mh.msg_id) {
+ case BFI_IOC_I2H_HBEAT:
+ break;
+
+ case BFI_IOC_I2H_READY_EVENT:
+ bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ break;
+
+ case BFI_IOC_I2H_ENABLE_REPLY:
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
+ break;
+
+ case BFI_IOC_I2H_DISABLE_REPLY:
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
+ break;
+
+ case BFI_IOC_I2H_GETATTR_REPLY:
+ bfa_ioc_getattr_reply(ioc);
+ break;
+
+ default:
+ bfa_assert(0);
+ }
+}
+
+/**
+ * IOC attach time initialization and setup.
+ *
+ * @param[in] ioc memory for IOC
+ * @param[in] bfa driver instance structure
+ * @param[in] trcmod kernel trace module
+ * @param[in] aen kernel aen event module
+ * @param[in] logm kernel logging module
+ */
+void
+bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
+ struct bfa_timer_mod_s *timer_mod, struct bfa_trc_mod_s *trcmod,
+ struct bfa_aen_s *aen, struct bfa_log_mod_s *logm)
+{
+ ioc->bfa = bfa;
+ ioc->cbfn = cbfn;
+ ioc->timer_mod = timer_mod;
+ ioc->trcmod = trcmod;
+ ioc->aen = aen;
+ ioc->logm = logm;
+ ioc->fcmode = BFA_FALSE;
+ ioc->pllinit = BFA_FALSE;
+ ioc->dbg_fwsave_once = BFA_TRUE;
+
+ bfa_ioc_mbox_attach(ioc);
+ INIT_LIST_HEAD(&ioc->hb_notify_q);
+
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+}
+
+/**
+ * Driver detach time IOC cleanup.
+ */
+void
+bfa_ioc_detach(struct bfa_ioc_s *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_DETACH);
+}
+
+/**
+ * Setup IOC PCI properties.
+ *
+ * @param[in] pcidev PCI device information for this IOC
+ */
+void
+bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
+ enum bfi_mclass mc)
+{
+ ioc->ioc_mc = mc;
+ ioc->pcidev = *pcidev;
+ ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
+ ioc->cna = ioc->ctdev && !ioc->fcmode;
+
+ bfa_ioc_map_port(ioc);
+ bfa_ioc_reg_init(ioc);
+}
+
+/**
+ * Initialize IOC dma memory
+ *
+ * @param[in] dm_kva kernel virtual address of IOC dma memory
+ * @param[in] dm_pa physical address of IOC dma memory
+ */
+void
+bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa)
+{
+ /**
+ * dma memory for firmware attribute
+ */
+ ioc->attr_dma.kva = dm_kva;
+ ioc->attr_dma.pa = dm_pa;
+ ioc->attr = (struct bfi_ioc_attr_s *)dm_kva;
+}
+
+/**
+ * Return size of dma memory required.
+ */
+u32
+bfa_ioc_meminfo(void)
+{
+ return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
+}
+
+void
+bfa_ioc_enable(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_enables);
+ ioc->dbg_fwsave_once = BFA_TRUE;
+
+ bfa_fsm_send_event(ioc, IOC_E_ENABLE);
+}
+
+void
+bfa_ioc_disable(struct bfa_ioc_s *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_disables);
+ bfa_fsm_send_event(ioc, IOC_E_DISABLE);
+}
+
+/**
+ * Returns memory required for saving firmware trace in case of crash.
+ * Driver must call this interface to allocate memory required for
+ * automatic saving of firmware trace. Driver should call
+ * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this
+ * trace memory.
+ */
+int
+bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
+{
+return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
+}
+
+/**
+ * Initialize memory for saving firmware trace. Driver must initialize
+ * trace memory before call bfa_ioc_enable().
+ */
+void
+bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
+{
+ bfa_assert(ioc->auto_recover);
+ ioc->dbg_fwsave = dbg_fwsave;
+ ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
+}
+
+u32
+bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr)
+{
+ return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
+}
+
+u32
+bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
+{
+ return PSS_SMEM_PGOFF(fmaddr);
+}
+
+/**
+ * Register mailbox message handler functions
+ *
+ * @param[in] ioc IOC instance
+ * @param[in] mcfuncs message class handler functions
+ */
+void
+bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+ int mc;
+
+ for (mc = 0; mc < BFI_MC_MAX; mc++)
+ mod->mbhdlr[mc].cbfn = mcfuncs[mc];
+}
+
+/**
+ * Register mailbox message handler function, to be called by common modules
+ */
+void
+bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
+ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+
+ mod->mbhdlr[mc].cbfn = cbfn;
+ mod->mbhdlr[mc].cbarg = cbarg;
+}
+
+/**
+ * Queue a mailbox command request to firmware. Waits if mailbox is busy.
+ * Responsibility of caller to serialize
+ *
+ * @param[in] ioc IOC instance
+ * @param[i] cmd Mailbox command
+ */
+void
+bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+ u32 stat;
+
+ /**
+ * If a previous command is pending, queue new command
+ */
+ if (!list_empty(&mod->cmd_q)) {
+ list_add_tail(&cmd->qe, &mod->cmd_q);
+ return;
+ }
+
+ /**
+ * If mailbox is busy, queue command for poll timer
+ */
+ stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
+ if (stat) {
+ list_add_tail(&cmd->qe, &mod->cmd_q);
+ return;
+ }
+
+ /**
+ * mailbox is free -- queue command to firmware
+ */
+ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+}
+
+/**
+ * Handle mailbox interrupts
+ */
+void
+bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
+{
+ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
+ struct bfi_mbmsg_s m;
+ int mc;
+
+ bfa_ioc_msgget(ioc, &m);
+
+ /**
+ * Treat IOC message class as special.
+ */
+ mc = m.mh.msg_class;
+ if (mc == BFI_MC_IOC) {
+ bfa_ioc_isr(ioc, &m);
+ return;
+ }
+
+ if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
+ return;
+
+ mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
+}
+
+void
+bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_HWERROR);
+}
+
+#ifndef BFA_BIOS_BUILD
+
+/**
+ * return true if IOC is disabled
+ */
+bfa_boolean_t
+bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
+{
+ return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
+ || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
+}
+
+/**
+ * return true if IOC firmware is different.
+ */
+bfa_boolean_t
+bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
+{
+ return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
+ || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck)
+ || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch);
+}
+
+#define bfa_ioc_state_disabled(__sm) \
+ (((__sm) == BFI_IOC_UNINIT) || \
+ ((__sm) == BFI_IOC_INITING) || \
+ ((__sm) == BFI_IOC_HWINIT) || \
+ ((__sm) == BFI_IOC_DISABLED) || \
+ ((__sm) == BFI_IOC_HBFAIL) || \
+ ((__sm) == BFI_IOC_CFG_DISABLED))
+
+/**
+ * Check if adapter is disabled -- both IOCs should be in a disabled
+ * state.
+ */
+bfa_boolean_t
+bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
+{
+ u32 ioc_state;
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+
+ if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
+ return BFA_FALSE;
+
+ ioc_state = bfa_reg_read(rb + BFA_IOC0_STATE_REG);
+ if (!bfa_ioc_state_disabled(ioc_state))
+ return BFA_FALSE;
+
+ ioc_state = bfa_reg_read(rb + BFA_IOC1_STATE_REG);
+ if (!bfa_ioc_state_disabled(ioc_state))
+ return BFA_FALSE;
+
+ return BFA_TRUE;
+}
+
+/**
+ * Add to IOC heartbeat failure notification queue. To be used by common
+ * modules such as
+ */
+void
+bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
+ struct bfa_ioc_hbfail_notify_s *notify)
+{
+ list_add_tail(¬ify->qe, &ioc->hb_notify_q);
+}
+
+#define BFA_MFG_NAME "Brocade"
+void
+bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
+ struct bfa_adapter_attr_s *ad_attr)
+{
+ struct bfi_ioc_attr_s *ioc_attr;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
+
+ ioc_attr = ioc->attr;
+ bfa_os_memcpy((void *)&ad_attr->serial_num,
+ (void *)ioc_attr->brcd_serialnum,
+ BFA_ADAPTER_SERIAL_NUM_LEN);
+
+ bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
+ bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
+ BFA_VERSION_LEN);
+ bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
+ BFA_ADAPTER_MFG_NAME_LEN);
+ bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
+ sizeof(struct bfa_mfg_vpd_s));
+
+ ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
+ ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
+
+ /**
+ * model name
+ */
+ if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
+ strcpy(model, "BR-10?0");
+ model[5] = '0' + ad_attr->nports;
+ } else {
+ strcpy(model, "Brocade-??5");
+ model[8] =
+ '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
+ model[9] = '0' + ad_attr->nports;
+ }
+
+ if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
+ ad_attr->prototype = 1;
+ else
+ ad_attr->prototype = 0;
+
+ bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
+ bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
+ BFA_ADAPTER_MODEL_NAME_LEN);
+
+ ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
+ ad_attr->mac = bfa_ioc_get_mac(ioc);
+
+ ad_attr->pcie_gen = ioc_attr->pcie_gen;
+ ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
+ ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
+ ad_attr->asic_rev = ioc_attr->asic_rev;
+ ad_attr->hw_ver[0] = 'R';
+ ad_attr->hw_ver[1] = 'e';
+ ad_attr->hw_ver[2] = 'v';
+ ad_attr->hw_ver[3] = '-';
+ ad_attr->hw_ver[4] = ioc_attr->asic_rev;
+ ad_attr->hw_ver[5] = '\0';
+
+ ad_attr->cna_capable = ioc->cna;
+}
+
+void
+bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
+{
+ bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
+
+ ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+ ioc_attr->port_id = ioc->port_id;
+
+ if (!ioc->ctdev)
+ ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
+ else if (ioc->ioc_mc == BFI_MC_IOCFC)
+ ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
+ else if (ioc->ioc_mc == BFI_MC_LL)
+ ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
+
+ bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
+
+ ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
+ ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
+ ioc_attr->pci_attr.chip_rev[0] = 'R';
+ ioc_attr->pci_attr.chip_rev[1] = 'e';
+ ioc_attr->pci_attr.chip_rev[2] = 'v';
+ ioc_attr->pci_attr.chip_rev[3] = '-';
+ ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
+ ioc_attr->pci_attr.chip_rev[5] = '\0';
+}
+
+/**
+ * hal_wwn_public
+ */
+wwn_t
+bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
+{
+ union {
+ wwn_t wwn;
+ u8 byte[sizeof(wwn_t)];
+ }
+ w;
+
+ w.wwn = ioc->attr->mfg_wwn;
+
+ if (bfa_ioc_portid(ioc) == 1)
+ w.byte[7]++;
+
+ return w.wwn;
+}
+
+wwn_t
+bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
+{
+ union {
+ wwn_t wwn;
+ u8 byte[sizeof(wwn_t)];
+ }
+ w;
+
+ w.wwn = ioc->attr->mfg_wwn;
+
+ if (bfa_ioc_portid(ioc) == 1)
+ w.byte[7]++;
+
+ w.byte[0] = 0x20;
+
+ return w.wwn;
+}
+
+wwn_t
+bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst)
+{
+ union {
+ wwn_t wwn;
+ u8 byte[sizeof(wwn_t)];
+ }
+ w , w5;
+
+
+ w.wwn = ioc->attr->mfg_wwn;
+ w5.byte[0] = 0x50 | w.byte[2] >> 4;
+ w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4;
+ w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4;
+ w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4;
+ w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4;
+ w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4;
+ w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8;
+ w5.byte[7] = (inst & 0xff);
+
+ return w5.wwn;
+}
+
+u64
+bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
+{
+ return ioc->attr->mfg_wwn;
+}
+
+mac_t
+bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
+{
+ mac_t mac;
+
+ mac = ioc->attr->mfg_mac;
+ mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
+
+ return mac;
+}
+
+void
+bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
+{
+ ioc->fcmode = BFA_TRUE;
+ ioc->port_id = bfa_ioc_pcifn(ioc);
+}
+
+bfa_boolean_t
+bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
+{
+ return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
+}
+
+/**
+ * Return true if interrupt should be claimed.
+ */
+bfa_boolean_t
+bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
+{
+ u32 isr, msk;
+
+ /**
+ * Always claim if not catapult.
+ */
+ if (!ioc->ctdev)
+ return BFA_TRUE;
+
+ /**
+ * FALSE if next device is claiming interrupt.
+ * TRUE if next device is not interrupting or not present.
+ */
+ msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
+ isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
+ return !(isr & ~msk);
+}
+
+/**
+ * Retrieve saved firmware trace from a prior IOC failure.
+ */
+bfa_status_t
+bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
+{
+ int tlen;
+
+ if (ioc->dbg_fwsave_len == 0)
+ return BFA_STATUS_ENOFSAVE;
+
+ tlen = *trclen;
+ if (tlen > ioc->dbg_fwsave_len)
+ tlen = ioc->dbg_fwsave_len;
+
+ bfa_os_memcpy(trcdata, ioc->dbg_fwsave, tlen);
+ *trclen = tlen;
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Retrieve saved firmware trace from a prior IOC failure.
+ */
+bfa_status_t
+bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
+{
+ u32 pgnum;
+ u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
+ int i, tlen;
+ u32 *tbuf = trcdata, r32;
+
+
+ pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ loff = bfa_ioc_smem_pgoff(ioc, loff);
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+
+ tlen = *trclen;
+ if (tlen > BFA_DBG_FWTRC_LEN)
+ tlen = BFA_DBG_FWTRC_LEN;
+ tlen /= sizeof(u32);
+
+
+ for (i = 0; i < tlen; i++) {
+ r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
+ tbuf[i] = bfa_os_ntohl(r32);
+ loff += sizeof(u32);
+
+ /**
+ * handle page offset wrap around
+ */
+ loff = PSS_SMEM_PGOFF(loff);
+ if (loff == 0) {
+ pgnum++;
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+ }
+ }
+ bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
+ bfa_ioc_smem_pgnum(ioc, 0));
+
+ *trclen = tlen * sizeof(u32);
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Save firmware trace if configured.
+ */
+static void
+bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
+{
+ int tlen;
+
+ if (ioc->dbg_fwsave_len) {
+ tlen = ioc->dbg_fwsave_len;
+ bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
+ }
+}
+
+/**
+ * Firmware failure detected. Start recovery actions.
+ */
+static void
+bfa_ioc_recover(struct bfa_ioc_s *ioc)
+{
+ if (ioc->dbg_fwsave_once) {
+ ioc->dbg_fwsave_once = BFA_FALSE;
+ bfa_ioc_debug_save(ioc);
+ }
+
+ bfa_ioc_stats(ioc, ioc_hbfails);
+ bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
+}
+
+#else
+
+static void
+bfa_ioc_recover(struct bfa_ioc_s *ioc)
+{
+ bfa_assert(0);
+}
+
+#endif
+
+
diff -ruP net-next-2.6-orig/drivers/net/bna/bfa_sm.c net-next-2.6-mod/drivers/net/bna/bfa_sm.c
--- net-next-2.6-orig/drivers/net/bna/bfa_sm.c 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bfa_sm.c 2009-10-31 21:34:47.858534000 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See LICENSE.bna for copyright and licensing details.
+ */
+
+/**
+ * bfasm.c BFA State machine utility functions
+ */
+
+#include <cs/bfa_sm.h>
+
+/**
+ * cs_sm_api
+ */
+
+int
+bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm)
+{
+ int i = 0;
+
+ while (smt[i].sm && smt[i].sm != sm)
+ i++;
+ return smt[i].state;
+}
+
+
diff -ruP net-next-2.6-orig/drivers/net/bna/bna_if.c net-next-2.6-mod/drivers/net/bna/bna_if.c
--- net-next-2.6-orig/drivers/net/bna/bna_if.c 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bna_if.c 2009-10-31 21:34:47.865537000 -0700
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2007-2008 Brocade Communications Systems, Inc.
+ * All rights reserved.
+ *
+ * file bna_if.c BNA Hardware and Firmware Interface
+ */
+#include <bna_os.h>
+#include "bna.h"
+#include "bna_hwreg.h"
+#include "bna_priv.h"
+#include "bna_iocll.h"
+#include "bna_intr.h"
+#include <bfi/bfi_cee.h>
+#include <protocol/types.h>
+#include <cee/bfa_cee.h>
+
+
+
+
+#define BNA_FLASH_DMA_BUF_SZ 0x010000 /* 64K */
+
+#define DO_CALLBACK(cbfn) \
+do { \
+ if (mb_cbfns->cbfn) { \
+ if (qe && qe->cbarg) { \
+ (mb_cbfns->cbfn)(qe->cbarg, status); \
+ } else { \
+ (mb_cbfns->cbfn)(dev->cbarg, status); \
+ } \
+ } \
+} while (0)
+
+#define DO_DIAG_CALLBACK(cbfn, data) \
+do { \
+ if (mb_cbfns->cbfn) { \
+ if (qe && qe->cbarg) { \
+ (mb_cbfns->cbfn)(qe->cbarg, data, status); \
+ } else { \
+ (mb_cbfns->cbfn)(dev->cbarg, data, status); \
+ } \
+ } \
+} while (0)
+
+#define bna_mbox_q_is_empty(mb_q) \
+ ((mb_q)->producer_index == \
+ (mb_q)->consumer_index)
+
+#define bna_mbox_q_first(mb_q) \
+ (&(mb_q)->mb_qe[(mb_q)->consumer_index])
+
+/* FIXME : Should come from the driver */
+static u32 bna_ioc_auto_recover;
+
+/**
+ * bna_register_callback()
+ *
+ * Function called by the driver to register a callback
+ * with the BNA
+ *
+ * @param[in] bna_dev - Opaque handle to BNA private device
+ * @param[in] cbfns - Structure for the callback functions.
+ * @param[in] cbarg - Argument to use with the callback
+ * @param[in] cmd_code - Command code exported to the drivers
+ *
+ * @return void
+ */
+void bna_register_callback(struct bna_dev_s *dev, struct bna_mbox_cbfn *cbfns,
+ void *cbarg)
+{
+ bna_os_memcpy(&dev->mb_cbfns, cbfns, sizeof(dev->mb_cbfns));
+ dev->cbarg = cbarg;
+}
+
+void
+bna_mbox_q_init(struct bna_mbox_q *q)
+{
+ BNA_ASSERT(BNA_POWER_OF_2(BNA_MAX_MBOX_CMD_QUEUE));
+
+ q->producer_index = q->consumer_index = 0;
+ q->posted = NULL;
+}
+
+static struct bna_mbox_cmd_qe *
+bna_mbox_enq(struct bna_mbox_q *mbox_q,
+ void *cmd, u32 cmd_len, void *cbarg) {
+ struct bna_mbox_cmd_qe *qe;
+
+ if (!BNA_QE_FREE_CNT(mbox_q, BNA_MAX_MBOX_CMD_QUEUE)) {
+ DPRINTK(WARNING, "No free Mbox Command Element\n");
+ return NULL;
+ }
+
+ DPRINTK(DEBUG, "Mbox PI 0x%x\n", mbox_q->producer_index);
+
+ qe = &mbox_q->mb_qe[mbox_q->producer_index];
+ BNA_QE_INDX_ADD(mbox_q->producer_index, 1,
+ BNA_MAX_MBOX_CMD_QUEUE);
+ bna_os_memcpy(&qe->cmd.msg[0], cmd, cmd_len);
+ qe->cmd_len = cmd_len;
+ qe->cbarg = cbarg;
+
+ return qe;
+}
+
+static void
+bna_mbox_deq(struct bna_mbox_q *mbox_q)
+{
+
+ DPRINTK(DEBUG, "Mbox CI 0x%x\n", mbox_q->consumer_index);
+
+ /* Free one from the head */
+ BNA_QE_INDX_ADD(mbox_q->consumer_index, 1,
+ BNA_MAX_MBOX_CMD_QUEUE);
+}
+
+static void
+bna_do_stats_update(struct bna_dev_s *dev, u8 status)
+{
+ if (status != BFI_LL_CMD_OK)
+ return;
+ bna_stats_process(dev);
+}
+
+static void
+bna_do_drv_ll_cb(struct bna_dev_s *dev, u8 cmd_code,
+ u8 status, struct bna_mbox_cmd_qe *qe)
+{
+ struct bna_mbox_cbfn *mb_cbfns = &dev->mb_cbfns;
+
+ switch (cmd_code) {
+ case BFI_LL_I2H_MAC_UCAST_SET_RSP:
+ DO_CALLBACK(ucast_set_cb);
+ break;
+ case BFI_LL_I2H_MAC_UCAST_ADD_RSP:
+ DO_CALLBACK(ucast_add_cb);
+ break;
+ case BFI_LL_I2H_MAC_UCAST_DEL_RSP:
+ DO_CALLBACK(ucast_del_cb);
+ break;
+ case BFI_LL_I2H_MAC_MCAST_ADD_RSP:
+ DO_CALLBACK(mcast_add_cb);
+ break;
+ case BFI_LL_I2H_MAC_MCAST_DEL_RSP:
+ DO_CALLBACK(mcast_del_cb);
+ break;
+ case BFI_LL_I2H_MAC_MCAST_FILTER_RSP:
+ DO_CALLBACK(mcast_filter_cb);
+ break;
+ case BFI_LL_I2H_MAC_MCAST_DEL_ALL_RSP:
+ DO_CALLBACK(mcast_del_all_cb);
+ break;
+ case BFI_LL_I2H_RXF_PROMISCUOUS_SET_RSP:
+ DO_CALLBACK(set_promisc_cb);
+ break;
+ case BFI_LL_I2H_RXF_DEFAULT_SET_RSP:
+ DO_CALLBACK(set_default_cb);
+ break;
+ case BFI_LL_I2H_TXQ_STOP_RSP:
+ DO_CALLBACK(txq_stop_cb);
+ break;
+ case BFI_LL_I2H_RXQ_STOP_RSP:
+ DO_CALLBACK(rxq_stop_cb);
+ break;
+ case BFI_LL_I2H_PORT_ADMIN_RSP:
+ DO_CALLBACK(port_admin_cb);
+ break;
+ case BFI_LL_I2H_STATS_GET_RSP:
+ bna_do_stats_update(dev, status);
+ DO_CALLBACK(stats_get_cb);
+ break;
+ case BFI_LL_I2H_STATS_CLEAR_RSP:
+ DO_CALLBACK(stats_clr_cb);
+ break;
+ case BFI_LL_I2H_LINK_DOWN_AEN:
+ DO_CALLBACK(link_down_cb);
+ break;
+ case BFI_LL_I2H_LINK_UP_AEN:
+ DO_CALLBACK(link_up_cb);
+ break;
+ case BFI_LL_I2H_DIAG_LOOPBACK_RSP:
+ DO_CALLBACK(set_diag_lb_cb);
+ break;
+ case BFI_LL_I2H_SET_PAUSE_RSP:
+ DO_CALLBACK(set_pause_cb);
+ break;
+ case BFI_LL_I2H_MTU_INFO_RSP:
+ DO_CALLBACK(mtu_info_cb);
+ break;
+ case BFI_LL_I2H_RX_RSP:
+ DO_CALLBACK(rxf_cb);
+ break;
+ case BFI_LL_I2H_CEE_DOWN_AEN:
+ break;
+ case BFI_LL_I2H_CEE_UP_AEN:
+ break;
+ default:
+ DPRINTK(WARNING, "cb(): unknown msg Id %d for LL class\n",
+ cmd_code);
+ break;
+ }
+}
+
+
+static enum bna_status_e
+bna_flush_mbox_q(struct bna_dev_s *dev, u8 wait_for_rsp)
+{
+ struct bna_mbox_q *q;
+ struct bna_mbox_cmd_qe *qe = NULL;
+ u8 msg_id = 0, msg_class = 0;
+
+ q = &dev->mbox_q;
+
+ if (bna_mbox_q_is_empty(q))
+ return BNA_OK;
+ if (q->posted != NULL && wait_for_rsp) {
+ qe = (struct bna_mbox_cmd_qe *)(q->posted);
+ /* The driver has to retry */
+ return BNA_BUSY;
+ }
+
+ while (!bna_mbox_q_is_empty(q)) {
+ qe = bna_mbox_q_first(q);
+ msg_class = ((struct bfi_mhdr_s *)(&qe->cmd.msg[0]))->msg_class;
+ msg_id = ((struct bfi_mhdr_s *)(&qe->cmd.msg[0]))->msg_id;
+
+
+ BNA_ASSERT(msg_class == BFI_MC_LL);
+
+ bna_do_drv_ll_cb(dev, BFA_I2HM(msg_id),
+ BFI_LL_CMD_NOT_EXEC, qe);
+ bna_mbox_deq(q);
+ }
+ /* Reinit the queue, i.e prod = cons = 0; */
+ bna_mbox_q_init(q);
+ return BNA_OK;
+}
+
+enum bna_status_e
+bna_cleanup(void *bna_dev)
+{
+ struct bna_dev_s *dev = (struct bna_dev_s *)bna_dev;
+
+ dev->msg_ctr = 0;
+
+ return bna_flush_mbox_q(dev, 0);
+}
+
+/**
+ * Check both command queues
+ * Write to mailbox if required
+ */
+static enum bna_status_e
+bna_chk_n_snd_q(struct bna_dev_s *dev)
+{
+ struct bna_mbox_cmd_qe *qe = NULL;
+ struct bna_mbox_q *q;
+ struct bfi_mhdr_s *mh = NULL;
+
+ q = &dev->mbox_q;
+
+ if ((bna_mbox_q_is_empty(q)) || (q->posted != NULL))
+ return BNA_OK;
+
+ qe = bna_mbox_q_first(q);
+ /* Do not post any more commands if disable pending */
+ if (dev->ioc_disable_pending == 1)
+ return BNA_OK;
+
+ mh = ((struct bfi_mhdr_s *)(&qe->cmd.msg[0]));
+ mh->mtag.i2htok = bna_os_htons(dev->msg_ctr);
+ dev->msg_ctr++;
+ bfa_ioc_mbox_queue(&dev->ioc, &qe->cmd);
+ q->posted = qe;
+
+ return BNA_OK;
+}
+
+enum bna_status_e
+bna_mbox_send(struct bna_dev_s *dev, void *cmd, u32 cmd_len,
+ void *cbarg)
+{
+ struct bna_mbox_cmd_qe *qe;
+ struct bna_mbox_q *q;
+
+ BNA_ASSERT(cmd_len <= BNA_MAX_MBOX_CMD_LEN);
+
+ if (dev->ioc_disable_pending) {
+ DPRINTK(WARNING,
+ "IOC Disable is pending :"
+ "Cannot queue Cmd class %d id %d\n",
+ mh->msg_class, mh->msg_id);
+ return BNA_FAIL;
+ }
+
+ if (!bfa_ioc_is_operational(&dev->ioc)) {
+ DPRINTK(ERR,
+ "IOC is not operational :"
+ "Cannot queue Cmd class %d id %d\n",
+ mh->msg_class, mh->msg_id);
+ return BNA_FAIL;
+ }
+
+ q = &dev->mbox_q;
+ qe = bna_mbox_enq(q, cmd, cmd_len, cbarg);
+ if (qe == NULL)
+ return BNA_FAIL;
+ return bna_chk_n_snd_q(dev);
+}
+
+
+/**
+ * Returns 1, if this is an aen, 0 otherwise
+ */
+static int
+bna_is_aen(u8 msg_id)
+{
+ return
+ (msg_id == BFI_LL_I2H_LINK_DOWN_AEN ||
+ msg_id == BFI_LL_I2H_LINK_UP_AEN ||
+ msg_id == BFI_LL_I2H_CEE_DOWN_AEN ||
+ msg_id == BFI_LL_I2H_CEE_UP_AEN);
+}
+
+static void
+bna_err_handler(struct bna_dev_s *dev, u32 intr_status)
+{
+ u32 curr_mask;
+
+ DPRINTK(DEBUG, "HW ERROR : INT statux 0x%x on port %d\n",
+ intr_status, dev->port);
+
+ bfa_ioc_error_isr(&dev->ioc);
+
+ /*
+ * Disable all the bits in interrupt mask, including
+ * the mbox & error bits.
+ * This is required so that once h/w error hits, we don't
+ * get into a loop.
+ */
+ bna_intx_disable(dev, &curr_mask);
+
+ if (dev->mb_cbfns.hw_error_cb)
+ (dev->mb_cbfns.hw_error_cb)(dev->cbarg, 0);
+}
+
+void
+bna_ll_isr(void *llarg, struct bfi_mbmsg_s *msg)
+{
+ u32 aen = 0;
+ struct bna_dev_s *dev = (struct bna_dev_s *)llarg;
+ struct bna_mbox_cmd_qe *qe = NULL;
+ struct bna_mbox_q *mbox_q = NULL;
+ struct bfi_ll_rsp *mb_rsp = NULL;
+
+ mb_rsp = (struct bfi_ll_rsp *)(msg);
+
+ BNA_ASSERT(mb_rsp->mh.msg_class == BFI_MC_LL);
+
+ aen = bna_is_aen(mb_rsp->mh.msg_id);
+ if (!aen) {
+ mbox_q = &dev->mbox_q;
+
+ BNA_ASSERT(!bna_mbox_q_is_empty(mbox_q));
+ qe = bna_mbox_q_first(mbox_q);
+ BNA_ASSERT(mbox_q->posted == qe);
+
+ if (BFA_I2HM(((struct bfi_mhdr_s *)
+ (&qe->cmd.msg[0]))->msg_id) != mb_rsp->mh.msg_id) {
+ DPRINTK(ERR,
+ "Invalid Rsp Msg %d:%d (Expected %d:%d) on %d\n",
+ mb_rsp->mh.msg_class, mb_rsp->mh.msg_id,
+ ((struct bfi_mhdr_s *)(&qe->cmd.msg[0]))->msg_class,
+ BFA_I2HM(((struct bfi_mhdr_s *)
+ (&qe->cmd.msg[0]))->msg_id),
+ dev->port);
+ BNA_ASSERT(0);
+ return;
+ }
+ bna_mbox_deq(mbox_q);
+ mbox_q->posted = NULL;
+ }
+ bna_do_drv_ll_cb(dev, mb_rsp->mh.msg_id, mb_rsp->error, qe);
+ bna_chk_n_snd_q(dev);
+}
+
+
+void
+bna_mbox_err_handler(struct bna_dev_s *dev, u32 intr_status)
+{
+ if (BNA_IS_ERR_INTR(intr_status)) {
+ bna_err_handler(dev, intr_status);
+ return;
+ }
+
+ if (BNA_IS_MBOX_INTR(intr_status))
+ bfa_ioc_mbox_isr(&dev->ioc);
+}
+
+/**
+ * bna_port_admin()
+ *
+ * Enable (up) or disable (down) the interface administratively.
+ *
+ * @param[in] dev - pointer to BNA device structure
+ * @param[in] enable - enable/disable the interface.
+ *
+ * @return BNA_OK or BNA_FAIL
+ */
+enum bna_status_e
+bna_port_admin(struct bna_dev_s *bna_dev, enum bna_enable_e enable)
+{
+ struct bna_dev_s *dev = (struct bna_dev_s *)bna_dev;
+ struct bfi_ll_port_admin_req ll_req;
+
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
+ ll_req.mh.mtag.i2htok = 0;
+
+ ll_req.up = enable;
+
+ /* send to f/w */
+ return bna_mbox_send(dev, &ll_req, sizeof(ll_req), dev->cbarg);
+}
+/**
+ * bna_port_param_get()
+ *
+ * Get the port parameters.
+ *
+ * @param[in] dev - pointer to BNA device structure
+ * @param[out] param_ptr - pointer to where the parameters will be returned.
+ *
+ * @return void
+ */
+void
+bna_port_param_get(struct bna_dev_s *dev, struct bna_port_param *param_ptr)
+{
+ param_ptr->supported = BNA_TRUE;
+ param_ptr->advertising = BNA_TRUE;
+ param_ptr->speed = BNA_LINK_SPEED_10Gbps;
+ param_ptr->duplex = BNA_TRUE;
+ param_ptr->autoneg = BNA_FALSE;
+ param_ptr->port = dev->port;
+}
+
+/**
+ * bna_port_mac_get()
+ *
+ * Get the Burnt-in or permanent MAC address. This function does not return
+ * the MAC set thru bna_rxf_ucast_mac_set() but the one that is assigned to
+ * the port upon reset.
+ *
+ * @param[in] dev - pointer to BNA device structure
+ * @param[out] mac_ptr - Burnt-in or permanent MAC address.
+ *
+ * @return void
+ */
+void
+bna_port_mac_get(struct bna_dev_s *bna_dev, u8 *mac_ptr)
+{
+ struct bna_dev_s *dev = (struct bna_dev_s *)bna_dev;
+ mac_t mac;
+
+ mac = bfa_ioc_get_mac(&dev->ioc);
+
+ /* TODO : Use mac_t, remove memcpy */
+ bna_os_memcpy(mac_ptr, &mac, sizeof(mac_t));
+}
+
+/**
+ * IOC Integration
+ */
+
+/**
+ * bfa_iocll_cbfn
+ * Structure for callbacks to be implemented by
+ * the driver.
+ */
+static struct bfa_ioc_cbfn_s bfa_iocll_cbfn = {
+ bna_iocll_enable_cbfn,
+ bna_iocll_disable_cbfn,
+ bna_iocll_hbfail_cbfn,
+ bna_iocll_reset_cbfn
+};
+
+
+static void
+bna_iocll_memclaim(struct bna_dev_s *dev, struct bna_meminfo *mi)
+{
+
+ bfa_ioc_mem_claim(&dev->ioc, mi[BNA_DMA_MEM_T_ATTR].kva,
+ mi[BNA_DMA_MEM_T_ATTR].dma);
+
+ if (bna_ioc_auto_recover)
+ bfa_ioc_debug_memclaim(&dev->ioc,
+ mi[BNA_KVA_MEM_T_FWTRC].kva);
+}
+
+void
+bna_iocll_meminfo(struct bna_dev_s *dev, struct bna_meminfo *mi)
+{
+
+
+ mi[BNA_DMA_MEM_T_ATTR].len =
+ BNA_ALIGN(bfa_ioc_meminfo(), BNA_PAGE_SIZE);
+
+ mi[BNA_KVA_MEM_T_FWTRC].len =
+ bfa_ioc_debug_trcsz(bna_ioc_auto_recover);
+}
+
+void
+bna_iocll_attach(struct bna_dev_s *dev, void *bnad, struct bna_meminfo *meminfo,
+ struct bfa_pcidev_s *pcidev, struct bfa_trc_mod_s *trcmod,
+ struct bfa_aen_s *aen, struct bfa_log_mod_s *logm)
+{
+ bfa_ioc_attach(&dev->ioc, bnad, &bfa_iocll_cbfn, &dev->timer_mod,
+ trcmod, aen, logm);
+ bfa_ioc_pci_init(&dev->ioc, pcidev, BFI_MC_LL);
+
+ bfa_ioc_mbox_regisr(&dev->ioc, BFI_MC_LL, bna_ll_isr, dev);
+ bna_iocll_memclaim(dev, meminfo);
+
+
+ bfa_timer_init(&dev->timer_mod);
+
+}
+
+/**
+ * FIXME :
+ * Either the driver or CAL should serialize
+ * this IOC disable
+ * Currently this is happening indirectly b'cos
+ * bfa_ioc_disable() is not called if there
+ * is an outstanding cmd in the queue, which
+ * could not be flushed.
+ */
+enum bna_status_e
+bna_iocll_disable(struct bna_dev_s *dev)
+{
+ enum bna_status_e ret;
+
+ dev->ioc_disable_pending = 1;
+ ret = bna_flush_mbox_q(dev, 1);
+ if (ret != BNA_OK) {
+ DPRINTK(WARNING, "Unable to flush Mbox Queues [%d]\n", ret);
+ return ret;
+ }
+
+ bfa_ioc_disable(&dev->ioc);
+ dev->ioc_disable_pending = 0;
+
+ return BNA_OK;
+}
+
+void
+bna_iocll_getinfo(struct bna_dev_s *dev, char *serial_num, u32 size)
+{
+ struct bfa_adapter_attr_s ad_attr;
+ u32 length;
+
+ bfa_ioc_get_adapter_attr(&dev->ioc, &ad_attr);
+ length = BNA_MIN(size, sizeof(ad_attr.serial_num));
+ bna_os_memcpy(serial_num, ad_attr.serial_num, length);
+}
+
+/* Dummy */
+/* FIXME : Delete once bfa_diag.c is fixed */
+void
+bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+ bfa_boolean_t link_e2e_beacon)
+{
+}
+
diff -ruP net-next-2.6-orig/drivers/net/bna/bna_iocll.h net-next-2.6-mod/drivers/net/bna/bna_iocll.h
--- net-next-2.6-orig/drivers/net/bna/bna_iocll.h 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bna_iocll.h 2009-10-31 21:34:47.872532000 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See LICENSE.bna for copyright and licensing details.
+ */
+
+#ifndef __BNA_IOCLL_H__
+#define __BNA_IOCLL_H__
+
+#include <bfa_ioc.h>
+#include <bfa_timer.h>
+#include <bfi/bfi_ll.h>
+
+#define BNA_IOC_TIMER_PERIOD BFA_TIMER_FREQ /* 200 ms */
+
+/*
+ * LL specific IOC functions.
+ */
+void bna_iocll_meminfo(struct bna_dev_s *bna_dev, struct bna_meminfo *meminfo);
+void bna_iocll_attach(struct bna_dev_s *bna_dev, void *bnad,
+ struct bna_meminfo *meminfo, struct bfa_pcidev_s *pcidev,
+ struct bfa_trc_mod_s *trcmod, struct bfa_aen_s *aen,
+ struct bfa_log_mod_s *logmod);
+enum bna_status_e bna_iocll_disable(struct bna_dev_s *bna_dev);
+void bna_iocll_getinfo(struct bna_dev_s *bna_dev, char *serial_num, u32 size);
+#define bna_iocll_detach(dev) bfa_ioc_detach(&((dev)->ioc))
+#define bna_iocll_enable(dev) bfa_ioc_enable(&((dev)->ioc))
+#define bna_iocll_debug_fwsave(dev, trc_data, trc_len) \
+ bfa_ioc_debug_fwsave(&((dev)->ioc), (trc_data), (trc_len))
+#define bna_iocll_debug_fwtrc(dev, trc_data, trc_len) \
+ bfa_ioc_debug_fwtrc(&((dev)->ioc), (trc_data), (trc_len))
+#define bna_iocll_timer(dev) bfa_timer_beat(&((dev)->timer_mod))
+#define bna_iocll_getstats(dev, ioc_stats) \
+ bfa_ioc_fetch_stats(&((dev)->ioc), (ioc_stats))
+#define bna_iocll_resetstats(dev) bfa_ioc_clr_stats(&((dev)->ioc))
+#define bna_iocll_getattr(dev, ioc_attr) \
+ bfa_ioc_get_attr(&((dev)->ioc), (ioc_attr))
+
+/**
+ * Callback functions to be implemented by the driver
+ */
+void bna_iocll_enable_cbfn(void *bnad, enum bfa_status status);
+void bna_iocll_disable_cbfn(void *bnad);
+void bna_iocll_hbfail_cbfn(void *bnad);
+void bna_iocll_reset_cbfn(void *bnad);
+
+#endif /* __BNA_IOCLL_H__ */
+
diff -ruP net-next-2.6-orig/drivers/net/bna/bna_os.h net-next-2.6-mod/drivers/net/bna/bna_os.h
--- net-next-2.6-orig/drivers/net/bna/bna_os.h 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bna_os.h 2009-10-31 21:34:47.878536000 -0700
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See <license_file> for copyright and licensing details.
+ */
+
+/**
+ * Contains declarations of linux specific calls required for Brocade
+ * FCoE HBA driver implementation. Each OS has to provide this file.
+ */
+
+/**
+ * bna_os.h Linux driver OS specific declarations.
+ */
+
+#ifndef __BNA_OS_H__
+#define __BNA_OS_H__
+
+#ifdef __KERNEL__
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/if_ether.h> /* Hack for ETH_ALEN: Do we care ? */
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/string.h>
+#else
+#include <sys/io.h>
+#endif
+
+#ifdef __KERNEL__
+
+#define BNA_PAGE_SIZE PAGE_SIZE
+#define BNA_PAGE_SHIFT PAGE_SHIFT
+
+#define BNA_ERR KERN_ERR
+#define BNA_WARNING KERN_WARNING
+#define BNA_NOTICE KERN_NOTICE
+#define BNA_INFO KERN_INFO
+#define BNA_DEBUG KERN_DEBUG
+
+
+#ifdef DEBUG
+
+#define PFX "BNA: "
+#define DPRINTK(klevel, fmt, args...) do { \
+ printk(KERN_##klevel PFX fmt, \
+ ## args); \
+} while (0)
+
+#ifdef BNA_ASSERT_PRINTK_ONLY
+#define BNA_ASSERT(p) do { \
+ if (!(p)) \
+ printk(KERN_ERR "assert(%s) failed at %s:%d\n", \
+ #p, __FILE__, __LINE__); \
+} while (0)
+#else
+#define BNA_ASSERT(p) do { \
+ if (!(p)) { \
+ printk(KERN_ERR "assert(%s) failed at %s:%d\n", \
+ #p, __FILE__, __LINE__); \
+ BUG(); \
+ } \
+} while (0)
+#endif
+
+#ifndef BNA_DEV_PRINTF
+#define BNA_DEV_PRINTF(bnad, level, fmt, arg...) \
+ dev_printk(level, &(((bnad_t *)(bnad)) \
+ ->pcidev->dev), fmt, ##arg);
+#endif
+
+#define BNA_PRINTF(level, fmt, arg...) \
+ printk(level fmt, ##arg);
+
+#else /* DEBUG */
+
+#define BNA_ASSERT(p)
+#define BNA_DEV_PRINTF(bnad, level, fmt, arg...)
+#define BNA_PRINTF(level, fmt, arg...)
+
+#define DPRINTK(klevel, fmt, args...) do { \
+ } while (0)
+
+#endif /* !DEBUG */
+
+#else /* __KERNEL__ */
+
+#define BNA_ASSERT(p)
+
+#endif /* !__KERNEL__ */
+
+#define bna_os_swap_3b(_x) \
+ ((((_x) & 0xff) << 16) | \
+ ((_x) & 0x00ff00) | \
+ (((_x) & 0xff0000) >> 16))
+
+#define bna_os_swap_8b(_x) \
+ ((((_x) & 0xff00000000000000ull) >> 56) \
+ | (((_x) & 0x00ff000000000000ull) >> 40) \
+ | (((_x) & 0x0000ff0000000000ull) >> 24) \
+ | (((_x) & 0x000000ff00000000ull) >> 8) \
+ | (((_x) & 0x00000000ff000000ull) << 8) \
+ | (((_x) & 0x0000000000ff0000ull) << 24) \
+ | (((_x) & 0x000000000000ff00ull) << 40) \
+ | (((_x) & 0x00000000000000ffull) << 56))
+
+#define bna_os_swap32(_x) \
+ ((((_x) & 0xff) << 24) | \
+ (((_x) & 0x0000ff00) << 8) | \
+ (((_x) & 0x00ff0000) >> 8) | \
+ (((_x) & 0xff000000) >> 24))
+
+
+#ifndef __BIGENDIAN
+#define bna_os_htons(_x) ((u16)((((_x) & 0xff00) >> 8) | \
+ (((_x) & 0x00ff) << 8)))
+
+#define bna_os_htonl(_x) bna_os_swap32(_x)
+#define bna_os_htonll(_x) bna_os_swap_8b(_x)
+
+#define bna_os_wtole(_x) (_x)
+#define bna_os_wtobe(_x) bna_os_swap32(_x)
+
+#define bna_os_dma_addr64(_x) bna_os_swap_8b(_x)
+
+#else
+
+#define bna_os_htons(_x) (_x)
+#define bna_os_htonl(_x) (_x)
+#define bna_os_htonll(_x) (_x)
+
+#define bna_os_wtole(_x) bna_os_swap32(_x)
+#define bna_os_wtobe(_x) (_x)
+
+#define bna_os_dma_addr64(_x) (_x)
+
+#endif
+
+#define bna_os_ntohs(_x) bna_os_htons(_x)
+#define bna_os_ntohl(_x) bna_os_htonl(_x)
+#define bna_os_ntohll(_x) bna_os_htonll(_x)
+#define bna_os_ntoh3b(_x) bna_os_hton3b(_x)
+
+#define bna_os_memset memset
+#define bna_os_memcpy memcpy
+#define bna_os_udelay udelay
+#define bna_os_vsprintf vsprintf
+
+#define bna_os_reg_read(_raddr) readl(_raddr)
+#define bna_os_reg_write(_raddr, _val) writel(_val, _raddr)
+#define bna_os_mem_read(_raddr, _off) \
+ bna_os_ntohl(((u32 *)_raddr)[(_off) >> 2])
+#define bna_os_mem_write(_raddr, _off, _val) \
+ (((u32 *)_raddr)[(_off) >> 2]) = bna_os_htonl(_val)
+
+#define bna_os_mem_readw(_raddr) \
+ bna_os_htonl(*((u32 *)(_raddr)))
+#define bna_os_mem_writew(_raddr, _val) \
+ {*((u32 *)(_raddr)) = bna_os_htonl((_val))}
+
+/* Required for DMA address manipulation in IOC */
+#define bfa_os_u32(__pa64) ((__pa64) >> 32)
+
+#endif /* __BNA_OS_H__ */
diff -ruP net-next-2.6-orig/drivers/net/bna/bna_priv.h net-next-2.6-mod/drivers/net/bna/bna_priv.h
--- net-next-2.6-orig/drivers/net/bna/bna_priv.h 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bna_priv.h 2009-10-31 21:34:47.885533000 -0700
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * See <license_file> for copyright and licensing details.
+ */
+
+/**
+ * BNA register access macros.p
+ */
+
+#ifndef __BNA_PRIV_H__
+#define __BNA_PRIV_H__
+
+
+#define bna_mem_read(_raddr, _off) bna_os_mem_read(_raddr, _off)
+#define bna_mem_write(_raddr, _off, _val) \
+ bna_os_mem_write(_raddr, _off, _val)
+
+
+/**
+ Macros to declare a bit table
+ *
+ * @param[in] _table - bit table to be declared
+ * @param[in] _size - size in bits
+ */
+#define BNA_BIT_TABLE_DECLARE(_table, _size) \
+ (u32 _table[(_size) / 32])
+/**
+ Macros to set bits in a bit table
+ *
+ * @param[in] _table - bit table to be declared
+ * @param[in] _bit - bit to be set
+ */
+#define BNA_BIT_TABLE_SET(_table, _bit) \
+ (_table[(_bit) / 32] |= (1 << ((_bit) & (32 - 1))))
+/**
+ Macros to clear bits in a bit table
+ *
+ * @param[in] _table - bit table to be declared
+ * @param[in] _bit - bit to be set
+ */
+#define BNA_BIT_TABLE_CLEAR(_table, _bit) \
+ (_table[(_bit) / 32] &= ~(1 << ((_bit) & (32 - 1))))
+/**
+ Macros to set bits in a 32 bit word
+ *
+ * @param[in] _word - word in which bit is to be set
+ * @param[in] _bit - bit to be set (starting at 0)
+ */
+#define BNA_BIT_WORD_SET(_word, _bit) \
+ ((_word) |= (1 << (_bit)))
+/**
+ Macros to clear bits in a 32 bit word
+ *
+ * @param[in] _word - word in which bit is to be cleared
+ * @param[in] _bit - bit to be cleared (starting at 0)
+ */
+#define BNA_BIT_WORD_CLEAR(_word, _bit) \
+ ((_word) &= ~(1 << (_bit)))
+
+/**
+ * BNA_GET_PAGE_NUM()
+ *
+ * Macro to calculate the page number for the
+ * memory spanning multiple pages.
+ *
+ * @param[in] _base_page - Base Page Number for memory
+ * @param[in] _offset - Offset for which page number
+ * is calculated
+ */
+#define BNA_GET_PAGE_NUM(_base_page, _offset) \
+ ((_base_page) + ((_offset) >> 15))
+/**
+ * BNA_GET_PAGE_OFFSET()
+ *
+ * Macro to calculate the page offset for the
+ * from the base offset (from the top of the block)
+ * Each page 0x8000 (32KB) in size
+ *
+ * @param[in] _offset - Offset from the top of the block
+ */
+#define BNA_GET_PAGE_OFFSET(_offset) \
+ ((_offset) & 0x7fff)
+
+/**
+ * BNA_GET_WORD_OFFSET()
+ *
+ * Macro to calculate the address of a word from
+ * the base address. Needed to access H/W memory
+ * as 4 byte words. Starts from 0.
+ *
+ * @param[in] _base_offset - Starting offset of the data
+ * @param[in] _word - Word no. for which address is calculated
+ */
+#define BNA_GET_WORD_OFFSET(_base_offset, _word) \
+ ((_base_offset) + ((_word) << 2))
+/**
+ * BNA_GET_BYTE_OFFSET()
+ *
+ * Macro to calculate the address of a byte from
+ * the base address. Most of H/W memory is accessed
+ * as 4 byte words, so use this macro carefully.
+ * Starts from 0.
+ *
+ * @param[in] _base_offset - Starting offset of the data
+ * @param[in] _byte - Byte no. for which address is calculated
+ */
+#define BNA_GET_BYTE_OFFSET(_base_offset, _byte) \
+ ((_base_offset) + (_byte))
+
+/**
+ * BNA_GET_MEM_BASE_ADDR()
+ *
+ * Macro to calculate the base address of
+ * any memory block given the bar0 address
+ * and the memory base offset
+ *
+ * @param[in] _bar0 - BARO address
+ * @param[in] _base_offset - Starting offset of the memory
+ */
+#define BNA_GET_MEM_BASE_ADDR(_bar0, _base_offset) \
+ ((_bar0) + HW_BLK_HOST_MEM_ADDR \
+ + BNA_GET_PAGE_OFFSET((_base_offset)))
+
+/**
+ * Structure which maps to Rx FnDb config
+ * Size : 4 words
+ * See catapult_spec.pdf, RxA for details
+ */
+struct bna_rx_fndb_ram {
+ u32 rss_prop;
+ u32 size_routing_props;
+ u32 rit_hds_mcastq;
+ u32 control_flags;
+};
+
+/**
+ * Structure which maps to Tx FnDb config
+ * Size : 1 word
+ * See catapult_spec.pdf, TxA for details
+ */
+struct bna_tx_fndb_ram {
+ u32 vlan_n_ctrl_flags;
+};
+
+/**
+ * Structure which maps to Unicast/Multicast CAM entry
+ * Size : 2 words
+ * See catapult_spec.pdf, LUT for details
+ */
+struct bna_cam {
+ u32 cam_mac_addr_47_32; /* 31:16->res;15:0->MAC */
+ u32 cam_mac_addr_31_0;
+};
+
+/**
+ * Structure which maps to Unicast RAM entry
+ * Size : 1 word
+ * See catapult_spec.pdf, LUT for details
+ */
+struct bna_ucast_mem {
+ u32 ucast_ram_entry;
+};
+
+/**
+ * Structure which maps to VLAN RAM entry
+ * Size : 1 word ?? Need to verify
+ * See catapult_spec.pdf, LUT for details
+ */
+struct bna_vlan_mem {
+ u32 vlan_ram_entry; /* FIXME */
+};
+#define BNA_GET_VLAN_MEM_ENTRY_ADDR(_bar0, _fn_id, _vlan_id)\
+ (_bar0 + (HW_BLK_HOST_MEM_ADDR) \
+ + (BNA_GET_PAGE_OFFSET(VLAN_RAM_BASE_OFFSET)) \
+ + (((_fn_id) & 0x3f) << 9) \
+ + (((_vlan_id) & 0xfe0) >> 3))
+
+/**
+ * Structure which maps to exact/approx MVT RAM entry
+ * Size : 4 words
+ * See catapult_spec.pdf, RxA for details
+ */
+struct bna_mvt_mem {
+ u32 reserved;
+ u32 fc_bit; /* 31:1->res;0->fc_bit */
+ u32 ll_fn_63_32; /* LL fns 63 to 32 */
+ u32 ll_fn_31_0; /* LL fns 31 to 0 */
+};
+
+/**
+ * Structure which maps to RxFn Indirection Table (RIT)
+ * Size : 1 word
+ * See catapult_spec.pdf, RxA for details
+ */
+struct bna_rit_mem {
+ u32 rxq_ids; /* 31:12->res;11:0->two 6 bit RxQ Ids */
+};
+
+/**
+ * Structure which maps to RSS Table entry
+ * Size : 16 words
+ * See catapult_spec.pdf, RAD for details
+ */
+struct bna_rss_mem {
+ u32 type_n_hash; /* 31:12->res;
+ 11:8 ->protocol type
+ 7:0 ->hash index */
+ u32 hash_key[10]; /* 40 byte Toeplitz hash key */
+ u32 reserved[5];
+};
+
+/**
+ * Structure which maps to RxQ Memory entry
+ * Size : 16 words, entries are 32 words apart
+ * Alternate arrangement of RxQ & TxQ
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_rxq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+#if 0
+ u32 nxt_pg_addr_lo;
+ u32 nxt_pg_addr_hi;
+#endif
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr;/* 31:16->total page count
+ 15:0 ->producer pointer (index?)*/
+ u32 entry_n_pg_size; /* 31:16->entry size
+ 15:0 ->page size */
+ u32 sg_n_cq_n_cns_ptr; /* 31:28->reserved; 27:24->sg count
+ 23:16->CQ; 15:0->consumer pointer(index?) */
+ u32 buf_sz_n_q_state; /* 31:16->buffer size; 15:0-> Q state */
+ u32 next_qid; /* 17:10->next QId */
+ u32 reserved3;
+ u32 reserved4[4];
+};
+
+
+/**
+ * Structure which maps to TxQ Memory entry
+ * Size : 16 words, entries are 32 words apart
+ * Alternate arrangement of RxQ & TxQ
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_txq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+#if 0 /* obsolete, now replaced by reserved fields */
+ u32 nxt_pg_addr_lo
+ u32 nxt_pg_addr_hi;
+#endif
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr;/* 31:16->total page count
+ 15:0 ->producer pointer (index?)*/
+ u32 entry_n_pg_size; /* 31:16->entry size
+ 15:0 ->page size */
+ u32 int_blk_n_cns_ptr;/* 31:24->Int Blk Id; 23:16->Int Blk Offset
+ 15:0 ->consumer pointer(index?) */
+ u32 cns_ptr2_n_q_state;/* 31:16->cons. ptr 2; 15:0-> Q state */
+ u32 nxt_qid_n_fid_n_pri;/* 17:10->next QId;9:3->FID;2:0->Priority */
+ u32 wvc_n_cquota_n_rquota; /* 31:24->WI Vector Count;
+ 23:12->Cfg Quota;
+ 11:0 ->Run Quota */
+ u32 reserved3[4];
+};
+
+/**
+ * Structure which maps to RxQ and TxQ Memory entry
+ * Size : 32 words, entries are 32 words apart
+ * Alternate arrangement of RxQ & TxQ
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_rxtx_q_mem {
+ struct bna_rxq_mem rxq;
+ struct bna_txq_mem txq;
+};
+
+/**
+ * Structure which maps to CQ Memory entry
+ * Size : 16 words
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_cq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+#if 0
+ u32 nxt_pg_addr_lo;
+ u32 nxt_pg_addr_hi;
+#endif
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr;/* 31:16->total page count
+ 15:0 ->producer pointer (index?)*/
+ u32 entry_n_pg_size; /* 31:16->entry size
+ 15:0 ->page size */
+ u32 int_blk_n_cns_ptr;/* 31:24->Int Blk Id; 23:16->Int Blk Offset
+ 15:0 ->consumer pointer(index?) */
+ u32 q_state; /* 31:16->reserved; 15:0-> Q state */
+ u32 reserved3[2];
+ u32 reserved4[4];
+};
+
+/**
+ * Structure which maps to Interrupt Block Memory entry
+ * Size : 8 words (used: 5 words)
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_ib_blk_mem {
+ u32 host_addr_lo;
+ u32 host_addr_hi;
+ u32 clsc_n_ctrl_n_msix;/* 31:24->coalescing;
+ 23:16->coalescing cfg;
+ 15:8 ->control;
+ 7:0 ->msix; */
+ u32 ipkt_n_ent_n_idxof;
+ u32 ipkt_cnt_cfg_n_unacked;
+
+ u32 reserved[3];
+};
+
+/**
+ * Structure which maps to Index Table Block Memory entry
+ * Size : 1 word
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_idx_tbl_mem {
+ u32 idx; /* 31:16->res;15:0->idx; */
+};
+
+/**
+ * Structure which maps to Doorbell QSet Memory,
+ * Organization of Doorbell address space for a
+ * QSet (RxQ, TxQ, Rx IB, Tx IB)
+ * For Non-VM qset entries are back to back.
+ * Size : 128 bytes / 4K bytes for Non-VM / VM
+ * See catapult_spec.pdf, HQM for details
+ */
+struct bna_doorbell_qset {
+ u32 rxq[0x20 >> 2];
+ u32 txq[0x20 >> 2];
+ u32 ib0[0x20 >> 2];
+ u32 ib1[0x20 >> 2];
+};
+
+
+#define BNA_GET_DOORBELL_BASE_ADDR(_bar0) \
+ ((_bar0) + HQM_DOORBELL_BLK_BASE_ADDR)
+
+
+/**
+ * BNA_GET_DOORBELL_ENTRY_OFFSET()
+ *
+ * Macro to calculate the offset of the Doorbell QSet
+ * in the Non VM case.
+ * Entries are 128 bytes apart. Does not need a page
+ * number register for access.
+ *
+ * @param[in] _entry - Entry Number
+ */
+#define BNA_GET_DOORBELL_ENTRY_OFFSET(_entry) \
+ ((HQM_DOORBELL_BLK_BASE_ADDR) \
+ + (_entry << 7))
+/**
+ * BNA_GET_DOORBELL_VM_ENTRY_OFFSET()
+ *
+ * Macro to calculate the offset of the Doorbell QSet
+ * in the VM case.
+ * Entries are 4K (0x1000) bytes apart.
+ * Does not need a page number register for access.
+ *
+ * @param[in] _entry - Entry Number
+ */
+#define BNA_GET_DOORBELL_VM_ENTRY_OFFSET(_entry) \
+ ((HQM_DOORBELL_VM_BLK_BASE_ADDR) \
+ + (_entry << 12))
+
+/**
+ * BNA_GET_PSS_SMEM_PAGE_NUM()
+ *
+ * Macro to calculate the page number of PSS SMEM
+ * block from a linear offset
+ *
+ * @param[in] _loff - Linear offset from the top of memory
+ */
+#define BNA_GET_PSS_SMEM_PAGE_NUM(_loff) \
+ (BNA_GET_PAGE_NUM(PSS_SMEM_BLK_PG_NUM, (_loff)))
+/**
+ * BNA_GET_PSS_SMEM_PAGE_OFFSET()
+ *
+ * Macro to calculate the page offset from the top
+ * of a PSS SMEM page, for a given linear offset
+ *
+ * @param[in] _loff - Linear offset from the top of memory
+ */
+#define BNA_GET_PSS_SMEM_PAGE_OFFSET(_loff) \
+ (PSS_SMEM_BLK_MEM_ADDR \
+ + BNA_GET_PAGE_OFFSET((_loff)))
+
+/**
+ * BNA_GET_MBOX_PAGE_NUM()
+ *
+ * Macro to calculate the page number of HostFn<->LPU/
+ * LPU<->HostFn Mailbox block from a linear offset
+ *
+ * @param[in] _loff - Linear offset from the top of memory
+ */
+#define BNA_GET_MBOX_PAGE_NUM(_loff) \
+ (BNA_GET_PAGE_NUM(CPQ_BLK_PG_NUM, (_loff)))
+/**
+ * BNA_GET_HOSTFN_LPU_MBOX_PAGE_OFFSET()
+ *
+ * Macro to calculate the HostFn<->LPU
+ * Mailbox page offset from the linear offset
+ *
+ * @param[in] _loff - Linear offset in bytes from the top of memory
+ */
+#define BNA_GET_HOSTFN_LPU_MBOX_PAGE_OFFSET(_loff) \
+ (HOSTFN_LPU_MBOX + BNA_GET_PAGE_OFFSET((_loff)))
+/**
+ * BNA_GET_LPU_HOSTFN_MBOX_PAGE_OFFSET()
+ *
+ * Macro to calculate the LPU<->HostFn
+ * Mailbox page offset from the linear offset
+ *
+ * @param[in] _loff - Linear offset from the top of memory
+ */
+#define BNA_GET_LPU_HOSTFN_MBOX_PAGE_OFFSET(_loff) \
+ (LPU_HOSTFN_MBOX + BNA_GET_PAGE_OFFSET((_loff)))
+
+
+#define bna_hw_stats_to_stats bna_os_dma_addr64
+
+void bna_mbox_q_init(struct bna_mbox_q *q);
+
+#define BNA_80K_PKT_RATE 80000
+#define BNA_70K_PKT_RATE 70000
+#define BNA_60K_PKT_RATE 60000
+#define BNA_50K_PKT_RATE 50000
+#define BNA_40K_PKT_RATE 40000
+#define BNA_30K_PKT_RATE 30000
+#define BNA_20K_PKT_RATE 20000
+#define BNA_10K_PKT_RATE 10000
+
+/**
+ * Defines are in order of decreasing load
+ * i.e BNA_HIGH_LOAD_3 has the highest load
+ * and BNA_LOW_LOAD_3 has the lowest load.
+ */
+
+#define BNA_HIGH_LOAD_4 0 /* r >= 80 */
+#define BNA_HIGH_LOAD_3 1 /* 60 <= r < 80 */
+#define BNA_HIGH_LOAD_2 2 /* 50 <= r < 60 */
+#define BNA_HIGH_LOAD_1 3 /* 40 <= r < 50 */
+#define BNA_LOW_LOAD_1 4 /* 30 <= r < 40 */
+#define BNA_LOW_LOAD_2 5 /* 20 <= r < 30 */
+#define BNA_LOW_LOAD_3 6 /* 10 <= r < 20 */
+#define BNA_LOW_LOAD_4 7 /* r < 10 K */
+#define BNA_LOAD_TYPES BNA_LOW_LOAD_4
+
+#define BNA_BIAS_TYPES 2 /* small : small > large*2 */
+ /* large : if small is false */
+
+#endif /* __BNA_PRIV_H__ */
diff -ruP net-next-2.6-orig/drivers/net/bna/bnad_compat.h net-next-2.6-mod/drivers/net/bna/bnad_compat.h
--- net-next-2.6-orig/drivers/net/bna/bnad_compat.h 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bnad_compat.h 2009-10-31 21:34:47.892532000 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _BNAD_COMPAT_H_
+#define _BNAD_COMPAT_H_
+
+#include <linux/version.h>
+
+#ifndef SET_MODULE_OWNER
+#define SET_MODULE_OWNER(netdev) do { } while (0)
+#endif
+
+#ifndef SET_NETDEV_DEV
+#define SET_NETDEV_DEV(netdev, dev) do { } while (0)
+#endif
+
+#ifndef module_param
+#define module_param(name, type, perm) MODULE_PARM(name, "i");
+#endif
+
+#ifndef NET_IP_ALIGN
+#define NET_IP_ALIGN 2
+#endif
+
+#ifndef NETDEV_TX_OK
+#define NETDEV_TX_OK 0 /* driver took care of the packet */
+#endif
+
+#ifndef NETDEV_TX_BUSY
+#define NETDEV_TX_BUSY 1 /* driver tx path was busy */
+#endif
+
+#ifndef NETDEV_TX_LOCKED
+#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */
+#endif
+
+#ifndef ALIGN
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#endif
+
+#ifndef ETH_FCS_LEN
+#define ETH_FCS_LEN 4
+#endif
+
+#ifndef CHECKSUM_PARTIAL
+#define CHECKSUM_PARTIAL CHECKSUM_HW
+#endif
+
+#ifndef IRQF_SHARED
+#define IRQF_SHARED SA_SHIRQ
+#endif
+
+#ifndef SKB_DATAREF_SHIFT
+#define skb_header_cloned(_skb) 0
+#endif
+
+#ifndef VERIFY_WRITE
+#define VERIFY_WRITE 1
+#endif
+
+#ifndef VERIFY_READ
+#define VERIFY_READ 0
+#endif
+
+#ifndef dev_err
+#define dev_err(dev, format, arg...) \
+ printk(KERN_ERR "bna: " format , ## arg)
+#endif
+#ifndef dev_info
+#define dev_info(dev, format, arg...) \
+ printk(KERN_INFO "bna: " format , ## arg)
+#endif
+#ifndef dev_warn
+#define dev_warn(dev, format, arg...) \
+ printk(KERN_WARNING "bna: " format , ## arg)
+#endif
+
+#endif /* _BNAD_COMPAT_H_ */
diff -ruP net-next-2.6-orig/drivers/net/bna/bnad_defs.h net-next-2.6-mod/drivers/net/bna/bnad_defs.h
--- net-next-2.6-orig/drivers/net/bna/bnad_defs.h 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/bnad_defs.h 2009-10-31 21:34:47.899534000 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _BNAD_DEFS_H_
+#define _BNAD_DEFS_H_
+
+#define BNAD_NAME "bna"
+#define BNAD_VERSION "2.0.0.0"
+
+#ifndef PCI_VENDOR_ID_BROCADE
+#define PCI_VENDOR_ID_BROCADE 0x1657
+#endif
+
+#ifndef PCI_DEVICE_ID_BROCADE_CATAPULT
+#define PCI_DEVICE_ID_BROCADE_CATAPULT 0x0014
+#endif
+
+#endif /* _BNAD_DEFS_H_ */
diff -ruP net-next-2.6-orig/drivers/net/bna/cna.h net-next-2.6-mod/drivers/net/bna/cna.h
--- net-next-2.6-orig/drivers/net/bna/cna.h 1969-12-31 16:00:00.000000000 -0800
+++ net-next-2.6-mod/drivers/net/bna/cna.h 2009-10-31 21:34:47.906532000 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __CNA_H__
+#define __CNA_H__
+
+#include <cs/bfa_trc.h>
+#include <defs/bfa_defs_types.h>
+
+extern char bfa_version[];
+void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
+
+#endif /* __CNA_H__ */
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox