* Re: [PATCH] net: Add DEVTYPE support for Ethernet based devices
From: Marcel Holtmann @ 2009-09-05 4:34 UTC (permalink / raw)
To: David Miller; +Cc: netdev, shemminger, johannes
In-Reply-To: <20090904.202750.249172306.davem@davemloft.net>
Hi Dave,
> > can you please give me some feedback on this patch.
>
> Johannes recommended using a NETDEV_REGISTER hook, I'm
> waiting for you to try and use that instead of this
> patch.
that was for the Wireless drivers part. Total different from what this
patch trying to achieve.
> Your patch is ugly, so I'd like to avoid it if possible.
What is ugly about it. Do you have any other recommendation on how let
userspace know what type of Ethernet device it is?
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] net: Add DEVTYPE support for Ethernet based devices
From: David Miller @ 2009-09-05 4:46 UTC (permalink / raw)
To: marcel; +Cc: netdev, shemminger, johannes
In-Reply-To: <1252125240.27694.5.camel@violet>
From: Marcel Holtmann <marcel@holtmann.org>
Date: Sat, 05 Sep 2009 06:34:00 +0200
> What is ugly about it. Do you have any other recommendation on how let
> userspace know what type of Ethernet device it is?
Well, for one thing, you're wasting 48 bytes on 64-bit when all you're
really intrested in is one string.
Also, you didn't setup an assignment for plain ethernet devices,
you just handle the non-traditional devices that do ethernet
framing. Is this intentional?
^ permalink raw reply
* Re: [PATCH] net: Add DEVTYPE support for Ethernet based devices
From: Stephen Hemminger @ 2009-09-05 4:49 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: netdev, davem, johannes
In-Reply-To: <1251788899-30156-1-git-send-email-marcel@holtmann.org>
On Tue, 1 Sep 2009 00:08:19 -0700
Marcel Holtmann <marcel@holtmann.org> wrote:
> The Ethernet framing is used for a lot of devices these days. Most
> prominent are WiFi and WiMAX based devices. However for userspace
> application it is important to classify these devices correctly and
> not only see them as Ethernet devices. The daemons like HAL, DeviceKit
> or even NetworkManager with udev support tries to do the classification
> in userspace with a lot trickery and extra system calls. This is not
> good and actually reaches its limitations. Especially since the kernel
> does know the type of the Ethernet device it is pretty stupid.
>
> To solve this problem the underlying device type needs to be set and
> then the value will be exported as DEVTYPE via uevents and available
> within udev.
>
> # cat /sys/class/net/wlan0/uevent
> DEVTYPE=wlan
> INTERFACE=wlan0
> IFINDEX=5
>
The problem with your idea is that there is only a nebulous definition of
what is a Wifi device, and what is a WiMAX device etc. What userspace should be looking
for is "does device XXX support API yyy?" and if it supports API
yyy then I it can be configured that way.
There already is some information in sysfs like /sys/class/net/XXX/type
which gives the hardware type (ARPHRD_ETHER, etc). Why not a better version
of something like this that provides "can do FOO" interface?
Doing a several system calls (open/read/close) per device is not a big
issue. Even an android phone can do open/read/close in less than a millisecond
I bet.
^ permalink raw reply
* Re: [PATCH] net: Add DEVTYPE support for Ethernet based devices
From: Marcel Holtmann @ 2009-09-05 5:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev, shemminger, johannes
In-Reply-To: <20090904.214615.198838334.davem@davemloft.net>
Hi David,
> > What is ugly about it. Do you have any other recommendation on how let
> > userspace know what type of Ethernet device it is?
>
> Well, for one thing, you're wasting 48 bytes on 64-bit when all you're
> really intrested in is one string.
the integration with struct device has plenty of other advantages. You
could use all the sysfs magic from it. For example in the next step the
hacking of some sysfs directories can be moved into the subsystem itself
and could be moved out of the core. Wireless would be one of them were
we would benefit here.
> Also, you didn't setup an assignment for plain ethernet devices,
> you just handle the non-traditional devices that do ethernet
> framing. Is this intentional?
For now it is. Mainly since some non plain Ethernet devices are using
alloc_etherdev instead of just alloc_netdev. So I would have to do some
extra work. I have planned it, but not gotten around it yet.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] net: Add DEVTYPE support for Ethernet based devices
From: David Miller @ 2009-09-05 5:55 UTC (permalink / raw)
To: marcel; +Cc: netdev, shemminger, johannes
In-Reply-To: <1252129940.27694.9.camel@violet>
From: Marcel Holtmann <marcel@holtmann.org>
Date: Sat, 05 Sep 2009 07:52:20 +0200
>> > What is ugly about it. Do you have any other recommendation on how let
>> > userspace know what type of Ethernet device it is?
>>
>> Well, for one thing, you're wasting 48 bytes on 64-bit when all you're
>> really intrested in is one string.
>
> the integration with struct device has plenty of other advantages
Ok, this I agree with.
^ permalink raw reply
* Re: [PATCH] net: Add DEVTYPE support for Ethernet based devices
From: Marcel Holtmann @ 2009-09-05 5:55 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, davem, johannes
In-Reply-To: <20090904214903.49e5a361@nehalam>
Hi Stephen,
> > The Ethernet framing is used for a lot of devices these days. Most
> > prominent are WiFi and WiMAX based devices. However for userspace
> > application it is important to classify these devices correctly and
> > not only see them as Ethernet devices. The daemons like HAL, DeviceKit
> > or even NetworkManager with udev support tries to do the classification
> > in userspace with a lot trickery and extra system calls. This is not
> > good and actually reaches its limitations. Especially since the kernel
> > does know the type of the Ethernet device it is pretty stupid.
> >
> > To solve this problem the underlying device type needs to be set and
> > then the value will be exported as DEVTYPE via uevents and available
> > within udev.
> >
> > # cat /sys/class/net/wlan0/uevent
> > DEVTYPE=wlan
> > INTERFACE=wlan0
> > IFINDEX=5
> >
>
> The problem with your idea is that there is only a nebulous definition of
> what is a Wifi device, and what is a WiMAX device etc. What userspace should be looking
> for is "does device XXX support API yyy?" and if it supports API
> yyy then I it can be configured that way.
We don't need that. We just need to know what technology is behind that
Ethernet device. Otherwise we have no real starting point.
> There already is some information in sysfs like /sys/class/net/XXX/type
> which gives the hardware type (ARPHRD_ETHER, etc). Why not a better version
> of something like this that provides "can do FOO" interface?
that was my initial idea, but I couldn't come up with something good.
And the DEVTYPE from struct device is a standard way of exposing such
information. Actually subsystem like SCSI, USB, Bluetooth etc. use that
already. So why not do the same for Ethernet based devices.
> Doing a several system calls (open/read/close) per device is not a big
> issue. Even an android phone can do open/read/close in less than a millisecond
> I bet.
It is not only the system calls that userspace has to do. There is no
central place for this stuff and why should be do it all if the kernel
already has all the details.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] WAN: remove deprecated PCI_DEVICE_ID from PCI200SYN driver.
From: David Miller @ 2009-09-05 6:07 UTC (permalink / raw)
To: khc; +Cc: netdev
In-Reply-To: <m363byk3af.fsf@intrepid.localdomain>
From: Krzysztof Halasa <khc@pm.waw.pl>
Date: Fri, 04 Sep 2009 19:50:16 +0200
> PCI200SYN has its own PCI subsystem device ID for 3+ years, now it's
> time to remove the generic PLX905[02] ID from the driver. Anyone with
> old EEPROM data will have to run the upgrade.
>
> Having the generic PLX905[02] (PCI-local bus bridge) ID is harmful
> as the driver tries to handle other devices based on these bridges.
Please provide a proper signoff with all patches.
Thanks.
^ permalink raw reply
* Re: net_sched 00/07: classful multiqueue dummy scheduler
From: David Miller @ 2009-09-05 7:27 UTC (permalink / raw)
To: kaber; +Cc: netdev
In-Reply-To: <20090904164111.27300.29929.sendpatchset@x2.localnet>
From: Patrick McHardy <kaber@trash.net>
Date: Fri, 4 Sep 2009 18:41:12 +0200 (MEST)
> Any comments and test results welcome :)
This looks really nice. I have them already checked into my
local net-next-2.6 tree and will push them out after I do
some multiqueue testing with NIU.
Thanks!
^ permalink raw reply
* Re: [PATCH] netlink: silence compiler warning
From: Jarek Poplawski @ 2009-09-05 7:52 UTC (permalink / raw)
To: David Miller; +Cc: brian.haley, marcel, netdev, Stephen Rothwell
In-Reply-To: <20090904.203318.112406812.davem@davemloft.net>
David Miller wrote, On 09/05/2009 05:33 AM:
> From: Brian Haley <brian.haley@hp.com>
> Date: Fri, 04 Sep 2009 21:36:06 -0400
>
>> Hi Marcel,
>>
>> Marcel Holtmann wrote:
>>> can we please add the err = -E... where it actually is needed and not
>>> stupidly go ahead and silence compiler warnings with err = 0. This has
>>> been posted before.
>> Sorry, I don't remember it being posted before. If you look at the code
>> though, err is correctly initialized, gcc just can't figure it out. The
>> choices I see are either what I originally posted, using uninitialized_var(err),
>> or the patch below. It doesn't matter to me.
>
> uninitialized_var() would be absolutely wrong here, as then we'd
> return garbage if such a path were actually possible.
If the main "thesis" of the patch is:
> From following the code 'err' is initialized, but set it to zero to
> silence the warning.
"we" should better be sure it "is initialized", so considering: "if such
a path were actually possible" "would be absolutely wrong here"...
Here is a link to the message which proved something else was possible
at some moment in -next (I didn't check the current code yet):
From: Stephen Rothwell <sfr@canb.auug.org.au>
Subject: Re: [PATCH] Fix Warnings from net/netlink/genetlink.c
Date: Wed, 12 Aug 2009 13:50:31 +1000
Archived-At: http://permalink.gmane.org/gmane.linux.kernel.next/8786
Jarek P.
^ permalink raw reply
* Re: [PATCH] netlink: silence compiler warning
From: David Miller @ 2009-09-05 8:13 UTC (permalink / raw)
To: jarkao2; +Cc: brian.haley, marcel, netdev, sfr
In-Reply-To: <4AA218C8.4050800@gmail.com>
From: Jarek Poplawski <jarkao2@gmail.com>
Date: Sat, 05 Sep 2009 09:52:40 +0200
> http://permalink.gmane.org/gmane.linux.kernel.next/8786
Right, and that was my thinking. So setting it to zero to
begin with is the right thing to do.
^ permalink raw reply
* Re: net_sched 02/07: make cls_ops->tcf_chain() optional
From: Jarek Poplawski @ 2009-09-05 8:13 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev
In-Reply-To: <20090904164113.27300.79145.sendpatchset@x2.localnet>
Patrick McHardy wrote, On 09/04/2009 06:41 PM:
> commit 6ea4233ef8f398289a14a3305d4ed440fb026d43
> Author: Patrick McHardy <kaber@trash.net>
> Date: Fri Sep 4 14:28:11 2009 +0200
>
> net_sched: make cls_ops->tcf_chain() optional
>
> Some qdiscs don't support attaching filters. Handle this centrally in
> cls_api and return a proper errno code (EOPNOTSUPP) instead of EINVAL.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
>
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index 09cdcdf..eaa8f43 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -181,6 +181,9 @@ replay:
> if ((cops = q->ops->cl_ops) == NULL)
> return -EINVAL;
>
> + if (cops->tcf_chain == NULL)
> + return -EOPNOTSUPP;
> +
You should probably repeat this in tc_dump_tfilter.
Jarek P.
^ permalink raw reply
* Re: [PATCH] WAN: remove deprecated PCI_DEVICE_ID from PCI200SYN driver.
From: Krzysztof Halasa @ 2009-09-05 10:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090904.230740.247551288.davem@davemloft.net>
David Miller <davem@davemloft.net> writes:
> Please provide a proper signoff with all patches.
Oops. Sure.
--
Krzysztof Halasa
^ permalink raw reply
* [PATCH] WAN: remove deprecated PCI_DEVICE_ID from PCI200SYN driver.
From: Krzysztof Halasa @ 2009-09-05 10:54 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <m363byk3af.fsf@intrepid.localdomain>
PCI200SYN has its own PCI subsystem device ID for 3+ years, now it's
time to remove the generic PLX905[02] ID from the driver. Anyone with
old EEPROM data will have to run the upgrade.
Having the generic PLX905[02] (PCI-local bus bridge) ID is harmful
as the driver tries to handle other devices based on these bridges.
Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -360,15 +360,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
" %u RX packets rings\n", ramsize / 1024, ramphys,
pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers);
- if (pdev->subsystem_device == PCI_DEVICE_ID_PLX_9050) {
- printk(KERN_ERR "Detected PCI200SYN card with old "
- "configuration data.\n");
- printk(KERN_ERR "See <http://www.kernel.org/pub/"
- "linux/utils/net/hdlc/pci200syn/> for update.\n");
- printk(KERN_ERR "The card will stop working with"
- " future versions of Linux if not updated.\n");
- }
-
if (card->tx_ring_buffers < 1) {
printk(KERN_ERR "pci200syn: RAM test failed\n");
pci200_pci_remove_one(pdev);
@@ -427,8 +418,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
static struct pci_device_id pci200_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX,
- PCI_DEVICE_ID_PLX_9050, 0, 0, 0 },
- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX,
PCI_DEVICE_ID_PLX_PCI200SYN, 0, 0, 0 },
{ 0, }
};
--
Krzysztof Halasa
^ permalink raw reply
* Re: [PATCH net-next] wan: dlci/sdla transmit return dehacking
From: Krzysztof Halasa @ 2009-09-05 11:09 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, sfr, linux-next, netdev
In-Reply-To: <20090904193810.46543e3c@nehalam>
Stephen Hemminger <shemminger@vyatta.com> writes:
> In the Vyatta product we use the Sangoma drivers, so we actually have
> to make and not configure in the existing WAN drivers.
I'd expect all users of their hw are doing precisely the same (not to
imply there are any S5* (ISA) cards still in use).
But I don't know for sure, sometimes people use really old and long
unmaintained drivers with success. OTOH ISA...
--
Krzysztof Halasa
^ permalink raw reply
* Re: net_sched 02/07: make cls_ops->tcf_chain() optional
From: Jarek Poplawski @ 2009-09-05 11:57 UTC (permalink / raw)
Cc: Patrick McHardy, netdev
In-Reply-To: <4AA21D9F.8090600@gmail.com>
Jarek Poplawski wrote, On 09/05/2009 10:13 AM:
> Patrick McHardy wrote, On 09/04/2009 06:41 PM:
>
>> commit 6ea4233ef8f398289a14a3305d4ed440fb026d43
>> Author: Patrick McHardy <kaber@trash.net>
>> Date: Fri Sep 4 14:28:11 2009 +0200
>>
>> net_sched: make cls_ops->tcf_chain() optional
>>
>> Some qdiscs don't support attaching filters. Handle this centrally in
>> cls_api and return a proper errno code (EOPNOTSUPP) instead of EINVAL.
>>
>> Signed-off-by: Patrick McHardy <kaber@trash.net>
>>
>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>> index 09cdcdf..eaa8f43 100644
>> --- a/net/sched/cls_api.c
>> +++ b/net/sched/cls_api.c
>> @@ -181,6 +181,9 @@ replay:
>> if ((cops = q->ops->cl_ops) == NULL)
>> return -EINVAL;
>>
>> + if (cops->tcf_chain == NULL)
>> + return -EOPNOTSUPP;
>> +
>
>
> You should probably repeat this in tc_dump_tfilter.
...In case somebody finds the way to list a filter before
adding it. ;-) But, since it's quite unlikely, let's foget it.
Sorry,
Jarek P.
^ permalink raw reply
* Re: [PATCH] atm: dereference of he_dev->rbps_virt in he_init_group()
From: Roel Kluin @ 2009-09-05 12:35 UTC (permalink / raw)
To: David Miller; +Cc: chas, linux-atm-general, netdev, akpm
In-Reply-To: <20090902.232548.238393942.davem@davemloft.net>
he_dev->rbps_virt or he_dev->rbpl_virt allocation may fail, so check
them. Make sure that he_init_group() cleans up after errors.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
> These new return statements will both leak resources allocated
> earlier.
>
> All the caller is going to do is return -ENOMEM as well and
> it does not cleanup actions at all.
>
> Please fix this up.
I am new to this api, so please review.
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 2de6406..1d873cb 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -777,7 +777,7 @@ he_init_cs_block_rcm(struct he_dev *he_dev)
static int __devinit
he_init_group(struct he_dev *he_dev, int group)
{
- int i;
+ int i, ret;
/* small buffer pool */
he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev,
@@ -790,19 +790,27 @@ he_init_group(struct he_dev *he_dev, int group)
he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev,
CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys);
if (he_dev->rbps_base == NULL) {
- hprintk("failed to alloc rbps\n");
- return -ENOMEM;
+ hprintk("failed to alloc rbps_base\n");
+ ret = -ENOMEM;
+ goto out_destroy_rbps_pool;
}
memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp));
he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL);
+ if (he_dev->rbps_virt == NULL) {
+ hprintk("failed to alloc rbps_virt\n");
+ ret = -ENOMEM;
+ goto out_free_rbps_base;
+ }
for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
dma_addr_t dma_handle;
void *cpuaddr;
cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
- if (cpuaddr == NULL)
- return -ENOMEM;
+ if (cpuaddr == NULL) {
+ ret = -ENOMEM;
+ goto out_free_rbps_virt;
+ }
he_dev->rbps_virt[i].virt = cpuaddr;
he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF);
@@ -827,25 +835,34 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_RBPL_BUFSIZE, 8, 0);
if (he_dev->rbpl_pool == NULL) {
hprintk("unable to create rbpl pool\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_free_rbps_virt;
}
he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev,
CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys);
if (he_dev->rbpl_base == NULL) {
- hprintk("failed to alloc rbpl\n");
- return -ENOMEM;
+ hprintk("failed to alloc rbpl_base\n");
+ ret = -ENOMEM;
+ goto out_destroy_rbpl_pool;
}
memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp));
he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL);
+ if (he_dev->rbpl_virt == NULL) {
+ hprintk("failed to alloc rbpl_virt\n");
+ ret = -ENOMEM;
+ goto out_free_rbpl_base;
+ }
for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
dma_addr_t dma_handle;
void *cpuaddr;
cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
- if (cpuaddr == NULL)
- return -ENOMEM;
+ if (cpuaddr == NULL) {
+ ret = -ENOMEM;
+ goto out_free_rbpl_virt;
+ }
he_dev->rbpl_virt[i].virt = cpuaddr;
he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
@@ -870,7 +887,8 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys);
if (he_dev->rbrq_base == NULL) {
hprintk("failed to allocate rbrq\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_free_rbpl_virt;
}
memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq));
@@ -894,7 +912,8 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), &he_dev->tbrq_phys);
if (he_dev->tbrq_base == NULL) {
hprintk("failed to allocate tbrq\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_free_rbpq_base;
}
memset(he_dev->tbrq_base, 0, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq));
@@ -906,6 +925,34 @@ he_init_group(struct he_dev *he_dev, int group)
he_writel(he_dev, CONFIG_TBRQ_THRESH, G0_TBRQ_THRESH + (group * 16));
return 0;
+
+out_free_rbpq_base:
+ pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
+ he_dev->rbrq_base, he_dev->rbrq_phys);
+ i = CONFIG_RBPL_SIZE;
+out_free_rbpl_virt:
+ while (--i)
+ pci_pool_free(he_dev->rbpl_virt[i].virt);
+ kfree(he_dev->rbpl_virt);
+
+out_free_rbpl_base:
+ pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE * sizeof(struct he_rbp),
+ he_dev->rbpl_base, he_dev->rbpl_phys);
+out_destroy_rbpl_pool:
+ pci_pool_destroy(he_dev->rbpl_pool);
+
+ i = CONFIG_RBPL_SIZE;
+out_free_rbps_virt:
+ while (--i)
+ pci_pool_free(he_dev->rbps_virt[i].virt);
+ kfree(he_dev->rbps_virt);
+
+out_free_rbps_base:
+ pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE * sizeof(struct he_rbp),
+ he_dev->rbps_base, he_dev->rbps_phys);
+out_destroy_rbps_pool:
+ pci_pool_destroy(he_dev->rbps_pool);
+ return ret;
}
static int __devinit
^ permalink raw reply related
* Re: net_sched 02/07: make cls_ops->tcf_chain() optional
From: Jarek Poplawski @ 2009-09-05 12:32 UTC (permalink / raw)
Cc: Patrick McHardy, netdev
In-Reply-To: <4AA2520D.2060603@gmail.com>
Jarek Poplawski wrote, On 09/05/2009 01:57 PM:
> Jarek Poplawski wrote, On 09/05/2009 10:13 AM:
>
>> Patrick McHardy wrote, On 09/04/2009 06:41 PM:
>>
>>> commit 6ea4233ef8f398289a14a3305d4ed440fb026d43
>>> Author: Patrick McHardy <kaber@trash.net>
>>> Date: Fri Sep 4 14:28:11 2009 +0200
>>>
>>> net_sched: make cls_ops->tcf_chain() optional
>>>
>>> Some qdiscs don't support attaching filters. Handle this centrally in
>>> cls_api and return a proper errno code (EOPNOTSUPP) instead of EINVAL.
>>>
>>> Signed-off-by: Patrick McHardy <kaber@trash.net>
>>>
>>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>>> index 09cdcdf..eaa8f43 100644
>>> --- a/net/sched/cls_api.c
>>> +++ b/net/sched/cls_api.c
>>> @@ -181,6 +181,9 @@ replay:
>>> if ((cops = q->ops->cl_ops) == NULL)
>>> return -EINVAL;
>>>
>>> + if (cops->tcf_chain == NULL)
>>> + return -EOPNOTSUPP;
>>> +
>>
>> You should probably repeat this in tc_dump_tfilter.
>
>
> ...In case somebody finds the way to list a filter before
> adding it. ;-) But, since it's quite unlikely, let's foget it.
...or simply tries to do it instead of meditating the code.
So this change is definitely needed in tc_dump_tfilter too.
Sorry to myself,
Jarek P.
^ permalink raw reply
* Staging: cpc-usb CAN driver TODO list
From: Oliver Hartkopp @ 2009-09-05 13:08 UTC (permalink / raw)
To: Greg KH, Sebastian Haas
Cc: Linux Netdev List, Felipe Balbi, Wolfgang Grandegger
Hello Greg and Sebastian,
i just looked around in the linux-next tree for the cpc-usb driver.
http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=tree;f=drivers/staging/cpc-usb;hb=HEAD
IMHO the sja2m16c* files are completely obsolete as the setting of the CAN
bittimings needs to be done by separate functions (one for the SJA1000 and one
for the M16C). For both of them a separate can_bittiming_const is needed, like
it is defined in drivers/net/can/sja1000/sja1000.c:
static struct can_bittiming_const sja1000_bittiming_const = {
.name = DRV_NAME,
.tseg1_min = 1,
.tseg1_max = 16,
.tseg2_min = 1,
.tseg2_max = 8,
.sjw_max = 4,
.brp_min = 1,
.brp_max = 64,
.brp_inc = 1,
};
Also a separate function to determine the register values from the calculated
bittiming values is needed for both hardware types (SJA1000(LPC2119)/M16C) of
the cpc-usb. How this is done can be checked in linux/drivers/net/can/* or in
the source code of upcoming drivers in
http://svn.berlios.de/svnroot/repos/socketcan/trunk/kernel/2.6/drivers/net/can/
I wondered about the following items in the TODO list:
- tie into CAN socket interfaces if possible
- figure out sane userspace api
This is definitely a no go! IMO there is no real alternative to make this
cpc-usb driver a real CAN network driver.
The CAN driver interface has a sane configuration API via netlink and brings
everything to configure CAN specific bitrates, error counters, recovery, etc.
The missing thing is to connect the usb-device to a netdevice (can%d), remove
all the chardev file-I/O stuff and adapt the cpc-usb to use the
bitrate-settings, error counters and whatever - which is already well-defined
and provided by the CAN driver interface library contributed by Wolfgang
Grandegger ( drivers/net/can/dev.c and include/linux/can/[dev.h|netlink.h] ).
Unfortunately i'm not an expert in USB programming and i don't have that
hardware - but if you need some ideas from the CAN driver peoples like
Wolfgang, questions are always welcome, e.g. on the socketcan-core ML:
http://developer.berlios.de/projects/socketcan
I don't think it's a big effort for people that know USB & CAN to clean up the
cpc-usb and make it a slim CAN netdev. Believe me, it took years to figure out
a sane userspace api for CAN interfaces, which is now provided by the netlink
interface ;-)
Best regards,
Oliver
^ permalink raw reply
* [PATCH] IXP42x HSS support for setting internal clock rate
From: Krzysztof Halasa @ 2009-09-05 13:59 UTC (permalink / raw)
To: David Miller; +Cc: netdev
HSS usually uses external clocks, so it's not a big deal. Internal clock
is used for direct DTE-DTE connections and when the DCE doesn't provide
it's own clock.
This also depends on the oscillator frequency. Intel seems to have
calculated the clock register settings for 33.33 MHz (66.66 MHz timer
base). Their settings seem quite suboptimal both in terms of average
frequency (60 ppm is unacceptable for G.703 applications, their primary
intended usage(?)) and jitter.
Many (most?) platforms use a 33.333 MHz oscillator, a 10 ppm difference
from Intel's base.
Instead of creating static tables, I've created a procedure to program
the HSS clock register. The register consists of 3 parts (A, B, C).
The average frequency (= bit rate) is:
66.66x MHz / (A + (B + 1) / (C + 1))
The procedure aims at the closest average frequency, possibly at the
cost of increased jitter. Nobody would be able to directly drive an
unbufferred transmitter with a HSS anyway, and the frequency error is
what it really counts.
I've verified the above with an oscilloscope on IXP425. It seems IXP46x
and possibly IXP43x use a bit different clock generation algorithm - it
looks like the avg frequency is:
(on IXP465) 66.66x MHz / (A + B / (C + 1)).
Also they use much greater precomputed A and B - on IXP425 it would
simply result in more jitter, but I don't know how does it work on
IXP46x (perhaps 3 least significant bits aren't used?).
Anyway it looks that they were aiming for exactly +60 ppm or -60 ppm,
while <1 ppm is typically possible (with a synchronized clock, of
course).
The attached patch makes it possible to set almost any bit rate
(my IXP425 533 MHz quits at > 22 Mb/s if a single port is used, and the
minimum is ca. 65 Kb/s).
This is independent of MVIP (multi-E1/T1 on one HSS) mode.
Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 1e93dfe..5083f03 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -416,6 +416,7 @@ static struct clocksource clocksource_ixp4xx = {
};
unsigned long ixp4xx_timer_freq = FREQ;
+EXPORT_SYMBOL(ixp4xx_timer_freq);
static int __init ixp4xx_clocksource_init(void)
{
clocksource_ixp4xx.mult =
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index bb719b6..c705046 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -166,6 +166,29 @@
#define CLK46X_SPEED_4096KHZ (( 16 << 22) | (280 << 12) | 1023)
#define CLK46X_SPEED_8192KHZ (( 8 << 22) | (280 << 12) | 2047)
+/*
+ * HSS_CONFIG_CLOCK_CR register consists of 3 parts:
+ * A (10 bits), B (10 bits) and C (12 bits).
+ * IXP42x HSS clock generator operation (verified with an oscilloscope):
+ * Each clock bit takes 7.5 ns (1 / 133.xx MHz).
+ * The clock sequence consists of (C - B) states of 0s and 1s, each state is
+ * A bits wide. It's followed by (B + 1) states of 0s and 1s, each state is
+ * (A + 1) bits wide.
+ *
+ * The resulting average clock frequency (assuming 33.333 MHz oscillator) is:
+ * freq = 66.666 MHz / (A + (B + 1) / (C + 1))
+ * minumum freq = 66.666 MHz / (A + 1)
+ * maximum freq = 66.666 MHz / A
+ *
+ * Example: A = 2, B = 2, C = 7, CLOCK_CR register = 2 << 22 | 2 << 12 | 7
+ * freq = 66.666 MHz / (2 + (2 + 1) / (7 + 1)) = 28.07 MHz (Mb/s).
+ * The clock sequence is: 1100110011 (5 doubles) 000111000 (3 triples).
+ * The sequence takes (C - B) * A + (B + 1) * (A + 1) = 5 * 2 + 3 * 3 bits
+ * = 19 bits (each 7.5 ns long) = 142.5 ns (then the sequence repeats).
+ * The sequence consists of 4 complete clock periods, thus the average
+ * frequency (= clock rate) is 4 / 142.5 ns = 28.07 MHz (Mb/s).
+ * (max specified clock rate for IXP42x HSS is 8.192 Mb/s).
+ */
/* hss_config, LUT entries */
#define TDMMAP_UNASSIGNED 0
@@ -239,6 +262,7 @@ struct port {
unsigned int clock_type, clock_rate, loopback;
unsigned int initialized, carrier;
u8 hdlc_cfg;
+ u32 clock_reg;
};
/* NPE message structure */
@@ -393,7 +417,7 @@ static void hss_config(struct port *port)
msg.cmd = PORT_CONFIG_WRITE;
msg.hss_port = port->id;
msg.index = HSS_CONFIG_CLOCK_CR;
- msg.data32 = CLK42X_SPEED_2048KHZ /* FIXME */;
+ msg.data32 = port->clock_reg;
hss_npe_send(port, &msg, "HSS_SET_CLOCK_CR");
memset(&msg, 0, sizeof(msg));
@@ -1160,6 +1184,62 @@ static int hss_hdlc_attach(struct net_device *dev, unsigned short encoding,
}
}
+static u32 check_clock(u32 rate, u32 a, u32 b, u32 c,
+ u32 *best, u32 *best_diff, u32 *reg)
+{
+ /* a is 10-bit, b is 10-bit, c is 12-bit */
+ u64 new_rate;
+ u32 new_diff;
+
+ new_rate = ixp4xx_timer_freq * (u64)(c + 1);
+ do_div(new_rate, a * (c + 1) + b + 1);
+ new_diff = abs((u32)new_rate - rate);
+
+ if (new_diff < *best_diff) {
+ *best = new_rate;
+ *best_diff = new_diff;
+ *reg = (a << 22) | (b << 12) | c;
+ }
+ return new_diff;
+}
+
+static void find_best_clock(u32 rate, u32 *best, u32 *reg)
+{
+ u32 a, b, diff = 0xFFFFFFFF;
+
+ a = ixp4xx_timer_freq / rate;
+
+ if (a > 0x3FF) { /* 10-bit value - we can go as slow as ca. 65 kb/s */
+ check_clock(rate, 0x3FF, 1, 1, best, &diff, reg);
+ return;
+ }
+ if (a == 0) { /* > 66.666 MHz */
+ a = 1; /* minimum divider is 1 (a = 0, b = 1, c = 1) */
+ rate = ixp4xx_timer_freq;
+ }
+
+ if (rate * a == ixp4xx_timer_freq) { /* don't divide by 0 later */
+ check_clock(rate, a - 1, 1, 1, best, &diff, reg);
+ return;
+ }
+
+ for (b = 0; b < 0x400; b++) {
+ u64 c = (b + 1) * (u64)rate;
+ do_div(c, ixp4xx_timer_freq - rate * a);
+ c--;
+ if (c >= 0xFFF) { /* 12-bit - no need to check more 'b's */
+ if (b == 0 && /* also try a bit higher rate */
+ !check_clock(rate, a - 1, 1, 1, best, &diff, reg))
+ return;
+ check_clock(rate, a, b, 0xFFF, best, &diff, reg);
+ return;
+ }
+ if (!check_clock(rate, a, b, c, best, &diff, reg))
+ return;
+ if (!check_clock(rate, a, b, c + 1, best, &diff, reg))
+ return;
+ }
+}
static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
@@ -1182,7 +1262,7 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
memset(&new_line, 0, sizeof(new_line));
new_line.clock_type = port->clock_type;
- new_line.clock_rate = 2048000; /* FIXME */
+ new_line.clock_rate = port->clock_rate;
new_line.loopback = port->loopback;
if (copy_to_user(line, &new_line, size))
return -EFAULT;
@@ -1206,7 +1286,13 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EINVAL;
port->clock_type = clk; /* Update settings */
- /* FIXME port->clock_rate = new_line.clock_rate */;
+ if (clk == CLOCK_INT)
+ find_best_clock(new_line.clock_rate, &port->clock_rate,
+ &port->clock_reg);
+ else {
+ port->clock_rate = 0;
+ port->clock_reg = CLK42X_SPEED_2048KHZ;
+ }
port->loopback = new_line.loopback;
spin_lock_irqsave(&npe_lock, flags);
@@ -1266,7 +1352,8 @@ static int __devinit hss_init_one(struct platform_device *pdev)
dev->netdev_ops = &hss_hdlc_ops;
dev->tx_queue_len = 100;
port->clock_type = CLOCK_EXT;
- port->clock_rate = 2048000;
+ port->clock_rate = 0;
+ port->clock_reg = CLK42X_SPEED_2048KHZ;
port->id = pdev->id;
port->dev = &pdev->dev;
port->plat = pdev->dev.platform_data;
--
Krzysztof Halasa
^ permalink raw reply related
* Re: ipw2200: firmware DMA loading rework
From: Theodore Tso @ 2009-09-05 14:28 UTC (permalink / raw)
To: Mel Gorman
Cc: Luis R. Rodriguez, Bartlomiej Zolnierkiewicz, Aneesh Kumar K.V,
Zhu Yi, Andrew Morton, Johannes Weiner, Pekka Enberg,
Rafael J. Wysocki, Linux Kernel Mailing List, Kernel Testers List,
Mel Gorman, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org, James Ketrenos,
Chatre, Reinette,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ipw2100-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
In-Reply-To: <20090903124913.GA26110-wPRd99KPJ+uzQB+pC5nmwQ@public.gmane.org>
On Thu, Sep 03, 2009 at 01:49:14PM +0100, Mel Gorman wrote:
> >
> > This looks very similar to the kmemleak ext4 reports upon a mount. If
> > it is the same issue, which from the trace it seems it is, then this
> > is due to an extra kmalloc() allocation and this apparently will not
> > get fixed on 2.6.31 due to the closeness of the merge window and the
> > non-criticalness this issue has been deemed.
No, it's a different problem.
> I suspect the more pressing concern is why is this kmalloc() resulting in
> an order-5 allocation request? What size is the buffer being requested?
> Was that expected? What is the contents of /proc/slabinfo in case a buffer
> that should have required order-1 or order-2 is using a higher order for
> some reason.
It's allocating 68,000 bytes for the mb_history structure, which is
used for debugging purposes. That's why it's optional and we continue
if it's not allocated. We should fix it to use vmalloc() and I'm
inclined to turn it off by default since it's not worth the overhead,
and most ext4 users won't find it useful or interesting.
- Ted
^ permalink raw reply
* Re: net_sched 00/07: classful multiqueue dummy scheduler
From: Patrick McHardy @ 2009-09-05 17:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090905.002705.16361217.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 405 bytes --]
David Miller wrote:
> From: Patrick McHardy <kaber@trash.net>
> Date: Fri, 4 Sep 2009 18:41:12 +0200 (MEST)
>
>> Any comments and test results welcome :)
>
> This looks really nice. I have them already checked into my
> local net-next-2.6 tree and will push them out after I do
> some multiqueue testing with NIU.
Thanks. Attached is a small fix on top hat fixes inverted logic
in mq_destroy().
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 417 bytes --]
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index 5e453fd..c84dec9 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -26,7 +26,7 @@ static void mq_destroy(struct Qdisc *sch)
struct mq_sched *priv = qdisc_priv(sch);
unsigned int ntx;
- if (priv->qdiscs)
+ if (!priv->qdiscs)
return;
for (ntx = 0; ntx < dev->num_tx_queues && priv->qdiscs[ntx]; ntx++)
qdisc_destroy(priv->qdiscs[ntx]);
^ permalink raw reply related
* Re: net_sched 02/07: make cls_ops->tcf_chain() optional
From: Patrick McHardy @ 2009-09-05 17:03 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev
In-Reply-To: <4AA25A51.2040100@gmail.com>
Jarek Poplawski wrote:
> Jarek Poplawski wrote, On 09/05/2009 01:57 PM:
>
>>>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>>>> index 09cdcdf..eaa8f43 100644
>>>> --- a/net/sched/cls_api.c
>>>> +++ b/net/sched/cls_api.c
>>>> @@ -181,6 +181,9 @@ replay:
>>>> if ((cops = q->ops->cl_ops) == NULL)
>>>> return -EINVAL;
>>>>
>>>> + if (cops->tcf_chain == NULL)
>>>> + return -EOPNOTSUPP;
>>>> +
>>> You should probably repeat this in tc_dump_tfilter.
>>
>>
>> ...In case somebody finds the way to list a filter before
>> adding it. ;-) But, since it's quite unlikely, let's foget it.
>
>
> ...or simply tries to do it instead of meditating the code.
> So this change is definitely needed in tc_dump_tfilter too.
Thanks Jarek. I'm on my way out the door, but I'll fix that tommorrow.
^ permalink raw reply
* [PATCH NEXT 1/6] netxen: handle firmware load errors
From: Dhananjay Phadke @ 2009-09-06 3:43 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1252208592-2240-1-git-send-email-dhananjay@netxen.com>
Unwind allocations and release file firmware when
when firmware load fails.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic_hw.c | 3 +++
drivers/net/netxen/netxen_nic_init.c | 1 +
drivers/net/netxen/netxen_nic_main.c | 20 ++++++++++++++++----
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index db510ce..d0ac8fa 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -566,6 +566,9 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
i = 0;
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return -EIO;
+
tx_ring = adapter->tx_ring;
__netif_tx_lock_bh(tx_ring->txq);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 04e36f2..534994d 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -905,6 +905,7 @@ netxen_release_firmware(struct netxen_adapter *adapter)
{
if (adapter->fw)
release_firmware(adapter->fw);
+ adapter->fw = NULL;
}
int netxen_init_dummy_dma(struct netxen_adapter *adapter)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 41b2967..47aede6 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -757,7 +757,7 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
err = netxen_need_fw_reset(adapter);
if (err < 0)
- return err;
+ goto err_out;
if (err == 0)
goto wait_init;
@@ -771,7 +771,9 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_set_port_mode(adapter);
- netxen_load_firmware(adapter);
+ err = netxen_load_firmware(adapter);
+ if (err)
+ goto err_out;
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
@@ -785,7 +787,7 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
err = netxen_init_dummy_dma(adapter);
if (err)
- return err;
+ goto err_out;
/*
* Tell the hardware our version number.
@@ -800,7 +802,7 @@ wait_init:
err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
if (err) {
netxen_free_dummy_dma(adapter);
- return err;
+ goto err_out;
}
nx_update_dma_mask(adapter);
@@ -808,6 +810,10 @@ wait_init:
netxen_nic_get_firmware_info(adapter);
return 0;
+
+err_out:
+ netxen_release_firmware(adapter);
+ return err;
}
static int
@@ -876,6 +882,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
{
int err;
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return -EIO;
+
err = adapter->init_port(adapter, adapter->physical_port);
if (err) {
printk(KERN_ERR "%s: Failed to initialize port %d\n",
@@ -914,6 +923,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
static void
netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ return;
+
spin_lock(&adapter->tx_clean_lock);
netif_carrier_off(netdev);
netif_tx_disable(netdev);
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 0/6] nexten: fixes and enhancements
From: Dhananjay Phadke @ 2009-09-06 3:43 UTC (permalink / raw)
To: davem; +Cc: netdev
Series of 6 driver enhancements / fixes, please apply to net-next-2.6.
Thanks,
Dhananjay
^ permalink raw reply
* [PATCH NEXT 3/6] netxen: fix ip addr hashing after firmware reset
From: Dhananjay Phadke @ 2009-09-06 3:43 UTC (permalink / raw)
To: davem; +Cc: netdev, Amit Kumar Salecha
In-Reply-To: <1252208592-2240-1-git-send-email-dhananjay@netxen.com>
From: Amit Kumar Salecha <amit@netxen.com>
Reprogram local IP addresses after firmware is reset
or after resuming from suspend.
Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic_main.c | 61 +++++++++++++++++++++------------
1 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4989436..7038e1b 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -86,6 +86,8 @@ static irqreturn_t netxen_intr(int irq, void *data);
static irqreturn_t netxen_msi_intr(int irq, void *data);
static irqreturn_t netxen_msix_intr(int irq, void *data);
+static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+
/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
@@ -1411,6 +1413,8 @@ netxen_nic_resume(struct pci_dev *pdev)
goto err_out_detach;
netif_device_attach(netdev);
+
+ netxen_config_indev_addr(netdev, NETDEV_UP);
}
netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
@@ -2057,6 +2061,7 @@ netxen_attach_work(struct work_struct *work)
goto done;
}
+ netxen_config_indev_addr(netdev, NETDEV_UP);
}
netif_device_attach(netdev);
@@ -2282,12 +2287,43 @@ netxen_destip_supported(struct netxen_adapter *adapter)
return 1;
}
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+{
+ struct in_device *indev;
+ struct netxen_adapter *adapter = netdev_priv(dev);
+
+ if (netxen_destip_supported(adapter))
+ return;
+
+ indev = in_dev_get(dev);
+ if (!indev)
+ return;
+
+ for_ifa(indev) {
+ switch (event) {
+ case NETDEV_UP:
+ netxen_config_ipaddr(adapter,
+ ifa->ifa_address, NX_IP_UP);
+ break;
+ case NETDEV_DOWN:
+ netxen_config_ipaddr(adapter,
+ ifa->ifa_address, NX_IP_DOWN);
+ break;
+ default:
+ break;
+ }
+ } endfor_ifa(indev);
+
+ in_dev_put(indev);
+ return;
+}
+
static int netxen_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct netxen_adapter *adapter;
struct net_device *dev = (struct net_device *)ptr;
- struct in_device *indev;
recheck:
if (dev == NULL)
@@ -2303,32 +2339,13 @@ recheck:
adapter = netdev_priv(dev);
- if (!adapter || !netxen_destip_supported(adapter))
+ if (!adapter)
goto done;
if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
goto done;
- indev = in_dev_get(dev);
- if (!indev)
- goto done;
-
- for_ifa(indev) {
- switch (event) {
- case NETDEV_UP:
- netxen_config_ipaddr(adapter,
- ifa->ifa_address, NX_IP_UP);
- break;
- case NETDEV_DOWN:
- netxen_config_ipaddr(adapter,
- ifa->ifa_address, NX_IP_DOWN);
- break;
- default:
- break;
- }
- } endfor_ifa(indev);
-
- in_dev_put(indev);
+ netxen_config_indev_addr(dev, event);
done:
return NOTIFY_DONE;
}
--
1.6.0.2
^ permalink raw reply related
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